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:
@@ -10,6 +10,34 @@ import useAPIKeysColumns from './use-apikeys-columns';
|
||||
import useModelsColumns from './use-models-columns';
|
||||
import useUsersColumns from './use-users-columns';
|
||||
|
||||
type ColumnLike = {
|
||||
title: any;
|
||||
dataIndex: string | string[];
|
||||
key?: string;
|
||||
};
|
||||
|
||||
const toFieldKey = (dataIndex: string | string[]): string =>
|
||||
Array.isArray(dataIndex) ? dataIndex.join('_') : dataIndex;
|
||||
|
||||
const buildSheetMeta = (columns: ColumnLike[]) => {
|
||||
const fields: string[] = [];
|
||||
const fieldLabels: Record<string, any> = {};
|
||||
const formatMap: Record<string, (raw: any, row: any) => any> = {};
|
||||
|
||||
columns.forEach((col) => {
|
||||
if (!col.dataIndex) return;
|
||||
const key = toFieldKey(col.dataIndex);
|
||||
fields.push(key);
|
||||
fieldLabels[key] = col.title;
|
||||
if (Array.isArray(col.dataIndex)) {
|
||||
const path = col.dataIndex;
|
||||
formatMap[key] = (_raw, row) => _.get(row, path);
|
||||
}
|
||||
});
|
||||
|
||||
return { fields, fieldLabels, formatMap };
|
||||
};
|
||||
|
||||
const useExportTable = () => {
|
||||
const store = useStore();
|
||||
const modelsColumns = useModelsColumns();
|
||||
@@ -20,53 +48,34 @@ const useExportTable = () => {
|
||||
const usersTableData = store.get(usersTableDataAtom);
|
||||
const apiKeysTableData = store.get(apiKeysTableDataAtom);
|
||||
const modelsTableData = store.get(modelsTableDataAtom);
|
||||
|
||||
const modelsMeta = buildSheetMeta(modelsColumns);
|
||||
const apiKeysMeta = buildSheetMeta(apiKeysColumns);
|
||||
const usersMeta = buildSheetMeta(usersColumns);
|
||||
|
||||
exportJsonToExcel({
|
||||
fileName: 'table_data.xlsx',
|
||||
sheets: [
|
||||
{
|
||||
jsonData: modelsTableData.dataList || [],
|
||||
sheetName: 'models',
|
||||
fields: modelsColumns
|
||||
.map((col: any) => _.join(col.dataIndex, '_'))
|
||||
.filter(Boolean) as string[],
|
||||
fieldLabels: modelsColumns.reduce(
|
||||
(map, col) => {
|
||||
map[_.join(col.dataIndex, '_')] = col.title;
|
||||
return map;
|
||||
},
|
||||
{} as Record<string, any>
|
||||
),
|
||||
formatMap: {}
|
||||
fields: modelsMeta.fields,
|
||||
fieldLabels: modelsMeta.fieldLabels,
|
||||
formatMap: modelsMeta.formatMap
|
||||
},
|
||||
{
|
||||
jsonData: apiKeysTableData.dataList || [],
|
||||
sheetName: 'api_keys',
|
||||
fields: apiKeysColumns
|
||||
.map((col: any) => col.dataIndex)
|
||||
.filter(Boolean) as string[],
|
||||
fieldLabels: apiKeysColumns.reduce(
|
||||
(map, col) => {
|
||||
map[_.join(col.dataIndex, '_')] = col.title;
|
||||
return map;
|
||||
},
|
||||
{} as Record<string, any>
|
||||
),
|
||||
formatMap: {}
|
||||
fields: apiKeysMeta.fields,
|
||||
fieldLabels: apiKeysMeta.fieldLabels,
|
||||
formatMap: apiKeysMeta.formatMap
|
||||
},
|
||||
{
|
||||
jsonData: usersTableData.dataList || [],
|
||||
sheetName: 'users',
|
||||
fields: usersColumns
|
||||
.map((col: any) => col.dataIndex)
|
||||
.filter(Boolean) as string[],
|
||||
fieldLabels: usersColumns.reduce(
|
||||
(map, col) => {
|
||||
map[_.join(col.dataIndex, '_')] = col.title;
|
||||
return map;
|
||||
},
|
||||
{} as Record<string, any>
|
||||
),
|
||||
formatMap: {}
|
||||
fields: usersMeta.fields,
|
||||
fieldLabels: usersMeta.fieldLabels,
|
||||
formatMap: usersMeta.formatMap
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user