Improve API + set functions in state (#17560)

Prefetch functions and set these in state

---------

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
This commit is contained in:
Thomas Trompette
2026-01-30 10:24:07 +01:00
committed by GitHub
parent 69c53c7dff
commit f7adf1698e
19 changed files with 111 additions and 98 deletions
@@ -1145,12 +1145,10 @@ export type CreateWorkflowVersionEdgeInput = {
};
export type CreateWorkflowVersionStepInput = {
/** Default settings for the step */
defaultSettings?: InputMaybe<Scalars['JSON']>;
/** Step ID */
id?: InputMaybe<Scalars['String']>;
/** Logic function ID */
logicFunctionId?: InputMaybe<Scalars['UUID']>;
/** Step name */
name?: InputMaybe<Scalars['String']>;
/** Next step ID */
nextStepId?: InputMaybe<Scalars['UUID']>;
/** Parent step connection options */
@@ -1112,12 +1112,10 @@ export type CreateWorkflowVersionEdgeInput = {
};
export type CreateWorkflowVersionStepInput = {
/** Default settings for the step */
defaultSettings?: InputMaybe<Scalars['JSON']>;
/** Step ID */
id?: InputMaybe<Scalars['String']>;
/** Logic function ID */
logicFunctionId?: InputMaybe<Scalars['UUID']>;
/** Step name */
name?: InputMaybe<Scalars['String']>;
/** Next step ID */
nextStepId?: InputMaybe<Scalars['UUID']>;
/** Parent step connection options */
@@ -23,7 +23,7 @@ import { BaseThemeProvider } from '@/ui/theme/components/BaseThemeProvider';
import { UserThemeProviderEffect } from '@/ui/theme/components/UserThemeProviderEffect';
import { PageFavicon } from '@/ui/utilities/page-favicon/components/PageFavicon';
import { PageTitle } from '@/ui/utilities/page-title/components/PageTitle';
import { UserAndViewsProviderEffect } from '@/users/components/UserAndViewsProviderEffect';
import { MetadataProviderEffect } from '@/users/components/MetadataProviderEffect';
import { UserProvider } from '@/users/components/UserProvider';
import { WorkspaceProviderEffect } from '@/workspace/components/WorkspaceProviderEffect';
import { StrictMode } from 'react';
@@ -38,7 +38,7 @@ export const AppRouterProviders = () => {
<ApolloProvider>
<BaseThemeProvider>
<ClientConfigProviderEffect />
<UserAndViewsProviderEffect />
<MetadataProviderEffect />
<WorkspaceProviderEffect />
<ClientConfigProvider>
<CaptchaProvider>
@@ -1,5 +1,5 @@
import { WorkflowActionMenuItems } from '@/command-menu/pages/workflow/action/components/WorkflowActionMenuItems';
import { useGetManyLogicFunctions } from '@/settings/logic-functions/hooks/useGetManyLogicFunctions';
import { logicFunctionsState } from '@/settings/logic-functions/states/logicFunctionsState';
import { type WorkflowActionType } from '@/workflow/types/Workflow';
import { RightDrawerStepListContainer } from '@/workflow/workflow-steps/components/RightDrawerWorkflowSelectStepContainer';
import { RightDrawerWorkflowSelectStepTitle } from '@/workflow/workflow-steps/components/RightDrawerWorkflowSelectStepTitle';
@@ -12,13 +12,15 @@ import { getActionIconColorOrThrow } from '@/workflow/workflow-steps/workflow-ac
import { useIsFeatureEnabled } from '@/workspace/hooks/useIsFeatureEnabled';
import { useTheme } from '@emotion/react';
import { useLingui } from '@lingui/react/macro';
import { useRecoilValue } from 'recoil';
import { IconFunction } from 'twenty-ui/display';
import { MenuItem } from 'twenty-ui/navigation';
import { FeatureFlagKey } from '~/generated/graphql';
export type WorkflowActionSelection =
| { type: WorkflowActionType; logicFunctionId?: undefined; name?: undefined }
| { type: 'LOGIC_FUNCTION'; logicFunctionId: string; name: string };
export type WorkflowActionSelection = {
type: WorkflowActionType;
defaultSettings?: Record<string, unknown>;
};
export const CommandMenuWorkflowSelectAction = ({
onActionSelected,
@@ -30,7 +32,7 @@ export const CommandMenuWorkflowSelectAction = ({
const { t } = useLingui();
const { logicFunctions } = useGetManyLogicFunctions();
const logicFunctions = useRecoilValue(logicFunctionsState);
const toolFunctions = logicFunctions.filter((fn) => fn.isTool === true);
@@ -38,8 +40,13 @@ export const CommandMenuWorkflowSelectAction = ({
onActionSelected({ type: actionType });
};
const handleFunctionClick = (logicFunctionId: string, name: string) => {
onActionSelected({ type: 'LOGIC_FUNCTION', logicFunctionId, name });
const handleFunctionClick = (logicFunctionId: string) => {
onActionSelected({
type: 'LOGIC_FUNCTION',
defaultSettings: {
input: { logicFunctionId, logicFunctionInput: {} },
},
});
};
return (
@@ -107,7 +114,7 @@ export const CommandMenuWorkflowSelectAction = ({
/>
)}
text={fn.name}
onClick={() => handleFunctionClick(fn.id, fn.name)}
onClick={() => handleFunctionClick(fn.id)}
/>
))}
</>
@@ -74,8 +74,7 @@ export const CommandMenuWorkflowCreateStepContent = () => {
nextStepId,
position,
connectionOptions,
logicFunctionId: selection.logicFunctionId,
name: selection.name,
defaultSettings: selection.defaultSettings,
});
if (!isDefined(createdStep)) {
@@ -52,24 +52,11 @@ export const CommandMenuWorkflowEditStepTypeContent = () => {
throw new Error('Step not found');
}
const stepUpdate =
selection.type === 'LOGIC_FUNCTION'
? {
...existingStep,
type: selection.type,
name: selection.name,
settings: {
...existingStep.settings,
input: {
logicFunctionId: selection.logicFunctionId,
logicFunctionInput: {},
},
},
}
: {
...existingStep,
type: selection.type,
};
const stepUpdate = {
...existingStep,
type: selection.type,
settings: selection.defaultSettings ?? existingStep.settings,
};
const { updatedStep } = await updateStep(stepUpdate as WorkflowAction);
@@ -1,24 +0,0 @@
import { useApolloCoreClient } from '@/object-metadata/hooks/useApolloCoreClient';
import { FIND_MANY_LOGIC_FUNCTIONS } from '@/settings/logic-functions/graphql/queries/findManyLogicFunctions';
import { useQuery } from '@apollo/client';
import {
type GetManyLogicFunctionsQuery,
type GetManyLogicFunctionsQueryVariables,
} from '~/generated-metadata/graphql';
export const useGetManyLogicFunctions = () => {
const apolloMetadataClient = useApolloCoreClient();
const { data, loading, error } = useQuery<
GetManyLogicFunctionsQuery,
GetManyLogicFunctionsQueryVariables
>(FIND_MANY_LOGIC_FUNCTIONS, {
client: apolloMetadataClient ?? undefined,
});
return {
logicFunctions: data?.findManyLogicFunctions || [],
loading,
error,
};
};
@@ -0,0 +1,10 @@
import { createState } from 'twenty-ui/utilities';
import { type GetManyLogicFunctionsQuery } from '~/generated-metadata/graphql';
export type LogicFunction =
GetManyLogicFunctionsQuery['findManyLogicFunctions'][number];
export const logicFunctionsState = createState<LogicFunction[]>({
key: 'logicFunctionsState',
defaultValue: [],
});
@@ -10,6 +10,7 @@ import { currentWorkspaceMembersState } from '@/auth/states/currentWorkspaceMemb
import { currentWorkspaceState } from '@/auth/states/currentWorkspaceState';
import { isCurrentUserLoadedState } from '@/auth/states/isCurrentUserLoadedState';
import { useInitializeFormatPreferences } from '@/localization/hooks/useInitializeFormatPreferences';
import { logicFunctionsState } from '@/settings/logic-functions/states/logicFunctionsState';
import { getDateFnsLocale } from '@/ui/field/display/utils/getDateFnsLocale.util';
import { coreViewsState } from '@/views/states/coreViewState';
import { type CoreViewWithRelations } from '@/views/types/CoreViewWithRelations';
@@ -24,13 +25,14 @@ import {
type WorkspaceMember,
useFindAllCoreViewsQuery,
useGetCurrentUserQuery,
useGetManyLogicFunctionsQuery,
} from '~/generated-metadata/graphql';
import { dateLocaleState } from '~/localization/states/dateLocaleState';
import { dynamicActivate } from '~/utils/i18n/dynamicActivate';
import { isDeeplyEqual } from '~/utils/isDeeplyEqual';
import { isMatchingLocation } from '~/utils/isMatchingLocation';
export const UserAndViewsProviderEffect = () => {
export const MetadataProviderEffect = () => {
const location = useLocation();
const [isCurrentUserLoaded, setIsCurrentUserLoaded] = useRecoilState(
@@ -45,6 +47,7 @@ export const UserAndViewsProviderEffect = () => {
const setCurrentWorkspace = useSetRecoilState(currentWorkspaceState);
const setCurrentUserWorkspace = useSetRecoilState(currentUserWorkspaceState);
const setAvailableWorkspaces = useSetRecoilState(availableWorkspacesState);
const setLogicFunctions = useSetRecoilState(logicFunctionsState);
const { initializeFormatPreferences } = useInitializeFormatPreferences();
const isLoggedIn = useIsLogged();
@@ -104,6 +107,16 @@ export const UserAndViewsProviderEffect = () => {
skip: shouldSkip,
});
const { data: logicFunctionsData } = useGetManyLogicFunctionsQuery({
skip: !isLoggedIn,
});
useEffect(() => {
if (isDefined(logicFunctionsData?.findManyLogicFunctions)) {
setLogicFunctions(logicFunctionsData.findManyLogicFunctions);
}
}, [logicFunctionsData?.findManyLogicFunctions, setLogicFunctions]);
useEffect(() => {
if (!userQueryLoading) {
setLocalIsCurrentUserLoaded(true);
@@ -36,8 +36,7 @@ export const useCreateStep = () => {
connectionOptions,
shouldSelectNode = true,
workflowVersionId: providedWorkflowVersionId,
logicFunctionId,
name,
defaultSettings,
}: {
newStepType: WorkflowActionType;
parentStepId: string | undefined;
@@ -46,8 +45,7 @@ export const useCreateStep = () => {
connectionOptions?: WorkflowStepConnectionOptions;
shouldSelectNode?: boolean;
workflowVersionId?: string;
logicFunctionId?: string;
name?: string;
defaultSettings?: Record<string, unknown>;
}) => {
if (isLoading === true) {
return;
@@ -69,8 +67,7 @@ export const useCreateStep = () => {
nextStepId,
position,
parentStepConnectionOptions: connectionOptions,
logicFunctionId,
name,
defaultSettings,
})
)?.data?.createWorkflowVersionStep;
@@ -2,10 +2,11 @@ import styled from '@emotion/styled';
import { useLingui } from '@lingui/react/macro';
import { useMemo, useState } from 'react';
import Skeleton from 'react-loading-skeleton';
import { useRecoilValue } from 'recoil';
import { useGetToolIndex } from '@/ai/hooks/useGetToolIndex';
import { useGetManyLogicFunctions } from '@/settings/logic-functions/hooks/useGetManyLogicFunctions';
import { usePersistLogicFunction } from '@/settings/logic-functions/hooks/usePersistLogicFunction';
import { logicFunctionsState } from '@/settings/logic-functions/states/logicFunctionsState';
import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar';
import { SettingsTextInput } from '@/ui/input/components/SettingsTextInput';
import { Table } from '@/ui/layout/table/components/Table';
@@ -59,7 +60,7 @@ const DEFAULT_TOOL_INPUT_SCHEMA = {
};
export const SettingsToolsTable = () => {
const { logicFunctions, loading } = useGetManyLogicFunctions();
const logicFunctions = useRecoilValue(logicFunctionsState);
const { toolIndex, loading: toolIndexLoading } = useGetToolIndex();
const { createLogicFunction } = usePersistLogicFunction();
@@ -116,7 +117,7 @@ export const SettingsToolsTable = () => {
[systemTools, builtInSearchTerm],
);
const showSkeleton = (loading || toolIndexLoading) && tools.length === 0;
const showSkeleton = toolIndexLoading && tools.length === 0;
const handleCreateTool = async () => {
setIsCreating(true);
@@ -15,7 +15,7 @@ import { ClientConfigProviderEffect } from '@/client-config/components/ClientCon
import { ApolloCoreClientMockedProvider } from '@/object-metadata/hooks/__mocks__/ApolloCoreClientMockedProvider';
import { DefaultLayout } from '@/ui/layout/page/components/DefaultLayout';
import { UserAndViewsProviderEffect } from '@/users/components/UserAndViewsProviderEffect';
import { MetadataProviderEffect } from '@/users/components/MetadataProviderEffect';
import { ClientConfigProvider } from '~/modules/client-config/components/ClientConfigProvider';
import { UserProvider } from '~/modules/users/components/UserProvider';
import { mockedApolloClient } from '~/testing/mockedApolloClient';
@@ -85,7 +85,7 @@ const Providers = () => {
<ApolloStorybookDevLogEffect />
<ClientConfigProviderEffect />
<ClientConfigProvider>
<UserAndViewsProviderEffect />
<MetadataProviderEffect />
<WorkspaceProviderEffect />
<UserProvider>
<ApolloCoreClientMockedProvider>
@@ -5,6 +5,7 @@ import graphqlTypeJson from 'graphql-type-json';
import { UUIDScalarType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars';
import { WorkflowStepPositionInput } from 'src/engine/core-modules/workflow/dtos/update-workflow-step-position-input.dto';
import { WorkflowStepConnectionOptions } from 'src/modules/workflow/workflow-builder/workflow-version-step/types/WorkflowStepCreationOptions';
import { WorkflowActionSettings } from 'src/modules/workflow/workflow-executor/workflow-actions/types/workflow-action-settings.type';
import { WorkflowActionType } from 'src/modules/workflow/workflow-executor/workflow-actions/types/workflow-action.type';
@InputType()
@@ -52,15 +53,9 @@ export class CreateWorkflowVersionStepInput {
})
id?: string;
@Field(() => String, {
description: 'Step name',
@Field(() => graphqlTypeJson, {
description: 'Default settings for the step',
nullable: true,
})
name?: string;
@Field(() => UUIDScalarType, {
description: 'Logic function ID',
nullable: true,
})
logicFunctionId?: string;
defaultSettings?: WorkflowActionSettings;
}
@@ -3,12 +3,14 @@ import { getRepositoryToken } from '@nestjs/typeorm';
import { AiAgentRoleService } from 'src/engine/metadata-modules/ai/ai-agent-role/ai-agent-role.service';
import { AgentEntity } from 'src/engine/metadata-modules/ai/ai-agent/entities/agent.entity';
import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
import { RoleTargetEntity } from 'src/engine/metadata-modules/role-target/role-target.entity';
import { RoleEntity } from 'src/engine/metadata-modules/role/role.entity';
import { createEmptyAllFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/constant/create-empty-all-flat-entity-maps.constant';
import { WorkspaceManyOrAllFlatEntityMapsCacheService } from 'src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.service';
import { LogicFunctionRuntime } from 'src/engine/metadata-modules/logic-function/logic-function.entity';
import { LogicFunctionService } from 'src/engine/metadata-modules/logic-function/logic-function.service';
import { type FlatLogicFunction } from 'src/engine/metadata-modules/logic-function/types/flat-logic-function.type';
import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
import { RoleTargetEntity } from 'src/engine/metadata-modules/role-target/role-target.entity';
import { RoleEntity } from 'src/engine/metadata-modules/role/role.entity';
import { GlobalWorkspaceOrmManager } from 'src/engine/twenty-orm/global-workspace-datasource/global-workspace-orm.manager';
import { WorkspaceCacheService } from 'src/engine/workspace-cache/services/workspace-cache.service';
import { WorkflowCommonWorkspaceService } from 'src/modules/workflow/common/workspace-services/workflow-common.workspace-service';
@@ -114,6 +116,15 @@ describe('WorkflowVersionStepOperationsWorkspaceService', () => {
provide: WorkspaceCacheService,
useValue: workspaceCacheService,
},
{
provide: WorkspaceManyOrAllFlatEntityMapsCacheService,
useValue: {
flushFlatEntityMaps: jest.fn(),
getOrRecomputeManyOrAllFlatEntityMaps: jest
.fn()
.mockResolvedValue(createEmptyAllFlatEntityMaps()),
},
},
],
}).compile();
@@ -38,8 +38,7 @@ export class WorkflowVersionStepCreationWorkspaceService {
position,
parentStepConnectionOptions,
id,
logicFunctionId,
name,
defaultSettings,
} = input;
const workflowVersion =
@@ -61,8 +60,7 @@ export class WorkflowVersionStepCreationWorkspaceService {
position,
workflowVersionId,
id,
logicFunctionId,
name,
defaultSettings,
},
);
@@ -20,7 +20,9 @@ import { type WorkflowStepPositionInput } from 'src/engine/core-modules/workflow
import { AiAgentRoleService } from 'src/engine/metadata-modules/ai/ai-agent-role/ai-agent-role.service';
import { AgentEntity } from 'src/engine/metadata-modules/ai/ai-agent/entities/agent.entity';
import { DEFAULT_SMART_MODEL } from 'src/engine/metadata-modules/ai/ai-models/constants/ai-models.const';
import { WorkspaceManyOrAllFlatEntityMapsCacheService } from 'src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.service';
import { LogicFunctionService } from 'src/engine/metadata-modules/logic-function/logic-function.service';
import { findFlatLogicFunctionOrThrow } from 'src/engine/metadata-modules/logic-function/utils/find-flat-logic-function-or-throw.util';
import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
import { RoleTargetEntity } from 'src/engine/metadata-modules/role-target/role-target.entity';
import { GlobalWorkspaceOrmManager } from 'src/engine/twenty-orm/global-workspace-datasource/global-workspace-orm.manager';
@@ -72,6 +74,7 @@ export class WorkflowVersionStepOperationsWorkspaceService {
private readonly workflowCommonWorkspaceService: WorkflowCommonWorkspaceService,
private readonly aiAgentRoleService: AiAgentRoleService,
private readonly workspaceCacheService: WorkspaceCacheService,
private readonly flatEntityMapsCacheService: WorkspaceManyOrAllFlatEntityMapsCacheService,
) {}
async runWorkflowVersionStepDeletionSideEffects({
@@ -135,16 +138,14 @@ export class WorkflowVersionStepOperationsWorkspaceService {
workflowVersionId,
position,
id,
logicFunctionId,
name,
defaultSettings,
}: {
type: WorkflowActionType;
workspaceId: string;
workflowVersionId: string;
position?: WorkflowStepPositionInput;
id?: string;
logicFunctionId?: string;
name?: string;
defaultSettings?: Record<string, unknown>;
}): Promise<{
builtStep: WorkflowAction;
additionalCreatedSteps?: WorkflowAction[];
@@ -200,17 +201,34 @@ export class WorkflowVersionStepOperationsWorkspaceService {
};
}
case WorkflowActionType.LOGIC_FUNCTION: {
if (!logicFunctionId) {
const logicFunctionId = (
defaultSettings?.input as { logicFunctionId: string } | undefined
)?.logicFunctionId;
if (!isDefined(logicFunctionId)) {
throw new WorkflowVersionStepException(
'Logic function ID is required for LOGIC_FUNCTION step',
WorkflowVersionStepExceptionCode.INVALID_REQUEST,
);
}
const { flatLogicFunctionMaps } =
await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps(
{
workspaceId,
flatMapsKeys: ['flatLogicFunctionMaps'],
},
);
const flatLogicFunction = findFlatLogicFunctionOrThrow({
id: logicFunctionId,
flatLogicFunctionMaps,
});
return {
builtStep: {
...baseStep,
name: name ?? 'Logic Function',
name: flatLogicFunction.name,
type: WorkflowActionType.LOGIC_FUNCTION,
settings: {
...BASE_STEP_DEFINITION,
@@ -8,8 +8,8 @@ import {
WorkflowVersionStepExceptionCode,
} from 'src/modules/workflow/common/exceptions/workflow-version-step.exception';
import { WorkflowSchemaWorkspaceService } from 'src/modules/workflow/workflow-builder/workflow-schema/workflow-schema.workspace-service';
import { WorkflowVersionStepOperationsWorkspaceService } from 'src/modules/workflow/workflow-builder/workflow-version-step/workflow-version-step-operations.workspace-service';
import { WorkflowVersionStepHelpersWorkspaceService } from 'src/modules/workflow/workflow-builder/workflow-version-step/workflow-version-step-helpers.workspace-service';
import { WorkflowVersionStepOperationsWorkspaceService } from 'src/modules/workflow/workflow-builder/workflow-version-step/workflow-version-step-operations.workspace-service';
import { type WorkflowAction } from 'src/modules/workflow/workflow-executor/workflow-actions/types/workflow-action.type';
@Injectable()
@@ -114,6 +114,7 @@ export class WorkflowVersionStepUpdateWorkspaceService {
workspaceId,
position: newStep.position,
workflowVersionId,
defaultSettings: newStep.settings,
},
);
@@ -4,10 +4,11 @@ import { NestjsQueryTypeOrmModule } from '@ptc-org/nestjs-query-typeorm';
import { AiAgentRoleModule } from 'src/engine/metadata-modules/ai/ai-agent-role/ai-agent-role.module';
import { AgentEntity } from 'src/engine/metadata-modules/ai/ai-agent/entities/agent.entity';
import { WorkspaceManyOrAllFlatEntityMapsCacheModule } from 'src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.module';
import { LogicFunctionModule } from 'src/engine/metadata-modules/logic-function/logic-function.module';
import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
import { RoleTargetEntity } from 'src/engine/metadata-modules/role-target/role-target.entity';
import { RoleEntity } from 'src/engine/metadata-modules/role/role.entity';
import { LogicFunctionModule } from 'src/engine/metadata-modules/logic-function/logic-function.module';
import { WorkspaceCacheModule } from 'src/engine/workspace-cache/workspace-cache.module';
import { WorkflowCommonModule } from 'src/modules/workflow/common/workflow-common.module';
import { WorkflowSchemaModule } from 'src/modules/workflow/workflow-builder/workflow-schema/workflow-schema.module';
@@ -31,6 +32,7 @@ import { WorkflowVersionStepWorkspaceService } from 'src/modules/workflow/workfl
RoleTargetEntity,
RoleEntity,
]),
WorkspaceManyOrAllFlatEntityMapsCacheModule,
],
providers: [
WorkflowVersionStepWorkspaceService,
@@ -7,6 +7,7 @@ import { type WorkflowFormActionSettings } from 'src/modules/workflow/workflow-e
import { type WorkflowHttpRequestActionSettings } from 'src/modules/workflow/workflow-executor/workflow-actions/http-request/types/workflow-http-request-action-settings.type';
import { type WorkflowIfElseActionSettings } from 'src/modules/workflow/workflow-executor/workflow-actions/if-else/types/workflow-if-else-action-settings.type';
import { type WorkflowIteratorActionSettings } from 'src/modules/workflow/workflow-executor/workflow-actions/iterator/types/workflow-iterator-action-settings.type';
import { type WorkflowLogicFunctionActionSettings } from 'src/modules/workflow/workflow-executor/workflow-actions/logic-function/types/workflow-logic-function-action-settings.type';
import { type WorkflowSendEmailActionSettings } from 'src/modules/workflow/workflow-executor/workflow-actions/mail-sender/types/workflow-send-email-action-settings.type';
import {
type WorkflowCreateRecordActionSettings,
@@ -29,6 +30,7 @@ export type BaseWorkflowActionSettings = {
};
export type WorkflowActionSettings =
| WorkflowLogicFunctionActionSettings
| WorkflowSendEmailActionSettings
| WorkflowCodeActionSettings
| WorkflowCreateRecordActionSettings