8839 workflow follow up code step (#8856)
- add readonly mode - fix falsy stepOutput computation
This commit is contained in:
@ -1571,6 +1571,8 @@ export type UpdateServerlessFunctionInput = {
|
|||||||
export type UpdateWorkflowVersionStepInput = {
|
export type UpdateWorkflowVersionStepInput = {
|
||||||
/** Step to update in JSON format */
|
/** Step to update in JSON format */
|
||||||
step: Scalars['JSON']['input'];
|
step: Scalars['JSON']['input'];
|
||||||
|
/** Boolean to check if we need to update stepOutput */
|
||||||
|
shouldUpdateStepOutput?: InputMaybe<Scalars['Boolean']['input']>;
|
||||||
/** Workflow version ID */
|
/** Workflow version ID */
|
||||||
workflowVersionId: Scalars['String']['input'];
|
workflowVersionId: Scalars['String']['input'];
|
||||||
};
|
};
|
||||||
@ -2249,4 +2251,4 @@ export const UpdateOneServerlessFunctionDocument = {"kind":"Document","definitio
|
|||||||
export const FindManyAvailablePackagesDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"FindManyAvailablePackages"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ServerlessFunctionIdInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"getAvailablePackages"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}]}]}}]} as unknown as DocumentNode<FindManyAvailablePackagesQuery, FindManyAvailablePackagesQueryVariables>;
|
export const FindManyAvailablePackagesDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"FindManyAvailablePackages"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ServerlessFunctionIdInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"getAvailablePackages"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}]}]}}]} as unknown as DocumentNode<FindManyAvailablePackagesQuery, FindManyAvailablePackagesQueryVariables>;
|
||||||
export const GetManyServerlessFunctionsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetManyServerlessFunctions"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"findManyServerlessFunctions"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"ServerlessFunctionFields"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ServerlessFunctionFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"ServerlessFunction"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"runtime"}},{"kind":"Field","name":{"kind":"Name","value":"syncStatus"}},{"kind":"Field","name":{"kind":"Name","value":"latestVersion"}},{"kind":"Field","name":{"kind":"Name","value":"latestVersionInputSchema"}},{"kind":"Field","name":{"kind":"Name","value":"publishedVersions"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"updatedAt"}}]}}]} as unknown as DocumentNode<GetManyServerlessFunctionsQuery, GetManyServerlessFunctionsQueryVariables>;
|
export const GetManyServerlessFunctionsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetManyServerlessFunctions"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"findManyServerlessFunctions"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"ServerlessFunctionFields"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ServerlessFunctionFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"ServerlessFunction"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"runtime"}},{"kind":"Field","name":{"kind":"Name","value":"syncStatus"}},{"kind":"Field","name":{"kind":"Name","value":"latestVersion"}},{"kind":"Field","name":{"kind":"Name","value":"latestVersionInputSchema"}},{"kind":"Field","name":{"kind":"Name","value":"publishedVersions"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"updatedAt"}}]}}]} as unknown as DocumentNode<GetManyServerlessFunctionsQuery, GetManyServerlessFunctionsQueryVariables>;
|
||||||
export const GetOneServerlessFunctionDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetOneServerlessFunction"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ServerlessFunctionIdInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"findOneServerlessFunction"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"ServerlessFunctionFields"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ServerlessFunctionFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"ServerlessFunction"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"runtime"}},{"kind":"Field","name":{"kind":"Name","value":"syncStatus"}},{"kind":"Field","name":{"kind":"Name","value":"latestVersion"}},{"kind":"Field","name":{"kind":"Name","value":"latestVersionInputSchema"}},{"kind":"Field","name":{"kind":"Name","value":"publishedVersions"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"updatedAt"}}]}}]} as unknown as DocumentNode<GetOneServerlessFunctionQuery, GetOneServerlessFunctionQueryVariables>;
|
export const GetOneServerlessFunctionDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetOneServerlessFunction"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ServerlessFunctionIdInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"findOneServerlessFunction"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"ServerlessFunctionFields"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ServerlessFunctionFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"ServerlessFunction"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"runtime"}},{"kind":"Field","name":{"kind":"Name","value":"syncStatus"}},{"kind":"Field","name":{"kind":"Name","value":"latestVersion"}},{"kind":"Field","name":{"kind":"Name","value":"latestVersionInputSchema"}},{"kind":"Field","name":{"kind":"Name","value":"publishedVersions"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"updatedAt"}}]}}]} as unknown as DocumentNode<GetOneServerlessFunctionQuery, GetOneServerlessFunctionQueryVariables>;
|
||||||
export const FindOneServerlessFunctionSourceCodeDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"FindOneServerlessFunctionSourceCode"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"GetServerlessFunctionSourceCodeInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"getServerlessFunctionSourceCode"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}]}]}}]} as unknown as DocumentNode<FindOneServerlessFunctionSourceCodeQuery, FindOneServerlessFunctionSourceCodeQueryVariables>;
|
export const FindOneServerlessFunctionSourceCodeDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"FindOneServerlessFunctionSourceCode"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"GetServerlessFunctionSourceCodeInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"getServerlessFunctionSourceCode"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}]}]}}]} as unknown as DocumentNode<FindOneServerlessFunctionSourceCodeQuery, FindOneServerlessFunctionSourceCodeQueryVariables>;
|
||||||
|
|||||||
@ -1279,6 +1279,8 @@ export type UpdateServerlessFunctionInput = {
|
|||||||
export type UpdateWorkflowVersionStepInput = {
|
export type UpdateWorkflowVersionStepInput = {
|
||||||
/** Step to update in JSON format */
|
/** Step to update in JSON format */
|
||||||
step: Scalars['JSON'];
|
step: Scalars['JSON'];
|
||||||
|
/** Boolean to check if we need to update stepOutput */
|
||||||
|
shouldUpdateStepOutput?: InputMaybe<Scalars['Boolean']>;
|
||||||
/** Workflow version ID */
|
/** Workflow version ID */
|
||||||
workflowVersionId: Scalars['String'];
|
workflowVersionId: Scalars['String'];
|
||||||
};
|
};
|
||||||
@ -4416,4 +4418,4 @@ export function useGetWorkspaceFromInviteHashLazyQuery(baseOptions?: Apollo.Lazy
|
|||||||
}
|
}
|
||||||
export type GetWorkspaceFromInviteHashQueryHookResult = ReturnType<typeof useGetWorkspaceFromInviteHashQuery>;
|
export type GetWorkspaceFromInviteHashQueryHookResult = ReturnType<typeof useGetWorkspaceFromInviteHashQuery>;
|
||||||
export type GetWorkspaceFromInviteHashLazyQueryHookResult = ReturnType<typeof useGetWorkspaceFromInviteHashLazyQuery>;
|
export type GetWorkspaceFromInviteHashLazyQueryHookResult = ReturnType<typeof useGetWorkspaceFromInviteHashLazyQuery>;
|
||||||
export type GetWorkspaceFromInviteHashQueryResult = Apollo.QueryResult<GetWorkspaceFromInviteHashQuery, GetWorkspaceFromInviteHashQueryVariables>;
|
export type GetWorkspaceFromInviteHashQueryResult = Apollo.QueryResult<GetWorkspaceFromInviteHashQuery, GetWorkspaceFromInviteHashQueryVariables>;
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
import { useApolloMetadataClient } from '@/object-metadata/hooks/useApolloMetadataClient';
|
import { useApolloMetadataClient } from '@/object-metadata/hooks/useApolloMetadataClient';
|
||||||
import { UPDATE_ONE_SERVERLESS_FUNCTION } from '@/settings/serverless-functions/graphql/mutations/updateOneServerlessFunction';
|
import { UPDATE_ONE_SERVERLESS_FUNCTION } from '@/settings/serverless-functions/graphql/mutations/updateOneServerlessFunction';
|
||||||
import { FIND_MANY_SERVERLESS_FUNCTIONS } from '@/settings/serverless-functions/graphql/queries/findManyServerlessFunctions';
|
import { FIND_MANY_SERVERLESS_FUNCTIONS } from '@/settings/serverless-functions/graphql/queries/findManyServerlessFunctions';
|
||||||
|
import { FIND_ONE_SERVERLESS_FUNCTION_SOURCE_CODE } from '@/settings/serverless-functions/graphql/queries/findOneServerlessFunctionSourceCode';
|
||||||
import { useMutation } from '@apollo/client';
|
import { useMutation } from '@apollo/client';
|
||||||
import { getOperationName } from '@apollo/client/utilities';
|
import { getOperationName } from '@apollo/client/utilities';
|
||||||
import {
|
import {
|
||||||
@ -26,7 +27,10 @@ export const useUpdateOneServerlessFunction = () => {
|
|||||||
input,
|
input,
|
||||||
},
|
},
|
||||||
awaitRefetchQueries: true,
|
awaitRefetchQueries: true,
|
||||||
refetchQueries: [getOperationName(FIND_MANY_SERVERLESS_FUNCTIONS) ?? ''],
|
refetchQueries: [
|
||||||
|
getOperationName(FIND_MANY_SERVERLESS_FUNCTIONS) ?? '',
|
||||||
|
getOperationName(FIND_ONE_SERVERLESS_FUNCTION_SOURCE_CODE) ?? '',
|
||||||
|
],
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -15,7 +15,6 @@ import {
|
|||||||
IconTrash,
|
IconTrash,
|
||||||
isDefined,
|
isDefined,
|
||||||
} from 'twenty-ui';
|
} from 'twenty-ui';
|
||||||
import { capitalize } from '~/utils/string/capitalize';
|
|
||||||
import { assertWorkflowWithCurrentVersionIsDefined } from '../utils/assertWorkflowWithCurrentVersionIsDefined';
|
import { assertWorkflowWithCurrentVersionIsDefined } from '../utils/assertWorkflowWithCurrentVersionIsDefined';
|
||||||
|
|
||||||
export const RecordShowPageWorkflowHeader = ({
|
export const RecordShowPageWorkflowHeader = ({
|
||||||
@ -73,17 +72,6 @@ export const RecordShowPageWorkflowHeader = ({
|
|||||||
workflowVersionId: workflowWithCurrentVersion.currentVersion.id,
|
workflowVersionId: workflowWithCurrentVersion.currentVersion.id,
|
||||||
workflowName: workflowWithCurrentVersion.name,
|
workflowName: workflowWithCurrentVersion.name,
|
||||||
});
|
});
|
||||||
|
|
||||||
enqueueSnackBar('', {
|
|
||||||
variant: SnackBarVariant.Success,
|
|
||||||
title: `${capitalize(workflowWithCurrentVersion.name)} starting...`,
|
|
||||||
icon: (
|
|
||||||
<IconSettingsAutomation
|
|
||||||
size={16}
|
|
||||||
color={theme.snackBar.success.color}
|
|
||||||
/>
|
|
||||||
),
|
|
||||||
});
|
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
|||||||
@ -14,7 +14,10 @@ export const useUpdateStep = ({
|
|||||||
const { getUpdatableWorkflowVersion } = useGetUpdatableWorkflowVersion();
|
const { getUpdatableWorkflowVersion } = useGetUpdatableWorkflowVersion();
|
||||||
const { updateWorkflowVersionStep } = useUpdateWorkflowVersionStep();
|
const { updateWorkflowVersionStep } = useUpdateWorkflowVersionStep();
|
||||||
|
|
||||||
const updateStep = async <T extends WorkflowStep>(updatedStep: T) => {
|
const updateStep = async <T extends WorkflowStep>(
|
||||||
|
updatedStep: T,
|
||||||
|
shouldUpdateStepOutput = true,
|
||||||
|
) => {
|
||||||
if (!isDefined(workflow.currentVersion)) {
|
if (!isDefined(workflow.currentVersion)) {
|
||||||
throw new Error('Can not update an undefined workflow version.');
|
throw new Error('Can not update an undefined workflow version.');
|
||||||
}
|
}
|
||||||
@ -23,6 +26,7 @@ export const useUpdateStep = ({
|
|||||||
await updateWorkflowVersionStep({
|
await updateWorkflowVersionStep({
|
||||||
workflowVersionId: workflowVersion.id,
|
workflowVersionId: workflowVersion.id,
|
||||||
step: updatedStep,
|
step: updatedStep,
|
||||||
|
shouldUpdateStepOutput,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -5,7 +5,7 @@ import { mergeDefaultFunctionInputAndFunctionInput } from '@/workflow/utils/merg
|
|||||||
import { setNestedValue } from '@/workflow/utils/setNestedValue';
|
import { setNestedValue } from '@/workflow/utils/setNestedValue';
|
||||||
import { useTheme } from '@emotion/react';
|
import { useTheme } from '@emotion/react';
|
||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
import { Fragment, ReactNode, useState } from 'react';
|
import { Fragment, ReactNode, useEffect, useState } from 'react';
|
||||||
import {
|
import {
|
||||||
CodeEditor,
|
CodeEditor,
|
||||||
HorizontalSeparator,
|
HorizontalSeparator,
|
||||||
@ -63,7 +63,10 @@ type WorkflowEditActionFormServerlessFunctionProps = {
|
|||||||
}
|
}
|
||||||
| {
|
| {
|
||||||
readonly?: false;
|
readonly?: false;
|
||||||
onActionUpdate: (action: WorkflowCodeAction) => void;
|
onActionUpdate: (
|
||||||
|
action: WorkflowCodeAction,
|
||||||
|
shouldUpdateStepOutput?: boolean,
|
||||||
|
) => void;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -88,9 +91,16 @@ export const WorkflowEditActionFormServerlessFunction = ({
|
|||||||
id: serverlessFunctionId,
|
id: serverlessFunctionId,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const [functionInput, setFunctionInput] =
|
||||||
|
useState<ServerlessFunctionInputFormData>(
|
||||||
|
action.settings.input.serverlessFunctionInput,
|
||||||
|
);
|
||||||
|
|
||||||
const { formValues, setFormValues, loading } =
|
const { formValues, setFormValues, loading } =
|
||||||
useServerlessFunctionUpdateFormState(serverlessFunctionId);
|
useServerlessFunctionUpdateFormState(serverlessFunctionId);
|
||||||
|
|
||||||
|
const headerTitle = action.name || 'Code - Serverless Function';
|
||||||
|
|
||||||
const save = async () => {
|
const save = async () => {
|
||||||
try {
|
try {
|
||||||
await updateOneServerlessFunction({
|
await updateOneServerlessFunction({
|
||||||
@ -112,6 +122,9 @@ export const WorkflowEditActionFormServerlessFunction = ({
|
|||||||
const handleSave = usePreventOverlapCallback(save, 1000);
|
const handleSave = usePreventOverlapCallback(save, 1000);
|
||||||
|
|
||||||
const onCodeChange = async (value: string) => {
|
const onCodeChange = async (value: string) => {
|
||||||
|
if (actionOptions.readonly === true) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
setFormValues((prevState) => ({
|
setFormValues((prevState) => ({
|
||||||
...prevState,
|
...prevState,
|
||||||
code: { ...prevState.code, [INDEX_FILE_PATH]: value },
|
code: { ...prevState.code, [INDEX_FILE_PATH]: value },
|
||||||
@ -121,6 +134,9 @@ export const WorkflowEditActionFormServerlessFunction = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
const updateFunctionInputSchema = async () => {
|
const updateFunctionInputSchema = async () => {
|
||||||
|
if (actionOptions.readonly === true) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
const sourceCode = formValues.code?.[INDEX_FILE_PATH];
|
const sourceCode = formValues.code?.[INDEX_FILE_PATH];
|
||||||
if (!isDefined(sourceCode)) {
|
if (!isDefined(sourceCode)) {
|
||||||
return;
|
return;
|
||||||
@ -141,27 +157,25 @@ export const WorkflowEditActionFormServerlessFunction = ({
|
|||||||
100,
|
100,
|
||||||
);
|
);
|
||||||
|
|
||||||
const [functionInput, setFunctionInput] =
|
|
||||||
useState<ServerlessFunctionInputFormData>(
|
|
||||||
action.settings.input.serverlessFunctionInput,
|
|
||||||
);
|
|
||||||
|
|
||||||
const updateFunctionInput = useDebouncedCallback(
|
const updateFunctionInput = useDebouncedCallback(
|
||||||
async (newFunctionInput: object) => {
|
async (newFunctionInput: object, shouldUpdateStepOutput = true) => {
|
||||||
if (actionOptions.readonly === true) {
|
if (actionOptions.readonly === true) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
actionOptions.onActionUpdate({
|
actionOptions.onActionUpdate(
|
||||||
...action,
|
{
|
||||||
settings: {
|
...action,
|
||||||
...action.settings,
|
settings: {
|
||||||
input: {
|
...action.settings,
|
||||||
...action.settings.input,
|
input: {
|
||||||
serverlessFunctionInput: newFunctionInput,
|
...action.settings.input,
|
||||||
|
serverlessFunctionInput: newFunctionInput,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
shouldUpdateStepOutput,
|
||||||
|
);
|
||||||
},
|
},
|
||||||
1_000,
|
1_000,
|
||||||
);
|
);
|
||||||
@ -171,7 +185,7 @@ export const WorkflowEditActionFormServerlessFunction = ({
|
|||||||
|
|
||||||
setFunctionInput(updatedFunctionInput);
|
setFunctionInput(updatedFunctionInput);
|
||||||
|
|
||||||
await updateFunctionInput(updatedFunctionInput);
|
await updateFunctionInput(updatedFunctionInput, false);
|
||||||
};
|
};
|
||||||
|
|
||||||
const renderFields = (
|
const renderFields = (
|
||||||
@ -230,10 +244,6 @@ export const WorkflowEditActionFormServerlessFunction = ({
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const headerTitle = isDefined(action.name)
|
|
||||||
? action.name
|
|
||||||
: 'Code - Serverless Function';
|
|
||||||
|
|
||||||
const handleEditorDidMount = async (
|
const handleEditorDidMount = async (
|
||||||
editor: editor.IStandaloneCodeEditor,
|
editor: editor.IStandaloneCodeEditor,
|
||||||
monaco: Monaco,
|
monaco: Monaco,
|
||||||
@ -252,10 +262,13 @@ export const WorkflowEditActionFormServerlessFunction = ({
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
actionOptions?.onActionUpdate({
|
actionOptions?.onActionUpdate(
|
||||||
...action,
|
{
|
||||||
...actionUpdate,
|
...action,
|
||||||
});
|
...actionUpdate,
|
||||||
|
},
|
||||||
|
false,
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const checkWorkflowUpdatable = async () => {
|
const checkWorkflowUpdatable = async () => {
|
||||||
@ -265,6 +278,10 @@ export const WorkflowEditActionFormServerlessFunction = ({
|
|||||||
await getUpdatableWorkflowVersion(workflow);
|
await getUpdatableWorkflowVersion(workflow);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setFunctionInput(action.settings.input.serverlessFunctionInput);
|
||||||
|
}, [action]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
!loading && (
|
!loading && (
|
||||||
<WorkflowEditGenericFormBase
|
<WorkflowEditGenericFormBase
|
||||||
@ -285,6 +302,10 @@ export const WorkflowEditActionFormServerlessFunction = ({
|
|||||||
await onCodeChange(value);
|
await onCodeChange(value);
|
||||||
}}
|
}}
|
||||||
onMount={handleEditorDidMount}
|
onMount={handleEditorDidMount}
|
||||||
|
options={{
|
||||||
|
readOnly: actionOptions.readonly,
|
||||||
|
domReadOnly: actionOptions.readonly,
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
{renderFields(functionInput)}
|
{renderFields(functionInput)}
|
||||||
</WorkflowEditGenericFormBase>
|
</WorkflowEditGenericFormBase>
|
||||||
|
|||||||
@ -319,6 +319,7 @@ export class LambdaDriver implements ServerlessDriver {
|
|||||||
await this.waitFunctionUpdates(functionToExecute.id, 10);
|
await this.waitFunctionUpdates(functionToExecute.id, 10);
|
||||||
|
|
||||||
const startTime = Date.now();
|
const startTime = Date.now();
|
||||||
|
|
||||||
const params: InvokeCommandInput = {
|
const params: InvokeCommandInput = {
|
||||||
FunctionName: functionName,
|
FunctionName: functionName,
|
||||||
Payload: JSON.stringify(payload),
|
Payload: JSON.stringify(payload),
|
||||||
|
|||||||
@ -17,4 +17,11 @@ export class UpdateWorkflowVersionStepInput {
|
|||||||
nullable: false,
|
nullable: false,
|
||||||
})
|
})
|
||||||
step: WorkflowAction;
|
step: WorkflowAction;
|
||||||
|
|
||||||
|
@Field(() => Boolean, {
|
||||||
|
description: 'Boolean to check if we need to update stepOutput',
|
||||||
|
nullable: true,
|
||||||
|
defaultValue: true,
|
||||||
|
})
|
||||||
|
shouldUpdateStepOutput: boolean;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -36,12 +36,18 @@ export class WorkflowVersionStepResolver {
|
|||||||
@Mutation(() => WorkflowActionDTO)
|
@Mutation(() => WorkflowActionDTO)
|
||||||
async updateWorkflowVersionStep(
|
async updateWorkflowVersionStep(
|
||||||
@AuthWorkspace() { id: workspaceId }: Workspace,
|
@AuthWorkspace() { id: workspaceId }: Workspace,
|
||||||
@Args('input') { step, workflowVersionId }: UpdateWorkflowVersionStepInput,
|
@Args('input')
|
||||||
|
{
|
||||||
|
step,
|
||||||
|
workflowVersionId,
|
||||||
|
shouldUpdateStepOutput,
|
||||||
|
}: UpdateWorkflowVersionStepInput,
|
||||||
): Promise<WorkflowActionDTO> {
|
): Promise<WorkflowActionDTO> {
|
||||||
return this.workflowVersionStepWorkspaceService.updateWorkflowVersionStep({
|
return this.workflowVersionStepWorkspaceService.updateWorkflowVersionStep({
|
||||||
workspaceId,
|
workspaceId,
|
||||||
workflowVersionId,
|
workflowVersionId,
|
||||||
step,
|
step,
|
||||||
|
shouldUpdateStepOutput,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -45,9 +45,9 @@ export class WorkspaceEventEmitter {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public emitCustomBatchEvent(
|
public emitCustomBatchEvent<T extends object>(
|
||||||
eventName: CustomEventName,
|
eventName: CustomEventName,
|
||||||
events: object[],
|
events: T[],
|
||||||
workspaceId: string,
|
workspaceId: string,
|
||||||
) {
|
) {
|
||||||
if (!events.length) {
|
if (!events.length) {
|
||||||
|
|||||||
@ -245,10 +245,12 @@ export class WorkflowVersionStepWorkspaceService {
|
|||||||
workspaceId,
|
workspaceId,
|
||||||
workflowVersionId,
|
workflowVersionId,
|
||||||
step,
|
step,
|
||||||
|
shouldUpdateStepOutput,
|
||||||
}: {
|
}: {
|
||||||
workspaceId: string;
|
workspaceId: string;
|
||||||
workflowVersionId: string;
|
workflowVersionId: string;
|
||||||
step: WorkflowAction;
|
step: WorkflowAction;
|
||||||
|
shouldUpdateStepOutput: boolean;
|
||||||
}): Promise<WorkflowAction> {
|
}): Promise<WorkflowAction> {
|
||||||
const workflowVersionRepository =
|
const workflowVersionRepository =
|
||||||
await this.twentyORMManager.getRepository<WorkflowVersionWorkspaceEntity>(
|
await this.twentyORMManager.getRepository<WorkflowVersionWorkspaceEntity>(
|
||||||
@ -275,10 +277,12 @@ export class WorkflowVersionStepWorkspaceService {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const enrichedNewStep = await this.enrichOutputSchema({
|
const enrichedNewStep = shouldUpdateStepOutput
|
||||||
step,
|
? await this.enrichOutputSchema({
|
||||||
workspaceId,
|
step,
|
||||||
});
|
workspaceId,
|
||||||
|
})
|
||||||
|
: step;
|
||||||
|
|
||||||
const updatedSteps = workflowVersion.steps.map((existingStep) => {
|
const updatedSteps = workflowVersion.steps.map((existingStep) => {
|
||||||
if (existingStep.id === step.id) {
|
if (existingStep.id === step.id) {
|
||||||
|
|||||||
@ -226,6 +226,7 @@ export class WorkflowBuilderWorkspaceService {
|
|||||||
|
|
||||||
const inputSchema =
|
const inputSchema =
|
||||||
codeIntrospectionService.getFunctionInputSchema(sourceCode);
|
codeIntrospectionService.getFunctionInputSchema(sourceCode);
|
||||||
|
|
||||||
const fakeFunctionInput =
|
const fakeFunctionInput =
|
||||||
codeIntrospectionService.generateInputData(inputSchema);
|
codeIntrospectionService.generateInputData(inputSchema);
|
||||||
|
|
||||||
@ -233,7 +234,7 @@ export class WorkflowBuilderWorkspaceService {
|
|||||||
await serverlessFunctionService.executeOneServerlessFunction(
|
await serverlessFunctionService.executeOneServerlessFunction(
|
||||||
serverlessFunctionId,
|
serverlessFunctionId,
|
||||||
workspaceId,
|
workspaceId,
|
||||||
fakeFunctionInput,
|
Object.values(fakeFunctionInput)?.[0] || {},
|
||||||
serverlessFunctionVersion,
|
serverlessFunctionVersion,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@ -35,7 +35,8 @@ export class CodeWorkflowAction implements WorkflowAction {
|
|||||||
await this.serverlessFunctionService.executeOneServerlessFunction(
|
await this.serverlessFunctionService.executeOneServerlessFunction(
|
||||||
workflowActionInput.serverlessFunctionId,
|
workflowActionInput.serverlessFunctionId,
|
||||||
workspaceId,
|
workspaceId,
|
||||||
workflowActionInput.serverlessFunctionInput,
|
Object.values(workflowActionInput.serverlessFunctionInput)?.[0] || {},
|
||||||
|
workflowActionInput.serverlessFunctionVersion,
|
||||||
);
|
);
|
||||||
|
|
||||||
if (result.error) {
|
if (result.error) {
|
||||||
|
|||||||
@ -8,6 +8,7 @@ import {
|
|||||||
WorkflowVersionBatchEvent,
|
WorkflowVersionBatchEvent,
|
||||||
WorkflowVersionEventType,
|
WorkflowVersionEventType,
|
||||||
} from 'src/modules/workflow/workflow-status/jobs/workflow-statuses-update.job';
|
} from 'src/modules/workflow/workflow-status/jobs/workflow-statuses-update.job';
|
||||||
|
import { ServerlessFunctionService } from 'src/engine/metadata-modules/serverless-function/serverless-function.service';
|
||||||
|
|
||||||
describe('WorkflowStatusesUpdate', () => {
|
describe('WorkflowStatusesUpdate', () => {
|
||||||
let job: WorkflowStatusesUpdateJob;
|
let job: WorkflowStatusesUpdateJob;
|
||||||
@ -21,6 +22,10 @@ describe('WorkflowStatusesUpdate', () => {
|
|||||||
getRepository: jest.fn().mockResolvedValue(mockWorkflowRepository),
|
getRepository: jest.fn().mockResolvedValue(mockWorkflowRepository),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const mockServerlessFunctionService = {
|
||||||
|
publishOneServerlessFunction: jest.fn(),
|
||||||
|
};
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
const module: TestingModule = await Test.createTestingModule({
|
const module: TestingModule = await Test.createTestingModule({
|
||||||
providers: [
|
providers: [
|
||||||
@ -29,6 +34,10 @@ describe('WorkflowStatusesUpdate', () => {
|
|||||||
provide: TwentyORMManager,
|
provide: TwentyORMManager,
|
||||||
useValue: mockTwentyORMManager,
|
useValue: mockTwentyORMManager,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
provide: ServerlessFunctionService,
|
||||||
|
useValue: mockServerlessFunctionService,
|
||||||
|
},
|
||||||
],
|
],
|
||||||
}).compile();
|
}).compile();
|
||||||
|
|
||||||
@ -94,6 +103,7 @@ describe('WorkflowStatusesUpdate', () => {
|
|||||||
statusUpdates: [
|
statusUpdates: [
|
||||||
{
|
{
|
||||||
workflowId: '1',
|
workflowId: '1',
|
||||||
|
workflowVersionId: '1',
|
||||||
previousStatus: WorkflowVersionStatus.ACTIVE,
|
previousStatus: WorkflowVersionStatus.ACTIVE,
|
||||||
newStatus: WorkflowVersionStatus.ACTIVE,
|
newStatus: WorkflowVersionStatus.ACTIVE,
|
||||||
},
|
},
|
||||||
@ -108,7 +118,7 @@ describe('WorkflowStatusesUpdate', () => {
|
|||||||
|
|
||||||
await job.handle(event);
|
await job.handle(event);
|
||||||
|
|
||||||
expect(mockWorkflowRepository.findOneOrFail).toHaveBeenCalledTimes(1);
|
expect(mockWorkflowRepository.findOneOrFail).toHaveBeenCalledTimes(2);
|
||||||
expect(mockWorkflowRepository.update).toHaveBeenCalledTimes(0);
|
expect(mockWorkflowRepository.update).toHaveBeenCalledTimes(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -119,6 +129,7 @@ describe('WorkflowStatusesUpdate', () => {
|
|||||||
statusUpdates: [
|
statusUpdates: [
|
||||||
{
|
{
|
||||||
workflowId: '1',
|
workflowId: '1',
|
||||||
|
workflowVersionId: '1',
|
||||||
previousStatus: WorkflowVersionStatus.ACTIVE,
|
previousStatus: WorkflowVersionStatus.ACTIVE,
|
||||||
newStatus: WorkflowVersionStatus.DRAFT,
|
newStatus: WorkflowVersionStatus.DRAFT,
|
||||||
},
|
},
|
||||||
@ -133,7 +144,7 @@ describe('WorkflowStatusesUpdate', () => {
|
|||||||
|
|
||||||
await job.handle(event);
|
await job.handle(event);
|
||||||
|
|
||||||
expect(mockWorkflowRepository.findOneOrFail).toHaveBeenCalledTimes(1);
|
expect(mockWorkflowRepository.findOneOrFail).toHaveBeenCalledTimes(2);
|
||||||
expect(mockWorkflowRepository.update).toHaveBeenCalledTimes(0);
|
expect(mockWorkflowRepository.update).toHaveBeenCalledTimes(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -144,6 +155,7 @@ describe('WorkflowStatusesUpdate', () => {
|
|||||||
statusUpdates: [
|
statusUpdates: [
|
||||||
{
|
{
|
||||||
workflowId: '1',
|
workflowId: '1',
|
||||||
|
workflowVersionId: '1',
|
||||||
previousStatus: WorkflowVersionStatus.DEACTIVATED,
|
previousStatus: WorkflowVersionStatus.DEACTIVATED,
|
||||||
newStatus: WorkflowVersionStatus.ACTIVE,
|
newStatus: WorkflowVersionStatus.ACTIVE,
|
||||||
},
|
},
|
||||||
@ -158,7 +170,7 @@ describe('WorkflowStatusesUpdate', () => {
|
|||||||
|
|
||||||
await job.handle(event);
|
await job.handle(event);
|
||||||
|
|
||||||
expect(mockWorkflowRepository.findOneOrFail).toHaveBeenCalledTimes(1);
|
expect(mockWorkflowRepository.findOneOrFail).toHaveBeenCalledTimes(2);
|
||||||
expect(mockWorkflowRepository.update).toHaveBeenCalledWith(
|
expect(mockWorkflowRepository.update).toHaveBeenCalledWith(
|
||||||
{ id: '1' },
|
{ id: '1' },
|
||||||
{ statuses: [WorkflowStatus.ACTIVE] },
|
{ statuses: [WorkflowStatus.ACTIVE] },
|
||||||
@ -172,6 +184,7 @@ describe('WorkflowStatusesUpdate', () => {
|
|||||||
statusUpdates: [
|
statusUpdates: [
|
||||||
{
|
{
|
||||||
workflowId: '1',
|
workflowId: '1',
|
||||||
|
workflowVersionId: '1',
|
||||||
previousStatus: WorkflowVersionStatus.ACTIVE,
|
previousStatus: WorkflowVersionStatus.ACTIVE,
|
||||||
newStatus: WorkflowVersionStatus.DEACTIVATED,
|
newStatus: WorkflowVersionStatus.DEACTIVATED,
|
||||||
},
|
},
|
||||||
@ -186,7 +199,7 @@ describe('WorkflowStatusesUpdate', () => {
|
|||||||
|
|
||||||
await job.handle(event);
|
await job.handle(event);
|
||||||
|
|
||||||
expect(mockWorkflowRepository.findOneOrFail).toHaveBeenCalledTimes(1);
|
expect(mockWorkflowRepository.findOneOrFail).toHaveBeenCalledTimes(2);
|
||||||
expect(mockWorkflowRepository.update).toHaveBeenCalledWith(
|
expect(mockWorkflowRepository.update).toHaveBeenCalledWith(
|
||||||
{ id: '1' },
|
{ id: '1' },
|
||||||
{ statuses: [WorkflowStatus.DEACTIVATED] },
|
{ statuses: [WorkflowStatus.DEACTIVATED] },
|
||||||
@ -200,6 +213,7 @@ describe('WorkflowStatusesUpdate', () => {
|
|||||||
statusUpdates: [
|
statusUpdates: [
|
||||||
{
|
{
|
||||||
workflowId: '1',
|
workflowId: '1',
|
||||||
|
workflowVersionId: '1',
|
||||||
previousStatus: WorkflowVersionStatus.DRAFT,
|
previousStatus: WorkflowVersionStatus.DRAFT,
|
||||||
newStatus: WorkflowVersionStatus.ACTIVE,
|
newStatus: WorkflowVersionStatus.ACTIVE,
|
||||||
},
|
},
|
||||||
@ -214,7 +228,7 @@ describe('WorkflowStatusesUpdate', () => {
|
|||||||
|
|
||||||
await job.handle(event);
|
await job.handle(event);
|
||||||
|
|
||||||
expect(mockWorkflowRepository.findOneOrFail).toHaveBeenCalledTimes(1);
|
expect(mockWorkflowRepository.findOneOrFail).toHaveBeenCalledTimes(2);
|
||||||
expect(mockWorkflowRepository.update).toHaveBeenCalledWith(
|
expect(mockWorkflowRepository.update).toHaveBeenCalledWith(
|
||||||
{ id: '1' },
|
{ id: '1' },
|
||||||
{ statuses: [WorkflowStatus.ACTIVE] },
|
{ statuses: [WorkflowStatus.ACTIVE] },
|
||||||
|
|||||||
@ -4,11 +4,21 @@ import { Process } from 'src/engine/core-modules/message-queue/decorators/proces
|
|||||||
import { Processor } from 'src/engine/core-modules/message-queue/decorators/processor.decorator';
|
import { Processor } from 'src/engine/core-modules/message-queue/decorators/processor.decorator';
|
||||||
import { MessageQueue } from 'src/engine/core-modules/message-queue/message-queue.constants';
|
import { MessageQueue } from 'src/engine/core-modules/message-queue/message-queue.constants';
|
||||||
import { TwentyORMManager } from 'src/engine/twenty-orm/twenty-orm.manager';
|
import { TwentyORMManager } from 'src/engine/twenty-orm/twenty-orm.manager';
|
||||||
import { WorkflowVersionStatus } from 'src/modules/workflow/common/standard-objects/workflow-version.workspace-entity';
|
import {
|
||||||
|
WorkflowVersionStatus,
|
||||||
|
WorkflowVersionWorkspaceEntity,
|
||||||
|
} from 'src/modules/workflow/common/standard-objects/workflow-version.workspace-entity';
|
||||||
import { WorkflowWorkspaceEntity } from 'src/modules/workflow/common/standard-objects/workflow.workspace-entity';
|
import { WorkflowWorkspaceEntity } from 'src/modules/workflow/common/standard-objects/workflow.workspace-entity';
|
||||||
import { getStatusCombinationFromArray } from 'src/modules/workflow/workflow-status/utils/get-status-combination-from-array.util';
|
import { getStatusCombinationFromArray } from 'src/modules/workflow/workflow-status/utils/get-status-combination-from-array.util';
|
||||||
import { getStatusCombinationFromUpdate } from 'src/modules/workflow/workflow-status/utils/get-status-combination-from-update.util';
|
import { getStatusCombinationFromUpdate } from 'src/modules/workflow/workflow-status/utils/get-status-combination-from-update.util';
|
||||||
import { getWorkflowStatusesFromCombination } from 'src/modules/workflow/workflow-status/utils/get-statuses-from-combination.util';
|
import { getWorkflowStatusesFromCombination } from 'src/modules/workflow/workflow-status/utils/get-statuses-from-combination.util';
|
||||||
|
import { ServerlessFunctionService } from 'src/engine/metadata-modules/serverless-function/serverless-function.service';
|
||||||
|
import {
|
||||||
|
WorkflowAction,
|
||||||
|
WorkflowActionType,
|
||||||
|
} from 'src/modules/workflow/workflow-executor/workflow-actions/types/workflow-action.type';
|
||||||
|
import { isDefined } from 'src/utils/is-defined';
|
||||||
|
import { WorkspaceRepository } from 'src/engine/twenty-orm/repository/workspace.repository';
|
||||||
|
|
||||||
export enum WorkflowVersionEventType {
|
export enum WorkflowVersionEventType {
|
||||||
CREATE = 'CREATE',
|
CREATE = 'CREATE',
|
||||||
@ -32,6 +42,7 @@ export type WorkflowVersionBatchCreateEvent = {
|
|||||||
|
|
||||||
export type WorkflowVersionStatusUpdate = {
|
export type WorkflowVersionStatusUpdate = {
|
||||||
workflowId: string;
|
workflowId: string;
|
||||||
|
workflowVersionId: string;
|
||||||
previousStatus: WorkflowVersionStatus;
|
previousStatus: WorkflowVersionStatus;
|
||||||
newStatus: WorkflowVersionStatus;
|
newStatus: WorkflowVersionStatus;
|
||||||
};
|
};
|
||||||
@ -48,7 +59,10 @@ export type WorkflowVersionBatchDelete = {
|
|||||||
|
|
||||||
@Processor({ queueName: MessageQueue.workflowQueue, scope: Scope.REQUEST })
|
@Processor({ queueName: MessageQueue.workflowQueue, scope: Scope.REQUEST })
|
||||||
export class WorkflowStatusesUpdateJob {
|
export class WorkflowStatusesUpdateJob {
|
||||||
constructor(private readonly twentyORMManager: TwentyORMManager) {}
|
constructor(
|
||||||
|
private readonly twentyORMManager: TwentyORMManager,
|
||||||
|
private readonly serverlessFunctionService: ServerlessFunctionService,
|
||||||
|
) {}
|
||||||
|
|
||||||
@Process(WorkflowStatusesUpdateJob.name)
|
@Process(WorkflowStatusesUpdateJob.name)
|
||||||
async handle(event: WorkflowVersionBatchEvent): Promise<void> {
|
async handle(event: WorkflowVersionBatchEvent): Promise<void> {
|
||||||
@ -63,7 +77,10 @@ export class WorkflowStatusesUpdateJob {
|
|||||||
case WorkflowVersionEventType.STATUS_UPDATE:
|
case WorkflowVersionEventType.STATUS_UPDATE:
|
||||||
await Promise.all(
|
await Promise.all(
|
||||||
event.statusUpdates.map((statusUpdate) =>
|
event.statusUpdates.map((statusUpdate) =>
|
||||||
this.handleWorkflowVersionStatusUpdated(statusUpdate),
|
this.handleWorkflowVersionStatusUpdated(
|
||||||
|
statusUpdate,
|
||||||
|
event.workspaceId,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
@ -119,20 +136,92 @@ export class WorkflowStatusesUpdateJob {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async handlePublishServerlessFunction({
|
||||||
|
statusUpdate,
|
||||||
|
workspaceId,
|
||||||
|
workflowVersion,
|
||||||
|
workflowVersionRepository,
|
||||||
|
}: {
|
||||||
|
statusUpdate: WorkflowVersionStatusUpdate;
|
||||||
|
workspaceId: string;
|
||||||
|
workflowVersion: WorkflowVersionWorkspaceEntity;
|
||||||
|
workflowVersionRepository: WorkspaceRepository<WorkflowVersionWorkspaceEntity>;
|
||||||
|
}) {
|
||||||
|
const shouldComputeNewSteps =
|
||||||
|
statusUpdate.newStatus === WorkflowVersionStatus.ACTIVE &&
|
||||||
|
isDefined(workflowVersion.steps) &&
|
||||||
|
workflowVersion.steps.filter(
|
||||||
|
(step) => step.type === WorkflowActionType.CODE,
|
||||||
|
).length > 0;
|
||||||
|
|
||||||
|
if (shouldComputeNewSteps) {
|
||||||
|
const newSteps: WorkflowAction[] = [];
|
||||||
|
|
||||||
|
for (const step of workflowVersion.steps || []) {
|
||||||
|
const newStep = { ...step };
|
||||||
|
|
||||||
|
if (step.type === WorkflowActionType.CODE) {
|
||||||
|
let serverlessFunction;
|
||||||
|
|
||||||
|
try {
|
||||||
|
serverlessFunction =
|
||||||
|
await this.serverlessFunctionService.publishOneServerlessFunction(
|
||||||
|
step.settings.input.serverlessFunctionId,
|
||||||
|
workspaceId,
|
||||||
|
);
|
||||||
|
} catch (e) {
|
||||||
|
serverlessFunction = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (serverlessFunction) {
|
||||||
|
const newStepSettings = { ...step.settings };
|
||||||
|
|
||||||
|
newStepSettings.input.serverlessFunctionVersion =
|
||||||
|
serverlessFunction.latestVersion;
|
||||||
|
|
||||||
|
newStep.settings = newStepSettings;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
newSteps.push(newStep);
|
||||||
|
}
|
||||||
|
|
||||||
|
await workflowVersionRepository.update(statusUpdate.workflowVersionId, {
|
||||||
|
steps: newSteps,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private async handleWorkflowVersionStatusUpdated(
|
private async handleWorkflowVersionStatusUpdated(
|
||||||
statusUpdate: WorkflowVersionStatusUpdate,
|
statusUpdate: WorkflowVersionStatusUpdate,
|
||||||
|
workspaceId: string,
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
const workflowRepository =
|
const workflowRepository =
|
||||||
await this.twentyORMManager.getRepository<WorkflowWorkspaceEntity>(
|
await this.twentyORMManager.getRepository<WorkflowWorkspaceEntity>(
|
||||||
'workflow',
|
'workflow',
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const workflowVersionRepository =
|
||||||
|
await this.twentyORMManager.getRepository<WorkflowVersionWorkspaceEntity>(
|
||||||
|
'workflowVersion',
|
||||||
|
);
|
||||||
|
|
||||||
const workflow = await workflowRepository.findOneOrFail({
|
const workflow = await workflowRepository.findOneOrFail({
|
||||||
where: {
|
where: {
|
||||||
id: statusUpdate.workflowId,
|
id: statusUpdate.workflowId,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const workflowVersion = await workflowVersionRepository.findOneOrFail({
|
||||||
|
where: { id: statusUpdate.workflowVersionId },
|
||||||
|
});
|
||||||
|
|
||||||
|
await this.handlePublishServerlessFunction({
|
||||||
|
workflowVersion,
|
||||||
|
workflowVersionRepository,
|
||||||
|
workspaceId,
|
||||||
|
statusUpdate,
|
||||||
|
});
|
||||||
|
|
||||||
const currentWorkflowStatusCombination = getStatusCombinationFromArray(
|
const currentWorkflowStatusCombination = getStatusCombinationFromArray(
|
||||||
workflow.statuses || [],
|
workflow.statuses || [],
|
||||||
);
|
);
|
||||||
|
|||||||
@ -2,8 +2,10 @@ import { Module } from '@nestjs/common';
|
|||||||
|
|
||||||
import { WorkflowStatusesUpdateJob } from 'src/modules/workflow/workflow-status/jobs/workflow-statuses-update.job';
|
import { WorkflowStatusesUpdateJob } from 'src/modules/workflow/workflow-status/jobs/workflow-statuses-update.job';
|
||||||
import { WorkflowVersionStatusListener } from 'src/modules/workflow/workflow-status/listeners/workflow-version-status.listener';
|
import { WorkflowVersionStatusListener } from 'src/modules/workflow/workflow-status/listeners/workflow-version-status.listener';
|
||||||
|
import { ServerlessFunctionModule } from 'src/engine/metadata-modules/serverless-function/serverless-function.module';
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
|
imports: [ServerlessFunctionModule],
|
||||||
providers: [WorkflowStatusesUpdateJob, WorkflowVersionStatusListener],
|
providers: [WorkflowStatusesUpdateJob, WorkflowVersionStatusListener],
|
||||||
})
|
})
|
||||||
export class WorkflowStatusModule {}
|
export class WorkflowStatusModule {}
|
||||||
|
|||||||
@ -28,6 +28,7 @@ import { assertNever } from 'src/utils/assert';
|
|||||||
import { DatabaseEventAction } from 'src/engine/api/graphql/graphql-query-runner/enums/database-event-action';
|
import { DatabaseEventAction } from 'src/engine/api/graphql/graphql-query-runner/enums/database-event-action';
|
||||||
import { WORKFLOW_VERSION_STATUS_UPDATED } from 'src/modules/workflow/workflow-status/constants/workflow-version-status-updated.constants';
|
import { WORKFLOW_VERSION_STATUS_UPDATED } from 'src/modules/workflow/workflow-status/constants/workflow-version-status-updated.constants';
|
||||||
import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
|
import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
|
||||||
|
import { WorkflowVersionStatusUpdate } from 'src/modules/workflow/workflow-status/jobs/workflow-statuses-update.job';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class WorkflowTriggerWorkspaceService {
|
export class WorkflowTriggerWorkspaceService {
|
||||||
@ -387,11 +388,12 @@ export class WorkflowTriggerWorkspaceService {
|
|||||||
workspaceId,
|
workspaceId,
|
||||||
});
|
});
|
||||||
|
|
||||||
this.workspaceEventEmitter.emitCustomBatchEvent(
|
this.workspaceEventEmitter.emitCustomBatchEvent<WorkflowVersionStatusUpdate>(
|
||||||
WORKFLOW_VERSION_STATUS_UPDATED,
|
WORKFLOW_VERSION_STATUS_UPDATED,
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
workflowId: workflowVersion.workflowId,
|
workflowId: workflowVersion.workflowId,
|
||||||
|
workflowVersionId: workflowVersion.id,
|
||||||
previousStatus: workflowVersion.status,
|
previousStatus: workflowVersion.status,
|
||||||
newStatus,
|
newStatus,
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user