mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Added relative/absolute/since time selector. Moved refresh func out to panel
This commit is contained in:
parent
a73242cae5
commit
834e63a123
@ -1,156 +0,0 @@
|
||||
/* =========================================================
|
||||
* bootstrap-datepicker.js
|
||||
* original by Stefan Petre
|
||||
* tweaked by gus
|
||||
* ========================================================= */
|
||||
|
||||
.bs-sc-datepicker.dropdown-menu {
|
||||
max-width: inherit;
|
||||
}
|
||||
.bs-sc-datepicker {
|
||||
top: 0;
|
||||
left: 0;
|
||||
padding: 4px;
|
||||
margin-top: 1px;
|
||||
-webkit-border-radius: 4px;
|
||||
-moz-border-radius: 4px;
|
||||
border-radius: 4px;
|
||||
z-index: 1051;
|
||||
}
|
||||
.bs-sc-datepicker:before {
|
||||
content: '';
|
||||
display: inline-block;
|
||||
border-left: 7px solid transparent;
|
||||
border-right: 7px solid transparent;
|
||||
border-bottom: 7px solid #ccc;
|
||||
border-bottom-color: rgba(0, 0, 0, 0.2);
|
||||
position: absolute;
|
||||
top: -7px;
|
||||
left: 6px;
|
||||
}
|
||||
.bs-sc-datepicker:after {
|
||||
content: '';
|
||||
display: inline-block;
|
||||
border-left: 6px solid transparent;
|
||||
border-right: 6px solid transparent;
|
||||
border-bottom: 6px solid #ffffff;
|
||||
position: absolute;
|
||||
top: -6px;
|
||||
left: 7px;
|
||||
}
|
||||
.bs-sc-datepicker table {
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
}
|
||||
.bs-sc-datepicker th {
|
||||
border-bottom: 1px solid #efefef;
|
||||
}
|
||||
.bs-sc-datepicker td, .bs-sc-datepicker th {
|
||||
text-align: center;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
-webkit-border-radius: 4px;
|
||||
-moz-border-radius: 4px;
|
||||
border-radius: 4px;
|
||||
padding: 5px !important;
|
||||
}
|
||||
.bs-sc-datepicker td.day:hover {
|
||||
background: #eeeeee;
|
||||
cursor: pointer;
|
||||
}
|
||||
.bs-sc-datepicker td.old, .bs-sc-datepicker td.new {
|
||||
color: #DDDDDD;
|
||||
}
|
||||
.bs-sc-datepicker td.active, .bs-sc-datepicker td.active:hover {
|
||||
background-color: #006dcc;
|
||||
background-image: -moz-linear-gradient(top, #0088cc, #0044cc);
|
||||
background-image: -ms-linear-gradient(top, #0088cc, #0044cc);
|
||||
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0044cc));
|
||||
background-image: -webkit-linear-gradient(top, #0088cc, #0044cc);
|
||||
background-image: -o-linear-gradient(top, #0088cc, #0044cc);
|
||||
background-image: linear-gradient(top, #0088cc, #0044cc);
|
||||
background-repeat: repeat-x;
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#0088cc', endColorstr='#0044cc', GradientType=0);
|
||||
border-color: #0044cc #0044cc #002a80;
|
||||
border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
|
||||
color: #fff;
|
||||
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
|
||||
}
|
||||
.bs-sc-datepicker td.active:hover,
|
||||
.bs-sc-datepicker td.active:hover:hover,
|
||||
.bs-sc-datepicker td.active:active,
|
||||
.bs-sc-datepicker td.active:hover:active,
|
||||
.bs-sc-datepicker td.active.active,
|
||||
.bs-sc-datepicker td.active:hover.active,
|
||||
.bs-sc-datepicker td.active.disabled,
|
||||
.bs-sc-datepicker td.active:hover.disabled,
|
||||
.bs-sc-datepicker td.active[disabled],
|
||||
.bs-sc-datepicker td.active:hover[disabled] {
|
||||
background-color: #0044cc;
|
||||
}
|
||||
.bs-sc-datepicker td.active:active,
|
||||
.bs-sc-datepicker td.active:hover:active,
|
||||
.bs-sc-datepicker td.active.active,
|
||||
.bs-sc-datepicker td.active:hover.active {
|
||||
background-color: #003399 \9;
|
||||
}
|
||||
.bs-sc-datepicker td span {
|
||||
display: block;
|
||||
width: 47px;
|
||||
height: 54px;
|
||||
line-height: 54px;
|
||||
float: left;
|
||||
margin: 2px;
|
||||
cursor: pointer;
|
||||
-webkit-border-radius: 4px;
|
||||
-moz-border-radius: 4px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
.bs-sc-datepicker td span:hover {
|
||||
background: #eeeeee;
|
||||
}
|
||||
.bs-sc-datepicker td span.active {
|
||||
background-color: #006dcc;
|
||||
background-image: -moz-linear-gradient(top, #0088cc, #0044cc);
|
||||
background-image: -ms-linear-gradient(top, #0088cc, #0044cc);
|
||||
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0044cc));
|
||||
background-image: -webkit-linear-gradient(top, #0088cc, #0044cc);
|
||||
background-image: -o-linear-gradient(top, #0088cc, #0044cc);
|
||||
background-image: linear-gradient(top, #0088cc, #0044cc);
|
||||
background-repeat: repeat-x;
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#0088cc', endColorstr='#0044cc', GradientType=0);
|
||||
border-color: #0044cc #0044cc #002a80;
|
||||
border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
|
||||
color: #fff;
|
||||
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
|
||||
}
|
||||
.bs-sc-datepicker td span.active:hover,
|
||||
.bs-sc-datepicker td span.active:active,
|
||||
.bs-sc-datepicker td span.active.active,
|
||||
.bs-sc-datepicker td span.active.disabled,
|
||||
.bs-sc-datepicker td span.active[disabled] {
|
||||
background-color: #0044cc;
|
||||
}
|
||||
.bs-sc-datepicker td span.active:active, .bs-sc-datepicker td span.active.active {
|
||||
background-color: #003399 \9;
|
||||
}
|
||||
.bs-sc-datepicker td span.old {
|
||||
color: #999999;
|
||||
}
|
||||
.bs-sc-datepicker th.switch {
|
||||
width: 145px;
|
||||
}
|
||||
.bs-sc-datepicker thead tr:first-child th {
|
||||
cursor: pointer;
|
||||
}
|
||||
.bs-sc-datepicker thead tr:first-child th:hover {
|
||||
background: #eeeeee;
|
||||
}
|
||||
.input-append.date .add-on i, .input-prepend.date .add-on i {
|
||||
display: block;
|
||||
cursor: pointer;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
@ -22,4 +22,33 @@
|
||||
|
||||
.pointer {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.small {
|
||||
font-size: 85%;
|
||||
}
|
||||
|
||||
.nomargin {
|
||||
margin: 0px;
|
||||
}
|
||||
|
||||
.strong {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.btn-active {
|
||||
background-color: #E6E6E6;
|
||||
background-image: none;
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.15) inset, 0 1px 2px rgba(0, 0, 0, 0.05);
|
||||
outline: 0 none
|
||||
}
|
||||
|
||||
.popover-title { display: none; }
|
||||
|
||||
.input-smaller {
|
||||
width: 75px;
|
||||
}
|
||||
|
||||
.tiny {
|
||||
font-size: 50%;
|
||||
}
|
91
common/css/timepicker.css
Normal file
91
common/css/timepicker.css
Normal file
@ -0,0 +1,91 @@
|
||||
|
||||
/*
|
||||
Datepicker for Bootstrap
|
||||
Copyright 2012 Stefan Petre
|
||||
Licensed under the Apache License v2.0
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
*/
|
||||
input[type="date"] { -webkit-appearance: none; } .datepicker { top: 0; left: 0; padding: 4px; margin-top: 1px; -webkit-border-radius: 4px; -moz-border-radius: 4px; border-radius: 4px; /*.dow { border-top: 1px solid #ddd !important; }*/ } .datepicker:before { content: ''; display: inline-block; border-left: 7px solid transparent; border-right: 7px solid transparent; border-bottom: 7px solid #ccc; border-bottom-color: rgba(0, 0, 0, 0.2); position: absolute; top: -7px; left: 6px; } .datepicker:after { content: ''; display: inline-block; border-left: 6px solid transparent; border-right: 6px solid transparent; border-bottom: 6px solid #ffffff; position: absolute; top: -6px; left: 7px; } .datepicker > div { display: none; } .datepicker table { width: 100%; margin: 0; } .datepicker td, .datepicker th { text-align: center; width: 20px; height: 20px; -webkit-border-radius: 4px; -moz-border-radius: 4px; border-radius: 4px; } .datepicker td.day:hover { background: #eeeeee; cursor: pointer; } .datepicker td.old, .datepicker td.new { color: #999999; } .datepicker td.active, .datepicker td.active:hover { background-color: #006dcc; background-image: -moz-linear-gradient(top, #0088cc, #0044cc); background-image: -ms-linear-gradient(top, #0088cc, #0044cc); background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0044cc)); background-image: -webkit-linear-gradient(top, #0088cc, #0044cc); background-image: -o-linear-gradient(top, #0088cc, #0044cc); background-image: linear-gradient(top, #0088cc, #0044cc); background-repeat: repeat-x; filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#0088cc', endColorstr='#0044cc', GradientType=0); border-color: #0044cc #0044cc #002a80; border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); color: #fff; text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); } .datepicker td.active:hover, .datepicker td.active:hover:hover, .datepicker td.active:active, .datepicker td.active:hover:active, .datepicker td.active.active, .datepicker td.active:hover.active, .datepicker td.active.disabled, .datepicker td.active:hover.disabled, .datepicker td.active[disabled], .datepicker td.active:hover[disabled] { background-color: #0044cc; } .datepicker td.active:active, .datepicker td.active:hover:active, .datepicker td.active.active, .datepicker td.active:hover.active { background-color: #003399 \9; } .datepicker td span { display: block; width: 47px; height: 54px; line-height: 54px; float: left; margin: 2px; cursor: pointer; -webkit-border-radius: 4px; -moz-border-radius: 4px; border-radius: 4px; } .datepicker td span:hover { background: #eeeeee; } .datepicker td span.active { background-color: #006dcc; background-image: -moz-linear-gradient(top, #0088cc, #0044cc); background-image: -ms-linear-gradient(top, #0088cc, #0044cc); background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0044cc)); background-image: -webkit-linear-gradient(top, #0088cc, #0044cc); background-image: -o-linear-gradient(top, #0088cc, #0044cc); background-image: linear-gradient(top, #0088cc, #0044cc); background-repeat: repeat-x; filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#0088cc', endColorstr='#0044cc', GradientType=0); border-color: #0044cc #0044cc #002a80; border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); color: #fff; text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); } .datepicker td span.active:hover, .datepicker td span.active:active, .datepicker td span.active.active, .datepicker td span.active.disabled, .datepicker td span.active[disabled] { background-color: #0044cc; } .datepicker td span.active:active, .datepicker td span.active.active { background-color: #003399 \9; } .datepicker td span.old { color: #999999; } .datepicker th.switch { width: 145px; } .datepicker th.next, .datepicker th.prev { font-size: 19.5px; } .datepicker thead tr:first-child th { cursor: pointer; } .datepicker thead tr:first-child th:hover { background: #eeeeee; } .input-append.date .add-on i, .input-prepend.date .add-on i { display: block; cursor: pointer; width: 16px; height: 16px; }
|
||||
|
||||
.bootstrap-timepicker.dropdown-menu {
|
||||
border-radius: 4px 4px 4px 4px;
|
||||
display: none;
|
||||
left: 0;
|
||||
margin-top: 1px;
|
||||
padding: 4px;
|
||||
top: 0;
|
||||
min-width: 10px;
|
||||
z-index: 99999;
|
||||
}
|
||||
.bootstrap-timepicker.dropdown-menu.open {
|
||||
display: inline-block;
|
||||
}
|
||||
.bootstrap-timepicker.dropdown-menu:before {
|
||||
border-bottom: 7px solid rgba(0, 0, 0, 0.2);
|
||||
border-left: 7px solid transparent;
|
||||
border-right: 7px solid transparent;
|
||||
content: "";
|
||||
left: 6px;
|
||||
position: absolute;
|
||||
top: -7px;
|
||||
}
|
||||
.bootstrap-timepicker.dropdown-menu:after {
|
||||
border-bottom: 6px solid #FFFFFF;
|
||||
border-left: 6px solid transparent;
|
||||
border-right: 6px solid transparent;
|
||||
content: "";
|
||||
left: 7px;
|
||||
position: absolute;
|
||||
top: -6px;
|
||||
}
|
||||
.bootstrap-timepicker.modal {
|
||||
margin-left: -100px;
|
||||
margin-top: 0;
|
||||
top: 30%;
|
||||
width: 200px;
|
||||
}
|
||||
.bootstrap-timepicker.modal .modal-content {
|
||||
padding: 0;
|
||||
}
|
||||
.bootstrap-timepicker table {
|
||||
margin: 0;
|
||||
width: 100%;
|
||||
}
|
||||
.bootstrap-timepicker table td {
|
||||
height: 30px;
|
||||
margin: 0;
|
||||
padding: 2px;
|
||||
text-align: center;
|
||||
}
|
||||
.bootstrap-timepicker table td span {
|
||||
width: 100%;
|
||||
}
|
||||
.bootstrap-timepicker table td a {
|
||||
border: 1px solid transparent;
|
||||
display: inline-block;
|
||||
margin: 0;
|
||||
outline: 0 none;
|
||||
padding: 8px 0;
|
||||
width: 3em;
|
||||
}
|
||||
.bootstrap-timepicker table td a:hover {
|
||||
background-color: #EEEEEE;
|
||||
border-color: #DDDDDD;
|
||||
border-radius: 4px 4px 4px 4px;
|
||||
}
|
||||
.bootstrap-timepicker table td a i {
|
||||
margin-top: 2px;
|
||||
}
|
||||
.bootstrap-timepicker table td input {
|
||||
margin: 0;
|
||||
text-align: center;
|
||||
width: 25px;
|
||||
}
|
||||
.bootstrap-timepicker-component .add-on {
|
||||
cursor: pointer;
|
||||
}
|
||||
.bootstrap-timepicker-component .add-on i {
|
||||
display: block;
|
||||
height: 16px;
|
||||
width: 16px;
|
||||
}
|
File diff suppressed because it is too large
Load Diff
806
common/lib/timepicker.js
Normal file
806
common/lib/timepicker.js
Normal file
@ -0,0 +1,806 @@
|
||||
/* =========================================================
|
||||
* bootstrap-timepicker.js
|
||||
* http://www.github.com/jdewit/bootstrap-timepicker
|
||||
* =========================================================
|
||||
* Copyright 2012
|
||||
*
|
||||
* Created By:
|
||||
* Joris de Wit @joris_dewit
|
||||
*
|
||||
* Contributions By:
|
||||
* Gilbert @mindeavor
|
||||
* Koen Punt info@koenpunt.nl
|
||||
* Nek
|
||||
* Chris Martin
|
||||
* Dominic Barnes contact@dominicbarnes.us
|
||||
* Olivier Louvignes @olouv
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* ========================================================= */
|
||||
|
||||
!function($) {
|
||||
|
||||
"use strict"; // jshint ;_;
|
||||
|
||||
var isTouch = 'ontouchstart' in window;
|
||||
|
||||
/* TIMEPICKER PUBLIC CLASS DEFINITION
|
||||
* ================================== */
|
||||
var Timepicker = function(element, options) {
|
||||
this.$element = $(element);
|
||||
this.options = $.extend({}, $.fn.timepicker.defaults, options, this.$element.data());
|
||||
this.minuteStep = this.options.minuteStep || this.minuteStep;
|
||||
this.secondStep = this.options.secondStep || this.secondStep;
|
||||
this.showMeridian = this.options.showMeridian || this.showMeridian;
|
||||
this.showSeconds = this.options.showSeconds || this.showSeconds;
|
||||
this.showInputs = this.options.showInputs || this.showInputs;
|
||||
this.disableFocus = this.options.disableFocus || this.disableFocus;
|
||||
this.template = this.options.template || this.template;
|
||||
this.modalBackdrop = this.options.modalBackdrop || this.modalBackdrop;
|
||||
this.defaultTime = this.options.defaultTime || this.defaultTime;
|
||||
this.open = false;
|
||||
this.init();
|
||||
};
|
||||
|
||||
Timepicker.prototype = {
|
||||
|
||||
constructor: Timepicker
|
||||
|
||||
, init: function () {
|
||||
if (this.$element.parent().hasClass('input-append')) {
|
||||
this.$element.parent('.input-append').find('.add-on').on('click', $.proxy(this.showWidget, this));
|
||||
this.$element.on({
|
||||
focus: $.proxy(this.highlightUnit, this),
|
||||
click: $.proxy(this.highlightUnit, this),
|
||||
keydown: $.proxy(this.elementKeydown, this),
|
||||
blur: $.proxy(this.blurElement, this)
|
||||
});
|
||||
|
||||
} else {
|
||||
if (this.template) {
|
||||
this.$element.on({
|
||||
focus: $.proxy(this.showWidget, this),
|
||||
click: $.proxy(this.showWidget, this),
|
||||
blur: $.proxy(this.blurElement, this)
|
||||
});
|
||||
} else {
|
||||
this.$element.on({
|
||||
focus: $.proxy(this.highlightUnit, this),
|
||||
click: $.proxy(this.highlightUnit, this),
|
||||
keydown: $.proxy(this.elementKeydown, this),
|
||||
blur: $.proxy(this.blurElement, this)
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
this.$widget = $(this.getTemplate()).appendTo('body');
|
||||
|
||||
this.$widget.on('click', $.proxy(this.widgetClick, this));
|
||||
|
||||
if (this.showInputs) {
|
||||
this.$widget.find('input').on({
|
||||
click: function() { this.select(); },
|
||||
keydown: $.proxy(this.widgetKeydown, this),
|
||||
change: $.proxy(this.updateFromWidgetInputs, this)
|
||||
});
|
||||
}
|
||||
|
||||
this.setDefaultTime(this.defaultTime);
|
||||
}
|
||||
|
||||
, showWidget: function(e) {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
|
||||
if (this.open) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.$element.trigger('show');
|
||||
|
||||
if (isTouch || this.disableFocus) {
|
||||
this.$element.blur();
|
||||
}
|
||||
|
||||
var pos = $.extend({}, this.$element.offset(), {
|
||||
height: this.$element[0].offsetHeight
|
||||
});
|
||||
|
||||
this.updateFromElementVal();
|
||||
|
||||
$('html')
|
||||
.one(isTouch ? 'touchstart.timepicker.data-api' : 'click.timepicker.data-api', $.proxy(this.hideWidget, this))
|
||||
.on(isTouch ? 'touchstart.timepicker.data-api' : 'click.timepicker.data-api', '.bootstrap-timepicker', function (e) { e.stopPropagation() });
|
||||
|
||||
if (this.template === 'modal') {
|
||||
this.$widget.modal('show').on('hidden', $.proxy(this.hideWidget, this));
|
||||
} else {
|
||||
this.$widget.css({
|
||||
top: pos.top + pos.height
|
||||
, left: pos.left
|
||||
})
|
||||
|
||||
if (!this.open) {
|
||||
this.$widget.addClass('open');
|
||||
}
|
||||
}
|
||||
|
||||
this.open = true;
|
||||
this.$element.trigger('shown');
|
||||
}
|
||||
|
||||
, hideWidget: function(){
|
||||
this.$element.trigger('hide');
|
||||
|
||||
if (this.template === 'modal') {
|
||||
this.$widget.modal('hide');
|
||||
} else {
|
||||
this.$widget.removeClass('open');
|
||||
}
|
||||
this.open = false;
|
||||
this.$element.trigger('hidden');
|
||||
}
|
||||
|
||||
, widgetClick: function(e) {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
|
||||
var action = $(e.target).closest('a').data('action');
|
||||
if (action) {
|
||||
this[action]();
|
||||
this.update();
|
||||
}
|
||||
}
|
||||
|
||||
, widgetKeydown: function(e) {
|
||||
var input = $(e.target).closest('input').attr('name');
|
||||
|
||||
switch (e.keyCode) {
|
||||
case 9: //tab
|
||||
if (this.showMeridian) {
|
||||
if (input == 'meridian') {
|
||||
this.hideWidget();
|
||||
}
|
||||
} else {
|
||||
if (this.showSeconds) {
|
||||
if (input == 'second') {
|
||||
this.hideWidget();
|
||||
}
|
||||
} else {
|
||||
if (input == 'minute') {
|
||||
this.hideWidget();
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 27: // escape
|
||||
this.hideWidget();
|
||||
break;
|
||||
case 38: // up arrow
|
||||
switch (input) {
|
||||
case 'hour':
|
||||
this.incrementHour();
|
||||
break;
|
||||
case 'minute':
|
||||
this.incrementMinute();
|
||||
break;
|
||||
case 'second':
|
||||
this.incrementSecond();
|
||||
break;
|
||||
case 'meridian':
|
||||
this.toggleMeridian();
|
||||
break;
|
||||
}
|
||||
this.update();
|
||||
break;
|
||||
case 40: // down arrow
|
||||
switch (input) {
|
||||
case 'hour':
|
||||
this.decrementHour();
|
||||
break;
|
||||
case 'minute':
|
||||
this.decrementMinute();
|
||||
break;
|
||||
case 'second':
|
||||
this.decrementSecond();
|
||||
break;
|
||||
case 'meridian':
|
||||
this.toggleMeridian();
|
||||
break;
|
||||
}
|
||||
this.update();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
, elementKeydown: function(e) {
|
||||
var input = this.$element.get(0);
|
||||
switch (e.keyCode) {
|
||||
case 0: //input
|
||||
break;
|
||||
case 9: //tab
|
||||
this.updateFromElementVal();
|
||||
if (this.showMeridian) {
|
||||
if (this.highlightedUnit != 'meridian') {
|
||||
e.preventDefault();
|
||||
this.highlightNextUnit();
|
||||
}
|
||||
} else {
|
||||
if (this.showSeconds) {
|
||||
if (this.highlightedUnit != 'second') {
|
||||
e.preventDefault();
|
||||
this.highlightNextUnit();
|
||||
}
|
||||
} else {
|
||||
if (this.highlightedUnit != 'minute') {
|
||||
e.preventDefault();
|
||||
this.highlightNextUnit();
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 27: // escape
|
||||
this.updateFromElementVal();
|
||||
break;
|
||||
case 37: // left arrow
|
||||
this.updateFromElementVal();
|
||||
this.highlightPrevUnit();
|
||||
break;
|
||||
case 38: // up arrow
|
||||
switch (this.highlightedUnit) {
|
||||
case 'hour':
|
||||
this.incrementHour();
|
||||
break;
|
||||
case 'minute':
|
||||
this.incrementMinute();
|
||||
break;
|
||||
case 'second':
|
||||
this.incrementSecond();
|
||||
break;
|
||||
case 'meridian':
|
||||
this.toggleMeridian();
|
||||
break;
|
||||
}
|
||||
this.updateElement();
|
||||
break;
|
||||
case 39: // right arrow
|
||||
this.updateFromElementVal();
|
||||
this.highlightNextUnit();
|
||||
break;
|
||||
case 40: // down arrow
|
||||
switch (this.highlightedUnit) {
|
||||
case 'hour':
|
||||
this.decrementHour();
|
||||
break;
|
||||
case 'minute':
|
||||
this.decrementMinute();
|
||||
break;
|
||||
case 'second':
|
||||
this.decrementSecond();
|
||||
break;
|
||||
case 'meridian':
|
||||
this.toggleMeridian();
|
||||
break;
|
||||
}
|
||||
this.updateElement();
|
||||
break;
|
||||
}
|
||||
|
||||
if (e.keyCode !== 0 && e.keyCode !== 8 && e.keyCode !== 9 && e.keyCode !== 46) {
|
||||
e.preventDefault();
|
||||
}
|
||||
}
|
||||
|
||||
, setValues: function(time) {
|
||||
if (this.showMeridian) {
|
||||
var arr = time.split(' ');
|
||||
var timeArray = arr[0].split(':');
|
||||
this.meridian = arr[1];
|
||||
} else {
|
||||
var timeArray = time.split(':');
|
||||
}
|
||||
|
||||
this.hour = parseInt(timeArray[0], 10);
|
||||
this.minute = parseInt(timeArray[1], 10);
|
||||
this.second = parseInt(timeArray[2], 10);
|
||||
|
||||
if (isNaN(this.hour)) {
|
||||
this.hour = 0;
|
||||
}
|
||||
if (isNaN(this.minute)) {
|
||||
this.minute = 0;
|
||||
}
|
||||
|
||||
if (this.showMeridian) {
|
||||
if (this.hour > 12) {
|
||||
this.hour = 12;
|
||||
} else if (this.hour < 1) {
|
||||
this.hour = 1;
|
||||
}
|
||||
|
||||
if (this.meridian == 'am' || this.meridian == 'a') {
|
||||
this.meridian = 'AM';
|
||||
} else if (this.meridian == 'pm' || this.meridian == 'p') {
|
||||
this.meridian = 'PM';
|
||||
}
|
||||
|
||||
if (this.meridian != 'AM' && this.meridian != 'PM') {
|
||||
this.meridian = 'AM';
|
||||
}
|
||||
} else {
|
||||
if (this.hour >= 24) {
|
||||
this.hour = 23;
|
||||
} else if (this.hour < 0) {
|
||||
this.hour = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (this.minute < 0) {
|
||||
this.minute = 0;
|
||||
} else if (this.minute >= 60) {
|
||||
this.minute = 59;
|
||||
}
|
||||
|
||||
if (this.showSeconds) {
|
||||
if (isNaN(this.second)) {
|
||||
this.second = 0;
|
||||
} else if (this.second < 0) {
|
||||
this.second = 0;
|
||||
} else if (this.second >= 60) {
|
||||
this.second = 59;
|
||||
}
|
||||
}
|
||||
|
||||
if ( this.$element.val() != '' )
|
||||
this.updateElement();
|
||||
this.updateWidget();
|
||||
}
|
||||
|
||||
, setMeridian: function(meridian) {
|
||||
if (meridian == 'a' || meridian == 'am' || meridian == 'AM' ) {
|
||||
this.meridian = 'AM';
|
||||
} else if (meridian == 'p' || meridian == 'pm' || meridian == 'PM' ) {
|
||||
this.meridian = 'PM';
|
||||
} else {
|
||||
this.updateWidget();
|
||||
}
|
||||
|
||||
this.updateElement();
|
||||
}
|
||||
|
||||
, setDefaultTime: function(defaultTime){
|
||||
if (defaultTime) {
|
||||
if (defaultTime === 'current') {
|
||||
var dTime = new Date();
|
||||
var hours = dTime.getHours();
|
||||
var minutes = Math.floor(dTime.getMinutes() / this.minuteStep) * this.minuteStep;
|
||||
var seconds = Math.floor(dTime.getSeconds() / this.secondStep) * this.secondStep;
|
||||
var meridian = "AM";
|
||||
if (this.showMeridian) {
|
||||
if (hours === 0) {
|
||||
hours = 12;
|
||||
} else if (hours >= 12) {
|
||||
if (hours > 12) {
|
||||
hours = hours - 12;
|
||||
}
|
||||
meridian = "PM";
|
||||
} else {
|
||||
meridian = "AM";
|
||||
}
|
||||
}
|
||||
this.hour = hours;
|
||||
this.minute = minutes;
|
||||
this.second = seconds;
|
||||
this.meridian = meridian;
|
||||
} else if (defaultTime === 'value') {
|
||||
this.setValues(this.$element.val());
|
||||
} else {
|
||||
this.setValues(defaultTime);
|
||||
}
|
||||
if ( this.$element.val() != '' )
|
||||
this.updateElement();
|
||||
this.updateWidget();
|
||||
} else {
|
||||
this.hour = 0;
|
||||
this.minute = 0;
|
||||
this.second = 0;
|
||||
}
|
||||
}
|
||||
|
||||
, formatTime: function(hour, minute, second, meridian) {
|
||||
hour = hour < 10 ? '0' + hour : hour;
|
||||
minute = minute < 10 ? '0' + minute : minute;
|
||||
second = second < 10 ? '0' + second : second;
|
||||
|
||||
return hour + ':' + minute + (this.showSeconds ? ':' + second : '') + (this.showMeridian ? ' ' + meridian : '');
|
||||
}
|
||||
|
||||
, getTime: function() {
|
||||
return this.formatTime(this.hour, this.minute, this.second, this.meridian);
|
||||
}
|
||||
|
||||
, setTime: function(time) {
|
||||
this.setValues(time);
|
||||
this.update();
|
||||
}
|
||||
|
||||
, update: function() {
|
||||
this.updateElement();
|
||||
this.updateWidget();
|
||||
}
|
||||
|
||||
, blurElement: function() {
|
||||
this.highlightedUnit = undefined;
|
||||
this.updateFromElementVal();
|
||||
}
|
||||
|
||||
, updateElement: function() {
|
||||
var time = this.getTime();
|
||||
|
||||
this.$element.val(time).change();
|
||||
|
||||
switch (this.highlightedUnit) {
|
||||
case 'hour':
|
||||
this.highlightHour();
|
||||
break;
|
||||
case 'minute':
|
||||
this.highlightMinute();
|
||||
break;
|
||||
case 'second':
|
||||
this.highlightSecond();
|
||||
break;
|
||||
case 'meridian':
|
||||
this.highlightMeridian();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
, updateWidget: function() {
|
||||
if (this.showInputs) {
|
||||
this.$widget.find('input.bootstrap-timepicker-hour').val(this.hour < 10 ? '0' + this.hour : this.hour);
|
||||
this.$widget.find('input.bootstrap-timepicker-minute').val(this.minute < 10 ? '0' + this.minute : this.minute);
|
||||
if (this.showSeconds) {
|
||||
this.$widget.find('input.bootstrap-timepicker-second').val(this.second < 10 ? '0' + this.second : this.second);
|
||||
}
|
||||
if (this.showMeridian) {
|
||||
this.$widget.find('input.bootstrap-timepicker-meridian').val(this.meridian);
|
||||
}
|
||||
} else {
|
||||
this.$widget.find('span.bootstrap-timepicker-hour').text(this.hour);
|
||||
this.$widget.find('span.bootstrap-timepicker-minute').text(this.minute < 10 ? '0' + this.minute : this.minute);
|
||||
if (this.showSeconds) {
|
||||
this.$widget.find('span.bootstrap-timepicker-second').text(this.second < 10 ? '0' + this.second : this.second);
|
||||
}
|
||||
if (this.showMeridian) {
|
||||
this.$widget.find('span.bootstrap-timepicker-meridian').text(this.meridian);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
, updateFromElementVal: function (e) {
|
||||
var time = this.$element.val();
|
||||
if (time) {
|
||||
this.setValues(time);
|
||||
this.updateWidget();
|
||||
}
|
||||
}
|
||||
|
||||
, updateFromWidgetInputs: function () {
|
||||
var time = $('input.bootstrap-timepicker-hour', this.$widget).val() + ':' +
|
||||
$('input.bootstrap-timepicker-minute', this.$widget).val() +
|
||||
(this.showSeconds ?
|
||||
':' + $('input.bootstrap-timepicker-second', this.$widget).val()
|
||||
: '') +
|
||||
(this.showMeridian ?
|
||||
' ' + $('input.bootstrap-timepicker-meridian', this.$widget).val()
|
||||
: '');
|
||||
|
||||
this.setValues(time);
|
||||
}
|
||||
|
||||
, getCursorPosition: function() {
|
||||
var input = this.$element.get(0);
|
||||
|
||||
if ('selectionStart' in input) {
|
||||
// Standard-compliant browsers
|
||||
return input.selectionStart;
|
||||
} else if (document.selection) {
|
||||
// IE fix
|
||||
input.focus();
|
||||
var sel = document.selection.createRange();
|
||||
var selLen = document.selection.createRange().text.length;
|
||||
sel.moveStart('character', - input.value.length);
|
||||
|
||||
return sel.text.length - selLen;
|
||||
}
|
||||
}
|
||||
|
||||
, highlightUnit: function () {
|
||||
var input = this.$element.get(0);
|
||||
|
||||
this.position = this.getCursorPosition();
|
||||
if (this.position >= 0 && this.position <= 2) {
|
||||
this.highlightHour();
|
||||
} else if (this.position >= 3 && this.position <= 5) {
|
||||
this.highlightMinute();
|
||||
} else if (this.position >= 6 && this.position <= 8) {
|
||||
if (this.showSeconds) {
|
||||
this.highlightSecond();
|
||||
} else {
|
||||
this.highlightMeridian();
|
||||
}
|
||||
} else if (this.position >= 9 && this.position <= 11) {
|
||||
this.highlightMeridian();
|
||||
}
|
||||
}
|
||||
|
||||
, highlightNextUnit: function() {
|
||||
switch (this.highlightedUnit) {
|
||||
case 'hour':
|
||||
this.highlightMinute();
|
||||
break;
|
||||
case 'minute':
|
||||
if (this.showSeconds) {
|
||||
this.highlightSecond();
|
||||
} else {
|
||||
this.highlightMeridian();
|
||||
}
|
||||
break;
|
||||
case 'second':
|
||||
this.highlightMeridian();
|
||||
break;
|
||||
case 'meridian':
|
||||
this.highlightHour();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
, highlightPrevUnit: function() {
|
||||
switch (this.highlightedUnit) {
|
||||
case 'hour':
|
||||
this.highlightMeridian();
|
||||
break;
|
||||
case 'minute':
|
||||
this.highlightHour();
|
||||
break;
|
||||
case 'second':
|
||||
this.highlightMinute();
|
||||
break;
|
||||
case 'meridian':
|
||||
if (this.showSeconds) {
|
||||
this.highlightSecond();
|
||||
} else {
|
||||
this.highlightMinute();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
, highlightHour: function() {
|
||||
this.highlightedUnit = 'hour';
|
||||
this.$element.get(0).setSelectionRange(0,2);
|
||||
}
|
||||
|
||||
, highlightMinute: function() {
|
||||
this.highlightedUnit = 'minute';
|
||||
this.$element.get(0).setSelectionRange(3,5);
|
||||
}
|
||||
|
||||
, highlightSecond: function() {
|
||||
this.highlightedUnit = 'second';
|
||||
this.$element.get(0).setSelectionRange(6,8);
|
||||
}
|
||||
|
||||
, highlightMeridian: function() {
|
||||
this.highlightedUnit = 'meridian';
|
||||
if (this.showSeconds) {
|
||||
this.$element.get(0).setSelectionRange(9,11);
|
||||
} else {
|
||||
this.$element.get(0).setSelectionRange(6,8);
|
||||
}
|
||||
}
|
||||
|
||||
, incrementHour: function() {
|
||||
if (this.showMeridian) {
|
||||
if (this.hour === 11) {
|
||||
this.toggleMeridian();
|
||||
} else if (this.hour === 12) {
|
||||
return this.hour = 1;
|
||||
}
|
||||
}
|
||||
if (this.hour === 23) {
|
||||
return this.hour = 0;
|
||||
}
|
||||
this.hour = this.hour + 1;
|
||||
}
|
||||
|
||||
, decrementHour: function() {
|
||||
if (this.showMeridian) {
|
||||
if (this.hour === 1) {
|
||||
return this.hour = 12;
|
||||
}
|
||||
else if (this.hour === 12) {
|
||||
this.toggleMeridian();
|
||||
}
|
||||
}
|
||||
if (this.hour === 0) {
|
||||
return this.hour = 23;
|
||||
}
|
||||
this.hour = this.hour - 1;
|
||||
}
|
||||
|
||||
, incrementMinute: function() {
|
||||
var newVal = this.minute + this.minuteStep - (this.minute % this.minuteStep);
|
||||
if (newVal > 59) {
|
||||
this.incrementHour();
|
||||
this.minute = newVal - 60;
|
||||
} else {
|
||||
this.minute = newVal;
|
||||
}
|
||||
}
|
||||
|
||||
, decrementMinute: function() {
|
||||
var newVal = this.minute - this.minuteStep;
|
||||
if (newVal < 0) {
|
||||
this.decrementHour();
|
||||
this.minute = newVal + 60;
|
||||
} else {
|
||||
this.minute = newVal;
|
||||
}
|
||||
}
|
||||
|
||||
, incrementSecond: function() {
|
||||
var newVal = this.second + this.secondStep - (this.second % this.secondStep);
|
||||
if (newVal > 59) {
|
||||
this.incrementMinute();
|
||||
this.second = newVal - 60;
|
||||
} else {
|
||||
this.second = newVal;
|
||||
}
|
||||
}
|
||||
|
||||
, decrementSecond: function() {
|
||||
var newVal = this.second - this.secondStep;
|
||||
if (newVal < 0) {
|
||||
this.decrementMinute();
|
||||
this.second = newVal + 60;
|
||||
} else {
|
||||
this.second = newVal;
|
||||
}
|
||||
}
|
||||
|
||||
, toggleMeridian: function() {
|
||||
this.meridian = this.meridian === 'AM' ? 'PM' : 'AM';
|
||||
|
||||
this.update();
|
||||
}
|
||||
|
||||
, getTemplate: function() {
|
||||
if (this.options.templates[this.options.template]) {
|
||||
return this.options.templates[this.options.template];
|
||||
}
|
||||
if (this.showInputs) {
|
||||
var hourTemplate = '<input type="text" name="hour" class="bootstrap-timepicker-hour" maxlength="2"/>';
|
||||
var minuteTemplate = '<input type="text" name="minute" class="bootstrap-timepicker-minute" maxlength="2"/>';
|
||||
var secondTemplate = '<input type="text" name="second" class="bootstrap-timepicker-second" maxlength="2"/>';
|
||||
var meridianTemplate = '<input type="text" name="meridian" class="bootstrap-timepicker-meridian" maxlength="2"/>';
|
||||
} else {
|
||||
var hourTemplate = '<span class="bootstrap-timepicker-hour"></span>';
|
||||
var minuteTemplate = '<span class="bootstrap-timepicker-minute"></span>';
|
||||
var secondTemplate = '<span class="bootstrap-timepicker-second"></span>';
|
||||
var meridianTemplate = '<span class="bootstrap-timepicker-meridian"></span>';
|
||||
}
|
||||
var templateContent = '<table class="'+ (this.showSeconds ? 'show-seconds' : '') +' '+ (this.showMeridian ? 'show-meridian' : '') +'">'+
|
||||
'<tr>'+
|
||||
'<td><a href="#" data-action="incrementHour"><i class="icon-chevron-up"></i></a></td>'+
|
||||
'<td class="separator"> </td>'+
|
||||
'<td><a href="#" data-action="incrementMinute"><i class="icon-chevron-up"></i></a></td>'+
|
||||
(this.showSeconds ?
|
||||
'<td class="separator"> </td>'+
|
||||
'<td><a href="#" data-action="incrementSecond"><i class="icon-chevron-up"></i></a></td>'
|
||||
: '') +
|
||||
(this.showMeridian ?
|
||||
'<td class="separator"> </td>'+
|
||||
'<td class="meridian-column"><a href="#" data-action="toggleMeridian"><i class="icon-chevron-up"></i></a></td>'
|
||||
: '') +
|
||||
'</tr>'+
|
||||
'<tr>'+
|
||||
'<td>'+ hourTemplate +'</td> '+
|
||||
'<td class="separator">:</td>'+
|
||||
'<td>'+ minuteTemplate +'</td> '+
|
||||
(this.showSeconds ?
|
||||
'<td class="separator">:</td>'+
|
||||
'<td>'+ secondTemplate +'</td>'
|
||||
: '') +
|
||||
(this.showMeridian ?
|
||||
'<td class="separator"> </td>'+
|
||||
'<td>'+ meridianTemplate +'</td>'
|
||||
: '') +
|
||||
'</tr>'+
|
||||
'<tr>'+
|
||||
'<td><a href="#" data-action="decrementHour"><i class="icon-chevron-down"></i></a></td>'+
|
||||
'<td class="separator"></td>'+
|
||||
'<td><a href="#" data-action="decrementMinute"><i class="icon-chevron-down"></i></a></td>'+
|
||||
(this.showSeconds ?
|
||||
'<td class="separator"> </td>'+
|
||||
'<td><a href="#" data-action="decrementSecond"><i class="icon-chevron-down"></i></a></td>'
|
||||
: '') +
|
||||
(this.showMeridian ?
|
||||
'<td class="separator"> </td>'+
|
||||
'<td><a href="#" data-action="toggleMeridian"><i class="icon-chevron-down"></i></a></td>'
|
||||
: '') +
|
||||
'</tr>'+
|
||||
'</table>';
|
||||
|
||||
var template;
|
||||
switch(this.options.template) {
|
||||
case 'modal':
|
||||
template = '<div class="bootstrap-timepicker modal hide fade in" style="top: 30%; margin-top: 0; width: 200px; margin-left: -100px;" data-backdrop="'+ (this.modalBackdrop ? 'true' : 'false') +'">'+
|
||||
'<div class="modal-header">'+
|
||||
'<a href="#" class="close" data-dismiss="modal">×</a>'+
|
||||
'<h3>Pick a Time</h3>'+
|
||||
'</div>'+
|
||||
'<div class="modal-content">'+
|
||||
templateContent +
|
||||
'</div>'+
|
||||
'<div class="modal-footer">'+
|
||||
'<a href="#" class="btn btn-primary" data-dismiss="modal">Ok</a>'+
|
||||
'</div>'+
|
||||
'</div>';
|
||||
|
||||
break;
|
||||
case 'dropdown':
|
||||
template = '<div class="bootstrap-timepicker dropdown-menu">'+
|
||||
templateContent +
|
||||
'</div>';
|
||||
break;
|
||||
|
||||
}
|
||||
return template;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/* TIMEPICKER PLUGIN DEFINITION
|
||||
* =========================== */
|
||||
|
||||
$.fn.timepicker = function (option) {
|
||||
return this.each(function () {
|
||||
var $this = $(this)
|
||||
, data = $this.data('timepicker')
|
||||
, options = typeof option == 'object' && option;
|
||||
if (!data) {
|
||||
$this.data('timepicker', (data = new Timepicker(this, options)));
|
||||
}
|
||||
if (typeof option == 'string') {
|
||||
data[option]();
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
$.fn.timepicker.defaults = {
|
||||
minuteStep: 15
|
||||
, secondStep: 15
|
||||
, disableFocus: false
|
||||
, defaultTime: 'current'
|
||||
, showSeconds: false
|
||||
, showInputs: true
|
||||
, showMeridian: true
|
||||
, template: 'dropdown'
|
||||
, modalBackdrop: false
|
||||
, templates: {} // set custom templates
|
||||
}
|
||||
|
||||
$.fn.timepicker.Constructor = Timepicker
|
||||
}(window.jQuery);
|
@ -30,7 +30,8 @@ var config = new Settings(
|
||||
timefield: '@timestamp',
|
||||
//indexpattern: '"logstash-"yyyy.mm.dd',
|
||||
indexpattern: '"shakespeare"',
|
||||
modules: ['histogram','map','pie','table','stringquery','sort'],
|
||||
modules: ['histogram','map','pie','table','stringquery','sort',
|
||||
'timepicker'],
|
||||
|
||||
defaultfields: ['line_text'],
|
||||
perpage: 50,
|
||||
|
@ -2,18 +2,38 @@ var dashboards =
|
||||
{
|
||||
title: "Infinite Monkey Dashboard",
|
||||
rows: [
|
||||
{
|
||||
{
|
||||
title: "Query Control",
|
||||
height: "30px",
|
||||
panels: [
|
||||
{
|
||||
type : "stringquery",
|
||||
span : 9,
|
||||
span : 12,
|
||||
group : "main",
|
||||
query : "wine"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
title: "Options",
|
||||
collapse: true,
|
||||
height: "30px",
|
||||
panels: [
|
||||
{
|
||||
type : "timepicker",
|
||||
span : 5,
|
||||
mode : 'relative',
|
||||
refresh : {
|
||||
enable : false,
|
||||
interval: 30,
|
||||
min : 10
|
||||
},
|
||||
timespan: '1h',
|
||||
group : "main"
|
||||
},
|
||||
{
|
||||
type : "sort",
|
||||
span : 3,
|
||||
span : 4,
|
||||
group : "main"
|
||||
}
|
||||
]
|
||||
@ -51,7 +71,7 @@ var dashboards =
|
||||
},
|
||||
{
|
||||
title: "Lines of Plays",
|
||||
height: "300px",
|
||||
height: "250px",
|
||||
panels: [
|
||||
{
|
||||
title : "Plays",
|
||||
@ -70,7 +90,7 @@ var dashboards =
|
||||
type : "table",
|
||||
span : 8,
|
||||
query : "*",
|
||||
fields : ['@timestamp','speaker','text_entry'],
|
||||
fields : ['@timestamp','play_name','speaker','text_entry'],
|
||||
group : "main"
|
||||
}
|
||||
]
|
||||
|
15
index.html
15
index.html
@ -1,8 +1,8 @@
|
||||
<!DOCTYPE html>
|
||||
<!--[if lt IE 7]> <html class="no-js lt-ie9 lt-ie8 lt-ie7 ng-app:kibana" lang="en" id="ng-app"> <![endif]-->
|
||||
<!--[if IE 7]> <html class="no-js lt-ie9 lt-ie8 ng-app:kibana" lang="en" id="ng-app"> <![endif]-->
|
||||
<!--[if IE 8]> <html class="no-js lt-ie9" lang="en" ng-app="kibana"> <![endif]-->
|
||||
<!--[if gt IE 8]><!--> <html class="no-js" lang="en" ng-app="kibana"> <!--<![endif]-->
|
||||
<!--[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>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
|
||||
@ -16,7 +16,7 @@
|
||||
<link rel="stylesheet" href="/common/css/bootstrap.min.css">
|
||||
<link rel="stylesheet" href="/common/css/bootstrap-responsive.min.css">
|
||||
<link rel="stylesheet" href="/common/css/elasticjs.css">
|
||||
<link rel="stylesheet" href="/common/css/datepicker.css">
|
||||
<link rel="stylesheet" href="/common/css/timepicker.css">
|
||||
|
||||
<!-- project dependency libs -->
|
||||
<script src="/common/lib/LAB.min.js"></script>
|
||||
@ -34,11 +34,6 @@
|
||||
<span class="brand">{{dashboards.title}}</span>
|
||||
<span class="brand"><small><small>Kibana Preview</small></small></span>
|
||||
<div class='pull-right' style="padding-top: 5px; padding-left: 10px"><input type="file" id="upload" upload /></div>
|
||||
<div class="btn-group pull-right">
|
||||
<button class="btn" ng-click="pause()"><i ng-class="{'icon-pause': playing,'icon-play': !playing}"></i></button>
|
||||
<button class="btn" ng-repeat='timespan in time_options' ng-click="set_timespan(timespan)">{{timespan}}</button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
13
js/app.js
13
js/app.js
@ -9,6 +9,7 @@ var modules = [
|
||||
'kibana.services',
|
||||
'kibana.directives',
|
||||
'elasticjs.service',
|
||||
'$strap.directives',
|
||||
'kibana.panels',
|
||||
]
|
||||
|
||||
@ -17,7 +18,10 @@ var scripts = []
|
||||
var labjs = $LAB
|
||||
.script("common/lib/jquery-1.8.0.min.js").wait()
|
||||
.script("common/lib/modernizr-2.6.1.min.js")
|
||||
.script("common/lib/underscore.min.js")
|
||||
.script("common/lib/underscore.min.js")
|
||||
.script("common/lib/bootstrap.min.js")
|
||||
.script('common/lib/datepicker.js')
|
||||
.script('common/lib/timepicker.js')
|
||||
.script("common/lib/angular.min.js")
|
||||
.script("common/lib/angular-strap.min.js")
|
||||
.script("common/lib/elastic.min.js")
|
||||
@ -26,12 +30,12 @@ var labjs = $LAB
|
||||
.script("common/lib/date.js")
|
||||
.script("common/lib/datepicker.js")
|
||||
.script("common/lib/shared.js")
|
||||
.script("dashboards.js")
|
||||
.script("js/services.js")
|
||||
.script("js/controllers.js")
|
||||
.script("js/filters.js")
|
||||
.script("js/directives.js")
|
||||
.script("js/panels.js")
|
||||
.script("dashboards.js");
|
||||
|
||||
_.each(config.modules, function(v) {
|
||||
labjs = labjs.script('panels/'+v+'/module.js').wait()
|
||||
@ -49,5 +53,8 @@ labjs.wait(function(){
|
||||
redirectTo: '/dashboard'
|
||||
});
|
||||
}]);
|
||||
|
||||
angular.element(document).ready(function() {
|
||||
$('body').attr('ng-controller', 'DashCtrl')
|
||||
angular.bootstrap(document, ['kibana']);
|
||||
});
|
||||
});
|
||||
|
@ -9,17 +9,20 @@ angular.module('kibana.controllers', [])
|
||||
$scope.config = config;
|
||||
$scope.dashboards = dashboards
|
||||
$scope.timespan = config.timespan
|
||||
$scope.from = time_ago($scope.timespan);
|
||||
$scope.to = new Date();
|
||||
|
||||
$scope.time_options = ['5m','15m','1h','6h','12h','24h','2d','7d','30d'];
|
||||
$scope.time = {
|
||||
from : time_ago($scope.timespan),
|
||||
to : new Date()
|
||||
}
|
||||
|
||||
// I'm leaving in all this refresh stuff until I figure out how index
|
||||
// list caching should work. Maybe it should be handled by each time panel?
|
||||
// That would require dashboard to contain a time panel. Hmm.
|
||||
$scope.counter = 0;
|
||||
$scope.playing = true;
|
||||
$scope.play = function(){
|
||||
$scope.counter++;
|
||||
$scope.to = new Date();
|
||||
$scope.from = time_ago($scope.timespan);
|
||||
$scope.time.to = new Date();
|
||||
$scope.time.from = time_ago($scope.timespan);
|
||||
$scope.$root.$eval()
|
||||
mytimeout = $timeout($scope.play,config.refresh);
|
||||
}
|
||||
@ -37,9 +40,9 @@ angular.module('kibana.controllers', [])
|
||||
|
||||
// If from/to to change, update index list
|
||||
$scope.$watch(function() {
|
||||
return angular.toJson([$scope.from, $scope.to])
|
||||
return angular.toJson([$scope.time.from, $scope.time.to])
|
||||
}, function(){
|
||||
indices($scope.from,$scope.to).then(function (p) {
|
||||
indices($scope.time.from,$scope.time.to).then(function (p) {
|
||||
$scope.index = p.join();
|
||||
});
|
||||
});
|
||||
@ -54,7 +57,7 @@ angular.module('kibana.controllers', [])
|
||||
|
||||
$scope.set_timespan = function(timespan) {
|
||||
$scope.timespan = timespan;
|
||||
$scope.from = time_ago($scope.timespan);
|
||||
$scope.time.from = time_ago($scope.timespan);
|
||||
}
|
||||
|
||||
// returns a promise containing an array of all indices matching the index
|
||||
|
@ -1,5 +1,5 @@
|
||||
angular.module('kibana.histogram', [])
|
||||
.controller('histogram', function($scope, $location) {
|
||||
.controller('histogram', function($scope, $rootScope) {
|
||||
|
||||
// Set and populate defaults
|
||||
var _d = {
|
||||
@ -14,14 +14,11 @@ angular.module('kibana.histogram', [])
|
||||
? _d[k] : $scope.panel[k];
|
||||
});
|
||||
|
||||
if (!(_.isUndefined($scope.panel.group))) {
|
||||
$scope.$on($scope.panel.group+"-query", function(event, query) {
|
||||
$scope.panel.query[0].query = query;
|
||||
$scope.get_data();
|
||||
});
|
||||
}
|
||||
|
||||
$scope.get_data = function() {
|
||||
// Make sure we have everything for the request to complete
|
||||
if(_.isUndefined($scope.panel.time))
|
||||
return
|
||||
|
||||
var request = $scope.ejs.Request().indices($scope.index);
|
||||
|
||||
// Build the question part of the query
|
||||
@ -30,8 +27,8 @@ angular.module('kibana.histogram', [])
|
||||
queries.push($scope.ejs.FilteredQuery(
|
||||
ejs.QueryStringQuery(v.query || '*'),
|
||||
ejs.RangeFilter(config.timefield)
|
||||
.from($scope.from)
|
||||
.to($scope.to)
|
||||
.from($scope.panel.time.from)
|
||||
.to($scope.panel.time.to)
|
||||
.cache(false))
|
||||
)
|
||||
});
|
||||
@ -53,15 +50,14 @@ angular.module('kibana.histogram', [])
|
||||
results.then(function(results) {
|
||||
$scope.hits = results.hits.total;
|
||||
// Null values at each end of the time range make sure we see entire range
|
||||
|
||||
$scope.data = [];
|
||||
_.each(results.facets, function(v, k) {
|
||||
var series = {};
|
||||
var data = [[$scope.from.getTime(), null]];
|
||||
var data = [[$scope.panel.time.from.getTime(), null]];
|
||||
_.each(v.entries, function(v, k) {
|
||||
data.push([v['time'],v['count']])
|
||||
});
|
||||
data.push([$scope.to.getTime(), null])
|
||||
data.push([$scope.panel.time.to.getTime(), null])
|
||||
series.data = {
|
||||
label: $scope.panel.query[k].label,
|
||||
data: data,
|
||||
@ -73,13 +69,22 @@ angular.module('kibana.histogram', [])
|
||||
});
|
||||
}
|
||||
|
||||
$scope.$watch(function() {
|
||||
return angular.toJson([$scope.from, $scope.to])
|
||||
}, function(){
|
||||
$scope.panel.interval = secondsToHms(
|
||||
calculate_interval($scope.from,$scope.to,50,0)/1000),
|
||||
$scope.get_data();
|
||||
});
|
||||
if (!(_.isUndefined($scope.panel.group))) {
|
||||
$scope.$on($scope.panel.group+"-query", function(event, query) {
|
||||
$scope.panel.query[0].query = query;
|
||||
$scope.get_data();
|
||||
});
|
||||
$scope.$on($scope.panel.group+"-time", function(event, time) {
|
||||
$scope.panel.time = time;
|
||||
$scope.panel.interval = secondsToHms(
|
||||
calculate_interval(time.from,time.to,50,0)/1000),
|
||||
$scope.get_data();
|
||||
});
|
||||
}
|
||||
|
||||
// Now that we're all setup, request the time from our group
|
||||
$rootScope.$broadcast($scope.panel.group+"-get_time")
|
||||
|
||||
|
||||
})
|
||||
.directive('histogram', function() {
|
||||
|
@ -1,5 +1,5 @@
|
||||
angular.module('kibana.map', [])
|
||||
.controller('map', function($scope, $location) {
|
||||
.controller('map', function($scope, $rootScope) {
|
||||
|
||||
// Set and populate defaults
|
||||
var _d = {
|
||||
@ -14,15 +14,11 @@ angular.module('kibana.map', [])
|
||||
? _d[k] : $scope.panel[k];
|
||||
});
|
||||
|
||||
|
||||
if (!(_.isUndefined($scope.panel.group))) {
|
||||
$scope.$on($scope.panel.group+"-query", function(event, query) {
|
||||
$scope.panel.query = query;
|
||||
$scope.get_data();
|
||||
});
|
||||
}
|
||||
|
||||
$scope.get_data = function() {
|
||||
// Make sure we have everything for the request to complete
|
||||
if(_.isUndefined($scope.panel.time))
|
||||
return
|
||||
|
||||
var request = $scope.ejs.Request().indices($scope.index);
|
||||
|
||||
// Then the insert into facet and make the request
|
||||
@ -35,8 +31,8 @@ angular.module('kibana.map', [])
|
||||
ejs.FilteredQuery(
|
||||
ejs.QueryStringQuery($scope.panel.query || '*'),
|
||||
ejs.RangeFilter(config.timefield)
|
||||
.from($scope.from)
|
||||
.to($scope.to)
|
||||
.from($scope.panel.time.from)
|
||||
.to($scope.panel.time.to)
|
||||
.cache(false)
|
||||
)))).size(0)
|
||||
.doSearch();
|
||||
@ -51,11 +47,19 @@ angular.module('kibana.map', [])
|
||||
});
|
||||
}
|
||||
|
||||
$scope.$watch(function() {
|
||||
return angular.toJson([$scope.from, $scope.to])
|
||||
}, function(){
|
||||
$scope.get_data();
|
||||
});
|
||||
if (!(_.isUndefined($scope.panel.group))) {
|
||||
$scope.$on($scope.panel.group+"-query", function(event, query) {
|
||||
$scope.panel.query = query;
|
||||
$scope.get_data();
|
||||
});
|
||||
$scope.$on($scope.panel.group+"-time", function(event, time) {
|
||||
$scope.panel.time = time;
|
||||
$scope.get_data();
|
||||
});
|
||||
}
|
||||
|
||||
// Now that we're all setup, request the time from our group
|
||||
$rootScope.$broadcast($scope.panel.group+"-get_time")
|
||||
|
||||
})
|
||||
.directive('map', function() {
|
||||
|
@ -2,7 +2,7 @@ labjs = labjs.script("common/lib/panels/jquery.flot.js")
|
||||
.script("common/lib/panels/jquery.flot.pie.js")
|
||||
|
||||
angular.module('kibana.pie', [])
|
||||
.controller('pie', function($scope, $location) {
|
||||
.controller('pie', function($scope, $rootScope) {
|
||||
|
||||
// Set and populate defaults
|
||||
var _d = {
|
||||
@ -26,6 +26,9 @@ angular.module('kibana.pie', [])
|
||||
}
|
||||
|
||||
$scope.get_data = function() {
|
||||
if(_.isUndefined($scope.panel.time))
|
||||
return
|
||||
|
||||
var request = $scope.ejs.Request().indices($scope.index);
|
||||
|
||||
// If we have an array, use query facet
|
||||
@ -36,8 +39,8 @@ angular.module('kibana.pie', [])
|
||||
queries.push(ejs.FilteredQuery(
|
||||
ejs.QueryStringQuery(v.query || '*'),
|
||||
ejs.RangeFilter(config.timefield)
|
||||
.from($scope.from)
|
||||
.to($scope.to)
|
||||
.from($scope.panel.time.from)
|
||||
.to($scope.panel.time.to)
|
||||
.cache(false))
|
||||
)
|
||||
});
|
||||
@ -74,8 +77,8 @@ angular.module('kibana.pie', [])
|
||||
ejs.FilteredQuery(
|
||||
ejs.QueryStringQuery($scope.panel.query.query || '*'),
|
||||
ejs.RangeFilter(config.timefield)
|
||||
.from($scope.from)
|
||||
.to($scope.to)
|
||||
.from($scope.panel.time.from)
|
||||
.to($scope.panel.time.to)
|
||||
.cache(false)
|
||||
)))).size(0)
|
||||
.doSearch();
|
||||
@ -100,11 +103,19 @@ angular.module('kibana.pie', [])
|
||||
}
|
||||
}
|
||||
|
||||
$scope.$watch(function() {
|
||||
return angular.toJson([$scope.from, $scope.to])
|
||||
}, function(){
|
||||
$scope.get_data();
|
||||
});
|
||||
if (!(_.isUndefined($scope.panel.group))) {
|
||||
$scope.$on($scope.panel.group+"-query", function(event, query) {
|
||||
$scope.panel.query.query = query;
|
||||
$scope.get_data();
|
||||
});
|
||||
$scope.$on($scope.panel.group+"-time", function(event, time) {
|
||||
$scope.panel.time = time;
|
||||
$scope.get_data();
|
||||
});
|
||||
}
|
||||
|
||||
// Now that we're all setup, request the time from our group
|
||||
$rootScope.$broadcast($scope.panel.group+"-get_time")
|
||||
|
||||
})
|
||||
.directive('pie', function() {
|
||||
|
@ -1,5 +1,6 @@
|
||||
<div ng-controller='sort' style="white-space: nowrap;">
|
||||
<h4 ng-class="{'ng-cloak': !panel.title}">{{panel.title}}</h4>
|
||||
<label><small>{{panel.label}}</small></label>
|
||||
<select style="width:85%" ng-model="panel.sort[0]" 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>
|
||||
<select ng-model="panel.sort[0]" ng-options="f for f in fields"></select>
|
||||
</div>
|
@ -3,6 +3,7 @@ angular.module('kibana.sort', [])
|
||||
|
||||
// Set and populate defaults
|
||||
var _d = {
|
||||
label : "Sort",
|
||||
query : "*",
|
||||
size : 100,
|
||||
sort : [config.timefield,'desc'],
|
||||
|
@ -1,7 +1,8 @@
|
||||
<div ng-controller='stringquery'>
|
||||
<h4 ng-class="{'ng-cloak': !panel.title}">{{panel.title}}</h4>
|
||||
<form class="form-search" style="margin-bottom:0px">
|
||||
<input type="text" class="input-medium search-query" ng-model="query" style="width:85%">
|
||||
<button type="submit" class="btn" ng-click="send_query(query)">Search</button>
|
||||
<form class="input-append" style="margin-bottom:0px; white-space:nowrap;">
|
||||
<label><small>{{panel.label}}</small></label>
|
||||
<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>
|
||||
</form>
|
||||
</div>
|
@ -3,6 +3,7 @@ angular.module('kibana.stringquery', [])
|
||||
|
||||
// Set and populate defaults
|
||||
var _d = {
|
||||
label : "Search",
|
||||
query : "*",
|
||||
size : 100,
|
||||
sort : [config.timefield,'desc'],
|
||||
|
@ -12,28 +12,23 @@ angular.module('kibana.table', [])
|
||||
? _d[k] : $scope.panel[k];
|
||||
});
|
||||
|
||||
// Events which this panel receives and sends
|
||||
if (!(_.isUndefined($scope.panel.group))) {
|
||||
// Receives these events
|
||||
$scope.$on($scope.panel.group+"-query", function(event, query) {
|
||||
$scope.panel.query = query;
|
||||
$scope.get_data();
|
||||
});
|
||||
}
|
||||
|
||||
$scope.toggle_sort = function() {
|
||||
$scope.panel.sort[1] = $scope.panel.sort[1] == 'asc' ? 'desc' : 'asc';
|
||||
}
|
||||
|
||||
$scope.get_data = function() {
|
||||
// Make sure we have everything for the request to complete
|
||||
if(_.isUndefined($scope.panel.time))
|
||||
return
|
||||
|
||||
var request = $scope.ejs.Request().indices($scope.index);
|
||||
|
||||
var results = request
|
||||
.query(ejs.FilteredQuery(
|
||||
ejs.QueryStringQuery($scope.panel.query || '*'),
|
||||
ejs.RangeFilter(config.timefield)
|
||||
.from($scope.from)
|
||||
.to($scope.to)
|
||||
.from($scope.panel.time.from)
|
||||
.to($scope.panel.time.to)
|
||||
.cache(false)
|
||||
)
|
||||
)
|
||||
@ -63,10 +58,22 @@ angular.module('kibana.table', [])
|
||||
});
|
||||
}
|
||||
|
||||
$scope.$watch(function() {
|
||||
return angular.toJson([$scope.from, $scope.to, $scope.panel.sort])
|
||||
}, function(){
|
||||
$scope.get_data();
|
||||
});
|
||||
$scope.$watch(function() {
|
||||
return angular.toJson($scope.panel.sort)
|
||||
}, function(){$scope.get_data()});
|
||||
|
||||
if (!(_.isUndefined($scope.panel.group))) {
|
||||
$scope.$on($scope.panel.group+"-query", function(event, query) {
|
||||
$scope.panel.query = query;
|
||||
$scope.get_data();
|
||||
});
|
||||
$scope.$on($scope.panel.group+"-time", function(event, time) {
|
||||
$scope.panel.time = time;
|
||||
$scope.get_data();
|
||||
});
|
||||
}
|
||||
|
||||
// Now that we're all setup, request the time from our group
|
||||
$rootScope.$broadcast($scope.panel.group+"-get_time")
|
||||
|
||||
})
|
||||
|
64
panels/timepicker/module.html
Normal file
64
panels/timepicker/module.html
Normal file
@ -0,0 +1,64 @@
|
||||
<div 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 ng-switch-when="absolute">
|
||||
<div class="span5">
|
||||
<form class="nomargin">
|
||||
<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-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>
|
||||
</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 ng-switch-when="since">
|
||||
<div class="span5">
|
||||
<form class="nomargin">
|
||||
<label><small>Since</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-mini" ng-change="time_check()" data-show-meridian="false" data-show-seconds="true" ng-model="timepicker.from.time" bs-timepicker>
|
||||
</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 ng-switch-when="relative">
|
||||
<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>
|
||||
</div>
|
168
panels/timepicker/module.js
Normal file
168
panels/timepicker/module.js
Normal file
@ -0,0 +1,168 @@
|
||||
angular.module('kibana.timepicker', [])
|
||||
.controller('timepicker', function($scope, $rootScope, $timeout) {
|
||||
|
||||
// Set and populate defaults
|
||||
var _d = {
|
||||
mode : "relative",
|
||||
time_options : ['5m','15m','1h','6h','12h','24h','2d','7d','30d'],
|
||||
timespan : '15m',
|
||||
refresh : {
|
||||
enable: false,
|
||||
interval: 3,
|
||||
min: 3
|
||||
},
|
||||
time : {
|
||||
from : $scope.time.from,
|
||||
to : $scope.time.to
|
||||
}
|
||||
}
|
||||
_.each(_d, function(v, k) {
|
||||
$scope.panel[k] = _.isUndefined($scope.panel[k])
|
||||
? _d[k] : $scope.panel[k];
|
||||
});
|
||||
|
||||
// Private refresh interval that we can use for view display without causing
|
||||
// unnecessary refreshes during changes
|
||||
$scope.refresh_interval = $scope.panel.refresh.interval
|
||||
|
||||
// Init a private time object with Date() objects depending on mode
|
||||
switch($scope.panel.mode) {
|
||||
case 'absolute':
|
||||
$scope.time = {
|
||||
from : Date.parse($scope.panel.time.from),
|
||||
to : Date.parse($scope.panel.time.to)
|
||||
}
|
||||
break;
|
||||
case 'since':
|
||||
$scope.time = {
|
||||
from : Date.parse($scope.panel.time.from),
|
||||
to : new Date()
|
||||
}
|
||||
break;
|
||||
case 'relative':
|
||||
$scope.time = {
|
||||
from : time_ago($scope.panel.timespan),
|
||||
to : new Date()
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// Init the values for the time/date pickers
|
||||
$scope.timepicker = {
|
||||
from : {
|
||||
time : $scope.time.from.format("HH:MM:ss"),
|
||||
date : $scope.time.from.format("mm/dd/yyyy")
|
||||
},
|
||||
to : {
|
||||
time : $scope.time.to.format("HH:MM:ss"),
|
||||
date : $scope.time.to.format("mm/dd/yyyy")
|
||||
}
|
||||
}
|
||||
|
||||
// In the case that a panel is not ready to receive a time event, it may
|
||||
// request one be sent by broadcasting a 'get_time' even to its group
|
||||
if (!(_.isUndefined($scope.panel.group))) {
|
||||
// Broadcast time when initializing
|
||||
$rootScope.$broadcast($scope.panel.group+"-time", $scope.time)
|
||||
|
||||
// And whenever it is requested
|
||||
$scope.$on($scope.panel.group+"-get_time", function(event) {
|
||||
$rootScope.$broadcast($scope.panel.group+"-time", $scope.time)
|
||||
});
|
||||
}
|
||||
|
||||
$scope.$watch('panel.refresh.enable', function() {$scope.refresh()});
|
||||
$scope.$watch('panel.refresh.interval', function() {
|
||||
$timeout(function(){
|
||||
if(_.isNumber($scope.panel.refresh.interval)) {
|
||||
if($scope.panel.refresh.interval < $scope.panel.refresh.min) {
|
||||
$scope.panel.refresh.interval = $scope.panel.refresh.min
|
||||
$timeout.cancel($scope.panel.refresh.timer)
|
||||
return;
|
||||
}
|
||||
$timeout.cancel($scope.panel.refresh.timer)
|
||||
$scope.refresh()
|
||||
} else {
|
||||
$timeout.cancel($scope.panel.refresh.timer)
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
$scope.refresh = function() {
|
||||
if ($scope.panel.refresh.enable) {
|
||||
$scope.time_apply();
|
||||
$scope.panel.refresh.timer = $timeout(
|
||||
$scope.refresh,
|
||||
$scope.panel.refresh.interval*1000
|
||||
);
|
||||
} else {
|
||||
$timeout.cancel($scope.panel.refresh.timer)
|
||||
}
|
||||
}
|
||||
|
||||
$scope.set_mode = function(mode) {
|
||||
$scope.panel.mode = mode;
|
||||
$scope.panel.refresh.enable = mode === 'absolute' ?
|
||||
false : $scope.panel.refresh.enable
|
||||
}
|
||||
|
||||
$scope.to_now = function() {
|
||||
$scope.timepicker.to = {
|
||||
time : new Date().format("HH:MM:ss"),
|
||||
date : new Date().format("mm/dd/yyyy")
|
||||
}
|
||||
}
|
||||
|
||||
$scope.set_timespan = function(timespan) {
|
||||
$scope.panel.timespan = timespan;
|
||||
$scope.timepicker.from = {
|
||||
time : time_ago(timespan).format("HH:MM:ss"),
|
||||
date : time_ago(timespan).format("mm/dd/yyyy")
|
||||
}
|
||||
$scope.time_apply();
|
||||
}
|
||||
|
||||
$scope.time_check = function(){
|
||||
var from = $scope.panel.mode === 'relative' ? time_ago($scope.panel.timespan) :
|
||||
Date.parse($scope.timepicker.from.date + " " + $scope.timepicker.from.time)
|
||||
var to = $scope.panel.mode !== 'absolute' ? new Date() :
|
||||
Date.parse($scope.timepicker.to.date + " " + $scope.timepicker.to.time)
|
||||
|
||||
if (from.getTime() >= to.getTime())
|
||||
from = new Date(to.getTime() - 1000)
|
||||
|
||||
// Janky 0s timeout to get around $scope queue processing view issue
|
||||
$timeout(function(){
|
||||
$scope.timepicker = {
|
||||
from : {
|
||||
time : from.format("HH:MM:ss"),
|
||||
date : from.format("mm/dd/yyyy")
|
||||
},
|
||||
to : {
|
||||
time : to.format("HH:MM:ss"),
|
||||
date : to.format("mm/dd/yyyy")
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
$scope.time_apply = function() {
|
||||
$scope.time_check();
|
||||
// Update internal time object
|
||||
$scope.time = {
|
||||
from : Date.parse($scope.timepicker.from.date + " " + $scope.timepicker.from.time),
|
||||
to : Date.parse($scope.timepicker.to.date + " " + $scope.timepicker.to.time)
|
||||
};
|
||||
|
||||
// Broadcast time
|
||||
$rootScope.$broadcast($scope.panel.group+"-time", $scope.time)
|
||||
|
||||
// Update panel's string representation of the time object
|
||||
$scope.panel.time = {
|
||||
from : $scope.time.from.format("mm/dd/yyyy HH:MM:ss"),
|
||||
to : $scope.time.to.format("mm/dd/yyyy HH:MM:ss")
|
||||
};
|
||||
};
|
||||
|
||||
})
|
5
panels/timepicker/refreshctrl.html
Normal file
5
panels/timepicker/refreshctrl.html
Normal file
@ -0,0 +1,5 @@
|
||||
<form name="refreshPopover" class='form-inline' style="margin:0px">
|
||||
<label><small>Interval (seconds)</small></label>
|
||||
<input type="number" class="input-mini" ng-model="refresh_interval">
|
||||
<button type="button" class="btn" ng-click="panel.refresh.interval=refresh_interval;dismiss()"><i class="icon-check"></i></button>
|
||||
</form>
|
Loading…
Reference in New Issue
Block a user