[APM][Settings][Custom links] Default field filter option always present (#190309)

## Summary

Closes https://github.com/elastic/kibana/issues/189987

It was discovered that when users manually select the default option
(`Select field`) for the field input, the option would disappear in some
scenarios, causing other input values to change automatically. This
issue occurred specifically when the default option was selected
manually by the user.

This happens because as options are selected by the user, they are
removed from the selection list to prevent duplicates.

With the fix
([commit](985cdc5317))
we are never removing the default option from the list.

|Scenario|Before|After|
|-|-|-|
|Two filters|<img
src="https://github.com/user-attachments/assets/2268b92f-e9be-4c06-aa74-5f2f003117d5"
width="280"> |<img
src="https://github.com/user-attachments/assets/278a4860-f691-4121-acb5-f61a76147b56"
width="280">|
|More than two filters|<img
src="https://github.com/user-attachments/assets/23aeb355-4932-452d-a6a8-ed1a2ccba428"
width="280">|<img
src="https://github.com/user-attachments/assets/30d7978e-1ec0-4736-8163-64790831bba0"
width="280">|
This commit is contained in:
Irene Blanco 2024-08-13 09:19:50 +02:00 committed by GitHub
parent 8b2e05b09e
commit aaf35ce945
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 57 additions and 44 deletions

View file

@ -7,76 +7,87 @@
import { getSelectOptions, replaceTemplateVariables } from './helper';
import { Transaction } from '../../../../../../typings/es_schemas/ui/transaction';
import { Filter } from '../../../../../../common/custom_link/custom_link_types';
describe('Custom link helper', () => {
describe('getSelectOptions', () => {
const options = {
default: { value: 'DEFAULT', text: 'Select field...' },
serviceName: { value: 'service.name', text: 'service.name' },
serviceEnvironment: { value: 'service.environment', text: 'service.environment' },
transactionType: { value: 'transaction.type', text: 'transaction.type' },
transactionName: { value: 'transaction.name', text: 'transaction.name' },
};
const filters: Record<string, Filter> = {
empty: { key: '', value: '' },
default: { key: 'DEFAULT' as Filter['key'], value: '' },
serviceName: { key: 'service.name', value: 'foo' },
serviceEnvironment: { key: 'service.environment', value: 'foo' },
transactionType: { key: 'transaction.type', value: 'foo' },
transactionName: { key: 'transaction.name', value: 'foo' },
};
it('returns all available options when no filters were selected', () => {
expect(
getSelectOptions(
[
{ key: '', value: '' },
{ key: '', value: '' },
{ key: '', value: '' },
{ key: '', value: '' },
],
''
)
getSelectOptions([filters.empty, filters.empty, filters.empty, filters.empty], '')
).toEqual([
{ value: 'DEFAULT', text: 'Select field...' },
{ value: 'service.name', text: 'service.name' },
{ value: 'service.environment', text: 'service.environment' },
{ value: 'transaction.type', text: 'transaction.type' },
{ value: 'transaction.name', text: 'transaction.name' },
options.default,
options.serviceName,
options.serviceEnvironment,
options.transactionType,
options.transactionName,
]);
});
it('removes item added in another filter', () => {
expect(
getSelectOptions(
[
{ key: 'service.name', value: 'foo' },
{ key: '', value: '' },
{ key: '', value: '' },
{ key: '', value: '' },
],
''
)
getSelectOptions([filters.serviceName, filters.empty, filters.empty, filters.empty], '')
).toEqual([
{ value: 'DEFAULT', text: 'Select field...' },
{ value: 'service.environment', text: 'service.environment' },
{ value: 'transaction.type', text: 'transaction.type' },
{ value: 'transaction.name', text: 'transaction.name' },
options.default,
options.serviceEnvironment,
options.transactionType,
options.transactionName,
]);
});
it('removes item added in another filter but keep the current selected', () => {
expect(
getSelectOptions(
[
{ key: 'service.name', value: 'foo' },
{ key: 'transaction.name', value: 'bar' },
{ key: '', value: '' },
{ key: '', value: '' },
],
'transaction.name'
[filters.serviceName, filters.transactionName, filters.empty, filters.empty],
filters.transactionName.key
)
).toEqual([
{ value: 'DEFAULT', text: 'Select field...' },
{ value: 'service.environment', text: 'service.environment' },
{ value: 'transaction.type', text: 'transaction.type' },
{ value: 'transaction.name', text: 'transaction.name' },
options.default,
options.serviceEnvironment,
options.transactionType,
options.transactionName,
]);
});
it('returns empty when all option were selected', () => {
expect(
getSelectOptions(
[
{ key: 'service.name', value: 'foo' },
{ key: 'transaction.name', value: 'bar' },
{ key: 'service.environment', value: 'baz' },
{ key: 'transaction.type', value: 'qux' },
filters.serviceName,
filters.transactionName,
filters.serviceEnvironment,
filters.transactionType,
],
''
)
).toEqual([{ value: 'DEFAULT', text: 'Select field...' }]);
).toEqual([options.default]);
});
it("does not remove item added if it's the default option", () => {
expect(
getSelectOptions([filters.serviceName, filters.empty, filters.empty], filters.default.key)
).toEqual([
options.default,
options.serviceEnvironment,
options.transactionType,
options.transactionName,
]);
});
});

View file

@ -41,7 +41,9 @@ export const FILTER_SELECT_OPTIONS: FilterSelectOption[] = [
*/
export const getSelectOptions = (filters: Filter[], selectedKey: Filter['key']) => {
return FILTER_SELECT_OPTIONS.filter(
({ value }) => !filters.some(({ key }) => key === value && key !== selectedKey)
({ value }) =>
value === DEFAULT_OPTION.value ||
!filters.some(({ key }) => key === value && key !== selectedKey)
);
};