# Menu & Navigation Management

Menu & Navigation Management gives administrators full control over the portal's navigation structure. Menus are stored in the database and loaded dynamically at runtime, so structural changes take effect immediately without a deployment. Access to individual menus and the pages they link to is controlled through the portal's security system — each user sees only the navigation items they are permitted to use.

## Table of Contents

* [Overview](#overview)
* [How the Dynamic Navigation System Works](#how-the-dynamic-navigation-system-works)
* [Menu Hierarchy](#menu-hierarchy)
  * [Top-Level Menu Items](#top-level-menu-items)
  * [Sub-Menus and Nested Items](#sub-menus-and-nested-items)
* [Routes and Menu Links](#routes-and-menu-links)
  * [What a Route Is](#what-a-route-is)
  * [How Menus and Routes Connect](#how-menus-and-routes-connect)
* [Per-User Menu Filtering](#per-user-menu-filtering)
  * [Security Groups and Menu Visibility](#security-groups-and-menu-visibility)
  * [Fallback Behavior for Unassigned Users](#fallback-behavior-for-unassigned-users)
  * [Container-Level Visibility and Section Cascade](#container-level-visibility-and-section-cascade)
* [Menu Administration](#menu-administration)
  * [Viewing the Menu List](#viewing-the-menu-list)
  * [Creating a Menu Item](#creating-a-menu-item)
  * [Editing a Menu Item](#editing-a-menu-item)
  * [Reordering Menu Items](#reordering-menu-items)
  * [Activating and Deactivating Menu Items](#activating-and-deactivating-menu-items)
  * [Deleting a Menu Item](#deleting-a-menu-item)
  * [Setting Menu Permissions](#setting-menu-permissions)
* [Route Administration](#route-administration)
  * [Viewing the Route List](#viewing-the-route-list)
  * [Creating a Route](#creating-a-route)
  * [Editing a Route](#editing-a-route)
  * [Public Routes](#public-routes)
  * [Deleting a Route](#deleting-a-route)
  * [Setting Route Permissions](#setting-route-permissions)
* [Troubleshooting](#troubleshooting)

***

## Overview

The navigation system in OtisEd.Nimble consists of two related concepts: **Menus** and **Routes**.

* A **Route** defines a URL path and the portal component (page) that should be displayed when a user visits that path. Routes are the technical backbone of the application's page structure.
* A **Menu item** is the visible link a user sees in the navigation bar. Each menu item is linked to a route (or an external URL) and carries display properties such as a label, icon, and sort position.

Because both menus and routes are stored in the database and delivered to the browser at login, administrators can change the entire portal navigation structure through the administration interface with no code changes required.

Key capabilities:

* Unlimited levels of parent/child menu hierarchy
* Each menu item optionally linked to an internal route or an external URL
* Per-user visibility based on security group membership
* Optional URL parameters appended automatically to menu links
* Control over whether links open in the same tab or a new window
* Routes can be marked public (accessible without login) or restricted to authenticated users

On some branded deployments, a designated parent menu also drives the **public home page** — its child items populate both the top navigation bar and the explore cards that visitors see on the public landing page. See [Public Pages](/guides/public-pages.md) for details on configuring that menu and linking it to the home page via the Public Site Menu ID setting.

***

## How the Dynamic Navigation System Works

When a user logs in, the portal performs two separate API calls before rendering the navigation bar:

1. **Route loading** — The portal requests only the routes this user is permitted to access. The browser uses this list to build the internal page router. Routes not in this list are treated as unknown pages.
2. **Menu loading** — The portal requests only the menu items this user is permitted to see. These items are assembled into the hierarchical tree that appears in the navigation bar.

Both lists are filtered server-side based on the user's identity and security group memberships. A user who is not assigned to any security group receives only the Dashboard route and its associated menu item, acting as a safe default.

The navigation bar renders automatically once these lists are loaded. Subsequent page navigations within the portal do not require additional API calls for the menu — the full permitted menu tree is already available in memory.

***

## Menu Hierarchy

### Top-Level Menu Items

Top-level items are the root entries that appear directly in the main navigation bar. They have no parent assigned (the Parent field is left empty or set to zero). Top-level items with children act as dropdown triggers — clicking them expands the list of sub-items rather than navigating anywhere.

Top-level items that have no children must be linked to a route or external URL so that clicking them navigates the user somewhere useful.

### Sub-Menus and Nested Items

A menu item becomes a child of another item by setting its **Parent** field to the desired parent menu. The portal supports multiple levels of nesting. The navigation bar renders these as expandable sub-menus:

* On desktop, clicking a parent item opens its children as a dropdown. Only one top-level dropdown is open at a time — opening a second one closes the first.
* On mobile and tablet, the navigation bar appears as a slide-in panel. All levels of nesting are shown expanded at once so that users can see the full menu without multiple taps.

Child items that themselves have children follow the same expand/collapse behavior, rendering a directional caret to indicate they can be expanded.

The **Sort Order** field controls the position of items within their level. Items with lower numbers appear first. Sort order is evaluated independently at each level of the hierarchy, so a top-level item and a sub-item can both have a sort order of 1 without conflict.

***

## Routes and Menu Links

### What a Route Is

A route is a mapping between a URL path and a named portal component (page). Every page in the portal that requires dynamic access control must have a corresponding route record. The route record stores:

| Field     | Description                                           |
| --------- | ----------------------------------------------------- |
| Name      | A descriptive label used when linking routes to menus |
| Path      | The URL path, such as `/reports/assessment`           |
| Component | The internal name of the React component to render    |
| Is Public | Whether the page is accessible without authentication |
| Is Active | Whether the route is currently enabled                |

Routes are tenant-specific. Each tenant in a multi-tenant deployment maintains its own route records.

### How Menus and Routes Connect

When creating or editing a menu item, an administrator selects a route from a dropdown lookup. The portal then resolves the route's path at display time and uses it as the link target for the menu item.

A menu item can alternatively specify an **External URL** instead of a route. This is useful for linking to third-party systems or resources outside the portal. If an external URL is provided, the route selection is ignored.

The **Target** field controls how the link opens:

* **Same window** — The default. The portal navigates within the current browser tab.
* **New window** — The link opens in a new browser tab. This is typically used for external URLs.

The **Parameters** field allows optional query-string parameters to be appended to the resolved URL automatically. For example, a parameter value of `?year=2024` would be appended to every click of that menu item. This is useful for pre-filtering report pages without requiring the user to select a filter manually.

A menu item with an External URL of `#` (a hash only) is treated as a parent placeholder — it renders as a non-navigating expandable label used solely to group child items under a heading in the menu.

***

## Per-User Menu Filtering

### Security Groups and Menu Visibility

Menu items and routes are both protected by the portal's security system. The filtering is applied at the API level before data reaches the browser, so users have no ability to circumvent visibility rules through direct URL access alone.

Permissions are attached to menu items and routes separately, and both must permit a user for end-to-end access to work correctly:

* **Menu permissions** determine whether the menu item appears in the navigation bar.
* **Route permissions** determine whether the corresponding page is loadable. A user who somehow navigates to a route URL they are not permitted to access will be redirected to the "page not found" screen.

Permissions are assigned to security roles (groups), and users inherit permissions through their role memberships. When a menu item's permissions are updated, the change applies the next time affected users load the portal.

### Fallback Behavior for Unassigned Users

If a user has no security group memberships at all, the portal applies a fallback: the user receives only the Dashboard route and the menu item linked to the Dashboard component. This prevents a blank or broken navigation state for users who have been created but not yet assigned to any group. Administrators should assign users to appropriate groups after account creation to restore normal navigation.

### Container-Level Visibility and Section Cascade

On report pages that use the Container Viewer, section groups in the side navigation can also disappear based on content visibility — not just security permissions. When all containers in a section group are suppressed for the selected organization and reporting term, the group's entry is removed from the side navigation automatically. This cascade is independent of menu permissions: a group can be fully permitted but still hidden because no visible containers remain for the current organization.

If a user switches organizations and their active section cascades out, the portal auto-navigates to the nearest non-empty section and shows a notification. First-load URL navigation is always silent.

For the full cascade rules, the five container render states, and operator configuration, see [Container-Level Visibility](/guides/container-level-visibility.md).

***

## Menu Administration

Administrators with the Menus permission can access the menu management interface. Users require the specific Create, Edit, or Delete sub-permission to perform those actions.

### Viewing the Menu List

**Where to find it:** Administration menu > Menus

The menu list displays all menu items for the current tenant. The list can be filtered by name, active status, icon, route, parent range, and sort order range. Each row shows the item name, its linked route (if any), parent identifier, sort order, and active status.

### Creating a Menu Item

1. Open the Menus administration page.
2. Select **New** (or equivalent create action).
3. Complete the form fields:

| Field        | Required | Description                                                                                                                                                                                                    |
| ------------ | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Name         | Yes      | The label displayed in the navigation bar                                                                                                                                                                      |
| Route        | No       | The internal route this item links to                                                                                                                                                                          |
| External URL | No       | A URL to use instead of a route (e.g., an external site)                                                                                                                                                       |
| Parent       | No       | Leave empty for a top-level item; select a parent item for nesting                                                                                                                                             |
| Sort Order   | Yes      | Numeric position within the same level (lower = earlier)                                                                                                                                                       |
| Icon         | No       | Icon class name or image path to display alongside the label. On branded deployments that use menu-driven public home pages, this field is treated as an image path and rendered as the explore card's visual. |
| Parameters   | No       | Query-string parameters appended to the resolved URL                                                                                                                                                           |
| Target       | No       | Same window (default) or new window                                                                                                                                                                            |
| Is Active    | Yes      | Uncheck to hide this item from all users without deleting it                                                                                                                                                   |

4. Save the record.

The new item appears in navigation bars immediately for users who reload the portal.

> When creating child items under the menu group used for the public home page (identified by the **Public Site Menu ID** site setting), each child's Name, Icon, and destination fields drive both the navbar links and the explore cards on the public landing page. See [Public Pages](/guides/public-pages.md) for the full setup walkthrough.

### Editing a Menu Item

1. Open the Menus administration page.
2. Locate the item in the list.
3. Open the item's edit form.
4. Make the required changes and save.

Changes are reflected in navigation bars at the next portal load for affected users.

### Reordering Menu Items

Sort order is controlled by the **Sort Order** field on each menu item. To change the position of an item within its level, edit the item and update the Sort Order value. Gaps between values (for example, using increments of 10 rather than 1) make it easier to insert new items later without renumbering all existing entries.

### Activating and Deactivating Menu Items

A menu item with **Is Active** set to false is excluded from every user's navigation, regardless of their security group membership. This is the recommended way to temporarily remove an item from navigation without deleting it or losing its configuration.

To deactivate a menu item:

1. Open the item's edit form.
2. Uncheck **Is Active**.
3. Save.

Child items under a deactivated parent continue to exist in the database, but because the parent is not visible, they will not be rendered. If you reactivate the parent, all active children reappear automatically.

### Deleting a Menu Item

1. Open the Menus administration page.
2. Locate the item.
3. Select the delete action and confirm.

Deleting a parent item does not automatically delete its children. Child items whose parent no longer exists will have an orphaned parent reference and will not appear in navigation until their parent is reassigned or they are promoted to top-level items.

Before deleting a parent item, review and reassign or delete its children first.

### Setting Menu Permissions

Menu permissions control which security groups can see a menu item.

1. Open the Menus administration page.
2. Locate the item.
3. Open the permissions editor for that item.
4. Add or remove security roles as needed.
5. Save the permission list.

Users whose roles include at least one of the assigned permissions will see the item. Users with no matching roles will not see it, even if they navigate directly to its path.

***

## Route Administration

Administrators with the Routes permission can access the route management interface.

### Viewing the Route List

**Where to find it:** Administration menu > Routes

The route list shows all route records for the current tenant. The list can be filtered by name, path, component, public status, and active status.

### Creating a Route

Routes should be created before linking them to menu items. A route must exist in the database for it to appear in the menu item's route dropdown.

1. Open the Routes administration page.
2. Select the create action.
3. Complete the form:

| Field     | Required | Description                                               |
| --------- | -------- | --------------------------------------------------------- |
| Name      | Yes      | Descriptive label used in the menu route lookup           |
| Path      | Yes      | URL path, starting with `/` (e.g., `/reports/assessment`) |
| Component | Yes      | Internal component name the portal uses to load the page  |
| Is Public | No       | Check if the page should be accessible without logging in |
| Is Active | Yes      | Uncheck to disable the route without deleting it          |

4. Save the record.

After saving, the route appears in the route lookup when creating or editing menu items.

### Editing a Route

1. Open the Routes administration page.
2. Locate the route.
3. Open the edit form, make changes, and save.

If you change a route's path, any menu items linked to that route will automatically resolve the new path on next page load. There is no need to update linked menu items manually.

### Public Routes

Routes with **Is Public** enabled are included in the user's route list even for unauthenticated or anonymous visitors. Use public routes for pages such as login splash screens, public report views, or informational pages that should be accessible without authentication.

Public routes are still subject to active/inactive status. A public route with **Is Active** unchecked will not be served to any user.

### Deleting a Route

1. Open the Routes administration page.
2. Locate the route.
3. Select the delete action and confirm.

Before deleting a route, check whether any menu items reference it. Menu items linked to a deleted route will have no valid path and may display incorrectly in navigation. Reassign or delete those menu items first.

### Setting Route Permissions

Route permissions control which security roles can load a given page.

1. Open the Routes administration page.
2. Locate the route.
3. Open the permissions editor.
4. Add or remove security roles.
5. Save.

Route permissions are enforced server-side. When the portal loads routes for a user, only routes associated with at least one of the user's roles are returned. A user who navigates directly to a restricted path will find it unrecognized by the browser router and will land on the "page not found" screen.

***

## Troubleshooting

**A menu item is not appearing for a user.**

* Confirm the menu item has **Is Active** checked.
* Confirm the user's security role is listed in the menu item's permissions.
* Confirm the parent item (if any) is also active and visible to the same user.
* Ask the user to reload the portal. Menu and route data is loaded at startup; changes made after login require a page refresh to take effect.

**Clicking a menu item leads to a "page not found" screen.**

* The linked route may have been deleted or deactivated. Open the menu item in administration and verify its route selection.
* The user may not have route permission for the linked route. Confirm the user's role is included in the route's permissions.
* The route path may have a typo. Verify the path field on the route record starts with `/` and matches the expected URL pattern.

**A user sees a blank navigation bar.**

* The user may not be assigned to any security group. Assign the user to at least one group that has menu permissions.
* All menu items may be inactive. Check the Menus list for items with **Is Active** enabled.
* The portal may be in maintenance mode. Check Site Settings if this is unexpected.

**A user can see a menu item but cannot access the underlying page.**

* The user has menu permission but not route permission. Open the linked route in Route administration and add the user's role to the route's permission list.

**A menu item opens in the same tab but should open in a new window.**

* Edit the menu item and change the **Target** field to "New window."

**Parameters are not being appended to the URL when a menu item is clicked.**

* Confirm the **Parameters** field on the menu item contains a valid query string, including the leading `?` (for example, `?year=2024`). The portal appends the parameters value exactly as entered.

**Changes to the public home-page menu are not appearing on the landing page.**

* Confirm the parent menu's numeric ID matches the value in the **Public Site Menu ID** site setting (Site Settings > Public Site Navigation). If the IDs do not match, the home page reads a different menu.
* Confirm the child items are active and saved correctly.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://nimble.docs.otised.com/guides/menu-navigation.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
