Combobox: Add a warning for combobox when exceeding the recommended amount of options (#96070)

* add a warning for components when they exceed the recommended options amount

* Update packages/grafana-ui/src/components/Combobox/Combobox.tsx

Co-authored-by: Tobias Skarhed <1438972+tskarhed@users.noreply.github.com>

* Update packages/grafana-ui/src/components/Combobox/Combobox.tsx

Co-authored-by: Tobias Skarhed <1438972+tskarhed@users.noreply.github.com>

* log faro

* log once with flag

* log in setItems

* move logOptions to utils and write tests

* import function, update betterer for combobox

* Fix lint errors

* log once without the try

* fix tests

---------

Co-authored-by: Tobias Skarhed <1438972+tskarhed@users.noreply.github.com>
Co-authored-by: joshhunt <josh@trtr.co>
This commit is contained in:
Brendan O'Handley 2024-11-14 14:19:40 -06:00 committed by GitHub
parent ec1a722504
commit e331b778c1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 59 additions and 2 deletions

View File

@ -5,6 +5,7 @@ import { debounce } from 'lodash';
import { ReactNode, useCallback, useId, useMemo, useState } from 'react';
import { useStyles2 } from '../../themes';
import { logOptions } from '../../utils';
import { t, Trans } from '../../utils/i18n';
import { Icon } from '../Icon/Icon';
import { AutoSizeInput } from '../Input/AutoSizeInput';
@ -48,6 +49,8 @@ interface ComboboxBaseProps<T extends string | number>
width?: number | 'auto';
}
const RECOMMENDED_ITEMS_AMOUNT = 100_000;
type AutoSizeConditionals =
| {
width: 'auto';
@ -123,7 +126,7 @@ export const Combobox = <T extends string | number>(props: ComboboxProps<T>) =>
const setItems = useCallback(
(items: Array<ComboboxOption<T>>, inputValue: string | undefined) => {
let itemsToSet = items;
logOptions(itemsToSet.length, RECOMMENDED_ITEMS_AMOUNT, id, ariaLabelledBy);
if (inputValue && createCustomValue) {
const optionMatchingInput = items.find(
(opt) => opt.label === 'Custom value: ' + inputValue || opt.value === inputValue
@ -146,7 +149,7 @@ export const Combobox = <T extends string | number>(props: ComboboxProps<T>) =>
baseSetItems(itemsToSet);
},
[createCustomValue]
[createCustomValue, id, ariaLabelledBy]
);
const selectedItemIndex = useMemo(() => {

View File

@ -18,5 +18,6 @@ export { createLogger } from './logger';
export { attachDebugger } from './debug';
export * from './nodeGraph';
export { fuzzyMatch } from './fuzzy';
export { logOptions } from './logOptions';
export { ReactUtils };

View File

@ -0,0 +1,30 @@
import { logOptions } from './logOptions';
const RECOMMENDED_AMOUNT = 10;
describe('logOptions', () => {
beforeEach(() => {
jest.clearAllMocks();
});
it('should not log anything if amount is less than or equal to recommendedAmount', () => {
console.warn = jest.fn();
logOptions(5, RECOMMENDED_AMOUNT, 'test-id', 'test-aria');
expect(console.warn).not.toHaveBeenCalled();
});
it('should log a warning if amount exceeds recommendedAmount', () => {
console.warn = jest.fn();
logOptions(15, RECOMMENDED_AMOUNT, 'test-id', 'test-aria');
expect(console.warn).toHaveBeenCalledWith('[Combobox] Items exceed the recommended amount 10.', {
itemsCount: '15',
recommendedAmount: '10',
'aria-labelledby': 'test-aria',
id: 'test-id',
});
});
});

View File

@ -0,0 +1,23 @@
/**
* This function logs a warning if the amount of items exceeds the recommended amount.
*
* @param amount
* @param id
* @param ariaLabelledBy
*/
export function logOptions(
amount: number,
recommendedAmount: number,
id: string | undefined,
ariaLabelledBy: string | undefined
): void {
if (amount > recommendedAmount) {
const msg = `[Combobox] Items exceed the recommended amount ${recommendedAmount}.`;
console.warn(msg, {
itemsCount: '' + amount,
recommendedAmount: '' + recommendedAmount,
'aria-labelledby': ariaLabelledBy ?? '',
id: id ?? '',
});
}
}