From a79294da1de61860de281c31f01552c871d5848c Mon Sep 17 00:00:00 2001 From: Stanley Hsu Date: Wed, 7 Jul 2021 10:54:13 +0200 Subject: [PATCH 1/4] Prevent to open a node w/o children and empty viewUrl --- core/src/services/routing.js | 21 +++++++++++++++++ .../e2e/tests/1-angular/navigation.spec.js | 23 +++++++++++++++++++ .../luigi-config/extended/projectDetailNav.js | 5 ++++ 3 files changed, 49 insertions(+) diff --git a/core/src/services/routing.js b/core/src/services/routing.js index 7efeae4307..5b6e44edd5 100644 --- a/core/src/services/routing.js +++ b/core/src/services/routing.js @@ -189,6 +189,27 @@ class RoutingClass { const pathUrlRaw = path && path.length ? GenericHelpers.getPathWithoutHash(path) : ''; const { nodeObject, pathData } = await Navigation.extractDataFromPath(path); const viewUrl = nodeObject.viewUrl || ''; + const hasChildrenNode = (nodeObject.children && nodeObject.children.length > 0) || false; + const intendToHaveEmptyViewUrl = + (nodeObject.intendToHaveEmptyViewUrl && nodeObject.intendToHaveEmptyViewUrl === true) || false; + + if (viewUrl.trim() === '' && !hasChildrenNode && !intendToHaveEmptyViewUrl) { + const warningMessage = 'This node was configured an empty viewUrl. Please double check it.'; + console.warn(warningMessage); + + // redirect to root when this empty viewUrl node be reached directly + if (!previousCompData.viewUrl) { + const rootPathData = await Navigation.getNavigationPath( + LuigiConfig.getConfigValueAsync('navigation.nodes'), + '/' + ); + const rootPath = await RoutingHelpers.getDefaultChildNode(rootPathData); + component.showAlert({ text: warningMessage, type: 'warning' }, false); + this.navigateTo(rootPath); + } + + return; + } if (!viewUrl && !nodeObject.compound) { const defaultChildNode = await RoutingHelpers.getDefaultChildNode(pathData, async (node, ctx) => { diff --git a/test/e2e-test-application/e2e/tests/1-angular/navigation.spec.js b/test/e2e-test-application/e2e/tests/1-angular/navigation.spec.js index ec045e0129..39c6cbc14a 100644 --- a/test/e2e-test-application/e2e/tests/1-angular/navigation.spec.js +++ b/test/e2e-test-application/e2e/tests/1-angular/navigation.spec.js @@ -260,6 +260,29 @@ describe('Navigation', () => { .should('be.visible'); }); }); + + it('Side nav does not broken while clicking empty viewUrl node', () => { + cy.get('.fd-shellbar') + .contains('Projects') + .click(); + + cy.get('.fd-app__sidebar .fd-nested-list__item') + .contains('Project One') + .click(); + + cy.get('.fd-side-nav') + .contains('Empty viewUrl node') + .click(); + + cy.get('.fd-side-nav').should('contain', 'Empty viewUrl node'); + }); + + it('Redirect to root path while reaching empty viewUrl node directly', () => { + cy.visit('/projects/pr2/emptyViewUrl'); + + cy.get('[data-testid=luigi-alert]').should('have.class', 'fd-message-strip--warning'); + cy.expectPathToBe('/overview'); + }); }); describe('Node activation hook', () => { diff --git a/test/e2e-test-application/src/luigi-config/extended/projectDetailNav.js b/test/e2e-test-application/src/luigi-config/extended/projectDetailNav.js index d5ca157cac..ad8d0927f9 100644 --- a/test/e2e-test-application/src/luigi-config/extended/projectDetailNav.js +++ b/test/e2e-test-application/src/luigi-config/extended/projectDetailNav.js @@ -280,6 +280,11 @@ export const projectDetailNavStructure = projectId => [ hideSideNav: true, icon: 'full-screen' }, + { + pathSegment: 'emptyViewUrl', + label: 'Empty viewUrl node', + viewUrl: '' + }, { pathSegment: 'virtual-tree', label: 'VirtualTree', From e20070bfe45ffc90486f71b0f863cea05666c780 Mon Sep 17 00:00:00 2001 From: Stanley Hsu Date: Wed, 7 Jul 2021 12:31:53 +0200 Subject: [PATCH 2/4] Change error alert --- core/src/services/routing.js | 5 ++--- .../e2e/tests/1-angular/navigation.spec.js | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/core/src/services/routing.js b/core/src/services/routing.js index 5b6e44edd5..f1b4e6d45e 100644 --- a/core/src/services/routing.js +++ b/core/src/services/routing.js @@ -194,8 +194,7 @@ class RoutingClass { (nodeObject.intendToHaveEmptyViewUrl && nodeObject.intendToHaveEmptyViewUrl === true) || false; if (viewUrl.trim() === '' && !hasChildrenNode && !intendToHaveEmptyViewUrl) { - const warningMessage = 'This node was configured an empty viewUrl. Please double check it.'; - console.warn(warningMessage); + console.warn('This node was configured an empty viewUrl. Please double check it.'); // redirect to root when this empty viewUrl node be reached directly if (!previousCompData.viewUrl) { @@ -204,7 +203,7 @@ class RoutingClass { '/' ); const rootPath = await RoutingHelpers.getDefaultChildNode(rootPathData); - component.showAlert({ text: warningMessage, type: 'warning' }, false); + this.showPageNotFoundError(component, rootPath, pathUrlRaw); this.navigateTo(rootPath); } diff --git a/test/e2e-test-application/e2e/tests/1-angular/navigation.spec.js b/test/e2e-test-application/e2e/tests/1-angular/navigation.spec.js index 39c6cbc14a..de68c74395 100644 --- a/test/e2e-test-application/e2e/tests/1-angular/navigation.spec.js +++ b/test/e2e-test-application/e2e/tests/1-angular/navigation.spec.js @@ -280,7 +280,7 @@ describe('Navigation', () => { it('Redirect to root path while reaching empty viewUrl node directly', () => { cy.visit('/projects/pr2/emptyViewUrl'); - cy.get('[data-testid=luigi-alert]').should('have.class', 'fd-message-strip--warning'); + cy.get('[data-testid=luigi-alert]').should('have.class', 'fd-message-strip--error'); cy.expectPathToBe('/overview'); }); }); From 631a775e7a13afd36362f8ba3d4336206b6f20c2 Mon Sep 17 00:00:00 2001 From: Stanley Hsu Date: Wed, 7 Jul 2021 14:25:51 +0200 Subject: [PATCH 3/4] Documentation --- docs/navigation-parameters-reference.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/navigation-parameters-reference.md b/docs/navigation-parameters-reference.md index 43f805fd4a..0f58c282ac 100644 --- a/docs/navigation-parameters-reference.md +++ b/docs/navigation-parameters-reference.md @@ -182,6 +182,9 @@ Node parameters are all the parameters that can be added to an individual naviga * dynamic path segments * node parameters +### intendToHaveEmptyViewUrl +- **type**: boolean +- **description**: forces to navigate to the empty viewUrl node. ### navigationContext - **type**: string - **description**: contains a named node that is mainly for use in combination with a dynamic **pathSegment** to start navigation from a dynamic node using ` LuigiClient.linkManager().fromContext('contextname')`. From ed3922374ce45214d70580d002edbf418b928544 Mon Sep 17 00:00:00 2001 From: Stanley Hsu Date: Thu, 8 Jul 2021 10:27:35 +0200 Subject: [PATCH 4/4] Update docs/navigation-parameters-reference.md Co-authored-by: Aleksandra Simeonova --- docs/navigation-parameters-reference.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/navigation-parameters-reference.md b/docs/navigation-parameters-reference.md index 0f58c282ac..1b151c0037 100644 --- a/docs/navigation-parameters-reference.md +++ b/docs/navigation-parameters-reference.md @@ -184,7 +184,7 @@ Node parameters are all the parameters that can be added to an individual naviga ### intendToHaveEmptyViewUrl - **type**: boolean -- **description**: forces to navigate to the empty viewUrl node. +- **description**: when set to `true`, it forces navigation to the empty **viewUrl** node. ### navigationContext - **type**: string - **description**: contains a named node that is mainly for use in combination with a dynamic **pathSegment** to start navigation from a dynamic node using ` LuigiClient.linkManager().fromContext('contextname')`.