"use client"; import { useState } from "react"; import { observer } from "mobx-react"; import { useParams, usePathname } from "next/navigation"; import { CircleDashed, Plus } from "lucide-react"; // types import { TIssue, ISearchIssueResponse } from "@plane/types"; // ui import { CustomMenu, TOAST_TYPE, setToast } from "@plane/ui"; // components import { ExistingIssuesListModal, MultipleSelectGroupAction } from "@/components/core"; import { CreateUpdateIssueModal } from "@/components/issues"; // constants // helpers import { cn } from "@/helpers/common.helper"; // hooks import { useEventTracker } from "@/hooks/store"; import { useIssueStoreType } from "@/hooks/use-issue-layout-store"; import { TSelectionHelper } from "@/hooks/use-multiple-select"; interface IHeaderGroupByCard { groupID: string; icon?: React.ReactNode; title: string; count: number; issuePayload: Partial; canEditProperties: (projectId: string | undefined) => boolean; toggleListGroup: () => void; disableIssueCreation?: boolean; addIssuesToView?: (issueIds: string[]) => Promise; selectionHelpers: TSelectionHelper; } export const HeaderGroupByCard = observer((props: IHeaderGroupByCard) => { const { groupID, icon, title, count, issuePayload, canEditProperties, disableIssueCreation, addIssuesToView, selectionHelpers, toggleListGroup, } = props; // states const [isOpen, setIsOpen] = useState(false); const [openExistingIssueListModal, setOpenExistingIssueListModal] = useState(false); // router const { workspaceSlug, projectId, moduleId, cycleId } = useParams(); const pathname = usePathname(); // hooks const { setTrackElement } = useEventTracker(); const storeType = useIssueStoreType(); // derived values const isDraftIssue = pathname.includes("draft-issue"); const renderExistingIssueModal = moduleId || cycleId; const existingIssuesListModalPayload = moduleId ? { module: moduleId.toString() } : { cycle: true }; const isGroupSelectionEmpty = selectionHelpers.isGroupSelected(groupID) === "empty"; // auth const canSelectIssues = canEditProperties(projectId?.toString()) && !selectionHelpers.isSelectionDisabled; const handleAddIssuesToView = async (data: ISearchIssueResponse[]) => { if (!workspaceSlug || !projectId) return; const issues = data.map((i) => i.id); try { await addIssuesToView?.(issues); setToast({ type: TOAST_TYPE.SUCCESS, title: "Success!", message: "Issues added to the cycle successfully.", }); } catch (error) { setToast({ type: TOAST_TYPE.ERROR, title: "Error!", message: "Selected issues could not be added to the cycle. Please try again.", }); } }; return ( <>
{canSelectIssues && (
)}
{icon ?? }
{title}
{count || 0}
{!disableIssueCreation && (renderExistingIssueModal ? ( } > { setTrackElement("List layout"); setIsOpen(true); }} > Create issue { setTrackElement("List layout"); setOpenExistingIssueListModal(true); }} > Add an existing issue ) : (
{ setTrackElement("List layout"); setIsOpen(true); }} >
))} setIsOpen(false)} data={issuePayload} storeType={storeType} isDraft={isDraftIssue} /> {renderExistingIssueModal && ( setOpenExistingIssueListModal(false)} searchParams={existingIssuesListModalPayload} handleOnSubmit={handleAddIssuesToView} /> )}
); });