yssadasd
All checks were successful
Deploy / deploy (push) Successful in 16s

This commit is contained in:
2026-05-15 23:08:24 +02:00
parent 838f4d7eec
commit b2dcff9cb6
2 changed files with 329 additions and 26 deletions

View File

@@ -139,7 +139,10 @@ function renderLibrary() {
ui.componentLibrary.innerHTML = filtered
.map(
(component) => `
<article class="component-card">
<article class="component-card component-card--${escapeHtml(component.category)}">
<div class="component-card__preview">
${renderComponentFace(component, "library")}
</div>
<div class="component-card__header">
<div>
<strong>${escapeHtml(component.name)}</strong>
@@ -235,23 +238,28 @@ function renderRack() {
const top = (rack.totalU - (item.startU + component.heightU) + 1) * 38;
const height = component.heightU * 38 - 2;
const element = document.createElement("article");
element.className = "rack-item";
element.className = `rack-item rack-item--${component.category.replace(/_/g, "-")}`;
element.dataset.standard = component.rackStandard;
element.draggable = true;
element.style.top = `${top}px`;
element.style.height = `${height}px`;
element.innerHTML = `
<div class="rack-item__header">
<div>
<strong>${escapeHtml(component.name)}</strong>
<div class="rack-item__meta">${component.heightU}U · ${component.depthMm} mm · ${formatCurrency(component.priceNet, component.currency)}</div>
</div>
<span class="chip">${item.startU}U</span>
<div class="rack-item__face rack-item__face--${escapeHtml(component.category)}">
${renderComponentFace(component, "rack")}
</div>
<div class="rack-item__actions">
<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 class="rack-item__overlay">
<div class="rack-item__header">
<div>
<strong>${escapeHtml(component.name)}</strong>
<div class="rack-item__meta">${component.heightU}U · ${component.depthMm} mm · ${formatCurrency(component.priceNet, component.currency)}</div>
</div>
<span class="chip">${item.startU}U</span>
</div>
<div class="rack-item__actions">
<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>
`;
@@ -634,6 +642,84 @@ function formatCurrency(value, currency) {
}).format(value);
}
function renderComponentFace(component, mode) {
const ports = renderPortStrip(component);
const leds = '<div class="device-leds"><span></span><span></span><span></span></div>';
const label = `<div class="device-silkscreen">${escapeHtml(component.manufacturer || component.category)}</div>`;
const modeClass = mode === "rack" ? "device-face--rack" : "device-face--library";
switch (component.category) {
case "switch":
return `
<div class="device-face device-face--switch ${modeClass}">
${label}
${leds}
${ports}
<div class="device-uplink"></div>
</div>
`;
case "patch_panel":
return `
<div class="device-face device-face--patch-panel ${modeClass}">
${label}
${renderPatchPanel(component)}
</div>
`;
case "pdu":
return `
<div class="device-face device-face--pdu ${modeClass}">
${label}
<div class="device-sockets">${renderSocketStrip(component)}</div>
${leds}
</div>
`;
case "ups":
return `
<div class="device-face device-face--ups ${modeClass}">
<div class="device-display"></div>
<div class="device-vents"></div>
${label}
</div>
`;
case "shelf":
return `
<div class="device-face device-face--shelf ${modeClass}">
<div class="device-shelf-top"></div>
${label}
</div>
`;
case "blank_panel":
return `
<div class="device-face device-face--blank ${modeClass}">
${label}
</div>
`;
default:
return `
<div class="device-face device-face--generic ${modeClass}">
${label}
</div>
`;
}
}
function renderPortStrip(component) {
const totalPorts = component.name.includes("24") ? 24 : component.name.includes("12") ? 12 : 8;
const ports = Array.from({ length: totalPorts }, (_, index) => `<span title="Port ${index + 1}"></span>`).join("");
return `<div class="device-ports device-ports--${Math.min(totalPorts, 24)}">${ports}</div>`;
}
function renderPatchPanel(component) {
const totalPorts = component.name.includes("24") ? 24 : 12;
const ports = Array.from({ length: totalPorts }, (_, index) => `<span title="Patch ${index + 1}"></span>`).join("");
return `<div class="device-keystones">${ports}</div>`;
}
function renderSocketStrip(component) {
const totalSockets = component.name.includes("8") ? 8 : 6;
return Array.from({ length: totalSockets }, () => "<span></span>").join("");
}
function escapeHtml(value) {
return String(value)
.replaceAll("&", "&amp;")