mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Command Palette: don't register dashboards as actions in the command palette (#61271)
* don't register dashboards as actions in the command palette * create ActionImpls in RenderResults, memoize some array creation * extract dashboard results out into separate hook * remove unnecessary memoization from useActions * move useDashboardResults into dashboardActions
This commit is contained in:
@@ -12,20 +12,19 @@ import {
|
||||
VisualState,
|
||||
useRegisterActions,
|
||||
useKBar,
|
||||
ActionImpl,
|
||||
} from 'kbar';
|
||||
import React, { useEffect, useRef } from 'react';
|
||||
import React, { useEffect, useMemo, useRef } from 'react';
|
||||
|
||||
import { GrafanaTheme2 } from '@grafana/data';
|
||||
import { reportInteraction } from '@grafana/runtime';
|
||||
import { useStyles2 } from '@grafana/ui';
|
||||
import { t } from 'app/core/internationalization';
|
||||
|
||||
import { ResultItem } from './ResultItem';
|
||||
import { useDashboardResults } from './actions/dashboardActions';
|
||||
import useActions from './actions/useActions';
|
||||
|
||||
/**
|
||||
* Wrap all the components from KBar here.
|
||||
* @constructor
|
||||
*/
|
||||
import { CommandPaletteAction } from './types';
|
||||
|
||||
export const CommandPalette = () => {
|
||||
const styles = useStyles2(getSearchStyles);
|
||||
@@ -35,8 +34,9 @@ export const CommandPalette = () => {
|
||||
searchQuery: state.searchQuery,
|
||||
}));
|
||||
|
||||
const actions = useActions(searchQuery, showing);
|
||||
const actions = useActions();
|
||||
useRegisterActions(actions, [actions]);
|
||||
const dashboardResults = useDashboardResults(searchQuery, showing);
|
||||
|
||||
const ref = useRef<HTMLDivElement>(null);
|
||||
const { overlayProps } = useOverlay(
|
||||
@@ -57,7 +57,7 @@ export const CommandPalette = () => {
|
||||
<FocusScope contain autoFocus restoreFocus>
|
||||
<div {...overlayProps} {...dialogProps}>
|
||||
<KBarSearch className={styles.search} />
|
||||
<RenderResults />
|
||||
<RenderResults dashboardResults={dashboardResults} />
|
||||
</div>
|
||||
</FocusScope>
|
||||
</KBarAnimator>
|
||||
@@ -66,14 +66,29 @@ export const CommandPalette = () => {
|
||||
) : null;
|
||||
};
|
||||
|
||||
const RenderResults = () => {
|
||||
interface RenderResultsProps {
|
||||
dashboardResults: CommandPaletteAction[];
|
||||
}
|
||||
|
||||
const RenderResults = ({ dashboardResults }: RenderResultsProps) => {
|
||||
const { results, rootActionId } = useMatches();
|
||||
const styles = useStyles2(getSearchStyles);
|
||||
const dashboardsSectionTitle = t('command-palette.section.dashboard-search-results', 'Dashboards');
|
||||
// because dashboard search results aren't registered as actions, we need to manually
|
||||
// convert them to ActionImpls before passing them as items to KBarResults
|
||||
const dashboardResultItems = useMemo(
|
||||
() => dashboardResults.map((dashboard) => new ActionImpl(dashboard, { store: {} })),
|
||||
[dashboardResults]
|
||||
);
|
||||
const items = useMemo(
|
||||
() => (dashboardResultItems.length > 0 ? [...results, dashboardsSectionTitle, ...dashboardResultItems] : results),
|
||||
[results, dashboardsSectionTitle, dashboardResultItems]
|
||||
);
|
||||
|
||||
return (
|
||||
<div className={styles.resultsContainer}>
|
||||
<KBarResults
|
||||
items={results}
|
||||
items={items}
|
||||
onRender={({ item, active }) =>
|
||||
typeof item === 'string' ? (
|
||||
<div className={styles.sectionHeader}>{item}</div>
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
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';
|
||||
@@ -10,6 +13,8 @@ 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({
|
||||
@@ -70,7 +75,17 @@ export async function getDashboardSearchResultActions(searchQuery: string): Prom
|
||||
return goToDashboardActions;
|
||||
}
|
||||
|
||||
// export default async (parentId: string) => {
|
||||
// const dashboardNav = await getDashboardNav(parentId);
|
||||
// return dashboardNav;
|
||||
// };
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -1,18 +1,14 @@
|
||||
import debounce from 'debounce-promise';
|
||||
import { useEffect, useMemo, useState } from 'react';
|
||||
import { useEffect, useState } from 'react';
|
||||
|
||||
import { useSelector } from 'app/types';
|
||||
|
||||
import { CommandPaletteAction } from '../types';
|
||||
|
||||
import { getDashboardSearchResultActions, getRecentDashboardActions } from './dashboardActions';
|
||||
import { getRecentDashboardActions } from './dashboardActions';
|
||||
import getStaticActions from './staticActions';
|
||||
|
||||
const debouncedDashboardSearch = debounce(getDashboardSearchResultActions, 200);
|
||||
|
||||
export default function useActions(searchQuery: string, isShowing: boolean) {
|
||||
export default function useActions() {
|
||||
const [staticActions, setStaticActions] = useState<CommandPaletteAction[]>([]);
|
||||
const [dashboardResultActions, setDashboardResultActions] = useState<CommandPaletteAction[]>([]);
|
||||
|
||||
const { navBarTree } = useSelector((state) => {
|
||||
return {
|
||||
@@ -35,16 +31,5 @@ export default function useActions(searchQuery: string, isShowing: boolean) {
|
||||
});
|
||||
}, []);
|
||||
|
||||
// Hit dashboards API
|
||||
useEffect(() => {
|
||||
if (isShowing && searchQuery.length > 0) {
|
||||
debouncedDashboardSearch(searchQuery).then((resultActions) => {
|
||||
setDashboardResultActions(resultActions);
|
||||
});
|
||||
}
|
||||
}, [isShowing, searchQuery]);
|
||||
|
||||
const actions = useMemo(() => [...staticActions, ...dashboardResultActions], [staticActions, dashboardResultActions]);
|
||||
|
||||
return actions;
|
||||
return staticActions;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user