Repository navigation
feat(ui): Redesign the workload overview - #627
Merged
Merged
Conversation
The overview now leads with a summary card in the ALB overview's style: status, endpoint, when it last changed, and the last hour's instances, CPU, memory, network and requests. Instances and configuration move into cards of their own, and recent activity replaces the recent-logs block that was usually empty. A deploy takes seconds, faster than the page polls, so the card no longer shows a step-by-step progress bar. It says what it can say truthfully: deploying, deployed (with a timeline rebuilt from condition timestamps), stalled with the cause the API reports (a missing Secret or ConfigMap, quota), or failed. Pages poll every 3s until instances are actually ready, not just until the workload reports Available. Instance pages explain a failure in plain words with what to try, and the instances table shows per-instance network traffic and status badges in the portal's style. The workload Metrics tab gains network in and out.
Tailwind's animate-pulse only faded the bar in place. The host compiles no keyframes the plugin could use, so the bar is animated with the Web Animations API instead, and stays still under prefers-reduced-motion.
…place
A Load balancers card on the workload Overview lists each load balancer
whose rules send traffic to the workload: its state, hostname and the
routes that reach it ("/ → :8080 (http)", with the workload's share when
a rule splits traffic). Route reading comes from Kevin's
feat/workload-overview-polish branch. With no load balancer, "Add to a
load balancer" makes the workload's NetworkService if it has none (the
same object `datumctl compute url` makes) and opens the portal's create
dialog with the workload chosen.
A hostname belongs to its load balancer, so the page no longer presents
one as the workload's URL: the URL and Visit button by the title, the
endpoint line on the overview card and the Load balancer row in
Configuration are gone.
Loading states now match what they stand in for. The stats strip holds
each value, hint and sparkline with a bone until its data is in, instead
of showing zero or a flat line. The Instances and Load balancers cards
load as their tables, headers included, and the page and workloads-list
skeletons use the live tables' markup.
Co-authored-by: Kevin Williams <kwilliams@datum.net>
4 tasks done
mattdjenkinson
marked this pull request as ready for review
November 6, 2026 16:55
mattdjenkinson
added a commit
to datum-cloud/cloud-portal
that referenced
this pull request
Nov 6, 2026
The compute plugin's workload Overview now has an "Add to a load balancer" button (datum-cloud/compute#627). It links to `/project/:id/alb?action=create&workload=<name>`. This makes that link open the new load balancer dialog with the workload already chosen. **The dialog now opens from the link** The ALB page read `?action=create` on its first render, before its create-permission check had answered. While the check loads, `useResourcePermissions` reports `canCreate` as false. The page deleted the parameter without opening anything, so the dialog usually didn't open from a link at all. The page now waits for the check to finish before reading or clearing the parameter. **It opens with the workload chosen** With `&workload=<name>`, the dialog: - opens on **Datum compute**, with that workload's NetworkService chosen; - chooses its port too, when it has only one; - sets the display name to the workload's name; - refetches the service list first, since the plugin may have just created the service; - says when the workload has no service, instead of leaving the picker empty. **Why the selection is set the way it is** - **The select's own control:** the choice goes through each select's own form control. A second `Form.useField` control on the same field never reaches the select, because Conform keeps a separate value per control. - **A tick after render:** the port select remounts when the workload changes, and a value set in the same render as that remount never reaches the form. ## Test plan - [x] `serviceForWorkload` unit tests (vitest), and `app/features/edge` tests pass - [x] New Cypress component test (`workload-service-fields.cy.tsx`) covers four cases: the workload and its only port are chosen; a workload with several ports gets only the workload; an outdated cached list is refetched; a workload with no service gets the note - [x] Typecheck and lint - [x] Locally, with the compute plugin: "Add to a load balancer" on `cpu-mem-wave` opens the dialog with it chosen
ecv
approved these changes
Nov 6, 2026
ecv
left a comment
Contributor
There was a problem hiding this comment.
Approve.
Every new API and metrics path stays project-scoped and the project label is pinned and escaped; no tenant-isolation, query-bound or supply-chain problem found.
- Tenant isolation holds. New reads (
WorkloadDeployments, NetworkService/HTTPProxy lists, theensureWorkloadServicePOST) all go throughgetProjectScopedBase(projectId)inui/consumer/src/lib/api.ts. The workload UID goes intolabelSelectorviaURLSearchParams, so it is encoded. - The new
networkTrafficTotalQueryandnetworkThroughputQueryreusenetworkTrafficLabels, which pinsresourcemanager_datumapis_com_project_nameandresource_namespacethroughescapePromQL, and escapes interface names withescapePromQLRegexp. The project comes from the route, the namespace and interface refs from the project's own Instance objects. A hostile project string cannot leave the quoted label. - The
__name__=~"rx|tx"regex innetworkThroughputQueryis two constants, with the same label pin beside it, so it cannot widen the selection. - Ranges and polling are bounded. Charts take
useOverviewRange(default 1h) and the 5m rate window; the 3s fast poll is limited to settling workloads, andworkloadSettlingcaps the "recently changed, short of replicas" case at 10 minutes. - Dependencies: only
@datum-cloud/datum-ui3.6.0 to 3.8.0 (consumer, pinned; provider,^3.8.0), plus its own bumps (isomorphic-dompurify3.23.0,tailwind-merge3.7.0). Every new lock entry carries anintegrityhash from the npm registry. The provider lock gainsai@7.0.163,@ai-sdk/*,@vercel/oidcand@datum-cloud/datum-ui-assistant-corebecause datum-ui 3.8.0 now declaresaias a peer; consumer already hadai. Say so in the PR body so the provider bundle growth is expected. - Tests are meaningful: exact-string query assertions,
albRoutesand presenter tests, andapi.test.tscovers the new helpers. No test feeds a hostile project or interface name through the new queries. - Versus network-services-operator#877: both build on the same project-label-pinned PromQL helpers. This PR adds a write (
ensureWorkloadServicecreates a NetworkService, treating 409 as success), which #877 does not.
Follow-ups:
useWorkloadDeploymentspolls every 3s for as long ascomingis true. A stalled deploy that staysDeployingpolls indefinitely; give it the same 10-minute settle window asworkloadSettling.ensureWorkloadServiceonly checks whether a service selects the workload, then POSTs; a 403 surfaces as a genericRequest failed. Show the permission cause in the load balancer UI.- Add a hostile-value test (quotes, backslash, regex metacharacters in project and interface ref) for the two new query builders.
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.
Summary
Redesigns the compute plugin's workload Overview, following the "hairline sections" concept explored in Pencil.
/ → :8080 (http), plus the workload's share when a rule splits traffic. Route reading comes from @kevwilliams'sfeat/workload-overview-polishbranch.datumctl compute urlcreates.Available(which happens as soon as a placement exists).Screen.Recording.2026-11-06.at.16.51.43.mov
Data the design wants that the API doesn't expose yet (the asleep state and wake-ups, structured crash details, image digest and revision, image pull progress) is left out for now and tracked in #626.
Test plan
pnpm typecheck,pnpm test(408 tests),pnpm buildcpu-mem-wave(which had no service) opens the dialog with it chosencompute-ui-state-testworkloads on staging:state-missing-secret(stalled),state-bad-image(failed),state-crashloop(crash band), plus a fresh demo deploy (deploying, then deployed)