Merge pull request #15141 from grafana/14946-panel-menu-on-move

Don't show panel menu on move
This commit is contained in:
Torkel Ödegaard 2019-01-30 16:11:10 +01:00 committed by GitHub
commit c33e94f438
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 84 additions and 32 deletions

View File

@ -25,7 +25,9 @@
"@types/node": "^8.0.31",
"@types/react": "^16.7.6",
"@types/react-dom": "^16.0.9",
"@types/react-grid-layout": "^0.16.6",
"@types/react-select": "^2.0.4",
"@types/react-virtualized": "^9.18.12",
"angular-mocks": "1.6.6",
"autoprefixer": "^6.4.0",
"axios": "^0.17.1",

View File

@ -1,6 +1,6 @@
import React from 'react';
import { hot } from 'react-hot-loader';
import ReactGridLayout from 'react-grid-layout';
import ReactGridLayout, { ItemCallback } from 'react-grid-layout';
import { GRID_CELL_HEIGHT, GRID_CELL_VMARGIN, GRID_COLUMN_COUNT } from 'app/core/constants';
import { DashboardPanel } from './DashboardPanel';
import { DashboardModel } from '../dashboard_model';
@ -11,6 +11,21 @@ import sizeMe from 'react-sizeme';
let lastGridWidth = 1200;
let ignoreNextWidthChange = false;
interface GridWrapperProps {
size: { width: number; };
layout: ReactGridLayout.Layout[];
onLayoutChange: (layout: ReactGridLayout.Layout[]) => void;
children: JSX.Element | JSX.Element[];
onDragStop: ItemCallback;
onResize: ItemCallback;
onResizeStop: ItemCallback;
onWidthChange: () => void;
className: string;
isResizable?: boolean;
isDraggable?: boolean;
isFullscreen?: boolean;
}
function GridWrapper({
size,
layout,
@ -24,7 +39,7 @@ function GridWrapper({
isResizable,
isDraggable,
isFullscreen,
}) {
}: GridWrapperProps) {
const width = size.width > 0 ? size.width : lastGridWidth;
// logic to ignore width changes (optimization)
@ -43,7 +58,6 @@ function GridWrapper({
className={className}
isDraggable={isDraggable}
isResizable={isResizable}
measureBeforeMount={false}
containerPadding={[0, 0]}
useCSSTransforms={false}
margin={[GRID_CELL_VMARGIN, GRID_CELL_VMARGIN]}
@ -71,22 +85,17 @@ export class DashboardGrid extends React.Component<DashboardGridProps> {
gridToPanelMap: any;
panelMap: { [id: string]: PanelModel };
constructor(props) {
constructor(props: DashboardGridProps) {
super(props);
this.onLayoutChange = this.onLayoutChange.bind(this);
this.onResize = this.onResize.bind(this);
this.onResizeStop = this.onResizeStop.bind(this);
this.onDragStop = this.onDragStop.bind(this);
this.onWidthChange = this.onWidthChange.bind(this);
// subscribe to dashboard events
const dashboard = this.props.dashboard;
dashboard.on('panel-added', this.triggerForceUpdate.bind(this));
dashboard.on('panel-removed', this.triggerForceUpdate.bind(this));
dashboard.on('repeats-processed', this.triggerForceUpdate.bind(this));
dashboard.on('view-mode-changed', this.onViewModeChanged.bind(this));
dashboard.on('row-collapsed', this.triggerForceUpdate.bind(this));
dashboard.on('row-expanded', this.triggerForceUpdate.bind(this));
dashboard.on('panel-added', this.triggerForceUpdate);
dashboard.on('panel-removed', this.triggerForceUpdate);
dashboard.on('repeats-processed', this.triggerForceUpdate);
dashboard.on('view-mode-changed', this.onViewModeChanged);
dashboard.on('row-collapsed', this.triggerForceUpdate);
dashboard.on('row-expanded', this.triggerForceUpdate);
}
buildLayout() {
@ -123,7 +132,7 @@ export class DashboardGrid extends React.Component<DashboardGridProps> {
return layout;
}
onLayoutChange(newLayout) {
onLayoutChange = (newLayout: ReactGridLayout.Layout[]) => {
for (const newPos of newLayout) {
this.panelMap[newPos.i].updateGridPos(newPos);
}
@ -131,22 +140,22 @@ export class DashboardGrid extends React.Component<DashboardGridProps> {
this.props.dashboard.sortPanelsByGridPos();
}
triggerForceUpdate() {
triggerForceUpdate = () => {
this.forceUpdate();
}
onWidthChange() {
onWidthChange = () => {
for (const panel of this.props.dashboard.panels) {
panel.resizeDone();
}
}
onViewModeChanged(payload) {
onViewModeChanged = () => {
ignoreNextWidthChange = true;
this.forceUpdate();
}
updateGridPos(item, layout) {
updateGridPos = (item: ReactGridLayout.Layout, layout: ReactGridLayout.Layout[]) => {
this.panelMap[item.i].updateGridPos(item);
// react-grid-layout has a bug (#670), and onLayoutChange() is only called when the component is mounted.
@ -154,16 +163,17 @@ export class DashboardGrid extends React.Component<DashboardGridProps> {
this.onLayoutChange(layout);
}
onResize(layout, oldItem, newItem) {
onResize: ItemCallback = (layout, oldItem, newItem) => {
console.log();
this.panelMap[newItem.i].updateGridPos(newItem);
}
onResizeStop(layout, oldItem, newItem) {
onResizeStop: ItemCallback = (layout, oldItem, newItem) => {
this.updateGridPos(newItem, layout);
this.panelMap[newItem.i].resizeDone();
}
onDragStop(layout, oldItem, newItem) {
onDragStop: ItemCallback = (layout, oldItem, newItem) => {
this.updateGridPos(newItem, layout);
}

View File

@ -1,5 +1,6 @@
import React, { Component } from 'react';
import classNames from 'classnames';
import { isEqual } from 'lodash';
import PanelHeaderCorner from './PanelHeaderCorner';
import { PanelHeaderMenu } from './PanelHeaderMenu';
@ -19,21 +20,45 @@ export interface Props {
links?: [];
}
interface ClickCoordinates {
x: number;
y: number;
}
interface State {
panelMenuOpen: boolean;
}
export class PanelHeader extends Component<Props, State> {
clickCoordinates: ClickCoordinates = {x: 0, y: 0};
state = {
panelMenuOpen: false,
clickCoordinates: {x: 0, y: 0}
};
onMenuToggle = event => {
event.stopPropagation();
eventToClickCoordinates = (event: React.MouseEvent<HTMLDivElement>) => {
return {
x: event.clientX,
y: event.clientY
};
}
this.setState(prevState => ({
panelMenuOpen: !prevState.panelMenuOpen,
}));
onMouseDown = (event: React.MouseEvent<HTMLDivElement>) => {
this.clickCoordinates = this.eventToClickCoordinates(event);
};
isClick = (clickCoordinates: ClickCoordinates) => {
return isEqual(clickCoordinates, this.clickCoordinates);
}
onMenuToggle = (event: React.MouseEvent<HTMLDivElement>) => {
if (this.isClick(this.eventToClickCoordinates(event))) {
event.stopPropagation();
this.setState(prevState => ({
panelMenuOpen: !prevState.panelMenuOpen,
}));
}
};
closeMenu = () => {
@ -64,7 +89,7 @@ export class PanelHeader extends Component<Props, State> {
<i className="fa fa-spinner fa-spin" />
</span>
)}
<div className="panel-title-container" onClick={this.onMenuToggle}>
<div className="panel-title-container" onClick={this.onMenuToggle} onMouseDown={this.onMouseDown}>
<div className="panel-title">
<span className="icon-gf panel-alert-icon" />
<span className="panel-title-text">

View File

@ -1,6 +1,6 @@
import React, { PureComponent } from 'react';
import { throttle } from 'lodash';
import Draggable from 'react-draggable';
import Draggable, { DraggableEventHandler } from 'react-draggable';
import { PanelModel } from '../panel_model';
@ -42,7 +42,7 @@ export class PanelResizer extends PureComponent<Props, State> {
return 100;
}
changeHeight = height => {
changeHeight = (height: number) => {
const sh = this.smallestHeight;
const lh = this.largestHeight;
height = height < sh ? sh : height;
@ -54,7 +54,7 @@ export class PanelResizer extends PureComponent<Props, State> {
});
};
onDrag = (evt, data) => {
onDrag: DraggableEventHandler = (evt, data) => {
const newHeight = this.state.editorHeight + data.y;
this.throttledChangeHeight(newHeight);
this.throttledResizeDone();

View File

@ -1773,6 +1773,13 @@
dependencies:
"@types/react" "*"
"@types/react-grid-layout@^0.16.6":
version "0.16.6"
resolved "https://registry.yarnpkg.com/@types/react-grid-layout/-/react-grid-layout-0.16.6.tgz#9149efe128e05d59c54063c7781d18b8febe112c"
integrity sha512-Jp0VfCHJE4uxekPBPpRkADKOjoSHssF2ba1ZMMAfCEqkoSkE+K+3bhI39++fbd7MqGySaqADVHeOoxlBnA3p5g==
dependencies:
"@types/react" "*"
"@types/react-select@^2.0.4":
version "2.0.11"
resolved "https://registry.yarnpkg.com/@types/react-select/-/react-select-2.0.11.tgz#9b2b1fdb12b67a5a617c5f572e15617636cc65af"
@ -1796,6 +1803,14 @@
dependencies:
"@types/react" "*"
"@types/react-virtualized@^9.18.12":
version "9.18.12"
resolved "https://registry.yarnpkg.com/@types/react-virtualized/-/react-virtualized-9.18.12.tgz#541e65c5e0b4629d6a1c6f339171c7943e016ecb"
integrity sha512-Msdpt9zvYlb5Ul4PA339QUkJ0/z2O+gaFxed1rG+2rZjbe6XdYo7jWfJe206KBnjj84DwPPIbPFQCtoGuNwNTQ==
dependencies:
"@types/prop-types" "*"
"@types/react" "*"
"@types/react@*", "@types/react@16.7.6", "@types/react@^16.7.6":
version "16.7.6"
resolved "https://registry.yarnpkg.com/@types/react/-/react-16.7.6.tgz#80e4bab0d0731ad3ae51f320c4b08bdca5f03040"