diff --git a/app/assets/javascripts/environments/components/deploy_board_component.js.es6 b/app/assets/javascripts/environments/components/deploy_board_component.js.es6 index 1533742e74cfbde15c186272983038ffb1f99040..a3223b4c7c3b1a96d0dc40f872e8dfdf108cf63b 100644 --- a/app/assets/javascripts/environments/components/deploy_board_component.js.es6 +++ b/app/assets/javascripts/environments/components/deploy_board_component.js.es6 @@ -2,7 +2,7 @@ * Renders a deploy board. * * A deploy board is composed by: - * - Information area with percentage of completition. + * - Information area with percentage of completion. * - Instances with status. * - Button Actions. * [Mockup](https://gitlab.com/gitlab-org/gitlab-ce/uploads/2f655655c0eadf655d0ae7467b53002a/environments__deploy-graphic.png) @@ -37,7 +37,7 @@ module.exports = Vue.component('deploy_boards_components', { required: true, }, - data: { + deployBoardData: { type: Object, required: true, }, @@ -49,6 +49,7 @@ module.exports = Vue.component('deploy_boards_components', { }, data() { + return { isLoading: false, hasContent: false, @@ -56,9 +57,8 @@ module.exports = Vue.component('deploy_boards_components', { }; }, - beforeMount() { + created() { this.isLoading = true; - this.service.getDeployBoard(this.environmentID) .then(resp => resp.json()) .then((response) => { @@ -79,20 +79,34 @@ module.exports = Vue.component('deploy_boards_components', { <i class="fa fa-spinner fa-spin"></i> </div> - <div v-if="!isLoading && hasContent"> + <div v-if="!isLoading"> <section class="deploy-board-information"> - + <span class="percentage">{{deployBoardData.completion}}%</span> + <span class="text">Complete</span> </section> <section class="deploy-board-instances"> - <p>Instances</p> + <p class="text">Instances</p> <div class="deploy-board-instances-container"> - + <template v-for="instance in deployBoardData.instances"> + <instance-component + :status="instance.status" + :tooltipText="instance.tooltipText"> + </instance-component> + </template> </div> </section> - <section class="deploy-board-actions"></section> + <section class="deploy-board-actions"> + <a class="btn" data-method="post" rel="nofollow"> + Rollback + </a> + + <a class="btn btn-red btn-inverted"> + Abort + </a> + </section> </div> <div v-if="!isLoading && hasError"> diff --git a/app/assets/javascripts/environments/components/deploy_board_instance_component.js.es6 b/app/assets/javascripts/environments/components/deploy_board_instance_component.js.es6 index 92ee630942f13226e82cac73bc947f6e4e4f7997..b1e641ede1b9ff24c46f739e87c2ae29931a837d 100644 --- a/app/assets/javascripts/environments/components/deploy_board_instance_component.js.es6 +++ b/app/assets/javascripts/environments/components/deploy_board_instance_component.js.es6 @@ -15,12 +15,12 @@ module.exports = Vue.component('deploy_board_instance_component', { props: { /** - * Represents the state of the pod. Each state is represented with a different + * Represents the status of the pod. Each state is represented with a different * color. * It should be one of the following: * finished || deploying || failed || ready || preparing || waiting */ - state: { + status: { type: String, required: true, default: 'finished', @@ -31,14 +31,20 @@ module.exports = Vue.component('deploy_board_instance_component', { required: false, default: '', }, + }, - template: ` - <div - class="js-deploy-board-instance deploy-board-instance deploy-board-instance-${this.state} has-tooltip" - data-title="tooltipText" - data-toggle="tooltip" - data-placement="top"> - </div> - `, + computed: { + cssClass() { + return `js-deploy-board-instance deploy-board-instance deploy-board-instance-${this.status} has-tooltip`; + }, }, + + template: ` + <div + :class="cssClass" + :data-title="tooltipText" + data-toggle="tooltip" + data-placement="top"> + </div> + `, }); diff --git a/app/assets/javascripts/environments/components/environment_item.js.es6 b/app/assets/javascripts/environments/components/environment_item.js.es6 index adf9db151ca668725f775c5edd5945a8224d550f..d6c2fa868bcf7e9dafe1d85f306786611d911150 100644 --- a/app/assets/javascripts/environments/components/environment_item.js.es6 +++ b/app/assets/javascripts/environments/components/environment_item.js.es6 @@ -253,11 +253,6 @@ module.exports = Vue.component('environment-item', { return undefined; }, - terminalIconSvg: { - type: String, - required: false, - }, - /** * If provided, returns the commit tag. * diff --git a/app/assets/javascripts/environments/components/environments_table.js.es6 b/app/assets/javascripts/environments/components/environments_table.js.es6 index beac369c2239527ac4f53543755909437a09733c..2173022debeb8484b6c5dc48fa8dc14c378c792c 100644 --- a/app/assets/javascripts/environments/components/environments_table.js.es6 +++ b/app/assets/javascripts/environments/components/environments_table.js.es6 @@ -97,7 +97,7 @@ module.exports = Vue.component('environment-table-component', { :store="store" :service="service" :environmentID="model.id" - :data="model.deployBoardData"> + :deployBoardData="model.deployBoardData"> </deploy-board> </td> diff --git a/app/assets/javascripts/environments/stores/environments_store.js.es6 b/app/assets/javascripts/environments/stores/environments_store.js.es6 index 3f9e2587b197bbc81ee0a1b216df7b75caa8d3cb..fa356b13efb617052a684e920444e33a90c8399d 100644 --- a/app/assets/javascripts/environments/stores/environments_store.js.es6 +++ b/app/assets/javascripts/environments/stores/environments_store.js.es6 @@ -54,8 +54,7 @@ class EnvironmentsStore { if (env.size === 1) { filtered = Object.assign({}, env, { isDeployBoardVisible: false, - deployBoardData: {}, - deployBoardEndpoint: `environments/${env.id}/status.json`, + deployBoardData: {} }); } @@ -139,8 +138,25 @@ class EnvironmentsStore { return this.state.environments; } + /** + * Store deploy board data for given environment. + * + * @param {Number} environmentID + * @param {Object} deployBoard + * @return {Array} + */ storeDeployBoard(environmentID, deployBoard) { - console.log(environmentID, deployBoard); + const environments = Object.assign([], this.state.environments); + + this.state.environments = environments.map((env) => { + let updated = Object.assign({}, env); + + if (env.id === environmentID) { + updated = Object.assign({}, updated, { deployBoardData: deployBoard }); + } + return updated; + }); + return this.state.environments; } } diff --git a/app/assets/javascripts/vue_shared/vue_resource_interceptor.js.es6 b/app/assets/javascripts/vue_shared/vue_resource_interceptor.js.es6 index d3229f9f73002d45c116dee27760ce907907c336..a27f9ff58e047b8a46ddf119f4b72b5937c68fb8 100644 --- a/app/assets/javascripts/vue_shared/vue_resource_interceptor.js.es6 +++ b/app/assets/javascripts/vue_shared/vue_resource_interceptor.js.es6 @@ -21,3 +21,84 @@ Vue.http.interceptors.push((request, next) => { } next(); }); + +// TODO - REMOVE THIS WHEN WE HAVE BACKEND API +Vue.http.interceptors.push((request, next) => { + const deployBoardData = { + instances: [ + { status: 'finished', tooltip: 'tanuki-2334 Finished' }, + { status: 'finished', tooltip: 'tanuki-2335 Finished' }, + { status: 'finished', tooltip: 'tanuki-2336 Finished' }, + { status: 'finished', tooltip: 'tanuki-2337 Finished' }, + { status: 'finished', tooltip: 'tanuki-2338 Finished' }, + { status: 'finished', tooltip: 'tanuki-2339 Finished' }, + { status: 'finished', tooltip: 'tanuki-2340 Finished' }, + { status: 'finished', tooltip: 'tanuki-2334 Finished' }, + { status: 'finished', tooltip: 'tanuki-2335 Finished' }, + { status: 'finished', tooltip: 'tanuki-2336 Finished' }, + { status: 'finished', tooltip: 'tanuki-2337 Finished' }, + { status: 'finished', tooltip: 'tanuki-2338 Finished' }, + { status: 'finished', tooltip: 'tanuki-2339 Finished' }, + { status: 'finished', tooltip: 'tanuki-2340 Finished' }, + { status: 'finished', tooltip: 'tanuki-2334 Finished' }, + { status: 'finished', tooltip: 'tanuki-2335 Finished' }, + { status: 'finished', tooltip: 'tanuki-2336 Finished' }, + { status: 'finished', tooltip: 'tanuki-2337 Finished' }, + { status: 'finished', tooltip: 'tanuki-2338 Finished' }, + { status: 'finished', tooltip: 'tanuki-2339 Finished' }, + { status: 'finished', tooltip: 'tanuki-2340 Finished' }, + { status: 'finished', tooltip: 'tanuki-2334 Finished' }, + { status: 'finished', tooltip: 'tanuki-2335 Finished' }, + { status: 'finished', tooltip: 'tanuki-2336 Finished' }, + { status: 'finished', tooltip: 'tanuki-2337 Finished' }, + { status: 'finished', tooltip: 'tanuki-2338 Finished' }, + { status: 'finished', tooltip: 'tanuki-2339 Finished' }, + { status: 'finished', tooltip: 'tanuki-2340 Finished' }, + { status: 'finished', tooltip: 'tanuki-2334 Finished' }, + { status: 'finished', tooltip: 'tanuki-2335 Finished' }, + { status: 'finished', tooltip: 'tanuki-2336 Finished' }, + { status: 'finished', tooltip: 'tanuki-2337 Finished' }, + { status: 'finished', tooltip: 'tanuki-2338 Finished' }, + { status: 'finished', tooltip: 'tanuki-2339 Finished' }, + { status: 'finished', tooltip: 'tanuki-2340 Finished' }, + { status: 'finished', tooltip: 'tanuki-2334 Finished' }, + { status: 'finished', tooltip: 'tanuki-2335 Finished' }, + { status: 'finished', tooltip: 'tanuki-2336 Finished' }, + { status: 'finished', tooltip: 'tanuki-2337 Finished' }, + { status: 'finished', tooltip: 'tanuki-2338 Finished' }, + { status: 'finished', tooltip: 'tanuki-2339 Finished' }, + { status: 'finished', tooltip: 'tanuki-2340 Finished' }, + { status: 'deploying', tooltip: 'tanuki-2341 Deploying' }, + { status: 'deploying', tooltip: 'tanuki-2342 Deploying' }, + { status: 'deploying', tooltip: 'tanuki-2343 Deploying' }, + { status: 'failed', tooltip: 'tanuki-2344 Failed' }, + { status: 'ready', tooltip: 'tanuki-2345 Ready' }, + { status: 'ready', tooltip: 'tanuki-2346 Ready' }, + { status: 'ready', tooltip: 'tanuki-2347 Ready' }, + { status: 'preparing', tooltip: 'tanuki-2348 Preparing' }, + { status: 'preparing', tooltip: 'tanuki-2349 Preparing' }, + { status: 'preparing', tooltip: 'tanuki-2350 Preparing' }, + { status: 'preparing', tooltip: 'tanuki-2351 Preparing' }, + { status: 'preparing', tooltip: 'tanuki-2352 Preparing' }, + { status: 'preparing', tooltip: 'tanuki-2353 Preparing' }, + { status: 'waiting', tooltip: 'tanuki-2354 Waiting' }, + { status: 'waiting', tooltip: 'tanuki-2355 Waiting' }, + { status: 'waiting', tooltip: 'tanuki-2356 Waiting' }, + { status: 'waiting', tooltip: 'tanuki-2357 Waiting' }, + { status: 'waiting', tooltip: 'tanuki-2358 Waiting' }, + { status: 'waiting', tooltip: 'tanuki-2359 Waiting' }, + ], + abort_url: '', + rollback_url: '', + completion: 87, + is_completed: true, + }; + + if (request.url === 'environments/{id}/status.json') { + next(request.respondWith(JSON.stringify(deployBoardData), { + status: 200, + })); + } + + next(); +}); diff --git a/app/assets/stylesheets/pages/environments.scss b/app/assets/stylesheets/pages/environments.scss index febe77f921c82f35a5ffc39ad9e8d2a819251c0c..9037e06c069ad9e659f40644105fe0773bd2675e 100644 --- a/app/assets/stylesheets/pages/environments.scss +++ b/app/assets/stylesheets/pages/environments.scss @@ -148,12 +148,57 @@ /** * Deploy boards */ + +.deploy-board > div { + display: flex; + justify-content: space-between; + + .deploy-board-information { + order: 1; + display: flex; + width: 80px; + flex-wrap: wrap; + justify-content: center; + margin: auto 10px; + + .percentage { + color: $gl-text-color; + } + + .text { + color: $gl-text-color-secondary; + } + } + + .deploy-board-instances { + order: 2; + max-width: 75%; + + .text { + color: $gl-text-color-secondary; + font-size: 12px; + } + + .deploy-board-instances-container { + display: flex; + flex-wrap: wrap; + flex-direction: row; + } + } + + .deploy-board-actions { + order: 3; + align-self: center; + } +} + .deploy-board-instance { width: 15px; height: 15px; border-radius: 3px; border-width: 1px; border-style: solid; + margin: 1px; &-finished { background-color: lighten($green-light, 25%); @@ -198,6 +243,13 @@ padding: 10px; background-color: #fbfbfb; min-height: 20px; + + .fa-spinner { + margin: 0 auto; + width: 20px; + display: block; + font-size: 20px; + } } td.deploy-board-container {