Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -102,19 +102,26 @@
{% endif %}
</td>
</tr>
{% for field in fields %}
{% with is_visible_in_ui=object|get_field_is_ui_visible:field %}
{% if field.is_single_value and is_visible_in_ui %}
<tr>
<th scope="row">{{ field }}</th>
<td>
{% with customfield=field value=object|get_field_value:field %}
{% include "builtins/customfield_value.html" %}
{% endwith %}
</td>
</tr>
{% endif %}
{% endwith %}
{% for group_name, group_fields in field_groups.items %}
{% if group_name %}
<tr class="table-group-header">
<th scope="row" colspan="2" class="fw-bold">{{ group_name }}</th>
</tr>
{% endif %}
{% for field in group_fields %}
{% with is_visible_in_ui=object|get_field_is_ui_visible:field %}
{% if field.is_single_value and is_visible_in_ui %}
<tr>
<th scope="row">{{ field }}</th>
<td>
{% with customfield=field value=object|get_field_value:field %}
{% include "builtins/customfield_value.html" %}
{% endwith %}
</td>
</tr>
{% endif %}
{% endwith %}
{% endfor %}
{% endfor %}
</table>
</div>
Expand All @@ -123,12 +130,15 @@
<div class="col col-md-6">
{% include 'inc/panels/tags.html' %}
{% plugin_right_page object %}
{% for field in fields %}
{% for group_name, group_fields in field_groups.items %}
{% for field in group_fields %}
{% if field.many %}
{% with field_values=object|get_child_relations:field is_visible_in_ui=object|get_field_is_ui_visible:field %}
{% if is_visible_in_ui %}
<div class="card">
<h2 class="card-header">{{ field }}</h2>
<h2 class="card-header">
{% if group_name %}{{ group_name }}: {% endif %}{{ field }}
</h2>
<table class="table table-hover attr-table">
{% for relation in field_values.all %}
<tr>
Expand All @@ -140,6 +150,7 @@ <h2 class="card-header">{{ field }}</h2>
{% endif %}
{% endwith %}
{% endif %}
{% endfor %}
{% endfor %}
</div>
</div>
Expand Down
63 changes: 45 additions & 18 deletions netbox_custom_objects/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,12 @@
from netbox.views.generic.mixins import TableMixin
from utilities.forms import ConfirmationForm
from utilities.htmx import htmx_partial
from utilities.views import (ConditionalLoginRequiredMixin, ViewTab,
get_viewname, register_model_view)
from utilities.views import (
ConditionalLoginRequiredMixin,
ViewTab,
get_viewname,
register_model_view,
)

from netbox_custom_objects.tables import CustomObjectTable

Expand All @@ -33,44 +37,53 @@ class CustomJournalEntryForm(JournalEntryForm):
"""

def __init__(self, *args, **kwargs):
self.custom_object = kwargs.pop('custom_object', None)
self.custom_object = kwargs.pop("custom_object", None)
super().__init__(*args, **kwargs)

def get_return_url(self):
"""
Override to return the correct URL for custom objects.
"""
if self.custom_object:
return reverse('plugins:netbox_custom_objects:customobject_journal', kwargs={
'custom_object_type': self.custom_object.custom_object_type.name,
'pk': self.custom_object.pk
})
return reverse(
"plugins:netbox_custom_objects:customobject_journal",
kwargs={
"custom_object_type": self.custom_object.custom_object_type.name,
"pk": self.custom_object.pk,
},
)
return super().get_return_url()


class CustomJournalEntryEditView(generic.ObjectEditView):
"""
Custom journal entry edit view that handles return URLs for custom objects.
"""

queryset = JournalEntry.objects.all()
form = CustomJournalEntryForm

def get_return_url(self, request, instance):
"""
Override to return the correct URL for custom objects.
"""
if instance.assigned_object and hasattr(instance.assigned_object, 'custom_object_type'):
if instance.assigned_object and hasattr(
instance.assigned_object, "custom_object_type"
):
# This is a custom object
return reverse('plugins:netbox_custom_objects:customobject_journal', kwargs={
'custom_object_type': instance.assigned_object.custom_object_type.name,
'pk': instance.assigned_object.pk
})
return reverse(
"plugins:netbox_custom_objects:customobject_journal",
kwargs={
"custom_object_type": instance.assigned_object.custom_object_type.name,
"pk": instance.assigned_object.pk,
},
)
# Fall back to standard behavior for non-custom objects
if not instance.assigned_object:
return reverse('extras:journalentry_list')
return reverse("extras:journalentry_list")
obj = instance.assigned_object
viewname = get_viewname(obj, 'journal')
return reverse(viewname, kwargs={'pk': obj.pk})
viewname = get_viewname(obj, "journal")
return reverse(viewname, kwargs={"pk": obj.pk})


class CustomObjectTableMixin(TableMixin):
Expand Down Expand Up @@ -391,9 +404,21 @@ def get_object(self, **kwargs):
return get_object_or_404(model.objects.all(), **lookup_kwargs)

def get_extra_context(self, request, instance):
fields = instance.custom_object_type.fields.all().order_by("weight")
fields = instance.custom_object_type.fields.all().order_by(
"group_name", "weight", "name"
)

# Group fields by group_name
field_groups = {}
for field in fields:
group_name = field.group_name or None # Use None for ungrouped fields
if group_name not in field_groups:
field_groups[group_name] = []
field_groups[group_name].append(field)

return {
"fields": fields,
"field_groups": field_groups,
}


Expand Down Expand Up @@ -631,7 +656,7 @@ def get(self, request, custom_object_type, **kwargs):
initial={
"assigned_object_type": content_type,
"assigned_object_id": obj.pk,
}
},
)
else:
form = None
Expand All @@ -649,7 +674,9 @@ def get(self, request, custom_object_type, **kwargs):
"table": journal_table,
"base_template": self.base_template,
"tab": "journal",
"form_action": reverse('plugins:netbox_custom_objects:custom_journalentry_add'),
"form_action": reverse(
"plugins:netbox_custom_objects:custom_journalentry_add"
),
},
)

Expand Down