Skip to content

Commit

Permalink
manager: smoother reports exports (fixes #7605) (#7606)
Browse files Browse the repository at this point in the history
Co-authored-by: dogi <[email protected]>
  • Loading branch information
Mutugiii and dogi authored Oct 17, 2024
1 parent e3cdb94 commit be9a229
Show file tree
Hide file tree
Showing 3 changed files with 115 additions and 21 deletions.
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
{
"name": "planet",
"license": "AGPL-3.0",
"version": "0.14.91",
"version": "0.14.92",
"myplanet": {
"latest": "v0.20.38",
"min": "v0.19.38"
"latest": "v0.20.42",
"min": "v0.19.42"
},
"scripts": {
"ng": "ng",
Expand Down
91 changes: 73 additions & 18 deletions src/app/manager-dashboard/reports/reports-detail.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { CouchService } from '../../shared/couchdb.service';
import { CustomValidators } from '../../validators/custom-validators';
import {
attachNamesToPlanets, filterByDate, setMonths, activityParams, codeToPlanetName, reportsDetailParams, xyChartData, datasetObject,
titleOfChartName, monthDataLabels, filterByMember
titleOfChartName, monthDataLabels, filterByMember, sortingOptionsMap
} from './reports.utils';
import { MatDialog } from '@angular/material/dialog';
import { DialogsResourcesViewerComponent } from '../../shared/dialogs/dialogs-resources-viewer.component';
Expand Down Expand Up @@ -362,55 +362,107 @@ export class ReportsDetailComponent implements OnInit, OnDestroy {
{ 'placeholder': $localize`To`, 'name': 'endDate', ...commonProps }
];
const teamField = { 'placeholder': $localize`Team`, 'name': 'team', 'options': teamOptions, 'type': 'selectbox' };
const fields = [ ...commonFields, ...(reportType === 'health' ? [] : [ teamField ]) ];
const sortingOptions = sortingOptionsMap[reportType];
const fields = [
...commonFields,
...(reportType === 'health' ? [] : [ teamField ]),
...(sortingOptions && sortingOptions.length > 0
? [ { 'placeholder': $localize`Sort By`, 'name': 'sortBy', 'options': sortingOptions, 'type': 'selectbox' } ]
: [])
];
const formGroup = {
startDate: this.dateFilterForm.controls.startDate.value,
endDate: [ this.dateFilterForm.controls.endDate.value, CustomValidators.endDateValidator() ],
team: reportType === 'health' ? 'All' : this.selectedTeam
team: reportType === 'health' ? 'All' : this.selectedTeam,
sortBy: sortingOptions && sortingOptions.length > 0 ? sortingOptions[0].value : null
};
this.dialogsFormService.openDialogsForm($localize`Select Date Range for Data Export`, fields, formGroup, {
onSubmit: (formValue: any) => {
this.getTeamMembers(formValue.team).subscribe(members => {
this.exportCSV(reportType, { startDate: formValue.startDate, endDate: formValue.endDate }, members);
this.exportCSV(reportType, { startDate: formValue.startDate, endDate: formValue.endDate }, members, formValue.sortBy);
});
}
});
}

exportCSV(reportType: string, dateRange: { startDate: Date, endDate: Date }, members: any[]) {
sortData(data: any[], sortBy: string): any[] {
const order = sortBy.endsWith('Asc') ? 1 : -1;
let field = sortBy.replace(/Asc|Desc/, '');
if (field === 'username') { field = 'user'; }
return data.sort((a, b) => {
let comparison = 0;
if ([ 'loginTime', 'logoutTime', 'time' ].includes(field)) {
const dateA = new Date(a[field]).getTime();
const dateB = new Date(b[field]).getTime();
comparison = dateA - dateB;
} else {
comparison = a[field].localeCompare(b[field]);
}
return comparison * order;
});
}

exportCSV(reportType: string, dateRange: { startDate: Date, endDate: Date }, members: any[], sortBy: string) {
switch (reportType) {
case 'logins':
this.csvService.exportCSV({
data: filterByMember(filterByDate(this.loginActivities.data, 'loginTime', dateRange), members)
let data = filterByMember(filterByDate(this.loginActivities.data, 'loginTime', dateRange), members)
.map(activity => ({
...activity,
androidId: activity.androidId || '',
deviceName: activity.deviceName || '',
customDeviceName: activity.customDeviceName || ''
})),
}));
if (sortBy) {
data = this.sortData(data, sortBy);
}
this.csvService.exportCSV({
data: data,
title: $localize`Member Visits`
});
break;
case 'resourceViews':
case 'courseViews':
case 'stepCompletions':
case 'health':
this.exportDocView(reportType, dateRange, members);
this.exportDocView(reportType, dateRange, members, sortBy);
break;
case 'summary':
this.exportSummary(dateRange, members);
this.exportSummary(dateRange, members, sortBy);
break;
case 'health':
this.exportDocView(reportType, dateRange, members, null);
break;
}
this.dialogsFormService.closeDialogsForm();
this.dialogsLoadingService.stop();
}

exportSummary(dateRange, members) {
exportSummary(dateRange: any, members: any[], sortBy: string) {
const loginData = filterByMember(filterByDate(this.loginActivities?.data, 'loginTime', dateRange), members);
const resourceData = filterByMember(filterByDate(this.resourceActivities?.total?.data, 'time', dateRange), members);
const courseData = filterByMember(filterByDate(this.courseActivities?.total?.data, 'time', dateRange), members);
const progressData = filterByMember(filterByDate(this.progress?.steps?.data, 'time', dateRange), members);

if (sortBy) {
const order = sortBy.endsWith('Asc') ? 1 : -1;
const sortFunction = (a, b) => {
const aDate = new Date(a.time || a.loginTime);
const bDate = new Date(b.time || b.loginTime);
const comparison =
(aDate.getFullYear() - bDate.getFullYear()) ||
(aDate.getMonth() - bDate.getMonth());
return comparison * order;
};
loginData.sort(sortFunction);
resourceData.sort(sortFunction);
courseData.sort(sortFunction);
progressData.sort(sortFunction);
}

this.csvService.exportSummaryCSV(
filterByMember(filterByDate(this.loginActivities.data, 'loginTime', dateRange), members),
filterByMember(filterByDate(this.resourceActivities.total.data, 'time', dateRange), members),
filterByMember(filterByDate(this.courseActivities.total.data, 'time', dateRange), members),
filterByMember(filterByDate(this.progress.steps.data, 'time', dateRange), members),
loginData,
resourceData,
courseData,
progressData,
this.planetName
);
}
Expand All @@ -425,8 +477,8 @@ export class ReportsDetailComponent implements OnInit, OnDestroy {
});
}

exportDocView(reportType, dateRange, members) {
const data = {
exportDocView(reportType: string, dateRange: any, members: any[], sortBy: string) {
let data = {
'resourceViews': this.resourceActivities.total.data,
'courseViews': this.courseActivities.total.data,
'stepCompletions': this.progress.steps.data,
Expand All @@ -437,6 +489,9 @@ export class ReportsDetailComponent implements OnInit, OnDestroy {
'courseViews': $localize`Course Views`,
'health': $localize`Community Health`,
'stepCompletions': $localize`Courses Progress` }[reportType];
if (sortBy) {
data = this.sortData(data, sortBy);
}
this.csvService.exportCSV({
data: this.activityService.appendAge(
filterByMember(filterByDate(data, reportType === 'health' ? 'date' : 'time', dateRange), members), this.today)
Expand Down
39 changes: 39 additions & 0 deletions src/app/manager-dashboard/reports/reports.utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,3 +102,42 @@ export const generateWeeksArray = (dateRange: { startDate: Date, endDate: Date }
export const scaleLabel = (labelString: string) => ({
display: true, labelString, fontSize: 12, fontStyle: 'bold'
});

export const sortingOptionsMap = {
'logins': [
{ name: $localize`Login Time Ascending`, value: 'loginTimeAsc' },
{ name: $localize`Login Time Descending`, value: 'loginTimeDesc' },
{ name: $localize`Logout Time Ascending`, value: 'logoutTimeAsc' },
{ name: $localize`Logout Time Descending`, value: 'logoutTimeDesc' },
{ name: $localize`User Ascending`, value: 'userAsc' },
{ name: $localize`User Descending`, value: 'userDesc' },
],
'resourceViews': [
{ name: $localize`Username Ascending`, value: 'userAsc' },
{ name: $localize`Username Descending`, value: 'userDesc' },
{ name: $localize`Time Ascending`, value: 'timeAsc' },
{ name: $localize`Time Descending`, value: 'timeDesc' },
{ name: $localize`Title Ascending`, value: 'titleAsc' },
{ name: $localize`Title Descending`, value: 'titleDesc' },
],
'courseViews': [
{ name: $localize`Username Ascending`, value: 'userAsc' },
{ name: $localize`Username Descending`, value: 'userDesc' },
{ name: $localize`Time Ascending`, value: 'timeAsc' },
{ name: $localize`Time Descending`, value: 'timeDesc' },
{ name: $localize`Title Ascending`, value: 'titleAsc' },
{ name: $localize`Title Descending`, value: 'titleDesc' },
],
'stepCompletions': [
{ name: $localize`Username Ascending`, value: 'userAsc' },
{ name: $localize`Username Descending`, value: 'userDesc' },
{ name: $localize`Time Ascending`, value: 'timeAsc' },
{ name: $localize`Time Descending`, value: 'timeDesc' },
{ name: $localize`Title Ascending`, value: 'titleAsc' },
{ name: $localize`Title Descending`, value: 'titleDesc' },
],
'summary': [
{ name: $localize`Month/Year Ascending`, value: 'monthYearAsc' },
{ name: $localize`Month/Year Descending`, value: 'monthYearDesc' },
],
};

0 comments on commit be9a229

Please sign in to comment.