Commit 9f3f7a4f by Rashid Khan

Refactored dashboard state/loading into service, css tweaks

parent 4f1b33b3
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
.axis path,
.axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
\ No newline at end of file
.jvectormap-label {
position: absolute;
display: none;
border: solid 1px #CDCDCD;
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
border-radius: 3px;
background: #292929;
color: white;
font-family: sans-serif, Verdana;
font-size: smaller;
padding: 3px;
}
.jvectormap-zoomin, .jvectormap-zoomout {
position: absolute;
left: 10px;
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
border-radius: 3px;
background: #292929;
padding: 3px;
color: white;
width: 10px;
height: 10px;
cursor: pointer;
line-height: 10px;
text-align: center;
}
.jvectormap-zoomin {
display: none;
top: 10px;
}
.jvectormap-zoomout {
display: none;
top: 30px;
}
\ No newline at end of file
...@@ -6,6 +6,12 @@ ...@@ -6,6 +6,12 @@
color: #000; color: #000;
} }
.spy {
position:absolute;
right:0px;
top:0px;
}
.navbar .brand { .navbar .brand {
color: #eee; color: #eee;
} }
......
{ {
"title": "Logstash Search", "title": "Logstash Search",
"services": {},
"rows": [ "rows": [
{ {
"title": "Options", "title": "Options",
......
...@@ -6,18 +6,17 @@ ...@@ -6,18 +6,17 @@
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="description" content="Search based application built using ElasticSearch, elastic.js, and Angular.js">
<meta name="viewport" content="width=device-width"> <meta name="viewport" content="width=device-width">
<title>Kibana 3</title> <title>Kibana 3</title>
<link rel="stylesheet" href="common/css/normalize.min.css"> <link rel="stylesheet" href="common/css/normalize.min.css">
<link rel="stylesheet" href="common/css/bootstrap.dark.min.css"> <link rel="stylesheet" href="common/css/bootstrap.dark.min.css" title="Dark">
<link rel="alternate stylesheet" href="common/css/bootstrap.light.min.css" title="Light">
<link rel="stylesheet" href="common/css/animate.min.css"> <link rel="stylesheet" href="common/css/animate.min.css">
<link rel="stylesheet" href="common/css/bootstrap-responsive.min.css"> <link rel="stylesheet" href="common/css/bootstrap-responsive.min.css">
<link rel="stylesheet" href="common/css/font-awesome.min.css"> <link rel="stylesheet" href="common/css/font-awesome.min.css">
<link rel="stylesheet" href="common/css/main.css"> <link rel="stylesheet" href="common/css/main.css">
<link rel="stylesheet" href="common/css/elasticjs.css">
<link rel="stylesheet" href="common/css/timepicker.css"> <link rel="stylesheet" href="common/css/timepicker.css">
<!-- project dependency libs --> <!-- project dependency libs -->
...@@ -39,8 +38,8 @@ ...@@ -39,8 +38,8 @@
<div class="navbar-inner"> <div class="navbar-inner">
<div class="container-fluid"> <div class="container-fluid">
<p class="navbar-text pull-right"><small><strong>Kibana 3</strong> <small>milestone 2</small></small></p> <p class="navbar-text pull-right"><small><strong>Kibana 3</strong> <small>milestone 2</small></small></p>
<span class="brand">{{dashboards.title}}</span> <span class="brand">{{dashboard.current.title}}</span>
<div class="brand"><i class='icon-cog pointer' ng-show='dashboards.editable' bs-modal="'partials/dasheditor.html'"></i></div> <div class="brand"><i class='icon-cog pointer' ng-show='dashboard.current.editable' bs-modal="'partials/dasheditor.html'"></i></div>
</div> </div>
</div> </div>
</div> </div>
......
...@@ -19,7 +19,6 @@ var scripts = [] ...@@ -19,7 +19,6 @@ var scripts = []
var labjs = $LAB var labjs = $LAB
.script("common/lib/jquery-1.8.0.min.js").wait() .script("common/lib/jquery-1.8.0.min.js").wait()
.script("common/lib/modernizr-2.6.1.min.js") .script("common/lib/modernizr-2.6.1.min.js")
.script("common/lib/underscore.min.js")
.script("common/lib/angular.min.js").wait() .script("common/lib/angular.min.js").wait()
.script("common/lib/angular-strap.min.js") .script("common/lib/angular-strap.min.js")
.script("common/lib/angular-sanitize.min.js") .script("common/lib/angular-sanitize.min.js")
...@@ -47,10 +46,10 @@ labjs.wait(function(){ ...@@ -47,10 +46,10 @@ labjs.wait(function(){
angular.module('kibana', modules).config(['$routeProvider', function($routeProvider) { angular.module('kibana', modules).config(['$routeProvider', function($routeProvider) {
$routeProvider $routeProvider
.when('/dashboard', { .when('/dashboard', {
templateUrl: 'partials/dashboard.html' templateUrl: 'partials/dashboard.html',
}) })
.when('/dashboard/:type/:id', { .when('/dashboard/:type/:id', {
templateUrl: 'partials/dashboard.html' templateUrl: 'partials/dashboard.html',
}) })
.when('/dashboard/:type/:id/:params', { .when('/dashboard/:type/:id/:params', {
templateUrl: 'partials/dashboard.html' templateUrl: 'partials/dashboard.html'
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
'use strict'; 'use strict';
angular.module('kibana.controllers', []) angular.module('kibana.controllers', [])
.controller('DashCtrl', function($scope, $rootScope, $http, $timeout, ejsResource, eventBus, fields) { .controller('DashCtrl', function($scope, $rootScope, $http, $timeout, $route, ejsResource, eventBus, fields, dashboard) {
var _d = { var _d = {
title: "", title: "",
...@@ -18,28 +18,18 @@ angular.module('kibana.controllers', []) ...@@ -18,28 +18,18 @@ angular.module('kibana.controllers', [])
// Make underscore.js available to views // Make underscore.js available to views
$scope._ = _; $scope._ = _;
$scope.dashboard = dashboard;
// Provide a global list of all see fields // Provide a global list of all see fields
$scope.fields = fields $scope.fields = fields
$scope.reset_row(); $scope.reset_row();
$scope.clear_all_alerts(); $scope.clear_all_alerts();
// Load dashboard by event
eventBus.register($scope,'dashboard', function(event,dashboard){
$scope.dashboards = dashboard.dashboard;
$scope.dashboards.last = dashboard.last;
_.defaults($scope.dashboards,_d)
})
// If the route changes, clear the existing dashboard
$rootScope.$on( "$routeChangeStart", function(event, next, current) {
delete $scope.dashboards
});
var ejs = $scope.ejs = ejsResource(config.elasticsearch); var ejs = $scope.ejs = ejsResource(config.elasticsearch);
} }
$scope.add_row = function(dashboards,row) { $scope.add_row = function(dash,row) {
$scope.dashboards.rows.push(row); dash.rows.push(row);
} }
$scope.reset_row = function() { $scope.reset_row = function() {
......
...@@ -49,7 +49,8 @@ angular.module('kibana.directives', []) ...@@ -49,7 +49,8 @@ angular.module('kibana.directives', [])
} }
}; };
}) })
.directive('upload', function(timer){ // Is this even used anymore? I don't think is is
.directive('upload', function(timer,dashboard){
return { return {
restrict: 'A', restrict: 'A',
link: function(scope, elem, attrs) { link: function(scope, elem, attrs) {
...@@ -62,9 +63,7 @@ angular.module('kibana.directives', []) ...@@ -62,9 +63,7 @@ angular.module('kibana.directives', [])
var reader = new FileReader(); var reader = new FileReader();
reader.onload = (function(theFile) { reader.onload = (function(theFile) {
return function(e) { return function(e) {
// Render thumbnail. dashboard.dash_load(JSON.parse(e.target.result))
scope.dashboards = JSON.parse(e.target.result)
timer.cancel_all();
scope.$apply(); scope.$apply();
}; };
})(f); })(f);
......
...@@ -52,7 +52,7 @@ angular.module('kibana.services', []) ...@@ -52,7 +52,7 @@ angular.module('kibana.services', [])
if(!(_.isArray(_group))) if(!(_.isArray(_group)))
_group = [_group]; _group = [_group];
// Transmit even only if the send is not the receiver AND one of the following: // Transmit event only if the sender is not the receiver AND one of the following:
// 1) Receiver has group in _to 2) Receiver's $id is in _to // 1) Receiver has group in _to 2) Receiver's $id is in _to
// 3) Event is addressed to ALL 4) Receiver is in ALL group // 3) Event is addressed to ALL 4) Receiver is in ALL group
if((_.intersection(_to,_group).length > 0 || if((_.intersection(_to,_group).length > 0 ||
...@@ -66,9 +66,9 @@ angular.module('kibana.services', []) ...@@ -66,9 +66,9 @@ angular.module('kibana.services', [])
} }
}); });
} }
}) })
/* Service: fields /*
Service: fields
Provides a global list of all seen fields for use in editor panels Provides a global list of all seen fields for use in editor panels
*/ */
.factory('fields', function($rootScope) { .factory('fields', function($rootScope) {
...@@ -119,7 +119,7 @@ angular.module('kibana.services', []) ...@@ -119,7 +119,7 @@ angular.module('kibana.services', [])
} }
// this is stupid, but there is otherwise no good way to ensure that when // this is stupid, but there is otherwise no good way to ensure that when
// I extract the date from an object that I'm get the UTC date. Stupid js. // I extract the date from an object that I get the UTC date. Stupid js.
// I die a little inside every time I call this function. // I die a little inside every time I call this function.
// Update: I just read this again. I died a little more inside. // Update: I just read this again. I died a little more inside.
// Update2: More death. // Update2: More death.
...@@ -186,6 +186,253 @@ angular.module('kibana.services', []) ...@@ -186,6 +186,253 @@ angular.module('kibana.services', [])
} }
}) })
.service('query', function() {
})
.service('dashboard', function($routeParams, $http, $rootScope, ejsResource, timer) {
// A hash of defaults to use when loading a dashboard
var _dash = {
title: "",
editable: true,
rows: [],
services: {}
};
// An elasticJS client to use
var ejs = ejsResource(config.elasticsearch);
var gist_pattern = /(^\d{5,}$)|(^[a-z0-9]{10,}$)|(gist.github.com(\/*.*)\/[a-z0-9]{5,}\/*$)/;
// Empty dashboard object
this.current = {};
this.last = {};
// Store a reference to this
var self = this;
$rootScope.$on('$routeChangeSuccess',function(){
route();
})
var route = function() {
// Is there a dashboard type and id in the URL?
if(!(_.isUndefined($routeParams.type)) && !(_.isUndefined($routeParams.id))) {
var _type = $routeParams.type;
var _id = $routeParams.id;
if(_type === 'elasticsearch')
self.elasticsearch_load('dashboard',_id)
if(_type === 'temp')
self.elasticsearch_load('temp',_id)
if(_type === 'file')
self.file_load(_id)
// No dashboard in the URL
} else {
// Check if browser supports localstorage, and if there's a dashboard
if (Modernizr.localstorage &&
!(_.isUndefined(localStorage['dashboard'])) &&
localStorage['dashboard'] !== ''
) {
var dashboard = JSON.parse(localStorage['dashboard']);
_.defaults(dashboard,_dash);
self.dash_load(dashboard)
// No? Ok, grab default.json, its all we have now
} else {
self.file_load('default')
}
}
}
this.to_file = function() {
var blob = new Blob([angular.toJson(self.current,true)], {type: "application/json;charset=utf-8"});
// from filesaver.js
saveAs(blob, self.current.title+"-"+new Date().getTime());
return true;
}
this.set_default = function(dashboard) {
if (Modernizr.localstorage) {
localStorage['dashboard'] = angular.toJson(dashboard || self.current);
return true;
} else {
return false;
}
}
this.purge_default = function() {
if (Modernizr.localstorage) {
localStorage['dashboard'] = '';
return true;
} else {
return false;
}
}
// TOFIX: Pretty sure this breaks when you're on a saved dashboard already
this.share_link = function(title,type,id) {
return {
location : location.href.replace(location.hash,""),
type : type,
id : id,
link : location.href.replace(location.hash,"")+"#dashboard/"+type+"/"+id,
title : title
};
}
this.file_load = function(file) {
return $http({
url: "dashboards/"+file,
method: "GET",
}).then(function(result) {
var _dashboard = result.data
_.defaults(_dashboard,_dash);
self.dash_load(_dashboard);
return true;
},function(result) {
return false;
});
}
this.elasticsearch_load = function(type,id) {
var request = ejs.Request().indices(config.kibana_index).types(type);
var results = request.query(
ejs.IdsQuery(id)
).doSearch();
return results.then(function(results) {
if(_.isUndefined(results)) {
return false;
} else {
self.dash_load(angular.fromJson(results.hits.hits[0]['_source']['dashboard']))
return true;
}
});
}
this.elasticsearch_save = function(type,title,ttl) {
// Clone object so we can modify it without influencing the existing obejct
var save = _.clone(self.current)
// Change title on object clone
if (type === 'dashboard') {
var id = save.title = _.isUndefined(title) ? self.current.title : title;
}
// Create request with id as title. Rethink this.
var request = ejs.Document(config.kibana_index,type,id).source({
user: 'guest',
group: 'guest',
title: save.title,
dashboard: angular.toJson(save)
})
if (type === 'temp')
request = request.ttl(ttl)
// TOFIX: Implement error handling here
return request.doIndex(
// Success
function(result) {
return result;
},
// Failure
function(result) {
return false;
}
);
}
this.elasticsearch_delete = function(id) {
return ejs.Document(config.kibana_index,'dashboard',id).doDelete(
// Success
function(result) {
return result;
},
// Failure
function(result) {
return false;
}
);
}
this.elasticsearch_list = function(query,count) {
var request = ejs.Request().indices(config.kibana_index).types('dashboard');
return request.query(
ejs.QueryStringQuery(query || '*')
).size(count).doSearch(
// Success
function(result) {
return result;
},
// Failure
function(result) {
return false;
}
);
}
// TOFIX: Gist functionality
this.save_gist = function(title,dashboard) {
var save = _.clone(dashboard || self.current)
save.title = title || self.current.title;
return $http({
url: "https://api.github.com/gists",
method: "POST",
data: {
"description": save.title,
"public": false,
"files": {
"kibana-dashboard.json": {
"content": angular.toJson(save,true)
}
}
}
}).then(function(data, status, headers, config) {
return data.data.html_url;
}, function(data, status, headers, config) {
return false;
});
}
this.gist_list = function(id) {
return $http.jsonp("https://api.github.com/gists/"+id+"?callback=JSON_CALLBACK"
).then(function(response) {
var files = []
_.each(response.data.data.files,function(v,k) {
try {
var file = JSON.parse(v.content)
files.push(file)
} catch(e) {
// Nothing?
}
});
return files;
}, function(data, status, headers, config) {
return false;
});
}
this.dash_load = function(dashboard) {
self.current = dashboard;
timer.cancel_all();
return true;
}
this.gist_id = function(string) {
if(self.is_gist(string))
return string.match(gist_pattern)[0].replace(/.*\//, '');
}
this.is_gist = function(string) {
if(!_.isUndefined(string) && string != '' && !_.isNull(string.match(gist_pattern)))
return string.match(gist_pattern).length > 0 ? true : false;
else
return false
}
})
.service('keylistener', function($rootScope) { .service('keylistener', function($rootScope) {
var keys = []; var keys = [];
$(document).keydown(function (e) { $(document).keydown(function (e) {
......
...@@ -11,12 +11,12 @@ ...@@ -11,12 +11,12 @@
<h5>Gist <small>Enter a gist number or url</small></h5> <h5>Gist <small>Enter a gist number or url</small></h5>
<form> <form>
<input type="text" ng-model="gist.url"/><br> <input type="text" ng-model="gist.url"/><br>
<button class="btn" ng-click="gist_dblist(gist_id(gist.url))" ng-show="is_gist(gist.url)"><i class="icon-github-alt"></i> Get gist:{{gist.url | gistid}}</button> <button class="btn" ng-click="gist_dblist(dashboard.gist_id(gist.url))" ng-show="dashboard.is_gist(gist.url)"><i class="icon-github-alt"></i> Get gist:{{gist.url | gistid}}</button>
<h6 ng-show="gist.files.length">Dashboards in gist:{{gist.url | gistid}} <small>click to load</small></h6> <h6 ng-show="gist.files.length">Dashboards in gist:{{gist.url | gistid}} <small>click to load</small></h6>
<h6 ng-hide="gist.files.length">No gist dashboards found</h6> <h6 ng-hide="gist.files.length">No gist dashboards found</h6>
<table class="table table-condensed table-striped"> <table class="table table-condensed table-striped">
<tr ng-repeat="file in gist.files"> <tr ng-repeat="file in gist.files">
<td><a ng-click="dash_load(file)">{{file.title}}</a></td> <td><a ng-click="dashboard.dash_load(file)">{{file.title}}</a></td>
</tr> </tr>
</table> </table>
</form> </form>
...@@ -30,10 +30,10 @@ ...@@ -30,10 +30,10 @@
<h6 ng-show="elasticsearch.dashboards.length">Elasticsearch stored dashboards</h6> <h6 ng-show="elasticsearch.dashboards.length">Elasticsearch stored dashboards</h6>
<h6 ng-hide="elasticsearch.dashboards.length">No dashboards matching your query found</h6> <h6 ng-hide="elasticsearch.dashboards.length">No dashboards matching your query found</h6>
<table class="table table-condensed table-striped"> <table class="table table-condensed table-striped">
<tr ng-repeat="dashboard in elasticsearch.dashboards"> <tr ng-repeat="row in elasticsearch.dashboards">
<td><a ng-click="elasticsearch_delete(dashboard)"><i class="icon-remove"></i></a></td> <td><a ng-click="elasticsearch_delete(row._id)"><i class="icon-remove"></i></a></td>
<td><a href="#/dashboard/elasticsearch/{{dashboard._id}}">{{dashboard._id}}</a></td> <td><a href="#/dashboard/elasticsearch/{{row._id}}">{{row._id}}</a></td>
<td><a><i class="icon-share" ng-click="share_link(dashboard._id,'elasticsearch',dashboard._id)" bs-modal="'panels/dashcontrol/share.html'"></i></a></td> <td><a><i class="icon-share" ng-click="share = dashboard.share_link(row._id,'elasticsearch',row._id)" bs-modal="'panels/dashcontrol/share.html'"></i></a></td>
</tr> </tr>
</table> </table>
</div> </div>
......
...@@ -2,5 +2,5 @@ ...@@ -2,5 +2,5 @@
<label class='small'>Dashboard Control</label> <label class='small'>Dashboard Control</label>
<button class='btn' ng-show="panel.load.gist || panel.load.elasticsearch || panel.load.local" data-placement="bottom" data-unique="1" ng-click="elasticsearch_dblist(elasticsearch.query)" bs-popover="'panels/dashcontrol/load.html'"><i class='icon-folder-open'></i> <i class='icon-caret-down'></i></button> <button class='btn' ng-show="panel.load.gist || panel.load.elasticsearch || panel.load.local" data-placement="bottom" data-unique="1" ng-click="elasticsearch_dblist(elasticsearch.query)" bs-popover="'panels/dashcontrol/load.html'"><i class='icon-folder-open'></i> <i class='icon-caret-down'></i></button>
<button class='btn' ng-show="panel.save.gist || panel.save.elasticsearch || panel.save.local || panel.save.default" data-placement="bottom" data-unique="1" bs-popover="'panels/dashcontrol/save.html'"><i class='icon-save'></i> <i class='icon-caret-down'></i></button> <button class='btn' ng-show="panel.save.gist || panel.save.elasticsearch || panel.save.local || panel.save.default" data-placement="bottom" data-unique="1" bs-popover="'panels/dashcontrol/save.html'"><i class='icon-save'></i> <i class='icon-caret-down'></i></button>
<button ng-show="panel.temp" class='btn' ng-click="elasticsearch_save('temp')" bs-modal="'panels/dashcontrol/share.html'"><i class='icon-share'></i></button> <button ng-show="panel.temp" class='btn' ng-click="elasticsearch_save('temp',panel.temp_ttl)" bs-modal="'panels/dashcontrol/share.html'"><i class='icon-share'></i></button>
</kibana-panel> </kibana-panel>
\ No newline at end of file
...@@ -6,9 +6,9 @@ ...@@ -6,9 +6,9 @@
<h5>Locally</h5> <h5>Locally</h5>
<form> <form>
<ul class="nav nav-list"> <ul class="nav nav-list">
<li><a ng-show="panel.save.local" ng-click="to_file()"><i class="icon-download"></i> Export to File</a></li> <li><a ng-show="panel.save.local" ng-click="dashboard.to_file()"><i class="icon-download"></i> Export to File</a></li>
<li><a ng-show="panel.save.default" ng-click="default()"><i class="icon-bookmark"></i> Set as My Default</a></li> <li><a ng-show="panel.save.default" ng-click="set_default()"><i class="icon-bookmark"></i> Set as My Default</a></li>
<li><a ng-show="panel.save.default" ng-click="purge()"><i class="icon-ban-circle"></i> Clear My Default</a></li> <li><a ng-show="panel.save.default" ng-click="purge_default()"><i class="icon-ban-circle"></i> Clear My Default</a></li>
</ul> </ul>
</form> </form>
</div> </div>
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
</div> </div>
<div class="modal-body"> <div class="modal-body">
<label>Share this dashboard with this URL</label> <label>Share this dashboard with this URL</label>
<input ng-model='share.link' type="text" style="width:90%" onclick="this.select()" onfocus="this.select()" ng-change="share_link(share.title,share.type,share.id)"> <input ng-model='share.link' type="text" style="width:90%" onclick="this.select()" onfocus="this.select()" ng-change="share = dashboard.share_link(share.title,share.type,share.id)">
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<button type="button" class="btn btn-success" ng-click="dismiss();$broadcast('render')">Close</button> <button type="button" class="btn btn-success" ng-click="dismiss();$broadcast('render')">Close</button>
......
<kibana-panel ng-controller='histogram' ng-init="init()" style="height:{{panel.height || row.height}}"> <kibana-panel ng-controller='histogram' ng-init="init()" style="height:{{panel.height || row.height}}">
<span ng-show="panel.spyable" style="position:absolute;right:0px;top:0px" class='panelextra pointer'> <style>
.histogram-legend {
display:inline-block;
padding-right:5px
}
.histogram-legend-dot {
display:inline-block;
height:10px;
width:10px;
border-radius:5px;
}
.histogram-legend-item {
display:inline-block;
}
.histogram-chart {
position:relative;
}
</style>
<span ng-show="panel.spyable" class='spy panelextra pointer'>
<i bs-modal="'partials/modal.html'" class="icon-eye-open"></i> <i bs-modal="'partials/modal.html'" class="icon-eye-open"></i>
</span> </span>
<div> <div>
...@@ -7,12 +25,12 @@ ...@@ -7,12 +25,12 @@
<a class='small' ng-click='zoom(0.5)'><i class='icon-zoom-in'></i> Zoom In</a> <a class='small' ng-click='zoom(0.5)'><i class='icon-zoom-in'></i> Zoom In</a>
<a class='small' ng-click='zoom(2)'><i class='icon-zoom-out'></i> Zoom Out</a> | <a class='small' ng-click='zoom(2)'><i class='icon-zoom-out'></i> Zoom Out</a> |
</span> </span>
<span ng-show="panel.legend" ng-repeat='series in plot.getData()' style='display:inline-block;padding-right:5px'> <span ng-show="panel.legend" ng-repeat='series in plot.getData()' class="histogram-legend">
<div style="display:inline-block;background:{{series.color}};height:10px;width:10px;border-radius:5px;"></div> <div class="histogram-legend-dot" style="background:{{series.color}};"></div>
<div class='small' style='display:inline-block'>{{series.label}} ({{series.hits}})</div> <div class='small histogram-legend-item'>{{series.label}} ({{series.hits}})</div>
</span> </span>
<span ng-show="panel.legend" class="small"><span ng-show="panel.value_field && panel.mode != 'count'">{{panel.value_field}}</span> {{panel.mode}} per <strong>{{panel.interval}}</strong> | (<strong>{{hits}}</strong> hits)</span> <span ng-show="panel.legend" class="small"><span ng-show="panel.value_field && panel.mode != 'count'">{{panel.value_field}}</span> {{panel.mode}} per <strong>{{panel.interval}}</strong> | (<strong>{{hits}}</strong> hits)</span>
</div> </div>
<center><img ng-show='panel.loading && _.isUndefined(data)' src="common/img/load_big.gif"></center> <center><img ng-show='panel.loading && _.isUndefined(data)' src="common/img/load_big.gif"></center>
<div histogram-chart params="{{panel}}" style="height:{{panel.height || row.height}};position:relative"></div> <div histogram-chart class="histogram-chart" params="{{panel}}" style="height:{{panel.height || row.height}};"></div>
</kibana-panel> </kibana-panel>
\ No newline at end of file
<kibana-panel ng-controller='map' ng-init="init()"> <kibana-panel ng-controller='map' ng-init="init()">
<span ng-show="panel.spyable" style="position:absolute;right:0px;top:0px" class='panelextra pointer'> <style>
.jvectormap-label {
position: absolute;
display: none;
border: solid 1px #CDCDCD;
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
border-radius: 3px;
background: #292929;
color: white;
font-family: sans-serif, Verdana;
font-size: smaller;
padding: 3px;
}
.jvectormap-zoomin, .jvectormap-zoomout {
position: absolute;
left: 10px;
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
border-radius: 3px;
background: #292929;
padding: 3px;
color: white;
width: 10px;
height: 10px;
cursor: pointer;
line-height: 10px;
text-align: center;
}
.jvectormap-zoomin {
display: none;
top: 10px;
}
.jvectormap-zoomout {
display: none;
top: 30px;
}
</style>
<span ng-show="panel.spyable" class='spy panelextra pointer'>
<i bs-modal="'partials/modal.html'" class="icon-eye-open"></i> <i bs-modal="'partials/modal.html'" class="icon-eye-open"></i>
</span> </span>
<div map params="{{panel}}" style="height:{{panel.height || row.height}}"></div> <div map params="{{panel}}" style="height:{{panel.height || row.height}}"></div>
......
<div class="row-fluid container" style="margin-top:10px"> <div class="row-fluid container" style="margin-top:10px">
<!-- Rows --> <!-- Rows -->
<div ng-controller="dashcontrol" ng-init="init()"></div> <div class="row-fluid kibana-row" ng-controller="RowCtrl" ng-repeat="(row_name, row) in dashboard.current.rows" ng-style="row_style(row)">
<div class="row-fluid kibana-row" ng-controller="RowCtrl" ng-repeat="(row_name, row) in dashboards.rows" ng-style="row_style(row)">
<div class="row-control"> <div class="row-control">
<div class="row-fluid row-header" style="padding:0px;margin:0px;height:0px"> <div class="row-fluid row-header" style="padding:0px;margin:0px;height:0px">
<div style="vertical-align:bottom"> <div style="vertical-align:bottom">
......
<div class="modal-header"> <div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button> <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h3>{{dashboards.title}} <small> editor</small></h3> <h3>{{dashboard.current.title}} <small> editor</small></h3>
</div> </div>
<div class="modal-body"> <div class="modal-body">
<h4>Dashboard Control</h4> <h4>Dashboard Control</h4>
<div class="row-fluid"> <div class="row-fluid">
<div class="span8"> <div class="span8">
<label class="small">Title</label><input type="text" class="input-large" ng-model='dashboards.title'></input> <label class="small">Title</label><input type="text" class="input-large" ng-model='dashboard.current.title'></input>
</div> </div>
<div class="span1"> <div class="span1">
<label class="small"> Editable </label><input type="checkbox" ng-model="dashboards.editable" ng-checked="dashboards.editable" /> <label class="small"> Editable </label><input type="checkbox" ng-model="dashboard.current.editable" ng-checked="dashboard.current.editable" />
</div> </div>
</div> </div>
<div class="row-fluid"> <div class="row-fluid">
...@@ -21,11 +21,11 @@ ...@@ -21,11 +21,11 @@
<th>Delete</th> <th>Delete</th>
<th>Move</th> <th>Move</th>
</thead> </thead>
<tr ng-repeat="row in dashboards.rows"> <tr ng-repeat="row in dashboard.current.rows">
<td>{{row.title}}</td> <td>{{row.title}}</td>
<td><i ng-click="dashboards.rows = _.without(dashboards.rows,row)" class="pointer icon-remove"></i></td> <td><i ng-click="dashboard.current.rows = _.without(dashboard.current.rows,row)" class="pointer icon-remove"></i></td>
<td><i ng-click="_.move(dashboards.rows,$index,$index-1)" ng-hide="$first" class="pointer icon-arrow-up"></i></td> <td><i ng-click="_.move(dashboard.current.rows,$index,$index-1)" ng-hide="$first" class="pointer icon-arrow-up"></i></td>
<td><i ng-click="_.move(dashboards.rows,$index,$index+1)" ng-hide="$last" class="pointer icon-arrow-down"></i></td> <td><i ng-click="_.move(dashboard.current.rows,$index,$index+1)" ng-hide="$last" class="pointer icon-arrow-down"></i></td>
</tr> </tr>
</table> </table>
</div> </div>
...@@ -45,7 +45,7 @@ ...@@ -45,7 +45,7 @@
<input type="checkbox" ng-model="row.editable" ng-checked="row.editable" /> <input type="checkbox" ng-model="row.editable" ng-checked="row.editable" />
</div> </div>
</div> </div>
<button ng-click="add_row(dashboards,row); reset_row();" class="btn btn-primary">Create Row</button><br> <button ng-click="add_row(dashboard.current,row); reset_row();" class="btn btn-primary">Create Row</button><br>
</div> </div>
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
......
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