mirror of
https://github.com/grafana/grafana.git
synced 2025-02-16 18:34:52 -06:00
Dashboards: Fix folder picker not showing correct results when typing too fast (#50303)
* Use callback form for loadOptions in folder picker * clean up * fix other tests * clarify comment
This commit is contained in:
parent
307a0d4538
commit
32d4f6ac60
@ -8,6 +8,7 @@ export type ActionMeta = SelectActionMeta<{}>;
|
||||
export type InputActionMeta = {
|
||||
action: 'set-value' | 'input-change' | 'input-blur' | 'menu-close';
|
||||
};
|
||||
export type LoadOptionsCallback<T> = (options: Array<SelectableValue<T>>) => void;
|
||||
|
||||
export interface SelectCommonProps<T> {
|
||||
/** Aria label applied to the input field */
|
||||
@ -87,8 +88,10 @@ export interface SelectCommonProps<T> {
|
||||
export interface SelectAsyncProps<T> {
|
||||
/** When specified as boolean the loadOptions will execute when component is mounted */
|
||||
defaultOptions?: boolean | Array<SelectableValue<T>>;
|
||||
|
||||
/** Asynchronously load select options */
|
||||
loadOptions?: (query: string) => Promise<Array<SelectableValue<T>>>;
|
||||
loadOptions?: (query: string, cb?: LoadOptionsCallback<T>) => Promise<Array<SelectableValue<T>>> | void;
|
||||
|
||||
/** If cacheOptions is true, then the loaded data will be cached. The cache will remain until cacheOptions changes value. */
|
||||
cacheOptions?: boolean;
|
||||
/** Message to display when options are loading */
|
||||
|
@ -3,7 +3,7 @@ import React, { PureComponent } from 'react';
|
||||
|
||||
import { AppEvents, SelectableValue } from '@grafana/data';
|
||||
import { selectors } from '@grafana/e2e-selectors';
|
||||
import { ActionMeta, AsyncSelect } from '@grafana/ui';
|
||||
import { ActionMeta, AsyncSelect, LoadOptionsCallback } from '@grafana/ui';
|
||||
import { contextSrv } from 'app/core/services/context_srv';
|
||||
import { createFolder, getFolderById, searchFolders } from 'app/features/manage-dashboards/state/actions';
|
||||
import { DashboardSearchHit } from 'app/features/search/types';
|
||||
@ -52,7 +52,7 @@ export class FolderPicker extends PureComponent<Props, State> {
|
||||
folder: null,
|
||||
};
|
||||
|
||||
this.debouncedSearch = debounce(this.getOptions, 300, {
|
||||
this.debouncedSearch = debounce(this.loadOptions, 300, {
|
||||
leading: true,
|
||||
trailing: true,
|
||||
});
|
||||
@ -82,7 +82,13 @@ export class FolderPicker extends PureComponent<Props, State> {
|
||||
await this.loadInitialValue();
|
||||
};
|
||||
|
||||
getOptions = async (query: string) => {
|
||||
// when debouncing, we must use the callback form of react-select's loadOptions so we don't
|
||||
// drop results for user input. This must not return a promise/use await.
|
||||
loadOptions = (query: string, callback: LoadOptionsCallback<number>): void => {
|
||||
this.searchFolders(query).then(callback);
|
||||
};
|
||||
|
||||
private searchFolders = async (query: string) => {
|
||||
const {
|
||||
rootName,
|
||||
enableReset,
|
||||
@ -159,7 +165,7 @@ export class FolderPicker extends PureComponent<Props, State> {
|
||||
const resetFolder: SelectableValue<number> = { label: initialTitle, value: undefined };
|
||||
const rootFolder: SelectableValue<number> = { label: rootName, value: 0 };
|
||||
|
||||
const options = await this.getOptions('');
|
||||
const options = await this.searchFolders('');
|
||||
|
||||
let folder: SelectableValue<number> | null = null;
|
||||
|
||||
|
@ -19,7 +19,7 @@ jest.mock('@grafana/runtime', () => ({
|
||||
}));
|
||||
|
||||
setBackendSrv({
|
||||
get: jest.fn().mockResolvedValue({}),
|
||||
get: jest.fn().mockResolvedValue([]),
|
||||
} as any);
|
||||
|
||||
describe('DashboardSettings', () => {
|
||||
|
@ -5,11 +5,16 @@ import { selectOptionInTest } from 'test/helpers/selectOptionInTest';
|
||||
import { byRole } from 'testing-library-selector';
|
||||
|
||||
import { selectors } from '@grafana/e2e-selectors';
|
||||
import { setBackendSrv } from '@grafana/runtime';
|
||||
|
||||
import { DashboardModel } from '../../state';
|
||||
|
||||
import { GeneralSettingsUnconnected as GeneralSettings, Props } from './GeneralSettings';
|
||||
|
||||
setBackendSrv({
|
||||
get: jest.fn().mockResolvedValue([]),
|
||||
} as any);
|
||||
|
||||
const setupTestContext = (options: Partial<Props>) => {
|
||||
const defaults: Props = {
|
||||
dashboard: {
|
||||
|
Loading…
Reference in New Issue
Block a user