Skip to content

Commit 7f87b2b

Browse files
author
Andrea Barbasso
committed
[DSC-2050] use queryParam for item reports
1 parent b9c2c2b commit 7f87b2b

7 files changed

Lines changed: 189 additions & 9 deletions

File tree

src/app/shared/metric/metric-embedded/metric-embedded-download/metric-embedded-download.component.spec.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { TranslateLoaderMock } from '../../../mocks/translate-loader.mock';
66
import {
77
metricEmbeddedDownload
88
} from '../../../../cris-layout/cris-layout-matrix/cris-layout-box-container/boxes/metrics/cris-layout-metrics-box.component.spec';
9+
import { Metric } from '../../../../core/shared/metric.model';
910

1011
describe('MetricEmbeddedDownloadComponent', () => {
1112
let component: MetricEmbeddedDownloadComponent;
@@ -34,4 +35,25 @@ describe('MetricEmbeddedDownloadComponent', () => {
3435
it('should create', () => {
3536
expect(component).toBeTruthy();
3637
});
38+
39+
it('should append reportType to href if href is defined and does not contain query parameters', () => {
40+
component.href = 'http://example.com';
41+
component.metric = {} as Metric;
42+
component.ngOnInit();
43+
expect(component.href).toBe('http://example.com?reportType=TotalDownloads');
44+
});
45+
46+
it('should append reportType to href if href is defined and contains query parameters', () => {
47+
component.href = 'http://example.com?param=value';
48+
component.metric = {} as Metric;
49+
component.ngOnInit();
50+
expect(component.href).toBe('http://example.com?param=value&reportType=TotalDownloads');
51+
});
52+
53+
it('should not modify href if href is not defined', () => {
54+
component.href = undefined;
55+
component.metric = {} as Metric;
56+
component.ngOnInit();
57+
expect(component.href).toBeUndefined();
58+
});
3759
});
Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,23 @@
1-
import { Component, Renderer2 } from '@angular/core';
1+
import { Component, OnInit, Renderer2 } from '@angular/core';
22
import { BaseEmbeddedHtmlMetricComponent } from '../base-embedded-html-metric.component';
33

4+
export const METRIC_TYPE_DOWNLOAD = 'TotalDownloads';
45
@Component({
56
selector: 'ds-metric-embedded-download',
67
templateUrl: './metric-embedded-download.component.html',
78
styleUrls: ['./metric-embedded-download.component.scss', '../../metric-loader/base-metric.component.scss']
89
})
9-
export class MetricEmbeddedDownloadComponent extends BaseEmbeddedHtmlMetricComponent {
10+
export class MetricEmbeddedDownloadComponent extends BaseEmbeddedHtmlMetricComponent implements OnInit {
1011

1112
constructor(protected render: Renderer2) {
1213
super(render);
1314
}
1415

16+
ngOnInit() {
17+
super.ngOnInit();
18+
if (this.href) {
19+
this.href += (this.href.includes('?') ? '&' : '?') + 'reportType=' + METRIC_TYPE_DOWNLOAD;
20+
}
21+
}
22+
1523
}

src/app/statistics-page/cris-statistics-page/cris-statistics-page.component.spec.ts

Lines changed: 69 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { ActivatedRoute } from '@angular/router';
44
import { DebugElement, NO_ERRORS_SCHEMA } from '@angular/core';
55
import { By } from '@angular/platform-browser';
66

7-
import { of as observableOf } from 'rxjs';
7+
import { of, of as observableOf } from 'rxjs';
88
import { TranslateLoader, TranslateModule } from '@ngx-translate/core';
99

1010
import { CrisStatisticsPageComponent } from './cris-statistics-page.component';
@@ -23,6 +23,7 @@ import { TranslateLoaderMock } from '../../shared/mocks/translate-loader.mock';
2323

2424
import { provideMockStore } from '@ngrx/store/testing';
2525
import { StatisticsState } from '../../core/statistics/statistics.reducer';
26+
import { UsageReport } from '../../core/statistics/models/usage-report.model';
2627

2728
describe('CrisStatisticsPageComponent', () => {
2829

@@ -141,4 +142,71 @@ describe('CrisStatisticsPageComponent', () => {
141142
fixture.detectChanges();
142143
});
143144

145+
it('should set selectedReportId to the first report id if no reportType query param is present', () => {
146+
const category = { id: 'category1' };
147+
const reports = [{ id: 'report1', reportType: 'type1' }, { id: 'report2', reportType: 'type2' }];
148+
spyOn(component, 'getReports$').and.returnValue(of(reports as UsageReport[]));
149+
spyOn(component, 'getReportId').and.returnValue(of(null));
150+
spyOn(component, 'getCategoryId').and.returnValue(of(null));
151+
spyOn(component, 'setStatisticsState');
152+
153+
component.getUserReports(category);
154+
155+
expect(component.setStatisticsState).toHaveBeenCalledWith('report1', 'category1');
156+
expect(component.selectedReportId).toBe('report1');
157+
});
158+
159+
it('should set selectedReportId to the report id matching the reportType query param', () => {
160+
const category = { id: 'category1' };
161+
const reports = [{ id: 'report1', reportType: 'type1' }, { id: 'report2', reportType: 'type2' }];
162+
spyOn(component, 'getReports$').and.returnValue(of(reports as UsageReport[]));
163+
spyOn(component, 'getReportId').and.returnValue(of(null));
164+
spyOn(component, 'getCategoryId').and.returnValue(of(null));
165+
spyOn(component, 'setStatisticsState');
166+
167+
component.getUserReports(category, 'type2');
168+
169+
expect(component.setStatisticsState).toHaveBeenCalledWith('report2', 'category1');
170+
expect(component.selectedReportId).toBe('report2');
171+
});
172+
173+
it('should set selectedReportId to the first report id if reportType query param does not match any report', () => {
174+
const category = { id: 'category1' };
175+
const reports = [{ id: 'report1', reportType: 'type1' }, { id: 'report2', reportType: 'type2' }];
176+
spyOn(component, 'getReports$').and.returnValue(of(reports as UsageReport[]));
177+
spyOn(component, 'getReportId').and.returnValue(of(null));
178+
spyOn(component, 'getCategoryId').and.returnValue(of(null));
179+
spyOn(component, 'setStatisticsState');
180+
181+
component.getUserReports(category, 'non_existing_type');
182+
183+
expect(component.setStatisticsState).toHaveBeenCalledWith('report1', 'category1');
184+
expect(component.selectedReportId).toBe('report1');
185+
});
186+
187+
it('should set selectedReportId and categoryId from state if they exist', () => {
188+
const category = { id: 'category1' };
189+
const reports = [{ id: 'report1', reportType: 'type1' }, { id: 'report2', reportType: 'type2' }];
190+
spyOn(component, 'getReports$').and.returnValue(of(reports as UsageReport[]));
191+
spyOn(component, 'getReportId').and.returnValue(of('report1'));
192+
spyOn(component, 'getCategoryId').and.returnValue(of('category1'));
193+
spyOn(component, 'setStatisticsState');
194+
195+
component.getUserReports(category);
196+
197+
expect(component.setStatisticsState).toHaveBeenCalledWith('report1', 'category1');
198+
});
199+
200+
it('should handle null category gracefully', () => {
201+
spyOn(component, 'getReports$').and.returnValue(of([]));
202+
spyOn(component, 'getReportId').and.returnValue(of(null));
203+
spyOn(component, 'getCategoryId').and.returnValue(of(null));
204+
spyOn(component, 'setStatisticsState');
205+
206+
component.getUserReports(null);
207+
208+
expect(component.setStatisticsState).not.toHaveBeenCalled();
209+
expect(component.selectedReportId).toBeUndefined();
210+
});
211+
144212
});

src/app/statistics-page/cris-statistics-page/cris-statistics-page.component.ts

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -178,8 +178,9 @@ export class CrisStatisticsPageComponent implements OnInit, OnDestroy {
178178
/**
179179
* Get the user reports for the specific category.
180180
* @param category the that is being selected
181+
* @param reportType
181182
*/
182-
getUserReports(category) {
183+
getUserReports(category, reportType = this.route?.snapshot?.queryParams?.reportType) {
183184
this.reports$ =
184185
of(category)
185186
.pipe(
@@ -189,8 +190,15 @@ export class CrisStatisticsPageComponent implements OnInit, OnDestroy {
189190
this.reports$, this.getReportId(), this.getCategoryId()
190191
]).subscribe(([report, reportId, categoryId]) => {
191192
if (!reportId && !categoryId) {
192-
this.setStatisticsState(report[0].id, category.id);
193-
this.selectedReportId = report[0].id;
193+
let reportToShowId = report[0].id;
194+
if (reportType) {
195+
const newReport = report.find((r) => r.reportType === reportType)?.id;
196+
if (newReport) {
197+
reportToShowId = newReport;
198+
}
199+
}
200+
this.setStatisticsState(reportToShowId, category.id);
201+
this.selectedReportId = reportToShowId;
194202
} else {
195203
this.setStatisticsState(reportId, categoryId);
196204
}

src/app/statistics-page/cris-statistics-page/statistics-chart/statistics-chart.component.html

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ <h2>{{'statistics.reports.title' | translate}}</h2>
1010
<ul class="nav nav-pills mb-2">
1111
<li class="nav-item mr-3" *ngFor="let report of (reports | dsFilterMap : false)">
1212
<a class="nav-link" [ngClass]="{'active' : !!selectedReport && selectedReport.id == report.id}"
13-
routerLink="./" (click)="$event.preventDefault();changeReport(report)">
13+
href="#"
14+
(click)="$event.preventDefault();$event.stopPropagation();changeReport(report)">
1415
{{'statistics.table.' + categoryType + '.title.' + report.reportType | translate}}
1516
</a>
1617
</li>

src/app/statistics-page/cris-statistics-page/statistics-chart/statistics-chart.component.spec.ts

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -189,10 +189,67 @@ describe('StatisticsChartComponent', () => {
189189
expect(de.query(By.css('.container'))).toBeNull();
190190
});
191191

192-
it('after reports check if container of pills are truthly', () => {
192+
it('after reports check if container of pills are truthy', () => {
193193
component.reports = reports;
194194
fixture.detectChanges();
195195
expect(de.query(By.css('.container'))).toBeTruthy();
196196
});
197197

198+
it('should set selectedReport to the report matching selectedReportId', () => {
199+
component.reports = reports;
200+
component.selectedReportId = '1911e8a4-6939-490c-b58b-a5d70f8d91fb_TotalVisits';
201+
component.ngOnInit();
202+
expect(component.selectedReport.id).toBe('1911e8a4-6939-490c-b58b-a5d70f8d91fb_TotalVisits');
203+
});
204+
205+
it('should set selectedReport to the first report if selectedReportId does not match any report', () => {
206+
component.reports = reports;
207+
component.selectedReportId = 'non_existing_id';
208+
component.ngOnInit();
209+
expect(component.selectedReport.id).toBe('1911e8a4-6939-490c-b58b-a5d70f8d91fb_TotalVisits');
210+
});
211+
212+
it('should emit changeReportEvent with the first report id if selectedReportId does not match any report', () => {
213+
spyOn(component.changeReportEvent, 'emit');
214+
component.reports = reports;
215+
component.selectedReportId = 'non_existing_id';
216+
component.ngOnInit();
217+
expect(component.changeReportEvent.emit).toHaveBeenCalledWith('1911e8a4-6939-490c-b58b-a5d70f8d91fb_TotalVisits');
218+
});
219+
220+
it('should call addQueryParams with the reportType of the selected report', () => {
221+
spyOn(component, 'addQueryParams');
222+
component.reports = reports;
223+
component.selectedReportId = '1911e8a4-6939-490c-b58b-a5d70f8d91fb_TotalVisits';
224+
component.ngOnInit();
225+
expect(component.addQueryParams).toHaveBeenCalledWith('TotalVisits');
226+
});
227+
228+
it('should not set selectedReport if reports is undefined', () => {
229+
component.reports = undefined;
230+
component.ngOnInit();
231+
expect(component.selectedReport).toBeUndefined();
232+
});
233+
234+
it('should not set selectedReport if reports is empty', () => {
235+
component.reports = [];
236+
component.ngOnInit();
237+
expect(component.selectedReport).toBeUndefined();
238+
});
239+
240+
it('should update selectedReport and emit changeReportEvent on changeReport', () => {
241+
spyOn(component.changeReportEvent, 'emit');
242+
const newReport = reports[1];
243+
component.changeReport(newReport);
244+
expect(component.selectedReport).toBe(newReport);
245+
expect(component.changeReportEvent.emit).toHaveBeenCalledWith(newReport.id);
246+
});
247+
248+
it('should call addQueryParams with the reportType of the new report on changeReport', () => {
249+
spyOn(component, 'addQueryParams');
250+
const newReport = reports[1];
251+
component.changeReport(newReport);
252+
expect(component.addQueryParams).toHaveBeenCalledWith(newReport.reportType);
253+
});
254+
198255
});

src/app/statistics-page/cris-statistics-page/statistics-chart/statistics-chart.component.ts

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1-
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
1+
import { Component, EventEmitter, inject, Input, OnInit, Output } from '@angular/core';
22

33
import { UsageReport } from '../../../core/statistics/models/usage-report.model';
44
import { StatisticsCategory } from '../../../core/statistics/models/statistics-category.model';
5+
import { ActivatedRoute, Router } from '@angular/router';
6+
import { Location } from '@angular/common';
57

68
@Component({
79
selector: 'ds-statistics-chart',
@@ -44,6 +46,10 @@ export class StatisticsChartComponent implements OnInit {
4446
*/
4547
@Output() changeReportEvent = new EventEmitter<string>();
4648

49+
router = inject(Router);
50+
activatedRoute = inject(ActivatedRoute);
51+
location = inject(Location);
52+
4753
/**
4854
* Requests the current set values for this chart
4955
* If the chart config is open by default OR the chart has at least one value, the chart should be initially expanded
@@ -58,6 +64,7 @@ export class StatisticsChartComponent implements OnInit {
5864
this.selectedReport = this.reports[0];
5965
this.changeReportEvent.emit(this.reports[0].id);
6066
}
67+
this.addQueryParams(this.selectedReport.reportType);
6168
}
6269
}
6370

@@ -68,6 +75,15 @@ export class StatisticsChartComponent implements OnInit {
6875
changeReport(report) {
6976
this.selectedReport = report;
7077
this.changeReportEvent.emit(report.id);
78+
this.addQueryParams(report.reportType);
79+
}
80+
81+
addQueryParams(reportType: string) {
82+
this.location.go(this.router.createUrlTree([], {
83+
queryParams: { reportType },
84+
queryParamsHandling: 'merge',
85+
relativeTo: this.activatedRoute
86+
}).toString());
7187
}
7288

7389
}

0 commit comments

Comments
 (0)