Commit 6347a1f1 by Ryan McKinley Committed by GitHub

VizPicker: show plugins that start with query text first (#23355)

* show plugins that start with queyr text first

* Memoize keyboard handler

Co-authored-by: Dominik Prokop <dominik.prokop@grafana.com>
parent 97184c17
import React, { FC, useState } from 'react';
import React, { FC, useCallback, useState } from 'react';
import { css } from 'emotion';
import { GrafanaTheme, PanelPlugin, PanelPluginMeta } from '@grafana/data';
import { CustomScrollbar, useTheme, stylesFactory, Icon, Input } from '@grafana/ui';
......@@ -6,7 +6,7 @@ import { changePanelPlugin } from '../../state/actions';
import { StoreState } from 'app/types';
import { PanelModel } from '../../state/PanelModel';
import { connect, MapStateToProps, MapDispatchToProps } from 'react-redux';
import { VizTypePicker } from '../../panel_editor/VizTypePicker';
import { VizTypePicker, getAllPanelPluginMeta, filterPluginList } from '../../panel_editor/VizTypePicker';
import { Field } from '@grafana/ui/src/components/Forms/Field';
interface OwnProps {
......@@ -35,6 +35,21 @@ export const VisualizationTabUnconnected: FC<Props> = ({ panel, plugin, changePa
const onPluginTypeChange = (meta: PanelPluginMeta) => {
changePanelPlugin(panel, meta.id);
};
const onKeyPress = useCallback(
(e: React.KeyboardEvent<HTMLInputElement>) => {
if (e.key === 'Enter') {
const query = e.currentTarget.value;
const plugins = getAllPanelPluginMeta();
const match = filterPluginList(plugins, query);
if (match && match.length) {
onPluginTypeChange(match[0]);
}
}
},
[onPluginTypeChange]
);
const suffix =
searchQuery !== '' ? (
<span className={styles.searchClear} onClick={() => setSearchQuery('')}>
......@@ -50,6 +65,7 @@ export const VisualizationTabUnconnected: FC<Props> = ({ panel, plugin, changePa
<Input
value={searchQuery}
onChange={e => setSearchQuery(e.currentTarget.value)}
onKeyPress={onKeyPress}
prefix={<Icon name="filter" className={styles.icon} />}
suffix={suffix}
placeholder="Filter visualisations"
......
......@@ -13,16 +13,39 @@ export interface Props {
onClose: () => void;
}
export const VizTypePicker: React.FC<Props> = ({ searchQuery, onTypeChange, current }) => {
const theme = useTheme();
const styles = getStyles(theme);
const pluginsList: PanelPluginMeta[] = useMemo(() => {
export function getAllPanelPluginMeta(): PanelPluginMeta[] {
const allPanels = config.panels;
return Object.keys(allPanels)
.filter(key => allPanels[key]['hideFromList'] === false)
.map(key => allPanels[key])
.sort((a: PanelPluginMeta, b: PanelPluginMeta) => a.sort - b.sort);
}
export function filterPluginList(pluginsList: PanelPluginMeta[], searchQuery: string): PanelPluginMeta[] {
if (!searchQuery.length) {
return pluginsList;
}
const query = searchQuery.toLowerCase();
const first: PanelPluginMeta[] = [];
const match: PanelPluginMeta[] = [];
for (const item of pluginsList) {
const name = item.name.toLowerCase();
const idx = name.indexOf(query);
if (idx === 0) {
first.push(item);
} else if (idx > 0) {
match.push(item);
}
}
return first.concat(match);
}
export const VizTypePicker: React.FC<Props> = ({ searchQuery, onTypeChange, current }) => {
const theme = useTheme();
const styles = getStyles(theme);
const pluginsList: PanelPluginMeta[] = useMemo(() => {
return getAllPanelPluginMeta();
}, []);
const renderVizPlugin = (plugin: PanelPluginMeta, index: number) => {
......@@ -42,10 +65,7 @@ export const VizTypePicker: React.FC<Props> = ({ searchQuery, onTypeChange, curr
};
const getFilteredPluginList = useCallback((): PanelPluginMeta[] => {
const regex = new RegExp(searchQuery, 'i');
return pluginsList.filter(item => {
return regex.test(item.name);
});
return filterPluginList(pluginsList, searchQuery);
}, [searchQuery]);
const filteredPluginList = getFilteredPluginList();
......
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