Skip to content

Commit

Permalink
Merge pull request #135 from europeana/feat/MET-4471-Series-Label-for…
Browse files Browse the repository at this point in the history
…-Dates-and-Dataset

Generate human-readable labels for date range and dataset id
  • Loading branch information
andyjmaclean authored May 2, 2022
2 parents 094b65b + 64205d6 commit 0f74cdd
Show file tree
Hide file tree
Showing 7 changed files with 238 additions and 55 deletions.
12 changes: 10 additions & 2 deletions src/app/app.component.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
import { Location, PopStateEvent } from '@angular/common';
import { Component, HostListener, OnInit } from '@angular/core';
import {
Component,
HostListener,
Inject,
LOCALE_ID,
OnInit
} from '@angular/core';
import { FormBuilder, FormControl, FormGroup } from '@angular/forms';
import { ActivatedRoute, Params, Router } from '@angular/router';
import { SubscriptionManager } from './subscription-manager';
Expand Down Expand Up @@ -30,7 +36,8 @@ export class AppComponent extends SubscriptionManager implements OnInit {
private readonly clickService: ClickService,
private readonly route: ActivatedRoute,
private readonly router: Router,
private readonly location: Location
private readonly location: Location,
@Inject(LOCALE_ID) private readonly locale: string
) {
super();
document.title = 'Statistics Dashboard';
Expand Down Expand Up @@ -170,6 +177,7 @@ export class AppComponent extends SubscriptionManager implements OnInit {
}
}
} else {
component.locale = this.locale;
this.landingComponentRef = undefined;
this.showPageTitle = false;
}
Expand Down
1 change: 1 addition & 0 deletions src/app/ct-zero-control/ct-zero-control.component.scss
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
.filter-title {
margin-left: 8px;
white-space: nowrap;
}
143 changes: 136 additions & 7 deletions src/app/overview/overview.component.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { FormBuilder, FormControl, ReactiveFormsModule } from '@angular/forms';
import { MatDialog } from '@angular/material/dialog';
import { IsScrollableDirective } from '../_directives/is-scrollable';
import { nonFacetFilters, portalNames } from '../_data';
import { today } from '../_helpers';
import { today, yearZero } from '../_helpers';

import {
createMockPipe,
Expand Down Expand Up @@ -240,14 +240,26 @@ describe('OverviewComponent', () => {
});

it('should refresh the chart', fakeAsync(() => {
component.showAppliedSeriesInGridAndChart();
spyOn(component.barChart, 'drawChart');

component.refreshChart();
component.refreshChart(true);
component.refreshChart(false);
component.refreshChart(true, 1);
component.refreshChart(false, 1);

expect(component.barChart.drawChart).toHaveBeenCalledTimes(2);

// test invocation
spyOn(component, 'refreshChart');

component.showAppliedSeriesInGridAndChart();
component.form.controls.facetParameter.setValue(
DimensionName.contentTier
);
expect(component.refreshChart).not.toHaveBeenCalled();
fixture.detectChanges();
tick(400);
expect(component.refreshChart).toHaveBeenCalled();
expect(component.refreshChart).toHaveBeenCalledWith(true, 0);
component.ngOnDestroy();
}));

Expand All @@ -264,10 +276,88 @@ describe('OverviewComponent', () => {
expect(component.barChart.zoomTop).toHaveBeenCalled();
});

it('should get the applied date range', () => {
let range = component.getAppliedDateRange();

expect(range[0]).toEqual(yearZero);
expect(range[1]).toEqual(today);

component.form.get('dateTo').setValue(today);
component.form.get('dateFrom').setValue(today);

range = component.getAppliedDateRange();

expect(range[0]).toEqual(today);
expect(range[1]).toEqual(today);
});

it('should get the grid data', () => {
expect(component.getGridData()).toBeTruthy();
});

it('should generate the series label', fakeAsync(() => {
queryParams.next({});
tick(1);
fixture.detectChanges();

let generatedLabel;
component.form.controls.facetParameter.setValue(
DimensionName.contentTier
);
generatedLabel = component.generateSeriesLabel();
expect(generatedLabel).toEqual('All (Content Tier)');

component.form.controls.facetParameter.setValue(
DimensionName.rightsCategory
);
generatedLabel = component.generateSeriesLabel();
expect(generatedLabel).toEqual('All (Rights Category)');

const nextParams = {};
nextParams[DimensionName.country] = ['Denmark', 'Iceland'];
queryParams.next(nextParams);

tick(10);
fixture.detectChanges();

generatedLabel = component.generateSeriesLabel();
expect(generatedLabel.indexOf('Denmark')).toBeGreaterThan(-1);

nextParams['date-to'] = [today];
queryParams.next(nextParams);
tick(10);
fixture.detectChanges();

expect(component.generateSeriesLabel().indexOf('Period')).toEqual(-1);

nextParams['date-from'] = [yearZero];
queryParams.next(nextParams);
tick(10);
fixture.detectChanges();

expect(component.generateSeriesLabel().indexOf('Period')).toBeGreaterThan(
-1
);

nextParams['date-to'] = [];
queryParams.next(nextParams);
tick(10);
fixture.detectChanges();

expect(component.generateSeriesLabel().indexOf('Period')).toEqual(-1);
expect(
component.generateSeriesLabel().indexOf('content-tier-zero')
).toEqual(-1);
nextParams['content-tier-zero'] = 'true';
queryParams.next(nextParams);
tick(10);
fixture.detectChanges();

queryParams.next({});
tick(10);
component.ngOnDestroy();
}));

it('should extract the series server data', () => {
const br: BreakdownResult = {
results: [
Expand Down Expand Up @@ -346,11 +436,39 @@ describe('OverviewComponent', () => {
component.ngOnDestroy();
}));

it('should get the url for a dataset', () => {
it('should get the url for a dataset', fakeAsync(() => {
expect(component.getUrl().indexOf('XXX')).toEqual(-1);
component.form.get('datasetId').setValue('XXX');
expect(component.getUrl().indexOf('XXX')).toBeTruthy();
});
expect(component.getUrl().indexOf('XXX')).toBeGreaterThan(-1);
component.form.get('datasetId').setValue('');

queryParams.next({});
tick(10);
fixture.detectChanges();

const qp = {};
qp[DimensionName.rightsCategory] = ['CC0'];
qp[DimensionName.country] = ['Italy'];

queryParams.next(qp);
tick(10);
fixture.detectChanges();

const url = component.getUrl();

expect(url.indexOf('CC0')).toEqual(-1);
expect(url.indexOf('Italy')).toBeGreaterThan(-1);

queryParams.next({ xxx: '10-11-12' });
fixture.detectChanges();
tick(1);
expect(component.getUrl().indexOf('Italy')).toEqual(-1);

queryParams.next({});
fixture.detectChanges();
tick(1);
component.ngOnDestroy();
}));

it('should get the url for filters', () => {
const countryUrlParamVal = 'Belgium';
Expand Down Expand Up @@ -614,6 +732,16 @@ describe('OverviewComponent', () => {
).toBeGreaterThan(-1);
});

it('should add the series', () => {
spyOn(component.snapshots, 'apply').and.callFake(() => false);
spyOn(component, 'showAppliedSeriesInGridAndChart').and.callFake(
() => false
);
component.addSeries(['series-key']);
expect(component.showAppliedSeriesInGridAndChart).toHaveBeenCalled();
expect(component.snapshots.apply).toHaveBeenCalled();
});

it('should remove the series', () => {
spyOn(component.snapshots, 'unapply').and.callFake(() => false);
spyOn(component, 'showAppliedSeriesInGridAndChart').and.callFake(
Expand All @@ -635,6 +763,7 @@ describe('OverviewComponent', () => {
beforeEach(() => {
b4Each();
component.form.value.facetParameter = DimensionName.contentTier;
fixture.detectChanges();
});

it('should get the data server request', () => {
Expand Down
98 changes: 61 additions & 37 deletions src/app/overview/overview.component.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Component, OnInit, TemplateRef, ViewChild } from '@angular/core';
import { formatDate } from '@angular/common';
import { FormBuilder, FormControl, FormGroup } from '@angular/forms';
import { MatDialog } from '@angular/material/dialog';
import { ActivatedRoute, Params, Router } from '@angular/router';
Expand Down Expand Up @@ -108,6 +109,7 @@ export class OverviewComponent extends SubscriptionManager implements OnInit {
disabledParams: IHashArray<string>;
form: FormGroup;
isLoading = true;
locale = 'en-GB';

selFacetIndex = 0;
resultTotal: number;
Expand Down Expand Up @@ -497,13 +499,6 @@ export class OverviewComponent extends SubscriptionManager implements OnInit {
this.filterStates.dates = { visible: false, disabled: false };
}

seriesNameFromUrl(): string {
return JSON.stringify(this.queryParams).replace(
/[:\".,\s\(\)\[\]\{\}]/g,
''
);
}

iHashNumberFromNVPs(
src: Array<NamesValuePercent>,
percent = false
Expand Down Expand Up @@ -537,6 +532,60 @@ export class OverviewComponent extends SubscriptionManager implements OnInit {
return result;
}

/** generateSeriesLabel
/* Generates a human readable label for the current series
**/
generateSeriesLabel(): string {
if (Object.keys(this.queryParams).length === 0) {
const friendlyName = portalNamesFriendly[this.form.value.facetParameter];
return $localize`:@@snapshotTitleAll:All (${friendlyName})`;
}

const snapshotTitleOr = $localize`:@@snapshotTitleOr:or`;
const snapshotTitleAnd = $localize`:@@snapshotTitleAnd:and`;

return Object.keys(this.queryParams)
.map((key: string) => {
const values = this.queryParamsRaw[key];
if (values.length === 0) {
return '';
} else if (key === 'content-tier-zero') {
return $localize`:@@snapshotTitleCTZero:CT-Zero`;
} else if (key === 'date-from') {
// return both dates, formatted and localised
const dateToValues = this.queryParamsRaw['date-to'];
if (dateToValues.length === 0) {
return '';
}
const fmt = 'MMM d, y';
const label = $localize`:@@snapshotTitlePeriod:Period`;
const dateFrom = formatDate(new Date(values[0]), fmt, this.locale);
const dateTo = formatDate(
new Date(dateToValues[0]),
fmt,
this.locale
);
return `${label} (${dateFrom} - ${dateTo})`;
} else if (key === 'date-to') {
// this is handled together with "date-from"
return '';
} else if (key === 'dataset-id') {
const label = $localize`:@@snapshotTitleDatasetId:Dataset Id`;
return `${label} (${values[0]})`;
} else {
const innerRes = [];
this.queryParamsRaw[key].forEach((valPart: string) => {
innerRes.push(valPart);
});
const friendlyKey = portalNamesFriendly[key];
const joinedVals = innerRes.join(` ${snapshotTitleOr} `);
return `${friendlyKey} (${joinedVals})`;
}
})
.filter((x) => x.length > 0)
.join(` ${snapshotTitleAnd} `);
}

/** storeSeries
/*
/* Store series data
Expand All @@ -547,43 +596,18 @@ export class OverviewComponent extends SubscriptionManager implements OnInit {
nvs: Array<NamesValuePercent>,
seriesTotal: number
): void {
const friendlyName = portalNamesFriendly[this.form.value.facetParameter];
let label = $localize`:@@snapshotTitleAll:All (${friendlyName})`;

// Generate human-readable label
if (Object.keys(this.queryParams).length > 0) {
label = Object.keys(this.queryParams)
.map((key: string) => {
if (key === 'content-tier-zero') {
return $localize`:@@snapshotTitleCTZero:CT-Zero`;
}

const innerRes = [];
if (!Object.values(nonFacetFilters).includes(key)) {
this.queryParamsRaw[key].forEach((valPart: string) => {
innerRes.push(valPart);
});

const friendlyKey = portalNamesFriendly[key];
return `${friendlyKey} (${innerRes.join(
$localize`:@@snapshotTitleOr: or `
)})`;
}
return '';
})
.filter((x) => x.length > 0)
.join($localize`:@@snapshotTitleAnd: and `);
}

const name = this.seriesNameFromUrl();
const name = JSON.stringify(this.queryParams).replace(
/[:\".,\s\(\)\[\]\{\}]/g,
''
);
const rightsInfo = this.form.value.rightsCategory;
const rightsFilters = Object.keys(rightsInfo).filter((key: string) => {
return rightsInfo[key];
});

this.snapshots.snap(this.form.value.facetParameter, name, {
name: name,
label: label,
label: this.generateSeriesLabel(),
data: this.iHashNumberFromNVPs(nvs),
dataPercent: this.iHashNumberFromNVPs(nvs, true),
orderOriginal: [],
Expand Down
Loading

0 comments on commit 0f74cdd

Please sign in to comment.