ACS-8572: Support for reloading document list from outside (#10065)

* support for external document list reload

* update docs [ci:force]

* reset selection api and docs [ci:force]
This commit is contained in:
Denys Vuika 2024-08-09 07:33:56 -04:00 committed by GitHub
parent 80a70cf789
commit 9966cf4405
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 122 additions and 25 deletions

View File

@ -5,57 +5,76 @@ Status: Active
Last reviewed: 2019-01-16 Last reviewed: 2019-01-16
--- ---
# [Document List service](../../../lib/content-services/src/lib/document-list/services/document-list.service.ts "Defined in document-list.service.ts") # Document List Service
Implements node operations used by the [Document List component](../components/document-list.component.md). `service`
## Class members Implements operations used by the [Document List component](../components/document-list.component.md).
## Usage
```typescript
import { DocumentListService } from '@alfresco/adf-core';
```
## API
### Events
| Name | Description |
|-------------------|-------------------------------------------------|
| `reload$` | Emits when the document list should be reloaded |
| `resetSelection$` | Emits when the selection should be reset |
### Methods ### Methods
- **copyNode**(nodeId: `string`, targetParentId: `string`): [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`NodeEntry`](https://github.com/Alfresco/alfresco-js-api/blob/master/src/alfresco-core-rest-api/docs/NodeEntry.md)`>`<br/> - **reload**(): `void`<br/>
Reloads the document list.
- **resetSelection**(): `void`<br/>
Resets the selection.
- **copyNode**(nodeId: `string`, targetParentId: `string`): `Observable<NodeEntry>`<br/>
Copy a node to destination node Copy a node to destination node
- _nodeId:_ `string` - The id of the node to be copied - _nodeId:_ `string` - The id of the node to be copied
- _targetParentId:_ `string` - The id of the folder where the node will be copied - _targetParentId:_ `string` - The id of the folder where the node will be copied
- **Returns** [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`NodeEntry`](https://github.com/Alfresco/alfresco-js-api/blob/master/src/alfresco-core-rest-api/docs/NodeEntry.md)`>` - NodeEntry for the copied node - **Returns** `Observable<NodeEntry>` - NodeEntry for the copied node
- **deleteNode**(nodeId: `string`): [`Observable`](http://reactivex.io/documentation/observable.html)`<any>`<br/> - **deleteNode**(nodeId: `string`): `Observable<any>`<br/>
Deletes a node. Deletes a node.
- _nodeId:_ `string` - ID of the node to delete - _nodeId:_ `string` - ID of the node to delete
- **Returns** [`Observable`](http://reactivex.io/documentation/observable.html)`<any>` - Empty response when the operation is complete - **Returns** `Observable<any>` - Empty response when the operation is complete
- **getFolder**(folder: `string`, opts?: `any`, includeFields: `string[]` = `[]`): [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`NodePaging`](https://github.com/Alfresco/alfresco-js-api/blob/develop/src/api/content-rest-api/docs/NodePaging.md)`>`<br/> - **getFolder**(folder: `string`, opts?: `any`, includeFields: `string[]` = `[]`): `Observable<NodePaging>`<br/>
Gets the folder node with the specified relative name path below the root node. Gets the folder node with the specified relative name path below the root node.
- _folder:_ `string` - Path to folder. - _folder:_ `string` - Path to folder.
- _opts:_ `any` - (Optional) Options. - _opts:_ `any` - (Optional) Options.
- _includeFields:_ `string[]` - Extra information to include (available options are "aspectNames", "isLink" and "association") - _includeFields:_ `string[]` - Extra information to include (available options are "aspectNames", "isLink" and "association")
- **Returns** [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`NodePaging`](https://github.com/Alfresco/alfresco-js-api/blob/develop/src/api/content-rest-api/docs/NodePaging.md)`>` - Details of the folder - **Returns** `Observable<NodePaging>` - Details of the folder
- **getFolderNode**(nodeId: `string`, includeFields: `string[]` = `[]`): [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`NodeEntry`](https://github.com/Alfresco/alfresco-js-api/blob/master/src/alfresco-core-rest-api/docs/NodeEntry.md)`>`<br/> - **getFolderNode**(nodeId: `string`, includeFields: `string[]` = `[]`): `Observable<NodeEntry>`<br/>
Gets a folder node via its node ID. Gets a folder node via its node ID.
- _nodeId:_ `string` - ID of the folder node - _nodeId:_ `string` - ID of the folder node
- _includeFields:_ `string[]` - Extra information to include (available options are "aspectNames", "isLink" and "association") - _includeFields:_ `string[]` - Extra information to include (available options are "aspectNames", "isLink" and "association")
- **Returns** [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`NodeEntry`](https://github.com/Alfresco/alfresco-js-api/blob/master/src/alfresco-core-rest-api/docs/NodeEntry.md)`>` - Details of the folder - **Returns** `Observable<NodeEntry>` - Details of the folder
- **getNode**(nodeId: `string`, includeFields: `string[]` = `[]`): [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`MinimalNode`](https://github.com/Alfresco/alfresco-js-api/blob/master/src/alfresco-core-rest-api/docs/NodeMinimalEntry.md)`>`<br/> - **getNode**(nodeId: `string`, includeFields: `string[]` = `[]`): `Observable<MinimalNode>`<br/>
Gets a node via its node ID. Gets a node via its node ID.
- _nodeId:_ `string` - ID of the target node - _nodeId:_ `string` - ID of the target node
- _includeFields:_ `string[]` - Extra information to include (available options are "aspectNames", "isLink" and "association") - _includeFields:_ `string[]` - Extra information to include (available options are "aspectNames", "isLink" and "association")
- **Returns** [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`MinimalNode`](https://github.com/Alfresco/alfresco-js-api/blob/master/src/alfresco-core-rest-api/docs/NodeMinimalEntry.md)`>` - Details of the folder - **Returns** `Observable<MinimalNode>` - Details of the folder
- **isCustomSourceService**(nodeId: `any`): `boolean`<br/> - **isCustomSourceService**(nodeId: `any`): `boolean`<br/>
- _nodeId:_ `any` - - _nodeId:_ `any` -
- **Returns** `boolean` - - **Returns** `boolean` -
- **loadFolderByNodeId**(nodeId: `string`, pagination: [`PaginationModel`](../../../lib/core/src/lib/models/pagination.model.ts), includeFields: `string[]`, where?: `string`, orderBy?: `string[]`): [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`DocumentLoaderNode`](../../../lib/content-services/src/lib/document-list/models/document-folder.model.ts)`>`<br/> - **loadFolderByNodeId**(nodeId: `string`, pagination: `PaginationModel`, includeFields: `string[]`, where?: `string`, orderBy?: `string[]`): `Observable<DocumentLoaderNode>`<br/>
Load a folder by Node Id. Load a folder by Node Id.
- _nodeId:_ `string` - ID of the folder node - _nodeId:_ `string` - ID of the folder node
- _pagination:_ [`PaginationModel`](../../../lib/core/src/lib/models/pagination.model.ts) - - _pagination:_ `PaginationModel` - pagination model
- _includeFields:_ `string[]` - List of data field names to include in the results - _includeFields:_ `string[]` - List of data field names to include in the results
- _where:_ `string` - (Optional) Optionally filter the list - _where:_ `string` - (Optional) Optionally filter the list
- _orderBy:_ `string[]` - (Optional) order by node property - _orderBy:_ `string[]` - (Optional) order by node property
- **Returns** [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`DocumentLoaderNode`](../../../lib/content-services/src/lib/document-list/models/document-folder.model.ts)`>` - Details of the folder - **Returns** `Observable<DocumentLoaderNode>` - Details of the folder
- **moveNode**(nodeId: `string`, targetParentId: `string`): [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`NodeEntry`](https://github.com/Alfresco/alfresco-js-api/blob/master/src/alfresco-core-rest-api/docs/NodeEntry.md)`>`<br/> - **moveNode**(nodeId: `string`, targetParentId: `string`): `Observable<NodeEntry>`<br/>
Moves a node to destination node. Moves a node to destination node.
- _nodeId:_ `string` - The id of the node to be moved - _nodeId:_ `string` - The id of the node to be moved
- _targetParentId:_ `string` - The id of the folder where the node will be moved - _targetParentId:_ `string` - The id of the folder where the node will be moved
- **Returns** [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`NodeEntry`](https://github.com/Alfresco/alfresco-js-api/blob/master/src/alfresco-core-rest-api/docs/NodeEntry.md)`>` - NodeEntry for the moved node - **Returns** `Observable<NodeEntry>` - NodeEntry for the moved node
## Details ## Details

View File

@ -126,6 +126,44 @@ describe('DocumentList', () => {
fixture.destroy(); fixture.destroy();
}); });
it('should reset selection and reload on documentListService reload$', () => {
spyOn(documentList, 'resetSelection').and.callThrough();
spyOn(documentList, 'reload').and.callThrough();
documentListService.reload();
expect(documentList.resetSelection).toHaveBeenCalled();
expect(documentList.reload).toHaveBeenCalled();
});
it('should not reset selection or reload after component is destroyed', () => {
spyOn(documentList, 'resetSelection').and.callThrough();
spyOn(documentList, 'reload').and.callThrough();
documentList.ngOnDestroy();
documentListService.reload();
expect(documentList.resetSelection).not.toHaveBeenCalled();
expect(documentList.reload).not.toHaveBeenCalled();
});
it('should reset selection when resetSelection$ is emitted', () => {
spyOn(documentList, 'resetSelection').and.callThrough();
documentListService.resetSelection();
expect(documentList.resetSelection).toHaveBeenCalled();
});
it('should not reset selection after component is destroyed', () => {
spyOn(documentList, 'resetSelection').and.callThrough();
documentList.ngOnDestroy();
documentListService.resetSelection();
expect(documentList.resetSelection).not.toHaveBeenCalled();
});
describe('presets', () => { describe('presets', () => {
const validatePreset = (keys: string[]) => { const validatePreset = (keys: string[]) => {
const columns = documentList.data.getColumns(); const columns = documentList.data.getColumns();

View File

@ -517,6 +517,15 @@ export class DocumentListComponent extends DataTableSchema implements OnInit, On
if (this.columnsPresetKey) { if (this.columnsPresetKey) {
this.setPresetKey(this.columnsPresetKey); this.setPresetKey(this.columnsPresetKey);
} }
this.documentListService.reload$.pipe(takeUntil(this.onDestroy$)).subscribe(() => {
this.resetSelection();
this.reload();
});
this.documentListService.resetSelection$.pipe(takeUntil(this.onDestroy$)).subscribe(() => {
this.resetSelection();
});
} }
ngAfterContentInit() { ngAfterContentInit() {

View File

@ -74,6 +74,20 @@ describe('DocumentListService', () => {
jasmine.Ajax.install(); jasmine.Ajax.install();
}); });
it('should emit resetSelection$ when resetSelection is called', (done) => {
service.resetSelection$.subscribe(() => {
done();
});
service.resetSelection();
});
it('should emit reload$ when reload is called', (done) => {
service.reload$.subscribe(() => {
done();
});
service.reload();
});
afterEach(() => { afterEach(() => {
jasmine.Ajax.uninstall(); jasmine.Ajax.uninstall();
}); });

View File

@ -17,10 +17,10 @@
import { AlfrescoApiService, PaginationModel } from '@alfresco/adf-core'; import { AlfrescoApiService, PaginationModel } from '@alfresco/adf-core';
import { NodesApiService } from '../../common/services/nodes-api.service'; import { NodesApiService } from '../../common/services/nodes-api.service';
import { Injectable } from '@angular/core'; import { inject, Injectable } from '@angular/core';
import { Node, NodeEntry, NodePaging, NodesApi } from '@alfresco/js-api'; import { Node, NodeEntry, NodePaging, NodesApi } from '@alfresco/js-api';
import { DocumentLoaderNode } from '../models/document-folder.model'; import { DocumentLoaderNode } from '../models/document-folder.model';
import { Observable, from, forkJoin } from 'rxjs'; import { Observable, from, forkJoin, Subject } from 'rxjs';
import { map } from 'rxjs/operators'; import { map } from 'rxjs/operators';
import { DocumentListLoader } from '../interfaces/document-list-loader.interface'; import { DocumentListLoader } from '../interfaces/document-list-loader.interface';
import { CustomResourcesService } from './custom-resources.service'; import { CustomResourcesService } from './custom-resources.service';
@ -31,17 +31,34 @@ const ROOT_ID = '-root-';
providedIn: 'root' providedIn: 'root'
}) })
export class DocumentListService implements DocumentListLoader { export class DocumentListService implements DocumentListLoader {
private nodesApiService = inject(NodesApiService);
private apiService = inject(AlfrescoApiService);
private customResourcesService = inject(CustomResourcesService);
private _nodesApi: NodesApi; private _nodesApi: NodesApi;
get nodes(): NodesApi { get nodes(): NodesApi {
this._nodesApi = this._nodesApi ?? new NodesApi(this.apiService.getInstance()); this._nodesApi = this._nodesApi ?? new NodesApi(this.apiService.getInstance());
return this._nodesApi; return this._nodesApi;
} }
constructor( private _reload = new Subject<void>();
private nodesApiService: NodesApiService, private _resetSelection = new Subject<void>();
private apiService: AlfrescoApiService,
private customResourcesService: CustomResourcesService /** Gets an observable that emits when the document list should be reloaded. */
) {} reload$ = this._reload.asObservable();
/** Gets an observable that emits when the selection should be reset. */
resetSelection$ = this._resetSelection.asObservable();
/** Reloads the document list. */
reload() {
this._reload.next();
}
/** Resets the selection. */
resetSelection() {
this._resetSelection.next();
}
/** /**
* Deletes a node. * Deletes a node.