1
0
mirror of https://github.com/netbox-community/netbox.git synced 2024-05-10 07:54:54 +00:00

Enable the association of inventory item templates with component templates

This commit is contained in:
jeremystretch
2021-12-29 16:30:44 -05:00
parent 4c15f4a84f
commit 791cc093f4
6 changed files with 40 additions and 27 deletions

View File

@ -1092,7 +1092,7 @@ class InventoryItemTemplateForm(BootstrapMixin, forms.ModelForm):
)
component_type = ContentTypeChoiceField(
queryset=ContentType.objects.all(),
limit_choices_to=MODULAR_COMPONENT_MODELS,
limit_choices_to=MODULAR_COMPONENT_TEMPLATE_MODELS,
required=False,
widget=forms.HiddenInput
)

View File

@ -8,6 +8,7 @@ from dcim.models import (
from utilities.tables import (
BaseTable, BooleanColumn, ButtonsColumn, ColorColumn, LinkedCountColumn, MarkdownColumn, TagColumn, ToggleColumn,
)
from .template_code import MODULAR_COMPONENT_TEMPLATE_BUTTONS
__all__ = (
'ConsolePortTemplateTable',
@ -114,7 +115,8 @@ class ComponentTemplateTable(BaseTable):
class ConsolePortTemplateTable(ComponentTemplateTable):
actions = ButtonsColumn(
model=ConsolePortTemplate,
buttons=('edit', 'delete')
buttons=('edit', 'delete'),
prepend_template=MODULAR_COMPONENT_TEMPLATE_BUTTONS
)
class Meta(ComponentTemplateTable.Meta):
@ -126,7 +128,8 @@ class ConsolePortTemplateTable(ComponentTemplateTable):
class ConsoleServerPortTemplateTable(ComponentTemplateTable):
actions = ButtonsColumn(
model=ConsoleServerPortTemplate,
buttons=('edit', 'delete')
buttons=('edit', 'delete'),
prepend_template=MODULAR_COMPONENT_TEMPLATE_BUTTONS
)
class Meta(ComponentTemplateTable.Meta):
@ -138,7 +141,8 @@ class ConsoleServerPortTemplateTable(ComponentTemplateTable):
class PowerPortTemplateTable(ComponentTemplateTable):
actions = ButtonsColumn(
model=PowerPortTemplate,
buttons=('edit', 'delete')
buttons=('edit', 'delete'),
prepend_template=MODULAR_COMPONENT_TEMPLATE_BUTTONS
)
class Meta(ComponentTemplateTable.Meta):
@ -150,7 +154,8 @@ class PowerPortTemplateTable(ComponentTemplateTable):
class PowerOutletTemplateTable(ComponentTemplateTable):
actions = ButtonsColumn(
model=PowerOutletTemplate,
buttons=('edit', 'delete')
buttons=('edit', 'delete'),
prepend_template=MODULAR_COMPONENT_TEMPLATE_BUTTONS
)
class Meta(ComponentTemplateTable.Meta):
@ -165,7 +170,8 @@ class InterfaceTemplateTable(ComponentTemplateTable):
)
actions = ButtonsColumn(
model=InterfaceTemplate,
buttons=('edit', 'delete')
buttons=('edit', 'delete'),
prepend_template=MODULAR_COMPONENT_TEMPLATE_BUTTONS
)
class Meta(ComponentTemplateTable.Meta):
@ -181,7 +187,8 @@ class FrontPortTemplateTable(ComponentTemplateTable):
color = ColorColumn()
actions = ButtonsColumn(
model=FrontPortTemplate,
buttons=('edit', 'delete')
buttons=('edit', 'delete'),
prepend_template=MODULAR_COMPONENT_TEMPLATE_BUTTONS
)
class Meta(ComponentTemplateTable.Meta):
@ -194,7 +201,8 @@ class RearPortTemplateTable(ComponentTemplateTable):
color = ColorColumn()
actions = ButtonsColumn(
model=RearPortTemplate,
buttons=('edit', 'delete')
buttons=('edit', 'delete'),
prepend_template=MODULAR_COMPONENT_TEMPLATE_BUTTONS
)
class Meta(ComponentTemplateTable.Meta):

View File

@ -93,6 +93,19 @@ LOCATION_ELEVATIONS = """
</a>
"""
#
# Device component templatebuttons
#
MODULAR_COMPONENT_TEMPLATE_BUTTONS = """
{% load helpers %}
{% if perms.dcim.add_invnetoryitemtemplate %}
<a href="{% url 'dcim:inventoryitemtemplate_add' %}?device_type={{ record.device_type.pk }}&component_type={{ record|content_type_id }}&component_id={{ record.pk }}&return_url={{ request.path }}" title="Add inventory item" class="btn btn-primary btn-sm">
<i class="mdi mdi-plus-thick" aria-hidden="true"></i>
</a>
{% endif %}
"""
#
# Device component buttons
#

View File

@ -1379,6 +1379,7 @@ class InventoryItemTemplateCreateView(generic.ComponentCreateView):
queryset = InventoryItemTemplate.objects.all()
form = forms.DeviceTypeComponentCreateForm
model_form = forms.InventoryItemTemplateForm
template_name = 'dcim/inventoryitem_create.html'
def alter_object(self, instance, request):
# Set component (if any)

View File

@ -737,6 +737,7 @@ class ComponentCreateView(GetReturnURLMixin, ObjectPermissionRequiredMixin, View
'return_url': self.get_return_url(request),
})
# TODO: Refactor this method for clarity & better error reporting
def validate_form(self, request, form):
"""
Validate form values and set errors on the form object as they are detected. If
@ -763,17 +764,7 @@ class ComponentCreateView(GetReturnURLMixin, ObjectPermissionRequiredMixin, View
if component_form.is_valid():
new_components.append(component_form)
else:
for field, errors in component_form.errors.as_data().items():
# Assign errors on the child form's name/label field to name_pattern/label_pattern on the parent form
if field == 'name':
field = 'name_pattern'
elif field == 'label':
field = 'label_pattern'
for e in errors:
form.add_error(field, '{}: {}'.format(name, ', '.join(e)))
if not form.errors:
if not form.errors and not component_form.errors:
try:
with transaction.atomic():
# Create the new components

View File

@ -1,17 +1,17 @@
{% extends 'dcim/component_create.html' %}
{% extends 'generic/object_edit.html' %}
{% load helpers %}
{% load form_helpers %}
{% block form %}
{% render_form replication_form %}
{% if obj.component %}
<div class="row mb-3">
<label class="col-sm-3 col-form-label text-lg-end required">
{{ obj.component|meta:"verbose_name"|bettertitle }}
</label>
<div class="col-sm-9">
<div class="form-control-plaintext">
<a href="{{ obj.component.get_absolute_url }}" class="">{{ obj.component }}</a>
<label class="col-sm-3 col-form-label text-lg-end">
{{ obj.component|meta:"verbose_name"|bettertitle }}
</label>
<div class="col">
<input class="form-control" value="{{ obj.component }}" disabled />
</div>
</div>
</div>
{% endif %}
{{ block.super }}