96e6fc70b4
Removes set favicon related methods from global scope Improves test related with favicon Removes convertPermissionToBoolean from global scope. Adds tests for convertPermissionToBoolean - were non existant Removes setParamInURL from gl.utils Removes parseIntPagination from gl.utils namespace Remove normalizeCRLFHeaders from gl.utils namespace Removes normalizeHeaders from gl.utils namespace Use gl.utils for filtered search Fix bad import Fix broken test by cleaning window.history namespace Adds changelog
268 lines
7.6 KiB
Vue
268 lines
7.6 KiB
Vue
<script>
|
|
/* global Flash */
|
|
import Visibility from 'visibilityjs';
|
|
import EnvironmentsService from '../services/environments_service';
|
|
import environmentTable from './environments_table.vue';
|
|
import EnvironmentsStore from '../stores/environments_store';
|
|
import loadingIcon from '../../vue_shared/components/loading_icon.vue';
|
|
import tablePagination from '../../vue_shared/components/table_pagination.vue';
|
|
import { convertPermissionToBoolean, getParameterByName, setParamInURL } from '../../lib/utils/common_utils';
|
|
import eventHub from '../event_hub';
|
|
import Poll from '../../lib/utils/poll';
|
|
import environmentsMixin from '../mixins/environments_mixin';
|
|
|
|
export default {
|
|
|
|
components: {
|
|
environmentTable,
|
|
tablePagination,
|
|
loadingIcon,
|
|
},
|
|
|
|
mixins: [
|
|
environmentsMixin,
|
|
],
|
|
|
|
data() {
|
|
const environmentsData = document.querySelector('#environments-list-view').dataset;
|
|
const store = new EnvironmentsStore();
|
|
|
|
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,
|
|
isMakingRequest: false,
|
|
|
|
// Pagination Properties,
|
|
paginationInformation: {},
|
|
pageNumber: 1,
|
|
};
|
|
},
|
|
|
|
computed: {
|
|
scope() {
|
|
return getParameterByName('scope');
|
|
},
|
|
|
|
canReadEnvironmentParsed() {
|
|
return convertPermissionToBoolean(this.canReadEnvironment);
|
|
},
|
|
|
|
canCreateDeploymentParsed() {
|
|
return convertPermissionToBoolean(this.canCreateDeployment);
|
|
},
|
|
|
|
canCreateEnvironmentParsed() {
|
|
return convertPermissionToBoolean(this.canCreateEnvironment);
|
|
},
|
|
},
|
|
|
|
/**
|
|
* Fetches all the environments and stores them.
|
|
* Toggles loading property.
|
|
*/
|
|
created() {
|
|
const scope = getParameterByName('scope') || this.visibility;
|
|
const page = getParameterByName('page') || this.pageNumber;
|
|
|
|
this.service = new EnvironmentsService(this.endpoint);
|
|
|
|
const poll = new Poll({
|
|
resource: this.service,
|
|
method: 'get',
|
|
data: { scope, page },
|
|
successCallback: this.successCallback,
|
|
errorCallback: this.errorCallback,
|
|
notificationCallback: (isMakingRequest) => {
|
|
this.isMakingRequest = isMakingRequest;
|
|
},
|
|
});
|
|
|
|
if (!Visibility.hidden()) {
|
|
this.isLoading = true;
|
|
poll.makeRequest();
|
|
}
|
|
|
|
Visibility.change(() => {
|
|
if (!Visibility.hidden()) {
|
|
poll.restart();
|
|
} else {
|
|
poll.stop();
|
|
}
|
|
});
|
|
|
|
eventHub.$on('toggleFolder', this.toggleFolder);
|
|
eventHub.$on('postAction', this.postAction);
|
|
},
|
|
|
|
beforeDestroy() {
|
|
eventHub.$off('toggleFolder');
|
|
eventHub.$off('postAction');
|
|
},
|
|
|
|
methods: {
|
|
toggleFolder(folder) {
|
|
this.store.toggleFolder(folder);
|
|
|
|
if (!folder.isOpen) {
|
|
this.fetchChildEnvironments(folder, true);
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Will change the page number and update the URL.
|
|
*
|
|
* @param {Number} pageNumber desired page to go to.
|
|
* @return {String}
|
|
*/
|
|
changePage(pageNumber) {
|
|
const param = setParamInURL('page', pageNumber);
|
|
|
|
gl.utils.visitUrl(param);
|
|
return param;
|
|
},
|
|
|
|
fetchEnvironments() {
|
|
const scope = getParameterByName('scope') || this.visibility;
|
|
const page = getParameterByName('page') || this.pageNumber;
|
|
|
|
this.isLoading = true;
|
|
|
|
return this.service.get({ scope, page })
|
|
.then(this.successCallback)
|
|
.catch(this.errorCallback);
|
|
},
|
|
|
|
fetchChildEnvironments(folder, showLoader = false) {
|
|
this.store.updateEnvironmentProp(folder, 'isLoadingFolderContent', showLoader);
|
|
|
|
this.service.getFolderContent(folder.folder_path)
|
|
.then(resp => resp.json())
|
|
.then(response => this.store.setfolderContent(folder, response.environments))
|
|
.then(() => this.store.updateEnvironmentProp(folder, 'isLoadingFolderContent', false))
|
|
.catch(() => {
|
|
// eslint-disable-next-line no-new
|
|
new Flash('An error occurred while fetching the environments.');
|
|
this.store.updateEnvironmentProp(folder, 'isLoadingFolderContent', false);
|
|
});
|
|
},
|
|
|
|
postAction(endpoint) {
|
|
if (!this.isMakingRequest) {
|
|
this.isLoading = true;
|
|
|
|
this.service.postAction(endpoint)
|
|
.then(() => this.fetchEnvironments())
|
|
.catch(() => new Flash('An error occured while making the request.'));
|
|
}
|
|
},
|
|
|
|
successCallback(resp) {
|
|
this.saveData(resp);
|
|
|
|
// We need to verify if any folder is open to also update it
|
|
const openFolders = this.store.getOpenFolders();
|
|
if (openFolders.length) {
|
|
openFolders.forEach(folder => this.fetchChildEnvironments(folder));
|
|
}
|
|
},
|
|
|
|
errorCallback() {
|
|
this.isLoading = false;
|
|
// eslint-disable-next-line no-new
|
|
new Flash('An error occurred while fetching the environments.');
|
|
},
|
|
},
|
|
};
|
|
</script>
|
|
<template>
|
|
<div :class="cssContainerClass">
|
|
<div class="top-area">
|
|
<ul
|
|
v-if="!isLoading"
|
|
class="nav-links">
|
|
<li :class="{ active: scope === null || scope === 'available' }">
|
|
<a :href="projectEnvironmentsPath">
|
|
Available
|
|
<span class="badge js-available-environments-count">
|
|
{{state.availableCounter}}
|
|
</span>
|
|
</a>
|
|
</li>
|
|
<li :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">
|
|
<loading-icon
|
|
label="Loading environments"
|
|
size="3"
|
|
v-if="isLoading"
|
|
/>
|
|
|
|
<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"
|
|
/>
|
|
</div>
|
|
|
|
<table-pagination
|
|
v-if="state.paginationInformation && state.paginationInformation.totalPages > 1"
|
|
:change="changePage"
|
|
:pageInfo="state.paginationInformation" />
|
|
</div>
|
|
</div>
|
|
</template>
|