feat(navigation): instance home app at /app, sidebar logo and breadcrumb root #53

Merged
KofTwentyTwo merged 5 commits from feature/home-app into main 2026-10-12 03:55:32 +00:00
KofTwentyTwo commented 2026-10-11 18:08:48 +00:00 (Migrated from github.com)

Why

Next UI's /app overview is hard-coded, so an application can't give users a real landing dashboard. Website-Backend now has a top-level home app (a widget dashboard) and redirects full page loads of /app/ to /app/home/ server-side. The sidebar logo and breadcrumb root, however, navigate client-side to /app and still show the generic overview.

What

This adds an instance-level home app. QQQ had nothing suitable (no home, default, or landing setting; the Material dashboard just uses the first accessible app), so the companion upstream change adds a minimal one: QRun-IO/qqq#1060 (QInstance.homeAppName, issue QRun-IO/qqq#1059). It is validated against the instance's apps, and the metadata publishes it only to users who may open that app.

When homeAppName is present and the app is in the user's metadata:

  • /app client-side redirects (router.replace) to /app/{homeAppName}, showing a busy placeholder meanwhile rather than flashing the overview.
  • Sidebar logo and the breadcrumb Home crumb link to that app.
  • One landing page: the home app becomes the single top nav entry, moved to the top whatever the backend's app order, in place of the built-in "Dashboard" entry. There are never two landing entries; kof22 labels its home app "Dashboard".

Without homeAppName, or when the named app is missing from the user's metadata (no access, or an older backend), behavior is unchanged: /app is Next's overview, and the logo and breadcrumb link to /app.

The logic lives in src/lib/utils/home-app.ts (homeAppName, homePath). buildRouteMap exposes the result as homePath, and the dashboard layout passes it to Sidebar and to Header → Breadcrumbs.

Tests

  • home-app.test.ts: designated app, URL encoding, and fallbacks (unset, empty, unknown app, no metadata).
  • use-routes.test.ts: homePath; the Dashboard entry kept or dropped; and no duplicate landing entry when homeAppName is set. The home app labeled "Dashboard" and ordered last becomes the single top entry, with no built-in /app entry.
  • Breadcrumbs.test.tsx / Sidebar.test.tsx: the home crumb and logo link to the home app or /app.
  • app/page.test.tsx (new): the overview without a home app; the redirect with one; the overview kept for an inaccessible app.

Local results:

  • pnpm typecheck and pnpm lint pass (0 errors; the 5 warnings are pre-existing), and so does the license check.
  • pnpm test: 2,168 passed. The 2 failures are the pre-existing Windows path-separator assertions in tests/standalone/acceptance-stage.test.ts and tests/acceptance/support/standalone-variant.test.ts; CI on Linux is authoritative.

Docs

The developer guide's /app route row and metadata section are updated, and docs/releases/unreleased.md gets a Features entry.

Merge order

The two PRs are independent. Before QQQ ships homeAppName, this PR is a no-op; once it ships, Next picks the field up. Not for a release: no version bump, tag or publish.

🤖 Generated with Claude Code

## Why Next UI's `/app` overview is hard-coded, so an application can't give users a real landing dashboard. Website-Backend now has a top-level `home` app (a widget dashboard) and redirects full page loads of `/app/` to `/app/home/` server-side. The sidebar logo and breadcrumb root, however, navigate client-side to `/app` and still show the generic overview. ## What This adds an instance-level **home app**. QQQ had nothing suitable (no home, default, or landing setting; the Material dashboard just uses the first accessible app), so the companion upstream change adds a minimal one: **QRun-IO/qqq#1060** (`QInstance.homeAppName`, issue QRun-IO/qqq#1059). It is validated against the instance's apps, and the metadata publishes it only to users who may open that app. When `homeAppName` is present and the app is in the user's metadata: - **`/app`** client-side redirects (`router.replace`) to `/app/{homeAppName}`, showing a busy placeholder meanwhile rather than flashing the overview. - **Sidebar logo** and the **breadcrumb Home crumb** link to that app. - **One landing page:** the home app becomes the **single top nav entry**, moved to the top whatever the backend's app order, in place of the built-in "Dashboard" entry. There are never two landing entries; kof22 labels its home app "Dashboard". Without `homeAppName`, or when the named app is missing from the user's metadata (no access, or an older backend), behavior is **unchanged**: `/app` is Next's overview, and the logo and breadcrumb link to `/app`. The logic lives in `src/lib/utils/home-app.ts` (`homeAppName`, `homePath`). `buildRouteMap` exposes the result as `homePath`, and the dashboard layout passes it to `Sidebar` and to `Header` → `Breadcrumbs`. ## Tests - **`home-app.test.ts`:** designated app, URL encoding, and fallbacks (unset, empty, unknown app, no metadata). - **`use-routes.test.ts`:** `homePath`; the Dashboard entry kept or dropped; and **no duplicate landing entry when `homeAppName` is set**. The home app labeled "Dashboard" and ordered last becomes the single top entry, with no built-in `/app` entry. - **`Breadcrumbs.test.tsx` / `Sidebar.test.tsx`:** the home crumb and logo link to the home app or `/app`. - **`app/page.test.tsx` (new):** the overview without a home app; the redirect with one; the overview kept for an inaccessible app. Local results: - `pnpm typecheck` and `pnpm lint` pass (0 errors; the 5 warnings are pre-existing), and so does the license check. - `pnpm test`: 2,168 passed. The 2 failures are the pre-existing Windows path-separator assertions in `tests/standalone/acceptance-stage.test.ts` and `tests/acceptance/support/standalone-variant.test.ts`; CI on Linux is authoritative. ## Docs The developer guide's `/app` route row and metadata section are updated, and `docs/releases/unreleased.md` gets a Features entry. ## Merge order The two PRs are independent. Before QQQ ships `homeAppName`, this PR is a no-op; once it ships, Next picks the field up. Not for a release: no version bump, tag or publish. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Sign in to join this conversation.