import React, { useState } from "react"; import Link from "next/link"; import Image from "next/image"; import { useRouter } from "next/router"; import useSWR from "swr"; import { Disclosure, Listbox, Transition } from "@headlessui/react"; // hooks import useIssuesProperties from "lib/hooks/useIssuesProperties"; // services import stateService from "lib/services/state.service"; import issuesService from "lib/services/issues.service"; import projectService from "lib/services/project.service"; import workspaceService from "lib/services/workspace.service"; // constants import { addSpaceIfCamelCase, classNames, findHowManyDaysLeft, renderShortNumericDateFormat, } from "constants/common"; import { PRIORITIES } from "constants/"; import { getPriorityIcon } from "constants/global"; import { PROJECT_DETAILS, PROJECT_ISSUES_LIST, STATE_LIST, WORKSPACE_MEMBERS, } from "constants/fetch-keys"; // ui import { CustomMenu, CustomSelect, Spinner } from "ui"; // icons import User from "public/user.png"; import { ChevronDownIcon, PlusIcon, CalendarDaysIcon } from "@heroicons/react/24/outline"; // components import CreateUpdateIssuesModal from "components/project/issues/create-update-issue-modal"; // types import { IIssue, IProject, IssueResponse, IWorkspaceMember, NestedKeyOf } from "types"; // types type Props = { groupedByIssues: any; selectedGroup: NestedKeyOf | null; setSelectedIssue: any; handleDeleteIssue: React.Dispatch>; partialUpdateIssue: (formData: Partial, issueId: string) => void; }; const ListView: React.FC = ({ groupedByIssues, selectedGroup, setSelectedIssue, handleDeleteIssue, partialUpdateIssue, }) => { const [isCreateIssuesModalOpen, setIsCreateIssuesModalOpen] = useState(false); const [preloadedData, setPreloadedData] = useState< (Partial & { actionType: "createIssue" | "edit" | "delete" }) | undefined >(undefined); const router = useRouter(); const { workspaceSlug, projectId } = router.query; const { data: issues } = useSWR( workspaceSlug && projectId ? PROJECT_ISSUES_LIST(workspaceSlug as string, projectId as string) : null, workspaceSlug && projectId ? () => issuesService.getIssues(workspaceSlug as string, projectId as string) : null ); 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 { data: projectDetails } = useSWR( workspaceSlug && projectId ? PROJECT_DETAILS(projectId as string) : null, workspaceSlug && projectId ? () => projectService.getProject(workspaceSlug as string, projectId as string) : null ); const [properties] = useIssuesProperties(workspaceSlug as string, projectId as string); return ( <>
{Object.keys(groupedByIssues).map((singleGroup) => ( {({ open }) => (
{selectedGroup !== null ? (

{singleGroup === null || singleGroup === "null" ? selectedGroup === "priority" && "No priority" : selectedGroup === "created_by" ? people?.find((p) => p.member.id === singleGroup)?.member ?.first_name ?? "Loading..." : addSpaceIfCamelCase(singleGroup)}

) : (

All Issues

)}

{groupedByIssues[singleGroup as keyof IIssue].length}

{groupedByIssues[singleGroup] ? ( groupedByIssues[singleGroup].length > 0 ? ( groupedByIssues[singleGroup].map((issue: IIssue) => { const assignees = [ ...(issue?.assignees_list ?? []), ...(issue?.assignees ?? []), ]?.map((assignee) => { const tempPerson = people?.find( (p) => p.member.id === assignee )?.member; return { avatar: tempPerson?.avatar, first_name: tempPerson?.first_name, email: tempPerson?.email, }; }); const totalChildren = issues?.results.filter( (i) => i.parent === issue.id ).length; return (
{properties.priority && ( { partialUpdateIssue({ priority: data }, issue.id); }} className="group relative flex-shrink-0" > {({ open }) => ( <>
{getPriorityIcon( issue.priority && issue.priority !== "" ? issue.priority ?? "" : "None", "text-sm" )} {PRIORITIES?.map((priority) => ( classNames( active ? "bg-indigo-50" : "bg-white", "flex cursor-pointer select-none items-center gap-x-2 px-3 py-2 capitalize" ) } 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 }, issue.id); }} maxHeight="md" noChevron > {states?.map((state) => ( <> {addSpaceIfCamelCase(state.name)} ))} )} {properties.due_date && (
{issue.target_date ? renderShortNumericDateFormat(issue.target_date) : "N/A"}
Target 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 && (
{totalChildren}{" "} {totalChildren === 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 }, issue.id); }} className="group relative flex-shrink-0" > {({ open }) => ( <>
{assignees.length > 0 ? ( assignees.map((assignee, index: number) => (
{assignee.avatar && assignee.avatar !== "" ? (
{assignee?.first_name}
) : (
{assignee.first_name?.charAt(0)}
)}
)) ) : (
No user
)}
{people?.map((person) => ( classNames( active ? "bg-indigo-50" : "bg-white", "cursor-pointer select-none p-2" ) } value={person.member.id} >
{person.member.avatar && person.member.avatar !== "" ? (
avatar
) : (
{person.member.first_name && person.member.first_name !== "" ? person.member.first_name.charAt(0) : person.member.email.charAt(0)}
)}

{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"}
)}
)} { setSelectedIssue({ ...issue, actionType: "edit", }); }} > Edit { handleDeleteIssue(issue.id); }} > Delete permanently
); }) ) : (

No issues.

) ) : (
)}
)}
))}
); }; export default ListView;