import { FC, ReactNode, useState } from "react"; import { useRouter } from "next/router"; import { observer } from "mobx-react-lite"; import useSWR from "swr"; import { MoveRight, MoveDiagonal, Bell, Link2, Trash2 } from "lucide-react"; // components import { PeekOverviewIssueDetails } from "./issue-detail"; import { PeekOverviewProperties } from "./properties"; import { IssueComment } from "./activity"; import { Button, CenterPanelIcon, CustomSelect, FullScreenPanelIcon, SidePanelIcon, Spinner } from "@plane/ui"; import { DeleteIssueModal, DeleteArchivedIssueModal, IssueUpdateStatus } from "components/issues/"; // types import { IIssue } from "types"; // hooks import { useMobxStore } from "lib/mobx/store-provider"; interface IIssueView { workspaceSlug: string; projectId: string; issueId: string; issue: IIssue | null; isLoading?: boolean; isArchived?: boolean; handleCopyText: (e: React.MouseEvent) => void; redirectToIssueDetail: () => void; issueUpdate: (issue: Partial) => void; issueReactionCreate: (reaction: string) => void; issueReactionRemove: (reaction: string) => void; issueCommentCreate: (comment: any) => void; issueCommentUpdate: (comment: any) => void; issueCommentRemove: (commentId: string) => void; issueCommentReactionCreate: (commentId: string, reaction: string) => void; issueCommentReactionRemove: (commentId: string, reaction: string) => void; issueSubscriptionCreate: () => void; issueSubscriptionRemove: () => void; handleDeleteIssue: () => Promise; children: ReactNode; disableUserActions?: boolean; showCommentAccessSpecifier?: boolean; } type TPeekModes = "side-peek" | "modal" | "full-screen"; const peekOptions: { key: TPeekModes; icon: any; title: string }[] = [ { key: "side-peek", icon: SidePanelIcon, title: "Side Peek", }, { key: "modal", icon: CenterPanelIcon, title: "Modal", }, { key: "full-screen", icon: FullScreenPanelIcon, title: "Full Screen", }, ]; export const IssueView: FC = observer((props) => { const { workspaceSlug, projectId, issueId, issue, isLoading, isArchived, handleCopyText, redirectToIssueDetail, issueUpdate, issueReactionCreate, issueReactionRemove, issueCommentCreate, issueCommentUpdate, issueCommentRemove, issueCommentReactionCreate, issueCommentReactionRemove, issueSubscriptionCreate, issueSubscriptionRemove, handleDeleteIssue, children, disableUserActions = false, showCommentAccessSpecifier = false, } = props; const router = useRouter(); const { peekIssueId } = router.query as { peekIssueId: string }; const { user: userStore, issueDetail: issueDetailStore } = useMobxStore(); const [peekMode, setPeekMode] = useState("side-peek"); const [deleteIssueModal, setDeleteIssueModal] = useState(false); const [isSubmitting, setIsSubmitting] = useState<"submitting" | "submitted" | "saved">("saved"); const updateRoutePeekId = () => { if (issueId != peekIssueId) { issueDetailStore.setPeekId(issueId); const { query } = router; router.push({ pathname: router.pathname, query: { ...query, peekIssueId: issueId, peekProjectId: projectId }, }); } }; const removeRoutePeekId = () => { const { query } = router; if (query.peekIssueId) { issueDetailStore.setPeekId(null); delete query.peekIssueId; delete query.peekProjectId; router.push({ pathname: router.pathname, query: { ...query }, }); } }; useSWR( workspaceSlug && projectId && issueId && peekIssueId && issueId === peekIssueId ? `ISSUE_PEEK_OVERVIEW_SUBSCRIPTION_${workspaceSlug}_${projectId}_${peekIssueId}` : null, async () => { if (workspaceSlug && projectId && issueId && peekIssueId && issueId === peekIssueId) { await issueDetailStore.fetchIssueSubscription(workspaceSlug, projectId, issueId); } } ); const issueReactions = issueDetailStore.getIssueReactions || []; const issueComments = issueDetailStore.getIssueComments || []; const issueSubscription = issueDetailStore.getIssueSubscription || []; const user = userStore?.currentUser; const currentMode = peekOptions.find((m) => m.key === peekMode); return ( <> {issue && !isArchived && ( setDeleteIssueModal(false)} data={issue} onSubmit={handleDeleteIssue} /> )} {issue && isArchived && ( setDeleteIssueModal(false)} onSubmit={handleDeleteIssue} /> )}
{children && (
{children}
)} {issueId === peekIssueId && (
{/* header */}
{currentMode && (
setPeekMode(val)} customButton={ } > {peekOptions.map((mode) => (
{mode.title}
))}
)}
{issue?.created_by !== user?.id && !issue?.assignees.includes(user?.id ?? "") && !router.pathname.includes("[archivedIssueId]") && ( )} {!disableUserActions && ( )}
{/* content */}
{isLoading && !issue ? (
) : ( issue && ( <> {["side-peek", "modal"].includes(peekMode) ? (
{isArchived && (
)} setIsSubmitting(value)} isSubmitting={isSubmitting} workspaceSlug={workspaceSlug} issue={issue} issueUpdate={issueUpdate} issueReactions={issueReactions} user={user} issueReactionCreate={issueReactionCreate} issueReactionRemove={issueReactionRemove} />
) : (
setIsSubmitting(value)} isSubmitting={isSubmitting} workspaceSlug={workspaceSlug} issue={issue} issueReactions={issueReactions} issueUpdate={issueUpdate} user={user} issueReactionCreate={issueReactionCreate} issueReactionRemove={issueReactionRemove} />
)} ) )}
)}
); });