From 4d0a2a163adefca0dd632baa45c90313da70c3c9 Mon Sep 17 00:00:00 2001 From: SkyHuang <906268297@qq.com> Date: Mon, 11 Mar 2024 17:47:09 +0800 Subject: [PATCH] fix: link editor of the form (#425) * fix: link editor for the form view * perf: remove redundant data when submitting the form * perf: optimize the operation when pre-filling the grid to prevent accidental touches * fix: supplement the readonly to the link field editor --- .../view/form/components/FormCellEditor.tsx | 25 +++++- .../view/form/components/FormPreviewer.tsx | 13 +++- .../app/blocks/view/grid/GridViewBase.tsx | 9 ++- .../upload-attachment/UploadAttachment.tsx | 5 +- .../sdk/src/components/editor/link/Editor.tsx | 76 ++++++++++++++----- 5 files changed, 95 insertions(+), 33 deletions(-) diff --git a/apps/nextjs-app/src/features/app/blocks/view/form/components/FormCellEditor.tsx b/apps/nextjs-app/src/features/app/blocks/view/form/components/FormCellEditor.tsx index e75e277ab..d2e49b5d6 100644 --- a/apps/nextjs-app/src/features/app/blocks/view/form/components/FormCellEditor.tsx +++ b/apps/nextjs-app/src/features/app/blocks/view/form/components/FormCellEditor.tsx @@ -1,6 +1,6 @@ -import type { IAttachmentCellValue, ILinkCellValue } from '@teable/core'; +import type { IAttachmentCellValue, ILinkCellValue, ILinkFieldOptions } from '@teable/core'; import { FieldType } from '@teable/core'; -import { AttachmentManager, CellEditor } from '@teable/sdk/components'; +import { AttachmentManager, CellEditor, LinkDisplayType, LinkEditor } from '@teable/sdk/components'; import { UploadAttachment } from '@teable/sdk/components/editor/attachment/upload-attachment/UploadAttachment'; import type { Field, LinkField } from '@teable/sdk/model'; import { cn } from '@teable/ui-lib/shadcn'; @@ -20,7 +20,9 @@ export const FormCellEditor = (props: IFormCellEditor) => { const { cellValue, field, className, onChange } = props; const router = useRouter(); const shareId = router.query.shareId; - if (shareId && field.type === FieldType.Link) { + const { id, type, options } = field; + + if (shareId && type === FieldType.Link) { return ( { /> ); } - if (shareId && field.type === FieldType.Attachment) { + + if (shareId && type === FieldType.Attachment) { attachmentManager.shareId = shareId as string; return ( { /> ); } + + if (type === FieldType.Link) { + return ( + + ); + } + return ( ); diff --git a/apps/nextjs-app/src/features/app/blocks/view/form/components/FormPreviewer.tsx b/apps/nextjs-app/src/features/app/blocks/view/form/components/FormPreviewer.tsx index fd02cdc25..42ca69f6f 100644 --- a/apps/nextjs-app/src/features/app/blocks/view/form/components/FormPreviewer.tsx +++ b/apps/nextjs-app/src/features/app/blocks/view/form/components/FormPreviewer.tsx @@ -28,9 +28,9 @@ export const FormPreviewer = (props: IFormPreviewerProps) => { LocalStorageKeys.ViewFromData, {} ); - const [formData, { set: setFormData, reset: resetFormData }] = useMap>( - formDataMap?.[localKey] ?? {} - ); + const [formData, { set: setFormData, reset: resetFormData, remove: removeFormData }] = useMap< + Record + >(formDataMap?.[localKey] ?? {}); const [errors, { add: addError, remove: removeError, reset: resetErrors }] = useSet( new Set([]) ); @@ -51,6 +51,13 @@ export const FormPreviewer = (props: IFormPreviewerProps) => { removeError(fieldId); } + if (value == null) { + removeFormData(fieldId); + return setTimeout(() => + setFormDataMap({ ...formDataMap, [localKey]: omit(formData, fieldId) }) + ); + } + setFormData(fieldId, value); // Store to local storage diff --git a/apps/nextjs-app/src/features/app/blocks/view/grid/GridViewBase.tsx b/apps/nextjs-app/src/features/app/blocks/view/grid/GridViewBase.tsx index 2e5175366..fda843730 100644 --- a/apps/nextjs-app/src/features/app/blocks/view/grid/GridViewBase.tsx +++ b/apps/nextjs-app/src/features/app/blocks/view/grid/GridViewBase.tsx @@ -134,6 +134,8 @@ export const GridViewBase: React.FC = (props: IGridViewProps) => getPrefillingCellContent, } = useGridPrefillingRow(columns); + const inPrefilling = prefillingRowIndex != null; + useEffect(() => { if (preTableId && preTableId !== tableId) { onReset(); @@ -587,11 +589,11 @@ export const GridViewBase: React.FC = (props: IGridViewProps) => }, [rowHeight, prefillingRowIndex]); useEffect(() => { - if (prefillingRowIndex == null) return; + if (!inPrefilling) return; const scrollState = gridRef.current?.getScrollState(); if (scrollState == null) return; prefillingGridRef.current?.scrollTo(scrollState.scrollLeft, undefined); - }, [prefillingRowIndex]); + }, [inPrefilling]); useClickAway(containerRef, () => { gridRef.current?.resetState(); @@ -606,6 +608,7 @@ export const GridViewBase: React.FC = (props: IGridViewProps) => = (props: IGridViewProps) => onItemClick={onItemClick} onItemHovered={onItemHovered} /> - {prefillingRowIndex != null && ( + {inPrefilling && ( { diff --git a/packages/sdk/src/components/editor/attachment/upload-attachment/UploadAttachment.tsx b/packages/sdk/src/components/editor/attachment/upload-attachment/UploadAttachment.tsx index 36e7221ec..86f9f7993 100644 --- a/packages/sdk/src/components/editor/attachment/upload-attachment/UploadAttachment.tsx +++ b/packages/sdk/src/components/editor/attachment/upload-attachment/UploadAttachment.tsx @@ -15,7 +15,7 @@ export interface IUploadAttachment { className?: string; attachments: IAttachmentCellValue; attachmentManager?: AttachmentManager; - onChange?: (attachment: IAttachmentCellValue) => void; + onChange?: (attachment: IAttachmentCellValue | null) => void; readonly?: boolean; } @@ -47,7 +47,8 @@ export const UploadAttachment = (props: IUploadAttachment) => { }, [newAttachments, onChange, uploadingFiles]); const onDelete = (id: string) => { - onChange?.(attachments.filter((attachment) => attachment.id !== id)); + const finalAttachments = attachments.filter((attachment) => attachment.id !== id); + onChange?.(!finalAttachments.length ? null : finalAttachments); }; const downloadFile = ({ presignedUrl, name }: IAttachmentItem) => { diff --git a/packages/sdk/src/components/editor/link/Editor.tsx b/packages/sdk/src/components/editor/link/Editor.tsx index f68564ae6..a28904361 100644 --- a/packages/sdk/src/components/editor/link/Editor.tsx +++ b/packages/sdk/src/components/editor/link/Editor.tsx @@ -9,21 +9,37 @@ import { ExpandRecorder } from '../../expand-record'; import type { ILinkEditorMainRef } from './EditorMain'; import { LinkEditorMain } from './EditorMain'; import { LinkListType } from './interface'; +import { LinkCard } from './LinkCard'; import type { ILinkListRef } from './LinkList'; import { LinkList } from './LinkList'; interface ILinkEditorProps { - fieldId: string; - recordId: string | undefined; options: ILinkFieldOptions; - cellValue?: ILinkCellValue | ILinkCellValue[]; - onChange?: (value?: ILinkCellValue | ILinkCellValue[]) => void; + fieldId: string; + recordId?: string; readonly?: boolean; className?: string; + cellValue?: ILinkCellValue | ILinkCellValue[]; + displayType?: LinkDisplayType; + onChange?: (value?: ILinkCellValue | ILinkCellValue[]) => void; +} + +export enum LinkDisplayType { + Grid = 'grid', + List = 'list', } export const LinkEditor = (props: ILinkEditorProps) => { - const { fieldId, recordId, cellValue, options, onChange, readonly, className } = props; + const { + fieldId, + recordId, + cellValue, + options, + onChange, + readonly, + className, + displayType = LinkDisplayType.Grid, + } = props; const { toast } = useToast(); const listRef = useRef(null); const linkEditorMainRef = useRef(null); @@ -64,6 +80,12 @@ export const LinkEditor = (props: ILinkEditorProps) => { updateExpandRecordId(recordId); }; + const onRecordDelete = (recordId: string) => { + onChange?.( + isMultiple ? (cellValue as ILinkCellValue[])?.filter((cv) => cv.id !== recordId) : undefined + ); + }; + const onRecordListChange = useCallback((value?: ILinkCellValue[]) => { setValues(value); }, []); @@ -84,22 +106,34 @@ export const LinkEditor = (props: ILinkEditorProps) => { return (
- {Boolean(selectedRowCount) && ( -
- - + + + +
+ ) : ( + cvArray?.map(({ id, title }) => ( + onRecordExpand(id)} + onDelete={() => onRecordDelete(id)} /> - -
- )} + )) + ))} {!readonly && ( <>
@@ -120,7 +154,7 @@ export const LinkEditor = (props: ILinkEditorProps) => { /> - {Boolean(selectedRowCount) && ( + {Boolean(selectedRowCount) && displayType === LinkDisplayType.Grid && (