Commit 5aeb3673 by Alex Khomenko Committed by GitHub

Core: DashboardPicker improvements (#22619)

* Refactor the picker to FC

* Remove redundant variable

* currentDashboardId => currentDashboard

* Make isClearable configurable

* Use useAsyncFn for options loading

* Move getDashboards outside of component
parent 385be776
import React, { PureComponent } from 'react'; import React, { FC } from 'react';
import { debounce } from 'lodash'; import { debounce } from 'lodash';
import { useAsyncFn } from 'react-use';
import { SelectableValue } from '@grafana/data'; import { SelectableValue } from '@grafana/data';
import { Forms } from '@grafana/ui'; import { Forms } from '@grafana/ui';
import { FormInputSize } from '@grafana/ui/src/components/Forms/types'; import { FormInputSize } from '@grafana/ui/src/components/Forms/types';
...@@ -8,64 +9,40 @@ import { DashboardSearchHit, DashboardDTO } from 'app/types'; ...@@ -8,64 +9,40 @@ import { DashboardSearchHit, DashboardDTO } from 'app/types';
export interface Props { export interface Props {
onSelected: (dashboard: DashboardDTO) => void; onSelected: (dashboard: DashboardDTO) => void;
currentDashboardId?: SelectableValue<number>; currentDashboard?: SelectableValue<number>;
size?: FormInputSize; size?: FormInputSize;
isClearable?: boolean;
} }
export interface State { const getDashboards = (query = '') => {
isLoading: boolean;
}
export class DashboardPicker extends PureComponent<Props, State> {
debouncedSearch: any;
static defaultProps = {
size: 'md',
};
constructor(props: Props) {
super(props);
this.state = {
isLoading: false,
};
this.debouncedSearch = debounce(this.getDashboards, 300, {
leading: true,
trailing: true,
});
}
getDashboards = (query = '') => {
this.setState({ isLoading: true });
return backendSrv.search({ type: 'dash-db', query }).then((result: DashboardSearchHit[]) => { return backendSrv.search({ type: 'dash-db', query }).then((result: DashboardSearchHit[]) => {
const dashboards = result.map((item: DashboardSearchHit) => ({ return result.map((item: DashboardSearchHit) => ({
id: item.id, id: item.id,
value: item.id, value: item.id,
label: `${item.folderTitle ? item.folderTitle : 'General'}/${item.title}`, label: `${item.folderTitle ? item.folderTitle : 'General'}/${item.title}`,
})); }));
});
};
this.setState({ isLoading: false }); export const DashboardPicker: FC<Props> = ({ onSelected, currentDashboard, size = 'md', isClearable = false }) => {
return dashboards; const debouncedSearch = debounce(getDashboards, 300, {
leading: true,
trailing: true,
}); });
};
render() { const [state, searchDashboards] = useAsyncFn(debouncedSearch, []);
const { size, onSelected, currentDashboardId } = this.props;
const { isLoading } = this.state;
return ( return (
<Forms.AsyncSelect <Forms.AsyncSelect
size={size} size={size}
isLoading={isLoading} isLoading={state.loading}
isClearable={true} isClearable={isClearable}
defaultOptions={true} defaultOptions={true}
loadOptions={this.debouncedSearch} loadOptions={searchDashboards}
onChange={onSelected} onChange={onSelected}
placeholder="Select dashboard" placeholder="Select dashboard"
noOptionsMessage={'No dashboards found'} noOptionsMessage="No dashboards found"
value={currentDashboardId} value={currentDashboard}
/> />
); );
} };
}
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