refactor(usage): switch breakdown dimension from model to route

Align with gpustack backend commits 7b57cd3b (add route dimension to
usage breakdown) and 51fd25c8 (use model_route_id as models_called):

* group_by, filters, and BreakdownItem now use the `route` dimension;
  `models` filter cascader is replaced with a flat `routes` selector
  (routes have no provider/cluster grouping).
* Tab / group_by option / column header keep the user-facing "模型 / Model"
  wording — only the underlying data dimension changed.
* Drop cluster_name / provider_type columns from the breakdown table;
  drop api_keys_used column per design.
* Fix pre-existing excel export bug in use-export-table — string
  dataIndex was lodash-joined char-by-char ("input_tokens" →
  "i_n_p_u_t..."), array dataIndex was used as a flat key against nested
  rows. Rebuilt around buildSheetMeta that emits a stable field key plus
  a formatMap using _.get(row, path) for nested values. Sheet name kept
  as `models` to match the visible column label.
This commit is contained in:
Yuxing Deng
2026-05-19 16:50:42 +08:00
parent 0274bcb8cd
commit 38107a67fe
15 changed files with 135 additions and 254 deletions
@@ -31,7 +31,7 @@ export const useQueryBreakdownList = (options?: {
ListItem,
Global.SearchParams & {
filters: {
models?: FilterOptionType[];
routes?: FilterOptionType[];
users?: FilterOptionType[];
api_keys?: FilterOptionType[];
};
@@ -46,7 +46,7 @@ export const useQueryBreakdownList = (options?: {
const fetchListData = async (
params: Global.SearchParams & {
filters: {
models?: FilterOptionType[];
routes?: FilterOptionType[];
users?: FilterOptionType[];
api_keys?: FilterOptionType[];
};
@@ -9,6 +9,10 @@ type UserOptionType = UsageFilterItem & {
value: string;
};
type RouteOptionType = UsageFilterItem & {
value: string;
};
export default function useQueryUsageMetaData() {
const { detailData, loading, cancelRequest, fetchData } =
useQueryData<UsageMeta>({
@@ -20,10 +24,12 @@ export default function useQueryUsageMetaData() {
models: GroupOption<UsageFilterItem>[];
users: UserOptionType[];
api_keys: GroupOption<UsageFilterItem>[];
routes: RouteOptionType[];
}>({
models: [],
users: [],
api_keys: []
api_keys: [],
routes: []
});
// the current user sort in the first place
@@ -70,7 +76,12 @@ export default function useQueryUsageMetaData() {
value: item.label,
label: item.identity.value.api_key_name || ''
})
})
}),
routes:
(res?.filters?.routes || []).map((item) => ({
...item,
value: item.label
})) || []
};
setResult(data);
};