import React, { useState } from "react"; import Link from "next/link"; import { useRouter } from "next/router"; import useSWR, { mutate } from "swr"; // services import issuesService from "services/issues.service"; import workspaceService from "services/workspace.service"; import stateService from "services/state.service"; // headless ui import { Listbox, Transition } from "@headlessui/react"; // ui import { CustomMenu, CustomSelect, AssigneesList, Avatar } from "components/ui"; // components import ConfirmIssueDeletion from "components/project/issues/confirm-issue-deletion"; // icons import { CalendarDaysIcon } from "@heroicons/react/24/outline"; // helpers import { renderShortNumericDateFormat, findHowManyDaysLeft } from "helpers/date-time.helper"; import { addSpaceIfCamelCase } from "helpers/string.helper"; // types import { IIssue, IWorkspaceMember, Properties, UserAuth } from "types"; // fetch-keys import { CYCLE_ISSUES, MODULE_ISSUES, PROJECT_ISSUES_LIST, STATE_LIST, WORKSPACE_MEMBERS, } from "constants/fetch-keys"; // constants import { getPriorityIcon } from "constants/global"; import { PRIORITIES } from "constants/"; type Props = { type?: string; typeId?: string; issue: IIssue; properties: Properties; editIssue: () => void; removeIssue?: () => void; userAuth: UserAuth; }; const SingleListIssue: React.FC = ({ type, typeId, issue, properties, editIssue, removeIssue, userAuth, }) => { const [deleteIssue, setDeleteIssue] = useState(); const router = useRouter(); const { workspaceSlug, projectId } = router.query; const { data: states } = useSWR( workspaceSlug && projectId ? STATE_LIST(projectId as string) : null, workspaceSlug && projectId ? () => stateService.getStates(workspaceSlug as string, projectId as string) : null ); const { data: people } = useSWR( workspaceSlug ? WORKSPACE_MEMBERS : null, workspaceSlug ? () => workspaceService.workspaceMembers(workspaceSlug as string) : null ); const partialUpdateIssue = (formData: Partial) => { if (!workspaceSlug || !projectId) return; issuesService .patchIssue(workspaceSlug as string, projectId as string, issue.id, formData) .then((res) => { if (typeId) { mutate(CYCLE_ISSUES(typeId ?? "")); mutate(MODULE_ISSUES(typeId ?? "")); } mutate(PROJECT_ISSUES_LIST(workspaceSlug as string, projectId as string)); }) .catch((error) => { console.log(error); }); }; const isNotAllowed = userAuth.isGuest || userAuth.isViewer; return ( <> setDeleteIssue(undefined)} isOpen={!!deleteIssue} data={deleteIssue} />
{properties.priority && ( { partialUpdateIssue({ priority: data }); }} className="group relative flex-shrink-0" disabled={isNotAllowed} > {({ open }) => ( <>
{getPriorityIcon( issue.priority && issue.priority !== "" ? issue.priority ?? "" : "None", "text-sm" )} {PRIORITIES?.map((priority) => ( `flex cursor-pointer select-none items-center gap-x-2 px-3 py-2 capitalize ${ active ? "bg-indigo-50" : "bg-white" }` } value={priority} > {getPriorityIcon(priority, "text-sm")} {priority ?? "None"} ))}
Priority
{issue.priority ?? "None"}
)}
)} {properties.state && ( {addSpaceIfCamelCase(issue.state_detail.name)} } value={issue.state} onChange={(data: string) => { partialUpdateIssue({ state: data }); }} maxHeight="md" noChevron disabled={isNotAllowed} > {states?.map((state) => ( <> {addSpaceIfCamelCase(state.name)} ))} )} {/* {properties.cycle && !typeId && (
{issue.issue_cycle ? issue.issue_cycle.cycle_detail.name : "None"}
)} */} {properties.due_date && (
{issue.target_date ? renderShortNumericDateFormat(issue.target_date) : "N/A"}
Due date
{renderShortNumericDateFormat(issue.target_date ?? "")}
{issue.target_date && (issue.target_date < new Date().toISOString() ? `Due date has passed by ${findHowManyDaysLeft(issue.target_date)} days` : findHowManyDaysLeft(issue.target_date) <= 3 ? `Due date is in ${findHowManyDaysLeft(issue.target_date)} days` : "Due date")}
)} {properties.sub_issue_count && (
{issue.sub_issues_count} {issue.sub_issues_count === 1 ? "sub-issue" : "sub-issues"}
)} {properties.assignee && ( { const newData = issue.assignees ?? []; if (newData.includes(data)) newData.splice(newData.indexOf(data), 1); else newData.push(data); partialUpdateIssue({ assignees_list: newData }); }} className="group relative flex-shrink-0" disabled={isNotAllowed} > {({ open }) => ( <>
{people?.map((person) => ( `flex items-center gap-x-1 cursor-pointer select-none p-2 ${ active ? "bg-indigo-50" : "" } ${ selected || issue.assignees?.includes(person.member.id) ? "bg-indigo-50 font-medium" : "font-normal" }` } value={person.member.id} >

{person.member.first_name && person.member.first_name !== "" ? person.member.first_name : person.member.email}

))}
Assigned to
{issue.assignee_details?.length > 0 ? issue.assignee_details.map((assignee) => assignee.first_name).join(", ") : "No one"}
)}
)} {type && !isNotAllowed && ( Edit {type !== "issue" && ( <>Remove from {type} )} setDeleteIssue(issue)}> Delete permanently )}
); }; export default SingleListIssue;