ui: Use HTMX to eliminate full page reloads

HTMX implementation is limited to HTML and JS files. No changes to Python files.

Signed-off-by: Joseph Nuthalapati <njoseph@riseup.net>
This commit is contained in:
Joseph Nuthalapati 2026-01-04 20:21:13 +05:30 committed by Sunil Mohan Adapa
parent 3c5f81ab8c
commit 01cafafcda
No known key found for this signature in database
GPG Key ID: 43EA1CFF0AA7C5F2
3 changed files with 24 additions and 29 deletions

View File

@ -252,7 +252,11 @@
</div>
{% block container %}
<div class="container content-container">
<div id="content-block" class="container content-container"
{% if refresh_page_sec %}
hx-get="." hx-trigger="load delay:{{ refresh_page_sec }}s"
hx-select="#content-block" hx-target="#content-block" hx-swap="outerHTML"
{% endif %}>
{% block content_row %}
{% include 'messages.html' %}

View File

@ -497,9 +497,8 @@ class AppOperationsView(TemplateView):
context['app_id'] = self.app.app_id
context['app_info'] = self.app.info
context['operations'] = operation.manager.filter(self.app.app_id)
context['refresh_page_sec'] = 0
if context['operations']:
context['refresh_page_sec'] = 3
# Refresh periodically while operations are running
context['refresh_page_sec'] = 3 if context['operations'] else 0
return context
@ -532,10 +531,10 @@ class SetupView(TemplateView):
!= app_module.App.SetupState.NEEDS_SETUP)
context['refresh_page_sec'] = None
if context['setup_state'] == app_module.App.SetupState.UP_TO_DATE:
context['refresh_page_sec'] = 0
elif context['operations']:
if context['operations']:
context['refresh_page_sec'] = 3
elif context['setup_state'] == app_module.App.SetupState.UP_TO_DATE:
context['refresh_page_sec'] = 0
return context
@ -550,10 +549,7 @@ class SetupView(TemplateView):
# Give a moment for the setup process to start and show
# meaningful status.
time.sleep(1)
response = self.render_to_response(self.get_context_data())
# Post/Response/Get pattern for reloads
response.status_code = 303
return response
return redirect(request.path)
return super().dispatch(request, *args, **kwargs)

View File

@ -33,24 +33,6 @@ document.addEventListener('DOMContentLoaded', function (event) {
html.classList.add('js');
});
/*
* Refresh page if marked for refresh.
*/
document.addEventListener('DOMContentLoaded', function () {
const body = document.querySelector('body');
if (body.hasAttribute('data-refresh-page-sec')) {
let seconds = body.getAttribute('data-refresh-page-sec');
seconds = parseInt(seconds, 10);
if (isNaN(seconds))
return;
window.setTimeout(() => {
// Refresh the page without resubmitting the POST data.
window.location = window.location.href;
}, seconds * 1000);
}
});
/*
* Return all submit buttons on the page
*/
@ -303,3 +285,16 @@ document.addEventListener('click', function (event) {
bsCollapse.hide();
}
});
/*
* Detect when hx-select element is not found in the response and reload the
* page. HTMX unfortunately does not seem to provide a JS event when hx-select
* element is not found in the response. However, in htmx:afterSwap event we can
* see that the target has no children and choose to refresh the whole page.
*/
document.addEventListener('htmx:afterSwap', function (event) {
const target = event.detail.target;
if (target && target.children.length === 0) {
window.location.reload();
}
});