mirror of
https://wget.la/https://github.com/leookun/cursor-byok
synced 2026-10-10 10:18:30 +08:00
feat(overview): 近4小时/近24小时移入自定义弹层,近4小时支持选择图表粒度
- 主时间栏移除近4小时/近24小时,改为自定义弹层顶部的快捷范围 - 近4小时点击后弹出粒度菜单:1分钟/15分钟/30分钟/1小时 - overview API 新增 bucket_ms 参数,支持客户端指定分桶粒度 - 指定粒度时桶数上限放宽至 1440,未指定时维持原自动逻辑
This commit is contained in:
@@ -5,7 +5,7 @@ import { DailyTokenUsageChart } from "./charts/DailyTokenUsageChart";
|
||||
import { HomeMetrics } from "./metrics/HomeMetrics";
|
||||
import { PageContent } from "../../shell/layout/PageContent";
|
||||
import type { VirtualPageSection } from "../../shell/layout/VirtualPage";
|
||||
import { OverviewTimeRangeFilter, type OverviewRangePreset } from "./overview/OverviewTimeRangeFilter";
|
||||
import { OverviewTimeRangeFilter, type OverviewRangePreset, type QuickPreset } from "./overview/OverviewTimeRangeFilter";
|
||||
import { PageActions } from "../../shell/PageActions";
|
||||
import { appStore, useAppStore } from "../../shared/store/appStore";
|
||||
import { formatTimeInput, parseTimeInput } from "../../shared/utils/parseTimeInput";
|
||||
@@ -25,13 +25,17 @@ function presetRange(preset: Exclude<OverviewRangePreset, "custom">, now = new D
|
||||
start.setMonth(start.getMonth() - 1);
|
||||
return { startMs: start.getTime(), endMs };
|
||||
}
|
||||
const duration = preset === "ten-minutes" ? 10 * 60_000 : preset === "hour" ? 60 * 60_000 : 7 * 24 * 60 * 60_000;
|
||||
const duration = preset === "ten-minutes" ? 10 * 60_000
|
||||
: preset === "hour" ? 60 * 60_000
|
||||
: 7 * 24 * 60 * 60_000;
|
||||
return { startMs: now.getTime() - duration, endMs };
|
||||
}
|
||||
|
||||
export function HomePage() {
|
||||
const { overview, busy, models, plugins } = useAppStore();
|
||||
const [preset, setPreset] = useState<OverviewRangePreset>("month");
|
||||
const [quick, setQuick] = useState<QuickPreset | null>(null);
|
||||
const [fourHourBucket, setFourHourBucket] = useState<number | undefined>(undefined);
|
||||
const [customRange, setCustomRange] = useState<TimeRange | null>(null);
|
||||
const [customOpen, setCustomOpen] = useState(false);
|
||||
const [customStart, setCustomStart] = useState("");
|
||||
@@ -50,13 +54,14 @@ export function HomePage() {
|
||||
void api.overview({
|
||||
...selectedRange,
|
||||
modelHashes: appliedModels,
|
||||
bucketMs: fourHourBucket,
|
||||
}).then((next) => {
|
||||
if (active) setRangeOverview(next);
|
||||
}).finally(() => {
|
||||
if (active) setRangeBusy(false);
|
||||
});
|
||||
return () => { active = false; };
|
||||
}, [preset, customRange, overview, refreshVersion, appliedModels]);
|
||||
}, [preset, customRange, overview, refreshVersion, appliedModels, fourHourBucket]);
|
||||
|
||||
const filteredOverview = rangeOverview ?? overview;
|
||||
const dailyTokenUsage = filteredOverview.token_usage_series.map((bucket) => ({
|
||||
@@ -93,9 +98,26 @@ export function HomePage() {
|
||||
if (startMs === null || endMs === null || startMs >= endMs) return;
|
||||
setCustomRange({ startMs, endMs });
|
||||
setAppliedModels(selectedModels);
|
||||
setQuick(null);
|
||||
setFourHourBucket(undefined);
|
||||
setPreset("custom");
|
||||
setCustomOpen(false);
|
||||
};
|
||||
const selectQuick = (durationMs: number, bucketMs?: number) => {
|
||||
const endMs = Date.now();
|
||||
setCustomRange({ startMs: endMs - durationMs, endMs });
|
||||
setAppliedModels(selectedModels);
|
||||
setQuick(durationMs === 4 * 60 * 60_000 ? "four-hours" : "twenty-four-hours");
|
||||
setFourHourBucket(durationMs === 4 * 60 * 60_000 ? bucketMs : undefined);
|
||||
setPreset("custom");
|
||||
setCustomOpen(false);
|
||||
};
|
||||
const selectPreset = (value: Exclude<OverviewRangePreset, "custom">) => {
|
||||
setPreset(value);
|
||||
setQuick(null);
|
||||
setFourHourBucket(undefined);
|
||||
setCustomOpen(false);
|
||||
};
|
||||
const refresh = async () => {
|
||||
await appStore.refresh();
|
||||
setRefreshVersion((version) => version + 1);
|
||||
@@ -138,13 +160,16 @@ export function HomePage() {
|
||||
return <>
|
||||
<PageActions><OverviewTimeRangeFilter
|
||||
value={preset}
|
||||
quick={quick}
|
||||
fourHourBucket={fourHourBucket}
|
||||
customOpen={customOpen}
|
||||
customStart={customStart}
|
||||
customEnd={customEnd}
|
||||
modelOptions={modelOptions}
|
||||
selectedModels={selectedModels}
|
||||
busy={busy || rangeBusy}
|
||||
onSelect={(value) => { setPreset(value); setCustomOpen(false); }}
|
||||
onSelect={selectPreset}
|
||||
onQuickSelect={selectQuick}
|
||||
onCustomOpenChange={openCustom}
|
||||
onCustomStartChange={setCustomStart}
|
||||
onCustomEndChange={setCustomEnd}
|
||||
|
||||
Reference in New Issue
Block a user