From 7232fd7a8a5b15a72b4941f89e9427d084d98bb0 Mon Sep 17 00:00:00 2001 From: Charles Driesler Date: Wed, 29 May 2024 16:20:35 +0100 Subject: [PATCH] create test automations, almost --- .../automate/automation/CreateDialog.vue | 39 +++++++++++++++++-- .../lib/common/generated/gql/gql.ts | 5 +++ .../lib/common/generated/gql/graphql.ts | 21 ++++++++++ .../composables/automationManagement.ts | 29 ++++++++++++++ .../lib/projects/graphql/mutations.ts | 15 +++++++ 5 files changed, 105 insertions(+), 4 deletions(-) diff --git a/packages/frontend-2/components/automate/automation/CreateDialog.vue b/packages/frontend-2/components/automate/automation/CreateDialog.vue index dc91b892a..66ec8ff4b 100644 --- a/packages/frontend-2/components/automate/automation/CreateDialog.vue +++ b/packages/frontend-2/components/automate/automation/CreateDialog.vue @@ -77,6 +77,7 @@ import { useForm } from 'vee-validate' import { useCreateAutomation, useCreateAutomationRevision, + useCreateTestAutomation, useUpdateAutomation } from '~/lib/projects/composables/automationManagement' import { formatJsonFormSchemaInputs } from '~/lib/automate/helpers/jsonSchema' @@ -147,6 +148,8 @@ const logger = useLogger() const updateAutomation = useUpdateAutomation() const createAutomation = useCreateAutomation() const createRevision = useCreateAutomationRevision() +const createTestAutomation = useCreateTestAutomation() + const { enumStep, step } = useEnumSteps({ order: stepsOrder }) const { items: stepsWidgetSteps, @@ -170,6 +173,14 @@ const shouldShowStepsWidget = computed(() => { return !!shouldShowWidget.value && !isTestAutomation.value }) +const enableSubmitTestAutomation = computed(() => { + const isValidInput = + !!automationName.value && !!selectedModel.value && !!selectedFunction.value + const isLoading = creationLoading.value + + return isValidInput && !isLoading +}) + const title = computed(() => { return isTestAutomation.value ? undefined : 'Create Automation' }) @@ -265,10 +276,8 @@ const buttons = computed((): LayoutDialogButton[] => { { id: 'submitTestAutomation', text: 'Create', - disabled: !automationName.value, - onClick: () => { - // TODO: Make request - } + disabled: !enableSubmitTestAutomation.value, + submit: true } ] @@ -355,9 +364,31 @@ const onDetailsSubmit = handleDetailsSubmit(async () => { } creationLoading.value = true + let aId: Optional = undefined let automationEncrypt: Optional = undefined try { + if (isTestAutomation.value) { + // Use simplified pathway + const testAutomationId = await createTestAutomation({ + projectId: project.id, + input: { + name, + functionId: fn.id, + modelId: model.id + } + }) + + if (!testAutomationId) { + logger.error('Failed to create test automation') + return + } + + automationId.value = testAutomationId + step.value++ + return + } + const createRes = await createAutomation({ projectId: project.id, input: { diff --git a/packages/frontend-2/lib/common/generated/gql/gql.ts b/packages/frontend-2/lib/common/generated/gql/gql.ts index f6ee816f5..bce40c288 100644 --- a/packages/frontend-2/lib/common/generated/gql/gql.ts +++ b/packages/frontend-2/lib/common/generated/gql/gql.ts @@ -154,6 +154,7 @@ const documents = { "\n mutation UpdateAutomation($projectId: ID!, $input: ProjectAutomationUpdateInput!) {\n projectMutations {\n automationMutations(projectId: $projectId) {\n update(input: $input) {\n id\n name\n enabled\n }\n }\n }\n }\n": types.UpdateAutomationDocument, "\n mutation CreateAutomationRevision(\n $projectId: ID!\n $input: ProjectAutomationRevisionCreateInput!\n ) {\n projectMutations {\n automationMutations(projectId: $projectId) {\n createRevision(input: $input) {\n id\n }\n }\n }\n }\n": types.CreateAutomationRevisionDocument, "\n mutation TriggerAutomation($projectId: ID!, $automationId: ID!) {\n projectMutations {\n automationMutations(projectId: $projectId) {\n trigger(automationId: $automationId)\n }\n }\n }\n": types.TriggerAutomationDocument, + "\n mutation CreateTestAutomation(\n $projectId: ID!,\n $input: ProjectTestAutomationCreateInput!\n ) {\n projectMutations {\n automationMutations(projectId: $projectId) {\n createTestAutomation(input: $input) {\n id\n }\n }\n }\n }\n": types.CreateTestAutomationDocument, "\n query ProjectAccessCheck($id: String!) {\n project(id: $id) {\n id\n }\n }\n": types.ProjectAccessCheckDocument, "\n query ProjectRoleCheck($id: String!) {\n project(id: $id) {\n id\n role\n }\n }\n": types.ProjectRoleCheckDocument, "\n query ProjectsDashboardQuery($filter: UserProjectsFilter, $cursor: String) {\n activeUser {\n id\n projects(filter: $filter, limit: 6, cursor: $cursor) {\n cursor\n totalCount\n items {\n ...ProjectDashboardItem\n }\n }\n ...ProjectsInviteBanners\n }\n }\n": types.ProjectsDashboardQueryDocument, @@ -808,6 +809,10 @@ export function graphql(source: "\n mutation CreateAutomationRevision(\n $pr * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. */ export function graphql(source: "\n mutation TriggerAutomation($projectId: ID!, $automationId: ID!) {\n projectMutations {\n automationMutations(projectId: $projectId) {\n trigger(automationId: $automationId)\n }\n }\n }\n"): (typeof documents)["\n mutation TriggerAutomation($projectId: ID!, $automationId: ID!) {\n projectMutations {\n automationMutations(projectId: $projectId) {\n trigger(automationId: $automationId)\n }\n }\n }\n"]; +/** + * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. + */ +export function graphql(source: "\n mutation CreateTestAutomation(\n $projectId: ID!,\n $input: ProjectTestAutomationCreateInput!\n ) {\n projectMutations {\n automationMutations(projectId: $projectId) {\n createTestAutomation(input: $input) {\n id\n }\n }\n }\n }\n"): (typeof documents)["\n mutation CreateTestAutomation(\n $projectId: ID!,\n $input: ProjectTestAutomationCreateInput!\n ) {\n projectMutations {\n automationMutations(projectId: $projectId) {\n createTestAutomation(input: $input) {\n id\n }\n }\n }\n }\n"]; /** * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. */ diff --git a/packages/frontend-2/lib/common/generated/gql/graphql.ts b/packages/frontend-2/lib/common/generated/gql/graphql.ts index 8a64a5431..cd81bd833 100644 --- a/packages/frontend-2/lib/common/generated/gql/graphql.ts +++ b/packages/frontend-2/lib/common/generated/gql/graphql.ts @@ -1781,6 +1781,7 @@ export type ProjectAutomationMutations = { __typename?: 'ProjectAutomationMutations'; create: Automation; createRevision: AutomationRevision; + createTestAutomation: Automation; /** * Trigger an automation with a fake "version created" trigger. The "version created" will * just refer to the last version of the model. @@ -1800,6 +1801,11 @@ export type ProjectAutomationMutationsCreateRevisionArgs = { }; +export type ProjectAutomationMutationsCreateTestAutomationArgs = { + input: ProjectTestAutomationCreateInput; +}; + + export type ProjectAutomationMutationsTriggerArgs = { automationId: Scalars['ID']; }; @@ -2086,6 +2092,12 @@ export enum ProjectPendingVersionsUpdatedMessageType { Updated = 'UPDATED' } +export type ProjectTestAutomationCreateInput = { + functionId: Scalars['String']; + modelId: Scalars['String']; + name: Scalars['String']; +}; + export type ProjectTriggeredAutomationsStatusUpdatedMessage = { __typename?: 'ProjectTriggeredAutomationsStatusUpdatedMessage'; model: Model; @@ -3937,6 +3949,14 @@ export type TriggerAutomationMutationVariables = Exact<{ export type TriggerAutomationMutation = { __typename?: 'Mutation', projectMutations: { __typename?: 'ProjectMutations', automationMutations: { __typename?: 'ProjectAutomationMutations', trigger: boolean } } }; +export type CreateTestAutomationMutationVariables = Exact<{ + projectId: Scalars['ID']; + input: ProjectTestAutomationCreateInput; +}>; + + +export type CreateTestAutomationMutation = { __typename?: 'Mutation', projectMutations: { __typename?: 'ProjectMutations', automationMutations: { __typename?: 'ProjectAutomationMutations', createTestAutomation: { __typename?: 'Automation', id: string } } } }; + export type ProjectAccessCheckQueryVariables = Exact<{ id: Scalars['String']; }>; @@ -4589,6 +4609,7 @@ export const CreateAutomationDocument = {"kind":"Document","definitions":[{"kind export const UpdateAutomationDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"UpdateAutomation"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"projectId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ProjectAutomationUpdateInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"projectMutations"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"automationMutations"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"projectId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"projectId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"update"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"enabled"}}]}}]}}]}}]}}]} as unknown as DocumentNode; export const CreateAutomationRevisionDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"CreateAutomationRevision"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"projectId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ProjectAutomationRevisionCreateInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"projectMutations"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"automationMutations"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"projectId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"projectId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"createRevision"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}}]}}]}}]}}]}}]} as unknown as DocumentNode; export const TriggerAutomationDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"TriggerAutomation"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"projectId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"automationId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"projectMutations"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"automationMutations"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"projectId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"projectId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"trigger"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"automationId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"automationId"}}}]}]}}]}}]}}]} as unknown as DocumentNode; +export const CreateTestAutomationDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"CreateTestAutomation"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"projectId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ProjectTestAutomationCreateInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"projectMutations"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"automationMutations"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"projectId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"projectId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"createTestAutomation"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}}]}}]}}]}}]}}]} as unknown as DocumentNode; export const ProjectAccessCheckDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"ProjectAccessCheck"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"id"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"project"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"id"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}}]}}]}}]} as unknown as DocumentNode; export const ProjectRoleCheckDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"ProjectRoleCheck"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"id"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"project"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"id"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"role"}}]}}]}}]} as unknown as DocumentNode; export const ProjectsDashboardQueryDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"ProjectsDashboardQuery"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"filter"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"UserProjectsFilter"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"cursor"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"activeUser"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"projects"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"filter"},"value":{"kind":"Variable","name":{"kind":"Name","value":"filter"}}},{"kind":"Argument","name":{"kind":"Name","value":"limit"},"value":{"kind":"IntValue","value":"6"}},{"kind":"Argument","name":{"kind":"Name","value":"cursor"},"value":{"kind":"Variable","name":{"kind":"Name","value":"cursor"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"cursor"}},{"kind":"Field","name":{"kind":"Name","value":"totalCount"}},{"kind":"Field","name":{"kind":"Name","value":"items"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"ProjectDashboardItem"}}]}}]}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"ProjectsInviteBanners"}}]}}]}},...ProjectDashboardItemFragmentDoc.definitions,...ProjectDashboardItemNoModelsFragmentDoc.definitions,...ProjectPageModelsCardProjectFragmentDoc.definitions,...ProjectPageModelsActions_ProjectFragmentDoc.definitions,...ProjectsModelPageEmbed_ProjectFragmentDoc.definitions,...ProjectsPageTeamDialogManagePermissions_ProjectFragmentDoc.definitions,...ProjectPageLatestItemsModelItemFragmentDoc.definitions,...PendingFileUploadFragmentDoc.definitions,...ProjectPageModelsCardRenameDialogFragmentDoc.definitions,...ProjectPageModelsCardDeleteDialogFragmentDoc.definitions,...ProjectPageModelsActionsFragmentDoc.definitions,...AutomateRunsTriggerStatus_TriggeredAutomationsStatusFragmentDoc.definitions,...TriggeredAutomationsStatusSummaryFragmentDoc.definitions,...FunctionRunStatusForSummaryFragmentDoc.definitions,...AutomateRunsTriggerStatusDialog_TriggeredAutomationsStatusFragmentDoc.definitions,...AutomateRunsTriggerStatusDialogRunsRows_AutomateRunFragmentDoc.definitions,...AutomateRunsTriggerStatusDialogFunctionRun_AutomateFunctionRunFragmentDoc.definitions,...AutomationsStatusOrderedRuns_AutomationRunFragmentDoc.definitions,...ProjectsInviteBannersFragmentDoc.definitions,...ProjectsInviteBannerFragmentDoc.definitions,...LimitedUserAvatarFragmentDoc.definitions]} as unknown as DocumentNode; diff --git a/packages/frontend-2/lib/projects/composables/automationManagement.ts b/packages/frontend-2/lib/projects/composables/automationManagement.ts index 9d9a522a8..6b5ac59eb 100644 --- a/packages/frontend-2/lib/projects/composables/automationManagement.ts +++ b/packages/frontend-2/lib/projects/composables/automationManagement.ts @@ -7,6 +7,7 @@ import { type ProjectAutomationsArgs, type CreateAutomationMutationVariables, type CreateAutomationRevisionMutationVariables, + type CreateTestAutomationMutationVariables, type OnProjectAutomationsUpdatedSubscription, type OnProjectTriggeredAutomationsStatusUpdatedSubscription, type Project, @@ -27,6 +28,7 @@ import { import { createAutomationMutation, createAutomationRevisionMutation, + createTestAutomationMutation, triggerAutomationMutation, updateAutomationMutation } from '~/lib/projects/graphql/mutations' @@ -64,6 +66,33 @@ export function useCreateAutomation() { } } +export function useCreateTestAutomation() { + const { activeUser } = useActiveUser() + const { triggerNotification } = useGlobalToast() + const { mutate: createTestAutomation } = useMutation(createTestAutomationMutation) + + return async (input: CreateTestAutomationMutationVariables) => { + if (!activeUser.value) return + + const res = await createTestAutomation(input).catch(convertThrowIntoFetchResult) + if (res?.data?.projectMutations?.automationMutations?.createTestAutomation?.id) { + triggerNotification({ + type: ToastNotificationType.Success, + title: 'Test automation created' + }) + } else { + const errMsg = getFirstErrorMessage(res?.errors) + triggerNotification({ + type: ToastNotificationType.Danger, + title: 'Failed to create test automation', + description: errMsg + }) + } + + return res?.data?.projectMutations?.automationMutations?.createTestAutomation?.id + } +} + export function useUpdateAutomation() { const { activeUser } = useActiveUser() const { triggerNotification } = useGlobalToast() diff --git a/packages/frontend-2/lib/projects/graphql/mutations.ts b/packages/frontend-2/lib/projects/graphql/mutations.ts index 9238759c4..ff8415c47 100644 --- a/packages/frontend-2/lib/projects/graphql/mutations.ts +++ b/packages/frontend-2/lib/projects/graphql/mutations.ts @@ -215,3 +215,18 @@ export const triggerAutomationMutation = graphql(` } } `) + +export const createTestAutomationMutation = graphql(` + mutation CreateTestAutomation( + $projectId: ID!, + $input: ProjectTestAutomationCreateInput! + ) { + projectMutations { + automationMutations(projectId: $projectId) { + createTestAutomation(input: $input) { + id + } + } + } + } +`)