From d61bfcfb03a116203df6280924eb9df94194026a Mon Sep 17 00:00:00 2001 From: kevalbhatt <kbhatt@apache.org> Date: Fri, 12 Apr 2019 22:21:49 +0530 Subject: [PATCH] ATLAS-3131: stats UI improvements Signed-off-by: Madhan Neethiraj <madhan@apache.org> --- dashboardv2/public/css/scss/theme.scss | 85 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ dashboardv2/public/js/templates/site/Statistics_Notification_table_tmpl.html | 39 +++++++++++++++++++++++++++++++++++++++ dashboardv2/public/js/templates/site/Statistics_tmpl.html | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++---------------------- dashboardv2/public/js/utils/Enums.js | 51 ++++++++++++++++++++++++++++++++++++++++++++++++++- dashboardv2/public/js/utils/Utils.js | 13 +++++++++++++ dashboardv2/public/js/views/site/Statistics.js | 131 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------- 6 files changed, 360 insertions(+), 31 deletions(-) create mode 100644 dashboardv2/public/js/templates/site/Statistics_Notification_table_tmpl.html diff --git a/dashboardv2/public/css/scss/theme.scss b/dashboardv2/public/css/scss/theme.scss index 25ca868..772f5f6 100644 --- a/dashboardv2/public/css/scss/theme.scss +++ b/dashboardv2/public/css/scss/theme.scss @@ -452,4 +452,89 @@ hr[size="10"] { img { height: 50px; } +} + +.server-stats-container { + + .connection-status { + height: 10px; + width: 10px; + border-radius: 50%; + display: inline-block; + + &.connected { + background-color: #4CAF50; + } + + &.not-connected { + background-color: #f44336; + } + } + + .notification-card { + padding-top: 5px; + } + + .card-container { + &.panel { + &.panel-primary { + border: 1px solid #ddd; + padding: 5px; + } + } + + &.panel-primary>.panel-heading { + color: #686868; + background-color: #fff; + font-size: 14px; + font-weight: bold; + } + } + + + .panel-group { + .panel { + padding: 5px; + } + } + + .panel { + &.panel-default { + padding: 5px; + } + + .panel-body { + + .col-sm-6, + .col-sm-12 { + padding: 5px; + + .panel-heading { + padding: 5px 0 0 15px; + } + } + + } + + } + + .table { + &.stat-table { + &.notification-table { + &.table-striped>tbody>tr:nth-of-type(odd) { + background-color: $color_white_lilac_approx; + } + + tr { + + th:not(:first-child), + td:not(:first-child) { + text-align: right; + } + } + } + + + } + } } \ No newline at end of file diff --git a/dashboardv2/public/js/templates/site/Statistics_Notification_table_tmpl.html b/dashboardv2/public/js/templates/site/Statistics_Notification_table_tmpl.html new file mode 100644 index 0000000..d302263 --- /dev/null +++ b/dashboardv2/public/js/templates/site/Statistics_Notification_table_tmpl.html @@ -0,0 +1,39 @@ +<!-- + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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. +--> +<thead> + <tr> + <th>Period</th> + <th>Count</th> + <th>Avg Time <span style="text-transform: lowercase;">(ms)</span></th> + <th>Creates</th> + <th>Updates</th> + <th>Deletes</th> + <th>Failed</th> + </tr> +</thead> +{{#if data}} +<tbody> + {{#each tableCol}} + <tr> + <td>{{{this.label}}}</td> + {{#each ../tableHeader}} + <td>{{callmyfunction ../../getValue ../this this}}</td> + {{/each }} + </tr> + {{/each}} +</tbody> +{{/if}} \ No newline at end of file diff --git a/dashboardv2/public/js/templates/site/Statistics_tmpl.html b/dashboardv2/public/js/templates/site/Statistics_tmpl.html index 71643c7..c29c9c6 100644 --- a/dashboardv2/public/js/templates/site/Statistics_tmpl.html +++ b/dashboardv2/public/js/templates/site/Statistics_tmpl.html @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. --> -<div class="panel-group" id="accordion"> +<div class="panel-group server-stats-container statsContainer hide" id="accordion"> <div class="panel panel-default expand_collapse_panel-icon" data-id="entityActive"> <div class="panel-heading" data-toggle="collapse" href="#collapse1" aria-expanded="true"> <h4 class="panel-title"> @@ -28,12 +28,12 @@ <div class="panel-body"> <table class="table stat-table"> <thead> - <tr> - <th>Entity</th> - <th>Count</th> - </tr> + <tr> + <th>Entity</th> + <th>Count</th> + </tr> </thead> - <tbody > + <tbody> </tbody> </table> </div> @@ -52,18 +52,17 @@ <div class="panel-body"> <table class="table stat-table"> <thead> - <tr> - <th>Entity</th> - <th>Count</th> - </tr> + <tr> + <th>Entity</th> + <th>Count</th> + </tr> </thead> - <tbody > + <tbody> </tbody> </table> </div> </div> </div> - <div class="panel panel-default expand_collapse_panel-icon" data-id="stats"> <div class="panel-heading" data-toggle="collapse" href="#collapse3"> <h4 class="panel-title"> @@ -75,17 +74,46 @@ </div> <div id="collapse3" class="panel-collapse collapse"> <div class="panel-body"> - <table class="table stat-table"> - <thead> - <tr> - <th>Parameter</th> - <th>Value</th> - </tr> - </thead> - <tbody > - </tbody> - </table> + <div class="col-sm-12"> + <div class="card-container panel panel-primary"> + <div class="panel-heading">Server Details</div> + <div class="panel-body"> + <table class="table stat-table"> + <tbody data-id="server-card"> + <tr class="empty text-center"> + <td colspan="2"><span>No records found!</span></td> + </tr> + </tbody> + </table> + </div> + </div> + </div> + <div class="col-sm-12"> + <div class="card-container panel panel-primary"> + <div class="panel-heading">Notification Details</div> + <div class="panel-body"> + <table class="table stat-table"> + <tbody data-id="notification-small-card"> + <tr class="empty text-center"> + <td colspan="2"><span>No records found!</span></td> + </tr> + </tbody> + </table> + <hr></hr> + <table data-id="notification-card" class="table stat-table notification-table table-striped "> + <tbody> + <tr class="empty text-center"> + <td colspan="2"><span>No records found!</span></td> + </tr> + </tbody> + </table> + </div> + </div> + </div> </div> </div> </div> +</div> +<div class="fontLoader-relative statsLoader show"> + <i class="fa fa-refresh fa-spin-custom"></i> </div> \ No newline at end of file diff --git a/dashboardv2/public/js/utils/Enums.js b/dashboardv2/public/js/utils/Enums.js index 8df22af..aeb8ec2 100644 --- a/dashboardv2/public/js/utils/Enums.js +++ b/dashboardv2/public/js/utils/Enums.js @@ -134,6 +134,55 @@ define(['require'], function(require) { validValues: getTermRelationAttributes(), validValuesFor: getTermRelationAttributes() } - Enums.addOnClassification = ["_CLASSIFIED", "_NOT_CLASSIFIED"] + Enums.addOnClassification = ["_CLASSIFIED", "_NOT_CLASSIFIED"]; + + Enums.stats = { + Server: { + "startTimeStamp": "day", + "activeTimeStamp": "day", + "upTime": "none" + }, + ConnectionStatus: { + "backendStore": "none", + "indexStore": "none" + }, + Notification: { + "currentDay": "number", + "currentDayAvgTime": "number", + "currentDayEntityCreates": "number", + "currentDayEntityDeletes": "number", + "currentDayEntityUpdates": "number", + "currentDayFailed": "number", + "currentDayStartTime": "day", + "currentHour": "number", + "currentHourAvgTime": "millisecond", + "currentHourEntityCreates": "number", + "currentHourEntityDeletes": "number", + "currentHourEntityUpdates": "number", + "currentHourFailed": "number", + "currentHourStartTime": "day", + "lastMessageProcessedTime": "day", + "offsetCurrent": "number", + "offsetStart": "number", + "previousDay": "number", + "previousDayAvgTime": "millisecond", + "previousDayEntityCreates": "number", + "previousDayEntityDeletes": "number", + "previousDayEntityUpdates": "number", + "previousDayFailed": "number", + "previousHour": "number", + "previousHourAvgTime": "millisecond", + "previousHourEntityCreates": "number", + "previousHourEntityDeletes": "number", + "previousHourEntityUpdates": "number", + "previousHourFailed": "number", + "total": "number", + "totalAvgTime": "millisecond", + "totalCreates": "number", + "totalDeletes": "number", + "totalFailed": "number", + "totalUpdates": "number" + } + }; return Enums; }); \ No newline at end of file diff --git a/dashboardv2/public/js/utils/Utils.js b/dashboardv2/public/js/utils/Utils.js index 56bd844..ae71602 100644 --- a/dashboardv2/public/js/utils/Utils.js +++ b/dashboardv2/public/js/utils/Utils.js @@ -814,5 +814,18 @@ define(['require', 'utils/Globals', 'pnotify', 'utils/Messages', 'utils/Enums', this.attr(attributeName, firstString); } } + + Utils.millisecondsToTime = function(duration) { + var milliseconds = parseInt((duration % 1000) / 100), + seconds = parseInt((duration / 1000) % 60), + minutes = parseInt((duration / (1000 * 60)) % 60), + hours = parseInt((duration / (1000 * 60 * 60)) % 24); + + hours = (hours < 10) ? "0" + hours : hours; + minutes = (minutes < 10) ? "0" + minutes : minutes; + seconds = (seconds < 10) ? "0" + seconds : seconds; + + return hours + ":" + minutes + ":" + seconds + "." + milliseconds; + } return Utils; }); \ No newline at end of file diff --git a/dashboardv2/public/js/views/site/Statistics.js b/dashboardv2/public/js/views/site/Statistics.js index 9d34784..bc25ddc 100644 --- a/dashboardv2/public/js/views/site/Statistics.js +++ b/dashboardv2/public/js/views/site/Statistics.js @@ -19,18 +19,24 @@ define(['require', 'backbone', 'hbs!tmpl/site/Statistics_tmpl', + 'hbs!tmpl/site/Statistics_Notification_table_tmpl', 'modules/Modal', 'models/VCommon', 'utils/UrlLinks', 'collection/VTagList', - 'utils/CommonViewFunction' -], function(require, Backbone, StatTmpl, Modal, VCommon, UrlLinks, VTagList, CommonViewFunction) { + 'utils/CommonViewFunction', + 'utils/Enums', + 'moment', + 'utils/Utils', + 'moment-timezone' +], function(require, Backbone, StatTmpl, StatsNotiTable, Modal, VCommon, UrlLinks, VTagList, CommonViewFunction, Enums, moment, Utils) { 'use strict'; var StatisticsView = Backbone.Marionette.LayoutView.extend( /** @lends AboutAtlasView */ { template: StatTmpl, + /** Layout sub regions */ regions: {}, /** ui selector cache */ @@ -39,7 +45,11 @@ define(['require', entityDelete: "[data-id='entityDelete'] tbody", entityActiveHeader: "[data-id='entityActive'] .count", entityDeletedHeader: "[data-id='entityDelete'] .count", - stats: "[data-id='stats'] tbody" + serverCard: "[data-id='server-card']", + connectionCard: "[data-id='connection-card']", + notificationCard: "[data-id='notification-card']", + statsNotificationTable: "[data-id='stats-notification-table']", + notificationSmallCard: "[data-id='notification-small-card']" }, /** ui events hash */ events: function() {}, @@ -54,7 +64,8 @@ define(['require', content: this, okCloses: true, showFooter: true, - allowCancel: false + allowCancel: false, + width: "60%" }).open(); modal.on('closeModal', function() { @@ -72,8 +83,8 @@ define(['require', var data = _.first(data.toJSON()), no_records = '<tr class="empty text-center"><td colspan="2"><span>No records found!</span></td></tr>', activeEntityTable = _.isEmpty(data.entity.entityActive) ? no_records : that.getTable({ valueObject: data.entity.entityActive }), - deleteEntityTable = _.isEmpty(data.entity.entityDeleted) ? no_records : that.getTable({ valueObject: data.entity.entityDeleted}), - stats = _.isEmpty(data.general.stats) ? no_records : that.getTable({ valueObject: data.general.stats, formatIntVal: false}); + deleteEntityTable = _.isEmpty(data.entity.entityDeleted) ? no_records : that.getTable({ valueObject: data.entity.entityDeleted }); + that.renderStats({ valueObject: data.general.stats }); var totalActive = 0, totalDeleted = 0; if (data.entity && data.general.entityCount) { @@ -86,14 +97,118 @@ define(['require', } that.ui.entityActive.html(activeEntityTable); that.ui.entityDelete.html(deleteEntityTable); - that.ui.stats.html(stats); that.ui.entityActiveHeader.html(" (" + _.numberFormatWithComa((totalActive - totalDeleted)) + ")"); that.ui.entityDeletedHeader.html(" (" + _.numberFormatWithComa(totalDeleted) + ")"); + that.$('.statsContainer,.statsNotificationContainer').removeClass('hide'); + that.$('.statsLoader,.statsNotificationLoader').removeClass('show'); + } + }); + }, + genrateStatusData: function(stateObject) { + var that = this, + stats = {}; + _.each(stateObject, function(val, key) { + var keys = key.split(":"), + key = keys[0], + subKey = keys[1]; + if (stats[key]) { + stats[key][subKey] = val; + } else { + stats[key] = {}; + stats[key][subKey] = val; } }); + return stats; + }, + renderStats: function(options) { + var that = this, + data = this.genrateStatusData(options.valueObject), + createTable = function(obj) { + var tableBody = '', + enums = obj.enums, + data = obj.data, + showConnectionStatus = obj.showConnectionStatus; + _.each(data, function(value, key, list) { + tableBody += '<tr><td>' + key + '</td><td class="">' + that.getValue({ + "value": value, + "type": enums[key], + "showConnectionStatus": showConnectionStatus + }) + '</td></tr>'; + }); + return tableBody; + }; + if (data.Notification) { + var tableCol = [{ label: "Total", key: "total" }, + { + label: "Current Hour <br> (from " + (that.getValue({ + "value": data.Notification["currentHourStartTime"], + "type": Enums.stats.Notification["currentHourStartTime"], + })) + ")", + key: "currentHour" + }, + { label: "Previous Hour", key: "previousHour" }, + { + label: "Current Day <br> (from " + (that.getValue({ + "value": data.Notification["currentDayStartTime"], + "type": Enums.stats.Notification["currentDayStartTime"], + })) + ")", + key: "currentDay" + }, + { label: "Previous Day", key: "previousDay" } + ], + tableHeader = ["count", "AvgTime", "EntityCreates", "EntityUpdates", "EntityDeletes", "Failed"]; + that.ui.notificationCard.html( + StatsNotiTable({ + "enums": Enums.stats.Notification, + "data": data.Notification, + "tableHeader": tableHeader, + "tableCol": tableCol, + "getValue": function(argument, args) { + var returnVal = (args == 'count' ? data.Notification[argument.key] : data.Notification[argument.key.concat(args)]); + return returnVal ? _.numberFormatWithComa(returnVal) : 0; + } + }) + ); + + that.ui.notificationSmallCard.html(createTable({ + "enums": Enums.stats.Notification, + "data": _.pick(data.Notification, 'lastMessageProcessedTime', 'offsetCurrent', 'offsetStart') + })); + } + + if (data.Server) { + that.ui.serverCard.html( + createTable({ + "enums": _.extend(Enums.stats.Server, Enums.stats.ConnectionStatus), + "data": _.extend(_.pick(data.Server, 'startTimeStamp', 'activeTimeStamp', 'upTime'), data.ConnectionStatus), + "showConnectionStatus": true + }) + ); + } + }, + getValue: function(options) { + var value = options.value, + type = options.type, + showConnectionStatus = options.showConnectionStatus; + if (type == 'time') { + return Utils.millisecondsToTime(value); + } else if (type == 'day') { + return moment.tz(value, moment.tz.guess()).format("MM/DD/YYYY h:mm A z"); + } else if (type == 'number') { + return _.numberFormatWithComa(value); + } else if (type == 'millisecond') { + return _.numberFormatWithComa(value) + " millisecond/s"; + } else if ((showConnectionStatus && (value.indexOf('connected') != -1))) { + return '<span class="connection-status ' + (showConnectionStatus && showConnectionStatus == true ? value : "") + '"></span>'; + } else { + return value; + } }, getTable: function(obj) { - return CommonViewFunction.propertyTable(_.extend({ scope: this, formatIntVal: true }, obj)) + return CommonViewFunction.propertyTable(_.extend({ + scope: this, + formatIntVal: true + }, obj)) } }); return StatisticsView; -- libgit2 0.27.1