/** * Copyright (c) 2023-present Plane Software, Inc. and contributors * SPDX-License-Identifier: AGPL-3.0-only * See the LICENSE file for details. */ import type { Dispatch, SetStateAction } from "react"; import { useEffect, useMemo, useRef } from "react"; import { observer } from "mobx-react"; import type { EditorRefApi } from "@plane/editor"; import { useTranslation } from "@plane/i18n"; import { TOAST_TYPE, setToast } from "@plane/propel/toast"; import type { TIssue, TNameDescriptionLoader } from "@plane/types"; import { EFileAssetType, EInboxIssueSource } from "@plane/types"; import { getTextContent } from "@plane/utils"; import { DescriptionVersionsRoot } from "@/components/core/description-versions"; import { DescriptionInput } from "@/components/editor/rich-text/description-input"; import { DescriptionInputLoader } from "@/components/editor/rich-text/description-input/loader"; import { IssueAttachmentRoot } from "@/components/issues/attachment"; import type { TIssueOperations } from "@/components/issues/issue-detail"; import { IssueActivity } from "@/components/issues/issue-detail/issue-activity"; import { IssueReaction } from "@/components/issues/issue-detail/reactions"; import { IssueTitleInput } from "@/components/issues/title-input"; import { useIssueDetail } from "@/hooks/store/use-issue-detail"; import { useMember } from "@/hooks/store/use-member"; import { useProject } from "@/hooks/store/use-project"; import { useProjectInbox } from "@/hooks/store/use-project-inbox"; import { useUser } from "@/hooks/store/user"; import useReloadConfirmations from "@/hooks/use-reload-confirmation"; import { DeDupeIssuePopoverRoot } from "@/plane-web/components/de-dupe/duplicate-popover"; import { useDebouncedDuplicateIssues } from "@/plane-web/hooks/use-debounced-duplicate-issues"; import { IntakeWorkItemVersionService } from "@/services/inbox"; import type { IInboxIssueStore } from "@/store/inbox/inbox-issue.store"; import { ExternalContoursIssueContentProperties } from "./issue-properties"; const intakeWorkItemVersionService = new IntakeWorkItemVersionService(); type Props = { workspaceSlug: string; projectId: string; inboxIssue: IInboxIssueStore; isEditable: boolean; isSubmitting: TNameDescriptionLoader; setIsSubmitting: Dispatch>; }; export const ExternalContoursIssueMainContent = observer(function ExternalContoursIssueMainContent(props: Props) { const { workspaceSlug, projectId, inboxIssue, isEditable, isSubmitting, setIsSubmitting } = props; const { t } = useTranslation(); const editorRef = useRef(null); const { data: currentUser } = useUser(); const { getUserDetails } = useMember(); const { loader } = useProjectInbox(); const { getProjectById } = useProject(); const { removeIssue, archiveIssue } = useIssueDetail(); const { setShowAlert } = useReloadConfirmations(isSubmitting === "submitting"); useEffect(() => { if (isSubmitting === "submitted") { setShowAlert(false); setTimeout(async () => setIsSubmitting("saved"), 3000); } else if (isSubmitting === "submitting") { setShowAlert(true); } }, [isSubmitting, setIsSubmitting, setShowAlert]); const issue = inboxIssue.issue; const projectDetails = issue?.project_id ? getProjectById(issue.project_id) : undefined; const { duplicateIssues } = useDebouncedDuplicateIssues(workspaceSlug, projectDetails?.workspace.toString(), projectId, { name: issue?.name, description_html: getTextContent(issue?.description_html), issueId: issue?.id, }); const issueOperations: TIssueOperations = useMemo( () => ({ fetch: async () => undefined, remove: async (_workspaceSlug: string, _projectId: string, issueId: string) => { try { await removeIssue(workspaceSlug, projectId, issueId); setToast({ title: t("success"), type: TOAST_TYPE.SUCCESS, message: t("inbox_issue.modals.delete.success") }); } catch (error) { console.log("Error in deleting work item:", error); setToast({ title: t("error"), type: TOAST_TYPE.ERROR, message: t("something_went_wrong_please_try_again") }); } }, update: async (_workspaceSlug: string, _projectId: string, _issueId: string, data: Partial) => { try { await inboxIssue.updateIssue(data); } catch { setToast({ title: t("error"), type: TOAST_TYPE.ERROR, message: t("issue_could_not_be_updated") }); } }, archive: async (_workspaceSlug: string, _projectId: string, issueId: string) => { try { await archiveIssue(workspaceSlug, projectId, issueId); } catch (error) { console.error("Error in archiving issue:", error); } }, }), [archiveIssue, inboxIssue, projectId, removeIssue, workspaceSlug] ); if (!issue || !issue.project_id || !issue.id) return <>; return ( <>
{duplicateIssues.length > 0 && ( )} setIsSubmitting(value)} issueOperations={issueOperations} disabled={!isEditable} value={issue.name} containerClassName="-ml-3" /> {loader === "issue-loading" || issue.description_html === undefined ? ( ) : (

" : issue.description_html} key={issue.id} onSubmit={async (value, isMigrationUpdate) => { await issueOperations.update(workspaceSlug, issue.project_id, issue.id, { description_html: value.description_html, ...(isMigrationUpdate ? { skip_activity: "true" } : {}), }); }} projectId={issue.project_id} setIsSubmitting={(value) => setIsSubmitting(value)} workspaceSlug={workspaceSlug} /> )}
{currentUser && ( )} {isEditable && ( intakeWorkItemVersionService.listDescriptionVersions(workspaceSlug, projectId, issueId), retrieveDescriptionVersion: (issueId, versionId) => intakeWorkItemVersionService.retrieveDescriptionVersion(workspaceSlug, projectId, issueId, versionId), }} handleRestore={(descriptionHTML) => editorRef.current?.setEditorValue(descriptionHTML, true)} projectId={projectId} workspaceSlug={workspaceSlug} /> )}
); });