From a95e0080d307f407c31366aea951c0adec75ae6e Mon Sep 17 00:00:00 2001 From: Aaryan Khandelwal Date: Thu, 15 Jan 2026 15:53:38 +0530 Subject: [PATCH 1/2] refactor: description input component --- .../rich-text/description-input/root.tsx | 23 +++++++++++++++---- .../components/inbox/content/issue-root.tsx | 2 +- .../issues/issue-detail/main-content.tsx | 2 +- .../issues/peek-overview/issue-detail.tsx | 2 +- 4 files changed, 21 insertions(+), 8 deletions(-) diff --git a/apps/web/core/components/editor/rich-text/description-input/root.tsx b/apps/web/core/components/editor/rich-text/description-input/root.tsx index 7c95e1ace5a..0d85100f76e 100644 --- a/apps/web/core/components/editor/rich-text/description-input/root.tsx +++ b/apps/web/core/components/editor/rich-text/description-input/root.tsx @@ -22,6 +22,7 @@ const workspaceService = new WorkspaceService(); type TFormData = { id: string; description_html: string; + description_json?: object; isMigrationUpdate: boolean; }; @@ -57,7 +58,13 @@ type Props = { /** * @description Submit handler, the actual function which will be called when the form is submitted */ - onSubmit: (value: string, isMigrationUpdate?: boolean) => Promise; + onSubmit: ( + value: { + description_html: string; + description_json: object | undefined; + }, + isMigrationUpdate?: boolean + ) => Promise; /** * @description Placeholder, if not provided, the placeholder will be the default placeholder */ @@ -97,13 +104,13 @@ export const DescriptionInput = observer(function DescriptionInput(props: Props) entityId, fileAssetType, initialValue, + issueSequenceId, onSubmit, placeholder, projectId, setIsSubmitting, swrDescription, workspaceSlug, - issueSequenceId, } = props; // states const [localDescription, setLocalDescription] = useState({ @@ -132,7 +139,13 @@ export const DescriptionInput = observer(function DescriptionInput(props: Props) // submit handler const handleDescriptionFormSubmit = useCallback( async (formData: TFormData) => { - await onSubmit(formData.description_html, formData.isMigrationUpdate); + await onSubmit( + { + description_html: formData.description_html, + description_json: formData.description_json, + }, + formData.isMigrationUpdate + ); }, [onSubmit] ); @@ -203,7 +216,6 @@ export const DescriptionInput = observer(function DescriptionInput(props: Props) editable={!disabled} ref={editorRef} id={entityId} - issueSequenceId={issueSequenceId} disabledExtensions={disabledExtensions} initialValue={localDescription.description_html ?? "

"} value={swrDescription ?? null} @@ -211,10 +223,11 @@ export const DescriptionInput = observer(function DescriptionInput(props: Props) workspaceId={workspaceDetails.id} projectId={projectId} dragDropEnabled - onChange={(_description, description_html, options) => { + onChange={(description_json, description_html, options) => { setIsSubmitting("submitting"); onChange(description_html); setValue("isMigrationUpdate", options?.isMigrationUpdate ?? false); + setValue("description_json", description_json); hasUnsavedChanges.current = true; debouncedFormSave(); }} diff --git a/apps/web/core/components/inbox/content/issue-root.tsx b/apps/web/core/components/inbox/content/issue-root.tsx index c09dc192f2e..9cc452b7f5f 100644 --- a/apps/web/core/components/inbox/content/issue-root.tsx +++ b/apps/web/core/components/inbox/content/issue-root.tsx @@ -173,7 +173,7 @@ export const InboxIssueMainContent = observer(function InboxIssueMainContent(pro onSubmit={async (value, isMigrationUpdate) => { if (!issue.id || !issue.project_id) return; await issueOperations.update(workspaceSlug, issue.project_id, issue.id, { - description_html: value, + description_html: value.description_html, ...(isMigrationUpdate ? { skip_activity: "true" } : {}), }); }} diff --git a/apps/web/core/components/issues/issue-detail/main-content.tsx b/apps/web/core/components/issues/issue-detail/main-content.tsx index 78ac4e7507e..b1d3cba90f2 100644 --- a/apps/web/core/components/issues/issue-detail/main-content.tsx +++ b/apps/web/core/components/issues/issue-detail/main-content.tsx @@ -137,7 +137,7 @@ export const IssueMainContent = observer(function IssueMainContent(props: Props) onSubmit={async (value, isMigrationUpdate) => { if (!issue.id || !issue.project_id) return; await issueOperations.update(workspaceSlug, issue.project_id, issue.id, { - description_html: value, + description_html: value.description_html, ...(isMigrationUpdate ? { skip_activity: "true" } : {}), }); }} diff --git a/apps/web/core/components/issues/peek-overview/issue-detail.tsx b/apps/web/core/components/issues/peek-overview/issue-detail.tsx index 3efdbf6418a..a08fdad4a49 100644 --- a/apps/web/core/components/issues/peek-overview/issue-detail.tsx +++ b/apps/web/core/components/issues/peek-overview/issue-detail.tsx @@ -137,7 +137,7 @@ export const PeekOverviewIssueDetails = observer(function PeekOverviewIssueDetai onSubmit={async (value, isMigrationUpdate) => { if (!issue.id || !issue.project_id) return; await issueOperations.update(workspaceSlug, issue.project_id, issue.id, { - description_html: value, + description_html: value.description_html, ...(isMigrationUpdate ? { skip_activity: "true" } : {}), }); }} From 0c37595acbd830e3172e31c800d6d5dc3d6c0f3b Mon Sep 17 00:00:00 2001 From: Aaryan Khandelwal Date: Thu, 15 Jan 2026 16:06:04 +0530 Subject: [PATCH 2/2] fix: add missing prop to rich text editor --- .../rich-text/description-input/root.tsx | 135 +++++++++--------- 1 file changed, 66 insertions(+), 69 deletions(-) diff --git a/apps/web/core/components/editor/rich-text/description-input/root.tsx b/apps/web/core/components/editor/rich-text/description-input/root.tsx index 0d85100f76e..10c0a4744e1 100644 --- a/apps/web/core/components/editor/rich-text/description-input/root.tsx +++ b/apps/web/core/components/editor/rich-text/description-input/root.tsx @@ -205,77 +205,74 @@ export const DescriptionInput = observer(function DescriptionInput(props: Props) if (!workspaceDetails) return null; + if (!localDescription.description_html) return ; + return ( - <> - {localDescription.description_html ? ( - ( -

"} - value={swrDescription ?? null} - workspaceSlug={workspaceSlug} - workspaceId={workspaceDetails.id} - projectId={projectId} - dragDropEnabled - onChange={(description_json, description_html, options) => { - setIsSubmitting("submitting"); - onChange(description_html); - setValue("isMigrationUpdate", options?.isMigrationUpdate ?? false); - setValue("description_json", description_json); - hasUnsavedChanges.current = true; - debouncedFormSave(); - }} - placeholder={placeholder ?? ((isFocused, value) => t(getDescriptionPlaceholderI18n(isFocused, value)))} - searchMentionCallback={async (payload) => - await workspaceService.searchEntity(workspaceSlug?.toString() ?? "", { - ...payload, - project_id: projectId, - }) - } - containerClassName={containerClassName} - uploadFile={async (blockId, file) => { - try { - const { asset_id } = await uploadEditorAsset({ - blockId, - data: { - entity_identifier: entityId, - entity_type: fileAssetType, - }, - file, - projectId, - workspaceSlug, - }); - return asset_id; - } catch (error) { - console.log("Error in uploading asset:", error); - throw new Error("Asset upload failed. Please try again later."); - } - }} - duplicateFile={async (assetId: string) => { - try { - const { asset_id } = await duplicateEditorAsset({ - assetId, - entityType: fileAssetType, - projectId, - workspaceSlug, - }); - return asset_id; - } catch { - throw new Error("Asset duplication failed. Please try again later."); - } - }} - /> - )} + ( +

"} + value={swrDescription ?? null} + workspaceSlug={workspaceSlug} + workspaceId={workspaceDetails.id} + projectId={projectId} + dragDropEnabled + onChange={(description_json, description_html, options) => { + setIsSubmitting("submitting"); + onChange(description_html); + setValue("isMigrationUpdate", options?.isMigrationUpdate ?? false); + setValue("description_json", description_json); + hasUnsavedChanges.current = true; + debouncedFormSave(); + }} + placeholder={placeholder ?? ((isFocused, value) => t(getDescriptionPlaceholderI18n(isFocused, value)))} + searchMentionCallback={async (payload) => + await workspaceService.searchEntity(workspaceSlug?.toString() ?? "", { + ...payload, + project_id: projectId, + }) + } + containerClassName={containerClassName} + uploadFile={async (blockId, file) => { + try { + const { asset_id } = await uploadEditorAsset({ + blockId, + data: { + entity_identifier: entityId, + entity_type: fileAssetType, + }, + file, + projectId, + workspaceSlug, + }); + return asset_id; + } catch (error) { + console.log("Error in uploading asset:", error); + throw new Error("Asset upload failed. Please try again later."); + } + }} + duplicateFile={async (assetId: string) => { + try { + const { asset_id } = await duplicateEditorAsset({ + assetId, + entityType: fileAssetType, + projectId, + workspaceSlug, + }); + return asset_id; + } catch { + throw new Error("Asset duplication failed. Please try again later."); + } + }} /> - ) : ( - )} - + /> ); });