diff --git a/docs/content-services/services/legal-hold.service.md b/docs/content-services/services/legal-hold.service.md
index 6ddb4408d4..ecd5905ad1 100644
--- a/docs/content-services/services/legal-hold.service.md
+++ b/docs/content-services/services/legal-hold.service.md
@@ -18,11 +18,13 @@ Manages holds for nodes.
- _filePlanId_: `string` - The identifier of a file plan. You can also use the -filePlan- alias
- _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
+
- **createHold**(filePlanId: `string`, hold: [`HoldBody`](../../../lib/js-api/src/api/gs-core-rest-api/docs/HoldBody.md)): [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`HoldEntry`](../../../lib/js-api/src/api/gs-core-rest-api/docs/HoldEntry.md)`>`
Create new hold in File Plan.
- _filePlanId_: `string` - The identifier of a file plan. You can also use the -filePlan- alias
- _hold_: [`HoldBody`](../../../lib/js-api/src/api/gs-core-rest-api/docs/HoldBody.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
+
- **createHolds**(filePlanId: `string`, holds: [`HoldBody`](../../../lib/js-api/src/api/gs-core-rest-api/docs/HoldBody.md)`[]`): [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`Hold`](../../../lib/js-api/src/api/gs-core-rest-api/docs/Hold.md)`[]>`
Create new holds in File Plan.
- _filePlanId_: `string` - The identifier of a file plan. You can also use the -filePlan- alias
@@ -33,7 +35,7 @@ Manages holds for nodes.
Assign a node 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
- - **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)`<`[`HoldPaging`](../../../lib/js-api/src/api/gs-core-rest-api/docs/HoldPaging.md)`>`
Assign multiple nodes to a hold.
@@ -47,6 +49,20 @@ Manages holds for nodes.
- _nodeId_: `string` - The Id of the node which is unassigned
- **Returns** [`Observable`](http://reactivex.io/documentation/observable.html)``
+- **bulkAssignHold**(holdId: `string`, query: [`RequestQuery`](../../../lib/js-api/src/api/search-rest-api/docs/RequestQuery.md)): [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`BulkAssignHoldResponse`](../../../lib/js-api/src/api/gs-core-rest-api/docs/BulkAssignHoldResponse.md)`>`
+ Assign multiple files to a hold.
+ - _holdId_: `string` - The hold id
+ - _query_: [`RequestQuery`](../../../lib/js-api/src/api/search-rest-api/docs/RequestQuery.md) - Search query
+ - **Returns** [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`BulkAssignHoldResponse`](../../../lib/js-api/src/api/gs-core-rest-api/docs/BulkAssignHoldResponse.md)`>` - Bulk status
+
+- **bulkAssignHoldToFolder**(holdId: `string`, folderId: `string`, language: `string`): [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`BulkAssignHoldResponse`](../../../lib/js-api/src/api/gs-core-rest-api/docs/BulkAssignHoldResponse.md)`>`
+ Assign a folder to a hold.
+ - _holdId_: `string` - The hold id
+ - _folderId_: `string` - The folder id
+ - _language_: `string` - Language code. `afts` can be used for search query
+
+ - **Returns** [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`BulkAssignHoldResponse`](../../../lib/js-api/src/api/gs-core-rest-api/docs/BulkAssignHoldResponse.md)`>` - Bulk status
+
## Details
diff --git a/lib/content-services/src/lib/category/services/category.service.spec.ts b/lib/content-services/src/lib/category/services/category.service.spec.ts
index 21bce87407..4e62690fad 100644
--- a/lib/content-services/src/lib/category/services/category.service.spec.ts
+++ b/lib/content-services/src/lib/category/services/category.service.spec.ts
@@ -25,7 +25,8 @@ import {
ResultNode,
ResultSetPaging,
ResultSetPagingList,
- ResultSetRowEntry
+ ResultSetRowEntry,
+ SEARCH_LANGUAGE
} from '@alfresco/js-api';
import { fakeAsync, TestBed } from '@angular/core/testing';
import { CategoryService } from './category.service';
@@ -122,7 +123,7 @@ describe('CategoryService', () => {
categoryService.searchCategories(name, skipCount, maxItems);
expect(categoryService.searchApi.search).toHaveBeenCalledWith({
query: {
- language: 'afts',
+ language: SEARCH_LANGUAGE.AFTS,
query: `cm:name:"*${name}*" AND TYPE:'cm:category' AND PATH:"/cm:categoryRoot/cm:generalclassifiable//*"`
},
paging: {
@@ -139,7 +140,7 @@ describe('CategoryService', () => {
categoryService.searchCategories(name);
expect(categoryService.searchApi.search).toHaveBeenCalledWith({
query: {
- language: 'afts',
+ language: SEARCH_LANGUAGE.AFTS,
query: `cm:name:"*${name}*" AND TYPE:'cm:category' AND PATH:"/cm:categoryRoot/cm:generalclassifiable//*"`
},
paging: {
diff --git a/lib/content-services/src/lib/category/services/category.service.ts b/lib/content-services/src/lib/category/services/category.service.ts
index ba9a8b8fff..f2ce9861ac 100644
--- a/lib/content-services/src/lib/category/services/category.service.ts
+++ b/lib/content-services/src/lib/category/services/category.service.ts
@@ -17,7 +17,16 @@
import { Injectable } from '@angular/core';
import { AlfrescoApiService, AppConfigService, UserPreferencesService } from '@alfresco/adf-core';
-import { CategoriesApi, CategoryBody, CategoryEntry, CategoryLinkBody, CategoryPaging, ResultSetPaging, SearchApi } from '@alfresco/js-api';
+import {
+ CategoriesApi,
+ CategoryBody,
+ CategoryEntry,
+ CategoryLinkBody,
+ CategoryPaging,
+ ResultSetPaging,
+ SearchApi,
+ SEARCH_LANGUAGE
+} from '@alfresco/js-api';
import { from, Observable } from 'rxjs';
@Injectable({ providedIn: 'root' })
@@ -113,7 +122,7 @@ export class CategoryService {
return from(
this.searchApi.search({
query: {
- language: 'afts',
+ language: SEARCH_LANGUAGE.AFTS,
query: `cm:name:"*${name}*" AND TYPE:'cm:category' AND PATH:"/cm:categoryRoot/cm:generalclassifiable//*"`
},
paging: {
@@ -163,6 +172,6 @@ export class CategoryService {
* @returns boolean true if categories plugin is enabled, false otherwise.
*/
areCategoriesEnabled(): boolean {
- return this.appConfigService.get('plugins.categoriesEnabled', true);
+ return this.appConfigService.get('plugins.categoriesEnabled', true);
}
}
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 e1bdc890e1..3ca09d12c2 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
@@ -43,7 +43,10 @@ export class NodesApiService {
return this._nodesApi;
}
- constructor(private apiService: AlfrescoApiService, private preferences: UserPreferencesService) {}
+ constructor(
+ private apiService: AlfrescoApiService,
+ private preferences: UserPreferencesService
+ ) {}
private getEntryFromEntity(entity: NodeEntry): Node {
return entity.entry;
@@ -164,82 +167,10 @@ export class NodesApiService {
* @param nodeId ID of the target node
* @returns Node metadata
*/
- public getNodeMetadata(nodeId: string): Observable {
+ getNodeMetadata(nodeId: string): Observable {
return from(this.nodesApi.getNode(nodeId)).pipe(map(this.cleanMetadataFromSemicolon));
}
- /**
- * Create a new Node from form metadata.
- *
- * @param nodeType Node type
- * @param nameSpace Namespace for properties
- * @param data Property data to store in the node under namespace
- * @param path Path to the node
- * @param name Node name
- * @returns The created node
- */
- public createNodeMetadata(nodeType: string, nameSpace: any, data: any, path: string, name?: string): Observable {
- const properties = {};
- for (const key in data) {
- if (data[key]) {
- properties[nameSpace + ':' + key] = data[key];
- }
- }
-
- return this.createNodeInsideRoot(name || this.randomNodeName(), nodeType, properties, path);
- }
-
- private randomNodeName(): string {
- return `node_${Date.now()}`;
- }
-
- /**
- * Gets content for the given node.
- *
- * @param nodeId ID of the target node
- * @returns Content data
- */
- getNodeContent(nodeId: string): Observable {
- return from(this.nodesApi.getNodeContent(nodeId)).pipe(catchError((err) => throwError(err)));
- }
-
- /**
- * Create a new Node inside `-root-` folder
- *
- * @param name Node name
- * @param nodeType Node type
- * @param properties Node body properties
- * @param path Path to the node
- * @returns The created node
- */
- public createNodeInsideRoot(name: string, nodeType: string, properties: any, path: string): Observable {
- const body = {
- name,
- nodeType,
- properties,
- relativePath: path
- };
- return from(this.nodesApi.createNode('-root-', body, {}));
- }
-
- private cleanMetadataFromSemicolon(nodeEntry: NodeEntry): NodeMetadata {
- const metadata = {};
-
- if (nodeEntry?.entry.properties) {
- for (const key in nodeEntry.entry.properties) {
- if (key) {
- if (key.indexOf(':') !== -1) {
- metadata[key.split(':')[1]] = nodeEntry.entry.properties[key];
- } else {
- metadata[key] = nodeEntry.entry.properties[key];
- }
- }
- }
- }
-
- return new NodeMetadata(metadata, nodeEntry.entry.nodeType);
- }
-
/**
* Gets the list of holds assigned to the node.
*
@@ -266,4 +197,76 @@ export class NodesApiService {
)
);
}
+
+ /**
+ * Gets content for the given node.
+ *
+ * @param nodeId ID of the target node
+ * @returns Content data
+ */
+ getNodeContent(nodeId: string): Observable {
+ return from(this.nodesApi.getNodeContent(nodeId)).pipe(catchError((err) => throwError(err)));
+ }
+
+ /**
+ * Create a new Node inside `-root-` folder
+ *
+ * @param name Node name
+ * @param nodeType Node type
+ * @param properties Node body properties
+ * @param path Path to the node
+ * @returns The created node
+ */
+ createNodeInsideRoot(name: string, nodeType: string, properties: any, path: string): Observable {
+ const body = {
+ name,
+ nodeType,
+ properties,
+ relativePath: path
+ };
+ return from(this.nodesApi.createNode('-root-', body, {}));
+ }
+
+ /**
+ * Create a new Node from form metadata.
+ *
+ * @param nodeType Node type
+ * @param nameSpace Namespace for properties
+ * @param data Property data to store in the node under namespace
+ * @param path Path to the node
+ * @param name Node name
+ * @returns The created node
+ */
+ createNodeMetadata(nodeType: string, nameSpace: any, data: any, path: string, name?: string): Observable {
+ const properties = {};
+ for (const key in data) {
+ if (data[key]) {
+ properties[nameSpace + ':' + key] = data[key];
+ }
+ }
+
+ return this.createNodeInsideRoot(name || this.randomNodeName(), nodeType, properties, path);
+ }
+
+ private randomNodeName(): string {
+ return `node_${Date.now()}`;
+ }
+
+ private cleanMetadataFromSemicolon(nodeEntry: NodeEntry): NodeMetadata {
+ const metadata = {};
+
+ if (nodeEntry?.entry.properties) {
+ for (const key in nodeEntry.entry.properties) {
+ if (key) {
+ if (key.indexOf(':') !== -1) {
+ metadata[key.split(':')[1]] = nodeEntry.entry.properties[key];
+ } else {
+ metadata[key] = nodeEntry.entry.properties[key];
+ }
+ }
+ }
+ }
+
+ return new NodeMetadata(metadata, nodeEntry.entry.nodeType);
+ }
}
diff --git a/lib/content-services/src/lib/document-list/services/custom-resources.service.ts b/lib/content-services/src/lib/document-list/services/custom-resources.service.ts
index 0cd4c9778e..61b0281bd8 100644
--- a/lib/content-services/src/lib/document-list/services/custom-resources.service.ts
+++ b/lib/content-services/src/lib/document-list/services/custom-resources.service.ts
@@ -31,7 +31,8 @@ import {
TrashcanApi,
NodesApi,
SitePaging,
- ResultSetPaging
+ ResultSetPaging,
+ SEARCH_LANGUAGE
} from '@alfresco/js-api';
import { Injectable } from '@angular/core';
import { Observable, from, of } from 'rxjs';
@@ -136,7 +137,7 @@ export class CustomResourcesService {
const query: SearchRequest = {
query: {
query: '*',
- language: 'afts'
+ language: SEARCH_LANGUAGE.AFTS
},
filterQueries,
include: ['path', 'properties', 'allowableOperations', 'aspectNames'],
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
index 94b87cf43f..d08cd13ec2 100644
--- 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
@@ -16,7 +16,7 @@
*/
import { AlfrescoApiService } from '@alfresco/adf-core';
-import { ContentPagingQuery, Hold, HoldBody, HoldEntry, HoldPaging, LegalHoldApi } from '@alfresco/js-api';
+import { BulkAssignHoldResponse, ContentPagingQuery, Hold, HoldBody, HoldEntry, HoldPaging, LegalHoldApi, RequestQuery } from '@alfresco/js-api';
import { Injectable } from '@angular/core';
import { Observable, from } from 'rxjs';
import { map } from 'rxjs/operators';
@@ -105,4 +105,32 @@ export class LegalHoldService {
createHolds(filePlanId: string, holds: HoldBody[]): Observable {
return from(this.legalHoldApi.createHolds(filePlanId, holds));
}
+
+ /**
+ * Start the asynchronous bulk process for a hold with id holdId based on search query results.
+ *
+ * @param holdId The identifier of a hold
+ * @param query Search query
+ * @returns Observable
+ */
+ bulkAssignHold(holdId: string, query: RequestQuery): Observable {
+ return from(this.legalHoldApi.bulkAssignHold(holdId, query));
+ }
+
+ /**
+ * Assign a folder to a hold.
+ *
+ * @param holdId The identifier of a hold
+ * @param folderId The identifier of a folder
+ * @param language Language code
+ * @returns Observable
+ */
+ bulkAssignHoldToFolder(holdId: string, folderId: string, language: string): Observable {
+ const query: RequestQuery = {
+ query: `ANCESTOR:'workspace://SpacesStore/${folderId}' and TYPE:content`,
+ language
+ };
+
+ return from(this.legalHoldApi.bulkAssignHold(holdId, query));
+ }
}
diff --git a/lib/content-services/src/lib/legal-hold/services/legal-holds.service.spec.ts b/lib/content-services/src/lib/legal-hold/services/legal-holds.service.spec.ts
index c9c149c790..1e5a64a04b 100644
--- a/lib/content-services/src/lib/legal-hold/services/legal-holds.service.spec.ts
+++ b/lib/content-services/src/lib/legal-hold/services/legal-holds.service.spec.ts
@@ -18,14 +18,17 @@
import { TestBed } from '@angular/core/testing';
import { LegalHoldService } from './legal-hold.service';
import { ContentTestingModule } from '../../testing/content.testing.module';
-import { Hold, HoldEntry, HoldPaging } from '@alfresco/js-api';
+import { BulkAssignHoldResponse, Hold, HoldEntry, HoldPaging, RequestQuery, SEARCH_LANGUAGE } from '@alfresco/js-api';
describe('LegalHoldsService', () => {
let service: LegalHoldService;
let legalHolds: HoldPaging;
let legalHoldEntry: HoldEntry;
let returnedHolds: Hold[];
- const mockId = 'mockId';
+ const filePlanId = 'mockId';
+ const nodeId = 'mockNodeId';
+ const holdId = 'holdId';
+ const mockBulkResponse: BulkAssignHoldResponse = { totalItems: 3, bulkStatusId: 'bulkStatus' };
beforeEach(() => {
TestBed.configureTestingModule({
@@ -41,7 +44,7 @@ describe('LegalHoldsService', () => {
legalHoldEntry = {
entry: {
- id: mockId,
+ id: holdId,
name: 'some name',
reason: 'some reason',
description: 'some description'
@@ -50,10 +53,12 @@ describe('LegalHoldsService', () => {
returnedHolds = [
{
- id: mockId,
+ id: holdId,
name: 'some name'
}
];
+
+ spyOn(service.legalHoldApi, 'bulkAssignHold').and.returnValue(Promise.resolve(mockBulkResponse));
});
it('should be created', () => {
@@ -64,9 +69,9 @@ describe('LegalHoldsService', () => {
it('should return array of Hold interface', (done) => {
spyOn(service.legalHoldApi, 'getHolds').and.returnValue(Promise.resolve(legalHolds));
- service.getHolds(mockId).subscribe((holds) => {
+ service.getHolds(filePlanId).subscribe((holds) => {
expect(holds).toEqual(returnedHolds);
- expect(service.legalHoldApi.getHolds).toHaveBeenCalledWith(mockId, undefined);
+ expect(service.legalHoldApi.getHolds).toHaveBeenCalledWith(filePlanId, undefined);
done();
});
});
@@ -74,8 +79,6 @@ describe('LegalHoldsService', () => {
describe('assignHold', () => {
it('should assign node to existing hold', (done) => {
- const nodeId = 'qwe';
- const holdId = 'foo';
const mockResponse = { entry: { id: holdId } };
spyOn(service.legalHoldApi, 'assignHold').and.returnValue(Promise.resolve(mockResponse));
@@ -90,7 +93,6 @@ describe('LegalHoldsService', () => {
describe('assignHolds', () => {
it('should assign nodes to existing hold', (done) => {
const nodeIds = [{ id: 'qwe' }, { id: 'abc' }];
- const holdId = 'foo';
spyOn(service.legalHoldApi, 'assignHolds').and.returnValue(Promise.resolve(legalHolds));
service.assignHolds(nodeIds, holdId).subscribe((holds) => {
@@ -103,9 +105,6 @@ describe('LegalHoldsService', () => {
describe('unassignHold', () => {
it('should unassign node from existing hold', (done) => {
- const nodeId = 'qwe';
- const holdId = 'foo';
-
spyOn(service.legalHoldApi, 'unassignHold').and.returnValue(Promise.resolve(undefined));
service.unassignHold(holdId, nodeId).subscribe(() => {
@@ -123,9 +122,9 @@ describe('LegalHoldsService', () => {
};
spyOn(service.legalHoldApi, 'createHold').and.returnValue(Promise.resolve(legalHoldEntry));
- service.createHold(mockId, mockHold).subscribe((hold) => {
+ service.createHold(filePlanId, mockHold).subscribe((hold) => {
expect(hold).toEqual(legalHoldEntry);
- expect(service.legalHoldApi.createHold).toHaveBeenCalledWith(mockId, mockHold);
+ expect(service.legalHoldApi.createHold).toHaveBeenCalledWith(filePlanId, mockHold);
done();
});
});
@@ -145,9 +144,40 @@ describe('LegalHoldsService', () => {
];
spyOn(service.legalHoldApi, 'createHolds').and.returnValue(Promise.resolve(legalHolds));
- service.createHolds(mockId, mockHolds).subscribe((holds) => {
+ service.createHolds(filePlanId, mockHolds).subscribe((holds) => {
expect(holds).toEqual(legalHolds);
- expect(service.legalHoldApi.createHolds).toHaveBeenCalledWith(mockId, mockHolds);
+ expect(service.legalHoldApi.createHolds).toHaveBeenCalledWith(filePlanId, mockHolds);
+ done();
+ });
+ });
+ });
+
+ describe('bulkAssignHold', () => {
+ it('should add nodes to hold based on search query results', (done) => {
+ const query: RequestQuery = {
+ query: 'mockQuery',
+ language: SEARCH_LANGUAGE.AFTS
+ };
+
+ service.bulkAssignHold(nodeId, query).subscribe((response) => {
+ expect(response).toEqual(mockBulkResponse);
+ expect(service.legalHoldApi.bulkAssignHold).toHaveBeenCalledWith(nodeId, query);
+ done();
+ });
+ });
+ });
+
+ describe('bulkAssignHoldToFolder', () => {
+ it('should add nodes to hold based on search query results', (done) => {
+ const folderId = 'mockFolderId';
+ const query: RequestQuery = {
+ query: `ANCESTOR:'workspace://SpacesStore/${folderId}' and TYPE:content`,
+ language: SEARCH_LANGUAGE.AFTS
+ };
+
+ service.bulkAssignHoldToFolder(nodeId, folderId, SEARCH_LANGUAGE.AFTS).subscribe((response) => {
+ expect(response).toEqual(mockBulkResponse);
+ expect(service.legalHoldApi.bulkAssignHold).toHaveBeenCalledWith(nodeId, query);
done();
});
});
diff --git a/lib/content-services/src/lib/mock/search-query.mock.ts b/lib/content-services/src/lib/mock/search-query.mock.ts
index 5d1943a21b..7b5fb008b7 100644
--- a/lib/content-services/src/lib/mock/search-query.mock.ts
+++ b/lib/content-services/src/lib/mock/search-query.mock.ts
@@ -15,12 +15,12 @@
* limitations under the License.
*/
-import { SearchRequest } from '@alfresco/js-api';
+import { SEARCH_LANGUAGE, SearchRequest } from '@alfresco/js-api';
export const mockSearchRequest = {
query: {
query: '(search-term*)',
- language: 'afts'
+ language: SEARCH_LANGUAGE.AFTS
},
include: ['path', 'allowableOperations'],
paging: {
diff --git a/lib/content-services/src/lib/search/services/base-query-builder.service.ts b/lib/content-services/src/lib/search/services/base-query-builder.service.ts
index c312fe7b3c..ab3773780e 100644
--- a/lib/content-services/src/lib/search/services/base-query-builder.service.ts
+++ b/lib/content-services/src/lib/search/services/base-query-builder.service.ts
@@ -24,7 +24,8 @@ import {
ResultSetPaging,
RequestHighlight,
RequestScope,
- SearchApi
+ SearchApi,
+ SEARCH_LANGUAGE
} from '@alfresco/js-api';
import { SearchCategory } from '../models/search-category.interface';
import { FilterQuery } from '../models/filter-query.interface';
@@ -86,7 +87,10 @@ export abstract class BaseQueryBuilderService {
// TODO: to be supported in future iterations
ranges: { [id: string]: SearchRange } = {};
- protected constructor(protected appConfig: AppConfigService, protected alfrescoApiService: AlfrescoApiService) {
+ protected constructor(
+ protected appConfig: AppConfigService,
+ protected alfrescoApiService: AlfrescoApiService
+ ) {
this.resetToDefaults();
}
@@ -342,7 +346,7 @@ export abstract class BaseQueryBuilderService {
const result: SearchRequest = {
query: {
query,
- language: 'afts'
+ language: SEARCH_LANGUAGE.AFTS
},
include,
paging: this.paging,
@@ -456,9 +460,9 @@ export abstract class BaseQueryBuilderService {
end: set.end,
startInclusive: set.startInclusive,
endInclusive: set.endInclusive
- } as any)
+ }) as any
)
- } as any)
+ }) as any
)
};
}
@@ -517,7 +521,7 @@ export abstract class BaseQueryBuilderService {
limit: facet.limit,
offset: facet.offset,
prefix: facet.prefix
- } as any)
+ }) as any
)
};
}
diff --git a/lib/core/src/lib/styles/_mat-selectors.scss b/lib/core/src/lib/styles/_mat-selectors.scss
index 0900e160ac..ab97021fcc 100644
--- a/lib/core/src/lib/styles/_mat-selectors.scss
+++ b/lib/core/src/lib/styles/_mat-selectors.scss
@@ -35,6 +35,7 @@ $mat-progress-bar: '.mat-mdc-progress-bar';
$mat-progress-spinner: '.mat-mdc-progress-spinner';
$mat-form-field: '.mat-mdc-form-field';
$mat-form-field-flex: '.mat-mdc-form-field-flex';
+$mat-form-field-outline: '.mat-mdc-form-field-outline';
$mat-form-field-wrapper: '.mat-mdc-text-field-wrapper';
$mat-line-ripple: '.mdc-line-ripple';
$mat-form-field-subscript-wrapper: '.mat-mdc-form-field-subscript-wrapper';
diff --git a/lib/extensions/src/lib/config/action.extensions.ts b/lib/extensions/src/lib/config/action.extensions.ts
index 3a7d3c31a7..4585def128 100644
--- a/lib/extensions/src/lib/config/action.extensions.ts
+++ b/lib/extensions/src/lib/config/action.extensions.ts
@@ -30,6 +30,7 @@ export interface ContentActionRef extends ExtensionElement {
type: ContentActionType;
title?: string;
+ tooltip?: string;
description?: string;
icon?: string;
children?: Array;
diff --git a/lib/js-api/index.ts b/lib/js-api/index.ts
index c447218ebe..4615a3ca45 100644
--- a/lib/js-api/index.ts
+++ b/lib/js-api/index.ts
@@ -42,3 +42,4 @@ export * from './src/to-deprecate/alfresco-api-type';
export * from './src/api-clients/api-client';
export * from './src/api-clients/http-client.interface';
export * from './src/utils';
+export * from './src/constants';
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
index b1f28b461f..c29af3f9e3 100644
--- 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
@@ -19,6 +19,8 @@ import { BaseApi } from './base.api';
import { throwIfNotDefined } from '../../../assert';
import { ContentPagingQuery } from '../../content-rest-api';
import { HoldBody, HoldEntry, HoldPaging } from './../model';
+import { BulkAssignHoldResponse } from '../model/bulkAssignHoldResponse';
+import { RequestQuery } from '../../search-rest-api';
/**
* Legal Holds service.
@@ -153,4 +155,25 @@ export class LegalHoldApi extends BaseApi {
returnType: HoldPaging
});
}
+
+ /**
+ * Start the asynchronous bulk process for a hold with id holdId based on search query results.
+ *
+ * @param holdId The identifier of a hold
+ * @param query Search query
+ * @returns Promise
+ */
+ bulkAssignHold(holdId: string, query: RequestQuery): Promise {
+ throwIfNotDefined(holdId, 'holdId');
+ throwIfNotDefined(query, 'query');
+
+ return this.post({
+ path: `/holds/{holdId}/bulk`,
+ pathParams: { holdId },
+ bodyParam: {
+ query,
+ op: 'ADD'
+ }
+ });
+ }
}
diff --git a/lib/js-api/src/api/gs-core-rest-api/docs/BulkAssignHoldResponse.md b/lib/js-api/src/api/gs-core-rest-api/docs/BulkAssignHoldResponse.md
new file mode 100644
index 0000000000..fbf584c21e
--- /dev/null
+++ b/lib/js-api/src/api/gs-core-rest-api/docs/BulkAssignHoldResponse.md
@@ -0,0 +1,17 @@
+# BulkAssignHoldResponse
+
+## Basic usage
+
+```ts
+export interface BulkAssignHoldResponse {
+ bulkStatusId: string;
+ totalItems: number;
+}
+```
+
+## Properties
+
+| Name | Type | Default value | Description |
+| ---------------- | ---------- | ------------- | ---------------------------------------- |
+| **bulkStatusId** | **string** | | Indentifier of Bulk Status |
+| **totalItems** | **number** | **0** | Amount of total nodes assigned to a hold |
diff --git a/lib/js-api/src/api/gs-core-rest-api/docs/LegalHoldApi.md b/lib/js-api/src/api/gs-core-rest-api/docs/LegalHoldApi.md
index dd4b3e497a..0e6bf6832e 100644
--- a/lib/js-api/src/api/gs-core-rest-api/docs/LegalHoldApi.md
+++ b/lib/js-api/src/api/gs-core-rest-api/docs/LegalHoldApi.md
@@ -8,8 +8,9 @@ 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 |
| [**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 |
-[**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
+| [**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 |
+| [**bulkAssignHold**](LegalHoldApi.md#bulkAssignHold) | **POST** /holds/{holdId}/bulk | Bulk add of nodes to the hold |
@@ -133,7 +134,7 @@ legalHoldApi.assignHolds([{ id: 'foo' }, { id: 'bar' }], 'holdId').then(
### Parameters
| Name | Type | Default value | Description |
-| ----------- |----------------------| ------------- | ---------------------------------------------------- |
+| ----------- | -------------------- | ------------- | ---------------------------------------------------- |
| **nodeIds** | **{ id: string }[]** | | The list with id of nodes to assign to existing hold |
| **holdId** | **string** | | The identifier of a hold. |
@@ -184,7 +185,9 @@ legalHoldApi.unassignHold('holdId', 'nodeId').then(
**void**
+
# **createHold**
+
> HoldEntry createHold(filePlanId, holds)
Create legal hold.
@@ -202,33 +205,35 @@ this.alfrescoApi.setConfig({
const legalHoldApi = new LegalHoldApi(this.alfrescoApi);
-const hold = {
- name: 'Hold 1',
- reason: 'Reason 1'
+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);
-});
-
+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.
+| Name | Type | Default value | Description |
+| -------------- | ---------- | ------------- | ---------------- |
+| **filePlanId** | **string** | | The site details |
+| **hold** | **Hold** | | Hold to create. |
### Return type
[**HoldEntry**](./HoldEntry.md)
+
# **createHolds**
-> HoldPaging createHolds(filePlanId, holds)
Create legal holds list.
@@ -245,8 +250,8 @@ this.alfrescoApi.setConfig({
const legalHoldApi = new LegalHoldApi(this.alfrescoApi);
-let opts = [
- {
+let holds = [
+ {
name: 'Hold 1',
reason: 'Reason 1'
},
@@ -257,21 +262,65 @@ let opts = [
}
];
-legalHoldApi.createHolds('-filePlan-', holds).then((data) => {
- console.log('API called successfully. Returned data: ' + data);
-}, function(error) {
- console.error(error);
-});
-
+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.
+| Name | Type | Default value | Description |
+| -------------- | ---------- | ------------- | ------------------- |
+| **filePlanId** | **string** | | The site details |
+| **holds** | **Hold[]** | | Array of new holds. |
### Return type
[**HoldPaging**](./HoldPaging.md)
+
+
+
+# **bulkAssignHold**
+
+> BulkAssignHoldResponse bulkAssignHold(holdId, query)
+
+Start the asynchronous bulk process for a hold with id `holdId` based on search query results.
+
+### 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);
+
+legalHoldApi.bulkAssignHold('holdId', { query: 'SITE:swsdp and TYPE:content', language: 'afts' }).then(
+ (data) => {
+ console.log('API called successfully. Returned data: ' + data);
+ },
+ function (error) {
+ console.error(error);
+ }
+);
+```
+
+### Parameters
+
+| Name | Type | Default value | Description |
+| ------------ | ---------- | ------------- | ------------------------ |
+| **holdId** | **string** | | The identifier of a hold |
+| **query** | **RequestQuery** | | Search query. |
+
+### Return type
+
+[**BulkAssignHoldResponse**](./BulkAssignHoldResponse.md)
diff --git a/lib/js-api/src/api/gs-core-rest-api/model/bulkAssignHoldResponse.ts b/lib/js-api/src/api/gs-core-rest-api/model/bulkAssignHoldResponse.ts
new file mode 100644
index 0000000000..578e2eac93
--- /dev/null
+++ b/lib/js-api/src/api/gs-core-rest-api/model/bulkAssignHoldResponse.ts
@@ -0,0 +1,21 @@
+/*!
+ * @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 interface BulkAssignHoldResponse {
+ bulkStatusId: string;
+ totalItems: number;
+}
diff --git a/lib/js-api/src/api/gs-core-rest-api/model/index.ts b/lib/js-api/src/api/gs-core-rest-api/model/index.ts
index c184d0cc74..bd8c7fff0c 100644
--- a/lib/js-api/src/api/gs-core-rest-api/model/index.ts
+++ b/lib/js-api/src/api/gs-core-rest-api/model/index.ts
@@ -79,3 +79,4 @@ export * from './holdBody';
export * from './holdEntry';
export * from './holdPaging';
export * from './holdPagingList';
+export * from './bulkAssignHoldResponse';
diff --git a/lib/js-api/src/constants/index.ts b/lib/js-api/src/constants/index.ts
new file mode 100644
index 0000000000..3364aff71b
--- /dev/null
+++ b/lib/js-api/src/constants/index.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 './language.constants';
diff --git a/lib/js-api/src/constants/language.constants.ts b/lib/js-api/src/constants/language.constants.ts
new file mode 100644
index 0000000000..e7e14408aa
--- /dev/null
+++ b/lib/js-api/src/constants/language.constants.ts
@@ -0,0 +1,22 @@
+/*!
+ * @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 const SEARCH_LANGUAGE = {
+ AFTS: 'afts',
+ LUCENE: 'lucene',
+ CMIS: 'cmis'
+};
diff --git a/lib/js-api/src/index.ts b/lib/js-api/src/index.ts
index 568ba99356..9498d241cc 100644
--- a/lib/js-api/src/index.ts
+++ b/lib/js-api/src/index.ts
@@ -42,3 +42,4 @@ export * from './to-deprecate/alfresco-api-type';
export * from './api-clients/api-client';
export * from './api-clients/http-client.interface';
export * from './utils';
+export * from './constants';
diff --git a/lib/js-api/test/mockObjects/content-services/search.mock.ts b/lib/js-api/test/mockObjects/content-services/search.mock.ts
index 16e83e277b..d2d9127d48 100644
--- a/lib/js-api/test/mockObjects/content-services/search.mock.ts
+++ b/lib/js-api/test/mockObjects/content-services/search.mock.ts
@@ -17,6 +17,7 @@
import nock from 'nock';
import { BaseMock } from '../base.mock';
+import { SEARCH_LANGUAGE } from '@alfresco/js-api';
export class SearchMock extends BaseMock {
get200Response(): void {
@@ -24,7 +25,7 @@ export class SearchMock extends BaseMock {
.post('/alfresco/api/-default-/public/search/versions/1/search', {
query: {
query: 'select * from cmis:folder',
- language: 'cmis'
+ language: SEARCH_LANGUAGE.CMIS
}
})
.reply(200, {
diff --git a/lib/js-api/test/searchApi.spec.spec.ts b/lib/js-api/test/searchApi.spec.spec.ts
index 077b834558..233556cf9f 100644
--- a/lib/js-api/test/searchApi.spec.spec.ts
+++ b/lib/js-api/test/searchApi.spec.spec.ts
@@ -16,7 +16,7 @@
*/
import assert from 'assert';
-import { AlfrescoApi, SearchApi } from '../src';
+import { AlfrescoApi, SEARCH_LANGUAGE, SearchApi } from '../src';
import { EcmAuthMock, SearchMock } from './mockObjects';
describe('Search', () => {
@@ -50,7 +50,7 @@ describe('Search', () => {
.search({
query: {
query: 'select * from cmis:folder',
- language: 'cmis'
+ language: SEARCH_LANGUAGE.CMIS
}
})
.then((data) => {