mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2025-07-24 17:32:15 +00:00
[MNT-24459] Aspect list get all aspects when not all were fetched by first call (#10980)
* [MNT-24459] Aspect list get all aspects when not all were fetched by first call * [MNT-24459] CR fixes * [MNT-24459] Sonar issues fixed
This commit is contained in:
@@ -132,7 +132,9 @@ describe('AspectListDialogComponent', () => {
|
||||
describe('Without passing node id', () => {
|
||||
beforeEach(() => {
|
||||
aspectListService = TestBed.inject(AspectListService);
|
||||
spyOn(aspectListService, 'getAspects').and.returnValue(of(aspectListMock));
|
||||
spyOn(aspectListService, 'getAllAspects').and.returnValue(
|
||||
of({ standardAspectPaging: { list: { entries: aspectListMock } }, customAspectPaging: { list: { entries: customAspectListMock } } })
|
||||
);
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
@@ -247,9 +249,11 @@ describe('AspectListDialogComponent', () => {
|
||||
data.nodeId = 'fake-node-id';
|
||||
aspectListService = TestBed.inject(AspectListService);
|
||||
nodeService = TestBed.inject(NodesApiService);
|
||||
spyOn(aspectListService, 'getAspects').and.returnValue(of([...aspectListMock, ...customAspectListMock]));
|
||||
spyOn(aspectListService, 'getAllAspects').and.returnValue(
|
||||
of({ standardAspectPaging: { list: { entries: aspectListMock } }, customAspectPaging: { list: { entries: customAspectListMock } } })
|
||||
);
|
||||
spyOn(aspectListService, 'getVisibleAspects').and.returnValue(['frs:AspectOne']);
|
||||
spyOn(aspectListService, 'getCustomAspects').and.returnValue(of(customAspectListMock));
|
||||
spyOn(aspectListService, 'getAspects').and.returnValue(of({ list: { entries: customAspectListMock } }));
|
||||
spyOn(nodeService, 'getNode').and.returnValue(
|
||||
of(new Node({ id: 'fake-node-id', aspectNames: ['frs:AspectOne', 'cst:customAspect'] })).pipe(delay(0))
|
||||
);
|
||||
|
@@ -19,15 +19,16 @@ import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { NodesApiService } from '../common/services/nodes-api.service';
|
||||
import { ContentTestingModule } from '../testing/content.testing.module';
|
||||
import { AspectListComponent } from './aspect-list.component';
|
||||
import { AspectListService } from './services/aspect-list.service';
|
||||
import { AspectListService, CustomAspectsWhere, StandardAspectsWhere } from './services/aspect-list.service';
|
||||
import { EMPTY, of } from 'rxjs';
|
||||
import { AspectEntry } from '@alfresco/js-api';
|
||||
import { AspectEntry, Pagination } from '@alfresco/js-api';
|
||||
import { HarnessLoader } from '@angular/cdk/testing';
|
||||
import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed';
|
||||
import { MatExpansionPanelHarness } from '@angular/material/expansion/testing';
|
||||
import { MatTableHarness } from '@angular/material/table/testing';
|
||||
import { MatCheckboxHarness } from '@angular/material/checkbox/testing';
|
||||
import { MatProgressSpinnerHarness } from '@angular/material/progress-spinner/testing';
|
||||
import { CustomAspectPaging } from './interfaces/custom-aspect-paging.interface';
|
||||
|
||||
const aspectListMock: AspectEntry[] = [
|
||||
{
|
||||
@@ -110,6 +111,11 @@ const customAspectListMock: AspectEntry[] = [
|
||||
}
|
||||
];
|
||||
|
||||
const allAspectsMock: CustomAspectPaging = {
|
||||
standardAspectPaging: { list: { entries: aspectListMock } },
|
||||
customAspectPaging: { list: { entries: customAspectListMock } }
|
||||
};
|
||||
|
||||
describe('AspectListComponent', () => {
|
||||
let loader: HarnessLoader;
|
||||
let component: AspectListComponent;
|
||||
@@ -122,10 +128,7 @@ describe('AspectListComponent', () => {
|
||||
imports: [ContentTestingModule, AspectListComponent],
|
||||
providers: [AspectListService]
|
||||
});
|
||||
});
|
||||
|
||||
describe('Loading', () => {
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(AspectListComponent);
|
||||
component = fixture.componentInstance;
|
||||
nodeService = TestBed.inject(NodesApiService);
|
||||
@@ -133,6 +136,7 @@ describe('AspectListComponent', () => {
|
||||
loader = TestbedHarnessEnvironment.loader(fixture);
|
||||
});
|
||||
|
||||
describe('Loading', () => {
|
||||
it('should show the loading spinner when result is loading', async () => {
|
||||
spyOn(nodeService, 'getNode').and.returnValue(EMPTY);
|
||||
spyOn(aspectListService, 'getAspects').and.returnValue(EMPTY);
|
||||
@@ -144,16 +148,11 @@ describe('AspectListComponent', () => {
|
||||
|
||||
describe('When passing a node id', () => {
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(AspectListComponent);
|
||||
component = fixture.componentInstance;
|
||||
aspectListService = TestBed.inject(AspectListService);
|
||||
spyOn(aspectListService, 'getAspects').and.returnValue(of([...aspectListMock, ...customAspectListMock]));
|
||||
spyOn(aspectListService, 'getCustomAspects').and.returnValue(of(customAspectListMock));
|
||||
spyOn(aspectListService, 'getAllAspects').and.returnValue(of(allAspectsMock));
|
||||
spyOn(aspectListService, 'getAspects').and.returnValue(of({ list: { entries: customAspectListMock } }));
|
||||
spyOn(aspectListService, 'getVisibleAspects').and.returnValue(['frs:AspectOne']);
|
||||
nodeService = TestBed.inject(NodesApiService);
|
||||
spyOn(nodeService, 'getNode').and.returnValue(of({ id: 'fake-node-id', aspectNames: ['frs:AspectOne', 'stored:aspect'] } as any));
|
||||
component.nodeId = 'fake-node-id';
|
||||
loader = TestbedHarnessEnvironment.loader(fixture);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
@@ -251,6 +250,13 @@ describe('AspectListComponent', () => {
|
||||
expect(component.valueChanged.emit).toHaveBeenCalledWith(['frs:AspectOne', 'frs:SecondAspect', ...storedAspect]);
|
||||
expect(component.updateCounter.emit).toHaveBeenCalledWith(2);
|
||||
});
|
||||
|
||||
it('should load aspects with 0 skip count as pagination by default', () => {
|
||||
expect(aspectListService.getAllAspects).toHaveBeenCalledWith(
|
||||
{ where: StandardAspectsWhere, include: ['properties'], skipCount: 0, maxItems: 100 },
|
||||
{ where: CustomAspectsWhere, include: ['properties'], skipCount: 0, maxItems: 100 }
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('with excluded aspects', () => {
|
||||
@@ -265,11 +271,7 @@ describe('AspectListComponent', () => {
|
||||
|
||||
describe('When no node id is passed', () => {
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(AspectListComponent);
|
||||
component = fixture.componentInstance;
|
||||
aspectListService = TestBed.inject(AspectListService);
|
||||
spyOn(aspectListService, 'getAspects').and.returnValue(of(aspectListMock));
|
||||
loader = TestbedHarnessEnvironment.loader(fixture);
|
||||
spyOn(aspectListService, 'getAllAspects').and.returnValue(of(allAspectsMock));
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
@@ -289,5 +291,38 @@ describe('AspectListComponent', () => {
|
||||
expect(await loader.hasHarness(MatExpansionPanelHarness.with({ selector: '#aspect-list-FirstAspect' }))).toBeFalse();
|
||||
expect(await loader.hasHarness(MatExpansionPanelHarness.with({ selector: '#aspect-list-SecondAspect' }))).toBeFalse();
|
||||
});
|
||||
|
||||
it('should load aspects with 0 skip count as pagination by default', () => {
|
||||
fixture.detectChanges();
|
||||
expect(aspectListService.getAllAspects).toHaveBeenCalledWith(
|
||||
{ where: StandardAspectsWhere, include: ['properties'], skipCount: 0, maxItems: 100 },
|
||||
{ where: CustomAspectsWhere, include: ['properties'], skipCount: 0, maxItems: 100 }
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
it('should load next batch of aspects if not all items were returned by first call', (done) => {
|
||||
fixture.detectChanges();
|
||||
const moreItemsPagination: Pagination = { count: 2, hasMoreItems: true };
|
||||
const allAspectsWithMoreItems: CustomAspectPaging = {
|
||||
standardAspectPaging: { list: { entries: aspectListMock, pagination: moreItemsPagination } },
|
||||
customAspectPaging: { list: { entries: customAspectListMock, pagination: moreItemsPagination } }
|
||||
};
|
||||
const getAspectsSpy = spyOn(aspectListService, 'getAllAspects').and.returnValues(of(allAspectsWithMoreItems), of(allAspectsMock));
|
||||
spyOn(aspectListService, 'getAspects').and.returnValues(
|
||||
of({ list: { entries: aspectListMock } }),
|
||||
of({ list: { entries: customAspectListMock } })
|
||||
);
|
||||
|
||||
component.aspects$.subscribe(() => {
|
||||
expect(getAspectsSpy.calls.argsFor(0)[0]).toEqual({ where: StandardAspectsWhere, include: ['properties'], skipCount: 0, maxItems: 100 });
|
||||
expect(getAspectsSpy.calls.argsFor(0)[1]).toEqual({ where: CustomAspectsWhere, include: ['properties'], skipCount: 0, maxItems: 100 });
|
||||
expect(getAspectsSpy.calls.argsFor(1)[0]).toEqual({ where: StandardAspectsWhere, include: ['properties'], skipCount: 2, maxItems: 100 });
|
||||
expect(getAspectsSpy.calls.argsFor(1)[1]).toEqual({ where: CustomAspectsWhere, include: ['properties'], skipCount: 2, maxItems: 100 });
|
||||
done();
|
||||
});
|
||||
|
||||
component.ngOnInit();
|
||||
fixture.detectChanges();
|
||||
});
|
||||
});
|
||||
|
@@ -17,11 +17,11 @@
|
||||
|
||||
import { Component, DestroyRef, EventEmitter, inject, Input, OnInit, Output, ViewEncapsulation } from '@angular/core';
|
||||
import { NodesApiService } from '../common/services/nodes-api.service';
|
||||
import { Observable, zip } from 'rxjs';
|
||||
import { concatMap, map, tap } from 'rxjs/operators';
|
||||
import { AspectListService } from './services/aspect-list.service';
|
||||
import { EMPTY, Observable, zip } from 'rxjs';
|
||||
import { concatMap, expand, map, reduce, take, tap } from 'rxjs/operators';
|
||||
import { AspectListService, CustomAspectsWhere, StandardAspectsWhere } from './services/aspect-list.service';
|
||||
import { MatCheckboxChange, MatCheckboxModule } from '@angular/material/checkbox';
|
||||
import { AspectEntry } from '@alfresco/js-api';
|
||||
import { AspectEntry, ContentPagingQuery, ListAspectsOpts } from '@alfresco/js-api';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { MatExpansionModule } from '@angular/material/expansion';
|
||||
import { MatTableModule } from '@angular/material/table';
|
||||
@@ -63,6 +63,10 @@ export class AspectListComponent implements OnInit {
|
||||
|
||||
private readonly destroyRef = inject(DestroyRef);
|
||||
|
||||
private customAspectsLoaded = 0;
|
||||
private standardAspectsLoaded = 0;
|
||||
private hasMoreAspects = false;
|
||||
|
||||
constructor(private aspectListService: AspectListService, private nodeApiService: NodesApiService) {}
|
||||
|
||||
ngOnInit(): void {
|
||||
@@ -70,8 +74,13 @@ export class AspectListComponent implements OnInit {
|
||||
if (this.nodeId) {
|
||||
const node$ = this.nodeApiService.getNode(this.nodeId);
|
||||
const customAspect$ = this.aspectListService
|
||||
.getCustomAspects(this.aspectListService.getVisibleAspects())
|
||||
.pipe(map((customAspects) => customAspects.flatMap((customAspect) => customAspect.entry.id)));
|
||||
.getAspects(this.aspectListService.getVisibleAspects(), {
|
||||
where: CustomAspectsWhere,
|
||||
include: ['properties'],
|
||||
skipCount: 0,
|
||||
maxItems: 100
|
||||
})
|
||||
.pipe(map((customAspects) => customAspects?.list?.entries.flatMap((customAspect) => customAspect.entry.id)));
|
||||
aspects$ = zip(node$, customAspect$).pipe(
|
||||
tap(([node, customAspects]) => {
|
||||
this.nodeAspects = node.aspectNames.filter(
|
||||
@@ -84,13 +93,19 @@ export class AspectListComponent implements OnInit {
|
||||
this.valueChanged.emit([...this.nodeAspects, ...this.notDisplayedAspects]);
|
||||
this.updateCounter.emit(this.nodeAspects.length);
|
||||
}),
|
||||
concatMap(() => this.aspectListService.getAspects()),
|
||||
concatMap(() => this.loadAspects({ skipCount: this.standardAspectsLoaded }, { skipCount: this.customAspectsLoaded })),
|
||||
takeUntilDestroyed(this.destroyRef)
|
||||
);
|
||||
} else {
|
||||
aspects$ = this.aspectListService.getAspects().pipe(takeUntilDestroyed(this.destroyRef));
|
||||
aspects$ = this.loadAspects({ skipCount: this.standardAspectsLoaded }, { skipCount: this.customAspectsLoaded });
|
||||
}
|
||||
this.aspects$ = aspects$.pipe(map((aspects) => aspects.filter((aspect) => !this.excludedAspects.includes(aspect.entry.id))));
|
||||
this.aspects$ = aspects$.pipe(
|
||||
expand(() =>
|
||||
this.hasMoreAspects ? this.loadAspects({ skipCount: this.standardAspectsLoaded }, { skipCount: this.customAspectsLoaded }) : EMPTY
|
||||
),
|
||||
map((aspects) => aspects.filter((aspect) => !this.excludedAspects.includes(aspect.entry.id))),
|
||||
reduce((acc, aspects) => [...acc, ...aspects])
|
||||
);
|
||||
}
|
||||
|
||||
onCheckBoxClick(event: Event) {
|
||||
@@ -141,4 +156,33 @@ export class AspectListComponent implements OnInit {
|
||||
this.hasEqualAspect = this.nodeAspects.every((aspect) => this.nodeAspectStatus.includes(aspect));
|
||||
}
|
||||
}
|
||||
|
||||
private loadAspects(standardAspectsPagination?: ContentPagingQuery, customAspectsPagination?: ContentPagingQuery): Observable<AspectEntry[]> {
|
||||
const standardAspectOpts: ListAspectsOpts = {
|
||||
where: StandardAspectsWhere,
|
||||
include: ['properties'],
|
||||
skipCount: standardAspectsPagination?.skipCount ?? 0,
|
||||
maxItems: 100
|
||||
};
|
||||
const customAspectOpts: ListAspectsOpts = {
|
||||
where: CustomAspectsWhere,
|
||||
include: ['properties'],
|
||||
skipCount: customAspectsPagination?.skipCount ?? 0,
|
||||
maxItems: 100
|
||||
};
|
||||
return this.aspectListService.getAllAspects(standardAspectOpts, customAspectOpts).pipe(
|
||||
take(1),
|
||||
tap((aspectsPaging) => {
|
||||
this.customAspectsLoaded += aspectsPaging.customAspectPaging?.list?.pagination?.count ?? 0;
|
||||
this.standardAspectsLoaded += aspectsPaging.standardAspectPaging?.list?.pagination?.count ?? 0;
|
||||
this.hasMoreAspects =
|
||||
aspectsPaging.customAspectPaging?.list?.pagination?.hasMoreItems ||
|
||||
aspectsPaging.standardAspectPaging?.list?.pagination?.hasMoreItems;
|
||||
}),
|
||||
map((aspectsPaging) => [
|
||||
...(aspectsPaging.standardAspectPaging?.list?.entries ?? []),
|
||||
...(aspectsPaging.customAspectPaging?.list?.entries ?? [])
|
||||
])
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,23 @@
|
||||
/*!
|
||||
* @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.
|
||||
*/
|
||||
|
||||
import { AspectPaging } from '@alfresco/js-api';
|
||||
|
||||
export interface CustomAspectPaging {
|
||||
standardAspectPaging: AspectPaging;
|
||||
customAspectPaging: AspectPaging;
|
||||
}
|
@@ -22,5 +22,6 @@ export * from './services/node-aspect.service';
|
||||
export * from './services/dialog-aspect-list.service';
|
||||
|
||||
export * from './aspect-list-dialog-data.interface';
|
||||
export * from './interfaces/custom-aspect-paging.interface';
|
||||
|
||||
export * from './aspect-list.module';
|
||||
|
@@ -16,96 +16,172 @@
|
||||
*/
|
||||
|
||||
import { TestBed } from '@angular/core/testing';
|
||||
import { AspectListService } from './aspect-list.service';
|
||||
import { AspectPaging, AspectsApi, AspectEntry } from '@alfresco/js-api';
|
||||
import { HttpClientTestingModule } from '@angular/common/http/testing';
|
||||
import { AspectListService, CustomAspectsWhere, StandardAspectsWhere } from './aspect-list.service';
|
||||
import { AspectPaging, AspectsApi, AspectEntry, ListAspectsOpts } from '@alfresco/js-api';
|
||||
import { provideHttpClientTesting } from '@angular/common/http/testing';
|
||||
import { AlfrescoApiService } from '../../services';
|
||||
import { provideHttpClient } from '@angular/common/http';
|
||||
import { AppConfigService } from '@alfresco/adf-core';
|
||||
|
||||
const stdAspect1: AspectEntry = { entry: { id: 'std:standardAspectOne', description: 'Standard Aspect One', title: 'StandardAspectOne' } };
|
||||
const stdAspect2: AspectEntry = { entry: { id: 'std:standardAspectTwo', description: 'Standard Aspect Two', title: 'StandardAspectTwo' } };
|
||||
const stdAspect3: AspectEntry = { entry: { id: 'std:standardAspectThree', description: 'Standard Aspect Three', title: 'StandardAspectThree' } };
|
||||
const standardAspectPagingMock: AspectPaging = { list: { entries: [stdAspect1, stdAspect2, stdAspect3] } };
|
||||
|
||||
const cstAspect1: AspectEntry = { entry: { id: 'cst:customAspectOne', description: 'Custom Aspect One', title: 'CustomAspectOne' } };
|
||||
const cstAspect2: AspectEntry = { entry: { id: 'cst:customAspectTwo', description: 'Custom Aspect Two', title: 'CustomAspectTwo' } };
|
||||
const cstAspect3: AspectEntry = { entry: { id: 'cst:customAspectThree', description: 'Custom Aspect Three', title: 'CustomAspectThree' } };
|
||||
const customAspectPagingMock: AspectPaging = { list: { entries: [cstAspect1, cstAspect2, cstAspect3] } };
|
||||
|
||||
const aspectsOpts: ListAspectsOpts = {
|
||||
where: StandardAspectsWhere,
|
||||
include: ['properties'],
|
||||
skipCount: 0,
|
||||
maxItems: 100
|
||||
};
|
||||
|
||||
const customAspectsOpts: ListAspectsOpts = {
|
||||
where: CustomAspectsWhere,
|
||||
include: ['properties'],
|
||||
skipCount: 0,
|
||||
maxItems: 100
|
||||
};
|
||||
|
||||
let standardAspectPagingMock: AspectPaging;
|
||||
let customAspectPagingMock: AspectPaging;
|
||||
|
||||
describe('AspectListService', () => {
|
||||
let aspectListService: AspectListService;
|
||||
let apiService: AlfrescoApiService;
|
||||
let aspectsApi: AspectsApi;
|
||||
let appConfigService: AppConfigService;
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [HttpClientTestingModule]
|
||||
providers: [provideHttpClient(), provideHttpClientTesting()]
|
||||
});
|
||||
|
||||
aspectListService = TestBed.inject(AspectListService);
|
||||
appConfigService = TestBed.inject(AppConfigService);
|
||||
apiService = TestBed.inject(AlfrescoApiService);
|
||||
aspectsApi = new AspectsApi(apiService.getInstance());
|
||||
spyOnProperty(aspectListService, 'aspectsApi', 'get').and.returnValue(aspectsApi);
|
||||
standardAspectPagingMock = { list: { entries: [stdAspect1, stdAspect2, stdAspect3] } };
|
||||
customAspectPagingMock = { list: { entries: [cstAspect1, cstAspect2, cstAspect3] } };
|
||||
});
|
||||
|
||||
it('should get one standard aspect', (done) => {
|
||||
describe('When API returns error', () => {
|
||||
const visibleAspects: string[] = [];
|
||||
|
||||
beforeEach(() => {
|
||||
spyOn(aspectsApi, 'listAspects').and.returnValue(Promise.reject(new Error('API error')));
|
||||
});
|
||||
|
||||
it('should return empty paging list for standard aspects when api returns error', (done) => {
|
||||
aspectListService.getAspects(visibleAspects, aspectsOpts).subscribe((response) => {
|
||||
expect(response.list.entries).toEqual([]);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should return empty paging list for custom aspects when api returns error', (done) => {
|
||||
aspectListService.getAspects(visibleAspects, aspectsOpts).subscribe((response) => {
|
||||
expect(response.list.entries).toEqual([]);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('When aspects are returned', () => {
|
||||
beforeEach(() => {
|
||||
spyOn(aspectsApi, 'listAspects').and.returnValue(Promise.resolve(standardAspectPagingMock));
|
||||
});
|
||||
|
||||
it('should add custom pagination for aspects list request when provided', (done) => {
|
||||
const visibleAspects: string[] = [];
|
||||
const customPagination: ListAspectsOpts = { skipCount: 10, maxItems: 20 };
|
||||
aspectListService.getAspects(visibleAspects, customPagination).subscribe(() => {
|
||||
expect(aspectsApi.listAspects).toHaveBeenCalledWith(customPagination);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should get one aspect', (done) => {
|
||||
const visibleAspects = ['std:standardAspectOne'];
|
||||
spyOn(aspectsApi, 'listAspects').and.returnValue(Promise.resolve(standardAspectPagingMock));
|
||||
aspectListService.getStandardAspects(visibleAspects).subscribe((response) => {
|
||||
expect(response).toEqual([stdAspect1]);
|
||||
aspectListService.getAspects(visibleAspects, aspectsOpts).subscribe((response) => {
|
||||
expect(response.list.entries).toEqual([stdAspect1]);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should get two standard aspects', (done) => {
|
||||
it('should get two aspects', (done) => {
|
||||
const visibleAspects = ['std:standardAspectTwo', 'std:standardAspectThree'];
|
||||
spyOn(aspectsApi, 'listAspects').and.returnValue(Promise.resolve(standardAspectPagingMock));
|
||||
aspectListService.getStandardAspects(visibleAspects).subscribe((response) => {
|
||||
expect(response).toEqual([stdAspect2, stdAspect3]);
|
||||
aspectListService.getAspects(visibleAspects, aspectsOpts).subscribe((response) => {
|
||||
expect(response.list.entries).toEqual([stdAspect2, stdAspect3]);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should get one custom aspect', (done) => {
|
||||
const visibleAspects = ['cst:customAspectTwo'];
|
||||
spyOn(aspectsApi, 'listAspects').and.returnValue(Promise.resolve(customAspectPagingMock));
|
||||
aspectListService.getCustomAspects(visibleAspects).subscribe((response) => {
|
||||
expect(response).toEqual([cstAspect2]);
|
||||
it('should get all aspects (visible aspects as undefined)', (done) => {
|
||||
const visibleAspects: string[] = undefined;
|
||||
aspectListService.getAspects(visibleAspects, aspectsOpts).subscribe((response) => {
|
||||
expect(response.list.entries).toEqual([stdAspect1, stdAspect2, stdAspect3]);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should get two custom aspects', (done) => {
|
||||
const visibleAspects = ['cst:customAspectOne', 'cst:customAspectThree'];
|
||||
spyOn(aspectsApi, 'listAspects').and.returnValue(Promise.resolve(customAspectPagingMock));
|
||||
aspectListService.getCustomAspects(visibleAspects).subscribe((response) => {
|
||||
expect(response).toEqual([cstAspect1, cstAspect3]);
|
||||
it('should get all aspects (visible aspects as empty array)', (done) => {
|
||||
const visibleAspects: string[] = [];
|
||||
aspectListService.getAspects(visibleAspects, aspectsOpts).subscribe((response) => {
|
||||
expect(response.list.entries).toEqual([stdAspect1, stdAspect2, stdAspect3]);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('getAllAspects', () => {
|
||||
beforeEach(() => {
|
||||
spyOn(aspectsApi, 'listAspects').and.returnValues(Promise.resolve(standardAspectPagingMock), Promise.resolve(customAspectPagingMock));
|
||||
});
|
||||
|
||||
it('should get all aspects (standard and custom) when visible aspects are empty', (done) => {
|
||||
spyOn(appConfigService, 'get').and.returnValue(undefined);
|
||||
aspectListService.getAllAspects(aspectsOpts, customAspectsOpts).subscribe((aspects) => {
|
||||
expect(aspects.standardAspectPaging.list.entries).toEqual([stdAspect1, stdAspect2, stdAspect3]);
|
||||
expect(aspects.customAspectPaging.list.entries).toEqual([cstAspect1, cstAspect2, cstAspect3]);
|
||||
expect(aspectsApi.listAspects).toHaveBeenCalledTimes(2);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should get all custom aspects (visible aspects as undefined)', (done) => {
|
||||
const visibleAspects = undefined;
|
||||
spyOn(aspectsApi, 'listAspects').and.returnValue(Promise.resolve(customAspectPagingMock));
|
||||
aspectListService.getCustomAspects(visibleAspects).subscribe((response) => {
|
||||
expect(response).toEqual([cstAspect1, cstAspect2, cstAspect3]);
|
||||
it('should get all aspects (standard and custom) filtered by visible aspects', (done) => {
|
||||
const visibleAspectConfig = {
|
||||
standard: ['std:standardAspectOne', 'std:standardAspectTwo'],
|
||||
custom: ['cst:customAspectOne']
|
||||
};
|
||||
spyOn(appConfigService, 'get').and.returnValue(visibleAspectConfig);
|
||||
aspectListService.getAllAspects(aspectsOpts, customAspectsOpts).subscribe((aspects) => {
|
||||
expect(aspects.standardAspectPaging.list.entries).toEqual([stdAspect1, stdAspect2]);
|
||||
expect(aspects.customAspectPaging.list.entries).toEqual([cstAspect1]);
|
||||
expect(aspectsApi.listAspects).toHaveBeenCalledTimes(2);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should get all custom aspects (visible aspects as empty array)', (done) => {
|
||||
const visibleAspects = [];
|
||||
spyOn(aspectsApi, 'listAspects').and.returnValue(Promise.resolve(customAspectPagingMock));
|
||||
aspectListService.getCustomAspects(visibleAspects).subscribe((response) => {
|
||||
expect(response).toEqual([cstAspect1, cstAspect2, cstAspect3]);
|
||||
done();
|
||||
});
|
||||
describe('getVisibleAspects', () => {
|
||||
it('should return empty array when visible aspects are not provided in the config', () => {
|
||||
spyOn(appConfigService, 'get').and.returnValue(undefined);
|
||||
const visibleAspects = aspectListService.getVisibleAspects();
|
||||
expect(visibleAspects).toEqual([]);
|
||||
});
|
||||
|
||||
it('should get all custom aspects (visible aspects not supplied)', (done) => {
|
||||
spyOn(aspectsApi, 'listAspects').and.returnValue(Promise.resolve(customAspectPagingMock));
|
||||
aspectListService.getCustomAspects().subscribe((response) => {
|
||||
expect(response).toEqual([cstAspect1, cstAspect2, cstAspect3]);
|
||||
done();
|
||||
it('should return visible aspects from config when provided', () => {
|
||||
const visibleAspectConfig = {
|
||||
standard: ['std:standardAspectOne', 'std:standardAspectTwo'],
|
||||
custom: ['cst:customAspectOne']
|
||||
};
|
||||
spyOn(appConfigService, 'get').and.returnValue(visibleAspectConfig);
|
||||
const visibleAspects = aspectListService.getVisibleAspects();
|
||||
expect(visibleAspects).toEqual(['std:standardAspectOne', 'std:standardAspectTwo', 'cst:customAspectOne']);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@@ -20,7 +20,11 @@ import { AlfrescoApiService } from '../../services/alfresco-api.service';
|
||||
import { AppConfigService } from '@alfresco/adf-core';
|
||||
import { from, Observable, of, zip } from 'rxjs';
|
||||
import { catchError, map } from 'rxjs/operators';
|
||||
import { AspectEntry, AspectPaging, AspectsApi } from '@alfresco/js-api';
|
||||
import { AspectEntry, AspectPaging, AspectsApi, ListAspectsOpts } from '@alfresco/js-api';
|
||||
import { CustomAspectPaging } from '../interfaces/custom-aspect-paging.interface';
|
||||
|
||||
export const StandardAspectsWhere = `(modelId in ('cm:contentmodel', 'emailserver:emailserverModel', 'smf:smartFolder', 'app:applicationmodel' ))`;
|
||||
export const CustomAspectsWhere = `(not namespaceUri matches('http://www.alfresco.*'))`;
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
@@ -34,37 +38,24 @@ export class AspectListService {
|
||||
|
||||
constructor(private alfrescoApiService: AlfrescoApiService, private appConfigService: AppConfigService) {}
|
||||
|
||||
getAspects(): Observable<AspectEntry[]> {
|
||||
getAllAspects(standardOpts?: ListAspectsOpts, customOpts?: ListAspectsOpts): Observable<CustomAspectPaging> {
|
||||
const visibleAspectList = this.getVisibleAspects();
|
||||
const standardAspects$ = this.getStandardAspects(visibleAspectList);
|
||||
const customAspects$ = this.getCustomAspects(visibleAspectList);
|
||||
const standardAspects$ = this.getAspects(visibleAspectList, standardOpts);
|
||||
const customAspects$ = this.getAspects(visibleAspectList, customOpts);
|
||||
return zip(standardAspects$, customAspects$).pipe(
|
||||
map(([standardAspectList, customAspectList]) => [...standardAspectList, ...customAspectList])
|
||||
map(([standardAspectPaging, customAspectPaging]) => ({ standardAspectPaging, customAspectPaging }))
|
||||
);
|
||||
}
|
||||
|
||||
getStandardAspects(whiteList: string[]): Observable<AspectEntry[]> {
|
||||
const where = `(modelId in ('cm:contentmodel', 'emailserver:emailserverModel', 'smf:smartFolder', 'app:applicationmodel' ))`;
|
||||
const opts: any = {
|
||||
where,
|
||||
include: ['properties']
|
||||
};
|
||||
|
||||
getAspects(whiteList: string[], opts?: ListAspectsOpts): Observable<AspectPaging> {
|
||||
return from(this.aspectsApi.listAspects(opts)).pipe(
|
||||
map((result: AspectPaging) => this.filterAspectByConfig(whiteList, result?.list?.entries)),
|
||||
catchError(() => of([]))
|
||||
);
|
||||
map((result) => {
|
||||
if (result?.list?.entries) {
|
||||
result.list.entries = this.filterAspectByConfig(whiteList, result.list.entries);
|
||||
}
|
||||
|
||||
getCustomAspects(whiteList?: string[]): Observable<AspectEntry[]> {
|
||||
const where = `(not namespaceUri matches('http://www.alfresco.*'))`;
|
||||
const opts: any = {
|
||||
where,
|
||||
include: ['properties']
|
||||
};
|
||||
return from(this.aspectsApi.listAspects(opts)).pipe(
|
||||
map((result: AspectPaging) => this.filterAspectByConfig(whiteList, result?.list?.entries)),
|
||||
catchError(() => of([]))
|
||||
return result;
|
||||
}),
|
||||
catchError(() => of({ list: { entries: [] } }))
|
||||
);
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user