https://github.com/user-attachments/assets/fe1461c7-0d5c-4c6f-8c2e-2cf569e7de90 ## What Fix `RECORD_SELECTION` items leaking into the command menu when nothing is selected, and unify how the menu renders in normal vs edit mode. ## The bug `RECORD_SELECTION`-availability items were showing up even when `numberOfSelectedRecords === 0`. New util `doesCommandMenuItemMatchSelectionState` gates them, applied consistently in the runtime provider and the editor. ## The refactor `PinnedCommandMenuItemButtonsEditMode` was a 140-line near-duplicate of `PinnedCommandMenuItemButtons` with its own (drifting) filter logic. Killed it. Edit mode now flows through the same `CommandMenuContextProvider` with a new `isInPreviewMode` flag — one filter chain, one rendering path. ## Behavior in edit mode **Header (pinned buttons in page header):** - Runs the full filter chain — object metadata, page type, selection state, page layout, *and the conditional availability expression* - Buttons render at full styling but are inert via `pointer-events: none` + `cursor: not-allowed` - Preview now reflects exactly what users will see on the live page (not a grayed-out approximation) **Side panel editor:** - New `useEditableCommandMenuItems` hook - Same filters as runtime *minus* the conditional availability expression and `FALLBACK` items — so it surfaces everything that's actually configurable for this page context - Still gates on selection state — if no records selected, `RECORD_SELECTION` items are hidden from the editor too. Open to feedback if we'd rather always show them so users can pin them ahead of time. ## Misc - `usePinnedCommandMenuItemsInlineLayout` — visible count now waits until every item is measured before committing. Fixes a flash of wrong counts on mount/resize - Renamed `useCommandMenuContextApi` → `useCurrentCommandMenuContextApi` — name now conveys it reads from the *current* scoped context store - Copy: "Records selected" → "Record(s) selected"
65 lines
2.0 KiB
TypeScript
65 lines
2.0 KiB
TypeScript
import { type CommandMenuContextApi } from 'twenty-shared/types';
|
|
import { isDefined } from 'twenty-shared/utils';
|
|
|
|
import { type CommandMenuContextType } from '@/command-menu-item/contexts/CommandMenuContext';
|
|
import { useWorkflowsWithCurrentVersions } from '@/command-menu-item/hooks/useWorkflowsWithCurrentVersions';
|
|
|
|
import { CommandMenuContextProviderContent } from './CommandMenuContextProviderContent';
|
|
|
|
type CommandMenuContextProviderWithWorkflowEnrichmentProps = {
|
|
displayType: CommandMenuContextType['displayType'];
|
|
containerType: CommandMenuContextType['containerType'];
|
|
children: React.ReactNode;
|
|
commandMenuContextApi: CommandMenuContextApi;
|
|
selectedWorkflowRecordIds: string[];
|
|
isInPreviewMode: boolean;
|
|
};
|
|
|
|
export const CommandMenuContextProviderWithWorkflowEnrichment = ({
|
|
displayType,
|
|
containerType,
|
|
children,
|
|
commandMenuContextApi,
|
|
selectedWorkflowRecordIds,
|
|
isInPreviewMode,
|
|
}: CommandMenuContextProviderWithWorkflowEnrichmentProps) => {
|
|
const workflowsWithCurrentVersions = useWorkflowsWithCurrentVersions(
|
|
selectedWorkflowRecordIds,
|
|
);
|
|
|
|
const enrichedSelectedRecords = commandMenuContextApi.selectedRecords.map(
|
|
(record) => {
|
|
const workflowWithCurrentVersion = workflowsWithCurrentVersions.find(
|
|
(workflow) => workflow.id === record.id,
|
|
);
|
|
|
|
if (!isDefined(workflowWithCurrentVersion)) {
|
|
return record;
|
|
}
|
|
|
|
return {
|
|
...record,
|
|
currentVersion: workflowWithCurrentVersion.currentVersion,
|
|
versions: workflowWithCurrentVersion.versions,
|
|
statuses: workflowWithCurrentVersion.statuses,
|
|
};
|
|
},
|
|
);
|
|
|
|
const enrichedCommandMenuContextApi = {
|
|
...commandMenuContextApi,
|
|
selectedRecords: enrichedSelectedRecords,
|
|
};
|
|
|
|
return (
|
|
<CommandMenuContextProviderContent
|
|
displayType={displayType}
|
|
containerType={containerType}
|
|
commandMenuContextApi={enrichedCommandMenuContextApi}
|
|
isInPreviewMode={isInPreviewMode}
|
|
>
|
|
{children}
|
|
</CommandMenuContextProviderContent>
|
|
);
|
|
};
|