Migrate frontend from monolithic app.js to vanilla ES modules
Build and Push Docker Image / build (push) Successful in 35s
Licence Check / Licence compatibility and copyright header verification (push) Failing after 49s
CI / Security audit (push) Successful in 1m9s
CI / Tests & coverage (push) Successful in 1m23s

- Delete React files (App.jsx, main.jsx, App.css)
- Create modular vanilla JS structure in client/src/:
  - state.js (global state object)
  - api.js (all fetch calls)
  - sse.js (SSE connection management)
  - ui/auth.js (authentication UI)
  - ui/downloads.js (downloads rendering)
  - ui/history.js (history section)
  - ui/statusPanel.js (status panel)
  - ui/webhooks.js (webhook management)
  - ui/filters.js (download client filter)
  - ui/theme.js (theme switching)
  - ui/tabs.js (tab navigation)
  - utils/format.js (formatting utilities)
  - utils/storage.js (localStorage helpers)
  - main.js (DOMContentLoaded bootstrap)
- Update vite.config.js for vanilla build outputting to ../public/app.js
- Build succeeds: 14 modules, 43.88 kB output
This commit is contained in:
2026-05-20 23:30:24 +01:00
parent a38fc4a8ce
commit 8dc105ff3e
19 changed files with 2173 additions and 2854 deletions
+38
View File
@@ -0,0 +1,38 @@
// Copyright (c) 2026 Gordon Bolton. MIT License.
// Global state (using objects for mutability across modules)
export const state = {
currentUser: null,
downloads: [],
downloadClients: [], // List of download clients from server (for ordering/filtering)
selectedDownloadClients: [], // Array of selected client IDs for multi-select filter
isAdmin: false,
showAll: false,
csrfToken: null, // double-submit CSRF token, sent as X-CSRF-Token on mutating requests
// History section state
historyDays: 7, // Default value, will be loaded from localStorage
historyRefreshHandle: null,
ignoreAvailable: false, // Default value, will be loaded from localStorage
lastHistoryItems: [], // raw items from last fetch, for re-filtering without a network round-trip
// SSE stream state
sseSource: null,
sseReconnectTimer: null,
// Status panel state
statusRefreshHandle: null,
// Webhooks state
webhookSectionExpanded: false,
webhookLoading: false,
sonarrWebhook: { enabled: false, triggers: { onGrab: false, onDownload: false, onImport: false, onUpgrade: false }, stats: null },
radarrWebhook: { enabled: false, triggers: { onGrab: false, onDownload: false, onImport: false, onUpgrade: false }, stats: null },
webhookMetrics: null
};
// Constants
export const SPLASH_MIN_MS = 1200; // minimum splash display time
export const HISTORY_REFRESH_MS = 5 * 60 * 1000; // auto-refresh history every 5 min
export const SSE_RECONNECT_MS = 3000; // browser already retries, but we add explicit backoff too
export const STATUS_REFRESH_MS = 5000;