mirror of
https://github.com/netbox-community/netbox.git
synced 2025-08-26 17:26:10 -06:00
WIP
This commit is contained in:
parent
c44eb65993
commit
9336670fec
@ -14,7 +14,7 @@ from tenancy.forms import TenancyForm
|
|||||||
from utilities.forms import (
|
from utilities.forms import (
|
||||||
APISelect, add_blank_choice, BootstrapMixin, ClearableFileInput, CommentField, ContentTypeChoiceField,
|
APISelect, add_blank_choice, BootstrapMixin, ClearableFileInput, CommentField, ContentTypeChoiceField,
|
||||||
DynamicModelChoiceField, DynamicModelMultipleChoiceField, JSONField, NumericArrayField, SelectWithPK,
|
DynamicModelChoiceField, DynamicModelMultipleChoiceField, JSONField, NumericArrayField, SelectWithPK,
|
||||||
SlugField, SelectSpeedWidget,
|
SlugField, SelectSpeedWidget, APISelectWithSelector
|
||||||
)
|
)
|
||||||
from virtualization.models import Cluster, ClusterGroup
|
from virtualization.models import Cluster, ClusterGroup
|
||||||
from wireless.models import WirelessLAN, WirelessLANGroup
|
from wireless.models import WirelessLAN, WirelessLANGroup
|
||||||
@ -441,26 +441,27 @@ class PlatformForm(NetBoxModelForm):
|
|||||||
|
|
||||||
|
|
||||||
class DeviceForm(TenancyForm, NetBoxModelForm):
|
class DeviceForm(TenancyForm, NetBoxModelForm):
|
||||||
region = DynamicModelChoiceField(
|
# region = DynamicModelChoiceField(
|
||||||
queryset=Region.objects.all(),
|
# queryset=Region.objects.all(),
|
||||||
required=False,
|
# required=False,
|
||||||
initial_params={
|
# initial_params={
|
||||||
'sites': '$site'
|
# 'sites': '$site'
|
||||||
}
|
# }
|
||||||
)
|
# )
|
||||||
site_group = DynamicModelChoiceField(
|
# site_group = DynamicModelChoiceField(
|
||||||
queryset=SiteGroup.objects.all(),
|
# queryset=SiteGroup.objects.all(),
|
||||||
required=False,
|
# required=False,
|
||||||
initial_params={
|
# initial_params={
|
||||||
'sites': '$site'
|
# 'sites': '$site'
|
||||||
}
|
# }
|
||||||
)
|
# )
|
||||||
site = DynamicModelChoiceField(
|
site = DynamicModelChoiceField(
|
||||||
queryset=Site.objects.all(),
|
queryset=Site.objects.all(),
|
||||||
query_params={
|
query_params={
|
||||||
'region_id': '$region',
|
'region_id': '$region',
|
||||||
'group_id': '$site_group',
|
'group_id': '$site_group',
|
||||||
}
|
},
|
||||||
|
widget=APISelectWithSelector
|
||||||
)
|
)
|
||||||
location = DynamicModelChoiceField(
|
location = DynamicModelChoiceField(
|
||||||
queryset=Location.objects.all(),
|
queryset=Location.objects.all(),
|
||||||
@ -556,7 +557,7 @@ class DeviceForm(TenancyForm, NetBoxModelForm):
|
|||||||
class Meta:
|
class Meta:
|
||||||
model = Device
|
model = Device
|
||||||
fields = [
|
fields = [
|
||||||
'name', 'device_role', 'device_type', 'serial', 'asset_tag', 'region', 'site_group', 'site', 'rack',
|
'name', 'device_role', 'device_type', 'serial', 'asset_tag', 'site', 'rack',
|
||||||
'location', 'position', 'face', 'status', 'airflow', 'platform', 'primary_ip4', 'primary_ip6',
|
'location', 'position', 'face', 'status', 'airflow', 'platform', 'primary_ip4', 'primary_ip6',
|
||||||
'cluster_group', 'cluster', 'tenant_group', 'tenant', 'virtual_chassis', 'vc_position', 'vc_priority',
|
'cluster_group', 'cluster', 'tenant_group', 'tenant', 'virtual_chassis', 'vc_position', 'vc_priority',
|
||||||
'description', 'config_template', 'comments', 'tags', 'local_context_data'
|
'description', 'config_template', 'comments', 'tags', 'local_context_data'
|
||||||
|
@ -10,7 +10,7 @@ from extras.plugins.urls import plugin_admin_patterns, plugin_patterns, plugin_a
|
|||||||
from netbox.api.views import APIRootView, StatusView
|
from netbox.api.views import APIRootView, StatusView
|
||||||
from netbox.graphql.schema import schema
|
from netbox.graphql.schema import schema
|
||||||
from netbox.graphql.views import GraphQLView
|
from netbox.graphql.views import GraphQLView
|
||||||
from netbox.views import HomeView, StaticMediaFailureView, SearchView
|
from netbox.views import HomeView, StaticMediaFailureView, SearchView, htmx
|
||||||
from users.views import LoginView, LogoutView
|
from users.views import LoginView, LogoutView
|
||||||
from .admin import admin_site
|
from .admin import admin_site
|
||||||
|
|
||||||
@ -51,6 +51,9 @@ _patterns = [
|
|||||||
path('virtualization/', include('virtualization.urls')),
|
path('virtualization/', include('virtualization.urls')),
|
||||||
path('wireless/', include('wireless.urls')),
|
path('wireless/', include('wireless.urls')),
|
||||||
|
|
||||||
|
# HTMX views
|
||||||
|
path('htmx/object-selector/', htmx.ObjectSelectorView.as_view(), name='htmx_object_selector'),
|
||||||
|
|
||||||
# API
|
# API
|
||||||
path('api/', APIRootView.as_view(), name='api-root'),
|
path('api/', APIRootView.as_view(), name='api-root'),
|
||||||
path('api/circuits/', include('circuits.api.urls')),
|
path('api/circuits/', include('circuits.api.urls')),
|
||||||
|
20
netbox/netbox/views/htmx.py
Normal file
20
netbox/netbox/views/htmx.py
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
from django.shortcuts import render
|
||||||
|
from django.views.generic import View
|
||||||
|
|
||||||
|
from dcim.forms import SiteFilterForm
|
||||||
|
|
||||||
|
|
||||||
|
class ObjectSelectorView(View):
|
||||||
|
template_name = 'htmx/object_selector.html'
|
||||||
|
|
||||||
|
def get(self, request):
|
||||||
|
form_class = self._get_form_class()
|
||||||
|
form = form_class(request.GET)
|
||||||
|
|
||||||
|
return render(request, self.template_name, {
|
||||||
|
'form': form,
|
||||||
|
})
|
||||||
|
|
||||||
|
def _get_form_class(self):
|
||||||
|
# TODO: Determine form class from request parameters
|
||||||
|
return SiteFilterForm
|
@ -29,8 +29,8 @@
|
|||||||
<div class="row mb-2">
|
<div class="row mb-2">
|
||||||
<h5 class="offset-sm-3">Location</h5>
|
<h5 class="offset-sm-3">Location</h5>
|
||||||
</div>
|
</div>
|
||||||
{% render_field form.region %}
|
{# {% render_field form.region %}#}
|
||||||
{% render_field form.site_group %}
|
{# {% render_field form.site_group %}#}
|
||||||
{% render_field form.site %}
|
{% render_field form.site %}
|
||||||
{% render_field form.location %}
|
{% render_field form.location %}
|
||||||
{% render_field form.rack %}
|
{% render_field form.rack %}
|
||||||
@ -117,3 +117,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block modals %}
|
||||||
|
{% include 'inc/htmx_modal.html' %}
|
||||||
|
{% endblock %}
|
||||||
|
11
netbox/templates/htmx/object_selector.html
Normal file
11
netbox/templates/htmx/object_selector.html
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
{% load form_helpers %}
|
||||||
|
|
||||||
|
<form>
|
||||||
|
<div class="modal-header">
|
||||||
|
<h5 class="modal-title">Object Selector</h5>
|
||||||
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
{% render_form form %}
|
||||||
|
</div>
|
||||||
|
</form>
|
@ -11,6 +11,7 @@ from .utils import add_blank_choice, parse_numeric_range
|
|||||||
__all__ = (
|
__all__ = (
|
||||||
'APISelect',
|
'APISelect',
|
||||||
'APISelectMultiple',
|
'APISelectMultiple',
|
||||||
|
'APISelectWithSelector',
|
||||||
'BulkEditNullBooleanSelect',
|
'BulkEditNullBooleanSelect',
|
||||||
'ClearableFileInput',
|
'ClearableFileInput',
|
||||||
'ColorSelect',
|
'ColorSelect',
|
||||||
@ -259,6 +260,10 @@ class APISelectMultiple(APISelect, forms.SelectMultiple):
|
|||||||
self.attrs['data-multiple'] = 1
|
self.attrs['data-multiple'] = 1
|
||||||
|
|
||||||
|
|
||||||
|
class APISelectWithSelector(APISelect):
|
||||||
|
template_name = 'widgets/apiselect_with_selector.html'
|
||||||
|
|
||||||
|
|
||||||
class DatePicker(forms.TextInput):
|
class DatePicker(forms.TextInput):
|
||||||
"""
|
"""
|
||||||
Date picker using Flatpickr.
|
Date picker using Flatpickr.
|
||||||
|
@ -0,0 +1,14 @@
|
|||||||
|
<div class="d-flex">
|
||||||
|
{% include 'django/forms/widgets/select.html' %}
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
title="Open selector"
|
||||||
|
class="btn btn-sm btn-outline-dark border-input ms-1"
|
||||||
|
data-bs-toggle="modal"
|
||||||
|
data-bs-target="#htmx-modal"
|
||||||
|
hx-get="{% url 'htmx_object_selector' %}"
|
||||||
|
hx-target="#htmx-modal-content"
|
||||||
|
>
|
||||||
|
<i class="mdi mdi-database-search-outline"></i>
|
||||||
|
</button>
|
||||||
|
</div>
|
Loading…
Reference in New Issue
Block a user