From c08c7dda500ce7c4a3366e8c5321a9446239dc11 Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Tue, 18 Apr 2023 16:33:43 -0400 Subject: [PATCH] Closes #12292: Replace SelectSpeedWidget and SelectDurationWidget with NumberWithOptions --- netbox/circuits/choices.py | 32 ++++++++++++++++++ netbox/circuits/forms/bulk_edit.py | 9 +++-- netbox/circuits/forms/filtersets.py | 9 +++-- netbox/circuits/forms/model_forms.py | 15 +++++--- netbox/dcim/choices.py | 14 ++++++++ netbox/dcim/forms/bulk_edit.py | 7 ++-- netbox/dcim/forms/filtersets.py | 7 ++-- netbox/dcim/forms/model_forms.py | 6 ++-- netbox/extras/choices.py | 13 ++++++- netbox/extras/forms/reports.py | 7 ++-- netbox/extras/forms/scripts.py | 7 ++-- netbox/project-static/dist/netbox.js | Bin 438231 -> 438237 bytes netbox/project-static/dist/netbox.js.map | Bin 401817 -> 401818 bytes .../project-static/src/forms/speedSelector.ts | 2 +- netbox/utilities/forms/widgets/misc.py | 17 ++++++++++ netbox/utilities/forms/widgets/select.py | 16 --------- .../widgets/number_with_options.html | 11 ++++++ .../templates/widgets/select_duration.html | 11 ------ .../templates/widgets/select_speed.html | 16 --------- 19 files changed, 132 insertions(+), 67 deletions(-) create mode 100644 netbox/utilities/templates/widgets/number_with_options.html delete mode 100644 netbox/utilities/templates/widgets/select_duration.html delete mode 100644 netbox/utilities/templates/widgets/select_speed.html diff --git a/netbox/circuits/choices.py b/netbox/circuits/choices.py index ddb00c64b..518baea9f 100644 --- a/netbox/circuits/choices.py +++ b/netbox/circuits/choices.py @@ -25,6 +25,22 @@ class CircuitStatusChoices(ChoiceSet): ] +class CircuitCommitRateChoices(ChoiceSet): + key = 'Circuit.commit_rate' + + CHOICES = [ + (10000, '10 Mbps'), + (100000, '100 Mbps'), + (1000000, '1 Gbps'), + (10000000, '10 Gbps'), + (25000000, '25 Gbps'), + (40000000, '40 Gbps'), + (100000000, '100 Gbps'), + (1544, 'T1 (1.544 Mbps)'), + (2048, 'E1 (2.048 Mbps)'), + ] + + # # CircuitTerminations # @@ -38,3 +54,19 @@ class CircuitTerminationSideChoices(ChoiceSet): (SIDE_A, 'A'), (SIDE_Z, 'Z') ) + + +class CircuitTerminationPortSpeedChoices(ChoiceSet): + key = 'CircuitTermination.port_speed' + + CHOICES = [ + (10000, '10 Mbps'), + (100000, '100 Mbps'), + (1000000, '1 Gbps'), + (10000000, '10 Gbps'), + (25000000, '25 Gbps'), + (40000000, '40 Gbps'), + (100000000, '100 Gbps'), + (1544, 'T1 (1.544 Mbps)'), + (2048, 'E1 (2.048 Mbps)'), + ] diff --git a/netbox/circuits/forms/bulk_edit.py b/netbox/circuits/forms/bulk_edit.py index efc9b5f3a..9dba87e47 100644 --- a/netbox/circuits/forms/bulk_edit.py +++ b/netbox/circuits/forms/bulk_edit.py @@ -1,14 +1,14 @@ from django import forms from django.utils.translation import gettext as _ -from circuits.choices import CircuitStatusChoices +from circuits.choices import CircuitCommitRateChoices, CircuitStatusChoices from circuits.models import * from ipam.models import ASN from netbox.forms import NetBoxModelBulkEditForm from tenancy.models import Tenant from utilities.forms import add_blank_choice from utilities.forms.fields import CommentField, DynamicModelChoiceField, DynamicModelMultipleChoiceField -from utilities.forms.widgets import DatePicker +from utilities.forms.widgets import DatePicker, NumberWithOptions __all__ = ( 'CircuitBulkEditForm', @@ -139,7 +139,10 @@ class CircuitBulkEditForm(NetBoxModelBulkEditForm): ) commit_rate = forms.IntegerField( required=False, - label=_('Commit rate (Kbps)') + label=_('Commit rate (Kbps)'), + widget=NumberWithOptions( + options=CircuitCommitRateChoices + ) ) description = forms.CharField( max_length=100, diff --git a/netbox/circuits/forms/filtersets.py b/netbox/circuits/forms/filtersets.py index 075855f3b..83da0d50a 100644 --- a/netbox/circuits/forms/filtersets.py +++ b/netbox/circuits/forms/filtersets.py @@ -1,14 +1,14 @@ from django import forms from django.utils.translation import gettext as _ -from circuits.choices import CircuitStatusChoices +from circuits.choices import CircuitCommitRateChoices, CircuitStatusChoices from circuits.models import * from dcim.models import Region, Site, SiteGroup from ipam.models import ASN from netbox.forms import NetBoxModelFilterSetForm from tenancy.forms import TenancyFilterForm, ContactModelFilterForm from utilities.forms.fields import DynamicModelMultipleChoiceField, TagFilterField -from utilities.forms.widgets import DatePicker +from utilities.forms.widgets import DatePicker, NumberWithOptions __all__ = ( 'CircuitFilterForm', @@ -168,6 +168,9 @@ class CircuitFilterForm(TenancyFilterForm, ContactModelFilterForm, NetBoxModelFi commit_rate = forms.IntegerField( required=False, min_value=0, - label=_('Commit rate (Kbps)') + label=_('Commit rate (Kbps)'), + widget=NumberWithOptions( + options=CircuitCommitRateChoices + ) ) tag = TagFilterField(model) diff --git a/netbox/circuits/forms/model_forms.py b/netbox/circuits/forms/model_forms.py index 2925efec1..d3929c08a 100644 --- a/netbox/circuits/forms/model_forms.py +++ b/netbox/circuits/forms/model_forms.py @@ -1,12 +1,13 @@ from django.utils.translation import gettext as _ +from circuits.choices import CircuitCommitRateChoices, CircuitTerminationPortSpeedChoices from circuits.models import * from dcim.models import Site from ipam.models import ASN from netbox.forms import NetBoxModelForm from tenancy.forms import TenancyForm from utilities.forms.fields import CommentField, DynamicModelChoiceField, DynamicModelMultipleChoiceField, SlugField -from utilities.forms.widgets import DatePicker, SelectSpeedWidget +from utilities.forms.widgets import DatePicker, NumberWithOptions __all__ = ( 'CircuitForm', @@ -116,7 +117,9 @@ class CircuitForm(TenancyForm, NetBoxModelForm): widgets = { 'install_date': DatePicker(), 'termination_date': DatePicker(), - 'commit_rate': SelectSpeedWidget(), + 'commit_rate': NumberWithOptions( + options=CircuitCommitRateChoices + ), } @@ -143,6 +146,10 @@ class CircuitTerminationForm(NetBoxModelForm): 'xconnect_id', 'pp_info', 'description', 'tags', ] widgets = { - 'port_speed': SelectSpeedWidget(), - 'upstream_speed': SelectSpeedWidget(), + 'port_speed': NumberWithOptions( + options=CircuitTerminationPortSpeedChoices + ), + 'upstream_speed': NumberWithOptions( + options=CircuitTerminationPortSpeedChoices + ), } diff --git a/netbox/dcim/choices.py b/netbox/dcim/choices.py index ad196a69e..8ad8a0eb7 100644 --- a/netbox/dcim/choices.py +++ b/netbox/dcim/choices.py @@ -1096,6 +1096,20 @@ class InterfaceTypeChoices(ChoiceSet): ) +class InterfaceSpeedChoices(ChoiceSet): + key = 'Interface.speed' + + CHOICES = [ + (10000, '10 Mbps'), + (100000, '100 Mbps'), + (1000000, '1 Gbps'), + (10000000, '10 Gbps'), + (25000000, '25 Gbps'), + (40000000, '40 Gbps'), + (100000000, '100 Gbps'), + ] + + class InterfaceDuplexChoices(ChoiceSet): DUPLEX_HALF = 'half' diff --git a/netbox/dcim/forms/bulk_edit.py b/netbox/dcim/forms/bulk_edit.py index 5966588fa..0762c0a32 100644 --- a/netbox/dcim/forms/bulk_edit.py +++ b/netbox/dcim/forms/bulk_edit.py @@ -12,7 +12,7 @@ from netbox.forms import NetBoxModelBulkEditForm from tenancy.models import Tenant from utilities.forms import BulkEditForm, add_blank_choice, form_from_model from utilities.forms.fields import ColorField, CommentField, DynamicModelChoiceField, DynamicModelMultipleChoiceField -from utilities.forms.widgets import BulkEditNullBooleanSelect, SelectSpeedWidget +from utilities.forms.widgets import BulkEditNullBooleanSelect, NumberWithOptions __all__ = ( 'CableBulkEditForm', @@ -1169,8 +1169,9 @@ class InterfaceBulkEditForm( ) speed = forms.IntegerField( required=False, - widget=SelectSpeedWidget(), - label=_('Speed') + widget=NumberWithOptions( + options=InterfaceSpeedChoices + ) ) mgmt_only = forms.NullBooleanField( required=False, diff --git a/netbox/dcim/forms/filtersets.py b/netbox/dcim/forms/filtersets.py index 727064e8f..a00c7fe26 100644 --- a/netbox/dcim/forms/filtersets.py +++ b/netbox/dcim/forms/filtersets.py @@ -12,7 +12,7 @@ from netbox.forms import NetBoxModelFilterSetForm from tenancy.forms import ContactModelFilterForm, TenancyFilterForm from utilities.forms import BOOLEAN_WITH_BLANK_CHOICES, FilterForm, add_blank_choice from utilities.forms.fields import ColorField, DynamicModelMultipleChoiceField, TagFilterField -from utilities.forms.widgets import APISelectMultiple, SelectSpeedWidget +from utilities.forms.widgets import APISelectMultiple, NumberWithOptions from wireless.choices import * __all__ = ( @@ -1154,8 +1154,9 @@ class InterfaceFilterForm(PathEndpointFilterForm, DeviceComponentFilterForm): ) speed = forms.IntegerField( required=False, - label='Speed', - widget=SelectSpeedWidget() + widget=NumberWithOptions( + options=InterfaceSpeedChoices + ) ) duplex = forms.MultipleChoiceField( choices=InterfaceDuplexChoices, diff --git a/netbox/dcim/forms/model_forms.py b/netbox/dcim/forms/model_forms.py index f899c31e1..ee1d57781 100644 --- a/netbox/dcim/forms/model_forms.py +++ b/netbox/dcim/forms/model_forms.py @@ -16,7 +16,7 @@ from utilities.forms.fields import ( CommentField, ContentTypeChoiceField, DynamicModelChoiceField, DynamicModelMultipleChoiceField, JSONField, NumericArrayField, SlugField, ) -from utilities.forms.widgets import APISelect, ClearableFileInput, HTMXSelect, SelectSpeedWidget, SelectWithPK +from utilities.forms.widgets import APISelect, ClearableFileInput, HTMXSelect, NumberWithOptions, SelectWithPK from virtualization.models import Cluster from wireless.models import WirelessLAN, WirelessLANGroup from .common import InterfaceCommonForm, ModuleCommonForm @@ -1136,7 +1136,9 @@ class InterfaceForm(InterfaceCommonForm, ModularDeviceComponentForm): 'untagged_vlan', 'tagged_vlans', 'vrf', 'tags', ] widgets = { - 'speed': SelectSpeedWidget(), + 'speed': NumberWithOptions( + options=InterfaceSpeedChoices + ), 'mode': HTMXSelect(), } labels = { diff --git a/netbox/extras/choices.py b/netbox/extras/choices.py index 878d9df6a..e10516c4c 100644 --- a/netbox/extras/choices.py +++ b/netbox/extras/choices.py @@ -116,7 +116,7 @@ class JournalEntryKindChoices(ChoiceSet): # -# Log Levels for Reports and Scripts +# Reports and Scripts # class LogLevelChoices(ChoiceSet): @@ -136,6 +136,17 @@ class LogLevelChoices(ChoiceSet): ) +class DurationChoices(ChoiceSet): + + CHOICES = ( + (60, 'Hourly'), + (720, '12 hours'), + (1440, 'Daily'), + (10080, 'Weekly'), + (43200, '30 days'), + ) + + # # Job results # diff --git a/netbox/extras/forms/reports.py b/netbox/extras/forms/reports.py index f3a9927f8..4000c01e6 100644 --- a/netbox/extras/forms/reports.py +++ b/netbox/extras/forms/reports.py @@ -1,8 +1,9 @@ from django import forms from django.utils.translation import gettext as _ +from extras.choices import DurationChoices from utilities.forms import BootstrapMixin -from utilities.forms.widgets import DateTimePicker, SelectDurationWidget +from utilities.forms.widgets import DateTimePicker, NumberWithOptions from utilities.utils import local_now __all__ = ( @@ -21,7 +22,9 @@ class ReportForm(BootstrapMixin, forms.Form): required=False, min_value=1, label=_("Recurs every"), - widget=SelectDurationWidget(), + widget=NumberWithOptions( + options=DurationChoices + ), help_text=_("Interval at which this report is re-run (in minutes)") ) diff --git a/netbox/extras/forms/scripts.py b/netbox/extras/forms/scripts.py index b19faba8f..05febaa6f 100644 --- a/netbox/extras/forms/scripts.py +++ b/netbox/extras/forms/scripts.py @@ -1,8 +1,9 @@ from django import forms from django.utils.translation import gettext as _ +from extras.choices import DurationChoices from utilities.forms import BootstrapMixin -from utilities.forms.widgets import DateTimePicker, SelectDurationWidget +from utilities.forms.widgets import DateTimePicker, NumberWithOptions from utilities.utils import local_now __all__ = ( @@ -27,7 +28,9 @@ class ScriptForm(BootstrapMixin, forms.Form): required=False, min_value=1, label=_("Recurs every"), - widget=SelectDurationWidget(), + widget=NumberWithOptions( + options=DurationChoices + ), help_text=_("Interval at which this script is re-run (in minutes)") ) diff --git a/netbox/project-static/dist/netbox.js b/netbox/project-static/dist/netbox.js index 7f20abbd6379deb783bce50cf4679e32025cb2af..e9509a52b36475c7916bc781f5f26996eb46c2b3 100644 GIT binary patch delta 48 zcmcb9U+V6CsfHHD7N!>FEi8`nxzjRJb5i2V5_3vZr_bwVm1vKf&jQ4(+vDc5RSEzA D?Nk#D delta 37 rcmcb6U+VgOsfHHD7N!>FEi8`nS&Iu&Q&ZY~=Cc4X>vo^{Y!d|lECvpp diff --git a/netbox/project-static/dist/netbox.js.map b/netbox/project-static/dist/netbox.js.map index 1cb775229debceaab81d033fe1b85f2e347e44d1..d71e223120bb464d998d6667b01c3c43bca3e197 100644 GIT binary patch delta 32 ocmbPvSYp;;iG~)&7N!>FEi4;~r=MYF<7(eo%(8uFG3$f10NEQ2c>n+a delta 37 tcmbPrSYqa3iG~)&7N!>FEi4;~SyCOH^QIf-ut>F^FJ{?(zL@p&S^yD|4#xlh diff --git a/netbox/project-static/src/forms/speedSelector.ts b/netbox/project-static/src/forms/speedSelector.ts index 9195afce3..ac7f570de 100644 --- a/netbox/project-static/src/forms/speedSelector.ts +++ b/netbox/project-static/src/forms/speedSelector.ts @@ -4,7 +4,7 @@ import { getElements } from '../util'; * Set the value of the number input field based on the selection of the dropdown. */ export function initSpeedSelector(): void { - for (const element of getElements('a.set_speed')) { + for (const element of getElements('a.set_field_value')) { if (element !== null) { function handleClick(event: Event) { // Don't reload the page (due to href="#"). diff --git a/netbox/utilities/forms/widgets/misc.py b/netbox/utilities/forms/widgets/misc.py index 751c3179f..ca2e64319 100644 --- a/netbox/utilities/forms/widgets/misc.py +++ b/netbox/utilities/forms/widgets/misc.py @@ -3,6 +3,7 @@ from django import forms __all__ = ( 'ClearableFileInput', 'MarkdownWidget', + 'NumberWithOptions', 'SlugWidget', ) @@ -21,6 +22,22 @@ class MarkdownWidget(forms.Textarea): template_name = 'widgets/markdown_input.html' +class NumberWithOptions(forms.NumberInput): + """ + Number field with a dropdown pre-populated with common values for convenience. + """ + template_name = 'widgets/number_with_options.html' + + def __init__(self, options, attrs=None): + self.options = options + super().__init__(attrs) + + def get_context(self, name, value, attrs): + context = super().get_context(name, value, attrs) + context['widget']['options'] = self.options + return context + + class SlugWidget(forms.TextInput): """ Subclass TextInput and add a slug regeneration button next to the form field. diff --git a/netbox/utilities/forms/widgets/select.py b/netbox/utilities/forms/widgets/select.py index f2cd6cb1d..2e2d829cd 100644 --- a/netbox/utilities/forms/widgets/select.py +++ b/netbox/utilities/forms/widgets/select.py @@ -7,8 +7,6 @@ __all__ = ( 'BulkEditNullBooleanSelect', 'ColorSelect', 'HTMXSelect', - 'SelectDurationWidget', - 'SelectSpeedWidget', 'SelectWithPK', ) @@ -63,17 +61,3 @@ class SelectWithPK(forms.Select): Include the primary key of each option in the option label (e.g. "Router7 (4721)"). """ option_template_name = 'widgets/select_option_with_pk.html' - - -class SelectDurationWidget(forms.NumberInput): - """ - Dropdown to select one of several common options for a time duration (in minutes). - """ - template_name = 'widgets/select_duration.html' - - -class SelectSpeedWidget(forms.NumberInput): - """ - Speed field with dropdown selections for convenience. - """ - template_name = 'widgets/select_speed.html' diff --git a/netbox/utilities/templates/widgets/number_with_options.html b/netbox/utilities/templates/widgets/number_with_options.html new file mode 100644 index 000000000..ed518650d --- /dev/null +++ b/netbox/utilities/templates/widgets/number_with_options.html @@ -0,0 +1,11 @@ +
+ {% include 'django/forms/widgets/number.html' %} + + +
diff --git a/netbox/utilities/templates/widgets/select_duration.html b/netbox/utilities/templates/widgets/select_duration.html deleted file mode 100644 index 639075a8c..000000000 --- a/netbox/utilities/templates/widgets/select_duration.html +++ /dev/null @@ -1,11 +0,0 @@ -
- {% include 'django/forms/widgets/number.html' %} - - -
diff --git a/netbox/utilities/templates/widgets/select_speed.html b/netbox/utilities/templates/widgets/select_speed.html deleted file mode 100644 index d9c63c44a..000000000 --- a/netbox/utilities/templates/widgets/select_speed.html +++ /dev/null @@ -1,16 +0,0 @@ -
- {% include 'django/forms/widgets/number.html' %} - - -