Files
antigravity-claude-proxy/public/views/accounts.html
Wha1eChai 217053839f feat(webui): Enhance dashboard, global styles, and settings module
## Dashboard Enhancements
- Add Request Volume trend chart with Chart.js line graph
  - Support Family/Model display modes for aggregation levels
  - Show Total/Today/1H usage statistics
  - Hierarchical filter dropdown with Smart select (Top 5 by 24h usage)
  - Persist chart preferences to localStorage
- Improve account health detection logic
  - Core models (sonnet/opus/pro/flash) require >5% quota to be healthy
  - Dynamic quota ring chart supporting any model family
- Unify table styles with standard-table class

## Global Style Refactoring
- Add CSS variable system for theming
  - Space color scale (950/900/850/800/border)
  - Neon accent colors (purple/green/cyan/yellow/red)
  - Text hierarchy (main/dim/muted/bright)
  - Chart palette (16 colors)
- Add unified component classes
  - .view-container for consistent page layouts
  - .section-header/.section-title/.section-desc
  - .standard-table for table styling
- Update scrollbar, nav-item, progress-bar to use theme variables

## Settings Module Extensions
- Add model mapping column in Models tab
- Enhance model selectors with family color indicators
- Support horizontal scroll for tabs on narrow screens
- Add defaultCooldownMs and maxWaitBeforeErrorMs config options

## New Module
- Add src/modules/usage-stats.js for request tracking
  - Track /v1/messages and /v1/chat/completions endpoints
  - Hierarchical storage: { hour: { family: { model: count } } }
  - Auto-save every minute, 30-day retention
  - GET /api/stats/history endpoint for dashboard chart

## Backend Changes
- Add direct account manipulation helpers (bypass AccountManager)
- Add POST /api/config/password endpoint for WebUI password change
- Auto-reload AccountManager after account operations
- Use CSS variables in OAuth callback pages

## Other
- Update .gitignore for runtime data directory
- Add i18n keys for new UI elements (EN/zh_CN)

Co-Authored-By: Claude <noreply@anthropic.com>
2026-01-08 19:04:43 +08:00

78 lines
4.6 KiB
HTML

<div x-data="accountManager" class="view-container">
<div class="section-header">
<div>
<h2 class="section-title" x-text="$store.global.t('accessCredentials')">
Access Credentials
</h2>
<p class="section-desc" x-text="$store.global.t('manageTokens')">
Manage OAuth tokens and session states
</p>
</div>
<button class="btn btn-primary btn-sm gap-2"
onclick="document.getElementById('add_account_modal').showModal()">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 4v16m8-8H4" />
</svg>
<span x-text="$store.global.t('addNode')">Add Node</span>
</button>
</div>
<div class="glass-panel rounded-xl overflow-hidden">
<table class="standard-table">
<thead>
<tr>
<th class="pl-6 w-24" x-text="$store.global.t('enabled')">Enabled</th>
<th x-text="$store.global.t('identity')">Identity (Email)</th>
<th x-text="$store.global.t('projectId')">Project ID</th>
<th class="w-32" x-text="$store.global.t('health')">Health</th>
<th class="text-right pr-6" x-text="$store.global.t('operations')">Operations</th>
</tr>
</thead>
<tbody>
<template x-for="acc in $store.data.accounts" :key="acc.email">
<tr>
<td class="pl-6">
<input type="checkbox"
class="toggle toggle-success toggle-sm"
:checked="acc.enabled !== false"
@change="toggleAccount(acc.email, $el.checked)">
</td>
<td class="font-medium text-gray-200" x-text="acc.email"></td>
<td class="font-mono text-xs text-gray-400" x-text="acc.projectId || '-'"></td>
<td>
<span class="badge badge-sm border-0 font-mono"
:class="acc.status === 'ok' ? 'bg-neon-green/10 text-neon-green' : 'bg-red-500/10 text-red-500'"
x-text="acc.status.toUpperCase()"></span>
</td>
<td class="text-right pr-6">
<div class="flex justify-end gap-1">
<!-- Fix Button -->
<button x-show="acc.status === 'invalid'"
class="btn btn-xs bg-yellow-500/10 text-yellow-500 hover:bg-yellow-500/20 border-none mr-1 px-2 font-mono"
@click="fixAccount(acc.email)"
x-text="$store.global.t('fix')">
FIX
</button>
<button class="btn btn-xs btn-square btn-ghost text-gray-400 hover:text-white"
@click="refreshAccount(acc.email)" :title="$store.global.t('refreshData')">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15" />
</svg>
</button>
<button
class="btn btn-xs btn-square btn-ghost text-red-400 hover:text-red-500 hover:bg-red-500/10"
@click="deleteAccount(acc.email)" :title="$store.global.t('delete')">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" />
</svg>
</button>
</div>
</td>
</tr>
</template>
</tbody>
</table>
</div>
</div>