Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement Sort option on the Dashboard page #3352

Merged
merged 3 commits into from
Jan 30, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
101 changes: 57 additions & 44 deletions apinf_packages/analytics/server/methods.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,11 @@ import { check } from 'meteor/check';

// Collections imports
import AnalyticsData from '/apinf_packages/analytics/collection';
import ProxyBackends from '/apinf_packages/proxy_backends/collection';

// Npm packages imports
import _ from 'lodash';
import moment from 'moment/moment';

// APInf imports
import { calculateTrend } from '/apinf_packages/dashboard/lib/trend_helpers';
Expand Down Expand Up @@ -107,22 +109,16 @@ Meteor.methods({

return errors;
},
summaryStatisticNumber (filter) {
summaryStatisticNumber (filter, proxyBackendIds) {
check(filter, Object);
check(proxyBackendIds, Array);

// Create query to $match
const matchQuery = {
date: { $gte: filter.fromDate, $lt: filter.toDate },
proxyBackendId: { $in: proxyBackendIds },
};

if (filter.proxyId) {
// Fetch data for particular Proxy (and several Proxy Backends)
matchQuery.proxyId = filter.proxyId;
} else {
// Fetch data for particular Proxy Backend
matchQuery.proxyBackendId = filter.proxyBackendId;
}

const requestPathsData = {};

AnalyticsData.aggregate(
Expand All @@ -142,27 +138,21 @@ Meteor.methods({
sumMedianTime: { $sum: '$medianResponseTime' },
sumUniqueUsers: { $sum: '$uniqueUsers' },
successCallsCount: { $sum: '$successCallsCount' },
redirectCallsCount: { $sum: '$redirectCallsCount' },
failCallsCount: { $sum: '$failCallsCount' },
errorCallsCount: { $sum: '$errorCallsCount' },
},
},
]
).forEach(dataset => {
// Create query
const query = { prefix: dataset._id, date: matchQuery.date, requestNumber: { $ne: 0 } };
// Expend query
matchQuery.prefix = dataset._id;
matchQuery.requestNumber = { $ne: 0 };

if (filter.proxyId) {
query.proxyId = filter.proxyId;
} else {
query.proxyBackendId = filter.proxyBackendId;
}

// Get the number of date when requests were
const existedValuesCount = AnalyticsData.find(query).count();
// Get the number of date when requests were no 0
const existedValuesCount = AnalyticsData.find(matchQuery).count();

// Calculate average (mean) value of Response time and Uniques users during period
requestPathsData[dataset._id] = {
prefix: dataset._id, // Just rename it
medianResponseTime: parseInt(dataset.sumMedianTime / existedValuesCount, 10) || 0,
avgUniqueUsers: parseInt(dataset.sumUniqueUsers / existedValuesCount, 10) || 0,
};
Expand All @@ -172,29 +162,6 @@ Meteor.methods({

return requestPathsData;
},
summaryStatisticTrend (filter, currentPeriodResponse) {
check(filter, Object);
check(currentPeriodResponse, Object);

// Get summary statistic data about previous period
const previousPeriodResponse = Meteor.call('summaryStatisticNumber', filter);

const comparisonData = {};

// Compare the current and previous periods data
_.mapKeys(currentPeriodResponse, (dataset, path) => {
const previousPeriodData = previousPeriodResponse[path] || {};

comparisonData[path] = {
compareRequests: calculateTrend(previousPeriodData.requestNumber, dataset.requestNumber),
compareResponse:
calculateTrend(previousPeriodData.medianResponseTime, dataset.medianResponseTime),
compareUsers: calculateTrend(previousPeriodData.avgUniqueUsers, dataset.avgUniqueUsers),
};
});

return comparisonData;
},
statusCodesData (filter) {
check(filter, Object);

Expand Down Expand Up @@ -282,4 +249,50 @@ Meteor.methods({

return requestPathsData;
},
totalNumberRequestsAndTrend (filter, proxyBackendIds) {
check(filter, Object);
check(proxyBackendIds, Array);

// Get data for Current period
const currentPeriodResponse =
Meteor.call('summaryStatisticNumber', filter, proxyBackendIds);

// Create date range filter for Previous period
const previousPeriodFilter = {
fromDate: moment(filter.fromDate).subtract(filter.timeframe, 'd').valueOf(),
toDate: filter.fromDate,
};

// Get data for Previous period
const previousPeriodResponse =
Meteor.call('summaryStatisticNumber', previousPeriodFilter, proxyBackendIds);

const response = [];

// Compare the current and previous periods data
_.mapKeys(currentPeriodResponse, (dataset, path) => {
const proxyBackend = ProxyBackends.findOne({
'apiUmbrella.url_matches.frontend_prefix': dataset.prefix,
});

if (proxyBackend) {
dataset.proxyBackendId = proxyBackend._id;
dataset.apiName = proxyBackend.apiName();
dataset.apiSlug = proxyBackend.apiSlug();
}

// Create a comparison data
const previousPeriodData = previousPeriodResponse[path] || {};
dataset.compareRequests =
calculateTrend(previousPeriodData.requestNumber, dataset.requestNumber);
dataset.compareResponse =
calculateTrend(previousPeriodData.medianResponseTime, dataset.medianResponseTime);
dataset.compareUsers =
calculateTrend(previousPeriodData.avgUniqueUsers, dataset.avgUniqueUsers);

response.push(dataset);
});

return response;
},
});
18 changes: 9 additions & 9 deletions apinf_packages/dashboard/client/analytic/body/body.html
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
<div class="col-xs-12 col-md-4">
<div class="api-view-card form-group">
<p class="overview-col-title">
{{_ 'apiAnalyticPageBody_text_requestsCount' count=(getStatistics 'requests') }}
{{_ 'apiAnalyticPageBody_text_requestsCount' count=analyticsData.requestNumber }}
</p>
<p class="overview-col-title">
{{_ 'apiAnalyticPageBody_chartTitle_apiRequests' }}
Expand All @@ -23,15 +23,15 @@
{{/ if }}
</div>

{{# with comparisonData }}
{{# if analyticsData }}
<div class="form-group">
<div class="{{ arrowDirection 'requests' }}"></div>
<!-- Keep the space symbol to set SPAN element a height -->
<span>
{{ summaryComparing 'requests' }}&nbsp;
</span>
</div>
{{/ with }}
{{/ if }}

<!-- response status list-->
<div class="row">
Expand All @@ -55,7 +55,7 @@
<div class="col-xs-12 col-md-4">
<div class="api-view-card form-group">
<p class="overview-col-title">
{{_ 'apiAnalyticPageBody_text_responseTime' time=(getStatistics 'time') }}
{{_ 'apiAnalyticPageBody_text_responseTime' time=analyticsData.medianResponseTime }}
</p>
<p class="overview-col-title">
{{_ 'apiAnalyticPageBody_chartTitle_medianResponseTime' }}
Expand All @@ -67,15 +67,15 @@
{{> spinner}}
{{/ if }}
</div>
{{# with comparisonData }}
{{# if analyticsData }}
<div class="form-group">
<div class="{{ arrowDirection 'time' }}"></div>
<!-- Keep the space symbol to set SPAN element a height -->
<span>
{{ summaryComparing 'time' }}&nbsp;
</span>
</div>
{{/ with }}
{{/ if }}
<!-- Keep the space symbol to set a height the element a height -->
<div class="row">&nbsp;</div>
</div>
Expand All @@ -85,7 +85,7 @@
<div class="col-xs-12 col-md-4">
<div class="api-view-card form-group">
<p class="overview-col-title">
{{_ 'apiAnalyticPageBody_text_usersCount' count=(getStatistics 'users') }} <sup>*</sup>
{{_ 'apiAnalyticPageBody_text_usersCount' count=analyticsData.avgUniqueUsers }} <sup>*</sup>
</p>
<p class="overview-col-title">
{{_ 'apiAnalyticPageBody_chartTitle_uniqueUsers' }}
Expand All @@ -97,15 +97,15 @@
{{> spinner}}
{{/ if }}
</div>
{{# with comparisonData }}
{{# if analyticsData }}
<div class="form-group">
<div class="{{ arrowDirection 'users' }}"></div>
<!-- Keep the space symbol to set SPAN element a height -->
<span>
{{ summaryComparing 'users' }}&nbsp;
</span>
</div>
{{/ with }}
{{/ if }}
<div class="overview-help-text">
<sup>*</sup> {{_ 'apiAnalyticPageBody_helpText_averageUniqueUsers' }}
</div>
Expand Down
83 changes: 23 additions & 60 deletions apinf_packages/dashboard/client/analytic/body/body.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ import _ from 'lodash';

// APInf import
import mostUsersRequest from '/apinf_packages/dashboard/client/elasticsearch_queries/most_users';
import promisifyCall from '/apinf_packages/core/helper_functions/promisify_call';
import {
arrowDirection,
percentageValue,
Expand All @@ -38,8 +37,7 @@ Template.apiAnalyticPageBody.onCreated(function () {

// Init variables
instance.overviewChartResponse = new ReactiveVar();
instance.summaryStatisticResponse = new ReactiveVar();
instance.comparisonStatisticResponse = new ReactiveVar();
instance.analyticsData = new ReactiveVar();
instance.statusCodesResponse = new ReactiveVar();
instance.timelineChartResponse = new ReactiveVar();
instance.allRequestPaths = new ReactiveVar();
Expand All @@ -55,22 +53,9 @@ Template.apiAnalyticPageBody.onCreated(function () {
// Get timestamp of timeframe ago 00:00:00 Date time (included value)
const fromDate = moment(toDate).subtract(timeframe, 'd').valueOf();

// Get data about summary statistic for current period
promisifyCall('summaryStatisticNumber', { proxyBackendId, fromDate, toDate })
.then((currentPeriodDataset) => {
instance.summaryStatisticResponse.set(currentPeriodDataset);

const previousFromDate = moment(fromDate).subtract(timeframe, 'd').valueOf();

// Get trend data is based on the current period data
Meteor.call('summaryStatisticTrend',
{ proxyBackendId, fromDate: previousFromDate, toDate: fromDate }, currentPeriodDataset,
(err, compareResponse) => {
// Save the response about Comparison data
instance.comparisonStatisticResponse.set(compareResponse);
});
}).catch((error) => {
throw new Meteor.Error(error);
Meteor.call('totalNumberRequestsAndTrend',
{ fromDate, toDate, timeframe }, [proxyBackendId], (error, result) => {
this.analyticsData.set(result);
});

// Get data about summary statistic over time
Expand Down Expand Up @@ -135,58 +120,45 @@ Template.apiAnalyticPageBody.onCreated(function () {
});

Template.apiAnalyticPageBody.helpers({
// TODO: Keep in mind to case with error result
arrowDirection (parameter) {
const instance = Template.instance();

const dataset = instance.analyticsData.get();

// Provide compared data
return arrowDirection(parameter, this);
return arrowDirection(parameter, dataset[0]);
},
percentages (parameter) {
const instance = Template.instance();

const dataset = instance.analyticsData.get() || [];

// Provide compared data
return percentageValue(parameter, this);
return percentageValue(parameter, dataset[0]);
},
summaryComparing (parameter) {
const instance = Template.instance();

// Get value of timeframe
const currentTimeframe = FlowRouter.getQueryParam('timeframe');

const dataset = instance.analyticsData.get() || [];

// Provide compared data
return summaryComparing(parameter, this, currentTimeframe);
return summaryComparing(parameter, dataset[0], currentTimeframe);
},
overviewChartResponse () {
const instance = Template.instance();

// Return boolean value of available overviewChart response
return !!(instance.overviewChartResponse.get());
},
getStatistics (param) {
analyticsData () {
const instance = Template.instance();
const path = instance.requestPath;

const summaryStatisticResponse = instance.summaryStatisticResponse.get();
const summaryStatistic = summaryStatisticResponse && summaryStatisticResponse[path];

let count;

switch (param) {

case 'requests': {
count = summaryStatistic ? summaryStatistic.requestNumber : 0;
break;
}
case 'time': {
count = summaryStatistic ? summaryStatistic.medianResponseTime : 0;
break;
}
case 'users': {
count = summaryStatistic ? summaryStatistic.avgUniqueUsers : 0;
break;
}
default: {
count = 0;
break;
}
}
const dataset = instance.analyticsData.get() || [];

return count;
// Return boolean value of available analyticsData response
return dataset[0];
},
getChartData (param) {
const instance = Template.instance();
Expand Down Expand Up @@ -218,15 +190,6 @@ Template.apiAnalyticPageBody.helpers({

return dataset;
},
comparisonData () {
const instance = Template.instance();
const path = instance.requestPath;

const comparisonResponse = instance.comparisonStatisticResponse.get();
const comparisonData = comparisonResponse && comparisonResponse[path];

return comparisonData || {};
},
getStatusCode (param) {
const instance = Template.instance();
const path = instance.requestPath;
Expand Down
6 changes: 6 additions & 0 deletions apinf_packages/dashboard/client/lib/routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,12 @@ signedIn.route('/dashboard', {
// Default value is 7
context.queryParams.timeframe = 7;
}

if (!context.queryParams.sort) {
// Initialize sort parameter if it doesn't specify
// Default value is 'name'
context.queryParams.sort = 'name';
}
}],
name: 'dashboard',
action () {
Expand Down
Loading