Files
NetBox-Concept/netbox_rack_concept/static/netbox_rack_concept/elevation.css
T
MrBlakeandClaude Sonnet 5 1793bf13e2 v0.2.3: visible cross-panel drag ghost, front-image fallback, shorter hint
- Fix invisible device while dragging from front to rear: the block
  being dragged stayed structurally inside its own source <svg>, so it
  rendered underneath the other panel once it visually overlapped it.
  Replaced the in-SVG transform with a free-floating HTML ghost fixed
  to <body> that tracks the pointer, unaffected by either SVG's own
  stacking - the original block just dims in place during the drag, as
  before.
- Fix rear elevation showing nothing for a device type with no
  rear_image: only full-depth devices (which have a genuinely
  different back) are restricted to their own rear image now; a
  shallow device (e.g. a PDU) falls back to its front image on the
  rear view, since that's usually the only picture that exists and is
  still recognisable either way.
- Shorten the drag-hint badge text; the German translation of the
  previous, longer wording didn't fit well next to the other controls
  above the elevation.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-16 14:01:42 +02:00

130 lines
2.9 KiB
CSS

/* Concept rack elevations. Colours follow the NetBox theme via CSS variables so the
elevation stays readable in both light and dark mode. */
.concept-elevation {
margin: 0 0.5rem 1rem;
}
.concept-elevation-svg {
max-width: 100%;
height: auto;
user-select: none;
touch-action: none;
}
.concept-elevation .unit-slot {
fill: var(--tblr-bg-surface-secondary, #f6f8fa);
stroke: var(--tblr-border-color, #dadfe5);
stroke-width: 1;
}
.concept-elevation .unit-slot.drop-target {
fill: var(--tblr-primary-lt, #d7e7fb);
}
.concept-elevation .unit-slot.free {
cursor: pointer;
}
.concept-elevation .unit-slot.free:hover {
fill: var(--tblr-primary-lt, #d7e7fb);
}
/* "+ Add device" hint, shown only while hovering an empty unit - same trick as
NetBox's own rack elevation. */
.concept-elevation .add-device-hint {
font-size: 10px;
fill: var(--tblr-primary, #206bc4);
opacity: 0;
pointer-events: none;
}
.concept-elevation a:hover .add-device-hint {
opacity: 1;
}
.concept-elevation .unit-label {
font-size: 10px;
fill: var(--tblr-secondary, #808f9c);
}
.concept-elevation .rack-frame {
stroke: var(--tblr-body-color, #35404a);
stroke-width: 2;
}
.concept-elevation .device-rect {
stroke: rgba(0, 0, 0, 0.35);
stroke-width: 1;
}
.concept-elevation .device-image {
pointer-events: none;
}
.concept-elevation .device-label {
font-size: 11px;
pointer-events: none;
}
/* Label drawn over an image: a black stroke pass behind a white fill pass gives crisp,
readable text on any picture without a solid backing box. */
.concept-elevation .device-image-label {
font-size: 11px;
pointer-events: none;
}
.concept-elevation .device-image-label-stroke {
fill: none;
stroke: #000000;
stroke-width: 0.2em;
stroke-linejoin: round;
}
.concept-elevation .device-image-label-fill {
fill: #ffffff;
}
/* Toggled by the "images and labels / images only / labels only" selector. */
.concept-elevation .hidden {
visibility: hidden;
}
.concept-elevation .opposite-hint {
font-size: 9px;
opacity: 0.8;
}
.concept-elevation .device-block.opposite .device-rect {
stroke-dasharray: 3 2;
}
.concept-elevation[data-editable="true"] .device-block:not(.opposite) {
cursor: grab;
}
.concept-elevation .device-block.dragging {
opacity: 0.3;
cursor: grabbing;
}
/* Follows the pointer during a drag - a plain HTML element fixed to <body>, not
scoped to either elevation's <svg>, so it stays visible the whole way from the
front panel to the rear one and back. */
.concept-drag-ghost {
position: fixed;
z-index: 2000;
pointer-events: none;
display: flex;
align-items: center;
border-radius: 2px;
padding-left: 6px;
font-size: 11px;
color: #ffffff;
text-shadow: 0 0 2px #000000, 0 0 2px #000000, 0 0 2px #000000;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.4);
white-space: nowrap;
overflow: hidden;
cursor: grabbing;
}