Diagram - Rack Builder
Mount fictional hardware in numbered 16U racks and track space and sample draw.
#Configure two hardware racks
Two original 16U cabinets contain fictional hardware. Rack A starts with seven units occupied and 645 W rated draw; Rack B starts with three units and 390 W. The unit numbers run from U1 at the bottom to U16 at the top. Choose a module and starting unit from the numbered buttons above the canvas or on a cabinet rail, inspect the full interval, then place it in the rack. You can also drag a catalog module, the active module handle or mounted hardware onto a numbered unit.
- Choose Compute sled in the module catalog. It is 2U with an illustrative 320 W rated draw. Choose Rack B and U14, using the unit rail buttons or the Rack B destination button and numbered U14 button. The dashed candidate covers U14–15.
- Press Place module. Its new ID appears on the equipment face and in Mounted device. Rack B now uses 5U and totals 710 W. Placement is one edit.
- With that device selected, choose Rack A, U8, then Move device. Its ID remains unchanged. Rack A now uses 9U and totals 965 W; Rack B returns to 3U and 390 W. Undo and Redo restore slot metadata, geometry and totals together.
- Try moving into U2 in Rack A. The existing 4U Vault shelf occupies U1–4. The error names the occupied unit and device; nothing changes. A 4U candidate starting at U14 instead explains the rack boundary. Choose a lower free slot.
- Choose 600 W / rack in Sample capacity. Above-budget readouts name the exact excess. This is a sample draw warning: a physically valid slot remains placeable. An occupied slot is a separate rejection, even with draw below budget.
- Choose Cancel to dismiss the dashed preview without writing the model. Select a mounted device by its face or by name, then Remove to release its units and draw. Reset racks restores the five initial devices and default controls; its model change is one undoable edit.
#Discrete placement and ownership
Both cabinets are genuine locked Diagram frames. Each module is a genuine symbol
node made with public createDiagramSymbolNode and one of four original
DiagramSymbolRegistry definitions. Port panels, compute vents, storage drive
faces, power sockets, cabinet rails and unit numbers are authored vector geometry.
There are no server-card connectors, background images or private DOM adapters.
One managed Store owns module IDs, kind/rack/starting-unit metadata and final
bounds. The pure placement helper checks the entire occupied interval, ignoring
only the moved device's own old interval. A valid add or move uses one public
store.transact command that changes saved metadata and bounds together. Removal
and reset are likewise atomic public transactions. beforeTransaction validates
all saved assignments against bounds and collisions before every commit, including
history. Failed candidates produce no command; invalid direct proposals are
cancelled by the guard with no snapshot/history change. Occupancy and exact integer
rated draw are derived from the current Store snapshot, never a second placement map.
The editor sits above the canvas: mounted-device choice, destination buttons, active device, numbered starting units, candidate feedback and Place/Move/Cancel stay together. The 16 numbered buttons replace the long unit dropdown. Their highlight covers the full 1U, 2U or 4U interval. The same full interval appears over hardware at the destination; its Fits/Blocked label and error text distinguish a valid candidate from collision or overflow. Overflow text names the exact rack and range. Direct choices and rejected releases reveal the complete candidate through public pan; hover keeps the camera stable and keeps its range badge within the viewport. The editor does not float over the rack. Message rows reserve space, so changing feedback does not move the target between hover and release. Undo/Redo sit beside the view controls.
Host-owned pointer state supplies drag-and-drop. A five-pixel movement threshold
separates selection clicks from drags. Catalog modules insert; the active module
handle and mounted faces move the same device ID. The captured pointer is measured
against the consumer-owned viewport element, then public session.screenToWorld
projects it through current pan/zoom. slotAtWorld maps the authored cabinet/unit
geometry to the same candidate used by numbered selection. The pointer denotes the
lower starting unit: a 4U module dropped at U12 occupies U12–15. It does not clamp
overflow or silently choose a neighboring free interval.
Hover changes only host candidate state. A valid release calls the same pure placement planner and one public transaction as Place/Move; there are no saved intermediate bounds or history repairs. Occupied or overflowing drops preserve the model and history and leave the named candidate available for recovery. Escape, pointer cancellation, lost capture and release outside the rack clear the drag without a write. Capturing the pointer permits releases outside its source; route destruction releases capture. No new Diagram runtime capability is needed.
Built-in free movement, resize, rotation, deletion, duplication and structural shortcuts remain disabled. The built-in bounds-only gesture cannot save this example's rack/unit metadata; the host composition handles the complete atomic placement instead. The public Session owns selection, focus, pan and zoom. Palette, pointer/candidate, capacity preset and feedback are host UI state. Narrow view starts with Rack A; View and destination buttons reach Rack B. Selection/navigation leave IDs, assignments and totals unchanged.
#Capacity, history and reset
Space is counted in exact rack units. A 1U module at U16 fits; a 2U module there extends beyond the rack and rejects. Total free units do not guarantee a contiguous slot large enough for a module. The sample capacity preset is 1200 or 600 W per rack; it is a host viewing scenario and never blocks physically valid placement. All catalog draw values and sums are integer watts. This is not an electrical, thermal, redundancy or operating-load certification.
Undo/Redo uses the authoritative public Store history. Every placement, move, removal or changed reset is one history entry; derived space and draw follow the restored model. Cancel and rejected candidates create none. Reset restores five original devices, Compute sled, Rack A/U8, the 1200 W preset and the appropriate wide/narrow view. Undoing Reset restores the previous model while retaining those reset host controls. Undo/Redo clears the candidate and selection, retaining view and capacity. Returning to the route creates a fresh sample and history.
#Copy and customize
Copy RackBuilderDemo.vue, RackWorkbench.vue, and the local rack-builder helpers: fixture.ts, placement.ts, RackIcon.vue and styles.css. The workbench reads live Diagram state with useDiagramContext(). Keep the relative imports together. PrimeVue Button and Select provide companion controls, and individual PrimeIcons Vue imports supply icons. Follow Setup for the application theme and Diagram styles. Local styles inherit semantic surface, text, primary and warning tokens. No external asset or raster is required.
Change catalog height and integer draw in fixture.ts, along with its original
symbol faces and module bounds calculation. Keep cabinet unit geometry and the
placement validator synchronized if changing the rack height or spacing.
placement.ts owns interval validation, authored world-to-slot mapping, occupied
slots, derived totals and command planning. Preserve unique IDs and the public pre-commit guard when customizing.
#Keyboard and lifecycle
Open named PrimeVue choices, use arrows or Home/End and press Enter; Escape dismisses them. Tab reaches the active starting-unit button; arrows choose an adjacent unit, Home chooses U16 and End chooses U1. Enter/Space activates a numbered choice. The button name includes the rack, and the candidate announces the entire interval. The cabinet rail buttons provide the same pointer selection; numbered buttons above the canvas provide the keyboard equivalent without a dropdown. Escape cancels an active drag. Use named device choice, destination/unit buttons and Move/Place as the keyboard equivalent of insertion and cross-rack dragging. Catalog buttons, Place/Move, Cancel, Remove, Undo/Redo and Reset work with keyboard activation. A polite status region announces action results, rejection and recovery. IDs, unit numbers, numeric draw and warning text convey meaning alongside color. Focus uses the semantic primary outline. Cancel and Remove return focus to the stable Place/Move action when their trigger had focus. Undo/Redo does the same when its focused history button becomes unavailable, so the next Tab reaches the next enabled control. Named device inspection keeps the wide viewport in place and fits its rack on narrow screens.
There is no playback clock, delayed commit, animation-dependent outcome or hidden progression. The host unsubscribes its Store observer and disposes the Store on destruction; Diagram cleans up its Session and viewport observers. These finite fixtures have no network discovery, SSH, device control, operational customer data, backend, persistence or performance-benchmark claim. Physical touch and portable custom-content export fidelity are not established by this example.
See symbols, permissions, navigation and architecture for the underlying public contracts.