From abe705c03462a5789fa09aa6bfa95127ac2e6ba5 Mon Sep 17 00:00:00 2001 From: michelia Date: Fri, 26 Jun 2026 18:26:03 +0800 Subject: [PATCH] fix(usage): fetch full trend/export series via page=-1 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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. --- src/pages/usage/components/resource-export-data.tsx | 5 +++-- src/pages/usage/hooks/use-usage-filters.ts | 5 +++++ src/pages/usage/instances-tab/index.tsx | 6 ++++-- src/pages/usage/storage-tab/index.tsx | 6 ++++-- src/pages/usage/summary-tab/index.tsx | 6 ++++++ 5 files changed, 22 insertions(+), 6 deletions(-) diff --git a/src/pages/usage/components/resource-export-data.tsx b/src/pages/usage/components/resource-export-data.tsx index 3dde4613..f71d33fa 100644 --- a/src/pages/usage/components/resource-export-data.tsx +++ b/src/pages/usage/components/resource-export-data.tsx @@ -163,11 +163,12 @@ const ResourceExportData: React.FC = (props) => { setPageParams({ page, perPage }); }; - // Export the full filtered set, not just the visible page. + // Export the full filtered set, not just the visible page. ``page: -1`` is + // the backend's no-pagination sentinel (perPage is then ignored). const handleSubmit = async () => { setExporting(true); try { - const res = await queryFn(buildRequest(1, 10000)); + const res = await queryFn(buildRequest(-1, INITIAL_PAGE.perPage)); exportBreakdownRows( res.items ?? [], toExportColumns(columns), diff --git a/src/pages/usage/hooks/use-usage-filters.ts b/src/pages/usage/hooks/use-usage-filters.ts index 5a0802d6..1dddc2bd 100644 --- a/src/pages/usage/hooks/use-usage-filters.ts +++ b/src/pages/usage/hooks/use-usage-filters.ts @@ -208,6 +208,11 @@ export const useUsageFilters = ({ fetchTimeSeriesData({ ...currentChartFilters, group_by: groupByArray, + // The trend chart needs the complete date series. ``page: -1`` is the + // backend's no-pagination sentinel — without it the default page (20 + // buckets, sorted by total tokens) drops low-traffic dates, leaving + // gaps in the chart for ranges spanning more than a handful of buckets. + page: -1, // Without ``scope`` the backend defaults to ``all``, while the // breakdown tables pass ``scope`` explicitly. The mismatch makes // the chart and the tables run different filters on the same diff --git a/src/pages/usage/instances-tab/index.tsx b/src/pages/usage/instances-tab/index.tsx index 7de4009d..bc83126b 100644 --- a/src/pages/usage/instances-tab/index.tsx +++ b/src/pages/usage/instances-tab/index.tsx @@ -148,7 +148,8 @@ const GpuInstancesTab: React.FC = () => { // whole range. The default order is metric-desc, so partial (current/ // recent) buckets have smaller values and would be pushed onto later // pages — dropping the newest hours from the chart under a small page. - perPage: 10000 + // ``page: -1`` is the backend's no-pagination sentinel. + page: -1 }); useEffect(() => { @@ -296,7 +297,8 @@ const GpuInstancesTab: React.FC = () => { ...baseRequest(), group_by: [g.key], // A breakdown export is the full filtered set, not a page. - perPage: 10000 + // ``page: -1`` is the backend's no-pagination sentinel. + page: -1 }) ) ); diff --git a/src/pages/usage/storage-tab/index.tsx b/src/pages/usage/storage-tab/index.tsx index b613b9fb..ded6badf 100644 --- a/src/pages/usage/storage-tab/index.tsx +++ b/src/pages/usage/storage-tab/index.tsx @@ -140,7 +140,8 @@ const StorageTab: React.FC = () => { // whole range. The default order is metric-desc, so partial (current/ // recent) buckets have smaller values and would be pushed onto later // pages — dropping the newest hours from the chart under a small page. - perPage: 10000 + // ``page: -1`` is the backend's no-pagination sentinel. + page: -1 }) ); @@ -283,7 +284,8 @@ const StorageTab: React.FC = () => { ...baseRequest(), group_by: [g.key], // A breakdown export is the full filtered set, not a page. - perPage: 10000 + // ``page: -1`` is the backend's no-pagination sentinel. + page: -1 }) ) ); diff --git a/src/pages/usage/summary-tab/index.tsx b/src/pages/usage/summary-tab/index.tsx index e4826812..8c3328a9 100644 --- a/src/pages/usage/summary-tab/index.tsx +++ b/src/pages/usage/summary-tab/index.tsx @@ -299,16 +299,21 @@ const SummaryTab: React.FC = () => { filters: creatorFilter }), + // Date-bucketed trends: fetch the whole series via the no-pagination + // sentinel (page: -1). A metric-desc page would drop low-traffic (often + // most recent) buckets and leave gaps in the chart. fetchTokenSeries({ ...commonParams, metric: 'total_tokens', group_by: ['date'], granularity, + page: -1, filters: {} }), fetchComputeBreakdown({ ...paginationParams, + page: -1, group_by: ['date'], granularity, filters: creatorFilter @@ -316,6 +321,7 @@ const SummaryTab: React.FC = () => { fetchStorageByDate({ ...paginationParams, + page: -1, group_by: ['date'], granularity, filters: creatorFilter