6b48f197d4
## Summary - **Removes the entire `modules/favorites/` directory** (~66 files, ~5000 lines deleted) — components, hooks, states, types, utils, tests, and the favorite-folder-picker sub-module - **Eliminates the dual-write pattern** where creating a favorite also created a NavigationMenuItem — all consumers now use `useCreateNavigationMenuItem` directly - **Removes `IS_NAVIGATION_MENU_ITEM_EDITING_ENABLED` feature flag checks** from ~12 files, always taking the NavigationMenuItem code path - **Cleans up backend dual-writes** in `object-metadata.service.ts` and `twenty-standard-application.service.ts` that were creating Favorite records alongside NavigationMenuItems - **Updates prefetch system** to only load NavigationMenuItems (removes favorites prefetch effects and states) - **Cleans up test infrastructure** — updates Storybook decorators, mock data, and graphql mocks to remove favorites references ### What was intentionally kept - **Backend entity definitions** (`FavoriteWorkspaceEntity`, `FavoriteFolderWorkspaceEntity`) — these define the database schema and need a proper database migration to remove - **Cascade deletion listeners** — still needed to clean up existing Favorite data in workspaces that haven't been fully migrated - **v1.18 migration commands** — needed for workspaces upgrading from older versions --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
91 lines
2.8 KiB
TypeScript
91 lines
2.8 KiB
TypeScript
import { isDefined } from 'twenty-shared/utils';
|
|
import { useMutation } from '@apollo/client/react';
|
|
import { CreateNavigationMenuItemDocument } from '~/generated-metadata/graphql';
|
|
|
|
import { useNavigationMenuItemsData } from '@/navigation-menu-item/hooks/useNavigationMenuItemsData';
|
|
import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState';
|
|
import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue';
|
|
import { type ObjectRecord } from '@/object-record/types/ObjectRecord';
|
|
|
|
export const useCreateNavigationMenuItem = () => {
|
|
const { navigationMenuItems, currentWorkspaceMemberId } =
|
|
useNavigationMenuItemsData();
|
|
const objectMetadataItems = useAtomStateValue(objectMetadataItemsState);
|
|
|
|
const [createNavigationMenuItemMutation] = useMutation(
|
|
CreateNavigationMenuItemDocument,
|
|
{
|
|
refetchQueries: ['FindManyNavigationMenuItems'],
|
|
},
|
|
);
|
|
|
|
const createNavigationMenuItem = async (
|
|
targetRecord: ObjectRecord,
|
|
targetObjectNameSingular: string,
|
|
folderId?: string,
|
|
) => {
|
|
const isView = targetObjectNameSingular === 'view';
|
|
|
|
if (isView) {
|
|
const relevantItems = folderId
|
|
? navigationMenuItems.filter((item) => item.folderId === folderId)
|
|
: navigationMenuItems.filter(
|
|
(item) =>
|
|
!isDefined(item.folderId) && isDefined(item.userWorkspaceId),
|
|
);
|
|
|
|
const maxPosition = Math.max(
|
|
...relevantItems.map((item) => item.position),
|
|
0,
|
|
);
|
|
|
|
await createNavigationMenuItemMutation({
|
|
variables: {
|
|
input: {
|
|
viewId: targetRecord.id,
|
|
userWorkspaceId: currentWorkspaceMemberId,
|
|
folderId,
|
|
position: maxPosition + 1,
|
|
},
|
|
},
|
|
});
|
|
} else {
|
|
const objectMetadataItem = objectMetadataItems.find(
|
|
(item) => item.nameSingular === targetObjectNameSingular,
|
|
);
|
|
|
|
if (!isDefined(objectMetadataItem)) {
|
|
throw new Error(
|
|
`Object metadata item not found for nameSingular: ${targetObjectNameSingular}`,
|
|
);
|
|
}
|
|
|
|
const relevantItems = folderId
|
|
? navigationMenuItems.filter((item) => item.folderId === folderId)
|
|
: navigationMenuItems.filter(
|
|
(item) =>
|
|
!isDefined(item.folderId) && isDefined(item.userWorkspaceId),
|
|
);
|
|
|
|
const maxPosition = Math.max(
|
|
...relevantItems.map((item) => item.position),
|
|
0,
|
|
);
|
|
|
|
await createNavigationMenuItemMutation({
|
|
variables: {
|
|
input: {
|
|
targetRecordId: targetRecord.id,
|
|
targetObjectMetadataId: objectMetadataItem.id,
|
|
userWorkspaceId: currentWorkspaceMemberId,
|
|
folderId,
|
|
position: maxPosition + 1,
|
|
},
|
|
},
|
|
});
|
|
}
|
|
};
|
|
|
|
return { createNavigationMenuItem };
|
|
};
|