From 5aeb367322bbe33d4b95d84c33a05da17676feac Mon Sep 17 00:00:00 2001 From: Alex Khomenko Date: Tue, 10 Mar 2020 11:16:56 +0200 Subject: [PATCH] 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 --- .../components/Select/DashboardPicker.tsx | 89 +++++++------------ 1 file changed, 33 insertions(+), 56 deletions(-) diff --git a/public/app/core/components/Select/DashboardPicker.tsx b/public/app/core/components/Select/DashboardPicker.tsx index 58cd8bf793a..918020c7c7a 100644 --- a/public/app/core/components/Select/DashboardPicker.tsx +++ b/public/app/core/components/Select/DashboardPicker.tsx @@ -1,5 +1,6 @@ -import React, { PureComponent } from 'react'; +import React, { FC } from 'react'; import { debounce } from 'lodash'; +import { useAsyncFn } from 'react-use'; import { SelectableValue } from '@grafana/data'; import { Forms } from '@grafana/ui'; import { FormInputSize } from '@grafana/ui/src/components/Forms/types'; @@ -8,64 +9,40 @@ import { DashboardSearchHit, DashboardDTO } from 'app/types'; export interface Props { onSelected: (dashboard: DashboardDTO) => void; - currentDashboardId?: SelectableValue; + currentDashboard?: SelectableValue; size?: FormInputSize; + isClearable?: boolean; } -export interface State { - isLoading: boolean; -} +const getDashboards = (query = '') => { + return backendSrv.search({ type: 'dash-db', query }).then((result: DashboardSearchHit[]) => { + return result.map((item: DashboardSearchHit) => ({ + id: item.id, + value: item.id, + label: `${item.folderTitle ? item.folderTitle : 'General'}/${item.title}`, + })); + }); +}; -export class DashboardPicker extends PureComponent { - debouncedSearch: any; +export const DashboardPicker: FC = ({ onSelected, currentDashboard, size = 'md', isClearable = false }) => { + const debouncedSearch = debounce(getDashboards, 300, { + leading: true, + trailing: true, + }); - static defaultProps = { - size: 'md', - }; + const [state, searchDashboards] = useAsyncFn(debouncedSearch, []); - 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[]) => { - const dashboards = result.map((item: DashboardSearchHit) => ({ - id: item.id, - value: item.id, - label: `${item.folderTitle ? item.folderTitle : 'General'}/${item.title}`, - })); - - this.setState({ isLoading: false }); - return dashboards; - }); - }; - - render() { - const { size, onSelected, currentDashboardId } = this.props; - const { isLoading } = this.state; - - return ( - - ); - } -} + return ( + + ); +};