feat(usage): resource usage metering page

Add the Usage page with Summary / Tokens / GPU Instances / Storage / Resource
Events tabs over the new metering endpoints: per-resource breakdowns with
date / scope / user / resource filters, trend charts, server-side sortable
tables (GPU-Hours, Instance-Hours, GB-Days, GB-Hours), Excel export with an
in-dialog preview, and KPI cards with help tooltips explaining each metric.

MaaS-only users (no Kubernetes cluster and no resource events) get a
tokens-only view with the tab bar dropped; GPU Service / the full page unlock
for admins, cluster owners, or anyone who has run a resource. Instance-type
rows reuse the GPU Instances list styling, and deleted users / instances /
volumes are flagged in breakdowns and filters.
This commit is contained in:
michelia
2026-06-04 19:52:52 +08:00
committed by jialin
parent 50601b0aff
commit 62f34ffcaf
14 changed files with 459 additions and 45 deletions
+7 -1
View File
@@ -3,6 +3,7 @@ import { applyAccessExtensions } from './access.extensions';
export default (initialState: {
currentUser?: Global.UserInfo;
hasKubernetesCluster?: boolean;
hasResourceEvents?: boolean;
}) => {
const isPlatformAdmin = !!(
initialState &&
@@ -20,6 +21,10 @@ export default (initialState: {
// role-based default so a transient network blip can't lock anyone
// out of the menu.
const hasKubernetesCluster = initialState?.hasKubernetesCluster;
// Having run GPU/CPU instances or storage (any resource_events) also unlocks
// GPU Service / the full Usage page — a user who used it keeps seeing it even
// without a current cluster. MaaS-only users (no cluster, no events) don't.
const hasResourceEvents = !!initialState?.hasResourceEvents;
// Predicate roles, top-down by strictness:
// * `canSeeAdmin` — strictly platform admin (`users.is_admin`).
@@ -41,7 +46,8 @@ export default (initialState: {
return applyAccessExtensions({
canSeeAdmin: isPlatformAdmin,
canSeeOrgAdmin: isPlatformAdmin,
canSeeGpuService: isPlatformAdmin || hasKubernetesCluster !== false,
canSeeGpuService:
isPlatformAdmin || hasKubernetesCluster !== false || hasResourceEvents,
canManageCurrentOrg: false,
canSeeUser,
canDelete: true,