gitlab-org--gitlab-foss/app/assets/javascripts/environments/components/environment_item.js.es6

522 lines
15 KiB
JavaScript
Raw Normal View History

/* global Vue */
/* global timeago */
/*= require timeago */
2016-11-16 06:23:36 -05:00
/*= require lib/utils/text_utility */
/*= require vue_common_component/commit */
/*= require ./environment_actions */
/*= require ./environment_external_url */
/*= require ./environment_stop */
/*= require ./environment_rollback */
2016-11-09 13:52:26 -05:00
2016-10-14 13:38:13 -04:00
(() => {
/**
* Envrionment Item Component
2016-10-26 11:00:16 -04:00
*
* Used in a hierarchical structure to show folders with children
* in a table.
2016-10-26 11:00:16 -04:00
* 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)
2016-11-16 06:23:36 -05:00
* for more information.15
*/
2016-10-26 11:00:16 -04:00
2016-10-14 13:38:13 -04:00
window.gl = window.gl || {};
window.gl.environmentsList = window.gl.environmentsList || {};
2016-11-29 13:54:34 -05:00
window.gl.environmentsList.timeagoInstance = new timeago(); // eslint-disable-line
2016-10-26 11:00:16 -04:00
gl.environmentsList.EnvironmentItem = Vue.component('environment-item', {
2016-10-26 11:00:16 -04:00
components: {
2016-11-09 12:36:42 -05:00
'commit-component': window.gl.CommitComponent,
'actions-component': window.gl.environmentsList.ActionsComponent,
'external-url-component': window.gl.environmentsList.ExternalUrlComponent,
2016-11-09 13:52:26 -05:00
'stop-component': window.gl.environmentsList.StopComponent,
'rollback-component': window.gl.environmentsList.RollbackComponent,
},
2016-10-14 13:38:13 -04:00
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,
},
2016-12-08 06:42:56 -05:00
commitIconSvg: {
type: String,
required: false,
},
playIconSvg: {
type: String,
required: false,
},
},
2016-10-14 13:38:13 -04:00
data() {
2016-10-14 13:38:13 -04:00
return {
rowClass: {
'children-row': this.model['vue-isChildren'],
},
2016-10-14 13:38:13 -04:00
};
},
2016-10-24 07:42:01 -04:00
2016-10-14 13:38:13 -04:00
computed: {
2016-10-26 11:00:16 -04:00
/**
* If an item has a `children` entry it means it is a folder.
* Folder items have different behaviours - it is possible to toggle
2016-10-26 11:00:16 -04:00
* them and show their children.
*
* @returns {Boolean|Undefined}
*/
isFolder() {
2016-11-17 11:20:52 -05:00
return this.model.children && this.model.children.length > 0;
},
2016-10-24 07:42:01 -04:00
/**
* If an item is inside a folder structure will return true.
* Used for css purposes.
*
* @returns {Boolean|undefined}
*/
isChildren() {
return this.model['vue-isChildren'];
},
2016-10-24 07:42:01 -04:00
/**
* Counts the number of environments in each folder.
* Used to show a badge with the counter.
*
* @returns {Number|Undefined} The number of environments for the current folder.
*/
childrenCounter() {
2016-11-17 11:20:52 -05:00
return this.model.children && this.model.children.length;
},
/**
* 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() {
2016-11-17 16:32:43 -05:00
if (this.model.last_deployment &&
!this.$options.isObjectEmpty(this.model.last_deployment)) {
return true;
}
return false;
},
/**
* Verifies is the given environment has manual actions.
* Used to verify if we should render them or nor.
*
* @returns {Boolean|Undefined}
*/
hasManualActions() {
return this.model.last_deployment && this.model.last_deployment.manual_actions &&
this.model.last_deployment.manual_actions.length > 0;
},
/**
* 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.
*
* @returns {Boolean|Undefined}
*/
canRetry() {
return this.hasLastDeploymentKey &&
this.model.last_deployment &&
this.model.last_deployment.deployable;
},
2016-11-29 13:54:34 -05:00
/**
* Verifies if the date to be shown is present.
*
* @returns {Boolean|Undefined}
*/
canShowDate() {
return this.model.last_deployment &&
this.model.last_deployment.deployable &&
2016-11-29 13:54:34 -05:00
this.model.last_deployment.deployable !== undefined;
},
2016-11-07 15:52:04 -05:00
/**
* Human readable date.
*
* @returns {String}
*/
createdDate() {
2016-11-29 13:54:34 -05:00
return window.gl.environmentsList.timeagoInstance.format(
this.model.last_deployment.deployable.created_at,
2016-11-29 13:54:34 -05:00
);
},
2016-11-07 15:52:04 -05:00
/**
* Returns the manual actions with the name parsed.
*
* @returns {Array.<Object>|Undefined}
2016-11-07 15:52:04 -05:00
*/
manualActions() {
if (this.hasManualActions) {
return this.model.last_deployment.manual_actions.map((action) => {
const parsedAction = {
name: gl.text.humanize(action.name),
2016-11-17 11:17:22 -05:00
play_path: action.play_path,
};
return parsedAction;
});
}
return [];
},
/**
* Builds the string used in the user image alt attribute.
*
* @returns {String}
*/
userImageAltDescription() {
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 '';
},
2016-11-09 06:26:27 -05:00
/**
* If provided, returns the commit tag.
*
* @returns {String|Undefined}
*/
commitTag() {
if (this.model.last_deployment &&
this.model.last_deployment.tag) {
return this.model.last_deployment.tag;
}
2016-11-09 06:26:27 -05:00
return undefined;
},
/**
* If provided, returns the commit ref.
*
* @returns {Object|Undefined}
*/
commitRef() {
2016-11-17 16:46:41 -05:00
if (this.model.last_deployment && this.model.last_deployment.ref) {
2016-11-09 06:26:27 -05:00
return this.model.last_deployment.ref;
}
2016-11-09 06:26:27 -05:00
return undefined;
},
2016-11-09 06:26:27 -05:00
/**
* If provided, returns the commit url.
*
* @returns {String|Undefined}
*/
commitUrl() {
if (this.model.last_deployment &&
this.model.last_deployment.commit &&
2016-11-17 11:17:22 -05:00
this.model.last_deployment.commit.commit_path) {
return this.model.last_deployment.commit.commit_path;
}
2016-11-09 06:26:27 -05:00
return undefined;
},
/**
* 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) {
2016-11-09 06:26:27 -05:00
return this.model.last_deployment.commit.short_id;
}
2016-11-09 06:26:27 -05:00
return undefined;
},
/**
* If provided, returns the commit title.
*
* @returns {String|Undefined}
*/
2016-11-09 06:26:27 -05:00
commitTitle() {
if (this.model.last_deployment &&
this.model.last_deployment.commit &&
this.model.last_deployment.commit.title) {
2016-11-09 06:26:27 -05:00
return this.model.last_deployment.commit.title;
}
2016-11-09 06:26:27 -05:00
return undefined;
},
/**
* If provided, returns the commit tag.
*
* @returns {Object|Undefined}
*/
2016-11-09 06:26:27 -05:00
commitAuthor() {
if (this.model.last_deployment &&
this.model.last_deployment.commit &&
this.model.last_deployment.commit.author) {
return this.model.last_deployment.commit.author;
}
2016-11-09 06:26:27 -05:00
return undefined;
},
2016-11-09 12:53:06 -05:00
/**
2016-11-17 11:17:22 -05:00
* Verifies if the `retry_path` key is present and returns its value.
*
* @returns {String|Undefined}
*/
2016-11-09 13:52:26 -05:00
retryUrl() {
if (this.model.last_deployment &&
this.model.last_deployment.deployable &&
2016-11-17 11:17:22 -05:00
this.model.last_deployment.deployable.retry_path) {
return this.model.last_deployment.deployable.retry_path;
2016-11-09 13:52:26 -05:00
}
return undefined;
},
/**
* Verifies if the `last?` key is present and returns its value.
*
* @returns {Boolean|Undefined}
*/
2016-11-09 13:52:26 -05:00
isLastDeployment() {
return this.model.last_deployment && this.model.last_deployment['last?'];
},
2016-11-14 06:17:02 -05:00
/**
* Builds the name of the builds needed to display both the name and the id.
*
* @returns {String}
*/
2016-11-14 06:17:02 -05:00
buildName() {
if (this.model.last_deployment &&
this.model.last_deployment.deployable) {
2016-11-14 06:17:02 -05:00
return `${this.model.last_deployment.deployable.name} #${this.model.last_deployment.deployable.id}`;
}
return '';
2016-11-14 06:17:02 -05:00
},
/**
* Builds the needed string to show the internal id.
*
* @returns {String}
*/
2016-11-14 06:17:02 -05:00
deploymentInternalId() {
if (this.model.last_deployment &&
this.model.last_deployment.iid) {
2016-11-14 06:17:02 -05:00
return `#${this.model.last_deployment.iid}`;
}
return '';
},
/**
* Verifies if the user object is present under last_deployment object.
*
* @returns {Boolean}
*/
deploymentHasUser() {
2016-11-17 16:46:41 -05:00
return !this.$options.isObjectEmpty(this.model.last_deployment) &&
!this.$options.isObjectEmpty(this.model.last_deployment.user);
},
/**
* Returns the user object nested with the last_deployment object.
* Used to render the template.
*
* @returns {Object}
*/
deploymentUser() {
2016-11-17 16:46:41 -05:00
if (!this.$options.isObjectEmpty(this.model.last_deployment) &&
!this.$options.isObjectEmpty(this.model.last_deployment.user)) {
return this.model.last_deployment.user;
}
return {};
},
2016-11-17 16:46:41 -05:00
/**
* 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;
},
2016-10-14 13:38:13 -04:00
},
2016-11-17 16:32:43 -05:00
/**
* 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;
},
template: `
<tr>
<td v-bind:class="{ 'children-row': isChildren}">
2016-11-21 08:57:27 -05:00
<a v-if="!isFolder"
2016-11-14 06:17:02 -05:00
class="environment-name"
2016-11-21 06:45:22 -05:00
:href="model.environment_path">
{{model.name}}
</a>
<span v-else v-on:click="toggleRow(model)" class="folder-name">
<span class="folder-icon">
<i v-show="model.isOpen" class="fa fa-caret-down"></i>
<i v-show="!model.isOpen" class="fa fa-caret-right"></i>
</span>
2016-11-21 06:45:22 -05:00
<span>
{{model.name}}
</span>
2016-11-21 06:45:22 -05:00
<span class="badge">
{{childrenCounter}}
</span>
</span>
</td>
<td class="deployment-column">
2016-11-21 08:57:27 -05:00
<span v-if="shouldRenderDeploymentID">
2016-11-21 06:45:22 -05:00
{{deploymentInternalId}}
</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>
</span>
</td>
<td class="environments-build-cell">
2016-11-17 16:46:41 -05:00
<a v-if="shouldRenderBuildName"
class="build-link"
2016-11-21 06:45:22 -05:00
:href="model.last_deployment.deployable.build_path">
{{buildName}}
</a>
</td>
<td>
<div v-if="!isFolder && hasLastDeploymentKey" class="js-commit-component">
<commit-component
:tag="commitTag"
2016-12-08 06:54:08 -05:00
:commit-ref="commitRef"
:commit-url="commitUrl"
:short-sha="commitShortSha"
:title="commitTitle"
2016-12-08 06:48:19 -05:00
:author="commitAuthor"
:commit-icon-svg="commitIconSvg">
</commit-component>
</div>
<p v-if="!isFolder && !hasLastDeploymentKey" class="commit-title">
No deployments yet
</p>
</td>
<td>
2016-11-14 06:17:02 -05:00
<span
v-if="!isFolder && canShowDate"
2016-11-21 06:45:22 -05:00
class="environment-created-date-timeago">
{{createdDate}}
</span>
</td>
<td class="hidden-xs">
<div v-if="!isFolder">
2016-11-17 16:46:41 -05:00
<div v-if="hasManualActions && canCreateDeployment"
class="inline js-manual-actions-container">
<actions-component
2016-12-08 06:42:56 -05:00
:play-icon-svg="playIconSvg"
2016-11-09 13:52:26 -05:00
:actions="manualActions">
</actions-component>
2016-11-09 12:36:42 -05:00
</div>
2016-11-09 13:52:26 -05:00
2016-11-17 16:46:41 -05:00
<div v-if="model.external_url && canReadEnvironment"
class="inline js-external-url-container">
<external-url-component
2016-12-08 06:54:08 -05:00
:external-url="model.external_url">
</external-url-component>
</div>
2016-11-09 13:52:26 -05:00
2016-11-17 16:46:41 -05:00
<div v-if="isStoppable && canCreateDeployment"
class="inline js-stop-component-container">
<stop-component
2016-12-08 06:54:08 -05:00
:stop-url="model.stop_path">
2016-11-09 13:52:26 -05:00
</stop-component>
</div>
2016-11-17 16:46:41 -05:00
<div v-if="canRetry && canCreateDeployment"
class="inline js-rollback-component-container">
<rollback-component
2016-12-08 06:54:08 -05:00
:is-last-deployment="isLastDeployment"
:retry-url="retryUrl">
2016-11-09 13:52:26 -05:00
</rollback-component>
</div>
</div>
</td>
</tr>
`,
});
2016-10-20 07:09:35 -04:00
})();