mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
progress on new design
This commit is contained in:
parent
c609586ff0
commit
9c50893221
@ -79,6 +79,7 @@
|
||||
"tether": "^1.2.0",
|
||||
"tether-drop": "^1.4.2",
|
||||
"tslint": "^3.4.0",
|
||||
"typescript": "^1.7.5"
|
||||
"typescript": "^1.7.5",
|
||||
"virtual-scroll": "^1.1.1"
|
||||
}
|
||||
}
|
||||
|
211
public/app/core/components/scroll/scroll.ts
Normal file
211
public/app/core/components/scroll/scroll.ts
Normal file
@ -0,0 +1,211 @@
|
||||
// ///<reference path="../../headers/common.d.ts" />
|
||||
//
|
||||
// import _ from 'lodash';
|
||||
//
|
||||
// var objectAssign = require('object-assign');
|
||||
// var Emitter = require('tiny-emitter');
|
||||
// var Lethargy = require('lethargy').Lethargy;
|
||||
// var support = require('./support');
|
||||
// var clone = require('./clone');
|
||||
// var bindAll = require('bindall-standalone');
|
||||
// var EVT_ID = 'virtualscroll';
|
||||
//
|
||||
// var keyCodes = {
|
||||
// LEFT: 37,
|
||||
// UP: 38,
|
||||
// RIGHT: 39,
|
||||
// DOWN: 40
|
||||
// };
|
||||
//
|
||||
// function VirtualScroll(this: any, options) {
|
||||
// _.bindAll(this, '_onWheel', '_onMouseWheel', '_onTouchStart', '_onTouchMove', '_onKeyDown');
|
||||
//
|
||||
// this.el = window;
|
||||
// if (options && options.el) {
|
||||
// this.el = options.el;
|
||||
// delete options.el;
|
||||
// }
|
||||
//
|
||||
// this.options = _.assign({
|
||||
// mouseMultiplier: 1,
|
||||
// touchMultiplier: 2,
|
||||
// firefoxMultiplier: 15,
|
||||
// keyStep: 120,
|
||||
// preventTouch: false,
|
||||
// unpreventTouchClass: 'vs-touchmove-allowed',
|
||||
// limitInertia: false
|
||||
// }, options);
|
||||
//
|
||||
// if (this.options.limitInertia) this._lethargy = new Lethargy();
|
||||
//
|
||||
// this._emitter = new Emitter();
|
||||
// this._event = {
|
||||
// y: 0,
|
||||
// x: 0,
|
||||
// deltaX: 0,
|
||||
// deltaY: 0
|
||||
// };
|
||||
//
|
||||
// this.touchStartX = null;
|
||||
// this.touchStartY = null;
|
||||
// this.bodyTouchAction = null;
|
||||
// }
|
||||
//
|
||||
// VirtualScroll.prototype._notify = function(e) {
|
||||
// var evt = this._event;
|
||||
// evt.x += evt.deltaX;
|
||||
// evt.y += evt.deltaY;
|
||||
//
|
||||
// this._emitter.emit(EVT_ID, {
|
||||
// x: evt.x,
|
||||
// y: evt.y,
|
||||
// deltaX: evt.deltaX,
|
||||
// deltaY: evt.deltaY,
|
||||
// originalEvent: e
|
||||
// });
|
||||
// };
|
||||
//
|
||||
// VirtualScroll.prototype._onWheel = function(e) {
|
||||
// var options = this.options;
|
||||
// if (this._lethargy && this._lethargy.check(e) === false) return;
|
||||
//
|
||||
// var evt = this._event;
|
||||
//
|
||||
// // In Chrome and in Firefox (at least the new one)
|
||||
// evt.deltaX = e.wheelDeltaX || e.deltaX * -1;
|
||||
// evt.deltaY = e.wheelDeltaY || e.deltaY * -1;
|
||||
//
|
||||
// // for our purpose deltamode = 1 means user is on a wheel mouse, not touch pad
|
||||
// // real meaning: https://developer.mozilla.org/en-US/docs/Web/API/WheelEvent#Delta_modes
|
||||
// if(support.isFirefox && e.deltaMode == 1) {
|
||||
// evt.deltaX *= options.firefoxMultiplier;
|
||||
// evt.deltaY *= options.firefoxMultiplier;
|
||||
// }
|
||||
//
|
||||
// evt.deltaX *= options.mouseMultiplier;
|
||||
// evt.deltaY *= options.mouseMultiplier;
|
||||
//
|
||||
// this._notify(e);
|
||||
// };
|
||||
//
|
||||
// VirtualScroll.prototype._onMouseWheel = function(e) {
|
||||
// if (this.options.limitInertia && this._lethargy.check(e) === false) return;
|
||||
//
|
||||
// var evt = this._event;
|
||||
//
|
||||
// // In Safari, IE and in Chrome if 'wheel' isn't defined
|
||||
// evt.deltaX = (e.wheelDeltaX) ? e.wheelDeltaX : 0;
|
||||
// evt.deltaY = (e.wheelDeltaY) ? e.wheelDeltaY : e.wheelDelta;
|
||||
//
|
||||
// this._notify(e);
|
||||
// };
|
||||
//
|
||||
// VirtualScroll.prototype._onTouchStart = function(e) {
|
||||
// var t = (e.targetTouches) ? e.targetTouches[0] : e;
|
||||
// this.touchStartX = t.pageX;
|
||||
// this.touchStartY = t.pageY;
|
||||
// };
|
||||
//
|
||||
// VirtualScroll.prototype._onTouchMove = function(e) {
|
||||
// var options = this.options;
|
||||
// if(options.preventTouch
|
||||
// && !e.target.classList.contains(options.unpreventTouchClass)) {
|
||||
// e.preventDefault();
|
||||
// }
|
||||
//
|
||||
// var evt = this._event;
|
||||
//
|
||||
// var t = (e.targetTouches) ? e.targetTouches[0] : e;
|
||||
//
|
||||
// evt.deltaX = (t.pageX - this.touchStartX) * options.touchMultiplier;
|
||||
// evt.deltaY = (t.pageY - this.touchStartY) * options.touchMultiplier;
|
||||
//
|
||||
// this.touchStartX = t.pageX;
|
||||
// this.touchStartY = t.pageY;
|
||||
//
|
||||
// this._notify(e);
|
||||
// };
|
||||
//
|
||||
// VirtualScroll.prototype._onKeyDown = function(e) {
|
||||
// var evt = this._event;
|
||||
// evt.deltaX = evt.deltaY = 0;
|
||||
//
|
||||
// switch(e.keyCode) {
|
||||
// case keyCodes.LEFT:
|
||||
// case keyCodes.UP:
|
||||
// evt.deltaY = this.options.keyStep;
|
||||
// break;
|
||||
//
|
||||
// case keyCodes.RIGHT:
|
||||
// case keyCodes.DOWN:
|
||||
// evt.deltaY = - this.options.keyStep;
|
||||
// break;
|
||||
//
|
||||
// default:
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// this._notify(e);
|
||||
// };
|
||||
//
|
||||
// VirtualScroll.prototype._bind = function() {
|
||||
// if(support.hasWheelEvent) this.el.addEventListener('wheel', this._onWheel);
|
||||
// if(support.hasMouseWheelEvent) this.el.addEventListener('mousewheel', this._onMouseWheel);
|
||||
//
|
||||
// if(support.hasTouch) {
|
||||
// this.el.addEventListener('touchstart', this._onTouchStart);
|
||||
// this.el.addEventListener('touchmove', this._onTouchMove);
|
||||
// }
|
||||
//
|
||||
// if(support.hasPointer && support.hasTouchWin) {
|
||||
// this.bodyTouchAction = document.body.style.msTouchAction;
|
||||
// document.body.style.msTouchAction = 'none';
|
||||
// this.el.addEventListener('MSPointerDown', this._onTouchStart, true);
|
||||
// this.el.addEventListener('MSPointerMove', this._onTouchMove, true);
|
||||
// }
|
||||
//
|
||||
// if(support.hasKeyDown) document.addEventListener('keydown', this._onKeyDown);
|
||||
// };
|
||||
//
|
||||
// VirtualScroll.prototype._unbind = function() {
|
||||
// if(support.hasWheelEvent) this.el.removeEventListener('wheel', this._onWheel);
|
||||
// if(support.hasMouseWheelEvent) this.el.removeEventListener('mousewheel', this._onMouseWheel);
|
||||
//
|
||||
// if(support.hasTouch) {
|
||||
// this.el.removeEventListener('touchstart', this._onTouchStart);
|
||||
// this.el.removeEventListener('touchmove', this._onTouchMove);
|
||||
// }
|
||||
//
|
||||
// if(support.hasPointer && support.hasTouchWin) {
|
||||
// document.body.style.msTouchAction = this.bodyTouchAction;
|
||||
// this.el.removeEventListener('MSPointerDown', this._onTouchStart, true);
|
||||
// this.el.removeEventListener('MSPointerMove', this._onTouchMove, true);
|
||||
// }
|
||||
//
|
||||
// if(support.hasKeyDown) document.removeEventListener('keydown', this._onKeyDown);
|
||||
// };
|
||||
//
|
||||
// VirtualScroll.prototype.on = function(cb, ctx) {
|
||||
// this._emitter.on(EVT_ID, cb, ctx);
|
||||
//
|
||||
// var events = this._emitter.e;
|
||||
// if (events && events[EVT_ID] && events[EVT_ID].length === 1) this._bind();
|
||||
// };
|
||||
//
|
||||
// VirtualScroll.prototype.off = function(cb, ctx) {
|
||||
// this._emitter.off(EVT_ID, cb, ctx);
|
||||
//
|
||||
// var events = this._emitter.e;
|
||||
// if (!events[EVT_ID] || events[EVT_ID].length <= 0) this._unbind();
|
||||
// };
|
||||
//
|
||||
// VirtualScroll.prototype.reset = function() {
|
||||
// var evt = this._event;
|
||||
// evt.x = 0;
|
||||
// evt.y = 0;
|
||||
// };
|
||||
//
|
||||
// VirtualScroll.prototype.destroy = function() {
|
||||
// this._emitter.off();
|
||||
// this._unbind();
|
||||
// };
|
58
public/app/features/dashboard/row/add_panel.html
Normal file
58
public/app/features/dashboard/row/add_panel.html
Normal file
@ -0,0 +1,58 @@
|
||||
<div class="dash-row-options">
|
||||
|
||||
<div class="gf-form-inline">
|
||||
<div class="gf-form">
|
||||
<span class="gf-form-label">Panel search</span>
|
||||
<input type="text" class="gf-form-input max-width-14" ng-model='ctrl.panelSearch' give-focus='true' ng-keydown="ctrl.keyDown($event)" ng-change="ctrl.panelSearchChanged()"></input>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<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)">
|
||||
<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>
|
||||
|
||||
<div class="edit-tab-content" ng-if="ctrl.subTabIndex === 1">
|
||||
<div class="gf-form-group">
|
||||
<h5 class="section-heading">Options</h5>
|
||||
<div class="gf-form-inline">
|
||||
<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">
|
||||
<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 class="gf-form-inline">
|
||||
<div class="gf-form">
|
||||
<span class="gf-form-label width-6">Height</span>
|
||||
<input type="text" class="gf-form-input max-width-14" ng-model='ctrl.row.height'></input>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h5 class="section-heading">Row Templating</h5>
|
||||
|
||||
<div class="gf-form-group">
|
||||
<div class="gf-form">
|
||||
<span class="gf-form-label">Repeat Row</span>
|
||||
<div class="gf-form-select-wrapper max-width-10">
|
||||
<select class="gf-form-input" ng-model="row.repeat" ng-options="f.name as f.name for f in dashboard.templating.list">
|
||||
<option value=""></option>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
113
public/app/features/dashboard/row/add_panel.ts
Normal file
113
public/app/features/dashboard/row/add_panel.ts
Normal file
@ -0,0 +1,113 @@
|
||||
///<reference path="../../../headers/common.d.ts" />
|
||||
|
||||
import _ from 'lodash';
|
||||
|
||||
import config from 'app/core/config';
|
||||
import {coreModule, appEvents} from 'app/core/core';
|
||||
// import VirtualScroll from 'virtual-scroll';
|
||||
// console.log(VirtualScroll);
|
||||
|
||||
export class AddPanelCtrl {
|
||||
row: any;
|
||||
dashboard: any;
|
||||
rowCtrl: any;
|
||||
allPanels: any;
|
||||
panelHits: any;
|
||||
activeIndex: any;
|
||||
panelSearch: any;
|
||||
|
||||
/** @ngInject */
|
||||
constructor(private $scope, private $timeout, private $rootScope) {
|
||||
this.row = this.rowCtrl.row;
|
||||
this.dashboard = this.rowCtrl.dashboard;
|
||||
this.allPanels = _.orderBy(_.map(config.panels, item => item), 'sort');
|
||||
this.panelHits = this.allPanels;
|
||||
this.activeIndex = 0;
|
||||
}
|
||||
|
||||
keyDown(evt) {
|
||||
if (evt.keyCode === 27) {
|
||||
this.rowCtrl.showOptions = false;
|
||||
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) {
|
||||
var defaultSpan = 12;
|
||||
var _as = 12 - this.dashboard.rowSpan(this.row);
|
||||
|
||||
var panel = {
|
||||
id: null,
|
||||
title: config.new_panel_title,
|
||||
error: false,
|
||||
span: _as < defaultSpan && _as > 0 ? _as : defaultSpan,
|
||||
editable: true,
|
||||
type: panelPluginInfo.id,
|
||||
isNew: true,
|
||||
};
|
||||
|
||||
this.rowCtrl.dropView = 0;
|
||||
this.dashboard.addPanel(panel, this.row);
|
||||
this.$timeout(() => {
|
||||
this.$rootScope.appEvent('panel-change-view', {
|
||||
fullscreen: true, edit: true, panelId: panel.id
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export function addPanelDirective() {
|
||||
return {
|
||||
restrict: 'E',
|
||||
templateUrl: 'public/app/features/dashboard/row/add_panel.html',
|
||||
controller: AddPanelCtrl,
|
||||
bindToController: true,
|
||||
controllerAs: 'ctrl',
|
||||
scope: {
|
||||
rowCtrl: "=",
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
coreModule.directive('dashRowAddPanel', addPanelDirective);
|
@ -1,77 +1,39 @@
|
||||
<div class="dash-row-options">
|
||||
|
||||
<div class="edit-tab-with-sidemenu">
|
||||
<aside class="edit-sidemenu-aside">
|
||||
<ul class="edit-sidemenu">
|
||||
<li ng-class="{active: ctrl.subTabIndex === 0}">
|
||||
<a ng-click="ctrl.subTabIndex = 0">Add Panel</a>
|
||||
</li>
|
||||
<li ng-class="{active: ctrl.subTabIndex === 1}">
|
||||
<a ng-click="ctrl.subTabIndex = 1">Row Options</a>
|
||||
</li>
|
||||
<li ng-class="{active: ctrl.subTabIndex === 2}">
|
||||
<a ng-click="ctrl.deleteRow()">Delete</a>
|
||||
</li>
|
||||
</ul>
|
||||
</aside>
|
||||
|
||||
<div class="edit-tab-content" ng-if="ctrl.subTabIndex === 0">
|
||||
<h5 class="section-heading">Add Panel</h5>
|
||||
<div class="gf-form-inline">
|
||||
<div class="gf-form">
|
||||
<span class="gf-form-label width-6">Search</span>
|
||||
<input type="text" class="gf-form-input max-width-14" ng-model='ctrl.panelSearch' give-focus='true' ng-keydown="ctrl.keyDown($event)" ng-change="ctrl.panelSearchChanged()"></input>
|
||||
<div class="gf-form-group">
|
||||
<h5 class="section-heading">Options</h5>
|
||||
<div class="gf-form-inline">
|
||||
<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">
|
||||
<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>
|
||||
|
||||
<div class="add-panel-panels-wrapper">
|
||||
<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)">
|
||||
<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>
|
||||
|
||||
<gf-form-switch class="gf-form" label="Show" checked="ctrl.row.showTitle">
|
||||
</gf-form-switch>
|
||||
</div>
|
||||
|
||||
<div class="edit-tab-content" ng-if="ctrl.subTabIndex === 1">
|
||||
<div class="gf-form-group">
|
||||
<h5 class="section-heading">Options</h5>
|
||||
<div class="gf-form-inline">
|
||||
<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">
|
||||
<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 class="gf-form-inline">
|
||||
<div class="gf-form">
|
||||
<span class="gf-form-label width-6">Height</span>
|
||||
<input type="text" class="gf-form-input max-width-14" ng-model='ctrl.row.height'></input>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h5 class="section-heading">Row Templating</h5>
|
||||
|
||||
<div class="gf-form-group">
|
||||
<div class="gf-form">
|
||||
<span class="gf-form-label">Repeat Row</span>
|
||||
<div class="gf-form-select-wrapper max-width-10">
|
||||
<select class="gf-form-input" ng-model="row.repeat" ng-options="f.name as f.name for f in dashboard.templating.list">
|
||||
<option value=""></option>
|
||||
</div>
|
||||
</div>
|
||||
<div class="gf-form-inline">
|
||||
<div class="gf-form">
|
||||
<span class="gf-form-label width-6">Height</span>
|
||||
<input type="text" class="gf-form-input max-width-14" ng-model='ctrl.row.height'></input>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h5 class="section-heading">Row Templating</h5>
|
||||
|
||||
<div class="gf-form-group">
|
||||
<div class="gf-form">
|
||||
<span class="gf-form-label">Repeat Row</span>
|
||||
<div class="gf-form-select-wrapper max-width-10">
|
||||
<select class="gf-form-input" ng-model="row.repeat" ng-options="f.name as f.name for f in dashboard.templating.list">
|
||||
<option value=""></option>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -4,99 +4,20 @@ import _ from 'lodash';
|
||||
|
||||
import config from 'app/core/config';
|
||||
import {coreModule, appEvents} from 'app/core/core';
|
||||
// import VirtualScroll from 'virtual-scroll';
|
||||
// console.log(VirtualScroll);
|
||||
|
||||
export class RowOptionsCtrl {
|
||||
row: any;
|
||||
dashboard: any;
|
||||
rowCtrl: any;
|
||||
subTabIndex: number;
|
||||
allPanels: any;
|
||||
panelHits: any;
|
||||
activeIndex: any;
|
||||
panelSearch: any;
|
||||
|
||||
fontSizes = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'];
|
||||
|
||||
/** @ngInject */
|
||||
constructor(private $scope, private $timeout, private $rootScope) {
|
||||
this.row = this.rowCtrl.row;
|
||||
this.dashboard = this.rowCtrl.dashboard;
|
||||
this.subTabIndex = 0;
|
||||
this.row.titleSize = this.row.titleSize || 'h6';
|
||||
this.allPanels = _.orderBy(_.map(config.panels, item => item), 'sort');
|
||||
this.panelHits = this.allPanels;
|
||||
this.activeIndex = 0;
|
||||
}
|
||||
|
||||
keyDown(evt) {
|
||||
if (evt.keyCode === 27) {
|
||||
this.rowCtrl.showOptions = false;
|
||||
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) {
|
||||
var defaultSpan = 12;
|
||||
var _as = 12 - this.dashboard.rowSpan(this.row);
|
||||
|
||||
var panel = {
|
||||
id: null,
|
||||
title: config.new_panel_title,
|
||||
error: false,
|
||||
span: _as < defaultSpan && _as > 0 ? _as : defaultSpan,
|
||||
editable: true,
|
||||
type: panelPluginInfo.id,
|
||||
isNew: true,
|
||||
};
|
||||
|
||||
this.rowCtrl.showOptions = false;
|
||||
this.dashboard.addPanel(panel, this.row);
|
||||
this.$timeout(() => {
|
||||
this.$rootScope.appEvent('panel-change-view', {
|
||||
fullscreen: true, edit: true, panelId: panel.id
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
deleteRow() {
|
||||
|
@ -1,21 +1,27 @@
|
||||
<div class="dash-row-header">
|
||||
<a class="dash-row-header-title" ng-click="ctrl.showOptions = !ctrl.showOptions">
|
||||
<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}}</span>
|
||||
<i class="fa fa-caret-down"></i>
|
||||
</a>
|
||||
|
||||
<div class="dash-row-header-spacer">
|
||||
</div>
|
||||
|
||||
<div class="dash-row-collapse-toggle" ng-click="ctrl.row.collapse = !ctrl.row.collapse">
|
||||
<a class="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>
|
||||
</a>
|
||||
<div class="dash-row-header-actions">
|
||||
<a class="pointer" ng-click="ctrl.showAddPanel()">Add Panel <i class="fa fa-plus"></i></a>
|
||||
<a class="pointer" ng-click="ctrl.showRowOptions()">Row Options <i class="fa fa-cog"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div ng-if="ctrl.showOptions">
|
||||
|
||||
<div ng-if="ctrl.dropView === 1">
|
||||
<dash-row-add-panel row-ctrl="ctrl"></dash-row-add-panel>
|
||||
</div>
|
||||
|
||||
<div ng-if="ctrl.dropView === 2">
|
||||
<dash-row-options row-ctrl="ctrl"></dash-row-options>
|
||||
</div>
|
||||
|
||||
|
@ -8,18 +8,19 @@ import config from 'app/core/config';
|
||||
import {coreModule} from 'app/core/core';
|
||||
|
||||
import './options';
|
||||
import './add_panel';
|
||||
|
||||
export class DashRowCtrl {
|
||||
dashboard: any;
|
||||
row: any;
|
||||
showOptions: boolean;
|
||||
dropView: number;
|
||||
|
||||
/** @ngInject */
|
||||
constructor(private $scope, private $rootScope, private $timeout, private uiSegmentSrv, private $q) {
|
||||
this.row.title = this.row.title || 'Row title';
|
||||
|
||||
if (this.row.isNew) {
|
||||
this.showOptions = true;
|
||||
this.dropView = 1;
|
||||
delete this.row.isNew;
|
||||
}
|
||||
}
|
||||
@ -76,6 +77,19 @@ export class DashRowCtrl {
|
||||
_.move(rowsList, rowIndex, newIndex);
|
||||
}
|
||||
}
|
||||
|
||||
toggleCollapse() {
|
||||
this.dropView = 0;
|
||||
this.row.collapse = !this.row.collapse;
|
||||
}
|
||||
|
||||
showAddPanel() {
|
||||
this.dropView = this.dropView === 1 ? 0 : 1;
|
||||
}
|
||||
|
||||
showRowOptions() {
|
||||
this.dropView = this.dropView === 2 ? 0 : 2;
|
||||
}
|
||||
}
|
||||
|
||||
export function rowDirective($rootScope) {
|
||||
|
5
public/app/headers/common.d.ts
vendored
5
public/app/headers/common.d.ts
vendored
@ -52,3 +52,8 @@ declare module 'eventemitter3' {
|
||||
var config: any;
|
||||
export default config;
|
||||
}
|
||||
|
||||
declare module 'virtual-scroll' {
|
||||
var config: any;
|
||||
export default config;
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ System.config({
|
||||
defaultJSExtenions: true,
|
||||
baseURL: 'public',
|
||||
paths: {
|
||||
'virtual-scroll': 'vendor/npm/virtual-scroll/src/index.js',
|
||||
'remarkable': 'vendor/npm/remarkable/dist/remarkable.js',
|
||||
'tether': 'vendor/npm/tether/dist/js/tether.js',
|
||||
'eventemitter3': 'vendor/npm/eventemitter3/index.js',
|
||||
@ -52,6 +53,10 @@ System.config({
|
||||
},
|
||||
|
||||
meta: {
|
||||
'vendor/npm/virtual-scroll/src/indx.js': {
|
||||
format: 'cjs',
|
||||
exports: 'VirtualScroll',
|
||||
},
|
||||
'vendor/angular/angular.js': {
|
||||
format: 'global',
|
||||
deps: ['jquery'],
|
||||
|
@ -6,10 +6,11 @@
|
||||
|
||||
.edit-tab-content {
|
||||
flex-grow: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.edit-sidemenu-aside {
|
||||
min-width: 16rem;
|
||||
min-width: 15rem;
|
||||
}
|
||||
|
||||
.edit-sidemenu {
|
||||
|
@ -206,24 +206,54 @@ div.flot-text {
|
||||
//
|
||||
|
||||
.dash-row {
|
||||
border-left: 1px solid $dark-2;
|
||||
}
|
||||
|
||||
.dash-row-header {
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
margin-right: $panel-margin;
|
||||
margin-left: $gf-form-margin;
|
||||
border-bottom: $panel-border;
|
||||
border-bottom: 1px solid $dark-4;
|
||||
|
||||
&:hover {
|
||||
.dash-row-header-actions {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.dash-row-header-title {
|
||||
padding: 0.7rem;
|
||||
i {
|
||||
font-size: 0.9rem;
|
||||
position: relative;
|
||||
top: 2px;
|
||||
left: 1px;
|
||||
padding: 0.6rem;
|
||||
|
||||
.dash-row-collapse-toggle {
|
||||
font-size: $font-size-sm;
|
||||
color: $text-muted;
|
||||
position: relative;
|
||||
left: -5px;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
.dash-row-collapse-toggle {
|
||||
color: $link-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.dash-row-header-actions {
|
||||
position: absolute;
|
||||
display: none;
|
||||
color: $text-muted;
|
||||
font-size: $font-size-sm;
|
||||
bottom: 5px;
|
||||
right: 1rem;
|
||||
a {
|
||||
color: $text-muted;
|
||||
padding-left: 1rem;
|
||||
&:hover {
|
||||
color: $link-hover-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -242,20 +272,6 @@ div.flot-text {
|
||||
flex: 50;
|
||||
}
|
||||
|
||||
.dash-row-collapse-toggle {
|
||||
flex-grow: 30;
|
||||
cursor: pointer;
|
||||
text-align: right;
|
||||
margin-right: 0.6rem;
|
||||
font-size: $font-size-sm;
|
||||
line-height: 2.5rem;
|
||||
a {
|
||||
color: $text-muted;
|
||||
}
|
||||
&:hover a {
|
||||
color: $link-color;
|
||||
}
|
||||
}
|
||||
|
||||
.dash-edit-mode {
|
||||
.dash-row {
|
||||
@ -287,17 +303,23 @@ div.flot-text {
|
||||
}
|
||||
}
|
||||
|
||||
.add-panel-panels-scroll {
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.add-panel-panels {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.add-panel-item {
|
||||
background: $input-label-bg;
|
||||
padding: $spacer;
|
||||
min-width: 10rem;
|
||||
max-width: 10rem;
|
||||
min-width: 9rem;
|
||||
max-width: 9rem;
|
||||
text-align: center;
|
||||
margin: $gf-form-margin;
|
||||
float: left;
|
||||
cursor: pointer;
|
||||
|
||||
&.active,
|
||||
@ -313,5 +335,5 @@ div.flot-text {
|
||||
}
|
||||
|
||||
.add-panel-item-img {
|
||||
width: 3.5rem;
|
||||
width: 3rem;
|
||||
}
|
||||
|
@ -31,6 +31,8 @@ module.exports = function(config) {
|
||||
'tether-drop/**/*',
|
||||
'tether-drop/**/*',
|
||||
'remarkable/dist/*',
|
||||
'remarkable/dist/*',
|
||||
'virtual-scroll/**/*',
|
||||
],
|
||||
dest: '<%= srcDir %>/vendor/npm'
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user