diff --git a/common/css/main.css b/common/css/main.css index 26625e8ae1a..4964d3f90ef 100644 --- a/common/css/main.css +++ b/common/css/main.css @@ -24,6 +24,11 @@ z-index: 1000; } +.panel-loading { + position:absolute; + z-index: 800; +} + .panel i.editlink { position: absolute; right: 5px; diff --git a/common/img/load.gif b/common/img/load.gif new file mode 100644 index 00000000000..2ff6ab45a53 Binary files /dev/null and b/common/img/load.gif differ diff --git a/common/lib/date.js b/common/lib/date.js index 77f498645c2..1c1a01df56e 100644 --- a/common/lib/date.js +++ b/common/lib/date.js @@ -1,104 +1,48 @@ -/** - * Version: 1.0 Alpha-1 - * Build Date: 13-Nov-2007 - * Copyright (c) 2006-2007, Coolite Inc. (http://www.coolite.com/). All rights reserved. - * License: Licensed under The MIT License. See license.txt and http://www.datejs.com/license/. - * Website: http://www.datejs.com/ or http://www.coolite.com/datejs/ - */ -Date.CultureInfo={name:"en-US",englishName:"English (United States)",nativeName:"English (United States)",dayNames:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],abbreviatedDayNames:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],shortestDayNames:["Su","Mo","Tu","We","Th","Fr","Sa"],firstLetterDayNames:["S","M","T","W","T","F","S"],monthNames:["January","February","March","April","May","June","July","August","September","October","November","December"],abbreviatedMonthNames:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],amDesignator:"AM",pmDesignator:"PM",firstDayOfWeek:0,twoDigitYearMax:2029,dateElementOrder:"mdy",formatPatterns:{shortDate:"M/d/yyyy",longDate:"dddd, MMMM dd, yyyy",shortTime:"h:mm tt",longTime:"h:mm:ss tt",fullDateTime:"dddd, MMMM dd, yyyy h:mm:ss tt",sortableDateTime:"yyyy-MM-ddTHH:mm:ss",universalSortableDateTime:"yyyy-MM-dd HH:mm:ssZ",rfc1123:"ddd, dd MMM yyyy HH:mm:ss GMT",monthDay:"MMMM dd",yearMonth:"MMMM, yyyy"},regexPatterns:{jan:/^jan(uary)?/i,feb:/^feb(ruary)?/i,mar:/^mar(ch)?/i,apr:/^apr(il)?/i,may:/^may/i,jun:/^jun(e)?/i,jul:/^jul(y)?/i,aug:/^aug(ust)?/i,sep:/^sep(t(ember)?)?/i,oct:/^oct(ober)?/i,nov:/^nov(ember)?/i,dec:/^dec(ember)?/i,sun:/^su(n(day)?)?/i,mon:/^mo(n(day)?)?/i,tue:/^tu(e(s(day)?)?)?/i,wed:/^we(d(nesday)?)?/i,thu:/^th(u(r(s(day)?)?)?)?/i,fri:/^fr(i(day)?)?/i,sat:/^sa(t(urday)?)?/i,future:/^next/i,past:/^last|past|prev(ious)?/i,add:/^(\+|after|from)/i,subtract:/^(\-|before|ago)/i,yesterday:/^yesterday/i,today:/^t(oday)?/i,tomorrow:/^tomorrow/i,now:/^n(ow)?/i,millisecond:/^ms|milli(second)?s?/i,second:/^sec(ond)?s?/i,minute:/^min(ute)?s?/i,hour:/^h(ou)?rs?/i,week:/^w(ee)?k/i,month:/^m(o(nth)?s?)?/i,day:/^d(ays?)?/i,year:/^y((ea)?rs?)?/i,shortMeridian:/^(a|p)/i,longMeridian:/^(a\.?m?\.?|p\.?m?\.?)/i,timezone:/^((e(s|d)t|c(s|d)t|m(s|d)t|p(s|d)t)|((gmt)?\s*(\+|\-)\s*\d\d\d\d?)|gmt)/i,ordinalSuffix:/^\s*(st|nd|rd|th)/i,timeContext:/^\s*(\:|a|p)/i},abbreviatedTimeZoneStandard:{GMT:"-000",EST:"-0400",CST:"-0500",MST:"-0600",PST:"-0700"},abbreviatedTimeZoneDST:{GMT:"-000",EDT:"-0500",CDT:"-0600",MDT:"-0700",PDT:"-0800"}}; -Date.getMonthNumberFromName=function(name){var n=Date.CultureInfo.monthNames,m=Date.CultureInfo.abbreviatedMonthNames,s=name.toLowerCase();for(var i=0;idate)?1:(this=start.getTime()&&t<=end.getTime();};Date.prototype.addMilliseconds=function(value){this.setMilliseconds(this.getMilliseconds()+value);return this;};Date.prototype.addSeconds=function(value){return this.addMilliseconds(value*1000);};Date.prototype.addMinutes=function(value){return this.addMilliseconds(value*60000);};Date.prototype.addHours=function(value){return this.addMilliseconds(value*3600000);};Date.prototype.addDays=function(value){return this.addMilliseconds(value*86400000);};Date.prototype.addWeeks=function(value){return this.addMilliseconds(value*604800000);};Date.prototype.addMonths=function(value){var n=this.getDate();this.setDate(1);this.setMonth(this.getMonth()+value);this.setDate(Math.min(n,this.getDaysInMonth()));return this;};Date.prototype.addYears=function(value){return this.addMonths(value*12);};Date.prototype.add=function(config){if(typeof config=="number"){this._orient=config;return this;} -var x=config;if(x.millisecond||x.milliseconds){this.addMilliseconds(x.millisecond||x.milliseconds);} -if(x.second||x.seconds){this.addSeconds(x.second||x.seconds);} -if(x.minute||x.minutes){this.addMinutes(x.minute||x.minutes);} -if(x.hour||x.hours){this.addHours(x.hour||x.hours);} -if(x.month||x.months){this.addMonths(x.month||x.months);} -if(x.year||x.years){this.addYears(x.year||x.years);} -if(x.day||x.days){this.addDays(x.day||x.days);} -return this;};Date._validate=function(value,min,max,name){if(typeof value!="number"){throw new TypeError(value+" is not a Number.");}else if(valuemax){throw new RangeError(value+" is not a valid value for "+name+".");} -return true;};Date.validateMillisecond=function(n){return Date._validate(n,0,999,"milliseconds");};Date.validateSecond=function(n){return Date._validate(n,0,59,"seconds");};Date.validateMinute=function(n){return Date._validate(n,0,59,"minutes");};Date.validateHour=function(n){return Date._validate(n,0,23,"hours");};Date.validateDay=function(n,year,month){return Date._validate(n,1,Date.getDaysInMonth(year,month),"days");};Date.validateMonth=function(n){return Date._validate(n,0,11,"months");};Date.validateYear=function(n){return Date._validate(n,1,9999,"seconds");};Date.prototype.set=function(config){var x=config;if(!x.millisecond&&x.millisecond!==0){x.millisecond=-1;} -if(!x.second&&x.second!==0){x.second=-1;} -if(!x.minute&&x.minute!==0){x.minute=-1;} -if(!x.hour&&x.hour!==0){x.hour=-1;} -if(!x.day&&x.day!==0){x.day=-1;} -if(!x.month&&x.month!==0){x.month=-1;} -if(!x.year&&x.year!==0){x.year=-1;} -if(x.millisecond!=-1&&Date.validateMillisecond(x.millisecond)){this.addMilliseconds(x.millisecond-this.getMilliseconds());} -if(x.second!=-1&&Date.validateSecond(x.second)){this.addSeconds(x.second-this.getSeconds());} -if(x.minute!=-1&&Date.validateMinute(x.minute)){this.addMinutes(x.minute-this.getMinutes());} -if(x.hour!=-1&&Date.validateHour(x.hour)){this.addHours(x.hour-this.getHours());} -if(x.month!==-1&&Date.validateMonth(x.month)){this.addMonths(x.month-this.getMonth());} -if(x.year!=-1&&Date.validateYear(x.year)){this.addYears(x.year-this.getFullYear());} -if(x.day!=-1&&Date.validateDay(x.day,this.getFullYear(),this.getMonth())){this.addDays(x.day-this.getDate());} -if(x.timezone){this.setTimezone(x.timezone);} -if(x.timezoneOffset){this.setTimezoneOffset(x.timezoneOffset);} -return this;};Date.prototype.clearTime=function(){this.setHours(0);this.setMinutes(0);this.setSeconds(0);this.setMilliseconds(0);return this;};Date.prototype.isLeapYear=function(){var y=this.getFullYear();return(((y%4===0)&&(y%100!==0))||(y%400===0));};Date.prototype.isWeekday=function(){return!(this.is().sat()||this.is().sun());};Date.prototype.getDaysInMonth=function(){return Date.getDaysInMonth(this.getFullYear(),this.getMonth());};Date.prototype.moveToFirstDayOfMonth=function(){return this.set({day:1});};Date.prototype.moveToLastDayOfMonth=function(){return this.set({day:this.getDaysInMonth()});};Date.prototype.moveToDayOfWeek=function(day,orient){var diff=(day-this.getDay()+7*(orient||+1))%7;return this.addDays((diff===0)?diff+=7*(orient||+1):diff);};Date.prototype.moveToMonth=function(month,orient){var diff=(month-this.getMonth()+12*(orient||+1))%12;return this.addMonths((diff===0)?diff+=12*(orient||+1):diff);};Date.prototype.getDayOfYear=function(){return Math.floor((this-new Date(this.getFullYear(),0,1))/86400000);};Date.prototype.getWeekOfYear=function(firstDayOfWeek){var y=this.getFullYear(),m=this.getMonth(),d=this.getDate();var dow=firstDayOfWeek||Date.CultureInfo.firstDayOfWeek;var offset=7+1-new Date(y,0,1).getDay();if(offset==8){offset=1;} -var daynum=((Date.UTC(y,m,d,0,0,0)-Date.UTC(y,0,1,0,0,0))/86400000)+1;var w=Math.floor((daynum-offset+7)/7);if(w===dow){y--;var prevOffset=7+1-new Date(y,0,1).getDay();if(prevOffset==2||prevOffset==8){w=53;}else{w=52;}} -return w;};Date.prototype.isDST=function(){console.log('isDST');return this.toString().match(/(E|C|M|P)(S|D)T/)[2]=="D";};Date.prototype.getTimezone=function(){return Date.getTimezoneAbbreviation(this.getUTCOffset,this.isDST());};Date.prototype.setTimezoneOffset=function(s){var here=this.getTimezoneOffset(),there=Number(s)*-6/10;this.addMinutes(there-here);return this;};Date.prototype.setTimezone=function(s){return this.setTimezoneOffset(Date.getTimezoneOffset(s));};Date.prototype.getUTCOffset=function(){var n=this.getTimezoneOffset()*-10/6,r;if(n<0){r=(n-10000).toString();return r[0]+r.substr(2);}else{r=(n+10000).toString();return"+"+r.substr(1);}};Date.prototype.getDayName=function(abbrev){return abbrev?Date.CultureInfo.abbreviatedDayNames[this.getDay()]:Date.CultureInfo.dayNames[this.getDay()];};Date.prototype.getMonthName=function(abbrev){return abbrev?Date.CultureInfo.abbreviatedMonthNames[this.getMonth()]:Date.CultureInfo.monthNames[this.getMonth()];};Date.prototype._toString=Date.prototype.toString;Date.prototype.toString=function(format){var self=this;var p=function p(s){return(s.toString().length==1)?"0"+s:s;};return format?format.replace(/dd?d?d?|MM?M?M?|yy?y?y?|hh?|HH?|mm?|ss?|tt?|zz?z?/g,function(format){switch(format){case"hh":return p(self.getHours()<13?self.getHours():(self.getHours()-12));case"h":return self.getHours()<13?self.getHours():(self.getHours()-12);case"HH":return p(self.getHours());case"H":return self.getHours();case"mm":return p(self.getMinutes());case"m":return self.getMinutes();case"ss":return p(self.getSeconds());case"s":return self.getSeconds();case"yyyy":return self.getFullYear();case"yy":return self.getFullYear().toString().substring(2,4);case"dddd":return self.getDayName();case"ddd":return self.getDayName(true);case"dd":return p(self.getDate());case"d":return self.getDate().toString();case"MMMM":return self.getMonthName();case"MMM":return self.getMonthName(true);case"MM":return p((self.getMonth()+1));case"M":return self.getMonth()+1;case"t":return self.getHours()<12?Date.CultureInfo.amDesignator.substring(0,1):Date.CultureInfo.pmDesignator.substring(0,1);case"tt":return self.getHours()<12?Date.CultureInfo.amDesignator:Date.CultureInfo.pmDesignator;case"zzz":case"zz":case"z":return"";}}):this._toString();}; -Date.now=function(){return new Date();};Date.today=function(){return Date.now().clearTime();};Date.prototype._orient=+1;Date.prototype.next=function(){this._orient=+1;return this;};Date.prototype.last=Date.prototype.prev=Date.prototype.previous=function(){this._orient=-1;return this;};Date.prototype._is=false;Date.prototype.is=function(){this._is=true;return this;};Number.prototype._dateElement="day";Number.prototype.fromNow=function(){var c={};c[this._dateElement]=this;return Date.now().add(c);};Number.prototype.ago=function(){var c={};c[this._dateElement]=this*-1;return Date.now().add(c);};(function(){var $D=Date.prototype,$N=Number.prototype;var dx=("sunday monday tuesday wednesday thursday friday saturday").split(/\s/),mx=("january february march april may june july august september october november december").split(/\s/),px=("Millisecond Second Minute Hour Day Week Month Year").split(/\s/),de;var df=function(n){return function(){if(this._is){this._is=false;return this.getDay()==n;} -return this.moveToDayOfWeek(n,this._orient);};};for(var i=0;i0&&!last){try{q=d.call(this,r[1]);}catch(ex){last=true;}}else{last=true;} -if(!last&&q[1].length===0){last=true;} -if(!last){var qx=[];for(var j=0;j0){rx[0]=rx[0].concat(p[0]);rx[1]=p[1];}} -if(rx[1].length1){args=Array.prototype.slice.call(arguments);}else if(arguments[0]instanceof Array){args=arguments[0];} -if(args){for(var i=0,px=args.shift();i2)?n:(n+(((n+2000)Date.getDaysInMonth(this.year,this.month)){throw new RangeError(this.day+" is not a valid value for days.");} -var r=new Date(this.year,this.month,this.day,this.hour,this.minute,this.second);if(this.timezone){r.set({timezone:this.timezone});}else if(this.timezoneOffset){r.set({timezoneOffset:this.timezoneOffset});} -return r;},finish:function(x){x=(x instanceof Array)?flattenAndCompact(x):[x];if(x.length===0){return null;} -for(var i=0;idate2)?1:0;}else{throw new TypeError(date1+" - "+date2);}};$D.equals=function(date1,date2){return(date1.compareTo(date2)===0);};$D.getDayNumberFromName=function(name){var n=$C.dayNames,m=$C.abbreviatedDayNames,o=$C.shortestDayNames,s=name.toLowerCase();for(var i=0;i=start.getTime()&&this.getTime()<=end.getTime();};$P.isAfter=function(date){return this.compareTo(date||new Date())===1;};$P.isBefore=function(date){return(this.compareTo(date||new Date())===-1);};$P.isToday=function(){return this.isSameDay(new Date());};$P.isSameDay=function(date){return this.clone().clearTime().equals(date.clone().clearTime());};$P.addMilliseconds=function(value){this.setMilliseconds(this.getMilliseconds()+value);return this;};$P.addSeconds=function(value){return this.addMilliseconds(value*1000);};$P.addMinutes=function(value){return this.addMilliseconds(value*60000);};$P.addHours=function(value){return this.addMilliseconds(value*3600000);};$P.addDays=function(value){this.setDate(this.getDate()+value);return this;};$P.addWeeks=function(value){return this.addDays(value*7);};$P.addMonths=function(value){var n=this.getDate();this.setDate(1);this.setMonth(this.getMonth()+value);this.setDate(Math.min(n,$D.getDaysInMonth(this.getFullYear(),this.getMonth())));return this;};$P.addYears=function(value){return this.addMonths(value*12);};$P.add=function(config){if(typeof config=="number"){this._orient=config;return this;} +var x=config;if(x.milliseconds){this.addMilliseconds(x.milliseconds);} +if(x.seconds){this.addSeconds(x.seconds);} +if(x.minutes){this.addMinutes(x.minutes);} +if(x.hours){this.addHours(x.hours);} +if(x.weeks){this.addWeeks(x.weeks);} +if(x.months){this.addMonths(x.months);} +if(x.years){this.addYears(x.years);} +if(x.days){this.addDays(x.days);} +return this;};var $y,$m,$d;$P.getWeek=function(){var a,b,c,d,e,f,g,n,s,w;$y=(!$y)?this.getFullYear():$y;$m=(!$m)?this.getMonth()+1:$m;$d=(!$d)?this.getDate():$d;if($m<=2){a=$y-1;b=(a/4|0)-(a/100|0)+(a/400|0);c=((a-1)/4|0)-((a-1)/100|0)+((a-1)/400|0);s=b-c;e=0;f=$d-1+(31*($m-1));}else{a=$y;b=(a/4|0)-(a/100|0)+(a/400|0);c=((a-1)/4|0)-((a-1)/100|0)+((a-1)/400|0);s=b-c;e=s+1;f=$d+((153*($m-3)+2)/5)+58+s;} +g=(a+b)%7;d=(f+g-e)%7;n=(f+3-d)|0;if(n<0){w=53-((g-s)/5|0);}else if(n>364+s){w=1;}else{w=(n/7|0)+1;} +$y=$m=$d=null;return w;};$P.getISOWeek=function(){$y=this.getUTCFullYear();$m=this.getUTCMonth()+1;$d=this.getUTCDate();return p(this.getWeek());};$P.setWeek=function(n){return this.moveToDayOfWeek(1).addWeeks(n-this.getWeek());};$D._validate=function(n,min,max,name){if(typeof n=="undefined"){return false;}else if(typeof n!="number"){throw new TypeError(n+" is not a Number.");}else if(nmax){throw new RangeError(n+" is not a valid value for "+name+".");} +return true;};$D.validateMillisecond=function(value){return $D._validate(value,0,999,"millisecond");};$D.validateSecond=function(value){return $D._validate(value,0,59,"second");};$D.validateMinute=function(value){return $D._validate(value,0,59,"minute");};$D.validateHour=function(value){return $D._validate(value,0,23,"hour");};$D.validateDay=function(value,year,month){return $D._validate(value,1,$D.getDaysInMonth(year,month),"day");};$D.validateMonth=function(value){return $D._validate(value,0,11,"month");};$D.validateYear=function(value){return $D._validate(value,0,9999,"year");};$P.set=function(config){if($D.validateMillisecond(config.millisecond)){this.addMilliseconds(config.millisecond-this.getMilliseconds());} +if($D.validateSecond(config.second)){this.addSeconds(config.second-this.getSeconds());} +if($D.validateMinute(config.minute)){this.addMinutes(config.minute-this.getMinutes());} +if($D.validateHour(config.hour)){this.addHours(config.hour-this.getHours());} +if($D.validateMonth(config.month)){this.addMonths(config.month-this.getMonth());} +if($D.validateYear(config.year)){this.addYears(config.year-this.getFullYear());} +if($D.validateDay(config.day,this.getFullYear(),this.getMonth())){this.addDays(config.day-this.getDate());} +if(config.timezone){this.setTimezone(config.timezone);} +if(config.timezoneOffset){this.setTimezoneOffset(config.timezoneOffset);} +if(config.week&&$D._validate(config.week,0,53,"week")){this.setWeek(config.week);} +return this;};$P.moveToFirstDayOfMonth=function(){return this.set({day:1});};$P.moveToLastDayOfMonth=function(){return this.set({day:$D.getDaysInMonth(this.getFullYear(),this.getMonth())});};$P.moveToNthOccurrence=function(dayOfWeek,occurrence){var shift=0;if(occurrence>0){shift=occurrence-1;} +else if(occurrence===-1){this.moveToLastDayOfMonth();if(this.getDay()!==dayOfWeek){this.moveToDayOfWeek(dayOfWeek,-1);} +return this;} +return this.moveToFirstDayOfMonth().addDays(-1).moveToDayOfWeek(dayOfWeek,+1).addWeeks(shift);};$P.moveToDayOfWeek=function(dayOfWeek,orient){var diff=(dayOfWeek-this.getDay()+7*(orient||+1))%7;return this.addDays((diff===0)?diff+=7*(orient||+1):diff);};$P.moveToMonth=function(month,orient){var diff=(month-this.getMonth()+12*(orient||+1))%12;return this.addMonths((diff===0)?diff+=12*(orient||+1):diff);};$P.getOrdinalNumber=function(){return Math.ceil((this.clone().clearTime()-new Date(this.getFullYear(),0,1))/86400000)+1;};$P.getTimezone=function(){return $D.getTimezoneAbbreviation(this.getUTCOffset());};$P.setTimezoneOffset=function(offset){var here=this.getTimezoneOffset(),there=Number(offset)*-6/10;return this.addMinutes(there-here);};$P.setTimezone=function(offset){return this.setTimezoneOffset($D.getTimezoneOffset(offset));};$P.hasDaylightSavingTime=function(){return(Date.today().set({month:0,day:1}).getTimezoneOffset()!==Date.today().set({month:6,day:1}).getTimezoneOffset());};$P.isDaylightSavingTime=function(){return(this.hasDaylightSavingTime()&&new Date().getTimezoneOffset()===Date.today().set({month:6,day:1}).getTimezoneOffset());};$P.getUTCOffset=function(){var n=this.getTimezoneOffset()*-10/6,r;if(n<0){r=(n-10000).toString();return r.charAt(0)+r.substr(2);}else{r=(n+10000).toString();return"+"+r.substr(1);}};$P.getElapsed=function(date){return(date||new Date())-this;};if(!$P.toISOString){$P.toISOString=function(){function f(n){return n<10?'0'+n:n;} +return'"'+this.getUTCFullYear()+'-'+ +f(this.getUTCMonth()+1)+'-'+ +f(this.getUTCDate())+'T'+ +f(this.getUTCHours())+':'+ +f(this.getUTCMinutes())+':'+ +f(this.getUTCSeconds())+'Z"';};} +$P._toString=$P.toString;$P.toString=function(format){var x=this;if(format&&format.length==1){var c=$C.formatPatterns;x.t=x.toString;switch(format){case"d":return x.t(c.shortDate);case"D":return x.t(c.longDate);case"F":return x.t(c.fullDateTime);case"m":return x.t(c.monthDay);case"r":return x.t(c.rfc1123);case"s":return x.t(c.sortableDateTime);case"t":return x.t(c.shortTime);case"T":return x.t(c.longTime);case"u":return x.t(c.universalSortableDateTime);case"y":return x.t(c.yearMonth);}} +var ord=function(n){switch(n*1){case 1:case 21:case 31:return"st";case 2:case 22:return"nd";case 3:case 23:return"rd";default:return"th";}};return format?format.replace(/(\\)?(dd?d?d?|MM?M?M?|yy?y?y?|hh?|HH?|mm?|ss?|tt?|S)/g,function(m){if(m.charAt(0)==="\\"){return m.replace("\\","");} +x.h=x.getHours;switch(m){case"hh":return p(x.h()<13?(x.h()===0?12:x.h()):(x.h()-12));case"h":return x.h()<13?(x.h()===0?12:x.h()):(x.h()-12);case"HH":return p(x.h());case"H":return x.h();case"mm":return p(x.getMinutes());case"m":return x.getMinutes();case"ss":return p(x.getSeconds());case"s":return x.getSeconds();case"yyyy":return p(x.getFullYear(),4);case"yy":return p(x.getFullYear());case"dddd":return $C.dayNames[x.getDay()];case"ddd":return $C.abbreviatedDayNames[x.getDay()];case"dd":return p(x.getDate());case"d":return x.getDate();case"MMMM":return $C.monthNames[x.getMonth()];case"MMM":return $C.abbreviatedMonthNames[x.getMonth()];case"MM":return p((x.getMonth()+1));case"M":return x.getMonth()+1;case"t":return x.h()<12?$C.amDesignator.substring(0,1):$C.pmDesignator.substring(0,1);case"tt":return x.h()<12?$C.amDesignator:$C.pmDesignator;case"S":return ord(x.getDate());default:return m;}}):this._toString();};}()); diff --git a/config.js b/config.js index 6f2508fcd85..7b7fd55412b 100644 --- a/config.js +++ b/config.js @@ -13,7 +13,7 @@ If you need to configure the default dashboard, please see dashboard.js */ var config = new Settings( { - elasticsearch: 'http://localhost:9200', + elasticsearch: 'http://demo.logstash.net:9200', timeformat: 'mm/dd HH:MM:ss', modules: ['histogram','map','pie','table','stringquery','sort', 'timepicker','text','fields','hits','dashcontrol'], diff --git a/js/controllers.js b/js/controllers.js index a31ea24665a..1fa30f340f8 100644 --- a/js/controllers.js +++ b/js/controllers.js @@ -100,7 +100,7 @@ angular.module('kibana.controllers', []) row.collapse = row.collapse ? false : true; if (!row.collapse) { $timeout(function() { - $scope.$broadcast('render') + $scope.send_render(); }); } } @@ -115,6 +115,8 @@ angular.module('kibana.controllers', []) $scope.reset_panel = function() { $scope.panel = { + loading: false, + error: false, span: 3, editable: true, group: ['default'], diff --git a/js/directives.js b/js/directives.js index c5c09f0ad39..f4c0fd76b1a 100644 --- a/js/directives.js +++ b/js/directives.js @@ -7,7 +7,7 @@ angular.module('kibana.directives', []) return { restrict: 'E', link: function(scope, elem, attrs) { - var template = ''+ + var template = ' '+ '

{{panel.title}}

'; elem.prepend($compile(angular.element(template))(scope)); } diff --git a/panels/fields/editor.html b/panels/fields/editor.html index a82f1a5f50f..f9e894600ee 100644 --- a/panels/fields/editor.html +++ b/panels/fields/editor.html @@ -1,4 +1,4 @@ -
+
Popup Position
diff --git a/panels/fields/module.js b/panels/fields/module.js index 334f964eee6..6496b991df6 100644 --- a/panels/fields/module.js +++ b/panels/fields/module.js @@ -52,7 +52,6 @@ angular.module('kibana.fields', []) $scope.active = _.without($scope.active,field) else $scope.active.push(field) - eventBus.broadcast($scope.$id,$scope.panel.group,"selected_fields",$scope.active) } diff --git a/panels/histogram/module.js b/panels/histogram/module.js index 6fe930ce034..bf013bbcb64 100644 --- a/panels/histogram/module.js +++ b/panels/histogram/module.js @@ -50,6 +50,7 @@ angular.module('kibana.histogram', []) if(_.isUndefined($scope.panel.index) || _.isUndefined($scope.time)) return + $scope.panel.loading = true; var request = $scope.ejs.Request().indices($scope.panel.index); // Build the question part of the query @@ -78,6 +79,7 @@ angular.module('kibana.histogram', []) // Populate scope when we have results results.then(function(results) { + $scope.panel.loading = false; $scope.hits = results.hits.total; $scope.data = []; _.each(results.facets, function(v, k) { diff --git a/panels/hits/module.js b/panels/hits/module.js index 6412a7eb471..c5ac3f6e48f 100644 --- a/panels/hits/module.js +++ b/panels/hits/module.js @@ -24,6 +24,7 @@ angular.module('kibana.hits', []) if(_.isUndefined($scope.panel.index) || _.isUndefined($scope.time)) return + $scope.panel.loading = true; var request = $scope.ejs.Request().indices($scope.panel.index); var results = request @@ -39,6 +40,7 @@ angular.module('kibana.hits', []) // Populate scope when we have results results.then(function(results) { + $scope.panel.loading = false; if(_.isUndefined(results)) { $scope.panel.error = 'Your query was unsuccessful'; return; diff --git a/panels/map/module.js b/panels/map/module.js index f3dbaded35d..900059d51f1 100644 --- a/panels/map/module.js +++ b/panels/map/module.js @@ -27,6 +27,7 @@ angular.module('kibana.map', []) if(_.isUndefined($scope.panel.index) || _.isUndefined($scope.time)) return + $scope.panel.loading = true; var request = $scope.ejs.Request().indices($scope.panel.index); // Then the insert into facet and make the request @@ -46,6 +47,7 @@ angular.module('kibana.map', []) // Populate scope when we have results results.then(function(results) { + $scope.panel.loading = false; $scope.hits = results.hits.total; $scope.data = {}; _.each(results.facets.map.terms, function(v) { diff --git a/panels/pie/module.js b/panels/pie/module.js index df27196cad7..4dc96777021 100644 --- a/panels/pie/module.js +++ b/panels/pie/module.js @@ -73,6 +73,7 @@ angular.module('kibana.pie', []) if(_.isUndefined($scope.panel.index) || _.isUndefined($scope.time)) return + $scope.panel.loading = true; var request = $scope.ejs.Request().indices($scope.panel.index); // If we have an array, use query facet @@ -101,6 +102,7 @@ angular.module('kibana.pie', []) // Populate scope when we have results results.then(function(results) { + $scope.panel.loading = false; $scope.hits = results.hits.total; $scope.data = []; _.each(results.facets, function(v, k) { @@ -133,6 +135,7 @@ angular.module('kibana.pie', []) // Populate scope when we have results results.then(function(results) { + $scope.panel.loading = false; $scope.hits = results.hits.total; $scope.data = []; var k = 0; @@ -159,6 +162,7 @@ angular.module('kibana.pie', []) .size(0) .doSearch(); results.then(function(results) { + $scope.panel.loading = false; var complete = results.hits.total; var remaining = $scope.panel.query.goal - complete; $scope.data = [ diff --git a/panels/table/module.js b/panels/table/module.js index 2863f2aa90f..b524f1dd414 100644 --- a/panels/table/module.js +++ b/panels/table/module.js @@ -76,7 +76,8 @@ angular.module('kibana.table', []) // Make sure we have everything for the request to complete if(_.isUndefined($scope.panel.index) || _.isUndefined($scope.time)) return - + + $scope.panel.loading = true; var request = $scope.ejs.Request().indices($scope.panel.index); var results = request @@ -94,6 +95,8 @@ angular.module('kibana.table', []) // Populate scope when we have results results.then(function(results) { + $scope.panel.loading = false; + if(_.isUndefined(results)) { $scope.panel.error = 'Your query was unsuccessful'; return; diff --git a/panels/timepicker/module.js b/panels/timepicker/module.js index d20676634d3..389973b8666 100644 --- a/panels/timepicker/module.js +++ b/panels/timepicker/module.js @@ -34,6 +34,8 @@ angular.module('kibana.timepicker', []) timefield : '@timestamp', index : '"logstash-"yyyy.mm.dd', defaultindex : "NOINDEX", + index_interval: "day", + timed_indices : true, group : "default", refresh : { enable : false, @@ -178,11 +180,15 @@ angular.module('kibana.timepicker', []) // Get indices for the time period, then broadcast time range and index list // in a single object. Not sure if I like this. - indices($scope.time.from,$scope.time.to).then(function (p) { - $scope.time.index = p.join(); - // Broadcast time + if($scope.panel.timed_indices) { + indices($scope.time.from,$scope.time.to).then(function (p) { + $scope.time.index = p.join(); + eventBus.broadcast($scope.$id,$scope.panel.group,'time',$scope.time) + }); + } else { + $scope.time.index = $scope.panel.index; eventBus.broadcast($scope.$id,$scope.panel.group,'time',$scope.time) - }); + } // Update panel's string representation of the time object $scope.panel.time = { @@ -196,7 +202,7 @@ angular.module('kibana.timepicker', []) // pattern that exist in a given range function indices(from,to) { var possible = []; - _.each(date_range(from,to.add_days(1)),function(d){ + _.each(expand_range(fake_utc(from),fake_utc(to),$scope.panel.index_interval),function(d){ possible.push(d.format($scope.panel.index)); }); @@ -226,6 +232,46 @@ angular.module('kibana.timepicker', []) }); } + // this is stupid, but there is otherwise no good way to ensure that when + // I extract the date from an object that I'm get the UTC date. Stupid js. + // I die a little inside every time I call this function. + function fake_utc(date) { + return new Date(date.getTime() + date.getTimezoneOffset() * 60000); + } + + // Create an array of date objects by a given interval + function expand_range(start, end, interval) { + if(_.contains(['hour','day','week','month','year'],interval)) { + var range; + start = start.clone(); + range = []; + while (start.isBefore(end)) { + range.push(start.clone()); + switch (interval) { + case 'hour': + start.addHours(1) + break + case 'day': + start.addDays(1) + break + case 'week': + start.addWeeks(1) + break + case 'month': + start.addMonths(1) + break + case 'year': + start.addYears(1) + break + } + } + range.push(end.clone()); + return range; + } else { + return false; + } + } + // Great, every function is ready, init. $scope.init();