[ACA-3043] Create From Template - relativePath not working when ACS installation language is different (#1411)

* use primary path to get node information

* breadcrumb transform based on paths intersection

* update tests
This commit is contained in:
Cilibiu Bogdan
2020-04-15 12:44:26 +01:00
committed by GitHub
parent 6e33766fc4
commit 88f8b4065e
4 changed files with 199 additions and 107 deletions
+156 -84
View File
@@ -40,11 +40,11 @@ describe('NodeTemplateService', () => {
let alfrescoApiService: AlfrescoApiService;
let nodeTemplateService: NodeTemplateService;
const fileTemplateConfig = {
relativePath: 'relative-path/parent-file-templates',
primaryPathName: 'parent-file-templates',
selectionType: 'file'
};
const folderTemplateConfig = {
relativePath: 'relative-path/parent-folder-templates',
primaryPathName: 'parent-folder-templates',
selectionType: 'folder'
};
@@ -63,30 +63,38 @@ describe('NodeTemplateService', () => {
nodeTemplateService = TestBed.get(NodeTemplateService);
});
it('should open dialog with parent node `id` as data property', () => {
spyOn(
alfrescoApiService.getInstance().nodes,
'getNodeInfo'
).and.returnValue(of({ id: 'parent-node-id' }));
it('should open dialog with parent node `id` as data property', fakeAsync(() => {
spyOn(alfrescoApiService.searchApi, 'search').and.returnValue(
of({ list: { entries: [{ entry: { id: 'parent-node-id' } }] } })
);
spyOn(dialog, 'open');
nodeTemplateService.selectTemplateDialog(fileTemplateConfig);
tick();
expect(dialog.open['calls'].argsFor(0)[1].data).toEqual(
jasmine.objectContaining({ currentFolderId: 'parent-node-id' })
);
});
}));
it('should remove parents for templates node breadcrumb path', () => {
spyOn(
alfrescoApiService.getInstance().nodes,
'getNodeInfo'
).and.returnValue(
it('should remove parents path for templates breadcrumb', fakeAsync(() => {
spyOn(alfrescoApiService.searchApi, 'search').and.returnValue(
of({
id: 'parent-node-id',
path: {
elements: [],
name: '/Company Home/Data Dictionary'
list: {
entries: [
{
entry: {
id: 'parent-node-id',
path: {
elements: [
{ id: 'id1', name: 'Company Home' },
{ id: 'id2', name: 'Data Dictionary' }
],
name: '/Company Home/Data Dictionary'
}
}
}
]
}
})
);
@@ -99,19 +107,63 @@ describe('NodeTemplateService', () => {
.data.breadcrumbTransform({
name: 'Node Templates',
path: {
elements: [{ name: 'Company Home' }, { name: 'Data Dictionary' }],
elements: [
{ id: 'id1', name: 'Company Home' },
{ id: 'id2', name: 'Data Dictionary' }
],
name: '/Company Home/Data Dictionary'
}
});
expect(breadcrumb.path.elements).toEqual([]);
});
}));
it('should set template folder path as root for breadcrumb', fakeAsync(() => {
spyOn(alfrescoApiService.searchApi, 'search').and.returnValue(
of({
list: {
entries: [
{
entry: {
id: 'parent-node-id',
path: {
elements: [
{ id: 'id1', name: 'Company Home' },
{ id: 'id2', name: 'Data Dictionary' }
],
name: '/Company Home/Data Dictionary'
}
}
}
]
}
})
);
spyOn(dialog, 'open');
nodeTemplateService.selectTemplateDialog(fileTemplateConfig);
const breadcrumb = dialog.open['calls']
.argsFor(0)[1]
.data.breadcrumbTransform({
name: 'Node Templates',
path: {
elements: [
{ id: 'id1', name: 'Company Home' },
{ id: 'id2', name: 'Data Dictionary' },
{ id: 'id3', name: 'Templates' }
],
name: '/Company Home/Data Dictionary/Templates'
}
});
expect(breadcrumb.path.elements).toEqual([
{ id: 'id3', name: 'Templates' }
]);
}));
it('should raise an error when getNodeInfo fails', fakeAsync(() => {
spyOn(
alfrescoApiService.getInstance().nodes,
'getNodeInfo'
).and.returnValue(
spyOn(alfrescoApiService.searchApi, 'search').and.returnValue(
Promise.reject({
message: `{ "error": { "statusCode": 404 } } `
})
@@ -127,15 +179,20 @@ describe('NodeTemplateService', () => {
}));
it('should return true if row is not a `link` nodeType', () => {
spyOn(
alfrescoApiService.getInstance().nodes,
'getNodeInfo'
).and.returnValue(
spyOn(alfrescoApiService.searchApi, 'search').and.returnValue(
of({
id: 'templates-folder-id',
path: {
elements: [],
name: '/Company Home/Data Dictionary'
list: {
entries: [
{
entry: {
id: 'templates-folder-id',
path: {
elements: [{}, {}],
name: '/Company Home/Data Dictionary'
}
}
}
]
}
})
);
@@ -151,15 +208,20 @@ describe('NodeTemplateService', () => {
});
it('should return false if row is a `filelink` nodeType', () => {
spyOn(
alfrescoApiService.getInstance().nodes,
'getNodeInfo'
).and.returnValue(
spyOn(alfrescoApiService.searchApi, 'search').and.returnValue(
of({
id: 'templates-folder-id',
path: {
elements: [],
name: '/Company Home/Data Dictionary'
list: {
entries: [
{
entry: {
id: 'templates-folder-id',
path: {
elements: [{}, {}],
name: '/Company Home/Data Dictionary'
}
}
}
]
}
})
);
@@ -175,15 +237,20 @@ describe('NodeTemplateService', () => {
});
it('should return false if row is a `folderlink` nodeType', () => {
spyOn(
alfrescoApiService.getInstance().nodes,
'getNodeInfo'
).and.returnValue(
spyOn(alfrescoApiService.searchApi, 'search').and.returnValue(
of({
id: 'templates-folder-id',
path: {
elements: [],
name: '/Company Home/Data Dictionary'
list: {
entries: [
{
entry: {
id: 'templates-folder-id',
path: {
elements: [{}, {}],
name: '/Company Home/Data Dictionary'
}
}
}
]
}
})
);
@@ -200,10 +267,9 @@ describe('NodeTemplateService', () => {
describe('File templates', () => {
it('should return false if selected node is not a file', () => {
spyOn(
alfrescoApiService.getInstance().nodes,
'getNodeInfo'
).and.returnValue(of({ id: 'templates-folder-id' }));
spyOn(alfrescoApiService.searchApi, 'search').and.returnValue(
of({ list: { entries: [{ entry: { id: 'templates-folder-id' } }] } })
);
spyOn(dialog, 'open');
nodeTemplateService.selectTemplateDialog(fileTemplateConfig);
@@ -213,17 +279,17 @@ describe('NodeTemplateService', () => {
.data.isSelectionValid({
name: 'some-folder-template',
isFile: false,
isFolder: true
isFolder: true,
path: { elements: [{}, {}] }
});
expect(isSelectionValid).toBe(false);
});
it('should return true if selected node is a template file', () => {
spyOn(
alfrescoApiService.getInstance().nodes,
'getNodeInfo'
).and.returnValue(of({ id: 'templates-folder-id' }));
spyOn(alfrescoApiService.searchApi, 'search').and.returnValue(
of({ list: { entries: [{ entry: { id: 'templates-folder-id' } }] } })
);
spyOn(dialog, 'open');
nodeTemplateService.selectTemplateDialog(fileTemplateConfig);
@@ -233,17 +299,17 @@ describe('NodeTemplateService', () => {
.data.isSelectionValid({
name: 'some-file-template',
isFile: true,
isFolder: false
isFolder: false,
path: { elements: [{}, {}] }
});
expect(isSelectionValid).toBe(true);
});
it('should set dialog title for file templates', () => {
spyOn(
alfrescoApiService.getInstance().nodes,
'getNodeInfo'
).and.returnValue(of({ id: 'templates-folder-id' }));
spyOn(alfrescoApiService.searchApi, 'search').and.returnValue(
of({ list: { entries: [{ entry: { id: 'templates-folder-id' } }] } })
);
spyOn(dialog, 'open');
nodeTemplateService.selectTemplateDialog(fileTemplateConfig);
@@ -256,10 +322,9 @@ describe('NodeTemplateService', () => {
describe('Folder templates', () => {
it('should return false if selected node is not a folder', () => {
spyOn(
alfrescoApiService.getInstance().nodes,
'getNodeInfo'
).and.returnValue(of({ id: 'templates-folder-id' }));
spyOn(alfrescoApiService.searchApi, 'search').and.returnValue(
of({ list: { entries: [{ entry: { id: 'templates-folder-id' } }] } })
);
spyOn(dialog, 'open');
nodeTemplateService.selectTemplateDialog(folderTemplateConfig);
@@ -269,17 +334,17 @@ describe('NodeTemplateService', () => {
.data.isSelectionValid({
name: 'some-file-template',
isFile: true,
isFolder: false
isFolder: false,
path: { elements: [{}, {}] }
});
expect(isSelectionValid).toBe(false);
});
it('should return false if current node is the parent folder', () => {
spyOn(
alfrescoApiService.getInstance().nodes,
'getNodeInfo'
).and.returnValue(of({ id: 'templates-folder-id' }));
it('should return false if current node is the parent folder', fakeAsync(() => {
spyOn(alfrescoApiService.searchApi, 'search').and.returnValue(
of({ list: { entries: [{ entry: { id: 'templates-folder-id' } }] } })
);
spyOn(dialog, 'open');
nodeTemplateService.selectTemplateDialog(folderTemplateConfig);
@@ -289,37 +354,44 @@ describe('NodeTemplateService', () => {
.data.isSelectionValid({
name: 'parent-folder-templates',
isFile: false,
isFolder: true
isFolder: true,
path: { elements: [] }
});
expect(isSelectionValid).toBe(false);
});
}));
it('should return true if selected node is a folder template', () => {
spyOn(
alfrescoApiService.getInstance().nodes,
'getNodeInfo'
).and.returnValue(of({ id: 'templates-folder-id' }));
it('should return true if selected node is a folder template', fakeAsync(() => {
spyOn(alfrescoApiService.searchApi, 'search').and.returnValue(
of({
list: {
entries: [
{ entry: { id: 'templates-folder-id', path: { elements: [] } } }
]
}
})
);
spyOn(dialog, 'open');
nodeTemplateService.selectTemplateDialog(folderTemplateConfig);
tick();
const isSelectionValid = dialog.open['calls']
.argsFor(0)[1]
.data.isSelectionValid({
name: 'some-folder-template',
isFile: false,
isFolder: true
isFolder: true,
path: { elements: [{}, {}] }
});
expect(isSelectionValid).toBe(true);
});
}));
it('should set dialog title for folder templates', () => {
spyOn(
alfrescoApiService.getInstance().nodes,
'getNodeInfo'
).and.returnValue(of({ id: 'templates-folder-id' }));
spyOn(alfrescoApiService.searchApi, 'search').and.returnValue(
of({ list: { entries: [{ entry: { id: 'templates-folder-id' } }] } })
);
spyOn(dialog, 'open');
nodeTemplateService.selectTemplateDialog(folderTemplateConfig);
+39 -19
View File
@@ -24,10 +24,20 @@
*/
import { Injectable } from '@angular/core';
import { MatDialog, MatDialogConfig, MatDialogRef } from '@angular/material';
import {
MatDialog,
MatDialogConfig,
MatDialogRef
} from '@angular/material/dialog';
import { CreateFromTemplateDialogComponent } from '../dialogs/node-template/create-from-template.dialog';
import { Subject, from, of } from 'rxjs';
import { Node, MinimalNode, MinimalNodeEntryEntity } from '@alfresco/js-api';
import {
Node,
MinimalNode,
MinimalNodeEntryEntity,
ResultNode,
PathElement
} from '@alfresco/js-api';
import { AlfrescoApiService, TranslationService } from '@alfresco/adf-core';
import { switchMap, catchError } from 'rxjs/operators';
import { Store } from '@ngrx/store';
@@ -39,7 +49,7 @@ import {
} from '@alfresco/adf-content-services';
export interface TemplateDialogConfig {
relativePath: string;
primaryPathName: string;
selectionType: string;
}
@@ -48,6 +58,7 @@ export interface TemplateDialogConfig {
})
export class NodeTemplateService {
private currentTemplateConfig: TemplateDialogConfig = null;
private rootNode: ResultNode;
constructor(
private store: Store<AppStore>,
@@ -78,14 +89,21 @@ export class NodeTemplateService {
rowFilter: this.rowFilter.bind(this)
};
from(
this.alfrescoApiService.getInstance().nodes.getNodeInfo('-root-', {
relativePath: config.relativePath
})
)
const query = {
query: {
query: `PATH:"//${config.primaryPathName}"`,
language: 'afts'
},
include: ['path', 'properties', 'allowableOperations', 'permissions']
};
from(this.alfrescoApiService.searchApi.search(query))
.pipe(
switchMap(node => {
data.currentFolderId = node.id;
switchMap(response => {
const entry = response.list.entries[0].entry;
this.rootNode = entry;
data.currentFolderId = entry.id;
return this.dialog
.open(ContentNodeSelectorComponent, <MatDialogConfig>{
data,
@@ -121,20 +139,13 @@ export class NodeTemplateService {
private transformNode(node: MinimalNode): MinimalNode {
if (node && node.path && node.path && node.path.elements instanceof Array) {
let {
path: { elements: elementsPath = [] }
} = node;
elementsPath = elementsPath.filter(
path => path.name !== 'Company Home' && path.name !== 'Data Dictionary'
);
node.path.elements = elementsPath;
node.path.elements = this.getPathElements(node);
}
return node;
}
private isSelectionValid(node: Node): boolean {
if (node.name === this.currentTemplateConfig.relativePath.split('/')[1]) {
if (!node.path.elements.length) {
return false;
}
@@ -167,4 +178,13 @@ export class NodeTemplateService {
node.nodeType !== 'app:filelink' && node.nodeType !== 'app:folderlink'
);
}
private getPathElements(node: Node): PathElement[] {
return node.path.elements.filter(
pathElement =>
!this.rootNode.path.elements.some(
rootPathElement => pathElement.id === rootPathElement.id
)
);
}
}
@@ -66,12 +66,12 @@ describe('TemplateEffects', () => {
}
};
const fileTemplateConfig = {
relativePath: 'Data Dictionary/Node Templates',
primaryPathName: 'app:node_templates',
selectionType: 'file'
};
const folderTemplateConfig = {
relativePath: 'Data Dictionary/Space Templates',
primaryPathName: 'app:space_templates',
selectionType: 'folder'
};
+2 -2
View File
@@ -63,7 +63,7 @@ export class TemplateEffects {
ofType<FileFromTemplate>(TemplateActionTypes.FileFromTemplate),
map(() => {
this.openDialog({
relativePath: 'Data Dictionary/Node Templates',
primaryPathName: 'app:node_templates',
selectionType: 'file'
});
})
@@ -74,7 +74,7 @@ export class TemplateEffects {
ofType<FolderFromTemplate>(TemplateActionTypes.FolderFromTemplate),
map(() =>
this.openDialog({
relativePath: 'Data Dictionary/Space Templates',
primaryPathName: 'app:space_templates',
selectionType: 'folder'
})
)