Create command menu items for workflows with manual trigger (#18746)

- Automatically create and sync command menu items for all workflows
with a manual trigger
- Refactor `useCommandMenuItemsFromBackend`
- Prefill a _Quick Lead_ workflow command menu item during workspace
setup and dev seeding
- Add a ready prop to `HeadlessEngineCommandWrapperEffect` to prevent
premature execution when async data hasn't loaded yet

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
This commit is contained in:
Raphaël Bosi
2026-03-22 23:52:43 +01:00
committed by GitHub
parent d16b94bde6
commit c107d804d2
29 changed files with 1277 additions and 860 deletions
@@ -7,10 +7,12 @@ import { useEffect } from 'react';
export type HeadlessEngineCommandWrapperEffectProps = {
execute: () => void | Promise<unknown>;
ready?: boolean;
};
export const HeadlessEngineCommandWrapperEffect = ({
execute,
ready = true,
}: HeadlessEngineCommandWrapperEffectProps) => {
const { isInitializedRef, setIsInitialized } =
useIsHeadlessEngineCommandEffectInitialized();
@@ -24,7 +26,7 @@ export const HeadlessEngineCommandWrapperEffect = ({
const { enqueueErrorSnackBar } = useSnackBar();
useEffect(() => {
if (isInitializedRef.current) {
if (isInitializedRef.current || !ready) {
return;
}
@@ -39,6 +41,7 @@ export const HeadlessEngineCommandWrapperEffect = ({
run();
}, [
execute,
ready,
isInitializedRef,
setIsInitialized,
engineCommandId,
@@ -28,5 +28,10 @@ export const ActivateWorkflowSingleRecordCommand = () => {
});
};
return <HeadlessEngineCommandWrapperEffect execute={handleExecute} />;
return (
<HeadlessEngineCommandWrapperEffect
execute={handleExecute}
ready={isDefined(workflowWithCurrentVersion)}
/>
);
};
@@ -27,5 +27,10 @@ export const DeactivateWorkflowSingleRecordCommand = () => {
});
};
return <HeadlessEngineCommandWrapperEffect execute={handleExecute} />;
return (
<HeadlessEngineCommandWrapperEffect
execute={handleExecute}
ready={isDefined(workflowWithCurrentVersion)}
/>
);
};
@@ -27,5 +27,10 @@ export const DiscardDraftWorkflowSingleRecordCommand = () => {
});
};
return <HeadlessEngineCommandWrapperEffect execute={handleExecute} />;
return (
<HeadlessEngineCommandWrapperEffect
execute={handleExecute}
ready={isDefined(workflowWithCurrentVersion)}
/>
);
};
@@ -28,5 +28,10 @@ export const TestWorkflowSingleRecordCommand = () => {
});
};
return <HeadlessEngineCommandWrapperEffect execute={handleExecute} />;
return (
<HeadlessEngineCommandWrapperEffect
execute={handleExecute}
ready={isDefined(workflowWithCurrentVersion)}
/>
);
};