diff options
Diffstat (limited to 'app/assets/javascripts/environments')
17 files changed, 510 insertions, 27 deletions
diff --git a/app/assets/javascripts/environments/components/confirm_rollback_modal.vue b/app/assets/javascripts/environments/components/confirm_rollback_modal.vue index 0e556f093e2..ce919f73858 100644 --- a/app/assets/javascripts/environments/components/confirm_rollback_modal.vue +++ b/app/assets/javascripts/environments/components/confirm_rollback_modal.vue @@ -99,8 +99,7 @@ export default { }; }, isLastDeployment() { - // eslint-disable-next-line @gitlab/require-i18n-strings - return this.environment?.isLastDeployment || this.environment?.lastDeployment?.['last?']; + return this.environment?.isLastDeployment || this.environment?.lastDeployment?.isLast; }, }, methods: { diff --git a/app/assets/javascripts/environments/components/deployment.vue b/app/assets/javascripts/environments/components/deployment.vue new file mode 100644 index 00000000000..ef43ca6bc33 --- /dev/null +++ b/app/assets/javascripts/environments/components/deployment.vue @@ -0,0 +1,25 @@ +<script> +import DeploymentStatusBadge from './deployment_status_badge.vue'; + +export default { + components: { + DeploymentStatusBadge, + }, + props: { + deployment: { + type: Object, + required: true, + }, + }, + computed: { + status() { + return this.deployment?.status; + }, + }, +}; +</script> +<template> + <div> + <deployment-status-badge v-if="status" :status="status" /> + </div> +</template> diff --git a/app/assets/javascripts/environments/components/deployment_status_badge.vue b/app/assets/javascripts/environments/components/deployment_status_badge.vue new file mode 100644 index 00000000000..5a026911766 --- /dev/null +++ b/app/assets/javascripts/environments/components/deployment_status_badge.vue @@ -0,0 +1,60 @@ +<script> +import { GlBadge } from '@gitlab/ui'; +import { s__ } from '~/locale'; + +const STATUS_TEXT = { + created: s__('Deployment|Created'), + running: s__('Deployment|Running'), + success: s__('Deployment|Success'), + failed: s__('Deployment|Failed'), + canceled: s__('Deployment|Cancelled'), + skipped: s__('Deployment|Skipped'), + blocked: s__('Deployment|Waiting'), +}; + +const STATUS_VARIANT = { + success: 'success', + running: 'info', + failed: 'danger', + created: 'neutral', + canceled: 'neutral', + skipped: 'neutral', + blocked: 'neutral', +}; + +const STATUS_ICON = { + success: 'status_success', + running: 'status_running', + failed: 'status_failed', + created: 'status_created', + canceled: 'status_canceled', + skipped: 'status_skipped', + blocked: 'status_manual', +}; + +export default { + components: { + GlBadge, + }, + props: { + status: { + type: String, + required: true, + }, + }, + computed: { + icon() { + return STATUS_ICON[this.status]; + }, + text() { + return STATUS_TEXT[this.status]; + }, + variant() { + return STATUS_VARIANT[this.status]; + }, + }, +}; +</script> +<template> + <gl-badge v-if="status" :icon="icon" :variant="variant">{{ text }}</gl-badge> +</template> diff --git a/app/assets/javascripts/environments/components/environment_actions.vue b/app/assets/javascripts/environments/components/environment_actions.vue index 2d98f00433a..98c95507168 100644 --- a/app/assets/javascripts/environments/components/environment_actions.vue +++ b/app/assets/javascripts/environments/components/environment_actions.vue @@ -1,8 +1,9 @@ <script> -import { GlDropdown, GlDropdownItem, GlIcon, GlLoadingIcon, GlTooltipDirective } from '@gitlab/ui'; +import { GlDropdown, GlDropdownItem, GlIcon, GlTooltipDirective } from '@gitlab/ui'; import { formatTime } from '~/lib/utils/datetime_utility'; import { __, s__, sprintf } from '~/locale'; import eventHub from '../event_hub'; +import actionMutation from '../graphql/mutations/action.mutation.graphql'; export default { directives: { @@ -12,7 +13,6 @@ export default { GlDropdown, GlDropdownItem, GlIcon, - GlLoadingIcon, }, props: { actions: { @@ -20,6 +20,11 @@ export default { required: false, default: () => [], }, + graphql: { + type: Boolean, + required: false, + default: false, + }, }, data() { return { @@ -49,7 +54,11 @@ export default { this.isLoading = true; - eventHub.$emit('postAction', { endpoint: action.playPath }); + if (this.graphql) { + this.$apollo.mutate({ mutation: actionMutation, variables: { action } }); + } else { + eventHub.$emit('postAction', { endpoint: action.playPath }); + } }, isActionDisabled(action) { @@ -70,18 +79,16 @@ export default { <template> <gl-dropdown v-gl-tooltip + :text="title" :title="title" + :loading="isLoading" :aria-label="title" - :disabled="isLoading" + icon="play" + text-sr-only right data-container="body" data-testid="environment-actions-button" > - <template #button-content> - <gl-icon name="play" /> - <gl-icon name="chevron-down" /> - <gl-loading-icon v-if="isLoading" size="sm" /> - </template> <gl-dropdown-item v-for="(action, i) in actions" :key="i" diff --git a/app/assets/javascripts/environments/components/environment_item.vue b/app/assets/javascripts/environments/components/environment_item.vue index be9bfb50de5..cfe35d26b94 100644 --- a/app/assets/javascripts/environments/components/environment_item.vue +++ b/app/assets/javascripts/environments/components/environment_item.vue @@ -1,5 +1,5 @@ <script> -import { GlDropdown, GlTooltipDirective, GlIcon, GlLink, GlSprintf } from '@gitlab/ui'; +import { GlDropdown, GlTooltipDirective, GlIcon, GlLink, GlSprintf, GlBadge } from '@gitlab/ui'; import { isEmpty } from 'lodash'; import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils'; import { __, s__, sprintf } from '~/locale'; @@ -30,6 +30,7 @@ export default { CommitComponent, ExternalUrlComponent, GlDropdown, + GlBadge, GlIcon, GlLink, GlSprintf, @@ -621,9 +622,9 @@ export default { <span v-if="model.size === 1">{{ model.name }}</span> <span v-else>{{ model.name_without_type }}</span> </a> - <span v-if="isProtected" class="badge badge-success"> - {{ s__('Environments|protected') }} - </span> + <gl-badge v-if="isProtected" variant="success">{{ + s__('Environments|protected') + }}</gl-badge> </span> <span v-else @@ -639,7 +640,7 @@ export default { <span> {{ model.folderName }} </span> - <span class="badge badge-pill"> {{ model.size }} </span> + <gl-badge>{{ model.size }}</gl-badge> </span> </div> diff --git a/app/assets/javascripts/environments/components/environment_stop.vue b/app/assets/javascripts/environments/components/environment_stop.vue index 0d4a1e76eb8..17a70fd0c34 100644 --- a/app/assets/javascripts/environments/components/environment_stop.vue +++ b/app/assets/javascripts/environments/components/environment_stop.vue @@ -8,6 +8,8 @@ import { GlTooltipDirective, GlButton, GlModalDirective } from '@gitlab/ui'; import { BV_HIDE_TOOLTIP } from '~/lib/utils/constants'; import { s__ } from '~/locale'; import eventHub from '../event_hub'; +import setEnvironmentToStopMutation from '../graphql/mutations/set_environment_to_stop.mutation.graphql'; +import isEnvironmentStoppingQuery from '../graphql/queries/is_environment_stopping.query.graphql'; export default { components: { @@ -22,6 +24,19 @@ export default { type: Object, required: true, }, + graphql: { + type: Boolean, + required: false, + default: false, + }, + }, + apollo: { + isEnvironmentStopping: { + query: isEnvironmentStoppingQuery, + variables() { + return { environment: this.environment }; + }, + }, }, i18n: { title: s__('Environments|Stop environment'), @@ -30,6 +45,7 @@ export default { data() { return { isLoading: false, + isEnvironmentStopping: false, }; }, mounted() { @@ -41,7 +57,14 @@ export default { methods: { onClick() { this.$root.$emit(BV_HIDE_TOOLTIP, this.$options.stopEnvironmentTooltipId); - eventHub.$emit('requestStopEnvironment', this.environment); + if (this.graphql) { + this.$apollo.mutate({ + mutation: setEnvironmentToStopMutation, + variables: { environment: this.environment }, + }); + } else { + eventHub.$emit('requestStopEnvironment', this.environment); + } }, onStopEnvironment(environment) { if (this.environment.id === environment.id) { @@ -56,7 +79,7 @@ export default { <gl-button v-gl-tooltip="{ id: $options.stopEnvironmentTooltipId }" v-gl-modal-directive="'stop-environment-modal'" - :loading="isLoading" + :loading="isLoading || isEnvironmentStopping" :title="$options.i18n.title" :aria-label="$options.i18n.title" icon="stop" diff --git a/app/assets/javascripts/environments/components/new_environment_folder.vue b/app/assets/javascripts/environments/components/new_environment_folder.vue index fe3d6f1e8ca..0d3867a4d74 100644 --- a/app/assets/javascripts/environments/components/new_environment_folder.vue +++ b/app/assets/javascripts/environments/components/new_environment_folder.vue @@ -2,9 +2,11 @@ import { GlButton, GlCollapse, GlIcon, GlBadge, GlLink } from '@gitlab/ui'; import { __, s__ } from '~/locale'; import folderQuery from '../graphql/queries/folder.query.graphql'; +import EnvironmentItem from './new_environment_item.vue'; export default { components: { + EnvironmentItem, GlButton, GlCollapse, GlIcon, @@ -51,17 +53,26 @@ export default { folderPath() { return this.nestedEnvironment.latest.folderPath; }, + environments() { + return this.folder?.environments; + }, }, methods: { toggleCollapse() { this.visible = !this.visible; }, + isFirstEnvironment(index) { + return index === 0; + }, }, }; </script> <template> - <div class="gl-border-b-solid gl-border-gray-100 gl-border-1 gl-px-3 gl-pt-3 gl-pb-5"> - <div class="gl-w-full gl-display-flex gl-align-items-center"> + <div + :class="{ 'gl-pb-5': !visible }" + class="gl-border-b-solid gl-border-gray-100 gl-border-1 gl-pt-3" + > + <div class="gl-w-full gl-display-flex gl-align-items-center gl-px-3"> <gl-button class="gl-mr-4 gl-fill-current-color gl-text-gray-500" :aria-label="label" @@ -77,6 +88,15 @@ export default { <gl-badge size="sm" class="gl-mr-auto">{{ count }}</gl-badge> <gl-link v-if="visible" :href="folderPath">{{ $options.i18n.link }}</gl-link> </div> - <gl-collapse :visible="visible" /> + <gl-collapse :visible="visible"> + <environment-item + v-for="(environment, index) in environments" + :key="environment.name" + :environment="environment" + :class="{ 'gl-mt-5': isFirstEnvironment(index) }" + class="gl-border-gray-100 gl-border-t-solid gl-border-1 gl-pt-3" + in-folder + /> + </gl-collapse> </div> </template> diff --git a/app/assets/javascripts/environments/components/new_environment_item.vue b/app/assets/javascripts/environments/components/new_environment_item.vue new file mode 100644 index 00000000000..d3624103c13 --- /dev/null +++ b/app/assets/javascripts/environments/components/new_environment_item.vue @@ -0,0 +1,265 @@ +<script> +import { + GlCollapse, + GlDropdown, + GlButton, + GlLink, + GlTooltipDirective as GlTooltip, +} from '@gitlab/ui'; +import { __ } from '~/locale'; +import { truncate } from '~/lib/utils/text_utility'; +import isLastDeployment from '../graphql/queries/is_last_deployment.query.graphql'; +import ExternalUrl from './environment_external_url.vue'; +import Actions from './environment_actions.vue'; +import StopComponent from './environment_stop.vue'; +import Rollback from './environment_rollback.vue'; +import Pin from './environment_pin.vue'; +import Monitoring from './environment_monitoring.vue'; +import Terminal from './environment_terminal_button.vue'; +import Delete from './environment_delete.vue'; +import Deployment from './deployment.vue'; + +export default { + components: { + GlCollapse, + GlDropdown, + GlButton, + GlLink, + Actions, + Deployment, + ExternalUrl, + StopComponent, + Rollback, + Monitoring, + Pin, + Terminal, + Delete, + }, + directives: { + GlTooltip, + }, + props: { + environment: { + required: true, + type: Object, + }, + inFolder: { + required: false, + default: false, + type: Boolean, + }, + }, + apollo: { + isLastDeployment: { + query: isLastDeployment, + variables() { + return { environment: this.environment }; + }, + }, + }, + i18n: { + collapse: __('Collapse'), + expand: __('Expand'), + }, + data() { + return { visible: false }; + }, + computed: { + icon() { + return this.visible ? 'angle-down' : 'angle-right'; + }, + externalUrl() { + return this.environment.externalUrl; + }, + name() { + return this.inFolder ? this.environment.nameWithoutType : this.environment.name; + }, + label() { + return this.visible ? this.$options.i18n.collapse : this.$options.i18n.expand; + }, + lastDeployment() { + return this.environment?.lastDeployment; + }, + upcomingDeployment() { + return this.environment?.upcomingDeployment; + }, + actions() { + if (!this.lastDeployment) { + return []; + } + const { manualActions = [], scheduledActions = [] } = this.lastDeployment; + const combinedActions = [...manualActions, ...scheduledActions]; + return combinedActions.map((action) => ({ + ...action, + })); + }, + canStop() { + return this.environment?.canStop; + }, + retryPath() { + return this.lastDeployment?.deployable?.retryPath; + }, + hasExtraActions() { + return Boolean( + this.retryPath || + this.canShowAutoStopDate || + this.metricsPath || + this.terminalPath || + this.canDeleteEnvironment, + ); + }, + canShowAutoStopDate() { + if (!this.environment?.autoStopAt) { + return false; + } + + const autoStopDate = new Date(this.environment?.autoStopAt); + const now = new Date(); + + return now < autoStopDate; + }, + autoStopPath() { + return this.environment?.cancelAutoStopPath ?? ''; + }, + metricsPath() { + return this.environment?.metricsPath ?? ''; + }, + terminalPath() { + return this.environment?.terminalPath ?? ''; + }, + canDeleteEnvironment() { + return Boolean(this.environment?.canDelete && this.environment?.deletePath); + }, + displayName() { + return truncate(this.name, 80); + }, + }, + methods: { + toggleCollapse() { + this.visible = !this.visible; + }, + }, + deploymentClasses: [ + 'gl-border-gray-100', + 'gl-border-t-solid', + 'gl-border-1', + 'gl-py-5', + 'gl-pl-7', + 'gl-bg-gray-10', + ], +}; +</script> +<template> + <div> + <div + class="gl-px-3 gl-pt-3 gl-pb-5 gl-display-flex gl-justify-content-space-between gl-align-items-center" + > + <div + :class="{ 'gl-ml-7': inFolder }" + class="gl-min-w-0 gl-mr-4 gl-display-flex gl-align-items-center" + > + <gl-button + class="gl-mr-4 gl-min-w-fit-content" + :icon="icon" + :aria-label="label" + size="small" + category="tertiary" + @click="toggleCollapse" + /> + <gl-link + v-gl-tooltip + :href="environment.environmentPath" + class="gl-text-blue-500 gl-text-truncate" + :class="{ 'gl-font-weight-bold': visible }" + :title="name" + > + {{ displayName }} + </gl-link> + </div> + <div> + <div class="btn-group table-action-buttons" role="group"> + <external-url + v-if="externalUrl" + :external-url="externalUrl" + data-track-action="click_button" + data-track-label="environment_url" + /> + + <actions + v-if="actions.length > 0" + :actions="actions" + data-track-action="click_dropdown" + data-track-label="environment_actions" + graphql + /> + + <stop-component + v-if="canStop" + :environment="environment" + class="gl-z-index-2" + data-track-action="click_button" + data-track-label="environment_stop" + graphql + /> + + <gl-dropdown + v-if="hasExtraActions" + icon="ellipsis_v" + text-sr-only + :text="__('More actions')" + category="secondary" + no-caret + right + > + <rollback + v-if="retryPath" + :environment="environment" + :is-last-deployment="isLastDeployment" + :retry-url="retryPath" + graphql + data-track-action="click_button" + data-track-label="environment_rollback" + /> + + <pin + v-if="canShowAutoStopDate" + :auto-stop-url="autoStopPath" + data-track-action="click_button" + data-track-label="environment_pin" + /> + + <monitoring + v-if="metricsPath" + :monitoring-url="metricsPath" + data-track-action="click_button" + data-track-label="environment_monitoring" + /> + + <terminal + v-if="terminalPath" + :terminal-path="terminalPath" + data-track-action="click_button" + data-track-label="environment_terminal" + /> + + <delete + v-if="canDeleteEnvironment" + :environment="environment" + data-track-action="click_button" + data-track-label="environment_delete" + graphql + /> + </gl-dropdown> + </div> + </div> + </div> + <gl-collapse :visible="visible"> + <div v-if="lastDeployment" :class="$options.deploymentClasses"> + <deployment :deployment="lastDeployment" :class="{ 'gl-ml-7': inFolder }" /> + </div> + <div v-if="upcomingDeployment" :class="$options.deploymentClasses"> + <deployment :deployment="upcomingDeployment" :class="{ 'gl-ml-7': inFolder }" /> + </div> + </gl-collapse> + </div> +</template> diff --git a/app/assets/javascripts/environments/components/new_environments_app.vue b/app/assets/javascripts/environments/components/new_environments_app.vue index 8d94e7021ca..cb36e226d0e 100644 --- a/app/assets/javascripts/environments/components/new_environments_app.vue +++ b/app/assets/javascripts/environments/components/new_environments_app.vue @@ -5,13 +5,24 @@ import { updateHistory, setUrlParams, queryToObject } from '~/lib/utils/url_util import environmentAppQuery from '../graphql/queries/environment_app.query.graphql'; import pollIntervalQuery from '../graphql/queries/poll_interval.query.graphql'; import pageInfoQuery from '../graphql/queries/page_info.query.graphql'; +import environmentToDeleteQuery from '../graphql/queries/environment_to_delete.query.graphql'; +import environmentToRollbackQuery from '../graphql/queries/environment_to_rollback.query.graphql'; +import environmentToStopQuery from '../graphql/queries/environment_to_stop.query.graphql'; import EnvironmentFolder from './new_environment_folder.vue'; import EnableReviewAppModal from './enable_review_app_modal.vue'; +import StopEnvironmentModal from './stop_environment_modal.vue'; +import EnvironmentItem from './new_environment_item.vue'; +import ConfirmRollbackModal from './confirm_rollback_modal.vue'; +import DeleteEnvironmentModal from './delete_environment_modal.vue'; export default { components: { + DeleteEnvironmentModal, + ConfirmRollbackModal, EnvironmentFolder, EnableReviewAppModal, + EnvironmentItem, + StopEnvironmentModal, GlBadge, GlPagination, GlTab, @@ -36,6 +47,15 @@ export default { pageInfo: { query: pageInfoQuery, }, + environmentToDelete: { + query: environmentToDeleteQuery, + }, + environmentToRollback: { + query: environmentToRollbackQuery, + }, + environmentToStop: { + query: environmentToStopQuery, + }, }, inject: ['newEnvironmentPath', 'canCreateEnvironment'], i18n: { @@ -57,6 +77,9 @@ export default { isReviewAppModalVisible: false, page: parseInt(page, 10), scope, + environmentToDelete: {}, + environmentToRollback: {}, + environmentToStop: {}, }; }, computed: { @@ -64,7 +87,10 @@ export default { return this.environmentApp?.reviewApp?.canSetupReviewApp; }, folders() { - return this.environmentApp?.environments.filter((e) => e.size > 1) ?? []; + return this.environmentApp?.environments?.filter((e) => e.size > 1) ?? []; + }, + environments() { + return this.environmentApp?.environments?.filter((e) => e.size === 1) ?? []; }, availableCount() { return this.environmentApp?.availableCount; @@ -119,7 +145,7 @@ export default { }, setScope(scope) { this.scope = scope; - this.resetPolling(); + this.moveToPage(1); }, movePage(direction) { this.moveToPage(this.pageInfo[`${direction}Page`]); @@ -157,6 +183,9 @@ export default { :modal-id="$options.modalId" data-testid="enable-review-app-modal" /> + <delete-environment-modal :environment="environmentToDelete" graphql /> + <stop-environment-modal :environment="environmentToStop" graphql /> + <confirm-rollback-modal :environment="environmentToRollback" graphql /> <gl-tabs :action-secondary="addEnvironment" :action-primary="openReviewAppModal" @@ -187,6 +216,12 @@ export default { class="gl-mb-3" :nested-environment="folder" /> + <environment-item + v-for="environment in environments" + :key="environment.name" + class="gl-mb-3 gl-border-gray-100 gl-border-1 gl-border-b-solid" + :environment="environment.latest" + /> <gl-pagination align="center" :total-items="totalItems" diff --git a/app/assets/javascripts/environments/components/stop_environment_modal.vue b/app/assets/javascripts/environments/components/stop_environment_modal.vue index 7a9233048a9..162ad598c8c 100644 --- a/app/assets/javascripts/environments/components/stop_environment_modal.vue +++ b/app/assets/javascripts/environments/components/stop_environment_modal.vue @@ -2,6 +2,7 @@ import { GlSprintf, GlTooltipDirective, GlModal } from '@gitlab/ui'; import { __, s__ } from '~/locale'; import eventHub from '../event_hub'; +import stopEnvironmentMutation from '../graphql/mutations/stop_environment.mutation.graphql'; export default { id: 'stop-environment-modal', @@ -21,6 +22,11 @@ export default { type: Object, required: true, }, + graphql: { + type: Boolean, + required: false, + default: false, + }, }, computed: { @@ -39,7 +45,14 @@ export default { methods: { onSubmit() { - eventHub.$emit('stopEnvironment', this.environment); + if (this.graphql) { + this.$apollo.mutate({ + mutation: stopEnvironmentMutation, + variables: { environment: this.environment }, + }); + } else { + eventHub.$emit('stopEnvironment', this.environment); + } }, }, }; diff --git a/app/assets/javascripts/environments/graphql/mutations/action.mutation.graphql b/app/assets/javascripts/environments/graphql/mutations/action.mutation.graphql new file mode 100644 index 00000000000..bc2c9b33367 --- /dev/null +++ b/app/assets/javascripts/environments/graphql/mutations/action.mutation.graphql @@ -0,0 +1,5 @@ +mutation action($action: LocalAction) { + action(action: $action) @client { + errors + } +} diff --git a/app/assets/javascripts/environments/graphql/mutations/set_environment_to_stop.mutation.graphql b/app/assets/javascripts/environments/graphql/mutations/set_environment_to_stop.mutation.graphql new file mode 100644 index 00000000000..2891f4c5101 --- /dev/null +++ b/app/assets/javascripts/environments/graphql/mutations/set_environment_to_stop.mutation.graphql @@ -0,0 +1,3 @@ +mutation SetEnvironmentToStop($environment: LocalEnvironmentInput) { + setEnvironmentToStop(environment: $environment) @client +} diff --git a/app/assets/javascripts/environments/graphql/queries/environment_to_stop.query.graphql b/app/assets/javascripts/environments/graphql/queries/environment_to_stop.query.graphql new file mode 100644 index 00000000000..128846145e8 --- /dev/null +++ b/app/assets/javascripts/environments/graphql/queries/environment_to_stop.query.graphql @@ -0,0 +1,3 @@ +query environmentToStop { + environmentToStop @client +} diff --git a/app/assets/javascripts/environments/graphql/queries/is_environment_stopping.query.graphql b/app/assets/javascripts/environments/graphql/queries/is_environment_stopping.query.graphql new file mode 100644 index 00000000000..ad05e252e6f --- /dev/null +++ b/app/assets/javascripts/environments/graphql/queries/is_environment_stopping.query.graphql @@ -0,0 +1,3 @@ +query isEnvironmentStopping($environment: LocalEnvironment) { + isEnvironmentStopping(environment: $environment) @client +} diff --git a/app/assets/javascripts/environments/graphql/queries/is_last_deployment.query.graphql b/app/assets/javascripts/environments/graphql/queries/is_last_deployment.query.graphql new file mode 100644 index 00000000000..5eda2f18567 --- /dev/null +++ b/app/assets/javascripts/environments/graphql/queries/is_last_deployment.query.graphql @@ -0,0 +1,3 @@ +query isLastDeployment($environment: LocalEnvironment) { + isLastDeployment(environment: $environment) @client +} diff --git a/app/assets/javascripts/environments/graphql/resolvers.js b/app/assets/javascripts/environments/graphql/resolvers.js index 9ebbc0ad1f8..812fa0c81f0 100644 --- a/app/assets/javascripts/environments/graphql/resolvers.js +++ b/app/assets/javascripts/environments/graphql/resolvers.js @@ -8,6 +8,7 @@ import { import pollIntervalQuery from './queries/poll_interval.query.graphql'; import environmentToRollbackQuery from './queries/environment_to_rollback.query.graphql'; +import environmentToStopQuery from './queries/environment_to_stop.query.graphql'; import environmentToDeleteQuery from './queries/environment_to_delete.query.graphql'; import pageInfoQuery from './queries/page_info.query.graphql'; @@ -65,8 +66,7 @@ export const resolvers = (endpoint) => ({ })); }, isLastDeployment(_, { environment }) { - // eslint-disable-next-line @gitlab/require-i18n-strings - return environment?.lastDeployment?.['last?']; + return environment?.lastDeployment?.isLast; }, }, Mutation: { @@ -108,6 +108,20 @@ export const resolvers = (endpoint) => ({ ]); }); }, + setEnvironmentToStop(_, { environment }, { client }) { + client.writeQuery({ + query: environmentToStopQuery, + data: { environmentToStop: environment }, + }); + }, + action(_, { action: { playPath } }) { + return axios + .post(playPath) + .then(() => buildErrors()) + .catch(() => + buildErrors([s__('Environments|An error occurred while making the request.')]), + ); + }, setEnvironmentToDelete(_, { environment }, { client }) { client.writeQuery({ query: environmentToDeleteQuery, diff --git a/app/assets/javascripts/environments/graphql/typedefs.graphql b/app/assets/javascripts/environments/graphql/typedefs.graphql index 4a3abb0e89f..c02f6b2838a 100644 --- a/app/assets/javascripts/environments/graphql/typedefs.graphql +++ b/app/assets/javascripts/environments/graphql/typedefs.graphql @@ -68,7 +68,9 @@ extend type Query { environmentToDelete: LocalEnvironment pageInfo: LocalPageInfo environmentToRollback: LocalEnvironment - isLastDeployment: Boolean + environmentToStop: LocalEnvironment + isEnvironmentStopping(environment: LocalEnvironmentInput): Boolean + isLastDeployment(environment: LocalEnvironmentInput): Boolean } extend type Mutation { @@ -78,4 +80,6 @@ extend type Mutation { cancelAutoStop(environment: LocalEnvironmentInput): LocalErrors setEnvironmentToDelete(environment: LocalEnvironmentInput): LocalErrors setEnvironmentToRollback(environment: LocalEnvironmentInput): LocalErrors + setEnvironmentToStop(environment: LocalEnvironmentInput): LocalErrors + action(environment: LocalEnvironmentInput): LocalErrors } |