소스 검색

Another take on resizing the panel, now using react-draggable

Johannes Schill 7 년 전
부모
커밋
a007730f5d

+ 16 - 4
public/app/features/dashboard/dashgrid/DashboardPanel.tsx

@@ -14,6 +14,7 @@ import { PanelEditor } from './PanelEditor';
 import { PanelModel } from '../panel_model';
 import { DashboardModel } from '../dashboard_model';
 import { PanelPlugin } from 'app/types';
+import { PanelResizer } from './PanelResizer';
 
 export interface Props {
   panel: PanelModel;
@@ -158,10 +159,21 @@ export class DashboardPanel extends PureComponent<Props, State> {
 
     return (
       <div className={containerClass}>
-        <div className={panelWrapperClass} onMouseEnter={this.onMouseEnter} onMouseLeave={this.onMouseLeave}>
-          {plugin.exports.Panel && this.renderReactPanel()}
-          {plugin.exports.PanelCtrl && this.renderAngularPanel()}
-        </div>
+        <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.PanelCtrl && this.renderAngularPanel()}
+            </div>
+          )}
+        />
         {panel.isEditing && (
           <PanelEditor
             panel={panel}

+ 69 - 0
public/app/features/dashboard/dashgrid/PanelResizer.tsx

@@ -0,0 +1,69 @@
+import React, { PureComponent } from 'react';
+import { debounce, 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;
+  debouncedChangeHeight: (height: number) => void;
+  debouncedResizeDone: () => void;
+
+  constructor(props) {
+    super(props);
+    const { panel } = this.props;
+
+    this.state = {
+      editorHeight: this.initialHeight,
+    };
+
+    this.debouncedChangeHeight = throttle(this.changeHeight, 20, { trailing: true });
+    this.debouncedResizeDone = debounce(() => {
+      panel.resizeDone();
+    }, 200);
+  }
+
+  changeHeight = height => {
+    this.prevEditorHeight = this.state.editorHeight;
+    this.setState({
+      editorHeight: height,
+    });
+  };
+
+  onDrag = (evt, data) => {
+    const newHeight = this.state.editorHeight + data.y;
+    this.debouncedChangeHeight(newHeight);
+    this.debouncedResizeDone();
+  };
+
+  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>
+        )}
+      </>
+    );
+  }
+}

+ 4 - 0
public/sass/_variables.dark.scss

@@ -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-shadow: inset 0 0 4px $black;
 $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;

+ 4 - 0
public/sass/_variables.light.scss

@@ -409,3 +409,7 @@ $logs-color-unkown: $gray-5;
 $button-toggle-group-btn-active-bg: $brand-primary;
 $button-toggle-group-btn-active-shadow: inset 0 0 4px $white;
 $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;

+ 21 - 34
public/sass/components/_panel_editor.scss

@@ -84,46 +84,34 @@
   }
 }
 
-.panel-editor-resizer {
-  position: absolute;
-  height: 2px;
-  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-container__resizer {
+  position: relative;
+  margin-top: -3px;
 }
 
 .panel-editor-resizer__handle {
-  display: inline-block;
-  width: 180px;
   position: relative;
-  border-radius: 2px;
-  height: 7px;
-  cursor: grabbing;
-  background: $input-label-bg;
-  top: -9px;
+  display: block;
+  background: $vertical-resize-handle-bg;
+  width: 150px;
+  margin-left: -75px;
+  height: 6px;
+  cursor: ns-resize;
+  border-radius: 3px;
+  margin: 0 auto;
 
-  &:hover {
-    transition: background 0.2s ease-in 0.4s;
-    transition-delay: 0.2s;
-    background: linear-gradient(90deg, $orange, $red);
-    .panel-editor-resizer__handle-dots {
-      transition: opacity 0.2s ease-in;
-      opacity: 0;
-    }
+  &::before {
+    content: ' ';
+    position: absolute;
+    left: 10px;
+    right: 10px;
+    top: 2px;
+    border-top: 2px dotted $vertical-resize-handle-dots;
   }
-}
 
-.panel-editor-resizer__handle-dots {
-  border-top: 2px dashed $text-color-faint;
-  position: relative;
-  top: 4px;
+  &:hover::before {
+    border-color: $vertical-resize-handle-dots-hover;
+  }
 }
 
 .viz-picker {
@@ -149,7 +137,6 @@
   display: flex;
   margin-right: 10px;
   margin-bottom: 10px;
-  //border: 1px solid transparent;
   align-items: center;
   justify-content: center;
   padding-bottom: 6px;