[ACS-9765]: updated logic for moving/copying dialogs

This commit is contained in:
Anton Ramanovich
2026-03-11 17:21:41 +01:00
parent 9650924493
commit 197e8ff0b8
2 changed files with 57 additions and 9 deletions
@@ -118,7 +118,7 @@ describe('NodeActionsService', () => {
spyOn(dialog, 'open').and.returnValue({ spyOn(dialog, 'open').and.returnValue({
afterClosed: of afterClosed: of
} as unknown as MatDialogRef<any>); } as unknown as MatDialogRef<any>);
const contentEntities = [new TestNode(), { entry: { nodeId: '1234' } }]; const contentEntities = [new TestNode(), { entry: { nodeId: '1234', nodeType: 'cm:content' } }];
service.getContentNodeSelection(NodeAction.CHOOSE, contentEntities as NodeEntry[]); service.getContentNodeSelection(NodeAction.CHOOSE, contentEntities as NodeEntry[]);
const isSelectionValid = dialog.open['calls'].argsFor(0)[1].data.isSelectionValid({ const isSelectionValid = dialog.open['calls'].argsFor(0)[1].data.isSelectionValid({
@@ -136,7 +136,7 @@ describe('NodeActionsService', () => {
spyOn(dialog, 'open').and.returnValue({ spyOn(dialog, 'open').and.returnValue({
afterClosed: of afterClosed: of
} as unknown as MatDialogRef<any>); } as unknown as MatDialogRef<any>);
const contentEntities = [new TestNode(), { entry: { nodeId: '1234' } }]; const contentEntities = [new TestNode(), { entry: { nodeId: '1234', nodeType: 'cm:content' } }];
service.getContentNodeSelection(NodeAction.CHOOSE, contentEntities as NodeEntry[]); service.getContentNodeSelection(NodeAction.CHOOSE, contentEntities as NodeEntry[]);
const isSelectionValid = dialog.open['calls'].argsFor(0)[1].data.isSelectionValid({ const isSelectionValid = dialog.open['calls'].argsFor(0)[1].data.isSelectionValid({
@@ -154,7 +154,7 @@ describe('NodeActionsService', () => {
spyOn(dialog, 'open').and.returnValue({ spyOn(dialog, 'open').and.returnValue({
afterClosed: of afterClosed: of
} as unknown as MatDialogRef<any>); } as unknown as MatDialogRef<any>);
const contentEntities = [new TestNode(), { entry: { nodeId: '1234' } }]; const contentEntities = [new TestNode(), { entry: { nodeId: '1234', nodeType: 'cm:content' } }];
service.getContentNodeSelection(NodeAction.CHOOSE, contentEntities as NodeEntry[]); service.getContentNodeSelection(NodeAction.CHOOSE, contentEntities as NodeEntry[]);
const isSelectionValid = dialog.open['calls'].argsFor(0)[1].data.isSelectionValid({ const isSelectionValid = dialog.open['calls'].argsFor(0)[1].data.isSelectionValid({
@@ -173,7 +173,7 @@ describe('NodeActionsService', () => {
spyOn(dialog, 'open').and.returnValue({ spyOn(dialog, 'open').and.returnValue({
afterClosed: of afterClosed: of
} as unknown as MatDialogRef<any>); } as unknown as MatDialogRef<any>);
const contentEntities = [new TestNode(), { entry: { nodeId: '1234' } }]; const contentEntities = [new TestNode(), { entry: { nodeId: '1234', nodeType: 'cm:content' } }];
service.getContentNodeSelection(NodeAction.CHOOSE, contentEntities as NodeEntry[]); service.getContentNodeSelection(NodeAction.CHOOSE, contentEntities as NodeEntry[]);
const isSelectionValid = dialog.open['calls'].argsFor(0)[1].data.isSelectionValid({ const isSelectionValid = dialog.open['calls'].argsFor(0)[1].data.isSelectionValid({
@@ -187,6 +187,51 @@ describe('NodeActionsService', () => {
expect(isSelectionValid).toBe(true); 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<any>);
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<any>);
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<any>);
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', () => { describe('doBatchOperation', () => {
@@ -399,7 +444,7 @@ describe('NodeActionsService', () => {
return { componentInstance: {}, afterClosed: of } as unknown as MatDialogRef<any>; return { componentInstance: {}, afterClosed: of } as unknown as MatDialogRef<any>;
}); });
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(spyOnBatchOperation).toHaveBeenCalled();
expect(dialogData).toBeDefined(); expect(dialogData).toBeDefined();
@@ -421,7 +466,7 @@ describe('NodeActionsService', () => {
return { componentInstance: {}, afterClosed: of } as unknown as MatDialogRef<any>; return { componentInstance: {}, afterClosed: of } as unknown as MatDialogRef<any>;
}); });
service.copyNodes([{ entry: { id: 'entry-id' } }]); service.copyNodes([{ entry: { id: 'entry-id', nodeType: 'cm:content' } }]);
expect(spyOnBatchOperation).toHaveBeenCalled(); expect(spyOnBatchOperation).toHaveBeenCalled();
expect(dialogData).toBeDefined(); expect(dialogData).toBeDefined();
@@ -37,7 +37,7 @@ import {
ContentService ContentService
} from '@alfresco/adf-content-services'; } from '@alfresco/adf-content-services';
import { NodeEntry, Node, SitePaging, NodeChildAssociationPaging, NodeChildAssociationEntry, NodesApi, Site, SitePagingList } from '@alfresco/js-api'; 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'; import { catchError, map, mergeMap } from 'rxjs/operators';
type BatchOperationType = Extract<NodeAction, 'COPY' | 'MOVE'>; type BatchOperationType = Extract<NodeAction, 'COPY' | 'MOVE'>;
@@ -170,6 +170,7 @@ export class NodeActionsService {
getContentNodeSelection(action: NodeAction, contentEntities: NodeEntry[], focusedElementOnCloseSelector?: string): Subject<Node[]> { getContentNodeSelection(action: NodeAction, contentEntities: NodeEntry[], focusedElementOnCloseSelector?: string): Subject<Node[]> {
const currentParentFolderId = this.getEntryParentId(contentEntities[0].entry); const currentParentFolderId = this.getEntryParentId(contentEntities[0].entry);
const isRmaRelated = contentEntities.some((node) => isRmaContent(node.entry));
const customDropdown = new SitePaging({ const customDropdown = new SitePaging({
list: { list: {
@@ -205,7 +206,9 @@ export class NodeActionsService {
isSelectionValid: this.canCopyMoveInsideIt.bind(this), isSelectionValid: this.canCopyMoveInsideIt.bind(this),
breadcrumbTransform: this.customizeBreadcrumb.bind(this), breadcrumbTransform: this.customizeBreadcrumb.bind(this),
select: new Subject<Node[]>(), select: new Subject<Node[]>(),
excludeSiteContent: ContentNodeDialogService.nonDocumentSiteContent excludeSiteContent: ContentNodeDialogService.nonDocumentSiteContent,
showSearch: !isRmaRelated,
showDropdownSiteList: !isRmaRelated
}; };
this.dialog this.dialog
@@ -239,7 +242,7 @@ export class NodeActionsService {
} }
private canCopyMoveInsideIt(entry: Node): boolean { 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 { private hasEntityCreatePermission(entry: Node): boolean {