Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Léo-Paul Géneau
gitlab-ce
Commits
d6ae01da
Commit
d6ae01da
authored
Feb 09, 2017
by
Filipa Lacerda
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Use CJS in all environments components
parent
8f3678f1
Changes
16
Hide whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
782 additions
and
817 deletions
+782
-817
app/assets/javascripts/environments/components/environment.js.es6
...ts/javascripts/environments/components/environment.js.es6
+178
-184
app/assets/javascripts/environments/components/environment_actions.js.es6
...cripts/environments/components/environment_actions.js.es6
+40
-47
app/assets/javascripts/environments/components/environment_external_url.js.es6
...s/environments/components/environment_external_url.js.es6
+16
-20
app/assets/javascripts/environments/components/environment_item.js.es6
...vascripts/environments/components/environment_item.js.es6
+455
-463
app/assets/javascripts/environments/components/environment_rollback.js.es6
...ripts/environments/components/environment_rollback.js.es6
+26
-29
app/assets/javascripts/environments/components/environment_stop.js.es6
...vascripts/environments/components/environment_stop.js.es6
+21
-24
app/assets/javascripts/environments/components/environment_terminal_button.js.es6
...nvironments/components/environment_terminal_button.js.es6
+22
-25
app/assets/javascripts/environments/environments_bundle.js.es6
...ssets/javascripts/environments/environments_bundle.js.es6
+2
-3
app/assets/javascripts/environments/services/environments_service.js.es6
...scripts/environments/services/environments_service.js.es6
+1
-1
app/assets/javascripts/vue_shared/components/commit.js.es6
app/assets/javascripts/vue_shared/components/commit.js.es6
+1
-0
spec/javascripts/environments/environment_actions_spec.js.es6
.../javascripts/environments/environment_actions_spec.js.es6
+3
-3
spec/javascripts/environments/environment_external_url_spec.js.es6
...scripts/environments/environment_external_url_spec.js.es6
+2
-2
spec/javascripts/environments/environment_item_spec.js.es6
spec/javascripts/environments/environment_item_spec.js.es6
+4
-4
spec/javascripts/environments/environment_rollback_spec.js.es6
...javascripts/environments/environment_rollback_spec.js.es6
+4
-4
spec/javascripts/environments/environment_spec.js.es6
spec/javascripts/environments/environment_spec.js.es6
+5
-6
spec/javascripts/environments/environment_stop_spec.js.es6
spec/javascripts/environments/environment_stop_spec.js.es6
+2
-2
No files found.
app/assets/javascripts/environments/components/environment.js.es6
View file @
d6ae01da
/* eslint-disable no-param-reassign, no-new */
/* global Vue */
/* global EnvironmentsService */
/* global Flash */
window.
Vue = require('vue');
window.
Vue.use(require('vue-resource'));
const
Vue = require('vue');
Vue.use(require('vue-resource'));
const EnvironmentsService = require('../services/environments_service');
require('./environment_item');
const EnvironmentItem =
require('./environment_item');
const Store = require('../stores/environments_store');
(() => {
window.gl = window.gl || {};
gl.environmentsList.EnvironmentsComponent = Vue.component('environment-component', {
components: {
'environment-item': gl.environmentsList.EnvironmentItem,
},
data() {
const environmentsData = document.querySelector('#environments-list-view').dataset;
const store = new Store();
return {
store,
state: store.state,
visibility: 'available',
isLoading: false,
cssContainerClass: environmentsData.cssClass,
endpoint: environmentsData.environmentsDataEndpoint,
canCreateDeployment: environmentsData.canCreateDeployment,
canReadEnvironment: environmentsData.canReadEnvironment,
canCreateEnvironment: environmentsData.canCreateEnvironment,
projectEnvironmentsPath: environmentsData.projectEnvironmentsPath,
projectStoppedEnvironmentsPath: environmentsData.projectStoppedEnvironmentsPath,
newEnvironmentPath: environmentsData.newEnvironmentPath,
helpPagePath: environmentsData.helpPagePath,
commitIconSvg: environmentsData.commitIconSvg,
playIconSvg: environmentsData.playIconSvg,
terminalIconSvg: environmentsData.terminalIconSvg,
};
module.exports = Vue.component('environment-component', {
components: {
'environment-item': EnvironmentItem,
},
data() {
const environmentsData = document.querySelector('#environments-list-view').dataset;
const store = new Store();
return {
store,
state: store.state,
visibility: 'available',
isLoading: false,
cssContainerClass: environmentsData.cssClass,
endpoint: environmentsData.environmentsDataEndpoint,
canCreateDeployment: environmentsData.canCreateDeployment,
canReadEnvironment: environmentsData.canReadEnvironment,
canCreateEnvironment: environmentsData.canCreateEnvironment,
projectEnvironmentsPath: environmentsData.projectEnvironmentsPath,
projectStoppedEnvironmentsPath: environmentsData.projectStoppedEnvironmentsPath,
newEnvironmentPath: environmentsData.newEnvironmentPath,
helpPagePath: environmentsData.helpPagePath,
commitIconSvg: environmentsData.commitIconSvg,
playIconSvg: environmentsData.playIconSvg,
terminalIconSvg: environmentsData.terminalIconSvg,
};
},
computed: {
scope() {
return this.$options.getQueryParameter('scope');
},
computed: {
scope() {
return this.$options.getQueryParameter('scope');
},
canReadEnvironmentParsed() {
return this.$options.convertPermissionToBoolean(this.canReadEnvironment);
},
canCreateDeploymentParsed() {
return this.$options.convertPermissionToBoolean(this.canCreateDeployment);
},
canCreateEnvironmentParsed() {
return this.$options.convertPermissionToBoolean(this.canCreateEnvironment);
},
canReadEnvironmentParsed() {
return this.$options.convertPermissionToBoolean(this.canReadEnvironment);
},
/**
* Fetches all the environments and stores them.
* Toggles loading property.
*/
created() {
const scope = this.$options.getQueryParameter('scope') || this.visibility;
const endpoint = `${this.endpoint}?scope=${scope}`;
const service = new EnvironmentsService(endpoint);
this.isLoading = true;
return service.all()
.then(resp => resp.json())
.then((json) => {
this.store.storeAvailableCount(json.available_count);
this.store.storeStoppedCount(json.stopped_count);
this.store.storeEnvironments(json.environments);
})
.then(() => {
this.isLoading = false;
})
.catch(() => {
this.isLoading = false;
new Flash('An error occurred while fetching the environments.', 'alert');
});
canCreateDeploymentParsed() {
return this.$options.convertPermissionToBoolean(this.canCreateDeployment);
},
/**
* Transforms the url parameter into an object and
* returns the one requested.
*
* @param {String} param
* @returns {String} The value of the requested parameter.
*/
getQueryParameter(parameter) {
return window.location.search.substring(1).split('&').reduce((acc, param) => {
const paramSplited = param.split('=');
acc[paramSplited[0]] = paramSplited[1];
return acc;
}, {})[parameter];
canCreateEnvironmentParsed() {
return this.$options.convertPermissionToBoolean(this.canCreateEnvironment);
},
/**
* Converts permission provided as strings to booleans.
* @param {String} string
* @returns {Boolean}
*/
convertPermissionToBoolean(string) {
return string === 'true';
},
/**
* Fetches all the environments and stores them.
* Toggles loading property.
*/
created() {
const scope = this.$options.getQueryParameter('scope') || this.visibility;
const endpoint = `${this.endpoint}?scope=${scope}`;
const service = new EnvironmentsService(endpoint);
this.isLoading = true;
return service.all()
.then(resp => resp.json())
.then((json) => {
this.store.storeAvailableCount(json.available_count);
this.store.storeStoppedCount(json.stopped_count);
this.store.storeEnvironments(json.environments);
})
.then(() => {
this.isLoading = false;
})
.catch(() => {
this.isLoading = false;
new Flash('An error occurred while fetching the environments.', 'alert');
});
},
/**
* Transforms the url parameter into an object and
* returns the one requested.
*
* @param {String} param
* @returns {String} The value of the requested parameter.
*/
getQueryParameter(parameter) {
return window.location.search.substring(1).split('&').reduce((acc, param) => {
const paramSplited = param.split('=');
acc[paramSplited[0]] = paramSplited[1];
return acc;
}, {})[parameter];
},
/**
* Converts permission provided as strings to booleans.
* @param {String} string
* @returns {Boolean}
*/
convertPermissionToBoolean(string) {
return string === 'true';
},
methods: {
toggleRow(model) {
return this.store.toggleFolder(model.name);
},
},
template: `
<div :class="cssContainerClass">
<div class="top-area">
<ul v-if="!isLoading" class="nav-links">
<li v-bind:class="{ 'active': scope === undefined }">
<a :href="projectEnvironmentsPath">
Available
<span class="badge js-available-environments-count">
{{state.availableCounter}}
</span>
</a>
</li>
<li v-bind:class="{ 'active' : scope === 'stopped' }">
<a :href="projectStoppedEnvironmentsPath">
Stopped
<span class="badge js-stopped-environments-count">
{{state.stoppedCounter}}
</span>
</a>
</li>
</ul>
<div v-if="canCreateEnvironmentParsed && !isLoading" class="nav-controls">
<a :href="newEnvironmentPath" class="btn btn-create">
New environment
</a>
</div>
</div>
methods: {
toggleRow(model) {
return this.store.toggleFolder(model.name);
},
},
<div class="environments-container">
<div class="environments-list-loading text-center" v-if="isLoading">
<i class="fa fa-spinner fa-spin"></i>
</div>
template: `
<div :class="cssContainerClass">
<div class="top-area">
<ul v-if="!isLoading" class="nav-links">
<li v-bind:class="{ 'active': scope === undefined }">
<a :href="projectEnvironmentsPath">
Available
<span class="badge js-available-environments-count">
{{state.availableCounter}}
</span>
</a>
</li>
<li v-bind:class="{ 'active' : scope === 'stopped' }">
<a :href="projectStoppedEnvironmentsPath">
Stopped
<span class="badge js-stopped-environments-count">
{{state.stoppedCounter}}
</span>
</a>
</li>
</ul>
<div v-if="canCreateEnvironmentParsed && !isLoading" class="nav-controls">
<a :href="newEnvironmentPath" class="btn btn-create">
New environment
<div class="blank-state blank-state-no-icon"
v-if="!isLoading && state.environments.length === 0">
<h2 class="blank-state-title js-blank-state-title">
You don't have any environments right now.
</h2>
<p class="blank-state-text">
Environments are places where code gets deployed, such as staging or production.
<br />
<a :href="helpPagePath">
Read more about environments
</a>
</div>
</p>
<a v-if="canCreateEnvironmentParsed"
:href="newEnvironmentPath"
class="btn btn-create js-new-environment-button">
New Environment
</a>
</div>
<div class="environments-container">
<div class="environments-list-loading text-center" v-if="isLoading">
<i class="fa fa-spinner fa-spin"></i>
</div>
<div class="blank-state blank-state-no-icon"
v-if="!isLoading && state.environments.length === 0">
<h2 class="blank-state-title js-blank-state-title">
You don't have any environments right now.
</h2>
<p class="blank-state-text">
Environments are places where code gets deployed, such as staging or production.
<br />
<a :href="helpPagePath">
Read more about environments
</a>
</p>
<a v-if="canCreateEnvironmentParsed"
:href="newEnvironmentPath"
class="btn btn-create js-new-environment-button">
New Environment
</a>
</div>
<div class="table-holder"
v-if="!isLoading && state.environments.length > 0">
<table class="table ci-table environments">
<thead>
<tr>
<th class="environments-name">Environment</th>
<th class="environments-deploy">Last deployment</th>
<th class="environments-build">Job</th>
<th class="environments-commit">Commit</th>
<th class="environments-date">Updated</th>
<th class="hidden-xs environments-actions"></th>
</tr>
</thead>
<tbody>
<template v-for="model in state.environments"
v-bind:model="model">
<tr is="environment-item"
:model="model"
:can-create-deployment="canCreateDeploymentParsed"
:can-read-environment="canReadEnvironmentParsed"
:play-icon-svg="playIconSvg"
:terminal-icon-svg="terminalIconSvg"
:commit-icon-svg="commitIconSvg"></tr>
</template>
</tbody>
</table>
</div>
<div class="table-holder"
v-if="!isLoading && state.environments.length > 0">
<table class="table ci-table environments">
<thead>
<tr>
<th class="environments-name">Environment</th>
<th class="environments-deploy">Last deployment</th>
<th class="environments-build">Job</th>
<th class="environments-commit">Commit</th>
<th class="environments-date">Updated</th>
<th class="hidden-xs environments-actions"></th>
</tr>
</thead>
<tbody>
<template v-for="model in state.environments"
v-bind:model="model">
<tr is="environment-item"
:model="model"
:can-create-deployment="canCreateDeploymentParsed"
:can-read-environment="canReadEnvironmentParsed"
:play-icon-svg="playIconSvg"
:terminal-icon-svg="terminalIconSvg"
:commit-icon-svg="commitIconSvg"></tr>
</template>
</tbody>
</table>
</div>
</div>
`,
});
})
()
;
</div>
`,
});
app/assets/javascripts/environments/components/environment_actions.js.es6
View file @
d6ae01da
/* global Vue */
window.Vue = require('vue');
(() => {
window.gl = window.gl || {};
window.gl.environmentsList = window.gl.environmentsList || {};
gl.environmentsList.ActionsComponent = Vue.component('actions-component', {
props: {
actions: {
type: Array,
required: false,
default: () => [],
},
playIconSvg: {
type: String,
required: false,
},
const Vue = require('vue');
module.exports = Vue.component('actions-component', {
props: {
actions: {
type: Array,
required: false,
default: () => [],
},
template: `
<div class="inline">
<div class="dropdown">
<a class="dropdown-new btn btn-default" data-toggle="dropdown">
<span class="js-dropdown-play-icon-container" v-html="playIconSvg"></span>
<i class="fa fa-caret-down"></i>
</a>
<ul class="dropdown-menu dropdown-menu-align-right">
<li v-for="action in actions">
<a :href="action.play_path"
data-method="post"
rel="nofollow"
class="js-manual-action-link">
<span class="js-action-play-icon-container" v-html="playIconSvg"></span>
<span>
{{action.name}}
</span>
</a>
</li>
</ul>
</div>
playIconSvg: {
type: String,
required: false,
},
},
template: `
<div class="inline">
<div class="dropdown">
<a class="dropdown-new btn btn-default" data-toggle="dropdown">
<span class="js-dropdown-play-icon-container" v-html="playIconSvg"></span>
<i class="fa fa-caret-down"></i>
</a>
<ul class="dropdown-menu dropdown-menu-align-right">
<li v-for="action in actions">
<a :href="action.play_path"
data-method="post"
rel="nofollow"
class="js-manual-action-link">
<span class="js-action-play-icon-container" v-html="playIconSvg"></span>
<span>
{{action.name}}
</span>
</a>
</li>
</ul>
</div>
`,
});
})
()
;
</div>
`,
});
app/assets/javascripts/environments/components/environment_external_url.js.es6
View file @
d6ae01da
/* global Vue */
/**
* Renders the external url link in environments table.
*/
const Vue = require('vue');
window.Vue = require('vue');
(() => {
window.gl = window.gl || {};
window.gl.environmentsList = window.gl.environmentsList || {};
gl.environmentsList.ExternalUrlComponent = Vue.component('external-url-component', {
props: {
externalUrl: {
type: String,
default: '',
},
module.exports = Vue.component('external-url-component', {
props: {
externalUrl: {
type: String,
default: '',
},
},
template: `
<a class="btn external_url" :href="externalUrl" target="_blank">
<i class="fa fa-external-link"></i>
</a>
`,
});
})();
template: `
<a class="btn external_url" :href="externalUrl" target="_blank">
<i class="fa fa-external-link"></i>
</a>
`,
});
app/assets/javascripts/environments/components/environment_item.js.es6
View file @
d6ae01da
/* global Vue */
/* global timeago */
window.
Vue = require('vue');
window.t
imeago = require('vendor/timeago');
const
Vue = require('vue');
const T
imeago = require('vendor/timeago');
require('../../lib/utils/text_utility');
require('../../vue_shared/components/commit');
require('./environment_actions');
require('./environment_external_url');
require('./environment_stop');
require('./environment_rollback');
require('./environment_terminal_button');
const ActionsComponent = require('./environment_actions');
const ExternalUrlComponent = require('./environment_external_url');
const StopComponent = require('./environment_stop');
const RollbackComponent = require('./environment_rollback');
const TerminalButtonComponent = require('./environment_terminal_button');
/**
* Envrionment Item Component
*
* Renders a table row for each environment.
*/
const timeagoInstance = new Timeago();
module.exports = Vue.component('environment-item', {
components: {
'commit-component': gl.CommitComponent,
'actions-component': ActionsComponent,
'external-url-component': ExternalUrlComponent,
'stop-component': StopComponent,
'rollback-component': RollbackComponent,
'terminal-button-component': TerminalButtonComponent,
},
props: {
model: {
type: Object,
required: true,
default: () => ({}),
},
(() => {
/**
* Envrionment Item Component
*
* Renders a table row for each environment.
*/
canCreateDeployment: {
type: Boolean,
required: false,
default: false,
},
window.gl = window.gl || {};
window.gl.environmentsList = window.gl.environmentsList || {};
window.gl.environmentsList.timeagoInstance = new timeago(); // eslint-disable-line
canReadEnvironment: {
type: Boolean,
required: false,
default: false,
},
gl.environmentsList.EnvironmentItem = Vue.component('environment-item', {
commitIconSvg: {
type: String,
required: false,
},
components: {
'commit-component': gl.CommitComponent,
'actions-component': gl.environmentsList.ActionsComponent,
'external-url-component': gl.environmentsList.ExternalUrlComponent,
'stop-component': gl.environmentsList.StopComponent,
'rollback-component': gl.environmentsList.RollbackComponent,
'terminal-button-component': gl.environmentsList.TerminalButtonComponent,
playIconSvg: {
type: String,
required: false,
},
props: {
model: {
type: Object,
required: true,
default: () => ({}),
},
canCreateDeployment: {
type: Boolean,
required: false,
default: false,
},
canReadEnvironment: {
type: Boolean,
required: false,
default: false,
},
commitIconSvg: {
type: String,
required: false,
},
playIconSvg: {
type: String,
required: false,
},
terminalIconSvg: {
type: String,
required: false,
},
terminalIconSvg: {
type: String,
required: false,
},
},
computed: {
/**
* 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() {
if (this.model.latest.last_deployment &&
!this.$options.isObjectEmpty(this.model.latest.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.latest.last_deployment &&
this.model.latest.last_deployment.manual_actions &&
this.model.latest.last_deployment.manual_actions.length > 0;
},
/**
* Returns the value of the `stop_action?` key provided in the response.
*
* @returns {Boolean}
*/
hasStopAction() {
return this.model['stop_action?'];
},
/**
* 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.latest.last_deployment &&
this.model.latest.last_deployment.deployable;
},
/**
* Verifies if the date to be shown is present.
*
* @returns {Boolean|Undefined}
*/
canShowDate() {
return this.model.latest.last_deployment &&
this.model.latest.last_deployment.deployable &&
this.model.latest.last_deployment.deployable !== undefined;
},
/**
* Human readable date.
*
* @returns {String}
*/
createdDate() {
return gl.environmentsList.timeagoInstance.format(
this.model.latest.last_deployment.deployable.created_at,
);
},
/**
* Returns the manual actions with the name parsed.
*
* @returns {Array.<Object>|Undefined}
*/
manualActions() {
if (this.hasManualActions) {
return this.model.latest.last_deployment.manual_actions.map((action) => {
const parsedAction = {
name: gl.text.humanize(action.name),
play_path: action.play_path,
};
return parsedAction;
});
}
return [];
},
/**
* Builds the string used in the user image alt attribute.
*
* @returns {String}
*/
userImageAltDescription() {
if (this.model.latest.last_deployment &&
this.model.latest.last_deployment.user &&
this.model.latest.last_deployment.user.username) {
return `${this.model.latest.last_deployment.user.username}'s avatar'`;
}
return '';
},
/**
* If provided, returns the commit tag.
*
* @returns {String|Undefined}
*/
commitTag() {
if (this.model.latest.last_deployment &&
this.model.latest.last_deployment.tag) {
return this.model.latest.last_deployment.tag;
}
return undefined;
},
/**
* If provided, returns the commit ref.
*
* @returns {Object|Undefined}
*/
commitRef() {
if (this.model.latest.last_deployment &&
this.model.latest.last_deployment.ref) {
return this.model.latest.last_deployment.ref;
}
return undefined;
},
/**
* If provided, returns the commit url.
*
* @returns {String|Undefined}
*/
commitUrl() {
if (this.model.latest.last_deployment &&
this.model.latest.last_deployment.commit &&
this.model.latest.last_deployment.commit.commit_path) {
return this.model.latest.last_deployment.commit.commit_path;
}
return undefined;
},
/**
* If provided, returns the commit short sha.
*
* @returns {String|Undefined}
*/
commitShortSha() {
if (this.model.latest.last_deployment &&
this.model.latest.last_deployment.commit &&
this.model.latest.last_deployment.commit.short_id) {
return this.model.latest.last_deployment.commit.short_id;
}
return undefined;
},
/**
* If provided, returns the commit title.
*
* @returns {String|Undefined}
*/
commitTitle() {
if (this.model.latest.last_deployment &&
this.model.latest.last_deployment.commit &&
this.model.latest.last_deployment.commit.title) {
return this.model.latest.last_deployment.commit.title;
}
return undefined;
},
/**
* If provided, returns the commit tag.
*
* @returns {Object|Undefined}
*/
commitAuthor() {
if (this.model.latest.last_deployment &&
this.model.latest.last_deployment.commit &&
this.model.latest.last_deployment.commit.author) {
return this.model.latest.last_deployment.commit.author;
}
return undefined;
},
/**
* Verifies if the `retry_path` key is present and returns its value.
*
* @returns {String|Undefined}
*/
retryUrl() {
if (this.model.latest.last_deployment &&
this.model.latest.last_deployment.deployable &&
this.model.latest.last_deployment.deployable.retry_path) {
return this.model.latest.last_deployment.deployable.retry_path;
}
return undefined;
},
/**
* Verifies if the `last?` key is present and returns its value.
*
* @returns {Boolean|Undefined}
*/
isLastDeployment() {
return this.model.latest.last_deployment &&
this.model.latest.last_deployment['last?'];
},
/**
* Builds the name of the builds needed to display both the name and the id.
*
* @returns {String}
*/
buildName() {
if (this.model.latest.last_deployment &&
this.model.latest.last_deployment.deployable) {
return `${this.model.latest.last_deployment.deployable.name} #${this.model.latest.last_deployment.deployable.id}`;
}
return '';
},
/**
* Builds the needed string to show the internal id.
*
* @returns {String}
*/
deploymentInternalId() {
if (this.model.latest.last_deployment &&
this.model.latest.last_deployment.iid) {
return `#${this.model.latest.last_deployment.iid}`;
}
return '';
},
/**
* Verifies if the user object is present under last_deployment object.
*
* @returns {Boolean}
*/
deploymentHasUser() {
return !this.$options.isObjectEmpty(this.model.latest.last_deployment) &&
!this.$options.isObjectEmpty(this.model.latest.last_deployment.user);
},
/**
* Returns the user object nested with the last_deployment object.
* Used to render the template.
*
* @returns {Object}
*/
deploymentUser() {
if (!this.$options.isObjectEmpty(this.model.latest.last_deployment) &&
!this.$options.isObjectEmpty(this.model.latest.last_deployment.user)) {
return this.model.latest.last_deployment.user;
}
return {};
},
/**
* 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.model.isFolder &&
!this.$options.isObjectEmpty(this.model.latest.last_deployment) &&
!this.$options.isObjectEmpty(this.model.latest.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.model.isFolder &&
!this.$options.isObjectEmpty(this.model.latest.last_deployment) &&
this.model.latest.last_deployment.iid !== undefined;
},
computed: {
/**
* 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() {
if (this.model.latest.last_deployment &&
!this.$options.isObjectEmpty(this.model.latest.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.latest.last_deployment &&
this.model.latest.last_deployment.manual_actions &&
this.model.latest.last_deployment.manual_actions.length > 0;
},
/**
* Returns the value of the `stop_action?` key provided in the response.
*
* @returns {Boolean}
*/
hasStopAction() {
return this.model['stop_action?'];
},
/**
* 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.latest.last_deployment &&
this.model.latest.last_deployment.deployable;
},
/**
* Verifies if the date to be shown is present.
*
* @returns {Boolean|Undefined}
*/
canShowDate() {
return this.model.latest.last_deployment &&
this.model.latest.last_deployment.deployable &&
this.model.latest.last_deployment.deployable !== undefined;
},
/**
* Human readable date.
*
* @returns {String}
*/
createdDate() {
return timeagoInstance.format(this.model.latest.last_deployment.deployable.created_at);
},
/**
* 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}
* Returns the manual actions with the name parsed.
*
* @returns {Array.<Object>|Undefined}
*/
isObjectEmpty(object) {
for (const key in object) { // eslint-disable-line
if (hasOwnProperty.call(object, key)) {
return false;
}
manualActions() {
if (this.hasManualActions) {
return this.model.latest.last_deployment.manual_actions.map((action) => {
const parsedAction = {
name: gl.text.humanize(action.name),
play_path: action.play_path,
};
return parsedAction;
});
}
return
true
;
return
[]
;
},
template: `
<tr>
<td>
<a v-if="!model.isFolder"
class="environment-name"
:href="model.latest.environment_path">
{{model.name}}
</a>
<a v-else class="folder-name">
<span class="folder-icon">
<i class="fa fa-caret-right" aria-hidden="true"></i>
<i class="fa fa-folder" aria-hidden="true"></i>
</span>
<span>
{{model.name}}
</span>
<span class="badge">
{{model.size}}
</span>
</a>
</td>
/**
* Builds the string used in the user image alt attribute.
*
* @returns {String}
*/
userImageAltDescription() {
if (this.model.latest.last_deployment &&
this.model.latest.last_deployment.user &&
this.model.latest.last_deployment.user.username) {
return `${this.model.latest.last_deployment.user.username}'s avatar'`;
}
return '';
},
/**
* If provided, returns the commit tag.
*
* @returns {String|Undefined}
*/
commitTag() {
if (this.model.latest.last_deployment &&
this.model.latest.last_deployment.tag) {
return this.model.latest.last_deployment.tag;
}
return undefined;
},
/**
* If provided, returns the commit ref.
*
* @returns {Object|Undefined}
*/
commitRef() {
if (this.model.latest.last_deployment &&
this.model.latest.last_deployment.ref) {
return this.model.latest.last_deployment.ref;
}
return undefined;
},
/**
* If provided, returns the commit url.
*
* @returns {String|Undefined}
*/
commitUrl() {
if (this.model.latest.last_deployment &&
this.model.latest.last_deployment.commit &&
this.model.latest.last_deployment.commit.commit_path) {
return this.model.latest.last_deployment.commit.commit_path;
}
return undefined;
},
/**
* If provided, returns the commit short sha.
*
* @returns {String|Undefined}
*/
commitShortSha() {
if (this.model.latest.last_deployment &&
this.model.latest.last_deployment.commit &&
this.model.latest.last_deployment.commit.short_id) {
return this.model.latest.last_deployment.commit.short_id;
}
return undefined;
},
/**
* If provided, returns the commit title.
*
* @returns {String|Undefined}
*/
commitTitle() {
if (this.model.latest.last_deployment &&
this.model.latest.last_deployment.commit &&
this.model.latest.last_deployment.commit.title) {
return this.model.latest.last_deployment.commit.title;
}
return undefined;
},
/**
* If provided, returns the commit tag.
*
* @returns {Object|Undefined}
*/
commitAuthor() {
if (this.model.latest.last_deployment &&
this.model.latest.last_deployment.commit &&
this.model.latest.last_deployment.commit.author) {
return this.model.latest.last_deployment.commit.author;
}
return undefined;
},
/**
* Verifies if the `retry_path` key is present and returns its value.
*
* @returns {String|Undefined}
*/
retryUrl() {
if (this.model.latest.last_deployment &&
this.model.latest.last_deployment.deployable &&
this.model.latest.last_deployment.deployable.retry_path) {
return this.model.latest.last_deployment.deployable.retry_path;
}
return undefined;
},
/**
* Verifies if the `last?` key is present and returns its value.
*
* @returns {Boolean|Undefined}
*/
isLastDeployment() {
return this.model.latest.last_deployment &&
this.model.latest.last_deployment['last?'];
},
/**
* Builds the name of the builds needed to display both the name and the id.
*
* @returns {String}
*/
buildName() {
if (this.model.latest.last_deployment &&
this.model.latest.last_deployment.deployable) {
return `${this.model.latest.last_deployment.deployable.name} #${this.model.latest.last_deployment.deployable.id}`;
}
return '';
},
<td class="deployment-column">
<span v-if="shouldRenderDeploymentID">
{{deploymentInternalId}}
/**
* Builds the needed string to show the internal id.
*
* @returns {String}
*/
deploymentInternalId() {
if (this.model.latest.last_deployment &&
this.model.latest.last_deployment.iid) {
return `#${this.model.latest.last_deployment.iid}`;
}
return '';
},
/**
* Verifies if the user object is present under last_deployment object.
*
* @returns {Boolean}
*/
deploymentHasUser() {
return !this.$options.isObjectEmpty(this.model.latest.last_deployment) &&
!this.$options.isObjectEmpty(this.model.latest.last_deployment.user);
},
/**
* Returns the user object nested with the last_deployment object.
* Used to render the template.
*
* @returns {Object}
*/
deploymentUser() {
if (!this.$options.isObjectEmpty(this.model.latest.last_deployment) &&
!this.$options.isObjectEmpty(this.model.latest.last_deployment.user)) {
return this.model.latest.last_deployment.user;
}
return {};
},
/**
* 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.model.isFolder &&
!this.$options.isObjectEmpty(this.model.latest.last_deployment) &&
!this.$options.isObjectEmpty(this.model.latest.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.model.isFolder &&
!this.$options.isObjectEmpty(this.model.latest.last_deployment) &&
this.model.latest.last_deployment.iid !== undefined;
},
},
/**
* 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>
<a v-if="!model.isFolder"
class="environment-name"
:href="model.latest.environment_path">
{{model.name}}
</a>
<a v-else class="folder-name">
<span class="folder-icon">
<i class="fa fa-caret-right" aria-hidden="true"></i>
<i class="fa fa-folder" aria-hidden="true"></i>
</span>
<span v-if="!model.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>
{{model.name}}
</span>
</td>
<td class="environments-build-cell">
<a v-if="shouldRenderBuildName"
class="build-link"
:href="model.latest.last_deployment.deployable.build_path">
{{buildName}}
<span class="badge">
{{model.size}}
</span>
</a>
</td>
<td class="deployment-column">
<span v-if="shouldRenderDeploymentID">
{{deploymentInternalId}}
</span>
<span v-if="!model.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>
</td>
<td>
<div v-if="!model.isFolder && hasLastDeploymentKey" class="js-commit-component">
<commit-component
:tag="commitTag"
:commit-ref="commitRef"
:commit-url="commitUrl"
:short-sha="commitShortSha"
:title="commitTitle"
:author="commitAuthor"
:commit-icon-svg="commitIconSvg">
</commit-component>
</span>
</td>
<td class="environments-build-cell">
<a v-if="shouldRenderBuildName"
class="build-link"
:href="model.latest.last_deployment.deployable.build_path">
{{buildName}}
</a>
</td>
<td>
<div v-if="!model.isFolder && hasLastDeploymentKey" class="js-commit-component">
<commit-component
:tag="commitTag"
:commit-ref="commitRef"
:commit-url="commitUrl"
:short-sha="commitShortSha"
:title="commitTitle"
:author="commitAuthor"
:commit-icon-svg="commitIconSvg">
</commit-component>
</div>
<p v-if="!model.isFolder && !hasLastDeploymentKey" class="commit-title">
No deployments yet
</p>
</td>
<td>
<span v-if="!model.isFolder && canShowDate"
class="environment-created-date-timeago">
{{createdDate}}
</span>
</td>
<td class="hidden-xs">
<div v-if="!model.isFolder">
<div v-if="hasManualActions && canCreateDeployment"
class="inline js-manual-actions-container">
<actions-component
:play-icon-svg="playIconSvg"
:actions="manualActions">
</actions-component>
</div>
<p v-if="!model.isFolder && !hasLastDeploymentKey" class="commit-title">
No deployments yet
</p>
</td>
<td>
<span v-if="!model.isFolder && canShowDate"
class="environment-created-date-timeago">
{{createdDate}}
</span>
</td>
<td class="hidden-xs">
<div v-if="!model.isFolder">
<div v-if="hasManualActions && canCreateDeployment"
class="inline js-manual-actions-container">
<actions-component
:play-icon-svg="playIconSvg"
:actions="manualActions">
</actions-component>
</div>
<div v-if="model.latest.external_url && canReadEnvironment"
class="inline js-external-url-container">
<external-url-component
:external-url="model.latest.external_url">
</external-url-component>
</div>
<div v-if="hasStopAction && canCreateDeployment"
class="inline js-stop-component-container">
<stop-component
:stop-url="model.latest.stop_path">
</stop-component>
</div>
<div v-if="model.latest.terminal_path"
class="inline js-terminal-button-container">
<terminal-button-component
:terminal-icon-svg="terminalIconSvg"
:terminal-path="model.latest.terminal_path">
</terminal-button-component>
</div>
<div v-if="canRetry && canCreateDeployment"
class="inline js-rollback-component-container">
<rollback-component
:is-last-deployment="isLastDeployment"
:retry-url="retryUrl">
</rollback-component>
</div>
<div v-if="model.latest.external_url && canReadEnvironment"
class="inline js-external-url-container">
<external-url-component
:external-url="model.latest.external_url">
</external-url-component>
</div>
<div v-if="hasStopAction && canCreateDeployment"
class="inline js-stop-component-container">
<stop-component
:stop-url="model.latest.stop_path">
</stop-component>
</div>
<div v-if="model.latest.terminal_path"
class="inline js-terminal-button-container">
<terminal-button-component
:terminal-icon-svg="terminalIconSvg"
:terminal-path="model.latest.terminal_path">
</terminal-button-component>
</div>
<div v-if="canRetry && canCreateDeployment"
class="inline js-rollback-component-container">
<rollback-component
:is-last-deployment="isLastDeployment"
:retry-url="retryUrl">
</rollback-component>
</div>
</
td
>
</t
r
>
`,
});
})
()
;
</
div
>
</t
d
>
</tr>
`,
});
app/assets/javascripts/environments/components/environment_rollback.js.es6
View file @
d6ae01da
/* global Vue */
/**
* Renders Rollback or Re deploy button in environments table depending
* of the provided property `isLastDeployment`
*/
const Vue = require('vue');
window.Vue = require('vue');
(() => {
window.gl = window.gl || {};
window.gl.environmentsList = window.gl.environmentsList || {};
gl.environmentsList.RollbackComponent = Vue.component('rollback-component', {
props: {
retryUrl: {
type: String,
default: '',
},
module.exports = Vue.component('rollback-component', {
props: {
retryUrl: {
type: String,
default: '',
},
isLastDeployment: {
type: Boolean,
default: true,
},
isLastDeployment: {
type: Boolean,
default: true,
},
},
template: `
<a class="btn" :href="retryUrl" data-method="post" rel="nofollow">
<span v-if="isLastDeployment">
Re-deploy
</span>
<span v-else>
Rollback
</span>
</a>
`,
});
})();
template: `
<a class="btn" :href="retryUrl" data-method="post" rel="nofollow">
<span v-if="isLastDeployment">
Re-deploy
</span>
<span v-else>
Rollback
</span>
</a>
`,
});
app/assets/javascripts/environments/components/environment_stop.js.es6
View file @
d6ae01da
/* global Vue */
/**
* Renders the stop "button" that allows stop an environment.
* Used in environments table.
*/
const Vue = require('vue');
window.Vue = require('vue');
(() => {
window.gl = window.gl || {};
window.gl.environmentsList = window.gl.environmentsList || {};
gl.environmentsList.StopComponent = Vue.component('stop-component', {
props: {
stopUrl: {
type: String,
default: '',
},
module.exports = Vue.component('stop-component', {
props: {
stopUrl: {
type: String,
default: '',
},
},
template: `
<a class="btn stop-env-link"
:href="stopUrl"
data-confirm="Are you sure you want to stop this environment?"
data-method="post"
rel="nofollow">
<i class="fa fa-stop stop-env-icon"></i>
</a>
`,
});
})();
template: `
<a class="btn stop-env-link"
:href="stopUrl"
data-confirm="Are you sure you want to stop this environment?"
data-method="post"
rel="nofollow">
<i class="fa fa-stop stop-env-icon" aria-hidden="true"></i>
</a>
`,
});
app/assets/javascripts/environments/components/environment_terminal_button.js.es6
View file @
d6ae01da
/* global Vue */
/**
* Renders a terminal button to open a web terminal.
* Used in environments table.
*/
const Vue = require('vue');
window.Vue = require('vue');
(() => {
window.gl = window.gl || {};
window.gl.environmentsList = window.gl.environmentsList || {};
gl.environmentsList.TerminalButtonComponent = Vue.component('terminal-button-component', {
props: {
terminalPath: {
type: String,
default: '',
},
terminalIconSvg: {
type: String,
default: '',
},
module.exports = Vue.component('terminal-button-component', {
props: {
terminalPath: {
type: String,
default: '',
},
terminalIconSvg: {
type: String,
default: '',
},
},
template: `
<a class="btn terminal-button"
:href="terminalPath">
<span class="js-terminal-icon-container" v-html="terminalIconSvg"></span>
</a>
`,
});
})();
template: `
<a class="btn terminal-button"
:href="terminalPath">
<span class="js-terminal-icon-container" v-html="terminalIconSvg"></span>
</a>
`,
});
app/assets/javascripts/environments/environments_bundle.js.es6
View file @
d6ae01da
window.Vue = require('vue');
require('./components/environment');
const EnvironmentsComponent = require('./components/environment');
require('../vue_shared/vue_resource_interceptor');
$(() => {
...
...
@@ -9,7 +8,7 @@ $(() => {
gl.EnvironmentsListApp.$destroy(true);
}
gl.EnvironmentsListApp = new
gl.environmentsList.
EnvironmentsComponent({
gl.EnvironmentsListApp = new EnvironmentsComponent({
el: document.querySelector('#environments-list-view'),
});
});
app/assets/javascripts/environments/services/environments_service.js.es6
View file @
d6ae01da
const Vue =
window.Vue =
require('vue');
const Vue = require('vue');
class EnvironmentsService {
constructor(endpoint) {
...
...
app/assets/javascripts/vue_shared/components/commit.js.es6
View file @
d6ae01da
/* global Vue */
window.Vue = require('vue');
(() => {
window.gl = window.gl || {};
...
...
spec/javascripts/environments/environment_actions_spec.js.es6
View file @
d6ae01da
require('~/environments/components/environment_actions');
const ActionsComponent =
require('~/environments/components/environment_actions');
describe('Actions Component', () => {
preloadFixtures('static/environments/element.html.raw');
...
...
@@ -19,7 +19,7 @@ describe('Actions Component', () => {
},
];
const component = new
window.gl.environmentsList.
ActionsComponent({
const component = new ActionsComponent({
el: document.querySelector('.test-dom-element'),
propsData: {
actions: actionsMock,
...
...
@@ -47,7 +47,7 @@ describe('Actions Component', () => {
},
];
const component = new
window.gl.environmentsList.
ActionsComponent({
const component = new ActionsComponent({
el: document.querySelector('.test-dom-element'),
propsData: {
actions: actionsMock,
...
...
spec/javascripts/environments/environment_external_url_spec.js.es6
View file @
d6ae01da
require('~/environments/components/environment_external_url');
const ExternalUrlComponent =
require('~/environments/components/environment_external_url');
describe('External URL Component', () => {
preloadFixtures('static/environments/element.html.raw');
...
...
@@ -8,7 +8,7 @@ describe('External URL Component', () => {
it('should link to the provided externalUrl prop', () => {
const externalURL = 'https://gitlab.com';
const component = new
window.gl.environmentsList.
ExternalUrlComponent({
const component = new ExternalUrlComponent({
el: document.querySelector('.test-dom-element'),
propsData: {
externalUrl: externalURL,
...
...
spec/javascripts/environments/environment_item_spec.js.es6
View file @
d6ae01da
window.timeago = require('vendor/timeago');
require('~/environments/components/environment_item');
const EnvironmentItem =
require('~/environments/components/environment_item');
f
describe('Environment item', () => {
describe('Environment item', () => {
preloadFixtures('static/environments/table.html.raw');
beforeEach(() => {
loadFixtures('static/environments/table.html.raw');
...
...
@@ -21,7 +21,7 @@ fdescribe('Environment item', () => {
},
};
component = new
window.gl.environmentsList.
EnvironmentItem({
component = new EnvironmentItem({
el: document.querySelector('tr#environment-row'),
propsData: {
model: mockItem,
...
...
@@ -111,7 +111,7 @@ fdescribe('Environment item', () => {
},
};
component = new
window.gl.environmentsList.
EnvironmentItem({
component = new EnvironmentItem({
el: document.querySelector('tr#environment-row'),
propsData: {
model: environment,
...
...
spec/javascripts/environments/environment_rollback_spec.js.es6
View file @
d6ae01da
require('~/environments/components/environment_rollback');
const RollbackComponent =
require('~/environments/components/environment_rollback');
describe('Rollback Component', () => {
preloadFixtures('static/environments/element.html.raw');
...
...
@@ -10,7 +10,7 @@ describe('Rollback Component', () => {
});
it('Should link to the provided retryUrl', () => {
const component = new
window.gl.environmentsList.
RollbackComponent({
const component = new RollbackComponent({
el: document.querySelector('.test-dom-element'),
propsData: {
retryUrl: retryURL,
...
...
@@ -22,7 +22,7 @@ describe('Rollback Component', () => {
});
it('Should render Re-deploy label when isLastDeployment is true', () => {
const component = new
window.gl.environmentsList.
RollbackComponent({
const component = new RollbackComponent({
el: document.querySelector('.test-dom-element'),
propsData: {
retryUrl: retryURL,
...
...
@@ -34,7 +34,7 @@ describe('Rollback Component', () => {
});
it('Should render Rollback label when isLastDeployment is false', () => {
const component = new
window.gl.environmentsList.
RollbackComponent({
const component = new RollbackComponent({
el: document.querySelector('.test-dom-element'),
propsData: {
retryUrl: retryURL,
...
...
spec/javascripts/environments/environment_spec.js.es6
View file @
d6ae01da
/* global Vue, environment */
const Vue = require('vue');
require('~/flash');
require('~/environments/components/environment');
const EnvironmentsComponent =
require('~/environments/components/environment');
const { environment } = require('./mock_data');
describe('Environment', () => {
...
...
@@ -32,7 +31,7 @@ describe('Environment', () => {
});
it('should render the empty state', (done) => {
component = new
gl.environmentsList.
EnvironmentsComponent({
component = new EnvironmentsComponent({
el: document.querySelector('#environments-list-view'),
});
...
...
@@ -72,7 +71,7 @@ describe('Environment', () => {
});
it('should render a table with environments', (done) => {
component = new
gl.environmentsList.
EnvironmentsComponent({
component = new EnvironmentsComponent({
el: document.querySelector('#environments-list-view'),
});
...
...
@@ -104,7 +103,7 @@ describe('Environment', () => {
});
it('should render empty state', (done) => {
component = new
gl.environmentsList.
EnvironmentsComponent({
component = new EnvironmentsComponent({
el: document.querySelector('#environments-list-view'),
});
...
...
spec/javascripts/environments/environment_stop_spec.js.es6
View file @
d6ae01da
require('~/environments/components/environment_stop');
const StopComponent =
require('~/environments/components/environment_stop');
describe('Stop Component', () => {
preloadFixtures('static/environments/element.html.raw');
...
...
@@ -10,7 +10,7 @@ describe('Stop Component', () => {
loadFixtures('static/environments/element.html.raw');
stopURL = '/stop';
component = new
window.gl.environmentsList.
StopComponent({
component = new StopComponent({
el: document.querySelector('.test-dom-element'),
propsData: {
stopUrl: stopURL,
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment