This commit is contained in:
@@ -226,6 +226,7 @@ function renderRack() {
|
||||
}
|
||||
|
||||
ui.rackGrid.style.setProperty("--rack-unit-height", `${RACK_UNIT_PX}px`);
|
||||
ui.rackGrid.style.setProperty("--rack-total-u", String(rack.totalU));
|
||||
applyRackColorTheme(ui.rackGrid, state.rackColor);
|
||||
|
||||
const slots = [];
|
||||
@@ -238,26 +239,25 @@ function renderRack() {
|
||||
`);
|
||||
}
|
||||
|
||||
const insertionZones = renderInsertionZones(rack);
|
||||
|
||||
ui.rackGrid.innerHTML = `
|
||||
<div class="rack-grid__header-badge rack-grid__header-badge--left">${rack.rackStandard === "19_inch" ? '19" Rack' : '10" Rack'}</div>
|
||||
<div class="rack-grid__header-badge rack-grid__header-badge--right">${rack.totalU} HE</div>
|
||||
<div class="rack-grid__bay">
|
||||
<div class="rack-grid__guides">${slots.join("")}</div>
|
||||
<div class="rack-insertion-layer">${insertionZones}</div>
|
||||
<div class="rack-insertion-layer" id="rack-insertion-layer"></div>
|
||||
<div class="rack-items-layer" id="rack-items-layer"></div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
const layer = document.getElementById("rack-items-layer");
|
||||
layer.style.height = "100%";
|
||||
|
||||
const insertionLayer = document.getElementById("rack-insertion-layer");
|
||||
insertionLayer.innerHTML = renderInsertionZones(rack);
|
||||
ui.rackGrid.querySelectorAll("[data-action='insert-component']").forEach((element) => {
|
||||
element.addEventListener("click", () => insertSelectedComponentAt(Number(element.dataset.insertY)));
|
||||
});
|
||||
|
||||
const layer = document.getElementById("rack-items-layer");
|
||||
const rackHeight = rack.totalU * RACK_UNIT_PX;
|
||||
layer.style.height = `${rackHeight}px`;
|
||||
|
||||
state.placedItems.forEach((item) => {
|
||||
const component = getComponent(item.componentId);
|
||||
if (!component) {
|
||||
@@ -284,21 +284,12 @@ function renderRack() {
|
||||
</div>
|
||||
<span class="chip">${formatRackPosition(item.y)}</span>
|
||||
</div>
|
||||
<div class="rack-item__actions">
|
||||
<button type="button" data-action="move-left">←</button>
|
||||
<button type="button" data-action="move-right">→</button>
|
||||
<button type="button" data-action="move-up">+1U</button>
|
||||
<button type="button" data-action="move-down">-1U</button>
|
||||
<button type="button" data-action="remove">Entfernen</button>
|
||||
</div>
|
||||
<div class="rack-item__drag-hint">Ziehen zum verschieben</div>
|
||||
<button type="button" class="rack-item__remove" data-action="remove" aria-label="Komponente entfernen">×</button>
|
||||
</div>
|
||||
`;
|
||||
|
||||
element.addEventListener("pointerdown", (event) => beginPointerDrag(event, item, component));
|
||||
element.querySelector("[data-action='move-left']").addEventListener("click", () => nudgePlacedItem(item.placementId, -2, 0));
|
||||
element.querySelector("[data-action='move-right']").addEventListener("click", () => nudgePlacedItem(item.placementId, 2, 0));
|
||||
element.querySelector("[data-action='move-up']").addEventListener("click", () => nudgePlacedItem(item.placementId, 0, -RACK_UNIT_PX));
|
||||
element.querySelector("[data-action='move-down']").addEventListener("click", () => nudgePlacedItem(item.placementId, 0, RACK_UNIT_PX));
|
||||
element.querySelector("[data-action='remove']").addEventListener("click", () => {
|
||||
state.placedItems = state.placedItems.filter((entry) => entry.placementId !== item.placementId);
|
||||
renderAll();
|
||||
@@ -308,19 +299,6 @@ function renderRack() {
|
||||
});
|
||||
}
|
||||
|
||||
function nudgePlacedItem(placementId, deltaX, deltaY) {
|
||||
const rack = getCurrentRackTemplate();
|
||||
const item = state.placedItems.find((entry) => entry.placementId === placementId);
|
||||
const component = item ? getComponent(item.componentId) : null;
|
||||
if (!rack || !item || !component) {
|
||||
return;
|
||||
}
|
||||
|
||||
item.x = clamp(item.x + deltaX, 0, 100 - getComponentWidthPercent(component));
|
||||
item.y = clamp(item.y + deltaY, 0, getRackHeightPx(rack) - getComponentHeightPx(component));
|
||||
renderAll();
|
||||
}
|
||||
|
||||
function insertSelectedComponentAt(y) {
|
||||
if (!state.selectedComponentId) {
|
||||
return;
|
||||
@@ -494,7 +472,7 @@ function renderCableEstimate() {
|
||||
return;
|
||||
}
|
||||
|
||||
const verticalMm = Math.abs(getPlacementCenterY(from, fromComponent) - getPlacementCenterY(to, toComponent)) * (44.45 / RACK_UNIT_PX);
|
||||
const verticalMm = Math.abs(getPlacementCenterY(from, fromComponent) - getPlacementCenterY(to, toComponent)) * (44.45 / getUnitHeightPx());
|
||||
const depthAllowance = Math.min(rack.usableDepthMm * 0.35, 280);
|
||||
const sideAllowance = estimateSideAllowance(fromComponent, toComponent);
|
||||
const rawLength = verticalMm + depthAllowance + sideAllowance;
|
||||
@@ -656,8 +634,9 @@ function findFirstFreePosition(heightU) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const testHeight = heightU * RACK_UNIT_PX;
|
||||
for (let y = 0; y <= getRackHeightPx(rack) - testHeight; y += RACK_UNIT_PX) {
|
||||
const unitHeight = getUnitHeightPx();
|
||||
const testHeight = heightU * unitHeight;
|
||||
for (let y = 0; y <= getRackHeightPx(rack) - testHeight; y += unitHeight) {
|
||||
const blocked = state.placedItems.some((item) => {
|
||||
const otherComponent = getComponent(item.componentId);
|
||||
if (!otherComponent) {
|
||||
@@ -883,8 +862,9 @@ function renderInsertionZones(rack) {
|
||||
return "";
|
||||
}
|
||||
|
||||
const unitHeight = getUnitHeightPx();
|
||||
const zones = [];
|
||||
for (let y = 0; y <= getRackHeightPx(rack) - getComponentHeightPx(component); y += RACK_UNIT_PX) {
|
||||
for (let y = 0; y <= getRackHeightPx(rack) - getComponentHeightPx(component); y += unitHeight) {
|
||||
const occupied = state.placedItems.some((item) => {
|
||||
const other = getComponent(item.componentId);
|
||||
if (!other) {
|
||||
@@ -929,11 +909,15 @@ function renderInsertionZones(rack) {
|
||||
}
|
||||
|
||||
function getRackHeightPx(rack) {
|
||||
const layer = document.getElementById("rack-items-layer");
|
||||
if (layer) {
|
||||
return layer.clientHeight || rack.totalU * RACK_UNIT_PX;
|
||||
}
|
||||
return rack.totalU * RACK_UNIT_PX;
|
||||
}
|
||||
|
||||
function getComponentHeightPx(component) {
|
||||
return component.heightU * RACK_UNIT_PX;
|
||||
return component.heightU * getUnitHeightPx();
|
||||
}
|
||||
|
||||
function getComponentWidthPercent(component) {
|
||||
@@ -961,7 +945,7 @@ function getPlacementCenterY(item, component) {
|
||||
}
|
||||
|
||||
function formatRackPosition(y) {
|
||||
return `${(y / RACK_UNIT_PX + 1).toFixed(1)}U`;
|
||||
return `${(y / getUnitHeightPx() + 1).toFixed(1)}U`;
|
||||
}
|
||||
|
||||
function getPlacementOverlaps() {
|
||||
@@ -995,6 +979,15 @@ function getRackInnerWidthPx() {
|
||||
return 620;
|
||||
}
|
||||
|
||||
function getUnitHeightPx() {
|
||||
const rack = getCurrentRackTemplate();
|
||||
const layer = document.getElementById("rack-items-layer");
|
||||
if (rack && layer && layer.clientHeight) {
|
||||
return layer.clientHeight / rack.totalU;
|
||||
}
|
||||
return RACK_UNIT_PX;
|
||||
}
|
||||
|
||||
function clamp(value, min, max) {
|
||||
return Math.max(min, Math.min(max, value));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user