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 4dd1bf926..9cd5d7fcd 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,6 +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 { useWorkflowSelectedNodeOrThrow } from '@/workflow/workflow-diagram/hooks/useWorkflowSelectedNodeOrThrow'; import { WorkflowRunStepInputDetail } from '@/workflow/workflow-steps/components/WorkflowRunStepInputDetail'; import { WorkflowStepDetail } from '@/workflow/workflow-steps/components/WorkflowStepDetail'; @@ -59,7 +60,9 @@ export const CommandMenuWorkflowRunViewStep = () => { } return ( - <> + { {activeTabId === 'input' ? ( ) : 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 93586fdac..554579f96 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,17 +1,21 @@ import { useFlowOrThrow } from '@/workflow/hooks/useFlowOrThrow'; +import { WorkflowVersionComponentInstanceContext } from '@/workflow/states/context/WorkflowVersionComponentInstanceContext'; import { useWorkflowSelectedNodeOrThrow } from '@/workflow/workflow-diagram/hooks/useWorkflowSelectedNodeOrThrow'; import { WorkflowStepDetail } from '@/workflow/workflow-steps/components/WorkflowStepDetail'; export const CommandMenuWorkflowViewStep = () => { const flow = useFlowOrThrow(); const workflowSelectedNode = useWorkflowSelectedNodeOrThrow(); - return ( - + + + ); }; 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 23d3b64ce..55f9a29ea 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 @@ -83,10 +83,6 @@ export const VariableChip = ({ const stepOutputSchema = getStepsOutputSchema([stepId])?.[0]; - if (!isDefined(stepOutputSchema)) { - return null; - } - const { variableLabel, variablePathLabel } = searchVariableThroughOutputSchema({ stepOutputSchema, diff --git a/packages/twenty-front/src/modules/object-record/record-show/components/CardComponents.tsx b/packages/twenty-front/src/modules/object-record/record-show/components/CardComponents.tsx index 7ccfec511..61db5c786 100644 --- a/packages/twenty-front/src/modules/object-record/record-show/components/CardComponents.tsx +++ b/packages/twenty-front/src/modules/object-record/record-show/components/CardComponents.tsx @@ -8,8 +8,8 @@ import { ActivityTargetableObject } from '@/activities/types/ActivityTargetableE import { FieldsCard } from '@/object-record/record-show/components/FieldsCard'; import { CardType } from '@/object-record/record-show/types/CardType'; import { ShowPageActivityContainer } from '@/ui/layout/show-page/components/ShowPageActivityContainer'; -import { WorkflowRunOutputVisualizer } from '@/workflow/components/WorkflowRunOutputVisualizer'; -import { WorkflowRunVisualizer } from '@/workflow/components/WorkflowRunVisualizer'; +import { WorkflowRunOutputVisualizer } from '@/workflow/workflow-diagram/components/WorkflowRunOutputVisualizer'; +import { WorkflowRunVisualizer } from '@/workflow/workflow-diagram/components/WorkflowRunVisualizer'; import { WorkflowRunVisualizerEffect } from '@/workflow/workflow-diagram/components/WorkflowRunVisualizerEffect'; import { WorkflowVersionVisualizer } from '@/workflow/workflow-diagram/components/WorkflowVersionVisualizer'; import { WorkflowVersionVisualizerEffect } from '@/workflow/workflow-diagram/components/WorkflowVersionVisualizerEffect'; diff --git a/packages/twenty-front/src/modules/workflow/hooks/useWorkflowVersion.ts b/packages/twenty-front/src/modules/workflow/hooks/useWorkflowVersion.ts index d16da6983..7c3ce4f07 100644 --- a/packages/twenty-front/src/modules/workflow/hooks/useWorkflowVersion.ts +++ b/packages/twenty-front/src/modules/workflow/hooks/useWorkflowVersion.ts @@ -2,7 +2,7 @@ import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSi import { useFindOneRecord } from '@/object-record/hooks/useFindOneRecord'; import { Workflow, WorkflowVersion } from '@/workflow/types/Workflow'; -export const useWorkflowVersion = (workflowVersionId: string) => { +export const useWorkflowVersion = (workflowVersionId?: string) => { const { record: workflowVersion } = useFindOneRecord< WorkflowVersion & { workflow: Omit & { @@ -30,6 +30,7 @@ export const useWorkflowVersion = (workflowVersionId: string) => { }, }, }, + skip: !workflowVersionId, }); return workflowVersion; diff --git a/packages/twenty-front/src/modules/workflow/states/flowState.ts b/packages/twenty-front/src/modules/workflow/states/flowState.ts index 21216f77a..228074ff1 100644 --- a/packages/twenty-front/src/modules/workflow/states/flowState.ts +++ b/packages/twenty-front/src/modules/workflow/states/flowState.ts @@ -3,6 +3,7 @@ import { createState } from '@ui/utilities/state/utils/createState'; export const flowState = createState< | { + workflowVersionId: string; trigger: WorkflowTrigger | null; steps: WorkflowAction[] | null; } 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 f781581fe..3735632b4 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 @@ -76,6 +76,7 @@ export const WorkflowDiagramEffect = ({ } setFlow({ + workflowVersionId: currentVersion.id, trigger: currentVersion.trigger, steps: currentVersion.steps, }); diff --git a/packages/twenty-front/src/modules/workflow/components/WorkflowRunOutputVisualizer.tsx b/packages/twenty-front/src/modules/workflow/workflow-diagram/components/WorkflowRunOutputVisualizer.tsx similarity index 100% rename from packages/twenty-front/src/modules/workflow/components/WorkflowRunOutputVisualizer.tsx rename to packages/twenty-front/src/modules/workflow/workflow-diagram/components/WorkflowRunOutputVisualizer.tsx diff --git a/packages/twenty-front/src/modules/workflow/components/WorkflowRunVisualizer.tsx b/packages/twenty-front/src/modules/workflow/workflow-diagram/components/WorkflowRunVisualizer.tsx similarity index 51% rename from packages/twenty-front/src/modules/workflow/components/WorkflowRunVisualizer.tsx rename to packages/twenty-front/src/modules/workflow/workflow-diagram/components/WorkflowRunVisualizer.tsx index 63a69fdec..b4890ede3 100644 --- a/packages/twenty-front/src/modules/workflow/components/WorkflowRunVisualizer.tsx +++ b/packages/twenty-front/src/modules/workflow/workflow-diagram/components/WorkflowRunVisualizer.tsx @@ -1,9 +1,11 @@ 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'; -const StyledSourceCodeContainer = styled.div` +const StyledContainer = styled.div` height: 100%; `; @@ -13,13 +15,16 @@ export const WorkflowRunVisualizer = ({ workflowRunId: string; }) => { const workflowRun = useWorkflowRun({ workflowRunId }); - if (!isDefined(workflowRun)) { + const workflowVersion = useWorkflowVersion(workflowRun?.workflowVersionId); + + if (!isDefined(workflowRun) || !isDefined(workflowVersion)) { 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 dad655f5c..7db1186b1 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 @@ -31,6 +31,7 @@ export const WorkflowRunVisualizerEffect = ({ } setFlow({ + workflowVersionId: workflowRun.workflowVersionId, trigger: workflowRun.output.flow.trigger, steps: workflowRun.output.flow.steps, }); @@ -42,7 +43,12 @@ export const WorkflowRunVisualizerEffect = ({ }); setWorkflowDiagram(nextWorkflowDiagram); - }, [setFlow, setWorkflowDiagram, workflowRun?.output]); + }, [ + setFlow, + setWorkflowDiagram, + workflowRun?.output, + workflowRun?.workflowVersionId, + ]); 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 9d909a6eb..349812afa 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,5 +1,6 @@ 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,6 +12,9 @@ export const WorkflowVersionVisualizer = ({ const workflowVersion = useWorkflowVersion(workflowVersionId); return isDefined(workflowVersion) ? ( - + <> + + + ) : null; }; 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 47c0024fe..e73cafc95 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 @@ -25,6 +25,7 @@ export const WorkflowVersionVisualizerEffect = ({ } setFlow({ + workflowVersionId: workflowVersion.id, trigger: workflowVersion.trigger, steps: workflowVersion.steps, }); 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 b52f33114..bb628304f 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,6 +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 { useWorkflowSelectedNodeOrThrow } from '@/workflow/workflow-diagram/hooks/useWorkflowSelectedNodeOrThrow'; import { WorkflowRunStepInputDetail } from '@/workflow/workflow-steps/components/WorkflowRunStepInputDetail'; import { WorkflowRunStepOutputDetail } from '@/workflow/workflow-steps/components/WorkflowRunStepOutputDetail'; @@ -65,7 +66,9 @@ 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 8b7d76b1e..727ddc656 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,4 +1,5 @@ import { useFlowOrThrow } from '@/workflow/hooks/useFlowOrThrow'; +import { WorkflowVersionComponentInstanceContext } from '@/workflow/states/context/WorkflowVersionComponentInstanceContext'; import { useWorkflowSelectedNodeOrThrow } from '@/workflow/workflow-diagram/hooks/useWorkflowSelectedNodeOrThrow'; import { WorkflowStepDetail } from '@/workflow/workflow-steps/components/WorkflowStepDetail'; @@ -7,11 +8,15 @@ export const RightDrawerWorkflowViewStep = () => { const workflowSelectedNode = useWorkflowSelectedNodeOrThrow(); return ( - + + + ); }; diff --git a/packages/twenty-front/src/modules/workflow/workflow-steps/components/__stories__/RightDrawerWorkflowRunViewStep.stories.tsx b/packages/twenty-front/src/modules/workflow/workflow-steps/components/__stories__/RightDrawerWorkflowRunViewStep.stories.tsx index b95716a05..1a1c8131a 100644 --- a/packages/twenty-front/src/modules/workflow/workflow-steps/components/__stories__/RightDrawerWorkflowRunViewStep.stories.tsx +++ b/packages/twenty-front/src/modules/workflow/workflow-steps/components/__stories__/RightDrawerWorkflowRunViewStep.stories.tsx @@ -40,7 +40,13 @@ const meta: Meta = { ); const setWorkflowRunId = useSetRecoilState(workflowRunIdState); - setFlow(oneFailedWorkflowRunQueryResult.workflowRun.output.flow); + setFlow({ + workflowVersionId: + oneFailedWorkflowRunQueryResult.workflowRun.workflowVersionId, + trigger: + oneFailedWorkflowRunQueryResult.workflowRun.output.flow.trigger, + steps: oneFailedWorkflowRunQueryResult.workflowRun.output.flow.steps, + }); setWorkflowSelectedNode( oneFailedWorkflowRunQueryResult.workflowRun.output.flow.steps[0].id, ); diff --git a/packages/twenty-front/src/modules/workflow/workflow-variables/utils/searchVariableThroughOutputSchema.ts b/packages/twenty-front/src/modules/workflow/workflow-variables/utils/searchVariableThroughOutputSchema.ts index dec4d50d0..642677ed6 100644 --- a/packages/twenty-front/src/modules/workflow/workflow-variables/utils/searchVariableThroughOutputSchema.ts +++ b/packages/twenty-front/src/modules/workflow/workflow-variables/utils/searchVariableThroughOutputSchema.ts @@ -93,6 +93,13 @@ export const searchVariableThroughOutputSchema = ({ rawVariableName: string; isFullRecord?: boolean; }) => { + if (!isDefined(stepOutputSchema)) { + return { + variableLabel: undefined, + variablePathLabel: undefined, + }; + } + const variableWithoutBrackets = rawVariableName.replace( CAPTURE_ALL_VARIABLE_TAG_INNER_REGEX, (_, variableName) => { diff --git a/packages/twenty-server/src/engine/core-modules/billing/services/billing-usage.service.ts b/packages/twenty-server/src/engine/core-modules/billing/services/billing-usage.service.ts index fb7d2732f..c8a51ed3f 100644 --- a/packages/twenty-server/src/engine/core-modules/billing/services/billing-usage.service.ts +++ b/packages/twenty-server/src/engine/core-modules/billing/services/billing-usage.service.ts @@ -13,6 +13,7 @@ import { BillingCustomer } from 'src/engine/core-modules/billing/entities/billin import { BillingSubscriptionService } from 'src/engine/core-modules/billing/services/billing-subscription.service'; import { StripeBillingMeterEventService } from 'src/engine/core-modules/billing/stripe/services/stripe-billing-meter-event.service'; import { BillingUsageEvent } from 'src/engine/core-modules/billing/types/billing-usage-event.type'; +import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service'; @Injectable() export class BillingUsageService { @@ -22,9 +23,14 @@ export class BillingUsageService { private readonly billingCustomerRepository: Repository, private readonly billingSubscriptionService: BillingSubscriptionService, private readonly stripeBillingMeterEventService: StripeBillingMeterEventService, + private readonly environmentService: EnvironmentService, ) {} async canFeatureBeUsed(workspaceId: string): Promise { + if (!this.environmentService.get('IS_BILLING_ENABLED')) { + return true; + } + const billingSubscription = await this.billingSubscriptionService.getCurrentBillingSubscriptionOrThrow( {