mirror of
https://github.com/ChuckBuilds/LEDMatrix.git
synced 2026-06-02 16:53:31 +00:00
fix(web): repair array-table.js syntax error and version static assets (#357)
Two issues left the v3 web UI's Overview (and other Alpine-driven tabs) blank: 1. array-table.js had two safeSetHTML(target, `...`) calls that closed the template-literal argument with `; instead of `); — a SyntaxError that aborts the script and halts widget registration / Alpine initialization. 2. Static assets are served `Cache-Control: public, max-age=31536000, immutable` but were referenced without a cache-busting version (the header comment assumed "versioning via query params", which was only ever applied by hand to app.css). So edited JS/CSS never reached browsers — including fix #1. Add a Flask url_defaults hook that appends each static file's mtime as a ?v= param to every url_for('static', ...), so changed files get a new URL and are refetched while unchanged files keep the long immutable cache. Drop the now redundant manual ?v= on app.css. Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -391,6 +391,22 @@ def captive_portal_redirect():
|
|||||||
# Redirect to lightweight captive portal setup page (not the full UI)
|
# Redirect to lightweight captive portal setup page (not the full UI)
|
||||||
return redirect(url_for('pages_v3.captive_setup'), code=302)
|
return redirect(url_for('pages_v3.captive_setup'), code=302)
|
||||||
|
|
||||||
|
# Append a content-version query param (file mtime) to every static URL so the
|
||||||
|
# long-lived `immutable` cache (see add_security_headers below) is actually safe:
|
||||||
|
# when a static file changes its URL changes, so browsers refetch it. Without
|
||||||
|
# this, edited JS/CSS were served immutable under an unchanging URL and never
|
||||||
|
# reached clients until a manual cache clear.
|
||||||
|
@app.url_defaults
|
||||||
|
def add_static_version(endpoint, values):
|
||||||
|
if endpoint == 'static' and values.get('filename'):
|
||||||
|
try:
|
||||||
|
file_path = os.path.join(app.static_folder, values['filename'])
|
||||||
|
values['v'] = int(os.path.getmtime(file_path))
|
||||||
|
except OSError:
|
||||||
|
# File missing (e.g. plugin asset not yet installed) — skip versioning.
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
# Add security headers and caching to all responses
|
# Add security headers and caching to all responses
|
||||||
@app.after_request
|
@app.after_request
|
||||||
def add_security_headers(response):
|
def add_security_headers(response):
|
||||||
|
|||||||
@@ -440,7 +440,7 @@
|
|||||||
<h3 class="text-base font-semibold text-gray-900">Advanced Properties</h3>
|
<h3 class="text-base font-semibold text-gray-900">Advanced Properties</h3>
|
||||||
<button type="button" onclick="window.closeArrayTableRowEditor()"
|
<button type="button" onclick="window.closeArrayTableRowEditor()"
|
||||||
class="text-gray-400 hover:text-gray-600"><i class="fas fa-times"></i></button>
|
class="text-gray-400 hover:text-gray-600"><i class="fas fa-times"></i></button>
|
||||||
</div>`;
|
</div>`);
|
||||||
|
|
||||||
const body = document.createElement('div');
|
const body = document.createElement('div');
|
||||||
body.className = 'px-5 py-4 space-y-4';
|
body.className = 'px-5 py-4 space-y-4';
|
||||||
@@ -512,7 +512,7 @@
|
|||||||
<button type="button" onclick="window.closeArrayTableRowEditor()"
|
<button type="button" onclick="window.closeArrayTableRowEditor()"
|
||||||
class="px-4 py-2 text-sm text-gray-700 border border-gray-300 rounded-md hover:bg-gray-100">Cancel</button>
|
class="px-4 py-2 text-sm text-gray-700 border border-gray-300 rounded-md hover:bg-gray-100">Cancel</button>
|
||||||
<button type="button" id="array-row-editor-save"
|
<button type="button" id="array-row-editor-save"
|
||||||
class="px-4 py-2 text-sm bg-blue-600 hover:bg-blue-700 text-white rounded-md">Save</button>`;
|
class="px-4 py-2 text-sm bg-blue-600 hover:bg-blue-700 text-white rounded-md">Save</button>`);
|
||||||
|
|
||||||
// Save handler
|
// Save handler
|
||||||
footer.querySelector('#array-row-editor-save').onclick = function() {
|
footer.querySelector('#array-row-editor-save').onclick = function() {
|
||||||
|
|||||||
@@ -867,7 +867,7 @@
|
|||||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css">
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css">
|
||||||
|
|
||||||
<!-- Custom v3 styles -->
|
<!-- Custom v3 styles -->
|
||||||
<link rel="stylesheet" href="{{ url_for('static', filename='v3/app.css') }}?v=20260216b">
|
<link rel="stylesheet" href="{{ url_for('static', filename='v3/app.css') }}">
|
||||||
</head>
|
</head>
|
||||||
<body x-data="app()" class="bg-gray-50 min-h-screen">
|
<body x-data="app()" class="bg-gray-50 min-h-screen">
|
||||||
<!-- Header -->
|
<!-- Header -->
|
||||||
|
|||||||
Reference in New Issue
Block a user