Merge pull request #412 from ProtectCookies/main

This commit is contained in:
leokun
2026-09-04 15:45:51 +08:00
16 changed files with 369 additions and 52 deletions
+29 -4
View File
@@ -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";
@@ -27,7 +27,9 @@ 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 };
}
@@ -35,6 +37,8 @@ export function HomePage() {
const { overview, busy, models, plugins } = useAppStore();
const { locale } = useI18n();
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("");
@@ -53,13 +57,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) => ({
@@ -96,9 +101,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);
@@ -146,13 +168,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}