App logic function as step (#17525)
- Add logic function as step - Rename previous one as Code <img width="494" height="573" alt="Capture d’écran 2026-01-28 à 16 15 29" src="https://github.com/user-attachments/assets/82f7e720-20da-4926-b5bc-94a33cd1f53a" /> <img width="494" height="264" alt="Capture d’écran 2026-01-28 à 16 15 39" src="https://github.com/user-attachments/assets/a0444ae9-8c50-418d-8c5f-68c4da08fce7" /> <img width="494" height="264" alt="Capture d’écran 2026-01-28 à 16 15 58" src="https://github.com/user-attachments/assets/3025db09-4e59-421e-8dc5-f3a7a7326554" /> --------- Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
This commit is contained in:
+53
-6
@@ -1,4 +1,5 @@
|
||||
import { WorkflowActionMenuItems } from '@/command-menu/pages/workflow/action/components/WorkflowActionMenuItems';
|
||||
import { useGetManyLogicFunctions } from '@/settings/logic-functions/hooks/useGetManyLogicFunctions';
|
||||
import { type WorkflowActionType } from '@/workflow/types/Workflow';
|
||||
import { RightDrawerStepListContainer } from '@/workflow/workflow-steps/components/RightDrawerWorkflowSelectStepContainer';
|
||||
import { RightDrawerWorkflowSelectStepTitle } from '@/workflow/workflow-steps/components/RightDrawerWorkflowSelectStepTitle';
|
||||
@@ -7,19 +8,40 @@ import { CORE_ACTIONS } from '@/workflow/workflow-steps/workflow-actions/constan
|
||||
import { FLOW_ACTIONS } from '@/workflow/workflow-steps/workflow-actions/constants/FlowActions';
|
||||
import { HUMAN_INPUT_ACTIONS } from '@/workflow/workflow-steps/workflow-actions/constants/HumanInputActions';
|
||||
import { RECORD_ACTIONS } from '@/workflow/workflow-steps/workflow-actions/constants/RecordActions';
|
||||
import { getActionIconColorOrThrow } from '@/workflow/workflow-steps/workflow-actions/utils/getActionIconColorOrThrow';
|
||||
import { useIsFeatureEnabled } from '@/workspace/hooks/useIsFeatureEnabled';
|
||||
import { useTheme } from '@emotion/react';
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
import { IconFunction } from 'twenty-ui/display';
|
||||
import { MenuItem } from 'twenty-ui/navigation';
|
||||
import { FeatureFlagKey } from '~/generated/graphql';
|
||||
|
||||
export type WorkflowActionSelection =
|
||||
| { type: WorkflowActionType; logicFunctionId?: undefined; name?: undefined }
|
||||
| { type: 'LOGIC_FUNCTION'; logicFunctionId: string; name: string };
|
||||
|
||||
export const CommandMenuWorkflowSelectAction = ({
|
||||
onActionSelected,
|
||||
}: {
|
||||
onActionSelected: (actionType: WorkflowActionType) => void;
|
||||
onActionSelected: (selection: WorkflowActionSelection) => void;
|
||||
}) => {
|
||||
const isAiEnabled = useIsFeatureEnabled(FeatureFlagKey.IS_AI_ENABLED);
|
||||
const theme = useTheme();
|
||||
|
||||
const { t } = useLingui();
|
||||
|
||||
const { logicFunctions } = useGetManyLogicFunctions();
|
||||
|
||||
const toolFunctions = logicFunctions.filter((fn) => fn.isTool === true);
|
||||
|
||||
const handleActionClick = (actionType: WorkflowActionType) => {
|
||||
onActionSelected({ type: actionType });
|
||||
};
|
||||
|
||||
const handleFunctionClick = (logicFunctionId: string, name: string) => {
|
||||
onActionSelected({ type: 'LOGIC_FUNCTION', logicFunctionId, name });
|
||||
};
|
||||
|
||||
return (
|
||||
<RightDrawerStepListContainer>
|
||||
<RightDrawerWorkflowSelectStepTitle>
|
||||
@@ -27,7 +49,7 @@ export const CommandMenuWorkflowSelectAction = ({
|
||||
</RightDrawerWorkflowSelectStepTitle>
|
||||
<WorkflowActionMenuItems
|
||||
actions={RECORD_ACTIONS}
|
||||
onClick={onActionSelected}
|
||||
onClick={handleActionClick}
|
||||
/>
|
||||
|
||||
{isAiEnabled && (
|
||||
@@ -37,7 +59,7 @@ export const CommandMenuWorkflowSelectAction = ({
|
||||
</RightDrawerWorkflowSelectStepTitle>
|
||||
<WorkflowActionMenuItems
|
||||
actions={AI_ACTIONS}
|
||||
onClick={onActionSelected}
|
||||
onClick={handleActionClick}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
@@ -47,7 +69,7 @@ export const CommandMenuWorkflowSelectAction = ({
|
||||
</RightDrawerWorkflowSelectStepTitle>
|
||||
<WorkflowActionMenuItems
|
||||
actions={FLOW_ACTIONS}
|
||||
onClick={onActionSelected}
|
||||
onClick={handleActionClick}
|
||||
/>
|
||||
|
||||
<RightDrawerWorkflowSelectStepTitle>
|
||||
@@ -55,7 +77,7 @@ export const CommandMenuWorkflowSelectAction = ({
|
||||
</RightDrawerWorkflowSelectStepTitle>
|
||||
<WorkflowActionMenuItems
|
||||
actions={CORE_ACTIONS}
|
||||
onClick={onActionSelected}
|
||||
onClick={handleActionClick}
|
||||
/>
|
||||
|
||||
<RightDrawerWorkflowSelectStepTitle>
|
||||
@@ -63,8 +85,33 @@ export const CommandMenuWorkflowSelectAction = ({
|
||||
</RightDrawerWorkflowSelectStepTitle>
|
||||
<WorkflowActionMenuItems
|
||||
actions={HUMAN_INPUT_ACTIONS}
|
||||
onClick={onActionSelected}
|
||||
onClick={handleActionClick}
|
||||
/>
|
||||
|
||||
{toolFunctions.length > 0 && (
|
||||
<>
|
||||
<RightDrawerWorkflowSelectStepTitle>
|
||||
{t`Applications`}
|
||||
</RightDrawerWorkflowSelectStepTitle>
|
||||
{toolFunctions.map((fn) => (
|
||||
<MenuItem
|
||||
key={fn.id}
|
||||
withIconContainer={true}
|
||||
LeftIcon={() => (
|
||||
<IconFunction
|
||||
color={getActionIconColorOrThrow({
|
||||
theme,
|
||||
actionType: 'LOGIC_FUNCTION',
|
||||
})}
|
||||
size={16}
|
||||
/>
|
||||
)}
|
||||
text={fn.name}
|
||||
onClick={() => handleFunctionClick(fn.id, fn.name)}
|
||||
/>
|
||||
))}
|
||||
</>
|
||||
)}
|
||||
</RightDrawerStepListContainer>
|
||||
);
|
||||
};
|
||||
|
||||
+8
-3
@@ -1,5 +1,8 @@
|
||||
import { useWorkflowCommandMenu } from '@/command-menu/hooks/useWorkflowCommandMenu';
|
||||
import { CommandMenuWorkflowSelectAction } from '@/command-menu/pages/workflow/action/components/CommandMenuWorkflowSelectAction';
|
||||
import {
|
||||
CommandMenuWorkflowSelectAction,
|
||||
type WorkflowActionSelection,
|
||||
} from '@/command-menu/pages/workflow/action/components/CommandMenuWorkflowSelectAction';
|
||||
import { commandMenuNavigationStackState } from '@/command-menu/states/commandMenuNavigationStackState';
|
||||
import { useRecoilComponentState } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentState';
|
||||
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
|
||||
@@ -55,7 +58,7 @@ export const CommandMenuWorkflowCreateStepContent = () => {
|
||||
await updateStep(updatedStep);
|
||||
};
|
||||
|
||||
const handleCreateStep = async (actionType: WorkflowActionType) => {
|
||||
const handleCreateStep = async (selection: WorkflowActionSelection) => {
|
||||
if (!isDefined(workflowVisualizerWorkflowId)) {
|
||||
throw new Error(
|
||||
'Workflow ID must be configured for the edge when creating a step',
|
||||
@@ -66,11 +69,13 @@ export const CommandMenuWorkflowCreateStepContent = () => {
|
||||
workflowInsertStepIds;
|
||||
|
||||
const createdStep = await createStep({
|
||||
newStepType: actionType,
|
||||
newStepType: selection.type,
|
||||
parentStepId,
|
||||
nextStepId,
|
||||
position,
|
||||
connectionOptions,
|
||||
logicFunctionId: selection.logicFunctionId,
|
||||
name: selection.name,
|
||||
});
|
||||
|
||||
if (!isDefined(createdStep)) {
|
||||
|
||||
+25
-6
@@ -1,5 +1,8 @@
|
||||
import { useWorkflowCommandMenu } from '@/command-menu/hooks/useWorkflowCommandMenu';
|
||||
import { CommandMenuWorkflowSelectAction } from '@/command-menu/pages/workflow/action/components/CommandMenuWorkflowSelectAction';
|
||||
import {
|
||||
CommandMenuWorkflowSelectAction,
|
||||
type WorkflowActionSelection,
|
||||
} from '@/command-menu/pages/workflow/action/components/CommandMenuWorkflowSelectAction';
|
||||
import { commandMenuNavigationStackState } from '@/command-menu/states/commandMenuNavigationStackState';
|
||||
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
|
||||
import { useFlowOrThrow } from '@/workflow/hooks/useFlowOrThrow';
|
||||
@@ -34,7 +37,7 @@ export const CommandMenuWorkflowEditStepTypeContent = () => {
|
||||
commandMenuNavigationStackState,
|
||||
);
|
||||
|
||||
const handleUpdateStepType = async (actionType: WorkflowActionType) => {
|
||||
const handleUpdateStepType = async (selection: WorkflowActionSelection) => {
|
||||
if (!isDefined(workflowVisualizerWorkflowId)) {
|
||||
throw new Error(
|
||||
'Workflow ID must be configured for the edge when creating a step',
|
||||
@@ -49,10 +52,26 @@ export const CommandMenuWorkflowEditStepTypeContent = () => {
|
||||
throw new Error('Step not found');
|
||||
}
|
||||
|
||||
const { updatedStep } = await updateStep({
|
||||
...existingStep,
|
||||
type: actionType,
|
||||
} as WorkflowAction);
|
||||
const stepUpdate =
|
||||
selection.type === 'LOGIC_FUNCTION'
|
||||
? {
|
||||
...existingStep,
|
||||
type: selection.type,
|
||||
name: selection.name,
|
||||
settings: {
|
||||
...existingStep.settings,
|
||||
input: {
|
||||
logicFunctionId: selection.logicFunctionId,
|
||||
logicFunctionInput: {},
|
||||
},
|
||||
},
|
||||
}
|
||||
: {
|
||||
...existingStep,
|
||||
type: selection.type,
|
||||
};
|
||||
|
||||
const { updatedStep } = await updateStep(stepUpdate as WorkflowAction);
|
||||
|
||||
if (!isDefined(updatedStep)) {
|
||||
return;
|
||||
|
||||
Reference in New Issue
Block a user