mirror of
https://github.com/netbox-community/netbox.git
synced 2025-07-22 12:06:53 -06:00
Merge branch 'feature' into 6829-graphql-reverse-relations
This commit is contained in:
commit
1b612816cc
@ -107,9 +107,15 @@ class ProviderBulkEditForm(BootstrapMixin, AddRemoveTagsForm, CustomFieldModelBu
|
|||||||
class ProviderFilterForm(BootstrapMixin, CustomFieldModelFilterForm):
|
class ProviderFilterForm(BootstrapMixin, CustomFieldModelFilterForm):
|
||||||
model = Provider
|
model = Provider
|
||||||
field_groups = [
|
field_groups = [
|
||||||
|
['q'],
|
||||||
['region_id', 'site_id'],
|
['region_id', 'site_id'],
|
||||||
['asn', 'tag'],
|
['asn', 'tag'],
|
||||||
]
|
]
|
||||||
|
q = forms.CharField(
|
||||||
|
required=False,
|
||||||
|
widget=forms.TextInput(attrs={'placeholder': _('All Fields')}),
|
||||||
|
label=_('Search')
|
||||||
|
)
|
||||||
region_id = DynamicModelMultipleChoiceField(
|
region_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=Region.objects.all(),
|
queryset=Region.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
@ -196,7 +202,12 @@ class ProviderNetworkBulkEditForm(BootstrapMixin, AddRemoveTagsForm, CustomField
|
|||||||
|
|
||||||
class ProviderNetworkFilterForm(BootstrapMixin, CustomFieldModelFilterForm):
|
class ProviderNetworkFilterForm(BootstrapMixin, CustomFieldModelFilterForm):
|
||||||
model = ProviderNetwork
|
model = ProviderNetwork
|
||||||
field_order = ['provider_id']
|
field_order = ['q', 'provider_id', 'tag']
|
||||||
|
q = forms.CharField(
|
||||||
|
required=False,
|
||||||
|
widget=forms.TextInput(attrs={'placeholder': _('All Fields')}),
|
||||||
|
label=_('Search')
|
||||||
|
)
|
||||||
provider_id = DynamicModelMultipleChoiceField(
|
provider_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=Provider.objects.all(),
|
queryset=Provider.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
@ -358,16 +369,22 @@ class CircuitBulkEditForm(BootstrapMixin, AddRemoveTagsForm, CustomFieldModelBul
|
|||||||
class CircuitFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldModelFilterForm):
|
class CircuitFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldModelFilterForm):
|
||||||
model = Circuit
|
model = Circuit
|
||||||
field_order = [
|
field_order = [
|
||||||
'type_id', 'provider_id', 'provider_network_id', 'status', 'region_id', 'site_id', 'tenant_group_id', 'tenant_id',
|
'q', 'type_id', 'provider_id', 'provider_network_id', 'status', 'region_id', 'site_id', 'tenant_group_id',
|
||||||
'commit_rate',
|
'tenant_id', 'commit_rate',
|
||||||
]
|
]
|
||||||
field_groups = [
|
field_groups = [
|
||||||
|
['q'],
|
||||||
['type_id', 'status', 'commit_rate'],
|
['type_id', 'status', 'commit_rate'],
|
||||||
['provider_id', 'provider_network_id'],
|
['provider_id', 'provider_network_id'],
|
||||||
['region_id', 'site_id'],
|
['region_id', 'site_id'],
|
||||||
['tenant_group_id', 'tenant_id'],
|
['tenant_group_id', 'tenant_id'],
|
||||||
['tag']
|
['tag']
|
||||||
]
|
]
|
||||||
|
q = forms.CharField(
|
||||||
|
required=False,
|
||||||
|
widget=forms.TextInput(attrs={'placeholder': _('All Fields')}),
|
||||||
|
label=_('Search')
|
||||||
|
)
|
||||||
type_id = DynamicModelMultipleChoiceField(
|
type_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=CircuitType.objects.all(),
|
queryset=CircuitType.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
|
@ -56,12 +56,18 @@ def get_device_by_name_or_pk(name):
|
|||||||
|
|
||||||
class DeviceComponentFilterForm(BootstrapMixin, CustomFieldModelFilterForm):
|
class DeviceComponentFilterForm(BootstrapMixin, CustomFieldModelFilterForm):
|
||||||
field_order = [
|
field_order = [
|
||||||
'name', 'label', 'region_id', 'site_group_id', 'site_id',
|
'q', 'name', 'label', 'region_id', 'site_group_id', 'site_id',
|
||||||
]
|
]
|
||||||
field_groups = [
|
field_groups = [
|
||||||
|
['q'],
|
||||||
['name', 'label'],
|
['name', 'label'],
|
||||||
['region_id', 'site_group_id', 'site_id'],
|
['region_id', 'site_group_id', 'site_id'],
|
||||||
]
|
]
|
||||||
|
q = forms.CharField(
|
||||||
|
required=False,
|
||||||
|
widget=forms.TextInput(attrs={'placeholder': _('All Fields')}),
|
||||||
|
label=_('Search')
|
||||||
|
)
|
||||||
name = forms.CharField(
|
name = forms.CharField(
|
||||||
required=False
|
required=False
|
||||||
)
|
)
|
||||||
@ -452,12 +458,18 @@ class SiteBulkEditForm(BootstrapMixin, AddRemoveTagsForm, CustomFieldModelBulkEd
|
|||||||
|
|
||||||
class SiteFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldModelFilterForm):
|
class SiteFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldModelFilterForm):
|
||||||
model = Site
|
model = Site
|
||||||
field_order = ['status', 'region_id', 'tenant_group_id', 'tenant_id']
|
field_order = ['q', 'status', 'region_id', 'tenant_group_id', 'tenant_id']
|
||||||
field_groups = [
|
field_groups = [
|
||||||
|
['q'],
|
||||||
['status', 'region_id'],
|
['status', 'region_id'],
|
||||||
['tenant_group_id', 'tenant_id'],
|
['tenant_group_id', 'tenant_id'],
|
||||||
['tag']
|
['tag']
|
||||||
]
|
]
|
||||||
|
q = forms.CharField(
|
||||||
|
required=False,
|
||||||
|
widget=forms.TextInput(attrs={'placeholder': _('All Fields')}),
|
||||||
|
label=_('Search')
|
||||||
|
)
|
||||||
status = forms.MultipleChoiceField(
|
status = forms.MultipleChoiceField(
|
||||||
choices=SiteStatusChoices,
|
choices=SiteStatusChoices,
|
||||||
required=False,
|
required=False,
|
||||||
@ -568,6 +580,11 @@ class LocationBulkEditForm(BootstrapMixin, CustomFieldModelBulkEditForm):
|
|||||||
|
|
||||||
class LocationFilterForm(BootstrapMixin, CustomFieldModelFilterForm):
|
class LocationFilterForm(BootstrapMixin, CustomFieldModelFilterForm):
|
||||||
model = Location
|
model = Location
|
||||||
|
q = forms.CharField(
|
||||||
|
required=False,
|
||||||
|
widget=forms.TextInput(attrs={'placeholder': _('All Fields')}),
|
||||||
|
label=_('Search')
|
||||||
|
)
|
||||||
region_id = DynamicModelMultipleChoiceField(
|
region_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=Region.objects.all(),
|
queryset=Region.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
@ -862,12 +879,18 @@ class RackBulkEditForm(BootstrapMixin, AddRemoveTagsForm, CustomFieldModelBulkEd
|
|||||||
|
|
||||||
class RackFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldModelFilterForm):
|
class RackFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldModelFilterForm):
|
||||||
model = Rack
|
model = Rack
|
||||||
field_order = ['region_id', 'site_id', 'location_id', 'status', 'role_id', 'tenant_group_id', 'tenant_id']
|
field_order = ['q', 'region_id', 'site_id', 'location_id', 'status', 'role_id', 'tenant_group_id', 'tenant_id']
|
||||||
field_groups = [
|
field_groups = [
|
||||||
|
['q'],
|
||||||
['status', 'role_id'],
|
['status', 'role_id'],
|
||||||
['region_id', 'site_id', 'location_id'],
|
['region_id', 'site_id', 'location_id'],
|
||||||
['tenant_group_id', 'tenant_id'],
|
['tenant_group_id', 'tenant_id'],
|
||||||
]
|
]
|
||||||
|
q = forms.CharField(
|
||||||
|
required=False,
|
||||||
|
widget=forms.TextInput(attrs={'placeholder': _('All Fields')}),
|
||||||
|
label=_('Search')
|
||||||
|
)
|
||||||
region_id = DynamicModelMultipleChoiceField(
|
region_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=Region.objects.all(),
|
queryset=Region.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
@ -927,7 +950,8 @@ class RackFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldModelFilterFo
|
|||||||
|
|
||||||
class RackElevationFilterForm(RackFilterForm):
|
class RackElevationFilterForm(RackFilterForm):
|
||||||
field_order = [
|
field_order = [
|
||||||
'region_id', 'site_id', 'location_id', 'id', 'status', 'role_id', 'tenant_group_id', 'tenant_id',
|
'q', 'region_id', 'site_id', 'location_id', 'id', 'status', 'role_id', 'tenant_group_id',
|
||||||
|
'tenant_id',
|
||||||
]
|
]
|
||||||
id = DynamicModelMultipleChoiceField(
|
id = DynamicModelMultipleChoiceField(
|
||||||
queryset=Rack.objects.all(),
|
queryset=Rack.objects.all(),
|
||||||
@ -1092,11 +1116,17 @@ class RackReservationBulkEditForm(BootstrapMixin, AddRemoveTagsForm, CustomField
|
|||||||
|
|
||||||
class RackReservationFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldModelFilterForm):
|
class RackReservationFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldModelFilterForm):
|
||||||
model = RackReservation
|
model = RackReservation
|
||||||
field_order = ['region_id', 'site_id', 'location_id', 'user_id', 'tenant_group_id', 'tenant_id']
|
field_order = ['q', 'region_id', 'site_id', 'location_id', 'user_id', 'tenant_group_id', 'tenant_id']
|
||||||
field_groups = [
|
field_groups = [
|
||||||
|
['q'],
|
||||||
['region_id', 'site_id', 'location_id'],
|
['region_id', 'site_id', 'location_id'],
|
||||||
['user_id', 'tenant_group_id', 'tenant_id'],
|
['user_id', 'tenant_group_id', 'tenant_id'],
|
||||||
]
|
]
|
||||||
|
q = forms.CharField(
|
||||||
|
required=False,
|
||||||
|
widget=forms.TextInput(attrs={'placeholder': _('All Fields')}),
|
||||||
|
label=_('Search')
|
||||||
|
)
|
||||||
region_id = DynamicModelMultipleChoiceField(
|
region_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=Region.objects.all(),
|
queryset=Region.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
@ -1246,12 +1276,18 @@ class DeviceTypeBulkEditForm(BootstrapMixin, AddRemoveTagsForm, CustomFieldModel
|
|||||||
class DeviceTypeFilterForm(BootstrapMixin, CustomFieldModelFilterForm):
|
class DeviceTypeFilterForm(BootstrapMixin, CustomFieldModelFilterForm):
|
||||||
model = DeviceType
|
model = DeviceType
|
||||||
field_groups = [
|
field_groups = [
|
||||||
|
['q'],
|
||||||
['manufacturer_id', 'subdevice_role'],
|
['manufacturer_id', 'subdevice_role'],
|
||||||
['console_ports', 'console_server_ports'],
|
['console_ports', 'console_server_ports'],
|
||||||
['power_ports', 'power_outlets'],
|
['power_ports', 'power_outlets'],
|
||||||
['interfaces', 'pass_through_ports'],
|
['interfaces', 'pass_through_ports'],
|
||||||
['tag']
|
['tag']
|
||||||
]
|
]
|
||||||
|
q = forms.CharField(
|
||||||
|
required=False,
|
||||||
|
widget=forms.TextInput(attrs={'placeholder': _('All Fields')}),
|
||||||
|
label=_('Search')
|
||||||
|
)
|
||||||
manufacturer_id = DynamicModelMultipleChoiceField(
|
manufacturer_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=Manufacturer.objects.all(),
|
queryset=Manufacturer.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
@ -2058,6 +2094,11 @@ class PlatformBulkEditForm(BootstrapMixin, CustomFieldModelBulkEditForm):
|
|||||||
|
|
||||||
class PlatformFilterForm(BootstrapMixin, CustomFieldModelFilterForm):
|
class PlatformFilterForm(BootstrapMixin, CustomFieldModelFilterForm):
|
||||||
model = Platform
|
model = Platform
|
||||||
|
q = forms.CharField(
|
||||||
|
required=False,
|
||||||
|
widget=forms.TextInput(attrs={'placeholder': _('All Fields')}),
|
||||||
|
label=_('Search')
|
||||||
|
)
|
||||||
manufacturer_id = DynamicModelMultipleChoiceField(
|
manufacturer_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=Manufacturer.objects.all(),
|
queryset=Manufacturer.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
@ -2465,16 +2506,23 @@ class DeviceBulkEditForm(BootstrapMixin, AddRemoveTagsForm, CustomFieldModelBulk
|
|||||||
class DeviceFilterForm(BootstrapMixin, LocalConfigContextFilterForm, TenancyFilterForm, CustomFieldModelFilterForm):
|
class DeviceFilterForm(BootstrapMixin, LocalConfigContextFilterForm, TenancyFilterForm, CustomFieldModelFilterForm):
|
||||||
model = Device
|
model = Device
|
||||||
field_order = [
|
field_order = [
|
||||||
'region_id', 'site_id', 'location_id', 'rack_id', 'status', 'role_id', 'tenant_group_id', 'tenant_id',
|
'q', 'region_id', 'site_id', 'location_id', 'rack_id', 'status', 'role_id',
|
||||||
'manufacturer_id', 'device_type_id', 'asset_tag', 'mac_address', 'has_primary_ip',
|
'tenant_group_id', 'tenant_id', 'manufacturer_id', 'device_type_id', 'asset_tag',
|
||||||
|
'mac_address', 'has_primary_ip',
|
||||||
]
|
]
|
||||||
field_groups = [
|
field_groups = [
|
||||||
|
['q'],
|
||||||
['region_id', 'site_id', 'location_id', 'rack_id'],
|
['region_id', 'site_id', 'location_id', 'rack_id'],
|
||||||
['status', 'role_id', 'asset_tag'],
|
['status', 'role_id', 'asset_tag'],
|
||||||
['tenant_group_id', 'tenant_id'],
|
['tenant_group_id', 'tenant_id'],
|
||||||
['manufacturer_id', 'device_type_id'],
|
['manufacturer_id', 'device_type_id'],
|
||||||
['mac_address', 'has_primary_ip'],
|
['mac_address', 'has_primary_ip'],
|
||||||
]
|
]
|
||||||
|
q = forms.CharField(
|
||||||
|
required=False,
|
||||||
|
widget=forms.TextInput(attrs={'placeholder': _('All Fields')}),
|
||||||
|
label=_('Search')
|
||||||
|
)
|
||||||
region_id = DynamicModelMultipleChoiceField(
|
region_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=Region.objects.all(),
|
queryset=Region.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
@ -2654,6 +2702,7 @@ class DeviceBulkAddComponentForm(BootstrapMixin, CustomFieldsMixin, ComponentFor
|
|||||||
class ConsolePortFilterForm(DeviceComponentFilterForm):
|
class ConsolePortFilterForm(DeviceComponentFilterForm):
|
||||||
model = ConsolePort
|
model = ConsolePort
|
||||||
field_groups = [
|
field_groups = [
|
||||||
|
['q'],
|
||||||
['name', 'label'],
|
['name', 'label'],
|
||||||
['type', 'speed'],
|
['type', 'speed'],
|
||||||
['region_id', 'site_group_id', 'site_id'],
|
['region_id', 'site_group_id', 'site_id'],
|
||||||
@ -2761,6 +2810,7 @@ class ConsolePortCSVForm(CustomFieldModelCSVForm):
|
|||||||
class ConsoleServerPortFilterForm(DeviceComponentFilterForm):
|
class ConsoleServerPortFilterForm(DeviceComponentFilterForm):
|
||||||
model = ConsoleServerPort
|
model = ConsoleServerPort
|
||||||
field_groups = [
|
field_groups = [
|
||||||
|
['q'],
|
||||||
['name', 'label'],
|
['name', 'label'],
|
||||||
['type', 'speed'],
|
['type', 'speed'],
|
||||||
['region_id', 'site_group_id', 'site_id'],
|
['region_id', 'site_group_id', 'site_id'],
|
||||||
@ -2868,6 +2918,7 @@ class ConsoleServerPortCSVForm(CustomFieldModelCSVForm):
|
|||||||
class PowerPortFilterForm(DeviceComponentFilterForm):
|
class PowerPortFilterForm(DeviceComponentFilterForm):
|
||||||
model = PowerPort
|
model = PowerPort
|
||||||
field_groups = [
|
field_groups = [
|
||||||
|
['q'],
|
||||||
['name', 'label', 'type'],
|
['name', 'label', 'type'],
|
||||||
['region_id', 'site_group_id', 'site_id'],
|
['region_id', 'site_group_id', 'site_id'],
|
||||||
['tag'],
|
['tag'],
|
||||||
@ -2973,6 +3024,7 @@ class PowerPortCSVForm(CustomFieldModelCSVForm):
|
|||||||
class PowerOutletFilterForm(DeviceComponentFilterForm):
|
class PowerOutletFilterForm(DeviceComponentFilterForm):
|
||||||
model = PowerOutlet
|
model = PowerOutlet
|
||||||
field_groups = [
|
field_groups = [
|
||||||
|
['q'],
|
||||||
['name', 'label', 'type'],
|
['name', 'label', 'type'],
|
||||||
['region_id', 'site_group_id', 'site_id'],
|
['region_id', 'site_group_id', 'site_id'],
|
||||||
['tag'],
|
['tag'],
|
||||||
@ -3145,6 +3197,7 @@ class PowerOutletCSVForm(CustomFieldModelCSVForm):
|
|||||||
class InterfaceFilterForm(DeviceComponentFilterForm):
|
class InterfaceFilterForm(DeviceComponentFilterForm):
|
||||||
model = Interface
|
model = Interface
|
||||||
field_groups = [
|
field_groups = [
|
||||||
|
['q'],
|
||||||
['name', 'label', 'type', 'enabled'],
|
['name', 'label', 'type', 'enabled'],
|
||||||
['mgmt_only', 'mac_address'],
|
['mgmt_only', 'mac_address'],
|
||||||
['region_id', 'site_group_id', 'site_id'],
|
['region_id', 'site_group_id', 'site_id'],
|
||||||
@ -3493,6 +3546,7 @@ class InterfaceCSVForm(CustomFieldModelCSVForm):
|
|||||||
|
|
||||||
class FrontPortFilterForm(DeviceComponentFilterForm):
|
class FrontPortFilterForm(DeviceComponentFilterForm):
|
||||||
field_groups = [
|
field_groups = [
|
||||||
|
['q'],
|
||||||
['name', 'label', 'type', 'color'],
|
['name', 'label', 'type', 'color'],
|
||||||
['region_id', 'site_group_id', 'site_id'],
|
['region_id', 'site_group_id', 'site_id'],
|
||||||
['tag']
|
['tag']
|
||||||
@ -3682,6 +3736,7 @@ class FrontPortCSVForm(CustomFieldModelCSVForm):
|
|||||||
class RearPortFilterForm(DeviceComponentFilterForm):
|
class RearPortFilterForm(DeviceComponentFilterForm):
|
||||||
model = RearPort
|
model = RearPort
|
||||||
field_groups = [
|
field_groups = [
|
||||||
|
['q'],
|
||||||
['name', 'label', 'type', 'color'],
|
['name', 'label', 'type', 'color'],
|
||||||
['region_id', 'site_group_id', 'site_id'],
|
['region_id', 'site_group_id', 'site_id'],
|
||||||
['tag']
|
['tag']
|
||||||
@ -3783,6 +3838,7 @@ class RearPortCSVForm(CustomFieldModelCSVForm):
|
|||||||
class DeviceBayFilterForm(DeviceComponentFilterForm):
|
class DeviceBayFilterForm(DeviceComponentFilterForm):
|
||||||
model = DeviceBay
|
model = DeviceBay
|
||||||
field_groups = [
|
field_groups = [
|
||||||
|
['q'],
|
||||||
['name', 'label'],
|
['name', 'label'],
|
||||||
['region_id', 'site_group_id', 'site_id'],
|
['region_id', 'site_group_id', 'site_id'],
|
||||||
['tag']
|
['tag']
|
||||||
@ -4013,6 +4069,7 @@ class InventoryItemBulkEditForm(
|
|||||||
class InventoryItemFilterForm(DeviceComponentFilterForm):
|
class InventoryItemFilterForm(DeviceComponentFilterForm):
|
||||||
model = InventoryItem
|
model = InventoryItem
|
||||||
field_groups = [
|
field_groups = [
|
||||||
|
['q'],
|
||||||
['name', 'label', 'manufacturer_id'],
|
['name', 'label', 'manufacturer_id'],
|
||||||
['serial', 'asset_tag', 'discovered'],
|
['serial', 'asset_tag', 'discovered'],
|
||||||
['region_id', 'site_group_id', 'site_id'],
|
['region_id', 'site_group_id', 'site_id'],
|
||||||
@ -4488,11 +4545,17 @@ class CableBulkEditForm(BootstrapMixin, AddRemoveTagsForm, CustomFieldModelBulkE
|
|||||||
class CableFilterForm(BootstrapMixin, CustomFieldModelFilterForm):
|
class CableFilterForm(BootstrapMixin, CustomFieldModelFilterForm):
|
||||||
model = Cable
|
model = Cable
|
||||||
field_groups = [
|
field_groups = [
|
||||||
|
['q'],
|
||||||
['type', 'status', 'color'],
|
['type', 'status', 'color'],
|
||||||
['device_id', 'rack_id'],
|
['device_id', 'rack_id'],
|
||||||
['region_id', 'site_id', 'tenant_id'],
|
['region_id', 'site_id', 'tenant_id'],
|
||||||
['tag']
|
['tag']
|
||||||
]
|
]
|
||||||
|
q = forms.CharField(
|
||||||
|
required=False,
|
||||||
|
widget=forms.TextInput(attrs={'placeholder': _('All Fields')}),
|
||||||
|
label=_('Search')
|
||||||
|
)
|
||||||
region_id = DynamicModelMultipleChoiceField(
|
region_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=Region.objects.all(),
|
queryset=Region.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
@ -4556,6 +4619,11 @@ class CableFilterForm(BootstrapMixin, CustomFieldModelFilterForm):
|
|||||||
#
|
#
|
||||||
|
|
||||||
class ConsoleConnectionFilterForm(BootstrapMixin, forms.Form):
|
class ConsoleConnectionFilterForm(BootstrapMixin, forms.Form):
|
||||||
|
q = forms.CharField(
|
||||||
|
required=False,
|
||||||
|
widget=forms.TextInput(attrs={'placeholder': _('All Fields')}),
|
||||||
|
label=_('Search')
|
||||||
|
)
|
||||||
region_id = DynamicModelMultipleChoiceField(
|
region_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=Region.objects.all(),
|
queryset=Region.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
@ -4583,6 +4651,11 @@ class ConsoleConnectionFilterForm(BootstrapMixin, forms.Form):
|
|||||||
|
|
||||||
|
|
||||||
class PowerConnectionFilterForm(BootstrapMixin, forms.Form):
|
class PowerConnectionFilterForm(BootstrapMixin, forms.Form):
|
||||||
|
q = forms.CharField(
|
||||||
|
required=False,
|
||||||
|
widget=forms.TextInput(attrs={'placeholder': _('All Fields')}),
|
||||||
|
label=_('Search')
|
||||||
|
)
|
||||||
region_id = DynamicModelMultipleChoiceField(
|
region_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=Region.objects.all(),
|
queryset=Region.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
@ -4610,6 +4683,11 @@ class PowerConnectionFilterForm(BootstrapMixin, forms.Form):
|
|||||||
|
|
||||||
|
|
||||||
class InterfaceConnectionFilterForm(BootstrapMixin, forms.Form):
|
class InterfaceConnectionFilterForm(BootstrapMixin, forms.Form):
|
||||||
|
q = forms.CharField(
|
||||||
|
required=False,
|
||||||
|
widget=forms.TextInput(attrs={'placeholder': _('All Fields')}),
|
||||||
|
label=_('Search')
|
||||||
|
)
|
||||||
region_id = DynamicModelMultipleChoiceField(
|
region_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=Region.objects.all(),
|
queryset=Region.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
@ -4877,12 +4955,18 @@ class VirtualChassisCSVForm(CustomFieldModelCSVForm):
|
|||||||
|
|
||||||
class VirtualChassisFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldModelFilterForm):
|
class VirtualChassisFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldModelFilterForm):
|
||||||
model = VirtualChassis
|
model = VirtualChassis
|
||||||
field_order = ['region_id', 'site_group_id', 'site_id', 'tenant_group_id', 'tenant_id']
|
field_order = ['q', 'region_id', 'site_group_id', 'site_id', 'tenant_group_id', 'tenant_id']
|
||||||
field_groups = [
|
field_groups = [
|
||||||
|
['q'],
|
||||||
['region_id', 'site_group_id', 'site_id'],
|
['region_id', 'site_group_id', 'site_id'],
|
||||||
['tenant_group_id', 'tenant_id'],
|
['tenant_group_id', 'tenant_id'],
|
||||||
['tag']
|
['tag']
|
||||||
]
|
]
|
||||||
|
q = forms.CharField(
|
||||||
|
required=False,
|
||||||
|
widget=forms.TextInput(attrs={'placeholder': _('All Fields')}),
|
||||||
|
label=_('Search')
|
||||||
|
)
|
||||||
region_id = DynamicModelMultipleChoiceField(
|
region_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=Region.objects.all(),
|
queryset=Region.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
@ -5022,6 +5106,11 @@ class PowerPanelBulkEditForm(BootstrapMixin, AddRemoveTagsForm, CustomFieldModel
|
|||||||
|
|
||||||
class PowerPanelFilterForm(BootstrapMixin, CustomFieldModelFilterForm):
|
class PowerPanelFilterForm(BootstrapMixin, CustomFieldModelFilterForm):
|
||||||
model = PowerPanel
|
model = PowerPanel
|
||||||
|
q = forms.CharField(
|
||||||
|
required=False,
|
||||||
|
widget=forms.TextInput(attrs={'placeholder': _('All Fields')}),
|
||||||
|
label=_('Search')
|
||||||
|
)
|
||||||
region_id = DynamicModelMultipleChoiceField(
|
region_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=Region.objects.all(),
|
queryset=Region.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
@ -5260,12 +5349,18 @@ class PowerFeedBulkEditForm(BootstrapMixin, AddRemoveTagsForm, CustomFieldModelB
|
|||||||
class PowerFeedFilterForm(BootstrapMixin, CustomFieldModelFilterForm):
|
class PowerFeedFilterForm(BootstrapMixin, CustomFieldModelFilterForm):
|
||||||
model = PowerFeed
|
model = PowerFeed
|
||||||
field_groups = [
|
field_groups = [
|
||||||
|
['q'],
|
||||||
['region_id', 'site_group_id', 'site_id'],
|
['region_id', 'site_group_id', 'site_id'],
|
||||||
['power_panel_id', 'rack_id'],
|
['power_panel_id', 'rack_id'],
|
||||||
['type', 'supply', 'max_utilization'],
|
['type', 'supply', 'max_utilization'],
|
||||||
['phase', 'voltage', 'amperage'],
|
['phase', 'voltage', 'amperage'],
|
||||||
['status', 'tag']
|
['status', 'tag']
|
||||||
]
|
]
|
||||||
|
q = forms.CharField(
|
||||||
|
required=False,
|
||||||
|
widget=forms.TextInput(attrs={'placeholder': _('All Fields')}),
|
||||||
|
label=_('Search')
|
||||||
|
)
|
||||||
region_id = DynamicModelMultipleChoiceField(
|
region_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=Region.objects.all(),
|
queryset=Region.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
|
@ -46,28 +46,40 @@ class CustomFieldFilterLogicChoices(ChoiceSet):
|
|||||||
class CustomLinkButtonClassChoices(ChoiceSet):
|
class CustomLinkButtonClassChoices(ChoiceSet):
|
||||||
|
|
||||||
CLASS_DEFAULT = 'outline-dark'
|
CLASS_DEFAULT = 'outline-dark'
|
||||||
CLASS_PRIMARY = 'primary'
|
CLASS_LINK = 'ghost-dark'
|
||||||
CLASS_SUCCESS = 'success'
|
CLASS_BLUE = 'blue'
|
||||||
CLASS_INFO = 'info'
|
CLASS_INDIGO = 'indigo'
|
||||||
CLASS_WARNING = 'warning'
|
CLASS_PURPLE = 'purple'
|
||||||
CLASS_DANGER = 'danger'
|
CLASS_PINK = 'pink'
|
||||||
CLASS_LINK = 'link'
|
CLASS_RED = 'red'
|
||||||
|
CLASS_ORANGE = 'orange'
|
||||||
|
CLASS_YELLOW = 'yellow'
|
||||||
|
CLASS_GREEN = 'green'
|
||||||
|
CLASS_TEAL = 'teal'
|
||||||
|
CLASS_CYAN = 'cyan'
|
||||||
|
CLASS_GRAY = 'secondary'
|
||||||
|
|
||||||
CHOICES = (
|
CHOICES = (
|
||||||
(CLASS_DEFAULT, 'Default'),
|
(CLASS_DEFAULT, 'Default'),
|
||||||
(CLASS_PRIMARY, 'Primary (blue)'),
|
(CLASS_LINK, 'Link'),
|
||||||
(CLASS_SUCCESS, 'Success (green)'),
|
(CLASS_BLUE, 'Blue'),
|
||||||
(CLASS_INFO, 'Info (aqua)'),
|
(CLASS_INDIGO, 'Indigo'),
|
||||||
(CLASS_WARNING, 'Warning (orange)'),
|
(CLASS_PURPLE, 'Purple'),
|
||||||
(CLASS_DANGER, 'Danger (red)'),
|
(CLASS_PINK, 'Pink'),
|
||||||
(CLASS_LINK, 'None (link)'),
|
(CLASS_RED, 'Red'),
|
||||||
|
(CLASS_ORANGE, 'Orange'),
|
||||||
|
(CLASS_YELLOW, 'Yellow'),
|
||||||
|
(CLASS_GREEN, 'Green'),
|
||||||
|
(CLASS_TEAL, 'Teal'),
|
||||||
|
(CLASS_CYAN, 'Cyan'),
|
||||||
|
(CLASS_GRAY, 'Gray'),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# ObjectChanges
|
# ObjectChanges
|
||||||
#
|
#
|
||||||
|
|
||||||
|
|
||||||
class ObjectChangeActionChoices(ChoiceSet):
|
class ObjectChangeActionChoices(ChoiceSet):
|
||||||
|
|
||||||
ACTION_CREATE = 'create'
|
ACTION_CREATE = 'create'
|
||||||
|
@ -77,9 +77,15 @@ class CustomFieldBulkEditForm(BootstrapMixin, BulkEditForm):
|
|||||||
|
|
||||||
class CustomFieldFilterForm(BootstrapMixin, forms.Form):
|
class CustomFieldFilterForm(BootstrapMixin, forms.Form):
|
||||||
field_groups = [
|
field_groups = [
|
||||||
|
['q'],
|
||||||
['type', 'content_types'],
|
['type', 'content_types'],
|
||||||
['weight', 'required'],
|
['weight', 'required'],
|
||||||
]
|
]
|
||||||
|
q = forms.CharField(
|
||||||
|
required=False,
|
||||||
|
widget=forms.TextInput(attrs={'placeholder': _('All Fields')}),
|
||||||
|
label=_('Search')
|
||||||
|
)
|
||||||
content_types = ContentTypeMultipleChoiceField(
|
content_types = ContentTypeMultipleChoiceField(
|
||||||
queryset=ContentType.objects.all(),
|
queryset=ContentType.objects.all(),
|
||||||
limit_choices_to=FeatureQuery('custom_fields')
|
limit_choices_to=FeatureQuery('custom_fields')
|
||||||
@ -167,9 +173,15 @@ class CustomLinkBulkEditForm(BootstrapMixin, BulkEditForm):
|
|||||||
|
|
||||||
class CustomLinkFilterForm(BootstrapMixin, forms.Form):
|
class CustomLinkFilterForm(BootstrapMixin, forms.Form):
|
||||||
field_groups = [
|
field_groups = [
|
||||||
|
['q'],
|
||||||
['content_type'],
|
['content_type'],
|
||||||
['weight', 'new_window'],
|
['weight', 'new_window'],
|
||||||
]
|
]
|
||||||
|
q = forms.CharField(
|
||||||
|
required=False,
|
||||||
|
widget=forms.TextInput(attrs={'placeholder': _('All Fields')}),
|
||||||
|
label=_('Search')
|
||||||
|
)
|
||||||
content_type = ContentTypeChoiceField(
|
content_type = ContentTypeChoiceField(
|
||||||
queryset=ContentType.objects.all(),
|
queryset=ContentType.objects.all(),
|
||||||
limit_choices_to=FeatureQuery('custom_fields')
|
limit_choices_to=FeatureQuery('custom_fields')
|
||||||
@ -252,9 +264,15 @@ class ExportTemplateBulkEditForm(BootstrapMixin, BulkEditForm):
|
|||||||
|
|
||||||
class ExportTemplateFilterForm(BootstrapMixin, forms.Form):
|
class ExportTemplateFilterForm(BootstrapMixin, forms.Form):
|
||||||
field_groups = [
|
field_groups = [
|
||||||
|
['q'],
|
||||||
['content_type', 'mime_type'],
|
['content_type', 'mime_type'],
|
||||||
['file_extension', 'as_attachment'],
|
['file_extension', 'as_attachment'],
|
||||||
]
|
]
|
||||||
|
q = forms.CharField(
|
||||||
|
required=False,
|
||||||
|
widget=forms.TextInput(attrs={'placeholder': _('All Fields')}),
|
||||||
|
label=_('Search')
|
||||||
|
)
|
||||||
content_type = ContentTypeChoiceField(
|
content_type = ContentTypeChoiceField(
|
||||||
queryset=ContentType.objects.all(),
|
queryset=ContentType.objects.all(),
|
||||||
limit_choices_to=FeatureQuery('custom_fields')
|
limit_choices_to=FeatureQuery('custom_fields')
|
||||||
@ -358,9 +376,15 @@ class WebhookBulkEditForm(BootstrapMixin, BulkEditForm):
|
|||||||
|
|
||||||
class WebhookFilterForm(BootstrapMixin, forms.Form):
|
class WebhookFilterForm(BootstrapMixin, forms.Form):
|
||||||
field_groups = [
|
field_groups = [
|
||||||
|
['q'],
|
||||||
['content_types', 'http_method'],
|
['content_types', 'http_method'],
|
||||||
['enabled', 'type_create', 'type_update', 'type_delete'],
|
['enabled', 'type_create', 'type_update', 'type_delete'],
|
||||||
]
|
]
|
||||||
|
q = forms.CharField(
|
||||||
|
required=False,
|
||||||
|
widget=forms.TextInput(attrs={'placeholder': _('All Fields')}),
|
||||||
|
label=_('Search')
|
||||||
|
)
|
||||||
content_types = ContentTypeMultipleChoiceField(
|
content_types = ContentTypeMultipleChoiceField(
|
||||||
queryset=ContentType.objects.all(),
|
queryset=ContentType.objects.all(),
|
||||||
limit_choices_to=FeatureQuery('custom_fields')
|
limit_choices_to=FeatureQuery('custom_fields')
|
||||||
@ -664,15 +688,21 @@ class ConfigContextBulkEditForm(BootstrapMixin, BulkEditForm):
|
|||||||
|
|
||||||
class ConfigContextFilterForm(BootstrapMixin, forms.Form):
|
class ConfigContextFilterForm(BootstrapMixin, forms.Form):
|
||||||
field_order = [
|
field_order = [
|
||||||
'region_id', 'site_group_id', 'site_id', 'role_id', 'platform_id', 'cluster_group_id', 'cluster_id',
|
'q', 'region_id', 'site_group_id', 'site_id', 'role_id', 'platform_id', 'cluster_group_id',
|
||||||
'tenant_group_id', 'tenant_id',
|
'cluster_id', 'tenant_group_id', 'tenant_id',
|
||||||
]
|
]
|
||||||
field_groups = [
|
field_groups = [
|
||||||
|
['q'],
|
||||||
['region_id', 'site_group_id', 'site_id'],
|
['region_id', 'site_group_id', 'site_id'],
|
||||||
['device_type_id', 'role_id', 'platform_id'],
|
['device_type_id', 'role_id', 'platform_id'],
|
||||||
['cluster_group_id', 'cluster_id'],
|
['cluster_group_id', 'cluster_id'],
|
||||||
['tenant_group_id', 'tenant_id', 'tag']
|
['tenant_group_id', 'tenant_id', 'tag']
|
||||||
]
|
]
|
||||||
|
q = forms.CharField(
|
||||||
|
required=False,
|
||||||
|
widget=forms.TextInput(attrs={'placeholder': _('All Fields')}),
|
||||||
|
label=_('Search')
|
||||||
|
)
|
||||||
region_id = DynamicModelMultipleChoiceField(
|
region_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=Region.objects.all(),
|
queryset=Region.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
@ -812,9 +842,15 @@ class JournalEntryBulkEditForm(BootstrapMixin, BulkEditForm):
|
|||||||
class JournalEntryFilterForm(BootstrapMixin, forms.Form):
|
class JournalEntryFilterForm(BootstrapMixin, forms.Form):
|
||||||
model = JournalEntry
|
model = JournalEntry
|
||||||
field_groups = [
|
field_groups = [
|
||||||
|
['q'],
|
||||||
['created_before', 'created_after', 'created_by_id'],
|
['created_before', 'created_after', 'created_by_id'],
|
||||||
['assigned_object_type_id', 'kind']
|
['assigned_object_type_id', 'kind']
|
||||||
]
|
]
|
||||||
|
q = forms.CharField(
|
||||||
|
required=False,
|
||||||
|
widget=forms.TextInput(attrs={'placeholder': _('All Fields')}),
|
||||||
|
label=_('Search')
|
||||||
|
)
|
||||||
created_after = forms.DateTimeField(
|
created_after = forms.DateTimeField(
|
||||||
required=False,
|
required=False,
|
||||||
label=_('After'),
|
label=_('After'),
|
||||||
@ -857,9 +893,15 @@ class JournalEntryFilterForm(BootstrapMixin, forms.Form):
|
|||||||
class ObjectChangeFilterForm(BootstrapMixin, forms.Form):
|
class ObjectChangeFilterForm(BootstrapMixin, forms.Form):
|
||||||
model = ObjectChange
|
model = ObjectChange
|
||||||
field_groups = [
|
field_groups = [
|
||||||
|
['q'],
|
||||||
['time_before', 'time_after', 'action'],
|
['time_before', 'time_after', 'action'],
|
||||||
['user_id', 'changed_object_type_id'],
|
['user_id', 'changed_object_type_id'],
|
||||||
]
|
]
|
||||||
|
q = forms.CharField(
|
||||||
|
required=False,
|
||||||
|
widget=forms.TextInput(attrs={'placeholder': _('All Fields')}),
|
||||||
|
label=_('Search')
|
||||||
|
)
|
||||||
time_after = forms.DateTimeField(
|
time_after = forms.DateTimeField(
|
||||||
required=False,
|
required=False,
|
||||||
label=_('After'),
|
label=_('After'),
|
||||||
|
@ -10,10 +10,10 @@ from utilities.utils import render_jinja2
|
|||||||
|
|
||||||
register = template.Library()
|
register = template.Library()
|
||||||
|
|
||||||
LINK_BUTTON = '<a href="{}"{} class="btn btn-sm btn-{} m-1">{}</a>\n'
|
LINK_BUTTON = '<a href="{}"{} class="btn btn-sm btn-{}">{}</a>\n'
|
||||||
|
|
||||||
GROUP_BUTTON = """
|
GROUP_BUTTON = """
|
||||||
<div class="dropdown m-1">
|
<div class="dropdown">
|
||||||
<button
|
<button
|
||||||
class="btn btn-sm btn-{} dropdown-toggle"
|
class="btn btn-sm btn-{} dropdown-toggle"
|
||||||
type="button"
|
type="button"
|
||||||
|
@ -75,13 +75,13 @@ class CustomLinkTestCase(ViewTestCases.PrimaryObjectViewTestCase):
|
|||||||
|
|
||||||
cls.csv_data = (
|
cls.csv_data = (
|
||||||
"name,content_type,weight,button_class,link_text,link_url",
|
"name,content_type,weight,button_class,link_text,link_url",
|
||||||
"Custom Link 4,dcim.site,100,primary,Link 4,http://exmaple.com/?4",
|
"Custom Link 4,dcim.site,100,blue,Link 4,http://exmaple.com/?4",
|
||||||
"Custom Link 5,dcim.site,100,primary,Link 5,http://exmaple.com/?5",
|
"Custom Link 5,dcim.site,100,blue,Link 5,http://exmaple.com/?5",
|
||||||
"Custom Link 6,dcim.site,100,primary,Link 6,http://exmaple.com/?6",
|
"Custom Link 6,dcim.site,100,blue,Link 6,http://exmaple.com/?6",
|
||||||
)
|
)
|
||||||
|
|
||||||
cls.bulk_edit_data = {
|
cls.bulk_edit_data = {
|
||||||
'button_class': CustomLinkButtonClassChoices.CLASS_INFO,
|
'button_class': CustomLinkButtonClassChoices.CLASS_CYAN,
|
||||||
'weight': 200,
|
'weight': 200,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,12 +106,18 @@ class VRFBulkEditForm(BootstrapMixin, AddRemoveTagsForm, CustomFieldModelBulkEdi
|
|||||||
|
|
||||||
class VRFFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldModelFilterForm):
|
class VRFFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldModelFilterForm):
|
||||||
model = VRF
|
model = VRF
|
||||||
field_order = ['import_target_id', 'export_target_id', 'tenant_group_id', 'tenant_id']
|
field_order = ['q', 'import_target_id', 'export_target_id', 'tenant_group_id', 'tenant_id']
|
||||||
field_groups = [
|
field_groups = [
|
||||||
|
['q'],
|
||||||
['import_target_id', 'export_target_id'],
|
['import_target_id', 'export_target_id'],
|
||||||
['tenant_group_id', 'tenant_id'],
|
['tenant_group_id', 'tenant_id'],
|
||||||
['tag']
|
['tag']
|
||||||
]
|
]
|
||||||
|
q = forms.CharField(
|
||||||
|
required=False,
|
||||||
|
widget=forms.TextInput(attrs={'placeholder': _('All Fields')}),
|
||||||
|
label=_('Search')
|
||||||
|
)
|
||||||
import_target_id = DynamicModelMultipleChoiceField(
|
import_target_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=RouteTarget.objects.all(),
|
queryset=RouteTarget.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
@ -179,11 +185,17 @@ class RouteTargetBulkEditForm(BootstrapMixin, AddRemoveTagsForm, CustomFieldMode
|
|||||||
|
|
||||||
class RouteTargetFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldModelFilterForm):
|
class RouteTargetFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldModelFilterForm):
|
||||||
model = RouteTarget
|
model = RouteTarget
|
||||||
field_order = ['name', 'tenant_group_id', 'tenant_id', 'importing_vrfs', 'exporting_vrfs']
|
field_order = ['q', 'name', 'tenant_group_id', 'tenant_id', 'importing_vrfs', 'exporting_vrfs']
|
||||||
field_groups = [
|
field_groups = [
|
||||||
|
['q'],
|
||||||
['importing_vrf_id', 'exporting_vrf_id'],
|
['importing_vrf_id', 'exporting_vrf_id'],
|
||||||
['tenant_group_id', 'tenant_id'],
|
['tenant_group_id', 'tenant_id'],
|
||||||
]
|
]
|
||||||
|
q = forms.CharField(
|
||||||
|
required=False,
|
||||||
|
widget=forms.TextInput(attrs={'placeholder': _('All Fields')}),
|
||||||
|
label=_('Search')
|
||||||
|
)
|
||||||
importing_vrf_id = DynamicModelMultipleChoiceField(
|
importing_vrf_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=VRF.objects.all(),
|
queryset=VRF.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
@ -335,11 +347,17 @@ class AggregateBulkEditForm(BootstrapMixin, AddRemoveTagsForm, CustomFieldModelB
|
|||||||
|
|
||||||
class AggregateFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldModelFilterForm):
|
class AggregateFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldModelFilterForm):
|
||||||
model = Aggregate
|
model = Aggregate
|
||||||
field_order = ['family', 'rir', 'tenant_group_id', 'tenant_id']
|
field_order = ['q', 'family', 'rir', 'tenant_group_id', 'tenant_id']
|
||||||
field_groups = [
|
field_groups = [
|
||||||
|
['q'],
|
||||||
['family', 'rir_id'],
|
['family', 'rir_id'],
|
||||||
['tenant_group_id', 'tenant_id']
|
['tenant_group_id', 'tenant_id']
|
||||||
]
|
]
|
||||||
|
q = forms.CharField(
|
||||||
|
required=False,
|
||||||
|
widget=forms.TextInput(attrs={'placeholder': _('All Fields')}),
|
||||||
|
label=_('Search')
|
||||||
|
)
|
||||||
family = forms.ChoiceField(
|
family = forms.ChoiceField(
|
||||||
required=False,
|
required=False,
|
||||||
choices=add_blank_choice(IPAddressFamilyChoices),
|
choices=add_blank_choice(IPAddressFamilyChoices),
|
||||||
@ -610,15 +628,22 @@ class PrefixBulkEditForm(BootstrapMixin, AddRemoveTagsForm, CustomFieldModelBulk
|
|||||||
class PrefixFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldModelFilterForm):
|
class PrefixFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldModelFilterForm):
|
||||||
model = Prefix
|
model = Prefix
|
||||||
field_order = [
|
field_order = [
|
||||||
'within_include', 'family', 'mask_length', 'vrf_id', 'present_in_vrf_id', 'status', 'region_id',
|
'q', 'within_include', 'family', 'mask_length', 'vrf_id', 'present_in_vrf_id', 'status',
|
||||||
'site_group_id', 'site_id', 'role_id', 'tenant_group_id', 'tenant_id', 'is_pool', 'mark_utilized',
|
'region_id', 'site_group_id', 'site_id', 'role_id', 'tenant_group_id', 'tenant_id',
|
||||||
|
'is_pool', 'mark_utilized',
|
||||||
]
|
]
|
||||||
field_groups = [
|
field_groups = [
|
||||||
|
['q'],
|
||||||
['role_id', 'within_include', 'family', 'mask_length'],
|
['role_id', 'within_include', 'family', 'mask_length'],
|
||||||
['vrf_id', 'present_in_vrf_id', 'is_pool', 'mark_utilized'],
|
['vrf_id', 'present_in_vrf_id', 'is_pool', 'mark_utilized'],
|
||||||
['region_id', 'site_group_id', 'site_id'],
|
['region_id', 'site_group_id', 'site_id'],
|
||||||
['tenant_group_id', 'tenant_id', 'status', 'tag']
|
['tenant_group_id', 'tenant_id', 'status', 'tag']
|
||||||
]
|
]
|
||||||
|
q = forms.CharField(
|
||||||
|
required=False,
|
||||||
|
widget=forms.TextInput(attrs={'placeholder': _('All Fields')}),
|
||||||
|
label=_('Search')
|
||||||
|
)
|
||||||
mask_length__lte = forms.IntegerField(
|
mask_length__lte = forms.IntegerField(
|
||||||
widget=forms.HiddenInput()
|
widget=forms.HiddenInput()
|
||||||
)
|
)
|
||||||
@ -813,12 +838,18 @@ class IPRangeBulkEditForm(BootstrapMixin, AddRemoveTagsForm, CustomFieldModelBul
|
|||||||
class IPRangeFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldModelFilterForm):
|
class IPRangeFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldModelFilterForm):
|
||||||
model = IPRange
|
model = IPRange
|
||||||
field_order = [
|
field_order = [
|
||||||
'family', 'vrf_id', 'status', 'role_id', 'tenant_group_id', 'tenant_id',
|
'q', 'family', 'vrf_id', 'status', 'role_id', 'tenant_group_id', 'tenant_id',
|
||||||
]
|
]
|
||||||
field_groups = [
|
field_groups = [
|
||||||
|
['q'],
|
||||||
['family', 'vrf_id', 'status', 'role_id'],
|
['family', 'vrf_id', 'status', 'role_id'],
|
||||||
['tenant_group_id', 'tenant_id', 'tag'],
|
['tenant_group_id', 'tenant_id', 'tag'],
|
||||||
]
|
]
|
||||||
|
q = forms.CharField(
|
||||||
|
required=False,
|
||||||
|
widget=forms.TextInput(attrs={'placeholder': _('All Fields')}),
|
||||||
|
label=_('Search')
|
||||||
|
)
|
||||||
family = forms.ChoiceField(
|
family = forms.ChoiceField(
|
||||||
required=False,
|
required=False,
|
||||||
choices=add_blank_choice(IPAddressFamilyChoices),
|
choices=add_blank_choice(IPAddressFamilyChoices),
|
||||||
@ -1244,15 +1275,21 @@ class IPAddressAssignForm(BootstrapMixin, forms.Form):
|
|||||||
class IPAddressFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldModelFilterForm):
|
class IPAddressFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldModelFilterForm):
|
||||||
model = IPAddress
|
model = IPAddress
|
||||||
field_order = [
|
field_order = [
|
||||||
'parent', 'family', 'mask_length', 'vrf_id', 'present_in_vrf_id', 'status', 'role',
|
'q', 'parent', 'family', 'mask_length', 'vrf_id', 'present_in_vrf_id', 'status', 'role',
|
||||||
'assigned_to_interface', 'tenant_group_id', 'tenant_id',
|
'assigned_to_interface', 'tenant_group_id', 'tenant_id',
|
||||||
]
|
]
|
||||||
field_groups = [
|
field_groups = [
|
||||||
|
['q'],
|
||||||
['parent', 'family', 'mask_length'],
|
['parent', 'family', 'mask_length'],
|
||||||
['status', 'vrf_id', 'present_in_vrf_id'],
|
['status', 'vrf_id', 'present_in_vrf_id'],
|
||||||
['role', 'assigned_to_interface'],
|
['role', 'assigned_to_interface'],
|
||||||
['tenant_group_id', 'tenant_id'],
|
['tenant_group_id', 'tenant_id'],
|
||||||
]
|
]
|
||||||
|
q = forms.CharField(
|
||||||
|
required=False,
|
||||||
|
widget=forms.TextInput(attrs={'placeholder': _('All Fields')}),
|
||||||
|
label=_('Search')
|
||||||
|
)
|
||||||
parent = forms.CharField(
|
parent = forms.CharField(
|
||||||
required=False,
|
required=False,
|
||||||
widget=forms.TextInput(
|
widget=forms.TextInput(
|
||||||
@ -1444,11 +1481,13 @@ class VLANGroupBulkEditForm(BootstrapMixin, CustomFieldModelBulkEditForm):
|
|||||||
|
|
||||||
class VLANGroupFilterForm(BootstrapMixin, forms.Form):
|
class VLANGroupFilterForm(BootstrapMixin, forms.Form):
|
||||||
field_groups = [
|
field_groups = [
|
||||||
|
['q'],
|
||||||
['region', 'sitegroup', 'site'],
|
['region', 'sitegroup', 'site'],
|
||||||
['location', 'rack']
|
['location', 'rack']
|
||||||
]
|
]
|
||||||
q = forms.CharField(
|
q = forms.CharField(
|
||||||
required=False,
|
required=False,
|
||||||
|
widget=forms.TextInput(attrs={'placeholder': _('All Fields')}),
|
||||||
label=_('Search')
|
label=_('Search')
|
||||||
)
|
)
|
||||||
region = DynamicModelMultipleChoiceField(
|
region = DynamicModelMultipleChoiceField(
|
||||||
@ -1662,13 +1701,20 @@ class VLANBulkEditForm(BootstrapMixin, AddRemoveTagsForm, CustomFieldModelBulkEd
|
|||||||
class VLANFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldModelFilterForm):
|
class VLANFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldModelFilterForm):
|
||||||
model = VLAN
|
model = VLAN
|
||||||
field_order = [
|
field_order = [
|
||||||
'region_id', 'site_group_id', 'site_id', 'group_id', 'status', 'role_id', 'tenant_group_id', 'tenant_id',
|
'q', 'region_id', 'site_group_id', 'site_id', 'group_id', 'status', 'role_id',
|
||||||
|
'tenant_group_id', 'tenant_id',
|
||||||
]
|
]
|
||||||
field_groups = [
|
field_groups = [
|
||||||
|
['q'],
|
||||||
['region_id', 'site_group_id', 'site_id'],
|
['region_id', 'site_group_id', 'site_id'],
|
||||||
['group_id', 'role_id', 'status'],
|
['group_id', 'role_id', 'status'],
|
||||||
['tenant_group_id', 'tenant_id'],
|
['tenant_group_id', 'tenant_id'],
|
||||||
]
|
]
|
||||||
|
q = forms.CharField(
|
||||||
|
required=False,
|
||||||
|
widget=forms.TextInput(attrs={'placeholder': _('All Fields')}),
|
||||||
|
label=_('Search')
|
||||||
|
)
|
||||||
region_id = DynamicModelMultipleChoiceField(
|
region_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=Region.objects.all(),
|
queryset=Region.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
@ -1765,6 +1811,11 @@ class ServiceForm(BootstrapMixin, CustomFieldModelForm):
|
|||||||
|
|
||||||
class ServiceFilterForm(BootstrapMixin, CustomFieldModelFilterForm):
|
class ServiceFilterForm(BootstrapMixin, CustomFieldModelFilterForm):
|
||||||
model = Service
|
model = Service
|
||||||
|
q = forms.CharField(
|
||||||
|
required=False,
|
||||||
|
widget=forms.TextInput(attrs={'placeholder': _('All Fields')}),
|
||||||
|
label=_('Search')
|
||||||
|
)
|
||||||
protocol = forms.ChoiceField(
|
protocol = forms.ChoiceField(
|
||||||
choices=add_blank_choice(ServiceProtocolChoices),
|
choices=add_blank_choice(ServiceProtocolChoices),
|
||||||
required=False,
|
required=False,
|
||||||
|
BIN
netbox/project-static/dist/netbox-dark.css
vendored
BIN
netbox/project-static/dist/netbox-dark.css
vendored
Binary file not shown.
BIN
netbox/project-static/dist/netbox-light.css
vendored
BIN
netbox/project-static/dist/netbox-light.css
vendored
Binary file not shown.
@ -89,8 +89,13 @@ table td > .progress {
|
|||||||
min-width: 6rem;
|
min-width: 6rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Automatically space out adjacent columns.
|
// Override Bootstrap form-control font-size when contained by .small element.
|
||||||
.col:not(:last-child):not(:only-child) {
|
.small .form-control {
|
||||||
|
font-size: $font-size-sm;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Automatically space out adjacent columns, but not within card bodies.
|
||||||
|
:not(.card-body) > .col:not(:last-child):not(:only-child) {
|
||||||
margin-bottom: $spacer;
|
margin-bottom: $spacer;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -113,15 +118,6 @@ table td > .progress {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.search-container {
|
|
||||||
display: flex;
|
|
||||||
width: 100%;
|
|
||||||
|
|
||||||
@include media-breakpoint-down(lg) {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.card > .table.table-flush {
|
.card > .table.table-flush {
|
||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
@ -265,25 +261,127 @@ div.title-container {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Object list control buttons (Add/Clone/Import/Export)
|
||||||
|
.controls {
|
||||||
|
margin-bottom: map.get($spacers, 2);
|
||||||
|
|
||||||
|
// Each group of buttons.
|
||||||
|
.control-group {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
// Left-align controls on mobile.
|
||||||
|
justify-content: flex-start;
|
||||||
|
|
||||||
|
// Right-align controls on larger screens.
|
||||||
|
@include media-breakpoint-up(md) {
|
||||||
|
justify-content: flex-end;
|
||||||
|
}
|
||||||
|
|
||||||
|
> * {
|
||||||
|
// Pad each control button.
|
||||||
|
margin: map.get($spacers, 1);
|
||||||
|
|
||||||
|
&:first-child {
|
||||||
|
// Don't pad the left side of the first control button.
|
||||||
|
margin-left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
// Don't pad the right side of the last control button.
|
||||||
|
margin-right: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.object-subtitle {
|
||||||
|
display: block;
|
||||||
|
font-size: $font-size-sm;
|
||||||
|
color: $text-muted;
|
||||||
|
|
||||||
|
@include media-breakpoint-up(md) {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
> span {
|
||||||
|
display: block;
|
||||||
|
|
||||||
|
// Hide the separator on small screens.
|
||||||
|
&.separator {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
&,
|
||||||
|
&.separator {
|
||||||
|
@include media-breakpoint-up(md) {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Global Search
|
||||||
nav.search {
|
nav.search {
|
||||||
// Don't overtake dropdowns
|
// Don't overtake dropdowns
|
||||||
z-index: 999;
|
z-index: 999;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
background-color: var(--nbx-body-bg);
|
background-color: var(--nbx-body-bg);
|
||||||
|
|
||||||
form button.dropdown-toggle {
|
.search-container {
|
||||||
|
display: flex;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
@include media-breakpoint-down(lg) {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Search Input & Selected Object Value & Object Selector
|
||||||
|
.input-group {
|
||||||
|
// Selected Object
|
||||||
|
.search-obj-selected {
|
||||||
|
border-color: $input-border-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Object Selector Dropdown Button
|
||||||
|
.dropdown-toggle {
|
||||||
|
// Generate the same styles as a regular Bootstrap button.
|
||||||
|
@include button-variant($input-group-addon-bg, $input-border-color);
|
||||||
|
margin-left: 0;
|
||||||
font-weight: $input-group-addon-font-weight;
|
font-weight: $input-group-addon-font-weight;
|
||||||
line-height: $input-line-height;
|
line-height: $input-line-height;
|
||||||
color: $input-group-addon-color;
|
color: $input-group-addon-color;
|
||||||
background-color: $input-group-addon-bg;
|
background-color: $input-group-addon-bg;
|
||||||
border: $input-border-width solid $input-group-addon-border-color;
|
border: $input-border-width solid $input-border-color;
|
||||||
border-color: $input-border-color;
|
|
||||||
@include border-radius($input-border-radius);
|
@include border-radius($input-border-radius);
|
||||||
border-left: 1px solid var(--nbx-search-filter-border-left-color);
|
border-left: 1px solid var(--nbx-search-filter-border-left-color);
|
||||||
|
|
||||||
&:focus {
|
&:focus {
|
||||||
box-shadow: unset !important;
|
box-shadow: unset !important;
|
||||||
}
|
}
|
||||||
|
// Don't show the dropdown icon — the filter icon is basically the same thing.
|
||||||
|
&:after {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Object Selector Dropdown Menu
|
||||||
|
.search-obj-selector {
|
||||||
|
@include media-breakpoint-down(lg) {
|
||||||
|
// Limit the height and enable scrolling on mobile devices.
|
||||||
|
max-height: 70vh;
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown-item,
|
||||||
|
.dropdown-header {
|
||||||
|
font-size: $font-size-sm;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown-header {
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -431,23 +529,6 @@ div.content-container {
|
|||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.search-obj-selector {
|
|
||||||
@include media-breakpoint-down(lg) {
|
|
||||||
// Limit the height and enable scrolling on mobile devices.
|
|
||||||
max-height: 75vh;
|
|
||||||
overflow-y: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dropdown-item,
|
|
||||||
.dropdown-header {
|
|
||||||
font-size: $font-size-sm;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dropdown-header {
|
|
||||||
text-transform: uppercase;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
span.color-label {
|
span.color-label {
|
||||||
display: block;
|
display: block;
|
||||||
width: 5rem;
|
width: 5rem;
|
||||||
@ -479,6 +560,14 @@ span.color-label {
|
|||||||
.card-body.small .form-select {
|
.card-body.small .form-select {
|
||||||
font-size: $input-font-size-sm;
|
font-size: $input-font-size-sm;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.card-divider {
|
||||||
|
width: 100%;
|
||||||
|
height: 1px;
|
||||||
|
margin: $hr-margin-y 0;
|
||||||
|
border-top: 1px solid $card-border-color;
|
||||||
|
opacity: $hr-opacity;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.form-floating {
|
.form-floating {
|
||||||
|
@ -21,6 +21,14 @@ $theme-colors: (
|
|||||||
'danger': $danger,
|
'danger': $danger,
|
||||||
'light': $light,
|
'light': $light,
|
||||||
'dark': $dark,
|
'dark': $dark,
|
||||||
|
'red': $red-300,
|
||||||
|
'yellow': $yellow-300,
|
||||||
|
'green': $green-300,
|
||||||
|
'blue': $blue-300,
|
||||||
|
'cyan': $cyan-300,
|
||||||
|
'indigo': $indigo-300,
|
||||||
|
'purple': $purple-300,
|
||||||
|
'pink': $pink-300,
|
||||||
);
|
);
|
||||||
|
|
||||||
$theme-colors: map-merge($theme-colors, $theme-color-addons);
|
$theme-colors: map-merge($theme-colors, $theme-color-addons);
|
||||||
|
@ -4,6 +4,20 @@
|
|||||||
|
|
||||||
$input-border-color: $gray-200;
|
$input-border-color: $gray-200;
|
||||||
|
|
||||||
|
$theme-colors: map-merge(
|
||||||
|
$theme-colors,
|
||||||
|
(
|
||||||
|
'red': $red-500,
|
||||||
|
'yellow': $yellow-500,
|
||||||
|
'green': $green-500,
|
||||||
|
'blue': $blue-500,
|
||||||
|
'cyan': $cyan-500,
|
||||||
|
'indigo': $indigo-500,
|
||||||
|
'purple': $purple-500,
|
||||||
|
'pink': $pink-500,
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
$theme-colors: map-merge($theme-colors, $theme-color-addons);
|
$theme-colors: map-merge($theme-colors, $theme-color-addons);
|
||||||
|
|
||||||
$light: $gray-200;
|
$light: $gray-200;
|
||||||
|
@ -2,14 +2,15 @@
|
|||||||
|
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<div class="card-header">
|
<div class="card-header">
|
||||||
<div class="float-end">
|
<strong class="d-block d-md-inline mb-3 mb-md-0">Termination - {{ side }} Side</strong>
|
||||||
|
<div class="float-md-end">
|
||||||
{% if not termination and perms.circuits.add_circuittermination %}
|
{% if not termination and perms.circuits.add_circuittermination %}
|
||||||
<a href="{% url 'circuits:circuittermination_add' circuit=object.pk %}?term_side={{ side }}" class="btn btn-sm btn-success lh-1">
|
<a href="{% url 'circuits:circuittermination_add' circuit=object.pk %}?term_side={{ side }}" class="btn btn-sm btn-success lh-1">
|
||||||
<span class="mdi mdi-plus-thick" aria-hidden="true"></span> Add
|
<span class="mdi mdi-plus-thick" aria-hidden="true"></span> Add
|
||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if termination and perms.circuits.change_circuittermination %}
|
{% if termination and perms.circuits.change_circuittermination %}
|
||||||
<a href="{% url 'circuits:circuittermination_edit' pk=termination.pk %}" class="btn btn-sm btn-yellow-500 lh-1">
|
<a href="{% url 'circuits:circuittermination_edit' pk=termination.pk %}" class="btn btn-sm btn-yellow lh-1">
|
||||||
<span class="mdi mdi-pencil" aria-hidden="true"></span> Edit
|
<span class="mdi mdi-pencil" aria-hidden="true"></span> Edit
|
||||||
</a>
|
</a>
|
||||||
<a href="{% url 'circuits:circuit_terminations_swap' pk=object.pk %}" class="btn btn-sm btn-primary lh-1">
|
<a href="{% url 'circuits:circuit_terminations_swap' pk=object.pk %}" class="btn btn-sm btn-primary lh-1">
|
||||||
@ -22,7 +23,6 @@
|
|||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
<strong>Termination - {{ side }} Side</strong>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
{% if termination %}
|
{% if termination %}
|
||||||
@ -44,17 +44,7 @@
|
|||||||
<span class="text-success"><i class="mdi mdi-check-bold"></i></span>
|
<span class="text-success"><i class="mdi mdi-check-bold"></i></span>
|
||||||
<span class="text-muted">Marked as connected</span>
|
<span class="text-muted">Marked as connected</span>
|
||||||
{% elif termination.cable %}
|
{% elif termination.cable %}
|
||||||
<div class="float-end">
|
<a class="d-block d-md-inline" href="{{ termination.cable.get_absolute_url }}">{{ termination.cable }}</a>
|
||||||
<a href="{% url 'circuits:circuittermination_trace' pk=termination.pk %}" class="btn btn-primary btn-sm lh-1" title="Trace">
|
|
||||||
<i class="mdi mdi-transit-connection-variant" aria-hidden="true"></i>
|
|
||||||
</a>
|
|
||||||
{% if perms.dcim.delete_cable %}
|
|
||||||
<a href="{% url 'dcim:cable_delete' pk=termination.cable.pk %}?return_url={{ termination.circuit.get_absolute_url }}" title="Remove cable" class="btn btn-danger btn-sm lh-1">
|
|
||||||
<i class="mdi mdi-ethernet-cable-off" aria-hidden="true"></i> Disconnect
|
|
||||||
</a>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
<a href="{{ termination.cable.get_absolute_url }}">{{ termination.cable }}</a>
|
|
||||||
{% with peer=termination.get_cable_peer %}
|
{% with peer=termination.get_cable_peer %}
|
||||||
to
|
to
|
||||||
{% if peer.device %}
|
{% if peer.device %}
|
||||||
@ -64,6 +54,16 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
<a href="{{ peer.get_absolute_url }}">{{ peer }}</a>
|
<a href="{{ peer.get_absolute_url }}">{{ peer }}</a>
|
||||||
{% endwith %}
|
{% endwith %}
|
||||||
|
<div class="float-md-end mt-3 mt-md-0">
|
||||||
|
<a href="{% url 'circuits:circuittermination_trace' pk=termination.pk %}" class="btn btn-primary btn-sm lh-1" title="Trace">
|
||||||
|
<i class="mdi mdi-transit-connection-variant" aria-hidden="true"></i>
|
||||||
|
</a>
|
||||||
|
{% if perms.dcim.delete_cable %}
|
||||||
|
<a href="{% url 'dcim:cable_delete' pk=termination.cable.pk %}?return_url={{ termination.circuit.get_absolute_url }}" title="Remove cable" class="btn btn-danger btn-sm lh-1">
|
||||||
|
<i class="mdi mdi-ethernet-cable-off" aria-hidden="true"></i> Disconnect
|
||||||
|
</a>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
{% elif perms.dcim.add_cable %}
|
{% elif perms.dcim.add_cable %}
|
||||||
<div class="dropdown">
|
<div class="dropdown">
|
||||||
<button type="button" class="btn btn-success btn-sm dropdown-toggle" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
<button type="button" class="btn btn-success btn-sm dropdown-toggle" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||||
|
@ -15,89 +15,70 @@
|
|||||||
|
|
||||||
{% block extra_controls %}
|
{% block extra_controls %}
|
||||||
{% if perms.dcim.change_device %}
|
{% if perms.dcim.change_device %}
|
||||||
<div class="dropdown m-1">
|
<div class="dropdown">
|
||||||
<button id="add-device-components" type="button" class="btn btn-sm btn-primary dropdown-toggle" data-bs-toggle="dropdown" aria-expanded="false">
|
<button id="add-device-components" type="button" class="btn btn-sm btn-primary dropdown-toggle" data-bs-toggle="dropdown" aria-expanded="false">
|
||||||
<i class="mdi mdi-plus-thick" aria-hidden="true"></i> Add Components
|
<i class="mdi mdi-plus-thick" aria-hidden="true"></i> Add Components
|
||||||
</button>
|
</button>
|
||||||
<ul class="dropdown-menu" aria-labeled-by="add-device-components">
|
<ul class="dropdown-menu" aria-labeled-by="add-device-components">
|
||||||
{% if perms.dcim.add_consoleport %}
|
{% if perms.dcim.add_consoleport %}
|
||||||
<li>
|
<li>
|
||||||
<a
|
<a class="dropdown-item" href="{% url 'dcim:consoleport_add' %}?device={{ object.pk }}&return_url={% url 'dcim:device_consoleports' pk=object.pk %}">
|
||||||
class="dropdown-item"
|
|
||||||
href="{% url 'dcim:consoleport_add' %}?device={{ object.pk }}&return_url={% url 'dcim:device_consoleports' pk=object.pk %}"
|
|
||||||
>
|
|
||||||
Console Ports
|
Console Ports
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if perms.dcim.add_consoleserverport %}
|
{% if perms.dcim.add_consoleserverport %}
|
||||||
<li>
|
<li>
|
||||||
<a
|
<a class="dropdown-item" href="{% url 'dcim:consoleserverport_add' %}?device={{ object.pk }}&return_url={% url 'dcim:device_consoleserverports' pk=object.pk %}">
|
||||||
class="dropdown-item"
|
|
||||||
href="{% url 'dcim:consoleserverport_add' %}?device={{ object.pk }}&return_url={% url 'dcim:device_consoleserverports' pk=object.pk %}">
|
|
||||||
Console Server Ports
|
Console Server Ports
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if perms.dcim.add_powerport %}
|
{% if perms.dcim.add_powerport %}
|
||||||
<li>
|
<li>
|
||||||
<a
|
<a class="dropdown-item" href="{% url 'dcim:powerport_add' %}?device={{ object.pk }}&return_url={% url 'dcim:device_powerports' pk=object.pk %}">
|
||||||
class="dropdown-item"
|
|
||||||
href="{% url 'dcim:powerport_add' %}?device={{ object.pk }}&return_url={% url 'dcim:device_powerports' pk=object.pk %}">
|
|
||||||
Power Ports
|
Power Ports
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if perms.dcim.add_poweroutlet %}
|
{% if perms.dcim.add_poweroutlet %}
|
||||||
<li>
|
<li>
|
||||||
<a
|
<a class="dropdown-item" href="{% url 'dcim:poweroutlet_add' %}?device={{ object.pk }}&return_url={% url 'dcim:device_poweroutlets' pk=object.pk %}">
|
||||||
class="dropdown-item"
|
|
||||||
href="{% url 'dcim:poweroutlet_add' %}?device={{ object.pk }}&return_url={% url 'dcim:device_poweroutlets' pk=object.pk %}">
|
|
||||||
Power Outlets
|
Power Outlets
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if perms.dcim.add_interface %}
|
{% if perms.dcim.add_interface %}
|
||||||
<li>
|
<li>
|
||||||
<a
|
<a class="dropdown-item" href="{% url 'dcim:interface_add' %}?device={{ object.pk }}&return_url={% url 'dcim:device_interfaces' pk=object.pk %}">
|
||||||
class="dropdown-item"
|
|
||||||
href="{% url 'dcim:interface_add' %}?device={{ object.pk }}&return_url={% url 'dcim:device_interfaces' pk=object.pk %}">
|
|
||||||
Interfaces
|
Interfaces
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if perms.dcim.add_frontport %}
|
{% if perms.dcim.add_frontport %}
|
||||||
<li>
|
<li>
|
||||||
<a
|
<a class="dropdown-item" href="{% url 'dcim:frontport_add' %}?device={{ object.pk }}&return_url={% url 'dcim:device_frontports' pk=object.pk %}">
|
||||||
class="dropdown-item"
|
|
||||||
href="{% url 'dcim:frontport_add' %}?device={{ object.pk }}&return_url={% url 'dcim:device_frontports' pk=object.pk %}">
|
|
||||||
Front Ports
|
Front Ports
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if perms.dcim.add_rearport %}
|
{% if perms.dcim.add_rearport %}
|
||||||
<li>
|
<li>
|
||||||
<a
|
<a class="dropdown-item" href="{% url 'dcim:rearport_add' %}?device={{ object.pk }}&return_url={% url 'dcim:device_rearports' pk=object.pk %}">
|
||||||
class="dropdown-item"
|
|
||||||
href="{% url 'dcim:rearport_add' %}?device={{ object.pk }}&return_url={% url 'dcim:device_rearports' pk=object.pk %}">
|
|
||||||
Rear Ports
|
Rear Ports
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if perms.dcim.add_devicebay %}
|
{% if perms.dcim.add_devicebay %}
|
||||||
<li>
|
<li>
|
||||||
<a
|
<a class="dropdown-item" href="{% url 'dcim:devicebay_add' %}?device={{ object.pk }}&return_url={% url 'dcim:device_devicebays' pk=object.pk %}">
|
||||||
class="dropdown-item"
|
|
||||||
href="{% url 'dcim:devicebay_add' %}?device={{ object.pk }}&return_url={% url 'dcim:device_devicebays' pk=object.pk %}">
|
|
||||||
Device Bays
|
Device Bays
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if perms.dcim.add_inventoryitem %}
|
{% if perms.dcim.add_inventoryitem %}
|
||||||
<li>
|
<li>
|
||||||
<a
|
<a class="dropdown-item" href="{% url 'dcim:inventoryitem_add' %}?device={{ object.pk }}&return_url={% url 'dcim:device_inventory' pk=object.pk %}">
|
||||||
class="dropdown-item"
|
|
||||||
href="{% url 'dcim:inventoryitem_add' %}?device={{ object.pk }}&return_url={% url 'dcim:device_inventory' pk=object.pk %}">
|
|
||||||
Inventory Items
|
Inventory Items
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
@ -108,16 +89,12 @@
|
|||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block tab_items %}
|
{% block tab_items %}
|
||||||
<li
|
<li role="presentation" class="nav-item">
|
||||||
role="presentation"
|
<a href="{% url 'dcim:device' pk=object.pk %}" class="nav-link{% if active_tab == 'device' %} active{% endif %}">
|
||||||
class="nav-item">
|
|
||||||
<a
|
|
||||||
href="{% url 'dcim:device' pk=object.pk %}"
|
|
||||||
class="nav-link{% if active_tab == 'device' %} active{% endif %}"
|
|
||||||
>
|
|
||||||
Device
|
Device
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
{% with interface_count=object.interfaces_count %}
|
{% with interface_count=object.interfaces_count %}
|
||||||
{% if interface_count %}
|
{% if interface_count %}
|
||||||
<li role="presentation" class="nav-item">
|
<li role="presentation" class="nav-item">
|
||||||
@ -189,6 +166,7 @@
|
|||||||
</li>
|
</li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endwith %}
|
{% endwith %}
|
||||||
|
|
||||||
{% if perms.dcim.napalm_read_device and object.status == 'active' and object.primary_ip and object.platform.napalm_driver %}
|
{% if perms.dcim.napalm_read_device and object.status == 'active' and object.primary_ip and object.platform.napalm_driver %}
|
||||||
{# NAPALM-enabled tabs #}
|
{# NAPALM-enabled tabs #}
|
||||||
<li role="presentation" class="nav-item">
|
<li role="presentation" class="nav-item">
|
||||||
@ -207,14 +185,10 @@
|
|||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if perms.extras.view_configcontext %}
|
{% if perms.extras.view_configcontext %}
|
||||||
<li
|
<li role="presentation" class="nav-item">
|
||||||
role="presentation"
|
<a href="{% url 'dcim:device_configcontext' pk=object.pk %}" class="nav-link{% if active_tab == 'config-context' %} active{% endif %}">
|
||||||
class="nav-item">
|
|
||||||
<a
|
|
||||||
href="{% url 'dcim:device_configcontext' pk=object.pk %}"
|
|
||||||
class="nav-link{% if active_tab == 'config-context' %} active{% endif %}"
|
|
||||||
>
|
|
||||||
Config Context
|
Config Context
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
|
|
||||||
{% block extra_controls %}
|
{% block extra_controls %}
|
||||||
{% if perms.dcim.change_devicetype %}
|
{% if perms.dcim.change_devicetype %}
|
||||||
<div class="dropdown m-1">
|
<div class="dropdown">
|
||||||
<button type="button" class="btn btn-primary btn-sm dropdown-toggle"data-bs-toggle="dropdown" aria-expanded="false">
|
<button type="button" class="btn btn-primary btn-sm dropdown-toggle"data-bs-toggle="dropdown" aria-expanded="false">
|
||||||
<i class="mdi mdi-plus-thick" aria-hidden="true"></i> Add Components
|
<i class="mdi mdi-plus-thick" aria-hidden="true"></i> Add Components
|
||||||
</button>
|
</button>
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
{% block extra_controls %}
|
{% block extra_controls %}
|
||||||
{% if perms.dcim.add_interface and not object.is_virtual %}
|
{% if perms.dcim.add_interface and not object.is_virtual %}
|
||||||
<a href="{% url 'dcim:interface_add' %}?device={{ object.device.pk }}&parent={{ object.pk }}&return_url={{ object.get_absolute_url }}" class="btn btn-sm btn-success m-1">
|
<a href="{% url 'dcim:interface_add' %}?device={{ object.device.pk }}&parent={{ object.pk }}&return_url={{ object.get_absolute_url }}" class="btn btn-sm btn-success">
|
||||||
<span class="mdi mdi-plus-thick" aria-hidden="true"></span> Add Child Interface
|
<span class="mdi mdi-plus-thick" aria-hidden="true"></span> Add Child Interface
|
||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
@ -18,14 +18,14 @@
|
|||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block extra_controls %}
|
{% block extra_controls %}
|
||||||
<button class="btn btn-sm btn-outline-blue-500 m-1 toggle-images" selected="selected">
|
<button class="btn btn-sm btn-outline-primary toggle-images" selected="selected">
|
||||||
<i class="mdi mdi-file-image-outline"></i>
|
<i class="mdi mdi-file-image-outline"></i>
|
||||||
Hide Images
|
Hide Images
|
||||||
</button>
|
</button>
|
||||||
<a {% if prev_rack %}href="{% url 'dcim:rack' pk=prev_rack.pk %}{% endif %}" class="btn btn-sm btn-primary m-1{% if not prev_rack %} disabled{% endif %}">
|
<a {% if prev_rack %}href="{% url 'dcim:rack' pk=prev_rack.pk %}{% endif %}" class="btn btn-sm btn-primary{% if not prev_rack %} disabled{% endif %}">
|
||||||
<i class="mdi mdi-chevron-left" aria-hidden="true"></i> Previous
|
<i class="mdi mdi-chevron-left" aria-hidden="true"></i> Previous
|
||||||
</a>
|
</a>
|
||||||
<a {% if next_rack %}href="{% url 'dcim:rack' pk=next_rack.pk %}{% endif %}" class="btn btn-sm btn-primary m-1{% if not next_rack %} disabled{% endif %}">
|
<a {% if next_rack %}href="{% url 'dcim:rack' pk=next_rack.pk %}{% endif %}" class="btn btn-sm btn-primary{% if not next_rack %} disabled{% endif %}">
|
||||||
<i class="mdi mdi-chevron-right" aria-hidden="true"></i> Next
|
<i class="mdi mdi-chevron-right" aria-hidden="true"></i> Next
|
||||||
</a>
|
</a>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
@ -5,16 +5,16 @@
|
|||||||
{% block title %}Rack Elevations{% endblock %}
|
{% block title %}Rack Elevations{% endblock %}
|
||||||
|
|
||||||
{% block controls %}
|
{% block controls %}
|
||||||
<div class="container mb-2 mx-0">
|
<div class="controls">
|
||||||
<div class="d-flex flex-wrap justify-content-end">
|
<div class="control-group">
|
||||||
<button class="btn btn-sm btn-outline-dark toggle-images m-1" selected="selected">
|
<button class="btn btn-sm btn-outline-dark toggle-images" selected="selected">
|
||||||
<span class="mdi mdi mdi-checkbox-marked-circle-outline" aria-hidden="true"></span> Show Images
|
<span class="mdi mdi mdi-checkbox-marked-circle-outline" aria-hidden="true"></span> Show Images
|
||||||
</button>
|
</button>
|
||||||
<div class="btn-group btn-group-sm m-1" role="group">
|
<div class="btn-group btn-group-sm" 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='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>
|
<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>
|
||||||
<div class="btn-group btn-group-sm m-1" role="group">
|
<div class="btn-group btn-group-sm" 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=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>
|
<a href="{% url 'dcim:rack_elevation_list' %}{% querystring request reverse='true' %}" class="btn btn-outline-secondary{% if reverse %} active{% endif %}">Reversed</a>
|
||||||
</div>
|
</div>
|
||||||
|
@ -20,18 +20,17 @@
|
|||||||
{% block title %}{{ object }}{% endblock %}
|
{% block title %}{{ object }}{% endblock %}
|
||||||
|
|
||||||
{% block subtitle %}
|
{% block subtitle %}
|
||||||
<small class="text-muted">
|
<div class="object-subtitle">
|
||||||
Created {{ object.created|annotated_date }} ·
|
<span>Created {{ object.created|annotated_date }}</span>
|
||||||
Updated <span title="{{ object.last_updated }}">{{ object.last_updated|timesince }}</span> ago
|
<span class="separator">·</span>
|
||||||
<span class="badge bg-secondary">{{ object|meta:"app_label" }}.{{ object|meta:"model_name" }}:{{ object.pk }}</span>
|
<span>Updated <span title="{{ object.last_updated }}">{{ object.last_updated|timesince }}</span> ago</span>
|
||||||
</small>
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block controls %}
|
{% block controls %}
|
||||||
{# Clone/Edit/Delete Buttons #}
|
{# Clone/Edit/Delete Buttons #}
|
||||||
<div class="controls pb-2 mx-0">
|
<div class="controls">
|
||||||
<div class="d-flex flex-wrap justify-content-end mb-2">
|
<div class="control-group">
|
||||||
{% custom_links object %}
|
|
||||||
{% plugin_buttons object %}
|
{% plugin_buttons object %}
|
||||||
|
|
||||||
{# Extra buttons #}
|
{# Extra buttons #}
|
||||||
@ -48,6 +47,9 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
<div class="control-group">
|
||||||
|
{% custom_links object %}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endblock controls %}
|
{% endblock controls %}
|
||||||
|
|
||||||
|
@ -8,11 +8,13 @@
|
|||||||
|
|
||||||
{% block controls %}
|
{% block controls %}
|
||||||
{% if settings.DOCS_ROOT %}
|
{% if settings.DOCS_ROOT %}
|
||||||
<div class="controls pt-1">
|
<div class="controls">
|
||||||
|
<div class="control-group">
|
||||||
<button type="button" class="btn btn-sm btn-outline-secondary" data-bs-toggle="modal" data-bs-target="#docs_modal" title="Help">
|
<button type="button" class="btn btn-sm btn-outline-secondary" data-bs-toggle="modal" data-bs-target="#docs_modal" title="Help">
|
||||||
<i class="mdi mdi-help-circle"></i> Help
|
<i class="mdi mdi-help-circle"></i> Help
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endblock controls %}
|
{% endblock controls %}
|
||||||
|
|
||||||
|
@ -7,8 +7,8 @@
|
|||||||
{% block title %}{{ content_type.model_class|meta:"verbose_name_plural"|bettertitle }}{% endblock %}
|
{% block title %}{{ content_type.model_class|meta:"verbose_name_plural"|bettertitle }}{% endblock %}
|
||||||
|
|
||||||
{% block controls %}
|
{% block controls %}
|
||||||
<div class="controls mb-2 mx-0">
|
<div class="controls">
|
||||||
<div class="d-flex flex-wrap justify-content-end">
|
<div class="control-group">
|
||||||
{% block extra_controls %}{% endblock %}
|
{% block extra_controls %}{% endblock %}
|
||||||
{% if permissions.add and 'add' in action_buttons %}
|
{% if permissions.add and 'add' in action_buttons %}
|
||||||
{% add_button content_type.model_class|validated_viewname:"add" %}
|
{% add_button content_type.model_class|validated_viewname:"add" %}
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
{{ field }}
|
{{ field }}
|
||||||
</div>
|
</div>
|
||||||
{% else %}
|
{% else %}
|
||||||
<div class="mb-3 mx-3">
|
<div class="mb-3 px-2">
|
||||||
<label class="form-label" for="{{ field.id_for_label }}">{{ field.label }}</label>
|
<label class="form-label" for="{{ field.id_for_label }}">{{ field.label }}</label>
|
||||||
{{ field }}
|
{{ field }}
|
||||||
</div>
|
</div>
|
||||||
@ -30,17 +30,20 @@
|
|||||||
{% endwith %}
|
{% endwith %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
|
{% if forloop.counter != filter_form.field_groups|length %}
|
||||||
|
<hr class="card-divider mt-0" />
|
||||||
|
{% endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% else %}
|
{% else %}
|
||||||
{% for field in filter_form.visible_fields %}
|
{% for field in filter_form.visible_fields %}
|
||||||
<div class="col">
|
<div class="col col-12">
|
||||||
{% if field|widget_type == 'checkboxinput' %}
|
{% if field|widget_type == 'checkboxinput' %}
|
||||||
<div class="form-check mb-3">
|
<div class="form-check mb-3">
|
||||||
<label class="form-check-label" for="{{ field.id_for_label }}">{{ field.label }}</label>
|
<label class="form-check-label" for="{{ field.id_for_label }}">{{ field.label }}</label>
|
||||||
{{ field }}
|
{{ field }}
|
||||||
</div>
|
</div>
|
||||||
{% else %}
|
{% else %}
|
||||||
<div class="mb-3">
|
<div class="mb-3 px-2">
|
||||||
<label class="form-label" for="{{ field.id_for_label }}">{{ field.label }}</label>
|
<label class="form-label" for="{{ field.id_for_label }}">{{ field.label }}</label>
|
||||||
{{ field }}
|
{{ field }}
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
{% load helpers %}
|
{% load helpers %}
|
||||||
|
|
||||||
{% if show_available is not None %}
|
{% if show_available is not None %}
|
||||||
<div class="btn-group m-1" role="group">
|
<div class="btn-group" role="group">
|
||||||
<a href="{{ request.path }}{% querystring request show_available='true' %}" class="btn btn-sm btn-outline-blue-500{% if show_available %} active disabled{% endif %}">
|
<a href="{{ request.path }}{% querystring request show_available='true' %}" class="btn btn-sm btn-outline-primary{% if show_available %} active disabled{% endif %}">
|
||||||
<i class="mdi mdi-eye"></i> Show Available
|
<i class="mdi mdi-eye"></i> Show Available
|
||||||
</a>
|
</a>
|
||||||
<a href="{{ request.path }}{% querystring request show_available='false' %}" class="btn btn-sm btn-outline-blue-500{% if not show_available %} active disabled{% endif %}">
|
<a href="{{ request.path }}{% querystring request show_available='false' %}" class="btn btn-sm btn-outline-primary{% if not show_available %} active disabled{% endif %}">
|
||||||
<i class="mdi mdi-eye-off"></i> Hide Available
|
<i class="mdi mdi-eye-off"></i> Hide Available
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
{% block extra_controls %}
|
{% block extra_controls %}
|
||||||
{% if perms.ipam.add_ipaddress and active_tab == 'ip-addresses' and object.first_available_ip %}
|
{% if perms.ipam.add_ipaddress and active_tab == 'ip-addresses' and object.first_available_ip %}
|
||||||
<a href="{% url 'ipam:ipaddress_add' %}?address={{ object.first_available_ip }}&vrf={{ object.vrf.pk }}&tenant_group={{ object.tenant.group.pk }}&tenant={{ object.tenant.pk }}" class="btn btn-sm btn-primary m-1">
|
<a href="{% url 'ipam:ipaddress_add' %}?address={{ object.first_available_ip }}&vrf={{ object.vrf.pk }}&tenant_group={{ object.tenant.group.pk }}&tenant={{ object.tenant.pk }}" class="btn btn-sm btn-primary">
|
||||||
<i class="mdi mdi-plus-thick" aria-hidden="true"></i> Add IP Address
|
<i class="mdi mdi-plus-thick" aria-hidden="true"></i> Add IP Address
|
||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
{% block extra_controls %}
|
{% block extra_controls %}
|
||||||
{% if perms.ipam.add_ipaddress and active_tab == 'ip-addresses' and first_available_ip %}
|
{% if perms.ipam.add_ipaddress and active_tab == 'ip-addresses' and first_available_ip %}
|
||||||
<a href="{% url 'ipam:ipaddress_add' %}?address={{ first_available_ip }}&vrf={{ object.vrf.pk }}&tenant_group={{ object.tenant.group.pk }}&tenant={{ object.tenant.pk }}" class="btn btn-sm btn-primary m-1">
|
<a href="{% url 'ipam:ipaddress_add' %}?address={{ first_available_ip }}&vrf={{ object.vrf.pk }}&tenant_group={{ object.tenant.group.pk }}&tenant={{ object.tenant.pk }}" class="btn btn-sm btn-primary">
|
||||||
<i class="mdi mdi-plus-thick" aria-hidden="true"></i> Add IP Address
|
<i class="mdi mdi-plus-thick" aria-hidden="true"></i> Add IP Address
|
||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
{% load helpers %}
|
{% load helpers %}
|
||||||
|
|
||||||
{% block extra_controls %}
|
{% block extra_controls %}
|
||||||
<div class="dropdown m-1">
|
<div class="dropdown">
|
||||||
<button class="btn btn-sm btn-outline-secondary dropdown-toggle" type="button" id="max_depth" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
|
<button class="btn btn-sm btn-outline-secondary dropdown-toggle" type="button" id="max_depth" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
|
||||||
Max Depth{% if "depth__lte" in request.GET %}: {{ request.GET.depth__lte }}{% endif %}
|
Max Depth{% if "depth__lte" in request.GET %}: {{ request.GET.depth__lte }}{% endif %}
|
||||||
</button>
|
</button>
|
||||||
@ -19,7 +19,7 @@
|
|||||||
{% endfor %}
|
{% endfor %}
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div class="dropdown m-1">
|
<div class="dropdown">
|
||||||
<button class="btn btn-sm btn-outline-secondary dropdown-toggle" type="button" id="max_length" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
|
<button class="btn btn-sm btn-outline-secondary dropdown-toggle" type="button" id="max_length" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
|
||||||
Max Length{% if "mask_length__lte" in request.GET %}: {{ request.GET.mask_length__lte }}{% endif %}
|
Max Length{% if "mask_length__lte" in request.GET %}: {{ request.GET.mask_length__lte }}{% endif %}
|
||||||
</button>
|
</button>
|
||||||
|
@ -13,12 +13,13 @@
|
|||||||
|
|
||||||
{% block extra_controls %}
|
{% block extra_controls %}
|
||||||
{% if perms.virtualization.change_cluster and perms.virtualization.add_virtualmachine %}
|
{% if perms.virtualization.change_cluster and perms.virtualization.add_virtualmachine %}
|
||||||
<a href="{% url 'virtualization:virtualmachine_add' %}?cluster_id={{ object.pk }}&return_url={{ object.get_absolute_url }}" class="btn btn-sm btn-primary m-1">
|
<a href="{% url 'virtualization:virtualmachine_add' %}?cluster_id={{ object.pk }}&return_url={{ object.get_absolute_url }}" class="btn btn-sm btn-primary">
|
||||||
<span class="mdi mdi-plus-thick" aria-hidden="true"></span> Add Virtual Machine
|
<span class="mdi mdi-plus-thick" aria-hidden="true"></span> Add Virtual Machine
|
||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if perms.virtualization.change_cluster %}
|
{% if perms.virtualization.change_cluster %}
|
||||||
<a href="{% url 'virtualization:cluster_add_devices' pk=object.pk %}?site_id={{ object.site.pk }}&return_url={{ object.get_absolute_url }}" class="btn btn-primary btn-sm m-1">
|
<a href="{% url 'virtualization:cluster_add_devices' pk=object.pk %}?site_id={{ object.site.pk }}&return_url={{ object.get_absolute_url }}" class="btn btn-primary btn-sm">
|
||||||
<span class="mdi mdi-plus-thick" aria-hidden="true"></span> Assign Device
|
<span class="mdi mdi-plus-thick" aria-hidden="true"></span> Assign Device
|
||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
@ -10,8 +10,8 @@
|
|||||||
|
|
||||||
{% block extra_controls %}
|
{% block extra_controls %}
|
||||||
{% if perms.virtualization.add_vminterface %}
|
{% if perms.virtualization.add_vminterface %}
|
||||||
<a href="{% url 'virtualization:vminterface_add' %}?virtual_machine={{ object.pk }}&return_url={% url 'virtualization:virtualmachine_interfaces' pk=object.pk %}" class="btn btn-sm btn-primary m-1">
|
<a href="{% url 'virtualization:vminterface_add' %}?virtual_machine={{ object.pk }}&return_url={% url 'virtualization:virtualmachine_interfaces' pk=object.pk %}" class="btn btn-sm btn-primary">
|
||||||
<span class="mdi mdi-plus-thick" aria-hidden="true"></span> Add Interfaces
|
<i class="mdi mdi-plus-thick"></i> Add Interfaces
|
||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
@ -64,6 +64,11 @@ class TenantGroupBulkEditForm(BootstrapMixin, CustomFieldModelBulkEditForm):
|
|||||||
|
|
||||||
class TenantGroupFilterForm(BootstrapMixin, CustomFieldModelFilterForm):
|
class TenantGroupFilterForm(BootstrapMixin, CustomFieldModelFilterForm):
|
||||||
model = TenantGroup
|
model = TenantGroup
|
||||||
|
q = forms.CharField(
|
||||||
|
required=False,
|
||||||
|
widget=forms.TextInput(attrs={'placeholder': _('All Fields')}),
|
||||||
|
label=_('Search')
|
||||||
|
)
|
||||||
parent_id = DynamicModelMultipleChoiceField(
|
parent_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=TenantGroup.objects.all(),
|
queryset=TenantGroup.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
@ -132,6 +137,7 @@ class TenantFilterForm(BootstrapMixin, CustomFieldModelFilterForm):
|
|||||||
model = Tenant
|
model = Tenant
|
||||||
q = forms.CharField(
|
q = forms.CharField(
|
||||||
required=False,
|
required=False,
|
||||||
|
widget=forms.TextInput(attrs={'placeholder': _('All Fields')}),
|
||||||
label=_('Search')
|
label=_('Search')
|
||||||
)
|
)
|
||||||
group_id = DynamicModelMultipleChoiceField(
|
group_id = DynamicModelMultipleChoiceField(
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
<div class="d-flex flex-shrink-1 m-1">
|
{% comment %} <div class="d-flex flex-shrink-1">
|
||||||
<a href="{{ add_url }}" type="button" class="btn btn-sm btn-success">
|
<a href="{{ add_url }}" type="button" class="btn btn-sm btn-success">
|
||||||
<i class="mdi mdi-plus-thick"></i>
|
<i class="mdi mdi-plus-thick"></i>
|
||||||
Add
|
Add
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div> {% endcomment %}
|
||||||
|
<a href="{{ add_url }}" type="button" class="btn btn-sm btn-success">
|
||||||
|
<i class="mdi mdi-plus-thick"></i> Add
|
||||||
|
</a>
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
<a href="{{ url }}" class="btn btn-sm btn-success m-1" role="button">
|
<a href="{{ url }}" class="btn btn-sm btn-success" role="button">
|
||||||
<i class="mdi mdi-content-copy" aria-hidden="true"></i> Clone
|
<i class="mdi mdi-content-copy" aria-hidden="true"></i> Clone
|
||||||
</a>
|
</a>
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
<a href="{{ url }}" class="btn btn-sm btn-danger m-1" role="button">
|
<a href="{{ url }}" class="btn btn-sm btn-danger" role="button">
|
||||||
<span class="mdi mdi-trash-can-outline" aria-hidden="true"></span> Delete
|
<span class="mdi mdi-trash-can-outline" aria-hidden="true"></span> Delete
|
||||||
</a>
|
</a>
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
<a href="{{ url }}" class="btn btn-sm btn-warning m-1" role="button">
|
<a href="{{ url }}" class="btn btn-sm btn-warning" role="button">
|
||||||
<span class="mdi mdi-pencil" aria-hidden="true"></span> Edit
|
<span class="mdi mdi-pencil" aria-hidden="true"></span> Edit
|
||||||
</a>
|
</a>
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<div class="dropdown m-1">
|
<div class="dropdown">
|
||||||
<button type="button" class="btn btn-sm btn-purple-500 dropdown-toggle" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
<button type="button" class="btn btn-sm btn-purple dropdown-toggle" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||||
<i class="mdi mdi-download"></i> Export
|
<i class="mdi mdi-download"></i> Export
|
||||||
</button>
|
</button>
|
||||||
<ul class="dropdown-menu dropdown-menu-end">
|
<ul class="dropdown-menu dropdown-menu-end">
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
<a href="{% url import_url %}" type="button" class="btn btn-sm btn-info m-1">
|
<a href="{% url import_url %}" type="button" class="btn btn-sm btn-info">
|
||||||
<i class="mdi mdi-upload"></i> Import
|
<i class="mdi mdi-upload"></i> Import
|
||||||
</a>
|
</a>
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
|
|
||||||
<span class="input-group-text search-obj-selected">All Objects</span>
|
<span class="input-group-text search-obj-selected">All Objects</span>
|
||||||
|
|
||||||
<button type="button" aria-expanded="false" data-bs-toggle="dropdown" class="btn btn-outline-secondary dropdown-toggle">
|
<button type="button" aria-expanded="false" data-bs-toggle="dropdown" class="btn dropdown-toggle">
|
||||||
<i class="mdi mdi-filter-variant"></i>
|
<i class="mdi mdi-filter-variant"></i>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
|
@ -225,14 +225,20 @@ class ClusterBulkEditForm(BootstrapMixin, AddRemoveTagsForm, CustomFieldModelBul
|
|||||||
class ClusterFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldModelFilterForm):
|
class ClusterFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldModelFilterForm):
|
||||||
model = Cluster
|
model = Cluster
|
||||||
field_order = [
|
field_order = [
|
||||||
'type_id', 'region_id', 'site_id', 'group_id', 'tenant_group_id', 'tenant_id',
|
'q', 'type_id', 'region_id', 'site_id', 'group_id', 'tenant_group_id', 'tenant_id',
|
||||||
]
|
]
|
||||||
field_groups = [
|
field_groups = [
|
||||||
|
['q'],
|
||||||
['type_id'],
|
['type_id'],
|
||||||
['region_id', 'site_id'],
|
['region_id', 'site_id'],
|
||||||
['tenant_group_id', 'tenant_id'],
|
['tenant_group_id', 'tenant_id'],
|
||||||
['tag'],
|
['tag'],
|
||||||
]
|
]
|
||||||
|
q = forms.CharField(
|
||||||
|
required=False,
|
||||||
|
widget=forms.TextInput(attrs={'placeholder': _('All Fields')}),
|
||||||
|
label=_('Search')
|
||||||
|
)
|
||||||
type_id = DynamicModelMultipleChoiceField(
|
type_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=ClusterType.objects.all(),
|
queryset=ClusterType.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
@ -540,6 +546,7 @@ class VirtualMachineFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldMod
|
|||||||
'site_id', 'tenant_group_id', 'tenant_id', 'platform_id', 'mac_address',
|
'site_id', 'tenant_group_id', 'tenant_id', 'platform_id', 'mac_address',
|
||||||
]
|
]
|
||||||
field_groups = [
|
field_groups = [
|
||||||
|
['q'],
|
||||||
['status', 'role_id'],
|
['status', 'role_id'],
|
||||||
['platform_id', 'mac_address'],
|
['platform_id', 'mac_address'],
|
||||||
['cluster_group_id', 'cluster_type_id', 'cluster_id'],
|
['cluster_group_id', 'cluster_type_id', 'cluster_id'],
|
||||||
@ -547,6 +554,11 @@ class VirtualMachineFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldMod
|
|||||||
['tenant_group_id', 'tenant_id'],
|
['tenant_group_id', 'tenant_id'],
|
||||||
|
|
||||||
]
|
]
|
||||||
|
q = forms.CharField(
|
||||||
|
required=False,
|
||||||
|
widget=forms.TextInput(attrs={'placeholder': _('All Fields')}),
|
||||||
|
label=_('Search')
|
||||||
|
)
|
||||||
cluster_group_id = DynamicModelMultipleChoiceField(
|
cluster_group_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=ClusterGroup.objects.all(),
|
queryset=ClusterGroup.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
@ -855,10 +867,16 @@ class VMInterfaceBulkRenameForm(BulkRenameForm):
|
|||||||
class VMInterfaceFilterForm(BootstrapMixin, forms.Form):
|
class VMInterfaceFilterForm(BootstrapMixin, forms.Form):
|
||||||
model = VMInterface
|
model = VMInterface
|
||||||
field_groups = [
|
field_groups = [
|
||||||
|
['q'],
|
||||||
['cluster_id', 'virtual_machine_id'],
|
['cluster_id', 'virtual_machine_id'],
|
||||||
['enabled', 'mac_address'],
|
['enabled', 'mac_address'],
|
||||||
['tag']
|
['tag']
|
||||||
]
|
]
|
||||||
|
q = forms.CharField(
|
||||||
|
required=False,
|
||||||
|
widget=forms.TextInput(attrs={'placeholder': _('All Fields')}),
|
||||||
|
label=_('Search')
|
||||||
|
)
|
||||||
cluster_id = DynamicModelMultipleChoiceField(
|
cluster_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=Cluster.objects.all(),
|
queryset=Cluster.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
|
Loading…
Reference in New Issue
Block a user