mirror of
https://github.com/twentyhq/twenty.git
synced 2024-12-24 20:42:05 +03:00
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:
parent
8864528d55
commit
96d990e275
@ -8,6 +8,7 @@ import { useMapToObjectRecordIdentifier } from '@/object-metadata/hooks/useMapTo
|
|||||||
import { objectMetadataItemFamilySelector } from '@/object-metadata/states/objectMetadataItemFamilySelector';
|
import { objectMetadataItemFamilySelector } from '@/object-metadata/states/objectMetadataItemFamilySelector';
|
||||||
import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState';
|
import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState';
|
||||||
import { getBasePathToShowPage } from '@/object-metadata/utils/getBasePathToShowPage';
|
import { getBasePathToShowPage } from '@/object-metadata/utils/getBasePathToShowPage';
|
||||||
|
import { getLabelIdentifierFieldMetadataItem } from '@/object-metadata/utils/getLabelIdentifierFieldMetadataItem';
|
||||||
import { getObjectMetadataItemsMock } from '@/object-metadata/utils/getObjectMetadataItemsMock';
|
import { getObjectMetadataItemsMock } from '@/object-metadata/utils/getObjectMetadataItemsMock';
|
||||||
import { useGenerateCreateManyRecordMutation } from '@/object-record/hooks/useGenerateCreateManyRecordMutation';
|
import { useGenerateCreateManyRecordMutation } from '@/object-record/hooks/useGenerateCreateManyRecordMutation';
|
||||||
import { useGenerateCreateOneRecordMutation } from '@/object-record/hooks/useGenerateCreateOneRecordMutation';
|
import { useGenerateCreateOneRecordMutation } from '@/object-record/hooks/useGenerateCreateOneRecordMutation';
|
||||||
@ -120,9 +121,8 @@ export const useObjectMetadataItem = (
|
|||||||
objectMetadataItem,
|
objectMetadataItem,
|
||||||
});
|
});
|
||||||
|
|
||||||
const labelIdentifierFieldMetadata = objectMetadataItem.fields.find(
|
const labelIdentifierFieldMetadata =
|
||||||
({ name }) => name === 'name',
|
getLabelIdentifierFieldMetadataItem(objectMetadataItem);
|
||||||
);
|
|
||||||
|
|
||||||
const basePathToShowPage = getBasePathToShowPage({
|
const basePathToShowPage = getBasePathToShowPage({
|
||||||
objectMetadataItem,
|
objectMetadataItem,
|
||||||
|
@ -51,7 +51,12 @@ export const useObjectMetadataItemForSettings = () => {
|
|||||||
const editObjectMetadataItem = (
|
const editObjectMetadataItem = (
|
||||||
input: Pick<
|
input: Pick<
|
||||||
ObjectMetadataItem,
|
ObjectMetadataItem,
|
||||||
'id' | 'labelPlural' | 'labelSingular' | 'icon' | 'description'
|
| 'description'
|
||||||
|
| 'icon'
|
||||||
|
| 'id'
|
||||||
|
| 'labelIdentifierFieldMetadataId'
|
||||||
|
| 'labelPlural'
|
||||||
|
| 'labelSingular'
|
||||||
>,
|
>,
|
||||||
) =>
|
) =>
|
||||||
updateOneObjectMetadataItem({
|
updateOneObjectMetadataItem({
|
||||||
|
@ -5,11 +5,17 @@ import { ObjectMetadataItem } from '../types/ObjectMetadataItem';
|
|||||||
export const formatObjectMetadataItemInput = (
|
export const formatObjectMetadataItemInput = (
|
||||||
input: Pick<
|
input: Pick<
|
||||||
ObjectMetadataItem,
|
ObjectMetadataItem,
|
||||||
'labelPlural' | 'labelSingular' | 'icon' | 'description'
|
| 'description'
|
||||||
|
| 'icon'
|
||||||
|
| 'labelIdentifierFieldMetadataId'
|
||||||
|
| 'labelPlural'
|
||||||
|
| 'labelSingular'
|
||||||
>,
|
>,
|
||||||
) => ({
|
) => ({
|
||||||
description: input.description?.trim() ?? null,
|
description: input.description?.trim() ?? null,
|
||||||
icon: input.icon,
|
icon: input.icon,
|
||||||
|
labelIdentifierFieldMetadataId:
|
||||||
|
input.labelIdentifierFieldMetadataId?.trim() ?? null,
|
||||||
labelPlural: input.labelPlural.trim(),
|
labelPlural: input.labelPlural.trim(),
|
||||||
labelSingular: input.labelSingular.trim(),
|
labelSingular: input.labelSingular.trim(),
|
||||||
namePlural: toCamelCase(input.labelPlural.trim()),
|
namePlural: toCamelCase(input.labelPlural.trim()),
|
||||||
|
@ -1,12 +1,13 @@
|
|||||||
import { FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem';
|
import { FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem';
|
||||||
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
||||||
|
import { isLabelIdentifierField } from '@/object-metadata/utils/isLabelIdentifierField';
|
||||||
|
|
||||||
export const getLabelIdentifierFieldMetadataItem = (
|
export const getLabelIdentifierFieldMetadataItem = (
|
||||||
objectMetadataItem: ObjectMetadataItem,
|
objectMetadataItem: ObjectMetadataItem,
|
||||||
): FieldMetadataItem | undefined => {
|
): FieldMetadataItem | undefined =>
|
||||||
return objectMetadataItem.fields.find(
|
objectMetadataItem.fields.find((fieldMetadataItem) =>
|
||||||
(field) =>
|
isLabelIdentifierField({
|
||||||
field.id === objectMetadataItem.labelIdentifierFieldMetadataId ||
|
fieldMetadataItem,
|
||||||
field.name === 'name',
|
objectMetadataItem,
|
||||||
|
}),
|
||||||
);
|
);
|
||||||
};
|
|
||||||
|
@ -1,17 +1,15 @@
|
|||||||
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
||||||
import { OrderBy } from '@/object-metadata/types/OrderBy';
|
import { OrderBy } from '@/object-metadata/types/OrderBy';
|
||||||
import { OrderByField } from '@/object-metadata/types/OrderByField';
|
import { OrderByField } from '@/object-metadata/types/OrderByField';
|
||||||
|
import { getLabelIdentifierFieldMetadataItem } from '@/object-metadata/utils/getLabelIdentifierFieldMetadataItem';
|
||||||
import { FieldMetadataType } from '~/generated-metadata/graphql';
|
import { FieldMetadataType } from '~/generated-metadata/graphql';
|
||||||
|
|
||||||
export const getObjectOrderByField = (
|
export const getObjectOrderByField = (
|
||||||
objectMetadataItem: ObjectMetadataItem,
|
objectMetadataItem: ObjectMetadataItem,
|
||||||
orderBy?: OrderBy | null,
|
orderBy?: OrderBy | null,
|
||||||
): OrderByField => {
|
): OrderByField => {
|
||||||
const labelIdentifierFieldMetadata = objectMetadataItem.fields.find(
|
const labelIdentifierFieldMetadata =
|
||||||
(field) =>
|
getLabelIdentifierFieldMetadataItem(objectMetadataItem);
|
||||||
field.id === objectMetadataItem.labelIdentifierFieldMetadataId ||
|
|
||||||
field.name === 'name',
|
|
||||||
);
|
|
||||||
|
|
||||||
if (labelIdentifierFieldMetadata) {
|
if (labelIdentifierFieldMetadata) {
|
||||||
switch (labelIdentifierFieldMetadata.type) {
|
switch (labelIdentifierFieldMetadata.type) {
|
||||||
|
@ -13,8 +13,7 @@ export const isLabelIdentifierField = ({
|
|||||||
ObjectMetadataItem,
|
ObjectMetadataItem,
|
||||||
'labelIdentifierFieldMetadataId'
|
'labelIdentifierFieldMetadataId'
|
||||||
>;
|
>;
|
||||||
}) => {
|
}) =>
|
||||||
return isDefined(objectMetadataItem.labelIdentifierFieldMetadataId)
|
isDefined(objectMetadataItem.labelIdentifierFieldMetadataId)
|
||||||
? fieldMetadataItem.id === objectMetadataItem.labelIdentifierFieldMetadataId
|
? fieldMetadataItem.id === objectMetadataItem.labelIdentifierFieldMetadataId
|
||||||
: fieldMetadataItem.name === DEFAULT_LABEL_IDENTIFIER_FIELD_NAME;
|
: fieldMetadataItem.name === DEFAULT_LABEL_IDENTIFIER_FIELD_NAME;
|
||||||
};
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import { useContext } from 'react';
|
import { useContext } from 'react';
|
||||||
import { useRecoilValue, useSetRecoilState } from 'recoil';
|
import { useRecoilValue, useSetRecoilState } from 'recoil';
|
||||||
|
|
||||||
|
import { isLabelIdentifierField } from '@/object-metadata/utils/isLabelIdentifierField';
|
||||||
import { useRecordTableStates } from '@/object-record/record-table/hooks/internal/useRecordTableStates';
|
import { useRecordTableStates } from '@/object-record/record-table/hooks/internal/useRecordTableStates';
|
||||||
import { RelationPickerHotkeyScope } from '@/object-record/relation-picker/types/RelationPickerHotkeyScope';
|
import { RelationPickerHotkeyScope } from '@/object-record/relation-picker/types/RelationPickerHotkeyScope';
|
||||||
import { contextMenuIsOpenState } from '@/ui/navigation/context-menu/states/contextMenuIsOpenState';
|
import { contextMenuIsOpenState } from '@/ui/navigation/context-menu/states/contextMenuIsOpenState';
|
||||||
@ -65,9 +66,16 @@ export const RecordTableCellContainer = ({
|
|||||||
useUpdateRecord: () => [updateRecord, {}],
|
useUpdateRecord: () => [updateRecord, {}],
|
||||||
hotkeyScope: customHotkeyScope,
|
hotkeyScope: customHotkeyScope,
|
||||||
basePathToShowPage: objectMetadataConfig?.basePathToShowPage,
|
basePathToShowPage: objectMetadataConfig?.basePathToShowPage,
|
||||||
isLabelIdentifier:
|
isLabelIdentifier: isLabelIdentifierField({
|
||||||
columnDefinition.fieldMetadataId ===
|
fieldMetadataItem: {
|
||||||
objectMetadataConfig?.labelIdentifierFieldMetadataId,
|
id: columnDefinition.fieldMetadataId,
|
||||||
|
name: columnDefinition.metadata.fieldName,
|
||||||
|
},
|
||||||
|
objectMetadataItem: {
|
||||||
|
labelIdentifierFieldMetadataId:
|
||||||
|
objectMetadataConfig?.labelIdentifierFieldMetadataId,
|
||||||
|
},
|
||||||
|
}),
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<RecordTableCell customHotkeyScope={{ scope: customHotkeyScope }} />
|
<RecordTableCell customHotkeyScope={{ scope: customHotkeyScope }} />
|
||||||
|
@ -3,6 +3,7 @@ import {
|
|||||||
IconDotsVertical,
|
IconDotsVertical,
|
||||||
IconEye,
|
IconEye,
|
||||||
IconPencil,
|
IconPencil,
|
||||||
|
IconTextSize,
|
||||||
} from '@/ui/display/icon';
|
} from '@/ui/display/icon';
|
||||||
import { LightIconButton } from '@/ui/input/button/components/LightIconButton';
|
import { LightIconButton } from '@/ui/input/button/components/LightIconButton';
|
||||||
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
|
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
|
||||||
@ -15,6 +16,7 @@ type SettingsObjectFieldActiveActionDropdownProps = {
|
|||||||
isCustomField?: boolean;
|
isCustomField?: boolean;
|
||||||
onDisable?: () => void;
|
onDisable?: () => void;
|
||||||
onEdit: () => void;
|
onEdit: () => void;
|
||||||
|
onSetAsLabelIdentifier?: () => void;
|
||||||
scopeKey: string;
|
scopeKey: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -22,6 +24,7 @@ export const SettingsObjectFieldActiveActionDropdown = ({
|
|||||||
isCustomField,
|
isCustomField,
|
||||||
onDisable,
|
onDisable,
|
||||||
onEdit,
|
onEdit,
|
||||||
|
onSetAsLabelIdentifier,
|
||||||
scopeKey,
|
scopeKey,
|
||||||
}: SettingsObjectFieldActiveActionDropdownProps) => {
|
}: SettingsObjectFieldActiveActionDropdownProps) => {
|
||||||
const dropdownId = `${scopeKey}-settings-field-active-action-dropdown`;
|
const dropdownId = `${scopeKey}-settings-field-active-action-dropdown`;
|
||||||
@ -38,6 +41,11 @@ export const SettingsObjectFieldActiveActionDropdown = ({
|
|||||||
closeDropdown();
|
closeDropdown();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleSetAsLabelIdentifier = () => {
|
||||||
|
onSetAsLabelIdentifier?.();
|
||||||
|
closeDropdown();
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Dropdown
|
<Dropdown
|
||||||
dropdownId={dropdownId}
|
dropdownId={dropdownId}
|
||||||
@ -52,6 +60,13 @@ export const SettingsObjectFieldActiveActionDropdown = ({
|
|||||||
LeftIcon={isCustomField ? IconPencil : IconEye}
|
LeftIcon={isCustomField ? IconPencil : IconEye}
|
||||||
onClick={handleEdit}
|
onClick={handleEdit}
|
||||||
/>
|
/>
|
||||||
|
{!!onSetAsLabelIdentifier && (
|
||||||
|
<MenuItem
|
||||||
|
text="Set as record text"
|
||||||
|
LeftIcon={IconTextSize}
|
||||||
|
onClick={handleSetAsLabelIdentifier}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
{!!onDisable && (
|
{!!onDisable && (
|
||||||
<MenuItem
|
<MenuItem
|
||||||
text="Disable"
|
text="Disable"
|
||||||
|
@ -26,6 +26,7 @@ import { Table } from '@/ui/layout/table/components/Table';
|
|||||||
import { TableHeader } from '@/ui/layout/table/components/TableHeader';
|
import { TableHeader } from '@/ui/layout/table/components/TableHeader';
|
||||||
import { TableSection } from '@/ui/layout/table/components/TableSection';
|
import { TableSection } from '@/ui/layout/table/components/TableSection';
|
||||||
import { Breadcrumb } from '@/ui/navigation/bread-crumb/components/Breadcrumb';
|
import { Breadcrumb } from '@/ui/navigation/bread-crumb/components/Breadcrumb';
|
||||||
|
import { FieldMetadataType } from '~/generated-metadata/graphql';
|
||||||
|
|
||||||
const StyledDiv = styled.div`
|
const StyledDiv = styled.div`
|
||||||
display: flex;
|
display: flex;
|
||||||
@ -37,8 +38,11 @@ export const SettingsObjectDetail = () => {
|
|||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
|
||||||
const { objectSlug = '' } = useParams();
|
const { objectSlug = '' } = useParams();
|
||||||
const { disableObjectMetadataItem, findActiveObjectMetadataItemBySlug } =
|
const {
|
||||||
useObjectMetadataItemForSettings();
|
disableObjectMetadataItem,
|
||||||
|
editObjectMetadataItem,
|
||||||
|
findActiveObjectMetadataItemBySlug,
|
||||||
|
} = useObjectMetadataItemForSettings();
|
||||||
|
|
||||||
const activeObjectMetadataItem =
|
const activeObjectMetadataItem =
|
||||||
findActiveObjectMetadataItemBySlug(objectSlug);
|
findActiveObjectMetadataItemBySlug(objectSlug);
|
||||||
@ -64,10 +68,17 @@ export const SettingsObjectDetail = () => {
|
|||||||
navigate('/settings/objects');
|
navigate('/settings/objects');
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleDisableField = async (
|
const handleDisableField = (activeFieldMetadatItem: FieldMetadataItem) => {
|
||||||
|
disableMetadataField(activeFieldMetadatItem);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleSetLabelIdentifierField = (
|
||||||
activeFieldMetadatItem: FieldMetadataItem,
|
activeFieldMetadatItem: FieldMetadataItem,
|
||||||
) => {
|
) => {
|
||||||
disableMetadataField(activeFieldMetadatItem);
|
editObjectMetadataItem({
|
||||||
|
...activeObjectMetadataItem,
|
||||||
|
labelIdentifierFieldMetadataId: activeFieldMetadatItem.id,
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -104,38 +115,56 @@ export const SettingsObjectDetail = () => {
|
|||||||
</StyledObjectFieldTableRow>
|
</StyledObjectFieldTableRow>
|
||||||
{!!activeMetadataFields.length && (
|
{!!activeMetadataFields.length && (
|
||||||
<TableSection title="Active">
|
<TableSection title="Active">
|
||||||
{activeMetadataFields.map((activeMetadataField) => (
|
{activeMetadataFields.map((activeMetadataField) => {
|
||||||
<SettingsObjectFieldItemTableRow
|
const isLabelIdentifier = isLabelIdentifierField({
|
||||||
key={activeMetadataField.id}
|
fieldMetadataItem: activeMetadataField,
|
||||||
identifierType={getFieldIdentifierType(
|
objectMetadataItem: activeObjectMetadataItem,
|
||||||
activeMetadataField,
|
});
|
||||||
activeObjectMetadataItem,
|
const canBeSetAsLabelIdentifier =
|
||||||
)}
|
activeObjectMetadataItem.isCustom &&
|
||||||
variant={
|
!isLabelIdentifier &&
|
||||||
activeObjectMetadataItem.isCustom
|
[FieldMetadataType.Text, FieldMetadataType.Number].includes(
|
||||||
? 'identifier'
|
activeMetadataField.type,
|
||||||
: 'field-type'
|
);
|
||||||
}
|
|
||||||
fieldMetadataItem={activeMetadataField}
|
return (
|
||||||
ActionIcon={
|
<SettingsObjectFieldItemTableRow
|
||||||
<SettingsObjectFieldActiveActionDropdown
|
key={activeMetadataField.id}
|
||||||
isCustomField={!!activeMetadataField.isCustom}
|
identifierType={getFieldIdentifierType(
|
||||||
scopeKey={activeMetadataField.id}
|
activeMetadataField,
|
||||||
onEdit={() =>
|
activeObjectMetadataItem,
|
||||||
navigate(`./${getFieldSlug(activeMetadataField)}`)
|
)}
|
||||||
}
|
variant={
|
||||||
onDisable={
|
activeObjectMetadataItem.isCustom
|
||||||
isLabelIdentifierField({
|
? 'identifier'
|
||||||
fieldMetadataItem: activeMetadataField,
|
: 'field-type'
|
||||||
objectMetadataItem: activeObjectMetadataItem,
|
}
|
||||||
})
|
fieldMetadataItem={activeMetadataField}
|
||||||
? undefined
|
ActionIcon={
|
||||||
: () => handleDisableField(activeMetadataField)
|
<SettingsObjectFieldActiveActionDropdown
|
||||||
}
|
isCustomField={!!activeMetadataField.isCustom}
|
||||||
/>
|
scopeKey={activeMetadataField.id}
|
||||||
}
|
onEdit={() =>
|
||||||
/>
|
navigate(`./${getFieldSlug(activeMetadataField)}`)
|
||||||
))}
|
}
|
||||||
|
onSetAsLabelIdentifier={
|
||||||
|
canBeSetAsLabelIdentifier
|
||||||
|
? () =>
|
||||||
|
handleSetLabelIdentifierField(
|
||||||
|
activeMetadataField,
|
||||||
|
)
|
||||||
|
: undefined
|
||||||
|
}
|
||||||
|
onDisable={
|
||||||
|
isLabelIdentifier
|
||||||
|
? undefined
|
||||||
|
: () => handleDisableField(activeMetadataField)
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
})}
|
||||||
</TableSection>
|
</TableSection>
|
||||||
)}
|
)}
|
||||||
{!!disabledMetadataFields.length && (
|
{!!disabledMetadataFields.length && (
|
||||||
|
@ -5,6 +5,7 @@ import { useFieldMetadataItem } from '@/object-metadata/hooks/useFieldMetadataIt
|
|||||||
import { useObjectMetadataItemForSettings } from '@/object-metadata/hooks/useObjectMetadataItemForSettings';
|
import { useObjectMetadataItemForSettings } from '@/object-metadata/hooks/useObjectMetadataItemForSettings';
|
||||||
import { useRelationMetadata } from '@/object-metadata/hooks/useRelationMetadata';
|
import { useRelationMetadata } from '@/object-metadata/hooks/useRelationMetadata';
|
||||||
import { getFieldSlug } from '@/object-metadata/utils/getFieldSlug';
|
import { getFieldSlug } from '@/object-metadata/utils/getFieldSlug';
|
||||||
|
import { isLabelIdentifierField } from '@/object-metadata/utils/isLabelIdentifierField';
|
||||||
import { SaveAndCancelButtons } from '@/settings/components/SaveAndCancelButtons/SaveAndCancelButtons';
|
import { SaveAndCancelButtons } from '@/settings/components/SaveAndCancelButtons/SaveAndCancelButtons';
|
||||||
import { SettingsHeaderContainer } from '@/settings/components/SettingsHeaderContainer';
|
import { SettingsHeaderContainer } from '@/settings/components/SettingsHeaderContainer';
|
||||||
import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer';
|
import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer';
|
||||||
@ -114,6 +115,11 @@ export const SettingsObjectFieldEdit = () => {
|
|||||||
|
|
||||||
const canSave = isValid && hasFormChanged;
|
const canSave = isValid && hasFormChanged;
|
||||||
|
|
||||||
|
const isLabelIdentifier = isLabelIdentifierField({
|
||||||
|
fieldMetadataItem: activeMetadataField,
|
||||||
|
objectMetadataItem: activeObjectMetadataItem,
|
||||||
|
});
|
||||||
|
|
||||||
const handleSave = async () => {
|
const handleSave = async () => {
|
||||||
if (!validatedFormValues) return;
|
if (!validatedFormValues) return;
|
||||||
|
|
||||||
@ -203,15 +209,17 @@ export const SettingsObjectFieldEdit = () => {
|
|||||||
select: formValues.select,
|
select: formValues.select,
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<Section>
|
{!isLabelIdentifier && (
|
||||||
<H2Title title="Danger zone" description="Disable this field" />
|
<Section>
|
||||||
<Button
|
<H2Title title="Danger zone" description="Disable this field" />
|
||||||
Icon={IconArchive}
|
<Button
|
||||||
title="Disable"
|
Icon={IconArchive}
|
||||||
size="small"
|
title="Disable"
|
||||||
onClick={handleDisable}
|
size="small"
|
||||||
/>
|
onClick={handleDisable}
|
||||||
</Section>
|
/>
|
||||||
|
</Section>
|
||||||
|
)}
|
||||||
</SettingsPageContainer>
|
</SettingsPageContainer>
|
||||||
</SubMenuTopBarContainer>
|
</SubMenuTopBarContainer>
|
||||||
);
|
);
|
||||||
|
@ -4,6 +4,7 @@ import styled from '@emotion/styled';
|
|||||||
|
|
||||||
import { useFieldMetadataItem } from '@/object-metadata/hooks/useFieldMetadataItem';
|
import { useFieldMetadataItem } from '@/object-metadata/hooks/useFieldMetadataItem';
|
||||||
import { useObjectMetadataItemForSettings } from '@/object-metadata/hooks/useObjectMetadataItemForSettings';
|
import { useObjectMetadataItemForSettings } from '@/object-metadata/hooks/useObjectMetadataItemForSettings';
|
||||||
|
import { isLabelIdentifierField } from '@/object-metadata/utils/isLabelIdentifierField';
|
||||||
import { SaveAndCancelButtons } from '@/settings/components/SaveAndCancelButtons/SaveAndCancelButtons';
|
import { SaveAndCancelButtons } from '@/settings/components/SaveAndCancelButtons/SaveAndCancelButtons';
|
||||||
import { SettingsHeaderContainer } from '@/settings/components/SettingsHeaderContainer';
|
import { SettingsHeaderContainer } from '@/settings/components/SettingsHeaderContainer';
|
||||||
import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer';
|
import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer';
|
||||||
@ -133,16 +134,23 @@ export const SettingsObjectNewFieldStep1 = () => {
|
|||||||
</StyledObjectFieldTableRow>
|
</StyledObjectFieldTableRow>
|
||||||
{!!activeMetadataFields.length && (
|
{!!activeMetadataFields.length && (
|
||||||
<TableSection isInitiallyExpanded={false} title="Active">
|
<TableSection isInitiallyExpanded={false} title="Active">
|
||||||
{activeMetadataFields.map((field) => (
|
{activeMetadataFields.map((activeMetadataField) => (
|
||||||
<SettingsObjectFieldItemTableRow
|
<SettingsObjectFieldItemTableRow
|
||||||
key={field.id}
|
key={activeMetadataField.id}
|
||||||
fieldMetadataItem={field}
|
fieldMetadataItem={activeMetadataField}
|
||||||
ActionIcon={
|
ActionIcon={
|
||||||
<LightIconButton
|
isLabelIdentifierField({
|
||||||
Icon={IconMinus}
|
fieldMetadataItem: activeMetadataField,
|
||||||
accent="tertiary"
|
objectMetadataItem: activeObjectMetadataItem,
|
||||||
onClick={() => handleToggleField(field.id)}
|
}) ? undefined : (
|
||||||
/>
|
<LightIconButton
|
||||||
|
Icon={IconMinus}
|
||||||
|
accent="tertiary"
|
||||||
|
onClick={() =>
|
||||||
|
handleToggleField(activeMetadataField.id)
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
)
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
@ -150,15 +158,17 @@ export const SettingsObjectNewFieldStep1 = () => {
|
|||||||
)}
|
)}
|
||||||
{!!disabledMetadataFields.length && (
|
{!!disabledMetadataFields.length && (
|
||||||
<TableSection title="Disabled">
|
<TableSection title="Disabled">
|
||||||
{disabledMetadataFields.map((field) => (
|
{disabledMetadataFields.map((disabledMetadataField) => (
|
||||||
<SettingsObjectFieldItemTableRow
|
<SettingsObjectFieldItemTableRow
|
||||||
key={field.name}
|
key={disabledMetadataField.name}
|
||||||
fieldMetadataItem={field}
|
fieldMetadataItem={disabledMetadataField}
|
||||||
ActionIcon={
|
ActionIcon={
|
||||||
<LightIconButton
|
<LightIconButton
|
||||||
Icon={IconPlus}
|
Icon={IconPlus}
|
||||||
accent="tertiary"
|
accent="tertiary"
|
||||||
onClick={() => handleToggleField(field.id)}
|
onClick={() =>
|
||||||
|
handleToggleField(disabledMetadataField.id)
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
@ -186,6 +186,14 @@ export class FieldMetadataService extends TypeOrmQueryService<FieldMetadataEntit
|
|||||||
throw new NotFoundException('Object does not exist');
|
throw new NotFoundException('Object does not exist');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
objectMetadata.labelIdentifierFieldMetadataId ===
|
||||||
|
existingFieldMetadata.id &&
|
||||||
|
fieldMetadataInput.isActive === false
|
||||||
|
) {
|
||||||
|
throw new BadRequestException('Cannot deactivate label identifier field');
|
||||||
|
}
|
||||||
|
|
||||||
// Check if the id of the options has been provided
|
// Check if the id of the options has been provided
|
||||||
if (fieldMetadataInput.options) {
|
if (fieldMetadataInput.options) {
|
||||||
for (const option of fieldMetadataInput.options) {
|
for (const option of fieldMetadataInput.options) {
|
||||||
|
Loading…
Reference in New Issue
Block a user