Commit 1ece0011 authored by David O'Regan's avatar David O'Regan

Merge branch '280851-prettify-mapping-builder' into 'master'

Prettify mapping builder form

See merge request gitlab-org/gitlab!47512
parents 27b3aaa9 c6819c43
......@@ -124,14 +124,14 @@ export default {
<template>
<div class="gl-display-table gl-w-full gl-mt-5">
<div class="gl-display-table-row">
<h5 class="gl-display-table-cell gl-py-3 gl-pr-3">
<h5 id="gitlabFieldsHeader" class="gl-display-table-cell gl-py-3 gl-pr-3">
{{ $options.i18n.columns.gitlabKeyTitle }}
</h5>
<h5 class="gl-display-table-cell gl-py-3 gl-pr-3">&nbsp;</h5>
<h5 class="gl-display-table-cell gl-py-3 gl-pr-3">
<h5 id="parsedFieldsHeader" class="gl-display-table-cell gl-py-3 gl-pr-3">
{{ $options.i18n.columns.payloadKeyTitle }}
</h5>
<h5 class="gl-display-table-cell gl-py-3 gl-pr-3">
<h5 id="fallbackFieldsHeader" class="gl-display-table-cell gl-py-3 gl-pr-3">
{{ $options.i18n.columns.fallbackKeyTitle }}
<gl-icon
v-gl-tooltip
......@@ -144,22 +144,24 @@ export default {
<div v-for="gitlabField in mappingData" :key="gitlabField.name" class="gl-display-table-row">
<div class="gl-display-table-cell gl-py-3 gl-pr-3 w-30p">
<gl-form-input
aria-labelledby="gitlabFieldsHeader"
disabled
:value="getFieldValue(gitlabField)"
class="gl-bg-transparent! gl-text-gray-900!"
/>
</div>
<div class="gl-display-table-cell gl-py-3 gl-pr-3">
<div class="right-arrow">
<div class="right-arrow gl-vertical-align-middle gl-mt-n1">
<i class="right-arrow-head"></i>
</div>
</div>
<div class="gl-display-table-cell gl-py-3 gl-pr-3 w-30p">
<gl-dropdown
:disabled="!gitlabField.mappingFields.length"
aria-labelledby="parsedFieldsHeader"
:text="selectedValue(gitlabField.mapping)"
class="gl-w-full"
class="gl-w-full gl-vertical-align-baseline!"
:header-text="$options.i18n.selectMappingKey"
>
<gl-search-box-by-type @input="setSearchTerm($event, 'searchTerm', gitlabField.name)" />
......@@ -181,8 +183,10 @@ export default {
<div class="gl-display-table-cell gl-py-3 w-30p">
<gl-dropdown
v-if="Boolean(gitlabField.numberOfFallbacks)"
:disabled="!gitlabField.mappingFields.length"
aria-labelledby="fallbackFieldsHeader"
:text="selectedValue(gitlabField.fallback)"
class="gl-w-full"
class="gl-w-full gl-vertical-align-baseline!"
:header-text="$options.i18n.selectMappingKey"
>
<gl-search-box-by-type
......
......@@ -73,11 +73,14 @@ export default {
resetOk: s__('AlertSettings|Proceed with editing'),
editPayload: s__('AlertSettings|Edit payload'),
submitPayload: s__('AlertSettings|Submit payload'),
payloadParsedSucessMsg: s__(
'AlertSettings|Sample payload has been parsed. You can now map the fields.',
),
},
step5: {
label: s__('AlertSettings|5. Map fields (optional)'),
intro: s__(
'AlertSettings|The default GitLab alert keys are listed below. In the event an exact match could be found in the sample payload provided, that key will be mapped automatically. In all other cases, please define which payload key should map to the specified GitLab key. Any payload keys not shown in this list will not display in the alert list, but will display on the alert details page.',
"AlertSettings|If you've provided a sample alert payload, you can create a custom mapping for your endpoint. The default GitLab alert keys are listed below. Please define which payload key should map to the specified GitLab key.",
),
},
prometheusFormUrl: {
......@@ -211,10 +214,10 @@ export default {
);
},
mappingBuilderFields() {
return this.customMapping?.samplePayload?.payloadAlerFields?.nodes || [];
return this.customMapping?.samplePayload?.payloadAlerFields?.nodes;
},
mappingBuilderMapping() {
return this.customMapping?.storedMapping?.nodes || [];
return this.customMapping?.storedMapping?.nodes;
},
hasSamplePayload() {
return Boolean(this.customMapping?.samplePayload);
......@@ -352,6 +355,8 @@ export default {
this.customMapping = res;
this.integrationTestPayload.json = res?.samplePayload.body;
this.resetSamplePayloadConfirmed = false;
this.$toast.show(this.$options.i18n.integrationFormSteps.step4.payloadParsedSucessMsg);
})
.finally(() => {
this.parsingPayload = false;
......@@ -528,6 +533,7 @@ export default {
id="test-integration"
:label="$options.i18n.integrationFormSteps.step4.label"
label-for="test-integration"
:class="{ 'gl-mb-0!': showMappingBuilder }"
:invalid-feedback="integrationTestPayload.error"
>
<alert-settings-form-help-block
......@@ -547,41 +553,44 @@ export default {
max-rows="10"
@input="validateJson"
/>
</gl-form-group>
<template v-if="showMappingBuilder">
<gl-button
v-if="canEditPayload"
v-gl-modal.resetPayloadModal
:disabled="!active"
class="gl-mt-3"
>
{{ $options.i18n.integrationFormSteps.step4.editPayload }}
</gl-button>
<template v-if="showMappingBuilder">
<gl-button
v-if="canEditPayload"
v-gl-modal.resetPayloadModal
data-testid="payload-action-btn"
:disabled="!active"
class="gl-mt-3"
>
{{ $options.i18n.integrationFormSteps.step4.editPayload }}
</gl-button>
<gl-button
v-else
:disabled="!active"
:loading="parsingPayload"
class="gl-mt-3"
@click="parseMapping"
>
{{ $options.i18n.integrationFormSteps.step4.submitPayload }}
</gl-button>
<gl-modal
modal-id="resetPayloadModal"
:title="$options.i18n.integrationFormSteps.step4.resetHeader"
:ok-title="$options.i18n.integrationFormSteps.step4.resetOk"
ok-variant="danger"
@ok="resetSamplePayloadConfirmed = true"
>
{{ $options.i18n.integrationFormSteps.step4.resetBody }}
</gl-modal>
</template>
</gl-form-group>
<gl-button
v-else
data-testid="payload-action-btn"
:class="{ 'gl-mt-3': integrationTestPayload.error }"
:disabled="!active"
:loading="parsingPayload"
@click="parseMapping"
>
{{ $options.i18n.integrationFormSteps.step4.submitPayload }}
</gl-button>
<gl-modal
modal-id="resetPayloadModal"
:title="$options.i18n.integrationFormSteps.step4.resetHeader"
:ok-title="$options.i18n.integrationFormSteps.step4.resetOk"
ok-variant="danger"
@ok="resetSamplePayloadConfirmed = true"
>
{{ $options.i18n.integrationFormSteps.step4.resetBody }}
</gl-modal>
</template>
<gl-form-group
v-if="showMappingBuilder"
id="mapping-builder"
class="gl-mt-5"
:label="$options.i18n.integrationFormSteps.step5.label"
label-for="mapping-builder"
>
......
import Vue from 'vue';
import { GlToast } from '@gitlab/ui';
import { parseBoolean } from '~/lib/utils/common_utils';
import AlertSettingsWrapper from './components/alerts_settings_wrapper.vue';
import apolloProvider from './graphql';
......@@ -8,6 +9,7 @@ apolloProvider.clients.defaultClient.cache.writeData({
currentIntegration: null,
},
});
Vue.use(GlToast);
export default el => {
if (!el) {
......
......@@ -2574,6 +2574,9 @@ msgstr ""
msgid "AlertSettings|If you edit the payload, the stored mapping will be reset, and you'll need to re-map the fields."
msgstr ""
msgid "AlertSettings|If you've provided a sample alert payload, you can create a custom mapping for your endpoint. The default GitLab alert keys are listed below. Please define which payload key should map to the specified GitLab key."
msgstr ""
msgid "AlertSettings|In free versions of GitLab, only one integration for each type can be added. %{linkStart}Upgrade your subscription%{linkEnd} to add additional integrations."
msgstr ""
......@@ -2613,6 +2616,9 @@ msgstr ""
msgid "AlertSettings|Review your external service's documentation to learn where to provide this information to your external service, and the %{linkStart}GitLab documentation%{linkEnd} to learn more about configuring your endpoint."
msgstr ""
msgid "AlertSettings|Sample payload has been parsed. You can now map the fields."
msgstr ""
msgid "AlertSettings|Save and test payload"
msgstr ""
......@@ -2634,9 +2640,6 @@ msgstr ""
msgid "AlertSettings|Test failed. Do you still want to save your changes anyway?"
msgstr ""
msgid "AlertSettings|The default GitLab alert keys are listed below. In the event an exact match could be found in the sample payload provided, that key will be mapped automatically. In all other cases, please define which payload key should map to the specified GitLab key. Any payload keys not shown in this list will not display in the alert list, but will display on the alert details page."
msgstr ""
msgid "AlertSettings|There was an error updating the alert settings."
msgstr ""
......
......@@ -80,10 +80,10 @@ exports[`AlertsSettingsFormNew with default values renders the initial template
<!---->
<!---->
<!---->
<!---->
</div>
</div>
<!---->
<!---->
</div>
<div class=\\"gl-display-flex gl-justify-content-end\\"><button type=\\"reset\\" class=\\"btn gl-mr-3 js-no-auto-disable btn-default btn-md gl-button\\">
<!---->
......
......@@ -6,14 +6,15 @@ import {
GlFormInput,
GlToggle,
GlFormTextarea,
GlButton,
} from '@gitlab/ui';
import waitForPromises from 'helpers/wait_for_promises';
import AlertsSettingsForm from '~/alerts_settings/components/alerts_settings_form_new.vue';
import { defaultAlertSettingsConfig } from './util';
import { typeSet } from '~/alerts_settings/constants';
describe('AlertsSettingsFormNew', () => {
let wrapper;
const mockToastShow = jest.fn();
const createComponent = ({
data = {},
......@@ -34,6 +35,11 @@ describe('AlertsSettingsFormNew', () => {
glFeatures: { multipleHttpIntegrationsCustomMapping },
...defaultAlertSettingsConfig,
},
mocks: {
$toast: {
show: mockToastShow,
},
},
});
};
......@@ -49,6 +55,7 @@ describe('AlertsSettingsFormNew', () => {
wrapper.find(`[data-testid="multi-integrations-not-supported"]`);
const findJsonTestSubmit = () => wrapper.find(`[data-testid="integration-test-and-submit"]`);
const findJsonTextArea = () => wrapper.find(`[id = "test-payload"]`);
const findActionBtn = () => wrapper.find(`[data-testid="payload-action-btn"]`);
afterEach(() => {
if (wrapper) {
......@@ -307,12 +314,28 @@ describe('AlertsSettingsFormNew', () => {
resetSamplePayloadConfirmed,
});
await wrapper.vm.$nextTick();
expect(
findTestPayloadSection()
.find(GlButton)
.text(),
).toBe(caption);
expect(findActionBtn().text()).toBe(caption);
});
});
});
describe('Parsing payload', () => {
it('displays a toast message on successful parse', async () => {
jest.useFakeTimers();
wrapper.setData({
selectedIntegration: typeSet.http,
customMapping: { samplePayload: false },
});
await wrapper.vm.$nextTick();
findActionBtn().vm.$emit('click');
jest.advanceTimersByTime(1000);
await waitForPromises();
expect(mockToastShow).toHaveBeenCalledWith(
'Sample payload has been parsed. You can now map the fields.',
);
});
});
});
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment