feat(usage): add resource-usage API client, meta hook, and shared utils
The data layer the resource tabs build on: - apis/resource.ts: adapter over the unified metered_usage read API (resource/gpu-instances/storage/summary/events breakdowns), flattening the server's generic shape into the per-tab item shape. - hooks/use-resource-meta.ts: loads creators/instances/volumes filter options for the current scope. - utils/time-buckets.ts: day/week/month/hour bucket keys + range fill. - utils/export-breakdown.ts: derive Excel columns from antd table specs.
This commit is contained in:
@@ -0,0 +1,58 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
import {
|
||||
queryResourceFilterMeta,
|
||||
ResourceFilterOption
|
||||
} from '../apis/resource';
|
||||
|
||||
export interface SelectOption {
|
||||
value: number;
|
||||
label: string;
|
||||
}
|
||||
|
||||
export interface ResourceMetaOptions {
|
||||
creators: SelectOption[];
|
||||
instances: SelectOption[];
|
||||
volumes: SelectOption[];
|
||||
}
|
||||
|
||||
const EMPTY: ResourceMetaOptions = {
|
||||
creators: [],
|
||||
instances: [],
|
||||
volumes: []
|
||||
};
|
||||
|
||||
const toOptions = (items: ResourceFilterOption[]): SelectOption[] =>
|
||||
items.map((i) => ({ value: i.id, label: i.label }));
|
||||
|
||||
/**
|
||||
* Loads the resource tabs' filter dropdown sources in one call:
|
||||
* - ``creators`` — "filter by user" (Tokens-tab equivalent of /usage/meta
|
||||
* users); only shown to managers, but cheap to always load.
|
||||
* - ``instances`` — "filter by GPU instance" (GPU Instances tab)
|
||||
* - ``volumes`` — "filter by volume" (Storage tab)
|
||||
*
|
||||
* Scope-aware: managers get the org-wide lists, others only their own
|
||||
* resources. Refetched when ``scope`` changes.
|
||||
*/
|
||||
export default function useResourceMeta(
|
||||
scope: 'self' | 'all' = 'all'
|
||||
): ResourceMetaOptions {
|
||||
const [meta, setMeta] = useState<ResourceMetaOptions>(EMPTY);
|
||||
|
||||
useEffect(() => {
|
||||
queryResourceFilterMeta(scope)
|
||||
.then((res) =>
|
||||
setMeta({
|
||||
creators: toOptions(res.creators),
|
||||
instances: toOptions(res.instances),
|
||||
volumes: toOptions(res.volumes)
|
||||
})
|
||||
)
|
||||
.catch(() => {
|
||||
// Network/auth errors surface via the global interceptor; leave the
|
||||
// dropdowns empty rather than crashing the tab.
|
||||
});
|
||||
}, [scope]);
|
||||
|
||||
return meta;
|
||||
}
|
||||
Reference in New Issue
Block a user