Skip to content

feat(#10583): add the admin dashboards and one role-aware admin dashboard menu entry - #10595

Open
agatha197 wants to merge 30 commits into
feat/gh-10582-dashboard-filter-barfrom
feat/gh-10583-admin-dashboard-routes
Open

agatha197 wants to merge 30 commits into
feat/gh-10582-dashboard-filter-barfrom
feat/gh-10583-admin-dashboard-routes

Conversation

@agatha197

@agatha197 agatha197 commented Oct 26, 2026 •

Copy link
Copy Markdown
Contributor

Resolves #10583

Summary

Fourth layer of the role-aware dashboard stack (#10422). The admin dashboard gets real routes and one menu entry that resolves by role.

  • Routes: AdminDashboardPage takes a page prop and is mounted at /admin/dashboard (admin, superadmin only) and /project/:projectName/admin/dashboard (projectAdmin). The project admin page reads its project from the URL only; the superadmin page passes no project and its page query counts the current domain (ADR 0012). Legacy /admin-dashboard redirects by role.
  • One menu entry: admin-dashboard is the first admin sidebar item for superadmins and for the current project's project admin; domain admins keep today's behaviour (no dashboard entry). pathBuilder.ts gains a role-aware resolver (superadmin wins); getPathFromMenuKey takes the admin role; /project/:name/admin lands a project admin on the dashboard.
  • Project-agnostic only on /admin: admin-dashboard is in PROJECT_AGNOSTIC_MENU_KEYS with canonical path /admin/dashboard, and useIsProjectAgnosticPage also checks the route scope, so the project admin page keeps the header project selector.
  • Explicit project: DashboardPanelBoard takes a project prop; cards read it through useDashboardProject / useDashboardQueryScope. AdminDashboardPage.tsx and DashboardPanels/** join the ESLint ban on the ambient project.
  • Catalog: agent stats and active agents only on the superadmin dashboard; the project-wide active sessions card only on the admin dashboards. The member dashboard query no longer asks for agent stats.
  • ADR 0001 amended (the admin dashboard is no longer an exception; key list updated), ADR 0018 gains the project admin page rules; docs/ARCHITECTURE.md row updated.

Changes after the 2026-10-26 review

  • Pinned boards are gone (Store dashboard boards in manager app config with role templates #10581), so the code that moved the URL to a pinned board's project is removed. The admin dashboards use the same refresh bar and per-card settings as the member dashboard: no project, resource group or range picker above the board. The superadmin resource group totals card has its own query and resource group setting.

Behaviour notes for review

  • Domain admins can still open /project/:n/admin/dashboard by URL through the subtree's default access (a comment on the route says so); scoped reads authorize the data.
  • The project admin dashboard shows only Active Sessions and custom panels until Project admin dashboard cards scoped to the managed projects #10585 adds its cards.
  • webui.menu.AdminDashboard had no other users and is removed from all locales; the route label is webui.menu.Dashboard.
  • Running prettier on ADR 0001 reformatted a few unrelated lines (required by the Format check).

Verification

VERIFY_BASE=feat/gh-10582-dashboard-filter-bar bash scripts/verify.sh
...
total: 19s
=== ALL PASS ===
  • VERIFY_TESTS=1: react Vitest 76 files, 841 tests pass; new useWebUIMenuItems.test.tsx role matrix (superadmin, domain admin, project admin, user); updated path, header and project-agnostic tests.
  • Browser check as a superadmin against a 26.10 manager: "Admin Settings" opens /admin/dashboard, whose first sidebar item is "Dashboard"; the page shows the board tab, the filter bar and the admin cards without a header project selector; /admin-dashboard redirects there; /project/default/admin/dashboard keeps the header selector; the member dashboard no longer shows agent cards.

Server load

  • The page query includes the session count, recently created sessions, total resources and agent stats fragments only while a rendered card reads them, refreshes no faster than its fastest reader (never faster than the previous 15s / 30s page interval), and stops refreshing when no card reads it. The project admin page no longer fetches recently created sessions, up to 100 agents with their slots, or (for a superadmin) agent stats every 30s, none of which it can show; a card removed from a board stops being fetched.

🤖 Generated with Claude Code

Walkthrough

Not shown in the walkthrough:

  • Domain admin view: no Dashboard item in the admin sidebar (this server signs in as a superadmin)
  • Legacy /admin-dashboard redirecting by role
  • Picking a pinned board on the project admin page moving the URL to its first pinned project
  • ADR 0001 and ADR 0018 updates, ESLint ambient-project ban on the dashboard engine
  • Menu role-matrix and path-resolution tests

Decisions (2026-10-29)

  • The page query refreshes on every dashboard tick while a rendered card reads it; pageQueryRefresh (the fastest reader's minimum) is removed with the per-card minimums (ADR 0018).

Risk tier: High — docs/ARCHITECTURE.md, docs/adr/0001-explicit-project-prop-contract.md, docs/adr/0018-dashboard-filter-bar.md, react/eslint.config.js, react/src/hooks/useRouteScope.ts
Suggested human approvals: 2 (branch protection decides)
Reviewed by fw ready gate at afa5dda (round 1)

Ready gate (round 1)

  • ec5b272: the superadmin page keeps its own domain-wide resource group; the session grid and the deployment/data presets read the page's scope (project or current domain); the eslint block repeats the useSetCurrentProject ban; stale JSDoc removed.

@agatha197

agatha197 commented Oct 26, 2026 •

Copy link
Copy Markdown
Contributor Author

Dev server on box sujin: stopped (was http://gh-10584-pr10596-rebuild-member-dashboard.sujin.10-82-0-159.sslip.io)

@agatha197

Copy link
Copy Markdown
Contributor Author

📍 Walkthrough · 4 stops · 38dec72 — Open the walkthrough
Served by gh-10583-pr10595-add-admin-dashboards.

  1. Dashboard › page-admin-dashboard › div "Skip to content Admin Settings Dashboard Operations Users Projec" — added menu
    The admin settings sidebar gained "Dashboard" as its first item. One entry serves both admin roles: a superadmin lands on /admin/dashboard, a project admin on /project//admin/dashboard. Before, the admin dashboard had no menu entry.
    check: Signed in as a superadmin, "Admin Settings" opens this page with "Dashboard" highlighted at the top of the sidebar; a domain admin sees no Dashboard item.
    code: react/src/hooks/useWebUIMenuItems.tsx:1, react/src/helper/pathBuilder.ts:1
  2. Dashboard › page-admin-dashboard › button "New board" — added button
    The superadmin dashboard shows the board tabs from the storage layer: "Default" plus "New board", with edit and delete next to the active tab. They were unreachable before this route existed.
    check: "New board" adds a "Board 2" tab seeded from the default layout; deleting it asks for confirmation, and the last board cannot be deleted.
    code: react/src/components/DashboardPanels/DashboardBoardTabs.tsx:1
  3. Dashboard › dashboard-filter-bar › div "ProjectsAll projectsNo resultsTotal 0 itemsResource groupsAll re" — added toolbar
    The superadmin dashboard has no header project selector; its filter bar picks projects of the current domain instead, and the cards read that domain (agent stats and active agents now appear only here).
    check: "All projects" lists this domain's projects; with none chosen, Active Sessions counts the whole current domain. The header shows no project selector on this page.
    code: react/src/pages/AdminDashboardPage.tsx:1, react/src/components/DashboardPanels/panelCatalog.tsx:300
  4. Dashboard › dashboard-filter-bar › div "Projects default Resource groups All resource groups Time range " — added toolbar
    The project admin dashboard lives under the project admin pages and keeps the header project selector; its filter bar starts on the URL's project.
    check: The filter bar's project picker reads "default" (the project in the address); switching the header project moves the page to that project's dashboard.
    code: react/src/routes.tsx:1, react/src/hooks/useIsProjectAgnosticPage.ts:1

@github-actions

github-actions Bot commented Oct 26, 2026 •

Copy link
Copy Markdown
Contributor

Coverage Report for react-coverage (./react)

Status Category Percentage Covered / Total
🔵 Lines 24.75% 10052 / 40611
🔵 Statements 22.08% 13309 / 60275
🔵 Functions 21.37% 1706 / 7981
🔵 Branches 17.62% 7601 / 43115
File Coverage
File Stmts Branches Functions Lines Uncovered Lines
Changed Files
react/src/routes.tsx 19.32% 2.73% 0% 23.55% 55-56, 58-59, 61, 62, 65-66, 67, 69-70, 71, 72, 74-75, 77-78, 79, 81-82, 84-85, 87-88, 90-91, 94-95, 97-98, 100-101, 102, 104-105, 106, 108, 109, 110, 111, 113-114, 116-117, 118, 120, 122, 123, 125-126, 128, 129, 131-132, 133, 135-136, 138-139, 141-142, 144-145, 147-148, 150-151, 153-154, 156-157, 159-160, 162-163, 166-167, 172-176, 193-229, 238-242, 311-1407, 1447-1458, 1462-1464, 1481-1488, 1608-1667
react/src/components/SessionResourceGrid.tsx 3% 0% 0% 4.34% 112-116, 119, 126-129, 162-500
react/src/components/TotalResourceWithinResourceGroup.tsx 2.45% 0% 0% 3.96% 110-157, 177-182, 196-422
react/src/components/UserDropdownMenu.tsx 2.09% 0% 0% 3% 56, 59-60, 80-233
react/src/components/DashboardPanels/DashboardEditSider.tsx 0% 0% 0% 0% 52-277
react/src/components/DashboardPanels/DashboardPanelBoard.tsx 0% 0% 0% 0% 39-169
react/src/components/DashboardPanels/DeploymentNodesPanel.tsx 2.89% 0% 0% 4.25% 42-90
react/src/components/DashboardPanels/ResourceCountPanel.tsx 3.07% 0% 0% 6.06% 33-39, 60-85
react/src/components/DashboardPanels/ResourceTablePanel.tsx 3.09% 0% 0% 5.35% 50-68, 111-149
react/src/components/DashboardPanels/SessionNodesPanel.tsx 1.51% 0% 0% 2.22% 32-69
react/src/components/DashboardPanels/SessionResourceGridPanel.tsx 3.5% 0% 0% 6.45% 29-34, 61-67
react/src/components/DashboardPanels/boardModel.ts 96.26% 86.56% 92.45% 96.39% 79-81, 194-197, 386, 407-411
react/src/components/DashboardPanels/pageQuery.ts 100% 100% 100% 100%
react/src/components/DashboardPanels/panelCatalog.tsx 15.28% 12.35% 20% 23.95% 46-48, 52-54, 58-61, 76-78, 92-95, 114-117, 133-138, 155-159, 175-185, 215-216, 227-229, 238-240
react/src/components/DashboardPanels/resourceRegistry.tsx 26.08% 0% 4.54% 28.57% 58, 66-70, 76-87, 96-99, 111-117, 163-180, 223-259, 299-344, 361-365, 372-374
react/src/components/DashboardPanels/types.ts 100% 100% 100% 100%
react/src/components/DashboardPanels/useDashboardBoard.tsx 0% 0% 0% 0% 64-283
react/src/components/DashboardPanels/useDashboardFilters.tsx 12.72% 0% 0% 18.91% 38-43, 57-63, 90, 94, 98-103
react/src/components/MainLayout/WebUIHeaderProjectSelect.tsx 1.03% 0% 0% 1.38% 52-77
react/src/components/MainLayout/WebUISiderNavigation.tsx 1.78% 0% 0% 2.77% 35-119
react/src/helper/pathBuilder.ts 100% 100% 100% 100%
react/src/helper/projectAgnosticRoutes.ts 100% 75% 100% 100%
react/src/hooks/useIsProjectAgnosticPage.ts 100% 85.71% 100% 100%
react/src/hooks/useRouteScope.ts 53.19% 42.62% 58.33% 57.33% 194-210, 239-243, 275-282
react/src/hooks/useWebUIMenuItems.tsx 94.13% 66.1% 86.2% 92.51% 200, 401, 639-654, 672, 898-914, 907
react/src/pages/AdminDashboardPage.tsx 0% 0% 0% 0% 32-146
react/src/pages/DashboardPage.tsx 0% 0% 0% 0% 29-120
Generated in workflow #2734 for commit 9b15068 by the Vitest Coverage Report Action

@agatha197
agatha197 force-pushed the feat/gh-10583-admin-dashboard-routes branch from 38dec72 to f428f6a Compare October 26, 2026 08:20
@agatha197
agatha197 force-pushed the feat/gh-10583-admin-dashboard-routes branch 2 times, most recently from 580f6df to a7d0107 Compare October 26, 2026 10:28
@agatha197
agatha197 force-pushed the feat/gh-10583-admin-dashboard-routes branch from a7d0107 to 5582763 Compare October 27, 2026 01:24
@agatha197
agatha197 force-pushed the feat/gh-10583-admin-dashboard-routes branch from a057625 to 540a87e Compare October 27, 2026 02:07
agatha197 and others added 5 commits October 27, 2026 02:32
…oard menu entry

The admin dashboard page existed at /admin/dashboard but no menu reached it,
it read the ambient header project, and the member dashboard still carried
the superadmin cards. Project admins and superadmins now each have a
dashboard behind one "Dashboard" entry at the top of the admin sidebar.

- Routes: AdminDashboardPage takes `page`. `/admin/dashboard` mounts it as
  `admin` (access superadmin) and `/project/:projectName/admin/dashboard`
  as `projectAdmin`, both with menuKey `admin-dashboard`. The project admin
  page reads its project from the URL (useUrlProjectValidity); the
  superadmin page passes `null` and its page query counts the current
  domain (`domain:<name>`, ADR 0012). Legacy `/admin-dashboard` redirects
  by role. Domain admins can still open the project admin page by URL
  through the subtree's default `projectAdmin` access; only the menu hides
  it from them.
- Menu: `admin-dashboard` is the first admin item for superadmins and for
  the current project's project admin, and absent for domain admins.
  pathBuilder gains PROJECT_ADMIN_MENU_KEY_ROUTES,
  resolveMenuKeyScopeFeature (superadmin wins over project admin) and
  featureKeyInScope, which the inverse lookups in useRouteScope and
  WebUIHeaderProjectSelect now use. getPathFromMenuKey takes the admin
  role; the sider's "Admin settings" entry and the /admin index redirect
  use the role-resolved item `to`, and the /project/:name/admin index
  redirect resolves as project admin.
- Project-agnostic surface: `admin-dashboard` joins
  PROJECT_AGNOSTIC_MENU_KEYS for `/admin/dashboard` only.
  useIsProjectAgnosticPage now requires the `admin` route scope for the
  menu-key match, so the project admin page keeps the header project
  selector; the legacy path regex fallback is unchanged.
- Explicit project: DashboardPanelBoard takes `project` and its filter
  context now carries it (and wraps the panel modal). Cards read it through
  useDashboardProject, custom panel queries through useDashboardQueryScope
  (the session preset falls back to the current domain when the project is
  null). AdminDashboardPage and components/DashboardPanels/** join the
  ESLint ban on useCurrentProjectValue.
- Catalog: agentStats and activeAgents live on the superadmin page only,
  activeSessions on the project admin and superadmin pages; the member page
  query no longer asks for agent stats.
- Pinned boards (open item from #10582): on the project admin page,
  choosing a pinned board whose pins do not contain the URL project moves
  the URL path to the first pinned project the viewer administers; a
  header project change inside the pins keeps the pinned board. The
  project picker always offers the URL project, so a superadmin who opens
  the project admin page by URL sees its name instead of its id.
- ADR 0001 drops the "admin dashboard is the only exception" sentences and
  records the dashboards; ADR 0015 records the pinned-board navigation and
  the page project; the ARCHITECTURE row follows.
- The route label is `webui.menu.Dashboard`; the now unused
  `webui.menu.AdminDashboard` is removed from all 21 locales. Search index
  regenerated.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…work

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
#10552 split the sider into a system admin menu (entered from the user
menu) and a Project Settings menu, and rebasing onto it left the
role-aware Dashboard entry broken: the project admin menu listed the
superadmin's dashboard at /admin/dashboard, /admin/dashboard selected the
Project Settings sider because its menu key is in both menus, a domain admin
who administers the project had no project dashboard, and the sider no
longer imported getPathFromMenuKey.

- The Project Settings menu always links a per-role key to its project
  admin route; the system admin menu keeps it only for superadmins.
- A per-role key is selected only in the menu whose item points at the
  current URL's scope.
- The dashboard item exists for superadmins and for anyone administering
  the current project; domain admins alone still have none.
- The sider's Project Settings entry, the user menu's system admin entry
  and the root redirect use the role-resolved item `to`.
- The menu test follows the split menus.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…in pages

The dashboard Edit button is rendered in the breadcrumb, which sat outside the
admin accent provider that wraps the page content, so on the project admin
dashboard it kept the user theme's primary color.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@agatha197
agatha197 force-pushed the feat/gh-10583-admin-dashboard-routes branch from 540a87e to 4fba318 Compare October 27, 2026 02:38
agatha197 and others added 2 commits October 27, 2026 03:25
The sider no longer labels a card "Superadmin only" or shows a greyed-out
"Not available in this environment" entry: role-limited cards were already
absent for other roles, and config-locked cards are now left out too. The
superadmin-only agent cards move into the Resources group, and the two
unused strings leave every locale.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
agatha197 and others added 6 commits October 27, 2026 05:37
The dashboard edit toggle it was added for is a secondary button now.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…admin-dashboard-routes

# Conflicts:
#	react/src/components/DashboardPanels/DashboardPanelBoard.tsx

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has insufficient remaining quota.

…admin-dashboard-routes

# Conflicts:
#	react/src/components/DashboardPanels/useDashboardFilters.tsx
@agatha197

Copy link
Copy Markdown
Contributor Author

Ready-gate agent review (Opus) - blocking issues only

No blocking issues.

Copilot: unavailable (insufficient remaining quota) - this review gated the PR alone. The fixes above landed after the review and were not re-reviewed; verified by VERIFY_TESTS=1 scripts/verify.sh ALL PASS on the stack top 8a250e2ad2 and on the review server.

@agatha197
agatha197 marked this pull request as ready for review October 27, 2026 13:41
agatha197 and others added 8 commits October 29, 2026 01:04
The dashboard page query carried the session count, recently created
sessions, total resources and agent stats fragments on every page and
refreshed all of them on the page timer, whether or not a card on the
board reads them. The project admin page offers none of the last three
cards, yet fetched recently created sessions and up to 100 agents with
their slots every 30s (plus agent stats for a superadmin); a card removed
from a board kept being fetched too.

Each fragment is now included only while a rendered card reads it, the
page query refreshes no faster than its fastest reader (never faster than
the previous page interval), and it stops refreshing when no card reads it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…admin-dashboard-routes

# Conflicts:
#	react/src/components/DashboardPanels/DashboardPanelBoard.tsx
…admin-dashboard-routes

The page query now refreshes on every dashboard tick while a rendered card
reads it; `pageQueryRefresh` (the fastest reader's `refresh.min`) is gone
with the per-card minimums (ADR 0017).

@agatha197 agatha197 left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ready-gate agent review — 7 findings — 5 Important, 2 Nit, 0 Pre-existing. The summary comment on this PR lists every finding and its outcome.

Comment thread react/eslint.config.js
Comment thread react/src/components/DashboardPanels/SessionResourceGridPanel.tsx Outdated
Comment thread react/src/components/DashboardPanels/panelCatalog.tsx
Comment thread react/src/components/DashboardPanels/types.ts Outdated
Comment thread react/src/components/DashboardPanels/types.ts
Comment thread react/src/helper/projectAgnosticRoutes.ts
Comment thread react/src/pages/AdminDashboardPage.tsx
@agatha197

agatha197 commented Oct 30, 2026 •

Copy link
Copy Markdown
Contributor Author

7 findings — 5 Important, 2 Nit, 0 Pre-existing

Round 1 — afa5dda

# Tag File:line Finding Outcome
1 Important react/eslint.config.js:205 This per-file block redeclares no-restricted-imports, which replaces the global options, and its patterns omit the FR-3428 useSetCurrentProject ban; adding AdminDashboardPage.tsx and DashboardPanels/** here lifts that ban for those files, contrary to the block's own note that the global patterns are repeated. fixed ec5b272
2 Important react/src/components/DashboardPanels/SessionResourceGridPanel.tsx:77 On the superadmin page project is null, so the grid runs compute_session_list(group_id: null) with no domain_name and lists sessions from every domain, while the same panel in table view scopes to domain:<current>; ADR 0018 (amended in this PR) says a null project means the current domain. fixed ec5b272
3 Nit react/src/components/DashboardPanels/panelCatalog.tsx:52 Page-query cards render null while their fragment is excluded, and the fragment set is deferred, so a newly added My Sessions / Active Sessions card shows an empty body with no skeleton for the whole background round trip. not-worth
4 Nit react/src/components/DashboardPanels/types.ts:215 The old JSDoc ('Fragment keys of the page queries the built-in cards still read...') was left stacked above the new one on DashboardPageQueryRefs and describes the removed shape. fixed ec5b272
5 Important react/src/components/DashboardPanels/types.ts:283 The new domainName scope (null project = current domain) is ignored by the deployment and vfolder presets in resourceRegistry.tsx: deployment drops its project filter and queries myDeployments unfiltered on the superadmin page, and vfolder's makeOffsetVariables ignores both project and domain, so on the newly routed project admin page it lists every folder in the system. fixed ec5b272
6 Important react/src/helper/projectAgnosticRoutes.ts:47 Making /admin/dashboard project-agnostic unmounts the header project selector, but the superadmin page still takes its resource group from the now-hidden ambient project (useCurrentResourceGroupValue in AdminDashboardPage, useDashboardFilters, and the Total Resources card's SharedResourceGroupSelectForCurrentProject), so resource groups not bound to that project become unreachable. fixed ec5b272
7 Important react/src/pages/AdminDashboardPage.tsx:56 queryFetchKey switches on the non-deferred fragmentsKey while the variables use deferredFragmentsKey, so adding the first page-query card after a refresh tick gives the urgent render a new fetchKey with network-only and the query suspends into the route-level skeleton (the FR-3386 flash the deferral exists to prevent). The same block is in DashboardPage.tsx:47; basing queryFetchKey on deferredFragmentsKey avoids it. intentional — superseded: the page query is removed in #10596

Security review: 0 findings

Posted inline: 7 · already inline from this round: 0 · table only (outside the diff): 0 · repeats of an earlier round dropped: 0 · Nits over the cap of 3 dropped: 0 · not posted (no file:line, or style-only): 0

agatha197 and others added 5 commits October 30, 2026 07:10
# Conflicts:
#	react/src/components/DashboardPanels/DashboardPanelBoard.tsx
#	react/src/components/DashboardPanels/boardModel.test.ts
#	react/src/pages/AdminDashboardPage.tsx
#	react/src/pages/DashboardPage.tsx
…n page, lint ban

- The superadmin dashboard keeps its own resource group
  (superadminResourceGroupAtom via usePageResourceGroup), since its route
  hides the header project selector. It starts from the hidden current
  project's group, cards default to it, and the Total Resources card's
  picker lists every resource group of the current domain.
- The session grid view passes domain_name when the page has no project,
  so the superadmin grid reads the current domain like the table view.
- The deployment and data presets read scopedDeployments and
  scopedVFoldersV2 with the card's scope: the viewer on the member page,
  the URL project on the project admin page, the current domain on the
  superadmin page. ResourceQueryArgs carries domainId and ownerId.
- The project-agnostic eslint block repeats the global FR-3428
  useSetCurrentProject ban, which its own no-restricted-imports replaced.
- The stale JSDoc above DashboardPageQueryRefs is removed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:i18n Localization area:ux UI / UX issue. size:XL 500~ LoC

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Admin dashboard routes and one role-aware admin dashboard menu entry

2 participants