Commit Graph
1980 Commits
Author SHA1 Message Date
gitlawrandjialin fdafdfc3d1 fix(gpu-service): show global instance templates under custom scopes
The Instance Templates management page requested the `mine` list scope,
which drops admin-curated Global templates for non-admin callers. The
Inference Backend page uses the default scope and shows Global + own
rows, so the two pages behaved inconsistently.

Use the default scope on the templates page so Global templates are
visible alongside the caller's own, and gate Edit/Delete on the card so
Global rows a non-admin can't modify render read-only.
2026-07-08 16:27:40 +08:00
jialinandjialin f18c12662b Revert "fix(usage): remove the delete tag of models and users in tokens tab"
This reverts commit 1b3d4748d4de963ba0c710e3aac91e3af0015531.
2026-07-08 10:45:23 +08:00
jialinandjialin 71840cfc8f refactor(footer): use useAtomValue for version 2026-07-07 20:37:39 +08:00
jialinandjialin e75beb7324 fix(footer): show version reactively via useAtom 2026-07-07 20:37:39 +08:00
jialinandjialin 90cc6ec753 fix(cluster): drive k8s cluster type from shared state
Replace unreliable Form.useWatch on the unregistered gpuInstanceOptions
path with explicit shared clusterType state. Fixes the type selector
being unclickable and flickering, and ensures a model cluster no longer
submits a stale gpuInstanceOptions payload.
2026-07-07 20:37:39 +08:00
jialinandjialin bd4954f161 fix(usage): remove the delete tag of models and users in tokens tab 2026-07-07 20:37:39 +08:00
jialinandjialin 32fab0fa62 style: gpu selector 2026-07-07 20:37:39 +08:00
gitlawrandjialin d12e92a916 fix(models): preselect the scoped default cluster on deploy
The deploy form's cluster select could open blank even when a valid
(default) cluster exists for the current scope. The open handler seeds
the cluster once, but that seed can be empty (options not loaded yet) or
point outside the resolved scope (the scope id and the option list both
settle after mount, and switching scope re-scopes the list), and nothing
re-picked afterwards — so the field stayed empty.

Make the form enforce the invariant directly: whenever the scope or the
available options change, if the current selection is empty or not among
the options, fall back to the scope's default cluster (then a Ready one,
then the first). A still-valid selection is left untouched.
2026-07-07 18:18:39 +08:00
jialinandjialin dc41b61d69 fix(deployments): display gpu allocated value in gpu selector 2026-07-06 17:48:22 +08:00
jialinandjialin 3a1565690d fix(worker): incorrect worker version 2026-07-06 11:58:51 +08:00
jialinandjialin 1bb9fd73db chore(template): theme logo 2026-07-06 11:58:51 +08:00
jialinandjialin 39024b1d46 chore(hooks): remove unused hooks 2026-07-06 11:58:51 +08:00
hibigandjialin 4ecaa0a326 chore: bump @gpustack/core-ui to v1.0.35 2026-07-02 13:23:14 +08:00
jialinandjialin e1af27e11c fix(dashboard): remove date from group_by 2026-07-02 13:18:04 +08:00
jialinandjialin f4ebd8d7d1 chore: remove old code 2026-07-02 13:18:04 +08:00
jialinandjialin bd58a911d5 chore: remove driver.js 2026-07-02 13:18:04 +08:00
jialinandjialin 5321973ebe perf(charts): import chart components from @gpustack/core-ui/charts
Switch all echarts-based chart imports to the dedicated core-ui charts
entry so echarts stays out of the synchronous entry bundle and loads
only on chart routes. Requires @gpustack/core-ui with the ./charts export.
2026-07-01 20:54:26 +08:00
jialinandjialin 0a1f875590 perf(markdown): load katex css lazily via local FullMarkdown wrapper
core-ui no longer bundles katex.min.css (it would base64-inline ~1.4MB
of fonts into the render-blocking global css). Wrap FullMarkdown locally
to co-locate the katex stylesheet so it loads only in the routes that
render math.
2026-07-01 20:54:26 +08:00
hibigandjialin ea2c9870a7 chore: bump @gpustack/core-ui to v1.0.34 2026-07-01 20:48:55 +08:00
jialinandjialin 23f0e4398a fix(pageContainer): remove leftContent, rightContent, props 2026-07-01 19:11:47 +08:00
jialinandjialin b342174fc2 feat(cluster-detail): add cluster switcher; consume core-ui header-slot
page-box now imports the header-slot bridge from core-ui and re-exports it, plus a dev warning when a header slot has multiple owners. cluster-detail breadcrumb becomes a BaseSelect to switch clusters, and the tab tables are keyed by id so they refetch on switch.
2026-07-01 19:11:47 +08:00
jialinandjialin d07d3b2c99 refactor(layout): adopt header-slot page container across pages 2026-07-01 19:11:47 +08:00
hibigandjialin 9d0a5d01b0 chore: bump @gpustack/core-ui to v1.0.33 2026-07-01 19:08:52 +08:00
gitlawrandjialin 1e97d29fca feat(login): surface SSO callback failures via error query param
The CAS / OIDC / SAML callbacks now redirect to `/login?error=<code>`
on failure instead of letting the browser land on a raw JSON error
page, so the actionable copy reaches the user. Two codes are
recognised:

* `source_conflict` — incoming SSO username collides with an existing
  account from a different source. Message points the user at an
  administrator to link or convert.
* `auth_failed` — anything else (bad ticket, expired state, IdP
  unreachable, malformed response). Generic message: try again or
  contact the administrator.

On mount the login form picks up the `?error=` query param, maps it
through a small `messageIdByCode` table to an i18n key, and routes
the result through the existing auth-error toast. Unknown codes are
silently ignored so a future server release adding a code doesn't
render a bare key. The query param is cleared via
`history.replaceState` so a refresh doesn't re-fire the toast.

Strings added to all five locales.
2026-07-01 15:39:10 +08:00
gitlawrandjialin 350f398cde feat(users): add authentication source dropdown to the user form
The add / edit user drawer now exposes a Source select (Local / OIDC /
SAML / CAS) so an admin can flip an existing account between Local
password and an external IdP without touching the database. Mirrors
the matching `PUT /v1/users/{id}` change on the backend.

Password field follows the selected source:

* Hidden when source != Local — those users authenticate via the IdP
  and a local password row would be a /login bypass.
* Required when CREATE-with-Local, or when EDIT is switching an SSO
  user back to Local (the backend rejects SSO -> Local without a
  fresh password to avoid locking the user out of /login).
* Optional when editing an already-Local user, matching today's
  behaviour.

A switch in EDIT mode surfaces a tip explaining the side effect
(password cleared / new password required) so the consequence isn't
hidden. The Source select is disabled on self-edit — same guard the
role column already uses — so an admin can't lock themselves out by
flipping their own row to an external source.

Strings are added to all five locales; the IdP protocol acronyms
(OIDC / SAML / CAS) render verbatim and don't need translation keys.
2026-07-01 15:39:10 +08:00
jialinandjialin 8a15172316 fix(provider): table sorting does not work 2026-07-01 11:42:30 +08:00
jialinandjialin 185e3475e7 feat: add model icon in my models 2026-07-01 11:42:30 +08:00
jialinandjialin 64720ccbfa chore: press enter key to submit while focus on password 2026-07-01 11:42:30 +08:00
jialinandjialin db17192e55 fix(usage): carry full filter set in breakdown tables and fix double fetch
- breakdown sub-tables now send all active filters (route/user/api_key), matching the trend chart
- summary tab filters the token trend by user and unions user options from both meta APIs (deduped by id)
- stabilize the filters reference so meta load no longer retriggers a second fetch on mount
2026-06-30 17:02:17 +08:00
gitlawr a1dd1ec861 ci: trigger backend pack on UI merge
After build-publish uploads the UI tarball to COS, dispatch a
repository_dispatch event (ui-built) to gpustack/gpustack so the
backend repack picks up the new UI.

Skipped for tag pushes — release tags drive the backend pack via
its own tag trigger. Requires a DISPATCH_PAT secret with
actions:write on gpustack/gpustack.
2026-06-30 15:57:33 +08:00
jialinandjialin a516e6ce72 feat(dashboard): split top user token usage into prompt/completion 2026-06-30 14:38:35 +08:00
micheliaandjialin 2e375c6603 fix(usage): label per-instance rows by shape, not an undefined title
The Instances-tab Instance Type column passed isCpu ? cpuOnlyLabel : undefined.
For a GPU row with vram but a missing/zero gpu_count, undefined let
renderInstanceType fall back to "CPU Only" (acceleratable=false). Pass
instanceTypeSeriesLabel(row) directly — consistent with the Instance Types
column and robust to that edge. (PR #1245 review)
2026-06-30 14:11:39 +08:00
micheliaandjialin 7d94c77c15 fix(usage): sum same-label buckets in the trend series
buildTrendSeries overwrote a (label, bucket) value on collision. Should two
backend groups ever map to the same display label, their values must add up
rather than letting the last write win. Accumulate instead.
2026-06-30 14:11:39 +08:00
micheliaandjialin 457d2f2f72 feat(usage): render instance types by actual shape (CPU spec / GPU x cards)
Instance Types are grouped by actual shape now, so each row/series is one
concrete type. Label them accordingly via a shared instanceTypeSeriesLabel,
used by both the table column and the trend legend so they read identically:
GPU shows "<product> x <cards>", CPU shows "CPU Only · N vCPU · M GB" (the
instance's real size, not the bare "CPU Only" + hover tooltip). The Instances
tab also uses the per-instance cpu/mem totals, so a 3c6g instance of a 1c2g
flavor reads 3c6g instead of 1c2g. flatten carries cpu_milli/memory_mib/
gpu_count from the breakdown dimensions.
2026-06-30 14:11:39 +08:00
gitlawrandjialin 5e7d83e5dd fix(api-keys): let platform admin create a non-tenant-pinned API key
The CreateOrgScopeField slot only renders a "Global" choice when the
host form passes ``allowGlobal: true``. Without it, an admin in the
"All Orgs" view sees only Personal + every org in the dropdown — and
the form's submit injects an ``X-Organization-Id`` header for every
choice, pinning the new key to a tenant. The matching backend change
(api_keys.owner_principal_id nullable) only kicks in when no header
is sent.

Pass ``allowGlobal: true`` (default-selects Global for admin) plus
``globalLabelId: 'scope.global'`` so the dropdown option reads as
plain "Global" — matching the existing tag / column labels for the
same concept elsewhere in the UI, instead of the longer
inference-backend "shared with all organizations" copy.

Relax the ListItem type so ``owner_principal_id`` may be ``null`` —
the OrganizationCell / OwnerScopeTag renderers already render the
"Global" placeholder for null/undefined; the type was the only thing
still claiming the column was always present.
2026-06-30 11:54:00 +08:00
jialinandjialin b1cffe047c docs: expand CLAUDE.md conventions (naming, types, config, core-ui)
- Clarify styles rule: avoid styled-components in new code; existing
  usage is legacy debt, not migrated wholesale
- Add naming conventions (module structure, file naming)
- Add config & types section (FormData/ListItem, config/index.ts)
- Expand Common components with frequently-reused core-ui inventory
2026-06-29 19:44:28 +08:00
jialinandjialin 6509f2a4ff docs: consolidate component conventions into CLAUDE.md and skill
- Add "Dynamic add-item form fields" guidance to CLAUDE.md (pick
  component by field schema: LabelSelector / ListInput / MetadataList)
- Fold StatusTag status-display recipe into create-crud-page skill
- Remove DESIGN.md (content migrated to the above)
2026-06-29 19:44:28 +08:00
jialinandjialin f719c11606 refactor(perferences): use center wrapper layout 2026-06-29 19:44:28 +08:00
jialinandjialin b8d7873b77 chore: dedupe agent instruction files into CLAUDE.md 2026-06-29 12:10:18 +08:00
jialinandjialin a9248a98a5 chore: add create-crud-page and form-patterns skills, refresh CLAUDE.md 2026-06-29 12:10:18 +08:00
micheliaandjialin 8f85e9a082 fix(usage): use frontend gpu_type token for instance-type legend
flattenItem receives the unmapped frontend dimension; the instance-type
grouping is 'gpu_type' (mapped to backend 'instance_type' via GROUP_BY_MAP),
so the previous 'instance_type' check never matched and the trend legend kept
showing the raw flavor slug. Check 'gpu_type'. (PR #1240 review)
2026-06-27 22:27:42 +08:00
micheliaandjialin 1a6d1654b2 fix(usage): label instance_type trend series by product name
The grouped-trend legend used the raw group key, which for instance_type is
the flavor slug (e.g. gpustack--generic-ln-x64-40c-160g--nvidia-a100-80g-4d).
Prefer the enriched product name so the chart legend matches the GPU Instances
list (#5700); falls back to the slug for legacy rows without dimension data.
2026-06-27 22:27:42 +08:00
micheliaandjialin abe705c034 fix(usage): fetch full trend/export series via page=-1
Trend charts and breakdown exports need the complete date series. The old
perPage=10000 workaround (and the missing page param on the token trend,
which fell back to perPage=20) dropped low-traffic — often most recent —
buckets, leaving gaps in the charts (#5690).

Send page=-1 (the backend's no-pagination sentinel) for the token trend,
the storage/instances trend charts and table exports, the resource export
dialog, and the summary-tab date trends.
2026-06-27 22:27:42 +08:00
jialinandjialin 8b34f68824 feat(cluster): resource topology entrance 2026-06-26 22:14:37 +08:00
jialinandjialin e37828a2cd fix: resource topology ux 2026-06-26 22:14:37 +08:00
jialinandjialin 4709661f93 fix(tts): reset form fields to initialvalues after model changed 2026-06-25 14:34:15 +08:00
jialinandjialin 1d7543f19c chore: adjust colors generator 2026-06-25 14:34:15 +08:00
jialinandjialin 1cf146ca32 fix(usage): dynamic bar color value 2026-06-24 20:54:16 +08:00
jialinandjialin b05c510776 fix: add warning tips when deleting ssh key 2026-06-24 20:54:16 +08:00
jialinandjialin e79d5f8962 fix(usage): selection maxTagCount 2026-06-24 20:54:16 +08:00