import { FC, useRef, useState } from "react"; import { observer } from "mobx-react-lite"; // ui import { Spinner } from "@plane/ui"; // components import { DeleteIssueModal, IssuePeekOverviewHeader, TPeekModes, PeekOverviewIssueDetails, PeekOverviewProperties, TIssueOperations, ArchiveIssueModal, PeekOverviewIssueAttachments, } from "@/components/issues"; // hooks import { useIssueDetail, useUser } from "@/hooks/store"; import useKeypress from "@/hooks/use-keypress"; import useOutsideClickDetector from "@/hooks/use-outside-click-detector"; // store hooks import { IssueActivity } from "../issue-detail/issue-activity"; import { SubIssuesRoot } from "../sub-issues"; interface IIssueView { workspaceSlug: string; projectId: string; issueId: string; isLoading?: boolean; is_archived: boolean; disabled?: boolean; issueOperations: TIssueOperations; } export const IssueView: FC = observer((props) => { const { workspaceSlug, projectId, issueId, isLoading, is_archived, disabled = false, issueOperations } = props; // states const [peekMode, setPeekMode] = useState("side-peek"); const [isSubmitting, setIsSubmitting] = useState<"submitting" | "submitted" | "saved">("saved"); // ref const issuePeekOverviewRef = useRef(null); // store hooks const { currentUser } = useUser(); const { setPeekIssue, isAnyModalOpen, isDeleteIssueModalOpen, isArchiveIssueModalOpen, toggleDeleteIssueModal, toggleArchiveIssueModal, issue: { getIssueById }, } = useIssueDetail(); const issue = getIssueById(issueId); // remove peek id const removeRoutePeekId = () => { setPeekIssue(undefined); }; useOutsideClickDetector(issuePeekOverviewRef, () => { if (!isAnyModalOpen) { removeRoutePeekId(); } }); const handleKeyDown = () => { const slashCommandDropdownElement = document.querySelector("#slash-command"); const dropdownElement = document.activeElement?.tagName === "INPUT"; if (!isAnyModalOpen && !slashCommandDropdownElement && !dropdownElement) { removeRoutePeekId(); const issueElement = document.getElementById(`issue-${issueId}`); if (issueElement) issueElement?.focus(); } }; useKeypress("Escape", handleKeyDown); const handleRestore = async () => { if (!issueOperations.restore) return; await issueOperations.restore(workspaceSlug, projectId, issueId); removeRoutePeekId(); }; return ( <> {issue && !is_archived && ( toggleArchiveIssueModal(false)} data={issue} onSubmit={async () => { if (issueOperations.archive) await issueOperations.archive(workspaceSlug, projectId, issueId); removeRoutePeekId(); }} /> )} {issue && !is_archived && ( { toggleDeleteIssueModal(false); }} data={issue} onSubmit={() => issueOperations.remove(workspaceSlug, projectId, issueId)} /> )} {issue && is_archived && ( toggleDeleteIssueModal(false)} onSubmit={() => issueOperations.remove(workspaceSlug, projectId, issueId)} /> )}
{issueId && (
{/* header */} setPeekMode(value)} removeRoutePeekId={removeRoutePeekId} toggleDeleteIssueModal={toggleDeleteIssueModal} toggleArchiveIssueModal={toggleArchiveIssueModal} handleRestoreIssue={handleRestore} isArchived={is_archived} issueId={issueId} workspaceSlug={workspaceSlug} projectId={projectId} isSubmitting={isSubmitting} disabled={disabled} /> {/* content */}
{isLoading && !issue ? (
) : ( issue && ( <> {["side-peek", "modal"].includes(peekMode) ? (
setIsSubmitting(value)} /> {currentUser && ( )}
) : (
setIsSubmitting(value)} /> {currentUser && ( )}
)} ) )}
)}
); });