diff options
author | Filipa Lacerda <filipa@gitlab.com> | 2017-02-12 14:55:18 +0000 |
---|---|---|
committer | Filipa Lacerda <filipa@gitlab.com> | 2017-02-15 19:57:46 +0000 |
commit | 26d18387dea786ded85df3a429542c5d1e4f1ac1 (patch) | |
tree | 05bb378b02c931ff9fc3a60c657956e0d091da12 | |
parent | 7af6982e5fcf2b76906f33d5046dd9b2298ac32c (diff) | |
download | gitlab-ce-26d18387dea786ded85df3a429542c5d1e4f1ac1.tar.gz |
First iteration
5 files changed, 268 insertions, 0 deletions
diff --git a/app/assets/javascripts/environments/folder/environments_folder_bundle.js.es6 b/app/assets/javascripts/environments/folder/environments_folder_bundle.js.es6 index e69de29bb2d..9cc1c2f4f18 100644 --- a/app/assets/javascripts/environments/folder/environments_folder_bundle.js.es6 +++ b/app/assets/javascripts/environments/folder/environments_folder_bundle.js.es6 @@ -0,0 +1,14 @@ +const EnvironmentsFolderComponent = require('./environments_folder_view'); +require('../vue_shared/vue_resource_interceptor'); + +$(() => { + window.gl = window.gl || {}; + + if (gl.EnvironmentsListFolderApp) { + gl.EnvironmentsListFolderApp.$destroy(true); + } + + gl.EnvironmentsListFolderApp = new EnvironmentsFolderComponent({ + el: document.querySelector('#environments-folder-list-view'), + }); +}); diff --git a/app/assets/javascripts/environments/folder/environments_folder_view.js.es6 b/app/assets/javascripts/environments/folder/environments_folder_view.js.es6 index e69de29bb2d..070bc84bbe3 100644 --- a/app/assets/javascripts/environments/folder/environments_folder_view.js.es6 +++ b/app/assets/javascripts/environments/folder/environments_folder_view.js.es6 @@ -0,0 +1,196 @@ +/* eslint-disable no-param-reassign, no-new */ +/* global Flash */ + +const Vue = require('vue'); +Vue.use(require('vue-resource')); +const EnvironmentsService = require('../services/environments_service'); +const EnvironmentTable = require('./environments_table'); +const Store = require('../stores/environments_folder_store'); +require('../../vue_shared/components/table_pagination'); + +module.exports = Vue.component('environment-folder-view', { + + components: { + 'environment-table': EnvironmentTable, + 'table-pagination': gl.VueGlPagination, + }, + + props: { + endpoint: { + type: String, + required: true, + default: '', + }, + + folderName: { + type: String, + required: true, + default: '', + }, + }, + + data() { + const store = new Store(); + + return { + store, + state: store.state, + isLoading: false, + + // Pagination Properties, + paginationInformation: {}, + pageNumber: 1, + }; + }, + + /** + * Fetches all the environments and stores them. + * Toggles loading property. + */ + created() { + const scope = this.$options.getQueryParameter('scope') || this.visibility; + const pageNumber = this.$options.getQueryParameter('page') || this.pageNumber; + + const endpoint = `${this.endpoint}?scope=${scope}&page=${pageNumber}`; + + const service = new EnvironmentsService(endpoint); + + this.isLoading = true; + + return service.all() + .then(resp => ({ + headers: resp.headers, + body: resp.json(), + })) + .then((response) => { + this.store.storeEnvironments(response.body.environments); + this.store.storePagination(response.headers); + }) + .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]; + }, + + methods: { + /** + * Will change the page number and update the URL. + * + * If no search params are present, we'll add param for page + * If param for page is already present, we'll update it + * If there are params but none for page, we'll add it at the end. + * + * @param {Number} pageNumber desired page to go to. + */ + changePage(pageNumber) { + let param; + if (window.location.search.length === 0) { + param = `?page=${pageNumber}`; + } + + if (window.location.search.indexOf('page') !== -1) { + param = window.location.search.replace(/page=\d/g, `page=${pageNumber}`); + } + + if (window.location.search.length && + window.location.search.indexOf('page') === -1) { + param = `${window.location.search}&page=${pageNumber}`; + } + + gl.utils.visitUrl(param); + return param; + }, + }, + + template: ` + <div :class="cssContainerClass"> + <div class="top-area"> + <ul v-if="!isLoading" class="nav-links"> + <li v-bind:class="{ 'active': scope === undefined || scope === 'available' }"> + <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> + + <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"> + + <environment-table + :environments="state.environments" + :can-create-deployment="canCreateDeploymentParsed" + :can-read-environment="canReadEnvironmentParsed" + :play-icon-svg="playIconSvg" + :terminal-icon-svg="terminalIconSvg" + :commit-icon-svg="commitIconSvg"> + </environment-table> + + <table-pagination v-if="state.paginationInformation && state.paginationInformation.totalPages > 1" + :change="changePage" + :pageInfo="state.paginationInformation"> + </table-pagination> + </div> + </div> + </div> + `, +}); diff --git a/app/assets/javascripts/environments/stores/environments_folder_store.js.es6 b/app/assets/javascripts/environments/stores/environments_folder_store.js.es6 new file mode 100644 index 00000000000..005ed52d9a1 --- /dev/null +++ b/app/assets/javascripts/environments/stores/environments_folder_store.js.es6 @@ -0,0 +1,49 @@ +require('~/lib/utils/common_utils'); +/** + * Environments Folder Store. + * + * Stores received environments that belong to a parent store. + */ +class EnvironmentsFolderStore { + constructor() { + this.state = {}; + this.state.environments = []; + this.state.paginationInformation = {}; + + return this; + } + + /** + * + * Stores the received environments. + * + * Each environment has the following schema + * { name: String, size: Number, latest: Object } + * + * + * @param {Array} environments + * @returns {Array} + */ + storeEnvironments(environments = []) { + this.state.environments = environments; + + return environments; + } + + storePagination(pagination = {}) { + const normalizedHeaders = gl.utils.normalizeHeaders(pagination); + const paginationInformation = { + perPage: parseInt(normalizedHeaders['X-PER-PAGE'], 10), + page: parseInt(normalizedHeaders['X-PAGE'], 10), + total: parseInt(normalizedHeaders['X-TOTAL'], 10), + totalPages: parseInt(normalizedHeaders['X-TOTAL-PAGES'], 10), + nextPage: parseInt(normalizedHeaders['X-NEXT-PAGE'], 10), + previousPage: parseInt(normalizedHeaders['X-PREV-PAGE'], 10), + }; + + this.state.paginationInformation = paginationInformation; + return paginationInformation; + } +} + +module.exports = EnvironmentsFolderStore; diff --git a/app/views/projects/environments/folder.html.haml b/app/views/projects/environments/folder.html.haml index e69de29bb2d..452d32fc8b6 100644 --- a/app/views/projects/environments/folder.html.haml +++ b/app/views/projects/environments/folder.html.haml @@ -0,0 +1,8 @@ +- @no_container = true +- page_title "Environments" += render "projects/pipelines/head" + +- content_for :page_specific_javascripts do + = page_specific_javascript_bundle_tag("environments_folder") + +#environments-folder-list-view diff --git a/config/webpack.config.js b/config/webpack.config.js index 00f448c1fbb..7fda5405ea2 100644 --- a/config/webpack.config.js +++ b/config/webpack.config.js @@ -22,6 +22,7 @@ var config = { commit_pipelines: './commit/pipelines/pipelines_bundle.js', diff_notes: './diff_notes/diff_notes_bundle.js', environments: './environments/environments_bundle.js', + environments_folder: './environments/folder/environments_folder_bundle.js', filtered_search: './filtered_search/filtered_search_bundle.js', graphs: './graphs/graphs_bundle.js', issuable: './issuable/issuable_bundle.js', |