summaryrefslogtreecommitdiff
path: root/app/assets/javascripts/jobs/components/sidebar_job_details_container.vue
blob: 3b1509e5be52eb46921431ed80c3f4598b82d647 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
<script>
import { mapState } from 'vuex';
import { GlBadge } from '@gitlab/ui';
import { timeIntervalInWords } from '~/lib/utils/datetime_utility';
import { __, sprintf } from '~/locale';
import timeagoMixin from '~/vue_shared/mixins/timeago';
import DetailRow from './sidebar_detail_row.vue';

export default {
  name: 'JobSidebarDetailsContainer',
  components: {
    DetailRow,
    GlBadge,
  },
  mixins: [timeagoMixin],
  computed: {
    ...mapState(['job']),
    coverage() {
      return `${this.job.coverage}%`;
    },
    duration() {
      return timeIntervalInWords(this.job.duration);
    },
    durationTitle() {
      return this.job.finished_at ? __('Duration') : __('Elapsed time');
    },
    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_duration ||
          this.job.runner ||
          this.job.coverage,
      );
    },
    runnerId() {
      const { id, short_sha: token, description } = this.job.runner;

      return `#${id} (${token}) ${description}`;
    },
    queuedDuration() {
      return timeIntervalInWords(this.job.queued_duration);
    },
    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,
      });
    },
  },
  i18n: {
    COVERAGE: __('Coverage'),
    FINISHED: __('Finished'),
    ERASED: __('Erased'),
    QUEUED: __('Queued'),
    RUNNER: __('Runner'),
    TAGS: __('Tags:'),
    TIMEOUT: __('Timeout'),
  },
  RUNNER_HELP_URL: 'https://docs.gitlab.com/runner/register/index.html',
};
</script>

<template>
  <div v-if="shouldRenderBlock">
    <detail-row v-if="job.duration" :value="duration" :title="durationTitle" />
    <detail-row
      v-if="job.finished_at"
      :value="finishedAt"
      data-testid="job-finished"
      :title="$options.i18n.FINISHED"
    />
    <detail-row v-if="job.erased_at" :value="erasedAt" :title="$options.i18n.ERASED" />
    <detail-row v-if="job.queued_duration" :value="queuedDuration" :title="$options.i18n.QUEUED" />
    <detail-row
      v-if="hasTimeout"
      :help-url="$options.RUNNER_HELP_URL"
      :value="timeout"
      data-testid="job-timeout"
      :title="$options.i18n.TIMEOUT"
    />
    <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">{{ $options.i18n.TAGS }}</span>
      <gl-badge v-for="(tag, i) in job.tags" :key="i" variant="info">{{ tag }}</gl-badge>
    </p>
  </div>
</template>