Commit d61bfcfb by kevalbhatt Committed by Madhan Neethiraj

ATLAS-3131: stats UI improvements

parent e6deb337
...@@ -452,4 +452,89 @@ hr[size="10"] { ...@@ -452,4 +452,89 @@ hr[size="10"] {
img { img {
height: 50px; 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
<!--
* 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
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * 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 panel-default expand_collapse_panel-icon" data-id="entityActive">
<div class="panel-heading" data-toggle="collapse" href="#collapse1" aria-expanded="true"> <div class="panel-heading" data-toggle="collapse" href="#collapse1" aria-expanded="true">
<h4 class="panel-title"> <h4 class="panel-title">
...@@ -28,12 +28,12 @@ ...@@ -28,12 +28,12 @@
<div class="panel-body"> <div class="panel-body">
<table class="table stat-table"> <table class="table stat-table">
<thead> <thead>
<tr> <tr>
<th>Entity</th> <th>Entity</th>
<th>Count</th> <th>Count</th>
</tr> </tr>
</thead> </thead>
<tbody > <tbody>
</tbody> </tbody>
</table> </table>
</div> </div>
...@@ -52,18 +52,17 @@ ...@@ -52,18 +52,17 @@
<div class="panel-body"> <div class="panel-body">
<table class="table stat-table"> <table class="table stat-table">
<thead> <thead>
<tr> <tr>
<th>Entity</th> <th>Entity</th>
<th>Count</th> <th>Count</th>
</tr> </tr>
</thead> </thead>
<tbody > <tbody>
</tbody> </tbody>
</table> </table>
</div> </div>
</div> </div>
</div> </div>
<div class="panel panel-default expand_collapse_panel-icon" data-id="stats"> <div class="panel panel-default expand_collapse_panel-icon" data-id="stats">
<div class="panel-heading" data-toggle="collapse" href="#collapse3"> <div class="panel-heading" data-toggle="collapse" href="#collapse3">
<h4 class="panel-title"> <h4 class="panel-title">
...@@ -75,17 +74,46 @@ ...@@ -75,17 +74,46 @@
</div> </div>
<div id="collapse3" class="panel-collapse collapse"> <div id="collapse3" class="panel-collapse collapse">
<div class="panel-body"> <div class="panel-body">
<table class="table stat-table"> <div class="col-sm-12">
<thead> <div class="card-container panel panel-primary">
<tr> <div class="panel-heading">Server Details</div>
<th>Parameter</th> <div class="panel-body">
<th>Value</th> <table class="table stat-table">
</tr> <tbody data-id="server-card">
</thead> <tr class="empty text-center">
<tbody > <td colspan="2"><span>No records found!</span></td>
</tbody> </tr>
</table> </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> </div>
</div>
<div class="fontLoader-relative statsLoader show">
<i class="fa fa-refresh fa-spin-custom"></i>
</div> </div>
\ No newline at end of file
...@@ -134,6 +134,55 @@ define(['require'], function(require) { ...@@ -134,6 +134,55 @@ define(['require'], function(require) {
validValues: getTermRelationAttributes(), validValues: getTermRelationAttributes(),
validValuesFor: 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; return Enums;
}); });
\ No newline at end of file
...@@ -814,5 +814,18 @@ define(['require', 'utils/Globals', 'pnotify', 'utils/Messages', 'utils/Enums', ...@@ -814,5 +814,18 @@ define(['require', 'utils/Globals', 'pnotify', 'utils/Messages', 'utils/Enums',
this.attr(attributeName, firstString); 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; return Utils;
}); });
\ No newline at end of file
...@@ -19,18 +19,24 @@ ...@@ -19,18 +19,24 @@
define(['require', define(['require',
'backbone', 'backbone',
'hbs!tmpl/site/Statistics_tmpl', 'hbs!tmpl/site/Statistics_tmpl',
'hbs!tmpl/site/Statistics_Notification_table_tmpl',
'modules/Modal', 'modules/Modal',
'models/VCommon', 'models/VCommon',
'utils/UrlLinks', 'utils/UrlLinks',
'collection/VTagList', 'collection/VTagList',
'utils/CommonViewFunction' 'utils/CommonViewFunction',
], function(require, Backbone, StatTmpl, Modal, VCommon, UrlLinks, VTagList, CommonViewFunction) { 'utils/Enums',
'moment',
'utils/Utils',
'moment-timezone'
], function(require, Backbone, StatTmpl, StatsNotiTable, Modal, VCommon, UrlLinks, VTagList, CommonViewFunction, Enums, moment, Utils) {
'use strict'; 'use strict';
var StatisticsView = Backbone.Marionette.LayoutView.extend( var StatisticsView = Backbone.Marionette.LayoutView.extend(
/** @lends AboutAtlasView */ /** @lends AboutAtlasView */
{ {
template: StatTmpl, template: StatTmpl,
/** Layout sub regions */ /** Layout sub regions */
regions: {}, regions: {},
/** ui selector cache */ /** ui selector cache */
...@@ -39,7 +45,11 @@ define(['require', ...@@ -39,7 +45,11 @@ define(['require',
entityDelete: "[data-id='entityDelete'] tbody", entityDelete: "[data-id='entityDelete'] tbody",
entityActiveHeader: "[data-id='entityActive'] .count", entityActiveHeader: "[data-id='entityActive'] .count",
entityDeletedHeader: "[data-id='entityDelete'] .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 */ /** ui events hash */
events: function() {}, events: function() {},
...@@ -54,7 +64,8 @@ define(['require', ...@@ -54,7 +64,8 @@ define(['require',
content: this, content: this,
okCloses: true, okCloses: true,
showFooter: true, showFooter: true,
allowCancel: false allowCancel: false,
width: "60%"
}).open(); }).open();
modal.on('closeModal', function() { modal.on('closeModal', function() {
...@@ -72,8 +83,8 @@ define(['require', ...@@ -72,8 +83,8 @@ define(['require',
var data = _.first(data.toJSON()), var data = _.first(data.toJSON()),
no_records = '<tr class="empty text-center"><td colspan="2"><span>No records found!</span></td></tr>', 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 }), 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}), 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}); that.renderStats({ valueObject: data.general.stats });
var totalActive = 0, var totalActive = 0,
totalDeleted = 0; totalDeleted = 0;
if (data.entity && data.general.entityCount) { if (data.entity && data.general.entityCount) {
...@@ -86,14 +97,118 @@ define(['require', ...@@ -86,14 +97,118 @@ define(['require',
} }
that.ui.entityActive.html(activeEntityTable); that.ui.entityActive.html(activeEntityTable);
that.ui.entityDelete.html(deleteEntityTable); that.ui.entityDelete.html(deleteEntityTable);
that.ui.stats.html(stats);
that.ui.entityActiveHeader.html("&nbsp;(" + _.numberFormatWithComa((totalActive - totalDeleted)) + ")"); that.ui.entityActiveHeader.html("&nbsp;(" + _.numberFormatWithComa((totalActive - totalDeleted)) + ")");
that.ui.entityDeletedHeader.html("&nbsp;(" + _.numberFormatWithComa(totalDeleted) + ")"); that.ui.entityDeletedHeader.html("&nbsp;(" + _.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) { getTable: function(obj) {
return CommonViewFunction.propertyTable(_.extend({ scope: this, formatIntVal: true }, obj)) return CommonViewFunction.propertyTable(_.extend({
scope: this,
formatIntVal: true
}, obj))
} }
}); });
return StatisticsView; return StatisticsView;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment