Enable HTMX boosting

This commit is contained in:
Jeremy Stretch 2024-02-01 19:58:59 -05:00
parent b3f25a400b
commit 6d06152573
9 changed files with 33 additions and 12 deletions

View File

@ -25,6 +25,7 @@ from netbox.views import generic
from netbox.views.generic.base import BaseObjectView
from netbox.views.generic.mixins import TableMixin
from utilities.forms import ConfirmationForm
from utilities.htmx import render_partial
from utilities.utils import count_related
from utilities.views import ContentTypePermissionRequiredMixin, register_model_view
from . import filtersets, forms, tables
@ -320,7 +321,7 @@ class BackgroundTaskListView(TableMixin, BaseRQView):
table = self.get_table(data, request, False)
# If this is an HTMX request, return only the rendered table HTML
if request.htmx:
if render_partial(request):
return render(request, 'htmx/table.html', {
'table': table,
})
@ -489,8 +490,8 @@ class WorkerListView(TableMixin, BaseRQView):
table = self.get_table(data, request, False)
# If this is an HTMX request, return only the rendered table HTML
if request.htmx:
if request.htmx.target != 'object_list':
if render_partial(request):
if not request.htmx.target:
table.embedded = True
# Hide selection checkboxes
if 'pk' in table.base_columns:

View File

@ -18,6 +18,7 @@ from extras.dashboard.utils import get_widget_class
from netbox.constants import DEFAULT_ACTION_PERMISSIONS
from netbox.views import generic
from utilities.forms import ConfirmationForm, get_field_value
from utilities.htmx import render_partial
from utilities.paginator import EnhancedPaginator, get_paginate_count
from utilities.rqworker import get_workers_for_queue
from utilities.templatetags.builtins.filters import render_markdown
@ -1168,7 +1169,7 @@ class ScriptResultView(ContentTypePermissionRequiredMixin, View):
}
# If this is an HTMX request, return only the result HTML
if request.htmx:
if render_partial(request):
response = render(request, 'extras/htmx/script_result.html', context)
if job.completed or not job.started:
response.status_code = 286

View File

@ -22,6 +22,7 @@ from utilities.error_handlers import handle_protectederror
from utilities.exceptions import AbortRequest, AbortTransaction, PermissionsViolation
from utilities.forms import BulkRenameForm, ConfirmationForm, restrict_form_fields
from utilities.forms.bulk_import import BulkImportForm
from utilities.htmx import render_partial
from utilities.permissions import get_permission_for_model
from utilities.utils import get_viewname
from utilities.views import GetReturnURLMixin
@ -161,8 +162,8 @@ class ObjectListView(BaseMultiObjectView, ActionsMixin, TableMixin):
table = self.get_table(self.queryset, request, has_bulk_actions)
# If this is an HTMX request, return only the rendered table HTML
if request.htmx:
if request.htmx.target != 'object_list':
if render_partial(request):
if not request.htmx.target:
table.embedded = True
# Hide selection checkboxes
if 'pk' in table.base_columns:

View File

@ -16,6 +16,7 @@ from extras.signals import clear_events
from utilities.error_handlers import handle_protectederror
from utilities.exceptions import AbortRequest, PermissionsViolation
from utilities.forms import ConfirmationForm, restrict_form_fields
from utilities.htmx import render_partial
from utilities.permissions import get_permission_for_model
from utilities.utils import get_viewname, normalize_querydict, prepare_cloned_fields
from utilities.views import GetReturnURLMixin
@ -135,7 +136,7 @@ class ObjectChildrenView(ObjectView, ActionsMixin, TableMixin):
table = self.get_table(table_data, request, has_bulk_actions)
# If this is an HTMX request, return only the rendered table HTML
if request.htmx:
if render_partial(request):
return render(request, 'htmx/table.html', {
'object': instance,
'table': table,
@ -223,7 +224,7 @@ class ObjectEditView(GetReturnURLMixin, BaseObjectView):
restrict_form_fields(form, request.user)
# If this is an HTMX request, return only the rendered form HTML
if request.htmx:
if render_partial(request):
return render(request, 'htmx/form.html', {
'form': form,
})
@ -479,7 +480,7 @@ class ComponentCreateView(GetReturnURLMixin, BaseObjectView):
instance = self.alter_object(self.queryset.model(), request)
# If this is an HTMX request, return only the rendered form HTML
if request.htmx:
if render_partial(request):
return render(request, 'htmx/form.html', {
'form': form,
})

View File

@ -17,6 +17,7 @@ from netbox.forms import SearchForm
from netbox.search import LookupTypes
from netbox.search.backends import search_backend
from netbox.tables import SearchTable
from utilities.htmx import render_partial
from utilities.paginator import EnhancedPaginator, get_paginate_count
__all__ = (
@ -104,7 +105,7 @@ class SearchView(View):
}).configure(table)
# If this is an HTMX request, return only the rendered table HTML
if request.htmx:
if render_partial(request):
return render(request, 'htmx/table.html', {
'table': table,
})

View File

@ -79,6 +79,7 @@ Blocks:
{# Page content #}
<div class="page-wrapper">
<div id="page-content" hx-boost="true" hx-target="#page-content" hx-select="#page-content" hx-swap="outerHTML">
{# Page header #}
{% block header %}
@ -122,6 +123,8 @@ Blocks:
{% endif %}
{# /Bottom banner #}
</div>
{# Page footer #}
<footer class="footer footer-transparent d-print-none py-2">
<div class="container-xl d-flex justify-content-between align-items-center">

12
netbox/utilities/htmx.py Normal file
View File

@ -0,0 +1,12 @@
__all__ = (
'render_partial',
)
PAGE_CONTAINER_ID = 'page-content'
def render_partial(request):
"""
Determines whether to render a partial response.
"""
return request.htmx and request.htmx.target != PAGE_CONTAINER_ID

View File

@ -1,4 +1,5 @@
<div class="card-body htmx-container table-responsive p-0"
hx-get="{% url viewname %}{% if url_params %}?{{ url_params.urlencode }}{% endif %}"
hx-trigger="load"
hx-target="this"
hx-trigger="load" hx-select="table" hx-swap="innerHTML"
></div>

View File

@ -1,6 +1,6 @@
{% load helpers %}
<ul class="navbar-nav pt-lg-2">
<ul class="navbar-nav pt-lg-2" hx-boost="true" hx-target="#page-content" hx-select="#page-content" hx-swap="innerHTML">
{% for menu, groups in nav_items %}
<li class="nav-item dropdown">