summaryrefslogtreecommitdiff
path: root/app/assets/javascripts/commit/pipelines/pipelines_table.js
blob: 598e62b4816f9c4afdf56a07e66fd40d6dd14f6e (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
/* eslint-disable no-new, no-param-reassign */
/* global Vue, CommitsPipelineStore, PipelinesService, Flash */

window.Vue = require('vue');
window.Vue.use(require('vue-resource'));
require('../../lib/utils/common_utils');
require('../../vue_shared/vue_resource_interceptor');
require('../../vue_shared/components/pipelines_table');
require('./pipelines_service');
const PipelineStore = require('./pipelines_store');

/**
 *
 * Uses `pipelines-table-component` to render Pipelines table with an API call.
 * Endpoint is provided in HTML and passed as `endpoint`.
 * We need a store to store the received environemnts.
 * We need a service to communicate with the server.
 *
 * Necessary SVG in the table are provided as props. This should be refactored
 * as soon as we have Webpack and can load them directly into JS files.
 */

(() => {
  window.gl = window.gl || {};
  gl.commits = gl.commits || {};
  gl.commits.pipelines = gl.commits.pipelines || {};

  gl.commits.pipelines.PipelinesTableView = Vue.component('pipelines-table', {

    components: {
      'pipelines-table-component': gl.pipelines.PipelinesTableComponent,
    },

    /**
     * Accesses the DOM to provide the needed data.
     * Returns the necessary props to render `pipelines-table-component` component.
     *
     * @return {Object}
     */
    data() {
      const pipelinesTableData = document.querySelector('#commit-pipeline-table-view').dataset;
      const store = new PipelineStore();

      return {
        endpoint: pipelinesTableData.endpoint,
        store,
        state: store.state,
        isLoading: false,
      };
    },

    /**
     * When the component is about to be mounted, tell the service to fetch the data
     *
     * A request to fetch the pipelines will be made.
     * In case of a successfull response we will store the data in the provided
     * store, in case of a failed response we need to warn the user.
     *
     */
    beforeMount() {
      this.service = new gl.commits.pipelines.PipelinesService(this.endpoint);

      this.fetchPipelines();
    },

    beforeUpdate() {
      if (this.state.pipelines.length && this.$children) {
        PipelineStore.startTimeAgoLoops.call(this, Vue);
      }
    },

    methods: {
      fetchPipelines() {
        this.isLoading = true;
        return this.service.all()
          .then(response => response.json())
          .then((json) => {
            // depending of the endpoint the response can either bring a `pipelines` key or not.
            const pipelines = json.pipelines || json;
            this.store.storePipelines(pipelines);
            this.isLoading = false;
          })
          .catch(() => {
            this.isLoading = false;
            new Flash('An error occurred while fetching the pipelines, please reload the page again.');
          });
      },
    },

    template: `
      <div class="pipelines">
        <div class="realtime-loading" v-if="isLoading">
          <i class="fa fa-spinner fa-spin"></i>
        </div>

        <div class="blank-state blank-state-no-icon"
          v-if="!isLoading && state.pipelines.length === 0">
          <h2 class="blank-state-title js-blank-state-title">
            No pipelines to show
          </h2>
        </div>

        <div class="table-holder pipelines"
          v-if="!isLoading && state.pipelines.length > 0">
          <pipelines-table-component
            :pipelines="state.pipelines"
            :service="service" />
        </div>
      </div>
    `,
  });
})();