Ver código fonte

grid: worked on row options modal and row removal

Torkel Ödegaard 8 anos atrás
pai
commit
38f97d5cc9

+ 0 - 2
public/app/core/app_events.ts

@@ -1,5 +1,3 @@
-///<reference path="../headers/common.d.ts" />
-
 import {Emitter} from './utils/emitter';
 
 var appEvents = new Emitter();

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

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

+ 0 - 2
public/app/features/dashboard/dashboard_model.ts

@@ -7,7 +7,6 @@ import {Emitter} from 'app/core/utils/emitter';
 import {contextSrv} from 'app/core/services/context_srv';
 import sortByKeys from 'app/core/utils/sort_by_keys';
 
-import {DashboardRow} from './row/row_model';
 import {PanelModel} from './panel_model';
 
 export class DashboardModel {
@@ -20,7 +19,6 @@ export class DashboardModel {
   timezone: any;
   editable: any;
   graphTooltip: any;
-  rows: DashboardRow[];
   time: any;
   timepicker: any;
   hideControls: any;

+ 36 - 7
public/app/features/dashboard/dashgrid/DashboardRow.tsx

@@ -1,7 +1,7 @@
 import React from 'react';
 import classNames from 'classnames';
-import {PanelModel} from '../panel_model';
-import {PanelContainer} from './PanelContainer';
+import { PanelModel } from '../panel_model';
+import { PanelContainer } from './PanelContainer';
 import appEvents from 'app/core/app_events';
 
 export interface DashboardRowProps {
@@ -28,20 +28,49 @@ export class DashboardRow extends React.Component<DashboardRowProps, any> {
     dashboard.toggleRow(this.props.panel);
 
     this.setState(prevState => {
-      return {collapsed: !prevState.collapsed};
+      return { collapsed: !prevState.collapsed };
     });
   }
 
   openSettings() {
     appEvents.emit('show-modal', {
-      src: 'public/app/features/dashboard/partials/shareModal.html',
-      scope: shareScope
+      templateHtml: `<row-options row="model.row" on-updated="model.onUpdated()" on-delete="model.onDelete()" dismiss="dismiss()"></row-options>`,
+      modalClass: 'modal--narrow',
+      model: {
+        row: this.props.panel,
+        onUpdated: this.forceUpdate.bind(this),
+        onDelete: this.onDelete.bind(this),
+      },
+    });
+  }
+
+  onDelete() {
+    let text2 = '';
+
+    if (this.props.panel.panels.length) {
+      text2 = 'This will also remove ' + this.props.panel.panels.length + ' panels';
+    }
+
+    appEvents.emit('confirm-modal', {
+      title: 'Delete Row',
+      text: 'Are you sure you want to remove this row?',
+      text2: text2,
+      icon: 'fa-trash',
+      onConfirm: () => {
+        const panelContainer = this.props.getPanelContainer();
+        const dashboard = panelContainer.getDashboard();
+        dashboard.removePanel(this.props.panel);
+      },
     });
   }
 
   render() {
-    const classes = classNames({'dashboard-row': true, 'dashboard-row--collapsed': this.state.collapsed});
-    const chevronClass = classNames({'fa': true, 'fa-chevron-down': !this.state.collapsed, 'fa-chevron-right': this.state.collapsed});
+    const classes = classNames({ 'dashboard-row': true, 'dashboard-row--collapsed': this.state.collapsed });
+    const chevronClass = classNames({
+      fa: true,
+      'fa-chevron-down': !this.state.collapsed,
+      'fa-chevron-right': this.state.collapsed,
+    });
     const hiddenPanels = this.props.panel.panels ? this.props.panel.panels.length : 0;
 
     return (

+ 45 - 0
public/app/features/dashboard/dashgrid/RowOptions.ts

@@ -0,0 +1,45 @@
+import {coreModule} from 'app/core/core';
+
+export class RowOptionsCtrl {
+  row: any;
+  source: any;
+  dismiss: any;
+  onUpdated: any;
+  onDelete: any;
+
+  /** @ngInject */
+  constructor() {
+    this.source = this.row;
+    this.row = this.row.getSaveModel();
+  }
+
+  update() {
+    this.source.title = this.row.title;
+    this.source.repeat = this.row.repeat;
+    this.onUpdated();
+    this.dismiss();
+  }
+
+  delete() {
+    this.onDelete();
+    this.dismiss();
+  }
+}
+
+export function rowOptionsDirective() {
+  return {
+    restrict: 'E',
+    templateUrl: 'public/app/features/dashboard/partials/row_options.html',
+    controller: RowOptionsCtrl,
+    bindToController: true,
+    controllerAs: 'ctrl',
+    scope: {
+      row: "=",
+      dismiss: "&",
+      onUpdated: "&",
+      onDelete: "&"
+    },
+  };
+}
+
+coreModule.directive('rowOptions', rowOptionsDirective);

+ 29 - 0
public/app/features/dashboard/partials/row_options.html

@@ -0,0 +1,29 @@
+<div class="modal-body">
+	<div class="modal-header">
+		<h2 class="modal-header-title">
+			<i class="fa fa-copy"></i>
+			<span class="p-l-1">Row Options</span>
+		</h2>
+
+		<a class="modal-header-close" ng-click="ctrl.dismiss();">
+			<i class="fa fa-remove"></i>
+		</a>
+	</div>
+
+	<form name="ctrl.saveForm" ng-submit="ctrl.save()" class="modal-content" novalidate>
+		<div class="gf-form">
+			<span class="gf-form-label width-7">Title</span>
+			<input type="text" class="gf-form-input max-width-13" ng-model='ctrl.row.title'></input>
+		</div>
+		<div class="gf-form">
+			<span class="gf-form-label width-7">Repeat for</span>
+			<dash-repeat-option panel="ctrl.row"></dash-repeat-option>
+		</div>
+
+		<div class="gf-form-button-row">
+			<button type="button" class="btn btn-success" ng-click="ctrl.update()">Update</button>
+			<button type="button" class="btn btn-danger" ng-click="ctrl.delete()">Remove</button>
+			<button type="button" class="btn btn-inverse" ng-click="ctrl.dismiss()">Cancel</button>
+		</div>
+	</form>
+</div>

+ 2 - 2
public/app/features/dashboard/repeat_option/repeat_option.ts

@@ -2,7 +2,7 @@ import {coreModule} from 'app/core/core';
 
 var template = `
 <div class="gf-form-select-wrapper max-width-13">
-  <select class="gf-form-input" ng-model="model.repeat" ng-options="f.value as f.text for f in variables" ng-change="optionChanged()">
+  <select class="gf-form-input" ng-model="panel.repeat" ng-options="f.value as f.text for f in variables" ng-change="optionChanged()">
   <option value=""></option>
 </div>
 `;
@@ -13,7 +13,7 @@ function dashRepeatOptionDirective(variableSrv) {
     restrict: 'E',
     template: template,
     scope: {
-      model: "=",
+      panel: "=",
     },
     link: function(scope, element) {
       element.css({display: 'block', width: '100%'});

+ 0 - 26
public/app/features/dashboard/row/add_panel.html

@@ -1,26 +0,0 @@
-<div class="tabbed-view-header">
-	<h2 class="tabbed-view-title">
-		Add Panel
-	</h2>
-
-	<input type="text" class="gf-form-input max-width-14 pull-left" ng-model='ctrl.panelSearch' give-focus='true' ng-keydown="ctrl.keyDown($event)" ng-change="ctrl.panelSearchChanged()" placeholder="panel search filter"></input>
-
-	<button class="tabbed-view-close-btn" ng-click="ctrl.dismiss();">
-		<i class="fa fa-remove"></i>
-	</button>
-</div>
-
-<div class="tabbed-view-body tabbed-view-body--small">
-	<div class="add-panel-panels-scroll">
-    <div class="add-panel-panels">
-      <div class="add-panel-item"
-					ng-repeat="panel in ctrl.panelHits"
-					ng-class="{active: $index === ctrl.activeIndex}"
-					ng-click="ctrl.addPanel(panel)"
-          title="{{panel.name}}">
-        <img class="add-panel-item-img" ng-src="{{panel.info.logos.small}}"></img>
-        <div class="add-panel-item-name">{{panel.name}}</div>
-      </div>
-    </div>
-  </div>
-</div>

+ 0 - 114
public/app/features/dashboard/row/add_panel.ts

@@ -1,114 +0,0 @@
-///<reference path="../../../headers/common.d.ts" />
-
-import _ from 'lodash';
-
-import config from 'app/core/config';
-import {coreModule} from 'app/core/core';
-
-export class AddPanelCtrl {
-  dashboard: any;
-  allPanels: any;
-  panelHits: any;
-  activeIndex: any;
-  panelSearch: any;
-
-  /** @ngInject */
-  constructor(private $rootScope, dashboardSrv) {
-    this.dashboard = dashboardSrv.getCurrent();
-    this.activeIndex = 0;
-
-    this.allPanels = _.chain(config.panels)
-      .filter({hideFromList: false})
-      .map(item => item)
-      .orderBy('sort')
-      .value();
-
-    this.panelHits = this.allPanels;
-  }
-
-  dismiss() {
-    this.$rootScope.appEvent('hide-dash-editor');
-  }
-
-  keyDown(evt) {
-    if (evt.keyCode === 27) {
-      this.dismiss();
-      return;
-    }
-
-    if (evt.keyCode === 40 || evt.keyCode === 39) {
-      this.moveSelection(1);
-    }
-
-    if (evt.keyCode === 38 || evt.keyCode === 37) {
-      this.moveSelection(-1);
-    }
-
-    if (evt.keyCode === 13) {
-      var selectedPanel = this.panelHits[this.activeIndex];
-      if (selectedPanel) {
-        this.addPanel(selectedPanel);
-      }
-    }
-  }
-
-  moveSelection(direction) {
-    var max = this.panelHits.length;
-    var newIndex = this.activeIndex + direction;
-    this.activeIndex = ((newIndex %= max) < 0) ? newIndex + max : newIndex;
-  }
-
-  panelSearchChanged() {
-    var items = this.allPanels.slice();
-    var startsWith = [];
-    var contains = [];
-    var searchLower = this.panelSearch.toLowerCase();
-    var item;
-
-    while (item = items.shift()) {
-      var nameLower = item.name.toLowerCase();
-      if (nameLower.indexOf(searchLower) === 0) {
-        startsWith.push(item);
-      } else if (nameLower.indexOf(searchLower) !== -1) {
-        contains.push(item);
-      }
-    }
-
-    this.panelHits = startsWith.concat(contains);
-    this.activeIndex = 0;
-  }
-
-  addPanel(panelPluginInfo) {
-    let defaultHeight = 6;
-    let defaultWidth = 6;
-
-    if (panelPluginInfo.id === "singlestat") {
-      defaultWidth = 3;
-      defaultHeight = 3;
-    }
-
-    this.dashboard.addPanel({
-      type: panelPluginInfo.id,
-      x: 0,
-      y: 0,
-      width: defaultWidth,
-      height: defaultHeight,
-      title: 'New panel',
-    });
-
-    this.dismiss();
-  }
-}
-
-export function addPanelDirective() {
-  return {
-    restrict: 'E',
-    templateUrl: 'public/app/features/dashboard/row/add_panel.html',
-    controller: AddPanelCtrl,
-    bindToController: true,
-    controllerAs: 'ctrl',
-    scope: {},
-  };
-}
-
-coreModule.directive('addPanel', addPanelDirective);

+ 0 - 34
public/app/features/dashboard/row/options.html

@@ -1,34 +0,0 @@
-<div class="dash-row-dropview">
-	<a class="dash-row-dropview-close pointer" ng-click="ctrl.rowCtrl.closeDropView();">
-		<i class="fa fa-remove"></i>
-	</a>
-
-	<div>
-		<div class="section">
-			<div class="gf-form">
-				<span class="gf-form-label width-6">Title</span>
-				<input type="text" class="gf-form-input max-width-14" ng-model='ctrl.row.title'></input>
-			</div>
-			<div class="gf-form-inline">
-				<div class="gf-form">
-					<label class="gf-form-label width-6">Size</label>
-					<div class="gf-form-select-wrapper">
-						<select class="input-small gf-form-input" ng-model="ctrl.row.titleSize" ng-options="f for f in ctrl.fontSizes"></select>
-					</div>
-				</div>
-				<gf-form-switch class="gf-form" label="Show" checked="ctrl.row.showTitle">
-				</gf-form-switch>
-			</div>
-		</div>
-		<div class="section">
-			<div class="gf-form">
-				<span class="gf-form-label width-7">Height</span>
-				<input type="text" class="gf-form-input max-width-14" ng-model='ctrl.row.height'></input>
-			</div>
-			<div class="gf-form">
-				<span class="gf-form-label width-7">Repeat for</span>
-				<dash-repeat-option model="ctrl.row"></dash-repeat-option>
-			</div>
-		</div>
-	</div>
-</div>

+ 0 - 34
public/app/features/dashboard/row/options.ts

@@ -1,34 +0,0 @@
-///<reference path="../../../headers/common.d.ts" />
-
-import {coreModule} from 'app/core/core';
-// import VirtualScroll from 'virtual-scroll';
-// console.log(VirtualScroll);
-
-export class RowOptionsCtrl {
-  row: any;
-  dashboard: any;
-  rowCtrl: any;
-  fontSizes = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'];
-
-  /** @ngInject */
-  constructor() {
-    this.row = this.rowCtrl.row;
-    this.dashboard = this.rowCtrl.dashboard;
-    this.row.titleSize = this.row.titleSize || 'h6';
-  }
-}
-
-export function rowOptionsDirective() {
-  return {
-    restrict: 'E',
-    templateUrl: 'public/app/features/dashboard/row/options.html',
-    controller: RowOptionsCtrl,
-    bindToController: true,
-    controllerAs: 'ctrl',
-    scope: {
-      rowCtrl: "=",
-    },
-  };
-}
-
-coreModule.directive('dashRowOptions', rowOptionsDirective);

+ 0 - 11
public/app/features/dashboard/row/row.html

@@ -1,11 +0,0 @@
-<div class="dash-row-header">
-	<a class="dash-row-header-title" ng-click="ctrl.toggleCollapse()">
-		<span class="dash-row-collapse-toggle pointer">
-			<i class="fa fa-chevron-down" ng-show="!ctrl.row.collapse"></i>
-			<i class="fa fa-chevron-right" ng-show="ctrl.row.collapse"></i>
-		</span>
-		<span ng-class="ctrl.row.titleSize">{{ctrl.row.title | interpolateTemplateVars:this}}</span>
-	</a>
-</div>
-
-

+ 0 - 134
public/app/features/dashboard/row/row_model.ts

@@ -1,134 +0,0 @@
-///<reference path="../../../headers/common.d.ts" />
-
-import _ from 'lodash';
-import {Emitter, appEvents, assignModelProperties} from 'app/core/core';
-
-export class DashboardRow {
-  panels: any;
-  title: any;
-  showTitle: any;
-  titleSize: any;
-  events: Emitter;
-  span: number;
-  height: number;
-  collapse: boolean;
-
-  defaults = {
-    title: 'Dashboard Row',
-    panels: [],
-    showTitle: false,
-    titleSize: 'h6',
-    height: 250,
-    isNew: false,
-    repeat: null,
-    repeatRowId: null,
-    repeatIteration: null,
-    collapse: false,
-  };
-
-  constructor(private model) {
-    assignModelProperties(this, model, this.defaults);
-    this.events = new Emitter();
-    this.updateRowSpan();
-  }
-
-  getSaveModel() {
-    this.model = {};
-    assignModelProperties(this.model, this, this.defaults);
-
-    // remove properties that dont server persisted purpose
-    delete this.model.isNew;
-    return this.model;
-  }
-
-  updateRowSpan() {
-    this.span = 0;
-    for (let panel of this.panels) {
-      this.span += panel.span;
-    }
-  }
-
-  panelSpanChanged(alwaysSendEvent?) {
-    var oldSpan = this.span;
-    this.updateRowSpan();
-
-    if (alwaysSendEvent || oldSpan !== this.span) {
-      this.events.emit('span-changed');
-    }
-  }
-
-  addPanel(panel) {
-    var rowSpan = this.span;
-    var panelCount = this.panels.length;
-    var space = (12 - rowSpan) - panel.span;
-
-    // try to make room of there is no space left
-    if (space <= 0) {
-      if (panelCount === 1) {
-        this.panels[0].span = 6;
-        panel.span = 6;
-      } else if (panelCount === 2) {
-        this.panels[0].span = 4;
-        this.panels[1].span = 4;
-        panel.span = 4;
-      } else if (panelCount === 3) {
-        this.panels[0].span = 3;
-        this.panels[1].span = 3;
-        this.panels[2].span = 3;
-        panel.span = 3;
-      }
-    }
-
-    this.panels.push(panel);
-    this.events.emit('panel-added', panel);
-    this.panelSpanChanged();
-  }
-
-  removePanel(panel, ask?) {
-    if (ask !== false) {
-      var text2, confirmText;
-      if (panel.alert) {
-        text2 = "Panel includes an alert rule, removing panel will also remove alert rule";
-        confirmText = "YES";
-      }
-
-      appEvents.emit('confirm-modal', {
-        title: 'Remove Panel',
-        text: 'Are you sure you want to remove this panel?',
-        text2: text2,
-        icon: 'fa-trash',
-        confirmText: confirmText,
-        yesText: 'Remove',
-        onConfirm: () => {
-          this.removePanel(panel, false);
-        }
-      });
-      return;
-    }
-
-    var index = _.indexOf(this.panels, panel);
-    this.panels.splice(index, 1);
-    this.events.emit('panel-removed', panel);
-    this.panelSpanChanged();
-  }
-
-  movePanel(fromIndex, toIndex) {
-    this.panels.splice(toIndex, 0, this.panels.splice(fromIndex, 1)[0]);
-  }
-
-  destroy() {
-    this.events.removeAllListeners();
-  }
-
-  copyPropertiesFromRowSource(source) {
-    this.height = source.height;
-    this.title = source.title;
-    this.showTitle = source.showTitle;
-    this.titleSize = source.titleSize;
-  }
-
-  toggleCollapse() {
-    this.collapse = !this.collapse;
-  }
-}
-

+ 1 - 1
public/app/partials/panelgeneral.html

@@ -16,7 +16,7 @@
     <h5 class="section-heading">Repeat</h5>
 		<div class="gf-form">
 			<span class="gf-form-label width-9">For each value of</span>
-			<dash-repeat-option model="ctrl.panel"></dash-repeat-option>
+			<dash-repeat-option panel="ctrl.panel"></dash-repeat-option>
 		</div>
 		<div class="gf-form" ng-show="ctrl.panel.repeat">
 			<span class="gf-form-label width-9">Min width</span>

+ 2 - 2
public/sass/base/_icons.scss

@@ -1,8 +1,8 @@
 .gicon {
   line-height: 1;
   display: inline-block;
-  width: 1.2057142857em;
-  height: 1.2057142857em;
+  width: 1.1057142857em;
+  height: 1.1057142857em;
   text-align: center;
   background-repeat: no-repeat;
   background-position: center;

+ 0 - 4
public/sass/components/_dashboard_grid.scss

@@ -21,10 +21,6 @@
   }
 }
 
-.react-grid-item {
-  overflow: hidden;
-}
-
 .theme-dark {
   .react-grid-item > .react-resizable-handle {
     background-image: url('../img/resize-handle-white.svg');

+ 1 - 1
tslint.json

@@ -14,7 +14,7 @@
     "forin": false,
     "indent": [true, "spaces", 2],
     "label-position": true,
-    "max-line-length": [true, 140],
+    "max-line-length": [true, 150],
     "member-access": false,
     "no-arg": true,
     "no-bitwise": true,