Skip to content

@volo/ngx-lepton-x.core NavbarService does not select dynamic menu item if their URL matches a previously defined menu item #25709

Description

@yonguelink

Is there an existing issue for this?

  • I have searched the existing issues

Description

If you need to add a dynamic menu to Lepton X and that menu shares the start of its URL with an already existing menu item, then when selecting the dynamic menu in the UI, the other menu item gets selected instead.

Reproduction Steps

  1. In route.provider.ts add a static route that has a basic path such as:
    routes.add([{
        path: '/base-path',
        name: 'Base Menu'
        // ...
    }]);
  2. Then dynamically add an item to the routes (e.g.: in your root page (/)
    this.routes.add([{
        path: '/base-path/some-other-path',
        name: 'Other Menu'
    }]);

Expected behavior

The Other Menu is selected

Actual behavior

The Base Menu gets selected

Regression?

I think it is because we migrated from ABP 9 where the issue wasn't present to ABP 10 which has the issue.

Known Workarounds

I patched the NavbarService with the following diff:

diff --git a/fesm2022/volo-ngx-lepton-x.core.mjs b/fesm2022/volo-ngx-lepton-x.core.mjs
index 62f4f478875b94d0f4d289d500ee8100bcec947a..bc7c6deab2621f67c269b9a42d6324ec44aa04ae 100644
--- a/fesm2022/volo-ngx-lepton-x.core.mjs
+++ b/fesm2022/volo-ngx-lepton-x.core.mjs
@@ -1346,10 +1346,13 @@ class NavbarService {
                     }
                 }
             }
-            // No exact match found, return best prefix match
-            return { item: bestMatch, location: bestMatchLocation };
+            return {};
         };
-        return searchTree(navbarItems);
+        const exactMatch = searchTree(navbarItems);
+        if (exactMatch.item) {
+            return exactMatch;
+        }
+        return { item: bestMatch, location: bestMatchLocation };
     }
     addContainerLinks(items, link = '') {
         return items.map((item) => ({

Which instead of shortcutting as soon as a node is a potential match (i.e.: a parent) simply runs the whole tree down and if there's an exact match anywhere, then stops & return that exact match. If no exact match is found, then the best match is returned (as it is currently)

Version

10.4

User Interface

Angular

Database Provider

EF Core (Default)

Tiered or separate authentication server

Tiered

Operation System

Linux

Other information

No response

Metadata

Metadata

Labels

Type

No type

Fields

No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions