Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-01-15 00:07:45 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2020-01-15 00:07:45 +0300
commit0b12a5312c9701fbfed25fbb334d47900ced736b (patch)
treea29a27e297134f573fd8e5c298d241f3156c207a /app/assets/javascripts/self_monitor
parent92f95ccac81911d1fcc32e999a7f1ce04624a56c (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/assets/javascripts/self_monitor')
-rw-r--r--app/assets/javascripts/self_monitor/components/self_monitor_form.vue160
-rw-r--r--app/assets/javascripts/self_monitor/index.js23
-rw-r--r--app/assets/javascripts/self_monitor/store/actions.js126
-rw-r--r--app/assets/javascripts/self_monitor/store/index.js21
-rw-r--r--app/assets/javascripts/self_monitor/store/mutation_types.js6
-rw-r--r--app/assets/javascripts/self_monitor/store/mutations.js22
-rw-r--r--app/assets/javascripts/self_monitor/store/state.js15
7 files changed, 373 insertions, 0 deletions
diff --git a/app/assets/javascripts/self_monitor/components/self_monitor_form.vue b/app/assets/javascripts/self_monitor/components/self_monitor_form.vue
new file mode 100644
index 00000000000..2f364eae67f
--- /dev/null
+++ b/app/assets/javascripts/self_monitor/components/self_monitor_form.vue
@@ -0,0 +1,160 @@
+<script>
+import Vue from 'vue';
+import { GlFormGroup, GlButton, GlModal, GlToast, GlToggle } from '@gitlab/ui';
+import { mapState, mapActions } from 'vuex';
+import { __, s__, sprintf } from '~/locale';
+import { visitUrl, getBaseURL } from '~/lib/utils/url_utility';
+
+Vue.use(GlToast);
+
+export default {
+ components: {
+ GlFormGroup,
+ GlButton,
+ GlModal,
+ GlToggle,
+ },
+ formLabels: {
+ createProject: __('Create Project'),
+ },
+ data() {
+ return {
+ modalId: 'delete-self-monitor-modal',
+ };
+ },
+ computed: {
+ ...mapState('selfMonitoring', [
+ 'projectEnabled',
+ 'projectCreated',
+ 'showAlert',
+ 'projectPath',
+ 'loading',
+ 'alertContent',
+ ]),
+ selfMonitorEnabled: {
+ get() {
+ return this.projectEnabled;
+ },
+ set(projectEnabled) {
+ this.setSelfMonitor(projectEnabled);
+ },
+ },
+ selfMonitorProjectFullUrl() {
+ return `${getBaseURL()}/${this.projectPath}`;
+ },
+ selfMonitoringFormText() {
+ if (this.projectCreated) {
+ return sprintf(
+ s__(
+ 'SelfMonitoring|Enabling this feature creates a %{projectLinkStart}project%{projectLinkEnd} that can be used to monitor the health of your instance.',
+ ),
+ {
+ projectLinkStart: `<a href="${this.selfMonitorProjectFullUrl}">`,
+ projectLinkEnd: '</a>',
+ },
+ false,
+ );
+ }
+
+ return s__(
+ 'SelfMonitoring|Enabling this feature creates a project that can be used to monitor the health of your instance.',
+ );
+ },
+ },
+ watch: {
+ selfMonitorEnabled() {
+ this.saveChangesSelfMonitorProject();
+ },
+ showAlert() {
+ let toastOptions = {
+ onComplete: () => {
+ this.resetAlert();
+ },
+ };
+
+ if (this.showAlert) {
+ if (this.alertContent.actionName && this.alertContent.actionName.length > 0) {
+ toastOptions = {
+ ...toastOptions,
+ action: {
+ text: this.alertContent.actionText,
+ onClick: (_, toastObject) => {
+ this[this.alertContent.actionName]();
+ toastObject.goAway(0);
+ },
+ },
+ };
+ }
+ this.$toast.show(this.alertContent.message, toastOptions);
+ }
+ },
+ },
+ methods: {
+ ...mapActions('selfMonitoring', [
+ 'setSelfMonitor',
+ 'createProject',
+ 'deleteProject',
+ 'resetAlert',
+ ]),
+ hideSelfMonitorModal() {
+ this.$root.$emit('bv::hide::modal', this.modalId);
+ this.setSelfMonitor(true);
+ },
+ showSelfMonitorModal() {
+ this.$root.$emit('bv::show::modal', this.modalId);
+ },
+ saveChangesSelfMonitorProject() {
+ if (this.projectCreated && !this.projectEnabled) {
+ this.showSelfMonitorModal();
+ } else {
+ this.createProject();
+ }
+ },
+ viewSelfMonitorProject() {
+ visitUrl(this.selfMonitorProjectFullUrl);
+ },
+ },
+};
+</script>
+<template>
+ <section class="settings no-animate js-self-monitoring-settings">
+ <div class="settings-header">
+ <h4 class="js-section-header">
+ {{ s__('SelfMonitoring|Self monitoring') }}
+ </h4>
+ <gl-button class="js-settings-toggle">{{ __('Expand') }}</gl-button>
+ <p class="js-section-sub-header">
+ {{ s__('SelfMonitoring|Enable or disable instance self monitoring') }}
+ </p>
+ </div>
+ <div class="settings-content">
+ <form name="self-monitoring-form">
+ <p v-html="selfMonitoringFormText"></p>
+ <gl-form-group :label="$options.formLabels.createProject" label-for="self-monitor-toggle">
+ <gl-toggle
+ v-model="selfMonitorEnabled"
+ :is-loading="loading"
+ name="self-monitor-toggle"
+ />
+ </gl-form-group>
+ </form>
+ </div>
+ <gl-modal
+ :title="s__('SelfMonitoring|Disable self monitoring?')"
+ :modal-id="modalId"
+ :ok-title="__('Delete project')"
+ :cancel-title="__('Cancel')"
+ ok-variant="danger"
+ @ok="deleteProject"
+ @cancel="hideSelfMonitorModal"
+ >
+ <div>
+ {{
+ s__(
+ 'SelfMonitoring|Disabling this feature will delete the self monitoring project. Are you sure you want to delete the project?',
+ )
+ }}
+ </div>
+ </gl-modal>
+ </section>
+</template>
diff --git a/app/assets/javascripts/self_monitor/index.js b/app/assets/javascripts/self_monitor/index.js
new file mode 100644
index 00000000000..42c94e11989
--- /dev/null
+++ b/app/assets/javascripts/self_monitor/index.js
@@ -0,0 +1,23 @@
+import Vue from 'vue';
+import store from './store';
+import SelfMonitorForm from './components/self_monitor_form.vue';
+
+export default () => {
+ const el = document.querySelector('.js-self-monitoring-settings');
+ let selfMonitorProjectCreated;
+
+ if (el) {
+ selfMonitorProjectCreated = el.dataset.selfMonitoringProjectExists;
+ // eslint-disable-next-line no-new
+ new Vue({
+ el,
+ store: store({
+ projectEnabled: selfMonitorProjectCreated,
+ ...el.dataset,
+ }),
+ render(createElement) {
+ return createElement(SelfMonitorForm);
+ },
+ });
+ }
+};
diff --git a/app/assets/javascripts/self_monitor/store/actions.js b/app/assets/javascripts/self_monitor/store/actions.js
new file mode 100644
index 00000000000..f8430a9b136
--- /dev/null
+++ b/app/assets/javascripts/self_monitor/store/actions.js
@@ -0,0 +1,126 @@
+import { __, s__ } from '~/locale';
+import axios from '~/lib/utils/axios_utils';
+import statusCodes from '~/lib/utils/http_status';
+import { backOff } from '~/lib/utils/common_utils';
+import * as types from './mutation_types';
+
+const TWO_MINUTES = 120000;
+
+function backOffRequest(makeRequestCallback) {
+ return backOff((next, stop) => {
+ makeRequestCallback()
+ .then(resp => {
+ if (resp.status === statusCodes.ACCEPTED) {
+ next();
+ } else {
+ stop(resp);
+ }
+ })
+ .catch(stop);
+ }, TWO_MINUTES);
+}
+
+export const setSelfMonitor = ({ commit }, enabled) => commit(types.SET_ENABLED, enabled);
+
+export const createProject = ({ dispatch }) => dispatch('requestCreateProject');
+
+export const resetAlert = ({ commit }) => commit(types.SET_SHOW_ALERT, false);
+
+export const requestCreateProject = ({ dispatch, state, commit }) => {
+ commit(types.SET_LOADING, true);
+ axios
+ .post(state.createProjectEndpoint)
+ .then(resp => {
+ if (resp.status === statusCodes.ACCEPTED) {
+ dispatch('requestCreateProjectStatus', resp.data.job_id);
+ }
+ })
+ .catch(error => {
+ dispatch('requestCreateProjectError', error);
+ });
+};
+
+export const requestCreateProjectStatus = ({ dispatch, state }, jobId) => {
+ backOffRequest(() => axios.get(state.createProjectStatusEndpoint, { params: { job_id: jobId } }))
+ .then(resp => {
+ if (resp.status === statusCodes.OK) {
+ dispatch('requestCreateProjectSuccess', resp.data);
+ }
+ })
+ .catch(error => {
+ dispatch('requestCreateProjectError', error);
+ });
+};
+
+export const requestCreateProjectSuccess = ({ commit }, selfMonitorData) => {
+ commit(types.SET_LOADING, false);
+ commit(types.SET_PROJECT_URL, selfMonitorData.project_full_path);
+ commit(types.SET_ALERT_CONTENT, {
+ message: s__('SelfMonitoring|Self monitoring project has been successfully created.'),
+ actionText: __('View project'),
+ actionName: 'viewSelfMonitorProject',
+ });
+ commit(types.SET_SHOW_ALERT, true);
+ commit(types.SET_PROJECT_CREATED, true);
+};
+
+export const requestCreateProjectError = ({ commit }, error) => {
+ const { response } = error;
+ const message = response.data && response.data.message ? response.data.message : '';
+
+ commit(types.SET_ALERT_CONTENT, {
+ message: `${__('There was an error saving your changes.')} ${message}`,
+ });
+ commit(types.SET_SHOW_ALERT, true);
+ commit(types.SET_LOADING, false);
+};
+
+export const deleteProject = ({ dispatch }) => dispatch('requestDeleteProject');
+
+export const requestDeleteProject = ({ dispatch, state, commit }) => {
+ commit(types.SET_LOADING, true);
+ axios
+ .delete(state.deleteProjectEndpoint)
+ .then(resp => {
+ if (resp.status === statusCodes.ACCEPTED) {
+ dispatch('requestDeleteProjectStatus', resp.data.job_id);
+ }
+ })
+ .catch(error => {
+ dispatch('requestDeleteProjectError', error);
+ });
+};
+
+export const requestDeleteProjectStatus = ({ dispatch, state }, jobId) => {
+ backOffRequest(() => axios.get(state.deleteProjectStatusEndpoint, { params: { job_id: jobId } }))
+ .then(resp => {
+ if (resp.status === statusCodes.OK) {
+ dispatch('requestDeleteProjectSuccess', resp.data);
+ }
+ })
+ .catch(error => {
+ dispatch('requestDeleteProjectError', error);
+ });
+};
+
+export const requestDeleteProjectSuccess = ({ commit }) => {
+ commit(types.SET_PROJECT_URL, '');
+ commit(types.SET_PROJECT_CREATED, false);
+ commit(types.SET_ALERT_CONTENT, {
+ message: s__('SelfMonitoring|Self monitoring project has been successfully deleted.'),
+ actionText: __('Undo'),
+ actionName: 'createProject',
+ });
+ commit(types.SET_SHOW_ALERT, true);
+ commit(types.SET_LOADING, false);
+};
+
+export const requestDeleteProjectError = ({ commit }, error) => {
+ const { response } = error;
+ const message = response.data && response.data.message ? response.data.message : '';
+
+ commit(types.SET_ALERT_CONTENT, {
+ message: `${__('There was an error saving your changes.')} ${message}`,
+ });
+ commit(types.SET_LOADING, false);
+};
diff --git a/app/assets/javascripts/self_monitor/store/index.js b/app/assets/javascripts/self_monitor/store/index.js
new file mode 100644
index 00000000000..a222e9c87b8
--- /dev/null
+++ b/app/assets/javascripts/self_monitor/store/index.js
@@ -0,0 +1,21 @@
+import Vue from 'vue';
+import Vuex from 'vuex';
+import createState from './state';
+import * as actions from './actions';
+import mutations from './mutations';
+
+Vue.use(Vuex);
+
+export const createStore = initialState =>
+ new Vuex.Store({
+ modules: {
+ selfMonitoring: {
+ namespaced: true,
+ state: createState(initialState),
+ actions,
+ mutations,
+ },
+ },
+ });
+
+export default createStore;
diff --git a/app/assets/javascripts/self_monitor/store/mutation_types.js b/app/assets/javascripts/self_monitor/store/mutation_types.js
new file mode 100644
index 00000000000..c5952b66144
--- /dev/null
+++ b/app/assets/javascripts/self_monitor/store/mutation_types.js
@@ -0,0 +1,6 @@
+export const SET_ENABLED = 'SET_ENABLED';
+export const SET_PROJECT_CREATED = 'SET_PROJECT_CREATED';
+export const SET_SHOW_ALERT = 'SET_SHOW_ALERT';
+export const SET_PROJECT_URL = 'SET_PROJECT_URL';
+export const SET_LOADING = 'SET_LOADING';
+export const SET_ALERT_CONTENT = 'SET_ALERT_CONTENT';
diff --git a/app/assets/javascripts/self_monitor/store/mutations.js b/app/assets/javascripts/self_monitor/store/mutations.js
new file mode 100644
index 00000000000..7dca8bcdc4d
--- /dev/null
+++ b/app/assets/javascripts/self_monitor/store/mutations.js
@@ -0,0 +1,22 @@
+import * as types from './mutation_types';
+
+export default {
+ [types.SET_ENABLED](state, enabled) {
+ state.projectEnabled = enabled;
+ },
+ [types.SET_PROJECT_CREATED](state, created) {
+ state.projectCreated = created;
+ },
+ [types.SET_SHOW_ALERT](state, show) {
+ state.showAlert = show;
+ },
+ [types.SET_PROJECT_URL](state, url) {
+ state.projectPath = url;
+ },
+ [types.SET_LOADING](state, loading) {
+ state.loading = loading;
+ },
+ [types.SET_ALERT_CONTENT](state, content) {
+ state.alertContent = content;
+ },
+};
diff --git a/app/assets/javascripts/self_monitor/store/state.js b/app/assets/javascripts/self_monitor/store/state.js
new file mode 100644
index 00000000000..b8b4a4af614
--- /dev/null
+++ b/app/assets/javascripts/self_monitor/store/state.js
@@ -0,0 +1,15 @@
+import { parseBoolean } from '~/lib/utils/common_utils';
+
+export default (initialState = {}) => ({
+ projectEnabled: parseBoolean(initialState.projectEnabled) || false,
+ projectCreated: parseBoolean(initialState.selfMonitorProjectCreated) || false,
+ createProjectEndpoint: initialState.createSelfMonitoringProjectPath || '',
+ deleteProjectEndpoint: initialState.deleteSelfMonitoringProjectPath || '',
+ createProjectStatusEndpoint: initialState.statusCreateSelfMonitoringProjectPath || '',
+ deleteProjectStatusEndpoint: initialState.statusDeleteSelfMonitoringProjectPath || '',
+ selfMonitorProjectPath: initialState.selfMonitoringProjectFullPath || '',
+ showAlert: false,
+ projectPath: '',
+ loading: false,
+ alertContent: {},
+});