import React, { FC, useCallback, useEffect, useRef, useState } from 'react'; import { css } from '@emotion/css'; import { GrafanaTheme, PanelPluginMeta, SelectableValue } from '@grafana/data'; import { Icon, Input, RadioButtonGroup, CustomScrollbar, useStyles, Button } from '@grafana/ui'; import { changePanelPlugin } from '../../state/actions'; import { StoreState } from 'app/types'; import { PanelModel } from '../../state/PanelModel'; import { useDispatch, useSelector } from 'react-redux'; import { VizTypePicker, getAllPanelPluginMeta, filterPluginList } from '../VizTypePicker/VizTypePicker'; import { Field } from '@grafana/ui/src/components/Forms/Field'; import { PanelLibraryOptionsGroup } from 'app/features/library-panels/components/PanelLibraryOptionsGroup/PanelLibraryOptionsGroup'; import { toggleVizPicker } from './state/reducers'; import { selectors } from '@grafana/e2e-selectors'; import { config } from 'app/core/config'; interface Props { panel: PanelModel; } export const VisualizationSelectPane: FC = ({ panel }) => { const plugin = useSelector((state: StoreState) => state.plugins.panels[panel.type]); const [searchQuery, setSearchQuery] = useState(''); const [listMode, setListMode] = useState(ListMode.Visualizations); const dispatch = useDispatch(); const styles = useStyles(getStyles); const searchRef = useRef(null); const onPluginTypeChange = useCallback( (meta: PanelPluginMeta) => { if (meta.id === plugin.meta.id) { dispatch(toggleVizPicker(false)); } else { dispatch(changePanelPlugin(panel, meta.id)); } }, [dispatch, panel, plugin.meta.id] ); // Give Search input focus when using radio button switch list mode useEffect(() => { if (searchRef.current) { searchRef.current.focus(); } }, [listMode]); const onCloseVizPicker = () => { dispatch(toggleVizPicker(false)); }; const onKeyPress = useCallback( (e: React.KeyboardEvent) => { if (e.key === 'Enter') { const query = e.currentTarget.value; const plugins = getAllPanelPluginMeta(); const match = filterPluginList(plugins, query, plugin.meta); if (match && match.length) { onPluginTypeChange(match[0]); } } }, [onPluginTypeChange, plugin.meta] ); const suffix = searchQuery !== '' ? ( ) : null; if (!plugin) { return null; } const radioOptions: Array> = [ { label: 'Visualizations', value: ListMode.Visualizations }, { label: 'Global panels', value: ListMode.Globals }, ]; return (
setSearchQuery(e.currentTarget.value)} onKeyPress={onKeyPress} prefix={} suffix={suffix} ref={searchRef} placeholder="Search for..." />
{config.featureToggles.panelLibrary && ( )}
{listMode === ListMode.Visualizations && ( {}} /> )} {listMode === ListMode.Globals && ( )}
); }; enum ListMode { Visualizations, Globals, } VisualizationSelectPane.displayName = 'VisualizationSelectPane'; const getStyles = (theme: GrafanaTheme) => { return { icon: css` color: ${theme.palette.gray33}; `, wrapper: css` display: flex; flex-direction: column; flex: 1 1 0; height: 100%; `, vizButton: css` text-align: left; `, scrollWrapper: css` flex-grow: 1; min-height: 0; `, scrollContent: css` padding: ${theme.spacing.sm}; `, openWrapper: css` display: flex; flex-direction: column; flex: 1 1 0; height: 100%; background: ${theme.colors.bg1}; border: 1px solid ${theme.colors.border1}; `, searchRow: css` display: flex; margin-bottom: ${theme.spacing.sm}; `, closeButton: css` margin-left: ${theme.spacing.sm}; `, customFieldMargin: css` margin-bottom: ${theme.spacing.sm}; `, formBox: css` padding: ${theme.spacing.sm}; padding-bottom: 0; `, }; };