mirror of
https://github.com/netbox-community/netbox.git
synced 2024-05-10 07:54:54 +00:00
Closes #7087: Add search/filter forms for all organizational models
This commit is contained in:
@ -8,6 +8,7 @@
|
||||
* [#6387](https://github.com/netbox-community/netbox/issues/6387) - Add xDSL interface type
|
||||
* [#6988](https://github.com/netbox-community/netbox/issues/6988) - Order tenants alphabetically without regard to group assignment
|
||||
* [#7032](https://github.com/netbox-community/netbox/issues/7032) - Add URM port types
|
||||
* [#7087](https://github.com/netbox-community/netbox/issues/7087) - Add search/filter forms for all organizational models
|
||||
* [#7208](https://github.com/netbox-community/netbox/issues/7208) - Add navigation breadcrumbs for custom scripts & reports
|
||||
* [#7239](https://github.com/netbox-community/netbox/issues/7239) - Redirect global search to filtered object list when an object type is selected
|
||||
|
||||
|
@ -266,6 +266,18 @@ class CircuitTypeCSVForm(CustomFieldModelCSVForm):
|
||||
}
|
||||
|
||||
|
||||
class CircuitTypeFilterForm(BootstrapMixin, CustomFieldModelFilterForm):
|
||||
model = CircuitType
|
||||
field_groups = [
|
||||
['q'],
|
||||
]
|
||||
q = forms.CharField(
|
||||
required=False,
|
||||
widget=forms.TextInput(attrs={'placeholder': _('All Fields')}),
|
||||
label=_('Search')
|
||||
)
|
||||
|
||||
|
||||
#
|
||||
# Circuits
|
||||
#
|
||||
|
@ -144,6 +144,8 @@ class CircuitTypeListView(generic.ObjectListView):
|
||||
queryset = CircuitType.objects.annotate(
|
||||
circuit_count=count_related(Circuit, 'type')
|
||||
)
|
||||
filterset = filtersets.CircuitTypeFilterSet
|
||||
filterset_form = forms.CircuitTypeFilterForm
|
||||
table = tables.CircuitTypeTable
|
||||
|
||||
|
||||
|
@ -696,6 +696,18 @@ class RackRoleBulkEditForm(BootstrapMixin, CustomFieldModelBulkEditForm):
|
||||
nullable_fields = ['color', 'description']
|
||||
|
||||
|
||||
class RackRoleFilterForm(BootstrapMixin, CustomFieldModelFilterForm):
|
||||
model = RackRole
|
||||
field_groups = [
|
||||
['q'],
|
||||
]
|
||||
q = forms.CharField(
|
||||
required=False,
|
||||
widget=forms.TextInput(attrs={'placeholder': _('All Fields')}),
|
||||
label=_('Search')
|
||||
)
|
||||
|
||||
|
||||
#
|
||||
# Racks
|
||||
#
|
||||
@ -1240,6 +1252,18 @@ class ManufacturerBulkEditForm(BootstrapMixin, CustomFieldModelBulkEditForm):
|
||||
nullable_fields = ['description']
|
||||
|
||||
|
||||
class ManufacturerFilterForm(BootstrapMixin, CustomFieldModelFilterForm):
|
||||
model = Manufacturer
|
||||
field_groups = [
|
||||
['q'],
|
||||
]
|
||||
q = forms.CharField(
|
||||
required=False,
|
||||
widget=forms.TextInput(attrs={'placeholder': _('All Fields')}),
|
||||
label=_('Search')
|
||||
)
|
||||
|
||||
|
||||
#
|
||||
# Device types
|
||||
#
|
||||
@ -2076,6 +2100,18 @@ class DeviceRoleBulkEditForm(BootstrapMixin, CustomFieldModelBulkEditForm):
|
||||
nullable_fields = ['color', 'description']
|
||||
|
||||
|
||||
class DeviceRoleFilterForm(BootstrapMixin, CustomFieldModelFilterForm):
|
||||
model = DeviceRole
|
||||
field_groups = [
|
||||
['q'],
|
||||
]
|
||||
q = forms.CharField(
|
||||
required=False,
|
||||
widget=forms.TextInput(attrs={'placeholder': _('All Fields')}),
|
||||
label=_('Search')
|
||||
)
|
||||
|
||||
|
||||
#
|
||||
# Platforms
|
||||
#
|
||||
|
@ -440,6 +440,8 @@ class RackRoleListView(generic.ObjectListView):
|
||||
queryset = RackRole.objects.annotate(
|
||||
rack_count=count_related(Rack, 'role')
|
||||
)
|
||||
filterset = filtersets.RackRoleFilterSet
|
||||
filterset_form = forms.RackRoleFilterForm
|
||||
table = tables.RackRoleTable
|
||||
|
||||
|
||||
@ -684,6 +686,8 @@ class ManufacturerListView(generic.ObjectListView):
|
||||
inventoryitem_count=count_related(InventoryItem, 'manufacturer'),
|
||||
platform_count=count_related(Platform, 'manufacturer')
|
||||
)
|
||||
filterset = filtersets.ManufacturerFilterSet
|
||||
filterset_form = forms.ManufacturerFilterForm
|
||||
table = tables.ManufacturerTable
|
||||
|
||||
|
||||
@ -1149,6 +1153,8 @@ class DeviceRoleListView(generic.ObjectListView):
|
||||
device_count=count_related(Device, 'device_role'),
|
||||
vm_count=count_related(VirtualMachine, 'role')
|
||||
)
|
||||
filterset = filtersets.DeviceRoleFilterSet
|
||||
filterset_form = forms.DeviceRoleFilterForm
|
||||
table = tables.DeviceRoleTable
|
||||
|
||||
|
||||
|
@ -256,7 +256,17 @@ class RIRBulkEditForm(BootstrapMixin, CustomFieldModelBulkEditForm):
|
||||
nullable_fields = ['is_private', 'description']
|
||||
|
||||
|
||||
class RIRFilterForm(BootstrapMixin, forms.Form):
|
||||
class RIRFilterForm(BootstrapMixin, CustomFieldModelFilterForm):
|
||||
model = RIR
|
||||
field_groups = [
|
||||
['q'],
|
||||
['is_private'],
|
||||
]
|
||||
q = forms.CharField(
|
||||
required=False,
|
||||
widget=forms.TextInput(attrs={'placeholder': _('All Fields')}),
|
||||
label=_('Search')
|
||||
)
|
||||
is_private = forms.NullBooleanField(
|
||||
required=False,
|
||||
label=_('Private'),
|
||||
@ -413,6 +423,18 @@ class RoleBulkEditForm(BootstrapMixin, CustomFieldModelBulkEditForm):
|
||||
nullable_fields = ['description']
|
||||
|
||||
|
||||
class RoleFilterForm(BootstrapMixin, CustomFieldModelFilterForm):
|
||||
model = Role
|
||||
field_groups = [
|
||||
['q'],
|
||||
]
|
||||
q = forms.CharField(
|
||||
required=False,
|
||||
widget=forms.TextInput(attrs={'placeholder': _('All Fields')}),
|
||||
label=_('Search')
|
||||
)
|
||||
|
||||
|
||||
#
|
||||
# Prefixes
|
||||
#
|
||||
@ -1460,11 +1482,12 @@ class VLANGroupBulkEditForm(BootstrapMixin, CustomFieldModelBulkEditForm):
|
||||
nullable_fields = ['site', 'description']
|
||||
|
||||
|
||||
class VLANGroupFilterForm(BootstrapMixin, forms.Form):
|
||||
class VLANGroupFilterForm(BootstrapMixin, CustomFieldModelFilterForm):
|
||||
field_groups = [
|
||||
['q'],
|
||||
['region', 'sitegroup', 'site', 'location', 'rack']
|
||||
]
|
||||
model = VLANGroup
|
||||
q = forms.CharField(
|
||||
required=False,
|
||||
widget=forms.TextInput(attrs={'placeholder': _('All Fields')}),
|
||||
|
@ -283,6 +283,8 @@ class RoleListView(generic.ObjectListView):
|
||||
prefix_count=count_related(Prefix, 'role'),
|
||||
vlan_count=count_related(VLAN, 'role')
|
||||
)
|
||||
filterset = filtersets.RoleFilterSet
|
||||
filterset_form = forms.RoleFilterForm
|
||||
table = tables.RoleTable
|
||||
|
||||
|
||||
|
@ -1 +1 @@
|
||||
svg{--nbx-rack-bg: #e9ecef;--nbx-rack-border: #000;--nbx-rack-slot-bg: #e9ecef;--nbx-rack-slot-border: #adb5bd;--nbx-rack-slot-hover-bg: #ced4da;--nbx-rack-link-color: #0d6efd;--nbx-rack-unit-color: #6c757d}svg[data-netbox-color-mode=dark]{--nbx-rack-bg: #343a40;--nbx-rack-border: #6c757d;--nbx-rack-slot-bg: #343a40;--nbx-rack-slot-border: #495057;--nbx-rack-slot-hover-bg: #212529;--nbx-rack-link-color: #9ec5fe;--nbx-rack-unit-color: #6c757d}*{font-family:system-ui,-apple-system,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans","Liberation Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-size:.875rem}rect{box-sizing:border-box}text{text-anchor:middle;dominant-baseline:middle}svg .unit{margin:0;padding:5px 0;fill:var(--nbx-rack-unit-color)}svg .hidden{visibility:hidden}svg .rack{fill:none;stroke-width:2px;stroke:var(--nbx-rack-border);background-color:var(--nbx-rack-bg)}svg .slot{fill:var(--nbx-rack-slot-bg);stroke:var(--nbx-rack-slot-border)}svg .slot:hover{fill:var(--nbx-rack-slot-hover-bg)}svg .slot+.add-device{fill:var(--nbx-rack-link-color);opacity:0;pointer-events:none}svg .slot:hover+.add-device{opacity:1}svg .slot.reserved:hover[class]+.add-device{fill:#000}svg .slot.reserved[class],svg .slot.reserved:hover[class]{fill:url(#reserved)}svg .slot.occupied[class],svg .slot.occupied:hover[class]{fill:url(#occupied)}svg .slot.blocked[class],svg .slot.blocked:hover[class]{fill:url(#blocked)}svg .slot.blocked:hover+.add-device{opacity:0}
|
||||
svg{--nbx-rack-bg: #e9ecef;--nbx-rack-border: #000;--nbx-rack-slot-bg: #e9ecef;--nbx-rack-slot-border: #adb5bd;--nbx-rack-slot-hover-bg: #ced4da;--nbx-rack-link-color: #0d6efd;--nbx-rack-unit-color: #6c757d}svg[data-netbox-color-mode=dark]{--nbx-rack-bg: #343a40;--nbx-rack-border: #6c757d;--nbx-rack-slot-bg: #343a40;--nbx-rack-slot-border: #495057;--nbx-rack-slot-hover-bg: #212529;--nbx-rack-link-color: #9ec5fe;--nbx-rack-unit-color: #6c757d}*{font-family:system-ui,-apple-system,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans","Liberation Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-size:.875rem}rect{box-sizing:border-box}text{text-anchor:middle;dominant-baseline:middle}svg .unit{margin:0;padding:5px 0;fill:var(--nbx-rack-unit-color)}svg a{overflow:hidden}svg .hidden{visibility:hidden}svg .rack{fill:none;stroke-width:2px;stroke:var(--nbx-rack-border);background-color:var(--nbx-rack-bg)}svg .slot{fill:var(--nbx-rack-slot-bg);stroke:var(--nbx-rack-slot-border)}svg .slot:hover{fill:var(--nbx-rack-slot-hover-bg)}svg .slot+.add-device{fill:var(--nbx-rack-link-color);opacity:0;pointer-events:none}svg .slot:hover+.add-device{opacity:1}svg .slot.reserved:hover[class]+.add-device{fill:#000}svg .slot.reserved[class],svg .slot.reserved:hover[class]{fill:url(#reserved)}svg .slot.occupied[class],svg .slot.occupied:hover[class]{fill:url(#occupied)}svg .slot.blocked[class],svg .slot.blocked:hover[class]{fill:url(#blocked)}svg .slot.blocked:hover+.add-device{opacity:0}
|
||||
|
@ -61,6 +61,18 @@ class ClusterTypeBulkEditForm(BootstrapMixin, CustomFieldModelBulkEditForm):
|
||||
nullable_fields = ['description']
|
||||
|
||||
|
||||
class ClusterTypeFilterForm(BootstrapMixin, CustomFieldModelFilterForm):
|
||||
model = ClusterType
|
||||
field_groups = [
|
||||
['q'],
|
||||
]
|
||||
q = forms.CharField(
|
||||
required=False,
|
||||
widget=forms.TextInput(attrs={'placeholder': _('All Fields')}),
|
||||
label=_('Search')
|
||||
)
|
||||
|
||||
|
||||
#
|
||||
# Cluster groups
|
||||
#
|
||||
@ -97,6 +109,18 @@ class ClusterGroupBulkEditForm(BootstrapMixin, CustomFieldModelBulkEditForm):
|
||||
nullable_fields = ['description']
|
||||
|
||||
|
||||
class ClusterGroupFilterForm(BootstrapMixin, CustomFieldModelFilterForm):
|
||||
model = ClusterGroup
|
||||
field_groups = [
|
||||
['q'],
|
||||
]
|
||||
q = forms.CharField(
|
||||
required=False,
|
||||
widget=forms.TextInput(attrs={'placeholder': _('All Fields')}),
|
||||
label=_('Search')
|
||||
)
|
||||
|
||||
|
||||
#
|
||||
# Clusters
|
||||
#
|
||||
|
@ -24,6 +24,8 @@ class ClusterTypeListView(generic.ObjectListView):
|
||||
queryset = ClusterType.objects.annotate(
|
||||
cluster_count=count_related(Cluster, 'type')
|
||||
)
|
||||
filterset = filtersets.ClusterTypeFilterSet
|
||||
filterset_form = forms.ClusterTypeFilterForm
|
||||
table = tables.ClusterTypeTable
|
||||
|
||||
|
||||
@ -86,6 +88,8 @@ class ClusterGroupListView(generic.ObjectListView):
|
||||
queryset = ClusterGroup.objects.annotate(
|
||||
cluster_count=count_related(Cluster, 'group')
|
||||
)
|
||||
filterset = filtersets.ClusterGroupFilterSet
|
||||
filterset_form = forms.ClusterGroupFilterForm
|
||||
table = tables.ClusterGroupTable
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user