summaryrefslogtreecommitdiff
path: root/app/assets/javascripts/environments/stores/environments_store.js.es6
blob: 928786f0741205ef8540360be3b79ac0e4a89bf2 (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
129
130
131
132
133
134
135
136
137
138
139
/* eslint-disable no-param-reassign */
(() => {
  window.gl = window.gl || {};
  window.gl.environmentsList = window.gl.environmentsList || {};

  gl.environmentsList.EnvironmentsStore = {
    state: {},

    create() {
      this.state.environments = [];
      this.state.stoppedCounter = 0;
      this.state.availableCounter = 0;

      return this;
    },

    /**
     * In order to display a tree view we need to modify the received
     * data in to a tree structure based on `environment_type`
     * sorted alphabetically.
     * In each children a `vue-` property will be added. This property will be
     * used to know if an item is a children mostly for css purposes. This is
     * needed because the children row is a fragment instance and therfore does
     * not accept non-prop attributes.
     *
     *
     * @example
     * it will transform this:
     * [
     *   { name: "environment", environment_type: "review" },
     *   { name: "environment_1", environment_type: null }
     *   { name: "environment_2, environment_type: "review" }
     * ]
     * into this:
     * [
     *   { name: "review", children:
     *      [
     *        { name: "environment", environment_type: "review", vue-isChildren: true},
     *        { name: "environment_2", environment_type: "review", vue-isChildren: true}
     *      ]
     *   },
     *  {name: "environment_1", environment_type: null}
     * ]
     *
     *
     * @param  {Array} environments List of environments.
     * @returns {Array} Tree structured array with the received environments.
     */
    storeEnvironments(environments = []) {
      this.state.stoppedCounter = this.countByState(environments, 'stopped');
      this.state.availableCounter = this.countByState(environments, 'available');

      const environmentsTree = environments.reduce((acc, environment) => {
        if (environment.environment_type !== null) {
          const occurs = acc.filter(element => element.children &&
             element.name === environment.environment_type);

          environment['vue-isChildren'] = true;

          if (occurs.length) {
            acc[acc.indexOf(occurs[0])].children.push(environment);
            acc[acc.indexOf(occurs[0])].children.sort(this.sortByName);
          } else {
            acc.push({
              name: environment.environment_type,
              children: [environment],
              isOpen: false,
              'vue-isChildren': environment['vue-isChildren'],
            });
          }
        } else {
          acc.push(environment);
        }

        return acc;
      }, []).sort(this.sortByName);

      this.state.environments = environmentsTree;

      return environmentsTree;
    },

    /**
     * Toggles folder open property given the environment type.
     *
     * @param  {String} envType
     * @return {Array}
     */
    toggleFolder(envType) {
      const environments = this.state.environments;

      const environmnetsCopy = environments.map((env) => {
        if (env['vue-isChildren'] === true && env.name === envType) {
          env.isOpen = !env.isOpen;
        }

        return env;
      });

      this.state.environments = environmnetsCopy;

      return environmnetsCopy;
    },

    /**
     * Given an array of environments, returns the number of environments
     * that have the given state.
     *
     * @param  {Array} environments
     * @param  {String} state
     * @returns {Number}
     */
    countByState(environments, state) {
      return environments.filter(env => env.state === state).length;
    },

    /**
     * Sorts the two objects provided by their name.
     *
     * @param  {Object} a
     * @param  {Object} b
     * @returns {Number}
     */
    sortByName(a, b) {
      const nameA = a.name.toUpperCase();
      const nameB = b.name.toUpperCase();

      if (nameA < nameB) {
        return -1;
      }

      if (nameA > nameB) {
        return 1;
      }

      return 0;
    },
  };
})();