Commit 19798b08 by Rashid Khan

added panel configuration framework

parent ee65f81a
...@@ -17,7 +17,24 @@ ...@@ -17,7 +17,24 @@
.panel-error { .panel-error {
opacity: 0.9; opacity: 0.9;
position:absolute; position:absolute;
z-index: 99999; z-index: 2000;
}
span.editlink {
position: absolute;
right: 5px;
z-index: 800;
display: none;
}
.panel:hover span.editlink {
display: block;
opacity: 0.3;
}
.panel span.editlink:hover {
display: block;
opacity: 1;
} }
.pointer { .pointer {
...@@ -54,8 +71,7 @@ ...@@ -54,8 +71,7 @@
} }
.remove:hover { .remove:hover {
color: #A60000; background-color: #A60000;
text-decoration: line-through;
} }
.typeahead { z-index: 1051; } .typeahead { z-index: 1051; }
\ No newline at end of file
...@@ -3,22 +3,26 @@ ...@@ -3,22 +3,26 @@
'use strict'; 'use strict';
angular.module('kibana.directives', []) angular.module('kibana.directives', [])
.directive('panel', function($compile) { .directive('kibanaPanel', function($compile) {
return { return {
restrict: 'A', restrict: 'E',
compile: function(element, attrs) { link: function(scope, elem, attrs) {
return function(scope, element, attrs) { var template = '<span class="pointer editlink" bs-modal="\'partials/paneleditor.html\'" ng-show="panel.editable != false">'+
scope.$watch(function () { '<i class="icon-edit"></i></span><h4>{{panel.title}}</h4>';
return (attrs.panel && scope.index) ? true : false; elem.prepend($compile(angular.element(template))(scope));
}, function (ready) { }
if (ready) { };
element.html($compile("<div "+attrs.panel+" params={{panel}} "+ })
"style='height:{{row.height}}'></div>")(scope)) .directive('panelEdit', function(){
} return {
}); restrict: 'E',
} replace: true,
scope: {
'panel': '=panel'
},
templateUrl: 'panels/table/editor.html',
//controller: 'ChildElement'
} }
}
}) })
.directive('arrayJoin', function() { .directive('arrayJoin', function() {
return { return {
...@@ -72,46 +76,5 @@ angular.module('kibana.directives', []) ...@@ -72,46 +76,5 @@ angular.module('kibana.directives', [])
} }
} }
} }
})
.directive('datepicker', function(){
return {
restrict: 'A',
require: 'ngModel',
link: function(scope, elem, attrs) {
elem.datepicker({
noDefault: false, // set this to true if you don't want the current date inserted if the value-attribute is empty
format: 'mm/dd/yyyy hh:ii:ss'
});
}
};
})
.directive('date', function(dateFilter) {
return {
require: 'ngModel',
link: function(scope, elm, attrs, ctrl) {
var dateFormat = attrs['date'] || 'yyyy-MM-dd HH:mm:ss';
var minDate = Date.parse(attrs['min']) || 0;
var maxDate = Date.parse(attrs['max']) || 9007199254740992;
ctrl.$parsers.unshift(function(viewValue) {
var parsedDateMilissec = Date.parse(viewValue);
if (parsedDateMilissec > 0) {
if (parsedDateMilissec >= minDate && parsedDateMilissec <= maxDate) {
ctrl.$setValidity('date', true);
return new Date(parsedDateMilissec);
}
}
// in all other cases it is invalid, return undefined (no model update)
ctrl.$setValidity('date', false);
return undefined;
});
ctrl.$formatters.unshift(function(modelValue) {
return dateFilter(modelValue, dateFormat);
});
}
};
}); });
<div ng-controller='fields'> <kibana-panel ng-controller='fields'>
<h4 ng-class="{'ng-cloak': !panel.title}">{{panel.title}}</h4>
<ul class="nav nav-list" style="height:{{row.height}};overflow-y:auto;overflow-x:hidden;"> <ul class="nav nav-list" style="height:{{row.height}};overflow-y:auto;overflow-x:hidden;">
<li ng-style="panel.style" ng-repeat="field in fields" ng-class="is_active(field)" ng-click="toggle_field(field)"><a>{{field}}</a></li> <li ng-style="panel.style" ng-repeat="field in fields" ng-class="is_active(field)" ng-click="toggle_field(field)"><a>{{field}}</a></li>
</ul> </ul>
</div> </kibana-panel>
\ No newline at end of file \ No newline at end of file
<div ng-controller='histogram' style="height:{{row.height}}"> <kibana-panel ng-controller='histogram' style="height:{{row.height}}">
<h4>{{panel.title}}</h4>
<div histogram params="{{panel}}" style="height:{{row.height}}"></div> <div histogram params="{{panel}}" style="height:{{row.height}}"></div>
</div> </kibana-panel>
\ No newline at end of file \ No newline at end of file
<div ng-controller='hits'> <kibana-panel ng-controller='hits'>
<h4 ng-class="{'ng-cloak': !panel.title}">{{panel.title}}</h4>
<p ng-style="panel.style">{{hits}}</p> <p ng-style="panel.style">{{hits}}</p>
</div> </kibana-panel>
\ No newline at end of file \ No newline at end of file
<div ng-controller='map'> <kibana-panel ng-controller='map'>
<h4>{{panel.title}}</h4>
<div map params="{{panel}}" style="height:{{row.height}}"></div> <div map params="{{panel}}" style="height:{{row.height}}"></div>
</div> </kibana-panel>
\ No newline at end of file \ No newline at end of file
<h4 style="text-transform: capitalize;">{{panel.type}} <small> panel settings</small></h4>
<div class="row-fluid">
<div class="span4">
<form class="input-append">
<h5>Field</h5>
<input type="text" style="width:70%" ng-model="panel.query.field">
<button class="btn" ng-click="get_data()"><i class="icon-search"></i></button>
</form>
</div>
<div class="span8">
<form class="input-append">
<h5>Query</h5>
<input type="text" style="width:80%" ng-model="panel.query.query">
<button class="btn" ng-click="get_data()"><i class="icon-search"></i></button>
</form>
</div>
</div>
<div class="row-fluid">
<div class="span1">
<label class="small"> Donut </label><input type="checkbox" ng-model="panel.donut" ng-checked="panel.donut">
</div>
<div class="span1">
<label class="small"> Tilt </label><input type="checkbox" ng-model="panel.tilt" ng-checked="panel.tilt">
</div>
<div class="span1">
<label class="small"> Legend </label><input type="checkbox" ng-model="panel.legend" ng-checked="panel.legend">
</div>
<div class="span1">
<label class="small"> Labels </label><input type="checkbox" ng-model="panel.labels" ng-checked="panel.labels">
</div>
</div>
<div class="row-fluid">
<div class="span4">
<h5>Sort</h5>
<select style="width:85%" ng-model="panel.sort[0]" ng-options="f for f in all_fields"></select>
<i ng-click="set_sort(panel.sort[0])" ng-class="{'icon-chevron-up': panel.sort[1] == 'asc','icon-chevron-down': panel.sort[1] == 'desc'}"></i>
</div>
<div class="span1">
<h5>Length</h5>
<input type="number" class="input-mini" ng-model="panel.size" ng-change="get_data()">
</div>
</div>
\ No newline at end of file
<div ng-controller='pie'> <kibana-panel ng-controller='pie'>
<h4>{{panel.title}}</h4>
<div pie params="{{panel}}" style="height:{{row.height}}"></div> <div pie params="{{panel}}" style="height:{{row.height}}"></div>
</div> </kibana-panel>
\ No newline at end of file \ No newline at end of file
<div ng-controller='sort' style="white-space: nowrap;"> <kibana-panel ng-controller='sort' style="white-space: nowrap;">
<h4 ng-class="{'ng-cloak': !panel.title}">{{panel.title}}</h4>
<label><small>{{panel.label}}</small></label> <label><small>{{panel.label}}</small></label>
<select style="width:85%" ng-model="panel.sort[0]" ng-change="set_sort()" ng-options="f for f in fields"></select> <select style="width:85%" ng-model="panel.sort[0]" ng-change="set_sort()" ng-options="f for f in fields"></select>
<i ng-click="toggle_sort()" ng-class="{'icon-chevron-up': panel.sort[1] == 'asc','icon-chevron-down': panel.sort[1] == 'desc'}"></i> <i ng-click="toggle_sort()" ng-class="{'icon-chevron-up': panel.sort[1] == 'asc','icon-chevron-down': panel.sort[1] == 'desc'}"></i>
</div> </kibana-panel>
\ No newline at end of file \ No newline at end of file
<div ng-controller='stringquery'> <kibana-panel ng-controller='stringquery'>
<h4 ng-class="{'ng-cloak': !panel.title}">{{panel.title}}</h4>
<form class="input-append" style="margin-bottom:0px; white-space:nowrap;"> <form class="input-append" style="margin-bottom:0px; white-space:nowrap;">
<label><small>{{panel.label}}</small></label> <label><small>{{panel.label}}</small></label>
<input type="text" ng-model="panel.query" style="width:90%"> <input type="text" ng-model="panel.query" style="width:90%">
<button type="submit" class="btn" ng-click="send_query(panel.query)"><i class="icon-search"></i></button> <button type="submit" class="btn" ng-click="send_query(panel.query)"><i class="icon-search"></i></button>
</form> </form>
</div> </kibana-panel>
\ No newline at end of file \ No newline at end of file
<div class="modal-header"> <div class="row-fluid">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button> <div class="span12">
<h3>{{panel.title}}</h3> <form class="input-append">
</div> <h5>Query</h5>
<div class="modal-body"> <input type="text" style="width:90%" ng-model="panel.query">
<h4>Panel Settings</h4> <button class="btn" ng-click="get_data();"><i class="icon-search"></i></button>
<form class="form-inline"> </form>
<label>Span</label> <input type="number" class="input-mini" ng-model="panel.span"><br> </div>
<label class="checkbox"> Editable <input type="checkbox" ng-model="panel.editable" ng-checked="panel.editable"></label> </div>
</form> <div class="row-fluid">
<label>Group(s)</label><input array-join type="text" class="input-large" ng-model='panel.group'></input> <small>Comma seperated</small>
<div class="row-fluid">
<div class="span4"> <div class="span4">
<form class="input-append"> <form class="input-append">
<h4>Add field</h4> <h5>Add field</h5>
<input bs-typeahead="all_fields" type="text" class="input-small" ng-model='newfield'> <input bs-typeahead="all_fields" type="text" class="input-small" ng-model='newfield'>
<button class="btn" ng-click="toggle_field(newfield);newfield=''"><i class="icon-plus"></i></button> <button class="btn" ng-click="toggle_field(newfield);newfield=''"><i class="icon-plus"></i></button>
</form> </form>
</div> </div>
<div class="span8"> <div class="span8">
<h4>Selected fields <small>Click to a field to remove it</small></h4> <h5>Selected fields <small>Click to remove</small></h5>
<span ng-click="toggle_field(field)" ng-repeat="field in panel.fields" class="remove pointer">{{field}} </span> <span style="margin-left:3px" ng-click="toggle_field(field)" ng-repeat="field in $parent.panel.fields" class="label remove pointer">{{field}} </span>
</div> </div>
</div> </div>
</div> <div class="row-fluid">
<div class="modal-footer"> <div class="span4">
<button type="button" class="btn" ng-click="dismiss()">Close</button> <h5>Sort</h5>
<button class="btn btn-primary" ng-click="dismiss()">Save changes</button> <select style="width:85%" ng-model="panel.sort[0]" ng-options="f for f in all_fields"></select>
</div> <i ng-click="set_sort(panel.sort[0])" ng-class="{'icon-chevron-up': panel.sort[1] == 'asc','icon-chevron-down': panel.sort[1] == 'desc'}"></i>
\ No newline at end of file </div>
<div class="span1">
<h5>Length</h5>
<input type="number" class="input-mini" ng-model="panel.size" ng-change="get_data()">
</div>
</div>
\ No newline at end of file
<div ng-controller='table'> <kibana-panel ng-controller='table'>
<h4>{{panel.title}} <small class="pointer" bs-modal="'panels/table/editor.html'" ng-hide="!panel.editable"><i class="icon-edit"></i></small></h4>
<div style="height:{{row.height}};overflow-y:auto;overflow-x:auto"> <div style="height:{{row.height}};overflow-y:auto;overflow-x:auto">
<table class="table table-condensed table-striped" ng-style="panel.style"> <table class="table table-condensed table-striped" ng-style="panel.style">
<thead> <thead>
...@@ -15,4 +14,4 @@ ...@@ -15,4 +14,4 @@
</tr> </tr>
</table> </table>
</div> </div>
</div> </kibana-panel>
\ No newline at end of file \ No newline at end of file
<label class="small">Font Size</label> <select class="input-mini" ng-model="panel.style['font-size']" ng-options="f for f in ['6pt','7pt','8pt','10pt','12pt','14pt','16pt','18pt','20pt','24pt','28pt','32pt','36pt','42pt','48pt','52pt','60pt','72pt']"></select>
<label class=small>Content</label>
<textarea ng-model="panel.content" rows="6" style="width:95%"></textarea>
\ No newline at end of file
<div ng-controller='text'> <kibana-panel ng-controller='text'>
<h4 ng-class="{'ng-cloak': !panel.title}">{{panel.title}}</h4>
<p ng-style="panel.style">{{panel.content}}</p> <p ng-style="panel.style">{{panel.content}}</p>
</div> </kibana-panel>
\ No newline at end of file \ No newline at end of file
<div ng-controller='timepicker' style="white-space: nowrap;"> <kibana-panel ng-controller='timepicker' style="white-space: nowrap;">
<h4 ng-class="{'ng-cloak': !panel.title}">{{panel.title}}</h4> <div class="row-fluid" ng-switch="panel.mode">
<div class="row-fluid" ng-switch="panel.mode"> <div ng-switch-when="absolute">
<div ng-switch-when="absolute"> <div class="span5">
<div class="span5"> <form class="nomargin">
<form class="nomargin"> <label><small>From</small></label>
<label><small>From</small></label> <input type="text" class="input-smaller" ng-change="time_check()" ng-model="timepicker.from.date" data-date-format="mm/dd/yyyy" bs-datepicker>
<input type="text" class="input-smaller" ng-change="time_check()" ng-model="timepicker.from.date" data-date-format="mm/dd/yyyy" bs-datepicker> <input type="text" class="input-mini" ng-change="time_check()" data-show-meridian="false" data-show-seconds="true" ng-model="timepicker.from.time" bs-timepicker>
<input type="text" class="input-mini" ng-change="time_check()" data-show-meridian="false" data-show-seconds="true" ng-model="timepicker.from.time" bs-timepicker>
</form>
</div>
<div class="span5" style="margin-left:10px">
<form class="nomargin">
<label style="margin-left:5px"><small>To (<a ng-click="to_now()">now</a>)</small></label>
<input type="text" class="input-smaller" ng-change="time_check()" ng-model="timepicker.to.date" data-date-format="mm/dd/yyyy" bs-datepicker>
<input type="text" class="input-mini" ng-change="time_check()" data-show-meridian="false" data-show-seconds="true" ng-model="timepicker.to.time" bs-timepicker>
</form> </form>
</div>
<div class="span1">
<form class="nomargin">
<label><small><br></small></label>
<button class="btn" ng-click="time_apply()" ><i class="icon-check"></i></button>
</form>
</div>
</div> </div>
<div ng-switch-when="since"> <div class="span5" style="margin-left:10px">
<div class="span5"> <form class="nomargin">
<form class="nomargin"> <label style="margin-left:5px"><small>To (<a ng-click="to_now()">now</a>)</small></label>
<label><small>Since</small></label> <input type="text" class="input-smaller" ng-change="time_check()" ng-model="timepicker.to.date" data-date-format="mm/dd/yyyy" bs-datepicker>
<input type="text" class="input-smaller" ng-change="time_check()" ng-model="timepicker.from.date" data-date-format="mm/dd/yyyy" bs-datepicker> <input type="text" class="input-mini" ng-change="time_check()" data-show-meridian="false" data-show-seconds="true" ng-model="timepicker.to.time" bs-timepicker>
<input type="text" class="input-mini" ng-change="time_check()" data-show-meridian="false" data-show-seconds="true" ng-model="timepicker.from.time" bs-timepicker> </form>
</form>
</div>
<div class="span1" style="margin-left:10px">
<form class="nomargin">
<label><small><br></small></label>
<button class="btn" ng-click="time_apply()" ><i class="icon-check"></i></button>
</form>
</div>
</div> </div>
<div ng-switch-when="relative"> <div class="span1">
<div class="span11"> <form class="nomargin">
<form class="nomargin input-append"> <label><small><br></small></label>
<label><small>The last</small></label> <button class="btn" ng-click="time_apply()" ><i class="icon-check"></i></button>
<button class="btn btn" ng-repeat='timespan in panel.time_options' ng-class="{'btn-success': (panel.timespan == timespan)}" ng-click="set_timespan(timespan)">{{timespan}}</button> </form>
<!--<select ng-model="panel.sort[0]" ng-options="f for f in fields"></select>-->
</form>
</div>
</div> </div>
</div> </div>
<div class="row-fluid nomargin"> <div ng-switch-when="since">
<div class="span12 small"> <div class="span5">
<a ng-click="set_mode('relative')" ng-class="{'strong': (panel.mode == 'relative')}">Relative</a> | <form class="nomargin">
<a ng-click="set_mode('absolute')" ng-class="{'strong': (panel.mode == 'absolute')}">Absolute</a> | <label><small>Since</small></label>
<a ng-click="set_mode('since')" ng-class="{'strong': (panel.mode == 'since')}">Since</a> <input type="text" class="input-smaller" ng-change="time_check()" ng-model="timepicker.from.date" data-date-format="mm/dd/yyyy" bs-datepicker>
<span ng-hide="panel.mode == 'absolute'"> | <input type="text" class="input-mini" ng-change="time_check()" data-show-meridian="false" data-show-seconds="true" ng-model="timepicker.from.time" bs-timepicker>
<input type="checkbox" ng-model="panel.refresh.enable"> Auto-refresh </form>
<span ng-class="{'ng-cloak': !panel.refresh.enable}"> </div>
every <a data-title="<small>Auto-refresh Settings</small>" data-placement="bottom" bs-popover="'panels/timepicker/refreshctrl.html'">{{panel.refresh.interval}}s</a>. <div class="span1" style="margin-left:10px">
</span> <form class="nomargin">
</span> <label><small><br></small></label>
<button class="btn" ng-click="time_apply()" ><i class="icon-check"></i></button>
</form>
</div> </div>
</div> </div>
</div> <div ng-switch-when="relative">
\ No newline at end of file <div class="span11">
<form class="nomargin input-append">
<label><small>The last</small></label>
<button class="btn btn" ng-repeat='timespan in panel.time_options' ng-class="{'btn-success': (panel.timespan == timespan)}" ng-click="set_timespan(timespan)">{{timespan}}</button>
<!--<select ng-model="panel.sort[0]" ng-options="f for f in fields"></select>-->
</form>
</div>
</div>
</div>
<div class="row-fluid nomargin">
<div class="span12 small">
<a ng-click="set_mode('relative')" ng-class="{'strong': (panel.mode == 'relative')}">Relative</a> |
<a ng-click="set_mode('absolute')" ng-class="{'strong': (panel.mode == 'absolute')}">Absolute</a> |
<a ng-click="set_mode('since')" ng-class="{'strong': (panel.mode == 'since')}">Since</a>
<span ng-hide="panel.mode == 'absolute'"> |
<input type="checkbox" ng-model="panel.refresh.enable"> Auto-refresh
<span ng-class="{'ng-cloak': !panel.refresh.enable}">
every <a data-title="<small>Auto-refresh Settings</small>" data-placement="bottom" bs-popover="'panels/timepicker/refreshctrl.html'">{{panel.refresh.interval}}s</a>.
</span>
</span>
</div>
</div>
</kibana-panel>
\ No newline at end of file
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
</div> </div>
<div class="row-fluid" style="padding-top:10px" ng-hide="row.collapse"> <div class="row-fluid" style="padding-top:10px" ng-hide="row.collapse">
<!-- Panels --> <!-- Panels -->
<div ng-repeat="(name, panel) in row.panels" ng-hide="panel.span == 0" class="span{{panel.span}}" style="min-height:{{row.height}}; position:relative"> <div ng-repeat="(name, panel) in row.panels" ng-hide="panel.span == 0" class="span{{panel.span}} panel" style="min-height:{{row.height}}; position:relative">
<!-- Error Panel --> <!-- Error Panel -->
<div class="row-fluid"> <div class="row-fluid">
<div class="span12 alert alert-error panel-error" ng-hide="!panel.error"> <div class="span12 alert alert-error panel-error" ng-hide="!panel.error">
......
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h3>{{panel.title}} <small>editor</small></h3>
</div>
<div class="modal-body">
<h4>General</h4>
<div class="row-fluid">
<div class="span4">
<label class="small">Title</label><input type="text" class="input-medium" ng-model='panel.title'></input>
</div>
<div class="span4">
<label class="small">Group(s) (comma seperated)</label><input array-join type="text" class="input-medium" ng-model='panel.group'></input>
</div>
<div class="span2">
<label class="small">Span</label> <select class="input-mini" ng-model="panel.span" ng-options="f for f in [0,1,2,3,4,5,6,7,8,9,10,11,12]"></select>
</div>
<div class="span1">
<label class="small"> Editable </label><input type="checkbox" ng-model="panel.editable" ng-checked="panel.editable">
</div>
</div>
<h4 style="text-transform: capitalize;">{{panel.type}} <small> panel settings</small></h4>
<div ng-include src="'panels/'+panel.type+'/editor.html'">No additional settings are available for this type of panel.</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-success" ng-click="dismiss()">Close</button>
</div>
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment