diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2021-01-22 06:09:04 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2021-01-22 06:09:04 +0300 |
commit | 6ef43e2aa1cad78daaed93eff1aebd6a4e7e18a6 (patch) | |
tree | b0f41c623936fd3b187aa302403d9bba10369b41 /app/assets/javascripts/alerts_settings | |
parent | 21796f414cf380088217c1a76a4c3ba5d7b6fdd1 (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/assets/javascripts/alerts_settings')
6 files changed, 199 insertions, 129 deletions
diff --git a/app/assets/javascripts/alerts_settings/components/alert_mapping_builder.vue b/app/assets/javascripts/alerts_settings/components/alert_mapping_builder.vue index c52e9f5c264..8a481db5cb6 100644 --- a/app/assets/javascripts/alerts_settings/components/alert_mapping_builder.vue +++ b/app/assets/javascripts/alerts_settings/components/alert_mapping_builder.vue @@ -13,6 +13,12 @@ import { s__, __ } from '~/locale'; // data format is defined and will be the same as mocked (maybe with some minor changes) // feature rollout plan - https://gitlab.com/gitlab-org/gitlab/-/issues/262707#note_442529171 import gitlabFieldsMock from './mocks/gitlabFields.json'; +import { capitalizeFirstCharacter } from '~/lib/utils/text_utility'; +import { + getMappingData, + getPayloadFields, + transformForSave, +} from '../utils/mapping_transformations'; export const i18n = { columns: { @@ -46,12 +52,12 @@ export default { }, }, props: { - payloadFields: { + parsedPayload: { type: Array, required: false, default: () => [], }, - mapping: { + savedMapping: { type: Array, required: false, default: () => [], @@ -63,27 +69,11 @@ export default { }; }, computed: { + payloadFields() { + return getPayloadFields(this.parsedPayload); + }, mappingData() { - return this.gitlabFields.map((gitlabField) => { - const mappingFields = this.payloadFields.filter(({ type }) => - type.some((t) => gitlabField.compatibleTypes.includes(t)), - ); - - const foundMapping = this.mapping.find( - ({ alertFieldName }) => alertFieldName === gitlabField.name, - ); - - const { fallbackAlertPaths, payloadAlertPaths } = foundMapping || {}; - - return { - mapping: payloadAlertPaths, - fallback: fallbackAlertPaths, - searchTerm: '', - fallbackSearchTerm: '', - mappingFields, - ...gitlabField, - }; - }); + return getMappingData(this.gitlabFields, this.payloadFields, this.savedMapping); }, }, methods: { @@ -91,6 +81,7 @@ export default { const fieldIndex = this.gitlabFields.findIndex((field) => field.name === gitlabKey); const updatedField = { ...this.gitlabFields[fieldIndex], ...{ [valueKey]: mappingKey } }; Vue.set(this.gitlabFields, fieldIndex, updatedField); + this.$emit('onMappingUpdate', transformForSave(this.mappingData)); }, setSearchTerm(search = '', searchFieldKey, gitlabKey) { const fieldIndex = this.gitlabFields.findIndex((field) => field.name === gitlabKey); @@ -99,7 +90,6 @@ export default { }, filterFields(searchTerm = '', fields) { const search = searchTerm.toLowerCase(); - return fields.filter((field) => field.label.toLowerCase().includes(search)); }, isSelected(fieldValue, mapping) { @@ -112,7 +102,9 @@ export default { ); }, getFieldValue({ label, type }) { - return `${label} (${type.join(__(' or '))})`; + const types = type.map((t) => capitalizeFirstCharacter(t.toLowerCase())).join(__(' or ')); + + return `${label} (${types})`; }, noResults(searchTerm, fields) { return !this.filterFields(searchTerm, fields).length; 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 1ae7f826ce6..3280e0424aa 100644 --- a/app/assets/javascripts/alerts_settings/components/alerts_settings_form.vue +++ b/app/assets/javascripts/alerts_settings/components/alerts_settings_form.vue @@ -152,6 +152,7 @@ export default { }, resetSamplePayloadConfirmed: false, customMapping: null, + mapping: [], parsingPayload: false, currentIntegration: null, }; @@ -199,10 +200,10 @@ export default { this.selectedIntegration === typeSet.http ); }, - mappingBuilderFields() { + parsedSamplePayload() { return this.customMapping?.samplePayload?.payloadAlerFields?.nodes; }, - mappingBuilderMapping() { + savedMapping() { return this.customMapping?.storedMapping?.nodes; }, hasSamplePayload() { @@ -255,9 +256,20 @@ export default { }, submit() { const { name, apiUrl } = this.integrationForm; + const customMappingVariables = this.glFeatures.multipleHttpIntegrationsCustomMapping + ? { + payloadAttributeMappings: this.mapping, + payloadExample: this.integrationTestPayload.json, + } + : {}; + const variables = this.selectedIntegration === typeSet.http - ? { name, active: this.active } + ? { + name, + active: this.active, + ...customMappingVariables, + } : { apiUrl, active: this.active }; const integrationPayload = { type: this.selectedIntegration, variables }; @@ -336,6 +348,9 @@ export default { this.integrationTestPayload.json = res?.samplePayload.body; }); }, + updateMapping(mapping) { + this.mapping = mapping; + }, }, }; </script> @@ -541,8 +556,9 @@ export default { > <span>{{ $options.i18n.integrationFormSteps.step5.intro }}</span> <mapping-builder - :payload-fields="mappingBuilderFields" - :mapping="mappingBuilderMapping" + :parsed-payload="parsedSamplePayload" + :saved-mapping="savedMapping" + @onMappingUpdate="updateMapping" /> </gl-form-group> </div> diff --git a/app/assets/javascripts/alerts_settings/components/mocks/gitlabFields.json b/app/assets/javascripts/alerts_settings/components/mocks/gitlabFields.json index ac559a30eda..e4d0e92a6f8 100644 --- a/app/assets/javascripts/alerts_settings/components/mocks/gitlabFields.json +++ b/app/assets/javascripts/alerts_settings/components/mocks/gitlabFields.json @@ -1,112 +1,123 @@ [ { - "name": "title", + "name": "TITLE", "label": "Title", "type": [ - "String" + "STRING" ], "compatibleTypes": [ - "String", - "Number", - "DateTime" + "STRING", + "NUMBER", + "DATETIME" ], "numberOfFallbacks": 1 }, { - "name": "description", + "name": "DESCRIPTION", "label": "Description", "type": [ - "String" + "STRING" ], "compatibleTypes": [ - "String", - "Number", - "DateTime" + "STRING", + "NUMBER", + "DATETIME" ] }, { - "name": "startTime", + "name": "START_TIME", "label": "Start time", "type": [ - "DateTime" + "DATETIME" ], "compatibleTypes": [ - "Number", - "DateTime" + "NUMBER", + "DATETIME" ] }, { - "name": "service", + "name": "END_TIME", + "label": "End time", + "type": [ + "DATETIME" + ], + "compatibleTypes": [ + "NUMBER", + "DATETIME" + ] + }, + { + "name": "SERVICE", "label": "Service", "type": [ - "String" + "STRING" ], "compatibleTypes": [ - "String", - "Number", - "DateTime" + "STRING", + "NUMBER", + "DATETIME" ] }, { - "name": "monitoringTool", + "name": "MONITORING_TOOL", "label": "Monitoring tool", "type": [ - "String" + "STRING" ], "compatibleTypes": [ - "String", - "Number", - "DateTime" + "STRING", + "NUMBER", + "DATETIME" ] }, { - "name": "hosts", + "name": "HOSTS", "label": "Hosts", "type": [ - "String", - "Array" + "STRING", + "ARRAY" ], "compatibleTypes": [ - "String", - "Array", - "Number", - "DateTime" + "STRING", + "ARRAY", + "NUMBER", + "DATETIME" ] }, { - "name": "severity", + "name": "SEVERITY", "label": "Severity", "type": [ - "String" + "STRING" ], "compatibleTypes": [ - "String", - "Number", - "DateTime" + "STRING", + "NUMBER", + "DATETIME" ] }, { - "name": "fingerprint", + "name": "FINGERPRINT", "label": "Fingerprint", "type": [ - "String" + "STRING" ], "compatibleTypes": [ - "String", - "Number", - "DateTime" + "STRING", + "NUMBER", + "DATETIME" ] }, { - "name": "environment", + "name": "GITLAB_ENVIRONMENT_NAME", "label": "Environment", "type": [ - "String" + "STRING" ], "compatibleTypes": [ - "String", - "Number", - "DateTime" + "STRING", + "NUMBER", + "DATETIME" ] } ] diff --git a/app/assets/javascripts/alerts_settings/components/mocks/parsedMapping.json b/app/assets/javascripts/alerts_settings/components/mocks/parsedMapping.json index 5326678155d..c1de0d6f0e0 100644 --- a/app/assets/javascripts/alerts_settings/components/mocks/parsedMapping.json +++ b/app/assets/javascripts/alerts_settings/components/mocks/parsedMapping.json @@ -4,95 +4,69 @@ "payloadAlerFields": { "nodes": [ { - "name": "dashboardId", + "path": ["dashboardId"], "label": "Dashboard Id", - "type": [ - "Number" - ] + "type": "STRING" }, { - "name": "evalMatches", + "path": ["evalMatches"], "label": "Eval Matches", - "type": [ - "Array" - ] + "type": "ARRAY" }, { - "name": "createdAt", + "path": ["createdAt"], "label": "Created At", - "type": [ - "DateTime" - ] + "type": "DATETIME" }, { - "name": "imageUrl", + "path": ["imageUrl"], "label": "Image Url", - "type": [ - "String" - ] + "type": "STRING" }, { - "name": "message", + "path": ["message"], "label": "Message", - "type": [ - "String" - ] + "type": "STRING" }, { - "name": "orgId", + "path": ["orgId"], "label": "Org Id", - "type": [ - "Number" - ] + "type": "STRING" }, { - "name": "panelId", + "path": ["panelId"], "label": "Panel Id", - "type": [ - "String" - ] + "type": "STRING" }, { - "name": "ruleId", + "path": ["ruleId"], "label": "Rule Id", - "type": [ - "Number" - ] + "type": "STRING" }, { - "name": "ruleName", + "path": ["ruleName"], "label": "Rule Name", - "type": [ - "String" - ] + "type": "STRING" }, { - "name": "ruleUrl", + "path": ["ruleUrl"], "label": "Rule Url", - "type": [ - "String" - ] + "type": "STRING" }, { - "name": "state", + "path": ["state"], "label": "State", - "type": [ - "String" - ] + "type": "STRING" }, { - "name": "title", + "path": ["title"], "label": "Title", - "type": [ - "String" - ] + "type": "STRING" }, { - "name": "tags", + "path": ["tags", "tag"], "label": "Tags", - "type": [ - "Object" - ] + "type": "STRING" } ] } diff --git a/app/assets/javascripts/alerts_settings/graphql/mutations/create_http_integration.mutation.graphql b/app/assets/javascripts/alerts_settings/graphql/mutations/create_http_integration.mutation.graphql index d1dacbad40a..f3fc10b4bd4 100644 --- a/app/assets/javascripts/alerts_settings/graphql/mutations/create_http_integration.mutation.graphql +++ b/app/assets/javascripts/alerts_settings/graphql/mutations/create_http_integration.mutation.graphql @@ -1,7 +1,21 @@ #import "../fragments/integration_item.fragment.graphql" -mutation createHttpIntegration($projectPath: ID!, $name: String!, $active: Boolean!) { - httpIntegrationCreate(input: { projectPath: $projectPath, name: $name, active: $active }) { +mutation createHttpIntegration( + $projectPath: ID! + $name: String! + $active: Boolean! + $payloadExample: JsonString + $payloadAttributeMappings: [AlertManagementPayloadAlertFieldInput!] +) { + httpIntegrationCreate( + input: { + projectPath: $projectPath + name: $name + active: $active + payloadExample: $payloadExample + payloadAttributeMappings: $payloadAttributeMappings + } + ) { errors integration { ...IntegrationItem diff --git a/app/assets/javascripts/alerts_settings/utils/mapping_transformations.js b/app/assets/javascripts/alerts_settings/utils/mapping_transformations.js new file mode 100644 index 00000000000..a7e43c93fbf --- /dev/null +++ b/app/assets/javascripts/alerts_settings/utils/mapping_transformations.js @@ -0,0 +1,63 @@ +/** + * Given data for GitLab alert fields, parsed payload fields data and previously stored mapping (if any) + * creates an object in a form convenient to build UI && interact with it + * @param {Object} gitlabFields - structure describing GitLab alert fields + * @param {Object} payloadFields - parsed from sample JSON sample alert fields + * @param {Object} savedMapping - GitLab fields to parsed fields mapping + * + * @return {Object} mapping data for UI mapping builder + */ +export const getMappingData = (gitlabFields, payloadFields, savedMapping) => { + return gitlabFields.map((gitlabField) => { + // find fields from payload that match gitlab alert field by type + const mappingFields = payloadFields.filter(({ type }) => + gitlabField.compatibleTypes.includes(type), + ); + + // find the mapping that was previously stored + const foundMapping = savedMapping.find(({ fieldName }) => fieldName === gitlabField.name); + + const { fallbackAlertPaths, payloadAlertPaths } = foundMapping || {}; + + return { + mapping: payloadAlertPaths, + fallback: fallbackAlertPaths, + searchTerm: '', + fallbackSearchTerm: '', + mappingFields, + ...gitlabField, + }; + }); +}; + +/** + * Based on mapping data configured by the user creates an object in a format suitable for save on BE + * @param {Object} mappingData - structure describing mapping between GitLab fields and parsed payload fields + * + * @return {Object} mapping data to send to BE + */ +export const transformForSave = (mappingData) => { + return mappingData.reduce((acc, field) => { + const mapped = field.mappingFields.find(({ name }) => name === field.mapping); + if (mapped) { + const { path, type, label } = mapped; + acc.push({ + fieldName: field.name, + path, + type, + label, + }); + } + return acc; + }, []); +}; + +/** + * Adds `name` prop to each provided by BE parsed payload field + * @param {Object} payload - parsed sample payload + * + * @return {Object} same as input with an extra `name` property which basically serves as a key to make a match + */ +export const getPayloadFields = (payload) => { + return payload.map((field) => ({ ...field, name: field.path.join('_') })); +}; |