diff --git a/web_interface/app.py b/web_interface/app.py index f8ffcbd3..d4d4c20f 100644 --- a/web_interface/app.py +++ b/web_interface/app.py @@ -391,6 +391,22 @@ def captive_portal_redirect(): # Redirect to lightweight captive portal setup page (not the full UI) 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 @app.after_request def add_security_headers(response): diff --git a/web_interface/static/v3/js/widgets/array-table.js b/web_interface/static/v3/js/widgets/array-table.js index 20078fa2..77e82edf 100644 --- a/web_interface/static/v3/js/widgets/array-table.js +++ b/web_interface/static/v3/js/widgets/array-table.js @@ -440,7 +440,7 @@

Advanced Properties

- `; + `); const body = document.createElement('div'); body.className = 'px-5 py-4 space-y-4'; @@ -512,7 +512,7 @@ `; + class="px-4 py-2 text-sm bg-blue-600 hover:bg-blue-700 text-white rounded-md">Save`); // Save handler footer.querySelector('#array-row-editor-save').onclick = function() { diff --git a/web_interface/templates/v3/base.html b/web_interface/templates/v3/base.html index 922dab42..841ed4c6 100644 --- a/web_interface/templates/v3/base.html +++ b/web_interface/templates/v3/base.html @@ -867,7 +867,7 @@ - +