Implement branch front end (#13489)
First PR to support workflow branches on frontend
This commit is contained in:
+3
-1
@@ -6,7 +6,9 @@ import { useCreateStep } from '../useCreateStep';
|
||||
|
||||
const mockCreateDraftFromWorkflowVersion = jest.fn().mockResolvedValue('457');
|
||||
const mockCreateWorkflowVersionStep = jest.fn().mockResolvedValue({
|
||||
data: { createWorkflowVersionStep: { id: '1', type: 'CODE' } },
|
||||
data: {
|
||||
createWorkflowVersionStep: { createdStep: { id: '1', type: 'CODE' } },
|
||||
},
|
||||
});
|
||||
|
||||
jest.mock(
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
import { WorkflowWithCurrentVersion } from '@/workflow/types/Workflow';
|
||||
import { useCreateWorkflowVersionEdge } from '@/workflow/workflow-steps/hooks/useCreateWorkflowVersionEdge';
|
||||
import { useState } from 'react';
|
||||
import { useGetUpdatableWorkflowVersion } from '@/workflow/hooks/useGetUpdatableWorkflowVersion';
|
||||
|
||||
export const useCreateEdge = ({
|
||||
workflow,
|
||||
}: {
|
||||
workflow: WorkflowWithCurrentVersion;
|
||||
}) => {
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
|
||||
const { createWorkflowVersionEdge } = useCreateWorkflowVersionEdge();
|
||||
|
||||
const { getUpdatableWorkflowVersion } = useGetUpdatableWorkflowVersion();
|
||||
|
||||
const createEdge = async ({
|
||||
source,
|
||||
target,
|
||||
}: {
|
||||
source: string;
|
||||
target: string;
|
||||
}) => {
|
||||
if (isLoading === true) {
|
||||
return;
|
||||
}
|
||||
|
||||
setIsLoading(true);
|
||||
|
||||
try {
|
||||
const workflowVersionId = await getUpdatableWorkflowVersion(workflow);
|
||||
|
||||
const createdEdge = (
|
||||
await createWorkflowVersionEdge({
|
||||
workflowVersionId,
|
||||
source,
|
||||
target,
|
||||
})
|
||||
)?.data?.createWorkflowVersionEdge;
|
||||
|
||||
if (!createdEdge) {
|
||||
return;
|
||||
}
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
return { createEdge };
|
||||
};
|
||||
@@ -36,10 +36,12 @@ export const useCreateStep = ({
|
||||
newStepType,
|
||||
parentStepId,
|
||||
nextStepId,
|
||||
position,
|
||||
}: {
|
||||
newStepType: WorkflowStepType;
|
||||
parentStepId: string;
|
||||
parentStepId: string | undefined;
|
||||
nextStepId: string | undefined;
|
||||
position?: { x: number; y: number };
|
||||
}) => {
|
||||
if (isLoading === true) {
|
||||
return;
|
||||
@@ -50,15 +52,18 @@ export const useCreateStep = ({
|
||||
try {
|
||||
const workflowVersionId = await getUpdatableWorkflowVersion(workflow);
|
||||
|
||||
const createdStep = (
|
||||
const workflowVersionStepChanges = (
|
||||
await createWorkflowVersionStep({
|
||||
workflowVersionId,
|
||||
stepType: newStepType,
|
||||
parentStepId,
|
||||
nextStepId,
|
||||
position,
|
||||
})
|
||||
)?.data?.createWorkflowVersionStep;
|
||||
|
||||
const createdStep = workflowVersionStepChanges?.createdStep;
|
||||
|
||||
if (!isDefined(createdStep)) {
|
||||
throw new Error("Couldn't create step");
|
||||
}
|
||||
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
import { useApolloCoreClient } from '@/object-metadata/hooks/useApolloCoreClient';
|
||||
import { useMutation } from '@apollo/client';
|
||||
import {
|
||||
CreateWorkflowVersionEdgeMutation,
|
||||
CreateWorkflowVersionEdgeMutationVariables,
|
||||
} from '~/generated-metadata/graphql';
|
||||
import { CREATE_WORKFLOW_VERSION_EDGE } from '@/workflow/graphql/mutations/createWorkflowVersionEdge';
|
||||
import { CreateWorkflowVersionEdgeInput } from '~/generated/graphql';
|
||||
import { useUpdateWorkflowVersionCache } from '@/workflow/workflow-steps/hooks/useUpdateWorkflowVersionCache';
|
||||
|
||||
export const useCreateWorkflowVersionEdge = () => {
|
||||
const apolloCoreClient = useApolloCoreClient();
|
||||
|
||||
const { updateWorkflowVersionCache } = useUpdateWorkflowVersionCache();
|
||||
|
||||
const [mutate] = useMutation<
|
||||
CreateWorkflowVersionEdgeMutation,
|
||||
CreateWorkflowVersionEdgeMutationVariables
|
||||
>(CREATE_WORKFLOW_VERSION_EDGE, { client: apolloCoreClient });
|
||||
|
||||
const createWorkflowVersionEdge = async (
|
||||
input: CreateWorkflowVersionEdgeInput,
|
||||
) => {
|
||||
const result = await mutate({ variables: { input } });
|
||||
|
||||
const workflowVersionStepChanges = result?.data?.createWorkflowVersionEdge;
|
||||
|
||||
updateWorkflowVersionCache({
|
||||
workflowVersionStepChanges,
|
||||
workflowVersionId: input.workflowVersionId,
|
||||
});
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
return { createWorkflowVersionEdge };
|
||||
};
|
||||
+10
-65
@@ -1,36 +1,25 @@
|
||||
import { useApolloCoreClient } from '@/object-metadata/hooks/useApolloCoreClient';
|
||||
import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem';
|
||||
import { useObjectMetadataItems } from '@/object-metadata/hooks/useObjectMetadataItems';
|
||||
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
|
||||
import { useGetRecordFromCache } from '@/object-record/cache/hooks/useGetRecordFromCache';
|
||||
import { updateRecordFromCache } from '@/object-record/cache/utils/updateRecordFromCache';
|
||||
import { useObjectPermissions } from '@/object-record/hooks/useObjectPermissions';
|
||||
import { CREATE_WORKFLOW_VERSION_STEP } from '@/workflow/graphql/mutations/createWorkflowVersionStep';
|
||||
import { WorkflowVersion } from '@/workflow/types/Workflow';
|
||||
import { useMutation } from '@apollo/client';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import {
|
||||
CreateWorkflowVersionStepInput,
|
||||
CreateWorkflowVersionStepMutation,
|
||||
CreateWorkflowVersionStepMutationVariables,
|
||||
} from '~/generated-metadata/graphql';
|
||||
import { useUpdateWorkflowVersionCache } from '@/workflow/workflow-steps/hooks/useUpdateWorkflowVersionCache';
|
||||
|
||||
export const useCreateWorkflowVersionStep = () => {
|
||||
const apolloCoreClient = useApolloCoreClient();
|
||||
const { objectMetadataItems } = useObjectMetadataItems();
|
||||
const { objectPermissionsByObjectMetadataId } = useObjectPermissions();
|
||||
const { objectMetadataItem } = useObjectMetadataItem({
|
||||
objectNameSingular: CoreObjectNameSingular.WorkflowVersion,
|
||||
});
|
||||
const getRecordFromCache = useGetRecordFromCache({
|
||||
objectNameSingular: CoreObjectNameSingular.WorkflowVersion,
|
||||
});
|
||||
|
||||
const { updateWorkflowVersionCache } = useUpdateWorkflowVersionCache();
|
||||
|
||||
const [mutate] = useMutation<
|
||||
CreateWorkflowVersionStepMutation,
|
||||
CreateWorkflowVersionStepMutationVariables
|
||||
>(CREATE_WORKFLOW_VERSION_STEP, {
|
||||
client: apolloCoreClient,
|
||||
});
|
||||
|
||||
const createWorkflowVersionStep = async (
|
||||
input: CreateWorkflowVersionStepInput,
|
||||
) => {
|
||||
@@ -38,57 +27,13 @@ export const useCreateWorkflowVersionStep = () => {
|
||||
variables: { input },
|
||||
});
|
||||
|
||||
const insertedStep = result?.data?.createWorkflowVersionStep;
|
||||
const workflowVersionStepChanges = result?.data?.createWorkflowVersionStep;
|
||||
|
||||
if (!isDefined(insertedStep)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const cachedRecord = getRecordFromCache<WorkflowVersion>(
|
||||
input.workflowVersionId,
|
||||
);
|
||||
|
||||
if (!isDefined(cachedRecord)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const { parentStepId, nextStepId } = input;
|
||||
|
||||
const updatedExistingSteps =
|
||||
cachedRecord.steps?.map((existingStep) => {
|
||||
if (existingStep.id === parentStepId) {
|
||||
return {
|
||||
...existingStep,
|
||||
nextStepIds: [
|
||||
...new Set([
|
||||
...(existingStep.nextStepIds?.filter(
|
||||
(id) => id !== nextStepId,
|
||||
) || []),
|
||||
insertedStep.id,
|
||||
]),
|
||||
],
|
||||
};
|
||||
}
|
||||
return existingStep;
|
||||
}) ?? [];
|
||||
|
||||
const newCachedRecord = {
|
||||
...cachedRecord,
|
||||
steps: [...updatedExistingSteps, insertedStep],
|
||||
};
|
||||
|
||||
const recordGqlFields = {
|
||||
steps: true,
|
||||
};
|
||||
|
||||
updateRecordFromCache({
|
||||
objectMetadataItems,
|
||||
objectMetadataItem,
|
||||
cache: apolloCoreClient.cache,
|
||||
record: newCachedRecord,
|
||||
recordGqlFields,
|
||||
objectPermissionsByObjectMetadataId,
|
||||
updateWorkflowVersionCache({
|
||||
workflowVersionStepChanges,
|
||||
workflowVersionId: input.workflowVersionId,
|
||||
});
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
import { WorkflowWithCurrentVersion } from '@/workflow/types/Workflow';
|
||||
import { useDeleteWorkflowVersionEdge } from '@/workflow/workflow-steps/hooks/useDeleteWorkflowVersionEdge';
|
||||
import { useState } from 'react';
|
||||
import { useGetUpdatableWorkflowVersion } from '@/workflow/hooks/useGetUpdatableWorkflowVersion';
|
||||
|
||||
export const useDeleteEdge = ({
|
||||
workflow,
|
||||
}: {
|
||||
workflow: WorkflowWithCurrentVersion;
|
||||
}) => {
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
|
||||
const { deleteWorkflowVersionEdge } = useDeleteWorkflowVersionEdge();
|
||||
|
||||
const { getUpdatableWorkflowVersion } = useGetUpdatableWorkflowVersion();
|
||||
|
||||
const deleteEdge = async ({
|
||||
source,
|
||||
target,
|
||||
}: {
|
||||
source: string;
|
||||
target: string;
|
||||
}) => {
|
||||
if (isLoading === true) {
|
||||
return;
|
||||
}
|
||||
|
||||
setIsLoading(true);
|
||||
|
||||
try {
|
||||
const workflowVersionId = await getUpdatableWorkflowVersion(workflow);
|
||||
|
||||
const deletedEdge = (
|
||||
await deleteWorkflowVersionEdge({
|
||||
workflowVersionId,
|
||||
source,
|
||||
target,
|
||||
})
|
||||
)?.data?.deleteWorkflowVersionEdge;
|
||||
|
||||
if (!deletedEdge) {
|
||||
return;
|
||||
}
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
return { deleteEdge };
|
||||
};
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
import { useApolloCoreClient } from '@/object-metadata/hooks/useApolloCoreClient';
|
||||
import { useMutation } from '@apollo/client';
|
||||
import { CreateWorkflowVersionEdgeInput } from '~/generated/graphql';
|
||||
import { DELETE_WORKFLOW_VERSION_EDGE } from '@/workflow/graphql/mutations/deleteWorkflowVersionEdge';
|
||||
import {
|
||||
DeleteWorkflowVersionEdgeMutation,
|
||||
DeleteWorkflowVersionEdgeMutationVariables,
|
||||
} from '~/generated-metadata/graphql';
|
||||
import { useUpdateWorkflowVersionCache } from '@/workflow/workflow-steps/hooks/useUpdateWorkflowVersionCache';
|
||||
|
||||
export const useDeleteWorkflowVersionEdge = () => {
|
||||
const apolloCoreClient = useApolloCoreClient();
|
||||
|
||||
const { updateWorkflowVersionCache } = useUpdateWorkflowVersionCache();
|
||||
|
||||
const [mutate] = useMutation<
|
||||
DeleteWorkflowVersionEdgeMutation,
|
||||
DeleteWorkflowVersionEdgeMutationVariables
|
||||
>(DELETE_WORKFLOW_VERSION_EDGE, { client: apolloCoreClient });
|
||||
|
||||
const deleteWorkflowVersionEdge = async (
|
||||
input: CreateWorkflowVersionEdgeInput,
|
||||
) => {
|
||||
const result = await mutate({ variables: { input } });
|
||||
|
||||
const workflowVersionStepChanges = result?.data?.deleteWorkflowVersionEdge;
|
||||
|
||||
updateWorkflowVersionCache({
|
||||
workflowVersionStepChanges,
|
||||
workflowVersionId: input.workflowVersionId,
|
||||
});
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
return { deleteWorkflowVersionEdge };
|
||||
};
|
||||
+95
@@ -0,0 +1,95 @@
|
||||
import { useApolloCoreClient } from '@/object-metadata/hooks/useApolloCoreClient';
|
||||
import { useObjectMetadataItems } from '@/object-metadata/hooks/useObjectMetadataItems';
|
||||
import { useObjectPermissions } from '@/object-record/hooks/useObjectPermissions';
|
||||
import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem';
|
||||
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
|
||||
import { useGetRecordFromCache } from '@/object-record/cache/hooks/useGetRecordFromCache';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { WorkflowVersion } from '@/workflow/types/Workflow';
|
||||
import {
|
||||
WorkflowAction,
|
||||
WorkflowVersionStepChanges,
|
||||
} from '~/generated/graphql';
|
||||
import { updateRecordFromCache } from '@/object-record/cache/utils/updateRecordFromCache';
|
||||
|
||||
export const useUpdateWorkflowVersionCache = () => {
|
||||
const apolloCoreClient = useApolloCoreClient();
|
||||
|
||||
const { objectMetadataItems } = useObjectMetadataItems();
|
||||
|
||||
const { objectPermissionsByObjectMetadataId } = useObjectPermissions();
|
||||
|
||||
const { objectMetadataItem } = useObjectMetadataItem({
|
||||
objectNameSingular: CoreObjectNameSingular.WorkflowVersion,
|
||||
});
|
||||
|
||||
const getRecordFromCache = useGetRecordFromCache({
|
||||
objectNameSingular: CoreObjectNameSingular.WorkflowVersion,
|
||||
});
|
||||
|
||||
const updateWorkflowVersionCache = ({
|
||||
workflowVersionStepChanges,
|
||||
workflowVersionId,
|
||||
}: {
|
||||
workflowVersionStepChanges: WorkflowVersionStepChanges | undefined;
|
||||
workflowVersionId: string;
|
||||
}) => {
|
||||
if (!isDefined(workflowVersionStepChanges)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const cachedRecord = getRecordFromCache<WorkflowVersion>(workflowVersionId);
|
||||
|
||||
if (!isDefined(cachedRecord)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const { triggerNextStepIds, stepsNextStepIds, createdStep, deletedStepId } =
|
||||
workflowVersionStepChanges;
|
||||
|
||||
const newCachedRecord = {
|
||||
...cachedRecord,
|
||||
trigger: isDefined(cachedRecord.trigger)
|
||||
? {
|
||||
...cachedRecord.trigger,
|
||||
nextStepIds: triggerNextStepIds,
|
||||
}
|
||||
: cachedRecord.trigger,
|
||||
steps: (cachedRecord.steps || []).map((step: WorkflowAction) => ({
|
||||
...step,
|
||||
nextStepIds: stepsNextStepIds[step.id] ?? step.nextStepIds,
|
||||
})),
|
||||
};
|
||||
|
||||
if (isDefined(createdStep)) {
|
||||
const formattedCreatedStep = {
|
||||
...createdStep,
|
||||
nextStepIds: createdStep.nextStepIds || [],
|
||||
};
|
||||
|
||||
newCachedRecord.steps.push(formattedCreatedStep);
|
||||
}
|
||||
|
||||
if (isDefined(deletedStepId)) {
|
||||
newCachedRecord.steps = newCachedRecord.steps.filter(
|
||||
(step) => step.id !== deletedStepId,
|
||||
);
|
||||
}
|
||||
|
||||
const recordGqlFields = {
|
||||
steps: true,
|
||||
trigger: true,
|
||||
};
|
||||
|
||||
updateRecordFromCache({
|
||||
objectMetadataItems,
|
||||
objectMetadataItem,
|
||||
cache: apolloCoreClient.cache,
|
||||
record: newCachedRecord,
|
||||
recordGqlFields,
|
||||
objectPermissionsByObjectMetadataId,
|
||||
});
|
||||
};
|
||||
|
||||
return { updateWorkflowVersionCache };
|
||||
};
|
||||
+6
-1
@@ -4,11 +4,16 @@ import { WorkflowVisualizerComponentInstanceContext } from '@/workflow/workflow-
|
||||
type WorkflowInsertStepIdsState = {
|
||||
parentStepId: string | undefined;
|
||||
nextStepId: string | undefined;
|
||||
position?: { x: number; y: number };
|
||||
};
|
||||
|
||||
export const workflowInsertStepIdsComponentState =
|
||||
createComponentStateV2<WorkflowInsertStepIdsState>({
|
||||
key: 'workflowInsertStepIdsComponentState',
|
||||
defaultValue: { parentStepId: undefined, nextStepId: undefined },
|
||||
defaultValue: {
|
||||
parentStepId: undefined,
|
||||
nextStepId: undefined,
|
||||
position: undefined,
|
||||
},
|
||||
componentInstanceContext: WorkflowVisualizerComponentInstanceContext,
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user