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-07-08 12:09:17 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2020-07-08 12:09:17 +0300
commit21341457a8c422d890a9ec30838b597dea565d62 (patch)
treeaa8aca2a9bce4e16936cc8d7b40aa1c79ca82e35 /app/assets/javascripts/alerts_settings
parent0a319374e7784aa5c2d1c30dd832d2a0509edbab (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/assets/javascripts/alerts_settings')
-rw-r--r--app/assets/javascripts/alerts_settings/components/alerts_settings_form.vue199
-rw-r--r--app/assets/javascripts/alerts_settings/constants.js13
-rw-r--r--app/assets/javascripts/alerts_settings/services/index.js9
3 files changed, 183 insertions, 38 deletions
diff --git a/app/assets/javascripts/alerts_settings/components/alerts_settings_form.vue b/app/assets/javascripts/alerts_settings/components/alerts_settings_form.vue
index 7dde9edbd27..63f3b3bc1f0 100644
--- a/app/assets/javascripts/alerts_settings/components/alerts_settings_form.vue
+++ b/app/assets/javascripts/alerts_settings/components/alerts_settings_form.vue
@@ -5,18 +5,21 @@ import {
GlForm,
GlFormGroup,
GlFormInput,
+ GlFormInputGroup,
+ GlFormTextarea,
GlLink,
GlModal,
GlModalDirective,
GlSprintf,
GlFormSelect,
} from '@gitlab/ui';
+import { debounce } from 'lodash';
import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import ClipboardButton from '~/vue_shared/components/clipboard_button.vue';
import ToggleButton from '~/vue_shared/components/toggle_button.vue';
import csrf from '~/lib/utils/csrf';
import service from '../services';
-import { i18n, serviceOptions } from '../constants';
+import { i18n, serviceOptions, JSON_VALIDATE_DELAY } from '../constants';
export default {
i18n,
@@ -27,7 +30,9 @@ export default {
GlForm,
GlFormGroup,
GlFormInput,
+ GlFormInputGroup,
GlFormSelect,
+ GlFormTextarea,
GlLink,
GlModal,
GlSprintf,
@@ -73,6 +78,11 @@ export default {
feedbackMessage: null,
isFeedbackDismissed: false,
},
+ testAlert: {
+ json: null,
+ error: null,
+ },
+ canSaveForm: false,
};
},
computed: {
@@ -109,12 +119,32 @@ export default {
showFeedbackMsg() {
return this.feedback.feedbackMessage && !this.isFeedbackDismissed;
},
+ showAlertSave() {
+ return (
+ this.feedback.feedbackMessage === this.$options.i18n.testAlertFailed &&
+ !this.isFeedbackDismissed
+ );
+ },
prometheusInfo() {
return !this.isGeneric ? this.$options.i18n.prometheusInfo : '';
},
prometheusFeatureEnabled() {
return !this.isGeneric && this.glFeatures.alertIntegrationsDropdown;
},
+ jsonIsValid() {
+ return this.testAlert.error === null;
+ },
+ canTestAlert() {
+ return this.selectedService.active && this.testAlert.json !== null;
+ },
+ canSaveConfig() {
+ return !this.loading && this.canSaveForm;
+ },
+ },
+ watch: {
+ 'testAlert.json': debounce(function debouncedJsonValidate() {
+ this.validateJson();
+ }, JSON_VALIDATE_DELAY),
},
created() {
if (this.glFeatures.alertIntegrationsDropdown) {
@@ -126,6 +156,9 @@ export default {
}
},
methods: {
+ clearJson() {
+ this.testAlert.json = null;
+ },
dismissFeedback() {
this.feedback = { ...this.feedback, feedbackMessage: null };
this.isFeedbackDismissed = false;
@@ -135,6 +168,7 @@ export default {
.updateGenericKey({ endpoint: this.generic.formPath, params: { service: { token: '' } } })
.then(({ data: { token } }) => {
this.authorizationKey.generic = token;
+ this.setFeedback({ feedbackMessage: this.$options.i18n.authKeyRest, variant: 'success' });
})
.catch(() => {
this.setFeedback({ feedbackMessage: this.$options.i18n.errorKeyMsg, variant: 'danger' });
@@ -145,11 +179,24 @@ export default {
.updatePrometheusKey({ endpoint: this.prometheus.prometheusResetKeyPath })
.then(({ data: { token } }) => {
this.authorizationKey.prometheus = token;
+ this.setFeedback({ feedbackMessage: this.$options.i18n.authKeyRest, variant: 'success' });
})
.catch(() => {
this.setFeedback({ feedbackMessage: this.$options.i18n.errorKeyMsg, variant: 'danger' });
});
},
+ toggleService(value) {
+ this.canSaveForm = true;
+ if (!this.glFeatures.alertIntegrationsDropdown) {
+ this.toggleActivated(value);
+ }
+
+ if (this.isGeneric) {
+ this.activated.generic = value;
+ } else {
+ this.activated.prometheus = value;
+ }
+ },
toggleActivated(value) {
return this.isGeneric
? this.toggleGenericActivated(value)
@@ -164,15 +211,14 @@ export default {
})
.then(() => {
this.activated.generic = value;
-
- if (value) {
- this.setFeedback({
- feedbackMessage: this.$options.i18n.endPointActivated,
- variant: 'success',
- });
- }
+ this.toggleSuccess(value);
+ })
+ .catch(() => {
+ this.setFeedback({
+ feedbackMessage: this.$options.i18n.errorMsg,
+ variant: 'danger',
+ });
})
- .catch(() => {})
.finally(() => {
this.loading = false;
});
@@ -191,12 +237,7 @@ export default {
})
.then(() => {
this.activated.prometheus = value;
- if (value) {
- this.setFeedback({
- feedbackMessage: this.$options.i18n.endPointActivated,
- variant: 'success',
- });
- }
+ this.toggleSuccess(value);
})
.catch(() => {
this.setFeedback({
@@ -208,16 +249,61 @@ export default {
this.loading = false;
});
},
+ toggleSuccess(value) {
+ if (value) {
+ this.setFeedback({
+ feedbackMessage: this.$options.i18n.endPointActivated,
+ variant: 'info',
+ });
+ } else {
+ this.setFeedback({
+ feedbackMessage: this.$options.i18n.changesSaved,
+ variant: 'info',
+ });
+ }
+ },
setFeedback({ feedbackMessage, variant }) {
this.feedback = { feedbackMessage, variant };
},
- onSubmit(evt) {
- // TODO: Add form submit as part of https://gitlab.com/gitlab-org/gitlab/-/issues/215356
- evt.preventDefault();
+ validateJson() {
+ this.testAlert.error = null;
+ try {
+ JSON.parse(this.testAlert.json);
+ } catch (e) {
+ this.testAlert.error = JSON.stringify(e.message);
+ }
},
- onReset(evt) {
- // TODO: Add form reset as part of https://gitlab.com/gitlab-org/gitlab/-/issues/215356
- evt.preventDefault();
+ validateTestAlert() {
+ this.loading = true;
+ this.validateJson();
+ return service
+ .updateTestAlert({
+ endpoint: this.selectedService.url,
+ data: this.testAlert.json,
+ authKey: this.selectedService.authKey,
+ })
+ .then(() => {
+ this.setFeedback({
+ feedbackMessage: this.$options.i18n.testAlertSuccess,
+ variant: 'success',
+ });
+ })
+ .catch(() => {
+ this.setFeedback({
+ feedbackMessage: this.$options.i18n.testAlertFailed,
+ variant: 'danger',
+ });
+ })
+ .finally(() => {
+ this.loading = false;
+ });
+ },
+ onSubmit() {
+ this.toggleActivated(this.selectedService.active);
+ },
+ onReset() {
+ this.testAlert.json = null;
+ this.dismissFeedback();
},
},
};
@@ -227,6 +313,15 @@ export default {
<div>
<gl-alert v-if="showFeedbackMsg" :variant="feedback.variant" @dismiss="dismissFeedback">
{{ feedback.feedbackMessage }}
+ <gl-button
+ v-if="showAlertSave"
+ variant="danger"
+ category="primary"
+ class="gl-display-block gl-mt-3"
+ @click="toggleActivated(selectedService.active)"
+ >
+ {{ __('Save anyway') }}
+ </gl-button>
</gl-alert>
<div data-testid="alert-settings-description" class="gl-mt-5">
<p v-for="section in sections" :key="section.text">
@@ -237,7 +332,7 @@ export default {
</gl-sprintf>
</p>
</div>
- <gl-form @submit="onSubmit" @reset="onReset">
+ <gl-form @submit.prevent="onSubmit" @reset.prevent="onReset">
<gl-form-group
v-if="glFeatures.alertIntegrationsDropdown"
:label="$options.i18n.integrationsLabel"
@@ -248,6 +343,7 @@ export default {
v-model="selectedEndpoint"
:options="options"
data-testid="alert-settings-select"
+ @change="clearJson"
/>
<span class="gl-text-gray-400">
<gl-sprintf :message="$options.i18n.integrationsInfo">
@@ -272,7 +368,7 @@ export default {
:disabled-input="loading"
:is-loading="loading"
:value="selectedService.active"
- @change="toggleActivated"
+ @change="toggleService"
/>
</gl-form-group>
<gl-form-group
@@ -293,12 +389,15 @@ export default {
</span>
</gl-form-group>
<gl-form-group :label="$options.i18n.urlLabel" label-for="url" label-class="label-bold">
- <div class="input-group">
- <gl-form-input id="url" :readonly="true" :value="selectedService.url" />
- <span class="input-group-append">
- <clipboard-button :text="selectedService.url" :title="$options.i18n.copyToClipboard" />
- </span>
- </div>
+ <gl-form-input-group id="url" :readonly="true" :value="selectedService.url">
+ <template #append>
+ <clipboard-button
+ :text="selectedService.url"
+ :title="$options.i18n.copyToClipboard"
+ class="gl-m-0!"
+ />
+ </template>
+ </gl-form-input-group>
<span class="gl-text-gray-400">
{{ prometheusInfo }}
</span>
@@ -308,15 +407,20 @@ export default {
label-for="authorization-key"
label-class="label-bold"
>
- <div class="input-group">
- <gl-form-input id="authorization-key" :readonly="true" :value="selectedService.authKey" />
- <span class="input-group-append">
+ <gl-form-input-group
+ id="authorization-key"
+ class="gl-mb-2"
+ :readonly="true"
+ :value="selectedService.authKey"
+ >
+ <template #append>
<clipboard-button
:text="selectedService.authKey"
:title="$options.i18n.copyToClipboard"
+ class="gl-m-0!"
/>
- </span>
- </div>
+ </template>
+ </gl-form-input-group>
<gl-button v-gl-modal.authKeyModal class="gl-mt-3">{{ $options.i18n.resetKey }}</gl-button>
<gl-modal
modal-id="authKeyModal"
@@ -328,11 +432,32 @@ export default {
{{ $options.i18n.restKeyInfo }}
</gl-modal>
</gl-form-group>
+ <gl-form-group
+ v-if="glFeatures.alertIntegrationsDropdown"
+ :label="$options.i18n.alertJson"
+ label-for="alert-json"
+ label-class="label-bold"
+ :invalid-feedback="testAlert.error"
+ >
+ <gl-form-textarea
+ id="alert-json"
+ v-model.trim="testAlert.json"
+ :disabled="!selectedService.active"
+ :state="jsonIsValid"
+ :placeholder="$options.i18n.alertJsonPlaceholder"
+ rows="6"
+ max-rows="10"
+ />
+ </gl-form-group>
+ <gl-button :disabled="!canTestAlert" @click="validateTestAlert">{{
+ $options.i18n.testAlertInfo
+ }}</gl-button>
<div
- class="footer-block row-content-block gl-display-flex gl-justify-content-space-between d-none"
+ v-if="glFeatures.alertIntegrationsDropdown"
+ class="footer-block row-content-block gl-display-flex gl-justify-content-space-between"
>
- <gl-button type="submit" variant="success" category="primary">
- {{ __('Save and test changes') }}
+ <gl-button type="submit" variant="success" category="primary" :disabled="!canSaveConfig">
+ {{ __('Save changes') }}
</gl-button>
<gl-button type="reset" variant="default" category="primary">
{{ __('Cancel') }}
diff --git a/app/assets/javascripts/alerts_settings/constants.js b/app/assets/javascripts/alerts_settings/constants.js
index 15618978145..0a022a07352 100644
--- a/app/assets/javascripts/alerts_settings/constants.js
+++ b/app/assets/javascripts/alerts_settings/constants.js
@@ -21,6 +21,7 @@ export const i18n = {
'AlertSettings|Resetting the authorization key for this project will require updating the authorization key in every alert source it is enabled in.',
),
endPointActivated: s__('AlertSettings|Alerts endpoint successfully activated.'),
+ changesSaved: s__('AlertSettings|Your changes were successfully updated.'),
prometheusInfo: s__('AlertSettings|Add URL and auth key to your Prometheus config file'),
integrationsInfo: s__(
'AlertSettings|Learn more about our %{linkStart}upcoming integrations%{linkEnd}',
@@ -32,10 +33,20 @@ export const i18n = {
authKeyLabel: s__('AlertSettings|Authorization key'),
urlLabel: s__('AlertSettings|Webhook URL'),
activeLabel: s__('AlertSettings|Active'),
- apiBaseUrlHelpText: s__(' AlertSettings|URL cannot be blank and must start with http or https'),
+ apiBaseUrlHelpText: s__('AlertSettings|URL cannot be blank and must start with http or https'),
+ testAlertInfo: s__('AlertSettings|Test alert payload'),
+ alertJson: s__('AlertSettings|Alert test payload'),
+ alertJsonPlaceholder: s__('AlertSettings|Enter test alert JSON....'),
+ testAlertFailed: s__('AlertSettings|Test failed. Do you still want to save your changes anyway?'),
+ testAlertSuccess: s__(
+ 'AlertSettings|Test alert sent successfully. If you have made other changes, please save them now.',
+ ),
+ authKeyRest: s__('AlertSettings|Authorization key has been successfully reset'),
};
export const serviceOptions = [
{ value: 'generic', text: s__('AlertSettings|Generic') },
{ value: 'prometheus', text: s__('AlertSettings|External Prometheus') },
];
+
+export const JSON_VALIDATE_DELAY = 250;
diff --git a/app/assets/javascripts/alerts_settings/services/index.js b/app/assets/javascripts/alerts_settings/services/index.js
index 669c40bc86b..c49992d4f57 100644
--- a/app/assets/javascripts/alerts_settings/services/index.js
+++ b/app/assets/javascripts/alerts_settings/services/index.js
@@ -1,3 +1,4 @@
+/* eslint-disable @gitlab/require-i18n-strings */
import axios from '~/lib/utils/axios_utils';
export default {
@@ -24,4 +25,12 @@ export default {
},
});
},
+ updateTestAlert({ endpoint, data, authKey }) {
+ return axios.post(endpoint, data, {
+ headers: {
+ 'Content-Type': 'application/json',
+ Authorization: `Bearer ${authKey}`,
+ },
+ });
+ },
};