[ACA-3542] - added sorting for filters (#5932)

* [ACA-3542] - added sorting for filters

* [ACA-3542] - removed wrong parameter

* [ACA-3542] - fixed test with fixed sorting mode parameter

* Update content-node-selector-panel.component.html

* fix e2e

* fix delete site

Co-authored-by: Eugenio Romano <eromano@users.noreply.github.com>
Co-authored-by: Eugenio Romano <eugenio.romano@alfresco.com>
This commit is contained in:
Vito
2020-08-03 10:30:14 +01:00
committed by GitHub
parent bfbb66ea8e
commit 85183ead0d
25 changed files with 114 additions and 27 deletions

View File

@@ -69,7 +69,7 @@
[contextMenuActions]="false"
[contentActions]="false"
[allowDropFiles]="false"
[sorting]="'server'"
sortingMode="server"
[where]="where"
(folderChange)="onFolderChange($event)"
(ready)="onFolderLoaded()"

View File

@@ -131,7 +131,7 @@ describe('ContentNodeSelectorComponent', () => {
});
it('should the document list use the server ordering', () => {
expect(component.documentList.sorting).toBe('server');
expect(component.documentList.sortingMode).toBe('server');
});
it('should trigger the select event when selection has been made', (done) => {

View File

@@ -13,7 +13,7 @@
[noPermission]="noPermission"
[showHeader]="showHeader"
[rowMenuCacheEnabled]="false"
[stickyHeader]="stickyHeader"
[stickyHeader]="stickyHeader"
[allowFiltering]="allowFiltering"
(showRowContextMenu)="onShowRowContextMenu($event)"
(showRowActionsMenu)="onShowRowActionsMenu($event)"

View File

@@ -1451,7 +1451,7 @@ describe('DocumentList', () => {
where: undefined,
maxItems: 25,
skipCount: 0,
orderBy: [ 'name ASC' ],
orderBy: ['nodeType DESC', 'name asc' ],
rootFolderId: 'fake-id'
}, ['test-include']);
});
@@ -1467,14 +1467,14 @@ describe('DocumentList', () => {
where: '(isFolder=true)',
maxItems: 25,
skipCount: 0,
orderBy: [ 'name ASC' ],
orderBy: ['nodeType DESC', 'name asc' ],
rootFolderId: 'fake-id'
}, ['test-include']);
});
it('should add orderBy in the server request', () => {
documentList.includeFields = ['test-include'];
documentList.orderBy = ['size DESC'];
documentList.sorting = ['size', 'DESC'];
documentList.currentFolderId = 'fake-id';
documentList.where = null;
@@ -1484,7 +1484,7 @@ describe('DocumentList', () => {
maxItems: 25,
skipCount: 0,
where: undefined,
orderBy: ['size DESC'],
orderBy: ['nodeType DESC', 'size DESC'],
rootFolderId: 'fake-id'
}, ['test-include']);
});
@@ -1502,7 +1502,7 @@ describe('DocumentList', () => {
expect(documentListService.getFolder).toHaveBeenCalledWith(null, {
maxItems: 25,
skipCount: 0,
orderBy: [ 'name ASC' ],
orderBy: ['nodeType DESC', 'name asc' ],
rootFolderId: 'folder-id',
where: undefined
}, undefined);

View File

@@ -183,7 +183,14 @@ export class DocumentListComponent implements OnInit, OnChanges, OnDestroy, Afte
* override the default sorting detected by the component based on columns.
*/
@Input()
sorting = ['nodeType', 'DESC'];
sorting = ['name', 'asc'];
/** Defines default sorting. The format is an array of strings `[key direction, otherKey otherDirection]`
* i.e. `['name desc', 'nodeType asc']` or `['name asc']`. Set this value if you want a base
* rule to be added to the sorting apart from the one driven by the header.
*/
@Input()
additionalSorting = ['nodeType DESC'];
/** Defines sorting mode. Can be either `client` (items in the list
* are sorted client-side) or `server` (the ordering supplied by the
@@ -255,6 +262,10 @@ export class DocumentListComponent implements OnInit, OnChanges, OnDestroy, Afte
set currentFolderId(currentFolderId: string) {
if (this._currentFolderId !== currentFolderId) {
this._currentFolderId = currentFolderId;
if (this.sorting) {
const [key, direction] = this.sorting;
this.orderBy = this.buildOrderByArray(key, direction);
}
if (this.data) {
this.data.loadPage(null, false);
this.resetNewFolderPagination();
@@ -456,10 +467,16 @@ export class DocumentListComponent implements OnInit, OnChanges, OnDestroy, Afte
ngOnChanges(changes: SimpleChanges) {
this.resetSelection();
if (changes.sorting && changes.sorting.currentValue) {
const [key, direction] = changes.sorting.currentValue;
this.orderBy = this.buildOrderByArray(key, direction);
}
if (this.data) {
this.data.thumbnails = this.thumbnails;
}
if (changes.sortingMode && !changes.sortingMode.firstChange && this.data) {
this.data.sortingMode = changes.sortingMode.currentValue;
}
@@ -475,7 +492,6 @@ export class DocumentListComponent implements OnInit, OnChanges, OnDestroy, Afte
if (this.data) {
if (changes.node && changes.node.currentValue) {
const merge = this._pagination ? this._pagination.merge : false;
this.data.loadPage(changes.node.currentValue, merge);
this.onDataReady(changes.node.currentValue);
} else if (changes.imageResolver) {
@@ -646,6 +662,7 @@ export class DocumentListComponent implements OnInit, OnChanges, OnDestroy, Afte
}
loadFolder() {
if (!this._pagination.merge) {
this.setLoadingState(true);
}
@@ -685,13 +702,16 @@ export class DocumentListComponent implements OnInit, OnChanges, OnDestroy, Afte
}
onSortingChanged(event: CustomEvent) {
const flattenExtraSortingOption = this.sorting.join(' ');
const orderArray = [flattenExtraSortingOption];
orderArray.push(''.concat(event.detail.key, ' ', event.detail.direction));
this.orderBy = orderArray;
this.orderBy = this.buildOrderByArray(event.detail.key, event.detail.direction);
this.reload();
}
private buildOrderByArray(currentKey: string, currentDirection: string ): string[] {
const orderArray = [...this.additionalSorting];
orderArray.push(''.concat(currentKey, ' ', currentDirection));
return orderArray;
}
/**
* Creates a set of predefined columns.
*/

View File

@@ -51,6 +51,7 @@ export abstract class BaseQueryBuilderService {
filterQueries: FilterQuery[] = [];
paging: { maxItems?: number; skipCount?: number } = null;
sorting: Array<SearchSortingDefinition> = [];
sortingOptions: Array<SearchSortingDefinition> = [];
protected userFacetBuckets: { [key: string]: Array<FacetFieldBucket> } = {};
@@ -93,6 +94,7 @@ export abstract class BaseQueryBuilderService {
this.userFacetBuckets = {};
if (this.config.sorting) {
this.sorting = this.config.sorting.defaults || [];
this.sortingOptions = this.config.sorting.options || [];
}
}
}

View File

@@ -149,6 +149,20 @@ describe('SearchHeaderComponent', () => {
await fixture.whenStable();
});
it('should execute a new query when a new sorting is requested', async (done) => {
spyOn(alfrescoApiService.searchApi, 'search').and.returnValue(Promise.resolve(fakeNodePaging));
spyOn(queryBuilder, 'buildQuery').and.returnValue({});
component.update.subscribe((newNodePaging) => {
expect(newNodePaging).toBe(fakeNodePaging);
done();
});
const skipCount = new SimpleChange(null, '123-asc', false);
component.ngOnChanges({ 'sorting': skipCount });
fixture.detectChanges();
await fixture.whenStable();
});
it('should emit the clear event when no filter has been selected', async (done) => {
spyOn(queryBuilder, 'isNoFilterActive').and.returnValue(true);
spyOn(alfrescoApiService.searchApi, 'search').and.returnValue(Promise.resolve(fakeNodePaging));

View File

@@ -67,6 +67,9 @@ export class SearchHeaderComponent implements OnInit, OnChanges, OnDestroy {
@Input()
skipCount: number;
@Input()
sorting: string = null;
/** Emitted when the result of the filter is received from the API. */
@Output()
update: EventEmitter<NodePaging> = new EventEmitter();
@@ -136,6 +139,14 @@ export class SearchHeaderComponent implements OnInit, OnChanges, OnDestroy {
this.searchHeaderQueryBuilder.setupCurrentPagination(actualMaxItems, actualSkipCount);
}
if (changes['sorting'] && changes['sorting'].currentValue) {
const [key, value] = changes['sorting'].currentValue.split('-');
if (key === this.col.key) {
this.searchHeaderQueryBuilder.setSorting(key, value);
}
}
}
ngOnDestroy() {

View File

@@ -23,6 +23,7 @@ import { SearchCategory } from './search-category.interface';
import { MinimalNode, QueryBody } from '@alfresco/js-api';
import { filter } from 'rxjs/operators';
import { Observable } from 'rxjs';
import { SearchSortingDefinition } from './search-sorting-definition.interface';
@Injectable({
providedIn: 'root'
@@ -77,6 +78,22 @@ export class SearchHeaderQueryBuilderService extends BaseQueryBuilderService {
}
}
setSorting(column: string, direction: string) {
const optionAscending = direction.toLocaleLowerCase() === 'asc' ? true : false;
const fieldValue = this.getSortingFieldFromColumnName(column);
const currentSort: SearchSortingDefinition = { key: column, label: 'current', type: 'FIELD', field: fieldValue, ascending: optionAscending};
this.sorting = [currentSort];
this.execute();
}
private getSortingFieldFromColumnName(columnName: string) {
if (this.sortingOptions.length > 0) {
const sortOption: SearchSortingDefinition = this.sortingOptions.find((option: SearchSortingDefinition) => option.key === columnName);
return sortOption.field;
}
return '';
}
getCategoryForColumn(columnKey: string): SearchCategory {
let foundCategory = null;
if (this.categories !== null) {