mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
parent
3fe94734f4
commit
a14ead5ca7
@ -11,7 +11,8 @@ define([
|
|||||||
'angular-sanitize',
|
'angular-sanitize',
|
||||||
'angular-strap',
|
'angular-strap',
|
||||||
'angular-dragdrop',
|
'angular-dragdrop',
|
||||||
'extend-jquery'
|
'extend-jquery',
|
||||||
|
'bindonce'
|
||||||
],
|
],
|
||||||
function (angular, $, _, appLevelRequire) {
|
function (angular, $, _, appLevelRequire) {
|
||||||
"use strict";
|
"use strict";
|
||||||
@ -84,7 +85,8 @@ function (angular, $, _, appLevelRequire) {
|
|||||||
'$strap.directives',
|
'$strap.directives',
|
||||||
'ngSanitize',
|
'ngSanitize',
|
||||||
'ngDragDrop',
|
'ngDragDrop',
|
||||||
'kibana'
|
'kibana',
|
||||||
|
'pasvaz.bindonce'
|
||||||
];
|
];
|
||||||
|
|
||||||
_.each('controllers directives factories services filters'.split(' '),
|
_.each('controllers directives factories services filters'.split(' '),
|
||||||
|
@ -20,6 +20,7 @@ require.config({
|
|||||||
'angular-sanitize': '../vendor/angular/angular-sanitize',
|
'angular-sanitize': '../vendor/angular/angular-sanitize',
|
||||||
timepicker: '../vendor/angular/timepicker',
|
timepicker: '../vendor/angular/timepicker',
|
||||||
datepicker: '../vendor/angular/datepicker',
|
datepicker: '../vendor/angular/datepicker',
|
||||||
|
bindonce: '../vendor/angular/bindonce',
|
||||||
|
|
||||||
underscore: 'components/underscore.extended',
|
underscore: 'components/underscore.extended',
|
||||||
'underscore-src': '../vendor/underscore',
|
'underscore-src': '../vendor/underscore',
|
||||||
@ -84,7 +85,7 @@ require.config({
|
|||||||
'angular-resource': ['angular'],
|
'angular-resource': ['angular'],
|
||||||
'angular-route': ['angular'],
|
'angular-route': ['angular'],
|
||||||
'angular-touch': ['angular'],
|
'angular-touch': ['angular'],
|
||||||
|
'bindonce': ['angular'],
|
||||||
'angular-strap': ['angular', 'bootstrap','timepicker', 'datepicker'],
|
'angular-strap': ['angular', 'bootstrap','timepicker', 'datepicker'],
|
||||||
|
|
||||||
timepicker: ['jquery', 'bootstrap'],
|
timepicker: ['jquery', 'bootstrap'],
|
||||||
|
@ -42,7 +42,7 @@
|
|||||||
<select class="input-small" ng-model="panel.style['font-size']" ng-options="f for f in ['7pt','8pt','9pt','10pt','12pt','14pt','16pt','18pt','20pt','24pt','28pt','32pt','36pt','42pt','48pt','52pt','60pt','72pt']"></select></span>
|
<select class="input-small" ng-model="panel.style['font-size']" ng-options="f for f in ['7pt','8pt','9pt','10pt','12pt','14pt','16pt','18pt','20pt','24pt','28pt','32pt','36pt','42pt','48pt','52pt','60pt','72pt']"></select></span>
|
||||||
</div>
|
</div>
|
||||||
<div class="span2">
|
<div class="span2">
|
||||||
<h6>Trim Factor <tip>Trim fields to this long divided by # of rows</tip></h6>
|
<h6>Trim Factor <tip>Trim fields to this long divided by # of rows. Requires data refresh.</tip></h6>
|
||||||
<input type="number" class="input-small" ng-model="panel.trimFactor">
|
<input type="number" class="input-small" ng-model="panel.trimFactor" ng-change="set_refresh(true)">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
@ -8,7 +8,7 @@
|
|||||||
</style>
|
</style>
|
||||||
|
|
||||||
<div class="row-fluid">
|
<div class="row-fluid">
|
||||||
<div ng-class="{'span3':panel.field_list}" ng-show="panel.field_list">
|
<div ng-class="{'span3':panel.field_list}" ng-if="panel.field_list">
|
||||||
<div class="sidebar-nav">
|
<div class="sidebar-nav">
|
||||||
<strong>Fields <i class=" icon-chevron-sign-left pointer " ng-click="panel.field_list = !panel.field_list" bs-tooltip="'Hide field list'" ng-show="panel.field_list"></i></strong><p>
|
<strong>Fields <i class=" icon-chevron-sign-left pointer " ng-click="panel.field_list = !panel.field_list" bs-tooltip="'Hide field list'" ng-show="panel.field_list"></i></strong><p>
|
||||||
<div class="small">
|
<div class="small">
|
||||||
@ -17,13 +17,15 @@
|
|||||||
</div>
|
</div>
|
||||||
<div><input type="text" class="input-medium" placeholder="Type to filter..." ng-model="fieldFilter"></div>
|
<div><input type="text" class="input-medium" placeholder="Type to filter..." ng-model="fieldFilter"></div>
|
||||||
|
|
||||||
|
<ul class="unstyled" style="{{panel.overflow}}:{{panel.height || row.height}};overflow-y:auto;overflow-x:hidden;" ng-if="panel.all_fields">
|
||||||
<ul class="unstyled" style="{{panel.overflow}}:{{panel.height || row.height}};overflow-y:auto;overflow-x:hidden;">
|
<li ng-style="panel.style" ng-repeat="field in fields.list|filter:fieldFilter|orderBy:identity">
|
||||||
<li ng-style="panel.style" ng-repeat="field in fields.list|filter:fieldFilter|orderBy:identity" ng-show="panel.all_fields">
|
|
||||||
<i class="pointer" ng-class="{'icon-check': _.contains(panel.fields,field),'icon-check-empty': !_.contains(panel.fields,field)}" ng-click="toggle_field(field)"></i>
|
<i class="pointer" ng-class="{'icon-check': _.contains(panel.fields,field),'icon-check-empty': !_.contains(panel.fields,field)}" ng-click="toggle_field(field)"></i>
|
||||||
<a class="pointer" data-unique="1" bs-popover="'app/panels/table/micropanel.html'" data-placement="rightTop" ng-click="toggle_micropanel(field,true)" ng-class="{label: _.contains(panel.fields,field)}">{{field}}</a>
|
<a class="pointer" data-unique="1" bs-popover="'app/panels/table/micropanel.html'" data-placement="rightTop" ng-click="toggle_micropanel(field,true)" ng-class="{label: _.contains(panel.fields,field)}">{{field}}</a>
|
||||||
</li>
|
</li>
|
||||||
<li ng-style="panel.style" ng-repeat="field in current_fields|filter:fieldFilter|orderBy:identity" ng-hide="panel.all_fields">
|
</ul>
|
||||||
|
|
||||||
|
<ul class="unstyled" style="{{panel.overflow}}:{{panel.height || row.height}};overflow-y:auto;overflow-x:hidden;" ng-if="!panel.all_fields">
|
||||||
|
<li ng-style="panel.style" ng-repeat="field in current_fields|filter:fieldFilter|orderBy:identity">
|
||||||
<i class="pointer" ng-class="{'icon-check': _.contains(panel.fields,field),'icon-check-empty': !_.contains(panel.fields,field)}" ng-click="toggle_field(field)"></i>
|
<i class="pointer" ng-class="{'icon-check': _.contains(panel.fields,field),'icon-check-empty': !_.contains(panel.fields,field)}" ng-click="toggle_field(field)"></i>
|
||||||
<a class="pointer" data-unique="1" bs-popover="'app/panels/table/micropanel.html'" data-placement="rightTop" ng-click="toggle_micropanel(field,true)" ng-class="{label: _.contains(panel.fields,field)}">{{field}}</a>
|
<a class="pointer" data-unique="1" bs-popover="'app/panels/table/micropanel.html'" data-placement="rightTop" ng-click="toggle_micropanel(field,true)" ng-class="{label: _.contains(panel.fields,field)}">{{field}}</a>
|
||||||
</li>
|
</li>
|
||||||
@ -61,12 +63,12 @@
|
|||||||
</th>
|
</th>
|
||||||
|
|
||||||
</thead>
|
</thead>
|
||||||
<tbody ng-repeat="event in data| slice:panel.offset:panel.offset+panel.size" ng-class-odd="'odd'">
|
<tbody bindonce ng-repeat="event in data| slice:panel.offset:panel.offset+panel.size" ng-class-odd="'odd'">
|
||||||
<tr ng-click="toggle_details(event)" class="pointer">
|
<tr ng-click="toggle_details(event)" class="pointer">
|
||||||
<td ng-show="panel.fields.length<1">{{event._source|stringify|tableTruncate:panel.trimFactor:1}}</td>
|
<td ng-if="panel.fields.length<1" bo-text="event._source|stringify|tableTruncate:panel.trimFactor:1"></td>
|
||||||
<td ng-show="panel.fields.length>0" ng-repeat="field in panel.fields" ng-bind-html-unsafe="(event.kibana.highlight[field]||event.kibana._source[field]) |tableHighlight | tableTruncate:panel.trimFactor:panel.fields.length"></td>
|
<td ng-show="panel.fields.length>0" ng-repeat="field in panel.fields" bo-html="(event.kibana.highlight[field]||event.kibana._source[field]) |tableHighlight | tableTruncate:panel.trimFactor:panel.fields.length"></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr ng-show="event.kibana.details">
|
<tr ng-if="event.kibana.details">
|
||||||
<td colspan={{panel.fields.length}} ng-switch="event.kibana.view">
|
<td colspan={{panel.fields.length}} ng-switch="event.kibana.view">
|
||||||
<span>
|
<span>
|
||||||
View:
|
View:
|
||||||
|
270
src/vendor/angular/bindonce.js
vendored
Normal file
270
src/vendor/angular/bindonce.js
vendored
Normal file
@ -0,0 +1,270 @@
|
|||||||
|
'use strict';
|
||||||
|
/**
|
||||||
|
* Bindonce - Zero watches binding for AngularJs
|
||||||
|
* @version v0.2.1 - 2013-05-07
|
||||||
|
* @link https://github.com/Pasvaz/bindonce
|
||||||
|
* @author Pasquale Vazzana <pasqualevazzana@gmail.com>
|
||||||
|
* @license MIT License, http://www.opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
angular.module('pasvaz.bindonce', [])
|
||||||
|
|
||||||
|
.directive('bindonce', function()
|
||||||
|
{
|
||||||
|
console.log('called');
|
||||||
|
var toBoolean = function(value)
|
||||||
|
{
|
||||||
|
if (value && value.length !== 0)
|
||||||
|
{
|
||||||
|
var v = angular.lowercase("" + value);
|
||||||
|
value = !(v == 'f' || v == '0' || v == 'false' || v == 'no' || v == 'n' || v == '[]');
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
value = false;
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
var msie = parseInt((/msie (\d+)/.exec(angular.lowercase(navigator.userAgent)) || [])[1], 10);
|
||||||
|
if (isNaN(msie))
|
||||||
|
{
|
||||||
|
msie = parseInt((/trident\/.*; rv:(\d+)/.exec(angular.lowercase(navigator.userAgent)) || [])[1], 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
var bindonceDirective =
|
||||||
|
{
|
||||||
|
restrict: "AM",
|
||||||
|
controller: ['$scope', '$element', '$attrs', '$interpolate', function($scope, $element, $attrs, $interpolate)
|
||||||
|
{
|
||||||
|
var showHideBinder = function(elm, attr, value)
|
||||||
|
{
|
||||||
|
var show = (attr == 'show') ? '' : 'none';
|
||||||
|
var hide = (attr == 'hide') ? '' : 'none';
|
||||||
|
elm.css('display', toBoolean(value) ? show : hide);
|
||||||
|
}
|
||||||
|
var classBinder = function(elm, value)
|
||||||
|
{
|
||||||
|
if (angular.isObject(value) && !angular.isArray(value))
|
||||||
|
{
|
||||||
|
var results = [];
|
||||||
|
angular.forEach(value, function(value, index)
|
||||||
|
{
|
||||||
|
if (value) results.push(index);
|
||||||
|
});
|
||||||
|
value = results;
|
||||||
|
}
|
||||||
|
if (value)
|
||||||
|
{
|
||||||
|
elm.addClass(angular.isArray(value) ? value.join(' ') : value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var ctrl =
|
||||||
|
{
|
||||||
|
watcherRemover : undefined,
|
||||||
|
binders : [],
|
||||||
|
group : $attrs.boName,
|
||||||
|
element : $element,
|
||||||
|
ran : false,
|
||||||
|
|
||||||
|
addBinder : function(binder)
|
||||||
|
{
|
||||||
|
this.binders.push(binder);
|
||||||
|
|
||||||
|
// In case of late binding (when using the directive bo-name/bo-parent)
|
||||||
|
// it happens only when you use nested bindonce, if the bo-children
|
||||||
|
// are not dom children the linking can follow another order
|
||||||
|
if (this.ran)
|
||||||
|
{
|
||||||
|
this.runBinders();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
setupWatcher : function(bindonceValue)
|
||||||
|
{
|
||||||
|
var that = this;
|
||||||
|
this.watcherRemover = $scope.$watch(bindonceValue, function(newValue)
|
||||||
|
{
|
||||||
|
if (newValue == undefined) return;
|
||||||
|
that.removeWatcher();
|
||||||
|
that.runBinders();
|
||||||
|
}, true);
|
||||||
|
},
|
||||||
|
|
||||||
|
removeWatcher : function()
|
||||||
|
{
|
||||||
|
if (this.watcherRemover != undefined)
|
||||||
|
{
|
||||||
|
this.watcherRemover();
|
||||||
|
this.watcherRemover = undefined;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
runBinders : function()
|
||||||
|
{
|
||||||
|
var i, max;
|
||||||
|
for (i = 0, max = this.binders.length; i < max; i ++)
|
||||||
|
{
|
||||||
|
var binder = this.binders[i];
|
||||||
|
if (this.group && this.group != binder.group ) continue;
|
||||||
|
var value = binder.scope.$eval((binder.interpolate) ? $interpolate(binder.value) : binder.value);
|
||||||
|
switch(binder.attr)
|
||||||
|
{
|
||||||
|
case 'if':
|
||||||
|
if (toBoolean(value))
|
||||||
|
{
|
||||||
|
binder.transclude(binder.scope.$new(), function (clone)
|
||||||
|
{
|
||||||
|
var parent = binder.element.parent();
|
||||||
|
var afterNode = binder.element && binder.element[binder.element.length - 1];
|
||||||
|
var parentNode = parent && parent[0] || afterNode && afterNode.parentNode;
|
||||||
|
var afterNextSibling = (afterNode && afterNode.nextSibling) || null;
|
||||||
|
angular.forEach(clone, function(node)
|
||||||
|
{
|
||||||
|
parentNode.insertBefore(node, afterNextSibling);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'hide':
|
||||||
|
case 'show':
|
||||||
|
showHideBinder(binder.element, binder.attr, value);
|
||||||
|
break;
|
||||||
|
case 'class':
|
||||||
|
classBinder(binder.element, value);
|
||||||
|
break;
|
||||||
|
case 'text':
|
||||||
|
binder.element.text(value);
|
||||||
|
break;
|
||||||
|
case 'html':
|
||||||
|
binder.element.html(value);
|
||||||
|
break;
|
||||||
|
case 'style':
|
||||||
|
binder.element.css(value);
|
||||||
|
break;
|
||||||
|
case 'src':
|
||||||
|
binder.element.attr(binder.attr, value);
|
||||||
|
if (msie) binder.element.prop('src', value);
|
||||||
|
case 'attr':
|
||||||
|
angular.forEach(binder.attrs, function(attrValue, attrKey)
|
||||||
|
{
|
||||||
|
var newAttr, newValue;
|
||||||
|
if (attrKey.match(/^boAttr./) && binder.attrs[attrKey])
|
||||||
|
{
|
||||||
|
newAttr = attrKey.replace(/^boAttr/, '').replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase();
|
||||||
|
newValue = binder.scope.$eval(binder.attrs[attrKey]);
|
||||||
|
binder.element.attr(newAttr, newValue);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
case 'href':
|
||||||
|
case 'alt':
|
||||||
|
case 'title':
|
||||||
|
case 'id':
|
||||||
|
case 'value':
|
||||||
|
binder.element.attr(binder.attr, value);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.ran = true;
|
||||||
|
this.binders = [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ctrl;
|
||||||
|
}],
|
||||||
|
|
||||||
|
link: function(scope, elm, attrs, bindonceController)
|
||||||
|
{
|
||||||
|
var value = (attrs.bindonce) ? scope.$eval(attrs.bindonce) : true;
|
||||||
|
if (value != undefined)
|
||||||
|
{
|
||||||
|
bindonceController.runBinders();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bindonceController.setupWatcher(attrs.bindonce);
|
||||||
|
elm.bind("$destroy", bindonceController.removeWatcher);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return bindonceDirective;
|
||||||
|
});
|
||||||
|
|
||||||
|
angular.forEach(
|
||||||
|
[
|
||||||
|
{directiveName:'boShow', attribute: 'show'},
|
||||||
|
{directiveName:'boIf', attribute: 'if', transclude: 'element', terminal: true, priority:1000},
|
||||||
|
{directiveName:'boHide', attribute:'hide'},
|
||||||
|
{directiveName:'boClass', attribute:'class'},
|
||||||
|
{directiveName:'boText', attribute:'text'},
|
||||||
|
{directiveName:'boHtml', attribute:'html'},
|
||||||
|
{directiveName:'boSrcI', attribute:'src', interpolate:true},
|
||||||
|
{directiveName:'boSrc', attribute:'src'},
|
||||||
|
{directiveName:'boHrefI', attribute:'href', interpolate:true},
|
||||||
|
{directiveName:'boHref', attribute:'href'},
|
||||||
|
{directiveName:'boAlt', attribute:'alt'},
|
||||||
|
{directiveName:'boTitle', attribute:'title'},
|
||||||
|
{directiveName:'boId', attribute:'id'},
|
||||||
|
{directiveName:'boStyle', attribute:'style'},
|
||||||
|
{directiveName:'boValue', attribute:'value'},
|
||||||
|
{directiveName:'boAttr', attribute:'attr'}
|
||||||
|
],
|
||||||
|
function(boDirective)
|
||||||
|
{
|
||||||
|
var childPriority = 200;
|
||||||
|
return angular.module('pasvaz.bindonce').directive(boDirective.directiveName, function()
|
||||||
|
{
|
||||||
|
var bindonceDirective =
|
||||||
|
{
|
||||||
|
priority: boDirective.priority || childPriority,
|
||||||
|
transclude: boDirective.transclude || false,
|
||||||
|
terminal: boDirective.terminal || false,
|
||||||
|
require: '^bindonce',
|
||||||
|
compile: function (tElement, tAttrs, transclude)
|
||||||
|
{
|
||||||
|
return function(scope, elm, attrs, bindonceController)
|
||||||
|
{
|
||||||
|
var name = attrs.boParent;
|
||||||
|
if (name && bindonceController.group != name)
|
||||||
|
{
|
||||||
|
var element = bindonceController.element.parent();
|
||||||
|
bindonceController = undefined;
|
||||||
|
var parentValue;
|
||||||
|
|
||||||
|
while (element[0].nodeType != 9 && element.length)
|
||||||
|
{
|
||||||
|
if ((parentValue = element.data('$bindonceController'))
|
||||||
|
&& parentValue.group == name)
|
||||||
|
{
|
||||||
|
bindonceController = parentValue
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
element = element.parent();
|
||||||
|
}
|
||||||
|
if (!bindonceController)
|
||||||
|
{
|
||||||
|
throw Error("No bindonce controller: " + name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bindonceController.addBinder(
|
||||||
|
{
|
||||||
|
element : elm,
|
||||||
|
attr : boDirective.attribute,
|
||||||
|
attrs : attrs,
|
||||||
|
value : attrs[boDirective.directiveName],
|
||||||
|
interpolate : boDirective.interpolate,
|
||||||
|
group : name,
|
||||||
|
transclude : transclude,
|
||||||
|
scope : scope
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return bindonceDirective;
|
||||||
|
});
|
||||||
|
});
|
Loading…
Reference in New Issue
Block a user