summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFilipa Lacerda <filipa@gitlab.com>2017-02-12 14:55:18 +0000
committerFilipa Lacerda <filipa@gitlab.com>2017-02-15 19:57:46 +0000
commit26d18387dea786ded85df3a429542c5d1e4f1ac1 (patch)
tree05bb378b02c931ff9fc3a60c657956e0d091da12
parent7af6982e5fcf2b76906f33d5046dd9b2298ac32c (diff)
downloadgitlab-ce-26d18387dea786ded85df3a429542c5d1e4f1ac1.tar.gz
First iteration
-rw-r--r--app/assets/javascripts/environments/folder/environments_folder_bundle.js.es614
-rw-r--r--app/assets/javascripts/environments/folder/environments_folder_view.js.es6196
-rw-r--r--app/assets/javascripts/environments/stores/environments_folder_store.js.es649
-rw-r--r--app/views/projects/environments/folder.html.haml8
-rw-r--r--config/webpack.config.js1
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',