diff --git a/assets/src/components/cd/ContinuousDeployment.tsx b/assets/src/components/cd/ContinuousDeployment.tsx index e40b9ce598..d6637a682d 100644 --- a/assets/src/components/cd/ContinuousDeployment.tsx +++ b/assets/src/components/cd/ContinuousDeployment.tsx @@ -133,6 +133,11 @@ function useDirectory({ filtered = true }: { filtered?: boolean } = {}) { label: 'Services', enabled: personaConfiguration?.all || config?.services, }, + { + path: GLOBAL_SERVICES_REL_PATH, + label: 'Global Services', + enabled: personaConfiguration?.all || config?.services, + }, { path: REPOS_REL_PATH, label: 'Repositories', @@ -153,11 +158,6 @@ function useDirectory({ filtered = true }: { filtered?: boolean } = {}) { label: 'Add-ons', enabled: personaConfiguration?.all || config?.addOns, }, - { - path: GLOBAL_SERVICES_REL_PATH, - label: 'Global Services', - enabled: personaConfiguration?.all || config?.services, - }, ] if (!filtered) { diff --git a/assets/src/components/cd/pipelines/job/PipelineJobLogs.tsx b/assets/src/components/cd/pipelines/job/PipelineJobLogs.tsx index e7b3d89f38..38f103a5c3 100644 --- a/assets/src/components/cd/pipelines/job/PipelineJobLogs.tsx +++ b/assets/src/components/cd/pipelines/job/PipelineJobLogs.tsx @@ -1,6 +1,17 @@ import { useMemo, useState } from 'react' -import { FormField, ListBoxItem, Select } from '@pluralsh/design-system' -import { useJobGateLogsQuery } from 'generated/graphql' +import { + Banner, + Button, + FormField, + ListBoxItem, + Select, +} from '@pluralsh/design-system' +import { + GateState, + useForceGateMutation, + useJobGateLogsQuery, + useJobGateQuery, +} from 'generated/graphql' import { useParams } from 'react-router-dom' import { useTheme } from 'styled-components' @@ -40,7 +51,13 @@ export default function PipelineJobLogs() { const [selectedContainer, setSelectedContainer] = useState( containers?.[0]?.name || '' ) + const { data: jobGateData } = useJobGateQuery({ + variables: { id }, + }) + const jobGateState = jobGateData?.pipelineGate?.state + const [forceGate, { loading: loadingForceGate, error: errorForceGate }] = + useForceGateMutation() const { data: currentData, previousData, @@ -66,6 +83,46 @@ export default function PipelineJobLogs() { + + + + ) : null + } >
+ {errorForceGate && ( + + {errorForceGate.message} + + )}
, insertedAt?: string | null, updatedAt?: string | null, pipeline?: { __typename?: 'Pipeline', id: string } | null, pullRequests?: Array<{ __typename?: 'PullRequest', id: string, title?: string | null, url: string, labels?: Array | null, creator?: string | null, status?: PrStatus | null, insertedAt?: string | null, updatedAt?: string | null, service?: { __typename?: 'ServiceDeployment', id: string, name: string, protect?: boolean | null, deletedAt?: string | null } | null, cluster?: { __typename?: 'Cluster', handle?: string | null, self?: boolean | null, protect?: boolean | null, deletedAt?: string | null, version?: string | null, currentVersion?: string | null, id: string, name: string, distro?: ClusterDistro | null, provider?: { __typename?: 'ClusterProvider', cloud: string } | null } | null } | null> | null, pipelinePullRequests?: Array<{ __typename?: 'PipelinePullRequest', id: string, service?: { __typename?: 'ServiceDeployment', id: string, name: string, protect?: boolean | null, deletedAt?: string | null } | null, pullRequest?: { __typename?: 'PullRequest', id: string, title?: string | null, url: string, labels?: Array | null, creator?: string | null, status?: PrStatus | null, insertedAt?: string | null, updatedAt?: string | null, service?: { __typename?: 'ServiceDeployment', id: string, name: string, protect?: boolean | null, deletedAt?: string | null } | null, cluster?: { __typename?: 'Cluster', handle?: string | null, self?: boolean | null, protect?: boolean | null, deletedAt?: string | null, version?: string | null, currentVersion?: string | null, id: string, name: string, distro?: ClusterDistro | null, provider?: { __typename?: 'ClusterProvider', cloud: string } | null } | null } | null } | null> | null } | null }; +export type ForceGateMutationVariables = Exact<{ + id: Scalars['ID']['input']; + state?: InputMaybe; +}>; + + +export type ForceGateMutation = { __typename?: 'RootMutationType', forceGate?: { __typename?: 'PipelineGate', id: string, name: string, state: GateState, type: GateType, insertedAt?: string | null, updatedAt?: string | null, approver?: { __typename?: 'User', id: string, pluralId?: string | null, name: string, email: string, profile?: string | null, backgroundColor?: string | null, readTimestamp?: string | null, roles?: { __typename?: 'UserRoles', admin?: boolean | null } | null, personas?: Array<{ __typename?: 'Persona', id: string, name: string, description?: string | null, bindings?: Array<{ __typename?: 'PolicyBinding', id?: string | null, user?: { __typename?: 'User', id: string, name: string, email: string } | null, group?: { __typename?: 'Group', id: string, name: string } | null } | null> | null, configuration?: { __typename?: 'PersonaConfiguration', all?: boolean | null, deployments?: { __typename?: 'PersonaDeployment', addOns?: boolean | null, clusters?: boolean | null, pipelines?: boolean | null, providers?: boolean | null, repositories?: boolean | null, services?: boolean | null } | null, sidebar?: { __typename?: 'PersonaSidebar', audits?: boolean | null, kubernetes?: boolean | null, pullRequests?: boolean | null, settings?: boolean | null, backups?: boolean | null, stacks?: boolean | null } | null } | null } | null> | null } | null, spec?: { __typename?: 'GateSpec', job?: { __typename?: 'JobGateSpec', annotations?: Record | null, labels?: Record | null, namespace: string, raw?: string | null, serviceAccount?: string | null, containers?: Array<{ __typename?: 'ContainerSpec', args?: Array | null, image: string, env?: Array<{ __typename?: 'ContainerEnv', name: string, value: string } | null> | null, envFrom?: Array<{ __typename?: 'ContainerEnvFrom', configMap: string, secret: string } | null> | null } | null> | null } | null } | null } | null }; + export type ProviderCredentialFragment = { __typename?: 'ProviderCredential', id: string, insertedAt?: string | null, kind: string, name: string, namespace: string, updatedAt?: string | null }; export type ClusterProviderFragment = { __typename?: 'ClusterProvider', id: string, name: string, namespace: string, cloud: string, editable?: boolean | null, supportedVersions?: Array | null, deletedAt?: string | null, insertedAt?: string | null, updatedAt?: string | null, git: { __typename?: 'GitRef', folder: string, ref: string }, repository?: { __typename?: 'GitRepository', id: string, url: string } | null, service?: { __typename?: 'ServiceDeployment', id: string, name: string, namespace: string } | null, credentials?: Array<{ __typename?: 'ProviderCredential', id: string, insertedAt?: string | null, kind: string, name: string, namespace: string, updatedAt?: string | null } | null> | null }; @@ -12666,6 +12674,40 @@ export function useCreatePipelineContextMutation(baseOptions?: Apollo.MutationHo export type CreatePipelineContextMutationHookResult = ReturnType; export type CreatePipelineContextMutationResult = Apollo.MutationResult; export type CreatePipelineContextMutationOptions = Apollo.BaseMutationOptions; +export const ForceGateDocument = gql` + mutation ForceGate($id: ID!, $state: GateState) { + forceGate(id: $id, state: $state) { + ...PipelineGate + } +} + ${PipelineGateFragmentDoc}`; +export type ForceGateMutationFn = Apollo.MutationFunction; + +/** + * __useForceGateMutation__ + * + * To run a mutation, you first call `useForceGateMutation` within a React component and pass it any options that fit your needs. + * When your component renders, `useForceGateMutation` returns a tuple that includes: + * - A mutate function that you can call at any time to execute the mutation + * - An object with fields that represent the current status of the mutation's execution + * + * @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2; + * + * @example + * const [forceGateMutation, { data, loading, error }] = useForceGateMutation({ + * variables: { + * id: // value for 'id' + * state: // value for 'state' + * }, + * }); + */ +export function useForceGateMutation(baseOptions?: Apollo.MutationHookOptions) { + const options = {...defaultOptions, ...baseOptions} + return Apollo.useMutation(ForceGateDocument, options); + } +export type ForceGateMutationHookResult = ReturnType; +export type ForceGateMutationResult = Apollo.MutationResult; +export type ForceGateMutationOptions = Apollo.BaseMutationOptions; export const ClusterProvidersDocument = gql` query ClusterProviders { clusterProviders(first: 100) { @@ -15814,6 +15856,7 @@ export const namedOperations = { deletePipeline: 'deletePipeline', ApproveGate: 'ApproveGate', CreatePipelineContext: 'CreatePipelineContext', + ForceGate: 'ForceGate', CreateClusterProvider: 'CreateClusterProvider', UpdateClusterProvider: 'UpdateClusterProvider', DeleteClusterProvider: 'DeleteClusterProvider', diff --git a/assets/src/graph/cdPipelines.graphql b/assets/src/graph/cdPipelines.graphql index 7c21308714..4ef6ae64bf 100644 --- a/assets/src/graph/cdPipelines.graphql +++ b/assets/src/graph/cdPipelines.graphql @@ -308,3 +308,9 @@ mutation CreatePipelineContext( } } } + +mutation ForceGate($id: ID!, $state: GateState) { + forceGate(id: $id, state: $state) { + ...PipelineGate + } +}