mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
92 lines
3.1 KiB
TypeScript
92 lines
3.1 KiB
TypeScript
import debounce from 'debounce-promise';
|
|
import { useEffect, useState } from 'react';
|
|
|
|
import { locationUtil } from '@grafana/data';
|
|
import { locationService } from '@grafana/runtime';
|
|
import { t } from 'app/core/internationalization';
|
|
import impressionSrv from 'app/core/services/impression_srv';
|
|
import { getGrafanaSearcher } from 'app/features/search/service';
|
|
|
|
import { CommandPaletteAction } from '../types';
|
|
import { RECENT_DASHBOARDS_PRORITY, SEARCH_RESULTS_PRORITY } from '../values';
|
|
|
|
const MAX_SEARCH_RESULTS = 100;
|
|
const MAX_RECENT_DASHBOARDS = 5;
|
|
|
|
const debouncedDashboardSearch = debounce(getDashboardSearchResultActions, 200);
|
|
|
|
export async function getRecentDashboardActions(): Promise<CommandPaletteAction[]> {
|
|
const recentUids = (await impressionSrv.getDashboardOpened()).slice(0, MAX_RECENT_DASHBOARDS);
|
|
const resultsDataFrame = await getGrafanaSearcher().search({
|
|
kind: ['dashboard'],
|
|
limit: MAX_RECENT_DASHBOARDS,
|
|
uid: recentUids,
|
|
});
|
|
|
|
// Search results are alphabetical, so reorder them according to recently viewed
|
|
const recentResults = resultsDataFrame.view.toArray();
|
|
recentResults.sort((resultA, resultB) => {
|
|
const orderA = recentUids.indexOf(resultA.uid);
|
|
const orderB = recentUids.indexOf(resultB.uid);
|
|
return orderA - orderB;
|
|
});
|
|
|
|
const recentDashboardActions: CommandPaletteAction[] = recentResults.map((item) => {
|
|
const { url, name } = item; // items are backed by DataFrameView, so must hold the url in a closure
|
|
return {
|
|
id: `recent-dashboards/${url}`,
|
|
name: `${name}`,
|
|
section: t('command-palette.section.recent-dashboards', 'Recent dashboards'),
|
|
priority: RECENT_DASHBOARDS_PRORITY,
|
|
perform: () => {
|
|
locationService.push(locationUtil.stripBaseFromUrl(url));
|
|
},
|
|
};
|
|
});
|
|
|
|
return recentDashboardActions;
|
|
}
|
|
|
|
export async function getDashboardSearchResultActions(searchQuery: string): Promise<CommandPaletteAction[]> {
|
|
// Empty strings should not come through to here
|
|
if (searchQuery.length === 0) {
|
|
return [];
|
|
}
|
|
|
|
const data = await getGrafanaSearcher().search({
|
|
kind: ['dashboard'],
|
|
query: searchQuery,
|
|
limit: MAX_SEARCH_RESULTS,
|
|
});
|
|
|
|
const goToDashboardActions: CommandPaletteAction[] = data.view.map((item) => {
|
|
const { url, name } = item; // items are backed by DataFrameView, so must hold the url in a closure
|
|
return {
|
|
id: `go/dashboard/${url}`,
|
|
name: `${name}`,
|
|
section: t('command-palette.section.dashboard-search-results', 'Dashboards'),
|
|
priority: SEARCH_RESULTS_PRORITY,
|
|
perform: () => {
|
|
locationService.push(locationUtil.stripBaseFromUrl(url));
|
|
},
|
|
};
|
|
});
|
|
|
|
return goToDashboardActions;
|
|
}
|
|
|
|
export function useDashboardResults(searchQuery: string, isShowing: boolean) {
|
|
const [dashboardResults, setDashboardResults] = useState<CommandPaletteAction[]>([]);
|
|
|
|
// Hit dashboards API
|
|
useEffect(() => {
|
|
if (isShowing && searchQuery.length > 0) {
|
|
debouncedDashboardSearch(searchQuery).then((resultActions) => {
|
|
setDashboardResults(resultActions);
|
|
});
|
|
}
|
|
}, [isShowing, searchQuery]);
|
|
|
|
return dashboardResults;
|
|
}
|