mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
DashboardGrid: Fixes moving panels on first load (#67953)
* DashboardGrid: Fixes moving panels on first load * Minor tweak * Use theme breakpoint and add media query
This commit is contained in:
parent
6137e45fe1
commit
ea1c1b9fb8
@ -107,6 +107,11 @@ function getStyles(theme: GrafanaTheme2) {
|
|||||||
flexDirection: 'column',
|
flexDirection: 'column',
|
||||||
maxWidth: '890px',
|
maxWidth: '890px',
|
||||||
gap: theme.spacing.gridSize * 4,
|
gap: theme.spacing.gridSize * 4,
|
||||||
|
paddingTop: theme.spacing(2),
|
||||||
|
|
||||||
|
[theme.breakpoints.up('sm')]: {
|
||||||
|
paddingTop: theme.spacing(12),
|
||||||
|
},
|
||||||
}),
|
}),
|
||||||
containerBox: css({
|
containerBox: css({
|
||||||
label: 'container-box',
|
label: 'container-box',
|
||||||
|
@ -24,12 +24,7 @@ export interface Props {
|
|||||||
viewPanel: PanelModel | null;
|
viewPanel: PanelModel | null;
|
||||||
hidePanelMenus?: boolean;
|
hidePanelMenus?: boolean;
|
||||||
}
|
}
|
||||||
|
export class DashboardGrid extends PureComponent<Props> {
|
||||||
export interface State {
|
|
||||||
isLayoutInitialized: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
export class DashboardGrid extends PureComponent<Props, State> {
|
|
||||||
private panelMap: { [key: string]: PanelModel } = {};
|
private panelMap: { [key: string]: PanelModel } = {};
|
||||||
private eventSubs = new Subscription();
|
private eventSubs = new Subscription();
|
||||||
private windowHeight = 1200;
|
private windowHeight = 1200;
|
||||||
@ -37,13 +32,10 @@ export class DashboardGrid extends PureComponent<Props, State> {
|
|||||||
private gridWidth = 0;
|
private gridWidth = 0;
|
||||||
/** Used to keep track of mobile panel layout position */
|
/** Used to keep track of mobile panel layout position */
|
||||||
private lastPanelBottom = 0;
|
private lastPanelBottom = 0;
|
||||||
|
private isLayoutInitialized = false;
|
||||||
|
|
||||||
constructor(props: Props) {
|
constructor(props: Props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
||||||
this.state = {
|
|
||||||
isLayoutInitialized: false,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
@ -93,15 +85,14 @@ export class DashboardGrid extends PureComponent<Props, State> {
|
|||||||
|
|
||||||
onLayoutChange = (newLayout: ReactGridLayout.Layout[]) => {
|
onLayoutChange = (newLayout: ReactGridLayout.Layout[]) => {
|
||||||
for (const newPos of newLayout) {
|
for (const newPos of newLayout) {
|
||||||
this.panelMap[newPos.i!].updateGridPos(newPos, this.state.isLayoutInitialized);
|
this.panelMap[newPos.i!].updateGridPos(newPos, this.isLayoutInitialized);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.isLayoutInitialized) {
|
||||||
|
this.isLayoutInitialized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.props.dashboard.sortPanelsByGridPos();
|
this.props.dashboard.sortPanelsByGridPos();
|
||||||
|
|
||||||
// This is called on grid mount as it can correct invalid initial grid positions
|
|
||||||
if (!this.state.isLayoutInitialized) {
|
|
||||||
this.setState({ isLayoutInitialized: true });
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
triggerForceUpdate = () => {
|
triggerForceUpdate = () => {
|
||||||
@ -210,9 +201,24 @@ export class DashboardGrid extends PureComponent<Props, State> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Without this hack the move animations are triggered on initial load and all panels fly into position.
|
||||||
|
* This can be quite distracting and make the dashboard appear to less snappy.
|
||||||
|
*/
|
||||||
|
onGetWrapperDivRef = (ref: HTMLDivElement | null) => {
|
||||||
|
if (ref) {
|
||||||
|
setTimeout(() => {
|
||||||
|
ref.classList.add('react-grid-layout--enable-move-animations');
|
||||||
|
}, 50);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { dashboard, isEditable } = this.props;
|
const { isEditable, dashboard } = this.props;
|
||||||
const hasPanels = dashboard.panels && dashboard.panels.length > 0;
|
|
||||||
|
if (config.featureToggles.emptyDashboardPage && dashboard.panels.length === 0) {
|
||||||
|
return <DashboardEmpty dashboard={dashboard} canCreate={isEditable} />;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* We have a parent with "flex: 1 1 0" we need to reset it to "flex: 1 1 auto" to have the AutoSizer
|
* We have a parent with "flex: 1 1 0" we need to reset it to "flex: 1 1 auto" to have the AutoSizer
|
||||||
@ -227,59 +233,23 @@ export class DashboardGrid extends PureComponent<Props, State> {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const draggable = width <= 769 ? false : isEditable;
|
// Disable draggable if mobile device, solving an issue with unintentionally
|
||||||
|
// moving panels. https://github.com/grafana/grafana/issues/18497
|
||||||
|
const draggable = width <= config.theme2.breakpoints.values.md ? false : isEditable;
|
||||||
|
|
||||||
/*
|
return (
|
||||||
Disable draggable if mobile device, solving an issue with unintentionally
|
|
||||||
moving panels. https://github.com/grafana/grafana/issues/18497
|
|
||||||
theme.breakpoints.md = 769
|
|
||||||
*/
|
|
||||||
return config.featureToggles.emptyDashboardPage ? (
|
|
||||||
hasPanels ? (
|
|
||||||
/**
|
|
||||||
* The children is using a width of 100% so we need to guarantee that it is wrapped
|
|
||||||
* in an element that has the calculated size given by the AutoSizer. The AutoSizer
|
|
||||||
* has a width of 0 and will let its content overflow its div.
|
|
||||||
*/
|
|
||||||
<div style={{ width: `${width}px`, height: '100%' }}>
|
|
||||||
<ReactGridLayout
|
|
||||||
width={width}
|
|
||||||
isDraggable={draggable}
|
|
||||||
isResizable={isEditable}
|
|
||||||
containerPadding={[0, 0]}
|
|
||||||
useCSSTransforms={false}
|
|
||||||
margin={[GRID_CELL_VMARGIN, GRID_CELL_VMARGIN]}
|
|
||||||
cols={GRID_COLUMN_COUNT}
|
|
||||||
rowHeight={GRID_CELL_HEIGHT}
|
|
||||||
draggableHandle=".grid-drag-handle"
|
|
||||||
draggableCancel=".grid-drag-cancel"
|
|
||||||
layout={this.buildLayout()}
|
|
||||||
onDragStop={this.onDragStop}
|
|
||||||
onResize={this.onResize}
|
|
||||||
onResizeStop={this.onResizeStop}
|
|
||||||
onLayoutChange={this.onLayoutChange}
|
|
||||||
>
|
|
||||||
{this.renderPanels(width, draggable)}
|
|
||||||
</ReactGridLayout>
|
|
||||||
</div>
|
|
||||||
) : (
|
|
||||||
<div style={{ width: `${width}px`, height: '100%', padding: `${draggable ? '100px 0' : '0'}` }}>
|
|
||||||
<DashboardEmpty dashboard={dashboard} canCreate={isEditable} />
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
) : (
|
|
||||||
/**
|
/**
|
||||||
* The children is using a width of 100% so we need to guarantee that it is wrapped
|
* The children is using a width of 100% so we need to guarantee that it is wrapped
|
||||||
* in an element that has the calculated size given by the AutoSizer. The AutoSizer
|
* in an element that has the calculated size given by the AutoSizer. The AutoSizer
|
||||||
* has a width of 0 and will let its content overflow its div.
|
* has a width of 0 and will let its content overflow its div.
|
||||||
*/
|
*/
|
||||||
<div style={{ width: `${width}px`, height: '100%' }}>
|
<div style={{ width: width, height: '100%' }} ref={this.onGetWrapperDivRef}>
|
||||||
<ReactGridLayout
|
<ReactGridLayout
|
||||||
width={width}
|
width={width}
|
||||||
isDraggable={draggable}
|
isDraggable={draggable}
|
||||||
isResizable={isEditable}
|
isResizable={isEditable}
|
||||||
containerPadding={[0, 0]}
|
containerPadding={[0, 0]}
|
||||||
useCSSTransforms={false}
|
useCSSTransforms={true}
|
||||||
margin={[GRID_CELL_VMARGIN, GRID_CELL_VMARGIN]}
|
margin={[GRID_CELL_VMARGIN, GRID_CELL_VMARGIN]}
|
||||||
cols={GRID_COLUMN_COUNT}
|
cols={GRID_COLUMN_COUNT}
|
||||||
rowHeight={GRID_CELL_HEIGHT}
|
rowHeight={GRID_CELL_HEIGHT}
|
||||||
|
@ -94,6 +94,8 @@
|
|||||||
transition-property: none;
|
transition-property: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.animated .react-grid-item.cssTransforms {
|
.react-grid-layout--enable-move-animations {
|
||||||
transition-property: transform;
|
.react-grid-item.cssTransforms {
|
||||||
|
transition-property: transform;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user