1import React, { FC } from 'react'; 2import { css } from '@emotion/css'; 3import { GrafanaTheme } from '@grafana/data'; 4import { ToolbarButton, ButtonGroup, useStyles } from '@grafana/ui'; 5import { StoreState } from 'app/types'; 6import { useDispatch, useSelector } from 'react-redux'; 7import { setPanelEditorUIState, toggleVizPicker } from './state/reducers'; 8import { selectors } from '@grafana/e2e-selectors'; 9import { PanelModel } from '../../state'; 10import { getPanelPluginWithFallback } from '../../state/selectors'; 11 12type Props = { 13 panel: PanelModel; 14}; 15 16export const VisualizationButton: FC<Props> = ({ panel }) => { 17 const styles = useStyles(getStyles); 18 const dispatch = useDispatch(); 19 const plugin = useSelector(getPanelPluginWithFallback(panel.type)); 20 const isPanelOptionsVisible = useSelector((state: StoreState) => state.panelEditor.ui.isPanelOptionsVisible); 21 const isVizPickerOpen = useSelector((state: StoreState) => state.panelEditor.isVizPickerOpen); 22 23 const onToggleOpen = () => { 24 dispatch(toggleVizPicker(!isVizPickerOpen)); 25 }; 26 27 const onToggleOptionsPane = () => { 28 dispatch(setPanelEditorUIState({ isPanelOptionsVisible: !isPanelOptionsVisible })); 29 }; 30 31 if (!plugin) { 32 return null; 33 } 34 35 return ( 36 <div className={styles.wrapper}> 37 <ButtonGroup> 38 <ToolbarButton 39 className={styles.vizButton} 40 tooltip="Click to change visualization" 41 imgSrc={plugin.meta.info.logos.small} 42 isOpen={isVizPickerOpen} 43 onClick={onToggleOpen} 44 aria-label={selectors.components.PanelEditor.toggleVizPicker} 45 fullWidth 46 > 47 {plugin.meta.name} 48 </ToolbarButton> 49 <ToolbarButton 50 tooltip={isPanelOptionsVisible ? 'Close options pane' : 'Show options pane'} 51 icon={isPanelOptionsVisible ? 'angle-right' : 'angle-left'} 52 onClick={onToggleOptionsPane} 53 aria-label={selectors.components.PanelEditor.toggleVizOptions} 54 /> 55 </ButtonGroup> 56 </div> 57 ); 58}; 59 60VisualizationButton.displayName = 'VisualizationTab'; 61 62const getStyles = (theme: GrafanaTheme) => { 63 return { 64 wrapper: css` 65 display: flex; 66 flex-direction: column; 67 `, 68 vizButton: css` 69 text-align: left; 70 `, 71 }; 72}; 73