[REFACTOR][FRONT]: Remove objectMetadata and fieldMetadata sluggification (#9441)
# Introduction For motivations and context please have a look to https://github.com/twentyhq/twenty/pull/9394 whom this PR results from. In this pull-request we remove any `metadataField` and `objectMetadata` sluggification. We directly consume `objectMetadata.namePlural` and `metadataField.name`, ***it seems like that historically the consumed `metadataField.name`*** are we sure that we wanna change this behavior ? ## Notes Unless I'm mistaken by reverting the `kebabcase` url formatting we might be creating deadlinks that user could have save beforehand => Discussed with Charles said it's controlled risk. --------- Co-authored-by: Paul Rastoin <paulrastoin@Pauls-MacBook-Pro.local>
This commit is contained in:
@ -20,7 +20,7 @@ export const useLastVisitedObjectMetadataItem = () => {
|
|||||||
useRecoilState(lastVisitedObjectMetadataItemIdState);
|
useRecoilState(lastVisitedObjectMetadataItemIdState);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
findActiveObjectMetadataItemBySlug,
|
findActiveObjectMetadataItemByNamePlural,
|
||||||
alphaSortedActiveObjectMetadataItems,
|
alphaSortedActiveObjectMetadataItems,
|
||||||
} = useFilteredObjectMetadataItems();
|
} = useFilteredObjectMetadataItems();
|
||||||
|
|
||||||
@ -51,7 +51,7 @@ export const useLastVisitedObjectMetadataItem = () => {
|
|||||||
|
|
||||||
const setLastVisitedObjectMetadataItem = (objectNamePlural: string) => {
|
const setLastVisitedObjectMetadataItem = (objectNamePlural: string) => {
|
||||||
const fallbackObjectMetadataItem =
|
const fallbackObjectMetadataItem =
|
||||||
findActiveObjectMetadataItemBySlug(objectNamePlural);
|
findActiveObjectMetadataItemByNamePlural(objectNamePlural);
|
||||||
|
|
||||||
if (isDefined(fallbackObjectMetadataItem)) {
|
if (isDefined(fallbackObjectMetadataItem)) {
|
||||||
setLastVisitedObjectMetadataItemId(fallbackObjectMetadataItem.id);
|
setLastVisitedObjectMetadataItemId(fallbackObjectMetadataItem.id);
|
||||||
|
|||||||
@ -35,7 +35,7 @@ const Wrapper = ({ children }: { children: ReactNode }) => (
|
|||||||
);
|
);
|
||||||
|
|
||||||
describe('useFilteredObjectMetadataItems', () => {
|
describe('useFilteredObjectMetadataItems', () => {
|
||||||
it('should findActiveObjectMetadataItemBySlug', async () => {
|
it('should findActiveObjectMetadataItemByNamePlural', async () => {
|
||||||
const { result } = renderHook(
|
const { result } = renderHook(
|
||||||
() => {
|
() => {
|
||||||
const setMetadataItems = useSetRecoilState(objectMetadataItemsState);
|
const setMetadataItems = useSetRecoilState(objectMetadataItemsState);
|
||||||
@ -49,13 +49,14 @@ describe('useFilteredObjectMetadataItems', () => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
act(() => {
|
act(() => {
|
||||||
const res = result.current.findActiveObjectMetadataItemBySlug('people');
|
const res =
|
||||||
|
result.current.findActiveObjectMetadataItemByNamePlural('people');
|
||||||
expect(res).toBeDefined();
|
expect(res).toBeDefined();
|
||||||
expect(res?.namePlural).toBe('people');
|
expect(res?.namePlural).toBe('people');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should findObjectMetadataItemBySlug', async () => {
|
it('should findObjectMetadataItemByNamePlural', async () => {
|
||||||
const { result } = renderHook(
|
const { result } = renderHook(
|
||||||
() => {
|
() => {
|
||||||
const setMetadataItems = useSetRecoilState(objectMetadataItemsState);
|
const setMetadataItems = useSetRecoilState(objectMetadataItemsState);
|
||||||
@ -69,7 +70,7 @@ describe('useFilteredObjectMetadataItems', () => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
act(() => {
|
act(() => {
|
||||||
const res = result.current.findObjectMetadataItemBySlug('people');
|
const res = result.current.findObjectMetadataItemByNamePlural('people');
|
||||||
expect(res).toBeDefined();
|
expect(res).toBeDefined();
|
||||||
expect(res?.namePlural).toBe('people');
|
expect(res?.namePlural).toBe('people');
|
||||||
});
|
});
|
||||||
|
|||||||
@ -2,8 +2,6 @@ import { useRecoilValue } from 'recoil';
|
|||||||
|
|
||||||
import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState';
|
import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState';
|
||||||
|
|
||||||
import { getObjectSlug } from '../utils/getObjectSlug';
|
|
||||||
|
|
||||||
export const useFilteredObjectMetadataItems = () => {
|
export const useFilteredObjectMetadataItems = () => {
|
||||||
const objectMetadataItems = useRecoilValue(objectMetadataItemsState);
|
const objectMetadataItems = useRecoilValue(objectMetadataItemsState);
|
||||||
|
|
||||||
@ -27,17 +25,6 @@ export const useFilteredObjectMetadataItems = () => {
|
|||||||
({ isActive, isSystem }) => !isActive && !isSystem,
|
({ isActive, isSystem }) => !isActive && !isSystem,
|
||||||
);
|
);
|
||||||
|
|
||||||
const findObjectMetadataItemBySlug = (slug: string) =>
|
|
||||||
objectMetadataItems.find(
|
|
||||||
(objectMetadataItem) => getObjectSlug(objectMetadataItem) === slug,
|
|
||||||
);
|
|
||||||
|
|
||||||
const findActiveObjectMetadataItemBySlug = (slug: string) =>
|
|
||||||
activeObjectMetadataItems.find(
|
|
||||||
(activeObjectMetadataItem) =>
|
|
||||||
getObjectSlug(activeObjectMetadataItem) === slug,
|
|
||||||
);
|
|
||||||
|
|
||||||
const findActiveObjectMetadataItemByNamePlural = (namePlural: string) =>
|
const findActiveObjectMetadataItemByNamePlural = (namePlural: string) =>
|
||||||
activeObjectMetadataItems.find(
|
activeObjectMetadataItems.find(
|
||||||
(activeObjectMetadataItem) =>
|
(activeObjectMetadataItem) =>
|
||||||
@ -56,13 +43,11 @@ export const useFilteredObjectMetadataItems = () => {
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
activeObjectMetadataItems,
|
activeObjectMetadataItems,
|
||||||
findActiveObjectMetadataItemBySlug,
|
|
||||||
findObjectMetadataItemById,
|
findObjectMetadataItemById,
|
||||||
findObjectMetadataItemByNamePlural,
|
findObjectMetadataItemByNamePlural,
|
||||||
findActiveObjectMetadataItemByNamePlural,
|
findActiveObjectMetadataItemByNamePlural,
|
||||||
inactiveObjectMetadataItems,
|
inactiveObjectMetadataItems,
|
||||||
objectMetadataItems,
|
objectMetadataItems,
|
||||||
findObjectMetadataItemBySlug,
|
|
||||||
alphaSortedActiveObjectMetadataItems,
|
alphaSortedActiveObjectMetadataItems,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,8 +0,0 @@
|
|||||||
import { getFieldSlug } from '@/object-metadata/utils/getFieldSlug';
|
|
||||||
|
|
||||||
describe('getFieldSlug', () => {
|
|
||||||
it('should work as expected', () => {
|
|
||||||
const res = getFieldSlug({ label: 'Pipeline Step' });
|
|
||||||
expect(res).toBe('pipeline-step');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@ -1,13 +0,0 @@
|
|||||||
import { getObjectSlug } from '@/object-metadata/utils/getObjectSlug';
|
|
||||||
import { generatedMockObjectMetadataItems } from '~/testing/mock-data/generatedMockObjectMetadataItems';
|
|
||||||
|
|
||||||
describe('getObjectSlug', () => {
|
|
||||||
it('should work as expected', () => {
|
|
||||||
const objectMetadataItem = generatedMockObjectMetadataItems.find(
|
|
||||||
(item) => item.nameSingular === 'person',
|
|
||||||
)!;
|
|
||||||
|
|
||||||
const res = getObjectSlug(objectMetadataItem);
|
|
||||||
expect(res).toBe('people');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@ -1,6 +0,0 @@
|
|||||||
import toKebabCase from 'lodash.kebabcase';
|
|
||||||
|
|
||||||
import { Field } from '~/generated-metadata/graphql';
|
|
||||||
|
|
||||||
export const getFieldSlug = (metadataField: Pick<Field, 'label'>) =>
|
|
||||||
toKebabCase(metadataField.label);
|
|
||||||
@ -1,7 +0,0 @@
|
|||||||
import toKebabCase from 'lodash.kebabcase';
|
|
||||||
|
|
||||||
import { ObjectMetadataItem } from '../types/ObjectMetadataItem';
|
|
||||||
|
|
||||||
export const getObjectSlug = (
|
|
||||||
objectMetadataItem: Pick<ObjectMetadataItem, 'namePlural'>,
|
|
||||||
) => toKebabCase(objectMetadataItem.namePlural);
|
|
||||||
@ -35,7 +35,7 @@ export const ObjectOptionsDropdownHiddenFieldsContent = () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const settingsUrl = getSettingsPagePath(SettingsPath.ObjectDetail, {
|
const settingsUrl = getSettingsPagePath(SettingsPath.ObjectDetail, {
|
||||||
objectSlug: objectNamePlural,
|
objectNamePlural,
|
||||||
});
|
});
|
||||||
|
|
||||||
const { handleColumnVisibilityChange, hiddenTableColumns } =
|
const { handleColumnVisibilityChange, hiddenTableColumns } =
|
||||||
|
|||||||
@ -54,8 +54,8 @@ export const ObjectOptionsDropdownHiddenRecordGroupsContent = () => {
|
|||||||
const viewGroupSettingsUrl = getSettingsPagePath(
|
const viewGroupSettingsUrl = getSettingsPagePath(
|
||||||
SettingsPath.ObjectFieldEdit,
|
SettingsPath.ObjectFieldEdit,
|
||||||
{
|
{
|
||||||
objectSlug: objectNamePlural,
|
objectNamePlural,
|
||||||
fieldSlug: recordGroupFieldMetadata?.name ?? '',
|
fieldName: recordGroupFieldMetadata?.name ?? '',
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@ -69,7 +69,7 @@ export const ObjectOptionsDropdownRecordGroupFieldsContent = () => {
|
|||||||
const newSelectFieldSettingsUrl = getSettingsPagePath(
|
const newSelectFieldSettingsUrl = getSettingsPagePath(
|
||||||
SettingsPath.ObjectNewFieldConfigure,
|
SettingsPath.ObjectNewFieldConfigure,
|
||||||
{
|
{
|
||||||
objectSlug: objectNamePlural,
|
objectNamePlural,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
fieldType: FieldMetadataType.Select,
|
fieldType: FieldMetadataType.Select,
|
||||||
|
|||||||
@ -1,6 +1,4 @@
|
|||||||
import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem';
|
import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem';
|
||||||
import { getFieldSlug } from '@/object-metadata/utils/getFieldSlug';
|
|
||||||
import { getObjectSlug } from '@/object-metadata/utils/getObjectSlug';
|
|
||||||
import { RecordBoardColumnContext } from '@/object-record/record-board/record-board-column/contexts/RecordBoardColumnContext';
|
import { RecordBoardColumnContext } from '@/object-record/record-board/record-board-column/contexts/RecordBoardColumnContext';
|
||||||
import { useRecordGroupVisibility } from '@/object-record/record-group/hooks/useRecordGroupVisibility';
|
import { useRecordGroupVisibility } from '@/object-record/record-group/hooks/useRecordGroupVisibility';
|
||||||
import { recordGroupFieldMetadataComponentState } from '@/object-record/record-group/states/recordGroupFieldMetadataComponentState';
|
import { recordGroupFieldMetadataComponentState } from '@/object-record/record-group/states/recordGroupFieldMetadataComponentState';
|
||||||
@ -55,7 +53,7 @@ export const useRecordGroupActions = ({
|
|||||||
throw new Error('recordGroupFieldMetadata is not a non-empty string');
|
throw new Error('recordGroupFieldMetadata is not a non-empty string');
|
||||||
}
|
}
|
||||||
|
|
||||||
const settingsPath = `/settings/objects/${getObjectSlug(objectMetadataItem)}/${getFieldSlug(recordGroupFieldMetadata)}`;
|
const settingsPath = `/settings/objects/${objectMetadataItem.namePlural}/${recordGroupFieldMetadata.name}`;
|
||||||
|
|
||||||
navigate(settingsPath);
|
navigate(settingsPath);
|
||||||
}, [
|
}, [
|
||||||
|
|||||||
@ -3,7 +3,6 @@ import { useLocation } from 'react-router-dom';
|
|||||||
import { useSetRecoilState } from 'recoil';
|
import { useSetRecoilState } from 'recoil';
|
||||||
import { IconSettings, MenuItem, UndecoratedLink, useIcons } from 'twenty-ui';
|
import { IconSettings, MenuItem, UndecoratedLink, useIcons } from 'twenty-ui';
|
||||||
|
|
||||||
import { getObjectSlug } from '@/object-metadata/utils/getObjectSlug';
|
|
||||||
import { FieldMetadata } from '@/object-record/record-field/types/FieldMetadata';
|
import { FieldMetadata } from '@/object-record/record-field/types/FieldMetadata';
|
||||||
import { useRecordTableContextOrThrow } from '@/object-record/record-table/contexts/RecordTableContext';
|
import { useRecordTableContextOrThrow } from '@/object-record/record-table/contexts/RecordTableContext';
|
||||||
import { useTableColumns } from '@/object-record/record-table/hooks/useTableColumns';
|
import { useTableColumns } from '@/object-record/record-table/hooks/useTableColumns';
|
||||||
@ -56,7 +55,7 @@ export const RecordTableHeaderPlusButtonContent = () => {
|
|||||||
<DropdownMenuItemsContainer scrollable={false}>
|
<DropdownMenuItemsContainer scrollable={false}>
|
||||||
<UndecoratedLink
|
<UndecoratedLink
|
||||||
fullWidth
|
fullWidth
|
||||||
to={`/settings/objects/${getObjectSlug(objectMetadataItem)}`}
|
to={`/settings/objects/${objectMetadataItem.namePlural}`}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setNavigationMemorizedUrl(location.pathname + location.search);
|
setNavigationMemorizedUrl(location.pathname + location.search);
|
||||||
}}
|
}}
|
||||||
|
|||||||
@ -68,7 +68,7 @@ export const SettingsDataModelNewFieldBreadcrumbDropDown = () => {
|
|||||||
const { closeDropdown } = useDropdown(dropdownId);
|
const { closeDropdown } = useDropdown(dropdownId);
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
const { objectSlug = '' } = useParams();
|
const { objectNamePlural = '' } = useParams();
|
||||||
const [searchParams] = useSearchParams();
|
const [searchParams] = useSearchParams();
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
|
|
||||||
@ -78,11 +78,11 @@ export const SettingsDataModelNewFieldBreadcrumbDropDown = () => {
|
|||||||
const handleClick = (step: 'select' | 'configure') => {
|
const handleClick = (step: 'select' | 'configure') => {
|
||||||
if (step === 'configure' && isDefined(fieldType)) {
|
if (step === 'configure' && isDefined(fieldType)) {
|
||||||
navigate(
|
navigate(
|
||||||
`/settings/objects/${objectSlug}/new-field/configure?fieldType=${fieldType}`,
|
`/settings/objects/${objectNamePlural}/new-field/configure?fieldType=${fieldType}`,
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
navigate(
|
navigate(
|
||||||
`/settings/objects/${objectSlug}/new-field/select${fieldType ? `?fieldType=${fieldType}` : ''}`,
|
`/settings/objects/${objectNamePlural}/new-field/select${fieldType ? `?fieldType=${fieldType}` : ''}`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
closeDropdown();
|
closeDropdown();
|
||||||
|
|||||||
@ -26,7 +26,7 @@ type SettingsObjectNewFieldSelectorProps = {
|
|||||||
'defaultValue' | 'options' | 'type'
|
'defaultValue' | 'options' | 'type'
|
||||||
>;
|
>;
|
||||||
|
|
||||||
objectSlug: string;
|
objectNamePlural: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
const StyledTypeSelectContainer = styled.div`
|
const StyledTypeSelectContainer = styled.div`
|
||||||
@ -58,7 +58,7 @@ const StyledSearchInput = styled(TextInput)`
|
|||||||
export const SettingsObjectNewFieldSelector = ({
|
export const SettingsObjectNewFieldSelector = ({
|
||||||
excludedFieldTypes = [],
|
excludedFieldTypes = [],
|
||||||
fieldMetadataItem,
|
fieldMetadataItem,
|
||||||
objectSlug,
|
objectNamePlural,
|
||||||
}: SettingsObjectNewFieldSelectorProps) => {
|
}: SettingsObjectNewFieldSelectorProps) => {
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
const { control, setValue } =
|
const { control, setValue } =
|
||||||
@ -128,7 +128,7 @@ export const SettingsObjectNewFieldSelector = ({
|
|||||||
.map(([key, config]) => (
|
.map(([key, config]) => (
|
||||||
<StyledCardContainer key={key}>
|
<StyledCardContainer key={key}>
|
||||||
<UndecoratedLink
|
<UndecoratedLink
|
||||||
to={`/settings/objects/${objectSlug}/new-field/configure?fieldType=${key}`}
|
to={`/settings/objects/${objectNamePlural}/new-field/configure?fieldType=${key}`}
|
||||||
fullWidth
|
fullWidth
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setValue('type', key as SettingsFieldType);
|
setValue('type', key as SettingsFieldType);
|
||||||
|
|||||||
@ -5,7 +5,6 @@ import { Link } from 'react-router-dom';
|
|||||||
import { IconChevronDown, IconChevronUp, useIcons } from 'twenty-ui';
|
import { IconChevronDown, IconChevronUp, useIcons } from 'twenty-ui';
|
||||||
|
|
||||||
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
||||||
import { getObjectSlug } from '@/object-metadata/utils/getObjectSlug';
|
|
||||||
import { useFindManyRecords } from '@/object-record/hooks/useFindManyRecords';
|
import { useFindManyRecords } from '@/object-record/hooks/useFindManyRecords';
|
||||||
import { ObjectFieldRow } from '@/settings/data-model/graph-overview/components/SettingsDataModelOverviewField';
|
import { ObjectFieldRow } from '@/settings/data-model/graph-overview/components/SettingsDataModelOverviewField';
|
||||||
import { SettingsDataModelObjectTypeTag } from '@/settings/data-model/objects/components/SettingsDataModelObjectTypeTag';
|
import { SettingsDataModelObjectTypeTag } from '@/settings/data-model/objects/components/SettingsDataModelObjectTypeTag';
|
||||||
@ -100,36 +99,38 @@ const StyledObjectLink = styled(Link)`
|
|||||||
`;
|
`;
|
||||||
|
|
||||||
export const SettingsDataModelOverviewObject = ({
|
export const SettingsDataModelOverviewObject = ({
|
||||||
data,
|
data: objectMetadataItem,
|
||||||
}: SettingsDataModelOverviewObjectProps) => {
|
}: SettingsDataModelOverviewObjectProps) => {
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
const { getIcon } = useIcons();
|
const { getIcon } = useIcons();
|
||||||
const [otherFieldsExpanded, setOtherFieldsExpanded] = useState(false);
|
const [otherFieldsExpanded, setOtherFieldsExpanded] = useState(false);
|
||||||
|
|
||||||
const { totalCount } = useFindManyRecords({
|
const { totalCount } = useFindManyRecords({
|
||||||
objectNameSingular: data.nameSingular,
|
objectNameSingular: objectMetadataItem.nameSingular,
|
||||||
});
|
});
|
||||||
|
|
||||||
const fields = data.fields.filter((x) => !x.isSystem);
|
const fields = objectMetadataItem.fields.filter((x) => !x.isSystem);
|
||||||
|
|
||||||
const countNonRelation = fields.filter(
|
const countNonRelation = fields.filter(
|
||||||
(x) => x.type !== FieldMetadataType.Relation,
|
(x) => x.type !== FieldMetadataType.Relation,
|
||||||
).length;
|
).length;
|
||||||
|
|
||||||
const Icon = getIcon(data.icon);
|
const Icon = getIcon(objectMetadataItem.icon);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<StyledNode>
|
<StyledNode>
|
||||||
<StyledHeader>
|
<StyledHeader>
|
||||||
<StyledObjectName onMouseEnter={() => {}} onMouseLeave={() => {}}>
|
<StyledObjectName onMouseEnter={() => {}} onMouseLeave={() => {}}>
|
||||||
<StyledObjectLink to={`/settings/objects/${getObjectSlug(data)}`}>
|
<StyledObjectLink
|
||||||
|
to={`/settings/objects/${objectMetadataItem.namePlural}`}
|
||||||
|
>
|
||||||
{Icon && <Icon size={theme.icon.size.md} />}
|
{Icon && <Icon size={theme.icon.size.md} />}
|
||||||
{capitalize(data.namePlural)}
|
{capitalize(objectMetadataItem.namePlural)}
|
||||||
</StyledObjectLink>
|
</StyledObjectLink>
|
||||||
<StyledObjectInstanceCount> · {totalCount}</StyledObjectInstanceCount>
|
<StyledObjectInstanceCount> · {totalCount}</StyledObjectInstanceCount>
|
||||||
</StyledObjectName>
|
</StyledObjectName>
|
||||||
<SettingsDataModelObjectTypeTag
|
<SettingsDataModelObjectTypeTag
|
||||||
objectTypeLabel={getObjectTypeLabel(data)}
|
objectTypeLabel={getObjectTypeLabel(objectMetadataItem)}
|
||||||
></SettingsDataModelObjectTypeTag>
|
></SettingsDataModelObjectTypeTag>
|
||||||
</StyledHeader>
|
</StyledHeader>
|
||||||
|
|
||||||
|
|||||||
@ -4,8 +4,6 @@ import { useGetRelationMetadata } from '@/object-metadata/hooks/useGetRelationMe
|
|||||||
import { useUpdateOneObjectMetadataItem } from '@/object-metadata/hooks/useUpdateOneObjectMetadataItem';
|
import { useUpdateOneObjectMetadataItem } from '@/object-metadata/hooks/useUpdateOneObjectMetadataItem';
|
||||||
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
|
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
|
||||||
import { FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem';
|
import { FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem';
|
||||||
import { getFieldSlug } from '@/object-metadata/utils/getFieldSlug';
|
|
||||||
import { getObjectSlug } from '@/object-metadata/utils/getObjectSlug';
|
|
||||||
import { isLabelIdentifierField } from '@/object-metadata/utils/isLabelIdentifierField';
|
import { isLabelIdentifierField } from '@/object-metadata/utils/isLabelIdentifierField';
|
||||||
import { useDeleteRecordFromCache } from '@/object-record/cache/hooks/useDeleteRecordFromCache';
|
import { useDeleteRecordFromCache } from '@/object-record/cache/hooks/useDeleteRecordFromCache';
|
||||||
import { usePrefetchedData } from '@/prefetch/hooks/usePrefetchedData';
|
import { usePrefetchedData } from '@/prefetch/hooks/usePrefetchedData';
|
||||||
@ -110,7 +108,7 @@ export const SettingsObjectFieldItemTableRow = ({
|
|||||||
!isLabelIdentifier &&
|
!isLabelIdentifier &&
|
||||||
LABEL_IDENTIFIER_FIELD_METADATA_TYPES.includes(fieldMetadataItem.type);
|
LABEL_IDENTIFIER_FIELD_METADATA_TYPES.includes(fieldMetadataItem.type);
|
||||||
|
|
||||||
const linkToNavigate = `./${getFieldSlug(fieldMetadataItem)}`;
|
const linkToNavigate = `./${fieldMetadataItem.name}`;
|
||||||
|
|
||||||
const {
|
const {
|
||||||
activateMetadataField,
|
activateMetadataField,
|
||||||
@ -246,7 +244,7 @@ export const SettingsObjectFieldItemTableRow = ({
|
|||||||
}
|
}
|
||||||
to={
|
to={
|
||||||
isRelatedObjectLinkable
|
isRelatedObjectLinkable
|
||||||
? `/settings/objects/${getObjectSlug(relationObjectMetadataItem)}`
|
? `/settings/objects/${relationObjectMetadataItem.namePlural}`
|
||||||
: undefined
|
: undefined
|
||||||
}
|
}
|
||||||
value={fieldType}
|
value={fieldType}
|
||||||
|
|||||||
@ -9,7 +9,6 @@ import { z, ZodError } from 'zod';
|
|||||||
import { useLastVisitedObjectMetadataItem } from '@/navigation/hooks/useLastVisitedObjectMetadataItem';
|
import { useLastVisitedObjectMetadataItem } from '@/navigation/hooks/useLastVisitedObjectMetadataItem';
|
||||||
import { useLastVisitedView } from '@/navigation/hooks/useLastVisitedView';
|
import { useLastVisitedView } from '@/navigation/hooks/useLastVisitedView';
|
||||||
import { useUpdateOneObjectMetadataItem } from '@/object-metadata/hooks/useUpdateOneObjectMetadataItem';
|
import { useUpdateOneObjectMetadataItem } from '@/object-metadata/hooks/useUpdateOneObjectMetadataItem';
|
||||||
import { getObjectSlug } from '@/object-metadata/utils/getObjectSlug';
|
|
||||||
import { RecordFieldValueSelectorContextProvider } from '@/object-record/record-store/contexts/RecordFieldValueSelectorContext';
|
import { RecordFieldValueSelectorContextProvider } from '@/object-record/record-store/contexts/RecordFieldValueSelectorContext';
|
||||||
import {
|
import {
|
||||||
IS_LABEL_SYNCED_WITH_NAME_LABEL,
|
IS_LABEL_SYNCED_WITH_NAME_LABEL,
|
||||||
@ -28,7 +27,7 @@ import styled from '@emotion/styled';
|
|||||||
import isEmpty from 'lodash.isempty';
|
import isEmpty from 'lodash.isempty';
|
||||||
import pick from 'lodash.pick';
|
import pick from 'lodash.pick';
|
||||||
import { useSetRecoilState } from 'recoil';
|
import { useSetRecoilState } from 'recoil';
|
||||||
import { updatedObjectSlugState } from '~/pages/settings/data-model/states/updatedObjectSlugState';
|
import { updatedObjectNamePluralState } from '~/pages/settings/data-model/states/updatedObjectNamePluralState';
|
||||||
import { computeMetadataNameFromLabel } from '~/pages/settings/data-model/utils/compute-metadata-name-from-label.utils';
|
import { computeMetadataNameFromLabel } from '~/pages/settings/data-model/utils/compute-metadata-name-from-label.utils';
|
||||||
|
|
||||||
const objectEditFormSchema = z
|
const objectEditFormSchema = z
|
||||||
@ -57,7 +56,9 @@ const StyledFormSection = styled(Section)`
|
|||||||
export const ObjectSettings = ({ objectMetadataItem }: ObjectSettingsProps) => {
|
export const ObjectSettings = ({ objectMetadataItem }: ObjectSettingsProps) => {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const { enqueueSnackBar } = useSnackBar();
|
const { enqueueSnackBar } = useSnackBar();
|
||||||
const setUpdatedObjectSlugState = useSetRecoilState(updatedObjectSlugState);
|
const setUpdatedObjectNamePlural = useSetRecoilState(
|
||||||
|
updatedObjectNamePluralState,
|
||||||
|
);
|
||||||
|
|
||||||
const { updateOneObjectMetadataItem } = useUpdateOneObjectMetadataItem();
|
const { updateOneObjectMetadataItem } = useUpdateOneObjectMetadataItem();
|
||||||
const { lastVisitedObjectMetadataItemId } =
|
const { lastVisitedObjectMetadataItemId } =
|
||||||
@ -131,12 +132,8 @@ export const ObjectSettings = ({ objectMetadataItem }: ObjectSettingsProps) => {
|
|||||||
const updatePayload = getUpdatePayload(formValues);
|
const updatePayload = getUpdatePayload(formValues);
|
||||||
const objectNamePluralForRedirection =
|
const objectNamePluralForRedirection =
|
||||||
updatePayload.namePlural ?? objectMetadataItem.namePlural;
|
updatePayload.namePlural ?? objectMetadataItem.namePlural;
|
||||||
const objectSlug = getObjectSlug({
|
|
||||||
...updatePayload,
|
|
||||||
namePlural: objectNamePluralForRedirection,
|
|
||||||
});
|
|
||||||
|
|
||||||
setUpdatedObjectSlugState(objectSlug);
|
setUpdatedObjectNamePlural(objectNamePluralForRedirection);
|
||||||
|
|
||||||
await updateOneObjectMetadataItem({
|
await updateOneObjectMetadataItem({
|
||||||
idToUpdate: objectMetadataItem.id,
|
idToUpdate: objectMetadataItem.id,
|
||||||
@ -154,7 +151,7 @@ export const ObjectSettings = ({ objectMetadataItem }: ObjectSettingsProps) => {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
navigate(`${settingsObjectsPagePath}/${objectSlug}`);
|
navigate(`${settingsObjectsPagePath}/${objectNamePluralForRedirection}`);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (error instanceof ZodError) {
|
if (error instanceof ZodError) {
|
||||||
enqueueSnackBar(error.issues[0].message, {
|
enqueueSnackBar(error.issues[0].message, {
|
||||||
|
|||||||
@ -10,10 +10,10 @@ export enum SettingsPath {
|
|||||||
Billing = 'billing',
|
Billing = 'billing',
|
||||||
Objects = 'objects',
|
Objects = 'objects',
|
||||||
ObjectOverview = 'objects/overview',
|
ObjectOverview = 'objects/overview',
|
||||||
ObjectDetail = 'objects/:objectSlug',
|
ObjectDetail = 'objects/:objectNamePlural',
|
||||||
ObjectNewFieldSelect = 'objects/:objectSlug/new-field/select',
|
ObjectNewFieldSelect = 'objects/:objectNamePlural/new-field/select',
|
||||||
ObjectNewFieldConfigure = 'objects/:objectSlug/new-field/configure',
|
ObjectNewFieldConfigure = 'objects/:objectNamePlural/new-field/configure',
|
||||||
ObjectFieldEdit = 'objects/:objectSlug/:fieldSlug',
|
ObjectFieldEdit = 'objects/:objectNamePlural/:fieldName',
|
||||||
NewObject = 'objects/new',
|
NewObject = 'objects/new',
|
||||||
NewServerlessFunction = 'functions/new',
|
NewServerlessFunction = 'functions/new',
|
||||||
ServerlessFunctionDetail = 'functions/:serverlessFunctionId',
|
ServerlessFunctionDetail = 'functions/:serverlessFunctionId',
|
||||||
|
|||||||
@ -3,7 +3,6 @@ import { useLocation, useNavigate } from 'react-router-dom';
|
|||||||
import { useRecoilValue, useSetRecoilState } from 'recoil';
|
import { useRecoilValue, useSetRecoilState } from 'recoil';
|
||||||
|
|
||||||
import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState';
|
import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState';
|
||||||
import { getObjectSlug } from '@/object-metadata/utils/getObjectSlug';
|
|
||||||
import { navigationMemorizedUrlState } from '@/ui/navigation/states/navigationMemorizedUrlState';
|
import { navigationMemorizedUrlState } from '@/ui/navigation/states/navigationMemorizedUrlState';
|
||||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
||||||
import { viewObjectMetadataIdComponentState } from '@/views/states/viewObjectMetadataIdComponentState';
|
import { viewObjectMetadataIdComponentState } from '@/views/states/viewObjectMetadataIdComponentState';
|
||||||
@ -36,9 +35,9 @@ export const useGetAvailableFieldsForKanban = () => {
|
|||||||
|
|
||||||
if (isDefined(objectMetadataItem?.namePlural)) {
|
if (isDefined(objectMetadataItem?.namePlural)) {
|
||||||
navigate(
|
navigate(
|
||||||
`/settings/objects/${getObjectSlug(
|
`/settings/objects/${
|
||||||
objectMetadataItem,
|
objectMetadataItem.namePlural
|
||||||
)}/new-field/configure?fieldType=${FieldMetadataType.Select}`,
|
}/new-field/configure?fieldType=${FieldMetadataType.Select}`,
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
navigate(`/settings/objects`);
|
navigate(`/settings/objects`);
|
||||||
|
|||||||
@ -5,7 +5,6 @@ import { H2Title, Section } from 'twenty-ui';
|
|||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
|
|
||||||
import { useCreateOneObjectMetadataItem } from '@/object-metadata/hooks/useCreateOneObjectMetadataItem';
|
import { useCreateOneObjectMetadataItem } from '@/object-metadata/hooks/useCreateOneObjectMetadataItem';
|
||||||
import { getObjectSlug } from '@/object-metadata/utils/getObjectSlug';
|
|
||||||
import { SaveAndCancelButtons } from '@/settings/components/SaveAndCancelButtons/SaveAndCancelButtons';
|
import { SaveAndCancelButtons } from '@/settings/components/SaveAndCancelButtons/SaveAndCancelButtons';
|
||||||
import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer';
|
import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer';
|
||||||
import {
|
import {
|
||||||
@ -50,9 +49,7 @@ export const SettingsNewObject = () => {
|
|||||||
|
|
||||||
navigate(
|
navigate(
|
||||||
response
|
response
|
||||||
? `${settingsObjectsPagePath}/${getObjectSlug(
|
? `${settingsObjectsPagePath}/${response.createOneObject.namePlural}`
|
||||||
response.createOneObject,
|
|
||||||
)}`
|
|
||||||
: settingsObjectsPagePath,
|
: settingsObjectsPagePath,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@ -32,7 +32,7 @@ import {
|
|||||||
} from 'twenty-ui';
|
} from 'twenty-ui';
|
||||||
import { FeatureFlagKey } from '~/generated/graphql';
|
import { FeatureFlagKey } from '~/generated/graphql';
|
||||||
import { SETTINGS_OBJECT_DETAIL_TABS } from '~/pages/settings/data-model/constants/SettingsObjectDetailTabs';
|
import { SETTINGS_OBJECT_DETAIL_TABS } from '~/pages/settings/data-model/constants/SettingsObjectDetailTabs';
|
||||||
import { updatedObjectSlugState } from '~/pages/settings/data-model/states/updatedObjectSlugState';
|
import { updatedObjectNamePluralState } from '~/pages/settings/data-model/states/updatedObjectNamePluralState';
|
||||||
|
|
||||||
const StyledContentContainer = styled.div`
|
const StyledContentContainer = styled.div`
|
||||||
flex: 1;
|
flex: 1;
|
||||||
@ -53,16 +53,16 @@ const StyledTitleContainer = styled.div`
|
|||||||
export const SettingsObjectDetailPage = () => {
|
export const SettingsObjectDetailPage = () => {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
|
||||||
const { objectSlug = '' } = useParams();
|
const { objectNamePlural = '' } = useParams();
|
||||||
const { findActiveObjectMetadataItemBySlug } =
|
const { findActiveObjectMetadataItemByNamePlural } =
|
||||||
useFilteredObjectMetadataItems();
|
useFilteredObjectMetadataItems();
|
||||||
|
|
||||||
const [updatedObjectSlug, setUpdatedObjectSlug] = useRecoilState(
|
const [updatedObjectNamePlural, setUpdatedObjectNamePlural] = useRecoilState(
|
||||||
updatedObjectSlugState,
|
updatedObjectNamePluralState,
|
||||||
);
|
);
|
||||||
const objectMetadataItem =
|
const objectMetadataItem =
|
||||||
findActiveObjectMetadataItemBySlug(objectSlug) ??
|
findActiveObjectMetadataItemByNamePlural(objectNamePlural) ??
|
||||||
findActiveObjectMetadataItemBySlug(updatedObjectSlug);
|
findActiveObjectMetadataItemByNamePlural(updatedObjectNamePlural);
|
||||||
|
|
||||||
const { activeTabId } = useTabList(
|
const { activeTabId } = useTabList(
|
||||||
SETTINGS_OBJECT_DETAIL_TABS.COMPONENT_INSTANCE_ID,
|
SETTINGS_OBJECT_DETAIL_TABS.COMPONENT_INSTANCE_ID,
|
||||||
@ -74,14 +74,15 @@ export const SettingsObjectDetailPage = () => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (objectSlug === updatedObjectSlug) setUpdatedObjectSlug('');
|
if (objectNamePlural === updatedObjectNamePlural)
|
||||||
|
setUpdatedObjectNamePlural('');
|
||||||
if (!isDefined(objectMetadataItem)) navigate(AppPath.NotFound);
|
if (!isDefined(objectMetadataItem)) navigate(AppPath.NotFound);
|
||||||
}, [
|
}, [
|
||||||
objectMetadataItem,
|
objectMetadataItem,
|
||||||
navigate,
|
navigate,
|
||||||
objectSlug,
|
objectNamePlural,
|
||||||
updatedObjectSlug,
|
updatedObjectNamePlural,
|
||||||
setUpdatedObjectSlug,
|
setUpdatedObjectNamePlural,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
if (!isDefined(objectMetadataItem)) return <></>;
|
if (!isDefined(objectMetadataItem)) return <></>;
|
||||||
|
|||||||
@ -18,7 +18,6 @@ import { useFilteredObjectMetadataItems } from '@/object-metadata/hooks/useFilte
|
|||||||
import { useGetRelationMetadata } from '@/object-metadata/hooks/useGetRelationMetadata';
|
import { useGetRelationMetadata } from '@/object-metadata/hooks/useGetRelationMetadata';
|
||||||
import { useUpdateOneFieldMetadataItem } from '@/object-metadata/hooks/useUpdateOneFieldMetadataItem';
|
import { useUpdateOneFieldMetadataItem } from '@/object-metadata/hooks/useUpdateOneFieldMetadataItem';
|
||||||
import { formatFieldMetadataItemInput } from '@/object-metadata/utils/formatFieldMetadataItemInput';
|
import { formatFieldMetadataItemInput } from '@/object-metadata/utils/formatFieldMetadataItemInput';
|
||||||
import { getFieldSlug } from '@/object-metadata/utils/getFieldSlug';
|
|
||||||
import { isLabelIdentifierField } from '@/object-metadata/utils/isLabelIdentifierField';
|
import { isLabelIdentifierField } from '@/object-metadata/utils/isLabelIdentifierField';
|
||||||
import { RecordFieldValueSelectorContextProvider } from '@/object-record/record-store/contexts/RecordFieldValueSelectorContext';
|
import { RecordFieldValueSelectorContextProvider } from '@/object-record/record-store/contexts/RecordFieldValueSelectorContext';
|
||||||
import { SaveAndCancelButtons } from '@/settings/components/SaveAndCancelButtons/SaveAndCancelButtons';
|
import { SaveAndCancelButtons } from '@/settings/components/SaveAndCancelButtons/SaveAndCancelButtons';
|
||||||
@ -48,16 +47,18 @@ export const SettingsObjectFieldEdit = () => {
|
|||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const { enqueueSnackBar } = useSnackBar();
|
const { enqueueSnackBar } = useSnackBar();
|
||||||
|
|
||||||
const { objectSlug = '', fieldSlug = '' } = useParams();
|
const { objectNamePlural = '', fieldName = '' } = useParams();
|
||||||
const { findObjectMetadataItemBySlug } = useFilteredObjectMetadataItems();
|
const { findObjectMetadataItemByNamePlural } =
|
||||||
|
useFilteredObjectMetadataItems();
|
||||||
|
|
||||||
const objectMetadataItem = findObjectMetadataItemBySlug(objectSlug);
|
const objectMetadataItem =
|
||||||
|
findObjectMetadataItemByNamePlural(objectNamePlural);
|
||||||
|
|
||||||
const { deactivateMetadataField, activateMetadataField } =
|
const { deactivateMetadataField, activateMetadataField } =
|
||||||
useFieldMetadataItem();
|
useFieldMetadataItem();
|
||||||
|
|
||||||
const fieldMetadataItem = objectMetadataItem?.fields.find(
|
const fieldMetadataItem = objectMetadataItem?.fields.find(
|
||||||
(fieldMetadataItem) => getFieldSlug(fieldMetadataItem) === fieldSlug,
|
(fieldMetadataItem) => fieldMetadataItem.name === fieldName,
|
||||||
);
|
);
|
||||||
|
|
||||||
const getRelationMetadata = useGetRelationMetadata();
|
const getRelationMetadata = useGetRelationMetadata();
|
||||||
@ -126,7 +127,7 @@ export const SettingsObjectFieldEdit = () => {
|
|||||||
Object.keys(otherDirtyFields),
|
Object.keys(otherDirtyFields),
|
||||||
);
|
);
|
||||||
|
|
||||||
navigate(`/settings/objects/${objectSlug}`);
|
navigate(`/settings/objects/${objectNamePlural}`);
|
||||||
|
|
||||||
await updateOneFieldMetadataItem({
|
await updateOneFieldMetadataItem({
|
||||||
objectMetadataId: objectMetadataItem.id,
|
objectMetadataId: objectMetadataItem.id,
|
||||||
@ -143,12 +144,12 @@ export const SettingsObjectFieldEdit = () => {
|
|||||||
|
|
||||||
const handleDeactivate = async () => {
|
const handleDeactivate = async () => {
|
||||||
await deactivateMetadataField(fieldMetadataItem.id, objectMetadataItem.id);
|
await deactivateMetadataField(fieldMetadataItem.id, objectMetadataItem.id);
|
||||||
navigate(`/settings/objects/${objectSlug}`);
|
navigate(`/settings/objects/${objectNamePlural}`);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleActivate = async () => {
|
const handleActivate = async () => {
|
||||||
await activateMetadataField(fieldMetadataItem.id, objectMetadataItem.id);
|
await activateMetadataField(fieldMetadataItem.id, objectMetadataItem.id);
|
||||||
navigate(`/settings/objects/${objectSlug}`);
|
navigate(`/settings/objects/${objectNamePlural}`);
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -168,7 +169,7 @@ export const SettingsObjectFieldEdit = () => {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
children: objectMetadataItem.labelPlural,
|
children: objectMetadataItem.labelPlural,
|
||||||
href: `/settings/objects/${objectSlug}`,
|
href: `/settings/objects/${objectNamePlural}`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
children: fieldMetadataItem.label,
|
children: fieldMetadataItem.label,
|
||||||
@ -178,7 +179,7 @@ export const SettingsObjectFieldEdit = () => {
|
|||||||
<SaveAndCancelButtons
|
<SaveAndCancelButtons
|
||||||
isSaveDisabled={!canSave}
|
isSaveDisabled={!canSave}
|
||||||
isCancelDisabled={isSubmitting}
|
isCancelDisabled={isSubmitting}
|
||||||
onCancel={() => navigate(`/settings/objects/${objectSlug}`)}
|
onCancel={() => navigate(`/settings/objects/${objectNamePlural}`)}
|
||||||
onSave={formConfig.handleSubmit(handleSave)}
|
onSave={formConfig.handleSubmit(handleSave)}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
|
|||||||
@ -41,17 +41,17 @@ const DEFAULT_ICON_FOR_NEW_FIELD = 'IconUsers';
|
|||||||
|
|
||||||
export const SettingsObjectNewFieldConfigure = () => {
|
export const SettingsObjectNewFieldConfigure = () => {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const { objectSlug = '' } = useParams();
|
const { objectNamePlural = '' } = useParams();
|
||||||
const [searchParams] = useSearchParams();
|
const [searchParams] = useSearchParams();
|
||||||
const fieldType =
|
const fieldType =
|
||||||
(searchParams.get('fieldType') as SettingsFieldType) ||
|
(searchParams.get('fieldType') as SettingsFieldType) ||
|
||||||
FieldMetadataType.Text;
|
FieldMetadataType.Text;
|
||||||
const { enqueueSnackBar } = useSnackBar();
|
const { enqueueSnackBar } = useSnackBar();
|
||||||
|
|
||||||
const { findActiveObjectMetadataItemBySlug } =
|
const { findActiveObjectMetadataItemByNamePlural } =
|
||||||
useFilteredObjectMetadataItems();
|
useFilteredObjectMetadataItems();
|
||||||
const activeObjectMetadataItem =
|
const activeObjectMetadataItem =
|
||||||
findActiveObjectMetadataItemBySlug(objectSlug);
|
findActiveObjectMetadataItemByNamePlural(objectNamePlural);
|
||||||
const { createMetadataField } = useFieldMetadataItem();
|
const { createMetadataField } = useFieldMetadataItem();
|
||||||
const apolloClient = useApolloClient();
|
const apolloClient = useApolloClient();
|
||||||
|
|
||||||
@ -163,7 +163,7 @@ export const SettingsObjectNewFieldConfigure = () => {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
navigate(`/settings/objects/${objectSlug}`);
|
navigate(`/settings/objects/${objectNamePlural}`);
|
||||||
|
|
||||||
// TODO: fix optimistic update logic
|
// TODO: fix optimistic update logic
|
||||||
// Forcing a refetch for now but it's not ideal
|
// Forcing a refetch for now but it's not ideal
|
||||||
@ -190,7 +190,7 @@ export const SettingsObjectNewFieldConfigure = () => {
|
|||||||
{ children: 'Objects', href: '/settings/objects' },
|
{ children: 'Objects', href: '/settings/objects' },
|
||||||
{
|
{
|
||||||
children: activeObjectMetadataItem.labelPlural,
|
children: activeObjectMetadataItem.labelPlural,
|
||||||
href: `/settings/objects/${objectSlug}`,
|
href: `/settings/objects/${objectNamePlural}`,
|
||||||
},
|
},
|
||||||
|
|
||||||
{ children: <SettingsDataModelNewFieldBreadcrumbDropDown /> },
|
{ children: <SettingsDataModelNewFieldBreadcrumbDropDown /> },
|
||||||
@ -201,7 +201,7 @@ export const SettingsObjectNewFieldConfigure = () => {
|
|||||||
isCancelDisabled={isSubmitting}
|
isCancelDisabled={isSubmitting}
|
||||||
onCancel={() =>
|
onCancel={() =>
|
||||||
navigate(
|
navigate(
|
||||||
`/settings/objects/${objectSlug}/new-field/select?fieldType=${fieldType}`,
|
`/settings/objects/${objectNamePlural}/new-field/select?fieldType=${fieldType}`,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
onSave={formConfig.handleSubmit(handleSave)}
|
onSave={formConfig.handleSubmit(handleSave)}
|
||||||
|
|||||||
@ -30,11 +30,11 @@ export type SettingsDataModelFieldTypeFormValues = z.infer<
|
|||||||
|
|
||||||
export const SettingsObjectNewFieldSelect = () => {
|
export const SettingsObjectNewFieldSelect = () => {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const { objectSlug = '' } = useParams();
|
const { objectNamePlural = '' } = useParams();
|
||||||
const { findActiveObjectMetadataItemBySlug } =
|
const { findActiveObjectMetadataItemByNamePlural } =
|
||||||
useFilteredObjectMetadataItems();
|
useFilteredObjectMetadataItems();
|
||||||
const activeObjectMetadataItem =
|
const activeObjectMetadataItem =
|
||||||
findActiveObjectMetadataItemBySlug(objectSlug);
|
findActiveObjectMetadataItemByNamePlural(objectNamePlural);
|
||||||
const formMethods = useForm({
|
const formMethods = useForm({
|
||||||
resolver: zodResolver(settingsDataModelFieldTypeFormSchema),
|
resolver: zodResolver(settingsDataModelFieldTypeFormSchema),
|
||||||
defaultValues: {
|
defaultValues: {
|
||||||
@ -69,14 +69,14 @@ export const SettingsObjectNewFieldSelect = () => {
|
|||||||
{ children: 'Objects', href: '/settings/objects' },
|
{ children: 'Objects', href: '/settings/objects' },
|
||||||
{
|
{
|
||||||
children: activeObjectMetadataItem.labelPlural,
|
children: activeObjectMetadataItem.labelPlural,
|
||||||
href: `/settings/objects/${objectSlug}`,
|
href: `/settings/objects/${objectNamePlural}`,
|
||||||
},
|
},
|
||||||
{ children: <SettingsDataModelNewFieldBreadcrumbDropDown /> },
|
{ children: <SettingsDataModelNewFieldBreadcrumbDropDown /> },
|
||||||
]}
|
]}
|
||||||
>
|
>
|
||||||
<SettingsPageContainer>
|
<SettingsPageContainer>
|
||||||
<SettingsObjectNewFieldSelector
|
<SettingsObjectNewFieldSelector
|
||||||
objectSlug={objectSlug}
|
objectNamePlural={objectNamePlural}
|
||||||
excludedFieldTypes={excludedFieldTypes}
|
excludedFieldTypes={excludedFieldTypes}
|
||||||
/>
|
/>
|
||||||
</SettingsPageContainer>
|
</SettingsPageContainer>
|
||||||
|
|||||||
@ -1,7 +1,6 @@
|
|||||||
import { useDeleteOneObjectMetadataItem } from '@/object-metadata/hooks/useDeleteOneObjectMetadataItem';
|
import { useDeleteOneObjectMetadataItem } from '@/object-metadata/hooks/useDeleteOneObjectMetadataItem';
|
||||||
import { useFilteredObjectMetadataItems } from '@/object-metadata/hooks/useFilteredObjectMetadataItems';
|
import { useFilteredObjectMetadataItems } from '@/object-metadata/hooks/useFilteredObjectMetadataItems';
|
||||||
import { useUpdateOneObjectMetadataItem } from '@/object-metadata/hooks/useUpdateOneObjectMetadataItem';
|
import { useUpdateOneObjectMetadataItem } from '@/object-metadata/hooks/useUpdateOneObjectMetadataItem';
|
||||||
import { getObjectSlug } from '@/object-metadata/utils/getObjectSlug';
|
|
||||||
import { useCombinedGetTotalCount } from '@/object-record/multiple-objects/hooks/useCombinedGetTotalCount';
|
import { useCombinedGetTotalCount } from '@/object-record/multiple-objects/hooks/useCombinedGetTotalCount';
|
||||||
import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer';
|
import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer';
|
||||||
import {
|
import {
|
||||||
@ -197,9 +196,9 @@ export const SettingsObjects = () => {
|
|||||||
stroke={theme.icon.stroke.sm}
|
stroke={theme.icon.stroke.sm}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
link={`/settings/objects/${getObjectSlug(
|
link={`/settings/objects/${
|
||||||
objectSettingsItem.objectMetadataItem,
|
objectSettingsItem.objectMetadataItem.namePlural
|
||||||
)}`}
|
}`}
|
||||||
/>
|
/>
|
||||||
),
|
),
|
||||||
)}
|
)}
|
||||||
|
|||||||
@ -16,8 +16,8 @@ const meta: Meta<PageDecoratorArgs> = {
|
|||||||
component: SettingsObjectDetailPage,
|
component: SettingsObjectDetailPage,
|
||||||
decorators: [PageDecorator],
|
decorators: [PageDecorator],
|
||||||
args: {
|
args: {
|
||||||
routePath: '/settings/objects/:objectSlug',
|
routePath: '/settings/objects/:objectNamePlural',
|
||||||
routeParams: { ':objectSlug': 'companies' },
|
routeParams: { ':objectNamePlural': 'companies' },
|
||||||
},
|
},
|
||||||
parameters: {
|
parameters: {
|
||||||
msw: graphqlMocks,
|
msw: graphqlMocks,
|
||||||
@ -36,7 +36,7 @@ export const StandardObject: Story = {
|
|||||||
|
|
||||||
export const CustomObject: Story = {
|
export const CustomObject: Story = {
|
||||||
args: {
|
args: {
|
||||||
routeParams: { ':objectSlug': 'my-customs' },
|
routeParams: { ':objectNamePlural': 'myCustoms' },
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -13,8 +13,8 @@ const meta: Meta<PageDecoratorArgs> = {
|
|||||||
component: SettingsObjectFieldEdit,
|
component: SettingsObjectFieldEdit,
|
||||||
decorators: [PageDecorator],
|
decorators: [PageDecorator],
|
||||||
args: {
|
args: {
|
||||||
routePath: '/settings/objects/:objectSlug/:fieldSlug',
|
routePath: '/settings/objects/:objectNamePlural/:fieldName',
|
||||||
routeParams: { ':objectSlug': 'companies', ':fieldSlug': 'name' },
|
routeParams: { ':objectNamePlural': 'companies', ':fieldName': 'name' },
|
||||||
},
|
},
|
||||||
parameters: {
|
parameters: {
|
||||||
msw: graphqlMocks,
|
msw: graphqlMocks,
|
||||||
@ -30,8 +30,8 @@ export const StandardField: Story = {};
|
|||||||
export const CustomField: Story = {
|
export const CustomField: Story = {
|
||||||
args: {
|
args: {
|
||||||
routeParams: {
|
routeParams: {
|
||||||
':objectSlug': 'companies',
|
':objectNamePlural': 'companies',
|
||||||
':fieldSlug': 'employees',
|
':fieldName': 'employees',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@ -14,8 +14,8 @@ const meta: Meta<PageDecoratorArgs> = {
|
|||||||
component: SettingsObjectNewFieldConfigure,
|
component: SettingsObjectNewFieldConfigure,
|
||||||
decorators: [PageDecorator],
|
decorators: [PageDecorator],
|
||||||
args: {
|
args: {
|
||||||
routePath: '/settings/objects/:objectSlug/new-field/configure',
|
routePath: '/settings/objects/:objectNamePlural/new-field/configure',
|
||||||
routeParams: { ':objectSlug': 'companies' },
|
routeParams: { ':objectNamePlural': 'companies' },
|
||||||
},
|
},
|
||||||
parameters: {
|
parameters: {
|
||||||
msw: graphqlMocks,
|
msw: graphqlMocks,
|
||||||
|
|||||||
@ -14,8 +14,8 @@ const meta: Meta<PageDecoratorArgs> = {
|
|||||||
component: SettingsObjectNewFieldSelect,
|
component: SettingsObjectNewFieldSelect,
|
||||||
decorators: [PageDecorator],
|
decorators: [PageDecorator],
|
||||||
args: {
|
args: {
|
||||||
routePath: '/settings/objects/:objectSlug/new-field/select',
|
routePath: '/settings/objects/:objectNamePlural/new-field/select',
|
||||||
routeParams: { ':objectSlug': 'companies' },
|
routeParams: { ':objectNamePlural': 'companies' },
|
||||||
},
|
},
|
||||||
parameters: {
|
parameters: {
|
||||||
msw: graphqlMocks,
|
msw: graphqlMocks,
|
||||||
|
|||||||
@ -0,0 +1,6 @@
|
|||||||
|
import { createState } from '@ui/utilities/state/utils/createState';
|
||||||
|
|
||||||
|
export const updatedObjectNamePluralState = createState<string>({
|
||||||
|
key: 'updatedObjectNamePluralState',
|
||||||
|
defaultValue: '',
|
||||||
|
});
|
||||||
@ -1,6 +0,0 @@
|
|||||||
import { createState } from '@ui/utilities/state/utils/createState';
|
|
||||||
|
|
||||||
export const updatedObjectSlugState = createState<string>({
|
|
||||||
key: 'updatedObjectSlugState',
|
|
||||||
defaultValue: '',
|
|
||||||
});
|
|
||||||
Reference in New Issue
Block a user