summaryrefslogtreecommitdiff
path: root/app/assets/javascripts/analytics/cycle_analytics/components/path_navigation.vue
blob: ac41bc4917c5811f86f86573718ba236c0bcb129 (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
113
114
<script>
import { GlPath, GlPopover, GlSkeletonLoader } from '@gitlab/ui';
import SafeHtml from '~/vue_shared/directives/safe_html';
import Tracking from '~/tracking';
import { OVERVIEW_STAGE_ID } from '../constants';
import FormattedStageCount from './formatted_stage_count.vue';

export default {
  name: 'PathNavigation',
  components: {
    GlPath,
    GlSkeletonLoader,
    GlPopover,
    FormattedStageCount,
  },
  directives: {
    SafeHtml,
  },
  mixins: [Tracking.mixin()],
  props: {
    loading: {
      type: Boolean,
      required: false,
      default: false,
    },
    stages: {
      type: Array,
      required: true,
    },
    selectedStage: {
      type: Object,
      required: false,
      default: () => ({}),
    },
  },
  methods: {
    showPopover({ id }) {
      return id && id !== OVERVIEW_STAGE_ID;
    },
    onSelectStage($event) {
      this.$emit('selected', $event);
      this.track('click_path_navigation', {
        extra: {
          stage_id: $event.id,
        },
      });
    },
  },
  popoverOptions: {
    triggers: 'hover',
    placement: 'bottom',
  },
};
</script>
<template>
  <gl-skeleton-loader v-if="loading" :width="235" :lines="2" />
  <gl-path v-else :key="selectedStage.id" :items="stages" @selected="onSelectStage">
    <template #default="{ pathItem, pathId }">
      <gl-popover
        v-if="showPopover(pathItem)"
        v-bind="$options.popoverOptions"
        :target="pathId"
        :css-classes="['stage-item-popover']"
        data-testid="stage-item-popover"
      >
        <template #title>{{ pathItem.title }}</template>
        <div class="gl-px-4">
          <div class="gl-display-flex gl-justify-content-space-between">
            <div class="gl-pr-4 gl-pb-4">
              {{ s__('ValueStreamEvent|Stage time (median)') }}
            </div>
            <div class="gl-pb-4 gl-font-weight-bold">{{ pathItem.metric }}</div>
          </div>
        </div>
        <div class="gl-px-4">
          <div class="gl-display-flex gl-justify-content-space-between">
            <div class="gl-pr-4 gl-pb-4">
              {{ s__('ValueStreamEvent|Items in stage') }}
            </div>
            <div class="gl-pb-4 gl-font-weight-bold">
              <formatted-stage-count :stage-count="pathItem.stageCount" />
            </div>
          </div>
        </div>
        <div class="gl-px-4 gl-pt-4 gl-border-t-1 gl-border-t-solid gl-border-gray-50">
          <div
            v-if="pathItem.startEventHtmlDescription"
            class="gl-display-flex gl-flex-direction-row"
          >
            <div class="gl-display-flex gl-flex-direction-column gl-pr-4 gl-pb-4 metric-label">
              {{ s__('ValueStreamEvent|Start') }}
            </div>
            <div
              v-safe-html="pathItem.startEventHtmlDescription"
              class="gl-display-flex gl-flex-direction-column gl-pb-4 stage-event-description"
            ></div>
          </div>
          <div
            v-if="pathItem.endEventHtmlDescription"
            class="gl-display-flex gl-flex-direction-row"
          >
            <div class="gl-display-flex gl-flex-direction-column gl-pr-4 metric-label">
              {{ s__('ValueStreamEvent|Stop') }}
            </div>
            <div
              v-safe-html="pathItem.endEventHtmlDescription"
              class="gl-display-flex gl-flex-direction-column stage-event-description"
            ></div>
          </div>
        </div>
      </gl-popover>
    </template>
  </gl-path>
</template>