summaryrefslogtreecommitdiff
path: root/app/assets/javascripts/cycle_analytics/cycle_analytics_bundle.js.es6
blob: 1ac715aab7706429f4db7d7bdddcac5dc12249a2 (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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
/* global Vue */
/* global Cookies */
/* global Flash */

window.Vue = require('vue');
window.Cookies = require('js-cookie');

function requireAll(context) { return context.keys().map(context); }
requireAll(require.context('./svg', false, /^\.\/.*\.(js|es6)$/));
requireAll(require.context('.', true, /^\.\/(?!cycle_analytics_bundle).*\.(js|es6)$/));

$(() => {
  const OVERVIEW_DIALOG_COOKIE = 'cycle_analytics_help_dismissed';
  const cycleAnalyticsEl = document.querySelector('#cycle-analytics');
  const cycleAnalyticsStore = gl.cycleAnalytics.CycleAnalyticsStore;
  const cycleAnalyticsService = new gl.cycleAnalytics.CycleAnalyticsService({
    requestPath: cycleAnalyticsEl.dataset.requestPath,
  });

  gl.cycleAnalyticsApp = new Vue({
    el: '#cycle-analytics',
    name: 'CycleAnalytics',
    data: {
      state: cycleAnalyticsStore.state,
      isLoading: false,
      isLoadingStage: false,
      isEmptyStage: false,
      hasError: false,
      startDate: 30,
      isOverviewDialogDismissed: Cookies.get(OVERVIEW_DIALOG_COOKIE),
    },
    computed: {
      currentStage() {
        return cycleAnalyticsStore.currentActiveStage();
      },
    },
    components: {
      'stage-issue-component': gl.cycleAnalytics.StageIssueComponent,
      'stage-plan-component': gl.cycleAnalytics.StagePlanComponent,
      'stage-code-component': gl.cycleAnalytics.StageCodeComponent,
      'stage-test-component': gl.cycleAnalytics.StageTestComponent,
      'stage-review-component': gl.cycleAnalytics.StageReviewComponent,
      'stage-staging-component': gl.cycleAnalytics.StageStagingComponent,
      'stage-production-component': gl.cycleAnalytics.StageProductionComponent,
    },
    created() {
      this.fetchCycleAnalyticsData();
    },
    methods: {
      handleError() {
        cycleAnalyticsStore.setErrorState(true);
        return new Flash('There was an error while fetching cycle analytics data.');
      },
      initDropdown() {
        const $dropdown = $('.js-ca-dropdown');
        const $label = $dropdown.find('.dropdown-label');

        $dropdown.find('li a').off('click').on('click', (e) => {
          e.preventDefault();
          const $target = $(e.currentTarget);
          this.startDate = $target.data('value');

          $label.text($target.text().trim());
          this.fetchCycleAnalyticsData({ startDate: this.startDate });
        });
      },
      fetchCycleAnalyticsData(options) {
        const fetchOptions = options || { startDate: this.startDate };

        this.isLoading = true;

        cycleAnalyticsService
          .fetchCycleAnalyticsData(fetchOptions)
          .done((response) => {
            cycleAnalyticsStore.setCycleAnalyticsData(response);
            this.selectDefaultStage();
            this.initDropdown();
          })
          .error(() => {
            this.handleError();
          })
          .always(() => {
            this.isLoading = false;
          });
      },
      selectDefaultStage() {
        const stage = this.state.stages.first();
        this.selectStage(stage);
      },
      selectStage(stage) {
        if (this.isLoadingStage) return;
        if (this.currentStage === stage) return;

        if (!stage.isUserAllowed) {
          cycleAnalyticsStore.setActiveStage(stage);
          return;
        }

        this.isLoadingStage = true;
        cycleAnalyticsStore.setStageEvents([], stage);
        cycleAnalyticsStore.setActiveStage(stage);

        cycleAnalyticsService
          .fetchStageData({
            stage,
            startDate: this.startDate,
          })
          .done((response) => {
            this.isEmptyStage = !response.events.length;
            cycleAnalyticsStore.setStageEvents(response.events, stage);
          })
          .error(() => {
            this.isEmptyStage = true;
          })
          .always(() => {
            this.isLoadingStage = false;
          });
      },
      dismissOverviewDialog() {
        this.isOverviewDialogDismissed = true;
        Cookies.set(OVERVIEW_DIALOG_COOKIE, '1');
      },
    },
  });

  // Register global components
  Vue.component('total-time', gl.cycleAnalytics.TotalTimeComponent);
});