Browse Source

newgrid: row progress

Torkel Ödegaard 8 years ago
parent
commit
cd10be0f52

+ 52 - 6
public/app/features/dashboard/dashboard_model.ts

@@ -82,9 +82,11 @@ export class DashboardModel {
     this.folderId = data.folderId || null;
     this.panels = _.map(data.panels || [], panelData => new PanelModel(panelData));
 
-    this.addBuiltInAnnotationQuery();
     this.initMeta(meta);
     this.updateSchema(data);
+
+    this.addBuiltInAnnotationQuery();
+    this.sortPanelsByGridPos();
   }
 
   addBuiltInAnnotationQuery() {
@@ -200,10 +202,12 @@ export class DashboardModel {
     return null;
   }
 
-  addPanel(panel) {
-    panel.id = this.getNextPanelId();
+  addPanel(panelData) {
+    panelData.id = this.getNextPanelId();
+
+    let panel = new PanelModel(panelData);
 
-    this.panels.unshift(new PanelModel(panel));
+    this.panels.unshift(panel);
 
     this.sortPanelsByGridPos();
 
@@ -395,9 +399,51 @@ export class DashboardModel {
 
   destroy() {
     this.events.removeAllListeners();
-    for (let row of this.rows) {
-      row.destroy();
+    for (let panel of this.panels) {
+      panel.destroy();
+    }
+  }
+
+  toggleRow(row) {
+    let rowPanels = [];
+    let rowFound = false;
+
+    // if already collapsed
+    if (row.collapse) {
+      row.collapse = false;
+
+      for (let panel of row.panels) {
+        this.panels.push(new PanelModel(panel));
+      }
+
+      row.panels = [];
+
+    } else {
+
+      for (let index = 0; index < this.panels.length; index++) {
+        let panel = this.panels[index];
+
+        if (rowFound) {
+          // break when encountering another row
+          if (panel.type === 'row') {
+            break;
+          }
+
+          // this panel must belong to row
+          rowPanels.push(panel);
+        } else if (panel === row) {
+          rowFound = true;
+        }
+      }
+      // remove panels
+      _.pull(this.panels, ...rowPanels);
+      // save panel models inside row panel
+      row.panels = _.map(rowPanels, panel => panel.getSaveModel());
+      row.collapse = true;
     }
+
+    // emit change event
+    this.events.emit('row-collapse-changed');
   }
 
   on(eventName, callback) {

+ 2 - 5
public/app/features/dashboard/dashgrid/AddPanelPanel.tsx

@@ -4,7 +4,6 @@ import _ from 'lodash';
 import config from 'app/core/config';
 import {PanelModel} from '../panel_model';
 import {PanelContainer} from './PanelContainer';
-import {GRID_COLUMN_COUNT} from 'app/core/constants';
 
 export interface AddPanelPanelProps {
   panel: PanelModel;
@@ -46,9 +45,6 @@ export class AddPanelPanel extends React.Component<AddPanelPanelProps, AddPanelP
     const dashboard = panelContainer.getDashboard();
     const {gridPos} = this.props.panel;
 
-    // remove add-panel panel
-    dashboard.removePanel(this.props.panel);
-
     var newPanel: any = {
       type: panelPluginInfo.id,
       title: 'Panel Title',
@@ -57,10 +53,11 @@ export class AddPanelPanel extends React.Component<AddPanelPanelProps, AddPanelP
 
     if (panelPluginInfo.id === 'row') {
       newPanel.title = 'Row title';
-      newPanel.gridPos = {x: 0, y: 0, w: GRID_COLUMN_COUNT, h: 1, static: true};
+      newPanel.gridPos = {x: 0, y: 0};
     }
 
     dashboard.addPanel(newPanel);
+    dashboard.removePanel(this.props.panel);
   }
 
   renderPanelItem(panel) {

+ 12 - 4
public/app/features/dashboard/dashgrid/DashboardGrid.tsx

@@ -70,6 +70,7 @@ export class DashboardGrid extends React.Component<DashboardGridProps, any> {
     this.dashboard.on('panel-removed', this.triggerForceUpdate.bind(this));
     this.dashboard.on('repeats-processed', this.triggerForceUpdate.bind(this));
     this.dashboard.on('view-mode-changed', this.triggerForceUpdate.bind(this));
+    this.dashboard.on('row-collapse-changed', this.triggerForceUpdate.bind(this));
   }
 
   buildLayout() {
@@ -85,14 +86,22 @@ export class DashboardGrid extends React.Component<DashboardGridProps, any> {
         continue;
       }
 
-      layout.push({
+      let panelPos: any = {
         i: stringId,
         x: panel.gridPos.x,
         y: panel.gridPos.y,
         w: panel.gridPos.w,
         h: panel.gridPos.h,
-        static: panel.gridPos.static,
-      });
+      };
+
+      if (panel.type === 'row') {
+        panelPos.w = GRID_COLUMN_COUNT;
+        panelPos.h = 1;
+        panelPos.isResizable = false;
+        panelPos.isDraggable = panel.collapse;
+      }
+
+      layout.push(panelPos);
     }
 
     return layout;
@@ -109,7 +118,6 @@ export class DashboardGrid extends React.Component<DashboardGridProps, any> {
   }
 
   onWidthChange() {
-    console.log('width change');
     for (const panel of this.dashboard.panels) {
       panel.resizeDone();
     }

+ 1 - 1
public/app/features/dashboard/dashgrid/DashboardPanel.tsx

@@ -39,7 +39,7 @@ export class DashboardPanel extends React.Component<DashboardPanelProps, any> {
   render() {
     // special handling for rows
     if (this.props.panel.type === 'row') {
-      return <DashboardRow panel={this.props.panel} />;
+      return <DashboardRow panel={this.props.panel} getPanelContainer={this.props.getPanelContainer} />;
     }
 
     if (this.props.panel.type === 'add-panel') {

+ 22 - 3
public/app/features/dashboard/dashgrid/DashboardRow.tsx

@@ -1,27 +1,46 @@
 import React from 'react';
+import classNames from 'classnames';
 import {PanelModel} from '../panel_model';
+import {PanelContainer} from './PanelContainer';
 
 export interface DashboardRowProps {
   panel: PanelModel;
+  getPanelContainer: () => PanelContainer;
 }
 
 export class DashboardRow extends React.Component<DashboardRowProps, any> {
   constructor(props) {
     super(props);
 
+    this.state = {
+      collapse: this.props.panel.collapse,
+    };
+
     this.toggle = this.toggle.bind(this);
     this.openSettings = this.openSettings.bind(this);
   }
 
-  toggle() {}
+  toggle() {
+    const panelContainer = this.props.getPanelContainer();
+    const dashboard = panelContainer.getDashboard();
+
+    dashboard.toggleRow(this.props.panel);
+
+    this.setState(prevState => {
+      return {collapse: !prevState.collapse};
+    });
+  }
 
   openSettings() {}
 
   render() {
+    const classes = classNames({'dashboard-row': true, 'dashboard-row--collapse': this.state.collapse});
+    const chevronClass = classNames({'fa': true, 'fa-chevron-down': !this.state.collapse, 'fa-chevron-right': this.state.collapse});
+
     return (
-      <div className="dashboard-row">
+      <div className={classes}>
         <a className="dashboard-row__title pointer" onClick={this.toggle}>
-          <i className="fa fa-chevron-down" />
+          <i className={chevronClass} />
           {this.props.panel.title}
         </a>
         <div className="dashboard-row__actions">

+ 2 - 2
public/app/features/dashboard/dashnav/dashnav.html

@@ -1,7 +1,7 @@
 <div class="navbar">
 	<div class="navbar-inner">
-		<a class="navbar-page-icon" ng-click="ctrl.starDashboard()">
-			<i class="gicon gicon-dashboard-starred"></i>
+		<a class="navbar-page-icon" ng-click="ctrl.starDashboard()" bs-tooltip="'Mark as favorite'" data-placement="bottom">
+      <i class="fa" ng-class="{'fa-star-o': !ctrl.dashboard.meta.isStarred, 'fa-star': ctrl.dashboard.meta.isStarred}"></i>
 		</a>
 
 		<a class="navbar-page-btn" ng-click="ctrl.showSearch()">

+ 5 - 0
public/app/features/dashboard/panel_model.ts

@@ -27,6 +27,7 @@ export class PanelModel {
   repeatPanelId?: number;
   repeatDirection?: string;
   minSpan?: number;
+  collapse?: boolean;
 
   // non persisted
   fullscreen: boolean;
@@ -86,5 +87,9 @@ export class PanelModel {
   resizeDone() {
     this.events.emit('panel-size-changed');
   }
+
+  destroy() {
+    this.events.removeAllListeners();
+  }
 }
 

+ 24 - 1
public/app/features/dashboard/specs/dashboard_model_specs.ts

@@ -168,7 +168,7 @@ describe('DashboardModel', function() {
     });
 
     it('should move pulldowns to new schema', function() {
-      expect(model.annotations.list[0].name).to.be('old');
+      expect(model.annotations.list[1].name).to.be('old');
     });
 
     it('table panel should only have two thresholds values', function() {
@@ -560,4 +560,27 @@ describe('DashboardModel', function() {
     });
   });
 
+  describe('When collapsing row', function(ctx) {
+    var dashboard;
+
+    beforeEach(function() {
+      dashboard = new DashboardModel({
+        panels: [
+          {id: 1, type: 'graph', gridPos: {x: 0, y: 0, w: 24, h: 2}},
+          {id: 2, type: 'row', gridPos: {x: 0, y: 2, w: 24, h: 2}},
+          {id: 3, type: 'graph', gridPos: {x: 0, y: 4, w: 12, h: 2}},
+          {id: 4, type: 'graph', gridPos: {x: 12, y: 4, w: 12, h: 2}},
+          {id: 5, type: 'row', gridPos: {x: 0, y: 6, w: 24, h: 2}},
+        ],
+      });
+      dashboard.toggleRow(dashboard.panels[1]);
+    });
+
+    it('should remove panels and put them inside collapsed row', function() {
+      expect(dashboard.panels.length).to.eql(3);
+      expect(dashboard.panels[1].panels.length).to.eql(2);
+    });
+
+  });
+
 });

+ 3 - 7
public/sass/components/_row.scss

@@ -1,5 +1,3 @@
-$dashboard-row-height: 30px;
-
 .dashboard-row {
   display: flex;
   height: 100%;
@@ -31,7 +29,6 @@ $dashboard-row-height: 30px;
   flex-grow: 0;
   font-size: 1.15rem;
   font-weight: $font-weight-semi-bold;
-  padding: 0rem 1rem 0.3rem 1rem;
   color: $text-color;
 
   .fa {
@@ -53,6 +50,8 @@ $dashboard-row-height: 30px;
       color: $link-hover-color;
     }
   }
+
+  flex-grow: 1;
 }
 
 .dashboard-row__panel_count {
@@ -61,15 +60,12 @@ $dashboard-row-height: 30px;
   font-size: $font-size-sm;
   font-weight: normal;
   display: none;
-  position: absolute;
-  right: 30px;
-  top: 0;
 }
 
 .dashboard-row__drag {
   cursor: move;
   width: 1rem;
-  height: $dashboard-row-height;
+  height: 100%;
   background: url("../img/grab_dark.svg") no-repeat 50% 50%;
   background-size: 8px;
   visibility: hidden;