0d056a45e9
Vue 3 + Vuetify 4 + TypeScript + Vue Router 4 + Pinia frontend, replacing the old Tailwind+Alpine.js static pages. Infrastructure (8 new files): - composables/useSnackbar.ts — centralized notifications - composables/useServerList.ts — server dropdown data - composables/useServerPagination.ts — paginated server table - types/api.ts — 14 typed API response interfaces - types/global.d.ts — Window augmentation - utils/status.ts — server status display helpers - utils/validation.ts — 8 form validation rules - components/MonacoEditor.vue — fullscreen code editor 14 pages rebuilt: - LoginPage, DashboardPage, ServersPage, TerminalPage - FilesPage, PushPage, ScriptsPage, CredentialsPage - SchedulesPage, RetriesPage, CommandsPage - AlertsPage, AuditPage, SettingsPage Critical fixes (from audit): - Files upload JWT auth (was missing Authorization header) - API Key reveal password verification dialog - 6 silent catch blocks → snackbar error feedback - 33 as any → 0 (typed interfaces + global.d.ts) - Dashboard: alerts/summary/categories/audit data loading - WebSocket reconnect timer cleanup + auth failure handling - Terminal ResizeObserver leak fix - PushPage timer cleanup on unmount - FilesPage path double-slash fix (joinPath helper) - Filter changes reset pagination to page 1 Features added: - Servers: batch operations, CSV export/import, detail panel - Push: sync modes, ZIP upload, WebSocket real-time progress, cancel - Scripts: quick execute panel, execution status tracking - Files: Monaco editor, context menu, batch delete, rename, chmod - Terminal: right-click menu, server sidebar, tab persistence - Settings: batch save, TOTP manual key, password TOTP verification - Dashboard: category distribution, recent audit, WS refresh Quality: - vue-tsc --noEmit zero errors - vite build passes (1613 modules) - Formal 8-step security audit passed (0 FINDING) - .gitignore: dist/ → **/dist/ to cover web/app/dist/ Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
36 lines
1014 B
TypeScript
36 lines
1014 B
TypeScript
/**
|
|
* Server status display utilities
|
|
*
|
|
* Extracted from DashboardPage and ServersPage.
|
|
*/
|
|
|
|
/** Vuetify chip color for server status */
|
|
export function statusChipColor(status: string): string {
|
|
switch (status) {
|
|
case 'online': return 'success'
|
|
case 'offline': return 'error'
|
|
default: return 'warning'
|
|
}
|
|
}
|
|
|
|
/** Chinese label for server status */
|
|
export function statusLabel(status: string): string {
|
|
switch (status) {
|
|
case 'online': return '在线'
|
|
case 'offline': return '离线'
|
|
default: return '未知'
|
|
}
|
|
}
|
|
|
|
/** Relative time formatting (Chinese) */
|
|
export function formatRelativeTime(t: string | null): string {
|
|
if (!t) return '—'
|
|
const date = new Date(t)
|
|
if (isNaN(date.getTime())) return '—'
|
|
const diff = Date.now() - date.getTime()
|
|
if (diff < 60000) return '刚刚'
|
|
if (diff < 3600000) return `${Math.floor(diff / 60000)} 分钟前`
|
|
if (diff < 86400000) return `${Math.floor(diff / 3600000)} 小时前`
|
|
return `${Math.floor(diff / 86400000)} 天前`
|
|
}
|