Files
twenty/packages/twenty-front/src/modules/navigation-menu-item/utils/getNavigationMenuItemLabel.ts
T
Charles Bochet 1bb642d7cd refactor: remove ProcessedNavigationMenuItem, derive display fields at point of use (#18687)
## Summary

- Removes `ProcessedNavigationMenuItem` type and the
`sortNavigationMenuItems` enrichment pipeline that pre-computed display
fields (label, link, icon, avatarUrl, etc.) for every navigation menu
item upfront
- Replaces with `filterAndSortNavigationMenuItems` (pure filter+sort
returning raw `NavigationMenuItem[]`) and small utility functions
(`getNavigationMenuItemLabel`, `getNavigationMenuItemComputedLink`,
`getNavigationMenuItemObjectNameSingular`) that components call on
demand
- Eliminates the redundant `itemType` field (was identical to the raw
`type` field) across ~30 consumer files
- Each type-specific renderer
(`NavigationDrawerItemForObjectMetadataItem`, `NavigationMenuItemIcon`,
link/folder components) now derives only the 1-2 display fields it
actually needs from the raw item + globally available Jotai atoms

Net result: -1199 / +1177 lines, 7 files deleted, 4 new utility files.
2026-03-17 00:33:06 +01:00

50 lines
1.7 KiB
TypeScript

import { type ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
import { type View } from '@/views/types/View';
import { ViewKey } from '@/views/types/ViewKey';
import { NavigationMenuItemType } from 'twenty-shared/types';
import { isDefined } from 'twenty-shared/utils';
import { type NavigationMenuItem } from '~/generated-metadata/graphql';
export const getNavigationMenuItemLabel = (
item: NavigationMenuItem,
objectMetadataItems: Pick<
ObjectMetadataItem,
'id' | 'labelPlural' | 'nameSingular'
>[],
views: Pick<View, 'id' | 'name' | 'objectMetadataId' | 'key'>[],
): string => {
switch (item.type) {
case NavigationMenuItemType.OBJECT: {
const objectMetadataItem = objectMetadataItems.find(
(meta) => meta.id === item.targetObjectMetadataId,
);
return objectMetadataItem?.labelPlural ?? '';
}
case NavigationMenuItemType.VIEW: {
const view = views.find((view) => view.id === item.viewId);
if (!isDefined(view)) {
return '';
}
if (view.key === ViewKey.INDEX) {
const objectMetadataItem = objectMetadataItems.find(
(meta) => meta.id === view.objectMetadataId,
);
return objectMetadataItem?.labelPlural ?? view.name;
}
return view.name;
}
case NavigationMenuItemType.LINK: {
const linkUrl = (item.link ?? '').trim();
return (item.name ?? linkUrl) || 'Link';
}
case NavigationMenuItemType.RECORD: {
return item.targetRecordIdentifier?.labelIdentifier ?? '';
}
case NavigationMenuItemType.FOLDER: {
return item.name ?? 'Folder';
}
default:
return item.name ?? '';
}
};