Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-10-30 21:08:56 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2020-10-30 21:08:56 +0300
commit98d7cc758fb73239fb957c297446c811ab4150d9 (patch)
tree227a5e8efe35d2ac158e762397609a3f1754b224 /app/assets/javascripts/jobs
parent038366a0932c5f88019cc3db85382f26af3933e7 (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/assets/javascripts/jobs')
-rw-r--r--app/assets/javascripts/jobs/components/sidebar.vue129
-rw-r--r--app/assets/javascripts/jobs/components/sidebar_job_details_container.vue102
-rw-r--r--app/assets/javascripts/jobs/store/getters.js2
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);