import React, { useCallback, useMemo, useState } from "react"; import { observer } from "mobx-react-lite"; import { Plus, ChevronRight, ChevronDown } from "lucide-react"; // hooks import { useIssueDetail, useIssues, useUser } from "hooks/store"; import useToast from "hooks/use-toast"; // components import { ExistingIssuesListModal } from "components/core"; import { CreateUpdateIssueModal, DeleteIssueModal } from "components/issues"; import { SubIssuesRootList } from "./issues-list"; import { ProgressBar } from "./progressbar"; // ui import { CustomMenu } from "@plane/ui"; // helpers import { copyTextToClipboard } from "helpers/string.helper"; // types import { IUser, TIssue, ISearchIssueResponse } from "@plane/types"; // services import { IssueService } from "services/issue"; // fetch keys import { SUB_ISSUES } from "constants/fetch-keys"; // constants import { EUserProjectRoles } from "constants/project"; import { EIssuesStoreType } from "constants/issue"; export interface ISubIssuesRoot { workspaceSlug: string; projectId: string; issueId: string; currentUser: IUser; is_archived: boolean; is_editable: boolean; } export const SubIssuesRoot: React.FC = observer((props) => { const { workspaceSlug, projectId, issueId, currentUser, is_archived, is_editable } = props; // store hooks const { membership: { currentProjectRole }, } = useUser(); const { setToastAlert } = useToast(); const { subIssues: { subIssuesByIssueId, subIssuesStateDistribution }, updateIssue, removeIssue, fetchSubIssues, createSubIssues, } = useIssueDetail(); // state const [currentIssue, setCurrentIssue] = useState(); console.log("subIssuesByIssueId", subIssuesByIssueId(issueId)); const copyText = (text: string) => { const originURL = typeof window !== "undefined" && window.location.origin ? window.location.origin : ""; copyTextToClipboard(`${originURL}/${text}`).then(() => { setToastAlert({ type: "success", title: "Link Copied!", message: "Issue link copied to clipboard.", }); }); }; const subIssueOperations = useMemo( () => ({ fetchSubIssues: async (workspaceSlug: string, projectId: string, issueId: string) => { try { await fetchSubIssues(workspaceSlug, projectId, issueId); } catch (error) {} }, update: async (workspaceSlug: string, projectId: string, issueId: string, data: Partial) => { try { await updateIssue(workspaceSlug, projectId, issueId, data); setToastAlert({ title: "Issue updated successfully", type: "success", message: "Issue updated successfully", }); } catch (error) { setToastAlert({ title: "Issue update failed", type: "error", message: "Issue update failed", }); } }, addSubIssue: async () => { try { } catch (error) {} }, removeSubIssue: async () => { try { } catch (error) {} }, updateIssue: async () => { try { } catch (error) {} }, deleteIssue: async () => { try { } catch (error) {} }, }), [] ); const [issueCrudOperation, setIssueCrudOperation] = React.useState<{ // type: "create" | "edit"; create: { toggle: boolean; issueId: string | null }; existing: { toggle: boolean; issueId: string | null }; }>({ create: { toggle: false, issueId: null, }, existing: { toggle: false, issueId: null, }, }); const handleIssueCrudOperation = ( key: "create" | "existing", issueId: string | null, issue: TIssue | null = null ) => { setIssueCrudOperation({ ...issueCrudOperation, [key]: { toggle: !issueCrudOperation[key].toggle, issueId: issueId, issue: issue, }, }); }; return (
{/* {!issues && isLoading ? (
Loading...
) : ( <> {issues && issues?.sub_issues && issues?.sub_issues?.length > 0 ? ( <>
handleIssuesLoader({ key: "visibility", issueId: parentIssue?.id })} >
{issuesLoader.visibility.includes(parentIssue?.id) ? ( ) : ( )}
Sub-issues
({issues?.sub_issues?.length || 0})
{is_editable && issuesLoader.visibility.includes(parentIssue?.id) && (
handleIssueCrudOperation("create", parentIssue?.id)} > Add sub-issue
handleIssueCrudOperation("existing", parentIssue?.id)} > Add an existing issue
)}
{issuesLoader.visibility.includes(parentIssue?.id) && workspaceSlug && projectId && (
)}
Add sub-issue } buttonClassName="whitespace-nowrap" placement="bottom-end" noBorder noChevron > { handleIssueCrudOperation("create", parentIssue?.id); }} > Create new { handleIssueCrudOperation("existing", parentIssue?.id); }} > Add an existing issue
) : ( is_editable && (
No Sub-Issues yet
Add sub-issue } buttonClassName="whitespace-nowrap" placement="bottom-end" noBorder noChevron > { handleIssueCrudOperation("create", parentIssue?.id); }} > Create new { handleIssueCrudOperation("existing", parentIssue?.id); }} > Add an existing issue
) )} {is_editable && issueCrudOperation?.create?.toggle && ( { handleIssueCrudOperation("create", null); }} /> )} {is_editable && issueCrudOperation?.existing?.toggle && issueCrudOperation?.existing?.issueId && ( handleIssueCrudOperation("existing", null)} searchParams={{ sub_issue: true, issue_id: issueCrudOperation?.existing?.issueId }} handleOnSubmit={addAsSubIssueFromExistingIssues} workspaceLevelToggle /> )} {is_editable && issueCrudOperation?.edit?.toggle && issueCrudOperation?.edit?.issueId && ( <> { handleIssueCrudOperation("edit", null, null); }} data={issueCrudOperation?.edit?.issue ?? undefined} /> )} {is_editable && workspaceSlug && projectId && issueCrudOperation?.delete?.issueId && issueCrudOperation?.delete?.issue && ( { handleIssueCrudOperation("delete", null, null); }} data={issueCrudOperation?.delete?.issue} onSubmit={async () => { await removeIssue( workspaceSlug.toString(), projectId.toString(), issueCrudOperation?.delete?.issue?.id ?? "" ); }} /> )} )} */}
); });