Files
twenty/packages/twenty-front/src/modules/workflow/hooks/useWorkflowWithCurrentVersion.ts
T
Thomas Trompette 53a18d7528 feat(workflow): route all version content readers through the flag-aware sources (#23583)
## What

Follow-up to #23499. Migrates every remaining reader of
`record.trigger`/`record.steps` so all version content flows through the
flag-aware sources, then removes `trigger`/`steps` from the record field
sets. The record CRUD path no longer carries version content anywhere in
the app.

Reading is still entirely behind `IS_WORKFLOW_VERSION_IN_CORE_ENABLED`:
this PR changes who asks, never where the answer comes from. Flag off
remains record reads (via the content hook's record branch), flag on the
core query.

## Per reader

| reader | now reads |
| --- | --- |
| `WorkflowDiagramCanvasEditable` (connect, drag-stop) | flow atom |
| `useDeleteStep` | flow atom |
| `WorkflowEditActionIfElseBody` (branch cleanup) | flow atom |
| `SidePanelWorkflowCreateStepContent` (parent-step lookup) | flow atom
|
| `SidePanelWorkflowStepInfo` | flow atom (explicit instance id),
falling back to `useWorkflowVersionContent` when the visualizer is not
mounted |
| `TestWorkflowSingleRecordCommand` | `useWorkflowVersionContent`;
`ready` gates on content being loaded |
| headless enrichment hook (imperative) | core content query when the
flag is on, record otherwise |
| `WorkflowRunVisualizerEffect` (step output schemas) | the run snapshot
(`state.flow`), which is what a run should show anyway |

## Field-set slimming

`useWorkflowVersion` and `useWorkflowWithCurrentVersion` stop fetching
`trigger`/`steps` (identity fields only). Three call sites lost their
only reason to call `useWorkflowWithCurrentVersion` and were dropped
entirely. Verified by grep that no `currentVersion.trigger/steps` reads
remain; the only remaining `.trigger`/`.steps` accesses are
argument-taking utils whose callers now pass flow/content-sourced
objects.

## Verification

- `nx typecheck twenty-front` green
- Front tests: 1058 green (the enrichment test gained mocks for the
apollo client and flag its hook now uses)
- Full-tree `oxfmt` + `oxlint --type-aware` green (3 remaining warnings
are pre-existing in unrelated record-field files)
- Live click-through pending, flag off and on

<!-- This is an auto-generated description by cubic. -->
<a
href="https://cubic.dev/pr/twentyhq/twenty/pull/23583?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>
<!-- End of auto-generated description by cubic. -->
2026-07-30 16:57:11 +00:00

79 lines
2.2 KiB
TypeScript

import { useFindOneRecord } from '@/object-record/hooks/useFindOneRecord';
import { useEffectiveDraftVersionId } from '@/workflow/hooks/useEffectiveDraftVersionId';
import {
type Workflow,
type WorkflowVersion,
type WorkflowWithCurrentVersion,
} from '@/workflow/types/Workflow';
import { CoreObjectNameSingular } from 'twenty-shared/types';
import { isDefined } from 'twenty-shared/utils';
type WorkflowWithAllVersions = Omit<Workflow, 'versions'> & {
versions: Array<
Pick<WorkflowVersion, 'id' | 'status' | 'name' | 'createdAt'>
>;
};
export const useWorkflowWithCurrentVersion = (
workflowId: string | undefined,
): WorkflowWithCurrentVersion | undefined => {
const { record: workflow } = useFindOneRecord<WorkflowWithAllVersions>({
objectNameSingular: CoreObjectNameSingular.Workflow,
objectRecordId: workflowId,
recordGqlFields: {
id: true,
name: true,
statuses: true,
lastPublishedVersionId: true,
versions: {
id: true,
status: true,
name: true,
createdAt: true,
},
},
skip: !isDefined(workflowId),
});
const draftVersionFromServer = workflow?.versions.find(
(workflowVersion) => workflowVersion.status === 'DRAFT',
);
const { effectiveDraftId, lastDiscardedDraftId } = useEffectiveDraftVersionId(
draftVersionFromServer,
);
const workflowVersions = [...(workflow?.versions ?? [])]
.filter((version) => version.id !== lastDiscardedDraftId)
.sort((a, b) => (a.createdAt > b.createdAt ? -1 : 1));
const latestVersion = workflowVersions[0];
const currentVersionId = effectiveDraftId ?? latestVersion?.id;
const { record: currentVersionWithSteps } = useFindOneRecord<WorkflowVersion>(
{
objectNameSingular: CoreObjectNameSingular.WorkflowVersion,
objectRecordId: currentVersionId,
recordGqlFields: {
id: true,
name: true,
status: true,
workflowId: true,
createdAt: true,
updatedAt: true,
},
skip: !isDefined(currentVersionId),
},
);
if (!isDefined(workflow) || !isDefined(currentVersionWithSteps)) {
return undefined;
}
return {
...workflow,
currentVersion: currentVersionWithSteps,
};
};