From 1230f3e48dc8064a5bd63c348869a775fcf727b3 Mon Sep 17 00:00:00 2001 From: Johannes Schill Date: Wed, 30 Jan 2019 15:28:41 +0100 Subject: [PATCH 1/4] chore: Fix typings and remove bindings for arrow functions in DashboardGrid --- .../dashboard/dashgrid/DashboardGrid.tsx | 56 +++++++++++-------- 1 file changed, 33 insertions(+), 23 deletions(-) diff --git a/public/app/features/dashboard/dashgrid/DashboardGrid.tsx b/public/app/features/dashboard/dashgrid/DashboardGrid.tsx index a401505b787..c9c1dd0d7b0 100644 --- a/public/app/features/dashboard/dashgrid/DashboardGrid.tsx +++ b/public/app/features/dashboard/dashgrid/DashboardGrid.tsx @@ -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 { 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 { 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 { 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 { 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); } From ef4611eb56841b73f6154dab59f57a9dc79e0b36 Mon Sep 17 00:00:00 2001 From: Johannes Schill Date: Wed, 30 Jan 2019 15:32:29 +0100 Subject: [PATCH 2/4] chore: Add missing typings in PanelResizer --- public/app/features/dashboard/dashgrid/PanelResizer.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/public/app/features/dashboard/dashgrid/PanelResizer.tsx b/public/app/features/dashboard/dashgrid/PanelResizer.tsx index ca8abd0d1e3..1ee5b3884a0 100644 --- a/public/app/features/dashboard/dashgrid/PanelResizer.tsx +++ b/public/app/features/dashboard/dashgrid/PanelResizer.tsx @@ -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 { 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 { }); }; - onDrag = (evt, data) => { + onDrag: DraggableEventHandler = (evt, data) => { const newHeight = this.state.editorHeight + data.y; this.throttledChangeHeight(newHeight); this.throttledResizeDone(); From 1afc590c703731cd2026fb8286388e1db6afc09f Mon Sep 17 00:00:00 2001 From: Johannes Schill Date: Wed, 30 Jan 2019 15:38:59 +0100 Subject: [PATCH 3/4] fix: Don't open panel menu when dragging (react-)panel in dashboard #14946 --- .../dashgrid/PanelHeader/PanelHeader.tsx | 37 ++++++++++++++++--- 1 file changed, 31 insertions(+), 6 deletions(-) diff --git a/public/app/features/dashboard/dashgrid/PanelHeader/PanelHeader.tsx b/public/app/features/dashboard/dashgrid/PanelHeader/PanelHeader.tsx index b5cd9258c08..6dd4af2dc03 100644 --- a/public/app/features/dashboard/dashgrid/PanelHeader/PanelHeader.tsx +++ b/public/app/features/dashboard/dashgrid/PanelHeader/PanelHeader.tsx @@ -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 { + clickCoordinates: ClickCoordinates = {x: 0, y: 0}; state = { panelMenuOpen: false, + clickCoordinates: {x: 0, y: 0} }; - onMenuToggle = event => { - event.stopPropagation(); + eventToClickCoordinates = (event: React.MouseEvent) => { + return { + x: event.clientX, + y: event.clientY + }; + } - this.setState(prevState => ({ - panelMenuOpen: !prevState.panelMenuOpen, - })); + onMouseDown = (event: React.MouseEvent) => { + this.clickCoordinates = this.eventToClickCoordinates(event); + }; + + isClick = (clickCoordinates: ClickCoordinates) => { + return isEqual(clickCoordinates, this.clickCoordinates); + } + + onMenuToggle = (event: React.MouseEvent) => { + if (this.isClick(this.eventToClickCoordinates(event))) { + event.stopPropagation(); + + this.setState(prevState => ({ + panelMenuOpen: !prevState.panelMenuOpen, + })); + } }; closeMenu = () => { @@ -64,7 +89,7 @@ export class PanelHeader extends Component { )} -
+
From 3165305377c05aaaf08fc86f7c352885d60a58c0 Mon Sep 17 00:00:00 2001 From: Johannes Schill Date: Wed, 30 Jan 2019 15:44:34 +0100 Subject: [PATCH 4/4] chore: Add typings for react-grid-layout and react-virtualized --- package.json | 2 ++ yarn.lock | 15 +++++++++++++++ 2 files changed, 17 insertions(+) diff --git a/package.json b/package.json index b8cb9ab7faf..d2b7effbf68 100644 --- a/package.json +++ b/package.json @@ -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", diff --git a/yarn.lock b/yarn.lock index 41928daab5e..169abd40ee4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -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"