mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2026-09-09 18:03:21 +00:00
ACS-7461 Remove ADF_DOCUMENT_PARENT_COMPONENT token (#11372)
This commit is contained in:
@@ -35,7 +35,11 @@
|
||||
<adf-filter-header
|
||||
[currentFolderId]="currentFolderId"
|
||||
[value]="filterValue"
|
||||
(filterSelection)="onFilterSelectionChange($event)" />
|
||||
[pagination]="pagination | async"
|
||||
[sorting]="sortingSubject | async"
|
||||
(filterSelection)="onFilterSelectionChange($event)"
|
||||
(searchResultsReady)="onFilterSearchResultsReady($event)"
|
||||
(filtersCleared)="onFiltersCleared()" />
|
||||
</div>
|
||||
|
||||
<adf-no-content-template>
|
||||
|
||||
@@ -77,7 +77,6 @@ import { PermissionStyleModel } from '../models/permissions-style.model';
|
||||
import { presetsDefaultModel } from '../models/preset.model';
|
||||
import { DocumentListService } from '../services/document-list.service';
|
||||
import { LockService } from '../services/lock.service';
|
||||
import { ADF_DOCUMENT_PARENT_COMPONENT } from './document-list.token';
|
||||
import { FileAutoDownloadComponent } from './file-auto-download/file-auto-download.component';
|
||||
import { NodeEntityEvent, NodeEntryEvent } from './node.event';
|
||||
import { CommonModule } from '@angular/common';
|
||||
@@ -108,13 +107,7 @@ const BYTES_TO_MB_CONVERSION_VALUE = 1048576;
|
||||
],
|
||||
templateUrl: './document-list.component.html',
|
||||
styleUrls: ['./document-list.component.scss'],
|
||||
providers: [
|
||||
{
|
||||
provide: ADF_DOCUMENT_PARENT_COMPONENT,
|
||||
useExisting: DocumentListComponent
|
||||
},
|
||||
DataTableService
|
||||
],
|
||||
providers: [DataTableService],
|
||||
encapsulation: ViewEncapsulation.None,
|
||||
host: { class: 'adf-document-list' }
|
||||
})
|
||||
@@ -1048,6 +1041,16 @@ export class DocumentListComponent extends DataTableSchema implements OnInit, On
|
||||
this.filterSelection.emit(activeFilters);
|
||||
}
|
||||
|
||||
onFilterSearchResultsReady(nodePaging: NodePaging) {
|
||||
this.node = nodePaging;
|
||||
this.reload();
|
||||
}
|
||||
|
||||
onFiltersCleared() {
|
||||
this.node = null;
|
||||
this.reload();
|
||||
}
|
||||
|
||||
resetNewFolderPagination() {
|
||||
this._pagination.skipCount = 0;
|
||||
this._pagination.maxItems = this.maxItems;
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
/*!
|
||||
* @license
|
||||
* Copyright © 2005-2025 Hyland Software, Inc. and its affiliates. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/* eslint-disable rxjs/no-subject-value */
|
||||
/* eslint-disable @typescript-eslint/naming-convention */
|
||||
|
||||
import { InjectionToken } from '@angular/core';
|
||||
|
||||
export const ADF_DOCUMENT_PARENT_COMPONENT = new InjectionToken(
|
||||
'ADF_DOCUMENT_PARENT_COMPONENT'
|
||||
);
|
||||
+6
-5
@@ -1,9 +1,10 @@
|
||||
<div *ngIf="isFilterServiceActive">
|
||||
@if (isFilterServiceActive) {
|
||||
<adf-header-filter-template>
|
||||
<ng-template let-col>
|
||||
<adf-search-filter-container [col]="col"
|
||||
[value]="value"
|
||||
(filterChange)="onFilterSelectionChange()" />
|
||||
<adf-search-filter-container
|
||||
[col]="col"
|
||||
[value]="value"
|
||||
(filterChange)="onFilterSelectionChange()" />
|
||||
</ng-template>
|
||||
</adf-header-filter-template>
|
||||
</div>
|
||||
}
|
||||
|
||||
+39
-26
@@ -15,17 +15,14 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Subject, BehaviorSubject } from 'rxjs';
|
||||
import { Subject } from 'rxjs';
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { DataTableComponent, DataSorting } from '@alfresco/adf-core';
|
||||
import { DataTableComponent, DataSorting, PaginationModel } from '@alfresco/adf-core';
|
||||
import { SearchService } from '../../../search/services/search.service';
|
||||
import { ContentTestingModule } from '../../../testing/content.testing.module';
|
||||
import { SimpleChange } from '@angular/core';
|
||||
import { SearchHeaderQueryBuilderService } from './../../../search/services/search-header-query-builder.service';
|
||||
import { DocumentListComponent } from './../document-list.component';
|
||||
import { FilterHeaderComponent } from './filter-header.component';
|
||||
import { Pagination } from '@alfresco/js-api';
|
||||
import { ADF_DOCUMENT_PARENT_COMPONENT } from '../document-list.token';
|
||||
|
||||
describe('FilterHeaderComponent', () => {
|
||||
let fixture: ComponentFixture<FilterHeaderComponent>;
|
||||
@@ -36,28 +33,16 @@ describe('FilterHeaderComponent', () => {
|
||||
dataLoaded: new Subject()
|
||||
};
|
||||
|
||||
const paginationMock = { maxItems: 10, skipCount: 0 };
|
||||
|
||||
const documentListMock = {
|
||||
node: 'my-node',
|
||||
sorting: ['name', 'asc'],
|
||||
pagination: new BehaviorSubject<Pagination>(paginationMock),
|
||||
sortingSubject: new BehaviorSubject<DataSorting[]>([]),
|
||||
reload: () => jasmine.createSpy('reload')
|
||||
};
|
||||
const paginationMock: PaginationModel = { maxItems: 10, skipCount: 0, totalItems: 0, hasMoreItems: false };
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [ContentTestingModule, FilterHeaderComponent],
|
||||
providers: [
|
||||
{ provide: ADF_DOCUMENT_PARENT_COMPONENT, useExisting: DocumentListComponent },
|
||||
{ provide: SearchService, useValue: searchMock },
|
||||
{ provide: DocumentListComponent, useValue: documentListMock },
|
||||
DataTableComponent
|
||||
]
|
||||
providers: [{ provide: SearchService, useValue: searchMock }, DataTableComponent]
|
||||
});
|
||||
fixture = TestBed.createComponent(FilterHeaderComponent);
|
||||
component = fixture.componentInstance;
|
||||
component.currentFolderId = 'test-folder-id';
|
||||
queryBuilder = fixture.componentInstance['searchFilterQueryBuilder'];
|
||||
});
|
||||
|
||||
@@ -68,23 +53,26 @@ describe('FilterHeaderComponent', () => {
|
||||
it('should subscribe to changes in document list pagination', async () => {
|
||||
const setupCurrentPaginationSpy = spyOn(queryBuilder, 'setupCurrentPagination');
|
||||
|
||||
const currentFolderNodeIdChange = new SimpleChange('current-node-id', 'next-node-id', true);
|
||||
component.ngOnChanges({ currentFolderId: currentFolderNodeIdChange });
|
||||
component.pagination = paginationMock;
|
||||
const paginationChange = new SimpleChange(undefined, paginationMock, true);
|
||||
component.ngOnChanges({ pagination: paginationChange });
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
|
||||
expect(setupCurrentPaginationSpy).toHaveBeenCalled();
|
||||
expect(setupCurrentPaginationSpy).toHaveBeenCalledWith(paginationMock.maxItems, paginationMock.skipCount);
|
||||
});
|
||||
|
||||
it('should subscribe to changes in document list sorting', async () => {
|
||||
const setSortingSpy = spyOn(queryBuilder, 'setSorting');
|
||||
const sortingMock: DataSorting[] = [new DataSorting('name', 'asc')];
|
||||
|
||||
const currentFolderNodeIdChange = new SimpleChange('current-node-id', 'next-node-id', true);
|
||||
component.ngOnChanges({ currentFolderId: currentFolderNodeIdChange });
|
||||
component.sorting = sortingMock;
|
||||
const sortingChange = new SimpleChange(undefined, sortingMock, true);
|
||||
component.ngOnChanges({ sorting: sortingChange });
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
|
||||
expect(setSortingSpy).toHaveBeenCalled();
|
||||
expect(setSortingSpy).toHaveBeenCalledWith(sortingMock);
|
||||
});
|
||||
|
||||
it('should reset filters after changing the folder node', async () => {
|
||||
@@ -143,4 +131,29 @@ describe('FilterHeaderComponent', () => {
|
||||
fixture.detectChanges();
|
||||
fixture.whenStable();
|
||||
});
|
||||
|
||||
it('should emit filtersCleared when no filters are active', (done) => {
|
||||
spyOn(queryBuilder, 'getActiveFilters').and.returnValue([]);
|
||||
spyOn(queryBuilder, 'isNoFilterActive').and.returnValue(true);
|
||||
|
||||
component.filtersCleared.subscribe(() => {
|
||||
done();
|
||||
});
|
||||
|
||||
component.onFilterSelectionChange();
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should emit searchResultsReady when search query builder executes', (done) => {
|
||||
fixture.detectChanges(); // Initialize component (triggers ngOnInit)
|
||||
|
||||
const mockNodePaging: any = { list: { entries: [] } };
|
||||
|
||||
component.searchResultsReady.subscribe((nodePaging) => {
|
||||
expect(nodePaging).toBe(mockNodePaging);
|
||||
done();
|
||||
});
|
||||
|
||||
queryBuilder.executed.next(mockNodePaging);
|
||||
});
|
||||
});
|
||||
|
||||
+35
-28
@@ -15,18 +15,17 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Component, DestroyRef, EventEmitter, Inject, inject, Input, OnChanges, OnInit, Output, SimpleChanges } from '@angular/core';
|
||||
import { Component, DestroyRef, EventEmitter, inject, Input, OnChanges, OnInit, Output, SimpleChanges } from '@angular/core';
|
||||
import { DataSorting, HeaderFilterTemplateDirective, PaginationModel } from '@alfresco/adf-core';
|
||||
import { SearchHeaderQueryBuilderService } from '../../../search/services/search-header-query-builder.service';
|
||||
import { FilterSearch } from './../../../search/models/filter-search.interface';
|
||||
import { ADF_DOCUMENT_PARENT_COMPONENT } from '../document-list.token';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { SearchFilterContainerComponent } from '../../../search/components/search-filter-container/search-filter-container.component';
|
||||
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
||||
import type { NodePaging } from '@alfresco/js-api';
|
||||
|
||||
@Component({
|
||||
selector: 'adf-filter-header',
|
||||
imports: [CommonModule, HeaderFilterTemplateDirective, SearchFilterContainerComponent],
|
||||
imports: [HeaderFilterTemplateDirective, SearchFilterContainerComponent],
|
||||
templateUrl: './filter-header.component.html'
|
||||
})
|
||||
export class FilterHeaderComponent implements OnInit, OnChanges {
|
||||
@@ -38,26 +37,37 @@ export class FilterHeaderComponent implements OnInit, OnChanges {
|
||||
@Input({ required: true })
|
||||
currentFolderId: string;
|
||||
|
||||
/** Pagination model from the document list */
|
||||
@Input()
|
||||
pagination: PaginationModel;
|
||||
|
||||
/** Sorting configuration from the document list */
|
||||
@Input()
|
||||
sorting: DataSorting[];
|
||||
|
||||
/** Emitted when a filter value is selected */
|
||||
@Output()
|
||||
filterSelection: EventEmitter<FilterSearch[]> = new EventEmitter();
|
||||
|
||||
/** Emitted when search results are ready */
|
||||
@Output()
|
||||
searchResultsReady: EventEmitter<NodePaging> = new EventEmitter();
|
||||
|
||||
/** Emitted when filters are cleared and document list should reload */
|
||||
@Output()
|
||||
filtersCleared: EventEmitter<void> = new EventEmitter();
|
||||
|
||||
isFilterServiceActive: boolean;
|
||||
|
||||
private readonly searchFilterQueryBuilder = inject(SearchHeaderQueryBuilderService);
|
||||
private readonly destroyRef = inject(DestroyRef);
|
||||
|
||||
constructor(@Inject(ADF_DOCUMENT_PARENT_COMPONENT) private documentList: any, private searchFilterQueryBuilder: SearchHeaderQueryBuilderService) {
|
||||
this.isFilterServiceActive = this.searchFilterQueryBuilder.isFilterServiceActive();
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.searchFilterQueryBuilder.executed.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((newNodePaging) => {
|
||||
this.documentList.node = newNodePaging;
|
||||
this.documentList.reload();
|
||||
this.searchFilterQueryBuilder.executed.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((resultSetPaging) => {
|
||||
// ResultSetPaging is structurally compatible with NodePaging for the document list
|
||||
// The data adapter can handle both types
|
||||
this.searchResultsReady.emit(resultSetPaging as unknown as NodePaging);
|
||||
});
|
||||
|
||||
this.initDataPagination();
|
||||
this.initDataSorting();
|
||||
}
|
||||
|
||||
ngOnChanges(changes: SimpleChanges) {
|
||||
@@ -65,13 +75,22 @@ export class FilterHeaderComponent implements OnInit, OnChanges {
|
||||
this.resetFilterHeader();
|
||||
this.configureSearchParent(changes['currentFolderId'].currentValue);
|
||||
}
|
||||
|
||||
if (changes['pagination']?.currentValue) {
|
||||
const pagination = changes['pagination'].currentValue as PaginationModel;
|
||||
this.searchFilterQueryBuilder.setupCurrentPagination(pagination.maxItems, pagination.skipCount);
|
||||
}
|
||||
|
||||
if (changes['sorting']?.currentValue) {
|
||||
const sorting = changes['sorting'].currentValue as DataSorting[];
|
||||
this.searchFilterQueryBuilder.setSorting(sorting);
|
||||
}
|
||||
}
|
||||
|
||||
onFilterSelectionChange() {
|
||||
this.filterSelection.emit(this.searchFilterQueryBuilder.getActiveFilters());
|
||||
if (this.searchFilterQueryBuilder.isNoFilterActive()) {
|
||||
this.documentList.node = null;
|
||||
this.documentList.reload();
|
||||
this.filtersCleared.emit();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -79,18 +98,6 @@ export class FilterHeaderComponent implements OnInit, OnChanges {
|
||||
this.searchFilterQueryBuilder.resetActiveFilters();
|
||||
}
|
||||
|
||||
initDataPagination() {
|
||||
this.documentList.pagination.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((newPagination: PaginationModel) => {
|
||||
this.searchFilterQueryBuilder.setupCurrentPagination(newPagination.maxItems, newPagination.skipCount);
|
||||
});
|
||||
}
|
||||
|
||||
initDataSorting() {
|
||||
this.documentList.sortingSubject.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((sorting: DataSorting[]) => {
|
||||
this.searchFilterQueryBuilder.setSorting(sorting);
|
||||
});
|
||||
}
|
||||
|
||||
private configureSearchParent(currentFolderId: string) {
|
||||
if (this.searchFilterQueryBuilder.isCustomSourceNode(currentFolderId)) {
|
||||
this.searchFilterQueryBuilder.getNodeIdForCustomSource(currentFolderId).subscribe((node) => {
|
||||
|
||||
Reference in New Issue
Block a user