diff --git a/netbox/circuits/forms.py b/netbox/circuits/forms.py index 56cd46d4a..201d1b203 100644 --- a/netbox/circuits/forms.py +++ b/netbox/circuits/forms.py @@ -131,10 +131,10 @@ class ProviderFilterForm(BootstrapMixin, CustomFieldModelFilterForm): site_id = DynamicModelMultipleChoiceField( queryset=Site.objects.all(), required=False, - query_params={ - 'region_id': '$region_id', - 'site_group_id': '$site_group_id', - }, + filter_fields=[ + {'accessor': 'region_id', 'field_name': 'region_id'}, + {'accessor': 'site_group_id', 'field_name': 'site_group_id'} + ], label=_('Site'), fetch_trigger='open' ) @@ -405,9 +405,9 @@ class CircuitFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldModelFilte provider_network_id = DynamicModelMultipleChoiceField( queryset=ProviderNetwork.objects.all(), required=False, - query_params={ - 'provider_id': '$provider_id' - }, + filter_fields=[ + {'accessor': 'provider_id', 'field_name': 'provider_id'} + ], label=_('Provider network'), fetch_trigger='open' ) @@ -431,10 +431,10 @@ class CircuitFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldModelFilte site_id = DynamicModelMultipleChoiceField( queryset=Site.objects.all(), required=False, - query_params={ - 'region_id': '$region_id', - 'site_group_id': '$site_group_id', - }, + filter_fields=[ + {'accessor': 'region_id', 'field_name': 'region_id'}, + {'accessor': 'site_group_id', 'field_name': 'site_group_id'}, + ], label=_('Site'), fetch_trigger='open' ) @@ -467,10 +467,10 @@ class CircuitTerminationForm(BootstrapMixin, forms.ModelForm): ) site = DynamicModelChoiceField( queryset=Site.objects.all(), - query_params={ - 'region_id': '$region', - 'group_id': '$site_group', - }, + filter_fields=[ + {'accessor': 'region_id', 'field_name': 'region'}, + {'accessor': 'site_group_id', 'field_name': 'site_group'}, + ], required=False ) provider_network = DynamicModelChoiceField( diff --git a/netbox/dcim/forms.py b/netbox/dcim/forms.py index 3456eee35..47109c233 100644 --- a/netbox/dcim/forms.py +++ b/netbox/dcim/forms.py @@ -84,29 +84,29 @@ class DeviceComponentFilterForm(BootstrapMixin, CustomFieldModelFilterForm): site_id = DynamicModelMultipleChoiceField( queryset=Site.objects.all(), required=False, - query_params={ - 'region_id': '$region_id', - 'group_id': '$site_group_id', - }, + filter_fields=[ + {'accessor': 'region_id', 'field_name': 'region_id'}, + {'accessor': 'group_id', 'field_name': 'site_group_id'}, + ], label=_('Site'), fetch_trigger='open' ) location_id = DynamicModelMultipleChoiceField( queryset=Location.objects.all(), required=False, - query_params={ - 'site_id': '$site_id', - }, + filter_fields=[ + {'accessor': 'site_id', 'field_name': 'site_id'}, + ], label=_('Location'), fetch_trigger='open' ) device_id = DynamicModelMultipleChoiceField( queryset=Device.objects.all(), required=False, - query_params={ - 'site_id': '$site_id', - 'location_id': '$location_id', - }, + filter_fields=[ + {'accessor': 'site_id', 'field_name': 'site_id'}, + {'accessor': 'location_id', 'field_name': 'location_id'}, + ], label=_('Device'), fetch_trigger='open' ) @@ -546,17 +546,17 @@ class LocationForm(BootstrapMixin, CustomFieldModelForm): ) site = DynamicModelChoiceField( queryset=Site.objects.all(), - query_params={ - 'region_id': '$region', - 'group_id': '$site_group', - } + filter_fields=[ + {'accessor': 'region_id', 'field_name': 'region'}, + {'accessor': 'group_id', 'field_name': 'site_group'}, + ] ) parent = DynamicModelChoiceField( queryset=Location.objects.all(), required=False, - query_params={ - 'site_id': '$site' - } + filter_fields=[ + {'accessor': 'site_id', 'field_name': 'site'}, + ] ) slug = SlugField() @@ -600,9 +600,9 @@ class LocationBulkEditForm(BootstrapMixin, CustomFieldModelBulkEditForm): parent = DynamicModelChoiceField( queryset=Location.objects.all(), required=False, - query_params={ - 'site_id': '$site' - } + filter_fields=[ + {'accessor': 'site_id', 'field_name': 'site'}, + ] ) description = forms.CharField( max_length=200, @@ -635,20 +635,20 @@ class LocationFilterForm(BootstrapMixin, CustomFieldModelFilterForm): site_id = DynamicModelMultipleChoiceField( queryset=Site.objects.all(), required=False, - query_params={ - 'region_id': '$region_id', - 'group_id': '$site_group_id', - }, + filter_fields=[ + {'accessor': 'region_id', 'field_name': 'region_id'}, + {'accessor': 'group_id', 'field_name': 'site_group_id'}, + ], label=_('Site'), fetch_trigger='open' ) parent_id = DynamicModelMultipleChoiceField( queryset=Location.objects.all(), required=False, - query_params={ - 'region_id': '$region_id', - 'site_id': '$site_id', - }, + filter_fields=[ + {'accessor': 'region_id', 'field_name': 'region_id'}, + {'accessor': 'site_id', 'field_name': 'site_id'}, + ], label=_('Parent'), fetch_trigger='open' ) @@ -717,17 +717,17 @@ class RackForm(BootstrapMixin, TenancyForm, CustomFieldModelForm): ) site = DynamicModelChoiceField( queryset=Site.objects.all(), - query_params={ - 'region_id': '$region', - 'group_id': '$site_group', - } + filter_fields=[ + {'accessor': 'region_id', 'field_name': 'region'}, + {'accessor': 'group_id', 'field_name': 'site_group'}, + ], ) location = DynamicModelChoiceField( queryset=Location.objects.all(), required=False, - query_params={ - 'site_id': '$site' - } + filter_fields=[ + {'accessor': 'site_id', 'field_name': 'site'}, + ], ) role = DynamicModelChoiceField( queryset=RackRole.objects.all(), @@ -841,17 +841,17 @@ class RackBulkEditForm(BootstrapMixin, AddRemoveTagsForm, CustomFieldModelBulkEd site = DynamicModelChoiceField( queryset=Site.objects.all(), required=False, - query_params={ - 'region_id': '$region', - 'group_id': '$site_group', - } + filter_fields=[ + {'accessor': 'region_id', 'field_name': 'region'}, + {'accessor': 'group_id', 'field_name': 'site_group'}, + ] ) location = DynamicModelChoiceField( queryset=Location.objects.all(), required=False, - query_params={ - 'site_id': '$site' - } + filter_fields=[ + {'accessor': 'site_id', 'field_name': 'site'}, + ] ) tenant = DynamicModelChoiceField( queryset=Tenant.objects.all(), @@ -943,9 +943,9 @@ class RackFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldModelFilterFo site_id = DynamicModelMultipleChoiceField( queryset=Site.objects.all(), required=False, - query_params={ - 'region_id': '$region_id' - }, + filter_fields=[ + {'accessor': 'region_id', 'field_name': 'region_id'}, + ], label=_('Site'), fetch_trigger='open' ) @@ -953,9 +953,9 @@ class RackFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldModelFilterFo queryset=Location.objects.all(), required=False, null_option='None', - query_params={ - 'site_id': '$site_id' - }, + filter_fields=[ + {'accessor': 'site_id', 'field_name': 'site_id'}, + ], label=_('Location'), fetch_trigger='open' ) @@ -1000,10 +1000,10 @@ class RackElevationFilterForm(RackFilterForm): queryset=Rack.objects.all(), label=_('Rack'), required=False, - query_params={ - 'site_id': '$site_id', - 'location_id': '$location_id', - }, + filter_fields=[ + {'accessor': 'site_id', 'field_name': 'site_id'}, + {'accessor': 'location_id', 'field_name': 'location_id'}, + ], fetch_trigger='open' ) @@ -1032,26 +1032,26 @@ class RackReservationForm(BootstrapMixin, TenancyForm, CustomFieldModelForm): site = DynamicModelChoiceField( queryset=Site.objects.all(), required=False, - query_params={ - 'region_id': '$region', - 'group_id': '$site_group', - }, + filter_fields=[ + {'accessor': 'region_id', 'field_name': 'region'}, + {'accessor': 'group_id', 'field_name': 'site_group'}, + ], fetch_trigger='open' ) location = DynamicModelChoiceField( queryset=Location.objects.all(), required=False, - query_params={ - 'site_id': '$site' - }, + filter_fields=[ + {'accessor': 'site_id', 'field_name': 'site'}, + ], fetch_trigger='open' ) rack = DynamicModelChoiceField( queryset=Rack.objects.all(), - query_params={ - 'site_id': '$site', - 'location_id': '$location', - }, + filter_fields=[ + {'accessor': 'site_id', 'field_name': 'site'}, + {'accessor': 'location_id', 'field_name': 'location'}, + ], fetch_trigger='open' ) units = NumericArrayField( @@ -1180,9 +1180,9 @@ class RackReservationFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldMo site_id = DynamicModelMultipleChoiceField( queryset=Site.objects.all(), required=False, - query_params={ - 'region_id': '$region_id' - }, + filter_fields=[ + {'accessor': 'region_id', 'field_name': 'region_id'}, + ], label=_('Site'), fetch_trigger='open' ) @@ -1402,9 +1402,9 @@ class ComponentTemplateCreateForm(BootstrapMixin, ComponentForm): ) device_type = DynamicModelChoiceField( queryset=DeviceType.objects.all(), - query_params={ - 'manufacturer_id': '$manufacturer' - } + filter_fields=[ + {'accessor': 'manufacturer_id', 'field_name': 'manufacturer'}, + ] ) description = forms.CharField( required=False @@ -2169,17 +2169,17 @@ class DeviceForm(BootstrapMixin, TenancyForm, CustomFieldModelForm): ) site = DynamicModelChoiceField( queryset=Site.objects.all(), - query_params={ - 'region_id': '$region', - 'group_id': '$site_group', - } + filter_fields=[ + {'accessor': 'region_id', 'field_name': 'region'}, + {'accessor': 'group_id', 'field_name': 'site_group'}, + ] ) location = DynamicModelChoiceField( queryset=Location.objects.all(), required=False, - query_params={ - 'site_id': '$site' - }, + filter_fields=[ + {'accessor': 'site_id', 'field_name': 'site'}, + ], initial_params={ 'racks': '$rack' } @@ -2187,10 +2187,10 @@ class DeviceForm(BootstrapMixin, TenancyForm, CustomFieldModelForm): rack = DynamicModelChoiceField( queryset=Rack.objects.all(), required=False, - query_params={ - 'site_id': '$site', - 'location_id': '$location', - } + filter_fields=[ + {'accessor': 'site_id', 'field_name': 'site'}, + {'accessor': 'location_id', 'field_name': 'location'}, + ], ) position = forms.IntegerField( required=False, @@ -2214,9 +2214,9 @@ class DeviceForm(BootstrapMixin, TenancyForm, CustomFieldModelForm): ) device_type = DynamicModelChoiceField( queryset=DeviceType.objects.all(), - query_params={ - 'manufacturer_id': '$manufacturer' - } + filter_fields=[ + {'accessor': 'manufacturer_id', 'field_name': 'manufacturer'}, + ], ) device_role = DynamicModelChoiceField( queryset=DeviceRole.objects.all() @@ -2224,9 +2224,13 @@ class DeviceForm(BootstrapMixin, TenancyForm, CustomFieldModelForm): platform = DynamicModelChoiceField( queryset=Platform.objects.all(), required=False, - query_params={ - 'manufacturer_id': ['$manufacturer', 'null'] - } + filter_fields=[ + { + 'accessor': 'manufacturer_id', + 'field_name': 'manufacturer', + 'include_null': True + } + ] ) cluster_group = DynamicModelChoiceField( queryset=ClusterGroup.objects.all(), @@ -2239,9 +2243,9 @@ class DeviceForm(BootstrapMixin, TenancyForm, CustomFieldModelForm): cluster = DynamicModelChoiceField( queryset=Cluster.objects.all(), required=False, - query_params={ - 'group_id': '$cluster_group' - } + filter_fields=[ + {'accessor': 'group_id', 'field_name': 'cluster_group'}, + ], ) comments = CommentField() local_context_data = JSONField( @@ -2500,9 +2504,9 @@ class DeviceBulkEditForm(BootstrapMixin, AddRemoveTagsForm, CustomFieldModelBulk device_type = DynamicModelChoiceField( queryset=DeviceType.objects.all(), required=False, - query_params={ - 'manufacturer_id': '$manufacturer' - } + filter_fields=[ + {'accessor': 'manufacturer_id', 'field_name': 'manufacturer'}, + ] ) device_role = DynamicModelChoiceField( queryset=DeviceRole.objects.all(), @@ -2515,9 +2519,9 @@ class DeviceBulkEditForm(BootstrapMixin, AddRemoveTagsForm, CustomFieldModelBulk location = DynamicModelChoiceField( queryset=Location.objects.all(), required=False, - query_params={ - 'site_id': '$site' - } + filter_fields=[ + {'accessor': 'site_id', 'field_name': 'site'}, + ] ) tenant = DynamicModelChoiceField( queryset=Tenant.objects.all(), @@ -2581,10 +2585,10 @@ class DeviceFilterForm(BootstrapMixin, LocalConfigContextFilterForm, TenancyFilt site_id = DynamicModelMultipleChoiceField( queryset=Site.objects.all(), required=False, - query_params={ - 'region_id': '$region_id', - 'group_id': '$site_group_id', - }, + filter_fields=[ + {'accessor': 'region_id', 'field_name': 'region_id'}, + {'accessor': 'group_id', 'field_name': 'site_group_id'}, + ], label=_('Site'), fetch_trigger='open' ) @@ -2592,9 +2596,9 @@ class DeviceFilterForm(BootstrapMixin, LocalConfigContextFilterForm, TenancyFilt queryset=Location.objects.all(), required=False, null_option='None', - query_params={ - 'site_id': '$site_id' - }, + filter_fields=[ + {'accessor': 'site_id', 'field_name': 'site_id'}, + ], label=_('Location'), fetch_trigger='open' ) @@ -2602,10 +2606,10 @@ class DeviceFilterForm(BootstrapMixin, LocalConfigContextFilterForm, TenancyFilt queryset=Rack.objects.all(), required=False, null_option='None', - query_params={ - 'site_id': '$site_id', - 'location_id': '$location_id', - }, + filter_fields=[ + {'accessor': 'site_id', 'field_name': 'site_id'}, + {'accessor': 'location_id', 'field_name': 'location_id'}, + ], label=_('Rack'), fetch_trigger='open' ) @@ -2624,9 +2628,9 @@ class DeviceFilterForm(BootstrapMixin, LocalConfigContextFilterForm, TenancyFilt device_type_id = DynamicModelMultipleChoiceField( queryset=DeviceType.objects.all(), required=False, - query_params={ - 'manufacturer_id': '$manufacturer_id' - }, + filter_fields=[ + {'accessor': 'manufacturer_id', 'field_name': 'manufacturer_id'}, + ], label=_('Model'), fetch_trigger='open' ) @@ -3279,9 +3283,9 @@ class InterfaceForm(BootstrapMixin, InterfaceCommonForm, CustomFieldModelForm): queryset=Interface.objects.all(), required=False, label='LAG interface', - query_params={ - 'type': 'lag', - } + filter_fields=[ + {'accessor': 'type', 'field_name': 'type', 'default_value': 'lag'}, + ] ) vlan_group = DynamicModelChoiceField( queryset=VLANGroup.objects.all(), @@ -3292,17 +3296,17 @@ class InterfaceForm(BootstrapMixin, InterfaceCommonForm, CustomFieldModelForm): queryset=VLAN.objects.all(), required=False, label='Untagged VLAN', - query_params={ - 'group_id': '$vlan_group', - } + filter_fields=[ + {'accessor': 'group_id', 'field_name': 'vlan_group'}, + ], ) tagged_vlans = DynamicModelMultipleChoiceField( queryset=VLAN.objects.all(), required=False, label='Tagged VLANs', - query_params={ - 'group_id': '$vlan_group', - } + filter_fields=[ + {'accessor': 'group_id', 'field_name': 'vlan_group'}, + ], ) tags = DynamicModelMultipleChoiceField( queryset=Tag.objects.all(), @@ -3358,17 +3362,17 @@ class InterfaceCreateForm(ComponentCreateForm, InterfaceCommonForm): parent = DynamicModelChoiceField( queryset=Interface.objects.all(), required=False, - query_params={ - 'device_id': '$device', - } + filter_fields=[ + {'accessor': 'device_id', 'field_name': 'device'}, + ], ) lag = DynamicModelChoiceField( queryset=Interface.objects.all(), required=False, - query_params={ - 'device_id': '$device', - 'type': 'lag', - } + filter_fields=[ + {'accessor': 'device_id', 'field_name': 'device'}, + {'accessor': 'type', 'field_name': 'type', 'default_value': 'lag'}, + ] ) mac_address = forms.CharField( required=False, @@ -3445,9 +3449,9 @@ class InterfaceBulkEditForm( lag = DynamicModelChoiceField( queryset=Interface.objects.all(), required=False, - query_params={ - 'type': 'lag', - } + filter_fields=[ + {'accessor': 'type', 'field_name': 'type', 'default_value': 'lag'}, + ], ) mgmt_only = forms.NullBooleanField( required=False, @@ -4015,9 +4019,9 @@ class InventoryItemForm(BootstrapMixin, CustomFieldModelForm): parent = DynamicModelChoiceField( queryset=InventoryItem.objects.all(), required=False, - query_params={ - 'device_id': '$device' - } + filter_fields=[ + {'accessor': 'device_id', 'field_name': 'device'}, + ], ) manufacturer = DynamicModelChoiceField( queryset=Manufacturer.objects.all(), @@ -4045,9 +4049,9 @@ class InventoryItemCreateForm(ComponentCreateForm): parent = DynamicModelChoiceField( queryset=InventoryItem.objects.all(), required=False, - query_params={ - 'device_id': '$device' - } + filter_fields=[ + {'accessor': 'device_id', 'field_name': 'device'}, + ] ) part_id = forms.CharField( max_length=50, @@ -4187,39 +4191,39 @@ class ConnectCableToDeviceForm(BootstrapMixin, CustomFieldModelForm): queryset=Site.objects.all(), label='Site', required=False, - query_params={ - 'region_id': '$termination_b_region', - 'group_id': '$termination_b_site_group', - } + filter_fields=[ + {'accessor': 'region_id', 'field_name': 'termination_b_region'}, + {'accessor': 'group_id', 'field_name': 'termination_b_site_group'}, + ], ) termination_b_location = DynamicModelChoiceField( queryset=Location.objects.all(), label='Location', required=False, null_option='None', - query_params={ - 'site_id': '$termination_b_site' - } + filter_fields=[ + {'accessor': 'site_id', 'field_name': 'termination_b_site'}, + ] ) termination_b_rack = DynamicModelChoiceField( queryset=Rack.objects.all(), label='Rack', required=False, null_option='None', - query_params={ - 'site_id': '$termination_b_site', - 'location_id': '$termination_b_location', - } + filter_fields=[ + {'accessor': 'site_id', 'field_name': 'termination_b_site'}, + {'accessor': 'location_id', 'field_name': 'termination_b_location'}, + ] ) termination_b_device = DynamicModelChoiceField( queryset=Device.objects.all(), label='Device', required=False, - query_params={ - 'site_id': '$termination_b_site', - 'location_id': '$termination_b_location', - 'rack_id': '$termination_b_rack', - } + filter_fields=[ + {'accessor': 'site_id', 'field_name': 'termination_b_site'}, + {'accessor': 'location_id', 'field_name': 'termination_b_location'}, + {'accessor': 'rack_id', 'field_name': 'termination_b_rack'} + ] ) tags = DynamicModelMultipleChoiceField( queryset=Tag.objects.all(), @@ -4248,9 +4252,9 @@ class ConnectCableToConsolePortForm(ConnectCableToDeviceForm): queryset=ConsolePort.objects.all(), label='Name', disabled_indicator='_occupied', - query_params={ - 'device_id': '$termination_b_device' - } + filter_fields=[ + {'accessor': 'device_id', 'field_name': 'termination_b_device'}, + ], ) @@ -4259,9 +4263,9 @@ class ConnectCableToConsoleServerPortForm(ConnectCableToDeviceForm): queryset=ConsoleServerPort.objects.all(), label='Name', disabled_indicator='_occupied', - query_params={ - 'device_id': '$termination_b_device' - } + filter_fields=[ + {'accessor': 'device_id', 'field_name': 'termination_b_device'}, + ], ) @@ -4270,9 +4274,9 @@ class ConnectCableToPowerPortForm(ConnectCableToDeviceForm): queryset=PowerPort.objects.all(), label='Name', disabled_indicator='_occupied', - query_params={ - 'device_id': '$termination_b_device' - } + filter_fields=[ + {'accessor': 'device_id', 'field_name': 'termination_b_device'}, + ], ) @@ -4281,9 +4285,9 @@ class ConnectCableToPowerOutletForm(ConnectCableToDeviceForm): queryset=PowerOutlet.objects.all(), label='Name', disabled_indicator='_occupied', - query_params={ - 'device_id': '$termination_b_device' - } + filter_fields=[ + {'accessor': 'device_id', 'field_name': 'termination_b_device'}, + ] ) @@ -4292,10 +4296,10 @@ class ConnectCableToInterfaceForm(ConnectCableToDeviceForm): queryset=Interface.objects.all(), label='Name', disabled_indicator='_occupied', - query_params={ - 'device_id': '$termination_b_device', - 'kind': 'physical', - } + filter_fields=[ + {'accessor': 'device_id', 'field_name': 'termination_b_device'}, + {'accessor': 'kind', 'field_name': 'kind', 'default_value': 'physical'} + ] ) @@ -4304,9 +4308,9 @@ class ConnectCableToFrontPortForm(ConnectCableToDeviceForm): queryset=FrontPort.objects.all(), label='Name', disabled_indicator='_occupied', - query_params={ - 'device_id': '$termination_b_device' - } + filter_fields=[ + {'accessor': 'device_id', 'field_name': 'termination_b_device'}, + ], ) @@ -4315,9 +4319,9 @@ class ConnectCableToRearPortForm(ConnectCableToDeviceForm): queryset=RearPort.objects.all(), label='Name', disabled_indicator='_occupied', - query_params={ - 'device_id': '$termination_b_device' - } + filter_fields=[ + {'accessor': 'device_id', 'field_name': 'termination_b_device'}, + ], ) @@ -4341,26 +4345,26 @@ class ConnectCableToCircuitTerminationForm(BootstrapMixin, CustomFieldModelForm) queryset=Site.objects.all(), label='Site', required=False, - query_params={ - 'region_id': '$termination_b_region', - 'group_id': '$termination_b_site_group', - } + filter_fields=[ + {'accessor': 'region_id', 'field_name': 'termination_b_region'}, + {'accessor': 'group_id', 'field_name': 'termination_b_site_group'}, + ], ) termination_b_circuit = DynamicModelChoiceField( queryset=Circuit.objects.all(), label='Circuit', - query_params={ - 'provider_id': '$termination_b_provider', - 'site_id': '$termination_b_site', - } + filter_fields=[ + {'accessor': 'provider_id', 'field_name': 'termination_b_provider'}, + {'accessor': 'site_id', 'field_name': 'termination_b_site'}, + ] ) termination_b_id = DynamicModelChoiceField( queryset=CircuitTermination.objects.all(), label='Side', disabled_indicator='_occupied', - query_params={ - 'circuit_id': '$termination_b_circuit' - } + filter_fields=[ + {'accessor': 'circuit_id', 'field_name': 'termination_b_circuit'}, + ] ) tags = DynamicModelMultipleChoiceField( queryset=Tag.objects.all(), @@ -4394,35 +4398,35 @@ class ConnectCableToPowerFeedForm(BootstrapMixin, CustomFieldModelForm): queryset=Site.objects.all(), label='Site', required=False, - query_params={ - 'region_id': '$termination_b_region', - 'group_id': '$termination_b_site_group', - } + filter_fields=[ + {'accessor': 'region_id', 'field_name': 'termination_b_region'}, + {'accessor': 'group_id', 'field_name': 'termination_b_site_group'}, + ], ) termination_b_location = DynamicModelChoiceField( queryset=Location.objects.all(), label='Location', required=False, - query_params={ - 'site_id': '$termination_b_site' - } + filter_fields=[ + {'accessor': 'site_id', 'field_name': 'termination_b_site'}, + ] ) termination_b_powerpanel = DynamicModelChoiceField( queryset=PowerPanel.objects.all(), label='Power Panel', required=False, - query_params={ - 'site_id': '$termination_b_site', - 'location_id': '$termination_b_location', - } + filter_fields=[ + {'accessor': 'site_id', 'field_name': 'termination_b_site'}, + {'accessor': 'location_id', 'field_name': 'termination_b_location'}, + ] ) termination_b_id = DynamicModelChoiceField( queryset=PowerFeed.objects.all(), label='Name', disabled_indicator='_occupied', - query_params={ - 'power_panel_id': '$termination_b_powerpanel' - } + filter_fields=[ + {'accessor': 'power_panel_id', 'field_name': 'termination_b_powerpanel'}, + ] ) tags = DynamicModelMultipleChoiceField( queryset=Tag.objects.all(), @@ -4633,9 +4637,9 @@ class CableFilterForm(BootstrapMixin, CustomFieldModelFilterForm): site_id = DynamicModelMultipleChoiceField( queryset=Site.objects.all(), required=False, - query_params={ - 'region_id': '$region_id' - }, + filter_fields=[ + {'accessor': 'region_id', 'field_name': 'region_id'}, + ], label=_('Site'), fetch_trigger='open' ) @@ -4650,9 +4654,9 @@ class CableFilterForm(BootstrapMixin, CustomFieldModelFilterForm): required=False, label=_('Rack'), null_option='None', - query_params={ - 'site_id': '$site_id' - }, + filter_fields=[ + {'accessor': 'site_id', 'field_name': 'site_id'}, + ], fetch_trigger='open' ) type = forms.MultipleChoiceField( @@ -4671,11 +4675,11 @@ class CableFilterForm(BootstrapMixin, CustomFieldModelFilterForm): device_id = DynamicModelMultipleChoiceField( queryset=Device.objects.all(), required=False, - query_params={ - 'site_id': '$site_id', - 'tenant_id': '$tenant_id', - 'rack_id': '$rack_id', - }, + filter_fields=[ + {'accessor': 'site_id', 'field_name': 'site_id'}, + {'accessor': 'tenant_id', 'field_name': 'tenant_id'}, + {'accessor': 'rack_id', 'field_name': 'rack_id'}, + ], label=_('Device'), fetch_trigger='open' ) @@ -4696,18 +4700,18 @@ class ConsoleConnectionFilterForm(BootstrapMixin, forms.Form): site_id = DynamicModelMultipleChoiceField( queryset=Site.objects.all(), required=False, - query_params={ - 'region_id': '$region_id' - }, + filter_fields=[ + {'accessor': 'region_id', 'field_name': 'region_id'}, + ], label=_('Site'), fetch_trigger='open' ) device_id = DynamicModelMultipleChoiceField( queryset=Device.objects.all(), required=False, - query_params={ - 'site_id': '$site_id' - }, + filter_fields=[ + {'accessor': 'site_id', 'field_name': 'site_id'}, + ], label=_('Device'), fetch_trigger='open' ) @@ -4723,18 +4727,18 @@ class PowerConnectionFilterForm(BootstrapMixin, forms.Form): site_id = DynamicModelMultipleChoiceField( queryset=Site.objects.all(), required=False, - query_params={ - 'region_id': '$region_id' - }, + filter_fields=[ + {'accessor': 'region_id', 'field_name': 'region_id'}, + ], label=_('Site'), fetch_trigger='open' ) device_id = DynamicModelMultipleChoiceField( queryset=Device.objects.all(), required=False, - query_params={ - 'site_id': '$site_id' - }, + filter_fields=[ + {'accessor': 'site_id', 'field_name': 'site_id'}, + ], label=_('Device'), fetch_trigger='open' ) @@ -4750,18 +4754,18 @@ class InterfaceConnectionFilterForm(BootstrapMixin, forms.Form): site_id = DynamicModelMultipleChoiceField( queryset=Site.objects.all(), required=False, - query_params={ - 'region_id': '$region_id' - }, + filter_fields=[ + {'accessor': 'region_id', 'field_name': 'region_id'}, + ], label=_('Site'), fetch_trigger='open' ) device_id = DynamicModelMultipleChoiceField( queryset=Device.objects.all(), required=False, - query_params={ - 'site_id': '$site_id' - }, + filter_fields=[ + {'accessor': 'site_id', 'field_name': 'site_id'}, + ], label=_('Device'), fetch_trigger='open' ) @@ -4796,26 +4800,26 @@ class VirtualChassisCreateForm(BootstrapMixin, CustomFieldModelForm): site = DynamicModelChoiceField( queryset=Site.objects.all(), required=False, - query_params={ - 'region_id': '$region', - 'group_id': '$site_group', - } + filter_fields=[ + {'accessor': 'region_id', 'field_name': 'region'}, + {'accessor': 'group_id', 'field_name': 'site_group'}, + ], ) rack = DynamicModelChoiceField( queryset=Rack.objects.all(), required=False, null_option='None', - query_params={ - 'site_id': '$site' - } + filter_fields=[ + {'accessor': 'site_id', 'field_name': 'site'}, + ] ) members = DynamicModelMultipleChoiceField( queryset=Device.objects.all(), required=False, - query_params={ - 'site_id': '$site', - 'rack_id': '$rack', - } + filter_fields=[ + {'accessor': 'site_id', 'field_name': 'site'}, + {'accessor': 'rack_id', 'field_name': 'rack'}, + ], ) initial_position = forms.IntegerField( initial=1, @@ -4948,26 +4952,30 @@ class VCMemberSelectForm(BootstrapMixin, forms.Form): site = DynamicModelChoiceField( queryset=Site.objects.all(), required=False, - query_params={ - 'region_id': '$region', - 'group_id': '$site_group', - } + filter_fields=[ + {'accessor': 'region_id', 'field_name': 'region'}, + {'accessor': 'group_id', 'field_name': 'site_group'}, + ] ) rack = DynamicModelChoiceField( queryset=Rack.objects.all(), required=False, null_option='None', - query_params={ - 'site_id': '$site' - } + filter_fields=[ + {'accessor': 'site_id', 'field_name': 'site'}, + ] ) device = DynamicModelChoiceField( queryset=Device.objects.all(), - query_params={ - 'site_id': '$site', - 'rack_id': '$rack', - 'virtual_chassis_id': 'null', - } + filter_fields=[ + {'accessor': 'site_id', 'field_name': 'site'}, + {'accessor': 'rack_id', 'field_name': 'rack'}, + { + 'accessor': 'virtual_chassis_id', + 'field_name': 'virtual_chassis_id', + 'default_value': None + }, + ] ) def clean_device(self): @@ -5034,10 +5042,10 @@ class VirtualChassisFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldMod site_id = DynamicModelMultipleChoiceField( queryset=Site.objects.all(), required=False, - query_params={ - 'region_id': '$region_id', - 'group_id': '$site_group_id', - }, + filter_fields=[ + {'accessor': 'region_id', 'field_name': 'region_id'}, + {'accessor': 'group_id', 'field_name': 'site_group_id'}, + ], label=_('Site'), fetch_trigger='open' ) @@ -5065,17 +5073,17 @@ class PowerPanelForm(BootstrapMixin, CustomFieldModelForm): ) site = DynamicModelChoiceField( queryset=Site.objects.all(), - query_params={ - 'region_id': '$region', - 'group_id': '$site_group', - } + filter_fields=[ + {'accessor': 'region_id', 'field_name': 'region'}, + {'accessor': 'group_id', 'field_name': 'site_group'}, + ], ) location = DynamicModelChoiceField( queryset=Location.objects.all(), required=False, - query_params={ - 'site_id': '$site' - } + filter_fields=[ + {'accessor': 'site_id', 'field_name': 'site'}, + ] ) tags = DynamicModelMultipleChoiceField( queryset=Tag.objects.all(), @@ -5140,17 +5148,17 @@ class PowerPanelBulkEditForm(BootstrapMixin, AddRemoveTagsForm, CustomFieldModel site = DynamicModelChoiceField( queryset=Site.objects.all(), required=False, - query_params={ - 'region_id': '$region', - 'group_id': '$site_group', - } + filter_fields=[ + {'accessor': 'region_id', 'field_name': 'region'}, + {'accessor': 'group_id', 'field_name': 'site_group'}, + ], ) location = DynamicModelChoiceField( queryset=Location.objects.all(), required=False, - query_params={ - 'site_id': '$site' - } + filter_fields=[ + {'accessor': 'site_id', 'field_name': 'site'}, + ] ) class Meta: @@ -5183,10 +5191,10 @@ class PowerPanelFilterForm(BootstrapMixin, CustomFieldModelFilterForm): site_id = DynamicModelMultipleChoiceField( queryset=Site.objects.all(), required=False, - query_params={ - 'region_id': '$region_id', - 'group_id': '$site_group_id', - }, + filter_fields=[ + {'accessor': 'region_id', 'field_name': 'region_id'}, + {'accessor': 'group_id', 'field_name': 'site_group_id'}, + ], label=_('Site'), fetch_trigger='open' ) @@ -5194,9 +5202,9 @@ class PowerPanelFilterForm(BootstrapMixin, CustomFieldModelFilterForm): queryset=Location.objects.all(), required=False, null_option='None', - query_params={ - 'site_id': '$site_id' - }, + filter_fields=[ + {'accessor': 'site_id', 'field_name': 'site'}, + ], label=_('Location'), fetch_trigger='open' ) @@ -5228,23 +5236,23 @@ class PowerFeedForm(BootstrapMixin, CustomFieldModelForm): initial_params={ 'powerpanel': '$power_panel' }, - query_params={ - 'region_id': '$region', - 'group_id': '$site_group', - } + filter_fields=[ + {'accessor': 'region_id', 'field_name': 'region'}, + {'accessor': 'group_id', 'field_name': 'site_group'}, + ], ) power_panel = DynamicModelChoiceField( queryset=PowerPanel.objects.all(), - query_params={ - 'site_id': '$site' - } + filter_fields=[ + {'accessor': 'site_id', 'field_name': 'site'}, + ], ) rack = DynamicModelChoiceField( queryset=Rack.objects.all(), required=False, - query_params={ - 'site_id': '$site' - } + filter_fields=[ + {'accessor': 'site_id', 'field_name': 'site'}, + ], ) comments = CommentField() tags = DynamicModelMultipleChoiceField( @@ -5432,9 +5440,9 @@ class PowerFeedFilterForm(BootstrapMixin, CustomFieldModelFilterForm): site_id = DynamicModelMultipleChoiceField( queryset=Site.objects.all(), required=False, - query_params={ - 'region_id': '$region_id' - }, + filter_fields=[ + {'accessor': 'region_id', 'field_name': 'region_id'}, + ], label=_('Site'), fetch_trigger='open' ) @@ -5442,9 +5450,9 @@ class PowerFeedFilterForm(BootstrapMixin, CustomFieldModelFilterForm): queryset=PowerPanel.objects.all(), required=False, null_option='None', - query_params={ - 'site_id': '$site_id' - }, + filter_fields=[ + {'accessor': 'site_id', 'field_name': 'site'}, + ], label=_('Power panel'), fetch_trigger='open' ) @@ -5452,9 +5460,9 @@ class PowerFeedFilterForm(BootstrapMixin, CustomFieldModelFilterForm): queryset=Rack.objects.all(), required=False, null_option='None', - query_params={ - 'site_id': '$site_id' - }, + filter_fields=[ + {'accessor': 'site_id', 'field_name': 'site'}, + ], label=_('Rack'), fetch_trigger='open' ) diff --git a/netbox/ipam/forms.py b/netbox/ipam/forms.py index 376e4b919..a34ce5c53 100644 --- a/netbox/ipam/forms.py +++ b/netbox/ipam/forms.py @@ -437,19 +437,19 @@ class PrefixForm(BootstrapMixin, TenancyForm, CustomFieldModelForm): queryset=Site.objects.all(), required=False, null_option='None', - query_params={ - 'region_id': '$region', - 'group_id': '$site_group', - } + filter_fields=[ + {'accessor': 'region_id', 'field_name': 'region'}, + {'accessor': 'group_id', 'field_name': 'site_group'}, + ] ) vlan_group = DynamicModelChoiceField( queryset=VLANGroup.objects.all(), required=False, label='VLAN group', null_option='None', - query_params={ - 'site_id': '$site' - }, + filter_fields=[ + {'accessor': 'site_id', 'field_name': 'site'}, + ], initial_params={ 'vlans': '$vlan' } @@ -458,10 +458,10 @@ class PrefixForm(BootstrapMixin, TenancyForm, CustomFieldModelForm): queryset=VLAN.objects.all(), required=False, label='VLAN', - query_params={ - 'site_id': '$site', - 'group_id': '$vlan_group', - } + filter_fields=[ + {'accessor': 'site_id', 'field_name': 'site'}, + {'accessor': 'group_id', 'field_name': 'vlan_group'}, + ] ) role = DynamicModelChoiceField( queryset=Role.objects.all(), @@ -573,10 +573,10 @@ class PrefixBulkEditForm(BootstrapMixin, AddRemoveTagsForm, CustomFieldModelBulk site = DynamicModelChoiceField( queryset=Site.objects.all(), required=False, - query_params={ - 'region_id': '$region', - 'group_id': '$site_group', - } + filter_fields=[ + {'accessor': 'region_id', 'field_name': 'region'}, + {'accessor': 'group_id', 'field_name': 'site_group'}, + ], ) vrf = DynamicModelChoiceField( queryset=VRF.objects.all(), @@ -695,9 +695,9 @@ class PrefixFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldModelFilter queryset=Site.objects.all(), required=False, null_option='None', - query_params={ - 'region_id': '$region_id' - }, + filter_fields=[ + {'accessor': 'region_id', 'field_name': 'region_id'}, + ], label=_('Site'), fetch_trigger='open' ) @@ -883,9 +883,9 @@ class IPAddressForm(BootstrapMixin, TenancyForm, CustomFieldModelForm): interface = DynamicModelChoiceField( queryset=Interface.objects.all(), required=False, - query_params={ - 'device_id': '$device' - } + filter_fields=[ + {'accessor': 'device_id', 'field_name': 'device'}, + ], ) virtual_machine = DynamicModelChoiceField( queryset=VirtualMachine.objects.all(), @@ -898,9 +898,9 @@ class IPAddressForm(BootstrapMixin, TenancyForm, CustomFieldModelForm): queryset=VMInterface.objects.all(), required=False, label='Interface', - query_params={ - 'virtual_machine_id': '$virtual_machine' - } + filter_fields=[ + {'accessor': 'virtual_machine_id', 'field_name': 'virtual_machine'}, + ] ) vrf = DynamicModelChoiceField( queryset=VRF.objects.all(), @@ -927,28 +927,28 @@ class IPAddressForm(BootstrapMixin, TenancyForm, CustomFieldModelForm): queryset=Site.objects.all(), required=False, label='Site', - query_params={ - 'region_id': '$nat_region', - 'group_id': '$nat_site_group', - } + filter_fields=[ + {'accessor': 'region_id', 'field_name': 'nat_region'}, + {'accessor': 'group_id', 'field_name': 'nat_site_group'}, + ], ) nat_rack = DynamicModelChoiceField( queryset=Rack.objects.all(), required=False, label='Rack', null_option='None', - query_params={ - 'site_id': '$site' - } + filter_fields=[ + {'accessor': 'site_id', 'field_name': 'site'}, + ], ) nat_device = DynamicModelChoiceField( queryset=Device.objects.all(), required=False, label='Device', - query_params={ - 'site_id': '$site', - 'rack_id': '$nat_rack', - } + filter_fields=[ + {'accessor': 'site_id', 'field_name': 'site'}, + {'accessor': 'rack_id', 'field_name': 'nat_rack'}, + ] ) nat_cluster = DynamicModelChoiceField( queryset=Cluster.objects.all(), @@ -959,9 +959,9 @@ class IPAddressForm(BootstrapMixin, TenancyForm, CustomFieldModelForm): queryset=VirtualMachine.objects.all(), required=False, label='Virtual Machine', - query_params={ - 'cluster_id': '$nat_cluster', - } + filter_fields=[ + {'accessor': 'cluster_id', 'field_name': 'nat_cluster'}, + ] ) nat_vrf = DynamicModelChoiceField( queryset=VRF.objects.all(), @@ -972,11 +972,11 @@ class IPAddressForm(BootstrapMixin, TenancyForm, CustomFieldModelForm): queryset=IPAddress.objects.all(), required=False, label='IP Address', - query_params={ - 'device_id': '$nat_device', - 'virtual_machine_id': '$nat_virtual_machine', - 'vrf_id': '$nat_vrf', - } + filter_fields=[ + {'accessor': 'device_id', 'field_name': 'nat_device'}, + {'accessor': 'virtual_machine_id', 'field_name': 'nat_virtual_machine'}, + {'accessor': 'vrf_id', 'field_name': 'nat_vrf'}, + ], ) primary_for_parent = forms.BooleanField( required=False, @@ -1365,10 +1365,10 @@ class VLANGroupForm(BootstrapMixin, CustomFieldModelForm): initial_params={ 'locations': '$location' }, - query_params={ - 'region_id': '$region', - 'group_id': '$sitegroup', - } + filter_fields=[ + {'accessor': 'region_id', 'field_name': 'region'}, + {'accessor': 'group_id', 'field_name': 'sitegroup'}, + ], ) location = DynamicModelChoiceField( queryset=Location.objects.all(), @@ -1376,17 +1376,17 @@ class VLANGroupForm(BootstrapMixin, CustomFieldModelForm): initial_params={ 'racks': '$rack' }, - query_params={ - 'site_id': '$site', - } + filter_fields=[ + {'accessor': 'site_id', 'field_name': 'site'}, + ] ) rack = DynamicModelChoiceField( queryset=Rack.objects.all(), required=False, - query_params={ - 'site_id': '$site', - 'location_id': '$location', - } + filter_fields=[ + {'accessor': 'site_id', 'field_name': 'site'}, + {'accessor': 'location_id', 'field_name': 'location'}, + ], ) clustergroup = DynamicModelChoiceField( queryset=ClusterGroup.objects.all(), @@ -1399,9 +1399,9 @@ class VLANGroupForm(BootstrapMixin, CustomFieldModelForm): cluster = DynamicModelChoiceField( queryset=Cluster.objects.all(), required=False, - query_params={ - 'group_id': '$clustergroup', - } + filter_fields=[ + {'accessor': 'group_id', 'field_name': 'clustergroup'}, + ], ) slug = SlugField() @@ -1541,9 +1541,9 @@ class VLANForm(BootstrapMixin, TenancyForm, CustomFieldModelForm): group = DynamicModelChoiceField( queryset=VLANGroup.objects.all(), required=False, - query_params={ - 'scope_type': '$scope_type', - }, + filter_fields=[ + {'accessor': 'scope_type', 'field_name': 'scope_type'}, + ], label='VLAN Group' ) @@ -1568,10 +1568,10 @@ class VLANForm(BootstrapMixin, TenancyForm, CustomFieldModelForm): queryset=Site.objects.all(), required=False, null_option='None', - query_params={ - 'region_id': '$region', - 'group_id': '$sitegroup', - } + filter_fields=[ + {'accessor': 'region_id', 'field_name': 'region'}, + {'accessor': 'group_id', 'field_name': 'sitegroup'}, + ] ) # Other fields @@ -1657,17 +1657,17 @@ class VLANBulkEditForm(BootstrapMixin, AddRemoveTagsForm, CustomFieldModelBulkEd site = DynamicModelChoiceField( queryset=Site.objects.all(), required=False, - query_params={ - 'region_id': '$region', - 'group_id': '$site_group', - } + filter_fields=[ + {'accessor': 'region_id', 'field_name': 'region'}, + {'accessor': 'group_id', 'field_name': 'site_group'}, + ] ) group = DynamicModelChoiceField( queryset=VLANGroup.objects.all(), required=False, - query_params={ - 'site_id': '$site' - } + filter_fields=[ + {'accessor': 'site_id', 'field_name': 'site'}, + ] ) tenant = DynamicModelChoiceField( queryset=Tenant.objects.all(), @@ -1722,9 +1722,9 @@ class VLANFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldModelFilterFo queryset=Site.objects.all(), required=False, null_option='None', - query_params={ - 'region': '$region' - }, + filter_fields=[ + {'accessor': 'region_id', 'field_name': 'region'}, + ], label=_('Site'), fetch_trigger='open' ) @@ -1732,9 +1732,9 @@ class VLANFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldModelFilterFo queryset=VLANGroup.objects.all(), required=False, null_option='None', - query_params={ - 'region': '$region' - }, + filter_fields=[ + {'accessor': 'region_id', 'field_name': 'region'}, + ], label=_('VLAN group'), fetch_trigger='open' ) diff --git a/netbox/project-static/dist/config.js b/netbox/project-static/dist/config.js index 0f5723b02..15ff8261b 100644 Binary files a/netbox/project-static/dist/config.js and b/netbox/project-static/dist/config.js differ diff --git a/netbox/project-static/dist/config.js.map b/netbox/project-static/dist/config.js.map index 62f1744f8..09e9cbec5 100644 Binary files a/netbox/project-static/dist/config.js.map and b/netbox/project-static/dist/config.js.map differ diff --git a/netbox/project-static/dist/jobs.js b/netbox/project-static/dist/jobs.js index 649d759ae..904b60cdb 100644 Binary files a/netbox/project-static/dist/jobs.js and b/netbox/project-static/dist/jobs.js differ diff --git a/netbox/project-static/dist/jobs.js.map b/netbox/project-static/dist/jobs.js.map index 9e9ea06b9..bbf27ef7a 100644 Binary files a/netbox/project-static/dist/jobs.js.map and b/netbox/project-static/dist/jobs.js.map differ diff --git a/netbox/project-static/dist/lldp.js b/netbox/project-static/dist/lldp.js index c5c9584a7..fee331fa1 100644 Binary files a/netbox/project-static/dist/lldp.js and b/netbox/project-static/dist/lldp.js differ diff --git a/netbox/project-static/dist/lldp.js.map b/netbox/project-static/dist/lldp.js.map index d42cb3025..cd9eceee7 100644 Binary files a/netbox/project-static/dist/lldp.js.map and b/netbox/project-static/dist/lldp.js.map differ diff --git a/netbox/project-static/dist/netbox.js b/netbox/project-static/dist/netbox.js index 1e5b6dd64..091be6775 100644 Binary files a/netbox/project-static/dist/netbox.js and b/netbox/project-static/dist/netbox.js differ diff --git a/netbox/project-static/dist/netbox.js.map b/netbox/project-static/dist/netbox.js.map index acb54704c..ee27fd56b 100644 Binary files a/netbox/project-static/dist/netbox.js.map and b/netbox/project-static/dist/netbox.js.map differ diff --git a/netbox/project-static/dist/status.js b/netbox/project-static/dist/status.js index a2d02a799..aef5eccf1 100644 Binary files a/netbox/project-static/dist/status.js and b/netbox/project-static/dist/status.js differ diff --git a/netbox/project-static/dist/status.js.map b/netbox/project-static/dist/status.js.map index cf69c347c..60a871b6b 100644 Binary files a/netbox/project-static/dist/status.js.map and b/netbox/project-static/dist/status.js.map differ diff --git a/netbox/project-static/src/select/api.ts b/netbox/project-static/src/select/api/apiSelect.ts similarity index 80% rename from netbox/project-static/src/select/api.ts rename to netbox/project-static/src/select/api/apiSelect.ts index 61c40dd8c..b1c381fd2 100644 --- a/netbox/project-static/src/select/api.ts +++ b/netbox/project-static/src/select/api/apiSelect.ts @@ -2,8 +2,9 @@ import queryString from 'query-string'; import debounce from 'just-debounce-it'; import { readableColor } from 'color2k'; import SlimSelect from 'slim-select'; -import { createToast } from '../bs'; -import { hasUrl, hasExclusions, isTrigger } from './util'; +import { createToast } from '../../bs'; +import { hasUrl, hasExclusions, isTrigger } from '../util'; +import { FilterFieldMap } from './filterFields'; import { isTruthy, hasMore, @@ -11,61 +12,14 @@ import { getElement, getApiData, isApiError, - getElements, createElement, uniqueByProperty, findFirstAdjacent, -} from '../util'; +} from '../../util'; import type { Stringifiable } from 'query-string'; import type { Option } from 'slim-select/dist/data'; - -/** - * Map of string keys to primitive array values accepted by `query-string`. Keys are used as - * URL query parameter keys. Values correspond to query param values, enforced as an array - * for easier handling. For example, a mapping of `{ site_id: [1, 2] }` is serialized by - * `query-string` as `?site_id=1&site_id=2`. Likewise, `{ site_id: [1] }` is serialized as - * `?site_id=1`. - */ -type QueryFilter = Map; - -/** - * Map of string keys to primitive values. Used to track variables within URLs from the server. For - * example, `/api/$key/thing`. `PathFilter` tracks `$key` as `{ key: '' }` in the map, and when the - * value is later known, the value is set — `{ key: 'value' }`, and the URL is transformed to - * `/api/value/thing`. - */ -type PathFilter = Map; - -/** - * Merge or replace incoming options with current options. - */ -type ApplyMethod = 'merge' | 'replace'; - -/** - * Trigger for which the select instance should fetch its data from the NetBox API. - */ -export type Trigger = - /** - * Load data when the select element is opened. - */ - | 'open' - /** - * Load data when the element is loaded. - */ - | 'load' - /** - * Load data when a parent element is uncollapsed. - */ - | 'collapse'; - -// Various one-off patterns to replace in query param keys. -const REPLACE_PATTERNS = [ - // Don't query `termination_a_device=1`, but rather `device=1`. - [new RegExp(/termination_(a|b)_(.+)/g), '$2'], - // A tenant's group relationship field is `group`, but the field name is `tenant_group`. - [new RegExp(/tenant_(group)/g), '$1'], -] as [RegExp, string][]; +import type { Trigger, PathFilter, ApplyMethod, QueryFilter } from './types'; // Empty placeholder option. const PLACEHOLDER = { @@ -81,7 +35,7 @@ const DISABLED_ATTRIBUTES = ['occupied'] as string[]; * Manage a single API-backed select element's state. Each API select element is likely controlled * or dynamically updated by one or more other API select (or static select) elements' values. */ -class APISelect { +export class APISelect { /** * Base `