claude-usage-dashboard 1.5.5 → 1.5.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/public/js/app.js +32 -11
package/package.json
CHANGED
package/public/js/app.js
CHANGED
|
@@ -30,6 +30,32 @@ const state = {
|
|
|
30
30
|
let datePicker, planSelector;
|
|
31
31
|
let _cachedCycleData = null;
|
|
32
32
|
|
|
33
|
+
/**
|
|
34
|
+
* Find a quota cycle whose period matches the selected date range.
|
|
35
|
+
* Returns the cycle's overall metrics, or null if no match.
|
|
36
|
+
* Tolerance: 25 hours (handles hour-level normalization and timezone offsets).
|
|
37
|
+
*/
|
|
38
|
+
function findMatchingCycle(dateRange, cycleData) {
|
|
39
|
+
if (!dateRange.from || !dateRange.to || !cycleData) return null;
|
|
40
|
+
const viewFrom = new Date(dateRange.from).getTime();
|
|
41
|
+
const viewTo = new Date(dateRange.to).getTime();
|
|
42
|
+
const tolerance = 25 * 60 * 60 * 1000;
|
|
43
|
+
|
|
44
|
+
const candidates = [];
|
|
45
|
+
if (cycleData.currentCycle) candidates.push(cycleData.currentCycle);
|
|
46
|
+
if (cycleData.history) candidates.push(...cycleData.history);
|
|
47
|
+
|
|
48
|
+
for (const c of candidates) {
|
|
49
|
+
if (!c.start || !c.resets_at || !c.overall?.tokens) continue;
|
|
50
|
+
const cStart = new Date(c.start).getTime();
|
|
51
|
+
const cEnd = new Date(c.resets_at).getTime();
|
|
52
|
+
if (Math.abs(viewFrom - cStart) < tolerance && Math.abs(viewTo - cEnd) < tolerance) {
|
|
53
|
+
return c.overall;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
58
|
+
|
|
33
59
|
function formatNumber(n) {
|
|
34
60
|
if (n >= 1_000_000) return (n / 1_000_000).toFixed(1) + 'M';
|
|
35
61
|
if (n >= 1_000) return (n / 1_000).toFixed(0) + 'K';
|
|
@@ -144,21 +170,16 @@ async function loadAll() {
|
|
|
144
170
|
fetchCache(params),
|
|
145
171
|
]);
|
|
146
172
|
|
|
147
|
-
// Summary cards — use multi-machine cycle data when
|
|
173
|
+
// Summary cards — use multi-machine cycle data when date range matches a cycle
|
|
148
174
|
const t = usage.total;
|
|
149
175
|
let tokIn = t.input_tokens, tokOut = t.output_tokens;
|
|
150
176
|
let tokCR = t.cache_read_tokens, tokCW = t.cache_creation_tokens;
|
|
151
177
|
let apiCost = cost.api_equivalent_cost_usd;
|
|
152
|
-
const
|
|
153
|
-
if (
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
if (mergedAll > localAll) {
|
|
158
|
-
tokIn = cct.input; tokOut = cct.output;
|
|
159
|
-
tokCR = cct.cacheRead; tokCW = cct.cacheCreation;
|
|
160
|
-
apiCost = cc.actualCost;
|
|
161
|
-
}
|
|
178
|
+
const matchedCycle = findMatchingCycle(state.dateRange, _cachedCycleData);
|
|
179
|
+
if (matchedCycle?.tokens) {
|
|
180
|
+
tokIn = matchedCycle.tokens.input; tokOut = matchedCycle.tokens.output;
|
|
181
|
+
tokCR = matchedCycle.tokens.cacheRead; tokCW = matchedCycle.tokens.cacheCreation;
|
|
182
|
+
apiCost = matchedCycle.actualCost;
|
|
162
183
|
}
|
|
163
184
|
const totalAll = tokIn + tokOut + tokCR + tokCW;
|
|
164
185
|
document.getElementById('val-total-tokens').textContent = formatNumber(totalAll);
|