Repository navigation
feat(ui): a cohesive redesign around the admin's core flows - #123
Merged
Merged
Conversation
Gkrumbach07
marked this pull request as ready for review
October 19, 2026 15:30
Daniel Warner's prototype (Daniel-Warner-X/dw-openshell-dashboard, feat/ui-cohesive-redesign at 5979b03), carried onto main as one commit: - Gateway becomes a dashboard: a Needs attention card (pending proposals and errored sandboxes, filterable by kind) leads, the gateway's facts sit in one line under the title, drivers and extensions below. - A Proposals page and a Sandboxes page across every workspace. - The sandbox Proposals tab is calmer: info banner, outline bulk actions, a status dropdown, the security flag kept on the collapsed row. - GET /draft-summary?allWorkspaces=true and the newest chunk's rationale in each sandbox's summary, for the Needs attention rows. - A mock API (make dev-mock) for UI work without a gateway. Left out: the prototyping toolchain (skill submodules and links, .mcp.json). Brought up to main: the build line and commit replace the old app version on the Gateway page, and the About dialog stays, read from the compatibility route so the shell still never asks for gateway info. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The shell counts proposals and sandboxes on every page for a platform admin. The proposal count is one request to the BFF but one draft read per sandbox on the gateway, and the shell asked for it every 15 s on every page. It now reads both counts every two minutes; the Gateway, Proposals and Sandboxes pages keep their own pace while they are open, and the counts ride on those reads. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The redesign renamed the Provider profiles entry and page to Providers, while Resources keeps a Providers tab for the providers made from them: two different things under one name. Profiles keep their name, and the page says what they are for and how a sandbox gets one (a workspace creates a provider from the profile and attaches it), without calling a sandbox an agent. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The fixtures still gave compatibility the supportedMin/supportedMax shape main has since replaced with supportedLine, and summarized one pending proposal for training-run-42 where its drafts list has two. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The Gateway page is where a platform admin lands and often leaves the tab open. Needs attention read every sandbox on the gateway every 5 s to find the ones in error, the cross-workspace proposal summary (one draft read per sandbox on the gateway) every 15 s, and every provider every 15 s only to say whether any exists. It now reads the sandboxes and the summary every 30 s and the providers every minute; the Sandboxes and Proposals pages keep their own pace. Measured against gateway 0.1.4: 28 requests a minute on the page before, 13 after. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The Gateway page no longer repeats the health the masthead shows, and states the gateway's version in one line rather than a card; the masthead's status reads `healthy` from the compatibility answer, which the stub now gives as the BFF does. The create sandbox form keeps the name behind its generated-by-default section. The cross-workspace reads the Gateway page and the shell make (sandboxes, providers, the all-workspaces proposal summary) are stubbed, so they no longer fall through to a BFF that is not there. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The Gateway page, the pages across workspaces and the sandbox views the redesign added text to had it inline. CLAUDE.md and ADR 0004 put new UI text through useI18n, so each gets a namespace: gateway, crossWorkspace and sandbox. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ered Needs attention was built from whatever each list held, so while a list was loading, or after it failed, the card said nothing needs attention. It now waits for every read, and a list that could not be read is a row of its own. Also from review of the prototype: - The gateway's own status (HEALTHY, DEGRADED, UNHEALTHY) is back beside its version; the masthead only shows the health check's yes or no. - Errored sandboxes are listed newest first before the cap, timed by their condition's transition, never by when the sandbox was created; the error is the Ready condition that is False. - A filter whose kind is gone is reset rather than kept to come back later. - Get started starts at the provider step: default exists already. - No agent in the copy (ADR 0003), and no claims the API does not back. - Text through the gateway catalog; test ids on the links and filter items. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Approving, rejecting or editing a proposal refreshed the sandbox's inbox but no summary, so the nav count, the Gateway page and the Proposals page went on showing it until their next poll. Decisions now invalidate every workspace's summary and the one across workspaces. Also from review of the prototype: - The Proposals page waits for every workspace's read before it says nothing is waiting, and counts the sandboxes it could not read in one alert after the ones it could. - The Sandboxes page links with Link and encoded paths instead of buttons that navigate, and shares the workspace-name helpers and ImageReference with All workspaces instead of copying them. - No agent in the copy; text through the crossWorkspace catalog. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Across workspaces there is no workspace to fall back on, so a sandbox the gateway lists without one was read with an empty selector, which the gateway refuses (hard fact 12), and reported under an empty workspace. It is now reported unavailable without a read, and logged once. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The prototype showed a sandbox's pending proposals as info even when the prover flagged them. Flagged ones are warning again: they are the ones approve-all skips unless asked (hard fact 25). Also from review of the prototype: - The Review link is back in the alert's action links, not its close slot. - Approve is a secondary button; the private PatternFly variables that coloured it green through style are gone (ADR 0004). - The create forms' optional section no longer says it is generated, says which field is, and stays open while it holds a value. - The terminal's light theme has an ANSI palette, so white text shows. - The status filter has an accessible name; new text through the sandbox catalog. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- The shell counted workspaces every 15 s on every page, for a user with no role too; it now reads at the navigation's pace and not for them. - The status in the masthead is in sentence case; capitals are spelled letter by letter by some screen readers in a live region. - The theme survives storage that throws. - A user who is not a platform admin is told to ask for a workspace rather than to create one. - Applying a global policy is a danger action again: it replaces every sandbox's own (hard fact 23). - Unused catalog keys and comments that no longer held are gone; the Provider profiles page text is in the catalog. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The fixtures were untyped and had drifted from what the BFF answers: network enums in spellings the gateway never sends, draft chunks with no review token, a user field that does not exist. They are typed against src/types now, and lint, format and typecheck cover frontend/mock. The drafts route honours ?status=, the CORS header is gone (same origin), and vite.config.ts loads the plugin only when MOCK_API is set. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
main added a sandboxes namespace (the cause of a failed tool server exchange or token grant) while this branch added a sandbox namespace for the create forms and the Proposals tab. Their keys do not overlap, so they are one namespace now, main's: the four components that read sandbox read sandboxes, and the i18n README lists every namespace. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
main put workspaceOf, scopedName and ImageReference in AllWorkspaceCells while this branch put the same helpers in utils/workspaceNames and components/sandbox/ImageReference. AllWorkspaceCells now re-exports those, so the lists keep their import and there is one definition of each. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
main paged the sandboxes of every workspace through the gateway (AllSandboxList: a cursor, a page size, label and type filters) on the All workspaces page's Sandboxes tab, while this branch had moved that list to a page of its own that read every sandbox at once. The Sandboxes page now renders AllSandboxList, which keeps the page's layout: the name leads, and the name and workspace are links rather than buttons. Its only user is this page, so the navigation callbacks are gone. main's tests of the type label, the empty type match and a conflicting type key moved with the list, from the All workspaces spec to the Sandboxes page's; the page's own text filter is "current page" as main's is. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
main pages the workspaces, a workspace's sandboxes and the sandboxes of
every workspace through the gateway (pageSize, pageToken). The mock API
answered those with the whole array, which the paged hooks cannot read, so
the lists were empty under make dev-mock. A list asked for with pageSize is
now answered as the BFF answers it, { items, nextPageToken }; without it,
as before.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
main's list fixtures are one page, { items, nextPageToken }, and its stubs
served that page to every request for the workspaces and for the sandboxes
of every workspace. The BFF answers a page only when it is asked for
pageSize; the shell's counts and the Gateway page ask without it and read an
array, so the Gateway page failed on the page object. The two stubs now
answer as the BFF would: the page with pageSize, the items without.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Gkrumbach07
force-pushed
the
feat/ui-cohesive-redesign
branch
from
October 22, 2026 22:47
0870eab to
22bbd92
Compare
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.
The UI redesign @Daniel-Warner-X prototyped on his fork (
Daniel-Warner-X/dw-openshell-dashboard,feat/ui-cohesive-redesignat5979b03), brought onto currentmainwith a review's fixes. The design and the first commit are his. The branch is rebased onmain61e2590(server-side pagination #122, live logs #124, OpenShell 0.1.5).The idea. The dashboard is for admins managing sandboxes, and three of their flows were buried: acting on policy proposals, finding out why a sandbox failed, and getting a provider onto a sandbox. Each is now one click from the landing page.
What changes
ERROR(with the gateway's condition message, newest first), filterable by kind. A proposal row opens the sandbox's Proposals tab; an error row opens its Logs tab. The gateway's own status, its version, the line this build is for and the compatibility verdict sit under the title. Compute drivers and extensions stay below.AllSandboxList), with its label and type filters. The name now leads and the name and workspace are links. It was the first tab of All workspaces, which is now Resources (providers, templates and services).NAV_COUNT_POLL_MS), and a decision on a proposal refreshes them at once.GET /api/v1/draft-summary?allWorkspaces=trueanswers the summary for every workspace. The gateway refuses the all-workspaces sandbox list to anyone but a platform admin, and that refusal is relayed as it is. Each sandbox's summary carrieslatestRationale. The route without a scope still answers empty, and a sandbox's drafts are never read with an empty workspace.make dev-mock, andmake dev-mock-emptyfor a gateway nobody has used yet (docs/mock-api.md). It answers the paged lists a page at a time, as the BFF does.Changed from the prototype
GetDraftPolicyper sandbox on the gateway. It also read every sandbox every 5 s on the Gateway page. Now:DEGRADED) was shown nowhere.gateway,crossWorkspaceandsandboxesi18n namespaces.styleoverride of private PatternFly variables dropped (ADR 0004).useNavigatefor navigation.MOCK_API.main./gateway/compatibility, so the shell never callsGET /gateway, which the gateway refuses to non-admins..mcp.json).For reviewers
AllSandboxListfrom feat(pagination): add server-side pagination and label filters (RHOAIENG-98858) #122 has one user now, the Sandboxes page. It lost its navigation callbacks: the name column leads and both cells are links. The type-label tests moved with it, from the All workspaces spec to the Sandboxes page's.mainonly a workspace admin gets Approve, Edit and Reject. The page's description ("review, edit, approve or reject") reads as though anyone can. Either the copy or the gating should change; that is a product call, left out of this PR.Not in this PR
Checked
22bbd92: build, check-frontend, check-backend, compat, e2e and helm.tsc(including the mock), ESLint, the Prettier check and the buildgo test -raceand golangci-lint v2.12.2, 0 issuesmake dev-fullagainst gateway 0.1.5, behind Keycloak sign-in:admin1(platform admin).curlto npm and GitHub from its Terminal tab, drafted two rules.pageSize=10), and a label selector came back filtered by the gateway.user1(member of one workspace)./gateway,/sandboxes,/all-workspaces,/provider-profilesand/settingseach sent the user to Workspaces.maingates it.unknown field outer_fencein its bootstrap). That is the gateway's upgrade, not this PR; Needs attention shows it as a sandbox error.🤖 Generated with Claude Code