## 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>
59 lines
1.8 KiB
JavaScript
59 lines
1.8 KiB
JavaScript
/**
|
|
* Settings Store
|
|
*/
|
|
document.addEventListener('alpine:init', () => {
|
|
Alpine.store('settings', {
|
|
refreshInterval: 60,
|
|
logLimit: 2000,
|
|
showExhausted: true,
|
|
showHiddenModels: false, // New field
|
|
compact: false,
|
|
port: 8080, // Display only
|
|
|
|
init() {
|
|
this.loadSettings();
|
|
},
|
|
|
|
// Call this method when toggling settings in the UI
|
|
toggle(key) {
|
|
if (this.hasOwnProperty(key) && typeof this[key] === 'boolean') {
|
|
this[key] = !this[key];
|
|
this.saveSettings(true);
|
|
}
|
|
},
|
|
|
|
loadSettings() {
|
|
const saved = localStorage.getItem('antigravity_settings');
|
|
if (saved) {
|
|
const parsed = JSON.parse(saved);
|
|
Object.keys(parsed).forEach(k => {
|
|
// Only load keys that exist in our default state (safety)
|
|
if (this.hasOwnProperty(k)) this[k] = parsed[k];
|
|
});
|
|
}
|
|
},
|
|
|
|
saveSettings(silent = false) {
|
|
const toSave = {
|
|
refreshInterval: this.refreshInterval,
|
|
logLimit: this.logLimit,
|
|
showExhausted: this.showExhausted,
|
|
showHiddenModels: this.showHiddenModels,
|
|
compact: this.compact
|
|
};
|
|
localStorage.setItem('antigravity_settings', JSON.stringify(toSave));
|
|
|
|
if (!silent) {
|
|
const store = Alpine.store('global');
|
|
store.showToast(store.t('configSaved'), 'success');
|
|
}
|
|
|
|
// Trigger updates
|
|
document.dispatchEvent(new CustomEvent('refresh-interval-changed'));
|
|
if (Alpine.store('data')) {
|
|
Alpine.store('data').computeQuotaRows();
|
|
}
|
|
}
|
|
});
|
|
});
|