mirror of
https://github.com/Alfresco/alfresco-content-app.git
synced 2026-09-09 18:02:54 +00:00
[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:
@@ -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);
|
||||
|
||||
@@ -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'
|
||||
};
|
||||
|
||||
|
||||
@@ -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'
|
||||
})
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user