273 lines
8.3 KiB
JavaScript
273 lines
8.3 KiB
JavaScript
/**
|
|
* Model for Multisites Dashboard aka All Websites Dashboard.
|
|
*
|
|
*/
|
|
angular.module('piwikApp').factory('multisitesDashboardModel', function (piwikApi, $filter, $timeout) {
|
|
/**
|
|
*
|
|
* this is the list of all available sites. For performance reason this list is different to model.sites. ngRepeat
|
|
* won't operate on the whole list this way. The allSites array contains websites and groups in the following
|
|
* structure
|
|
*
|
|
* - website1
|
|
* - website2
|
|
* - website3.sites = [ // this is a group
|
|
* - website4
|
|
* - website5
|
|
* ]
|
|
* - website6
|
|
*
|
|
* This structure allows us to display the sites within a group directly under the group without big logic and also
|
|
* allows us to calculate the summary for each group easily
|
|
*/
|
|
var allSitesByGroup = [];
|
|
|
|
var model = {};
|
|
// those sites are going to be displayed
|
|
model.sites = [];
|
|
model.isLoading = false;
|
|
model.pageSize = 5;
|
|
model.currentPage = 0;
|
|
model.totalVisits = '?';
|
|
model.totalActions = '?';
|
|
model.totalRevenue = '?';
|
|
model.searchTerm = '';
|
|
model.lastVisits = '?';
|
|
model.lastVisitsDate = '?';
|
|
|
|
fetchPreviousSummary();
|
|
|
|
// create a new group object which has similar structure than a website
|
|
function createGroup(name){
|
|
return {
|
|
label: name,
|
|
sites: [],
|
|
nb_visits: 0,
|
|
nb_pageviews: 0,
|
|
revenue: 0,
|
|
isGroup: true
|
|
};
|
|
}
|
|
|
|
// create a new group with empty site to make sure we do not change the original group in $allSites
|
|
function copyGroup(group)
|
|
{
|
|
return {
|
|
label: group.label,
|
|
sites: [],
|
|
nb_visits: group.nb_visits,
|
|
nb_pageviews: group.nb_pageviews,
|
|
revenue: group.revenue,
|
|
isGroup: true
|
|
};
|
|
}
|
|
|
|
function onError () {
|
|
model.errorLoadingSites = true;
|
|
model.sites = [];
|
|
allSitesByGroup = [];
|
|
}
|
|
|
|
function calculateMetricsForEachGroup(groups)
|
|
{
|
|
angular.forEach(groups, function (group) {
|
|
angular.forEach(group.sites, function (site) {
|
|
var revenue = (site.revenue+'').match(/(\d+\.?\d*)/); // convert $ 0.00 to 0.00 or 5€ to 5
|
|
group.nb_visits += parseInt(site.nb_visits, 10);
|
|
group.nb_pageviews += parseInt(site.nb_pageviews, 10);
|
|
if (revenue.length) {
|
|
group.revenue += parseInt(revenue[0], 10);
|
|
}
|
|
});
|
|
});
|
|
}
|
|
|
|
function createGroupsAndMoveSitesIntoRelatedGroup(allSitesUnordered, reportMetadata)
|
|
{
|
|
var sitesByGroup = [];
|
|
var groups = {};
|
|
|
|
// we do 3 things (complete site information, create groups, move sites into group) in one step for
|
|
// performance reason, there can be > 20k sites
|
|
angular.forEach(allSitesUnordered, function (site, index) {
|
|
site.idsite = reportMetadata[index].idsite;
|
|
site.group = reportMetadata[index].group;
|
|
site.main_url = reportMetadata[index].main_url;
|
|
|
|
if (site.group) {
|
|
|
|
if (!groups[site.group]) {
|
|
var group = createGroup(site.group);
|
|
|
|
groups[site.group] = group;
|
|
sitesByGroup.push(group);
|
|
}
|
|
|
|
groups[site.group].sites.push(site);
|
|
|
|
} else {
|
|
sitesByGroup.push(site);
|
|
}
|
|
});
|
|
|
|
calculateMetricsForEachGroup(groups);
|
|
|
|
return sitesByGroup;
|
|
}
|
|
|
|
model.updateWebsitesList = function (processedReport) {
|
|
if (!processedReport) {
|
|
onError();
|
|
return;
|
|
}
|
|
|
|
var allSitesUnordered = processedReport.reportData;
|
|
model.totalVisits = processedReport.reportTotal.nb_visits;
|
|
model.totalActions = processedReport.reportTotal.nb_actions;
|
|
model.totalRevenue = processedReport.reportTotal.revenue;
|
|
|
|
allSitesByGroup = createGroupsAndMoveSitesIntoRelatedGroup(allSitesUnordered, processedReport.reportMetadata);
|
|
|
|
if (!allSitesByGroup.length) {
|
|
return;
|
|
}
|
|
|
|
if (model.searchTerm) {
|
|
model.searchSite(model.searchTerm);
|
|
} else {
|
|
model.sites = allSitesByGroup;
|
|
}
|
|
};
|
|
|
|
model.getNumberOfFilteredSites = function () {
|
|
var numSites = model.sites.length;
|
|
|
|
var groupNames = {};
|
|
|
|
for (var index = 0; index < model.sites.length; index++) {
|
|
var site = model.sites[index];
|
|
if (site && site.isGroup) {
|
|
numSites += site.sites.length;
|
|
}
|
|
}
|
|
|
|
return numSites;
|
|
};
|
|
|
|
model.getNumberOfPages = function () {
|
|
return Math.ceil(model.getNumberOfFilteredSites() / model.pageSize - 1);
|
|
};
|
|
|
|
model.getCurrentPagingOffsetStart = function() {
|
|
return Math.ceil(model.currentPage * model.pageSize);
|
|
};
|
|
|
|
model.getCurrentPagingOffsetEnd = function() {
|
|
var end = model.getCurrentPagingOffsetStart() + parseInt(model.pageSize, 10);
|
|
var max = model.getNumberOfFilteredSites();
|
|
if (end > max) {
|
|
end = max;
|
|
}
|
|
return parseInt(end, 10);
|
|
};
|
|
|
|
model.previousPage = function () {
|
|
model.currentPage = model.currentPage - 1;
|
|
};
|
|
|
|
model.nextPage = function () {
|
|
model.currentPage = model.currentPage + 1;
|
|
};
|
|
|
|
function nestedSearch(sitesByGroup, term)
|
|
{
|
|
var filteredSites = [];
|
|
|
|
for (var index in sitesByGroup) {
|
|
var site = sitesByGroup[index];
|
|
if (site.isGroup) {
|
|
var matchingSites = nestedSearch(site.sites, term);
|
|
if (matchingSites.length || (''+site.label).toLowerCase().indexOf(term) > -1) {
|
|
var clonedGroup = copyGroup(site);
|
|
clonedGroup.sites = matchingSites;
|
|
filteredSites.push(clonedGroup);
|
|
}
|
|
} else if ((''+site.label).toLowerCase().indexOf(term) > -1) {
|
|
filteredSites.push(site);
|
|
} else if (site.group && (''+site.group).toLowerCase().indexOf(term) > -1) {
|
|
filteredSites.push(site);
|
|
}
|
|
}
|
|
|
|
return filteredSites;
|
|
}
|
|
|
|
model.searchSite = function (term) {
|
|
model.searchTerm = term;
|
|
model.currentPage = 0;
|
|
model.sites = nestedSearch(allSitesByGroup, term);
|
|
};
|
|
|
|
function fetchPreviousSummary () {
|
|
piwikApi.fetch({
|
|
method: 'API.getLastDate'
|
|
}).then(function (response) {
|
|
if (response && response.value) {
|
|
return response.value;
|
|
}
|
|
}).then(function (lastDate) {
|
|
if (!lastDate) {
|
|
return;
|
|
}
|
|
|
|
model.lastVisitsDate = lastDate;
|
|
|
|
return piwikApi.fetch({
|
|
method: 'API.getProcessedReport',
|
|
apiModule: 'MultiSites',
|
|
apiAction: 'getAll',
|
|
hideMetricsDoc: '1',
|
|
filter_limit: '0',
|
|
showColumns: 'label,nb_visits',
|
|
enhanced: 1,
|
|
date: lastDate
|
|
});
|
|
}).then(function (response) {
|
|
if (response && response.reportTotal) {
|
|
model.lastVisits = response.reportTotal.nb_visits;
|
|
}
|
|
});
|
|
}
|
|
|
|
model.fetchAllSites = function (refreshInterval) {
|
|
|
|
if (model.isLoading) {
|
|
piwikApi.abort();
|
|
}
|
|
|
|
model.isLoading = true;
|
|
model.errorLoadingSites = false;
|
|
|
|
return piwikApi.fetch({
|
|
method: 'API.getProcessedReport',
|
|
apiModule: 'MultiSites',
|
|
apiAction: 'getAll',
|
|
hideMetricsDoc: '1',
|
|
filter_limit: '-1',
|
|
showColumns: 'label,nb_visits,nb_pageviews,visits_evolution,pageviews_evolution,revenue_evolution,nb_actions,revenue',
|
|
enhanced: 1
|
|
}).then(function (response) {
|
|
model.updateWebsitesList(response);
|
|
}, onError)['finally'](function () {
|
|
model.isLoading = false;
|
|
|
|
if (refreshInterval && refreshInterval > 0) {
|
|
$timeout(function () {
|
|
model.fetchAllSites(refreshInterval);
|
|
}, refreshInterval * 1000);
|
|
}
|
|
});
|
|
};
|
|
|
|
return model;
|
|
});
|