Skip to content

Add Add-button on Typed tabs with reverse-reference prefill (closes #9)#10

Open
Kani999 wants to merge 2 commits intomasterfrom
feature/typed-tab-add-button
Open

Add Add-button on Typed tabs with reverse-reference prefill (closes #9)#10
Kani999 wants to merge 2 commits intomasterfrom
feature/typed-tab-add-button

Conversation

@Kani999
Copy link
Copy Markdown
Collaborator

@Kani999 Kani999 commented Apr 22, 2026

Summary

  • Each Typed tab now shows an Add Type button (top-right) that links to the native customobject_add view with the back-reference field pre-populated to the parent object's PK and return_url set to the current tab path. One click + fill form + save → back on the tab, filters preserved.
  • When a Custom Object Type has multiple back-reference fields to the same parent model (e.g. primary_device and backup_device both → dcim.device), the button becomes a Bootstrap split-dropdown listing each field ("via label"). Single button otherwise.
  • Hidden for users without add_customobject permission (via get_permission_for_model(model, 'add') + user.has_perm(), mirroring the pattern used by CustomObjectActionsColumn).
  • hide_if_empty=True is unchanged: the tab appears only once the first object is linked (via the native menu); subsequent additions use the new button.

Design

  • New module-level _build_add_links(slug, pk, field_infos, return_url) helper — pure function, fully unit-tested. Produces [{field_name, label, url}].
  • field_infos tuples widened from (name, type) to (name, type, label) so the field label is resolved once at registration time instead of per-request. All call sites adjusted; existing 2-tuple tests remain green via *_ unpacking.
  • register_typed_tabs sorts each group by field name for deterministic button ordering.
  • Prefill contract: relies on NetBox's ObjectEditView.get() doing initial = normalize_querydict(request.GET). Works uniformly for TYPE_OBJECT (DynamicModelChoiceField) and TYPE_MULTIOBJECT (DynamicModelMultipleChoiceField).

Test plan

  • Unit tests for _build_add_links (no-reverse fallback, single field, multi-field, dedup, label fallback, URL encoding without double-encoding).
  • register_typed_tabs label population + deterministic sort test.
  • Existing 60 tests still pass (61 total).
  • ruff check + ruff format clean.
  • Manual: Device page → Typed tab → Add → form opens with Device prefilled → save → back on tab.
  • Manual: CO Type with two FKs to Device → split-dropdown renders, each option prefills its own field.
  • Manual: User without add_customobject perm sees no button.

Closes #9.

Kani999 added 2 commits April 22, 2026 14:33
Each typed tab now exposes an "Add <Type>" button that links to the native
customobject_add view with the back-reference field pre-populated to the
parent object's PK and return_url set to the current tab path. After saving,
the user lands back on the tab with filters preserved.

When a Custom Object Type has multiple back-reference fields to the same
parent model (e.g. primary_device + backup_device both -> dcim.device),
the button becomes a Bootstrap split-dropdown listing each field. The
button is hidden for users without add_customobject permission.

Implementation:
- New module-level _build_add_links() helper computes URLs from
  (slug, instance_pk, field_infos, return_url). Pure function, fully unit-tested.
- field_infos tuples extended from (name, type) to (name, type, label) so the
  dropdown can show human-readable field labels. Star-unpacking in
  _count_for_type and the queryset filter loop preserves backward compatibility
  with 2-tuple shapes used by existing tests.
- Permission gate uses utilities.permissions.get_permission_for_model, matching
  the pattern used by netbox_custom_objects.tables.CustomObjectActionsColumn.
- field_infos is sorted by field name in register_typed_tabs so the dropdown
  order is deterministic.

Tab placement: top-right of tab content, scoped entirely to typed/tab.html.
Tabs with hide_if_empty=True remain hidden until the first object is created
via the native menu - the button surfaces once the tab is visible.

Bumps version to 2.2.0 (minor, new feature). Test suite extended from 53 to 61
tests covering reverse failure, single/multi field, deduplication, label
fallback, 2-tuple back-compat, and return_url URL-encoding.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature] Add possibility to add additional custom obects from Typed-tab

1 participant