mirror of
https://github.com/grafana/grafana.git
synced 2024-11-28 11:44:26 -06:00
Refactor SplitPaneWrapper to be more centralized component, refactor PanelEditor to use it (#58380)
* Move layout to paneleditor, make SplitPaneWrapper more generic * Read/write the size ratio in local storage * Add min height to enable scrollbar * Enable show/hide panel options * Change back variable name
This commit is contained in:
parent
78f0340031
commit
2055d922f3
@ -1,28 +1,23 @@
|
||||
import { css, cx } from '@emotion/css';
|
||||
import React, { createRef, MutableRefObject, PureComponent, ReactNode } from 'react';
|
||||
import SplitPane from 'react-split-pane';
|
||||
import React, { createRef, MutableRefObject, PureComponent } from 'react';
|
||||
import SplitPane, { Split } from 'react-split-pane';
|
||||
|
||||
import { GrafanaTheme2 } from '@grafana/data';
|
||||
import { config } from 'app/core/config';
|
||||
|
||||
enum Pane {
|
||||
Right,
|
||||
Top,
|
||||
}
|
||||
|
||||
interface Props {
|
||||
leftPaneComponents: ReactNode[] | ReactNode;
|
||||
rightPaneComponents: ReactNode;
|
||||
uiState: { topPaneSize: number; rightPaneSize: number };
|
||||
rightPaneVisible?: boolean;
|
||||
updateUiState: (uiState: { topPaneSize?: number; rightPaneSize?: number }) => void;
|
||||
splitOrientation?: Split;
|
||||
paneSize: number;
|
||||
splitVisible?: boolean;
|
||||
maxSize?: number;
|
||||
primary?: 'first' | 'second';
|
||||
onDragFinished?: (size?: number) => void;
|
||||
secondaryPaneStyle?: React.CSSProperties;
|
||||
}
|
||||
|
||||
export class SplitPaneWrapper extends PureComponent<Props> {
|
||||
//requestAnimationFrame reference
|
||||
rafToken: MutableRefObject<number | null> = createRef();
|
||||
static defaultProps = {
|
||||
rightPaneVisible: true,
|
||||
};
|
||||
|
||||
componentDidMount() {
|
||||
window.addEventListener('resize', this.updateSplitPaneSize);
|
||||
@ -41,86 +36,41 @@ export class SplitPaneWrapper extends PureComponent<Props> {
|
||||
});
|
||||
};
|
||||
|
||||
onDragFinished = (pane: Pane, size?: number) => {
|
||||
onDragFinished = (size?: number) => {
|
||||
document.body.style.cursor = 'auto';
|
||||
|
||||
// When the drag handle is just clicked size is undefined
|
||||
if (!size) {
|
||||
return;
|
||||
}
|
||||
|
||||
const { updateUiState } = this.props;
|
||||
if (pane === Pane.Top) {
|
||||
updateUiState({
|
||||
topPaneSize: size / window.innerHeight,
|
||||
});
|
||||
} else {
|
||||
updateUiState({
|
||||
rightPaneSize: size / window.innerWidth,
|
||||
});
|
||||
if (this.props.onDragFinished && size !== undefined) {
|
||||
this.props.onDragFinished(size);
|
||||
}
|
||||
};
|
||||
|
||||
onDragStarted = () => {
|
||||
document.body.style.cursor = 'row-resize';
|
||||
document.body.style.cursor = this.props.splitOrientation === 'horizontal' ? 'row-resize' : 'col-resize';
|
||||
};
|
||||
|
||||
renderHorizontalSplit() {
|
||||
const { leftPaneComponents, uiState } = this.props;
|
||||
const styles = getStyles(config.theme2);
|
||||
const topPaneSize = uiState.topPaneSize >= 1 ? uiState.topPaneSize : uiState.topPaneSize * window.innerHeight;
|
||||
|
||||
/*
|
||||
Guesstimate the height of the browser window minus
|
||||
panel toolbar and editor toolbar (~120px). This is to prevent resizing
|
||||
the preview window beyond the browser window.
|
||||
*/
|
||||
|
||||
if (Array.isArray(leftPaneComponents)) {
|
||||
return (
|
||||
<SplitPane
|
||||
split="horizontal"
|
||||
maxSize={-200}
|
||||
primary="first"
|
||||
size={topPaneSize}
|
||||
pane2Style={{ minHeight: 0 }}
|
||||
resizerClassName={styles.resizerH}
|
||||
onDragStarted={this.onDragStarted}
|
||||
onDragFinished={(size) => this.onDragFinished(Pane.Top, size)}
|
||||
>
|
||||
{leftPaneComponents}
|
||||
</SplitPane>
|
||||
);
|
||||
}
|
||||
|
||||
return <div className={styles.singleLeftPane}>{leftPaneComponents}</div>;
|
||||
}
|
||||
|
||||
render() {
|
||||
const { rightPaneVisible, rightPaneComponents, uiState } = this.props;
|
||||
const { paneSize, splitOrientation, maxSize, primary, secondaryPaneStyle } = this.props;
|
||||
// Limit options pane width to 90% of screen.
|
||||
const styles = getStyles(config.theme2);
|
||||
|
||||
// Need to handle when width is relative. ie a percentage of the viewport
|
||||
const rightPaneSize =
|
||||
uiState.rightPaneSize <= 1 ? uiState.rightPaneSize * window.innerWidth : uiState.rightPaneSize;
|
||||
|
||||
if (!rightPaneVisible) {
|
||||
return this.renderHorizontalSplit();
|
||||
}
|
||||
const paneSizePx =
|
||||
paneSize <= 1
|
||||
? paneSize * (splitOrientation === 'horizontal' ? window.innerHeight : window.innerWidth)
|
||||
: paneSize;
|
||||
|
||||
return (
|
||||
<SplitPane
|
||||
split="vertical"
|
||||
maxSize={-300}
|
||||
size={rightPaneSize}
|
||||
primary="second"
|
||||
resizerClassName={styles.resizerV}
|
||||
onDragStarted={() => (document.body.style.cursor = 'col-resize')}
|
||||
onDragFinished={(size) => this.onDragFinished(Pane.Right, size)}
|
||||
split={splitOrientation}
|
||||
maxSize={maxSize}
|
||||
size={paneSizePx}
|
||||
primary={primary}
|
||||
resizerClassName={splitOrientation === 'horizontal' ? styles.resizerH : styles.resizerV}
|
||||
onDragStarted={() => this.onDragStarted()}
|
||||
onDragFinished={(size) => this.onDragFinished(size)}
|
||||
pane2Style={secondaryPaneStyle}
|
||||
>
|
||||
{this.renderHorizontalSplit()}
|
||||
{rightPaneComponents}
|
||||
{this.props.children}
|
||||
</SplitPane>
|
||||
);
|
||||
}
|
||||
|
@ -47,7 +47,7 @@ import { PanelEditorTableView } from './PanelEditorTableView';
|
||||
import { PanelEditorTabs } from './PanelEditorTabs';
|
||||
import { VisualizationButton } from './VisualizationButton';
|
||||
import { discardPanelChanges, initPanelEditor, updatePanelEditorUIState } from './state/actions';
|
||||
import { toggleTableView } from './state/reducers';
|
||||
import { PanelEditorUIState, toggleTableView } from './state/reducers';
|
||||
import { getPanelEditorTabs } from './state/selectors';
|
||||
import { DisplayMode, displayModes, PanelEditorTab } from './types';
|
||||
import { calculatePanelSize } from './utils';
|
||||
@ -438,8 +438,27 @@ export class PanelEditorUnconnected extends PureComponent<Props> {
|
||||
);
|
||||
}
|
||||
|
||||
renderHorizontalSplit(uiState: PanelEditorUIState, styles: EditorStyles) {
|
||||
return (
|
||||
<SplitPaneWrapper
|
||||
splitOrientation="horizontal"
|
||||
maxSize={-200}
|
||||
paneSize={uiState.topPaneSize}
|
||||
primary="first"
|
||||
secondaryPaneStyle={{ minHeight: 0 }}
|
||||
onDragFinished={(size) => {
|
||||
if (size) {
|
||||
updatePanelEditorUIState({ topPaneSize: size / window.innerHeight });
|
||||
}
|
||||
}}
|
||||
>
|
||||
{this.renderPanelAndEditor(styles)}
|
||||
</SplitPaneWrapper>
|
||||
);
|
||||
}
|
||||
|
||||
render() {
|
||||
const { initDone, updatePanelEditorUIState, uiState, theme, sectionNav, pageNav, className } = this.props;
|
||||
const { initDone, uiState, theme, sectionNav, pageNav, className, updatePanelEditorUIState } = this.props;
|
||||
const styles = getStyles(theme, this.props);
|
||||
|
||||
if (!initDone) {
|
||||
@ -457,13 +476,24 @@ export class PanelEditorUnconnected extends PureComponent<Props> {
|
||||
>
|
||||
<div className={styles.wrapper}>
|
||||
<div className={styles.verticalSplitPanesWrapper}>
|
||||
<SplitPaneWrapper
|
||||
leftPaneComponents={this.renderPanelAndEditor(styles)}
|
||||
rightPaneComponents={this.renderOptionsPane()}
|
||||
uiState={uiState}
|
||||
updateUiState={updatePanelEditorUIState}
|
||||
rightPaneVisible={uiState.isPanelOptionsVisible}
|
||||
/>
|
||||
{!uiState.isPanelOptionsVisible ? (
|
||||
this.renderHorizontalSplit(uiState, styles)
|
||||
) : (
|
||||
<SplitPaneWrapper
|
||||
splitOrientation="vertical"
|
||||
maxSize={-300}
|
||||
paneSize={uiState.rightPaneSize}
|
||||
primary="second"
|
||||
onDragFinished={(size) => {
|
||||
if (size) {
|
||||
updatePanelEditorUIState({ rightPaneSize: size / window.innerWidth });
|
||||
}
|
||||
}}
|
||||
>
|
||||
{this.renderHorizontalSplit(uiState, styles)}
|
||||
{this.renderOptionsPane()}
|
||||
</SplitPaneWrapper>
|
||||
)}
|
||||
</div>
|
||||
{this.state.showSaveLibraryPanelModal && (
|
||||
<SaveLibraryPanelModal
|
||||
|
Loading…
Reference in New Issue
Block a user