Fix remote object read-only + remove relations (#4921)

- Set `readOnly` boolean in table row context. Preventing updates and
deletion
- Show page is null for remote objects. No need for complicated design
since this is temporary?
- Relation creations are now behind a feature flag for remote objects
- Refetch objects and views after syncing objects

---------

Co-authored-by: Thomas Trompette <thomast@twenty.com>
This commit is contained in:
Thomas Trompette
2024-04-11 17:58:02 +02:00
committed by GitHub
parent fc56775c2a
commit f332213e0d
29 changed files with 275 additions and 158 deletions

View File

@ -106,7 +106,21 @@ export const useRecordActionBar = ({
recordIndexId: objectMetadataItem.namePlural,
});
const isRemoteObject = objectMetadataItem.isRemote;
const baseActions: ContextMenuEntry[] = useMemo(
() => [
{
label: `${progress === undefined ? `Export` : `Export (${progress}%)`}`,
Icon: IconFileExport,
accent: 'default',
onClick: () => download(),
},
],
[download, progress],
);
const deletionActions: ContextMenuEntry[] = useMemo(
() => [
{
label: 'Delete',
@ -130,17 +144,9 @@ export const useRecordActionBar = ({
/>
),
},
{
label: `${progress === undefined ? `Export` : `Export (${progress}%)`}`,
Icon: IconFileExport,
accent: 'default',
onClick: () => download(),
},
],
[
handleDeleteClick,
download,
progress,
selectedRecordIds,
isDeleteRecordsModalOpen,
setIsDeleteRecordsModalOpen,
@ -160,8 +166,9 @@ export const useRecordActionBar = ({
return {
setContextMenuEntries: useCallback(() => {
setContextMenuEntries([
...(isRemoteObject ? [] : deletionActions),
...baseActions,
...(isFavorite && hasOnlyOneRecordSelected
...(!isRemoteObject && isFavorite && hasOnlyOneRecordSelected
? [
{
label: 'Remove from favorites',
@ -170,7 +177,7 @@ export const useRecordActionBar = ({
},
]
: []),
...(!isFavorite && hasOnlyOneRecordSelected
...(!isRemoteObject && !isFavorite && hasOnlyOneRecordSelected
? [
{
label: 'Add to favorites',
@ -182,9 +189,11 @@ export const useRecordActionBar = ({
]);
}, [
baseActions,
deletionActions,
handleFavoriteButtonClick,
hasOnlyOneRecordSelected,
isFavorite,
isRemoteObject,
setContextMenuEntries,
]),
@ -209,12 +218,15 @@ export const useRecordActionBar = ({
},
]
: []),
...(isRemoteObject ? [] : deletionActions),
...baseActions,
]);
}, [
baseActions,
dataExecuteQuickActionOnmentEnabled,
deletionActions,
handleExecuteQuickActionOnClick,
isRemoteObject,
setActionBarEntriesState,
]),
};

View File

@ -47,6 +47,7 @@ type FieldInputProps = {
onEscape?: FieldInputEvent;
onTab?: FieldInputEvent;
onShiftTab?: FieldInputEvent;
isReadOnly?: boolean;
};
export const FieldInput = ({
@ -58,6 +59,7 @@ export const FieldInput = ({
onShiftTab,
onTab,
onClickOutside,
isReadOnly,
}: FieldInputProps) => {
const { fieldDefinition } = useContext(FieldContext);
@ -136,7 +138,7 @@ export const FieldInput = ({
onShiftTab={onShiftTab}
/>
) : isFieldBoolean(fieldDefinition) ? (
<BooleanFieldInput onSubmit={onSubmit} />
<BooleanFieldInput onSubmit={onSubmit} readonly={isReadOnly} />
) : isFieldRating(fieldDefinition) ? (
<RatingFieldInput onSubmit={onSubmit} />
) : isFieldSelect(fieldDefinition) ? (

View File

@ -92,6 +92,7 @@ export const RecordInlineCell = ({ readonly }: RecordInlineCellProps) => {
onTab={handleTab}
onShiftTab={handleShiftTab}
onClickOutside={handleClickOutside}
isReadOnly={readonly}
/>
}
displayModeContent={<FieldDisplay />}

View File

@ -47,6 +47,7 @@ export const RecordTableRow = ({ recordId, rowIndex }: RecordTableRowProps) => {
objectNameSingular: objectMetadataItem.nameSingular,
}) + recordId,
isSelected: currentRowSelected,
isReadOnly: objectMetadataItem.isRemote ?? false,
}}
>
<tr

View File

@ -5,6 +5,7 @@ type RecordTableRowContextProps = {
recordId: string;
rowIndex: number;
isSelected: boolean;
isReadOnly: boolean;
};
export const RecordTableRowContext = createContext<RecordTableRowContextProps>(

View File

@ -4,6 +4,7 @@ import { FieldDisplay } from '@/object-record/record-field/components/FieldDispl
import { FieldInput } from '@/object-record/record-field/components/FieldInput';
import { FieldContext } from '@/object-record/record-field/contexts/FieldContext';
import { FieldInputEvent } from '@/object-record/record-field/types/FieldInputEvent';
import { RecordTableRowContext } from '@/object-record/record-table/contexts/RecordTableRowContext';
import { useRecordTableMoveFocus } from '@/object-record/record-table/hooks/useRecordTableMoveFocus';
import { RecordTableCellContainer } from '@/object-record/record-table/record-table-cell/components/RecordTableCellContainer';
import { useCloseRecordTableCell } from '@/object-record/record-table/record-table-cell/hooks/useCloseRecordTableCell';
@ -21,6 +22,7 @@ export const RecordTableCell = ({
const { moveLeft, moveRight, moveDown } = useRecordTableMoveFocus();
const { entityId, fieldDefinition } = useContext(FieldContext);
const { isReadOnly } = useContext(RecordTableRowContext);
const handleEnter: FieldInputEvent = (persistField) => {
upsertRecord(persistField);
@ -78,6 +80,7 @@ export const RecordTableCell = ({
onShiftTab={handleShiftTab}
onSubmit={handleSubmit}
onTab={handleTab}
isReadOnly={isReadOnly}
/>
}
nonEditModeContent={<FieldDisplay />}

View File

@ -90,7 +90,7 @@ export const RecordTableCellContainer = ({
openTableCell();
};
const { isSelected } = useContext(RecordTableRowContext);
const { isSelected, isReadOnly } = useContext(RecordTableRowContext);
const setContextMenuPosition = useSetRecoilState(contextMenuPositionState);
const setContextMenuOpenState = useSetRecoilState(contextMenuIsOpenState);
@ -146,7 +146,8 @@ export const RecordTableCellContainer = ({
hasSoftFocus &&
!isCurrentTableCellInEditMode &&
!editModeContentOnly &&
(!isFirstColumn || !isEmpty);
(!isFirstColumn || !isEmpty) &&
!isReadOnly;
return (
<StyledTd

View File

@ -23,7 +23,7 @@ export const DEFAULT_CELL_SCOPE: HotkeyScope = {
};
export const useOpenRecordTableCell = () => {
const { pathToShowPage } = useContext(RecordTableRowContext);
const { pathToShowPage, isReadOnly } = useContext(RecordTableRowContext);
const { setCurrentTableCellInEditMode } = useCurrentTableCellEditMode();
const setHotkeyScope = useSetHotkeyScope();
@ -46,6 +46,10 @@ export const useOpenRecordTableCell = () => {
const openTableCell = useRecoilCallback(
() => (options?: { initialValue?: string }) => {
if (isReadOnly) {
return;
}
if (isFirstColumnCell && !isEmpty) {
leaveTableFocus();
navigate(pathToShowPage);
@ -70,15 +74,16 @@ export const useOpenRecordTableCell = () => {
}
},
[
isReadOnly,
isFirstColumnCell,
isEmpty,
leaveTableFocus,
navigate,
pathToShowPage,
setDragSelectionStartEnabled,
setCurrentTableCellInEditMode,
initFieldInputDraftValue,
customCellHotkeyScope,
leaveTableFocus,
navigate,
pathToShowPage,
setHotkeyScope,
],
);