- Add a `pageLayoutId` foreign key to `CommandMenuItem`, allowing command menu items to be scoped to a specific page layout instead of being globally available - Filter command menu items by the current page layout on the frontend. Items with a `pageLayoutId` only appear when viewing that layout, while items without one remain globally visible - Create an effect to track the current page layout ID - Include a seed example: a "Show Notification" command pinned to the Star history standalone page layout --------- Co-authored-by: Charles Bochet <charles@twenty.com>
65 lines
2.5 KiB
TypeScript
65 lines
2.5 KiB
TypeScript
import {
|
|
CommandMenuContext,
|
|
type CommandMenuContextType,
|
|
} from '@/command-menu-item/contexts/CommandMenuContext';
|
|
import { commandMenuItemsSelector } from '@/command-menu-item/states/commandMenuItemsSelector';
|
|
import { doesCommandMenuItemMatchObjectMetadataId } from '@/command-menu-item/utils/doesCommandMenuItemMatchObjectMetadataId';
|
|
import { doesCommandMenuItemMatchPageLayoutId } from '@/command-menu-item/utils/doesCommandMenuItemMatchPageLayoutId';
|
|
import { doesCommandMenuItemMatchPageType } from '@/command-menu-item/utils/doesCommandMenuItemMatchPageType';
|
|
import { currentPageLayoutIdState } from '@/page-layout/states/currentPageLayoutIdState';
|
|
import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue';
|
|
import { useMemo } from 'react';
|
|
import { type CommandMenuContextApi } from 'twenty-shared/types';
|
|
import { evaluateConditionalAvailabilityExpression } from 'twenty-shared/utils';
|
|
|
|
type CommandMenuContextProviderContentProps = {
|
|
displayType: CommandMenuContextType['displayType'];
|
|
containerType: CommandMenuContextType['containerType'];
|
|
children: React.ReactNode;
|
|
commandMenuContextApi: CommandMenuContextApi;
|
|
};
|
|
|
|
export const CommandMenuContextProviderContent = ({
|
|
displayType,
|
|
containerType,
|
|
children,
|
|
commandMenuContextApi,
|
|
}: CommandMenuContextProviderContentProps) => {
|
|
const commandMenuItems = useAtomStateValue(commandMenuItemsSelector);
|
|
const currentPageLayoutId = useAtomStateValue(currentPageLayoutIdState);
|
|
|
|
const filteredCommandMenuItems = useMemo(() => {
|
|
const currentObjectMetadataItemId =
|
|
commandMenuContextApi.objectMetadataItem.id;
|
|
|
|
return commandMenuItems
|
|
.filter(
|
|
doesCommandMenuItemMatchObjectMetadataId(currentObjectMetadataItemId),
|
|
)
|
|
.filter(doesCommandMenuItemMatchPageType(commandMenuContextApi.pageType))
|
|
.filter(doesCommandMenuItemMatchPageLayoutId(currentPageLayoutId))
|
|
.filter((item) =>
|
|
evaluateConditionalAvailabilityExpression(
|
|
item.conditionalAvailabilityExpression,
|
|
commandMenuContextApi,
|
|
),
|
|
)
|
|
.sort(
|
|
(firstItem, secondItem) => firstItem.position - secondItem.position,
|
|
);
|
|
}, [commandMenuItems, commandMenuContextApi, currentPageLayoutId]);
|
|
|
|
return (
|
|
<CommandMenuContext.Provider
|
|
value={{
|
|
displayType,
|
|
containerType,
|
|
commandMenuItems: filteredCommandMenuItems,
|
|
commandMenuContextApi,
|
|
}}
|
|
>
|
|
{children}
|
|
</CommandMenuContext.Provider>
|
|
);
|
|
};
|