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

@ -22,6 +22,7 @@ type SettingsObjectFieldItemTableRowProps = {
fieldMetadataItem: FieldMetadataItem;
identifierType?: Nullable<FieldIdentifierType>;
variant?: 'field-type' | 'identifier';
isRemoteObjectField?: boolean;
};
export const StyledObjectFieldTableRow = styled(TableRow)`
@ -43,6 +44,7 @@ export const SettingsObjectFieldItemTableRow = ({
fieldMetadataItem,
identifierType,
variant = 'field-type',
isRemoteObjectField,
}: SettingsObjectFieldItemTableRowProps) => {
const theme = useTheme();
const { getIcon } = useIcons();
@ -76,7 +78,11 @@ export const SettingsObjectFieldItemTableRow = ({
</StyledNameTableCell>
<TableCell>
{variant === 'field-type' &&
(fieldMetadataItem.isCustom ? 'Custom' : 'Standard')}
(isRemoteObjectField
? 'Remote'
: fieldMetadataItem.isCustom
? 'Custom'
: 'Standard')}
{variant === 'identifier' &&
!!identifierType &&
(identifierType === 'label' ? 'Record text' : 'Record image')}

View File

@ -4,7 +4,8 @@ import styled from '@emotion/styled';
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
import { useFindManyRecords } from '@/object-record/hooks/useFindManyRecords';
import { SettingsDataModelIsCustomTag } from '@/settings/data-model/objects/SettingsDataModelIsCustomTag';
import { SettingsDataModelObjectTypeTag } from '@/settings/data-model/objects/SettingsDataModelObjectTypeTag';
import { getObjectTypeLabel } from '@/settings/data-model/utils/getObjectTypeLabel';
import { useIcons } from '@/ui/display/icon/hooks/useIcons';
import { TableCell } from '@/ui/layout/table/components/TableCell';
import { TableRow } from '@/ui/layout/table/components/TableRow';
@ -42,6 +43,7 @@ export const SettingsObjectItemTableRow = ({
});
const { getIcon } = useIcons();
const Icon = getIcon(objectItem.icon);
const objectTypeLabel = getObjectTypeLabel(objectItem);
return (
<StyledObjectTableRow key={objectItem.namePlural} onClick={onClick}>
@ -52,7 +54,7 @@ export const SettingsObjectItemTableRow = ({
{objectItem.labelPlural}
</StyledNameTableCell>
<TableCell>
<SettingsDataModelIsCustomTag isCustom={objectItem.isCustom} />
<SettingsDataModelObjectTypeTag objectTypeLabel={objectTypeLabel} />
</TableCell>
<TableCell align="right">
{objectItem.fields.filter((field) => !field.isSystem).length}

View File

@ -2,8 +2,10 @@ import { useTheme } from '@emotion/react';
import styled from '@emotion/styled';
import { IconArchive, IconDotsVertical, IconPencil } from 'twenty-ui';
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
import { SettingsSummaryCard } from '@/settings/components/SettingsSummaryCard';
import { SettingsDataModelIsCustomTag } from '@/settings/data-model/objects/SettingsDataModelIsCustomTag';
import { SettingsDataModelObjectTypeTag } from '@/settings/data-model/objects/SettingsDataModelObjectTypeTag';
import { getObjectTypeLabel } from '@/settings/data-model/utils/getObjectTypeLabel';
import { useIcons } from '@/ui/display/icon/hooks/useIcons';
import { LightIconButton } from '@/ui/input/button/components/LightIconButton';
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
@ -13,14 +15,14 @@ import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
import { MenuItem } from '@/ui/navigation/menu-item/components/MenuItem';
type SettingsObjectSummaryCardProps = {
objectMetadataItem: ObjectMetadataItem;
iconKey?: string;
isCustom: boolean;
name: string;
onDeactivate: () => void;
onEdit: () => void;
};
const StyledIsCustomTag = styled(SettingsDataModelIsCustomTag)`
const StyledObjectTypeTag = styled(SettingsDataModelObjectTypeTag)`
box-sizing: border-box;
height: ${({ theme }) => theme.spacing(6)};
`;
@ -28,8 +30,8 @@ const StyledIsCustomTag = styled(SettingsDataModelIsCustomTag)`
const dropdownId = 'settings-object-edit-about-menu-dropdown';
export const SettingsObjectSummaryCard = ({
objectMetadataItem,
iconKey = '',
isCustom,
name,
onDeactivate,
onEdit,
@ -50,6 +52,8 @@ export const SettingsObjectSummaryCard = ({
closeDropdown();
};
const objectTypeLabel = getObjectTypeLabel(objectMetadataItem);
return (
<SettingsSummaryCard
title={
@ -60,7 +64,7 @@ export const SettingsObjectSummaryCard = ({
}
rightComponent={
<>
<StyledIsCustomTag isCustom={isCustom} />
<StyledObjectTypeTag objectTypeLabel={objectTypeLabel} />
<Dropdown
dropdownId={dropdownId}
clickableComponent={

View File

@ -1,18 +0,0 @@
import { Tag } from '@/ui/display/tag/components/Tag';
type SettingsDataModelIsCustomTagProps = {
className?: string;
isCustom?: boolean;
};
export const SettingsDataModelIsCustomTag = ({
className,
isCustom,
}: SettingsDataModelIsCustomTagProps) => (
<Tag
className={className}
color={isCustom ? 'orange' : 'blue'}
text={isCustom ? 'Custom' : 'Standard'}
weight="medium"
/>
);

View File

@ -2,15 +2,13 @@ import { useTheme } from '@emotion/react';
import styled from '@emotion/styled';
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
import { SettingsDataModelIsCustomTag } from '@/settings/data-model/objects/SettingsDataModelIsCustomTag';
import { SettingsDataModelObjectTypeTag } from '@/settings/data-model/objects/SettingsDataModelObjectTypeTag';
import { getObjectTypeLabel } from '@/settings/data-model/utils/getObjectTypeLabel';
import { useIcons } from '@/ui/display/icon/hooks/useIcons';
export type SettingsDataModelObjectSummaryProps = {
className?: string;
objectMetadataItem: Pick<
ObjectMetadataItem,
'icon' | 'isCustom' | 'labelPlural'
>;
objectMetadataItem: ObjectMetadataItem;
};
const StyledObjectSummary = styled.div`
@ -35,6 +33,7 @@ export const SettingsDataModelObjectSummary = ({
const { getIcon } = useIcons();
const ObjectIcon = getIcon(objectMetadataItem.icon);
const objectTypeLabel = getObjectTypeLabel(objectMetadataItem);
return (
<StyledObjectSummary className={className}>
@ -42,7 +41,7 @@ export const SettingsDataModelObjectSummary = ({
<ObjectIcon size={theme.icon.size.sm} stroke={theme.icon.stroke.md} />
{objectMetadataItem.labelPlural}
</StyledObjectName>
<SettingsDataModelIsCustomTag isCustom={objectMetadataItem.isCustom} />
<SettingsDataModelObjectTypeTag objectTypeLabel={objectTypeLabel} />
</StyledObjectSummary>
);
};

View File

@ -0,0 +1,21 @@
import { ObjectTypeLabel } from '@/settings/data-model/utils/getObjectTypeLabel';
import { Tag } from '@/ui/display/tag/components/Tag';
type SettingsDataModelObjectTypeTagProps = {
objectTypeLabel: ObjectTypeLabel;
className?: string;
};
export const SettingsDataModelObjectTypeTag = ({
className,
objectTypeLabel,
}: SettingsDataModelObjectTypeTagProps) => {
return (
<Tag
className={className}
color={objectTypeLabel.labelColor}
text={objectTypeLabel.labelText}
weight="medium"
/>
);
};

View File

@ -0,0 +1,39 @@
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
export type ObjectTypeLabel =
| StandardObjectTypeLabel
| CustomObjectTypeLabel
| RemoteObjectTypeLabel;
type StandardObjectTypeLabel = {
labelText: 'Standard';
labelColor: 'blue';
};
type CustomObjectTypeLabel = {
labelText: 'Custom';
labelColor: 'orange';
};
type RemoteObjectTypeLabel = {
labelText: 'Remote';
labelColor: 'green';
};
export const getObjectTypeLabel = (
objectMetadataItem: ObjectMetadataItem,
): ObjectTypeLabel =>
objectMetadataItem.isCustom
? {
labelText: 'Custom',
labelColor: 'orange',
}
: objectMetadataItem.isRemote
? {
labelText: 'Remote',
labelColor: 'green',
}
: {
labelText: 'Standard',
labelColor: 'blue',
};