This commit is contained in:
@@ -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("&", "&")
|
||||
|
||||
Reference in New Issue
Block a user