Files
twenty/packages/twenty-server/src/engine/metadata-modules/flat-command-menu-item/utils/from-flat-command-menu-item-to-command-menu-item-dto.util.ts
T
Weiko f63f053444 CommandMenuItem overridable entity (#21486)
## Context
Second PR of the overridable-entities track (after #21436 for views):
command menu items become overridable so that edits on non-owned items
are stored as overrides instead of mutating the row, and
deletion/deactivation becomes reversible.

 ## What this does

- `CommandMenuItemEntity` now extends
`OverridableEntity<CommandMenuItemOverrides>` (adds `isActive` +
`overrides`). All editable properties are overridable for now (to
discuss).
- **Update**: mutations on a command item not owned by the caller
(standard items) are written into `overrides`; reads merge them in the
DTO. The command palette edit mode (pin,
reorder, shortLabel) now preserves standard values, "Reset label to
default" gains true post-save semantics.
- **Delete**: protected items are deactivated (`isActive = false`)
instead of deleted; custom items still hard-delete.
- **Object deactivate/enable toggle**: now flips `isActive` on the
command item (merged into the main migration call) instead of
delete/recreate; a create-if-missing fallback covers legacy deactivated
objects.
- **Front**: inactive command items are filtered out of the palette
selector.


<!-- This is an auto-generated description by cubic. -->
<a
href="https://cubic.dev/pr/twentyhq/twenty/pull/21486?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>
<!-- End of auto-generated description by cubic. -->

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2026-06-13 14:21:27 +02:00

40 lines
1.9 KiB
TypeScript

import { type CommandMenuItemDTO } from 'src/engine/metadata-modules/command-menu-item/dtos/command-menu-item.dto';
import { type FlatCommandMenuItem } from 'src/engine/metadata-modules/flat-command-menu-item/types/flat-command-menu-item.type';
export const fromFlatCommandMenuItemToCommandMenuItemDto = (
flatCommandMenuItem: FlatCommandMenuItem,
): CommandMenuItemDTO => {
const effectiveFlatCommandMenuItem = {
...flatCommandMenuItem,
...(flatCommandMenuItem.overrides ?? {}),
};
return {
id: effectiveFlatCommandMenuItem.id,
workflowVersionId:
effectiveFlatCommandMenuItem.workflowVersionId ?? undefined,
frontComponentId:
effectiveFlatCommandMenuItem.frontComponentId ?? undefined,
engineComponentKey: effectiveFlatCommandMenuItem.engineComponentKey,
label: effectiveFlatCommandMenuItem.label,
icon: effectiveFlatCommandMenuItem.icon ?? undefined,
shortLabel: effectiveFlatCommandMenuItem.shortLabel ?? undefined,
position: effectiveFlatCommandMenuItem.position,
isPinned: effectiveFlatCommandMenuItem.isPinned,
payload: effectiveFlatCommandMenuItem.payload ?? undefined,
hotKeys: effectiveFlatCommandMenuItem.hotKeys ?? undefined,
availabilityType: effectiveFlatCommandMenuItem.availabilityType,
conditionalAvailabilityExpression:
effectiveFlatCommandMenuItem.conditionalAvailabilityExpression ??
undefined,
availabilityObjectMetadataId:
effectiveFlatCommandMenuItem.availabilityObjectMetadataId ?? undefined,
pageLayoutId: effectiveFlatCommandMenuItem.pageLayoutId ?? undefined,
workspaceId: effectiveFlatCommandMenuItem.workspaceId,
applicationId: effectiveFlatCommandMenuItem.applicationId ?? undefined,
isActive: effectiveFlatCommandMenuItem.isActive,
createdAt: new Date(effectiveFlatCommandMenuItem.createdAt),
updatedAt: new Date(effectiveFlatCommandMenuItem.updatedAt),
};
};