[WIKI-874] refactor: description input component (#8544)
* refactor: description input component * fix: add missing prop to rich text editor
This commit is contained in:
parent
c3a9f99789
commit
2e429e5198
4 changed files with 87 additions and 78 deletions
|
|
@ -28,6 +28,7 @@ const workspaceService = new WorkspaceService();
|
|||
type TFormData = {
|
||||
id: string;
|
||||
description_html: string;
|
||||
description_json?: object;
|
||||
isMigrationUpdate: boolean;
|
||||
};
|
||||
|
||||
|
|
@ -67,7 +68,13 @@ type Props = {
|
|||
/**
|
||||
* @description Submit handler, the actual function which will be called when the form is submitted
|
||||
*/
|
||||
onSubmit: (value: string, isMigrationUpdate?: boolean) => Promise<void>;
|
||||
onSubmit: (
|
||||
value: {
|
||||
description_html: string;
|
||||
description_json: object | undefined;
|
||||
},
|
||||
isMigrationUpdate?: boolean
|
||||
) => Promise<void>;
|
||||
/**
|
||||
* @description Placeholder, if not provided, the placeholder will be the default placeholder
|
||||
*/
|
||||
|
|
@ -107,13 +114,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<TFormData>({
|
||||
|
|
@ -144,7 +151,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
|
||||
);
|
||||
// Update lastSavedContent after successful save
|
||||
lastSavedContent.current = formData.description_html;
|
||||
},
|
||||
|
|
@ -209,80 +222,76 @@ export const DescriptionInput = observer(function DescriptionInput(props: Props)
|
|||
|
||||
if (!workspaceDetails) return null;
|
||||
|
||||
if (!localDescription.description_html) return <DescriptionInputLoader />;
|
||||
|
||||
return (
|
||||
<>
|
||||
{localDescription.description_html ? (
|
||||
<Controller
|
||||
name="description_html"
|
||||
control={control}
|
||||
render={({ field: { onChange } }) => (
|
||||
<RichTextEditor
|
||||
key={entityId}
|
||||
editable={!disabled}
|
||||
ref={editorRef}
|
||||
id={entityId}
|
||||
issueSequenceId={issueSequenceId}
|
||||
disabledExtensions={disabledExtensions}
|
||||
initialValue={localDescription.description_html ?? "<p></p>"}
|
||||
value={swrDescription ?? null}
|
||||
workspaceSlug={workspaceSlug}
|
||||
workspaceId={workspaceDetails.id}
|
||||
projectId={projectId}
|
||||
dragDropEnabled
|
||||
onChange={(_description, description_html, options) => {
|
||||
// Skip if content hasn't actually changed (handles editor normalization on init)
|
||||
if (description_html === lastSavedContent.current) return;
|
||||
setIsSubmitting("submitting");
|
||||
onChange(description_html);
|
||||
setValue("isMigrationUpdate", options?.isMigrationUpdate ?? false);
|
||||
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.");
|
||||
}
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
<Controller
|
||||
name="description_html"
|
||||
control={control}
|
||||
render={({ field: { onChange } }) => (
|
||||
<RichTextEditor
|
||||
key={entityId}
|
||||
editable={!disabled}
|
||||
ref={editorRef}
|
||||
id={entityId}
|
||||
issueSequenceId={issueSequenceId}
|
||||
disabledExtensions={disabledExtensions}
|
||||
initialValue={localDescription.description_html ?? "<p></p>"}
|
||||
value={swrDescription ?? null}
|
||||
workspaceSlug={workspaceSlug}
|
||||
workspaceId={workspaceDetails.id}
|
||||
projectId={projectId}
|
||||
dragDropEnabled
|
||||
onChange={(description_json, description_html, options) => {
|
||||
if (description_html === lastSavedContent.current) return;
|
||||
setIsSubmitting("submitting");
|
||||
onChange(description_html);
|
||||
setValue("isMigrationUpdate", !!options?.isMigrationUpdate);
|
||||
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.");
|
||||
}
|
||||
}}
|
||||
/>
|
||||
) : (
|
||||
<DescriptionInputLoader />
|
||||
)}
|
||||
</>
|
||||
/>
|
||||
);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -180,7 +180,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" } : {}),
|
||||
});
|
||||
}}
|
||||
|
|
|
|||
|
|
@ -144,7 +144,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" } : {}),
|
||||
});
|
||||
}}
|
||||
|
|
|
|||
|
|
@ -144,7 +144,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" } : {}),
|
||||
});
|
||||
}}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue