environment_item.js.es6 13.9 KB
Newer Older
Filipa Lacerda's avatar
Filipa Lacerda committed
1 2 3 4 5 6 7
/*= require lib/utils/timeago */
/*= require lib/utils/text_utility */
/*= require vue_common_component/commit */
/*= require ./environment_actions */
/*= require ./environment_external_url */
/*= require ./environment_stop */
/*= require ./environment_rollback */
8

Filipa Lacerda's avatar
Filipa Lacerda committed
9
/* globals Vue, timeago */
Filipa Lacerda's avatar
Filipa Lacerda committed
10

Filipa Lacerda's avatar
Filipa Lacerda committed
11
(() => {
12 13
  /**
   * Envrionment Item Component
14
   *
15 16
   * Used in a hierarchical structure to show folders with children
   * in a table.
17 18 19
   * Recursive component based on [Tree View](https://vuejs.org/examples/tree-view.html)
   *
   * See this [issue](https://gitlab.com/gitlab-org/gitlab-ce/issues/22539)
Filipa Lacerda's avatar
Filipa Lacerda committed
20
   * for more information.15
21
   */
22

Filipa Lacerda's avatar
Filipa Lacerda committed
23 24
  window.gl = window.gl || {};
  window.gl.environmentsList = window.gl.environmentsList || {};
25

26
  gl.environmentsList.EnvironmentItem = Vue.component('environment-item', {
27

Filipa Lacerda's avatar
Filipa Lacerda committed
28
    components: {
Filipa Lacerda's avatar
Filipa Lacerda committed
29 30
      'commit-component': window.gl.CommitComponent,
      'actions-component': window.gl.environmentsList.ActionsComponent,
31
      'external-url-component': window.gl.environmentsList.ExternalUrlComponent,
32 33
      'stop-component': window.gl.environmentsList.StopComponent,
      'rollback-component': window.gl.environmentsList.RollbackComponent,
Filipa Lacerda's avatar
Filipa Lacerda committed
34
    },
Filipa Lacerda's avatar
Filipa Lacerda committed
35

Filipa Lacerda's avatar
Filipa Lacerda committed
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
    props: {
      model: {
        type: Object,
        required: true,
        default: () => ({}),
      },

      toggleRow: {
        type: Function,
        required: false,
      },

      canCreateDeployment: {
        type: Boolean,
        required: false,
        default: false,
      },

      canReadEnvironment: {
        type: Boolean,
        required: false,
        default: false,
      },
    },
Filipa Lacerda's avatar
Filipa Lacerda committed
60

Filipa Lacerda's avatar
Filipa Lacerda committed
61
    data() {
Filipa Lacerda's avatar
Filipa Lacerda committed
62
      return {
Filipa Lacerda's avatar
Filipa Lacerda committed
63 64 65
        rowClass: {
          'children-row': this.model['vue-isChildren'],
        },
Filipa Lacerda's avatar
Filipa Lacerda committed
66 67
      };
    },
68

Filipa Lacerda's avatar
Filipa Lacerda committed
69
    computed: {
70

71 72 73
      /**
       * If an item has a `children` entry it means it is a folder.
       * Folder items have different behaviours - it is possible to toggle
74
       * them and show their children.
75
       *
Filipa Lacerda's avatar
Filipa Lacerda committed
76
       * @returns {Boolean|Undefined}
77
       */
Filipa Lacerda's avatar
Filipa Lacerda committed
78
      isFolder() {
Filipa Lacerda's avatar
Filipa Lacerda committed
79
        return this.model.children && this.model.children.length > 0;
80
      },
81

82 83 84 85 86 87
      /**
       * If an item is inside a folder structure will return true.
       * Used for css purposes.
       *
       * @returns {Boolean|undefined}
       */
Filipa Lacerda's avatar
Filipa Lacerda committed
88
      isChildren() {
89
        return this.model['vue-isChildren'];
90
      },
91

92 93 94 95
      /**
       * Counts the number of environments in each folder.
       * Used to show a badge with the counter.
       *
Filipa Lacerda's avatar
Filipa Lacerda committed
96
       * @returns {Number|Undefined}  The number of environments for the current folder.
97
       */
Filipa Lacerda's avatar
Filipa Lacerda committed
98
      childrenCounter() {
Filipa Lacerda's avatar
Filipa Lacerda committed
99
        return this.model.children && this.model.children.length;
Filipa Lacerda's avatar
Filipa Lacerda committed
100 101 102 103 104 105 106 107 108 109
      },

      /**
       * Verifies if `last_deployment` key exists in the current Envrionment.
       * This key is required to render most of the html - this method works has
       * an helper.
       *
       * @returns {Boolean}
       */
      hasLastDeploymentKey() {
110 111
        if (this.model.last_deployment &&
          !this.$options.isObjectEmpty(this.model.last_deployment)) {
Filipa Lacerda's avatar
Filipa Lacerda committed
112 113 114
          return true;
        }
        return false;
Filipa Lacerda's avatar
Filipa Lacerda committed
115 116 117 118 119 120
      },

      /**
       * Verifies is the given environment has manual actions.
       * Used to verify if we should render them or nor.
       *
Filipa Lacerda's avatar
Filipa Lacerda committed
121
       * @returns {Boolean|Undefined}
Filipa Lacerda's avatar
Filipa Lacerda committed
122 123
       */
      hasManualActions() {
Filipa Lacerda's avatar
Filipa Lacerda committed
124 125
        return this.model.last_deployment && this.model.last_deployment.manual_actions &&
          this.model.last_deployment.manual_actions.length > 0;
Filipa Lacerda's avatar
Filipa Lacerda committed
126 127 128 129 130 131 132 133 134 135 136 137 138 139 140
      },

      /**
       * Returns the value of the `stoppable?` key provided in the response.
       *
       * @returns {Boolean}
       */
      isStoppable() {
        return this.model['stoppable?'];
      },

      /**
       * Verifies if the `deployable` key is present in `last_deployment` key.
       * Used to verify whether we should or not render the rollback partial.
       *
Filipa Lacerda's avatar
Filipa Lacerda committed
141
       * @returns {Boolean|Undefined}
Filipa Lacerda's avatar
Filipa Lacerda committed
142 143
       */
      canRetry() {
Filipa Lacerda's avatar
Filipa Lacerda committed
144 145
        return this.hasLastDeploymentKey &&
          this.model.last_deployment &&
Filipa Lacerda's avatar
Filipa Lacerda committed
146
          this.model.last_deployment.deployable;
Filipa Lacerda's avatar
Filipa Lacerda committed
147 148
      },

Filipa Lacerda's avatar
Filipa Lacerda committed
149 150 151 152 153
      /**
       * Human readable date.
       *
       * @returns {String}
       */
Filipa Lacerda's avatar
Filipa Lacerda committed
154
      createdDate() {
Filipa Lacerda's avatar
Filipa Lacerda committed
155
        const timeagoInstance = new timeago(); // eslint-disable-line
Filipa Lacerda's avatar
Filipa Lacerda committed
156 157

        return timeagoInstance.format(this.model.created_at);
Filipa Lacerda's avatar
Filipa Lacerda committed
158 159
      },

Filipa Lacerda's avatar
Filipa Lacerda committed
160 161 162
      /**
       * Returns the manual actions with the name parsed.
       *
Filipa Lacerda's avatar
Filipa Lacerda committed
163
       * @returns {Array.<Object>|Undefined}
Filipa Lacerda's avatar
Filipa Lacerda committed
164
       */
Filipa Lacerda's avatar
Filipa Lacerda committed
165
      manualActions() {
Filipa Lacerda's avatar
Filipa Lacerda committed
166 167 168 169
        if (this.hasManualActions) {
          return this.model.last_deployment.manual_actions.map((action) => {
            const parsedAction = {
              name: gl.text.humanize(action.name),
Filipa Lacerda's avatar
Filipa Lacerda committed
170
              play_path: action.play_path,
Filipa Lacerda's avatar
Filipa Lacerda committed
171 172 173 174 175
            };
            return parsedAction;
          });
        }
        return [];
Filipa Lacerda's avatar
Filipa Lacerda committed
176
      },
Filipa Lacerda's avatar
Filipa Lacerda committed
177

Filipa Lacerda's avatar
Filipa Lacerda committed
178 179 180 181 182
      /**
       * Builds the string used in the user image alt attribute.
       *
       * @returns {String}
       */
Filipa Lacerda's avatar
Filipa Lacerda committed
183
      userImageAltDescription() {
Filipa Lacerda's avatar
Filipa Lacerda committed
184 185 186 187 188 189
        if (this.model.last_deployment &&
          this.model.last_deployment.user &&
          this.model.last_deployment.user.username) {
          return `${this.model.last_deployment.user.username}'s avatar'`;
        }
        return '';
Filipa Lacerda's avatar
Filipa Lacerda committed
190
      },
Filipa Lacerda's avatar
Filipa Lacerda committed
191

Filipa Lacerda's avatar
Filipa Lacerda committed
192 193 194 195 196 197
      /**
       * If provided, returns the commit tag.
       *
       * @returns {String|Undefined}
       */
      commitTag() {
Filipa Lacerda's avatar
Filipa Lacerda committed
198 199
        if (this.model.last_deployment &&
          this.model.last_deployment.tag) {
Filipa Lacerda's avatar
Filipa Lacerda committed
200 201
          return this.model.last_deployment.tag;
        }
Filipa Lacerda's avatar
Filipa Lacerda committed
202
        return undefined;
Filipa Lacerda's avatar
Filipa Lacerda committed
203 204 205 206 207 208 209 210
      },

      /**
       * If provided, returns the commit ref.
       *
       * @returns {Object|Undefined}
       */
      commitRef() {
Filipa Lacerda's avatar
Filipa Lacerda committed
211
        if (this.model.last_deployment && this.model.last_deployment.ref) {
Filipa Lacerda's avatar
Filipa Lacerda committed
212
          return this.model.last_deployment.ref;
Filipa Lacerda's avatar
Filipa Lacerda committed
213
        }
Filipa Lacerda's avatar
Filipa Lacerda committed
214
        return undefined;
Filipa Lacerda's avatar
Filipa Lacerda committed
215
      },
Filipa Lacerda's avatar
Filipa Lacerda committed
216

Filipa Lacerda's avatar
Filipa Lacerda committed
217 218 219 220 221 222 223 224
      /**
       * If provided, returns the commit url.
       *
       * @returns {String|Undefined}
       */
      commitUrl() {
        if (this.model.last_deployment &&
          this.model.last_deployment.commit &&
Filipa Lacerda's avatar
Filipa Lacerda committed
225 226
          this.model.last_deployment.commit.commit_path) {
          return this.model.last_deployment.commit.commit_path;
Filipa Lacerda's avatar
Filipa Lacerda committed
227
        }
Filipa Lacerda's avatar
Filipa Lacerda committed
228
        return undefined;
Filipa Lacerda's avatar
Filipa Lacerda committed
229 230 231 232 233 234 235 236 237 238 239
      },

      /**
       * If provided, returns the commit short sha.
       *
       * @returns {String|Undefined}
       */
      commitShortSha() {
        if (this.model.last_deployment &&
          this.model.last_deployment.commit &&
          this.model.last_deployment.commit.short_id) {
Filipa Lacerda's avatar
Filipa Lacerda committed
240
          return this.model.last_deployment.commit.short_id;
Filipa Lacerda's avatar
Filipa Lacerda committed
241
        }
Filipa Lacerda's avatar
Filipa Lacerda committed
242
        return undefined;
Filipa Lacerda's avatar
Filipa Lacerda committed
243 244 245 246 247 248 249
      },

      /**
       * If provided, returns the commit title.
       *
       * @returns {String|Undefined}
       */
Filipa Lacerda's avatar
Filipa Lacerda committed
250
      commitTitle() {
Filipa Lacerda's avatar
Filipa Lacerda committed
251 252 253
        if (this.model.last_deployment &&
          this.model.last_deployment.commit &&
          this.model.last_deployment.commit.title) {
Filipa Lacerda's avatar
Filipa Lacerda committed
254
          return this.model.last_deployment.commit.title;
Filipa Lacerda's avatar
Filipa Lacerda committed
255
        }
Filipa Lacerda's avatar
Filipa Lacerda committed
256
        return undefined;
Filipa Lacerda's avatar
Filipa Lacerda committed
257 258 259 260 261 262 263
      },

      /**
       * If provided, returns the commit tag.
       *
       * @returns {Object|Undefined}
       */
Filipa Lacerda's avatar
Filipa Lacerda committed
264
      commitAuthor() {
Filipa Lacerda's avatar
Filipa Lacerda committed
265 266 267 268 269
        if (this.model.last_deployment &&
          this.model.last_deployment.commit &&
          this.model.last_deployment.commit.author) {
          return this.model.last_deployment.commit.author;
        }
Filipa Lacerda's avatar
Filipa Lacerda committed
270 271

        return undefined;
Filipa Lacerda's avatar
Filipa Lacerda committed
272
      },
273

Filipa Lacerda's avatar
Filipa Lacerda committed
274
      /**
Filipa Lacerda's avatar
Filipa Lacerda committed
275
       * Verifies if the `retry_path` key is present and returns its value.
Filipa Lacerda's avatar
Filipa Lacerda committed
276 277 278
       *
       * @returns {String|Undefined}
       */
279 280 281
      retryUrl() {
        if (this.model.last_deployment &&
          this.model.last_deployment.deployable &&
Filipa Lacerda's avatar
Filipa Lacerda committed
282 283
          this.model.last_deployment.deployable.retry_path) {
          return this.model.last_deployment.deployable.retry_path;
284 285 286 287
        }
        return undefined;
      },

Filipa Lacerda's avatar
Filipa Lacerda committed
288 289 290 291 292
      /**
       * Verifies if the `last?` key is present and returns its value.
       *
       * @returns {Boolean|Undefined}
       */
293 294 295
      isLastDeployment() {
        return this.model.last_deployment && this.model.last_deployment['last?'];
      },
Filipa Lacerda's avatar
Filipa Lacerda committed
296

Filipa Lacerda's avatar
Filipa Lacerda committed
297 298 299 300 301
      /**
       * Builds the name of the builds needed to display both the name and the id.
       *
       * @returns {String}
       */
Filipa Lacerda's avatar
Filipa Lacerda committed
302
      buildName() {
Filipa Lacerda's avatar
Filipa Lacerda committed
303 304
        if (this.model.last_deployment &&
          this.model.last_deployment.deployable) {
Filipa Lacerda's avatar
Filipa Lacerda committed
305 306
          return `${this.model.last_deployment.deployable.name} #${this.model.last_deployment.deployable.id}`;
        }
Filipa Lacerda's avatar
Filipa Lacerda committed
307
        return '';
Filipa Lacerda's avatar
Filipa Lacerda committed
308 309
      },

Filipa Lacerda's avatar
Filipa Lacerda committed
310 311 312 313 314
      /**
       * Builds the needed string to show the internal id.
       *
       * @returns {String}
       */
Filipa Lacerda's avatar
Filipa Lacerda committed
315
      deploymentInternalId() {
Filipa Lacerda's avatar
Filipa Lacerda committed
316 317
        if (this.model.last_deployment &&
          this.model.last_deployment.iid) {
Filipa Lacerda's avatar
Filipa Lacerda committed
318 319 320 321
          return `#${this.model.last_deployment.iid}`;
        }
        return '';
      },
Filipa Lacerda's avatar
Filipa Lacerda committed
322

Filipa Lacerda's avatar
Filipa Lacerda committed
323 324 325 326 327 328
      /**
       * Verifies if the user object is present under last_deployment object.
       *
       * @returns {Boolean}
       */
      deploymentHasUser() {
Filipa Lacerda's avatar
Filipa Lacerda committed
329 330
        return !this.$options.isObjectEmpty(this.model.last_deployment) &&
          !this.$options.isObjectEmpty(this.model.last_deployment.user);
Filipa Lacerda's avatar
Filipa Lacerda committed
331 332 333 334 335 336 337 338 339
      },

      /**
       * Returns the user object nested with the last_deployment object.
       * Used to render the template.
       *
       * @returns {Object}
       */
      deploymentUser() {
Filipa Lacerda's avatar
Filipa Lacerda committed
340 341
        if (!this.$options.isObjectEmpty(this.model.last_deployment) &&
          !this.$options.isObjectEmpty(this.model.last_deployment.user)) {
Filipa Lacerda's avatar
Filipa Lacerda committed
342 343 344 345
          return this.model.last_deployment.user;
        }
        return {};
      },
Filipa Lacerda's avatar
Filipa Lacerda committed
346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371

      /**
       * Verifies if the build name column should be rendered by verifing
       * if all the information needed is present
       * and if the environment is not a folder.
       *
       * @returns {Boolean}
       */
      shouldRenderBuildName() {
        return !this.isFolder &&
          !this.$options.isObjectEmpty(this.model.last_deployment) &&
          !this.$options.isObjectEmpty(this.model.last_deployment.deployable);
      },

      /**
       * Verifies if deplyment internal ID should be rendered by verifing
       * if all the information needed is present
       * and if the environment is not a folder.
       *
       * @returns {Boolean}
       */
      shouldRenderDeploymentID() {
        return !this.isFolder &&
          !this.$options.isObjectEmpty(this.model.last_deployment) &&
          this.model.last_deployment.iid !== undefined;
      },
Filipa Lacerda's avatar
Filipa Lacerda committed
372 373
    },

374 375 376 377 378 379 380 381 382 383 384 385 386 387 388
    /**
     * Helper to verify if certain given object are empty.
     * Should be replaced by lodash _.isEmpty - https://lodash.com/docs/4.17.2#isEmpty
     * @param  {Object} object
     * @returns {Bollean}
     */
    isObjectEmpty(object) {
      for (const key in object) { // eslint-disable-line
        if (hasOwnProperty.call(object, key)) {
          return false;
        }
      }
      return true;
    },

Filipa Lacerda's avatar
Filipa Lacerda committed
389 390
    template: `
      <tr>
391
        <td v-bind:class="{ 'children-row': isChildren}">
Filipa Lacerda's avatar
Filipa Lacerda committed
392
          <a v-if="!isFolder"
Filipa Lacerda's avatar
Filipa Lacerda committed
393
            class="environment-name"
Filipa Lacerda's avatar
Filipa Lacerda committed
394 395
            :href="model.environment_path">
            {{model.name}}
Filipa Lacerda's avatar
Filipa Lacerda committed
396
          </a>
397
          <span v-else v-on:click="toggleRow(model)" class="folder-name">
Filipa Lacerda's avatar
Filipa Lacerda committed
398
            <span class="folder-icon">
399 400
              <i v-show="model.isOpen" class="fa fa-caret-down"></i>
              <i v-show="!model.isOpen" class="fa fa-caret-right"></i>
Filipa Lacerda's avatar
Filipa Lacerda committed
401 402
            </span>

Filipa Lacerda's avatar
Filipa Lacerda committed
403 404 405
            <span>
              {{model.name}}
            </span>
Filipa Lacerda's avatar
Filipa Lacerda committed
406

Filipa Lacerda's avatar
Filipa Lacerda committed
407 408 409
            <span class="badge">
              {{childrenCounter}}
            </span>
Filipa Lacerda's avatar
Filipa Lacerda committed
410 411 412
          </span>
        </td>

413
        <td class="deployment-column">
Filipa Lacerda's avatar
Filipa Lacerda committed
414
          <span v-if="shouldRenderDeploymentID">
Filipa Lacerda's avatar
Filipa Lacerda committed
415
            {{deploymentInternalId}}
Filipa Lacerda's avatar
Filipa Lacerda committed
416 417 418 419 420 421 422 423 424 425
          </span>

          <span v-if="!isFolder && deploymentHasUser">
            by
            <a :href="deploymentUser.web_url" class="js-deploy-user-container">
              <img class="avatar has-tooltip s20"
                :src="deploymentUser.avatar_url"
                :alt="userImageAltDescription"
                :title="deploymentUser.username" />
            </a>
Filipa Lacerda's avatar
Filipa Lacerda committed
426 427 428
          </span>
        </td>

429
        <td>
Filipa Lacerda's avatar
Filipa Lacerda committed
430
          <a v-if="shouldRenderBuildName"
Filipa Lacerda's avatar
Filipa Lacerda committed
431
            class="build-link"
Filipa Lacerda's avatar
Filipa Lacerda committed
432 433
            :href="model.last_deployment.deployable.build_path">
            {{buildName}}
Filipa Lacerda's avatar
Filipa Lacerda committed
434 435 436
          </a>
        </td>

437
        <td>
Filipa Lacerda's avatar
Filipa Lacerda committed
438
          <div v-if="!isFolder && hasLastDeploymentKey" class="js-commit-component">
Filipa Lacerda's avatar
Filipa Lacerda committed
439 440 441 442 443 444 445 446 447
            <commit-component
              :tag="commitTag"
              :ref="commitRef"
              :commit_url="commitUrl"
              :short_sha="commitShortSha"
              :title="commitTitle"
              :author="commitAuthor">
            </commit-component>
          </div>
Filipa Lacerda's avatar
Filipa Lacerda committed
448
          <p v-if="!isFolder && !hasLastDeploymentKey" class="commit-title">
Filipa Lacerda's avatar
Filipa Lacerda committed
449 450 451 452
            No deployments yet
          </p>
        </td>

453
        <td>
Filipa Lacerda's avatar
Filipa Lacerda committed
454 455
          <span
            v-if="!isFolder && model.last_deployment"
Filipa Lacerda's avatar
Filipa Lacerda committed
456 457
            class="environment-created-date-timeago">
            {{createdDate}}
Filipa Lacerda's avatar
Filipa Lacerda committed
458 459 460
          </span>
        </td>

461
        <td class="hidden-xs">
Filipa Lacerda's avatar
Filipa Lacerda committed
462
          <div v-if="!isFolder">
Filipa Lacerda's avatar
Filipa Lacerda committed
463 464
            <div v-if="hasManualActions && canCreateDeployment"
              class="inline js-manual-actions-container">
Filipa Lacerda's avatar
Filipa Lacerda committed
465
              <actions-component
466 467
                :actions="manualActions">
              </actions-component>
Filipa Lacerda's avatar
Filipa Lacerda committed
468
            </div>
469

Filipa Lacerda's avatar
Filipa Lacerda committed
470 471
            <div v-if="model.external_url && canReadEnvironment"
              class="inline js-external-url-container">
Filipa Lacerda's avatar
Filipa Lacerda committed
472
              <external-url-component
473 474 475
                :external_url="model.external_url">
              </external_url-component>
            </div>
476

Filipa Lacerda's avatar
Filipa Lacerda committed
477 478
            <div v-if="isStoppable && canCreateDeployment"
              class="inline js-stop-component-container">
Filipa Lacerda's avatar
Filipa Lacerda committed
479
              <stop-component
480
                :stop_url="model.stop_path">
481 482 483
              </stop-component>
            </div>

Filipa Lacerda's avatar
Filipa Lacerda committed
484 485
            <div v-if="canRetry && canCreateDeployment"
              class="inline js-rollback-component-container">
Filipa Lacerda's avatar
Filipa Lacerda committed
486
              <rollback-component
487 488 489 490
                :is_last_deployment="isLastDeployment"
                :retry_url="retryUrl">
                </rollback-component>
            </div>
Filipa Lacerda's avatar
Filipa Lacerda committed
491 492 493 494
          </div>
        </td>
      </tr>
    `,
Filipa Lacerda's avatar
Filipa Lacerda committed
495
  });
496
})();