Skip to content

Commit

Permalink
fix: link editor of the form (#425)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
Sky-FE committed Mar 11, 2024
1 parent 19676aa commit 4d0a2a1
Show file tree
Hide file tree
Showing 5 changed files with 95 additions and 33 deletions.
Original file line number Diff line number Diff line change
@@ -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';
Expand All @@ -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 (
<ShareFormLinkEditor
shareId={shareId as string}
Expand All @@ -31,7 +33,8 @@ export const FormCellEditor = (props: IFormCellEditor) => {
/>
);
}
if (shareId && field.type === FieldType.Attachment) {

if (shareId && type === FieldType.Attachment) {
attachmentManager.shareId = shareId as string;
return (
<UploadAttachment
Expand All @@ -42,6 +45,20 @@ export const FormCellEditor = (props: IFormCellEditor) => {
/>
);
}

if (type === FieldType.Link) {
return (
<LinkEditor
className={className}
cellValue={cellValue as ILinkCellValue | ILinkCellValue[]}
options={options as ILinkFieldOptions}
onChange={onChange}
fieldId={id}
displayType={LinkDisplayType.List}
/>
);
}

return (
<CellEditor cellValue={cellValue} field={field} onChange={onChange} className={className} />
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@ export const FormPreviewer = (props: IFormPreviewerProps) => {
LocalStorageKeys.ViewFromData,
{}
);
const [formData, { set: setFormData, reset: resetFormData }] = useMap<Record<string, unknown>>(
formDataMap?.[localKey] ?? {}
);
const [formData, { set: setFormData, reset: resetFormData, remove: removeFormData }] = useMap<
Record<string, unknown>
>(formDataMap?.[localKey] ?? {});
const [errors, { add: addError, remove: removeError, reset: resetErrors }] = useSet<string>(
new Set([])
);
Expand All @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,8 @@ export const GridViewBase: React.FC<IGridViewProps> = (props: IGridViewProps) =>
getPrefillingCellContent,
} = useGridPrefillingRow(columns);

const inPrefilling = prefillingRowIndex != null;

useEffect(() => {
if (preTableId && preTableId !== tableId) {
onReset();
Expand Down Expand Up @@ -587,11 +589,11 @@ export const GridViewBase: React.FC<IGridViewProps> = (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();
Expand All @@ -606,6 +608,7 @@ export const GridViewBase: React.FC<IGridViewProps> = (props: IGridViewProps) =>
<Grid
ref={gridRef}
theme={theme}
style={{ pointerEvents: inPrefilling ? 'none' : 'auto' }}
draggable={draggable}
isTouchDevice={isTouchDevice}
rowCount={realRowCount}
Expand Down Expand Up @@ -643,7 +646,7 @@ export const GridViewBase: React.FC<IGridViewProps> = (props: IGridViewProps) =>
onItemClick={onItemClick}
onItemHovered={onItemHovered}
/>
{prefillingRowIndex != null && (
{inPrefilling && (
<PrefillingRowContainer
style={prefillingRowStyle}
onClickOutside={() => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export interface IUploadAttachment {
className?: string;
attachments: IAttachmentCellValue;
attachmentManager?: AttachmentManager;
onChange?: (attachment: IAttachmentCellValue) => void;
onChange?: (attachment: IAttachmentCellValue | null) => void;
readonly?: boolean;
}

Expand Down Expand Up @@ -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) => {
Expand Down
76 changes: 55 additions & 21 deletions packages/sdk/src/components/editor/link/Editor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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<ILinkListRef>(null);
const linkEditorMainRef = useRef<ILinkEditorMainRef>(null);
Expand Down Expand Up @@ -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);
}, []);
Expand All @@ -84,22 +106,34 @@ export const LinkEditor = (props: ILinkEditorProps) => {

return (
<div className="space-y-3">
{Boolean(selectedRowCount) && (
<div className="relative h-40 w-full overflow-hidden rounded-md border">
<AnchorProvider tableId={foreignTableId}>
<LinkList
ref={listRef}
type={LinkListType.Selected}
rowCount={selectedRowCount}
cellValue={cellValue}
isMultiple={isMultiple}
recordQuery={recordQuery}
onChange={onRecordListChange}
onExpand={onRecordExpand}
{Boolean(selectedRowCount) &&
(displayType === LinkDisplayType.Grid ? (
<div className="relative h-40 w-full overflow-hidden rounded-md border">
<AnchorProvider tableId={foreignTableId}>
<LinkList
ref={listRef}
type={LinkListType.Selected}
rowCount={selectedRowCount}
readonly={readonly}
cellValue={cellValue}
isMultiple={isMultiple}
recordQuery={recordQuery}
onChange={onRecordListChange}
onExpand={onRecordExpand}
/>
</AnchorProvider>
</div>
) : (
cvArray?.map(({ id, title }) => (
<LinkCard
key={id}
title={title}
readonly={readonly}
onClick={() => onRecordExpand(id)}
onDelete={() => onRecordDelete(id)}
/>
</AnchorProvider>
</div>
)}
))
))}
{!readonly && (
<>
<div className="flex justify-between">
Expand All @@ -120,7 +154,7 @@ export const LinkEditor = (props: ILinkEditorProps) => {
/>
</DialogContent>
</Dialog>
{Boolean(selectedRowCount) && (
{Boolean(selectedRowCount) && displayType === LinkDisplayType.Grid && (
<Button size={'sm'} onClick={onConfirm}>
{t('common.confirm')}
</Button>
Expand Down

0 comments on commit 4d0a2a1

Please sign in to comment.