feat: set field as custom object label identifier in Object Detail (#3360)

* feat: set field as custom object label identifier in Object Detail

Closes #3302

* feat: prevent disabling Object label identitifer field in back-end

* refactor: review - extract isLabelIdentifier variable
This commit is contained in:
Thaïs
2024-01-17 08:19:41 -03:00
committed by GitHub
parent 8864528d55
commit 96d990e275
12 changed files with 166 additions and 79 deletions

View File

@ -26,6 +26,7 @@ import { Table } from '@/ui/layout/table/components/Table';
import { TableHeader } from '@/ui/layout/table/components/TableHeader';
import { TableSection } from '@/ui/layout/table/components/TableSection';
import { Breadcrumb } from '@/ui/navigation/bread-crumb/components/Breadcrumb';
import { FieldMetadataType } from '~/generated-metadata/graphql';
const StyledDiv = styled.div`
display: flex;
@ -37,8 +38,11 @@ export const SettingsObjectDetail = () => {
const navigate = useNavigate();
const { objectSlug = '' } = useParams();
const { disableObjectMetadataItem, findActiveObjectMetadataItemBySlug } =
useObjectMetadataItemForSettings();
const {
disableObjectMetadataItem,
editObjectMetadataItem,
findActiveObjectMetadataItemBySlug,
} = useObjectMetadataItemForSettings();
const activeObjectMetadataItem =
findActiveObjectMetadataItemBySlug(objectSlug);
@ -64,10 +68,17 @@ export const SettingsObjectDetail = () => {
navigate('/settings/objects');
};
const handleDisableField = async (
const handleDisableField = (activeFieldMetadatItem: FieldMetadataItem) => {
disableMetadataField(activeFieldMetadatItem);
};
const handleSetLabelIdentifierField = (
activeFieldMetadatItem: FieldMetadataItem,
) => {
disableMetadataField(activeFieldMetadatItem);
editObjectMetadataItem({
...activeObjectMetadataItem,
labelIdentifierFieldMetadataId: activeFieldMetadatItem.id,
});
};
return (
@ -104,38 +115,56 @@ export const SettingsObjectDetail = () => {
</StyledObjectFieldTableRow>
{!!activeMetadataFields.length && (
<TableSection title="Active">
{activeMetadataFields.map((activeMetadataField) => (
<SettingsObjectFieldItemTableRow
key={activeMetadataField.id}
identifierType={getFieldIdentifierType(
activeMetadataField,
activeObjectMetadataItem,
)}
variant={
activeObjectMetadataItem.isCustom
? 'identifier'
: 'field-type'
}
fieldMetadataItem={activeMetadataField}
ActionIcon={
<SettingsObjectFieldActiveActionDropdown
isCustomField={!!activeMetadataField.isCustom}
scopeKey={activeMetadataField.id}
onEdit={() =>
navigate(`./${getFieldSlug(activeMetadataField)}`)
}
onDisable={
isLabelIdentifierField({
fieldMetadataItem: activeMetadataField,
objectMetadataItem: activeObjectMetadataItem,
})
? undefined
: () => handleDisableField(activeMetadataField)
}
/>
}
/>
))}
{activeMetadataFields.map((activeMetadataField) => {
const isLabelIdentifier = isLabelIdentifierField({
fieldMetadataItem: activeMetadataField,
objectMetadataItem: activeObjectMetadataItem,
});
const canBeSetAsLabelIdentifier =
activeObjectMetadataItem.isCustom &&
!isLabelIdentifier &&
[FieldMetadataType.Text, FieldMetadataType.Number].includes(
activeMetadataField.type,
);
return (
<SettingsObjectFieldItemTableRow
key={activeMetadataField.id}
identifierType={getFieldIdentifierType(
activeMetadataField,
activeObjectMetadataItem,
)}
variant={
activeObjectMetadataItem.isCustom
? 'identifier'
: 'field-type'
}
fieldMetadataItem={activeMetadataField}
ActionIcon={
<SettingsObjectFieldActiveActionDropdown
isCustomField={!!activeMetadataField.isCustom}
scopeKey={activeMetadataField.id}
onEdit={() =>
navigate(`./${getFieldSlug(activeMetadataField)}`)
}
onSetAsLabelIdentifier={
canBeSetAsLabelIdentifier
? () =>
handleSetLabelIdentifierField(
activeMetadataField,
)
: undefined
}
onDisable={
isLabelIdentifier
? undefined
: () => handleDisableField(activeMetadataField)
}
/>
}
/>
);
})}
</TableSection>
)}
{!!disabledMetadataFields.length && (

View File

@ -5,6 +5,7 @@ import { useFieldMetadataItem } from '@/object-metadata/hooks/useFieldMetadataIt
import { useObjectMetadataItemForSettings } from '@/object-metadata/hooks/useObjectMetadataItemForSettings';
import { useRelationMetadata } from '@/object-metadata/hooks/useRelationMetadata';
import { getFieldSlug } from '@/object-metadata/utils/getFieldSlug';
import { isLabelIdentifierField } from '@/object-metadata/utils/isLabelIdentifierField';
import { SaveAndCancelButtons } from '@/settings/components/SaveAndCancelButtons/SaveAndCancelButtons';
import { SettingsHeaderContainer } from '@/settings/components/SettingsHeaderContainer';
import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer';
@ -114,6 +115,11 @@ export const SettingsObjectFieldEdit = () => {
const canSave = isValid && hasFormChanged;
const isLabelIdentifier = isLabelIdentifierField({
fieldMetadataItem: activeMetadataField,
objectMetadataItem: activeObjectMetadataItem,
});
const handleSave = async () => {
if (!validatedFormValues) return;
@ -203,15 +209,17 @@ export const SettingsObjectFieldEdit = () => {
select: formValues.select,
}}
/>
<Section>
<H2Title title="Danger zone" description="Disable this field" />
<Button
Icon={IconArchive}
title="Disable"
size="small"
onClick={handleDisable}
/>
</Section>
{!isLabelIdentifier && (
<Section>
<H2Title title="Danger zone" description="Disable this field" />
<Button
Icon={IconArchive}
title="Disable"
size="small"
onClick={handleDisable}
/>
</Section>
)}
</SettingsPageContainer>
</SubMenuTopBarContainer>
);

View File

@ -4,6 +4,7 @@ import styled from '@emotion/styled';
import { useFieldMetadataItem } from '@/object-metadata/hooks/useFieldMetadataItem';
import { useObjectMetadataItemForSettings } from '@/object-metadata/hooks/useObjectMetadataItemForSettings';
import { isLabelIdentifierField } from '@/object-metadata/utils/isLabelIdentifierField';
import { SaveAndCancelButtons } from '@/settings/components/SaveAndCancelButtons/SaveAndCancelButtons';
import { SettingsHeaderContainer } from '@/settings/components/SettingsHeaderContainer';
import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer';
@ -133,16 +134,23 @@ export const SettingsObjectNewFieldStep1 = () => {
</StyledObjectFieldTableRow>
{!!activeMetadataFields.length && (
<TableSection isInitiallyExpanded={false} title="Active">
{activeMetadataFields.map((field) => (
{activeMetadataFields.map((activeMetadataField) => (
<SettingsObjectFieldItemTableRow
key={field.id}
fieldMetadataItem={field}
key={activeMetadataField.id}
fieldMetadataItem={activeMetadataField}
ActionIcon={
<LightIconButton
Icon={IconMinus}
accent="tertiary"
onClick={() => handleToggleField(field.id)}
/>
isLabelIdentifierField({
fieldMetadataItem: activeMetadataField,
objectMetadataItem: activeObjectMetadataItem,
}) ? undefined : (
<LightIconButton
Icon={IconMinus}
accent="tertiary"
onClick={() =>
handleToggleField(activeMetadataField.id)
}
/>
)
}
/>
))}
@ -150,15 +158,17 @@ export const SettingsObjectNewFieldStep1 = () => {
)}
{!!disabledMetadataFields.length && (
<TableSection title="Disabled">
{disabledMetadataFields.map((field) => (
{disabledMetadataFields.map((disabledMetadataField) => (
<SettingsObjectFieldItemTableRow
key={field.name}
fieldMetadataItem={field}
key={disabledMetadataField.name}
fieldMetadataItem={disabledMetadataField}
ActionIcon={
<LightIconButton
Icon={IconPlus}
accent="tertiary"
onClick={() => handleToggleField(field.id)}
onClick={() =>
handleToggleField(disabledMetadataField.id)
}
/>
}
/>