diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2020-11-10 15:08:57 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2020-11-10 15:08:57 +0300 |
commit | a08f8baa63c0aea7fcf969da40d30e6cf56365cc (patch) | |
tree | 57b5d1964407332189ce027bc3c99301b7a1f515 /app/assets/javascripts/jobs | |
parent | 01c201bc6a9b99e1f3095f4139110c6fd0cf7aa9 (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/assets/javascripts/jobs')
9 files changed, 212 insertions, 52 deletions
diff --git a/app/assets/javascripts/jobs/components/job_retry_forward_deployment_modal.vue b/app/assets/javascripts/jobs/components/job_retry_forward_deployment_modal.vue new file mode 100644 index 00000000000..5ce9d08035d --- /dev/null +++ b/app/assets/javascripts/jobs/components/job_retry_forward_deployment_modal.vue @@ -0,0 +1,66 @@ +<script> +import { GlLink, GlModal } from '@gitlab/ui'; +import { JOB_RETRY_FORWARD_DEPLOYMENT_MODAL } from '../constants'; + +export default { + name: 'JobRetryForwardDeploymentModal', + components: { + GlLink, + GlModal, + }, + i18n: { + ...JOB_RETRY_FORWARD_DEPLOYMENT_MODAL, + }, + props: { + modalId: { + type: String, + required: true, + }, + href: { + type: String, + required: true, + }, + }, + inject: { + retryOutdatedJobDocsUrl: { + default: '', + }, + }, + data() { + return { + primaryProps: { + text: this.$options.i18n.primaryText, + attributes: [ + { + 'data-method': 'post', + 'data-testid': 'retry-button-modal', + href: this.href, + variant: 'danger', + }, + ], + }, + cancelProps: { + text: this.$options.i18n.cancel, + attributes: [{ category: 'secondary', variant: 'default' }], + }, + }; + }, +}; +</script> + +<template> + <gl-modal + :action-cancel="cancelProps" + :action-primary="primaryProps" + :modal-id="modalId" + :title="$options.i18n.title" + > + <p> + {{ $options.i18n.info }} + <gl-link v-if="retryOutdatedJobDocsUrl" :href="retryOutdatedJobDocsUrl" target="_blank"> + {{ $options.i18n.moreInfo }} + </gl-link> + </p> + <p>{{ $options.i18n.areYouSure }}</p> + </gl-modal> +</template> diff --git a/app/assets/javascripts/jobs/components/job_sidebar_retry_button.vue b/app/assets/javascripts/jobs/components/job_sidebar_retry_button.vue new file mode 100644 index 00000000000..258b8cadd63 --- /dev/null +++ b/app/assets/javascripts/jobs/components/job_sidebar_retry_button.vue @@ -0,0 +1,45 @@ +<script> +import { GlButton, GlLink, GlModalDirective } from '@gitlab/ui'; +import { mapGetters } from 'vuex'; +import { JOB_SIDEBAR } from '../constants'; + +export default { + name: 'JobSidebarRetryButton', + i18n: { + retryLabel: JOB_SIDEBAR.retry, + }, + components: { + GlButton, + GlLink, + }, + directives: { + GlModal: GlModalDirective, + }, + props: { + modalId: { + type: String, + required: true, + }, + href: { + type: String, + required: true, + }, + }, + computed: { + ...mapGetters(['hasForwardDeploymentFailure']), + }, +}; +</script> +<template> + <gl-button + v-if="hasForwardDeploymentFailure" + v-gl-modal="modalId" + :aria-label="$options.i18n.retryLabel" + category="primary" + variant="info" + >{{ $options.i18n.retryLabel }}</gl-button + > + <gl-link v-else :href="href" data-method="post" rel="nofollow" + >{{ $options.i18n.retryLabel }} + </gl-link> +</template> diff --git a/app/assets/javascripts/jobs/components/jobs_container.vue b/app/assets/javascripts/jobs/components/jobs_container.vue index 951bcb36600..df64b6422c7 100644 --- a/app/assets/javascripts/jobs/components/jobs_container.vue +++ b/app/assets/javascripts/jobs/components/jobs_container.vue @@ -24,7 +24,7 @@ export default { }; </script> <template> - <div class="js-jobs-container builds-container"> + <div class="builds-container"> <job-container-item v-for="job in jobs" :key="job.id" diff --git a/app/assets/javascripts/jobs/components/sidebar.vue b/app/assets/javascripts/jobs/components/sidebar.vue index e1372a5c05e..0789bb54f0f 100644 --- a/app/assets/javascripts/jobs/components/sidebar.vue +++ b/app/assets/javascripts/jobs/components/sidebar.vue @@ -1,28 +1,39 @@ <script> import { isEmpty } from 'lodash'; -import { mapActions, mapState } from 'vuex'; +import { mapActions, mapGetters, mapState } from 'vuex'; import { GlButton, GlIcon, GlLink } from '@gitlab/ui'; import TooltipOnTruncate from '~/vue_shared/components/tooltip_on_truncate.vue'; import ArtifactsBlock from './artifacts_block.vue'; +import JobSidebarRetryButton from './job_sidebar_retry_button.vue'; +import JobRetryForwardDeploymentModal from './job_retry_forward_deployment_modal.vue'; import TriggerBlock from './trigger_block.vue'; import CommitBlock from './commit_block.vue'; import StagesDropdown from './stages_dropdown.vue'; import JobsContainer from './jobs_container.vue'; -import SidebarJobDetailsContainer from './sidebar_job_details_container.vue'; +import JobSidebarDetailsContainer from './sidebar_job_details_container.vue'; +import { JOB_SIDEBAR } from '../constants'; + +export const forwardDeploymentFailureModalId = 'forward-deployment-failure'; export default { name: 'JobSidebar', + i18n: { + ...JOB_SIDEBAR, + }, + forwardDeploymentFailureModalId, components: { ArtifactsBlock, CommitBlock, + GlButton, + GlLink, GlIcon, - TriggerBlock, - StagesDropdown, JobsContainer, - GlLink, - GlButton, - SidebarJobDetailsContainer, + JobSidebarRetryButton, + JobRetryForwardDeploymentModal, + JobSidebarDetailsContainer, + StagesDropdown, TooltipOnTruncate, + TriggerBlock, }, props: { artifactHelpUrl: { @@ -37,9 +48,10 @@ export default { }, }, computed: { + ...mapGetters(['hasForwardDeploymentFailure']), ...mapState(['job', 'stages', 'jobs', 'selectedStage']), retryButtonClass() { - let className = 'js-retry-button btn btn-retry'; + let className = 'btn btn-retry'; className += this.job.status && this.job.recoverable ? ' btn-primary' : ' btn-inverted-secondary'; return className; @@ -56,6 +68,9 @@ export default { commit() { return this.job?.pipeline?.commit || {}; }, + shouldShowJobRetryForwardDeploymentModal() { + return this.job.retry_path && this.hasForwardDeploymentFailure; + }, }, methods: { ...mapActions(['fetchJobsForStage', 'toggleSidebar']), @@ -73,27 +88,27 @@ export default { </h4> </tooltip-on-truncate> <div class="flex-grow-1 flex-shrink-0 text-right"> - <gl-link + <job-sidebar-retry-button v-if="job.retry_path" :class="retryButtonClass" :href="job.retry_path" - data-method="post" + :modal-id="$options.forwardDeploymentFailureModalId" data-qa-selector="retry_button" - rel="nofollow" - >{{ __('Retry') }} - </gl-link> + data-testid="retry-button" + /> <gl-link v-if="job.cancel_path" :href="job.cancel_path" - class="js-cancel-job btn btn-default" + class="btn btn-default" data-method="post" + data-testid="cancel-button" rel="nofollow" - >{{ __('Cancel') }} + >{{ $options.i18n.cancel }} </gl-link> </div> <gl-button - :aria-label="__('Toggle Sidebar')" + :aria-label="$options.i18n.toggleSidebar" category="tertiary" class="gl-display-md-none gl-ml-2 js-sidebar-build-toggle" icon="chevron-double-lg-right" @@ -107,19 +122,20 @@ export default { :href="job.new_issue_path" class="btn btn-success btn-inverted float-left mr-2" data-testid="job-new-issue" - >{{ __('New issue') }} + >{{ $options.i18n.newIssue }} </gl-link> <gl-link v-if="job.terminal_path" :href="job.terminal_path" - class="js-terminal-link btn btn-primary btn-inverted visible-md-block visible-lg-block float-left" + class="btn btn-primary btn-inverted visible-md-block visible-lg-block float-left" target="_blank" + data-testid="terminal-link" > - {{ __('Debug') }} + {{ $options.i18n.debug }} <gl-icon :size="14" name="external-link" /> </gl-link> </div> - <sidebar-job-details-container :runner-help-url="runnerHelpUrl" /> + <job-sidebar-details-container :runner-help-url="runnerHelpUrl" /> <artifacts-block v-if="hasArtifact" :artifact="job.artifact" :help-url="artifactHelpUrl" /> <trigger-block v-if="hasTriggers" :trigger="job.trigger" /> <commit-block @@ -139,5 +155,10 @@ export default { <jobs-container v-if="jobs.length" :job-id="job.id" :jobs="jobs" /> </div> + <job-retry-forward-deployment-modal + v-if="shouldShowJobRetryForwardDeploymentModal" + :modal-id="$options.forwardDeploymentFailureModalId" + :href="job.retry_path" + /> </aside> </template> diff --git a/app/assets/javascripts/jobs/components/sidebar_job_details_container.vue b/app/assets/javascripts/jobs/components/sidebar_job_details_container.vue index 887fea982ad..8ad1008278e 100644 --- a/app/assets/javascripts/jobs/components/sidebar_job_details_container.vue +++ b/app/assets/javascripts/jobs/components/sidebar_job_details_container.vue @@ -6,7 +6,7 @@ import timeagoMixin from '~/vue_shared/mixins/timeago'; import { timeIntervalInWords } from '~/lib/utils/datetime_utility'; export default { - name: 'SidebarJobDetailsContainer', + name: 'JobSidebarDetailsContainer', components: { DetailRow, }, diff --git a/app/assets/javascripts/jobs/components/stages_dropdown.vue b/app/assets/javascripts/jobs/components/stages_dropdown.vue index 116331d9549..aeae9f26ed3 100644 --- a/app/assets/javascripts/jobs/components/stages_dropdown.vue +++ b/app/assets/javascripts/jobs/components/stages_dropdown.vue @@ -1,11 +1,13 @@ <script> import { isEmpty } from 'lodash'; -import { GlLink } from '@gitlab/ui'; +import { GlLink, GlDropdown, GlDropdownItem } from '@gitlab/ui'; import CiIcon from '~/vue_shared/components/ci_icon.vue'; export default { components: { CiIcon, + GlDropdown, + GlDropdownItem, GlLink, }, props: { @@ -78,20 +80,15 @@ export default { </template> </div> - <button - type="button" - data-toggle="dropdown" - class="js-selected-stage dropdown-menu-toggle gl-mt-3" - > - {{ selectedStage }} <i class="fa fa-chevron-down"></i> - </button> - - <ul class="dropdown-menu"> - <li v-for="stage in stages" :key="stage.name"> - <button type="button" class="js-stage-item stage-item" @click="onStageClick(stage)"> - {{ stage.name }} - </button> - </li> - </ul> + <gl-dropdown :text="selectedStage" class="js-selected-stage gl-w-full gl-mt-3"> + <gl-dropdown-item + v-for="stage in stages" + :key="stage.name" + class="js-stage-item stage-item" + @click="onStageClick(stage)" + > + {{ stage.name }} + </gl-dropdown-item> + </gl-dropdown> </div> </template> diff --git a/app/assets/javascripts/jobs/constants.js b/app/assets/javascripts/jobs/constants.js new file mode 100644 index 00000000000..d0d625d794d --- /dev/null +++ b/app/assets/javascripts/jobs/constants.js @@ -0,0 +1,24 @@ +import { __, s__ } from '~/locale'; + +const cancel = __('Cancel'); +const moreInfo = __('More information'); + +export const JOB_SIDEBAR = { + cancel, + debug: __('Debug'), + newIssue: __('New issue'), + retry: __('Retry'), + toggleSidebar: __('Toggle Sidebar'), +}; + +export const JOB_RETRY_FORWARD_DEPLOYMENT_MODAL = { + cancel, + info: s__( + `Jobs|You're about to retry a job that failed because it attempted to deploy code that is older than the latest deployment. + Retrying this job could result in overwriting the environment with the older source code.`, + ), + areYouSure: s__('Jobs|Are you sure you want to proceed?'), + moreInfo, + primaryText: __('Retry job'), + title: s__('Jobs|Are you sure you want to retry this job?'), +}; diff --git a/app/assets/javascripts/jobs/index.js b/app/assets/javascripts/jobs/index.js index 6e15360b66c..1ad6292a030 100644 --- a/app/assets/javascripts/jobs/index.js +++ b/app/assets/javascripts/jobs/index.js @@ -10,27 +10,31 @@ export default () => { // Let's start initializing the store (i.e. fetching data) right away store.dispatch('init', element.dataset); + const { + artifactHelpUrl, + deploymentHelpUrl, + runnerHelpUrl, + runnerSettingsUrl, + variablesSettingsUrl, + subscriptionsMoreMinutesUrl, + endpoint, + pagePath, + logState, + buildStatus, + projectPath, + retryOutdatedJobDocsUrl, + } = element.dataset; + return new Vue({ el: element, store, components: { JobApp, }, + provide: { + retryOutdatedJobDocsUrl, + }, render(createElement) { - const { - artifactHelpUrl, - deploymentHelpUrl, - runnerHelpUrl, - runnerSettingsUrl, - variablesSettingsUrl, - subscriptionsMoreMinutesUrl, - endpoint, - pagePath, - logState, - buildStatus, - projectPath, - } = element.dataset; - return createElement('job-app', { props: { artifactHelpUrl, diff --git a/app/assets/javascripts/jobs/store/getters.js b/app/assets/javascripts/jobs/store/getters.js index bf924bc1917..8c2d1dd8ab2 100644 --- a/app/assets/javascripts/jobs/store/getters.js +++ b/app/assets/javascripts/jobs/store/getters.js @@ -3,6 +3,9 @@ import { isScrolledToBottom } from '~/lib/utils/scroll_utils'; export const headerTime = state => (state.job.started ? state.job.started : state.job.created_at); +export const hasForwardDeploymentFailure = state => + state?.job?.failure_reason === 'forward_deployment_failure'; + export const hasUnmetPrerequisitesFailure = state => state?.job?.failure_reason === 'unmet_prerequisites'; |