feat(cluster): explicit cluster home for connecting#1403
Open
dawsontoth wants to merge 21 commits into
Open
Conversation
First cut of the cluster landing page (stacked on the JWT/direct-connect work).
Instead of the cluster card guessing a connection mode and the route guard
auto-Fabric-Connecting, a dedicated home page owns the choice.
- ClusterHome: hero + status, a Fabric Connect / Direct sign-in picker when
unconnected, connected status with switch/disconnect, and a "Manage" grid
(Instances, Databases, Scaling, Domains) that surfaces the buried ⋯ actions.
- The last chosen mode is remembered (authStore.setLastConnectMode, persisted)
and highlighted with a green "Last used" pill; first-timers see "Recommended"
on Fabric Connect.
- Mounted at /{org}/{clusterId}/home (safe sibling route — keeps getParentRoute
and addChildren in lockstep). The cluster card now just opens the home rather
than guessing Fabric/Direct/Direct Sign In.
Follow-up (needs browser validation): promote the home to the cluster index and
move the instance dashboard behind the Databases tile; redirect unconnected
deep-links to the home instead of auto-connecting.
Refs #1398
Contributor
There was a problem hiding this comment.
Code Review
This pull request introduces a new cluster landing page (ClusterHome) that centralizes the connection options (Fabric Connect and Direct sign-in) and displays the cluster's connection status and management options. It also adds persistence for the last used connection mode in localStorage to highlight it on subsequent visits. The feedback focuses on enhancing security during disconnects by fully clearing local authentication flags, handling permission checks before redirecting users to setup pages when a password reset is required, and adding appropriate size classes to the ArrowRight and Loader2 icons to ensure consistent UI rendering.
The home rendered directly under clusterLayoutRoute (a bare Outlet), so its hero sat behind the fixed 80px app header. Add the standard cluster sub-nav breadcrumb bar (fixed top-20) + mt-32 content offset, matching the sign-in page.
The "Open" action is now the full card via a stretched link to the cluster home, with a generous 40x40 hit area for the ⋯ menu (lifted above the overlay with stopPropagation so it opens the menu instead of navigating). Right-click still opens the context menu (unchanged — the card is wrapped in EntityContextMenu). Edge states (no FQDN → Instances, resetPassword → Finish Setup / Pending Owner Setup) keep their own explicit CTA and aren't full-card.
The purple accents used --primary (#403b8a), a dark purple that nearly disappears on the dark card/grey-700 surfaces (icon vs card ~1.2:1). Keep --primary on light and switch to a bright violet-300/400 on dark for the hero, tile, and connect-option icons, the "Recommended" pill, and its border.
The cluster home is now the cluster index (/{org}/{clusterId}) — clicking the
cluster in the breadcrumb lands on it, and there's no more "Home" crumb. The
within-cluster tabs move under it:
- /{org}/{clusterId} → ClusterHome (no instance nav chrome)
- /{org}/{clusterId}/apps → Applications (was the index)
- /{org}/{clusterId}/databases, /status, /logs, /config, /apis
Applications only re-paths to /apps in cluster mode; local and instance modes
keep it at the index (verified both still resolve), so local studio is
unaffected. The Apps nav tab and ClusterHome's Enter/Databases links point at
the new paths; the cluster card opens the index.
Also make the cards reactive: cluster cards and the home's Manage tiles grow
slightly and shift border/background on hover.
Refs #1398
The content offset (mt-32 = 128px) landed exactly at the fixed breadcrumb bar's bottom (128px), so the hero icon/name abutted the breadcrumbs. Bump to mt-40 for a 32px gap.
Apply the same hover reactivity to org cards as cluster cards: grow slightly, lift (shadow), and shift color. Since Card uses a ring (not a border), the earlier hover:border-primary was invisible — switch both org and cluster cards to hover:ring-2 hover:ring-primary/60 (dark: violet-400) so the color shift actually shows.
- Org cards get the same stretched-link treatment as cluster cards: the whole card opens the org, with the ⋯ menu lifted above the overlay (z-10 + stopPropagation) and right-click still opening the context menu. "View" becomes a visual affordance; update its test to find the card link by role. - Right-align the cluster card's "Open" action (ml-auto).
The cluster card's copy-to-clipboard control was a bare icon with no hover feedback — wrap it in a button with a rounded bg/text hover, matching the cluster ⋯ menu. Give the org card's ⋯ trigger the same rounded bg hover instead of a text-only color change, so both cards' controls feel consistent.
Adds an OrgPageLayout shell with a responsive org sub-nav (left rail on desktop, dropdown when small) — Clusters, Users, Roles, Billing, Settings — gated by the same permissions the org card menu uses. Wraps the five org-level pages (clusters list, users, roles, billing, settings) so those sections are discoverable from the org page itself, mirroring the instance Config pattern. With that in place, remove Organizations (it's in the breadcrumbs) and Roles / Users / Billing (now in the org sub-nav) from the global header; Profile, Docs, Report an Issue, Discord, and Sign Out stay. Routing is unchanged — the shell is a shared component each page renders, not a route layout — so there's no risk to param matching.
Pull "Filter by name" out of the breadcrumb bar and into the top of the cluster list content (a light search input above the grid, list bumped down). The breadcrumb bar keeps only the New Cluster action.
Give the org sub-nav support for nested items that expand under the active section. Billing now expands to Payment Method / Invoices and Payments in the rail, so its own two-column inner nav is removed — the billing page just hosts the active sub-page. Sub-items expand on desktop and in the mobile dropdown.
Drop the pill (no background/border/rounding, incl. the dark:bg override) and make "Filter by name" a full-width underlined input across the list.
Extract the responsive sub-nav (left rail on desktop, dropdown when small, with expandable sub-items) into a shared SubNavRail so the org and cluster layouts use the same plumbing. Add ClusterPageLayout with an Overview / Instances / Scaling / Domains rail (permission-gated; domains hides for self-managed) and apply it across those cluster-scoped pages so the rail persists — the in-cluster studio (apps, databases, …) keeps its own top nav. The cluster home now renders inside the rail (its old horizontal "Manage" tiles are gone — the rail replaces them); Instances, Scaling, and Domains adopt it too (StartingUp stays plain — nothing to manage pre-provision).
- Make the connected-state "Enter cluster" a big accented card (rocket + what's inside), drop the status banner to a one-line label, and demote Disconnect / Direct sign out to a quiet text link. - Point the Scaling rail item at /edit (the cluster editor) to match the card's "Edit Scaling", instead of the /scaling update-progress screen.
Turn the cluster's host on the home page into a link (opens https://host) and add a copy button beside it with "Copy host name" and "Copy API URL", so both are reachable from the home like they are on the cluster card.
UpsertCluster keeps the plain layout for new clusters, but wraps the edit and edit-version cases in ClusterPageLayout so the cluster sub-nav rail persists while editing scaling or version (new-cluster has no cluster context, so no rail).
Adds a Version item (→ /edit/version) beside Scaling in the cluster rail so the version editor is reachable directly. Both Scaling (/edit) and Version (/edit/version) are now exact matches so /edit/version doesn't also light up Scaling. Gated like Domains: manage permission and not self-managed. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Addresses PR review on ClusterHome: - onDisconnect now clears the Fabric Connect flag and Basic Auth credentials from localStorage even when the logout POST fails (previously the swallowed error left them behind). - reset-password clusters no longer redirect view-only members into the finish-setup flow they can't complete; they see a Pending Owner Setup message instead, matching ClusterCardAction. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What & why
Started as a fix for the connect-mode guessing behind #1333 and grew into a cohesive pass over the cluster and org navigation. Instead of the cluster card guessing a connection mode and the route guard auto-Fabric-Connecting, a dedicated cluster home owns the choice explicitly — and the surrounding cards/nav were brought in line with it.
Cluster home (connect choice) — #1333, #1398
ClusterHomeis now the cluster index (/{org}/{clusterId}/); the in-cluster studio moved to/{org}/{clusterId}/apps. Hero with name/status/instance count, the host linkified (opens in a new tab) with a copy menu (Copy host name / Copy API URL).authStore.setLastConnectMode— a preference, not a secret), purple "Recommended" for first-timers.authStorerather than the lagging router-context snapshot (the root cause of the direct-sign-in clobber).Full-card clickable cards — closes #1260
⋯menu; right-click still opens the context menu.⋯. Cluster card's "Open →" is right-aligned.Sub-nav rails (Config-page paradigm)
/edit, Version →/edit/version(both exact so they don't cross-highlight); editing scaling/version keeps the rail.Design decisions (agreed while building)
SubNavRail,OrgPageLayout,ClusterPageLayout) rendered per page, rather than restructuring the route tree — keepsgetParentRoute/addChildrenin lockstep per CLAUDE.md (router-matching regression test stays green).Verification
Typecheck, lint, format, full suite (1036 passing) incl. the router-matching regression test. Browser-verified on a live authenticated dev server across cluster / instance / local-studio modes: index promotion, card clickability, both rails and their active states, the connect picker, and the host copy menu.
Closes #1260
Refs #1398, #1333
🤖 Generated with Claude Code