- Split the device detail page's single "Components" table into the
same seven tabs a real dcim.Device has, in the same order: Console
Ports, Console Server Ports, Power Ports, Power Outlets, Interfaces,
Front Ports, Rear Ports. Each tab is its own ObjectChildrenView
filtered by component_type (one ConceptComponent model backs all of
them, so this only needed the view/URL layer, not a schema change),
hidden when empty, exactly like core NetBox. Replace the ad hoc "Add
component" button with the same "Add Components" dropdown real
device pages use, one entry per type, each landing back on its own
tab.
- When copying a real rack into a concept (or merging two real racks
into one), automatically sync every copied device's components and
recreate, as ConceptCables, every real cable whose both ends land on
one of those devices - reading the same CableTermination data dcim
itself uses, so the copy comes out cabled internally the same as the
source. Cables reaching outside the copied rack(s), or multi-
termination trunk cables, are skipped and reported as a count in the
success message - the other end isn't part of the concept, so it
can't be represented. copy_rack_to_concept() and
merge_racks_to_concept() now return an extra cable_summary value;
updated all their callers (views and API).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- Fix "images only" leaving plain labels visible on faces where a
device has no image for that side (e.g. no rear_image set): the
view selector now hides every plain label outright in that mode,
not just the ones an image happens to sit on top of.
- Remove the "Add planned device" button from the elevation card.
Empty units are now click targets themselves - clicking one opens
the add-device form pre-filled with that position and face, exactly
like a real rack's elevation. Occupancy is computed per unit per
face from the existing device blocks.
- Add cabling for concept devices: ConceptComponent (interfaces,
front/rear ports, power ports/outlets, console ports) and
ConceptCable (a connection between two components, restricted to
devices in the same concept). components.sync_components()
populates a device's components from its device type's templates,
including the front/rear port pass-through mapping copied from
DeviceType.port_mappings - so a device with front/rear port
templates (a patch panel being the common case) behaves exactly
like a real one, without hardcoding anything role-specific.
Placeholder devices without a device type get components added by
hand. Full CRUD views, tables, filtersets, API endpoints and a
"Connect" action wired in from the device detail page.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>