diff --git a/lib/content-services/src/lib/common/services/nodes-api.service.ts b/lib/content-services/src/lib/common/services/nodes-api.service.ts index e258b0439d..c927dcddd2 100644 --- a/lib/content-services/src/lib/common/services/nodes-api.service.ts +++ b/lib/content-services/src/lib/common/services/nodes-api.service.ts @@ -16,7 +16,7 @@ */ import { Injectable } from '@angular/core'; -import { NodeEntry, NodePaging, NodesApi, TrashcanApi, Node, NodeHold } from '@alfresco/js-api'; +import { NodeEntry, NodePaging, NodesApi, TrashcanApi, Node, Hold } from '@alfresco/js-api'; import { Subject, from, Observable, throwError } from 'rxjs'; import { AlfrescoApiService, UserPreferencesService } from '@alfresco/adf-core'; import { catchError, map } from 'rxjs/operators'; @@ -246,14 +246,14 @@ export class NodesApiService { * @param nodeId ID of the target node * @returns List of assigned holds */ - getNodeAssignHolds(nodeId: string): Observable { + getNodeAssignHolds(nodeId: string): Observable { const queryOptions = Object.assign({ maxItems: this.preferences.paginationSize, skipCount: 0, where: `(assocType='rma:frozenContent')` }); - return from(this.nodesApi.listAssignedHolds(nodeId, queryOptions)).pipe( + return from(this.nodesApi.listParents(nodeId, queryOptions)).pipe( map((holds) => holds.list?.entries?.map((entity) => ({ id: entity.entry.id, diff --git a/lib/js-api/src/api/content-rest-api/model/nodeAssinedHoldsPaging.ts b/lib/content-services/src/lib/legal-hold/index.ts similarity index 63% rename from lib/js-api/src/api/content-rest-api/model/nodeAssinedHoldsPaging.ts rename to lib/content-services/src/lib/legal-hold/index.ts index 3669707610..54beb1a252 100644 --- a/lib/js-api/src/api/content-rest-api/model/nodeAssinedHoldsPaging.ts +++ b/lib/content-services/src/lib/legal-hold/index.ts @@ -15,15 +15,4 @@ * limitations under the License. */ -import { NodeAssignedHoldPagingList } from './nodeAssignedHoldPagingList'; - -export class NodeAssignedHoldPaging { - list?: NodeAssignedHoldPagingList; - - constructor(input?: Partial) { - if (input) { - Object.assign(this, input); - this.list = input.list ? new NodeAssignedHoldPagingList(input.list) : undefined; - } - } -} +export * from './public-api'; diff --git a/lib/content-services/src/lib/legal-hold/public-api.ts b/lib/content-services/src/lib/legal-hold/public-api.ts new file mode 100644 index 0000000000..70ec7d89c7 --- /dev/null +++ b/lib/content-services/src/lib/legal-hold/public-api.ts @@ -0,0 +1,18 @@ +/*! + * @license + * Copyright © 2005-2024 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. + */ + +export * from './services/legal-hold.service'; diff --git a/lib/content-services/src/lib/legal-hold/services/legal-hold.service.ts b/lib/content-services/src/lib/legal-hold/services/legal-hold.service.ts new file mode 100644 index 0000000000..2a61bd7351 --- /dev/null +++ b/lib/content-services/src/lib/legal-hold/services/legal-hold.service.ts @@ -0,0 +1,61 @@ +/*! + * @license + * Copyright © 2005-2024 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 { AlfrescoApiService } from '@alfresco/adf-core'; +import { ContentPagingQuery, Hold, LegalHoldApi } from '@alfresco/js-api'; +import { Injectable } from '@angular/core'; +import { Observable, from, throwError } from 'rxjs'; +import { catchError, map } from 'rxjs/operators'; + +@Injectable({ + providedIn: 'root' +}) +export class LegalHoldService { + private _legalHoldApi: LegalHoldApi; + get legalHoldApi(): LegalHoldApi { + this._legalHoldApi = this._legalHoldApi ?? new LegalHoldApi(this.apiService.getInstance()); + return this._legalHoldApi; + } + + constructor(private apiService: AlfrescoApiService) {} + + /** + * Gets the list of holds assigned to the node. + * + * @param filePlanId The identifier of a file plan. You can also use the -filePlan- alias. + * @param options Optional parameters supported by JS-API + * @returns List of assigned holds + */ + getHolds(filePlanId: string, options: ContentPagingQuery = {}): Observable { + const queryOptions = Object.assign({ + maxItems: options?.maxItems, + skipCount: options?.skipCount + }); + + return from(this.legalHoldApi.getHolds(filePlanId, queryOptions)).pipe( + map((holds) => + holds.list?.entries?.map((entity) => ({ + id: entity.entry.id, + name: entity.entry.name, + reason: entity.entry.reason, + description: entity.entry.description + })) + ), + catchError((err) => throwError(err)) + ); + } +} diff --git a/lib/js-api/src/api/content-rest-api/model/nodeAssignedHoldPagingList.ts b/lib/content-services/src/lib/legal-hold/services/legal-holds.service.spec.ts similarity index 53% rename from lib/js-api/src/api/content-rest-api/model/nodeAssignedHoldPagingList.ts rename to lib/content-services/src/lib/legal-hold/services/legal-holds.service.spec.ts index 3c32be7fec..32de1ff55a 100644 --- a/lib/js-api/src/api/content-rest-api/model/nodeAssignedHoldPagingList.ts +++ b/lib/content-services/src/lib/legal-hold/services/legal-holds.service.spec.ts @@ -15,20 +15,18 @@ * limitations under the License. */ -import { Pagination } from '..'; -import { NodeAssignedHoldEntry } from './nodeAssignedHoldEntry'; +import { TestBed } from '@angular/core/testing'; +import { LegalHoldService } from './legal-hold.service'; -export class NodeAssignedHoldPagingList { - pagination: Pagination; - entries: NodeAssignedHoldEntry[]; +describe('LegalHoldsService', () => { + let service: LegalHoldService; - constructor(input?: Partial) { - if (input) { - Object.assign(this, input); - this.pagination = input.pagination ? new Pagination(input.pagination) : undefined; - if (input.entries) { - this.entries = input.entries.map((item) => new NodeAssignedHoldEntry(item)); - } - } - } -} + beforeEach(() => { + TestBed.configureTestingModule({}); + service = TestBed.inject(LegalHoldService); + }); + + it('should be created', () => { + expect(service).toBeTruthy(); + }); +}); diff --git a/lib/content-services/src/public-api.ts b/lib/content-services/src/public-api.ts index 7a8de43f2d..950a0b18c1 100644 --- a/lib/content-services/src/public-api.ts +++ b/lib/content-services/src/public-api.ts @@ -45,5 +45,6 @@ export * from './lib/viewer/index'; export * from './lib/security/index'; export * from './lib/infinite-scroll-datasource'; export * from './lib/prediction/index'; +export * from './lib/legal-hold/index'; export * from './lib/content.module'; diff --git a/lib/js-api/src/api/content-rest-api/api/nodes.api.ts b/lib/js-api/src/api/content-rest-api/api/nodes.api.ts index 1f0abe347c..3a551af21a 100644 --- a/lib/js-api/src/api/content-rest-api/api/nodes.api.ts +++ b/lib/js-api/src/api/content-rest-api/api/nodes.api.ts @@ -34,7 +34,6 @@ import { BaseApi } from './base.api'; import { throwIfNotDefined } from '../../../assert'; import { buildCollectionParam } from '../../../alfrescoApiClient'; import { ContentPagingQuery } from './types'; -import { NodeAssignedHoldPaging } from '../model/nodeAssinedHoldsPaging'; export type NodesIncludeQuery = { /** @@ -983,48 +982,4 @@ export class NodesApi extends BaseApi { returnType: DirectAccessUrlEntry }); } - - /** - * List Assigned Holds - * - * **Note:** this endpoint is available in Alfresco 7.1 and newer versions. - * - * Gets a list of assigned holds that are associated with the current **nodeId**. - * - * @param nodeId The identifier of a child node. You can also use one of these well-known aliases: - * - -my- - * - -shared- - * - -root- - * @param opts Optional parameters - * @param opts.where Optionally filter the list by **frozenContent**: - * - where=(assocType='rma:frozenContent') - * @returns Promise - */ - - listAssignedHolds( - nodeId: string, - opts?: { - where?: string; - } & ContentPagingQuery - ): Promise { - throwIfNotDefined(nodeId, 'nodeId'); - opts = opts || {}; - - const pathParams = { - nodeId - }; - - const queryParams = { - where: opts?.where, - skipCount: opts?.skipCount, - maxItems: opts?.maxItems - }; - - return this.get({ - path: '/nodes/{nodeId}/parents', - pathParams, - queryParams, - returnType: NodeAssignedHoldPaging - }); - } } diff --git a/lib/js-api/src/api/content-rest-api/model/index.ts b/lib/js-api/src/api/content-rest-api/model/index.ts index a21d94d20c..40193439e3 100644 --- a/lib/js-api/src/api/content-rest-api/model/index.ts +++ b/lib/js-api/src/api/content-rest-api/model/index.ts @@ -199,7 +199,4 @@ export * from './versionPagingList'; export * from './deletedNode'; export * from './nodeAssociation'; export * from './nodeChildAssociation'; -export * from './nodeAssignedHoldPagingList'; -export * from './nodeAssinedHoldsPaging'; -export * from './nodeAssignedHoldEntry'; -export * from './nodeAssignedHold'; +export * from './nodeHold'; diff --git a/lib/js-api/src/api/content-rest-api/model/nodeAssignedHold.ts b/lib/js-api/src/api/content-rest-api/model/nodeAssignedHold.ts deleted file mode 100644 index 4b109bbe0c..0000000000 --- a/lib/js-api/src/api/content-rest-api/model/nodeAssignedHold.ts +++ /dev/null @@ -1,48 +0,0 @@ -/*! - * @license - * Copyright © 2005-2024 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 { DateAlfresco } from '../../content-custom-api'; -import { UserInfo } from './userInfo'; -import { ChildAssociationInfo } from './childAssociationInfo'; - -export class NodeAssignedHold { - id: string; - /** - * The name must not contain spaces or the following special characters: * \" < > \\ / ? : and |. - * The character . must not be used at the end of the name. - */ - name: string; - nodeType: string; - isFolder: boolean; - isFile: boolean; - modifiedAt: Date; - modifiedByUser: UserInfo; - createdAt: Date; - createdByUser: UserInfo; - parentId?: string; - association?: ChildAssociationInfo; - - constructor(input?: Partial) { - if (input) { - Object.assign(this, input); - this.modifiedAt = input.modifiedAt ? DateAlfresco.parseDate(input.modifiedAt) : undefined; - this.modifiedByUser = input.modifiedByUser ? new UserInfo(input.modifiedByUser) : undefined; - this.createdAt = input.createdAt ? DateAlfresco.parseDate(input.createdAt) : undefined; - this.createdByUser = input.createdByUser ? new UserInfo(input.createdByUser) : undefined; - } - } -} diff --git a/lib/js-api/src/api/content-rest-api/model/nodeChildAssociation.ts b/lib/js-api/src/api/content-rest-api/model/nodeChildAssociation.ts index 253d04c36b..4231ec3aae 100644 --- a/lib/js-api/src/api/content-rest-api/model/nodeChildAssociation.ts +++ b/lib/js-api/src/api/content-rest-api/model/nodeChildAssociation.ts @@ -49,6 +49,8 @@ export class NodeChildAssociation { permissions?: PermissionsInfo; definition?: Definition; association?: ChildAssociationInfo; + reason?: string; + description?: string; constructor(input?: Partial) { if (input) { diff --git a/lib/js-api/src/api/content-rest-api/model/nodeAssignedHoldEntry.ts b/lib/js-api/src/api/content-rest-api/model/nodeHold.ts similarity index 69% rename from lib/js-api/src/api/content-rest-api/model/nodeAssignedHoldEntry.ts rename to lib/js-api/src/api/content-rest-api/model/nodeHold.ts index 16afa4e824..0eeb4c4a2d 100644 --- a/lib/js-api/src/api/content-rest-api/model/nodeAssignedHoldEntry.ts +++ b/lib/js-api/src/api/content-rest-api/model/nodeHold.ts @@ -15,15 +15,19 @@ * limitations under the License. */ -import { NodeAssignedHold } from './nodeAssignedHold'; +export class NodeHold { + id: string; + /** + * The name must not contain spaces or the following special characters: * \" < > \\ / ? : and |. + * The character . must not be used at the end of the name. + */ + name: string; + reason: string; + description: string; -export class NodeAssignedHoldEntry { - entry: NodeAssignedHold; - - constructor(input?: Partial) { + constructor(input?: Partial) { if (input) { Object.assign(this, input); - this.entry = input.entry ? new NodeAssignedHold(input.entry) : undefined; } } } diff --git a/lib/js-api/src/api/gs-classification-rest-api/model/nodeHold.ts b/lib/js-api/src/api/gs-classification-rest-api/model/nodeHold.ts index f395068745..edabc1d414 100644 --- a/lib/js-api/src/api/gs-classification-rest-api/model/nodeHold.ts +++ b/lib/js-api/src/api/gs-classification-rest-api/model/nodeHold.ts @@ -15,7 +15,7 @@ * limitations under the License. */ -export interface NodeHold { +export interface Hold { id: string; name: string; reason?: string; diff --git a/lib/js-api/src/api/gs-core-rest-api/api/index.ts b/lib/js-api/src/api/gs-core-rest-api/api/index.ts index 087eb26628..4df05570a1 100644 --- a/lib/js-api/src/api/gs-core-rest-api/api/index.ts +++ b/lib/js-api/src/api/gs-core-rest-api/api/index.ts @@ -26,3 +26,4 @@ export * from './transferContainers.api'; export * from './transfers.api'; export * from './unfiledContainers.api'; export * from './unfiledRecordFolders.api'; +export * from './legal-hold.api'; diff --git a/lib/js-api/src/api/gs-core-rest-api/api/legal-hold.api.ts b/lib/js-api/src/api/gs-core-rest-api/api/legal-hold.api.ts new file mode 100644 index 0000000000..72be0f88cc --- /dev/null +++ b/lib/js-api/src/api/gs-core-rest-api/api/legal-hold.api.ts @@ -0,0 +1,54 @@ +/*! + * @license + * Copyright © 2005-2024 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 { BaseApi } from './base.api'; +import { throwIfNotDefined } from '../../../assert'; +import { ContentPagingQuery, NodeChildAssociationPaging } from '../../content-rest-api'; + +/** + * Legal Holds service. + * + * @module RecordsApi + */ +export class LegalHoldApi extends BaseApi { + /** + * List of legal holds + * + * @param filePlanId The identifier of a file plan. You can also use the -filePlan- alias. + * @param opts Optional parameters + * @returns Promise + */ + getHolds(filePlanId: string = '-filePlan-', opts?: ContentPagingQuery): Promise { + throwIfNotDefined(filePlanId, 'filePlanId'); + + const pathParams = { + filePlanId + }; + + const queryParams = { + skipCount: opts?.skipCount, + maxItems: opts?.maxItems + }; + + return this.get({ + path: '/file-plans/{filePlanId}/holds', + pathParams, + queryParams, + returnType: NodeChildAssociationPaging + }); + } +}