import React, { useCallback } from "react"; import Link from "next/link"; import { useRouter } from "next/router"; import { mutate } from "swr"; // react-beautiful-dnd import { DraggableProvided, DraggableStateSnapshot } from "react-beautiful-dnd"; // services import issuesService from "services/issues.service"; // hooks import useCalendarIssuesView from "hooks/use-calendar-issues-view"; import useIssuesProperties from "hooks/use-issue-properties"; import useToast from "hooks/use-toast"; // components import { CustomMenu, Tooltip } from "components/ui"; import { ViewAssigneeSelect, ViewDueDateSelect, ViewEstimateSelect, ViewPrioritySelect, ViewStateSelect, } from "components/issues"; // icons import { LinkIcon, PaperClipIcon, PencilIcon, TrashIcon } from "@heroicons/react/24/outline"; // helper import { copyTextToClipboard, truncateText } from "helpers/string.helper"; // type import { IIssue } from "types"; // fetch-keys import { CYCLE_ISSUES_WITH_PARAMS, MODULE_ISSUES_WITH_PARAMS, PROJECT_ISSUES_LIST_WITH_PARAMS, VIEW_ISSUES, } from "constants/fetch-keys"; type Props = { handleEditIssue: (issue: IIssue) => void; handleDeleteIssue: (issue: IIssue) => void; index: number; provided: DraggableProvided; snapshot: DraggableStateSnapshot; issue: IIssue; isNotAllowed: boolean; }; export const SingleCalendarIssue: React.FC = ({ handleEditIssue, handleDeleteIssue, index, provided, snapshot, issue, isNotAllowed, }) => { const router = useRouter(); const { workspaceSlug, projectId, cycleId, moduleId, viewId } = router.query; const { setToastAlert } = useToast(); const { params } = useCalendarIssuesView(); const [properties] = useIssuesProperties(workspaceSlug as string, projectId as string); const partialUpdateIssue = useCallback( (formData: Partial, issueId: string) => { if (!workspaceSlug || !projectId) return; const fetchKey = cycleId ? CYCLE_ISSUES_WITH_PARAMS(cycleId.toString(), params) : moduleId ? MODULE_ISSUES_WITH_PARAMS(moduleId.toString(), params) : viewId ? VIEW_ISSUES(viewId.toString(), params) : PROJECT_ISSUES_LIST_WITH_PARAMS(projectId.toString(), params); mutate( fetchKey, (prevData) => (prevData ?? []).map((p) => { if (p.id === issueId) { return { ...p, ...formData, assignees: formData?.assignees_list ?? p.assignees, }; } return p; }), false ); issuesService .patchIssue(workspaceSlug as string, projectId as string, issueId as string, formData) .then(() => { mutate(fetchKey); }) .catch((error) => { console.log(error); }); }, [workspaceSlug, projectId, cycleId, moduleId, params] ); const handleCopyText = () => { const originURL = typeof window !== "undefined" && window.location.origin ? window.location.origin : ""; copyTextToClipboard( `${originURL}/${workspaceSlug}/projects/${projectId}/issues/${issue.id}` ).then(() => { setToastAlert({ type: "success", title: "Link Copied!", message: "Issue link copied to clipboard.", }); }); }; const displayProperties = properties ? Object.values(properties).some((value) => value === true) : false; return (
{!isNotAllowed && (
handleEditIssue(issue)}>
Edit issue
handleDeleteIssue(issue)}>
Delete issue
Copy issue Link
)} {properties.key && ( {issue.project_detail?.identifier}-{issue.sequence_id} )} {truncateText(issue.name, 25)} {displayProperties && (
{properties.priority && ( )} {properties.state && ( )} {properties.due_date && ( )} {properties.sub_issue_count && (
{issue.sub_issues_count} {issue.sub_issues_count === 1 ? "sub-issue" : "sub-issues"}
)} {properties.labels && issue.label_details.length > 0 ? (
{issue.label_details.map((label) => ( {label.name} ))}
) : ( "" )} {properties.assignee && ( )} {properties.estimate && ( )} {properties.link && (
{issue.link_count}
)} {properties.attachment_count && (
{issue.attachment_count}
)}
)}
); };