Skip to content

Commit

Permalink
feat: set field as custom object label identifier in Object Detail
Browse files Browse the repository at this point in the history
Closes #3302
  • Loading branch information
thaisguigon committed Jan 10, 2024
1 parent 4f9ea78 commit 8f01936
Show file tree
Hide file tree
Showing 11 changed files with 154 additions and 76 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { useMapToObjectRecordIdentifier } from '@/object-metadata/hooks/useMapTo
import { objectMetadataItemFamilySelector } from '@/object-metadata/states/objectMetadataItemFamilySelector';
import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState';
import { getBasePathToShowPage } from '@/object-metadata/utils/getBasePathToShowPage';
import { getLabelIdentifierFieldMetadataItem } from '@/object-metadata/utils/getLabelIdentifierFieldMetadataItem';
import { getObjectMetadataItemsMock } from '@/object-metadata/utils/getObjectMetadataItemsMock';
import { useGenerateCreateManyRecordMutation } from '@/object-record/hooks/useGenerateCreateManyRecordMutation';
import { useGenerateCreateOneRecordMutation } from '@/object-record/hooks/useGenerateCreateOneRecordMutation';
Expand Down Expand Up @@ -118,9 +119,8 @@ export const useObjectMetadataItem = (
objectMetadataItem,
});

const labelIdentifierFieldMetadata = objectMetadataItem.fields.find(
({ name }) => name === 'name',
);
const labelIdentifierFieldMetadata =
getLabelIdentifierFieldMetadataItem(objectMetadataItem);

const basePathToShowPage = getBasePathToShowPage({
objectMetadataItem,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,12 @@ export const useObjectMetadataItemForSettings = () => {
const editObjectMetadataItem = (
input: Pick<
ObjectMetadataItem,
'id' | 'labelPlural' | 'labelSingular' | 'icon' | 'description'
| 'description'
| 'icon'
| 'id'
| 'labelIdentifierFieldMetadataId'
| 'labelPlural'
| 'labelSingular'
>,
) =>
updateOneObjectMetadataItem({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,17 @@ import { ObjectMetadataItem } from '../types/ObjectMetadataItem';
export const formatObjectMetadataItemInput = (
input: Pick<
ObjectMetadataItem,
'labelPlural' | 'labelSingular' | 'icon' | 'description'
| 'description'
| 'icon'
| 'labelIdentifierFieldMetadataId'
| 'labelPlural'
| 'labelSingular'
>,
) => ({
description: input.description?.trim() ?? null,
icon: input.icon,
labelIdentifierFieldMetadataId:
input.labelIdentifierFieldMetadataId?.trim() ?? null,
labelPlural: input.labelPlural.trim(),
labelSingular: input.labelSingular.trim(),
namePlural: toCamelCase(input.labelPlural.trim()),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import { FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem';
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
import { isLabelIdentifierField } from '@/object-metadata/utils/isLabelIdentifierField';

export const getLabelIdentifierFieldMetadataItem = (
objectMetadataItem: ObjectMetadataItem,
): FieldMetadataItem | undefined => {
return objectMetadataItem.fields.find(
(field) =>
field.id === objectMetadataItem.labelIdentifierFieldMetadataId ||
field.name === 'name',
): FieldMetadataItem | undefined =>
objectMetadataItem.fields.find((fieldMetadataItem) =>
isLabelIdentifierField({
fieldMetadataItem,
objectMetadataItem,
}),
);
};
Original file line number Diff line number Diff line change
@@ -1,17 +1,15 @@
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
import { OrderBy } from '@/object-metadata/types/OrderBy';
import { OrderByField } from '@/object-metadata/types/OrderByField';
import { getLabelIdentifierFieldMetadataItem } from '@/object-metadata/utils/getLabelIdentifierFieldMetadataItem';
import { FieldMetadataType } from '~/generated-metadata/graphql';

export const getObjectOrderByField = (
objectMetadataItem: ObjectMetadataItem,
orderBy?: OrderBy | null,
): OrderByField => {
const labelIdentifierFieldMetadata = objectMetadataItem.fields.find(
(field) =>
field.id === objectMetadataItem.labelIdentifierFieldMetadataId ||
field.name === 'name',
);
const labelIdentifierFieldMetadata =
getLabelIdentifierFieldMetadataItem(objectMetadataItem);

if (labelIdentifierFieldMetadata) {
switch (labelIdentifierFieldMetadata.type) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@ export const isLabelIdentifierField = ({
fieldMetadataItem,
objectMetadataItem,
}: {
fieldMetadataItem: FieldMetadataItem;
objectMetadataItem: ObjectMetadataItem;
}) => {
return (
fieldMetadataItem.id ===
objectMetadataItem.labelIdentifierFieldMetadataId ||
fieldMetadataItem.name === DEFAULT_LABEL_IDENTIFIER_FIELD_NAME
);
};
fieldMetadataItem: Pick<FieldMetadataItem, 'id' | 'name'>;
objectMetadataItem: Pick<
ObjectMetadataItem,
'labelIdentifierFieldMetadataId'
>;
}) =>
objectMetadataItem.labelIdentifierFieldMetadataId
? fieldMetadataItem.id === objectMetadataItem.labelIdentifierFieldMetadataId
: fieldMetadataItem.name === DEFAULT_LABEL_IDENTIFIER_FIELD_NAME;
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { useContext } from 'react';
import { useRecoilValue, useSetRecoilState } from 'recoil';

import { isLabelIdentifierField } from '@/object-metadata/utils/isLabelIdentifierField';
import { useRecordTableScopedStates } from '@/object-record/record-table/hooks/internal/useRecordTableScopedStates';
import { getRecordTableScopeInjector } from '@/object-record/record-table/utils/getRecordTableScopeInjector';
import { RelationPickerHotkeyScope } from '@/object-record/relation-picker/types/RelationPickerHotkeyScope';
Expand Down Expand Up @@ -70,9 +71,16 @@ export const RecordTableCellContainer = ({
useUpdateRecord: () => [updateRecord, {}],
hotkeyScope: customHotkeyScope,
basePathToShowPage: objectMetadataConfig?.basePathToShowPage,
isLabelIdentifier:
columnDefinition.fieldMetadataId ===
objectMetadataConfig?.labelIdentifierFieldMetadataId,
isLabelIdentifier: isLabelIdentifierField({
fieldMetadataItem: {
id: columnDefinition.fieldMetadataId,
name: columnDefinition.metadata.fieldName,
},
objectMetadataItem: {
labelIdentifierFieldMetadataId:
objectMetadataConfig?.labelIdentifierFieldMetadataId,
},
}),
}}
>
<RecordTableCell customHotkeyScope={{ scope: customHotkeyScope }} />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {
IconDotsVertical,
IconEye,
IconPencil,
IconTextSize,
} from '@/ui/display/icon';
import { LightIconButton } from '@/ui/input/button/components/LightIconButton';
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
Expand All @@ -15,13 +16,15 @@ type SettingsObjectFieldActiveActionDropdownProps = {
isCustomField?: boolean;
onDisable?: () => void;
onEdit: () => void;
onSetAsLabelIdentifier?: () => void;
scopeKey: string;
};

export const SettingsObjectFieldActiveActionDropdown = ({
isCustomField,
onDisable,
onEdit,
onSetAsLabelIdentifier,
scopeKey,
}: SettingsObjectFieldActiveActionDropdownProps) => {
const dropdownId = `${scopeKey}-settings-field-active-action-dropdown`;
Expand All @@ -38,6 +41,11 @@ export const SettingsObjectFieldActiveActionDropdown = ({
closeDropdown();
};

const handleSetAsLabelIdentifier = () => {
onSetAsLabelIdentifier?.();
closeDropdown();
};

return (
<Dropdown
dropdownId={dropdownId}
Expand All @@ -52,6 +60,13 @@ export const SettingsObjectFieldActiveActionDropdown = ({
LeftIcon={isCustomField ? IconPencil : IconEye}
onClick={handleEdit}
/>
{!!onSetAsLabelIdentifier && (
<MenuItem
text="Set as record text"
LeftIcon={IconTextSize}
onClick={handleSetAsLabelIdentifier}
/>
)}
{!!onDisable && (
<MenuItem
text="Disable"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,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;
Expand All @@ -36,8 +37,11 @@ export const SettingsObjectDetail = () => {
const navigate = useNavigate();

const { objectSlug = '' } = useParams();
const { disableObjectMetadataItem, findActiveObjectMetadataItemBySlug } =
useObjectMetadataItemForSettings();
const {
disableObjectMetadataItem,
editObjectMetadataItem,
findActiveObjectMetadataItemBySlug,
} = useObjectMetadataItemForSettings();

const activeObjectMetadataItem =
findActiveObjectMetadataItemBySlug(objectSlug);
Expand All @@ -63,10 +67,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 (
Expand Down Expand Up @@ -99,29 +110,47 @@ export const SettingsObjectDetail = () => {
</StyledObjectFieldTableRow>
{!!activeMetadataFields.length && (
<TableSection title="Active">
{activeMetadataFields.map((activeMetadataField) => (
<SettingsObjectFieldItemTableRow
key={activeMetadataField.id}
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}
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 && (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -203,15 +204,20 @@ 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>
{!isLabelIdentifierField({
fieldMetadataItem: activeMetadataField,
objectMetadataItem: activeObjectMetadataItem,
}) && (
<Section>
<H2Title title="Danger zone" description="Disable this field" />
<Button
Icon={IconArchive}
title="Disable"
size="small"
onClick={handleDisable}
/>
</Section>
)}
</SettingsPageContainer>
</SubMenuTopBarContainer>
);
Expand Down
Loading

0 comments on commit 8f01936

Please sign in to comment.