forked from hazza/dspace-angular
fixed issue that didn't allow to select tree node after a search
This commit is contained in:
@@ -34,6 +34,7 @@ export class TreeviewFlatNode {
|
|||||||
constructor(public item: VocabularyEntryDetail,
|
constructor(public item: VocabularyEntryDetail,
|
||||||
public level = 1,
|
public level = 1,
|
||||||
public expandable = false,
|
public expandable = false,
|
||||||
|
public childrenLoaded = false,
|
||||||
public pageInfo: PageInfo = new PageInfo(),
|
public pageInfo: PageInfo = new PageInfo(),
|
||||||
public loadMoreParentItem: VocabularyEntryDetail | null = null,
|
public loadMoreParentItem: VocabularyEntryDetail | null = null,
|
||||||
public isSearchNode = false,
|
public isSearchNode = false,
|
||||||
|
@@ -143,6 +143,7 @@ export class VocabularyTreeviewComponent implements OnDestroy, OnInit {
|
|||||||
node.item,
|
node.item,
|
||||||
level,
|
level,
|
||||||
node.hasChildren,
|
node.hasChildren,
|
||||||
|
(node.hasChildren && isNotEmpty(node.children)),
|
||||||
node.pageInfo,
|
node.pageInfo,
|
||||||
node.loadMoreParentItem,
|
node.loadMoreParentItem,
|
||||||
node.isSearchNode,
|
node.isSearchNode,
|
||||||
@@ -150,7 +151,9 @@ export class VocabularyTreeviewComponent implements OnDestroy, OnInit {
|
|||||||
);
|
);
|
||||||
this.nodeMap.set(node.item.id, newNode);
|
this.nodeMap.set(node.item.id, newNode);
|
||||||
|
|
||||||
if ((((level + 1) < this.preloadLevel) && newNode.expandable) || newNode.isSearchNode || newNode.isInInitValueHierarchy) {
|
if ((((level + 1) < this.preloadLevel) && newNode.childrenLoaded)
|
||||||
|
|| (newNode.isSearchNode && newNode.childrenLoaded)
|
||||||
|
|| newNode.isInInitValueHierarchy) {
|
||||||
if (!newNode.isSearchNode) {
|
if (!newNode.isSearchNode) {
|
||||||
this.loadChildren(newNode);
|
this.loadChildren(newNode);
|
||||||
}
|
}
|
||||||
|
@@ -13,6 +13,7 @@ import { PageInfo } from '../../core/shared/page-info.model';
|
|||||||
import { VocabularyEntryDetail } from '../../core/submission/vocabularies/models/vocabulary-entry-detail.model';
|
import { VocabularyEntryDetail } from '../../core/submission/vocabularies/models/vocabulary-entry-detail.model';
|
||||||
import { PaginatedList } from '../../core/data/paginated-list';
|
import { PaginatedList } from '../../core/data/paginated-list';
|
||||||
import { createSuccessfulRemoteDataObject } from '../remote-data.utils';
|
import { createSuccessfulRemoteDataObject } from '../remote-data.utils';
|
||||||
|
import { VocabularyEntry } from '../../core/submission/vocabularies/models/vocabulary-entry.model';
|
||||||
|
|
||||||
describe('VocabularyTreeviewService test suite', () => {
|
describe('VocabularyTreeviewService test suite', () => {
|
||||||
|
|
||||||
@@ -34,6 +35,7 @@ describe('VocabularyTreeviewService test suite', () => {
|
|||||||
let childNode: TreeviewNode;
|
let childNode: TreeviewNode;
|
||||||
let child2: VocabularyEntryDetail;
|
let child2: VocabularyEntryDetail;
|
||||||
let childNode2: TreeviewNode;
|
let childNode2: TreeviewNode;
|
||||||
|
let childEntry3: VocabularyEntry;
|
||||||
let child3: VocabularyEntryDetail;
|
let child3: VocabularyEntryDetail;
|
||||||
let childNode3: TreeviewNode;
|
let childNode3: TreeviewNode;
|
||||||
let searchItemNode: TreeviewNode;
|
let searchItemNode: TreeviewNode;
|
||||||
@@ -71,37 +73,46 @@ describe('VocabularyTreeviewService test suite', () => {
|
|||||||
});
|
});
|
||||||
loadMoreNode = new TreeviewNode(LOAD_MORE_NODE, false, new PageInfo(), item);
|
loadMoreNode = new TreeviewNode(LOAD_MORE_NODE, false, new PageInfo(), item);
|
||||||
loadMoreRootNode = new TreeviewNode(LOAD_MORE_ROOT_NODE, false, new PageInfo(), null);
|
loadMoreRootNode = new TreeviewNode(LOAD_MORE_ROOT_NODE, false, new PageInfo(), null);
|
||||||
loadMoreRootFlatNode = new TreeviewFlatNode(LOAD_MORE_ROOT_NODE, 1, false, new PageInfo(), null);
|
loadMoreRootFlatNode = new TreeviewFlatNode(LOAD_MORE_ROOT_NODE, 1, false, false, new PageInfo(), null);
|
||||||
item = new VocabularyEntryDetail();
|
item = new VocabularyEntryDetail();
|
||||||
item.id = item.value = item.display = 'root1';
|
item.id = 'vocabularyTest:root1';
|
||||||
|
item.value = item.display = 'root1';
|
||||||
item.otherInformation = { hasChildren: 'true', id: 'root1' };
|
item.otherInformation = { hasChildren: 'true', id: 'root1' };
|
||||||
itemNode = new TreeviewNode(item, true, pageInfo);
|
itemNode = new TreeviewNode(item, true, pageInfo);
|
||||||
searchItemNode = new TreeviewNode(item, true, new PageInfo(), null, true);
|
searchItemNode = new TreeviewNode(item, true, new PageInfo(), null, true);
|
||||||
|
|
||||||
item2 = new VocabularyEntryDetail();
|
item2 = new VocabularyEntryDetail();
|
||||||
item2.id = item2.value = item2.display = 'root2';
|
item2.id = 'vocabularyTest:root2';
|
||||||
|
item2.value = item2.display = 'root2';
|
||||||
item2.otherInformation = { id: 'root2' };
|
item2.otherInformation = { id: 'root2' };
|
||||||
itemNode2 = new TreeviewNode(item2, false, pageInfo);
|
itemNode2 = new TreeviewNode(item2, false, pageInfo);
|
||||||
|
|
||||||
item3 = new VocabularyEntryDetail();
|
item3 = new VocabularyEntryDetail();
|
||||||
item3.id = item3.value = item3.display = 'root3';
|
item3.id = 'vocabularyTest:root3';
|
||||||
|
item3.value = item3.display = 'root3';
|
||||||
item3.otherInformation = { id: 'root3' };
|
item3.otherInformation = { id: 'root3' };
|
||||||
itemNode3 = new TreeviewNode(item3, false, pageInfo);
|
itemNode3 = new TreeviewNode(item3, false, pageInfo);
|
||||||
|
|
||||||
child = new VocabularyEntryDetail();
|
child = new VocabularyEntryDetail();
|
||||||
child.id = child.value = child.display = 'root1-child1';
|
child.id = 'vocabularyTest:root1-child1';
|
||||||
|
child.value = child.display = 'root1-child1';
|
||||||
child.otherInformation = { parent: 'root1', hasChildren: 'true', id: 'root1-child1' };
|
child.otherInformation = { parent: 'root1', hasChildren: 'true', id: 'root1-child1' };
|
||||||
childNode = new TreeviewNode(child);
|
childNode = new TreeviewNode(child);
|
||||||
searchChildNode = new TreeviewNode(child, true, new PageInfo(), item, true);
|
searchChildNode = new TreeviewNode(child, true, new PageInfo(), item, true);
|
||||||
|
|
||||||
|
childEntry3 = new VocabularyEntry();
|
||||||
|
childEntry3.value = childEntry3.display = 'root1-child1-child1';
|
||||||
|
childEntry3.otherInformation = { parent: 'root1-child1', id: 'root1-child1-child1' };
|
||||||
child3 = new VocabularyEntryDetail();
|
child3 = new VocabularyEntryDetail();
|
||||||
child3.id = child3.value = child3.display = 'root1-child1-child1';
|
child3.id = 'vocabularyTest:root1-child1-child1';
|
||||||
|
child3.value = child3.display = 'root1-child1-child1';
|
||||||
child3.otherInformation = { parent: 'root1-child1', id: 'root1-child1-child1' };
|
child3.otherInformation = { parent: 'root1-child1', id: 'root1-child1-child1' };
|
||||||
childNode3 = new TreeviewNode(child3);
|
childNode3 = new TreeviewNode(child3);
|
||||||
searchChildNode3 = new TreeviewNode(child3, false, new PageInfo(), child, true);
|
searchChildNode3 = new TreeviewNode(child3, false, new PageInfo(), child, true);
|
||||||
|
|
||||||
child2 = new VocabularyEntryDetail();
|
child2 = new VocabularyEntryDetail();
|
||||||
child2.id = child2.value = child2.display = 'root1-child2';
|
child2.id = 'vocabularyTest:root1-child2';
|
||||||
|
child2.value = child2.display = 'root1-child2';
|
||||||
child2.otherInformation = { parent: 'root1', id: 'root1-child2' };
|
child2.otherInformation = { parent: 'root1', id: 'root1-child2' };
|
||||||
childNode2 = new TreeviewNode(child2, true);
|
childNode2 = new TreeviewNode(child2, true);
|
||||||
initValueChildNode2 = new TreeviewNode(child2, false, new PageInfo(), item, false, true);
|
initValueChildNode2 = new TreeviewNode(child2, false, new PageInfo(), item, false, true);
|
||||||
@@ -184,7 +195,6 @@ describe('VocabularyTreeviewService test suite', () => {
|
|||||||
|
|
||||||
expect(serviceAsAny.vocabularyName).toEqual(vocabularyOptions.name);
|
expect(serviceAsAny.vocabularyName).toEqual(vocabularyOptions.name);
|
||||||
expect(serviceAsAny.pageInfo).toEqual(pageInfo);
|
expect(serviceAsAny.pageInfo).toEqual(pageInfo);
|
||||||
console.log(serviceAsAny.dataChange.value[0].pageInfo, itemNode.pageInfo);
|
|
||||||
expect(serviceAsAny.dataChange.value).toEqual([itemNode, itemNode2, itemNode3]);
|
expect(serviceAsAny.dataChange.value).toEqual([itemNode, itemNode2, itemNode3]);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -290,7 +300,11 @@ describe('VocabularyTreeviewService test suite', () => {
|
|||||||
currentPage: 1
|
currentPage: 1
|
||||||
});
|
});
|
||||||
serviceAsAny.vocabularyService.getVocabularyEntriesByValue.and.returnValue(hot('-a', {
|
serviceAsAny.vocabularyService.getVocabularyEntriesByValue.and.returnValue(hot('-a', {
|
||||||
a: createSuccessfulRemoteDataObject(new PaginatedList(pageInfo, [child3]))
|
a: createSuccessfulRemoteDataObject(new PaginatedList(pageInfo, [childEntry3]))
|
||||||
|
}));
|
||||||
|
|
||||||
|
serviceAsAny.vocabularyService.findEntryDetailByValue.and.returnValue(hot('-a', {
|
||||||
|
a: createSuccessfulRemoteDataObject(child3)
|
||||||
}));
|
}));
|
||||||
|
|
||||||
serviceAsAny.vocabularyService.getEntryDetailParent.and.returnValues(
|
serviceAsAny.vocabularyService.getEntryDetailParent.and.returnValues(
|
||||||
@@ -305,6 +319,7 @@ describe('VocabularyTreeviewService test suite', () => {
|
|||||||
|
|
||||||
scheduler.schedule(() => service.searchByQuery(vocabularyOptions));
|
scheduler.schedule(() => service.searchByQuery(vocabularyOptions));
|
||||||
scheduler.flush();
|
scheduler.flush();
|
||||||
|
|
||||||
searchChildNode.childrenChange.next([searchChildNode3]);
|
searchChildNode.childrenChange.next([searchChildNode3]);
|
||||||
searchItemNode.childrenChange.next([searchChildNode]);
|
searchItemNode.childrenChange.next([searchChildNode]);
|
||||||
expect(serviceAsAny.dataChange.value.length).toEqual(1);
|
expect(serviceAsAny.dataChange.value.length).toEqual(1);
|
||||||
|
@@ -134,13 +134,13 @@ export class VocabularyTreeviewService {
|
|||||||
* @param onlyFirstTime
|
* @param onlyFirstTime
|
||||||
*/
|
*/
|
||||||
loadMore(item: VocabularyEntryDetail, onlyFirstTime = false) {
|
loadMore(item: VocabularyEntryDetail, onlyFirstTime = false) {
|
||||||
if (!this.nodeMap.has(item.id)) {
|
if (!this.nodeMap.has(item.otherInformation.id)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const parent: TreeviewNode = this.nodeMap.get(item.id)!;
|
const parent: TreeviewNode = this.nodeMap.get(item.otherInformation.id)!;
|
||||||
const children = this.nodeMap.get(item.id)!.children || [];
|
const children = this.nodeMap.get(item.otherInformation.id)!.children || [];
|
||||||
children.pop();
|
children.pop();
|
||||||
this.getChildrenNodesByParent(item.id, parent.pageInfo).subscribe((list: PaginatedList<VocabularyEntryDetail>) => {
|
this.getChildrenNodesByParent(item.otherInformation.id, parent.pageInfo).subscribe((list: PaginatedList<VocabularyEntryDetail>) => {
|
||||||
|
|
||||||
if (onlyFirstTime && parent.children!.length > 0) {
|
if (onlyFirstTime && parent.children!.length > 0) {
|
||||||
return;
|
return;
|
||||||
@@ -187,9 +187,14 @@ export class VocabularyTreeviewService {
|
|||||||
this.vocabularyService.getVocabularyEntriesByValue(query, false, this.vocabularyOptions, new PageInfo()).pipe(
|
this.vocabularyService.getVocabularyEntriesByValue(query, false, this.vocabularyOptions, new PageInfo()).pipe(
|
||||||
getFirstSucceededRemoteListPayload(),
|
getFirstSucceededRemoteListPayload(),
|
||||||
flatMap((result: VocabularyEntry[]) => (result.length > 0) ? result : observableOf(null)),
|
flatMap((result: VocabularyEntry[]) => (result.length > 0) ? result : observableOf(null)),
|
||||||
flatMap((entry: VocabularyEntry) => this.getNodeHierarchy(entry)),
|
flatMap((entry: VocabularyEntry) =>
|
||||||
|
this.vocabularyService.findEntryDetailByValue(entry.otherInformation.id, this.vocabularyName).pipe(
|
||||||
|
getFirstSucceededRemoteDataPayload()
|
||||||
|
)
|
||||||
|
),
|
||||||
|
flatMap((entry: VocabularyEntryDetail) => this.getNodeHierarchy(entry)),
|
||||||
scan((acc: TreeviewNode[], value: TreeviewNode) => {
|
scan((acc: TreeviewNode[], value: TreeviewNode) => {
|
||||||
if (isEmpty(value) || findIndex(acc, (node) => node.item.id === value.item.id) !== -1) {
|
if (isEmpty(value) || findIndex(acc, (node) => node.item.otherInformation.id === value.item.otherInformation.id) !== -1) {
|
||||||
return acc;
|
return acc;
|
||||||
} else {
|
} else {
|
||||||
return [...acc, value]
|
return [...acc, value]
|
||||||
@@ -217,24 +222,21 @@ export class VocabularyTreeviewService {
|
|||||||
/**
|
/**
|
||||||
* Generate a {@link TreeviewNode} object from vocabulary entry
|
* Generate a {@link TreeviewNode} object from vocabulary entry
|
||||||
*
|
*
|
||||||
* @param entry The vocabulary entry
|
* @param entry The vocabulary entry detail
|
||||||
* @param isSearchNode A Boolean representing if given entry is the result of a search
|
* @param isSearchNode A Boolean representing if given entry is the result of a search
|
||||||
* @param toStore A Boolean representing if the node created is to store or not
|
* @param toStore A Boolean representing if the node created is to store or not
|
||||||
* @return TreeviewNode
|
* @return TreeviewNode
|
||||||
*/
|
*/
|
||||||
private _generateNode(entry: VocabularyEntry, isSearchNode = false, toStore = true): TreeviewNode {
|
private _generateNode(entry: VocabularyEntryDetail, isSearchNode = false, toStore = true): TreeviewNode {
|
||||||
const entryId = entry.otherInformation.id;
|
const entryId = entry.otherInformation.id;
|
||||||
if (this.nodeMap.has(entryId)) {
|
if (this.nodeMap.has(entryId)) {
|
||||||
return this.nodeMap.get(entryId)!;
|
return this.nodeMap.get(entryId)!;
|
||||||
}
|
}
|
||||||
const entryDetail: VocabularyEntryDetail = Object.assign(new VocabularyEntryDetail(), entry, {
|
|
||||||
id: entryId
|
|
||||||
});
|
|
||||||
const hasChildren = entry.hasOtherInformation() && (entry.otherInformation as any)!.hasChildren === 'true';
|
const hasChildren = entry.hasOtherInformation() && (entry.otherInformation as any)!.hasChildren === 'true';
|
||||||
const pageInfo: PageInfo = this.pageInfo;
|
const pageInfo: PageInfo = this.pageInfo;
|
||||||
const isInInitValueHierarchy = this.initValueHierarchy.includes(entryId);
|
const isInInitValueHierarchy = this.initValueHierarchy.includes(entryId);
|
||||||
const result = new TreeviewNode(
|
const result = new TreeviewNode(
|
||||||
entryDetail,
|
entry,
|
||||||
hasChildren,
|
hasChildren,
|
||||||
pageInfo,
|
pageInfo,
|
||||||
null,
|
null,
|
||||||
@@ -328,7 +330,7 @@ export class VocabularyTreeviewService {
|
|||||||
* @param toStore A Boolean representing if the node created is to store or not
|
* @param toStore A Boolean representing if the node created is to store or not
|
||||||
* @return Observable<string[]>
|
* @return Observable<string[]>
|
||||||
*/
|
*/
|
||||||
private getNodeHierarchy(item: VocabularyEntry, children?: TreeviewNode[], toStore = true): Observable<TreeviewNode> {
|
private getNodeHierarchy(item: VocabularyEntryDetail, children?: TreeviewNode[], toStore = true): Observable<TreeviewNode> {
|
||||||
if (isEmpty(item)) {
|
if (isEmpty(item)) {
|
||||||
return observableOf(null);
|
return observableOf(null);
|
||||||
}
|
}
|
||||||
@@ -337,7 +339,7 @@ export class VocabularyTreeviewService {
|
|||||||
if (isNotEmpty(children)) {
|
if (isNotEmpty(children)) {
|
||||||
const newChildren = children
|
const newChildren = children
|
||||||
.filter((entry: TreeviewNode) => {
|
.filter((entry: TreeviewNode) => {
|
||||||
return findIndex(node.children, (nodeEntry) => nodeEntry.item.id === entry.item.id) === -1;
|
return findIndex(node.children, (nodeEntry) => nodeEntry.item.otherInformation.id === entry.item.otherInformation.id) === -1;
|
||||||
});
|
});
|
||||||
newChildren.forEach((entry: TreeviewNode) => {
|
newChildren.forEach((entry: TreeviewNode) => {
|
||||||
entry.loadMoreParentItem = node.item
|
entry.loadMoreParentItem = node.item
|
||||||
@@ -346,7 +348,7 @@ export class VocabularyTreeviewService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (node.item.hasOtherInformation() && isNotEmpty(node.item.otherInformation.parent)) {
|
if (node.item.hasOtherInformation() && isNotEmpty(node.item.otherInformation.parent)) {
|
||||||
return this.getParentNode(node.item.id).pipe(
|
return this.getParentNode(node.item.otherInformation.id).pipe(
|
||||||
flatMap((parentItem: VocabularyEntryDetail) => this.getNodeHierarchy(parentItem, [node], toStore))
|
flatMap((parentItem: VocabularyEntryDetail) => this.getNodeHierarchy(parentItem, [node], toStore))
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
@@ -362,8 +364,8 @@ export class VocabularyTreeviewService {
|
|||||||
* @return string[]
|
* @return string[]
|
||||||
*/
|
*/
|
||||||
private getNodeHierarchyIds(node: TreeviewNode, hierarchyIds: string[] = []): string[] {
|
private getNodeHierarchyIds(node: TreeviewNode, hierarchyIds: string[] = []): string[] {
|
||||||
if (!hierarchyIds.includes(node.item.id)) {
|
if (!hierarchyIds.includes(node.item.otherInformation.id)) {
|
||||||
hierarchyIds.push(node.item.id);
|
hierarchyIds.push(node.item.otherInformation.id);
|
||||||
}
|
}
|
||||||
if (isNotEmpty(node.children)) {
|
if (isNotEmpty(node.children)) {
|
||||||
return this.getNodeHierarchyIds(node.children[0], hierarchyIds);
|
return this.getNodeHierarchyIds(node.children[0], hierarchyIds);
|
||||||
|
Reference in New Issue
Block a user