diff options
Diffstat (limited to 'app/assets/javascripts/jobs')
8 files changed, 45 insertions, 24 deletions
diff --git a/app/assets/javascripts/jobs/components/job_app.vue b/app/assets/javascripts/jobs/components/job_app.vue index 85fe5ed7e26..396b015ad83 100644 --- a/app/assets/javascripts/jobs/components/job_app.vue +++ b/app/assets/javascripts/jobs/components/job_app.vue @@ -94,7 +94,7 @@ export default { 'emptyStateIllustration', 'isScrollingDown', 'emptyStateAction', - 'hasRunnersForProject', + 'hasOfflineRunnersForProject', ]), shouldRenderContent() { @@ -220,7 +220,7 @@ export default { <!-- Body Section --> <stuck-block v-if="job.stuck" - :has-no-runners-for-project="hasRunnersForProject" + :has-offline-runners-for-project="hasOfflineRunnersForProject" :tags="job.tags" :runners-path="runnerSettingsUrl" /> diff --git a/app/assets/javascripts/jobs/components/sidebar.vue b/app/assets/javascripts/jobs/components/sidebar.vue index 1b4c9ebdf7d..cc099dba72f 100644 --- a/app/assets/javascripts/jobs/components/sidebar.vue +++ b/app/assets/javascripts/jobs/components/sidebar.vue @@ -125,6 +125,7 @@ export default { :title="$options.i18n.cancelJobButtonLabel" :aria-label="$options.i18n.cancelJobButtonLabel" :href="job.cancel_path" + variant="danger" icon="cancel" data-method="post" data-testid="cancel-button" 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 5428f657252..2ba531c9e95 100644 --- a/app/assets/javascripts/jobs/components/sidebar_job_details_container.vue +++ b/app/assets/javascripts/jobs/components/sidebar_job_details_container.vue @@ -56,7 +56,7 @@ export default { }); }, runnerId() { - const { id, short_sha: token, description } = this.job?.runner; + const { id, short_sha: token, description } = this.job.runner; return `#${id} (${token}) ${description}`; }, @@ -71,11 +71,20 @@ export default { return ''; } - return sprintf(__(` (from %{timeoutSource})`), { + return sprintf(__(' (from %{timeoutSource})'), { timeoutSource: this.job.metadata.timeout_source, }); }, }, + i18n: { + COVERAGE: __('Coverage'), + FINISHED: __('Finished'), + ERASED: __('Erased'), + QUEUED: __('Queued'), + RUNNER: __('Runner'), + TAGS: __('Tags:'), + TIMEOUT: __('Timeout'), + }, }; </script> @@ -86,22 +95,22 @@ export default { v-if="job.finished_at" :value="finishedAt" data-testid="job-finished" - title="Finished" + :title="$options.i18n.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="job.erased_at" :value="erasedAt" :title="$options.i18n.ERASED" /> + <detail-row v-if="job.queued" :value="queued" :title="$options.i18n.QUEUED" /> <detail-row v-if="hasTimeout" :help-url="runnerHelpUrl" :value="timeout" data-testid="job-timeout" - title="Timeout" + :title="$options.i18n.TIMEOUT" /> - <detail-row v-if="job.runner" :value="runnerId" title="Runner" /> - <detail-row v-if="job.coverage" :value="coverage" title="Coverage" /> + <detail-row v-if="job.runner" :value="runnerId" :title="$options.i18n.RUNNER" /> + <detail-row v-if="job.coverage" :value="coverage" :title="$options.i18n.COVERAGE" /> <p v-if="hasTags" class="build-detail-row" data-testid="job-tags"> - <span class="font-weight-bold">{{ __('Tags:') }}</span> + <span class="font-weight-bold">{{ $options.i18n.TAGS }}</span> <gl-badge v-for="(tag, i) in job.tags" :key="i" variant="info">{{ tag }}</gl-badge> </p> </div> diff --git a/app/assets/javascripts/jobs/components/stuck_block.vue b/app/assets/javascripts/jobs/components/stuck_block.vue index abd0c13702a..f9cde61e917 100644 --- a/app/assets/javascripts/jobs/components/stuck_block.vue +++ b/app/assets/javascripts/jobs/components/stuck_block.vue @@ -11,7 +11,7 @@ export default { GlLink, }, props: { - hasNoRunnersForProject: { + hasOfflineRunnersForProject: { type: Boolean, required: true, }, @@ -37,7 +37,7 @@ export default { dataTestId: 'job-stuck-with-tags', showTags: true, }; - } else if (this.hasNoRunnersForProject) { + } else if (this.hasOfflineRunnersForProject) { return { text: s__(`Job|This job is stuck because the project doesn't have any runners online assigned to it.`), diff --git a/app/assets/javascripts/jobs/components/table/cells/actions_cell.vue b/app/assets/javascripts/jobs/components/table/cells/actions_cell.vue index f16e0287d5d..02aeb46a22b 100644 --- a/app/assets/javascripts/jobs/components/table/cells/actions_cell.vue +++ b/app/assets/javascripts/jobs/components/table/cells/actions_cell.vue @@ -1,6 +1,7 @@ <script> import { GlButton, GlButtonGroup, GlModal, GlModalDirective, GlSprintf } from '@gitlab/ui'; import GlCountdown from '~/vue_shared/components/gl_countdown.vue'; +import { redirectTo } from '~/lib/utils/url_utility'; import { ACTIONS_DOWNLOAD_ARTIFACTS, ACTIONS_START_NOW, @@ -108,11 +109,11 @@ export default { }, }, methods: { - async postJobAction(name, mutation) { + async postJobAction(name, mutation, redirect = false) { try { const { data: { - [name]: { errors }, + [name]: { errors, job }, }, } = await this.$apollo.mutate({ mutation, @@ -121,6 +122,10 @@ export default { if (errors.length > 0) { reportMessageToSentry(this.$options.name, errors.join(', '), {}); this.showToastMessage(); + } else if (redirect) { + // Retry and Play actions redirect to job detail view + // we don't need to refetch with jobActionPerformed event + redirectTo(job.detailedStatus.detailsPath); } else { eventHub.$emit('jobActionPerformed'); } @@ -147,12 +152,12 @@ export default { retryJob() { this.retryBtnDisabled = true; - this.postJobAction(this.$options.jobRetry, retryJobMutation); + this.postJobAction(this.$options.jobRetry, retryJobMutation, true); }, playJob() { this.playManualBtnDisabled = true; - this.postJobAction(this.$options.jobPlay, playJobMutation); + this.postJobAction(this.$options.jobPlay, playJobMutation, true); }, unscheduleJob() { this.unscheduleBtnDisabled = true; diff --git a/app/assets/javascripts/jobs/components/table/graphql/fragments/job.fragment.graphql b/app/assets/javascripts/jobs/components/table/graphql/fragments/job.fragment.graphql index 06b065a86ce..3038216fdfc 100644 --- a/app/assets/javascripts/jobs/components/table/graphql/fragments/job.fragment.graphql +++ b/app/assets/javascripts/jobs/components/table/graphql/fragments/job.fragment.graphql @@ -1,3 +1,7 @@ fragment Job on CiJob { id + detailedStatus { + id + detailsPath + } } diff --git a/app/assets/javascripts/jobs/components/table/jobs_table_tabs.vue b/app/assets/javascripts/jobs/components/table/jobs_table_tabs.vue index 0a25dc5bea5..27e3b8028b7 100644 --- a/app/assets/javascripts/jobs/components/table/jobs_table_tabs.vue +++ b/app/assets/javascripts/jobs/components/table/jobs_table_tabs.vue @@ -54,7 +54,9 @@ export default { <gl-tab v-for="tab in tabs" :key="tab.text" - :title-link-attributes="{ 'data-testid': tab.testId }" + :title-link-attributes="/* eslint-disable @gitlab/vue-no-new-non-primitive-in-template */ { + 'data-testid': tab.testId, + } /* eslint-enable @gitlab/vue-no-new-non-primitive-in-template */" @click="$emit('fetchJobsByStatus', tab.scope)" > <template #title> diff --git a/app/assets/javascripts/jobs/store/getters.js b/app/assets/javascripts/jobs/store/getters.js index 9d255822250..a0f9db7409d 100644 --- a/app/assets/javascripts/jobs/store/getters.js +++ b/app/assets/javascripts/jobs/store/getters.js @@ -1,7 +1,7 @@ -import { isEmpty, isString } from 'lodash'; +import { isEmpty } from 'lodash'; import { isScrolledToBottom } from '~/lib/utils/scroll_utils'; -export const headerTime = (state) => (state.job.started ? state.job.started : state.job.created_at); +export const headerTime = (state) => state.job.started_at || state.job.created_at; export const hasForwardDeploymentFailure = (state) => state?.job?.failure_reason === 'forward_deployment_failure'; @@ -13,10 +13,10 @@ export const shouldRenderCalloutMessage = (state) => !isEmpty(state.job.status) && !isEmpty(state.job.callout_message); /** - * When job has not started the key will be null - * When job started the key will be a string with a date. + * When the job has not started the value of job.started_at will be null + * When job has started the value of job.started_at will be a string with a date. */ -export const shouldRenderTriggeredLabel = (state) => isString(state.job.started); +export const shouldRenderTriggeredLabel = (state) => Boolean(state.job.started_at); export const hasEnvironment = (state) => !isEmpty(state.job.deployment_status); @@ -46,5 +46,5 @@ export const shouldRenderSharedRunnerLimitWarning = (state) => export const isScrollingDown = (state) => isScrolledToBottom() && !state.isJobLogComplete; -export const hasRunnersForProject = (state) => +export const hasOfflineRunnersForProject = (state) => state?.job?.runners?.available && !state?.job?.runners?.online; |