From 197e8ff0b8cee93dffecb6d33d8e8da9ff0f1eb2 Mon Sep 17 00:00:00 2001 From: Anton Ramanovich Date: Wed, 11 Mar 2026 15:48:18 +0100 Subject: [PATCH] [ACS-9765]: updated logic for moving/copying dialogs --- .../lib/services/node-actions.service.spec.ts | 57 +++++++++++++++++-- .../src/lib/services/node-actions.service.ts | 9 ++- 2 files changed, 57 insertions(+), 9 deletions(-) diff --git a/projects/aca-content/src/lib/services/node-actions.service.spec.ts b/projects/aca-content/src/lib/services/node-actions.service.spec.ts index 1acb0f9a2..51a57e0cb 100644 --- a/projects/aca-content/src/lib/services/node-actions.service.spec.ts +++ b/projects/aca-content/src/lib/services/node-actions.service.spec.ts @@ -118,7 +118,7 @@ describe('NodeActionsService', () => { spyOn(dialog, 'open').and.returnValue({ afterClosed: of } as unknown as MatDialogRef); - const contentEntities = [new TestNode(), { entry: { nodeId: '1234' } }]; + const contentEntities = [new TestNode(), { entry: { nodeId: '1234', nodeType: 'cm:content' } }]; service.getContentNodeSelection(NodeAction.CHOOSE, contentEntities as NodeEntry[]); const isSelectionValid = dialog.open['calls'].argsFor(0)[1].data.isSelectionValid({ @@ -136,7 +136,7 @@ describe('NodeActionsService', () => { spyOn(dialog, 'open').and.returnValue({ afterClosed: of } as unknown as MatDialogRef); - const contentEntities = [new TestNode(), { entry: { nodeId: '1234' } }]; + const contentEntities = [new TestNode(), { entry: { nodeId: '1234', nodeType: 'cm:content' } }]; service.getContentNodeSelection(NodeAction.CHOOSE, contentEntities as NodeEntry[]); const isSelectionValid = dialog.open['calls'].argsFor(0)[1].data.isSelectionValid({ @@ -154,7 +154,7 @@ describe('NodeActionsService', () => { spyOn(dialog, 'open').and.returnValue({ afterClosed: of } as unknown as MatDialogRef); - const contentEntities = [new TestNode(), { entry: { nodeId: '1234' } }]; + const contentEntities = [new TestNode(), { entry: { nodeId: '1234', nodeType: 'cm:content' } }]; service.getContentNodeSelection(NodeAction.CHOOSE, contentEntities as NodeEntry[]); const isSelectionValid = dialog.open['calls'].argsFor(0)[1].data.isSelectionValid({ @@ -173,7 +173,7 @@ describe('NodeActionsService', () => { spyOn(dialog, 'open').and.returnValue({ afterClosed: of } as unknown as MatDialogRef); - const contentEntities = [new TestNode(), { entry: { nodeId: '1234' } }]; + const contentEntities = [new TestNode(), { entry: { nodeId: '1234', nodeType: 'cm:content' } }]; service.getContentNodeSelection(NodeAction.CHOOSE, contentEntities as NodeEntry[]); const isSelectionValid = dialog.open['calls'].argsFor(0)[1].data.isSelectionValid({ @@ -187,6 +187,51 @@ describe('NodeActionsService', () => { expect(isSelectionValid).toBe(true); }); + + it('should invalidate selection if destination is an RMA system folder', () => { + spyOn(dialog, 'open').and.returnValue({ + afterClosed: of + } as unknown as MatDialogRef); + const contentEntities = [new TestNode(), { entry: { nodeId: '1234', nodeType: 'rma:holdContainer' } }]; + service.getContentNodeSelection(NodeAction.CHOOSE, contentEntities as NodeEntry[]); + + const isSelectionValid = dialog.open['calls'].argsFor(0)[1].data.isSelectionValid({ + name: 'rma-hold-container', + isFile: false, + isFolder: true, + path: { elements: [{}, {}] }, + nodeType: 'rma:holdContainer', + allowableOperations: ['create'] + }); + + expect(isSelectionValid).toBe(false); + }); + + it('should hide search and site dropdown when at least one selected node is RMA-related', () => { + spyOn(dialog, 'open').and.returnValue({ + afterClosed: of + } as unknown as MatDialogRef); + + const contentEntities = [new TestNode('regular-folder-id', false), new TestNode('rma-folder-id', false, 'rma-folder', [], 'rma:holdContainer')]; + service.getContentNodeSelection(NodeAction.CHOOSE, contentEntities as NodeEntry[]); + + const dialogConfig = dialog.open['calls'].argsFor(0)[1].data; + expect(dialogConfig.showSearch).toBe(false); + expect(dialogConfig.showDropdownSiteList).toBe(false); + }); + + it('should show search and site dropdown when selected nodes are not RMA-related', () => { + spyOn(dialog, 'open').and.returnValue({ + afterClosed: of + } as unknown as MatDialogRef); + + const contentEntities = [new TestNode('folder-a-id', false), new TestNode('folder-b-id', false)]; + service.getContentNodeSelection(NodeAction.CHOOSE, contentEntities as NodeEntry[]); + + const dialogConfig = dialog.open['calls'].argsFor(0)[1].data; + expect(dialogConfig.showSearch).toBe(true); + expect(dialogConfig.showDropdownSiteList).toBe(true); + }); }); describe('doBatchOperation', () => { @@ -399,7 +444,7 @@ describe('NodeActionsService', () => { return { componentInstance: {}, afterClosed: of } as unknown as MatDialogRef; }); - service.copyNodes([{ entry: { id: 'entry-id', name: 'entry-name' } }]); + service.copyNodes([{ entry: { id: 'entry-id', name: 'entry-name', nodeType: 'cm:content' } }]); expect(spyOnBatchOperation).toHaveBeenCalled(); expect(dialogData).toBeDefined(); @@ -421,7 +466,7 @@ describe('NodeActionsService', () => { return { componentInstance: {}, afterClosed: of } as unknown as MatDialogRef; }); - service.copyNodes([{ entry: { id: 'entry-id' } }]); + service.copyNodes([{ entry: { id: 'entry-id', nodeType: 'cm:content' } }]); expect(spyOnBatchOperation).toHaveBeenCalled(); expect(dialogData).toBeDefined(); diff --git a/projects/aca-content/src/lib/services/node-actions.service.ts b/projects/aca-content/src/lib/services/node-actions.service.ts index 0d3906c8e..93e258ac2 100644 --- a/projects/aca-content/src/lib/services/node-actions.service.ts +++ b/projects/aca-content/src/lib/services/node-actions.service.ts @@ -37,7 +37,7 @@ import { ContentService } from '@alfresco/adf-content-services'; import { NodeEntry, Node, SitePaging, NodeChildAssociationPaging, NodeChildAssociationEntry, NodesApi, Site, SitePagingList } from '@alfresco/js-api'; -import { ContentApiService } from '@alfresco/aca-shared'; +import { ContentApiService, isRmaContent, isRmaSystemFolder } from '@alfresco/aca-shared'; import { catchError, map, mergeMap } from 'rxjs/operators'; type BatchOperationType = Extract; @@ -170,6 +170,7 @@ export class NodeActionsService { getContentNodeSelection(action: NodeAction, contentEntities: NodeEntry[], focusedElementOnCloseSelector?: string): Subject { const currentParentFolderId = this.getEntryParentId(contentEntities[0].entry); + const isRmaRelated = contentEntities.some((node) => isRmaContent(node.entry)); const customDropdown = new SitePaging({ list: { @@ -205,7 +206,9 @@ export class NodeActionsService { isSelectionValid: this.canCopyMoveInsideIt.bind(this), breadcrumbTransform: this.customizeBreadcrumb.bind(this), select: new Subject(), - excludeSiteContent: ContentNodeDialogService.nonDocumentSiteContent + excludeSiteContent: ContentNodeDialogService.nonDocumentSiteContent, + showSearch: !isRmaRelated, + showDropdownSiteList: !isRmaRelated }; this.dialog @@ -239,7 +242,7 @@ export class NodeActionsService { } private canCopyMoveInsideIt(entry: Node): boolean { - return this.hasEntityCreatePermission(entry) && !this.isSite(entry); + return this.hasEntityCreatePermission(entry) && !this.isSite(entry) && !isRmaSystemFolder(entry); } private hasEntityCreatePermission(entry: Node): boolean {