import { css, cx } from '@emotion/css'; import { useEffect } from 'react'; import { GrafanaTheme2 } from '@grafana/data'; import { selectors } from '@grafana/e2e-selectors'; import { SceneComponentProps, VizPanel } from '@grafana/scenes'; import { Button, Spinner, ToolbarButton, useStyles2 } from '@grafana/ui'; import { useEditPaneCollapsed } from '../edit-pane/shared'; import { NavToolbarActions } from '../scene/NavToolbarActions'; import { UnlinkModal } from '../scene/UnlinkModal'; import { getDashboardSceneFor, getLibraryPanelBehavior } from '../utils/utils'; import { PanelEditor } from './PanelEditor'; import { SaveLibraryVizPanelModal } from './SaveLibraryVizPanelModal'; import { useSnappingSplitter } from './splitter/useSnappingSplitter'; export function PanelEditorRenderer({ model }: SceneComponentProps) { const dashboard = getDashboardSceneFor(model); const { optionsPane } = model.useState(); const styles = useStyles2(getStyles); const [isCollapsed, setIsCollapsed] = useEditPaneCollapsed(); const { containerProps, primaryProps, secondaryProps, splitterProps, splitterState, onToggleCollapse } = useSnappingSplitter({ direction: 'row', dragPosition: 'end', initialSize: 0.8, collapsed: isCollapsed, paneOptions: { collapseBelowPixels: 250, snapOpenToPixels: 400, }, }); useEffect(() => { setIsCollapsed(splitterState.collapsed); }, [splitterState.collapsed, setIsCollapsed]); return ( <>
{splitterState.collapsed && (
)} {!splitterState.collapsed && optionsPane && } {!splitterState.collapsed && !optionsPane && }
); } function VizAndDataPane({ model }: SceneComponentProps) { const dashboard = getDashboardSceneFor(model); const { dataPane, showLibraryPanelSaveModal, showLibraryPanelUnlinkModal, tableView } = model.useState(); const panel = model.getPanel(); const libraryPanel = getLibraryPanelBehavior(panel); const { controls } = dashboard.useState(); const styles = useStyles2(getStyles); const { containerProps, primaryProps, secondaryProps, splitterProps, splitterState, onToggleCollapse } = useSnappingSplitter({ direction: 'column', dragPosition: 'start', initialSize: 0.5, paneOptions: { collapseBelowPixels: 150, }, }); containerProps.className = cx(containerProps.className, styles.container); if (!dataPane) { primaryProps.style.flexGrow = 1; } return (
{controls && (
)}
{showLibraryPanelSaveModal && libraryPanel && ( )} {showLibraryPanelUnlinkModal && libraryPanel && ( )} {dataPane && ( <>
{splitterState.collapsed && (
)} {!splitterState.collapsed && }
)}
); } interface VizWrapperProps { panel: VizPanel; tableView?: VizPanel; } function VizWrapper({ panel, tableView }: VizWrapperProps) { const styles = useStyles2(getStyles); const panelToShow = tableView ?? panel; return (
); } function getStyles(theme: GrafanaTheme2) { return { pageContainer: css({ display: 'grid', gridTemplateAreas: ` "panels"`, gridTemplateColumns: `1fr`, gridTemplateRows: '1fr', height: '100%', }), pageContainerWithControls: css({ gridTemplateAreas: ` "controls" "panels"`, gridTemplateRows: 'auto 1fr', }), container: css({ gridArea: 'panels', height: '100%', }), canvasContent: css({ label: 'canvas-content', display: 'flex', flexDirection: 'column', flexBasis: '100%', flexGrow: 1, minHeight: 0, width: '100%', }), content: css({ position: 'absolute', width: '100%', height: '100%', }), body: css({ label: 'body', flexGrow: 1, display: 'flex', flexDirection: 'column', minHeight: 0, }), optionsPane: css({ flexDirection: 'column', borderLeft: `1px solid ${theme.colors.border.weak}`, background: theme.colors.background.primary, }), expandOptionsWrapper: css({ display: 'flex', flexDirection: 'column', padding: theme.spacing(2, 1), }), expandDataPane: css({ display: 'flex', flexDirection: 'row', padding: theme.spacing(1), borderTop: `1px solid ${theme.colors.border.weak}`, borderRight: `1px solid ${theme.colors.border.weak}`, background: theme.colors.background.primary, flexGrow: 1, justifyContent: 'space-around', }), rotate180: css({ rotate: '180deg', }), controlsWrapper: css({ display: 'flex', flexDirection: 'column', flexGrow: 0, gridArea: 'controls', }), openDataPaneButton: css({ width: theme.spacing(8), justifyContent: 'center', svg: { rotate: '-90deg', }, }), vizWrapper: css({ height: '100%', width: '100%', paddingLeft: theme.spacing(2), }), }; }