zozul-cli 0.2.5 → 0.3.1

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.
@@ -454,6 +454,7 @@
454
454
  <div class="container">
455
455
  <!-- Summary View -->
456
456
  <div id="view-summary" class="view active">
457
+ <div class="time-selector"></div>
457
458
  <div class="stats-grid" id="summary-stats"></div>
458
459
  <div class="chart-card"><h3>Daily Cost (30d)</h3><canvas id="chart-daily-cost"></canvas></div>
459
460
  <div class="panel">
@@ -524,6 +525,7 @@
524
525
 
525
526
  <!-- Task View -->
526
527
  <div id="view-tasks" class="view">
528
+ <div class="time-selector"></div>
527
529
  <div class="panel">
528
530
  <div class="panel-header">
529
531
  <span>Tasks</span>
@@ -544,6 +546,7 @@
544
546
 
545
547
  <!-- Tag View -->
546
548
  <div id="view-tags" class="view">
549
+ <div class="time-selector"></div>
547
550
  <div class="panel">
548
551
  <div class="panel-header">
549
552
  <span>Tags</span>
@@ -824,6 +827,15 @@ function timeQueryString() {
824
827
  return 'from=' + encodeURIComponent(from) + '&to=' + encodeURIComponent(now.toISOString());
825
828
  }
826
829
 
830
+ function renderTimeSelectors() {
831
+ document.querySelectorAll('.time-selector').forEach(el => {
832
+ el.innerHTML = ['7d', '30d', 'all'].map(w =>
833
+ '<button class="time-btn' + (w === currentTimeWindow ? ' active' : '') + '" data-window="' + w + '">' +
834
+ (w === 'all' ? 'All' : w) + '</button>'
835
+ ).join('');
836
+ });
837
+ }
838
+
827
839
  // ── Navigation ──
828
840
 
829
841
  function showView(name) {
@@ -860,6 +872,14 @@ document.addEventListener('keydown', e => {
860
872
  });
861
873
 
862
874
  document.addEventListener('click', e => {
875
+ const timeBtn = e.target.closest('.time-btn');
876
+ if (timeBtn) {
877
+ currentTimeWindow = timeBtn.dataset.window;
878
+ renderTimeSelectors();
879
+ loadViewData(currentView);
880
+ return;
881
+ }
882
+
863
883
  const th = e.target.closest('th.sortable');
864
884
  if (th) {
865
885
  const [table, key] = th.dataset.sort.split(':');
@@ -902,11 +922,14 @@ function sortData(arr, state) {
902
922
 
903
923
  async function loadSummary() {
904
924
  try {
925
+ const timeQs = timeQueryString();
926
+ const timeParam = timeQs ? '?' + timeQs : '';
927
+ const timeSep = timeQs ? '&' + timeQs : '';
905
928
  const [stats, tasks, costSeries, sessionsResp] = await Promise.all([
906
- fetchJson('/api/stats'),
929
+ fetchJson('/api/stats' + timeParam),
907
930
  fetchJson('/api/tasks'),
908
931
  fetchJson('/api/metrics/cost?range=' + (currentTimeWindow === 'all' ? '90d' : currentTimeWindow) + '&step=1d'),
909
- fetchJson('/api/sessions?limit=500&offset=0'),
932
+ fetchJson('/api/sessions?limit=500&offset=0' + timeSep),
910
933
  ]);
911
934
  renderSummaryStats({
912
935
  totalCost: stats.total_cost_usd ?? 0,
@@ -1688,6 +1711,7 @@ function scheduleAutoRefresh() {
1688
1711
 
1689
1712
  // ── Init ──
1690
1713
 
1714
+ renderTimeSelectors();
1691
1715
  detectDataSource().then(() => {
1692
1716
  checkTeamAccess();
1693
1717
  return loadDashboard();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zozul-cli",
3
- "version": "0.2.5",
3
+ "version": "0.3.1",
4
4
  "description": "Observability for Claude Code — track token usage, costs, turns, and conversation history",
5
5
  "readmeFilename": "README.md",
6
6
  "type": "module",
@@ -454,6 +454,7 @@
454
454
  <div class="container">
455
455
  <!-- Summary View -->
456
456
  <div id="view-summary" class="view active">
457
+ <div class="time-selector"></div>
457
458
  <div class="stats-grid" id="summary-stats"></div>
458
459
  <div class="chart-card"><h3>Daily Cost (30d)</h3><canvas id="chart-daily-cost"></canvas></div>
459
460
  <div class="panel">
@@ -524,6 +525,7 @@
524
525
 
525
526
  <!-- Task View -->
526
527
  <div id="view-tasks" class="view">
528
+ <div class="time-selector"></div>
527
529
  <div class="panel">
528
530
  <div class="panel-header">
529
531
  <span>Tasks</span>
@@ -544,6 +546,7 @@
544
546
 
545
547
  <!-- Tag View -->
546
548
  <div id="view-tags" class="view">
549
+ <div class="time-selector"></div>
547
550
  <div class="panel">
548
551
  <div class="panel-header">
549
552
  <span>Tags</span>
@@ -824,6 +827,15 @@ function timeQueryString() {
824
827
  return 'from=' + encodeURIComponent(from) + '&to=' + encodeURIComponent(now.toISOString());
825
828
  }
826
829
 
830
+ function renderTimeSelectors() {
831
+ document.querySelectorAll('.time-selector').forEach(el => {
832
+ el.innerHTML = ['7d', '30d', 'all'].map(w =>
833
+ '<button class="time-btn' + (w === currentTimeWindow ? ' active' : '') + '" data-window="' + w + '">' +
834
+ (w === 'all' ? 'All' : w) + '</button>'
835
+ ).join('');
836
+ });
837
+ }
838
+
827
839
  // ── Navigation ──
828
840
 
829
841
  function showView(name) {
@@ -860,6 +872,14 @@ document.addEventListener('keydown', e => {
860
872
  });
861
873
 
862
874
  document.addEventListener('click', e => {
875
+ const timeBtn = e.target.closest('.time-btn');
876
+ if (timeBtn) {
877
+ currentTimeWindow = timeBtn.dataset.window;
878
+ renderTimeSelectors();
879
+ loadViewData(currentView);
880
+ return;
881
+ }
882
+
863
883
  const th = e.target.closest('th.sortable');
864
884
  if (th) {
865
885
  const [table, key] = th.dataset.sort.split(':');
@@ -902,11 +922,14 @@ function sortData(arr, state) {
902
922
 
903
923
  async function loadSummary() {
904
924
  try {
925
+ const timeQs = timeQueryString();
926
+ const timeParam = timeQs ? '?' + timeQs : '';
927
+ const timeSep = timeQs ? '&' + timeQs : '';
905
928
  const [stats, tasks, costSeries, sessionsResp] = await Promise.all([
906
- fetchJson('/api/stats'),
929
+ fetchJson('/api/stats' + timeParam),
907
930
  fetchJson('/api/tasks'),
908
931
  fetchJson('/api/metrics/cost?range=' + (currentTimeWindow === 'all' ? '90d' : currentTimeWindow) + '&step=1d'),
909
- fetchJson('/api/sessions?limit=500&offset=0'),
932
+ fetchJson('/api/sessions?limit=500&offset=0' + timeSep),
910
933
  ]);
911
934
  renderSummaryStats({
912
935
  totalCost: stats.total_cost_usd ?? 0,
@@ -1688,6 +1711,7 @@ function scheduleAutoRefresh() {
1688
1711
 
1689
1712
  // ── Init ──
1690
1713
 
1714
+ renderTimeSelectors();
1691
1715
  detectDataSource().then(() => {
1692
1716
  checkTeamAccess();
1693
1717
  return loadDashboard();