- 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>
106 lines
4.2 KiB
TypeScript
106 lines
4.2 KiB
TypeScript
import { isDefined } from 'twenty-shared/utils';
|
|
|
|
import { type FlatCommandMenuItem } from 'src/engine/metadata-modules/flat-command-menu-item/types/flat-command-menu-item.type';
|
|
import {
|
|
FlatEntityMapsException,
|
|
FlatEntityMapsExceptionCode,
|
|
} from 'src/engine/metadata-modules/flat-entity/exceptions/flat-entity-maps.exception';
|
|
import { type FromEntityToFlatEntityArgs } from 'src/engine/workspace-cache/types/from-entity-to-flat-entity-args.type';
|
|
|
|
export const fromCommandMenuItemEntityToFlatCommandMenuItem = ({
|
|
entity: commandMenuItemEntity,
|
|
applicationIdToUniversalIdentifierMap,
|
|
objectMetadataIdToUniversalIdentifierMap,
|
|
frontComponentIdToUniversalIdentifierMap,
|
|
pageLayoutIdToUniversalIdentifierMap,
|
|
}: FromEntityToFlatEntityArgs<'commandMenuItem'>): FlatCommandMenuItem => {
|
|
const applicationUniversalIdentifier =
|
|
applicationIdToUniversalIdentifierMap.get(
|
|
commandMenuItemEntity.applicationId,
|
|
);
|
|
|
|
if (!isDefined(applicationUniversalIdentifier)) {
|
|
throw new FlatEntityMapsException(
|
|
`Application with id ${commandMenuItemEntity.applicationId} not found for commandMenuItem ${commandMenuItemEntity.id}`,
|
|
FlatEntityMapsExceptionCode.ENTITY_NOT_FOUND,
|
|
);
|
|
}
|
|
|
|
let availabilityObjectMetadataUniversalIdentifier: string | null = null;
|
|
|
|
if (isDefined(commandMenuItemEntity.availabilityObjectMetadataId)) {
|
|
availabilityObjectMetadataUniversalIdentifier =
|
|
objectMetadataIdToUniversalIdentifierMap.get(
|
|
commandMenuItemEntity.availabilityObjectMetadataId,
|
|
) ?? null;
|
|
|
|
if (!isDefined(availabilityObjectMetadataUniversalIdentifier)) {
|
|
throw new FlatEntityMapsException(
|
|
`ObjectMetadata with id ${commandMenuItemEntity.availabilityObjectMetadataId} not found for commandMenuItem ${commandMenuItemEntity.id}`,
|
|
FlatEntityMapsExceptionCode.ENTITY_NOT_FOUND,
|
|
);
|
|
}
|
|
}
|
|
|
|
let frontComponentUniversalIdentifier: string | null = null;
|
|
|
|
if (isDefined(commandMenuItemEntity.frontComponentId)) {
|
|
frontComponentUniversalIdentifier =
|
|
frontComponentIdToUniversalIdentifierMap.get(
|
|
commandMenuItemEntity.frontComponentId,
|
|
) ?? null;
|
|
|
|
if (!isDefined(frontComponentUniversalIdentifier)) {
|
|
throw new FlatEntityMapsException(
|
|
`FrontComponent with id ${commandMenuItemEntity.frontComponentId} not found for commandMenuItem ${commandMenuItemEntity.id}`,
|
|
FlatEntityMapsExceptionCode.ENTITY_NOT_FOUND,
|
|
);
|
|
}
|
|
}
|
|
|
|
let pageLayoutUniversalIdentifier: string | null = null;
|
|
|
|
if (isDefined(commandMenuItemEntity.pageLayoutId)) {
|
|
pageLayoutUniversalIdentifier =
|
|
pageLayoutIdToUniversalIdentifierMap.get(
|
|
commandMenuItemEntity.pageLayoutId,
|
|
) ?? null;
|
|
|
|
if (!isDefined(pageLayoutUniversalIdentifier)) {
|
|
throw new FlatEntityMapsException(
|
|
`PageLayout with id ${commandMenuItemEntity.pageLayoutId} not found for commandMenuItem ${commandMenuItemEntity.id}`,
|
|
FlatEntityMapsExceptionCode.ENTITY_NOT_FOUND,
|
|
);
|
|
}
|
|
}
|
|
|
|
return {
|
|
id: commandMenuItemEntity.id,
|
|
workflowVersionId: commandMenuItemEntity.workflowVersionId,
|
|
frontComponentId: commandMenuItemEntity.frontComponentId,
|
|
engineComponentKey: commandMenuItemEntity.engineComponentKey,
|
|
label: commandMenuItemEntity.label,
|
|
icon: commandMenuItemEntity.icon,
|
|
shortLabel: commandMenuItemEntity.shortLabel,
|
|
position: commandMenuItemEntity.position,
|
|
isPinned: commandMenuItemEntity.isPinned,
|
|
payload: commandMenuItemEntity.payload,
|
|
hotKeys: commandMenuItemEntity.hotKeys,
|
|
availabilityType: commandMenuItemEntity.availabilityType,
|
|
availabilityObjectMetadataId:
|
|
commandMenuItemEntity.availabilityObjectMetadataId,
|
|
workspaceId: commandMenuItemEntity.workspaceId,
|
|
universalIdentifier: commandMenuItemEntity.universalIdentifier,
|
|
applicationId: commandMenuItemEntity.applicationId,
|
|
createdAt: commandMenuItemEntity.createdAt.toISOString(),
|
|
updatedAt: commandMenuItemEntity.updatedAt.toISOString(),
|
|
applicationUniversalIdentifier,
|
|
conditionalAvailabilityExpression:
|
|
commandMenuItemEntity.conditionalAvailabilityExpression,
|
|
availabilityObjectMetadataUniversalIdentifier,
|
|
frontComponentUniversalIdentifier,
|
|
pageLayoutId: commandMenuItemEntity.pageLayoutId,
|
|
pageLayoutUniversalIdentifier,
|
|
};
|
|
};
|