Create workflow version show page (#7466)
In this PR: - Refactored components to clarify their behavior. For example, I renamed the `Workflow` component to `WorkflowVisualizer`. This moved forward the issue #7010. - Create two variants of several workflow-related components: one version for editing and another for viewing. For instance, there is `WorkflowDiagramCanvasEditable.tsx` and `WorkflowDiagramCanvasReadonly.tsx` - Implement the show page for workflow versions. On this page, we display a readonly workflow visualizer. Users can click on nodes and it will expand the right drawer. - I added buttons in the header of the RecordShowPage for workflow versions: users can activate, deactivate or use the currently viewed version as the next draft. **There are many cache desynchronisation and I'll fix them really soon.** ## Demo (Turn sound on) https://github.com/user-attachments/assets/97fafa48-8902-4dab-8b39-f40848bf041e
This commit is contained in:
committed by
GitHub
parent
d5bd320b8d
commit
1863636003
@ -2,11 +2,7 @@ import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSi
|
||||
import { useCreateOneRecord } from '@/object-record/hooks/useCreateOneRecord';
|
||||
import { WorkflowVersion } from '@/workflow/types/Workflow';
|
||||
|
||||
export const useCreateNewWorkflowVersion = ({
|
||||
workflowId,
|
||||
}: {
|
||||
workflowId: string;
|
||||
}) => {
|
||||
export const useCreateNewWorkflowVersion = () => {
|
||||
const { createOneRecord: createOneWorkflowVersion } =
|
||||
useCreateOneRecord<WorkflowVersion>({
|
||||
objectNameSingular: CoreObjectNameSingular.WorkflowVersion,
|
||||
@ -15,13 +11,10 @@ export const useCreateNewWorkflowVersion = ({
|
||||
const createNewWorkflowVersion = (
|
||||
workflowVersionData: Pick<
|
||||
WorkflowVersion,
|
||||
'name' | 'status' | 'trigger' | 'steps'
|
||||
'workflowId' | 'name' | 'status' | 'trigger' | 'steps'
|
||||
>,
|
||||
) => {
|
||||
return createOneWorkflowVersion({
|
||||
workflowId,
|
||||
...workflowVersionData,
|
||||
});
|
||||
return createOneWorkflowVersion(workflowVersionData);
|
||||
};
|
||||
|
||||
return {
|
||||
|
||||
@ -32,9 +32,7 @@ export const useCreateStep = ({
|
||||
objectNameSingular: CoreObjectNameSingular.WorkflowVersion,
|
||||
});
|
||||
|
||||
const { createNewWorkflowVersion } = useCreateNewWorkflowVersion({
|
||||
workflowId: workflow.id,
|
||||
});
|
||||
const { createNewWorkflowVersion } = useCreateNewWorkflowVersion();
|
||||
|
||||
const insertNodeAndSave = async ({
|
||||
parentNodeId,
|
||||
@ -66,6 +64,7 @@ export const useCreateStep = ({
|
||||
}
|
||||
|
||||
await createNewWorkflowVersion({
|
||||
workflowId: workflow.id,
|
||||
name: `v${workflow.versions.length + 1}`,
|
||||
status: 'DRAFT',
|
||||
trigger: workflow.currentVersion.trigger,
|
||||
|
||||
@ -20,9 +20,7 @@ export const useDeleteOneStep = ({
|
||||
objectNameSingular: CoreObjectNameSingular.WorkflowVersion,
|
||||
});
|
||||
|
||||
const { createNewWorkflowVersion } = useCreateNewWorkflowVersion({
|
||||
workflowId: workflow.id,
|
||||
});
|
||||
const { createNewWorkflowVersion } = useCreateNewWorkflowVersion();
|
||||
|
||||
const deleteOneStep = async () => {
|
||||
if (workflow.currentVersion.status !== 'DRAFT') {
|
||||
@ -30,6 +28,7 @@ export const useDeleteOneStep = ({
|
||||
|
||||
if (stepId === TRIGGER_STEP_ID) {
|
||||
await createNewWorkflowVersion({
|
||||
workflowId: workflow.id,
|
||||
name: newVersionName,
|
||||
status: 'DRAFT',
|
||||
trigger: null,
|
||||
@ -37,6 +36,7 @@ export const useDeleteOneStep = ({
|
||||
});
|
||||
} else {
|
||||
await createNewWorkflowVersion({
|
||||
workflowId: workflow.id,
|
||||
name: newVersionName,
|
||||
status: 'DRAFT',
|
||||
trigger: workflow.currentVersion.trigger,
|
||||
|
||||
@ -0,0 +1,36 @@
|
||||
import { workflowDiagramTriggerNodeSelectionState } from '@/workflow/states/workflowDiagramTriggerNodeSelectionState';
|
||||
import {
|
||||
WorkflowDiagramEdge,
|
||||
WorkflowDiagramNode,
|
||||
} from '@/workflow/types/WorkflowDiagram';
|
||||
import { useReactFlow } from '@xyflow/react';
|
||||
import { useEffect } from 'react';
|
||||
import { useRecoilValue, useSetRecoilState } from 'recoil';
|
||||
import { isDefined } from 'twenty-ui';
|
||||
|
||||
export const useTriggerNodeSelection = () => {
|
||||
const reactflow = useReactFlow<WorkflowDiagramNode, WorkflowDiagramEdge>();
|
||||
|
||||
const workflowDiagramTriggerNodeSelection = useRecoilValue(
|
||||
workflowDiagramTriggerNodeSelectionState,
|
||||
);
|
||||
const setWorkflowDiagramTriggerNodeSelection = useSetRecoilState(
|
||||
workflowDiagramTriggerNodeSelectionState,
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (!isDefined(workflowDiagramTriggerNodeSelection)) {
|
||||
return;
|
||||
}
|
||||
|
||||
reactflow.updateNode(workflowDiagramTriggerNodeSelection, {
|
||||
selected: true,
|
||||
});
|
||||
|
||||
setWorkflowDiagramTriggerNodeSelection(undefined);
|
||||
}, [
|
||||
reactflow,
|
||||
setWorkflowDiagramTriggerNodeSelection,
|
||||
workflowDiagramTriggerNodeSelection,
|
||||
]);
|
||||
};
|
||||
@ -21,9 +21,7 @@ export const useUpdateWorkflowVersionStep = ({
|
||||
objectNameSingular: CoreObjectNameSingular.WorkflowVersion,
|
||||
});
|
||||
|
||||
const { createNewWorkflowVersion } = useCreateNewWorkflowVersion({
|
||||
workflowId: workflow.id,
|
||||
});
|
||||
const { createNewWorkflowVersion } = useCreateNewWorkflowVersion();
|
||||
|
||||
const updateStep = async <T extends WorkflowStep>(updatedStep: T) => {
|
||||
if (!isDefined(workflow.currentVersion)) {
|
||||
@ -48,6 +46,7 @@ export const useUpdateWorkflowVersionStep = ({
|
||||
}
|
||||
|
||||
await createNewWorkflowVersion({
|
||||
workflowId: workflow.id,
|
||||
name: `v${workflow.versions.length + 1}`,
|
||||
status: 'DRAFT',
|
||||
trigger: workflow.currentVersion.trigger,
|
||||
|
||||
@ -18,9 +18,7 @@ export const useUpdateWorkflowVersionTrigger = ({
|
||||
objectNameSingular: CoreObjectNameSingular.WorkflowVersion,
|
||||
});
|
||||
|
||||
const { createNewWorkflowVersion } = useCreateNewWorkflowVersion({
|
||||
workflowId: workflow.id,
|
||||
});
|
||||
const { createNewWorkflowVersion } = useCreateNewWorkflowVersion();
|
||||
|
||||
const updateTrigger = async (updatedTrigger: WorkflowTrigger) => {
|
||||
if (!isDefined(workflow.currentVersion)) {
|
||||
@ -39,6 +37,7 @@ export const useUpdateWorkflowVersionTrigger = ({
|
||||
}
|
||||
|
||||
await createNewWorkflowVersion({
|
||||
workflowId: workflow.id,
|
||||
name: `v${workflow.versions.length + 1}`,
|
||||
status: 'DRAFT',
|
||||
trigger: updatedTrigger,
|
||||
|
||||
@ -0,0 +1,36 @@
|
||||
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
|
||||
import { useFindOneRecord } from '@/object-record/hooks/useFindOneRecord';
|
||||
import { Workflow, WorkflowVersion } from '@/workflow/types/Workflow';
|
||||
|
||||
export const useWorkflowVersion = (workflowVersionId: string) => {
|
||||
const { record: workflowVersion } = useFindOneRecord<
|
||||
WorkflowVersion & {
|
||||
workflow: Omit<Workflow, 'versions'> & {
|
||||
versions: Array<{ __typename: string }>;
|
||||
};
|
||||
}
|
||||
>({
|
||||
objectNameSingular: CoreObjectNameSingular.WorkflowVersion,
|
||||
objectRecordId: workflowVersionId,
|
||||
recordGqlFields: {
|
||||
id: true,
|
||||
name: true,
|
||||
createdAt: true,
|
||||
updatedAt: true,
|
||||
workflowId: true,
|
||||
trigger: true,
|
||||
steps: true,
|
||||
status: true,
|
||||
workflow: {
|
||||
id: true,
|
||||
name: true,
|
||||
statuses: true,
|
||||
versions: {
|
||||
totalCount: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
return workflowVersion;
|
||||
};
|
||||
Reference in New Issue
Block a user