diff --git a/netbox/circuits/forms.py b/netbox/circuits/forms.py index 126b2a47b..56cd46d4a 100644 --- a/netbox/circuits/forms.py +++ b/netbox/circuits/forms.py @@ -107,9 +107,9 @@ class ProviderBulkEditForm(BootstrapMixin, AddRemoveTagsForm, CustomFieldModelBu class ProviderFilterForm(BootstrapMixin, CustomFieldModelFilterForm): model = Provider field_groups = [ - ['q'], - ['region_id', 'site_id'], - ['asn', 'tag'], + ['q', 'tag'], + ['region_id', 'site_group_id', 'site_id'], + ['asn'], ] q = forms.CharField( required=False, @@ -122,11 +122,18 @@ class ProviderFilterForm(BootstrapMixin, CustomFieldModelFilterForm): label=_('Region'), fetch_trigger='open' ) + site_group_id = DynamicModelMultipleChoiceField( + queryset=SiteGroup.objects.all(), + required=False, + label=_('Site group'), + fetch_trigger='open' + ) site_id = DynamicModelMultipleChoiceField( queryset=Site.objects.all(), required=False, query_params={ - 'region_id': '$region_id' + 'region_id': '$region_id', + 'site_group_id': '$site_group_id', }, label=_('Site'), fetch_trigger='open' @@ -202,7 +209,10 @@ class ProviderNetworkBulkEditForm(BootstrapMixin, AddRemoveTagsForm, CustomField class ProviderNetworkFilterForm(BootstrapMixin, CustomFieldModelFilterForm): model = ProviderNetwork - field_order = ['q', 'provider_id', 'tag'] + field_groups = ( + ('q', 'tag'), + ('provider_id',), + ) q = forms.CharField( required=False, widget=forms.TextInput(attrs={'placeholder': _('All Fields')}), @@ -368,17 +378,12 @@ class CircuitBulkEditForm(BootstrapMixin, AddRemoveTagsForm, CustomFieldModelBul class CircuitFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldModelFilterForm): model = Circuit - field_order = [ - 'q', 'type_id', 'provider_id', 'provider_network_id', 'status', 'region_id', 'site_id', 'tenant_group_id', - 'tenant_id', 'commit_rate', - ] field_groups = [ - ['q'], - ['type_id', 'status', 'commit_rate'], + ['q', 'tag'], ['provider_id', 'provider_network_id'], - ['region_id', 'site_id'], + ['type_id', 'status', 'commit_rate'], + ['region_id', 'site_group_id', 'site_id'], ['tenant_group_id', 'tenant_id'], - ['tag'] ] q = forms.CharField( required=False, @@ -417,11 +422,18 @@ class CircuitFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldModelFilte label=_('Region'), fetch_trigger='open' ) + site_group_id = DynamicModelMultipleChoiceField( + queryset=SiteGroup.objects.all(), + required=False, + label=_('Site group'), + fetch_trigger='open' + ) site_id = DynamicModelMultipleChoiceField( queryset=Site.objects.all(), required=False, query_params={ - 'region_id': '$region_id' + 'region_id': '$region_id', + 'site_group_id': '$site_group_id', }, label=_('Site'), fetch_trigger='open' diff --git a/netbox/dcim/forms.py b/netbox/dcim/forms.py index 5c85ac661..428cb9c79 100644 --- a/netbox/dcim/forms.py +++ b/netbox/dcim/forms.py @@ -58,11 +58,6 @@ class DeviceComponentFilterForm(BootstrapMixin, CustomFieldModelFilterForm): field_order = [ 'q', 'name', 'label', 'region_id', 'site_group_id', 'site_id', ] - field_groups = [ - ['q'], - ['name', 'label'], - ['region_id', 'site_group_id', 'site_id'], - ] q = forms.CharField( required=False, widget=forms.TextInput(attrs={'placeholder': _('All Fields')}), @@ -90,7 +85,8 @@ class DeviceComponentFilterForm(BootstrapMixin, CustomFieldModelFilterForm): queryset=Site.objects.all(), required=False, query_params={ - 'region_id': '$region_id' + 'region_id': '$region_id', + 'group_id': '$site_group_id', }, label=_('Site'), fetch_trigger='open' @@ -250,12 +246,19 @@ class RegionFilterForm(BootstrapMixin, CustomFieldModelFilterForm): model = Site field_groups = [ ['q'], + ['parent_id'], ] q = forms.CharField( required=False, widget=forms.TextInput(attrs={'placeholder': _('All Fields')}), label=_('Search') ) + parent_id = DynamicModelMultipleChoiceField( + queryset=Region.objects.all(), + required=False, + label=_('Parent region'), + fetch_trigger='open' + ) # @@ -311,12 +314,19 @@ class SiteGroupFilterForm(BootstrapMixin, CustomFieldModelFilterForm): model = SiteGroup field_groups = [ ['q'], + ['parent_id'], ] q = forms.CharField( required=False, widget=forms.TextInput(attrs={'placeholder': _('All Fields')}), label=_('Search') ) + parent_id = DynamicModelMultipleChoiceField( + queryset=SiteGroup.objects.all(), + required=False, + label=_('Parent group'), + fetch_trigger='open' + ) # @@ -476,10 +486,9 @@ class SiteFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldModelFilterFo model = Site field_order = ['q', 'status', 'region_id', 'tenant_group_id', 'tenant_id'] field_groups = [ - ['q'], - ['status', 'region_id'], + ['q', 'tag'], + ['status', 'region_id', 'group_id'], ['tenant_group_id', 'tenant_id'], - ['tag'] ] q = forms.CharField( required=False, @@ -500,7 +509,7 @@ class SiteFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldModelFilterFo group_id = DynamicModelMultipleChoiceField( queryset=SiteGroup.objects.all(), required=False, - label=_('Group'), + label=_('Site group'), fetch_trigger='open' ) tag = TagFilterField(model) @@ -607,11 +616,18 @@ class LocationFilterForm(BootstrapMixin, CustomFieldModelFilterForm): label=_('Region'), fetch_trigger='open' ) + site_group_id = DynamicModelMultipleChoiceField( + queryset=SiteGroup.objects.all(), + required=False, + label=_('Site group'), + fetch_trigger='open' + ) site_id = DynamicModelMultipleChoiceField( queryset=Site.objects.all(), required=False, query_params={ - 'region_id': '$region_id' + 'region_id': '$region_id', + 'group_id': '$site_group_id', }, label=_('Site'), fetch_trigger='open' @@ -897,9 +913,10 @@ class RackFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldModelFilterFo model = Rack field_order = ['q', 'region_id', 'site_id', 'location_id', 'status', 'role_id', 'tenant_group_id', 'tenant_id'] field_groups = [ - ['q'], - ['status', 'role_id'], + ['q', 'tag'], ['region_id', 'site_id', 'location_id'], + ['status', 'role_id'], + ['type', 'width', 'asset_tag'], ['tenant_group_id', 'tenant_id'], ] q = forms.CharField( @@ -1134,9 +1151,10 @@ class RackReservationFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldMo model = RackReservation field_order = ['q', 'region_id', 'site_id', 'location_id', 'user_id', 'tenant_group_id', 'tenant_id'] field_groups = [ - ['q'], + ['q', 'tag'], + ['user_id'], ['region_id', 'site_id', 'location_id'], - ['user_id', 'tenant_group_id', 'tenant_id'], + ['tenant_group_id', 'tenant_id'], ] q = forms.CharField( required=False, @@ -1155,7 +1173,7 @@ class RackReservationFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldMo query_params={ 'region_id': '$region_id' }, - label=_('Region'), + label=_('Site'), fetch_trigger='open' ) location_id = DynamicModelMultipleChoiceField( @@ -1292,12 +1310,9 @@ class DeviceTypeBulkEditForm(BootstrapMixin, AddRemoveTagsForm, CustomFieldModel class DeviceTypeFilterForm(BootstrapMixin, CustomFieldModelFilterForm): model = DeviceType field_groups = [ - ['q'], + ['q', 'tag'], ['manufacturer_id', 'subdevice_role'], - ['console_ports', 'console_server_ports'], - ['power_ports', 'power_outlets'], - ['interfaces', 'pass_through_ports'], - ['tag'] + ['console_ports', 'console_server_ports', 'power_ports', 'power_outlets', 'interfaces', 'pass_through_ports'], ] q = forms.CharField( required=False, @@ -2526,12 +2541,15 @@ class DeviceFilterForm(BootstrapMixin, LocalConfigContextFilterForm, TenancyFilt 'tenant_id', 'manufacturer_id', 'device_type_id', 'asset_tag', 'mac_address', 'has_primary_ip', ] field_groups = [ - ['q'], - ['region_id', 'site_id', 'location_id', 'rack_id'], - ['status', 'role_id', 'asset_tag'], + ['q', 'tag'], + ['region_id', 'site_group_id', 'site_id', 'location_id', 'rack_id'], + ['status', 'role_id', 'asset_tag', 'mac_address'], + ['manufacturer_id', 'device_type_id', 'platform_id'], ['tenant_group_id', 'tenant_id'], - ['manufacturer_id', 'device_type_id'], - ['mac_address', 'has_primary_ip'], + [ + 'has_primary_ip', 'virtual_chassis_member', 'console_ports', 'console_server_ports', 'power_ports', + 'power_outlets', 'interfaces', 'pass_through_ports', 'local_context_data', + ], ] q = forms.CharField( required=False, @@ -2547,7 +2565,8 @@ class DeviceFilterForm(BootstrapMixin, LocalConfigContextFilterForm, TenancyFilt site_group_id = DynamicModelMultipleChoiceField( queryset=SiteGroup.objects.all(), required=False, - label=_('Site group') + label=_('Site group'), + fetch_trigger='open' ) site_id = DynamicModelMultipleChoiceField( queryset=Site.objects.all(), @@ -2723,11 +2742,9 @@ class DeviceBulkAddComponentForm(BootstrapMixin, CustomFieldsMixin, ComponentFor class ConsolePortFilterForm(DeviceComponentFilterForm): model = ConsolePort field_groups = [ - ['q'], - ['name', 'label'], - ['type', 'speed'], - ['region_id', 'site_group_id', 'site_id'], - ['tag'] + ['q', 'tag'], + ['name', 'label', 'type', 'speed'], + ['region_id', 'site_group_id', 'site_id', 'device_id'], ] type = forms.MultipleChoiceField( choices=ConsolePortTypeChoices, @@ -2831,11 +2848,9 @@ class ConsolePortCSVForm(CustomFieldModelCSVForm): class ConsoleServerPortFilterForm(DeviceComponentFilterForm): model = ConsoleServerPort field_groups = [ - ['q'], - ['name', 'label'], - ['type', 'speed'], - ['region_id', 'site_group_id', 'site_id'], - ['tag'] + ['q', 'tag'], + ['name', 'label', 'type', 'speed'], + ['region_id', 'site_group_id', 'site_id', 'device_id'], ] type = forms.MultipleChoiceField( choices=ConsolePortTypeChoices, @@ -2939,10 +2954,9 @@ class ConsoleServerPortCSVForm(CustomFieldModelCSVForm): class PowerPortFilterForm(DeviceComponentFilterForm): model = PowerPort field_groups = [ - ['q'], + ['q', 'tag'], ['name', 'label', 'type'], - ['region_id', 'site_group_id', 'site_id'], - ['tag'], + ['region_id', 'site_group_id', 'site_id', 'device_id'], ] type = forms.MultipleChoiceField( choices=PowerPortTypeChoices, @@ -3045,10 +3059,9 @@ class PowerPortCSVForm(CustomFieldModelCSVForm): class PowerOutletFilterForm(DeviceComponentFilterForm): model = PowerOutlet field_groups = [ - ['q'], + ['q', 'tag'], ['name', 'label', 'type'], - ['region_id', 'site_group_id', 'site_id'], - ['tag'], + ['region_id', 'site_group_id', 'site_id', 'device_id'], ] type = forms.MultipleChoiceField( choices=PowerOutletTypeChoices, @@ -3218,11 +3231,9 @@ class PowerOutletCSVForm(CustomFieldModelCSVForm): class InterfaceFilterForm(DeviceComponentFilterForm): model = Interface field_groups = [ - ['q'], - ['name', 'label', 'type', 'enabled'], - ['mgmt_only', 'mac_address'], - ['region_id', 'site_group_id', 'site_id'], - ['tag'], + ['q', 'tag'], + ['name', 'label', 'type', 'enabled', 'mgmt_only', 'mac_address'], + ['region_id', 'site_group_id', 'site_id', 'device_id'], ] type = forms.MultipleChoiceField( choices=InterfaceTypeChoices, @@ -3578,10 +3589,9 @@ class InterfaceCSVForm(CustomFieldModelCSVForm): class FrontPortFilterForm(DeviceComponentFilterForm): field_groups = [ - ['q'], + ['q', 'tag'], ['name', 'label', 'type', 'color'], - ['region_id', 'site_group_id', 'site_id'], - ['tag'] + ['region_id', 'site_group_id', 'site_id', 'device_id'], ] model = FrontPort type = forms.MultipleChoiceField( @@ -3768,10 +3778,9 @@ class FrontPortCSVForm(CustomFieldModelCSVForm): class RearPortFilterForm(DeviceComponentFilterForm): model = RearPort field_groups = [ - ['q'], + ['q', 'tag'], ['name', 'label', 'type', 'color'], - ['region_id', 'site_group_id', 'site_id'], - ['tag'] + ['region_id', 'site_group_id', 'site_id', 'device_id'], ] type = forms.MultipleChoiceField( choices=PortTypeChoices, @@ -3870,10 +3879,9 @@ class RearPortCSVForm(CustomFieldModelCSVForm): class DeviceBayFilterForm(DeviceComponentFilterForm): model = DeviceBay field_groups = [ - ['q'], + ['q', 'tag'], ['name', 'label'], - ['region_id', 'site_group_id', 'site_id'], - ['tag'] + ['region_id', 'site_group_id', 'site_id', 'device_id'], ] tag = TagFilterField(model) @@ -4122,11 +4130,9 @@ class InventoryItemBulkEditForm( class InventoryItemFilterForm(DeviceComponentFilterForm): model = InventoryItem field_groups = [ - ['q'], - ['name', 'label', 'manufacturer_id'], - ['serial', 'asset_tag', 'discovered'], - ['region_id', 'site_group_id', 'site_id'], - ['tag'] + ['q', 'tag'], + ['name', 'label', 'manufacturer_id', 'serial', 'asset_tag', 'discovered'], + ['region_id', 'site_group_id', 'site_id', 'device_id'], ] manufacturer_id = DynamicModelMultipleChoiceField( queryset=Manufacturer.objects.all(), @@ -4598,11 +4604,10 @@ class CableBulkEditForm(BootstrapMixin, AddRemoveTagsForm, CustomFieldModelBulkE class CableFilterForm(BootstrapMixin, CustomFieldModelFilterForm): model = Cable field_groups = [ - ['q'], + ['q', 'tag'], + ['site_id', 'rack_id', 'device_id'], ['type', 'status', 'color'], - ['device_id', 'rack_id'], - ['region_id', 'site_id', 'tenant_id'], - ['tag'] + ['tenant_id'], ] q = forms.CharField( required=False, @@ -4672,11 +4677,6 @@ class CableFilterForm(BootstrapMixin, CustomFieldModelFilterForm): # class ConsoleConnectionFilterForm(BootstrapMixin, forms.Form): - q = forms.CharField( - required=False, - widget=forms.TextInput(attrs={'placeholder': _('All Fields')}), - label=_('Search') - ) region_id = DynamicModelMultipleChoiceField( queryset=Region.objects.all(), required=False, @@ -4704,11 +4704,6 @@ class ConsoleConnectionFilterForm(BootstrapMixin, forms.Form): class PowerConnectionFilterForm(BootstrapMixin, forms.Form): - q = forms.CharField( - required=False, - widget=forms.TextInput(attrs={'placeholder': _('All Fields')}), - label=_('Search') - ) region_id = DynamicModelMultipleChoiceField( queryset=Region.objects.all(), required=False, @@ -4736,11 +4731,6 @@ class PowerConnectionFilterForm(BootstrapMixin, forms.Form): class InterfaceConnectionFilterForm(BootstrapMixin, forms.Form): - q = forms.CharField( - required=False, - widget=forms.TextInput(attrs={'placeholder': _('All Fields')}), - label=_('Search') - ) region_id = DynamicModelMultipleChoiceField( queryset=Region.objects.all(), required=False, @@ -5010,10 +5000,9 @@ class VirtualChassisFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldMod model = VirtualChassis field_order = ['q', 'region_id', 'site_group_id', 'site_id', 'tenant_group_id', 'tenant_id'] field_groups = [ - ['q'], + ['q', 'tag'], ['region_id', 'site_group_id', 'site_id'], ['tenant_group_id', 'tenant_id'], - ['tag'] ] q = forms.CharField( required=False, @@ -5036,7 +5025,8 @@ class VirtualChassisFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldMod queryset=Site.objects.all(), required=False, query_params={ - 'region_id': '$region_id' + 'region_id': '$region_id', + 'group_id': '$site_group_id', }, label=_('Site'), fetch_trigger='open' @@ -5159,6 +5149,10 @@ class PowerPanelBulkEditForm(BootstrapMixin, AddRemoveTagsForm, CustomFieldModel class PowerPanelFilterForm(BootstrapMixin, CustomFieldModelFilterForm): model = PowerPanel + field_groups = ( + ('q', 'tag'), + ('region_id', 'site_group_id', 'site_id', 'location_id') + ) q = forms.CharField( required=False, widget=forms.TextInput(attrs={'placeholder': _('All Fields')}), @@ -5180,7 +5174,8 @@ class PowerPanelFilterForm(BootstrapMixin, CustomFieldModelFilterForm): queryset=Site.objects.all(), required=False, query_params={ - 'region_id': '$region_id' + 'region_id': '$region_id', + 'group_id': '$site_group_id', }, label=_('Site'), fetch_trigger='open' @@ -5402,12 +5397,10 @@ class PowerFeedBulkEditForm(BootstrapMixin, AddRemoveTagsForm, CustomFieldModelB class PowerFeedFilterForm(BootstrapMixin, CustomFieldModelFilterForm): model = PowerFeed field_groups = [ - ['q'], + ['q', 'tag'], ['region_id', 'site_group_id', 'site_id'], ['power_panel_id', 'rack_id'], - ['type', 'supply', 'max_utilization'], - ['phase', 'voltage', 'amperage'], - ['status', 'tag'] + ['status', 'type', 'supply', 'phase', 'voltage', 'amperage', 'max_utilization'], ] q = forms.CharField( required=False, diff --git a/netbox/extras/forms.py b/netbox/extras/forms.py index 37dddf202..841ea213d 100644 --- a/netbox/extras/forms.py +++ b/netbox/extras/forms.py @@ -88,12 +88,14 @@ class CustomFieldFilterForm(BootstrapMixin, forms.Form): ) content_types = ContentTypeMultipleChoiceField( queryset=ContentType.objects.all(), - limit_choices_to=FeatureQuery('custom_fields') + limit_choices_to=FeatureQuery('custom_fields'), + required=False ) type = forms.MultipleChoiceField( choices=CustomFieldTypeChoices, required=False, - widget=StaticSelectMultiple() + widget=StaticSelectMultiple(), + label=_('Field type') ) weight = forms.IntegerField( required=False @@ -174,8 +176,7 @@ class CustomLinkBulkEditForm(BootstrapMixin, BulkEditForm): class CustomLinkFilterForm(BootstrapMixin, forms.Form): field_groups = [ ['q'], - ['content_type'], - ['weight', 'new_window'], + ['content_type', 'weight', 'new_window'], ] q = forms.CharField( required=False, @@ -184,7 +185,8 @@ class CustomLinkFilterForm(BootstrapMixin, forms.Form): ) content_type = ContentTypeChoiceField( queryset=ContentType.objects.all(), - limit_choices_to=FeatureQuery('custom_fields') + limit_choices_to=FeatureQuery('custom_fields'), + required=False ) weight = forms.IntegerField( required=False @@ -265,8 +267,7 @@ class ExportTemplateBulkEditForm(BootstrapMixin, BulkEditForm): class ExportTemplateFilterForm(BootstrapMixin, forms.Form): field_groups = [ ['q'], - ['content_type', 'mime_type'], - ['file_extension', 'as_attachment'], + ['content_type', 'mime_type', 'file_extension', 'as_attachment'], ] q = forms.CharField( required=False, @@ -275,10 +276,12 @@ class ExportTemplateFilterForm(BootstrapMixin, forms.Form): ) content_type = ContentTypeChoiceField( queryset=ContentType.objects.all(), - limit_choices_to=FeatureQuery('custom_fields') + limit_choices_to=FeatureQuery('custom_fields'), + required=False ) mime_type = forms.CharField( - required=False + required=False, + label=_('MIME type') ) file_extension = forms.CharField( required=False @@ -377,8 +380,8 @@ class WebhookBulkEditForm(BootstrapMixin, BulkEditForm): class WebhookFilterForm(BootstrapMixin, forms.Form): field_groups = [ ['q'], - ['content_types', 'http_method'], - ['enabled', 'type_create', 'type_update', 'type_delete'], + ['content_types', 'http_method', 'enabled'], + ['type_create', 'type_update', 'type_delete'], ] q = forms.CharField( required=False, @@ -387,12 +390,14 @@ class WebhookFilterForm(BootstrapMixin, forms.Form): ) content_types = ContentTypeMultipleChoiceField( queryset=ContentType.objects.all(), - limit_choices_to=FeatureQuery('custom_fields') + limit_choices_to=FeatureQuery('custom_fields'), + required=False ) http_method = forms.MultipleChoiceField( choices=WebhookHttpMethodChoices, required=False, - widget=StaticSelectMultiple() + widget=StaticSelectMultiple(), + label=_('HTTP method') ) enabled = forms.NullBooleanField( required=False, @@ -693,16 +698,12 @@ class ConfigContextBulkEditForm(BootstrapMixin, BulkEditForm): class ConfigContextFilterForm(BootstrapMixin, forms.Form): - field_order = [ - 'q', 'region_id', 'site_group_id', 'site_id', 'role_id', 'platform_id', 'cluster_group_id', - 'cluster_id', 'tenant_group_id', 'tenant_id', - ] field_groups = [ - ['q'], + ['q', 'tag'], ['region_id', 'site_group_id', 'site_id'], - ['device_type_id', 'role_id', 'platform_id'], + ['device_type_id', 'platform_id', 'role_id'], ['cluster_group_id', 'cluster_id'], - ['tenant_group_id', 'tenant_id', 'tag'] + ['tenant_group_id', 'tenant_id'] ] q = forms.CharField( required=False, diff --git a/netbox/ipam/forms.py b/netbox/ipam/forms.py index 78805822c..376e4b919 100644 --- a/netbox/ipam/forms.py +++ b/netbox/ipam/forms.py @@ -107,12 +107,10 @@ class VRFBulkEditForm(BootstrapMixin, AddRemoveTagsForm, CustomFieldModelBulkEdi class VRFFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldModelFilterForm): model = VRF - field_order = ['q', 'import_target_id', 'export_target_id', 'tenant_group_id', 'tenant_id'] field_groups = [ - ['q'], + ['q', 'tag'], ['import_target_id', 'export_target_id'], ['tenant_group_id', 'tenant_id'], - ['tag'] ] q = forms.CharField( required=False, @@ -186,9 +184,8 @@ class RouteTargetBulkEditForm(BootstrapMixin, AddRemoveTagsForm, CustomFieldMode class RouteTargetFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldModelFilterForm): model = RouteTarget - field_order = ['q', 'name', 'tenant_group_id', 'tenant_id', 'importing_vrfs', 'exporting_vrfs'] field_groups = [ - ['q'], + ['q', 'tag'], ['importing_vrf_id', 'exporting_vrf_id'], ['tenant_group_id', 'tenant_id'], ] @@ -348,9 +345,8 @@ class AggregateBulkEditForm(BootstrapMixin, AddRemoveTagsForm, CustomFieldModelB class AggregateFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldModelFilterForm): model = Aggregate - field_order = ['q', 'family', 'rir', 'tenant_group_id', 'tenant_id'] field_groups = [ - ['q'], + ['q', 'tag'], ['family', 'rir_id'], ['tenant_group_id', 'tenant_id'] ] @@ -628,17 +624,13 @@ class PrefixBulkEditForm(BootstrapMixin, AddRemoveTagsForm, CustomFieldModelBulk class PrefixFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldModelFilterForm): model = Prefix - field_order = [ - 'q', 'within_include', 'family', 'mask_length', 'vrf_id', 'present_in_vrf_id', 'status', - 'region_id', 'site_group_id', 'site_id', 'role_id', 'tenant_group_id', 'tenant_id', - 'is_pool', 'mark_utilized', - ] field_groups = [ - ['q'], - ['role_id', 'within_include', 'family', 'mask_length'], - ['vrf_id', 'present_in_vrf_id', 'is_pool', 'mark_utilized'], + ['q', 'tag'], + ['within_include', 'family', 'status', 'role_id'], + ['vrf_id', 'present_in_vrf_id'], + ['mask_length', 'is_pool', 'mark_utilized'], ['region_id', 'site_group_id', 'site_id'], - ['tenant_group_id', 'tenant_id', 'status', 'tag'] + ['tenant_group_id', 'tenant_id'] ] q = forms.CharField( required=False, @@ -838,13 +830,10 @@ class IPRangeBulkEditForm(BootstrapMixin, AddRemoveTagsForm, CustomFieldModelBul class IPRangeFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldModelFilterForm): model = IPRange - field_order = [ - 'q', 'family', 'vrf_id', 'status', 'role_id', 'tenant_group_id', 'tenant_id', - ] field_groups = [ - ['q'], + ['q', 'tag'], ['family', 'vrf_id', 'status', 'role_id'], - ['tenant_group_id', 'tenant_id', 'tag'], + ['tenant_group_id', 'tenant_id'], ] q = forms.CharField( required=False, @@ -1280,10 +1269,10 @@ class IPAddressFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldModelFil 'assigned_to_interface', 'tenant_group_id', 'tenant_id', ] field_groups = [ - ['q'], - ['parent', 'family', 'mask_length'], - ['status', 'vrf_id', 'present_in_vrf_id'], - ['role', 'assigned_to_interface'], + ['q', 'tag'], + ['parent', 'family', 'status', 'role'], + ['vrf_id', 'present_in_vrf_id'], + ['mask_length', 'assigned_to_interface'], ['tenant_group_id', 'tenant_id'], ] q = forms.CharField( @@ -1489,8 +1478,7 @@ class VLANGroupBulkEditForm(BootstrapMixin, CustomFieldModelBulkEditForm): class VLANGroupFilterForm(BootstrapMixin, forms.Form): field_groups = [ ['q'], - ['region', 'sitegroup', 'site'], - ['location', 'rack'] + ['region', 'sitegroup', 'site', 'location', 'rack'] ] q = forms.CharField( required=False, @@ -1707,14 +1695,10 @@ class VLANBulkEditForm(BootstrapMixin, AddRemoveTagsForm, CustomFieldModelBulkEd class VLANFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldModelFilterForm): model = VLAN - field_order = [ - 'q', 'region_id', 'site_group_id', 'site_id', 'group_id', 'status', 'role_id', - 'tenant_group_id', 'tenant_id', - ] field_groups = [ - ['q'], + ['q', 'tag'], ['region_id', 'site_group_id', 'site_id'], - ['group_id', 'role_id', 'status'], + ['group_id', 'status', 'role_id'], ['tenant_group_id', 'tenant_id'], ] q = forms.CharField( @@ -1818,6 +1802,10 @@ class ServiceForm(BootstrapMixin, CustomFieldModelForm): class ServiceFilterForm(BootstrapMixin, CustomFieldModelFilterForm): model = Service + field_groups = ( + ('q', 'tag'), + ('protocol', 'port'), + ) q = forms.CharField( required=False, widget=forms.TextInput(attrs={'placeholder': _('All Fields')}), diff --git a/netbox/templates/inc/filter_list.html b/netbox/templates/inc/filter_list.html index 4da03b5cc..cf1ec342e 100644 --- a/netbox/templates/inc/filter_list.html +++ b/netbox/templates/inc/filter_list.html @@ -4,42 +4,52 @@
- {% for field in filter_form.hidden_fields %} - {{ field }} - {% endfor %} - {% if filter_form.field_groups %} - {% for group in filter_form.field_groups %} -
- {% for name in group %} - {% with field=filter_form|get_item:name %} - {% render_field field %} - {% endwith %} - {% endfor %} -
-
- {% endfor %} - {% for name in filter_form.custom_field_filters %} -
- {% with field=filter_form|get_item:name %} - {% render_field field %} - {% endwith %} -
- {% endfor %} - {% else %} - {% for field in filter_form.visible_fields %} -
- {% render_field field %} -
- {% endfor %} + {% for field in filter_form.hidden_fields %} + {{ field }} + {% endfor %} + {% if filter_form.field_groups %} + {# List filters by group #} + {% for group in filter_form.field_groups %} +
+ {% for name in group %} + {% with field=filter_form|get_item:name %} + {% render_field field %} + {% endwith %} + {% endfor %} +
+ {% if not forloop.last %} +
{% endif %} + {% endfor %} + {% else %} + {# List all non-customfield filters as declared in the form class #} + {% for field in filter_form.visible_fields %} + {% if not filter_form.custom_field_filters or field.name not in filter_form.custom_field_filters %} +
+ {% render_field field %} +
+ {% endif %} + {% endfor %} + {% endif %} + {% if filter_form.custom_field_filters %} + {# List all custom field filters #} +
+ {% for name in filter_form.custom_field_filters %} +
+ {% with field=filter_form|get_item:name %} + {% render_field field %} + {% endwith %} +
+ {% endfor %} + {% endif %}
diff --git a/netbox/tenancy/forms.py b/netbox/tenancy/forms.py index 58c1ae60a..63dcdd468 100644 --- a/netbox/tenancy/forms.py +++ b/netbox/tenancy/forms.py @@ -135,6 +135,10 @@ class TenantBulkEditForm(BootstrapMixin, AddRemoveTagsForm, CustomFieldModelBulk class TenantFilterForm(BootstrapMixin, CustomFieldModelFilterForm): model = Tenant + field_groups = ( + ('q', 'tag'), + ('group_id',), + ) q = forms.CharField( required=False, widget=forms.TextInput(attrs={'placeholder': _('All Fields')}), diff --git a/netbox/virtualization/forms.py b/netbox/virtualization/forms.py index 6744cd6de..efb787eca 100644 --- a/netbox/virtualization/forms.py +++ b/netbox/virtualization/forms.py @@ -228,11 +228,10 @@ class ClusterFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldModelFilte 'q', 'type_id', 'region_id', 'site_id', 'group_id', 'tenant_group_id', 'tenant_id', ] field_groups = [ - ['q'], - ['type_id'], - ['region_id', 'site_id'], + ['q', 'tag'], + ['group_id', 'type_id'], + ['region_id', 'site_group_id', 'site_id'], ['tenant_group_id', 'tenant_id'], - ['tag'], ] q = forms.CharField( required=False, @@ -251,12 +250,19 @@ class ClusterFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldModelFilte label=_('Region'), fetch_trigger='open' ) + site_group_id = DynamicModelMultipleChoiceField( + queryset=SiteGroup.objects.all(), + required=False, + label=_('Site group'), + fetch_trigger='open' + ) site_id = DynamicModelMultipleChoiceField( queryset=Site.objects.all(), required=False, null_option='None', query_params={ - 'region_id': '$region_id' + 'region_id': '$region_id', + 'site_group_id': '$site_group_id', }, label=_('Site'), fetch_trigger='open' @@ -541,18 +547,12 @@ class VirtualMachineBulkEditForm(BootstrapMixin, AddRemoveTagsForm, CustomFieldM class VirtualMachineFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldModelFilterForm): model = VirtualMachine - field_order = [ - 'q', 'cluster_group_id', 'cluster_type_id', 'cluster_id', 'status', 'role_id', 'region_id', 'site_group_id', - 'site_id', 'tenant_group_id', 'tenant_id', 'platform_id', 'mac_address', - ] field_groups = [ - ['q'], - ['status', 'role_id'], - ['platform_id', 'mac_address'], + ['q', 'tag'], ['cluster_group_id', 'cluster_type_id', 'cluster_id'], - ['region_id', 'site_id'], + ['region_id', 'site_group_id', 'site_id'], + ['status', 'role_id', 'platform_id', 'mac_address', 'has_primary_ip'], ['tenant_group_id', 'tenant_id'], - ] q = forms.CharField( required=False, @@ -878,10 +878,9 @@ class VMInterfaceBulkRenameForm(BulkRenameForm): class VMInterfaceFilterForm(BootstrapMixin, forms.Form): model = VMInterface field_groups = [ - ['q'], + ['q', 'tag'], ['cluster_id', 'virtual_machine_id'], ['enabled', 'mac_address'], - ['tag'] ] q = forms.CharField( required=False,