Commit 14d48f92 authored by Olena Horal-Koretska's avatar Olena Horal-Koretska Committed by Scott Hampton

Add label and tooltip for nested fields

Formats how labels are displayed when fields are nested
in alerts http integration custom mapping tool.

In the mapping tool nested fields are displayed with
`...` before the field's name and have a tooltip that
shows the field path in the JSON.
parent 7d524985
...@@ -12,7 +12,11 @@ import Vue from 'vue'; ...@@ -12,7 +12,11 @@ import Vue from 'vue';
import { capitalizeFirstCharacter } from '~/lib/utils/text_utility'; import { capitalizeFirstCharacter } from '~/lib/utils/text_utility';
import { s__, __ } from '~/locale'; import { s__, __ } from '~/locale';
import { mappingFields } from '../constants'; import { mappingFields } from '../constants';
import { getMappingData, transformForSave } from '../utils/mapping_transformations'; import {
getMappingData,
transformForSave,
setFieldsLabels,
} from '../utils/mapping_transformations';
export const i18n = { export const i18n = {
columns: { columns: {
...@@ -72,11 +76,14 @@ export default { ...@@ -72,11 +76,14 @@ export default {
}, },
computed: { computed: {
mappingData() { mappingData() {
return getMappingData(this.gitlabFields, this.parsedPayload, this.savedMapping); return getMappingData(this.gitlabFields, this.formattedParsedPayload, this.savedMapping);
}, },
hasFallbackColumn() { hasFallbackColumn() {
return this.gitlabFields.some(({ numberOfFallbacks }) => Boolean(numberOfFallbacks)); return this.gitlabFields.some(({ numberOfFallbacks }) => Boolean(numberOfFallbacks));
}, },
formattedParsedPayload() {
return setFieldsLabels(this.parsedPayload);
},
}, },
methods: { methods: {
setMapping(gitlabKey, mappingKey, valueKey = mappingFields.mapping) { setMapping(gitlabKey, mappingKey, valueKey = mappingFields.mapping) {
...@@ -92,14 +99,16 @@ export default { ...@@ -92,14 +99,16 @@ export default {
}, },
filterFields(searchTerm = '', fields) { filterFields(searchTerm = '', fields) {
const search = searchTerm.toLowerCase(); const search = searchTerm.toLowerCase();
return fields.filter((field) => field.label.toLowerCase().includes(search)); return fields.filter((field) =>
field.displayLabel.replace('...', '').toLowerCase().includes(search),
);
}, },
isSelected(fieldValue, mapping) { isSelected(fieldValue, mapping) {
return isEqual(fieldValue, mapping); return isEqual(fieldValue, mapping);
}, },
selectedValue(mapping) { selectedValue(mapping) {
return ( return (
this.parsedPayload.find((item) => isEqual(item.path, mapping))?.label || this.formattedParsedPayload.find((item) => isEqual(item.path, mapping))?.displayLabel ||
this.$options.i18n.makeSelection this.$options.i18n.makeSelection
); );
}, },
...@@ -167,11 +176,13 @@ export default { ...@@ -167,11 +176,13 @@ export default {
<gl-dropdown-item <gl-dropdown-item
v-for="mappingField in filterFields(gitlabField.searchTerm, gitlabField.mappingFields)" v-for="mappingField in filterFields(gitlabField.searchTerm, gitlabField.mappingFields)"
:key="`${mappingField.path}__mapping`" :key="`${mappingField.path}__mapping`"
v-gl-tooltip
:is-checked="isSelected(gitlabField.mapping, mappingField.path)" :is-checked="isSelected(gitlabField.mapping, mappingField.path)"
is-check-item is-check-item
:title="mappingField.tooltip"
@click="setMapping(gitlabField.name, mappingField.path)" @click="setMapping(gitlabField.name, mappingField.path)"
> >
{{ mappingField.label }} {{ mappingField.displayLabel }}
</gl-dropdown-item> </gl-dropdown-item>
<gl-dropdown-item v-if="noResults(gitlabField.searchTerm, gitlabField.mappingFields)"> <gl-dropdown-item v-if="noResults(gitlabField.searchTerm, gitlabField.mappingFields)">
{{ $options.i18n.noResults }} {{ $options.i18n.noResults }}
...@@ -197,13 +208,15 @@ export default { ...@@ -197,13 +208,15 @@ export default {
gitlabField.mappingFields, gitlabField.mappingFields,
)" )"
:key="`${mappingField.path}__fallback`" :key="`${mappingField.path}__fallback`"
v-gl-tooltip
:is-checked="isSelected(gitlabField.fallback, mappingField.path)" :is-checked="isSelected(gitlabField.fallback, mappingField.path)"
is-check-item is-check-item
:title="mappingField.tooltip"
@click=" @click="
setMapping(gitlabField.name, mappingField.path, $options.mappingFields.fallback) setMapping(gitlabField.name, mappingField.path, $options.mappingFields.fallback)
" "
> >
{{ mappingField.label }} {{ mappingField.displayLabel }}
</gl-dropdown-item> </gl-dropdown-item>
<gl-dropdown-item <gl-dropdown-item
v-if="noResults(gitlabField.fallbackSearchTerm, gitlabField.mappingFields)" v-if="noResults(gitlabField.fallbackSearchTerm, gitlabField.mappingFields)"
......
import { isEqual } from 'lodash'; import { isEqual } from 'lodash';
import { capitalizeFirstCharacter } from '~/lib/utils/text_utility';
/** /**
* Given data for GitLab alert fields, parsed payload fields data and previously stored mapping (if any) * 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 * creates an object in a form convenient to build UI && interact with it
...@@ -32,6 +34,26 @@ export const getMappingData = (gitlabFields, payloadFields, savedMapping) => { ...@@ -32,6 +34,26 @@ export const getMappingData = (gitlabFields, payloadFields, savedMapping) => {
}); });
}; };
export const setFieldsLabels = (fields) => {
return fields.map((field) => {
const { label } = field;
let displayLabel;
let tooltip;
const labels = label.split('/');
if (labels.length > 1) {
tooltip = labels.join('.');
displayLabel = `...${capitalizeFirstCharacter(labels.pop())}`;
} else {
displayLabel = capitalizeFirstCharacter(label);
}
return {
...field,
displayLabel,
tooltip,
};
});
};
/** /**
* Based on mapping data configured by the user creates an object in a format suitable for save on BE * 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 * @param {Object} mappingData - structure describing mapping between GitLab fields and parsed payload fields
......
---
title: Add display label and tooltip for nested fields in mapping builder
merge_request: 59793
author:
type: changed
import { getMappingData, transformForSave } from '~/alerts_settings/utils/mapping_transformations'; import {
getMappingData,
setFieldsLabels,
transformForSave,
} from '~/alerts_settings/utils/mapping_transformations';
import alertFields from '../mocks/alert_fields.json'; import alertFields from '../mocks/alert_fields.json';
import parsedMapping from '../mocks/parsed_mapping.json'; import parsedMapping from '../mocks/parsed_mapping.json';
...@@ -64,4 +68,33 @@ describe('Mapping Transformation Utilities', () => { ...@@ -64,4 +68,33 @@ describe('Mapping Transformation Utilities', () => {
expect(result).toEqual([]); expect(result).toEqual([]);
}); });
}); });
describe('setFieldsLabels', () => {
const nonNestedFields = [{ label: 'title' }];
const nonNestedFieldsResult = { displayLabel: 'Title', tooltip: undefined };
const nestedFields = [
{
label: 'field/subfield',
},
];
const nestedFieldsResult = { displayLabel: '...Subfield', tooltip: 'field.subfield' };
const nestedArrayFields = [
{
label: 'fields[1]/subfield',
},
];
const nestedArrayFieldsResult = { displayLabel: '...Subfield', tooltip: 'fields[1].subfield' };
it.each`
type | fields | result
${'not nested field'} | ${nonNestedFields} | ${nonNestedFieldsResult}
${'nested field'} | ${nestedFields} | ${nestedFieldsResult}
${'nested inside array'} | ${nestedArrayFields} | ${nestedArrayFieldsResult}
`('adds correct displayLabel and tooltip for $type', ({ fields, result }) => {
expect(setFieldsLabels(fields)[0]).toMatchObject(result);
});
});
}); });
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