From ea3f0f0fe11f2563f8ffdc646715c495d5e73acd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20G=C3=BCnther?= Date: Wed, 3 Jun 2020 13:58:26 +0200 Subject: [PATCH] Use the visible parent if the actual parent is not visible In case a user sees the root node, but not an intermediate parent, an error will be raised by the frontend trying to access `child.parent` which is null in that case. We can use the visible parent that it got deferred under to ensure it can render successfully --- .../modes/hierarchy/hierarchy-render-pass.ts | 2 +- .../wp-relations-hierarchy.directive.ts | 13 ++++++------- .../wp-relations-hierarchy.service.ts | 5 ++++- .../actions/hierarchy-drag-action.service.ts | 2 +- .../modules/hal/resources/work-package-resource.ts | 4 ++-- 5 files changed, 14 insertions(+), 12 deletions(-) diff --git a/frontend/src/app/components/wp-fast-table/builders/modes/hierarchy/hierarchy-render-pass.ts b/frontend/src/app/components/wp-fast-table/builders/modes/hierarchy/hierarchy-render-pass.ts index 5a29b56dc3..4d061cfbb2 100644 --- a/frontend/src/app/components/wp-fast-table/builders/modes/hierarchy/hierarchy-render-pass.ts +++ b/frontend/src/app/components/wp-fast-table/builders/modes/hierarchy/hierarchy-render-pass.ts @@ -152,7 +152,7 @@ export class HierarchyRenderPass extends PrimaryRenderPass { // If the work package has deferred children to render, // run them through the callback deferredChildren.forEach((child:WorkPackageResource) => { - this.insertUnderParent(this.getOrBuildRow(child), child.parent); + this.insertUnderParent(this.getOrBuildRow(child), child.parent || workPackage); // Descend into any children the child WP might have and callback this.renderAllDeferredChildren(child); diff --git a/frontend/src/app/components/wp-relations/wp-relations-hierarchy/wp-relations-hierarchy.directive.ts b/frontend/src/app/components/wp-relations/wp-relations-hierarchy/wp-relations-hierarchy.directive.ts index c2af905afd..14dd0f0948 100644 --- a/frontend/src/app/components/wp-relations/wp-relations-hierarchy/wp-relations-hierarchy.directive.ts +++ b/frontend/src/app/components/wp-relations/wp-relations-hierarchy/wp-relations-hierarchy.directive.ts @@ -82,15 +82,14 @@ export class WorkPackageRelationsHierarchyComponent extends UntilDestroyedMixin this.workPackage = wp; let toLoad:string[] = []; + let parentId = this.workPackage.parent?.id?.toString(); - if (this.workPackage.parent) { - toLoad.push(this.workPackage.parent.id.toString()); + if (parentId) { + toLoad.push(parentId.toString()); - this.wpCacheService.loadWorkPackage(this.workPackage.parent.id).values$() - .pipe( - take(1) - ) - .subscribe((parent:WorkPackageResource) => { + this.wpCacheService + .require(parentId) + .then((parent:WorkPackageResource) => { this.workPackage.parent = parent; }); } diff --git a/frontend/src/app/components/wp-relations/wp-relations-hierarchy/wp-relations-hierarchy.service.ts b/frontend/src/app/components/wp-relations/wp-relations-hierarchy/wp-relations-hierarchy.service.ts index cc31dfff88..c022cdda1b 100644 --- a/frontend/src/app/components/wp-relations/wp-relations-hierarchy/wp-relations-hierarchy.service.ts +++ b/frontend/src/app/components/wp-relations/wp-relations-hierarchy/wp-relations-hierarchy.service.ts @@ -135,7 +135,10 @@ export class WorkPackageRelationsHierarchyService { }, lockVersion: childWorkPackage.lockVersion }).then(wp => { - this.wpCacheService.loadWorkPackage(parentWorkPackage.id!, true); + if (parentWorkPackage) { + this.wpCacheService.require(parentWorkPackage.id!, true); + } + this.wpCacheService.updateWorkPackage(wp); }) .catch((error) => { diff --git a/frontend/src/app/components/wp-table/drag-and-drop/actions/hierarchy-drag-action.service.ts b/frontend/src/app/components/wp-table/drag-and-drop/actions/hierarchy-drag-action.service.ts index 9b112f9578..1f41da034a 100644 --- a/frontend/src/app/components/wp-table/drag-and-drop/actions/hierarchy-drag-action.service.ts +++ b/frontend/src/app/components/wp-table/drag-and-drop/actions/hierarchy-drag-action.service.ts @@ -93,7 +93,7 @@ export class HierarchyDragActionService extends TableDragActionService { private loadParentOfWP(wpId:string):Promise { return this.wpCacheService.require(wpId) .then((wp:WorkPackageResource) => { - return Promise.resolve(wp.parent.id); + return Promise.resolve(wp.parent?.id || null); }); } } diff --git a/frontend/src/app/modules/hal/resources/work-package-resource.ts b/frontend/src/app/modules/hal/resources/work-package-resource.ts index 955e7211a5..682b89e0f7 100644 --- a/frontend/src/app/modules/hal/resources/work-package-resource.ts +++ b/frontend/src/app/modules/hal/resources/work-package-resource.ts @@ -59,7 +59,7 @@ export interface WorkPackageResourceEmbedded { availableWatchers:HalResource|any; category:HalResource|any; children:WorkPackageResource[]; - parent:HalResource|any; + parent:WorkPackageResource|null; priority:HalResource|any; project:HalResource|any; relations:CollectionResource; @@ -237,7 +237,7 @@ export class WorkPackageBaseResource extends HalResource { } public isParentOf(otherWorkPackage:WorkPackageResource) { - return otherWorkPackage.parent.$links.self.$link.href === this.$links.self.$link.href; + return otherWorkPackage.parent?.$links.self.$link.href === this.$links.self.$link.href; } /**