debian-mirror-gitlab/app/assets/javascripts/clusters/clusters_bundle.js

255 lines
7.9 KiB
JavaScript
Raw Normal View History

2018-03-17 18:26:18 +05:30
import Visibility from 'visibilityjs';
import Vue from 'vue';
2018-12-13 13:39:08 +05:30
import initDismissableCallout from '~/dismissable_callout';
2018-03-17 18:26:18 +05:30
import { s__, sprintf } from '../locale';
import Flash from '../flash';
import Poll from '../lib/utils/poll';
import initSettingsPanels from '../settings_panels';
import eventHub from './event_hub';
2018-11-20 20:47:30 +05:30
import { APPLICATION_STATUS, REQUEST_LOADING, REQUEST_SUCCESS, REQUEST_FAILURE } from './constants';
2018-03-17 18:26:18 +05:30
import ClustersService from './services/clusters_service';
import ClustersStore from './stores/clusters_store';
2018-12-23 12:14:25 +05:30
import Applications from './components/applications.vue';
2018-03-17 18:26:18 +05:30
import setupToggleButtons from '../toggle_buttons';
/**
* Cluster page has 2 separate parts:
* Toggle button and applications section
*
* - Polling status while creating or scheduled
* - Update status area with the response result
*/
export default class Clusters {
constructor() {
const {
statusPath,
installHelmPath,
installIngressPath,
2018-12-23 12:14:25 +05:30
installCertManagerPath,
2018-03-17 18:26:18 +05:30
installRunnerPath,
2018-11-08 19:23:39 +05:30
installJupyterPath,
2018-12-13 13:39:08 +05:30
installKnativePath,
2018-03-17 18:26:18 +05:30
installPrometheusPath,
managePrometheusPath,
2018-12-23 12:14:25 +05:30
clusterType,
2018-03-17 18:26:18 +05:30
clusterStatus,
clusterStatusReason,
helpPath,
ingressHelpPath,
2018-03-27 19:54:05 +05:30
ingressDnsHelpPath,
2018-03-17 18:26:18 +05:30
} = document.querySelector('.js-edit-cluster-form').dataset;
this.store = new ClustersStore();
2018-03-27 19:54:05 +05:30
this.store.setHelpPaths(helpPath, ingressHelpPath, ingressDnsHelpPath);
2018-03-17 18:26:18 +05:30
this.store.setManagePrometheusPath(managePrometheusPath);
this.store.updateStatus(clusterStatus);
this.store.updateStatusReason(clusterStatusReason);
this.service = new ClustersService({
endpoint: statusPath,
installHelmEndpoint: installHelmPath,
installIngressEndpoint: installIngressPath,
2018-12-23 12:14:25 +05:30
installCertManagerEndpoint: installCertManagerPath,
2018-03-17 18:26:18 +05:30
installRunnerEndpoint: installRunnerPath,
installPrometheusEndpoint: installPrometheusPath,
2018-11-08 19:23:39 +05:30
installJupyterEndpoint: installJupyterPath,
2018-12-13 13:39:08 +05:30
installKnativeEndpoint: installKnativePath,
2018-03-17 18:26:18 +05:30
});
this.installApplication = this.installApplication.bind(this);
this.showToken = this.showToken.bind(this);
this.errorContainer = document.querySelector('.js-cluster-error');
this.successContainer = document.querySelector('.js-cluster-success');
this.creatingContainer = document.querySelector('.js-cluster-creating');
this.errorReasonContainer = this.errorContainer.querySelector('.js-error-reason');
this.successApplicationContainer = document.querySelector('.js-cluster-application-notice');
this.showTokenButton = document.querySelector('.js-show-cluster-token');
this.tokenField = document.querySelector('.js-cluster-token');
2018-12-13 13:39:08 +05:30
initDismissableCallout('.js-cluster-security-warning');
2018-03-17 18:26:18 +05:30
initSettingsPanels();
setupToggleButtons(document.querySelector('.js-cluster-enable-toggle-area'));
2018-12-23 12:14:25 +05:30
this.initApplications(clusterType);
2018-03-17 18:26:18 +05:30
if (this.store.state.status !== 'created') {
this.updateContainer(null, this.store.state.status, this.store.state.statusReason);
}
this.addListeners();
if (statusPath) {
this.initPolling();
}
}
2018-12-23 12:14:25 +05:30
initApplications(type) {
2018-11-08 19:23:39 +05:30
const { store } = this;
2018-03-17 18:26:18 +05:30
const el = document.querySelector('#js-cluster-applications');
this.applications = new Vue({
el,
data() {
return {
state: store.state,
};
},
render(createElement) {
2018-12-23 12:14:25 +05:30
return createElement(Applications, {
2018-03-17 18:26:18 +05:30
props: {
2018-12-23 12:14:25 +05:30
type,
2018-03-17 18:26:18 +05:30
applications: this.state.applications,
helpPath: this.state.helpPath,
ingressHelpPath: this.state.ingressHelpPath,
managePrometheusPath: this.state.managePrometheusPath,
2018-03-27 19:54:05 +05:30
ingressDnsHelpPath: this.state.ingressDnsHelpPath,
2018-03-17 18:26:18 +05:30
},
});
},
});
}
addListeners() {
if (this.showTokenButton) this.showTokenButton.addEventListener('click', this.showToken);
eventHub.$on('installApplication', this.installApplication);
}
removeListeners() {
if (this.showTokenButton) this.showTokenButton.removeEventListener('click', this.showToken);
eventHub.$off('installApplication', this.installApplication);
}
initPolling() {
this.poll = new Poll({
resource: this.service,
method: 'fetchData',
successCallback: data => this.handleSuccess(data),
errorCallback: () => Clusters.handleError(),
});
if (!Visibility.hidden()) {
this.poll.makeRequest();
} else {
2018-11-20 20:47:30 +05:30
this.service
.fetchData()
2018-03-17 18:26:18 +05:30
.then(data => this.handleSuccess(data))
.catch(() => Clusters.handleError());
}
Visibility.change(() => {
if (!Visibility.hidden() && !this.destroyed) {
this.poll.restart();
} else {
this.poll.stop();
}
});
}
static handleError() {
Flash(s__('ClusterIntegration|Something went wrong on our end.'));
}
handleSuccess(data) {
const prevStatus = this.store.state.status;
const prevApplicationMap = Object.assign({}, this.store.state.applications);
this.store.updateStateFromServer(data.data);
this.checkForNewInstalls(prevApplicationMap, this.store.state.applications);
this.updateContainer(prevStatus, this.store.state.status, this.store.state.statusReason);
}
showToken() {
const type = this.tokenField.getAttribute('type');
if (type === 'password') {
this.tokenField.setAttribute('type', 'text');
2018-11-18 11:00:15 +05:30
this.showTokenButton.textContent = s__('ClusterIntegration|Hide');
2018-03-17 18:26:18 +05:30
} else {
this.tokenField.setAttribute('type', 'password');
2018-11-18 11:00:15 +05:30
this.showTokenButton.textContent = s__('ClusterIntegration|Show');
2018-03-17 18:26:18 +05:30
}
}
hideAll() {
this.errorContainer.classList.add('hidden');
this.successContainer.classList.add('hidden');
this.creatingContainer.classList.add('hidden');
}
checkForNewInstalls(prevApplicationMap, newApplicationMap) {
const appTitles = Object.keys(newApplicationMap)
2018-11-20 20:47:30 +05:30
.filter(
appId =>
newApplicationMap[appId].status === APPLICATION_STATUS.INSTALLED &&
prevApplicationMap[appId].status !== APPLICATION_STATUS.INSTALLED &&
prevApplicationMap[appId].status !== null,
)
2018-03-17 18:26:18 +05:30
.map(appId => newApplicationMap[appId].title);
if (appTitles.length > 0) {
2018-11-20 20:47:30 +05:30
const text = sprintf(
s__('ClusterIntegration|%{appList} was successfully installed on your Kubernetes cluster'),
{
appList: appTitles.join(', '),
},
);
2018-03-17 18:26:18 +05:30
Flash(text, 'notice', this.successApplicationContainer);
}
}
updateContainer(prevStatus, status, error) {
this.hideAll();
// We poll all the time but only want the `created` banner to show when newly created
if (this.store.state.status !== 'created' || prevStatus !== this.store.state.status) {
switch (status) {
case 'created':
this.successContainer.classList.remove('hidden');
break;
case 'errored':
this.errorContainer.classList.remove('hidden');
this.errorReasonContainer.textContent = error;
break;
case 'scheduled':
case 'creating':
this.creatingContainer.classList.remove('hidden');
break;
default:
this.hideAll();
}
}
}
2018-11-08 19:23:39 +05:30
installApplication(data) {
const appId = data.id;
2018-03-17 18:26:18 +05:30
this.store.updateAppProperty(appId, 'requestStatus', REQUEST_LOADING);
this.store.updateAppProperty(appId, 'requestReason', null);
2018-11-20 20:47:30 +05:30
this.service
.installApplication(appId, data.params)
2018-03-17 18:26:18 +05:30
.then(() => {
this.store.updateAppProperty(appId, 'requestStatus', REQUEST_SUCCESS);
})
.catch(() => {
this.store.updateAppProperty(appId, 'requestStatus', REQUEST_FAILURE);
2018-11-20 20:47:30 +05:30
this.store.updateAppProperty(
appId,
'requestReason',
s__('ClusterIntegration|Request to begin installing failed'),
);
2018-03-17 18:26:18 +05:30
});
}
destroy() {
this.destroyed = true;
this.removeListeners();
if (this.poll) {
this.poll.stop();
}
this.applications.$destroy();
}
}