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-16 18:09:38 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2020-07-16 18:09:38 +0300
commit2d8454515e7b631a8f39a6415c86154d6c62841c (patch)
treed3d5fac01f23a735226cf20a4073e2cb611664d3 /app/assets/javascripts/incidents_settings
parent9d67bc14cb59a27c9877474e77d155173a1dedff (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/assets/javascripts/incidents_settings')
-rw-r--r--app/assets/javascripts/incidents_settings/components/alerts_form.vue25
-rw-r--r--app/assets/javascripts/incidents_settings/components/incidents_settings_tabs.vue14
-rw-r--r--app/assets/javascripts/incidents_settings/components/pagerduty_form.vue183
-rw-r--r--app/assets/javascripts/incidents_settings/constants.js38
-rw-r--r--app/assets/javascripts/incidents_settings/incidents_settings_service.js32
-rw-r--r--app/assets/javascripts/incidents_settings/index.js19
6 files changed, 284 insertions, 27 deletions
diff --git a/app/assets/javascripts/incidents_settings/components/alerts_form.vue b/app/assets/javascripts/incidents_settings/components/alerts_form.vue
index 40eaef55c48..a394f404ee1 100644
--- a/app/assets/javascripts/incidents_settings/components/alerts_form.vue
+++ b/app/assets/javascripts/incidents_settings/components/alerts_form.vue
@@ -9,15 +9,11 @@ import {
GlNewDropdown,
GlNewDropdownItem,
} from '@gitlab/ui';
-import axios from '~/lib/utils/axios_utils';
-import { refreshCurrentPage } from '~/lib/utils/url_utility';
-import createFlash from '~/flash';
import {
I18N_ALERT_SETTINGS_FORM,
NO_ISSUE_TEMPLATE_SELECTED,
TAKING_INCIDENT_ACTION_DOCS_LINK,
ISSUE_TEMPLATES_DOCS_LINK,
- ERROR_MSG,
} from '../constants';
export default {
@@ -31,7 +27,7 @@ export default {
GlNewDropdown,
GlNewDropdownItem,
},
- inject: ['alertSettings', 'operationsSettingsEndpoint'],
+ inject: ['service', 'alertSettings'],
data() {
return {
templates: [NO_ISSUE_TEMPLATE_SELECTED, ...this.alertSettings.templates],
@@ -65,23 +61,10 @@ export default {
},
updateAlertsIntegrationSettings() {
this.loading = true;
- return axios
- .patch(this.operationsSettingsEndpoint, {
- project: {
- incident_management_setting_attributes: this.formData,
- },
- })
- .then(() => {
- refreshCurrentPage();
- })
- .catch(({ response }) => {
- const message = response?.data?.message || '';
- createFlash(`${ERROR_MSG} ${message}`, 'alert');
- })
- .finally(() => {
- this.loading = false;
- });
+ this.service.updateSettings(this.formData).catch(() => {
+ this.loading = false;
+ });
},
},
};
diff --git a/app/assets/javascripts/incidents_settings/components/incidents_settings_tabs.vue b/app/assets/javascripts/incidents_settings/components/incidents_settings_tabs.vue
index 763568fd2c9..0623c275c5a 100644
--- a/app/assets/javascripts/incidents_settings/components/incidents_settings_tabs.vue
+++ b/app/assets/javascripts/incidents_settings/components/incidents_settings_tabs.vue
@@ -1,6 +1,8 @@
<script>
import { GlButton, GlTabs, GlTab } from '@gitlab/ui';
import AlertsSettingsForm from './alerts_form.vue';
+import PagerDutySettingsForm from './pagerduty_form.vue';
+import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import { INTEGRATION_TABS_CONFIG, I18N_INTEGRATION_TABS } from '../constants';
export default {
@@ -9,9 +11,19 @@ export default {
GlTabs,
GlTab,
AlertsSettingsForm,
+ PagerDutySettingsForm,
},
+ mixins: [glFeatureFlagMixin()],
tabs: INTEGRATION_TABS_CONFIG,
i18n: I18N_INTEGRATION_TABS,
+ methods: {
+ isFeatureFlagEnabled(tab) {
+ if (tab.featureFlag) {
+ return this.glFeatures[tab.featureFlag];
+ }
+ return true;
+ },
+ },
};
</script>
@@ -37,7 +49,7 @@ export default {
<gl-tabs>
<gl-tab
v-for="(tab, index) in $options.tabs"
- v-if="tab.active"
+ v-if="tab.active && isFeatureFlagEnabled(tab)"
:key="`${tab.title}_${index}`"
:title="tab.title"
>
diff --git a/app/assets/javascripts/incidents_settings/components/pagerduty_form.vue b/app/assets/javascripts/incidents_settings/components/pagerduty_form.vue
new file mode 100644
index 00000000000..027848db6e9
--- /dev/null
+++ b/app/assets/javascripts/incidents_settings/components/pagerduty_form.vue
@@ -0,0 +1,183 @@
+<script>
+import {
+ GlAlert,
+ GlButton,
+ GlSprintf,
+ GlLink,
+ GlIcon,
+ GlFormGroup,
+ GlFormInputGroup,
+ GlToggle,
+ GlModal,
+ GlModalDirective,
+} from '@gitlab/ui';
+import ClipboardButton from '~/vue_shared/components/clipboard_button.vue';
+import { I18N_PAGERDUTY_SETTINGS_FORM, CONFIGURE_PAGERDUTY_WEBHOOK_DOCS_LINK } from '../constants';
+import { isEqual } from 'lodash';
+
+export default {
+ components: {
+ GlAlert,
+ GlButton,
+ GlSprintf,
+ GlLink,
+ GlIcon,
+ GlFormGroup,
+ GlFormInputGroup,
+ GlToggle,
+ GlModal,
+ ClipboardButton,
+ },
+ directives: {
+ 'gl-modal': GlModalDirective,
+ },
+ inject: ['service', 'pagerDutySettings'],
+ data() {
+ return {
+ active: this.pagerDutySettings.active,
+ webhookUrl: this.pagerDutySettings.webhookUrl,
+ loading: false,
+ resettingWebhook: false,
+ webhookUpdateFailed: false,
+ showAlert: false,
+ };
+ },
+ i18n: I18N_PAGERDUTY_SETTINGS_FORM,
+ CONFIGURE_PAGERDUTY_WEBHOOK_DOCS_LINK,
+ computed: {
+ formData() {
+ return {
+ pagerduty_active: this.active,
+ };
+ },
+ isFormUpdated() {
+ return isEqual(this.pagerDutySettings, {
+ active: this.active,
+ webhookUrl: this.webhookUrl,
+ });
+ },
+ isSaveDisabled() {
+ return this.isFormUpdated || this.loading || this.resettingWebhook;
+ },
+ webhookUpdateAlertMsg() {
+ return this.webhookUpdateFailed
+ ? this.$options.i18n.webhookUrl.updateErrMsg
+ : this.$options.i18n.webhookUrl.updateSuccessMsg;
+ },
+ webhookUpdateAlertVariant() {
+ return this.webhookUpdateFailed ? 'danger' : 'success';
+ },
+ },
+ methods: {
+ updatePagerDutyIntegrationSettings() {
+ this.loading = true;
+
+ this.service.updateSettings(this.formData).catch(() => {
+ this.loading = false;
+ });
+ },
+ resetWebhookUrl() {
+ this.resettingWebhook = true;
+
+ this.service
+ .resetWebhookUrl()
+ .then(({ data: { pagerduty_webhook_url: url } }) => {
+ this.webhookUrl = url;
+ this.showAlert = true;
+ this.webhookUpdateFailed = false;
+ })
+ .catch(() => {
+ this.showAlert = true;
+ this.webhookUpdateFailed = true;
+ })
+ .finally(() => {
+ this.resettingWebhook = false;
+ });
+ },
+ },
+};
+</script>
+
+<template>
+ <div>
+ <gl-alert
+ v-if="showAlert"
+ class="gl-mb-3"
+ :variant="webhookUpdateAlertVariant"
+ @dismiss="showAlert = false"
+ >
+ {{ webhookUpdateAlertMsg }}
+ </gl-alert>
+
+ <p>{{ $options.i18n.introText }}</p>
+ <form ref="settingsForm" @submit.prevent="updatePagerDutyIntegrationSettings">
+ <gl-form-group class="col-8 col-md-9 gl-p-0">
+ <gl-toggle
+ id="active"
+ v-model="active"
+ :is-loading="loading"
+ :label="$options.i18n.activeToggle.label"
+ />
+ </gl-form-group>
+
+ <gl-form-group
+ class="col-8 col-md-9 gl-p-0"
+ :label="$options.i18n.webhookUrl.label"
+ label-for="url"
+ label-class="label-bold"
+ >
+ <gl-form-input-group id="url" data-testid="webhook-url" readonly :value="webhookUrl">
+ <template #append>
+ <clipboard-button
+ :text="webhookUrl"
+ :title="$options.i18n.webhookUrl.copyToClipboard"
+ />
+ </template>
+ </gl-form-input-group>
+
+ <div class="gl-text-gray-400 gl-pt-2">
+ <gl-sprintf :message="$options.i18n.webhookUrl.helpText">
+ <template #docsLink>
+ <gl-link
+ :href="$options.CONFIGURE_PAGERDUTY_WEBHOOK_DOCS_LINK"
+ target="_blank"
+ class="gl-display-inline-flex"
+ >
+ <span>{{ $options.i18n.webhookUrl.helpDocsLink }}</span>
+ <gl-icon name="external-link" />
+ </gl-link>
+ </template>
+ </gl-sprintf>
+ </div>
+ <gl-button
+ v-gl-modal.resetWebhookModal
+ class="gl-mt-3"
+ :disabled="loading"
+ :loading="resettingWebhook"
+ data-testid="webhook-reset-btn"
+ >
+ {{ $options.i18n.webhookUrl.resetWebhookUrl }}
+ </gl-button>
+ <gl-modal
+ modal-id="resetWebhookModal"
+ :title="$options.i18n.webhookUrl.resetWebhookUrl"
+ :ok-title="$options.i18n.webhookUrl.resetWebhookUrl"
+ ok-variant="danger"
+ @ok="resetWebhookUrl"
+ >
+ {{ $options.i18n.webhookUrl.restKeyInfo }}
+ </gl-modal>
+ </gl-form-group>
+
+ <gl-button
+ ref="submitBtn"
+ :disabled="isSaveDisabled"
+ variant="success"
+ type="submit"
+ class="js-no-auto-disable"
+ >
+ {{ $options.i18n.saveBtnLabel }}
+ </gl-button>
+ </form>
+ </div>
+</template>
diff --git a/app/assets/javascripts/incidents_settings/constants.js b/app/assets/javascripts/incidents_settings/constants.js
index bd6ee55ae42..b443c237f0f 100644
--- a/app/assets/javascripts/incidents_settings/constants.js
+++ b/app/assets/javascripts/incidents_settings/constants.js
@@ -1,5 +1,6 @@
import { __, s__ } from '~/locale';
+/* Integration tabs constants */
export const INTEGRATION_TABS_CONFIG = [
{
title: s__('IncidentSettings|Alert integration'),
@@ -8,8 +9,9 @@ export const INTEGRATION_TABS_CONFIG = [
},
{
title: s__('IncidentSettings|PagerDuty integration'),
- component: '',
- active: false,
+ component: 'PagerDutySettingsForm',
+ active: true,
+ featureFlag: 'pagerdutyWebhook',
},
{
title: s__('IncidentSettings|Grafana integration'),
@@ -21,12 +23,13 @@ export const INTEGRATION_TABS_CONFIG = [
export const I18N_INTEGRATION_TABS = {
headerText: s__('IncidentSettings|Incidents'),
expandBtnLabel: __('Expand'),
- saveBtnLabel: __('Save changes'),
subHeaderText: s__(
'IncidentSettings|Set up integrations with external tools to help better manage incidents.',
),
};
+/* Alerts integration settings constants */
+
export const I18N_ALERT_SETTINGS_FORM = {
saveBtnLabel: __('Save changes'),
introText: __('Action to take when receiving an alert. %{docsLink}'),
@@ -48,4 +51,33 @@ export const TAKING_INCIDENT_ACTION_DOCS_LINK =
export const ISSUE_TEMPLATES_DOCS_LINK =
'/help/user/project/description_templates#creating-issue-templates';
+/* PagerDuty integration settings constants */
+
+export const I18N_PAGERDUTY_SETTINGS_FORM = {
+ introText: s__(
+ 'PagerDutySettings|Setting up a webhook with PagerDuty will automatically create a GitLab issue for each PagerDuty incident.',
+ ),
+ activeToggle: {
+ label: s__('PagerDutySettings|Active'),
+ },
+ webhookUrl: {
+ label: s__('PagerDutySettings|Webhook URL'),
+ helpText: s__(
+ 'PagerDutySettings|Create a GitLab issue for each PagerDuty incident by %{docsLink}',
+ ),
+ helpDocsLink: s__('PagerDutySettings|configuring a webhook in PagerDuty'),
+ resetWebhookUrl: s__('PagerDutySettings|Reset webhook URL'),
+ copyToClipboard: __('Copy'),
+ updateErrMsg: s__('PagerDutySettings|Failed to update Webhook URL'),
+ updateSuccessMsg: s__('PagerDutySettings|Webhook URL update was successful'),
+ restKeyInfo: s__(
+ "PagerDutySettings|Resetting the webhook URL for this project will require updating this integration's settings in PagerDuty.",
+ ),
+ },
+ saveBtnLabel: __('Save changes'),
+};
+
+export const CONFIGURE_PAGERDUTY_WEBHOOK_DOCS_LINK = 'https://support.pagerduty.com/docs/webhooks';
+
+/* common constants */
export const ERROR_MSG = __('There was an error saving your changes.');
diff --git a/app/assets/javascripts/incidents_settings/incidents_settings_service.js b/app/assets/javascripts/incidents_settings/incidents_settings_service.js
new file mode 100644
index 00000000000..bd4f5bb8820
--- /dev/null
+++ b/app/assets/javascripts/incidents_settings/incidents_settings_service.js
@@ -0,0 +1,32 @@
+import axios from '~/lib/utils/axios_utils';
+import { refreshCurrentPage } from '~/lib/utils/url_utility';
+import createFlash from '~/flash';
+import { ERROR_MSG } from './constants';
+
+export default class IncidentsSettingsService {
+ constructor(settingsEndpoint, webhookUpdateEndpoint) {
+ this.settingsEndpoint = settingsEndpoint;
+ this.webhookUpdateEndpoint = webhookUpdateEndpoint;
+ }
+
+ updateSettings(data) {
+ return axios
+ .patch(this.settingsEndpoint, {
+ project: {
+ incident_management_setting_attributes: data,
+ },
+ })
+ .then(() => {
+ refreshCurrentPage();
+ })
+ .catch(({ response }) => {
+ const message = response?.data?.message || '';
+
+ createFlash(`${ERROR_MSG} ${message}`, 'alert');
+ });
+ }
+
+ resetWebhookUrl() {
+ return axios.post(this.webhookUpdateEndpoint);
+ }
+}
diff --git a/app/assets/javascripts/incidents_settings/index.js b/app/assets/javascripts/incidents_settings/index.js
index 25fed0d10de..80e7d07feca 100644
--- a/app/assets/javascripts/incidents_settings/index.js
+++ b/app/assets/javascripts/incidents_settings/index.js
@@ -1,6 +1,7 @@
import Vue from 'vue';
import { parseBoolean } from '~/lib/utils/common_utils';
import SettingsTabs from './components/incidents_settings_tabs.vue';
+import IncidentsSettingsService from './incidents_settings_service';
export default () => {
const el = document.querySelector('.js-incidents-settings');
@@ -10,19 +11,33 @@ export default () => {
}
const {
- dataset: { operationsSettingsEndpoint, templates, createIssue, issueTemplateKey, sendEmail },
+ dataset: {
+ operationsSettingsEndpoint,
+ templates,
+ createIssue,
+ issueTemplateKey,
+ sendEmail,
+ pagerdutyActive,
+ pagerdutyWebhookUrl,
+ pagerdutyResetKeyPath,
+ },
} = el;
+ const service = new IncidentsSettingsService(operationsSettingsEndpoint, pagerdutyResetKeyPath);
return new Vue({
el,
provide: {
- operationsSettingsEndpoint,
+ service,
alertSettings: {
templates: JSON.parse(templates),
createIssue: parseBoolean(createIssue),
issueTemplateKey,
sendEmail: parseBoolean(sendEmail),
},
+ pagerDutySettings: {
+ active: parseBoolean(pagerdutyActive),
+ webhookUrl: pagerdutyWebhookUrl,
+ },
},
render(createElement) {
return createElement(SettingsTabs);