Commit 5f293743 by Torkel Ödegaard Committed by GitHub

Merge pull request #14572 from grafana/develop-draggable-panel

Another take on resizing the panel, now using react-draggable
parents a6d90151 9cd00671
...@@ -14,6 +14,7 @@ import { PanelEditor } from './PanelEditor'; ...@@ -14,6 +14,7 @@ import { PanelEditor } from './PanelEditor';
import { PanelModel } from '../panel_model'; import { PanelModel } from '../panel_model';
import { DashboardModel } from '../dashboard_model'; import { DashboardModel } from '../dashboard_model';
import { PanelPlugin } from 'app/types'; import { PanelPlugin } from 'app/types';
import { PanelResizer } from './PanelResizer';
export interface Props { export interface Props {
panel: PanelModel; panel: PanelModel;
...@@ -158,10 +159,21 @@ export class DashboardPanel extends PureComponent<Props, State> { ...@@ -158,10 +159,21 @@ export class DashboardPanel extends PureComponent<Props, State> {
return ( return (
<div className={containerClass}> <div className={containerClass}>
<div className={panelWrapperClass} onMouseEnter={this.onMouseEnter} onMouseLeave={this.onMouseLeave}> <PanelResizer
isEditing={!!isEditing}
panel={panel}
render={(panelHeight: number | 'inherit') => (
<div
className={panelWrapperClass}
onMouseEnter={this.onMouseEnter}
onMouseLeave={this.onMouseLeave}
style={{ height: panelHeight }}
>
{plugin.exports.Panel && this.renderReactPanel()} {plugin.exports.Panel && this.renderReactPanel()}
{plugin.exports.PanelCtrl && this.renderAngularPanel()} {plugin.exports.PanelCtrl && this.renderAngularPanel()}
</div> </div>
)}
/>
{panel.isEditing && ( {panel.isEditing && (
<PanelEditor <PanelEditor
panel={panel} panel={panel}
......
import React, { PureComponent } from 'react';
import { throttle } from 'lodash';
import Draggable from 'react-draggable';
import { PanelModel } from '../panel_model';
interface Props {
isEditing: boolean;
render: (height: number | 'inherit') => JSX.Element;
panel: PanelModel;
}
interface State {
editorHeight: number;
}
export class PanelResizer extends PureComponent<Props, State> {
initialHeight: number = Math.floor(document.documentElement.scrollHeight * 0.4);
prevEditorHeight: number;
throttledChangeHeight: (height: number) => void;
throttledResizeDone: () => void;
constructor(props) {
super(props);
const { panel } = this.props;
this.state = {
editorHeight: this.initialHeight,
};
this.throttledChangeHeight = throttle(this.changeHeight, 20, { trailing: true });
this.throttledResizeDone = throttle(() => {
panel.resizeDone();
}, 50);
}
get largestHeight() {
return document.documentElement.scrollHeight * 0.9;
}
get smallestHeight() {
return 100;
}
changeHeight = height => {
const sh = this.smallestHeight;
const lh = this.largestHeight;
height = height < sh ? sh : height;
height = height > lh ? lh : height;
this.prevEditorHeight = this.state.editorHeight;
this.setState({
editorHeight: height,
});
};
onDrag = (evt, data) => {
const newHeight = this.state.editorHeight + data.y;
this.throttledChangeHeight(newHeight);
this.throttledResizeDone();
};
render() {
const { render, isEditing } = this.props;
const { editorHeight } = this.state;
return (
<>
{render(isEditing ? editorHeight : 'inherit')}
{isEditing && (
<div className="panel-editor-container__resizer">
<Draggable axis="y" grid={[100, 1]} onDrag={this.onDrag} position={{ x: 0, y: 0 }}>
<div className="panel-editor-resizer">
<div className="panel-editor-resizer__handle" />
</div>
</Draggable>
</div>
)}
</>
);
}
}
...@@ -400,3 +400,7 @@ $logs-color-unkown: $gray-2; ...@@ -400,3 +400,7 @@ $logs-color-unkown: $gray-2;
$button-toggle-group-btn-active-bg: linear-gradient(90deg, $orange, $red); $button-toggle-group-btn-active-bg: linear-gradient(90deg, $orange, $red);
$button-toggle-group-btn-active-shadow: inset 0 0 4px $black; $button-toggle-group-btn-active-shadow: inset 0 0 4px $black;
$button-toggle-group-btn-seperator-border: 1px solid $page-bg; $button-toggle-group-btn-seperator-border: 1px solid $page-bg;
$vertical-resize-handle-bg: $dark-5;
$vertical-resize-handle-dots: $gray-1;
$vertical-resize-handle-dots-hover: $gray-2;
...@@ -409,3 +409,7 @@ $logs-color-unkown: $gray-5; ...@@ -409,3 +409,7 @@ $logs-color-unkown: $gray-5;
$button-toggle-group-btn-active-bg: $brand-primary; $button-toggle-group-btn-active-bg: $brand-primary;
$button-toggle-group-btn-active-shadow: inset 0 0 4px $white; $button-toggle-group-btn-active-shadow: inset 0 0 4px $white;
$button-toggle-group-btn-seperator-border: 1px solid $gray-6; $button-toggle-group-btn-seperator-border: 1px solid $gray-6;
$vertical-resize-handle-bg: $gray-4;
$vertical-resize-handle-dots: $gray-3;
$vertical-resize-handle-dots-hover: $gray-2;
...@@ -84,46 +84,34 @@ ...@@ -84,46 +84,34 @@
} }
} }
.panel-editor-resizer { .panel-editor-container__resizer {
position: absolute; position: relative;
height: 2px; margin-top: -3px;
width: 100%;
top: -23px;
text-align: center;
border-bottom: 2px dashed transparent;
&:hover {
transition: border-color 0.2s ease-in 0.4s;
transition-delay: 0.2s;
border-color: $text-color-faint;
}
} }
.panel-editor-resizer__handle { .panel-editor-resizer__handle {
display: inline-block;
width: 180px;
position: relative; position: relative;
border-radius: 2px; display: block;
height: 7px; background: $vertical-resize-handle-bg;
cursor: grabbing; width: 150px;
background: $input-label-bg; margin-left: -75px;
top: -9px; height: 6px;
cursor: ns-resize;
border-radius: 3px;
margin: 0 auto;
&:hover { &::before {
transition: background 0.2s ease-in 0.4s; content: ' ';
transition-delay: 0.2s; position: absolute;
background: linear-gradient(90deg, $orange, $red); left: 10px;
.panel-editor-resizer__handle-dots { right: 10px;
transition: opacity 0.2s ease-in; top: 2px;
opacity: 0; border-top: 2px dotted $vertical-resize-handle-dots;
}
} }
}
.panel-editor-resizer__handle-dots { &:hover::before {
border-top: 2px dashed $text-color-faint; border-color: $vertical-resize-handle-dots-hover;
position: relative; }
top: 4px;
} }
.viz-picker { .viz-picker {
...@@ -149,7 +137,6 @@ ...@@ -149,7 +137,6 @@
display: flex; display: flex;
margin-right: 10px; margin-right: 10px;
margin-bottom: 10px; margin-bottom: 10px;
//border: 1px solid transparent;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
padding-bottom: 6px; padding-bottom: 6px;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment