mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2025-07-24 17:32:15 +00:00
[ACS-7690] Saving adding o a new hold (#9862)
* ACS-7689 Save and delete to existing hold * ACS-7689 Save and delete to existing hold, cleanup * ACS-7689 Save and delete to existing hold, revert to separate methods * ACS-7689 Save and delete to existing hold, fix specs * ACS-7689 Save and delete to existing hold, fix specs * ACS-7689 Save and delete to existing hold * ACS-8055 add listAssignedHolds API * ACS-8055 create legal-hold service * ACS-8055 add documentation * ACS-8055 fix imports * ACS-8055 add HoldPaging class and documentation * ACS-8055 add interface and fix test * ACS-7689 Save and delete to existing hold, fix specs * ACS-7689 Save and delete to existing hold, fix specs * ACS-7690 integrate create and assign holds endpoints * ACS-7690 fix imports * ACS-7690 add bulk method * ACS-7690 update readme file * ACS-7690 add tests * ACS-7690 update docs file * ACS-7690 remove interface * ACS-7690 update geHolds description and md file with createHold * ACS-7690 add createHolds to md file * ACS-7690 fix typo in spec, and description in legal-hold service * ACS-7690 refactor create hold parameter and documentation * ACS-7690 fixed test * ACS-7690 fix test for getHolds * ACS-7690 fix md for create hold action * ACS-7690 fix rebase conflicts --------- Co-authored-by: Tomasz Nastaly <tomasz.nastaly@hyland.com> Co-authored-by: DaryaBalvanovich <darya.balvanovich1@hyland.com>
This commit is contained in:
@@ -5,7 +5,7 @@ Status: Active
|
|||||||
Last reviewed: 2024-06-19
|
Last reviewed: 2024-06-19
|
||||||
---
|
---
|
||||||
|
|
||||||
# [Legal Hold service](../../../lib/content-services/src/lib/legal-hold/services/legal-hold.service.ts) "Defined in legal-hold.service.ts"
|
# [Legal Hold service](../../../lib/content-services/src/lib/legal-hold/services/legal-hold.service.ts "Defined in legal-hold.service.ts")
|
||||||
|
|
||||||
Manages holds for nodes.
|
Manages holds for nodes.
|
||||||
|
|
||||||
@@ -17,15 +17,25 @@ Manages holds for nodes.
|
|||||||
Gets the list of holds for a node.
|
Gets the list of holds for a node.
|
||||||
- _filePlanId_: `string` - The identifier of a file plan. You can also use the -filePlan- alias
|
- _filePlanId_: `string` - The identifier of a file plan. You can also use the -filePlan- alias
|
||||||
- _options_: `ContentPagingQuery` - Optional parameters supported by JS-API
|
- _options_: `ContentPagingQuery` - Optional parameters supported by JS-API
|
||||||
- **Returns** [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`Hold`](../../../lib/js-api/src/api/gs-core-rest-api/docs/Hold.md)`[]>` - List of holds
|
- **Returns** [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`Hold`](../../../lib/js-api/src/api/gs-core-rest-api/docs/Hold.md)`[]>` - List of holds <br/>
|
||||||
|
- **createHold**(filePlanId: `string`, hold: [`Hold`](../../../lib/js-api/src/api/gs-core-rest-api/docs/Hold.md)): [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`HoldEntry`](../../../lib/js-api/src/api/gs-core-rest-api/docs/HoldEntry.md)`>`<br/>
|
||||||
|
Create new hold in File Plan.
|
||||||
|
- _filePlanId_: `string` - The identifier of a file plan. You can also use the -filePlan- alias
|
||||||
|
- _hold_: [`Hold`](../../../lib/js-api/src/api/gs-core-rest-api/docs/Hold.md) - Hold that should be created
|
||||||
|
- **Returns** [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`HoldEntry`](../../../lib/js-api/src/api/gs-core-rest-api/docs/HoldEntry.md)`>` - Hold entry<br/>
|
||||||
|
- **createHolds**(filePlanId: `string`, holds: [`Hold`](../../../lib/js-api/src/api/gs-core-rest-api/docs/Hold.md)`[]`): [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`Hold`](../../../lib/js-api/src/api/gs-core-rest-api/docs/Hold.md)`[]>`<br/>
|
||||||
|
Create new holds in File Plan.
|
||||||
|
- _filePlanId_: `string` - The identifier of a file plan. You can also use the -filePlan- alias
|
||||||
|
- _holds_: `<`[`Hold`](../../../lib/js-api/src/api/gs-core-rest-api/docs/Hold.md)`[]>` - Array of holds that should be created
|
||||||
|
- **Returns** [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`HoldPaging`](../../../lib/js-api/src/api/gs-core-rest-api/docs/HoldPaging.md)`>` - List of paginated holds entries
|
||||||
|
|
||||||
- **assignHold**(nodeId: `string`, holdId: `string`): [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`Hold`](../../../lib/js-api/src/api/gs-core-rest-api/docs/Hold.md)`>`<br/>
|
- **assignHold**(nodeId: `string`, holdId: `string`): [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`HoldEntry`](../../../lib/js-api/src/api/gs-core-rest-api/docs/HoldEntry.md)`>`<br/>
|
||||||
Assign a node to a hold.
|
Assign a node to a hold.
|
||||||
- _nodeId_: `string` - The Id of the node which will be assigned to a hold
|
- _nodeId_: `string` - The Id of the node which will be assigned to a hold
|
||||||
- _holdId_: `string` - The Id of the hold to which nodes will be assigned
|
- _holdId_: `string` - The Id of the hold to which nodes will be assigned
|
||||||
- **Returns** [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`HoldEntry`](../../../lib/js-api/src/api/gs-core-rest-api/docs/HoldEntry.md)`>` - Entry with the hold
|
- **Returns** [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`HoldEntry`](../../../lib/js-api/src/api/gs-core-rest-api/docs/HoldEntry.md)`>` - Entry with the hold
|
||||||
|
|
||||||
- **assignHolds**(nodeIds: `<{id: string}[]>`, holdId: `string`): [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`Hold`](../../../lib/js-api/src/api/gs-core-rest-api/docs/HoldPaging.md)`>`<br/>
|
- **assignHolds**(nodeIds: `<{id: string}[]>`, holdId: `string`): [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`HoldPaging`](../../../lib/js-api/src/api/gs-core-rest-api/docs/HoldPaging.md)`>`<br/>
|
||||||
Assign a node to a hold.
|
Assign a node to a hold.
|
||||||
- _nodeIds_: `<{id: string}[]>` - The Ids of the nodes which will be assigned to a hold
|
- _nodeIds_: `<{id: string}[]>` - The Ids of the nodes which will be assigned to a hold
|
||||||
- _holdId_: `string` - The Id of the hold to which nodes will be assigned
|
- _holdId_: `string` - The Id of the hold to which nodes will be assigned
|
||||||
|
@@ -34,7 +34,7 @@ export class LegalHoldService {
|
|||||||
constructor(private readonly apiService: AlfrescoApiService) {}
|
constructor(private readonly apiService: AlfrescoApiService) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the list of holds.
|
* Gets the list of holds available in the file plan.
|
||||||
*
|
*
|
||||||
* @param filePlanId The identifier of a file plan. You can also use the -filePlan- alias.
|
* @param filePlanId The identifier of a file plan. You can also use the -filePlan- alias.
|
||||||
* @param options Optional parameters supported by JS-API
|
* @param options Optional parameters supported by JS-API
|
||||||
@@ -83,4 +83,26 @@ export class LegalHoldService {
|
|||||||
unassignHold(holdId: string, nodeId: string): Observable<void> {
|
unassignHold(holdId: string, nodeId: string): Observable<void> {
|
||||||
return from(this.legalHoldApi.unassignHold(holdId, nodeId));
|
return from(this.legalHoldApi.unassignHold(holdId, nodeId));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create hold.
|
||||||
|
*
|
||||||
|
* @param filePlanId The identifier of a file plan. You can also use the -filePlan- alias.
|
||||||
|
* @param hold Hold to create
|
||||||
|
* @returns List of created holds Observable<HoldEntry>
|
||||||
|
*/
|
||||||
|
createHold(filePlanId: string, hold: Hold): Observable<HoldEntry> {
|
||||||
|
return from(this.legalHoldApi.createHold(filePlanId, hold));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create list of holds.
|
||||||
|
*
|
||||||
|
* @param filePlanId The identifier of a file plan. You can also use the -filePlan- alias.
|
||||||
|
* @param holds Array of holds to create
|
||||||
|
* @returns List of created holds Observable<HoldPaging>
|
||||||
|
*/
|
||||||
|
createHolds(filePlanId: string, holds: Hold[]): Observable<HoldPaging> {
|
||||||
|
return from(this.legalHoldApi.createHolds(filePlanId, holds));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -18,11 +18,12 @@
|
|||||||
import { TestBed } from '@angular/core/testing';
|
import { TestBed } from '@angular/core/testing';
|
||||||
import { LegalHoldService } from './legal-hold.service';
|
import { LegalHoldService } from './legal-hold.service';
|
||||||
import { ContentTestingModule } from '../../testing/content.testing.module';
|
import { ContentTestingModule } from '../../testing/content.testing.module';
|
||||||
import { Hold, HoldPaging } from '@alfresco/js-api';
|
import { Hold, HoldEntry, HoldPaging } from '@alfresco/js-api';
|
||||||
|
|
||||||
describe('LegalHoldsService', () => {
|
describe('LegalHoldsService', () => {
|
||||||
let service: LegalHoldService;
|
let service: LegalHoldService;
|
||||||
let legalHolds: HoldPaging;
|
let legalHolds: HoldPaging;
|
||||||
|
let legalHoldEntry: HoldEntry;
|
||||||
let returnedHolds: Hold[];
|
let returnedHolds: Hold[];
|
||||||
const mockId = 'mockId';
|
const mockId = 'mockId';
|
||||||
|
|
||||||
@@ -34,24 +35,23 @@ describe('LegalHoldsService', () => {
|
|||||||
|
|
||||||
legalHolds = {
|
legalHolds = {
|
||||||
list: {
|
list: {
|
||||||
entries: [
|
entries: [legalHoldEntry]
|
||||||
{
|
|
||||||
entry: {
|
|
||||||
id: mockId,
|
|
||||||
name: 'some name',
|
|
||||||
reason: 'some description'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
} as HoldPaging;
|
} as HoldPaging;
|
||||||
|
|
||||||
|
legalHoldEntry = {
|
||||||
|
entry: {
|
||||||
|
id: mockId,
|
||||||
|
name: 'some name',
|
||||||
|
reason: 'some reason',
|
||||||
|
description: 'some description'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
returnedHolds = [
|
returnedHolds = [
|
||||||
{
|
{
|
||||||
id: mockId,
|
id: mockId,
|
||||||
name: 'some name',
|
name: 'some name'
|
||||||
reason: 'some description',
|
|
||||||
description: undefined
|
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
});
|
});
|
||||||
@@ -66,7 +66,7 @@ describe('LegalHoldsService', () => {
|
|||||||
|
|
||||||
service.getHolds(mockId).subscribe((holds) => {
|
service.getHolds(mockId).subscribe((holds) => {
|
||||||
expect(holds).toEqual(returnedHolds);
|
expect(holds).toEqual(returnedHolds);
|
||||||
expect(service.legalHoldApi.getHolds).toHaveBeenCalledWith(mockId, {});
|
expect(service.legalHoldApi.getHolds).toHaveBeenCalledWith(mockId, undefined);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -89,7 +89,7 @@ describe('LegalHoldsService', () => {
|
|||||||
|
|
||||||
describe('assignHolds', () => {
|
describe('assignHolds', () => {
|
||||||
it('should assign nodes to existing hold', (done) => {
|
it('should assign nodes to existing hold', (done) => {
|
||||||
const nodeIds = [{ id: 'qwe' }, { id: 'abc'}];
|
const nodeIds = [{ id: 'qwe' }, { id: 'abc' }];
|
||||||
const holdId = 'foo';
|
const holdId = 'foo';
|
||||||
spyOn(service.legalHoldApi, 'assignHolds').and.returnValue(Promise.resolve(legalHolds));
|
spyOn(service.legalHoldApi, 'assignHolds').and.returnValue(Promise.resolve(legalHolds));
|
||||||
|
|
||||||
@@ -114,4 +114,42 @@ describe('LegalHoldsService', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('createHold', () => {
|
||||||
|
it('should create new hold', (done) => {
|
||||||
|
const mockHold = {
|
||||||
|
name: 'Hold 1',
|
||||||
|
reason: 'reason 1'
|
||||||
|
};
|
||||||
|
spyOn(service.legalHoldApi, 'createHold').and.returnValue(Promise.resolve(legalHoldEntry));
|
||||||
|
|
||||||
|
service.createHold(mockId, mockHold).subscribe((hold) => {
|
||||||
|
expect(hold).toEqual(legalHoldEntry);
|
||||||
|
expect(service.legalHoldApi.createHold).toHaveBeenCalledWith(mockId, mockHold);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('createHolds', () => {
|
||||||
|
it('should create list of holds', (done) => {
|
||||||
|
const mockHolds = [
|
||||||
|
{
|
||||||
|
name: 'Hold 1',
|
||||||
|
reason: 'reason 1'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Hold 2',
|
||||||
|
reason: 'reason 2'
|
||||||
|
}
|
||||||
|
];
|
||||||
|
spyOn(service.legalHoldApi, 'createHolds').and.returnValue(Promise.resolve(legalHolds));
|
||||||
|
|
||||||
|
service.createHolds(mockId, mockHolds).subscribe((holds) => {
|
||||||
|
expect(holds).toEqual(legalHolds);
|
||||||
|
expect(service.legalHoldApi.createHolds).toHaveBeenCalledWith(mockId, mockHolds);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@@ -18,8 +18,7 @@
|
|||||||
import { BaseApi } from './base.api';
|
import { BaseApi } from './base.api';
|
||||||
import { throwIfNotDefined } from '../../../assert';
|
import { throwIfNotDefined } from '../../../assert';
|
||||||
import { ContentPagingQuery } from '../../content-rest-api';
|
import { ContentPagingQuery } from '../../content-rest-api';
|
||||||
import { HoldPaging } from '../model/holdPaging';
|
import { Hold, HoldEntry, HoldPaging } from './../model';
|
||||||
import { HoldEntry } from '../model';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Legal Holds service.
|
* Legal Holds service.
|
||||||
@@ -108,4 +107,50 @@ export class LegalHoldApi extends BaseApi {
|
|||||||
pathParams: { holdId, nodeId }
|
pathParams: { holdId, nodeId }
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create new hold
|
||||||
|
*
|
||||||
|
* @param filePlanId The identifier of a file plan. You can also use the -filePlan- alias.
|
||||||
|
* @param hold Hold to create
|
||||||
|
* @returns Promise<HoldEntry>
|
||||||
|
*/
|
||||||
|
createHold(filePlanId: string, hold: Hold): Promise<HoldEntry> {
|
||||||
|
throwIfNotDefined(filePlanId, 'filePlanId');
|
||||||
|
throwIfNotDefined(hold, 'hold');
|
||||||
|
|
||||||
|
const pathParams = {
|
||||||
|
filePlanId
|
||||||
|
};
|
||||||
|
|
||||||
|
return this.post({
|
||||||
|
path: '/file-plans/{filePlanId}/holds',
|
||||||
|
pathParams,
|
||||||
|
bodyParam: [hold],
|
||||||
|
returnType: HoldEntry
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create list of new holds
|
||||||
|
*
|
||||||
|
* @param filePlanId The identifier of a file plan. You can also use the -filePlan- alias.
|
||||||
|
* @param holds Array of holds
|
||||||
|
* @returns Promise<HoldPaging>
|
||||||
|
*/
|
||||||
|
createHolds(filePlanId = '-filePlan-', holds: Hold[]): Promise<HoldPaging> {
|
||||||
|
throwIfNotDefined(filePlanId, 'filePlanId');
|
||||||
|
throwIfNotDefined(holds, 'holds');
|
||||||
|
|
||||||
|
const pathParams = {
|
||||||
|
filePlanId
|
||||||
|
};
|
||||||
|
|
||||||
|
return this.post({
|
||||||
|
path: '/file-plans/{filePlanId}/holds',
|
||||||
|
pathParams,
|
||||||
|
bodyParam: holds,
|
||||||
|
returnType: HoldPaging
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -8,6 +8,8 @@ All URIs are relative to _https://localhost/alfresco/api/-default-/public/gs/ver
|
|||||||
| [**assignHold**](LegalHoldApi.md#assignHold) | **POST** /holds/{holdId}/children | Assign node to legal hold |
|
| [**assignHold**](LegalHoldApi.md#assignHold) | **POST** /holds/{holdId}/children | Assign node to legal hold |
|
||||||
| [**assignHolds**](LegalHoldApi.md#assignHolds) | **POST** /holds/{holdId}/children | Assign nodes to legal hold |
|
| [**assignHolds**](LegalHoldApi.md#assignHolds) | **POST** /holds/{holdId}/children | Assign nodes to legal hold |
|
||||||
| [**unassignHold**](LegalHoldApi.md#unassignHold) | **DELETE** /holds/{holdId}/children/{nodeId} | Unassign node from legal hold |
|
| [**unassignHold**](LegalHoldApi.md#unassignHold) | **DELETE** /holds/{holdId}/children/{nodeId} | Unassign node from legal hold |
|
||||||
|
[**createHold**](LegalHoldApi.md#createHold) | **POST** /file-plans/{filePlanId}/holds | Create one hold
|
||||||
|
[**createHolds**](LegalHoldApi.md#createHolds) | **POST** /file-plans/{filePlanId}/holds | Create list of holds
|
||||||
|
|
||||||
<a name="getHolds"></a>
|
<a name="getHolds"></a>
|
||||||
|
|
||||||
@@ -28,7 +30,7 @@ this.alfrescoApi.setConfig({
|
|||||||
hostEcm: 'http://127.0.0.1:8080'
|
hostEcm: 'http://127.0.0.1:8080'
|
||||||
});
|
});
|
||||||
|
|
||||||
let legalHoldApi = new LegalHoldApi(this.alfrescoApi);
|
const legalHoldApi = new LegalHoldApi(this.alfrescoApi);
|
||||||
|
|
||||||
let opts = {
|
let opts = {
|
||||||
'skipCount': 56 // | The number of entities that exist in the collection before those included in this list.
|
'skipCount': 56 // | The number of entities that exist in the collection before those included in this list.
|
||||||
@@ -180,3 +182,96 @@ legalHoldApi.unassignHold('holdId', 'nodeId').then(
|
|||||||
### Return type
|
### Return type
|
||||||
|
|
||||||
**void**
|
**void**
|
||||||
|
|
||||||
|
<a name="createHold"></a>
|
||||||
|
# **createHold**
|
||||||
|
> HoldEntry createHold(filePlanId, holds)
|
||||||
|
|
||||||
|
Create legal hold.
|
||||||
|
|
||||||
|
### Example
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
import LegalHoldApi from 'LegalHoldApi';
|
||||||
|
import { AlfrescoApi } from '@alfresco/js-api';
|
||||||
|
|
||||||
|
this.alfrescoApi = new AlfrescoApi();
|
||||||
|
this.alfrescoApi.setConfig({
|
||||||
|
hostEcm: 'http://127.0.0.1:8080'
|
||||||
|
});
|
||||||
|
|
||||||
|
const legalHoldApi = new LegalHoldApi(this.alfrescoApi);
|
||||||
|
|
||||||
|
const hold = {
|
||||||
|
name: 'Hold 1',
|
||||||
|
reason: 'Reason 1'
|
||||||
|
};
|
||||||
|
|
||||||
|
legalHoldApi.createHold('-filePlan-', hold).then((data) => {
|
||||||
|
console.log('API called successfully. Returned data: ' + data);
|
||||||
|
}, function(error) {
|
||||||
|
console.error(error);
|
||||||
|
});
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
### Parameters
|
||||||
|
|
||||||
|
Name | Type | Default value | Description
|
||||||
|
------------- | ------------- | ------------- | -------------
|
||||||
|
**filePlanId** | **string** | | The site details
|
||||||
|
**hold** | **Hold**| | Hold to create.
|
||||||
|
|
||||||
|
### Return type
|
||||||
|
|
||||||
|
[**HoldEntry**](./HoldEntry.md)
|
||||||
|
|
||||||
|
<a name="createHolds"></a>
|
||||||
|
# **createHolds**
|
||||||
|
> HoldPaging createHolds(filePlanId, holds)
|
||||||
|
|
||||||
|
Create legal holds list.
|
||||||
|
|
||||||
|
### Example
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
import LegalHoldApi from 'LegalHoldApi';
|
||||||
|
import { AlfrescoApi } from '@alfresco/js-api';
|
||||||
|
|
||||||
|
this.alfrescoApi = new AlfrescoApi();
|
||||||
|
this.alfrescoApi.setConfig({
|
||||||
|
hostEcm: 'http://127.0.0.1:8080'
|
||||||
|
});
|
||||||
|
|
||||||
|
const legalHoldApi = new LegalHoldApi(this.alfrescoApi);
|
||||||
|
|
||||||
|
let opts = [
|
||||||
|
{
|
||||||
|
name: 'Hold 1',
|
||||||
|
reason: 'Reason 1'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Hold 2',
|
||||||
|
reason: 'Reason 2',
|
||||||
|
description: 'Description'
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
legalHoldApi.createHolds('-filePlan-', holds).then((data) => {
|
||||||
|
console.log('API called successfully. Returned data: ' + data);
|
||||||
|
}, function(error) {
|
||||||
|
console.error(error);
|
||||||
|
});
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
### Parameters
|
||||||
|
|
||||||
|
Name | Type | Default value | Description
|
||||||
|
------------- | ------------- | ------------- | -------------
|
||||||
|
**filePlanId** | **string** | | The site details
|
||||||
|
**holds** | **Hold[]**| | Array of new holds.
|
||||||
|
|
||||||
|
### Return type
|
||||||
|
|
||||||
|
[**HoldPaging**](./HoldPaging.md)
|
||||||
|
Reference in New Issue
Block a user