Skip to content

Commit

Permalink
aggregation: add possibility to reorder aggregation and limit size
Browse files Browse the repository at this point in the history
* Adds reorder aggregation.
* Adds aggregation expand or limit element with more or less link

Co-Authored-by: Bertrand Zuchuat <bertrand.zuchuat@rero.ch>
  • Loading branch information
Garfield-fr authored and Sébastien Délèze committed Nov 29, 2019
1 parent a1b8816 commit bf7d607
Show file tree
Hide file tree
Showing 13 changed files with 187 additions and 39 deletions.
29 changes: 25 additions & 4 deletions projects/ng-core-tester/src/app/app-routing.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,12 @@ export function institutionsMatcher(url: Array<UrlSegment>) {
return null;
}

const aggrDocumentOrder = ['document_type', 'author', 'library', 'organisation', 'language', 'subject', 'status'];

const aggrDocumentExpand = ['document_type'];

const aggrBucketSize = 5;

const routes: Routes = [
{
path: '',
Expand All @@ -95,7 +101,10 @@ const routes: Routes = [
{
key: 'documents',
label: 'Documents',
component: DocumentComponent
component: DocumentComponent,
aggregationsOrder: aggrDocumentOrder,
aggregationsExpand: aggrDocumentExpand,
aggregationsBucketSize: aggrBucketSize
}
]
}
Expand Down Expand Up @@ -127,7 +136,10 @@ const routes: Routes = [
component: DocumentComponent,
preFilters: {
institution: 'usi'
}
},
aggregationsOrder: aggrDocumentOrder,
aggregationsExpand: aggrDocumentExpand,
// aggregationsBucketSize: aggrBucketSize
}
]
}
Expand All @@ -145,7 +157,10 @@ const routes: Routes = [
component: DocumentComponent,
preFilters: {
institution: 'hevs'
}
},
aggregationsOrder: aggrDocumentOrder,
aggregationsExpand: aggrDocumentExpand,
// aggregationsBucketSize: aggrBucketSize
}
]
}
Expand All @@ -163,7 +178,10 @@ const routes: Routes = [
{
key: 'documents',
label: 'Documents',
component: DocumentComponent
component: DocumentComponent,
aggregationsOrder: aggrDocumentOrder,
aggregationsExpand: aggrDocumentExpand,
aggregationsBucketSize: aggrBucketSize
}
]
}
Expand All @@ -183,6 +201,9 @@ const routes: Routes = [
canDelete,
canRead,
aggregations,
aggregationsOrder: aggrDocumentOrder,
aggregationsExpand: aggrDocumentExpand,
// aggregationsBucketSize: aggrBucketSize,
listHeaders: {
'Content-Type': 'application/rero+json'
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ <h5 class="mb-0">
<div class="collapse" [class.show]="showAggregation()">
<div class="card-body">
<ul class="list-unstyled m-0">
<li class="form-check" *ngFor="let bucket of aggregation.value.buckets">
<li class="form-check" *ngFor="let bucket of aggregation.value.buckets|slice:0:bucketSize">
<input class="form-check-input" type="checkbox" [checked]="isSelected(bucket.key)"
(click)="updateFilter(bucket.key) ">
<label class="form-check-label">
Expand All @@ -35,6 +35,10 @@ <h5 class="mb-0">
</label>
</li>
</ul>
<div *ngIf="displayMoreAndLessLink()">
<button class="btn btn-link ml-2" *ngIf="moreMode" (click)="setMoreMode(false)" translate>more…</button>
<button class="btn btn-link ml-2" *ngIf="!moreMode" (click)="setMoreMode(true)" translate>less…</button>
</div>
</div>
</div>
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ describe('RecordSearchAggregationComponent', () => {
component = fixture.componentInstance;
component.aggregation = {
key: 'author',
bucketSize: 2,
value: {
buckets: [
{
Expand Down Expand Up @@ -87,4 +88,24 @@ describe('RecordSearchAggregationComponent', () => {
component.updateFilter('Filippini, Massimo');
expect(component.selectedValues.includes('Filippini, Massimo')).toBe(false);
});

it('should return a correct bucket size', () => {
component.aggregation.bucketSize = null;
expect(component.bucketSize).toBe(2);

component.aggregation.bucketSize = 1;
expect(component.bucketSize).toBe(1);

component.moreMode = false;
component.aggregation.bucketSize = 1;
expect(component.bucketSize).toBe(2);
});

it('should display link', () => {
component.aggregation.bucketSize = 1;
expect(component.displayMoreAndLessLink).toBeTruthy();

component.aggregation.bucketSize = 5;
expect(component.displayMoreAndLessLink).toBeTruthy();
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ export class RecordSearchAggregationComponent {
* Aggregation data
*/
@Input()
public aggregation: { key: string, value: { buckets: {}[] } };
public aggregation: { key: string, bucketSize: any, value: { buckets: {}[] } };

/**
* Selected value for filter
Expand All @@ -46,6 +46,11 @@ export class RecordSearchAggregationComponent {
@Output()
public updateAggregationFilter = new EventEmitter<{ term: string, values: string[] }>();

/**
* More and less on aggregation content (facet)
*/
moreMode = true;

/**
* Constructor
* @param translate TranslateService
Expand Down Expand Up @@ -81,10 +86,44 @@ export class RecordSearchAggregationComponent {
this.updateAggregationFilter.emit({ term: this.aggregation.key, values: this.selectedValues });
}

/**
* Return bucket size
*/
get bucketSize() {
const aggregationBucketSize = this.aggregation.value.buckets.length;
if (this.aggregation.bucketSize === null) {
return aggregationBucketSize;
} else {
if (this.moreMode) {
return this.aggregation.bucketSize;
} else {
return aggregationBucketSize;
}
}
}

/**
* Show filter values
* @return boolean
*/
showAggregation() {
return this.expand || this.selectedValues.length > 0;
}

/**
* Display more or less link
* @return boolean
*/
displayMoreAndLessLink(): boolean {
return this.aggregation.value.buckets.length > this.aggregation.bucketSize;
}

/**
* Set More mode
* @param state - boolean
* @return void
*/
setMoreMode(state: boolean) {
this.moreMode = state;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,12 @@ export class RecordSearchComponent implements OnInit {
canUpdate?: any,
canDelete?: any,
canRead?: any,
aggregations?: any
aggregations?: any,
listHeaders?: any,
itemHeaders?: any,
aggregationsOrder?: Array<string>,
aggregationsExpand?: Array<string>,
aggregationsBucketSize?: number
}[] = [{ key: 'documents', label: 'Documents' }];

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,8 @@
</div>
</div>
<div class="row">
<div class="col-sm-3" *ngIf="total && aggregations && (aggregations | keyvalue).length">
<div *ngFor="let item of aggregations | keyvalue">
<div class="col-sm-3" *ngIf="total && aggregations && aggregations.length">
<div *ngFor="let item of aggregations">
<ng-core-record-search-aggregation [aggregation]="item"
[selectedValues]="getFilterSelectedValues(item.key)" [expand]="expandFacet(item.key)"
(updateAggregationFilter)="updateAggregationFilter($event)">
Expand Down Expand Up @@ -83,4 +83,4 @@
<i class="fa fa-spin fa-spinner fa-2x"></i>
</div>
</ng-template>
</ng-template>
</ng-template>
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,11 @@ describe('RecordSearchComponent', () => {
queryParams: of({})
};

const aggregations = {
author: { buckets: []},
language: { buckets: []}
};

beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [
Expand Down Expand Up @@ -307,4 +312,25 @@ describe('RecordSearchComponent', () => {
});
}));

it('should reorder aggregations', async(() => {
component.currentType = 'documents';
const result = [
{ key: 'author', bucketSize: null, value: { buckets: [] }},
{ key: 'language', bucketSize: null, value: { buckets: [] }},
];
expect(component.aggregationsOrder(aggregations)).toEqual(result);

const resultOrder = [
{ key: 'language', bucketSize: null, value: { buckets: [] }},
{ key: 'author', bucketSize: null, value: { buckets: [] }},
];
recordUiServiceSpy.getResourceConfig.and.returnValue({ key: 'documents', aggregationsOrder: ['language', 'author'] });
expect(component.aggregationsOrder(aggregations)).toEqual(resultOrder);
}));

it('should expand aggregation', async(() => {
recordUiServiceSpy.getResourceConfig.and.returnValue({ key: 'documents', aggregationsExpand: ['language'] });
expect(component.expandFacet('language')).toBeTruthy();
expect(component.expandFacet('author')).toBeFalsy();
}));
});
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ export class RecordSearchComponent implements OnInit, OnChanges {
/**
* Facets retreived from request result
*/
aggregations: { [key: string]: object } = {};
aggregations: Array<{key: string, bucketSize: any, value: {buckets: []}}>;

/**
* Search is processing
Expand Down Expand Up @@ -123,7 +123,10 @@ export class RecordSearchComponent implements OnInit, OnChanges {
canRead?: any,
aggregations?: any,
listHeaders?: any,
itemHeaders?: any
itemHeaders?: any,
aggregationsOrder?: Array<string>,
aggregationsExpand?: Array<string>,
aggregationsBucketSize?: number
}[] = [{ key: 'documents', label: 'Documents' }];

/**
Expand Down Expand Up @@ -355,7 +358,7 @@ export class RecordSearchComponent implements OnInit, OnChanges {
this.records = records.hits.hits;
this.total = records.hits.total;
this.aggregationsFilters(records.aggregations).subscribe((aggr: any) => {
this.aggregations = aggr;
this.aggregations = this.aggregationsOrder(aggr);
});
this.isLoading = false;
},
Expand All @@ -366,6 +369,28 @@ export class RecordSearchComponent implements OnInit, OnChanges {
);
}

/**
* Aggregations order (facets)
* @param aggr - Aggregations dictonary
*/
aggregationsOrder(aggr: any) {
const aggregations = [];
const config = this.recordUiService.getResourceConfig(this.currentType);
const bucketSize = ('aggregationsBucketSize' in config) ? config.aggregationsBucketSize : null;
if ('aggregationsOrder' in config) {
config.aggregationsOrder.forEach((key: string) => {
if (key in aggr) {
aggregations.push({ key, bucketSize, value: { buckets: aggr[key].buckets }});
}
});
} else {
Object.keys(aggr).forEach((key: string) => {
aggregations.push({ key, bucketSize, value: { buckets: aggr[key].buckets }});
});
}
return aggregations;
}

/**
* Aggregations filters (facets)
* @param records - Result records
Expand All @@ -383,12 +408,9 @@ export class RecordSearchComponent implements OnInit, OnChanges {
* @param key facet key
*/
expandFacet(key: string) {
if ('_settings' in this.aggregations) {
const settings = this.aggregations._settings;
const keyExpand = 'expand';
if (keyExpand in settings && settings[keyExpand].indexOf(key) > -1) {
return true;
}
const config = this.recordUiService.getResourceConfig(this.currentType);
const expandConfig = ('aggregationsExpand' in config) ? config.aggregationsExpand : [];
if (expandConfig.indexOf(key) === -1) {
return false;
}
return true;
Expand Down
22 changes: 12 additions & 10 deletions projects/rero/ng-core/src/lib/translate/i18n/de.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,27 +4,29 @@
"Cancel": "Abbrechen",
"Confirmation": "Bestätigung",
"Delete": "Löschen",
"Do you really want to delete this record?": "",
"Do you really want to delete this record?": "Möchten Sie diesen Datensatz wirklich löschen ?",
"Edit": "Bearbeiten",
"Help": "Hilfe",
"Information": "",
"Information": "Information",
"New": "Neu",
"OK": "OK",
"Record Created with pid: ": "",
"Record Updated!": "",
"Record Created with pid: ": "Datensatz erstellt mit pid: ",
"Record Updated!": "Datensatz aktualisiert!",
"Record deleted.": "Datensatz gelöscht.",
"Remove": "Entfernen",
"Remove all": "Alle entfernen",
"Show": "",
"You cannot read this record": "",
"You cannot update this record": "",
"Show": "Show",
"You cannot read this record": "You cannot read this record",
"You cannot update this record": "You cannot update this record",
"create": "erstellen",
"de": "Deutsch",
"en": "Englisch",
"fr": "Französisch",
"it": "Italienisch",
"link to authority": "",
"required fields": "",
"less…": "Weniger…",
"link to authority": "link to authority",
"more…": "Weiteres…",
"required fields": "required fields",
"results": "Resultate",
"search": "suchen"
}
}
2 changes: 2 additions & 0 deletions projects/rero/ng-core/src/lib/translate/i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@
"en": "English",
"fr": "French",
"it": "Italian",
"less…": "less…",
"link to authority": "link to authority",
"more…": "more…",
"required fields": "required fields",
"results": "results",
"search": "search"
Expand Down
2 changes: 2 additions & 0 deletions projects/rero/ng-core/src/lib/translate/i18n/en_US.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@
"en": "English",
"fr": "French",
"it": "Italian",
"less…": "less…",
"link to authority": "link to authority",
"more…": "more…",
"required fields": "required fields",
"results": "results",
"search": "search"
Expand Down
Loading

0 comments on commit bf7d607

Please sign in to comment.