浏览代码

grid: progress on react grid

Torkel Ödegaard 8 年之前
父节点
当前提交
2e77bd0cb1

+ 1 - 1
public/app/core/directives/dash_edit_link.js

@@ -123,7 +123,7 @@ function ($, angular, coreModule, _) {
           }, 10);
         }
 
-        scope.$watch("dashboardViewState.state.editview", function(newValue, oldValue) {
+        scope.$watch("ctrl.dashboardViewState.state.editview", function(newValue, oldValue) {
           if (newValue) {
             showEditorPane(null, {editview: newValue});
           } else if (oldValue) {

+ 7 - 8
public/app/features/dashboard/PanelModel.ts

@@ -8,7 +8,6 @@ export interface GridPos {
 }
 
 const notPersistedProperties: {[str: string]: boolean} = {
-  "model": true,
   "events": true,
 };
 
@@ -19,26 +18,26 @@ export class PanelModel {
   title: string;
   events: Emitter;
 
-  constructor(private model) {
+  constructor(model) {
+    this.events = new Emitter();
+
     // copy properties from persisted model
     for (var property in model) {
       this[property] = model[property];
     }
-
-    this.events = new Emitter();
   }
 
   getSaveModel() {
-    this.model = {};
+    const model: any = {};
     for (var property in this) {
       if (notPersistedProperties[property] || !this.hasOwnProperty(property)) {
-        console.log('PanelModel.getSaveModel() skiping property', property);
         continue;
       }
 
-      this.model[property] = this[property];
+      model[property] = this[property];
     }
-    return this.model;
+
+    return model;
   }
 
   updateGridPos(newPos: GridPos) {

+ 1 - 0
public/app/features/dashboard/all.js

@@ -25,6 +25,7 @@ define([
   './repeat_option/repeat_option',
   './dashgrid/DashboardGrid',
   './dashgrid/PanelLoader',
+  './row/add_panel',
   './acl/acl',
   './folder_picker/picker',
   './folder_modal/folder'

+ 4 - 10
public/app/features/dashboard/dashboard_ctrl.ts

@@ -3,12 +3,12 @@ import config from 'app/core/config';
 import coreModule from 'app/core/core_module';
 import {PanelContainer} from './dashgrid/PanelContainer';
 import {DashboardModel} from './model';
-import {PanelModel} from './PanelModel';
 
 export class DashboardCtrl implements PanelContainer {
   dashboard: DashboardModel;
   dashboardViewState: any;
   loadedFallbackDashboard: boolean;
+  editTab: number;
 
   /** @ngInject */
   constructor(
@@ -27,6 +27,9 @@ export class DashboardCtrl implements PanelContainer {
       // can't use controllerAs on route yet
       $scope.ctrl = this;
 
+      // TODO: break out settings view to separate view & controller
+      this.editTab = 0;
+
       // funcs called from React component bindings and needs this binding
       this.getPanelContainer = this.getPanelContainer.bind(this);
     }
@@ -116,15 +119,6 @@ export class DashboardCtrl implements PanelContainer {
       return this.panelLoader;
     }
 
-    getPanels() {
-      return this.dashboard.panels;
-    }
-
-    panelPossitionUpdated(panel: PanelModel) {
-      //console.log('panel pos updated', panel);
-      //this.$rootScope.$broadcast('render');
-    }
-
     timezoneChanged() {
       this.$rootScope.$broadcast("refresh");
     }

+ 21 - 6
public/app/features/dashboard/dashgrid/DashboardGrid.tsx

@@ -3,13 +3,14 @@ import coreModule from 'app/core/core_module';
 import ReactGridLayout from 'react-grid-layout';
 import {CELL_HEIGHT, CELL_VMARGIN} from '../model';
 import {DashboardPanel} from './DashboardPanel';
+import {DashboardModel} from '../model';
 import {PanelContainer} from './PanelContainer';
 import {PanelModel} from '../PanelModel';
 import sizeMe from 'react-sizeme';
 
 const COLUMN_COUNT = 12;
 
-function GridWrapper({size, layout, onLayoutChange, children}) {
+function GridWrapper({size, layout, onLayoutChange, children, onResize}) {
   if (size.width === 0) {
     console.log('size is zero!');
   }
@@ -30,6 +31,7 @@ function GridWrapper({size, layout, onLayoutChange, children}) {
       rowHeight={CELL_HEIGHT}
       draggableHandle=".grid-drag-handle"
       layout={layout}
+      onResize={onResize}
       onLayoutChange={onLayoutChange}>
       {children}
     </ReactGridLayout>
@@ -45,20 +47,25 @@ export interface DashboardGridProps {
 export class DashboardGrid extends React.Component<DashboardGridProps, any> {
   gridToPanelMap: any;
   panelContainer: PanelContainer;
+  dashboard: DashboardModel;
   panelMap: {[id: string]: PanelModel};
 
   constructor(props) {
     super(props);
     this.panelContainer = this.props.getPanelContainer();
     this.onLayoutChange = this.onLayoutChange.bind(this);
+    this.onResize = this.onResize.bind(this);
+
+    // subscribe to dashboard events
+    this.dashboard = this.panelContainer.getDashboard();
+    this.dashboard.on('panel-added', this.panelAdded.bind(this));
   }
 
   buildLayout() {
     const layout = [];
-    const panels = this.panelContainer.getPanels();
     this.panelMap = {};
 
-    for (let panel of panels) {
+    for (let panel of this.dashboard.panels) {
       let stringId = panel.id.toString();
       this.panelMap[stringId] = panel;
 
@@ -85,11 +92,18 @@ export class DashboardGrid extends React.Component<DashboardGridProps, any> {
     }
   }
 
+  panelAdded() {
+    this.forceUpdate();
+  }
+
+  onResize(layout, oldItem, newItem) {
+    this.panelMap[newItem.i].updateGridPos(newItem);
+  }
+
   renderPanels() {
-    const panels = this.panelContainer.getPanels();
     const panelElements = [];
 
-    for (let panel of panels) {
+    for (let panel of this.dashboard.panels) {
       panelElements.push(
         <div key={panel.id.toString()} className="panel">
           <DashboardPanel panel={panel} getPanelContainer={this.props.getPanelContainer} />
@@ -101,8 +115,9 @@ export class DashboardGrid extends React.Component<DashboardGridProps, any> {
   }
 
   render() {
+    console.log('DashboardGrid.render()');
     return (
-      <SizedReactLayoutGrid layout={this.buildLayout()} onLayoutChange={this.onLayoutChange}>
+      <SizedReactLayoutGrid layout={this.buildLayout()} onLayoutChange={this.onLayoutChange} onResize={this.onResize}>
         {this.renderPanels()}
       </SizedReactLayoutGrid>
     );

+ 0 - 3
public/app/features/dashboard/dashgrid/PanelContainer.ts

@@ -1,11 +1,8 @@
-import {PanelModel} from '../PanelModel';
 import {DashboardModel}  from '../model';
 import {PanelLoader} from './PanelLoader';
 
 export interface PanelContainer {
-  getPanels(): PanelModel[];
   getPanelLoader(): PanelLoader;
   getDashboard(): DashboardModel;
-  panelPossitionUpdated(panel: PanelModel);
 }
 

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

@@ -70,7 +70,7 @@
 				</ul>
 			</li>
 			<li class="navbar-mini-btn-wrapper" ng-show="::ctrl.dashboard.meta.canSave">
-				<button class="btn btn-secondary btn-mini" ng-click="ctrl.openEditView('add-panel')">
+				<button class="btn btn-secondary btn-mini" ng-click="ctrl.addPanel()">
 					<i class="fa fa-plus-circle"></i> Add Panel
 				</button>
 			</li>

+ 8 - 0
public/app/features/dashboard/dashnav/dashnav.ts

@@ -145,6 +145,14 @@ export class DashNavCtrl {
       this.$rootScope.appEvent('show-dash-search');
     }
 
+    addPanel() {
+      this.dashboard.addPanel({
+        type: 'graph',
+        gridPos: {x: 0, y: 0, w: 6, h: 5},
+        title: 'New Graph',
+      });
+    }
+
     navItemClicked(navItem, evt) {
       if (navItem.clickHandler) {
         navItem.clickHandler();

+ 10 - 1
public/app/features/dashboard/model.ts

@@ -180,7 +180,8 @@ export class DashboardModel {
 
   addPanel(panel) {
     panel.id = this.getNextPanelId();
-    this.panels.push(panel);
+    this.panels.unshift(new PanelModel(panel));
+    this.events.emit('panel-added', panel);
   }
 
   removePanel(panel, ask?) {
@@ -282,6 +283,14 @@ export class DashboardModel {
     }
   }
 
+  on(eventName, callback) {
+    this.events.on(eventName, callback);
+  }
+
+  off(eventName, callback?) {
+    this.events.off(eventName, callback);
+  }
+
   cycleGraphTooltip() {
     this.graphTooltip = (this.graphTooltip + 1) % 3;
   }

+ 13 - 13
public/app/features/dashboard/partials/settings.html

@@ -5,7 +5,7 @@
 
 	<ul class="gf-tabs">
 		<li class="gf-tabs-item" ng-repeat="tab in ::['General', 'Links', 'Time picker']">
-			<a class="gf-tabs-link" ng-click="editor.index = $index" ng-class="{active: editor.index === $index}">
+			<a class="gf-tabs-link" ng-click="ctrl.editTab = $index" ng-class="{active: ctrl.editTab === $index}">
 				{{::tab}}
 			</a>
 		</li>
@@ -17,30 +17,30 @@
 </div>
 
 <div class="tabbed-view-body">
-	<div ng-if="editor.index == 0">
+	<div ng-if="ctrl.editTab == 0">
 
 		<div class="gf-form-group section">
       <h5 class="section-heading">Details</h5>
 			<div class="gf-form">
 				<label class="gf-form-label width-7">Name</label>
-				<input type="text" class="gf-form-input width-30" ng-model='dashboard.title'></input>
+				<input type="text" class="gf-form-input width-30" ng-model='ctrl.dashboard.title'></input>
 			</div>
       <div class="gf-form">
 				<label class="gf-form-label width-7">Description</label>
-				<input type="text" class="gf-form-input width-30" ng-model='dashboard.description'></input>
+				<input type="text" class="gf-form-input width-30" ng-model='ctrl.dashboard.description'></input>
 			</div>
       <div class="gf-form">
 				<label class="gf-form-label width-7">
           Tags
           <info-popover mode="right-normal">Press enter to add a tag</info-popover>
         </label>
-				<bootstrap-tagsinput ng-model="dashboard.tags" tagclass="label label-tag" placeholder="add tags">
+				<bootstrap-tagsinput ng-model="ctrl.dashboard.tags" tagclass="label label-tag" placeholder="add tags">
 				</bootstrap-tagsinput>
 			</div>
 
-      <folder-picker ng-if="!dashboardMeta.isFolder"
-										 initial-title="dashboardMeta.folderTitle"
-										 on-change="onFolderChange($folder)"
+      <folder-picker ng-if="!ctrl.dashboard.meta.isFolder"
+										 initial-title="ctrl.dashboard.meta.folderTitle"
+										 on-change="ctrl.onFolderChange($folder)"
 										 label-class="width-7">
 			</folder-picker>
 		</div>
@@ -51,19 +51,19 @@
         <div class="gf-form">
           <label class="gf-form-label width-11">Timezone</label>
           <div class="gf-form-select-wrapper">
-            <select ng-model="dashboard.timezone" class='gf-form-input' ng-options="f.value as f.text for f in [{value: '', text: 'Default'}, {value: 'browser', text: 'Local browser time'},{value: 'utc', text: 'UTC'}]" ng-change="timezoneChanged()"></select>
+            <select ng-model="ctrl.dashboard.timezone" class='gf-form-input' ng-options="f.value as f.text for f in [{value: '', text: 'Default'}, {value: 'browser', text: 'Local browser time'},{value: 'utc', text: 'UTC'}]" ng-change="timezoneChanged()"></select>
           </div>
         </div>
         <gf-form-switch class="gf-form"
                         label="Editable"
                         tooltip="Uncheck, then save and reload to disable all dashboard editing"
-                        checked="dashboard.editable"
+                        checked="ctrl.dashboard.editable"
                         label-class="width-11">
         </gf-form-switch>
 				<gf-form-switch class="gf-form"
                         label="Hide Controls"
                         tooltip="Hide row controls. Shortcut: CTRL+H or CMD+H"
-                        checked="dashboard.hideControls"
+                        checked="ctrl.dashboard.hideControls"
                         label-class="width-11">
         </gf-form-switch>
       </div>
@@ -79,7 +79,7 @@
           </info-popover>
         </label>
         <div class="gf-form-select-wrapper">
-          <select ng-model="dashboard.graphTooltip" class='gf-form-input' ng-options="f.value as f.text for f in [{value: 0, text: 'Default'}, {value: 1, text: 'Shared crosshair'},{value: 2, text: 'Shared Tooltip'}]"></select>
+          <select ng-model="ctrl.dashboard.graphTooltip" class='gf-form-input' ng-options="f.value as f.text for f in [{value: 0, text: 'Default'}, {value: 1, text: 'Shared crosshair'},{value: 2, text: 'Shared Tooltip'}]"></select>
         </div>
       </div>
     </div>
@@ -90,7 +90,7 @@
 	</div>
 
 	<div ng-if="editor.index == 2">
-		<gf-time-picker-settings dashboard="dashboard"></gf-time-picker-settings>
+		<gf-time-picker-settings dashboard="ctrl.dashboard"></gf-time-picker-settings>
 	</div>
 
 </div>

+ 1 - 1
public/app/features/panel/panel_ctrl.ts

@@ -178,7 +178,7 @@ export class PanelCtrl {
     this.calculatePanelHeight();
     this.$timeout(() => {
       this.render();
-    });
+    }, 100);
   }
 
   duplicate() {

+ 3 - 3
public/sass/_variables.dark.scss

@@ -105,9 +105,9 @@ $tight-form-bg:     	$dark-3;
 $tight-form-func-bg: 		    #333;
 $tight-form-func-highlight-bg:  #444;
 
-$modal-background: $black;
-$code-tag-bg:      $gray-1;
-$code-tag-border:  lighten($code-tag-bg, 2%);
+$modal-backdrop-bg: $dark-3;
+$code-tag-bg:       $gray-1;
+$code-tag-border:   lighten($code-tag-bg, 2%);
 
 
 // Lists

+ 3 - 3
public/sass/_variables.light.scss

@@ -112,9 +112,9 @@ $tight-form-bg:    		$gray-6;
 $tight-form-func-bg:            $gray-5;
 $tight-form-func-highlight-bg:  $gray-6;
 
-$modal-background: $body-bg;
-$code-tag-bg:      $gray-6;
-$code-tag-border:  darken($code-tag-bg, 3%);
+$modal-backdrop-bg: $body-bg;
+$code-tag-bg:       $gray-6;
+$code-tag-border:   darken($code-tag-bg, 3%);
 
 // Lists
 $grafanaListBackground:    	   $gray-6;

+ 1 - 1
public/sass/components/_modals.scss

@@ -10,7 +10,7 @@
   bottom: 0;
   left: 0;
   z-index: $zindex-modal-backdrop;
-  background-color: $black;
+  background-color: $modal-backdrop-bg;
 }
 
 .modal-backdrop,