Deprecate collapsible advanced search and re-implement field-based filtering on object views
This commit is contained in:
parent
0b09365d0d
commit
863048cda2
|
|
@ -113,7 +113,8 @@ class ProviderFilterForm(BootstrapMixin, CustomFieldModelFilterForm):
|
|||
region_id = DynamicModelMultipleChoiceField(
|
||||
queryset=Region.objects.all(),
|
||||
required=False,
|
||||
label=_('Region')
|
||||
label=_('Region'),
|
||||
fetch_trigger='open'
|
||||
)
|
||||
site_id = DynamicModelMultipleChoiceField(
|
||||
queryset=Site.objects.all(),
|
||||
|
|
@ -121,7 +122,8 @@ class ProviderFilterForm(BootstrapMixin, CustomFieldModelFilterForm):
|
|||
query_params={
|
||||
'region_id': '$region_id'
|
||||
},
|
||||
label=_('Site')
|
||||
label=_('Site'),
|
||||
fetch_trigger='open'
|
||||
)
|
||||
asn = forms.IntegerField(
|
||||
required=False,
|
||||
|
|
@ -198,7 +200,8 @@ class ProviderNetworkFilterForm(BootstrapMixin, CustomFieldModelFilterForm):
|
|||
provider_id = DynamicModelMultipleChoiceField(
|
||||
queryset=Provider.objects.all(),
|
||||
required=False,
|
||||
label=_('Provider')
|
||||
label=_('Provider'),
|
||||
fetch_trigger='open'
|
||||
)
|
||||
tag = TagFilterField(model)
|
||||
|
||||
|
|
@ -368,12 +371,14 @@ class CircuitFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldModelFilte
|
|||
type_id = DynamicModelMultipleChoiceField(
|
||||
queryset=CircuitType.objects.all(),
|
||||
required=False,
|
||||
label=_('Type')
|
||||
label=_('Type'),
|
||||
fetch_trigger='open'
|
||||
)
|
||||
provider_id = DynamicModelMultipleChoiceField(
|
||||
queryset=Provider.objects.all(),
|
||||
required=False,
|
||||
label=_('Provider')
|
||||
label=_('Provider'),
|
||||
fetch_trigger='open'
|
||||
)
|
||||
provider_network_id = DynamicModelMultipleChoiceField(
|
||||
queryset=ProviderNetwork.objects.all(),
|
||||
|
|
@ -381,7 +386,8 @@ class CircuitFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldModelFilte
|
|||
query_params={
|
||||
'provider_id': '$provider_id'
|
||||
},
|
||||
label=_('Provider network')
|
||||
label=_('Provider network'),
|
||||
fetch_trigger='open'
|
||||
)
|
||||
status = forms.MultipleChoiceField(
|
||||
choices=CircuitStatusChoices,
|
||||
|
|
@ -391,7 +397,8 @@ class CircuitFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldModelFilte
|
|||
region_id = DynamicModelMultipleChoiceField(
|
||||
queryset=Region.objects.all(),
|
||||
required=False,
|
||||
label=_('Region')
|
||||
label=_('Region'),
|
||||
fetch_trigger='open'
|
||||
)
|
||||
site_id = DynamicModelMultipleChoiceField(
|
||||
queryset=Site.objects.all(),
|
||||
|
|
@ -399,7 +406,8 @@ class CircuitFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldModelFilte
|
|||
query_params={
|
||||
'region_id': '$region_id'
|
||||
},
|
||||
label=_('Site')
|
||||
label=_('Site'),
|
||||
fetch_trigger='open'
|
||||
)
|
||||
commit_rate = forms.IntegerField(
|
||||
required=False,
|
||||
|
|
|
|||
|
|
@ -71,12 +71,14 @@ class DeviceComponentFilterForm(BootstrapMixin, CustomFieldModelFilterForm):
|
|||
region_id = DynamicModelMultipleChoiceField(
|
||||
queryset=Region.objects.all(),
|
||||
required=False,
|
||||
label=_('Region')
|
||||
label=_('Region'),
|
||||
fetch_trigger='open'
|
||||
)
|
||||
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(),
|
||||
|
|
@ -84,7 +86,8 @@ class DeviceComponentFilterForm(BootstrapMixin, CustomFieldModelFilterForm):
|
|||
query_params={
|
||||
'region_id': '$region_id'
|
||||
},
|
||||
label=_('Site')
|
||||
label=_('Site'),
|
||||
fetch_trigger='open'
|
||||
)
|
||||
device_id = DynamicModelMultipleChoiceField(
|
||||
queryset=Device.objects.all(),
|
||||
|
|
@ -92,7 +95,8 @@ class DeviceComponentFilterForm(BootstrapMixin, CustomFieldModelFilterForm):
|
|||
query_params={
|
||||
'site_id': '$site_id'
|
||||
},
|
||||
label=_('Device')
|
||||
label=_('Device'),
|
||||
fetch_trigger='open'
|
||||
)
|
||||
|
||||
|
||||
|
|
@ -457,17 +461,19 @@ class SiteFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldModelFilterFo
|
|||
status = forms.MultipleChoiceField(
|
||||
choices=SiteStatusChoices,
|
||||
required=False,
|
||||
widget=StaticSelectMultiple()
|
||||
widget=StaticSelectMultiple(),
|
||||
)
|
||||
region_id = DynamicModelMultipleChoiceField(
|
||||
queryset=Region.objects.all(),
|
||||
required=False,
|
||||
label=_('Region')
|
||||
label=_('Region'),
|
||||
fetch_trigger='open'
|
||||
)
|
||||
group_id = DynamicModelMultipleChoiceField(
|
||||
queryset=SiteGroup.objects.all(),
|
||||
required=False,
|
||||
label=_('Group')
|
||||
label=_('Group'),
|
||||
fetch_trigger='open'
|
||||
)
|
||||
tag = TagFilterField(model)
|
||||
|
||||
|
|
@ -565,7 +571,8 @@ class LocationFilterForm(BootstrapMixin, CustomFieldModelFilterForm):
|
|||
region_id = DynamicModelMultipleChoiceField(
|
||||
queryset=Region.objects.all(),
|
||||
required=False,
|
||||
label=_('Region')
|
||||
label=_('Region'),
|
||||
fetch_trigger='open'
|
||||
)
|
||||
site_id = DynamicModelMultipleChoiceField(
|
||||
queryset=Site.objects.all(),
|
||||
|
|
@ -573,7 +580,8 @@ class LocationFilterForm(BootstrapMixin, CustomFieldModelFilterForm):
|
|||
query_params={
|
||||
'region_id': '$region_id'
|
||||
},
|
||||
label=_('Site')
|
||||
label=_('Site'),
|
||||
fetch_trigger='open'
|
||||
)
|
||||
parent_id = DynamicModelMultipleChoiceField(
|
||||
queryset=Location.objects.all(),
|
||||
|
|
@ -582,7 +590,8 @@ class LocationFilterForm(BootstrapMixin, CustomFieldModelFilterForm):
|
|||
'region_id': '$region_id',
|
||||
'site_id': '$site_id',
|
||||
},
|
||||
label=_('Parent')
|
||||
label=_('Parent'),
|
||||
fetch_trigger='open'
|
||||
)
|
||||
|
||||
|
||||
|
|
@ -862,7 +871,8 @@ class RackFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldModelFilterFo
|
|||
region_id = DynamicModelMultipleChoiceField(
|
||||
queryset=Region.objects.all(),
|
||||
required=False,
|
||||
label=_('Region')
|
||||
label=_('Region'),
|
||||
fetch_trigger='open'
|
||||
)
|
||||
site_id = DynamicModelMultipleChoiceField(
|
||||
queryset=Site.objects.all(),
|
||||
|
|
@ -870,7 +880,8 @@ class RackFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldModelFilterFo
|
|||
query_params={
|
||||
'region_id': '$region_id'
|
||||
},
|
||||
label=_('Site')
|
||||
label=_('Site'),
|
||||
fetch_trigger='open'
|
||||
)
|
||||
location_id = DynamicModelMultipleChoiceField(
|
||||
queryset=Location.objects.all(),
|
||||
|
|
@ -879,7 +890,8 @@ class RackFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldModelFilterFo
|
|||
query_params={
|
||||
'site_id': '$site_id'
|
||||
},
|
||||
label=_('Location')
|
||||
label=_('Location'),
|
||||
fetch_trigger='open'
|
||||
)
|
||||
status = forms.MultipleChoiceField(
|
||||
choices=RackStatusChoices,
|
||||
|
|
@ -900,7 +912,8 @@ class RackFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldModelFilterFo
|
|||
queryset=RackRole.objects.all(),
|
||||
required=False,
|
||||
null_option='None',
|
||||
label=_('Role')
|
||||
label=_('Role'),
|
||||
fetch_trigger='open'
|
||||
)
|
||||
asset_tag = forms.CharField(
|
||||
required=False
|
||||
|
|
@ -923,7 +936,8 @@ class RackElevationFilterForm(RackFilterForm):
|
|||
query_params={
|
||||
'site_id': '$site_id',
|
||||
'location_id': '$location_id',
|
||||
}
|
||||
},
|
||||
fetch_trigger='open'
|
||||
)
|
||||
|
||||
|
||||
|
|
@ -937,14 +951,16 @@ class RackReservationForm(BootstrapMixin, TenancyForm, CustomFieldModelForm):
|
|||
required=False,
|
||||
initial_params={
|
||||
'sites': '$site'
|
||||
}
|
||||
},
|
||||
fetch_trigger='open'
|
||||
)
|
||||
site_group = DynamicModelChoiceField(
|
||||
queryset=SiteGroup.objects.all(),
|
||||
required=False,
|
||||
initial_params={
|
||||
'sites': '$site'
|
||||
}
|
||||
},
|
||||
fetch_trigger='open'
|
||||
)
|
||||
site = DynamicModelChoiceField(
|
||||
queryset=Site.objects.all(),
|
||||
|
|
@ -952,21 +968,24 @@ class RackReservationForm(BootstrapMixin, TenancyForm, CustomFieldModelForm):
|
|||
query_params={
|
||||
'region_id': '$region',
|
||||
'group_id': '$site_group',
|
||||
}
|
||||
},
|
||||
fetch_trigger='open'
|
||||
)
|
||||
location = DynamicModelChoiceField(
|
||||
queryset=Location.objects.all(),
|
||||
required=False,
|
||||
query_params={
|
||||
'site_id': '$site'
|
||||
}
|
||||
},
|
||||
fetch_trigger='open'
|
||||
)
|
||||
rack = DynamicModelChoiceField(
|
||||
queryset=Rack.objects.all(),
|
||||
query_params={
|
||||
'site_id': '$site',
|
||||
'location_id': '$location',
|
||||
}
|
||||
},
|
||||
fetch_trigger='open'
|
||||
)
|
||||
units = NumericArrayField(
|
||||
base_field=forms.IntegerField(),
|
||||
|
|
@ -980,7 +999,8 @@ class RackReservationForm(BootstrapMixin, TenancyForm, CustomFieldModelForm):
|
|||
)
|
||||
tags = DynamicModelMultipleChoiceField(
|
||||
queryset=Tag.objects.all(),
|
||||
required=False
|
||||
required=False,
|
||||
fetch_trigger='open'
|
||||
)
|
||||
|
||||
class Meta:
|
||||
|
|
@ -1080,7 +1100,8 @@ class RackReservationFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldMo
|
|||
region_id = DynamicModelMultipleChoiceField(
|
||||
queryset=Region.objects.all(),
|
||||
required=False,
|
||||
label=_('Region')
|
||||
label=_('Region'),
|
||||
fetch_trigger='open'
|
||||
)
|
||||
site_id = DynamicModelMultipleChoiceField(
|
||||
queryset=Site.objects.all(),
|
||||
|
|
@ -1088,13 +1109,15 @@ class RackReservationFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldMo
|
|||
query_params={
|
||||
'region_id': '$region_id'
|
||||
},
|
||||
label=_('Region')
|
||||
label=_('Region'),
|
||||
fetch_trigger='open'
|
||||
)
|
||||
location_id = DynamicModelMultipleChoiceField(
|
||||
queryset=Location.objects.prefetch_related('site'),
|
||||
required=False,
|
||||
label=_('Location'),
|
||||
null_option='None'
|
||||
null_option='None',
|
||||
fetch_trigger='open'
|
||||
)
|
||||
user_id = DynamicModelMultipleChoiceField(
|
||||
queryset=User.objects.all(),
|
||||
|
|
@ -1102,7 +1125,8 @@ class RackReservationFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldMo
|
|||
label=_('User'),
|
||||
widget=APISelectMultiple(
|
||||
api_url='/api/users/users/',
|
||||
)
|
||||
),
|
||||
fetch_trigger='open'
|
||||
)
|
||||
tag = TagFilterField(model)
|
||||
|
||||
|
|
@ -1231,7 +1255,8 @@ class DeviceTypeFilterForm(BootstrapMixin, CustomFieldModelFilterForm):
|
|||
manufacturer_id = DynamicModelMultipleChoiceField(
|
||||
queryset=Manufacturer.objects.all(),
|
||||
required=False,
|
||||
label=_('Manufacturer')
|
||||
label=_('Manufacturer'),
|
||||
fetch_trigger='open'
|
||||
)
|
||||
subdevice_role = forms.MultipleChoiceField(
|
||||
choices=add_blank_choice(SubdeviceRoleChoices),
|
||||
|
|
@ -2036,7 +2061,8 @@ class PlatformFilterForm(BootstrapMixin, CustomFieldModelFilterForm):
|
|||
manufacturer_id = DynamicModelMultipleChoiceField(
|
||||
queryset=Manufacturer.objects.all(),
|
||||
required=False,
|
||||
label=_('Manufacturer')
|
||||
label=_('Manufacturer'),
|
||||
fetch_trigger='open'
|
||||
)
|
||||
|
||||
|
||||
|
|
@ -2452,7 +2478,8 @@ class DeviceFilterForm(BootstrapMixin, LocalConfigContextFilterForm, TenancyFilt
|
|||
region_id = DynamicModelMultipleChoiceField(
|
||||
queryset=Region.objects.all(),
|
||||
required=False,
|
||||
label=_('Region')
|
||||
label=_('Region'),
|
||||
fetch_trigger='open'
|
||||
)
|
||||
site_id = DynamicModelMultipleChoiceField(
|
||||
queryset=Site.objects.all(),
|
||||
|
|
@ -2460,7 +2487,8 @@ class DeviceFilterForm(BootstrapMixin, LocalConfigContextFilterForm, TenancyFilt
|
|||
query_params={
|
||||
'region_id': '$region_id'
|
||||
},
|
||||
label=_('Site')
|
||||
label=_('Site'),
|
||||
fetch_trigger='open'
|
||||
)
|
||||
location_id = DynamicModelMultipleChoiceField(
|
||||
queryset=Location.objects.all(),
|
||||
|
|
@ -2469,7 +2497,8 @@ class DeviceFilterForm(BootstrapMixin, LocalConfigContextFilterForm, TenancyFilt
|
|||
query_params={
|
||||
'site_id': '$site_id'
|
||||
},
|
||||
label=_('Location')
|
||||
label=_('Location'),
|
||||
fetch_trigger='open'
|
||||
)
|
||||
rack_id = DynamicModelMultipleChoiceField(
|
||||
queryset=Rack.objects.all(),
|
||||
|
|
@ -2479,17 +2508,20 @@ class DeviceFilterForm(BootstrapMixin, LocalConfigContextFilterForm, TenancyFilt
|
|||
'site_id': '$site_id',
|
||||
'location_id': '$location_id',
|
||||
},
|
||||
label=_('Rack')
|
||||
label=_('Rack'),
|
||||
fetch_trigger='open'
|
||||
)
|
||||
role_id = DynamicModelMultipleChoiceField(
|
||||
queryset=DeviceRole.objects.all(),
|
||||
required=False,
|
||||
label=_('Role')
|
||||
label=_('Role'),
|
||||
fetch_trigger='open'
|
||||
)
|
||||
manufacturer_id = DynamicModelMultipleChoiceField(
|
||||
queryset=Manufacturer.objects.all(),
|
||||
required=False,
|
||||
label=_('Manufacturer')
|
||||
label=_('Manufacturer'),
|
||||
fetch_trigger='open'
|
||||
)
|
||||
device_type_id = DynamicModelMultipleChoiceField(
|
||||
queryset=DeviceType.objects.all(),
|
||||
|
|
@ -2497,13 +2529,15 @@ class DeviceFilterForm(BootstrapMixin, LocalConfigContextFilterForm, TenancyFilt
|
|||
query_params={
|
||||
'manufacturer_id': '$manufacturer_id'
|
||||
},
|
||||
label=_('Model')
|
||||
label=_('Model'),
|
||||
fetch_trigger='open'
|
||||
)
|
||||
platform_id = DynamicModelMultipleChoiceField(
|
||||
queryset=Platform.objects.all(),
|
||||
required=False,
|
||||
null_option='None',
|
||||
label=_('Platform')
|
||||
label=_('Platform'),
|
||||
fetch_trigger='open'
|
||||
)
|
||||
status = forms.MultipleChoiceField(
|
||||
choices=DeviceStatusChoices,
|
||||
|
|
@ -3987,7 +4021,8 @@ class InventoryItemFilterForm(DeviceComponentFilterForm):
|
|||
manufacturer_id = DynamicModelMultipleChoiceField(
|
||||
queryset=Manufacturer.objects.all(),
|
||||
required=False,
|
||||
label=_('Manufacturer')
|
||||
label=_('Manufacturer'),
|
||||
fetch_trigger='open'
|
||||
)
|
||||
serial = forms.CharField(
|
||||
required=False
|
||||
|
|
@ -4461,7 +4496,8 @@ class CableFilterForm(BootstrapMixin, CustomFieldModelFilterForm):
|
|||
region_id = DynamicModelMultipleChoiceField(
|
||||
queryset=Region.objects.all(),
|
||||
required=False,
|
||||
label=_('Region')
|
||||
label=_('Region'),
|
||||
fetch_trigger='open'
|
||||
)
|
||||
site_id = DynamicModelMultipleChoiceField(
|
||||
queryset=Site.objects.all(),
|
||||
|
|
@ -4469,12 +4505,14 @@ class CableFilterForm(BootstrapMixin, CustomFieldModelFilterForm):
|
|||
query_params={
|
||||
'region_id': '$region_id'
|
||||
},
|
||||
label=_('Site')
|
||||
label=_('Site'),
|
||||
fetch_trigger='open'
|
||||
)
|
||||
tenant_id = DynamicModelMultipleChoiceField(
|
||||
queryset=Tenant.objects.all(),
|
||||
required=False,
|
||||
label=_('Tenant')
|
||||
label=_('Tenant'),
|
||||
fetch_trigger='open'
|
||||
)
|
||||
rack_id = DynamicModelMultipleChoiceField(
|
||||
queryset=Rack.objects.all(),
|
||||
|
|
@ -4483,7 +4521,8 @@ class CableFilterForm(BootstrapMixin, CustomFieldModelFilterForm):
|
|||
null_option='None',
|
||||
query_params={
|
||||
'site_id': '$site_id'
|
||||
}
|
||||
},
|
||||
fetch_trigger='open'
|
||||
)
|
||||
type = forms.MultipleChoiceField(
|
||||
choices=add_blank_choice(CableTypeChoices),
|
||||
|
|
@ -4506,7 +4545,8 @@ class CableFilterForm(BootstrapMixin, CustomFieldModelFilterForm):
|
|||
'tenant_id': '$tenant_id',
|
||||
'rack_id': '$rack_id',
|
||||
},
|
||||
label=_('Device')
|
||||
label=_('Device'),
|
||||
fetch_trigger='open'
|
||||
)
|
||||
tag = TagFilterField(model)
|
||||
|
||||
|
|
@ -4519,7 +4559,8 @@ class ConsoleConnectionFilterForm(BootstrapMixin, forms.Form):
|
|||
region_id = DynamicModelMultipleChoiceField(
|
||||
queryset=Region.objects.all(),
|
||||
required=False,
|
||||
label=_('Region')
|
||||
label=_('Region'),
|
||||
fetch_trigger='open'
|
||||
)
|
||||
site_id = DynamicModelMultipleChoiceField(
|
||||
queryset=Site.objects.all(),
|
||||
|
|
@ -4527,7 +4568,8 @@ class ConsoleConnectionFilterForm(BootstrapMixin, forms.Form):
|
|||
query_params={
|
||||
'region_id': '$region_id'
|
||||
},
|
||||
label=_('Site')
|
||||
label=_('Site'),
|
||||
fetch_trigger='open'
|
||||
)
|
||||
device_id = DynamicModelMultipleChoiceField(
|
||||
queryset=Device.objects.all(),
|
||||
|
|
@ -4535,7 +4577,8 @@ class ConsoleConnectionFilterForm(BootstrapMixin, forms.Form):
|
|||
query_params={
|
||||
'site_id': '$site_id'
|
||||
},
|
||||
label=_('Device')
|
||||
label=_('Device'),
|
||||
fetch_trigger='open'
|
||||
)
|
||||
|
||||
|
||||
|
|
@ -4543,7 +4586,8 @@ class PowerConnectionFilterForm(BootstrapMixin, forms.Form):
|
|||
region_id = DynamicModelMultipleChoiceField(
|
||||
queryset=Region.objects.all(),
|
||||
required=False,
|
||||
label=_('Region')
|
||||
label=_('Region'),
|
||||
fetch_trigger='open'
|
||||
)
|
||||
site_id = DynamicModelMultipleChoiceField(
|
||||
queryset=Site.objects.all(),
|
||||
|
|
@ -4551,7 +4595,8 @@ class PowerConnectionFilterForm(BootstrapMixin, forms.Form):
|
|||
query_params={
|
||||
'region_id': '$region_id'
|
||||
},
|
||||
label=_('Site')
|
||||
label=_('Site'),
|
||||
fetch_trigger='open'
|
||||
)
|
||||
device_id = DynamicModelMultipleChoiceField(
|
||||
queryset=Device.objects.all(),
|
||||
|
|
@ -4559,7 +4604,8 @@ class PowerConnectionFilterForm(BootstrapMixin, forms.Form):
|
|||
query_params={
|
||||
'site_id': '$site_id'
|
||||
},
|
||||
label=_('Device')
|
||||
label=_('Device'),
|
||||
fetch_trigger='open'
|
||||
)
|
||||
|
||||
|
||||
|
|
@ -4567,7 +4613,8 @@ class InterfaceConnectionFilterForm(BootstrapMixin, forms.Form):
|
|||
region_id = DynamicModelMultipleChoiceField(
|
||||
queryset=Region.objects.all(),
|
||||
required=False,
|
||||
label=_('Region')
|
||||
label=_('Region'),
|
||||
fetch_trigger='open'
|
||||
)
|
||||
site_id = DynamicModelMultipleChoiceField(
|
||||
queryset=Site.objects.all(),
|
||||
|
|
@ -4575,7 +4622,8 @@ class InterfaceConnectionFilterForm(BootstrapMixin, forms.Form):
|
|||
query_params={
|
||||
'region_id': '$region_id'
|
||||
},
|
||||
label=_('Site')
|
||||
label=_('Site'),
|
||||
fetch_trigger='open'
|
||||
)
|
||||
device_id = DynamicModelMultipleChoiceField(
|
||||
queryset=Device.objects.all(),
|
||||
|
|
@ -4583,7 +4631,8 @@ class InterfaceConnectionFilterForm(BootstrapMixin, forms.Form):
|
|||
query_params={
|
||||
'site_id': '$site_id'
|
||||
},
|
||||
label=_('Device')
|
||||
label=_('Device'),
|
||||
fetch_trigger='open'
|
||||
)
|
||||
|
||||
|
||||
|
|
@ -4837,12 +4886,14 @@ class VirtualChassisFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldMod
|
|||
region_id = DynamicModelMultipleChoiceField(
|
||||
queryset=Region.objects.all(),
|
||||
required=False,
|
||||
label=_('Region')
|
||||
label=_('Region'),
|
||||
fetch_trigger='open'
|
||||
)
|
||||
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(),
|
||||
|
|
@ -4850,7 +4901,8 @@ class VirtualChassisFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldMod
|
|||
query_params={
|
||||
'region_id': '$region_id'
|
||||
},
|
||||
label=_('Site')
|
||||
label=_('Site'),
|
||||
fetch_trigger='open'
|
||||
)
|
||||
tag = TagFilterField(model)
|
||||
|
||||
|
|
@ -4973,12 +5025,14 @@ class PowerPanelFilterForm(BootstrapMixin, CustomFieldModelFilterForm):
|
|||
region_id = DynamicModelMultipleChoiceField(
|
||||
queryset=Region.objects.all(),
|
||||
required=False,
|
||||
label=_('Region')
|
||||
label=_('Region'),
|
||||
fetch_trigger='open'
|
||||
)
|
||||
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(),
|
||||
|
|
@ -4986,7 +5040,8 @@ class PowerPanelFilterForm(BootstrapMixin, CustomFieldModelFilterForm):
|
|||
query_params={
|
||||
'region_id': '$region_id'
|
||||
},
|
||||
label=_('Site')
|
||||
label=_('Site'),
|
||||
fetch_trigger='open'
|
||||
)
|
||||
location_id = DynamicModelMultipleChoiceField(
|
||||
queryset=Location.objects.all(),
|
||||
|
|
@ -4995,7 +5050,8 @@ class PowerPanelFilterForm(BootstrapMixin, CustomFieldModelFilterForm):
|
|||
query_params={
|
||||
'site_id': '$site_id'
|
||||
},
|
||||
label=_('Location')
|
||||
label=_('Location'),
|
||||
fetch_trigger='open'
|
||||
)
|
||||
tag = TagFilterField(model)
|
||||
|
||||
|
|
@ -5213,12 +5269,14 @@ class PowerFeedFilterForm(BootstrapMixin, CustomFieldModelFilterForm):
|
|||
region_id = DynamicModelMultipleChoiceField(
|
||||
queryset=Region.objects.all(),
|
||||
required=False,
|
||||
label=_('Region')
|
||||
label=_('Region'),
|
||||
fetch_trigger='open'
|
||||
)
|
||||
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(),
|
||||
|
|
@ -5226,7 +5284,8 @@ class PowerFeedFilterForm(BootstrapMixin, CustomFieldModelFilterForm):
|
|||
query_params={
|
||||
'region_id': '$region_id'
|
||||
},
|
||||
label=_('Site')
|
||||
label=_('Site'),
|
||||
fetch_trigger='open'
|
||||
)
|
||||
power_panel_id = DynamicModelMultipleChoiceField(
|
||||
queryset=PowerPanel.objects.all(),
|
||||
|
|
@ -5235,7 +5294,8 @@ class PowerFeedFilterForm(BootstrapMixin, CustomFieldModelFilterForm):
|
|||
query_params={
|
||||
'site_id': '$site_id'
|
||||
},
|
||||
label=_('Power panel')
|
||||
label=_('Power panel'),
|
||||
fetch_trigger='open'
|
||||
)
|
||||
rack_id = DynamicModelMultipleChoiceField(
|
||||
queryset=Rack.objects.all(),
|
||||
|
|
@ -5244,7 +5304,8 @@ class PowerFeedFilterForm(BootstrapMixin, CustomFieldModelFilterForm):
|
|||
query_params={
|
||||
'site_id': '$site_id'
|
||||
},
|
||||
label=_('Rack')
|
||||
label=_('Rack'),
|
||||
fetch_trigger='open'
|
||||
)
|
||||
status = forms.MultipleChoiceField(
|
||||
choices=PowerFeedStatusChoices,
|
||||
|
|
|
|||
|
|
@ -676,58 +676,69 @@ class ConfigContextFilterForm(BootstrapMixin, forms.Form):
|
|||
region_id = DynamicModelMultipleChoiceField(
|
||||
queryset=Region.objects.all(),
|
||||
required=False,
|
||||
label=_('Regions')
|
||||
label=_('Regions'),
|
||||
fetch_trigger='open'
|
||||
)
|
||||
site_group_id = DynamicModelMultipleChoiceField(
|
||||
queryset=SiteGroup.objects.all(),
|
||||
required=False,
|
||||
label=_('Site groups')
|
||||
label=_('Site groups'),
|
||||
fetch_trigger='open'
|
||||
)
|
||||
site_id = DynamicModelMultipleChoiceField(
|
||||
queryset=Site.objects.all(),
|
||||
required=False,
|
||||
label=_('Sites')
|
||||
label=_('Sites'),
|
||||
fetch_trigger='open'
|
||||
)
|
||||
device_type_id = DynamicModelMultipleChoiceField(
|
||||
queryset=DeviceType.objects.all(),
|
||||
required=False,
|
||||
label=_('Device types')
|
||||
label=_('Device types'),
|
||||
fetch_trigger='open'
|
||||
)
|
||||
role_id = DynamicModelMultipleChoiceField(
|
||||
queryset=DeviceRole.objects.all(),
|
||||
required=False,
|
||||
label=_('Roles')
|
||||
label=_('Roles'),
|
||||
fetch_trigger='open'
|
||||
)
|
||||
platform_id = DynamicModelMultipleChoiceField(
|
||||
queryset=Platform.objects.all(),
|
||||
required=False,
|
||||
label=_('Platforms')
|
||||
label=_('Platforms'),
|
||||
fetch_trigger='open'
|
||||
)
|
||||
cluster_group_id = DynamicModelMultipleChoiceField(
|
||||
queryset=ClusterGroup.objects.all(),
|
||||
required=False,
|
||||
label=_('Cluster groups')
|
||||
label=_('Cluster groups'),
|
||||
fetch_trigger='open'
|
||||
)
|
||||
cluster_id = DynamicModelMultipleChoiceField(
|
||||
queryset=Cluster.objects.all(),
|
||||
required=False,
|
||||
label=_('Clusters')
|
||||
label=_('Clusters'),
|
||||
fetch_trigger='open'
|
||||
)
|
||||
tenant_group_id = DynamicModelMultipleChoiceField(
|
||||
queryset=TenantGroup.objects.all(),
|
||||
required=False,
|
||||
label=_('Tenant groups')
|
||||
label=_('Tenant groups'),
|
||||
fetch_trigger='open'
|
||||
)
|
||||
tenant_id = DynamicModelMultipleChoiceField(
|
||||
queryset=Tenant.objects.all(),
|
||||
required=False,
|
||||
label=_('Tenant')
|
||||
label=_('Tenant'),
|
||||
fetch_trigger='open'
|
||||
)
|
||||
tag = DynamicModelMultipleChoiceField(
|
||||
queryset=Tag.objects.all(),
|
||||
to_field_name='slug',
|
||||
required=False,
|
||||
label=_('Tags')
|
||||
label=_('Tags'),
|
||||
fetch_trigger='open'
|
||||
)
|
||||
|
||||
|
||||
|
|
@ -820,7 +831,8 @@ class JournalEntryFilterForm(BootstrapMixin, forms.Form):
|
|||
label=_('User'),
|
||||
widget=APISelectMultiple(
|
||||
api_url='/api/users/users/',
|
||||
)
|
||||
),
|
||||
fetch_trigger='open'
|
||||
)
|
||||
assigned_object_type_id = DynamicModelMultipleChoiceField(
|
||||
queryset=ContentType.objects.all(),
|
||||
|
|
@ -828,7 +840,8 @@ class JournalEntryFilterForm(BootstrapMixin, forms.Form):
|
|||
label=_('Object Type'),
|
||||
widget=APISelectMultiple(
|
||||
api_url='/api/extras/content-types/',
|
||||
)
|
||||
),
|
||||
fetch_trigger='open'
|
||||
)
|
||||
kind = forms.ChoiceField(
|
||||
choices=add_blank_choice(JournalEntryKindChoices),
|
||||
|
|
@ -868,7 +881,8 @@ class ObjectChangeFilterForm(BootstrapMixin, forms.Form):
|
|||
label=_('User'),
|
||||
widget=APISelectMultiple(
|
||||
api_url='/api/users/users/',
|
||||
)
|
||||
),
|
||||
fetch_trigger='open'
|
||||
)
|
||||
changed_object_type_id = DynamicModelMultipleChoiceField(
|
||||
queryset=ContentType.objects.all(),
|
||||
|
|
@ -876,7 +890,8 @@ class ObjectChangeFilterForm(BootstrapMixin, forms.Form):
|
|||
label=_('Object Type'),
|
||||
widget=APISelectMultiple(
|
||||
api_url='/api/extras/content-types/',
|
||||
)
|
||||
),
|
||||
fetch_trigger='open'
|
||||
)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -115,12 +115,14 @@ class VRFFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldModelFilterFor
|
|||
import_target_id = DynamicModelMultipleChoiceField(
|
||||
queryset=RouteTarget.objects.all(),
|
||||
required=False,
|
||||
label=_('Import targets')
|
||||
label=_('Import targets'),
|
||||
fetch_trigger='open'
|
||||
)
|
||||
export_target_id = DynamicModelMultipleChoiceField(
|
||||
queryset=RouteTarget.objects.all(),
|
||||
required=False,
|
||||
label=_('Export targets')
|
||||
label=_('Export targets'),
|
||||
fetch_trigger='open'
|
||||
)
|
||||
tag = TagFilterField(model)
|
||||
|
||||
|
|
@ -185,12 +187,14 @@ class RouteTargetFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldModelF
|
|||
importing_vrf_id = DynamicModelMultipleChoiceField(
|
||||
queryset=VRF.objects.all(),
|
||||
required=False,
|
||||
label=_('Imported by VRF')
|
||||
label=_('Imported by VRF'),
|
||||
fetch_trigger='open'
|
||||
)
|
||||
exporting_vrf_id = DynamicModelMultipleChoiceField(
|
||||
queryset=VRF.objects.all(),
|
||||
required=False,
|
||||
label=_('Exported by VRF')
|
||||
label=_('Exported by VRF'),
|
||||
fetch_trigger='open'
|
||||
)
|
||||
tag = TagFilterField(model)
|
||||
|
||||
|
|
@ -345,7 +349,8 @@ class AggregateFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldModelFil
|
|||
rir_id = DynamicModelMultipleChoiceField(
|
||||
queryset=RIR.objects.all(),
|
||||
required=False,
|
||||
label=_('RIR')
|
||||
label=_('RIR'),
|
||||
fetch_trigger='open'
|
||||
)
|
||||
tag = TagFilterField(model)
|
||||
|
||||
|
|
@ -642,12 +647,14 @@ class PrefixFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldModelFilter
|
|||
queryset=VRF.objects.all(),
|
||||
required=False,
|
||||
label=_('Assigned VRF'),
|
||||
null_option='Global'
|
||||
null_option='Global',
|
||||
fetch_trigger='open'
|
||||
)
|
||||
present_in_vrf_id = DynamicModelChoiceField(
|
||||
queryset=VRF.objects.all(),
|
||||
required=False,
|
||||
label=_('Present in VRF')
|
||||
label=_('Present in VRF'),
|
||||
fetch_trigger='open'
|
||||
)
|
||||
status = forms.MultipleChoiceField(
|
||||
choices=PrefixStatusChoices,
|
||||
|
|
@ -657,12 +664,14 @@ class PrefixFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldModelFilter
|
|||
region_id = DynamicModelMultipleChoiceField(
|
||||
queryset=Region.objects.all(),
|
||||
required=False,
|
||||
label=_('Region')
|
||||
label=_('Region'),
|
||||
fetch_trigger='open'
|
||||
)
|
||||
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(),
|
||||
|
|
@ -671,13 +680,15 @@ class PrefixFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldModelFilter
|
|||
query_params={
|
||||
'region_id': '$region_id'
|
||||
},
|
||||
label=_('Site')
|
||||
label=_('Site'),
|
||||
fetch_trigger='open'
|
||||
)
|
||||
role_id = DynamicModelMultipleChoiceField(
|
||||
queryset=Role.objects.all(),
|
||||
required=False,
|
||||
null_option='None',
|
||||
label=_('Role')
|
||||
label=_('Role'),
|
||||
fetch_trigger='open'
|
||||
)
|
||||
is_pool = forms.NullBooleanField(
|
||||
required=False,
|
||||
|
|
@ -818,7 +829,8 @@ class IPRangeFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldModelFilte
|
|||
queryset=VRF.objects.all(),
|
||||
required=False,
|
||||
label=_('Assigned VRF'),
|
||||
null_option='Global'
|
||||
null_option='Global',
|
||||
fetch_trigger='open'
|
||||
)
|
||||
status = forms.MultipleChoiceField(
|
||||
choices=PrefixStatusChoices,
|
||||
|
|
@ -829,7 +841,8 @@ class IPRangeFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldModelFilte
|
|||
queryset=Role.objects.all(),
|
||||
required=False,
|
||||
null_option='None',
|
||||
label=_('Role')
|
||||
label=_('Role'),
|
||||
fetch_trigger='open'
|
||||
)
|
||||
tag = TagFilterField(model)
|
||||
|
||||
|
|
@ -1265,12 +1278,14 @@ class IPAddressFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldModelFil
|
|||
queryset=VRF.objects.all(),
|
||||
required=False,
|
||||
label=_('Assigned VRF'),
|
||||
null_option='Global'
|
||||
null_option='Global',
|
||||
fetch_trigger='open'
|
||||
)
|
||||
present_in_vrf_id = DynamicModelChoiceField(
|
||||
queryset=VRF.objects.all(),
|
||||
required=False,
|
||||
label=_('Present in VRF')
|
||||
label=_('Present in VRF'),
|
||||
fetch_trigger='open'
|
||||
)
|
||||
status = forms.MultipleChoiceField(
|
||||
choices=IPAddressStatusChoices,
|
||||
|
|
@ -1439,27 +1454,32 @@ class VLANGroupFilterForm(BootstrapMixin, forms.Form):
|
|||
region = DynamicModelMultipleChoiceField(
|
||||
queryset=Region.objects.all(),
|
||||
required=False,
|
||||
label=_('Region')
|
||||
label=_('Region'),
|
||||
fetch_trigger='open'
|
||||
)
|
||||
sitegroup = DynamicModelMultipleChoiceField(
|
||||
queryset=SiteGroup.objects.all(),
|
||||
required=False,
|
||||
label=_('Site group')
|
||||
label=_('Site group'),
|
||||
fetch_trigger='open'
|
||||
)
|
||||
site = DynamicModelMultipleChoiceField(
|
||||
queryset=Site.objects.all(),
|
||||
required=False,
|
||||
label=_('Site')
|
||||
label=_('Site'),
|
||||
fetch_trigger='open'
|
||||
)
|
||||
location = DynamicModelMultipleChoiceField(
|
||||
queryset=Location.objects.all(),
|
||||
required=False,
|
||||
label=_('Location')
|
||||
label=_('Location'),
|
||||
fetch_trigger='open'
|
||||
)
|
||||
rack = DynamicModelMultipleChoiceField(
|
||||
queryset=Rack.objects.all(),
|
||||
required=False,
|
||||
label=_('Rack')
|
||||
label=_('Rack'),
|
||||
fetch_trigger='open'
|
||||
)
|
||||
|
||||
|
||||
|
|
@ -1652,12 +1672,14 @@ class VLANFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldModelFilterFo
|
|||
region_id = DynamicModelMultipleChoiceField(
|
||||
queryset=Region.objects.all(),
|
||||
required=False,
|
||||
label=_('Region')
|
||||
label=_('Region'),
|
||||
fetch_trigger='open'
|
||||
)
|
||||
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(),
|
||||
|
|
@ -1666,7 +1688,8 @@ class VLANFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldModelFilterFo
|
|||
query_params={
|
||||
'region': '$region'
|
||||
},
|
||||
label=_('Site')
|
||||
label=_('Site'),
|
||||
fetch_trigger='open'
|
||||
)
|
||||
group_id = DynamicModelMultipleChoiceField(
|
||||
queryset=VLANGroup.objects.all(),
|
||||
|
|
@ -1675,7 +1698,8 @@ class VLANFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldModelFilterFo
|
|||
query_params={
|
||||
'region': '$region'
|
||||
},
|
||||
label=_('VLAN group')
|
||||
label=_('VLAN group'),
|
||||
fetch_trigger='open'
|
||||
)
|
||||
status = forms.MultipleChoiceField(
|
||||
choices=VLANStatusChoices,
|
||||
|
|
@ -1686,7 +1710,8 @@ class VLANFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldModelFilterFo
|
|||
queryset=Role.objects.all(),
|
||||
required=False,
|
||||
null_option='None',
|
||||
label=_('Role')
|
||||
label=_('Role'),
|
||||
fetch_trigger='open'
|
||||
)
|
||||
tag = TagFilterField(model)
|
||||
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -2,7 +2,7 @@ import queryString from 'query-string';
|
|||
import { readableColor } from 'color2k';
|
||||
import SlimSelect from 'slim-select';
|
||||
import { createToast } from '../bs';
|
||||
import { hasUrl, hasExclusions } from './util';
|
||||
import { hasUrl, hasExclusions, isTrigger } from './util';
|
||||
import {
|
||||
isTruthy,
|
||||
hasError,
|
||||
|
|
@ -10,6 +10,7 @@ import {
|
|||
getApiData,
|
||||
isApiError,
|
||||
getElements,
|
||||
createElement,
|
||||
findFirstAdjacent,
|
||||
} from '../util';
|
||||
|
||||
|
|
@ -17,6 +18,20 @@ import type { Option } from 'slim-select/dist/data';
|
|||
|
||||
type QueryFilter = Map<string, string | number | boolean>;
|
||||
|
||||
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`.
|
||||
|
|
@ -57,6 +72,17 @@ class APISelect {
|
|||
*/
|
||||
public readonly placeholder: string;
|
||||
|
||||
/**
|
||||
* Event that will initiate the API call to NetBox to load option data. By default, the trigger
|
||||
* is `'load'`, so data will be fetched when the element renders on the page.
|
||||
*/
|
||||
private readonly trigger: Trigger;
|
||||
|
||||
/**
|
||||
* If `true`, a refresh button will be added next to the search/filter `<input/>` element.
|
||||
*/
|
||||
private readonly allowRefresh: boolean = true;
|
||||
|
||||
/**
|
||||
* Event to be dispatched when dependent fields' values change.
|
||||
*/
|
||||
|
|
@ -153,6 +179,7 @@ class APISelect {
|
|||
allowDeselect: true,
|
||||
deselectLabel: `<i class="mdi mdi-close-circle" style="color:currentColor;"></i>`,
|
||||
placeholder: this.placeholder,
|
||||
searchPlaceholder: 'Filter',
|
||||
onChange: () => this.handleSlimChange(),
|
||||
});
|
||||
|
||||
|
|
@ -186,20 +213,44 @@ class APISelect {
|
|||
// Initialize controlling elements.
|
||||
this.initResetButton();
|
||||
|
||||
// Add the refresh button to the search element.
|
||||
this.initRefreshButton();
|
||||
|
||||
// Add dependency event listeners.
|
||||
this.addEventListeners();
|
||||
|
||||
// Determine if the fetch trigger has been set.
|
||||
const triggerAttr = this.base.getAttribute('data-fetch-trigger');
|
||||
|
||||
// Determine if this element is part of collapsible element.
|
||||
const collapse = this.base.closest('.content-container .collapse');
|
||||
if (collapse !== null) {
|
||||
// If this element is part of a collapsible element, only load the data when the
|
||||
// collapsible element is shown.
|
||||
// See: https://getbootstrap.com/docs/5.0/components/collapse/#events
|
||||
collapse.addEventListener('show.bs.collapse', () => this.loadData());
|
||||
collapse.addEventListener('hide.bs.collapse', () => this.resetOptions());
|
||||
|
||||
if (isTrigger(triggerAttr)) {
|
||||
this.trigger = triggerAttr;
|
||||
} else if (collapse !== null) {
|
||||
this.trigger = 'collapse';
|
||||
} else {
|
||||
// Otherwise, load the data on render.
|
||||
Promise.all([this.loadData()]);
|
||||
this.trigger = 'load';
|
||||
}
|
||||
|
||||
switch (this.trigger) {
|
||||
case 'collapse':
|
||||
if (collapse !== null) {
|
||||
// If this element is part of a collapsible element, only load the data when the
|
||||
// collapsible element is shown.
|
||||
// See: https://getbootstrap.com/docs/5.0/components/collapse/#events
|
||||
collapse.addEventListener('show.bs.collapse', () => this.loadData());
|
||||
collapse.addEventListener('hide.bs.collapse', () => this.resetOptions());
|
||||
}
|
||||
break;
|
||||
case 'open':
|
||||
// If the trigger is 'open', only load API data when the select element is opened.
|
||||
this.slim.beforeOpen = () => this.loadData();
|
||||
break;
|
||||
case 'load':
|
||||
// Otherwise, load the data immediately.
|
||||
Promise.all([this.loadData()]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -713,21 +764,37 @@ class APISelect {
|
|||
}
|
||||
|
||||
/**
|
||||
* Initialize any adjacent reset buttons so that when clicked, the instance's selected value is cleared.
|
||||
* Initialize any adjacent reset buttons so that when clicked, the page is reloaded without
|
||||
* query parameters.
|
||||
*/
|
||||
private initResetButton(): void {
|
||||
const resetButton = findFirstAdjacent<HTMLButtonElement>(this.base, 'button[data-reset-select');
|
||||
const resetButton = findFirstAdjacent<HTMLButtonElement>(
|
||||
this.base,
|
||||
'button[data-reset-select]',
|
||||
);
|
||||
if (resetButton !== null) {
|
||||
resetButton.addEventListener('click', () => {
|
||||
this.base.value = '';
|
||||
if (this.base.multiple) {
|
||||
this.slim.setSelected([]);
|
||||
} else {
|
||||
this.slim.setSelected('');
|
||||
}
|
||||
window.location.assign(window.location.origin + window.location.pathname);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a refresh button to the search container element. When clicked, the API data will be
|
||||
* reloaded.
|
||||
*/
|
||||
private initRefreshButton(): void {
|
||||
if (this.allowRefresh) {
|
||||
const refreshButton = createElement(
|
||||
'button',
|
||||
{ type: 'button' },
|
||||
['btn', 'btn-sm', 'btn-ghost-dark'],
|
||||
[createElement('i', {}, ['mdi', 'mdi-reload'])],
|
||||
);
|
||||
refreshButton.addEventListener('click', () => this.loadData());
|
||||
this.slim.slim.search.container.appendChild(refreshButton);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function initApiSelect() {
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
import type { Trigger } from './api';
|
||||
|
||||
/**
|
||||
* Determine if an element has the `data-url` attribute set.
|
||||
*/
|
||||
|
|
@ -15,3 +17,10 @@ export function hasExclusions(
|
|||
const exclude = el.getAttribute('data-query-param-exclude');
|
||||
return typeof exclude === 'string' && exclude !== '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if a trigger value is valid.
|
||||
*/
|
||||
export function isTrigger(value: unknown): value is Trigger {
|
||||
return typeof value === 'string' && ['load', 'open', 'collapse'].includes(value);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@
|
|||
}
|
||||
|
||||
* {
|
||||
transition: $transition-100ms-ease-in-out;
|
||||
transition: background-color, color 0.1s ease-in-out;
|
||||
}
|
||||
|
||||
.mw-25 {
|
||||
|
|
@ -302,8 +302,13 @@ span.profile-button .dropdown-menu {
|
|||
}
|
||||
}
|
||||
|
||||
div#advanced-search-content div.card div.card-body div.col:not(:last-child) {
|
||||
margin-right: 1rem;
|
||||
div#advanced-search-content {
|
||||
&.collapsing {
|
||||
transition: height 0.1s ease-in-out;
|
||||
}
|
||||
div.card div.card-body div.col:not(:last-child) {
|
||||
margin-right: 1rem;
|
||||
}
|
||||
}
|
||||
|
||||
body {
|
||||
|
|
@ -430,6 +435,7 @@ nav.search {
|
|||
background-color: var(--nbx-body-bg);
|
||||
// Don't overtake dropdowns
|
||||
z-index: 999;
|
||||
justify-content: center;
|
||||
form button.dropdown-toggle {
|
||||
border-color: $input-border-color;
|
||||
font-weight: $input-group-addon-font-weight;
|
||||
|
|
|
|||
|
|
@ -71,8 +71,8 @@ $spacing-s: $input-padding-x;
|
|||
border-color: currentColor;
|
||||
}
|
||||
}
|
||||
// Don't show the depth indicator outside of the menu.
|
||||
.placeholder .depth {
|
||||
// Don't show the depth indicator outside of the menu.
|
||||
display: none;
|
||||
}
|
||||
span.placeholder > *,
|
||||
|
|
@ -94,6 +94,11 @@ $spacing-s: $input-padding-x;
|
|||
.ss-value {
|
||||
border-radius: $badge-border-radius;
|
||||
color: var(--nbx-select-value-color);
|
||||
|
||||
// Don't show the depth indicator outside of the menu.
|
||||
.depth {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
.ss-add {
|
||||
|
|
@ -133,10 +138,34 @@ $spacing-s: $input-padding-x;
|
|||
opacity: 0.3;
|
||||
}
|
||||
}
|
||||
&::-webkit-scrollbar {
|
||||
right: 0;
|
||||
width: 4px;
|
||||
&:hover {
|
||||
opacity: 0.8;
|
||||
}
|
||||
}
|
||||
|
||||
&::-webkit-scrollbar-track {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
&::-webkit-scrollbar-thumb {
|
||||
right: 0;
|
||||
width: 2px;
|
||||
background-color: var(--nbx-sidebar-scroll);
|
||||
}
|
||||
}
|
||||
border-bottom-left-radius: $form-select-border-radius;
|
||||
border-bottom-right-radius: $form-select-border-radius;
|
||||
|
||||
.ss-search {
|
||||
padding-right: $spacer * 0.5;
|
||||
|
||||
button {
|
||||
margin-left: $spacer * 0.75;
|
||||
}
|
||||
|
||||
input[type='search'] {
|
||||
background-color: $form-select-bg;
|
||||
color: $input-color;
|
||||
|
|
|
|||
|
|
@ -1,42 +1,24 @@
|
|||
{% extends 'base/layout.html' %}
|
||||
{% load buttons %}
|
||||
{% load render_table from django_tables2 %}
|
||||
|
||||
{% block title %}{{ title }}{% endblock %}
|
||||
|
||||
{% block extra_controls %}{% export_button content_type %}{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
{% if filter_form %}
|
||||
<div class="col col-md-12 noprint">
|
||||
{% include 'inc/advanced_search.html' %}
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="row mb-3">
|
||||
<div class="col col-md-12">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<div class="row">
|
||||
<div class="col col-md-4 offset-md-8 d-flex noprint table-controls">
|
||||
<div class="input-group input-group-sm">
|
||||
<input type="text" class="form-control object-filter" placeholder="Filter" title="Filter text (regular expressions supported)" />
|
||||
{% if filter_form %}
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-sm btn-outline-dark"
|
||||
data-bs-toggle="collapse"
|
||||
data-bs-target="#advanced-search-content">
|
||||
Advanced Search
|
||||
</button>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
{% include 'inc/responsive_table.html' %}
|
||||
<div class="row mb-3">
|
||||
<div class="col col-md-7 col-lg-8 col-xl-9 col-xxl-10">
|
||||
{% include 'inc/table_controls.html' %}
|
||||
|
||||
<div class="table-responsive">
|
||||
{% render_table table 'inc/table.html' %}
|
||||
</div>
|
||||
|
||||
{% include 'inc/paginator.html' with paginator=table.paginator page=table.page %}
|
||||
</div>
|
||||
{% include 'inc/paginator.html' with paginator=table.paginator page=table.page %}
|
||||
{% if filter_form %}
|
||||
{% include 'inc/filter_list.html' %}
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
|
|
|||
|
|
@ -5,63 +5,58 @@
|
|||
{% block title %}Rack Elevations{% endblock %}
|
||||
|
||||
{% block controls %}
|
||||
<div class="container mb-2 mx-0">
|
||||
<div class="d-flex flex-wrap justify-content-end">
|
||||
<button type="button" class="btn btn-sm btn-outline-dark m-1" data-bs-toggle="collapse" data-bs-target="#advanced-search-content">
|
||||
Advanced Search
|
||||
</button>
|
||||
<button class="btn btn-sm btn-outline-dark toggle-images m-1" selected="selected">
|
||||
<span class="mdi mdi mdi-checkbox-marked-circle-outline" aria-hidden="true"></span> Show Images
|
||||
</button>
|
||||
<div class="btn-group btn-group-sm m-1" role="group">
|
||||
<a href="{% url 'dcim:rack_elevation_list' %}{% querystring request face='front' %}" class="btn btn-outline-secondary{% if rack_face == 'front' %} active{% endif %}">Front</a>
|
||||
<a href="{% url 'dcim:rack_elevation_list' %}{% querystring request face='rear' %}" class="btn btn-outline-secondary{% if rack_face == 'rear' %} active{% endif %}">Rear</a>
|
||||
</div>
|
||||
<div class="btn-group btn-group-sm m-1" role="group">
|
||||
<a href="{% url 'dcim:rack_elevation_list' %}{% querystring request reverse=None %}" class="btn btn-outline-secondary{% if not reverse %} active{% endif %}">Normal</a>
|
||||
<a href="{% url 'dcim:rack_elevation_list' %}{% querystring request reverse='true' %}" class="btn btn-outline-secondary{% if reverse %} active{% endif %}">Reversed</a>
|
||||
<div class="container mb-2 mx-0">
|
||||
<div class="d-flex flex-wrap justify-content-end">
|
||||
<button class="btn btn-sm btn-outline-dark toggle-images m-1" selected="selected">
|
||||
<span class="mdi mdi mdi-checkbox-marked-circle-outline" aria-hidden="true"></span> Show Images
|
||||
</button>
|
||||
<div class="btn-group btn-group-sm m-1" role="group">
|
||||
<a href="{% url 'dcim:rack_elevation_list' %}{% querystring request face='front' %}" class="btn btn-outline-secondary{% if rack_face == 'front' %} active{% endif %}">Front</a>
|
||||
<a href="{% url 'dcim:rack_elevation_list' %}{% querystring request face='rear' %}" class="btn btn-outline-secondary{% if rack_face == 'rear' %} active{% endif %}">Rear</a>
|
||||
</div>
|
||||
<div class="btn-group btn-group-sm m-1" role="group">
|
||||
<a href="{% url 'dcim:rack_elevation_list' %}{% querystring request reverse=None %}" class="btn btn-outline-secondary{% if not reverse %} active{% endif %}">Normal</a>
|
||||
<a href="{% url 'dcim:rack_elevation_list' %}{% querystring request reverse='true' %}" class="btn btn-outline-secondary{% if reverse %} active{% endif %}">Reversed</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="col col-md-12 noprint">
|
||||
{% include 'inc/advanced_search.html' %}
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col col-md-12">
|
||||
{% if page %}
|
||||
<div style="white-space: nowrap; overflow-x: scroll;">
|
||||
{% for rack in page %}
|
||||
<div style="display: inline-block; margin-right: 12px; width: 254px">
|
||||
<div style="margin-left: 30px">
|
||||
<div class="text-center">
|
||||
<strong><a href="{% url 'dcim:rack' pk=rack.pk %}">{{ rack.name }}</a></strong>
|
||||
{% if rack.role %}
|
||||
<br /><span class="badge my-3" style="color: {{ rack.role.color|fgcolor }}; background-color: #{{ rack.role.color }}">{{ rack.role }}</span>
|
||||
{% endif %}
|
||||
{% if rack.facility_id %}
|
||||
<br /><small class="text-muted">{{ rack.facility_id }}</small>
|
||||
{% endif %}
|
||||
<div class="row">
|
||||
<div class="col col-md-7 col-lg-8 col-xl-9 col-xxl-10">
|
||||
{% if page %}
|
||||
<div style="white-space: nowrap; overflow-x: scroll;">
|
||||
{% for rack in page %}
|
||||
<div style="display: inline-block; margin-right: 12px; width: 254px">
|
||||
<div style="margin-left: 30px">
|
||||
<div class="text-center">
|
||||
<strong><a href="{% url 'dcim:rack' pk=rack.pk %}">{{ rack.name }}</a></strong>
|
||||
{% if rack.role %}
|
||||
<br /><span class="badge my-3" style="color: {{ rack.role.color|fgcolor }}; background-color: #{{ rack.role.color }}">{{ rack.role }}</span>
|
||||
{% endif %}
|
||||
{% if rack.facility_id %}
|
||||
<br /><small class="text-muted">{{ rack.facility_id }}</small>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% include 'dcim/inc/rack_elevation.html' with object=rack face=rack_face %}
|
||||
<div class="clearfix"></div>
|
||||
<div class="text-center">
|
||||
<strong><a href="{% url 'dcim:rack' pk=rack.pk %}">{{ rack.name }}</a></strong>
|
||||
{% if rack.facility_id %}
|
||||
<small class="text-muted">({{ rack.facility_id }})</small>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
{% include 'dcim/inc/rack_elevation.html' with object=rack face=rack_face %}
|
||||
<div class="clearfix"></div>
|
||||
<div class="text-center">
|
||||
<strong><a href="{% url 'dcim:rack' pk=rack.pk %}">{{ rack.name }}</a></strong>
|
||||
{% if rack.facility_id %}
|
||||
<small class="text-muted">({{ rack.facility_id }})</small>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
<br />
|
||||
{% include 'inc/paginator.html' %}
|
||||
{% else %}
|
||||
<p>No Racks Found</p>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
<br />
|
||||
{% include 'inc/paginator.html' %}
|
||||
{% else %}
|
||||
<p>No Racks Found</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% include 'inc/filter_list.html' %}
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
|
|
|||
|
|
@ -24,9 +24,6 @@
|
|||
{% endblock controls %}
|
||||
|
||||
{% block content %}
|
||||
{% if filter_form %}
|
||||
{% include 'inc/advanced_search.html' %}
|
||||
{% endif %}
|
||||
{% if table.paginator.num_pages > 1 %}
|
||||
{% with bulk_edit_url=content_type.model_class|validated_viewname:"bulk_edit" bulk_delete_url=content_type.model_class|validated_viewname:"bulk_delete" %}
|
||||
<div id="select-all-box" class="d-none card noprint">
|
||||
|
|
@ -57,12 +54,12 @@
|
|||
{% endwith %}
|
||||
{% endif %}
|
||||
|
||||
{# Object list filter, table config #}
|
||||
{% include 'inc/table_controls.html' with table_modal="ObjectTable_config" %}
|
||||
|
||||
{# Object table #}
|
||||
<div class="row">
|
||||
<div class="col col-md-12">
|
||||
<div class="col col-md-7 col-lg-8 col-xl-9 col-xxl-10">
|
||||
{# Object list filter, table config #}
|
||||
{% include 'inc/table_controls.html' with table_modal="ObjectTable_config" %}
|
||||
|
||||
{% with bulk_edit_url=content_type.model_class|validated_viewname:"bulk_edit" bulk_delete_url=content_type.model_class|validated_viewname:"bulk_delete" %}
|
||||
{% if permissions.change or permissions.delete %}
|
||||
<form method="post" class="form form-horizontal">
|
||||
|
|
@ -95,6 +92,9 @@
|
|||
{% endwith %}
|
||||
{% include 'inc/paginator.html' with paginator=table.paginator page=table.page %}
|
||||
</div>
|
||||
{% if filter_form %}
|
||||
{% include 'inc/filter_list.html' %}
|
||||
{% endif %}
|
||||
</div>
|
||||
{% table_config_form table table_name="ObjectTable" %}
|
||||
{% endblock content %}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,62 @@
|
|||
{% load form_helpers %}
|
||||
{% load helpers %}
|
||||
|
||||
<div class="col col-md-5 col-lg-4 col-xl-3 col-xxl-2 noprint">
|
||||
<form action="." method="get">
|
||||
<div class="card small">
|
||||
<h5 class="card-header">
|
||||
Field Filters
|
||||
</h5>
|
||||
<div class="card-body overflow-visible d-flex flex-wrap justify-content-between py-3">
|
||||
{% for field in filter_form.hidden_fields %}
|
||||
{{ field }}
|
||||
{% endfor %}
|
||||
{% if filter_form.field_groups %}
|
||||
{% for group in filter_form.field_groups %}
|
||||
<div class="col col-12">
|
||||
{% for name in group %}
|
||||
{% with field=filter_form|get_item:name %}
|
||||
{% if field|widget_type == 'checkboxinput' %}
|
||||
<div class="form-check mb-3">
|
||||
<label class="form-check-label" for="{{ field.id_for_label }}">{{ field.label }}</label>
|
||||
{{ field }}
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="mb-3 mx-3">
|
||||
<label class="form-label" for="{{ field.id_for_label }}">{{ field.label }}</label>
|
||||
{{ field }}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endwith %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
{% for field in filter_form.visible_fields %}
|
||||
<div class="col">
|
||||
{% if field|widget_type == 'checkboxinput' %}
|
||||
<div class="form-check mb-3">
|
||||
<label class="form-check-label" for="{{ field.id_for_label }}">{{ field.label }}</label>
|
||||
{{ field }}
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="mb-3">
|
||||
<label class="form-label" for="{{ field.id_for_label }}">{{ field.label }}</label>
|
||||
{{ field }}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="card-footer text-end noprint border-0">
|
||||
<button type="button" class="btn btn-sm btn-outline-danger m-1" data-reset-select>
|
||||
<i class="mdi mdi-backspace"></i> Reset
|
||||
</button>
|
||||
<button type="submit" class="btn btn-sm btn-primary m-1">
|
||||
<i class="mdi mdi-filter-variant"></i> Filter
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
<div class="row mb-3 justify-content-between">
|
||||
<div class="col col-md-2 mb-0 d-flex noprint table-controls">
|
||||
{% if request.user.is_authenticated %}
|
||||
{% if request.user.is_authenticated and table_modal %}
|
||||
<div class="input-group input-group-sm">
|
||||
<button
|
||||
type="button"
|
||||
|
|
@ -22,16 +22,6 @@
|
|||
placeholder="Filter"
|
||||
title="Filter text (regular expressions supported)"
|
||||
/>
|
||||
{% if filter_form %}
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-sm btn-outline-dark"
|
||||
data-bs-toggle="collapse"
|
||||
data-bs-target="#advanced-search-content"
|
||||
>
|
||||
Advanced Search
|
||||
</button>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -67,7 +67,8 @@ class TenantGroupFilterForm(BootstrapMixin, CustomFieldModelFilterForm):
|
|||
parent_id = DynamicModelMultipleChoiceField(
|
||||
queryset=TenantGroup.objects.all(),
|
||||
required=False,
|
||||
label=_('Parent group')
|
||||
label=_('Parent group'),
|
||||
fetch_trigger='open'
|
||||
)
|
||||
|
||||
|
||||
|
|
@ -137,7 +138,8 @@ class TenantFilterForm(BootstrapMixin, CustomFieldModelFilterForm):
|
|||
queryset=TenantGroup.objects.all(),
|
||||
required=False,
|
||||
null_option='None',
|
||||
label=_('Group')
|
||||
label=_('Group'),
|
||||
fetch_trigger='open'
|
||||
)
|
||||
tag = TagFilterField(model)
|
||||
|
||||
|
|
@ -169,7 +171,8 @@ class TenancyFilterForm(forms.Form):
|
|||
queryset=TenantGroup.objects.all(),
|
||||
required=False,
|
||||
null_option='None',
|
||||
label=_('Tenant group')
|
||||
label=_('Tenant group'),
|
||||
fetch_trigger='open'
|
||||
)
|
||||
tenant_id = DynamicModelMultipleChoiceField(
|
||||
queryset=Tenant.objects.all(),
|
||||
|
|
@ -178,5 +181,6 @@ class TenancyFilterForm(forms.Form):
|
|||
query_params={
|
||||
'group_id': '$tenant_group_id'
|
||||
},
|
||||
label=_('Tenant')
|
||||
label=_('Tenant'),
|
||||
fetch_trigger='open'
|
||||
)
|
||||
|
|
|
|||
|
|
@ -363,16 +363,19 @@ class DynamicModelChoiceMixin:
|
|||
:param null_option: The string used to represent a null selection (if any)
|
||||
:param disabled_indicator: The name of the field which, if populated, will disable selection of the
|
||||
choice (optional)
|
||||
:param str fetch_trigger: The event type which will cause the select element to
|
||||
fetch data from the API. Must be 'load', 'open', or 'collapse'. (optional)
|
||||
"""
|
||||
filter = django_filters.ModelChoiceFilter
|
||||
widget = widgets.APISelect
|
||||
|
||||
def __init__(self, query_params=None, initial_params=None, null_option=None, disabled_indicator=None, *args,
|
||||
def __init__(self, query_params=None, initial_params=None, null_option=None, disabled_indicator=None, fetch_trigger=None, *args,
|
||||
**kwargs):
|
||||
self.query_params = query_params or {}
|
||||
self.initial_params = initial_params or {}
|
||||
self.null_option = null_option
|
||||
self.disabled_indicator = disabled_indicator
|
||||
self.fetch_trigger = fetch_trigger
|
||||
|
||||
# to_field_name is set by ModelChoiceField.__init__(), but we need to set it early for reference
|
||||
# by widget_attrs()
|
||||
|
|
@ -394,6 +397,10 @@ class DynamicModelChoiceMixin:
|
|||
# Set the disabled indicator, if any
|
||||
if self.disabled_indicator is not None:
|
||||
attrs['disabled-indicator'] = self.disabled_indicator
|
||||
|
||||
# Set the fetch trigger, if any.
|
||||
if self.fetch_trigger is not None:
|
||||
attrs['data-fetch-trigger'] = self.fetch_trigger
|
||||
|
||||
# Attach any static query parameters
|
||||
for key, value in self.query_params.items():
|
||||
|
|
|
|||
|
|
@ -236,12 +236,14 @@ class ClusterFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldModelFilte
|
|||
type_id = DynamicModelMultipleChoiceField(
|
||||
queryset=ClusterType.objects.all(),
|
||||
required=False,
|
||||
label=_('Type')
|
||||
label=_('Type'),
|
||||
fetch_trigger='open'
|
||||
)
|
||||
region_id = DynamicModelMultipleChoiceField(
|
||||
queryset=Region.objects.all(),
|
||||
required=False,
|
||||
label=_('Region')
|
||||
label=_('Region'),
|
||||
fetch_trigger='open'
|
||||
)
|
||||
site_id = DynamicModelMultipleChoiceField(
|
||||
queryset=Site.objects.all(),
|
||||
|
|
@ -250,13 +252,15 @@ class ClusterFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldModelFilte
|
|||
query_params={
|
||||
'region_id': '$region_id'
|
||||
},
|
||||
label=_('Site')
|
||||
label=_('Site'),
|
||||
fetch_trigger='open'
|
||||
)
|
||||
group_id = DynamicModelMultipleChoiceField(
|
||||
queryset=ClusterGroup.objects.all(),
|
||||
required=False,
|
||||
null_option='None',
|
||||
label=_('Group')
|
||||
label=_('Group'),
|
||||
fetch_trigger='open'
|
||||
)
|
||||
tag = TagFilterField(model)
|
||||
|
||||
|
|
@ -547,28 +551,33 @@ class VirtualMachineFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldMod
|
|||
queryset=ClusterGroup.objects.all(),
|
||||
required=False,
|
||||
null_option='None',
|
||||
label=_('Cluster group')
|
||||
label=_('Cluster group'),
|
||||
fetch_trigger='open'
|
||||
)
|
||||
cluster_type_id = DynamicModelMultipleChoiceField(
|
||||
queryset=ClusterType.objects.all(),
|
||||
required=False,
|
||||
null_option='None',
|
||||
label=_('Cluster type')
|
||||
label=_('Cluster type'),
|
||||
fetch_trigger='open'
|
||||
)
|
||||
cluster_id = DynamicModelMultipleChoiceField(
|
||||
queryset=Cluster.objects.all(),
|
||||
required=False,
|
||||
label=_('Cluster')
|
||||
label=_('Cluster'),
|
||||
fetch_trigger='open'
|
||||
)
|
||||
region_id = DynamicModelMultipleChoiceField(
|
||||
queryset=Region.objects.all(),
|
||||
required=False,
|
||||
label=_('Region')
|
||||
label=_('Region'),
|
||||
fetch_trigger='open'
|
||||
)
|
||||
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(),
|
||||
|
|
@ -578,7 +587,8 @@ class VirtualMachineFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldMod
|
|||
'region_id': '$region_id',
|
||||
'group_id': '$site_group_id',
|
||||
},
|
||||
label=_('Site')
|
||||
label=_('Site'),
|
||||
fetch_trigger='open'
|
||||
)
|
||||
role_id = DynamicModelMultipleChoiceField(
|
||||
queryset=DeviceRole.objects.all(),
|
||||
|
|
@ -587,7 +597,8 @@ class VirtualMachineFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldMod
|
|||
query_params={
|
||||
'vm_role': "True"
|
||||
},
|
||||
label=_('Role')
|
||||
label=_('Role'),
|
||||
fetch_trigger='open'
|
||||
)
|
||||
status = forms.MultipleChoiceField(
|
||||
choices=VirtualMachineStatusChoices,
|
||||
|
|
@ -598,7 +609,8 @@ class VirtualMachineFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldMod
|
|||
queryset=Platform.objects.all(),
|
||||
required=False,
|
||||
null_option='None',
|
||||
label=_('Platform')
|
||||
label=_('Platform'),
|
||||
fetch_trigger='open'
|
||||
)
|
||||
mac_address = forms.CharField(
|
||||
required=False,
|
||||
|
|
@ -850,7 +862,8 @@ class VMInterfaceFilterForm(BootstrapMixin, forms.Form):
|
|||
cluster_id = DynamicModelMultipleChoiceField(
|
||||
queryset=Cluster.objects.all(),
|
||||
required=False,
|
||||
label=_('Cluster')
|
||||
label=_('Cluster'),
|
||||
fetch_trigger='open'
|
||||
)
|
||||
virtual_machine_id = DynamicModelMultipleChoiceField(
|
||||
queryset=VirtualMachine.objects.all(),
|
||||
|
|
@ -858,7 +871,8 @@ class VMInterfaceFilterForm(BootstrapMixin, forms.Form):
|
|||
query_params={
|
||||
'cluster_id': '$cluster_id'
|
||||
},
|
||||
label=_('Virtual machine')
|
||||
label=_('Virtual machine'),
|
||||
fetch_trigger='open'
|
||||
)
|
||||
enabled = forms.NullBooleanField(
|
||||
required=False,
|
||||
|
|
|
|||
Loading…
Reference in New Issue