Commit c6d8ea23 by Rashid Khan

Merge pull request #467 from rashidkpc/navbar-control

Moved dash controller to navbar. Settings for it to dashboard settings.
parents 9798f8be eb25ce5f
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.
......@@ -91,40 +91,6 @@
"status": "Stable"
}
]
},
{
"title": "Loader",
"height": "50px",
"editable": true,
"collapse": false,
"collapsable": true,
"panels": [
{
"error": false,
"span": 3,
"editable": true,
"group": [
"default"
],
"type": "dashcontrol",
"save": {
"gist": false,
"elasticsearch": true,
"local": true,
"default": true
},
"load": {
"gist": true,
"elasticsearch": true,
"local": true
},
"hide_control": false,
"elasticsearch_size": 20,
"temp": true,
"ttl_enable": true,
"temp_ttl": "30d"
}
]
}
],
"editable": true,
......
......@@ -40,45 +40,6 @@
"panels": [
{
"error": false,
"span": 3,
"editable": true,
"group": [
"default"
],
"type": "dashcontrol",
"save": {
"gist": false,
"elasticsearch": true,
"local": true,
"default": true
},
"load": {
"gist": true,
"elasticsearch": true,
"local": true
},
"hide_control": false,
"elasticsearch_size": 20,
"temp": true,
"temp_ttl": "30d",
"ttl_enable": true
},
{
"error": false,
"span": 4,
"editable": true,
"group": [
"default"
],
"type": "text",
"status": "Stable",
"mode": "markdown",
"content": "The dashcontrol panel to the left lets you save this dashboard to Elasticsearch once you have it how you like it. See the note on the welcome page about setting a global default.",
"style": {},
"title": "The dashcontrol panel"
},
{
"error": false,
"span": 5,
"editable": true,
"group": [
......
......@@ -129,10 +129,6 @@ dashboard.rows[0].panels = [
type: 'timepicker',
span: 6,
timespan: ARGS.from||_d_timespan
},
{
type: 'dashcontrol',
span: 3
}
];
......
......@@ -76,31 +76,6 @@
},
"filter_id": 0,
"status": "Stable"
},
{
"error": false,
"span": 3,
"editable": true,
"group": [
"default"
],
"type": "dashcontrol",
"save": {
"gist": false,
"elasticsearch": true,
"local": true,
"default": true
},
"load": {
"gist": true,
"elasticsearch": true,
"local": true
},
"hide_control": false,
"elasticsearch_size": 20,
"temp": true,
"temp_ttl": "30d",
"ttl_enable": true
}
]
},
......
......@@ -40,45 +40,6 @@
"panels": [
{
"error": false,
"span": 3,
"editable": true,
"group": [
"default"
],
"type": "dashcontrol",
"save": {
"gist": false,
"elasticsearch": true,
"local": true,
"default": true
},
"load": {
"gist": true,
"elasticsearch": true,
"local": true
},
"hide_control": false,
"elasticsearch_size": 20,
"temp": true,
"temp_ttl": "30d",
"ttl_enable": true
},
{
"error": false,
"span": 4,
"editable": true,
"group": [
"default"
],
"type": "text",
"status": "Stable",
"mode": "markdown",
"content": "The dashcontrol panel to the left lets you save this dashboard to Elasticsearch once you have it how you like it. See the note on the welcome page about setting a global default.",
"style": {},
"title": "The dashcontrol panel"
},
{
"error": false,
"span": 5,
"editable": true,
"group": [
......@@ -212,6 +173,6 @@
"index": {
"interval": "none",
"pattern": "[logstash-]YYYY.MM.DD",
"default": "NOT_CONFIGURED"
"default": "_all"
}
}
\ No newline at end of file
}
<!DOCTYPE html>
<!--[if lt IE 7]> <html class="no-js lt-ie9 lt-ie8 lt-ie7" lang="en" id="ng-app"> <![endif]-->
<!--[if IE 7]> <html class="no-js lt-ie9 lt-ie8" lang="en" id="ng-app"> <![endif]-->
<!--[if IE 8]> <html class="no-js lt-ie9" lang="en"> <![endif]-->
<!--[if gt IE 8]><!--> <html class="no-js" lang="en"> <!--<![endif]-->
<head>
......@@ -39,9 +37,14 @@
<div class="navbar navbar-static-top">
<div class="navbar-inner">
<div class="container-fluid">
<p class="navbar-text pull-right version"><strong>Kibana 3</strong> milestone 3</p>
<span class="brand">{{dashboard.current.title}}</span>
<div class="brand"><i class='icon-cog pointer' ng-show='dashboard.current.editable' bs-modal="'partials/dasheditor.html'"></i></div>
<ul class="nav" ng-show='dashboard.current.editable'>
<li>
<a href='#' bs-modal="'partials/dasheditor.html'"><i class='icon-cog pointer'></i></a>
</li>
</ul>
<ul class="nav pull-right" ng-controller='dashLoader' ng-init="init()" ng-include="'partials/dashLoader.html'">
</ul>
</div>
</div>
</div>
......
......@@ -43,6 +43,7 @@ _.each(config.modules, function(v) {
/* Application level module which depends on filters, controllers, and services */
labjs.wait(function(){
// Create the module
angular.module('kibana', modules).config(['$routeProvider', function($routeProvider) {
$routeProvider
.when('/dashboard', {
......@@ -58,6 +59,8 @@ labjs.wait(function(){
redirectTo: 'dashboard'
});
}]);
// Wait for ready, then bootstrap
angular.element(document).ready(function() {
$('body').attr('ng-controller', 'DashCtrl');
angular.bootstrap(document, ['kibana']);
......
......@@ -118,6 +118,118 @@ angular.module('kibana.controllers', [])
$scope.init();
})
.controller('dashLoader', function($scope, $http, timer, dashboard, alertSrv) {
$scope.loader = dashboard.current.loader;
$scope.init = function() {
$scope.gist_pattern = /(^\d{5,}$)|(^[a-z0-9]{10,}$)|(gist.github.com(\/*.*)\/[a-z0-9]{5,}\/*$)/;
$scope.gist = $scope.gist || {};
$scope.elasticsearch = $scope.elasticsearch || {};
};
$scope.showDropdown = function(type) {
var _l = $scope.loader;
if(type === 'load') {
return (_l.load_elasticsearch || _l.load_gist || _l.load_local);
}
if(type === 'save') {
return (_l.save_elasticsearch || _l.save_gist || _l.local_local || _l.save_default);
}
if(type === 'share') {
return (_l.save_temp);
}
return false;
};
$scope.set_default = function() {
if(dashboard.set_default()) {
alertSrv.set('Local Default Set',dashboard.current.title+' has been set as your local default','success',5000);
} else {
alertSrv.set('Incompatible Browser','Sorry, your browser is too old for this feature','error',5000);
}
};
$scope.purge_default = function() {
if(dashboard.purge_default()) {
alertSrv.set('Local Default Clear','Your local default dashboard has been cleared','success',5000);
} else {
alertSrv.set('Incompatible Browser','Sorry, your browser is too old for this feature','error',5000);
}
};
$scope.elasticsearch_save = function(type,ttl) {
dashboard.elasticsearch_save(
type,
($scope.elasticsearch.title || dashboard.current.title),
($scope.loader.save_temp_ttl_enable ? ttl : false)
).then(
function(result) {
if(!_.isUndefined(result._id)) {
alertSrv.set('Dashboard Saved','This dashboard has been saved to Elasticsearch as "' +
result._id + '"','success',5000);
if(type === 'temp') {
$scope.share = dashboard.share_link(dashboard.current.title,'temp',result._id);
}
} else {
alertSrv.set('Save failed','Dashboard could not be saved to Elasticsearch','error',5000);
}
});
};
$scope.elasticsearch_delete = function(id) {
dashboard.elasticsearch_delete(id).then(
function(result) {
if(!_.isUndefined(result)) {
if(result.found) {
alertSrv.set('Dashboard Deleted',id+' has been deleted','success',5000);
// Find the deleted dashboard in the cached list and remove it
var toDelete = _.where($scope.elasticsearch.dashboards,{_id:id})[0];
$scope.elasticsearch.dashboards = _.without($scope.elasticsearch.dashboards,toDelete);
} else {
alertSrv.set('Dashboard Not Found','Could not find '+id+' in Elasticsearch','warning',5000);
}
} else {
alertSrv.set('Dashboard Not Deleted','An error occurred deleting the dashboard','error',5000);
}
}
);
};
$scope.elasticsearch_dblist = function(query) {
dashboard.elasticsearch_list(query,$scope.loader.load_elasticsearch_size).then(
function(result) {
if(!_.isUndefined(result.hits)) {
$scope.hits = result.hits.total;
$scope.elasticsearch.dashboards = result.hits.hits;
}
});
};
$scope.save_gist = function() {
dashboard.save_gist($scope.gist.title).then(
function(link) {
if(!_.isUndefined(link)) {
$scope.gist.last = link;
alertSrv.set('Gist saved','You will be able to access your exported dashboard file at '+
'<a href="'+link+'">'+link+'</a> in a moment','success');
} else {
alertSrv.set('Save failed','Gist could not be saved','error',5000);
}
});
};
$scope.gist_dblist = function(id) {
dashboard.gist_list(id).then(
function(files) {
if(files && files.length > 0) {
$scope.gist.files = files;
} else {
alertSrv.set('Gist Failed','Could not retrieve dashboard list from gist','error',5000);
}
});
};
});
......
......@@ -12,7 +12,7 @@ angular.module('kibana.directives', [])
' <span class="editlink panelextra pointer" style="right:15px;top:0px" ' +
'bs-modal="\'partials/paneleditor.html\'" ng-show="panel.editable != false">'+
'<span class="small">{{panel.type}}</span> <i class="icon-cog pointer"></i> '+
'</span><h4>'+
'</span><h4 ng-show="panel.title">'+
'{{panel.title}} '+
'<i class="icon-spinner smaller icon-spin icon-large" ng-show="panelMeta.loading == true && panel.title"></i>'+
'</h4>';
......@@ -24,7 +24,8 @@ angular.module('kibana.directives', [])
return {
restrict: 'E',
link: function(scope, elem, attrs) {
var _t = '<i class="icon-question-sign" bs-tooltip="\''+elem.text()+'\'"></i>';
var _t = '<i class="icon-'+(attrs.icon||'question-sign')+'" bs-tooltip="\''+
kbn.addslashes(elem.text())+'\'"></i>';
elem.replaceWith($compile(angular.element(_t))(scope));
}
};
......@@ -96,5 +97,37 @@ angular.module('kibana.directives', [])
});
});
};
}]);
}])
.directive('dashUpload', function(timer, dashboard, alertSrv){
return {
restrict: 'A',
link: function(scope, elem, attrs) {
function file_selected(evt) {
var files = evt.target.files; // FileList object
// files is a FileList of File objects. List some properties.
var output = [];
var readerOnload = function(theFile) {
return function(e) {
dashboard.dash_load(JSON.parse(e.target.result));
scope.$apply();
};
};
for (var i = 0, f; f = files[i]; i++) {
var reader = new FileReader();
reader.onload = (readerOnload)(f);
reader.readAsText(f);
}
}
// Check for the various File API support.
if (window.File && window.FileReader && window.FileList && window.Blob) {
// Something
document.getElementById('dashupload').addEventListener('change', file_selected, false);
} else {
alertSrv.set('Oops','Sorry, the HTML5 File APIs are not fully supported in this browser.','error');
}
}
};
});
......@@ -68,4 +68,15 @@ angular.module('kibana.filters', [])
});
return text;
};
}).filter('gistid', function() {
var gist_pattern = /(\d{5,})|([a-z0-9]{10,})|(gist.github.com(\/*.*)\/[a-z0-9]{5,}\/*$)/;
return function(input, scope) {
//return input+"boners"
if(!(_.isUndefined(input))) {
var output = input.match(gist_pattern);
if(!_.isNull(output) && !_.isUndefined(output)) {
return output[0].replace(/.*\//, '');
}
}
};
});
\ No newline at end of file
......@@ -579,6 +579,20 @@ angular.module('kibana.services', [])
failover: false,
rows: [],
services: {},
loader: {
save_gist: false,
save_elasticsearch: true,
save_local: true,
save_default: true,
save_temp: true,
save_temp_ttl_enable: true,
save_temp_ttl: '30d',
load_gist: true,
load_elasticsearch: true,
load_elasticsearch_size: 20,
load_local: true,
hide: false
},
index: {
interval: 'none',
pattern: '_all',
......@@ -683,13 +697,20 @@ angular.module('kibana.services', [])
}
};
var dash_defaults = function(dashboard) {
_.defaults(dashboard,_dash);
_.defaults(dashboard.index,_dash.index);
_.defaults(dashboard.loader,_dash.loader);
return dashboard;
};
this.dash_load = function(dashboard) {
// Cancel all timers
timer.cancel_all();
// Make sure the dashboard being loaded has everything required
_.defaults(dashboard,_dash);
dashboard = dash_defaults(dashboard);
// If not using time based indices, use the default index
if(dashboard.index.interval === 'none') {
......@@ -790,9 +811,7 @@ angular.module('kibana.services', [])
return false;
}
var _dashboard = result.data;
_.defaults(_dashboard,_dash);
self.dash_load(_dashboard);
self.dash_load(dash_defaults(result.data));
return true;
},function(result) {
alertSrv.set('Error',"Could not load <i>dashboards/"+file+"</i>. Please make sure it exists" ,'error');
......@@ -834,9 +853,7 @@ angular.module('kibana.services', [])
if(!result) {
return false;
}
var _dashboard = result.data;
_.defaults(_dashboard,_dash);
self.dash_load(_dashboard);
self.dash_load(dash_defaults(result.data));
return true;
},function(result) {
alertSrv.set('Error',
......@@ -907,7 +924,6 @@ angular.module('kibana.services', [])
);
};
// TOFIX: Gist functionality
this.save_gist = function(title,dashboard) {
var save = _.clone(dashboard || self.current);
save.title = title || self.current.title;
......@@ -939,7 +955,7 @@ angular.module('kibana.services', [])
var file = JSON.parse(v.content);
files.push(file);
} catch(e) {
// Nothing?
return false;
}
});
return files;
......
<kibana-panel ng-controller='dashcontrol' ng-init="init()">
<label class='small'>Dashboard Control</label>
<label class='small'>Dash Control <tip icon="warning-sign">This panel is deprecated! Please remove it from your dashboard</tip></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.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',panel.temp_ttl)" bs-modal="'panels/dashcontrol/share.html'"><i class='icon-share'></i></button>
......
......@@ -27,8 +27,8 @@ angular.module('kibana.dashcontrol', [])
.controller('dashcontrol', function($scope, $http, timer, dashboard, alertSrv) {
$scope.panelMeta = {
status : "Stable",
description : "This panel allows for saving, loading, exporting and sharing dashboard schemas."
status : "Deprecated",
description : "This panel has been moved to the navigation bar. See the dashboard setting editor to configure it."
};
$scope.panel = $scope.panel || {};
......
......@@ -8,7 +8,7 @@
<ul class="nav nav-list">
<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="set_default()"><i class="icon-bookmark"></i> Set as 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>
<li><a ng-show="panel.save.default" ng-click="purge_default()"><i class="icon-ban-circle"></i> Clear My Default</a></li>
</ul>
</form>
</div>
......
<li class="dropdown" bs-tooltip="'Load'" data-placement="bottom" ng-show="showDropdown('load')" >
<a href="#" class="dropdown-toggle" data-toggle="dropdown" ng-click="elasticsearch_dblist('*')">
<i class='icon-folder-open'></i>
</a>
<ul class="dropdown-menu" style="padding:10px">
<li ng-show='loader.load_local'>
<h5>Local File <tip>Load dashboard JSON layout from file</tip></h5>
<form>
<input type="file" id="dashupload" dash-upload /><br>
</form>
</li>
<li ng-show='loader.load_gist'>
<h5>Gist <tip>Enter a gist number or url</tip></h5>
<form>
<input type="text" ng-model="gist.url"/ placeholder="Gist number or URL"><br>
<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-hide="gist.files.length">No gist dashboards found</h6>
<table class="table table-condensed table-striped">
<tr ng-repeat="file in gist.files">
<td><a ng-click="dashboard.dash_load(file)">{{file.title}}</a></td>
</tr>
</table>
</form>
</li>
<li ng-show='loader.load_elasticsearch'>
<h5>Elasticsearch</h5>
<form>
<input type="text" ng-model="elasticsearch.query" ng-change="elasticsearch_dblist('title:'+elasticsearch.query+'*')" placeholder="Type to filter"/>
</form>
<h6 ng-show="elasticsearch.dashboards.length">Elasticsearch stored dashboards</h6>
<h6 ng-hide="elasticsearch.dashboards.length">No dashboards matching your query found</h6>
<table class="table table-condensed table-striped">
<tr ng-repeat="row in elasticsearch.dashboards | orderBy:['_id']">
<td><a ng-click="elasticsearch_delete(row._id)"><i class="icon-remove"></i></a></td>
<td><a href="#/dashboard/elasticsearch/{{row._id}}">{{row._id}}</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>
</table>
</li>
</ul>
</li>
<li class="dropdown" bs-tooltip="'Save'" data-placement="bottom" ng-show="showDropdown('save')">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">
<i class='icon-save'></i>
</a>
<ul class="dropdown-menu" style="padding:10px">
<li ng-show="loader.save_default || loader.save_local">
<h5>Locally</h5>
<ul class="unstyled">
<li><a class="link" ng-show="loader.save_local" ng-click="dashboard.to_file()"><i class="icon-download"></i> Export to File</a> <tip>Export layout, not data, to file</tip></li>
<li><a class="link" ng-show="loader.save_default" ng-click="set_default()"><i class="icon-bookmark"></i> Set as Browser Default</a> <tip>Store dashboard preference to browser's localStorage</tip></li>
<li><a class="link" ng-show="loader.save_default" ng-click="purge_default()"><i class="icon-ban-circle"></i> Clear Browser Default</a></li>
</ul>
</li>
<li ng-show="loader.save_gist">
<h5>Gist</h5>
<form class="input-append">
<input class='input-medium' placeholder='Title' type="text" ng-model="gist.title"/>
<button class="btn" ng-click="save_gist()"><i class="icon-github-alt"></i></button>
</form><br>
<small ng-show="gist.last">Last gist: <a target="_blank" href="{{gist.last}}">{{gist.last}}</a></small>
</li>
<li ng-show="loader.save_elasticsearch">
<h5>Elasticsearch</h5>
<form class="input-append">
<input class='input-medium' placeholder='Title' type="text" ng-model="elasticsearch.title"/>
<button class="btn" ng-click="elasticsearch_save('dashboard')"><i class="icon-save"></i></button>
</form>
</li>
</ul>
</li>
<li ng-show="showDropdown('share')"><a bs-tooltip="'Share'" data-placement="bottom" ng-click="elasticsearch_save('temp',loader.save_temp_ttl)" bs-modal="'partials/dashLoaderShare.html'"><i class='icon-share'></i></a></li>
\ No newline at end of file
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h3>{{share.title}} <small>shareable link</small></h3>
</div>
<div class="modal-body">
<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 = dashboard.share_link(share.title,share.type,share.id)">
</div>
<div class="modal-footer">
<button type="button" class="btn btn-success" ng-click="dismiss();$broadcast('render')">Close</button>
</div>
\ No newline at end of file
......@@ -2,44 +2,47 @@
<div class="pull-right editor-title">Dashboard settings</div>
<div ng-model="editor.index" bs-tabs>
<div ng-repeat="tab in ['General','Index','Rows']" data-title="{{tab}}">
<div ng-repeat="tab in ['General','Index','Rows','Controls']" data-title="{{tab}}">
</div>
</div>
<div class="row-fluid" ng-show="editor.index == 0">
<div class="span4">
<label class="small">Title</label><input type="text" class="input-large" ng-model='dashboard.current.title'></input>
</div>
<div class="span1">
<label class="small"> Editable </label><input type="checkbox" ng-model="dashboard.current.editable" ng-checked="dashboard.current.editable" />
</div>
<div class="span3">
<label class="small">Style</label><select class="input-small" ng-model="dashboard.current.style" ng-options='f for f in ["dark","light"]'></select>
<div ng-show="editor.index == 0">
<div class="row-fluid">
<div class="span4">
<label class="small">Title</label><input type="text" class="input-large" ng-model='dashboard.current.title'></input>
</div>
<div class="span1">
<label class="small"> Editable </label><input type="checkbox" ng-model="dashboard.current.editable" ng-checked="dashboard.current.editable" />
</div>
<div class="span3">
<label class="small">Style</label><select class="input-small" ng-model="dashboard.current.style" ng-options='f for f in ["dark","light"]'></select>
</div>
</div>
</div>
<div class="row-fluid" ng-show="editor.index == 1">
<h4>Index Settings</h4>
<div ng-show="dashboard.current.index.interval != 'none'" class="row-fluid">
<div class="span12">
<p class="small">
Time stamped indices use your selected time range to create a list of
indices that match a specified timestamp pattern. This can be very
efficient for some data sets (eg, logs) For example, to match the
default logstash index pattern you might use
<code>[logstash-]YYYY.MM.DD</code>. The [] in "[logstash-]" are
important as they instruct Kibana not to treat those letters as a
pattern.
Please also note that indices should rollover at midnight <strong>UTC</strong>.
</p>
<p class="small">
See <a href="http://momentjs.com/docs/#/displaying/format/">http://momentjs.com/docs/#/displaying/format/</a>
for documentation on date formatting.
</p>
</div>
<div ng-show="editor.index == 1">
<div class="row-fluid">
<h4>Index Settings</h4>
<div ng-show="dashboard.current.index.interval != 'none'" class="row-fluid">
<div class="span12">
<p class="small">
Time stamped indices use your selected time range to create a list of
indices that match a specified timestamp pattern. This can be very
efficient for some data sets (eg, logs) For example, to match the
default logstash index pattern you might use
<code>[logstash-]YYYY.MM.DD</code>. The [] in "[logstash-]" are
important as they instruct Kibana not to treat those letters as a
pattern.
Please also note that indices should rollover at midnight <strong>UTC</strong>.
</p>
<p class="small">
See <a href="http://momentjs.com/docs/#/displaying/format/">http://momentjs.com/docs/#/displaying/format/</a>
for documentation on date formatting.
</p>
</div>
</div>
</div>
<div class="row-fluid">
<div class="row-fluid">
<div class="span2">
<h6>Timestamping</h6><select class="input-small" ng-model="dashboard.current.index.interval" ng-options='f for f in ["none","hour","day","week","month","year"]'></select>
</div>
......@@ -57,43 +60,90 @@
</div>
</div>
</div>
<div class="row-fluid" ng-show="editor.index == 2">
<div class="span12">
<table class="table table-condensed table-striped">
<thead>
<th>Title</th>
<th>Delete</th>
<th>Move</th>
</thead>
<tr ng-repeat="row in dashboard.current.rows">
<td>{{row.title}}</td>
<td><i ng-click="dashboard.current.rows = _.without(dashboard.current.rows,row)" class="pointer icon-remove"></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(dashboard.current.rows,$index,$index+1)" ng-hide="$last" class="pointer icon-arrow-down"></i></td>
</tr>
</table>
<div ng-show="editor.index == 2">
<div class="row-fluid">
<div class="span12">
<table class="table table-condensed table-striped">
<thead>
<th>Title</th>
<th>Delete</th>
<th>Move</th>
</thead>
<tr ng-repeat="row in dashboard.current.rows">
<td>{{row.title}}</td>
<td><i ng-click="dashboard.current.rows = _.without(dashboard.current.rows,row)" class="pointer icon-remove"></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(dashboard.current.rows,$index,$index+1)" ng-hide="$last" class="pointer icon-arrow-down"></i></td>
</tr>
</table>
</div>
</div>
<div class="row-fluid">
<form>
<div class="span5">
<label class="small">Title</label>
<input type="text" class="input-large" ng-model='row.title' placeholder="New row"></input>
</div>
<div class="span2">
<label class="small">Height</label>
<input type="text" class="input-mini" ng-model='row.height'></input>
</div>
<div class="span1">
<label class="small"> Editable </label>
<input type="checkbox" ng-model="row.editable" ng-checked="row.editable" />
</div>
</form>
</div>
</div>
<div class="row-fluid" ng-show="editor.index == 2">
<form>
<div class="span5">
<label class="small">Title</label>
<input type="text" class="input-large" ng-model='row.title' placeholder="New row"></input>
<div ng-show="editor.index == 3" ng-controller="dashLoader">
<h5>Allow saving to</h5>
<div class="row-fluid">
<div class="span2">
<label class="small">File</label><input type="checkbox" ng-model="loader.save_local" ng-checked="loader.save_local">
</div>
<div class="span2">
<label class="small">Height</label>
<input type="text" class="input-mini" ng-model='row.height'></input>
<label class="small">Browser</label><input type="checkbox" ng-model="loader.save_default" ng-checked="loader.save_default">
</div>
<div class="span1">
<label class="small"> Editable </label>
<input type="checkbox" ng-model="row.editable" ng-checked="row.editable" />
<div class="span2">
<label class="small">Gist <tip>Requires your domain to be OAUTH registered with Github<tip></label><input type="checkbox" ng-model="loader.save_gist" ng-checked="loader.save_gist">
</div>
<div class="span2">
<label class="small">Elasticsearch</label><input type="checkbox" ng-model="loader.save_elasticsearch" ng-checked="loader.save_elasticsearch">
</div>
</div>
<h5>Allow loading from</h5>
<div class="row-fluid">
<div class="span2">
<label class="small">Local file</label><input type="checkbox" ng-model="loader.load_local" ng-checked="loader.load_local">
</div>
<div class="span2">
<label class="small">Gist</label><input type="checkbox" ng-model="loader.load_gist" ng-checked="loader.load_gist">
</div>
<div class="span2">
<label class="small">Elasticsearch</label><input type="checkbox" ng-model="loader.load_elasticsearch" ng-checked="loader.load_elasticsearch">
</div>
</form>
<div class="span3" ng-show="loader.load.elasticsearch">
<label class="small">ES list size</label><input class="input-mini" type="number" ng-model="loader.load_elasticsearch_size">
</div>
</div>
<h5>Sharing</h5>
<div class="row-fluid">
<div class="span2" >
<label class="small">Allow Sharing <tip>Allow generating adhoc links to dashboards</tip></label><input type="checkbox" ng-model="loader.save_temp" ng-checked="loader.save_temp">
</div>
<div class="span2" ng-show="loader.save_temp">
<label class="small">TTL <tip>Expire temp urls</tip></label><input type="checkbox" ng-model="loader.save_temp_ttl_enable">
</div>
<div class="span5" ng-show="loader.save_temp && loader.save_temp_ttl_enable">
<label class="small">TTL Duration <tip>Elasticsearch date math, eg: 1m,1d,1w,30d </tip></label><input class="input-small" type="text" ng-model="loader.save_temp_ttl">
</div>
</div>
</div>
<!--<div class="row-fluid" ng-show="editor.index == 3">
<h6>Region</h6><select class="input-small" ng-model="dashboard.current.time.region" ng-options='f for f in ["africa","america","asia","atlantic","australia","europe","indian","pacific"]'></select>
</div>-->
</div>
<div class="modal-footer">
<button ng-click="add_row(dashboard.current,row); reset_row();" class="btn btn-success" ng-show="editor.index == 2">Create Row</button>
<button type="button" class="btn btn-danger" ng-click="editor.index=0;dismiss();reset_panel();dashboard.refresh()">Close</button>
......
......@@ -62,7 +62,7 @@ hr {
.nav > li.active > a:hover {
color: @grayLighter;
background-color: @grayDark;
#gradient > .directional(lighten(@grayDarker, 4%), lighten(@grayDark, 4%), 280deg);
#gradient > .directional(lighten(@grayDarker, 2%), lighten(@grayDark, 2%), 0deg);
border-right: 1px solid darken(@gray, 15%);
}
......@@ -309,7 +309,7 @@ div.subnav {
li > a,
li > span {
border: 1px solid transparent;
.box-shadow('0 1px 3px rgba(0, 0, 0, 0.25), inset 0 -1px 0 rgba(0, 0, 0, 0.1)');
#gradient > .vertical-three-colors(@gray, @grayDark, 70%, @grayDark);
......@@ -318,7 +318,7 @@ div.subnav {
#gradient > .directional(@grayDarker, @grayDark, 280deg);
border: 1px solid transparent;
}
}
}
.disabled a,
.disabled a:hover {
......
......@@ -186,7 +186,7 @@
@navbarBorder: darken(@navbarBackground, 12%);
@navbarText: @white;
@navbarLinkColor: @textColor;
@navbarLinkColor: @white;
@navbarLinkColorHover: @white;
@navbarLinkColorActive: @navbarLinkColorHover;
@navbarLinkBackgroundHover: @grayDark;
......
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