diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2020-10-30 21:08:56 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2020-10-30 21:08:56 +0300 |
commit | 98d7cc758fb73239fb957c297446c811ab4150d9 (patch) | |
tree | 227a5e8efe35d2ac158e762397609a3f1754b224 /app/assets/javascripts/jobs | |
parent | 038366a0932c5f88019cc3db85382f26af3933e7 (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/assets/javascripts/jobs')
3 files changed, 122 insertions, 111 deletions
diff --git a/app/assets/javascripts/jobs/components/sidebar.vue b/app/assets/javascripts/jobs/components/sidebar.vue index 8701e05a01f..e1372a5c05e 100644 --- a/app/assets/javascripts/jobs/components/sidebar.vue +++ b/app/assets/javascripts/jobs/components/sidebar.vue @@ -1,33 +1,29 @@ <script> import { isEmpty } from 'lodash'; import { mapActions, mapState } from 'vuex'; -import { GlLink, GlButton, GlIcon } from '@gitlab/ui'; -import { __, sprintf } from '~/locale'; -import timeagoMixin from '~/vue_shared/mixins/timeago'; +import { GlButton, GlIcon, GlLink } from '@gitlab/ui'; import TooltipOnTruncate from '~/vue_shared/components/tooltip_on_truncate.vue'; -import { timeIntervalInWords } from '~/lib/utils/datetime_utility'; -import DetailRow from './sidebar_detail_row.vue'; import ArtifactsBlock from './artifacts_block.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'; export default { name: 'JobSidebar', components: { ArtifactsBlock, CommitBlock, - DetailRow, GlIcon, TriggerBlock, StagesDropdown, JobsContainer, GlLink, GlButton, + SidebarJobDetailsContainer, TooltipOnTruncate, }, - mixins: [timeagoMixin], props: { artifactHelpUrl: { type: String, @@ -42,53 +38,12 @@ export default { }, computed: { ...mapState(['job', 'stages', 'jobs', 'selectedStage']), - coverage() { - return `${this.job.coverage}%`; - }, - duration() { - return timeIntervalInWords(this.job.duration); - }, - queued() { - return timeIntervalInWords(this.job.queued); - }, - runnerId() { - return `${this.job.runner.description} (#${this.job.runner.id})`; - }, retryButtonClass() { let className = 'js-retry-button btn btn-retry'; className += this.job.status && this.job.recoverable ? ' btn-primary' : ' btn-inverted-secondary'; return className; }, - hasTimeout() { - return this.job.metadata != null && this.job.metadata.timeout_human_readable !== null; - }, - timeout() { - if (this.job.metadata == null) { - return ''; - } - - let t = this.job.metadata.timeout_human_readable; - if (this.job.metadata.timeout_source !== '') { - t += sprintf(__(` (from %{timeoutSource})`), { - timeoutSource: this.job.metadata.timeout_source, - }); - } - - return t; - }, - renderBlock() { - return ( - this.job.duration || - this.job.finished_at || - this.job.erased_at || - this.job.queued || - this.hasTimeout || - this.job.runner || - this.job.coverage || - this.job.tags.length - ); - }, hasArtifact() { return !isEmpty(this.job.artifact); }, @@ -96,16 +51,10 @@ export default { return !isEmpty(this.job.trigger); }, hasStages() { - return ( - (this.job && - this.job.pipeline && - this.job.pipeline.stages && - this.job.pipeline.stages.length > 0) || - false - ); + return this.job?.pipeline?.stages?.length > 0; }, commit() { - return this.job.pipeline && this.job.pipeline.commit ? this.job.pipeline.commit : {}; + return this.job?.pipeline?.commit || {}; }, }, methods: { @@ -131,22 +80,22 @@ export default { data-method="post" data-qa-selector="retry_button" rel="nofollow" - >{{ __('Retry') }}</gl-link - > + >{{ __('Retry') }} + </gl-link> <gl-link v-if="job.cancel_path" :href="job.cancel_path" class="js-cancel-job btn btn-default" data-method="post" rel="nofollow" - >{{ __('Cancel') }}</gl-link - > + >{{ __('Cancel') }} + </gl-link> </div> <gl-button :aria-label="__('Toggle Sidebar')" - class="d-md-none gl-ml-2 js-sidebar-build-toggle" category="tertiary" + class="gl-display-md-none gl-ml-2 js-sidebar-build-toggle" icon="chevron-double-lg-right" @click="toggleSidebar" /> @@ -158,77 +107,37 @@ export default { :href="job.new_issue_path" class="btn btn-success btn-inverted float-left mr-2" data-testid="job-new-issue" - >{{ __('New issue') }}</gl-link - > + >{{ __('New issue') }} + </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" target="_blank" > - {{ __('Debug') }} <gl-icon name="external-link" :size="14" /> + {{ __('Debug') }} + <gl-icon :size="14" name="external-link" /> </gl-link> </div> - - <div v-if="renderBlock" class="block"> - <detail-row - v-if="job.duration" - :value="duration" - class="js-job-duration" - title="Duration" - /> - <detail-row - v-if="job.finished_at" - :value="timeFormatted(job.finished_at)" - class="js-job-finished" - title="Finished" - /> - <detail-row - v-if="job.erased_at" - :value="timeFormatted(job.erased_at)" - class="js-job-erased" - title="Erased" - /> - <detail-row v-if="job.queued" :value="queued" class="js-job-queued" title="Queued" /> - <detail-row - v-if="hasTimeout" - :help-url="runnerHelpUrl" - :value="timeout" - class="js-job-timeout" - title="Timeout" - /> - <detail-row v-if="job.runner" :value="runnerId" class="js-job-runner" title="Runner" /> - <detail-row - v-if="job.coverage" - :value="coverage" - class="js-job-coverage" - title="Coverage" - /> - <p v-if="job.tags.length" class="build-detail-row js-job-tags"> - <span class="font-weight-bold">{{ __('Tags:') }}</span> - <span v-for="(tag, i) in job.tags" :key="i" class="badge badge-primary mr-1">{{ - tag - }}</span> - </p> - </div> - + <sidebar-job-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 - :is-last-block="hasStages" :commit="commit" + :is-last-block="hasStages" :merge-request="job.merge_request" /> <stages-dropdown - :stages="stages" + v-if="job.pipeline" :pipeline="job.pipeline" :selected-stage="selectedStage" + :stages="stages" @requestSidebarStageDropdown="fetchJobsForStage" /> </div> - <jobs-container v-if="jobs.length" :jobs="jobs" :job-id="job.id" /> + <jobs-container v-if="jobs.length" :job-id="job.id" :jobs="jobs" /> </div> </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 new file mode 100644 index 00000000000..887fea982ad --- /dev/null +++ b/app/assets/javascripts/jobs/components/sidebar_job_details_container.vue @@ -0,0 +1,102 @@ +<script> +import { mapState } from 'vuex'; +import DetailRow from './sidebar_detail_row.vue'; +import { __, sprintf } from '~/locale'; +import timeagoMixin from '~/vue_shared/mixins/timeago'; +import { timeIntervalInWords } from '~/lib/utils/datetime_utility'; + +export default { + name: 'SidebarJobDetailsContainer', + components: { + DetailRow, + }, + mixins: [timeagoMixin], + props: { + runnerHelpUrl: { + type: String, + required: false, + default: '', + }, + }, + computed: { + ...mapState(['job']), + coverage() { + return `${this.job.coverage}%`; + }, + duration() { + return timeIntervalInWords(this.job.duration); + }, + erasedAt() { + return this.timeFormatted(this.job.erased_at); + }, + finishedAt() { + return this.timeFormatted(this.job.finished_at); + }, + hasTags() { + return this.job?.tags?.length; + }, + hasTimeout() { + return this.job?.metadata?.timeout_human_readable ?? false; + }, + hasAnyDetail() { + return Boolean( + this.job.duration || + this.job.finished_at || + this.job.erased_at || + this.job.queued || + this.job.runner || + this.job.coverage, + ); + }, + queued() { + return timeIntervalInWords(this.job.queued); + }, + runnerId() { + return `${this.job.runner.description} (#${this.job.runner.id})`; + }, + shouldRenderBlock() { + return Boolean(this.hasAnyDetail || this.hasTimeout || this.hasTags); + }, + timeout() { + return `${this.job?.metadata?.timeout_human_readable}${this.timeoutSource}`; + }, + timeoutSource() { + if (!this.job?.metadata?.timeout_source) { + return ''; + } + + return sprintf(__(` (from %{timeoutSource})`), { + timeoutSource: this.job.metadata.timeout_source, + }); + }, + }, +}; +</script> + +<template> + <div v-if="shouldRenderBlock" class="block"> + <detail-row v-if="job.duration" :value="duration" title="Duration" /> + <detail-row + v-if="job.finished_at" + :value="finishedAt" + data-testid="job-finished" + title="Finished" + /> + <detail-row v-if="job.erased_at" :value="erasedAt" title="Erased" /> + <detail-row v-if="job.queued" :value="queued" title="Queued" /> + <detail-row + v-if="hasTimeout" + :help-url="runnerHelpUrl" + :value="timeout" + data-testid="job-timeout" + title="Timeout" + /> + <detail-row v-if="job.runner" :value="runnerId" title="Runner" /> + <detail-row v-if="job.coverage" :value="coverage" title="Coverage" /> + + <p v-if="hasTags" class="build-detail-row" data-testid="job-tags"> + <span class="font-weight-bold">{{ __('Tags:') }}</span> + <span v-for="(tag, i) in job.tags" :key="i" class="badge badge-primary mr-1">{{ tag }}</span> + </p> + </div> +</template> diff --git a/app/assets/javascripts/jobs/store/getters.js b/app/assets/javascripts/jobs/store/getters.js index dc4a3578a86..bf924bc1917 100644 --- a/app/assets/javascripts/jobs/store/getters.js +++ b/app/assets/javascripts/jobs/store/getters.js @@ -4,7 +4,7 @@ import { isScrolledToBottom } from '~/lib/utils/scroll_utils'; export const headerTime = state => (state.job.started ? state.job.started : state.job.created_at); export const hasUnmetPrerequisitesFailure = state => - state.job && state.job.failure_reason && state.job.failure_reason === 'unmet_prerequisites'; + state?.job?.failure_reason === 'unmet_prerequisites'; export const shouldRenderCalloutMessage = state => !isEmpty(state.job.status) && !isEmpty(state.job.callout_message); |