mirror of
https://github.com/Gitlawb/openclaude.git
synced 2026-08-24 10:14:19 -05:00
fix(typecheck): type stats dialog state (#1569)
This commit is contained in:
+40
-27
@@ -11,7 +11,7 @@ import { applyColor } from '../ink/colorize.js';
|
||||
import { stringWidth as getStringWidth } from '../ink/stringWidth.js';
|
||||
import type { Color } from '../ink/styles.js';
|
||||
// eslint-disable-next-line custom-rules/prefer-use-keybindings -- raw j/k/arrow stats navigation
|
||||
import { Ansi, Box, Text, useInput } from '../ink.js';
|
||||
import { Ansi, Box, type Key, Text, useInput } from '../ink.js';
|
||||
import { useKeybinding } from '../keybindings/useKeybinding.js';
|
||||
import { getGlobalConfig } from '../utils/config.js';
|
||||
import { formatDuration, formatNumber } from '../utils/format.js';
|
||||
@@ -46,6 +46,10 @@ type StatsResult = {
|
||||
} | {
|
||||
type: 'empty';
|
||||
};
|
||||
type StatsTab = 'Overview' | 'Models';
|
||||
type StatsCache = Partial<Record<StatsDateRange, ClaudeCodeStats>>;
|
||||
type ModelUsageStats = ClaudeCodeStats['modelUsage'][string];
|
||||
type ModelUsageEntry = [string, ModelUsageStats];
|
||||
const DATE_RANGE_LABELS: Record<StatsDateRange, string> = {
|
||||
'7d': 'Last 7 days',
|
||||
'30d': 'Last 30 days',
|
||||
@@ -80,19 +84,19 @@ function createAllTimeStatsPromise(): Promise<StatsResult> {
|
||||
};
|
||||
});
|
||||
}
|
||||
export function Stats(t0) {
|
||||
export function Stats(t0: Props): React.ReactNode {
|
||||
const $ = _c(4);
|
||||
const {
|
||||
onClose
|
||||
} = t0;
|
||||
let t1;
|
||||
let t1: Promise<StatsResult>;
|
||||
if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
|
||||
t1 = createAllTimeStatsPromise();
|
||||
$[0] = t1;
|
||||
} else {
|
||||
t1 = $[0];
|
||||
}
|
||||
const allTimePromise = t1;
|
||||
const allTimePromise: Promise<StatsResult> = t1;
|
||||
let t2;
|
||||
if ($[1] === Symbol.for("react.memo_cache_sentinel")) {
|
||||
t2 = <Box marginTop={1}><Spinner /><Text> Loading your OpenClaude stats…</Text></Box>;
|
||||
@@ -119,27 +123,27 @@ type StatsContentProps = {
|
||||
* Inner component that uses React 19's use() to read the stats promise.
|
||||
* Suspends while loading all-time stats, then handles date range changes without suspending.
|
||||
*/
|
||||
function StatsContent(t0) {
|
||||
function StatsContent(t0: StatsContentProps): React.ReactNode {
|
||||
const $ = _c(34);
|
||||
const {
|
||||
allTimePromise,
|
||||
onClose
|
||||
} = t0;
|
||||
const allTimeResult = use(allTimePromise);
|
||||
const [dateRange, setDateRange] = useState("all");
|
||||
let t1;
|
||||
const allTimeResult: StatsResult = use(allTimePromise);
|
||||
const [dateRange, setDateRange] = useState<StatsDateRange>("all");
|
||||
let t1: StatsCache;
|
||||
if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
|
||||
t1 = {};
|
||||
$[0] = t1;
|
||||
} else {
|
||||
t1 = $[0];
|
||||
}
|
||||
const [statsCache, setStatsCache] = useState(t1);
|
||||
const [statsCache, setStatsCache] = useState<StatsCache>(t1);
|
||||
const [isLoadingFiltered, setIsLoadingFiltered] = useState(false);
|
||||
const [activeTab, setActiveTab] = useState("Overview");
|
||||
const [copyStatus, setCopyStatus] = useState(null);
|
||||
let t2;
|
||||
let t3;
|
||||
const [activeTab, setActiveTab] = useState<StatsTab>("Overview");
|
||||
const [copyStatus, setCopyStatus] = useState<string | null>(null);
|
||||
let t2: React.EffectCallback;
|
||||
let t3: [StatsDateRange, StatsCache];
|
||||
if ($[1] !== dateRange || $[2] !== statsCache) {
|
||||
t2 = () => {
|
||||
if (dateRange === "all") {
|
||||
@@ -177,8 +181,8 @@ function StatsContent(t0) {
|
||||
t3 = $[4];
|
||||
}
|
||||
useEffect(t2, t3);
|
||||
const displayStats = dateRange === "all" ? allTimeResult.type === "success" ? allTimeResult.data : null : statsCache[dateRange] ?? (allTimeResult.type === "success" ? allTimeResult.data : null);
|
||||
const allTimeStats = allTimeResult.type === "success" ? allTimeResult.data : null;
|
||||
const displayStats: ClaudeCodeStats | null = dateRange === "all" ? allTimeResult.type === "success" ? allTimeResult.data : null : statsCache[dateRange] ?? (allTimeResult.type === "success" ? allTimeResult.data : null);
|
||||
const allTimeStats: ClaudeCodeStats | null = allTimeResult.type === "success" ? allTimeResult.data : null;
|
||||
let t4;
|
||||
if ($[5] !== onClose) {
|
||||
t4 = () => {
|
||||
@@ -202,9 +206,9 @@ function StatsContent(t0) {
|
||||
t5 = $[7];
|
||||
}
|
||||
useKeybinding("confirm:no", handleClose, t5);
|
||||
let t6;
|
||||
let t6: (input: string, key: Key) => void;
|
||||
if ($[8] !== activeTab || $[9] !== dateRange || $[10] !== displayStats || $[11] !== onClose) {
|
||||
t6 = (input, key) => {
|
||||
t6 = (input: string, key: Key) => {
|
||||
if (key.ctrl && (input === "c" || input === "d")) {
|
||||
onClose("Stats dialog dismissed", {
|
||||
display: "system"
|
||||
@@ -310,10 +314,14 @@ function StatsContent(t0) {
|
||||
}
|
||||
return t12;
|
||||
}
|
||||
function _temp(prev_0) {
|
||||
function _temp(prev_0: StatsTab): StatsTab {
|
||||
return prev_0 === "Overview" ? "Models" : "Overview";
|
||||
}
|
||||
function DateRangeSelector(t0) {
|
||||
type DateRangeSelectorProps = {
|
||||
dateRange: StatsDateRange;
|
||||
isLoading: boolean;
|
||||
};
|
||||
function DateRangeSelector(t0: DateRangeSelectorProps): React.ReactNode {
|
||||
const $ = _c(9);
|
||||
const {
|
||||
dateRange,
|
||||
@@ -714,7 +722,12 @@ function generateFunFactoid(stats: ClaudeCodeStats, totalTokens: number): string
|
||||
const randomIndex = Math.floor(Math.random() * factoids.length);
|
||||
return factoids[randomIndex]!;
|
||||
}
|
||||
function ModelsTab(t0) {
|
||||
type ModelsTabProps = {
|
||||
stats: ClaudeCodeStats;
|
||||
dateRange: StatsDateRange;
|
||||
isLoading: boolean;
|
||||
};
|
||||
function ModelsTab(t0: ModelsTabProps): React.ReactNode {
|
||||
const $ = _c(15);
|
||||
const {
|
||||
stats,
|
||||
@@ -729,7 +742,7 @@ function ModelsTab(t0) {
|
||||
const {
|
||||
columns: terminalWidth
|
||||
} = useTerminalSize();
|
||||
const modelEntries = Object.entries(stats.modelUsage).sort(_temp7);
|
||||
const modelEntries: ModelUsageEntry[] = Object.entries(stats.modelUsage).sort(_temp7);
|
||||
const t1 = !headerFocused;
|
||||
let t2;
|
||||
if ($[0] !== t1) {
|
||||
@@ -814,21 +827,21 @@ function ModelsTab(t0) {
|
||||
return <ModelEntry key={model_0} model={model_0} usage={usage_0} totalTokens={totalTokens} />;
|
||||
})}</Box>{t9}</Box>{t10}</Box>;
|
||||
}
|
||||
function _temp1(item, i) {
|
||||
function _temp1(item: ChartLegend, i: number): React.ReactNode {
|
||||
return <Text key={item.model}>{i > 0 ? " \xB7 " : ""}<Ansi>{item.coloredBullet}</Ansi> {item.model}</Text>;
|
||||
}
|
||||
function _temp0(t0) {
|
||||
function _temp0(t0: ModelUsageEntry): string {
|
||||
const [model] = t0;
|
||||
return model;
|
||||
}
|
||||
function _temp9(sum, t0) {
|
||||
function _temp9(sum: number, t0: ModelUsageEntry): number {
|
||||
const [, usage] = t0;
|
||||
return sum + usage.inputTokens + usage.outputTokens;
|
||||
}
|
||||
function _temp8(prev_0) {
|
||||
function _temp8(prev_0: number): number {
|
||||
return Math.max(prev_0 - 2, 0);
|
||||
}
|
||||
function _temp7(t0, t1) {
|
||||
function _temp7(t0: ModelUsageEntry, t1: ModelUsageEntry): number {
|
||||
const [, a] = t0;
|
||||
const [, b] = t1;
|
||||
return b.inputTokens + b.outputTokens - (a.inputTokens + a.outputTokens);
|
||||
@@ -842,7 +855,7 @@ type ModelEntryProps = {
|
||||
};
|
||||
totalTokens: number;
|
||||
};
|
||||
function ModelEntry(t0) {
|
||||
function ModelEntry(t0: ModelEntryProps): React.ReactNode {
|
||||
const $ = _c(21);
|
||||
const {
|
||||
model,
|
||||
|
||||
Reference in New Issue
Block a user