diff options
author | Yusaku Sako <yusaku@apache.org> | 2012-12-09 14:42:31 +0000 |
---|---|---|
committer | Yusaku Sako <yusaku@apache.org> | 2012-12-09 14:42:31 +0000 |
commit | 7ab2fbf4fbb083bc41b24bf361a2b0dae3eaad79 (patch) | |
tree | da689ef889b14886fa21b72f26dd6edcc1ea6b0f /ambari-web | |
parent | ec1abe07667f65636846fc42e5e1bd91d552acb2 (diff) |
AMBARI-1039. Improve Nagios alerts time display. (Srimanth Gunturi via yusaku)
git-svn-id: https://svn.apache.org/repos/asf/incubator/ambari/branches/AMBARI-666@1418981 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'ambari-web')
-rw-r--r-- | ambari-web/app/assets/licenses/NOTICE.txt | 5 | ||||
-rw-r--r-- | ambari-web/app/mappers/alerts_mapper.js | 2 | ||||
-rw-r--r-- | ambari-web/app/models/alert.js | 32 | ||||
-rw-r--r-- | ambari-web/app/styles/application.less | 9 | ||||
-rw-r--r-- | ambari-web/app/templates/main/service/info/client_summary.hbs | 2 | ||||
-rw-r--r-- | ambari-web/app/templates/main/service/info/summary.hbs | 2 | ||||
-rw-r--r-- | ambari-web/app/views/main/service/info/summary.js | 2 | ||||
-rw-r--r-- | ambari-web/config.coffee | 1 | ||||
-rw-r--r-- | ambari-web/vendor/scripts/jquery.timeago.js | 152 |
9 files changed, 197 insertions, 10 deletions
diff --git a/ambari-web/app/assets/licenses/NOTICE.txt b/ambari-web/app/assets/licenses/NOTICE.txt index f238d78473..0606a2933a 100644 --- a/ambari-web/app/assets/licenses/NOTICE.txt +++ b/ambari-web/app/assets/licenses/NOTICE.txt @@ -33,4 +33,7 @@ Copyright (c) 2012 Stefan Petre This product includes Font Awesome 2.0 (http://fortawesome.github.com/Font-Awesome - Creative Commons 3.0) This product incudes Rickshaw 1.1.2 (http://code.shutterstock.com/rickshaw/ - MIT License) -Copyright (C) 2011 by Shutterstock Images, LLC
\ No newline at end of file +Copyright (C) 2011 by Shutterstock Images, LLC + +This product includes Timeago (http://timeago.yarp.com/ - MIT License) +Copyright (c) 2008-2012, Ryan McGeary (ryan -[at]- mcgeary [*dot*] org)
\ No newline at end of file diff --git a/ambari-web/app/mappers/alerts_mapper.js b/ambari-web/app/mappers/alerts_mapper.js index 1577157fc4..fa64bd1d39 100644 --- a/ambari-web/app/mappers/alerts_mapper.js +++ b/ambari-web/app/mappers/alerts_mapper.js @@ -23,7 +23,7 @@ App.alertsMapper = App.QuickDataMapper.create({ $alert_id:'' , title: "service_description", service_type: "service_type", - date: "last_check", + date: "last_hard_state_change", status: "current_state", message: "plugin_output", host_name: "host_name", diff --git a/ambari-web/app/models/alert.js b/ambari-web/app/models/alert.js index 77df655e56..8a570a6f4e 100644 --- a/ambari-web/app/models/alert.js +++ b/ambari-web/app/models/alert.js @@ -53,19 +53,41 @@ App.Alert = DS.Model.extend({ }.property('status'), /** - * Used to show appropriate date in UI + * Provides how long ago this alert happened. + * + * @type {String} */ - dateDisplay: function () { + timeSinceAlert: function () { var d = this.get('date'); if (d) { - var dateString = d.toDateString() + ". " + d.toLocaleTimeString(); - dateString = dateString.substr(dateString.indexOf(" ") + 1); - return dateString; + return $.timeago(d); } return ""; }.property('date'), /** + * Provides more details about when this alert happened. + * + * @type {String} + */ + timeSinceAlertDetails: function () { + var details = ""; + var date = this.get('date'); + if (date) { + var dateString = date.toDateString(); + dateString = dateString.substr(dateString.indexOf(" ") + 1); + dateString = "Occurred on " + dateString + ", " + date.toLocaleTimeString(); + details += dateString; + } + var lastCheck = this.get('lastCheck'); + if (lastCheck) { + lastCheck = new Date(lastCheck * 1000); + details = details + "<br>Last checked " + $.timeago(lastCheck); + } + return details; + }.property('lastCheck', 'date'), + + /** * Used to show appropriate service label in UI */ serviceName: function () { diff --git a/ambari-web/app/styles/application.less b/ambari-web/app/styles/application.less index 5c7f7be75b..83bde02491 100644 --- a/ambari-web/app/styles/application.less +++ b/ambari-web/app/styles/application.less @@ -196,6 +196,10 @@ h1 { color: #FF4B4B; } +.tooltip-inner { + text-align: left; +} + #installer, #add-host, #add-service { h2 { margin-top: 0; @@ -632,7 +636,10 @@ a:focus { padding-top: 7px; } .date-time { - color: #777; + color: #999; + font-style: italic; + font-size: small; + text-align: right; } .message { font-size: 13px; diff --git a/ambari-web/app/templates/main/service/info/client_summary.hbs b/ambari-web/app/templates/main/service/info/client_summary.hbs index 07cfd89507..f2721315df 100644 --- a/ambari-web/app/templates/main/service/info/client_summary.hbs +++ b/ambari-web/app/templates/main/service/info/client_summary.hbs @@ -86,7 +86,7 @@ <div class="row-fluid"> <div class="span7 title">{{title}} </div> - <div class="span5 date-time">{{dateDisplay}}</div> + <div rel="tooltip" {{bindAttr data-title="timeSinceAlertDetails"}} data-placement="right" class="span5 date-time">{{timeSinceAlert}}</div> </div> <div class="row-fluid message">{{message}}</div> </div> diff --git a/ambari-web/app/templates/main/service/info/summary.hbs b/ambari-web/app/templates/main/service/info/summary.hbs index 9f644cb21d..721ab9e798 100644 --- a/ambari-web/app/templates/main/service/info/summary.hbs +++ b/ambari-web/app/templates/main/service/info/summary.hbs @@ -149,7 +149,7 @@ <div class="row-fluid"> <div class="span7 title">{{title}} </div> - <div class="span5 date-time">{{dateDisplay}}</div> + <div rel="tooltip" {{bindAttr data-title="timeSinceAlertDetails"}} data-placement="right" class="span5 date-time">{{timeSinceAlert}}</div> </div> <div class="row-fluid message">{{message}}</div> </div> diff --git a/ambari-web/app/views/main/service/info/summary.js b/ambari-web/app/views/main/service/info/summary.js index 8ec29a0353..f5f22d33ab 100644 --- a/ambari-web/app/views/main/service/info/summary.js +++ b/ambari-web/app/views/main/service/info/summary.js @@ -183,6 +183,8 @@ App.MainServiceInfoSummaryView = Em.View.extend({ $(summaryTable).attr('style', "height:" + alertsList.clientHeight + "px;"); } } + // Tooltips for alerts need to be enabled. + $("div[rel=tooltip]").tooltip(); }, clientHosts:App.Host.find(), diff --git a/ambari-web/config.coffee b/ambari-web/config.coffee index f31f600ce1..8b1ef877de 100644 --- a/ambari-web/config.coffee +++ b/ambari-web/config.coffee @@ -52,6 +52,7 @@ exports.config = 'vendor/scripts/jquery.ui.sortable.js', 'vendor/scripts/jquery.ui.custom-effects.js', 'vendor/scripts/jquery.dataTables.js', + 'vendor/scripts/jquery.timeago.js', 'vendor/scripts/workflow_visualization.js', 'vendor/scripts/rickshaw.js' ] diff --git a/ambari-web/vendor/scripts/jquery.timeago.js b/ambari-web/vendor/scripts/jquery.timeago.js new file mode 100644 index 0000000000..2e8d29f536 --- /dev/null +++ b/ambari-web/vendor/scripts/jquery.timeago.js @@ -0,0 +1,152 @@ +/** + * Timeago is a jQuery plugin that makes it easy to support automatically + * updating fuzzy timestamps (e.g. "4 minutes ago" or "about 1 day ago"). + * + * @name timeago + * @version 0.11.4 + * @requires jQuery v1.2.3+ + * @author Ryan McGeary + * @license MIT License - http://www.opensource.org/licenses/mit-license.php + * + * For usage and examples, visit: + * http://timeago.yarp.com/ + * + * Copyright (c) 2008-2012, Ryan McGeary (ryan -[at]- mcgeary [*dot*] org) + */ +(function($) { + $.timeago = function(timestamp) { + if (timestamp instanceof Date) { + return inWords(timestamp); + } else if (typeof timestamp === "string") { + return inWords($.timeago.parse(timestamp)); + } else if (typeof timestamp === "number") { + return inWords(new Date(timestamp)); + } else { + return inWords($.timeago.datetime(timestamp)); + } + }; + var $t = $.timeago; + + $.extend($.timeago, { + settings: { + refreshMillis: 60000, + allowFuture: false, + strings: { + prefixAgo: null, + prefixFromNow: null, + suffixAgo: "ago", + suffixFromNow: "from now", + seconds: "less than a minute", + minute: "about a minute", + minutes: "%d minutes", + hour: "about an hour", + hours: "about %d hours", + day: "a day", + days: "%d days", + month: "about a month", + months: "%d months", + year: "about a year", + years: "%d years", + wordSeparator: " ", + numbers: [] + } + }, + inWords: function(distanceMillis) { + var $l = this.settings.strings; + var prefix = $l.prefixAgo; + var suffix = $l.suffixAgo; + if (this.settings.allowFuture) { + if (distanceMillis < 0) { + prefix = $l.prefixFromNow; + suffix = $l.suffixFromNow; + } + } + + var seconds = Math.abs(distanceMillis) / 1000; + var minutes = seconds / 60; + var hours = minutes / 60; + var days = hours / 24; + var years = days / 365; + + function substitute(stringOrFunction, number) { + var string = $.isFunction(stringOrFunction) ? stringOrFunction(number, distanceMillis) : stringOrFunction; + var value = ($l.numbers && $l.numbers[number]) || number; + return string.replace(/%d/i, value); + } + + var words = seconds < 45 && substitute($l.seconds, Math.round(seconds)) || + seconds < 90 && substitute($l.minute, 1) || + minutes < 45 && substitute($l.minutes, Math.round(minutes)) || + minutes < 90 && substitute($l.hour, 1) || + hours < 24 && substitute($l.hours, Math.round(hours)) || + hours < 42 && substitute($l.day, 1) || + days < 30 && substitute($l.days, Math.round(days)) || + days < 45 && substitute($l.month, 1) || + days < 365 && substitute($l.months, Math.round(days / 30)) || + years < 1.5 && substitute($l.year, 1) || + substitute($l.years, Math.round(years)); + + var separator = $l.wordSeparator === undefined ? " " : $l.wordSeparator; + return $.trim([prefix, words, suffix].join(separator)); + }, + parse: function(iso8601) { + var s = $.trim(iso8601); + s = s.replace(/\.\d+/,""); // remove milliseconds + s = s.replace(/-/,"/").replace(/-/,"/"); + s = s.replace(/T/," ").replace(/Z/," UTC"); + s = s.replace(/([\+\-]\d\d)\:?(\d\d)/," $1$2"); // -04:00 -> -0400 + return new Date(s); + }, + datetime: function(elem) { + var iso8601 = $t.isTime(elem) ? $(elem).attr("datetime") : $(elem).attr("title"); + return $t.parse(iso8601); + }, + isTime: function(elem) { + // jQuery's `is()` doesn't play well with HTML5 in IE + return $(elem).get(0).tagName.toLowerCase() === "time"; // $(elem).is("time"); + } + }); + + $.fn.timeago = function() { + var self = this; + self.each(refresh); + + var $s = $t.settings; + if ($s.refreshMillis > 0) { + setInterval(function() { self.each(refresh); }, $s.refreshMillis); + } + return self; + }; + + function refresh() { + var data = prepareData(this); + if (!isNaN(data.datetime)) { + $(this).text(inWords(data.datetime)); + } + return this; + } + + function prepareData(element) { + element = $(element); + if (!element.data("timeago")) { + element.data("timeago", { datetime: $t.datetime(element) }); + var text = $.trim(element.text()); + if (text.length > 0 && !($t.isTime(element) && element.attr("title"))) { + element.attr("title", text); + } + } + return element.data("timeago"); + } + + function inWords(date) { + return $t.inWords(distance(date)); + } + + function distance(date) { + return (new Date().getTime() - date.getTime()); + } + + // fix for IE6 suckage + document.createElement("abbr"); + document.createElement("time"); +}(jQuery)); |