- 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>
130 lines
2.9 KiB
CSS
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;
|
|
}
|