Jelajahi Sumber

Add color to PowerOutletTemplate (#20530)

Alexander 3 bulan lalu
induk
melakukan
52d4498caf

+ 1 - 1
netbox/dcim/api/serializers_/devicetype_components.py

@@ -155,7 +155,7 @@ class PowerOutletTemplateSerializer(ComponentTemplateSerializer):
         model = PowerOutletTemplate
         fields = [
             'id', 'url', 'display', 'device_type', 'module_type', 'name', 'label', 'type',
-            'power_port', 'feed_leg', 'description', 'created', 'last_updated',
+            'color', 'power_port', 'feed_leg', 'description', 'created', 'last_updated',
         ]
         brief_fields = ('id', 'url', 'display', 'name', 'description')
 

+ 1 - 1
netbox/dcim/filtersets.py

@@ -842,7 +842,7 @@ class PowerOutletTemplateFilterSet(ChangeLoggedModelFilterSet, ModularDeviceType
 
     class Meta:
         model = PowerOutletTemplate
-        fields = ('id', 'name', 'label', 'type', 'feed_leg', 'description')
+        fields = ('id', 'name', 'label', 'type', 'color', 'feed_leg', 'description')
 
 
 class InterfaceTemplateFilterSet(ChangeLoggedModelFilterSet, ModularDeviceTypeComponentFilterSet):

+ 4 - 0
netbox/dcim/forms/bulk_edit.py

@@ -1163,6 +1163,10 @@ class PowerOutletTemplateBulkEditForm(ComponentTemplateBulkEditForm):
         choices=add_blank_choice(PowerOutletTypeChoices),
         required=False
     )
+    color = ColorField(
+        label=_('Color'),
+        required=False
+    )
     power_port = forms.ModelChoiceField(
         label=_('Power port'),
         queryset=PowerPortTemplate.objects.all(),

+ 2 - 2
netbox/dcim/forms/model_forms.py

@@ -1092,14 +1092,14 @@ class PowerOutletTemplateForm(ModularComponentTemplateForm):
                 FieldSet('device_type', name=_('Device Type')),
                 FieldSet('module_type', name=_('Module Type')),
             ),
-            'name', 'label', 'type', 'power_port', 'feed_leg', 'description',
+            'name', 'label', 'type', 'color', 'power_port', 'feed_leg', 'description',
         ),
     )
 
     class Meta:
         model = PowerOutletTemplate
         fields = [
-            'device_type', 'module_type', 'name', 'label', 'type', 'power_port', 'feed_leg', 'description',
+            'device_type', 'module_type', 'name', 'label', 'type', 'color', 'power_port', 'feed_leg', 'description',
         ]
 
 

+ 1 - 0
netbox/dcim/graphql/types.py

@@ -673,6 +673,7 @@ class PowerOutletType(ModularComponentType, CabledObjectMixin, PathEndpointMixin
 )
 class PowerOutletTemplateType(ModularComponentTemplateType):
     power_port: Annotated["PowerPortTemplateType", strawberry.lazy('dcim.graphql.types')] | None
+    color: str
 
 
 @strawberry_django.type(

+ 17 - 0
netbox/dcim/migrations/0216_poweroutlettemplate_color.py

@@ -0,0 +1,17 @@
+import utilities.fields
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('dcim', '0215_rackreservation_status'),
+    ]
+
+    operations = [
+        migrations.AddField(
+            model_name='poweroutlettemplate',
+            name='color',
+            field=utilities.fields.ColorField(blank=True, max_length=6),
+        ),
+    ]

+ 6 - 0
netbox/dcim/models/device_component_templates.py

@@ -339,6 +339,10 @@ class PowerOutletTemplate(ModularComponentTemplateModel):
         blank=True,
         null=True
     )
+    color = ColorField(
+        verbose_name=_('color'),
+        blank=True
+    )
     power_port = models.ForeignKey(
         to='dcim.PowerPortTemplate',
         on_delete=models.SET_NULL,
@@ -389,6 +393,7 @@ class PowerOutletTemplate(ModularComponentTemplateModel):
             name=self.resolve_name(kwargs.get('module')),
             label=self.resolve_label(kwargs.get('module')),
             type=self.type,
+            color=self.color,
             power_port=power_port,
             feed_leg=self.feed_leg,
             **kwargs
@@ -399,6 +404,7 @@ class PowerOutletTemplate(ModularComponentTemplateModel):
         return {
             'name': self.name,
             'type': self.type,
+            'color': self.color,
             'power_port': self.power_port.name if self.power_port else None,
             'feed_leg': self.feed_leg,
             'label': self.label,

+ 4 - 1
netbox/dcim/tables/devicetypes.py

@@ -211,6 +211,9 @@ class PowerPortTemplateTable(ComponentTemplateTable):
 
 
 class PowerOutletTemplateTable(ComponentTemplateTable):
+    color = columns.ColorColumn(
+        verbose_name=_('Color'),
+    )
     actions = columns.ActionsColumn(
         actions=('edit', 'delete'),
         extra_buttons=MODULAR_COMPONENT_TEMPLATE_BUTTONS
@@ -218,7 +221,7 @@ class PowerOutletTemplateTable(ComponentTemplateTable):
 
     class Meta(ComponentTemplateTable.Meta):
         model = models.PowerOutletTemplate
-        fields = ('pk', 'name', 'label', 'type', 'power_port', 'feed_leg', 'description', 'actions')
+        fields = ('pk', 'name', 'label', 'type', 'color', 'power_port', 'feed_leg', 'description', 'actions')
         empty_text = "None"
 
 

+ 7 - 0
netbox/dcim/tests/test_filtersets.py

@@ -1919,18 +1919,21 @@ class PowerOutletTemplateTestCase(TestCase, DeviceComponentTemplateFilterSetTest
                 device_type=device_types[0],
                 name='Power Outlet 1',
                 feed_leg=PowerOutletFeedLegChoices.FEED_LEG_A,
+                color=ColorChoices.COLOR_RED,
                 description='foobar1'
             ),
             PowerOutletTemplate(
                 device_type=device_types[1],
                 name='Power Outlet 2',
                 feed_leg=PowerOutletFeedLegChoices.FEED_LEG_B,
+                color=ColorChoices.COLOR_GREEN,
                 description='foobar2'
             ),
             PowerOutletTemplate(
                 device_type=device_types[2],
                 name='Power Outlet 3',
                 feed_leg=PowerOutletFeedLegChoices.FEED_LEG_C,
+                color=ColorChoices.COLOR_BLUE,
                 description='foobar3'
             ),
         ))
@@ -1943,6 +1946,10 @@ class PowerOutletTemplateTestCase(TestCase, DeviceComponentTemplateFilterSetTest
         params = {'feed_leg': [PowerOutletFeedLegChoices.FEED_LEG_A, PowerOutletFeedLegChoices.FEED_LEG_B]}
         self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
 
+    def test_color(self):
+        params = {'color': [ColorChoices.COLOR_RED, ColorChoices.COLOR_GREEN]}
+        self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
+
 
 class InterfaceTemplateTestCase(TestCase, DeviceComponentTemplateFilterSetTests, ChangeLoggedFilterSetTests):
     queryset = InterfaceTemplate.objects.all()