diff --git a/packages/twenty-front/src/modules/command-menu/pages/workflow/step/edit/components/CommandMenuWorkflowEditStep.tsx b/packages/twenty-front/src/modules/command-menu/pages/workflow/step/edit/components/CommandMenuWorkflowEditStep.tsx index 3022c0a5c..4aeb0a9cd 100644 --- a/packages/twenty-front/src/modules/command-menu/pages/workflow/step/edit/components/CommandMenuWorkflowEditStep.tsx +++ b/packages/twenty-front/src/modules/command-menu/pages/workflow/step/edit/components/CommandMenuWorkflowEditStep.tsx @@ -2,7 +2,7 @@ import { workflowIdComponentState } from '@/command-menu/pages/workflow/states/w import { CommandMenuWorkflowEditStepContent } from '@/command-menu/pages/workflow/step/edit/components/CommandMenuWorkflowEditStepContent'; import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2'; import { useWorkflowWithCurrentVersion } from '@/workflow/hooks/useWorkflowWithCurrentVersion'; -import { WorkflowVersionComponentInstanceContext } from '@/workflow/states/context/WorkflowVersionComponentInstanceContext'; +import { WorkflowStepContextProvider } from '@/workflow/states/context/WorkflowStepContext'; import { isDefined } from 'twenty-shared'; export const CommandMenuWorkflowEditStep = () => { @@ -14,10 +14,10 @@ export const CommandMenuWorkflowEditStep = () => { } return ( - - + ); }; diff --git a/packages/twenty-front/src/modules/command-menu/pages/workflow/step/view-run/components/CommandMenuWorkflowRunViewStep.tsx b/packages/twenty-front/src/modules/command-menu/pages/workflow/step/view-run/components/CommandMenuWorkflowRunViewStep.tsx index 1adff9df2..1ff2c7c74 100644 --- a/packages/twenty-front/src/modules/command-menu/pages/workflow/step/view-run/components/CommandMenuWorkflowRunViewStep.tsx +++ b/packages/twenty-front/src/modules/command-menu/pages/workflow/step/view-run/components/CommandMenuWorkflowRunViewStep.tsx @@ -4,7 +4,7 @@ import { useTabList } from '@/ui/layout/tab/hooks/useTabList'; import { useFlowOrThrow } from '@/workflow/hooks/useFlowOrThrow'; import { useWorkflowRun } from '@/workflow/hooks/useWorkflowRun'; import { useWorkflowRunIdOrThrow } from '@/workflow/hooks/useWorkflowRunIdOrThrow'; -import { WorkflowVersionComponentInstanceContext } from '@/workflow/states/context/WorkflowVersionComponentInstanceContext'; +import { WorkflowStepContextProvider } from '@/workflow/states/context/WorkflowStepContext'; import { useWorkflowSelectedNodeOrThrow } from '@/workflow/workflow-diagram/hooks/useWorkflowSelectedNodeOrThrow'; import { WorkflowRunStepInputDetail } from '@/workflow/workflow-steps/components/WorkflowRunStepInputDetail'; import { WorkflowRunStepOutputDetail } from '@/workflow/workflow-steps/components/WorkflowRunStepOutputDetail'; @@ -66,8 +66,8 @@ export const CommandMenuWorkflowRunViewStep = () => { } return ( - { {activeTabId === 'output' ? ( ) : null} - + ); }; diff --git a/packages/twenty-front/src/modules/command-menu/pages/workflow/step/view/components/CommandMenuWorkflowViewStep.tsx b/packages/twenty-front/src/modules/command-menu/pages/workflow/step/view/components/CommandMenuWorkflowViewStep.tsx index 554579f96..97825c9c1 100644 --- a/packages/twenty-front/src/modules/command-menu/pages/workflow/step/view/components/CommandMenuWorkflowViewStep.tsx +++ b/packages/twenty-front/src/modules/command-menu/pages/workflow/step/view/components/CommandMenuWorkflowViewStep.tsx @@ -1,5 +1,5 @@ import { useFlowOrThrow } from '@/workflow/hooks/useFlowOrThrow'; -import { WorkflowVersionComponentInstanceContext } from '@/workflow/states/context/WorkflowVersionComponentInstanceContext'; +import { WorkflowStepContextProvider } from '@/workflow/states/context/WorkflowStepContext'; import { useWorkflowSelectedNodeOrThrow } from '@/workflow/workflow-diagram/hooks/useWorkflowSelectedNodeOrThrow'; import { WorkflowStepDetail } from '@/workflow/workflow-steps/components/WorkflowStepDetail'; @@ -7,8 +7,8 @@ export const CommandMenuWorkflowViewStep = () => { const flow = useFlowOrThrow(); const workflowSelectedNode = useWorkflowSelectedNodeOrThrow(); return ( - { steps={flow.steps} readonly /> - + ); }; diff --git a/packages/twenty-front/src/modules/object-record/record-field/form-types/components/VariableChip.tsx b/packages/twenty-front/src/modules/object-record/record-field/form-types/components/VariableChip.tsx index e286ff6f2..1fc18c8b4 100644 --- a/packages/twenty-front/src/modules/object-record/record-field/form-types/components/VariableChip.tsx +++ b/packages/twenty-front/src/modules/object-record/record-field/form-types/components/VariableChip.tsx @@ -1,9 +1,11 @@ -import { useStepsOutputSchema } from '@/workflow/hooks/useStepsOutputSchema'; +import { useWorkflowStepContextOrThrow } from '@/workflow/states/context/WorkflowStepContext'; +import { stepsOutputSchemaFamilySelector } from '@/workflow/states/selectors/stepsOutputSchemaFamilySelector'; import { extractRawVariableNamePart } from '@/workflow/workflow-variables/utils/extractRawVariableNamePart'; import { searchVariableThroughOutputSchema } from '@/workflow/workflow-variables/utils/searchVariableThroughOutputSchema'; import { css, useTheme } from '@emotion/react'; import styled from '@emotion/styled'; import { useLingui } from '@lingui/react/macro'; +import { useRecoilValue } from 'recoil'; import { isDefined } from 'twenty-shared'; import { IconAlertTriangle, IconX } from 'twenty-ui'; @@ -76,21 +78,26 @@ export const VariableChip = ({ }: VariableChipProps) => { const theme = useTheme(); const { t } = useLingui(); - const { getStepsOutputSchema } = useStepsOutputSchema({}); + const { workflowVersionId } = useWorkflowStepContextOrThrow(); + const stepId = extractRawVariableNamePart({ rawVariableName, part: 'stepId', }); + const stepsOutputSchema = useRecoilValue( + stepsOutputSchemaFamilySelector({ + workflowVersionId, + stepIds: [stepId], + }), + ); if (!isDefined(stepId)) { return null; } - const stepOutputSchema = getStepsOutputSchema([stepId])?.[0]; - const { variableLabel, variablePathLabel } = searchVariableThroughOutputSchema({ - stepOutputSchema, + stepOutputSchema: stepsOutputSchema?.[0], rawVariableName, isFullRecord, }); diff --git a/packages/twenty-front/src/modules/workflow/hooks/usePopulateStepsOutputSchema.ts b/packages/twenty-front/src/modules/workflow/hooks/usePopulateStepsOutputSchema.ts deleted file mode 100644 index 590735ebb..000000000 --- a/packages/twenty-front/src/modules/workflow/hooks/usePopulateStepsOutputSchema.ts +++ /dev/null @@ -1,76 +0,0 @@ -import { useRecoilComponentCallbackStateV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentCallbackStateV2'; -import { stepsOutputSchemaComponentFamilyState } from '@/workflow/states/stepsOutputSchemaFamilyState'; -import { WorkflowVersion } from '@/workflow/types/Workflow'; -import { splitWorkflowTriggerEventName } from '@/workflow/utils/splitWorkflowTriggerEventName'; -import { getActionIcon } from '@/workflow/workflow-steps/workflow-actions/utils/getActionIcon'; -import { TRIGGER_STEP_ID } from '@/workflow/workflow-trigger/constants/TriggerStepId'; -import { getTriggerIcon } from '@/workflow/workflow-trigger/utils/getTriggerIcon'; -import { - OutputSchema, - StepOutputSchema, -} from '@/workflow/workflow-variables/types/StepOutputSchema'; -import { getTriggerStepName } from '@/workflow/workflow-variables/utils/getTriggerStepName'; -import { useRecoilCallback } from 'recoil'; -import { isDefined } from 'twenty-shared'; - -export const usePopulateStepsOutputSchema = ({ - workflowVersionId, -}: { - workflowVersionId: string; -}) => { - const stepsOutputSchemaFamilyState = useRecoilComponentCallbackStateV2( - stepsOutputSchemaComponentFamilyState, - workflowVersionId, - ); - - const populateStepsOutputSchema = useRecoilCallback( - ({ set }) => - (workflowVersion: WorkflowVersion) => { - workflowVersion?.steps?.forEach((step) => { - const stepOutputSchema: StepOutputSchema = { - id: step.id, - name: step.name, - icon: getActionIcon(step.type), - outputSchema: step.settings.outputSchema as OutputSchema, - }; - - set(stepsOutputSchemaFamilyState(step.id), stepOutputSchema); - }); - - const trigger = workflowVersion.trigger; - - if (isDefined(trigger)) { - const triggerIconKey = - trigger.type === 'DATABASE_EVENT' - ? getTriggerIcon({ - type: trigger.type, - eventName: splitWorkflowTriggerEventName( - trigger.settings?.eventName, - ).event, - }) - : getTriggerIcon({ - type: trigger.type, - }); - - const triggerOutputSchema: StepOutputSchema = { - id: TRIGGER_STEP_ID, - name: isDefined(trigger.name) - ? trigger.name - : getTriggerStepName(trigger), - icon: triggerIconKey, - outputSchema: trigger.settings.outputSchema as OutputSchema, - }; - - set( - stepsOutputSchemaFamilyState(TRIGGER_STEP_ID), - triggerOutputSchema, - ); - } - }, - [stepsOutputSchemaFamilyState], - ); - - return { - populateStepsOutputSchema, - }; -}; diff --git a/packages/twenty-front/src/modules/workflow/hooks/useStepsOutputSchema.ts b/packages/twenty-front/src/modules/workflow/hooks/useStepsOutputSchema.ts index f7a7e0dd4..063ab1433 100644 --- a/packages/twenty-front/src/modules/workflow/hooks/useStepsOutputSchema.ts +++ b/packages/twenty-front/src/modules/workflow/hooks/useStepsOutputSchema.ts @@ -1,40 +1,97 @@ -import { useAvailableComponentInstanceIdOrThrow } from '@/ui/utilities/state/component-state/hooks/useAvailableComponentInstanceIdOrThrow'; -import { useRecoilComponentCallbackStateV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentCallbackStateV2'; -import { WorkflowVersionComponentInstanceContext } from '@/workflow/states/context/WorkflowVersionComponentInstanceContext'; -import { stepsOutputSchemaComponentFamilyState } from '@/workflow/states/stepsOutputSchemaFamilyState'; +import { stepsOutputSchemaFamilyState } from '@/workflow/states/stepsOutputSchemaFamilyState'; +import { WorkflowVersion } from '@/workflow/types/Workflow'; +import { getStepOutputSchemaFamilyStateKey } from '@/workflow/utils/getStepOutputSchemaFamilyStateKey'; +import { splitWorkflowTriggerEventName } from '@/workflow/utils/splitWorkflowTriggerEventName'; +import { getActionIcon } from '@/workflow/workflow-steps/workflow-actions/utils/getActionIcon'; +import { TRIGGER_STEP_ID } from '@/workflow/workflow-trigger/constants/TriggerStepId'; +import { getTriggerIcon } from '@/workflow/workflow-trigger/utils/getTriggerIcon'; +import { + OutputSchema, + StepOutputSchema, +} from '@/workflow/workflow-variables/types/StepOutputSchema'; +import { getTriggerStepName } from '@/workflow/workflow-variables/utils/getTriggerStepName'; import { useRecoilCallback } from 'recoil'; import { isDefined } from 'twenty-shared'; -export const useStepsOutputSchema = ({ - instanceIdFromProps, -}: { - instanceIdFromProps?: string; -}) => { - const instanceId = useAvailableComponentInstanceIdOrThrow( - WorkflowVersionComponentInstanceContext, - instanceIdFromProps, - ); +export const useStepsOutputSchema = () => { + const populateStepsOutputSchema = useRecoilCallback( + ({ set }) => + (workflowVersion: WorkflowVersion) => { + workflowVersion.steps?.forEach((step) => { + const stepOutputSchema: StepOutputSchema = { + id: step.id, + name: step.name, + icon: getActionIcon(step.type), + outputSchema: step.settings?.outputSchema as OutputSchema, + }; - const stepsOutputSchemaFamilyState = useRecoilComponentCallbackStateV2( - stepsOutputSchemaComponentFamilyState, - instanceId, - ); + set( + stepsOutputSchemaFamilyState( + getStepOutputSchemaFamilyStateKey(workflowVersion.id, step.id), + ), + stepOutputSchema, + ); + }); - const getStepsOutputSchema = useRecoilCallback( - ({ snapshot }) => - (stepIds: string[]) => { - const stepsOutputSchema = stepIds - .map((stepId) => - snapshot - .getLoadable(stepsOutputSchemaFamilyState(stepId)) - .getValue(), - ) - .filter(isDefined); + const trigger = workflowVersion.trigger; - return stepsOutputSchema; + if (isDefined(trigger)) { + const triggerIconKey = + trigger.type === 'DATABASE_EVENT' + ? getTriggerIcon({ + type: trigger.type, + eventName: splitWorkflowTriggerEventName( + trigger.settings?.eventName, + ).event, + }) + : getTriggerIcon({ + type: trigger.type, + }); + + const triggerOutputSchema: StepOutputSchema = { + id: TRIGGER_STEP_ID, + name: isDefined(trigger.name) + ? trigger.name + : getTriggerStepName(trigger), + icon: triggerIconKey, + outputSchema: trigger.settings?.outputSchema as OutputSchema, + }; + + set( + stepsOutputSchemaFamilyState( + getStepOutputSchemaFamilyStateKey( + workflowVersion.id, + TRIGGER_STEP_ID, + ), + ), + triggerOutputSchema, + ); + } }, - [stepsOutputSchemaFamilyState], + [], ); - return { getStepsOutputSchema }; + const deleteStepOutputSchema = useRecoilCallback( + ({ set }) => + ({ + stepId, + workflowVersionId, + }: { + stepId: string; + workflowVersionId: string; + }) => { + set( + stepsOutputSchemaFamilyState( + getStepOutputSchemaFamilyStateKey(workflowVersionId, stepId), + ), + null, + ); + }, + [], + ); + + return { + populateStepsOutputSchema, + deleteStepOutputSchema, + }; }; diff --git a/packages/twenty-front/src/modules/workflow/states/context/WorkflowStepContext.ts b/packages/twenty-front/src/modules/workflow/states/context/WorkflowStepContext.ts new file mode 100644 index 000000000..3f1962eab --- /dev/null +++ b/packages/twenty-front/src/modules/workflow/states/context/WorkflowStepContext.ts @@ -0,0 +1,8 @@ +import { createRequiredContext } from '~/utils/createRequiredContext'; + +type WorkflowStepContextType = { + workflowVersionId: string; +}; + +export const [WorkflowStepContextProvider, useWorkflowStepContextOrThrow] = + createRequiredContext('WorkflowStepContext'); diff --git a/packages/twenty-front/src/modules/workflow/states/context/WorkflowVersionComponentInstanceContext.ts b/packages/twenty-front/src/modules/workflow/states/context/WorkflowVersionComponentInstanceContext.ts deleted file mode 100644 index dfa548cc9..000000000 --- a/packages/twenty-front/src/modules/workflow/states/context/WorkflowVersionComponentInstanceContext.ts +++ /dev/null @@ -1,4 +0,0 @@ -import { createComponentInstanceContext } from '@/ui/utilities/state/component-state/utils/createComponentInstanceContext'; - -export const WorkflowVersionComponentInstanceContext = - createComponentInstanceContext(); diff --git a/packages/twenty-front/src/modules/workflow/states/selectors/stepsOutputSchemaFamilySelector.ts b/packages/twenty-front/src/modules/workflow/states/selectors/stepsOutputSchemaFamilySelector.ts new file mode 100644 index 000000000..6e4367ed2 --- /dev/null +++ b/packages/twenty-front/src/modules/workflow/states/selectors/stepsOutputSchemaFamilySelector.ts @@ -0,0 +1,26 @@ +import { stepsOutputSchemaFamilyState } from '@/workflow/states/stepsOutputSchemaFamilyState'; +import { getStepOutputSchemaFamilyStateKey } from '@/workflow/utils/getStepOutputSchemaFamilyStateKey'; +import { StepOutputSchema } from '@/workflow/workflow-variables/types/StepOutputSchema'; +import { selectorFamily } from 'recoil'; +import { isDefined } from 'twenty-shared'; + +export const stepsOutputSchemaFamilySelector = selectorFamily< + StepOutputSchema[], + { workflowVersionId: string; stepIds: string[] } +>({ + key: 'stepsOutputSchemaFamilySelector', + get: + ({ workflowVersionId, stepIds }) => + ({ get }) => { + const stepsOutputSchema = stepIds + .map((stepId) => + getStepOutputSchemaFamilyStateKey(workflowVersionId, stepId), + ) + .map((stepOutputSchemaKey) => + get(stepsOutputSchemaFamilyState(stepOutputSchemaKey)), + ) + .filter(isDefined); + + return stepsOutputSchema; + }, +}); diff --git a/packages/twenty-front/src/modules/workflow/states/stepsOutputSchemaFamilyState.ts b/packages/twenty-front/src/modules/workflow/states/stepsOutputSchemaFamilyState.ts index 2713dc708..0e86ad56d 100644 --- a/packages/twenty-front/src/modules/workflow/states/stepsOutputSchemaFamilyState.ts +++ b/packages/twenty-front/src/modules/workflow/states/stepsOutputSchemaFamilyState.ts @@ -1,10 +1,10 @@ -import { createComponentFamilyStateV2 } from '@/ui/utilities/state/component-state/utils/createComponentFamilyStateV2'; -import { WorkflowVersionComponentInstanceContext } from '@/workflow/states/context/WorkflowVersionComponentInstanceContext'; +import { createFamilyState } from '@/ui/utilities/state/utils/createFamilyState'; import { StepOutputSchema } from '@/workflow/workflow-variables/types/StepOutputSchema'; -export const stepsOutputSchemaComponentFamilyState = - createComponentFamilyStateV2({ - key: 'stepsOutputSchemaComponentFamilyState', - defaultValue: null, - componentInstanceContext: WorkflowVersionComponentInstanceContext, - }); +export const stepsOutputSchemaFamilyState = createFamilyState< + StepOutputSchema | null, + string | undefined +>({ + key: 'stepsOutputSchemaFamilyState', + defaultValue: null, +}); diff --git a/packages/twenty-front/src/modules/workflow/utils/getStepOutputSchemaFamilyStateKey.ts b/packages/twenty-front/src/modules/workflow/utils/getStepOutputSchemaFamilyStateKey.ts new file mode 100644 index 000000000..e4fbc8427 --- /dev/null +++ b/packages/twenty-front/src/modules/workflow/utils/getStepOutputSchemaFamilyStateKey.ts @@ -0,0 +1,4 @@ +export const getStepOutputSchemaFamilyStateKey = ( + workflowVersionId: string, + stepId: string, +) => `${workflowVersionId}-${stepId}`; diff --git a/packages/twenty-front/src/modules/workflow/workflow-diagram/components/WorkflowDiagramEffect.tsx b/packages/twenty-front/src/modules/workflow/workflow-diagram/components/WorkflowDiagramEffect.tsx index 3735632b4..dbc6de715 100644 --- a/packages/twenty-front/src/modules/workflow/workflow-diagram/components/WorkflowDiagramEffect.tsx +++ b/packages/twenty-front/src/modules/workflow/workflow-diagram/components/WorkflowDiagramEffect.tsx @@ -1,4 +1,5 @@ import { getSnapshotValue } from '@/ui/utilities/state/utils/getSnapshotValue'; +import { useStepsOutputSchema } from '@/workflow/hooks/useStepsOutputSchema'; import { flowState } from '@/workflow/states/flowState'; import { workflowLastCreatedStepIdState } from '@/workflow/states/workflowLastCreatedStepIdState'; import { @@ -22,6 +23,7 @@ export const WorkflowDiagramEffect = ({ }) => { const setWorkflowDiagram = useSetRecoilState(workflowDiagramState); const setFlow = useSetRecoilState(flowState); + const { populateStepsOutputSchema } = useStepsOutputSchema(); const computeAndMergeNewWorkflowDiagram = useRecoilCallback( ({ snapshot, set }) => { @@ -66,8 +68,8 @@ export const WorkflowDiagramEffect = ({ [], ); + const currentVersion = workflowWithCurrentVersion?.currentVersion; useEffect(() => { - const currentVersion = workflowWithCurrentVersion?.currentVersion; if (!isDefined(currentVersion)) { setFlow(undefined); setWorkflowDiagram(undefined); @@ -86,8 +88,16 @@ export const WorkflowDiagramEffect = ({ computeAndMergeNewWorkflowDiagram, setFlow, setWorkflowDiagram, - workflowWithCurrentVersion?.currentVersion, + currentVersion, ]); + useEffect(() => { + if (!isDefined(currentVersion)) { + return; + } + + populateStepsOutputSchema(currentVersion); + }, [currentVersion, populateStepsOutputSchema]); + return null; }; diff --git a/packages/twenty-front/src/modules/workflow/workflow-diagram/components/WorkflowRunVisualizer.tsx b/packages/twenty-front/src/modules/workflow/workflow-diagram/components/WorkflowRunVisualizer.tsx index b4890ede3..3b7b9e69b 100644 --- a/packages/twenty-front/src/modules/workflow/workflow-diagram/components/WorkflowRunVisualizer.tsx +++ b/packages/twenty-front/src/modules/workflow/workflow-diagram/components/WorkflowRunVisualizer.tsx @@ -1,7 +1,5 @@ import { useWorkflowRun } from '@/workflow/hooks/useWorkflowRun'; -import { useWorkflowVersion } from '@/workflow/hooks/useWorkflowVersion'; import { WorkflowRunDiagramCanvas } from '@/workflow/workflow-diagram/components/WorkflowRunDiagramCanvas'; -import { WorkflowVersionOutputSchemaEffect } from '@/workflow/workflow-diagram/components/WorkflowVersionOutputSchemaEffect'; import styled from '@emotion/styled'; import { isDefined } from 'twenty-shared'; @@ -15,15 +13,13 @@ export const WorkflowRunVisualizer = ({ workflowRunId: string; }) => { const workflowRun = useWorkflowRun({ workflowRunId }); - const workflowVersion = useWorkflowVersion(workflowRun?.workflowVersionId); - if (!isDefined(workflowRun) || !isDefined(workflowVersion)) { + if (!isDefined(workflowRun)) { return null; } return ( - ); diff --git a/packages/twenty-front/src/modules/workflow/workflow-diagram/components/WorkflowRunVisualizerEffect.tsx b/packages/twenty-front/src/modules/workflow/workflow-diagram/components/WorkflowRunVisualizerEffect.tsx index 7db1186b1..293d7452d 100644 --- a/packages/twenty-front/src/modules/workflow/workflow-diagram/components/WorkflowRunVisualizerEffect.tsx +++ b/packages/twenty-front/src/modules/workflow/workflow-diagram/components/WorkflowRunVisualizerEffect.tsx @@ -1,4 +1,6 @@ +import { useStepsOutputSchema } from '@/workflow/hooks/useStepsOutputSchema'; import { useWorkflowRun } from '@/workflow/hooks/useWorkflowRun'; +import { useWorkflowVersion } from '@/workflow/hooks/useWorkflowVersion'; import { flowState } from '@/workflow/states/flowState'; import { workflowRunIdState } from '@/workflow/states/workflowRunIdState'; import { workflowDiagramState } from '@/workflow/workflow-diagram/states/workflowDiagramState'; @@ -13,10 +15,12 @@ export const WorkflowRunVisualizerEffect = ({ workflowRunId: string; }) => { const workflowRun = useWorkflowRun({ workflowRunId }); + const workflowVersion = useWorkflowVersion(workflowRun?.workflowVersionId); const setWorkflowRunId = useSetRecoilState(workflowRunIdState); const setFlow = useSetRecoilState(flowState); const setWorkflowDiagram = useSetRecoilState(workflowDiagramState); + const { populateStepsOutputSchema } = useStepsOutputSchema(); useEffect(() => { setWorkflowRunId(workflowRunId); @@ -50,5 +54,13 @@ export const WorkflowRunVisualizerEffect = ({ workflowRun?.workflowVersionId, ]); + useEffect(() => { + if (!isDefined(workflowVersion)) { + return; + } + + populateStepsOutputSchema(workflowVersion); + }, [populateStepsOutputSchema, workflowVersion]); + return null; }; diff --git a/packages/twenty-front/src/modules/workflow/workflow-diagram/components/WorkflowVersionOutputSchemaEffect.tsx b/packages/twenty-front/src/modules/workflow/workflow-diagram/components/WorkflowVersionOutputSchemaEffect.tsx deleted file mode 100644 index 53e86178c..000000000 --- a/packages/twenty-front/src/modules/workflow/workflow-diagram/components/WorkflowVersionOutputSchemaEffect.tsx +++ /dev/null @@ -1,19 +0,0 @@ -import { usePopulateStepsOutputSchema } from '@/workflow/hooks/usePopulateStepsOutputSchema'; -import { WorkflowVersion } from '@/workflow/types/Workflow'; -import { useEffect } from 'react'; - -export const WorkflowVersionOutputSchemaEffect = ({ - workflowVersion, -}: { - workflowVersion: WorkflowVersion; -}) => { - const { populateStepsOutputSchema } = usePopulateStepsOutputSchema({ - workflowVersionId: workflowVersion.id, - }); - - useEffect(() => { - populateStepsOutputSchema(workflowVersion); - }, [populateStepsOutputSchema, workflowVersion]); - - return null; -}; diff --git a/packages/twenty-front/src/modules/workflow/workflow-diagram/components/WorkflowVersionVisualizer.tsx b/packages/twenty-front/src/modules/workflow/workflow-diagram/components/WorkflowVersionVisualizer.tsx index 349812afa..c4946ecb4 100644 --- a/packages/twenty-front/src/modules/workflow/workflow-diagram/components/WorkflowVersionVisualizer.tsx +++ b/packages/twenty-front/src/modules/workflow/workflow-diagram/components/WorkflowVersionVisualizer.tsx @@ -1,6 +1,5 @@ import { useWorkflowVersion } from '@/workflow/hooks/useWorkflowVersion'; import { WorkflowDiagramCanvasReadonly } from '@/workflow/workflow-diagram/components/WorkflowDiagramCanvasReadonly'; -import { WorkflowVersionOutputSchemaEffect } from '@/workflow/workflow-diagram/components/WorkflowVersionOutputSchemaEffect'; import '@xyflow/react/dist/style.css'; import { isDefined } from 'twenty-shared'; @@ -11,10 +10,11 @@ export const WorkflowVersionVisualizer = ({ }) => { const workflowVersion = useWorkflowVersion(workflowVersionId); - return isDefined(workflowVersion) ? ( - <> - - - - ) : null; + if (!isDefined(workflowVersion)) { + return null; + } + + return ( + + ); }; diff --git a/packages/twenty-front/src/modules/workflow/workflow-diagram/components/WorkflowVersionVisualizerEffect.tsx b/packages/twenty-front/src/modules/workflow/workflow-diagram/components/WorkflowVersionVisualizerEffect.tsx index e73cafc95..b1b673304 100644 --- a/packages/twenty-front/src/modules/workflow/workflow-diagram/components/WorkflowVersionVisualizerEffect.tsx +++ b/packages/twenty-front/src/modules/workflow/workflow-diagram/components/WorkflowVersionVisualizerEffect.tsx @@ -1,3 +1,4 @@ +import { useStepsOutputSchema } from '@/workflow/hooks/useStepsOutputSchema'; import { useWorkflowVersion } from '@/workflow/hooks/useWorkflowVersion'; import { flowState } from '@/workflow/states/flowState'; import { workflowDiagramState } from '@/workflow/workflow-diagram/states/workflowDiagramState'; @@ -16,7 +17,7 @@ export const WorkflowVersionVisualizerEffect = ({ const setFlow = useSetRecoilState(flowState); const setWorkflowDiagram = useSetRecoilState(workflowDiagramState); - + const { populateStepsOutputSchema } = useStepsOutputSchema(); useEffect(() => { if (!isDefined(workflowVersion)) { setFlow(undefined); @@ -45,5 +46,13 @@ export const WorkflowVersionVisualizerEffect = ({ setWorkflowDiagram(nextWorkflowDiagram); }, [setWorkflowDiagram, workflowVersion]); + useEffect(() => { + if (!isDefined(workflowVersion)) { + return; + } + + populateStepsOutputSchema(workflowVersion); + }, [populateStepsOutputSchema, workflowVersion]); + return null; }; diff --git a/packages/twenty-front/src/modules/workflow/workflow-diagram/components/WorkflowVisualizer.tsx b/packages/twenty-front/src/modules/workflow/workflow-diagram/components/WorkflowVisualizer.tsx index 8bbb4032f..94d3b6993 100644 --- a/packages/twenty-front/src/modules/workflow/workflow-diagram/components/WorkflowVisualizer.tsx +++ b/packages/twenty-front/src/modules/workflow/workflow-diagram/components/WorkflowVisualizer.tsx @@ -1,28 +1,24 @@ import { useWorkflowWithCurrentVersion } from '@/workflow/hooks/useWorkflowWithCurrentVersion'; import { WorkflowDiagramCanvasEditable } from '@/workflow/workflow-diagram/components/WorkflowDiagramCanvasEditable'; import { WorkflowDiagramEffect } from '@/workflow/workflow-diagram/components/WorkflowDiagramEffect'; -import { WorkflowVersionOutputSchemaEffect } from '@/workflow/workflow-diagram/components/WorkflowVersionOutputSchemaEffect'; import '@xyflow/react/dist/style.css'; import { isDefined } from 'twenty-shared'; export const WorkflowVisualizer = ({ workflowId }: { workflowId: string }) => { const workflowWithCurrentVersion = useWorkflowWithCurrentVersion(workflowId); - const workflowVersion = workflowWithCurrentVersion?.currentVersion; + + if (!isDefined(workflowWithCurrentVersion)) { + return null; + } return ( <> - {isDefined(workflowVersion) && ( - - )} - - {isDefined(workflowWithCurrentVersion) ? ( - - ) : null} + ); }; diff --git a/packages/twenty-front/src/modules/workflow/workflow-steps/components/RightDrawerWorkflowEditStep.tsx b/packages/twenty-front/src/modules/workflow/workflow-steps/components/RightDrawerWorkflowEditStep.tsx index a9a2f6cb7..acd9c20f8 100644 --- a/packages/twenty-front/src/modules/workflow/workflow-steps/components/RightDrawerWorkflowEditStep.tsx +++ b/packages/twenty-front/src/modules/workflow/workflow-steps/components/RightDrawerWorkflowEditStep.tsx @@ -1,5 +1,5 @@ import { useWorkflowWithCurrentVersion } from '@/workflow/hooks/useWorkflowWithCurrentVersion'; -import { WorkflowVersionComponentInstanceContext } from '@/workflow/states/context/WorkflowVersionComponentInstanceContext'; +import { WorkflowStepContextProvider } from '@/workflow/states/context/WorkflowStepContext'; import { workflowIdState } from '@/workflow/states/workflowIdState'; import { RightDrawerWorkflowEditStepContent } from '@/workflow/workflow-steps/components/RightDrawerWorkflowEditStepContent'; import { useRecoilValue } from 'recoil'; @@ -14,10 +14,10 @@ export const RightDrawerWorkflowEditStep = () => { } return ( - - + ); }; diff --git a/packages/twenty-front/src/modules/workflow/workflow-steps/components/RightDrawerWorkflowRunViewStep.tsx b/packages/twenty-front/src/modules/workflow/workflow-steps/components/RightDrawerWorkflowRunViewStep.tsx index bb628304f..b9ffcc93c 100644 --- a/packages/twenty-front/src/modules/workflow/workflow-steps/components/RightDrawerWorkflowRunViewStep.tsx +++ b/packages/twenty-front/src/modules/workflow/workflow-steps/components/RightDrawerWorkflowRunViewStep.tsx @@ -4,7 +4,7 @@ import { useTabList } from '@/ui/layout/tab/hooks/useTabList'; import { useFlowOrThrow } from '@/workflow/hooks/useFlowOrThrow'; import { useWorkflowRun } from '@/workflow/hooks/useWorkflowRun'; import { useWorkflowRunIdOrThrow } from '@/workflow/hooks/useWorkflowRunIdOrThrow'; -import { WorkflowVersionComponentInstanceContext } from '@/workflow/states/context/WorkflowVersionComponentInstanceContext'; +import { WorkflowStepContextProvider } from '@/workflow/states/context/WorkflowStepContext'; import { useWorkflowSelectedNodeOrThrow } from '@/workflow/workflow-diagram/hooks/useWorkflowSelectedNodeOrThrow'; import { WorkflowRunStepInputDetail } from '@/workflow/workflow-steps/components/WorkflowRunStepInputDetail'; import { WorkflowRunStepOutputDetail } from '@/workflow/workflow-steps/components/WorkflowRunStepOutputDetail'; @@ -66,8 +66,8 @@ export const RightDrawerWorkflowRunViewStep = () => { } return ( - { {activeTabId === 'output' ? ( ) : null} - + ); }; diff --git a/packages/twenty-front/src/modules/workflow/workflow-steps/components/RightDrawerWorkflowViewStep.tsx b/packages/twenty-front/src/modules/workflow/workflow-steps/components/RightDrawerWorkflowViewStep.tsx index 727ddc656..95a1dfc70 100644 --- a/packages/twenty-front/src/modules/workflow/workflow-steps/components/RightDrawerWorkflowViewStep.tsx +++ b/packages/twenty-front/src/modules/workflow/workflow-steps/components/RightDrawerWorkflowViewStep.tsx @@ -1,5 +1,5 @@ import { useFlowOrThrow } from '@/workflow/hooks/useFlowOrThrow'; -import { WorkflowVersionComponentInstanceContext } from '@/workflow/states/context/WorkflowVersionComponentInstanceContext'; +import { WorkflowStepContextProvider } from '@/workflow/states/context/WorkflowStepContext'; import { useWorkflowSelectedNodeOrThrow } from '@/workflow/workflow-diagram/hooks/useWorkflowSelectedNodeOrThrow'; import { WorkflowStepDetail } from '@/workflow/workflow-steps/components/WorkflowStepDetail'; @@ -8,8 +8,8 @@ export const RightDrawerWorkflowViewStep = () => { const workflowSelectedNode = useWorkflowSelectedNodeOrThrow(); return ( - { steps={flow.steps} readonly /> - + ); }; diff --git a/packages/twenty-front/src/modules/workflow/workflow-steps/hooks/useDeleteStep.ts b/packages/twenty-front/src/modules/workflow/workflow-steps/hooks/useDeleteStep.ts index bb5008497..4fa6adaea 100644 --- a/packages/twenty-front/src/modules/workflow/workflow-steps/hooks/useDeleteStep.ts +++ b/packages/twenty-front/src/modules/workflow/workflow-steps/hooks/useDeleteStep.ts @@ -4,6 +4,7 @@ import { useUpdateOneRecord } from '@/object-record/hooks/useUpdateOneRecord'; import { useRightDrawer } from '@/ui/layout/right-drawer/hooks/useRightDrawer'; import { useDeleteWorkflowVersionStep } from '@/workflow/hooks/useDeleteWorkflowVersionStep'; import { useGetUpdatableWorkflowVersion } from '@/workflow/hooks/useGetUpdatableWorkflowVersion'; +import { useStepsOutputSchema } from '@/workflow/hooks/useStepsOutputSchema'; import { WorkflowVersion, WorkflowWithCurrentVersion, @@ -20,6 +21,7 @@ export const useDeleteStep = ({ useUpdateOneRecord({ objectNameSingular: CoreObjectNameSingular.WorkflowVersion, }); + const { deleteStepOutputSchema } = useStepsOutputSchema(); const { getUpdatableWorkflowVersion } = useGetUpdatableWorkflowVersion(); const { closeRightDrawer } = useRightDrawer(); @@ -36,11 +38,15 @@ export const useDeleteStep = ({ trigger: null, }, }); - return; + } else { + await deleteWorkflowVersionStep({ + workflowVersionId, + stepId, + }); } - await deleteWorkflowVersionStep({ - workflowVersionId, + deleteStepOutputSchema({ stepId, + workflowVersionId, }); }; diff --git a/packages/twenty-front/src/modules/workflow/workflow-variables/hooks/useAvailableVariablesInWorkflowStep.ts b/packages/twenty-front/src/modules/workflow/workflow-variables/hooks/useAvailableVariablesInWorkflowStep.ts index 30544f0c5..2ed636550 100644 --- a/packages/twenty-front/src/modules/workflow/workflow-variables/hooks/useAvailableVariablesInWorkflowStep.ts +++ b/packages/twenty-front/src/modules/workflow/workflow-variables/hooks/useAvailableVariablesInWorkflowStep.ts @@ -1,5 +1,5 @@ import { useFlowOrThrow } from '@/workflow/hooks/useFlowOrThrow'; -import { useStepsOutputSchema } from '@/workflow/hooks/useStepsOutputSchema'; +import { stepsOutputSchemaFamilySelector } from '@/workflow/states/selectors/stepsOutputSchemaFamilySelector'; import { useWorkflowSelectedNodeOrThrow } from '@/workflow/workflow-diagram/hooks/useWorkflowSelectedNodeOrThrow'; import { TRIGGER_STEP_ID } from '@/workflow/workflow-trigger/constants/TriggerStepId'; import { @@ -8,6 +8,7 @@ import { } from '@/workflow/workflow-variables/types/StepOutputSchema'; import { filterOutputSchema } from '@/workflow/workflow-variables/utils/filterOutputSchema'; import { isEmptyObject } from '@tiptap/core'; +import { useRecoilValue } from 'recoil'; import { isDefined } from 'twenty-shared'; export const useAvailableVariablesInWorkflowStep = ({ @@ -17,7 +18,6 @@ export const useAvailableVariablesInWorkflowStep = ({ }): StepOutputSchema[] => { const workflowSelectedNode = useWorkflowSelectedNodeOrThrow(); const flow = useFlowOrThrow(); - const { getStepsOutputSchema } = useStepsOutputSchema({}); const steps = flow.steps ?? []; @@ -30,17 +30,14 @@ export const useAvailableVariablesInWorkflowStep = ({ previousStepIds.push(step.id); } - const availableStepsOutputSchema: StepOutputSchema[] = - getStepsOutputSchema(previousStepIds).filter(isDefined); + const availableStepsOutputSchema: StepOutputSchema[] = useRecoilValue( + stepsOutputSchemaFamilySelector({ + workflowVersionId: flow.workflowVersionId, + stepIds: [TRIGGER_STEP_ID, ...previousStepIds], + }), + ); - const triggersOutputSchema: StepOutputSchema[] = isDefined(flow.trigger) - ? getStepsOutputSchema([TRIGGER_STEP_ID]).filter(isDefined) - : []; - - const availableVariablesInWorkflowStep = [ - ...availableStepsOutputSchema, - ...triggersOutputSchema, - ] + const availableVariablesInWorkflowStep = availableStepsOutputSchema .map((stepOutputSchema) => { const outputSchema = filterOutputSchema( stepOutputSchema.outputSchema, diff --git a/packages/twenty-front/src/testing/decorators/WorkflowStepDecorator.tsx b/packages/twenty-front/src/testing/decorators/WorkflowStepDecorator.tsx index f0f0458ae..56c71bf33 100644 --- a/packages/twenty-front/src/testing/decorators/WorkflowStepDecorator.tsx +++ b/packages/twenty-front/src/testing/decorators/WorkflowStepDecorator.tsx @@ -1,5 +1,5 @@ -import { usePopulateStepsOutputSchema } from '@/workflow/hooks/usePopulateStepsOutputSchema'; -import { WorkflowVersionComponentInstanceContext } from '@/workflow/states/context/WorkflowVersionComponentInstanceContext'; +import { useStepsOutputSchema } from '@/workflow/hooks/useStepsOutputSchema'; +import { WorkflowStepContextProvider } from '@/workflow/states/context/WorkflowStepContext'; import { workflowIdState } from '@/workflow/states/workflowIdState'; import { WorkflowVersion } from '@/workflow/types/Workflow'; import { workflowSelectedNodeState } from '@/workflow/workflow-diagram/states/workflowSelectedNodeState'; @@ -16,9 +16,7 @@ export const WorkflowStepDecorator: Decorator = (Story) => { const setWorkflowSelectedNode = useSetRecoilState(workflowSelectedNodeState); const workflowVersion = getWorkflowMock().versions.edges[0] .node as WorkflowVersion; - const { populateStepsOutputSchema } = usePopulateStepsOutputSchema({ - workflowVersionId: workflowVersion.id, - }); + const { populateStepsOutputSchema } = useStepsOutputSchema(); const [ready, setReady] = useState(false); useEffect(() => { @@ -34,10 +32,10 @@ export const WorkflowStepDecorator: Decorator = (Story) => { ]); return ( - {ready && } - + ); };