mirror of
https://github.com/netbox-community/netbox.git
synced 2025-08-17 13:08:16 -06:00
Enable HTMX boosting
This commit is contained in:
parent
b3f25a400b
commit
6d06152573
@ -25,6 +25,7 @@ from netbox.views import generic
|
|||||||
from netbox.views.generic.base import BaseObjectView
|
from netbox.views.generic.base import BaseObjectView
|
||||||
from netbox.views.generic.mixins import TableMixin
|
from netbox.views.generic.mixins import TableMixin
|
||||||
from utilities.forms import ConfirmationForm
|
from utilities.forms import ConfirmationForm
|
||||||
|
from utilities.htmx import render_partial
|
||||||
from utilities.utils import count_related
|
from utilities.utils import count_related
|
||||||
from utilities.views import ContentTypePermissionRequiredMixin, register_model_view
|
from utilities.views import ContentTypePermissionRequiredMixin, register_model_view
|
||||||
from . import filtersets, forms, tables
|
from . import filtersets, forms, tables
|
||||||
@ -320,7 +321,7 @@ class BackgroundTaskListView(TableMixin, BaseRQView):
|
|||||||
table = self.get_table(data, request, False)
|
table = self.get_table(data, request, False)
|
||||||
|
|
||||||
# If this is an HTMX request, return only the rendered table HTML
|
# 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', {
|
return render(request, 'htmx/table.html', {
|
||||||
'table': table,
|
'table': table,
|
||||||
})
|
})
|
||||||
@ -489,8 +490,8 @@ class WorkerListView(TableMixin, BaseRQView):
|
|||||||
table = self.get_table(data, request, False)
|
table = self.get_table(data, request, False)
|
||||||
|
|
||||||
# If this is an HTMX request, return only the rendered table HTML
|
# If this is an HTMX request, return only the rendered table HTML
|
||||||
if request.htmx:
|
if render_partial(request):
|
||||||
if request.htmx.target != 'object_list':
|
if not request.htmx.target:
|
||||||
table.embedded = True
|
table.embedded = True
|
||||||
# Hide selection checkboxes
|
# Hide selection checkboxes
|
||||||
if 'pk' in table.base_columns:
|
if 'pk' in table.base_columns:
|
||||||
|
@ -18,6 +18,7 @@ from extras.dashboard.utils import get_widget_class
|
|||||||
from netbox.constants import DEFAULT_ACTION_PERMISSIONS
|
from netbox.constants import DEFAULT_ACTION_PERMISSIONS
|
||||||
from netbox.views import generic
|
from netbox.views import generic
|
||||||
from utilities.forms import ConfirmationForm, get_field_value
|
from utilities.forms import ConfirmationForm, get_field_value
|
||||||
|
from utilities.htmx import render_partial
|
||||||
from utilities.paginator import EnhancedPaginator, get_paginate_count
|
from utilities.paginator import EnhancedPaginator, get_paginate_count
|
||||||
from utilities.rqworker import get_workers_for_queue
|
from utilities.rqworker import get_workers_for_queue
|
||||||
from utilities.templatetags.builtins.filters import render_markdown
|
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 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)
|
response = render(request, 'extras/htmx/script_result.html', context)
|
||||||
if job.completed or not job.started:
|
if job.completed or not job.started:
|
||||||
response.status_code = 286
|
response.status_code = 286
|
||||||
|
@ -22,6 +22,7 @@ from utilities.error_handlers import handle_protectederror
|
|||||||
from utilities.exceptions import AbortRequest, AbortTransaction, PermissionsViolation
|
from utilities.exceptions import AbortRequest, AbortTransaction, PermissionsViolation
|
||||||
from utilities.forms import BulkRenameForm, ConfirmationForm, restrict_form_fields
|
from utilities.forms import BulkRenameForm, ConfirmationForm, restrict_form_fields
|
||||||
from utilities.forms.bulk_import import BulkImportForm
|
from utilities.forms.bulk_import import BulkImportForm
|
||||||
|
from utilities.htmx import render_partial
|
||||||
from utilities.permissions import get_permission_for_model
|
from utilities.permissions import get_permission_for_model
|
||||||
from utilities.utils import get_viewname
|
from utilities.utils import get_viewname
|
||||||
from utilities.views import GetReturnURLMixin
|
from utilities.views import GetReturnURLMixin
|
||||||
@ -161,8 +162,8 @@ class ObjectListView(BaseMultiObjectView, ActionsMixin, TableMixin):
|
|||||||
table = self.get_table(self.queryset, request, has_bulk_actions)
|
table = self.get_table(self.queryset, request, has_bulk_actions)
|
||||||
|
|
||||||
# If this is an HTMX request, return only the rendered table HTML
|
# If this is an HTMX request, return only the rendered table HTML
|
||||||
if request.htmx:
|
if render_partial(request):
|
||||||
if request.htmx.target != 'object_list':
|
if not request.htmx.target:
|
||||||
table.embedded = True
|
table.embedded = True
|
||||||
# Hide selection checkboxes
|
# Hide selection checkboxes
|
||||||
if 'pk' in table.base_columns:
|
if 'pk' in table.base_columns:
|
||||||
|
@ -16,6 +16,7 @@ from extras.signals import clear_events
|
|||||||
from utilities.error_handlers import handle_protectederror
|
from utilities.error_handlers import handle_protectederror
|
||||||
from utilities.exceptions import AbortRequest, PermissionsViolation
|
from utilities.exceptions import AbortRequest, PermissionsViolation
|
||||||
from utilities.forms import ConfirmationForm, restrict_form_fields
|
from utilities.forms import ConfirmationForm, restrict_form_fields
|
||||||
|
from utilities.htmx import render_partial
|
||||||
from utilities.permissions import get_permission_for_model
|
from utilities.permissions import get_permission_for_model
|
||||||
from utilities.utils import get_viewname, normalize_querydict, prepare_cloned_fields
|
from utilities.utils import get_viewname, normalize_querydict, prepare_cloned_fields
|
||||||
from utilities.views import GetReturnURLMixin
|
from utilities.views import GetReturnURLMixin
|
||||||
@ -135,7 +136,7 @@ class ObjectChildrenView(ObjectView, ActionsMixin, TableMixin):
|
|||||||
table = self.get_table(table_data, request, has_bulk_actions)
|
table = self.get_table(table_data, request, has_bulk_actions)
|
||||||
|
|
||||||
# If this is an HTMX request, return only the rendered table HTML
|
# 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', {
|
return render(request, 'htmx/table.html', {
|
||||||
'object': instance,
|
'object': instance,
|
||||||
'table': table,
|
'table': table,
|
||||||
@ -223,7 +224,7 @@ class ObjectEditView(GetReturnURLMixin, BaseObjectView):
|
|||||||
restrict_form_fields(form, request.user)
|
restrict_form_fields(form, request.user)
|
||||||
|
|
||||||
# If this is an HTMX request, return only the rendered form HTML
|
# 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', {
|
return render(request, 'htmx/form.html', {
|
||||||
'form': form,
|
'form': form,
|
||||||
})
|
})
|
||||||
@ -479,7 +480,7 @@ class ComponentCreateView(GetReturnURLMixin, BaseObjectView):
|
|||||||
instance = self.alter_object(self.queryset.model(), request)
|
instance = self.alter_object(self.queryset.model(), request)
|
||||||
|
|
||||||
# If this is an HTMX request, return only the rendered form HTML
|
# 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', {
|
return render(request, 'htmx/form.html', {
|
||||||
'form': form,
|
'form': form,
|
||||||
})
|
})
|
||||||
|
@ -17,6 +17,7 @@ from netbox.forms import SearchForm
|
|||||||
from netbox.search import LookupTypes
|
from netbox.search import LookupTypes
|
||||||
from netbox.search.backends import search_backend
|
from netbox.search.backends import search_backend
|
||||||
from netbox.tables import SearchTable
|
from netbox.tables import SearchTable
|
||||||
|
from utilities.htmx import render_partial
|
||||||
from utilities.paginator import EnhancedPaginator, get_paginate_count
|
from utilities.paginator import EnhancedPaginator, get_paginate_count
|
||||||
|
|
||||||
__all__ = (
|
__all__ = (
|
||||||
@ -104,7 +105,7 @@ class SearchView(View):
|
|||||||
}).configure(table)
|
}).configure(table)
|
||||||
|
|
||||||
# If this is an HTMX request, return only the rendered table HTML
|
# 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', {
|
return render(request, 'htmx/table.html', {
|
||||||
'table': table,
|
'table': table,
|
||||||
})
|
})
|
||||||
|
@ -79,6 +79,7 @@ Blocks:
|
|||||||
|
|
||||||
{# Page content #}
|
{# Page content #}
|
||||||
<div class="page-wrapper">
|
<div class="page-wrapper">
|
||||||
|
<div id="page-content" hx-boost="true" hx-target="#page-content" hx-select="#page-content" hx-swap="outerHTML">
|
||||||
|
|
||||||
{# Page header #}
|
{# Page header #}
|
||||||
{% block header %}
|
{% block header %}
|
||||||
@ -122,6 +123,8 @@ Blocks:
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
{# /Bottom banner #}
|
{# /Bottom banner #}
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
{# Page footer #}
|
{# Page footer #}
|
||||||
<footer class="footer footer-transparent d-print-none py-2">
|
<footer class="footer footer-transparent d-print-none py-2">
|
||||||
<div class="container-xl d-flex justify-content-between align-items-center">
|
<div class="container-xl d-flex justify-content-between align-items-center">
|
||||||
|
12
netbox/utilities/htmx.py
Normal file
12
netbox/utilities/htmx.py
Normal 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
|
@ -1,4 +1,5 @@
|
|||||||
<div class="card-body htmx-container table-responsive p-0"
|
<div class="card-body htmx-container table-responsive p-0"
|
||||||
hx-get="{% url viewname %}{% if url_params %}?{{ url_params.urlencode }}{% endif %}"
|
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>
|
></div>
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{% load helpers %}
|
{% 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 %}
|
{% for menu, groups in nav_items %}
|
||||||
<li class="nav-item dropdown">
|
<li class="nav-item dropdown">
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user