mirror of
https://github.com/Studio-Saelix/sencho.git
synced 2026-08-06 08:58:05 +00:00
feat: add routable browser URLs for stacks and shell views (#1586)
* feat: add routable browser URLs for stacks and shell views Sync in-memory navigation to the address bar via a History API hook so deep links, refresh, Back/Forward, and bookmarks work across nodes, views, stack editor tabs, and mobile surfaces. Gate role/tier URL normalization on permissions and license readiness, preserve URLs on metadata fetch failure, and surface retryable stack-list errors without rewriting pending stack paths. * fix: preserve deep-link views on cold load and refresh Stop the node-switch effect from resetting to dashboard on initial mount. Defer URL writer settlement until hydrated activeView matches the route. Adds E2E coverage for shell cold loads, stack refresh, and compose env tab. * fix: keep mobile dashboard on list surface so sidebar renders On mobile, the URL sync hook was routing /nodes/<slug>/dashboard to the content surface, hiding the stack list sidebar. This prevented the data-stacks-loaded sentinel from appearing, causing sidebar truncation E2E tests to time out after reload on a mobile viewport. Mobile dashboard now stays on the list surface; other non-editor views still render on the content surface. * fix: complete mobile URL routing follow-ups for stack deep links Restore mobile /dashboard vs /stacks, list surface always writes /stacks. Hydrate pendingDetailStack, freeze compose failures with routeDetailError, and add unit plus E2E coverage. * fix: hydrate shell views from URL and sync in-app navigation Bootstrap activeView and tab state from the pathname on cold load. Settle route phase when state already matches, normalize unknown segments, and open Monaco editor tabs from stack deep links via applyEditorRouteState. * fix: prevent mobile stack deep links from hanging on cold load The resolvePendingStack effect did not re-fire when the pending stack ref was populated during URL hydration, because the urlHydratingStack state set in the same callback was not listed in the effect's dependency array. Adding it causes the effect to retry once hydration has committed. A resolvingRef mutex prevents concurrent invocations. When the target file is already loaded, route state is applied directly without calling loadFileForRoute, which avoids unmounting the editor (and hiding the recovery chip) if a background refresh triggers route resolution during a deploy operation. * test: adapt stack, deploy, and sidebar e2e specs to routable stack URLs * ci: raise E2E Playwright job timeout to 20 minutes
This commit is contained in:
+3
-2
@@ -132,8 +132,9 @@
|
||||
"group": "Observability",
|
||||
"expanded": true,
|
||||
"pages": [
|
||||
"features/dashboard",
|
||||
"features/global-search",
|
||||
"features/dashboard",
|
||||
"features/deep-links",
|
||||
"features/global-search",
|
||||
"features/global-observability",
|
||||
"features/alerts-notifications",
|
||||
"features/audit-log"
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
---
|
||||
title: Deep links and URLs
|
||||
description: Bookmark, share, and refresh Sencho views with real browser URLs that survive Back and Forward.
|
||||
---
|
||||
|
||||
Every major screen in Sencho now has a stable address in the browser bar. Refresh the page, paste a link to a teammate, or use Back and Forward without losing your place.
|
||||
|
||||
## What gets its own URL
|
||||
|
||||
Sencho encodes the active node, the view you are on, and the deep state that view cares about.
|
||||
|
||||
| Destination | Example path | What it opens |
|
||||
|-------------|--------------|---------------|
|
||||
| Home dashboard | `/nodes/local/dashboard` | The home dashboard for the `local` node |
|
||||
| Stack list (phone) | `/nodes/local/stacks` | The full-width stack list on a phone |
|
||||
| Stack editor | `/nodes/local/stacks/radarr/compose` | Radarr's compose tab |
|
||||
| Env tab + file | `/nodes/local/stacks/radarr/env?env=.env.prod` | Radarr's env tab with a specific env file selected |
|
||||
| Resources | `/nodes/local/resources` | Resources for the active node |
|
||||
| Security tab | `/nodes/local/security/images` | Security view on the Images tab |
|
||||
| Settings section | `/nodes/local/settings/nodes` | Settings on the Nodes section |
|
||||
| Fleet tab | `/nodes/local/fleet/snapshots` | Fleet on the Snapshots tab (desktop) |
|
||||
| Schedules filter | `/nodes/local/schedules?node=3` | Scheduled operations filtered to node `3` |
|
||||
|
||||
Remote nodes use a slug derived from the node name and id (for example `/nodes/nas-box-42/dashboard`). The default local node keeps the short `local` slug.
|
||||
|
||||
## Node slugs
|
||||
|
||||
- The primary local node is always `/nodes/local/...`.
|
||||
- Every other node uses `/nodes/<name-slug>-<id>/...`, which stays stable when you rename the node (the id suffix is what Sencho resolves).
|
||||
|
||||
## Bookmarks and sharing
|
||||
|
||||
Copy the address bar after you land on a screen. Anyone with access to that Sencho instance and the right role can open the same view from the link. Sencho waits for permissions and license metadata to finish loading before it redirects a link you are allowed to see, so a valid paid or admin-only URL is not rewritten while metadata is still in flight.
|
||||
|
||||
If a link points at a stack that cannot be loaded (for example the node is offline), Sencho keeps the URL and shows a retryable error in the sidebar or on the phone stack detail screen instead of silently sending you home.
|
||||
|
||||
## Back, Forward, and refresh
|
||||
|
||||
- **Back / Forward** walk through the views you opened in order, including stack editor tabs where applicable.
|
||||
- **Refresh** reloads the current URL and restores the same node, view, stack, and tab when the underlying data is available.
|
||||
- **Unsaved edits** still block navigation. Sencho prompts before you leave a dirty compose or env buffer via Back, a sidebar link, or another stack.
|
||||
|
||||
## Phone layout
|
||||
|
||||
On a phone, Home and the stack list are distinct URLs even though both relate to stacks on desktop:
|
||||
|
||||
- `/nodes/local/dashboard` opens the home dashboard.
|
||||
- `/nodes/local/stacks` opens the stack list.
|
||||
|
||||
Settings follows the same list/detail split: `/nodes/local/settings` is the section list; `/nodes/local/settings/<section>` opens a section directly.
|
||||
|
||||
## Tips
|
||||
|
||||
- Use the global search palette (<kbd>Ctrl</kbd>+<kbd>K</kbd>) as today; navigation still updates the URL when you pick a page, node, or stack.
|
||||
- Deep links use stack directory names (the name you see in the sidebar), not internal compose filenames.
|
||||
- Opening Sencho at `/` sends you to the active node's dashboard once you are signed in.
|
||||
Reference in New Issue
Block a user