🚧 WIP
This commit is contained in:
@@ -528,7 +528,12 @@ async function renderConfig() {
|
|||||||
renderNameEditor();
|
renderNameEditor();
|
||||||
const list = document.getElementById("module-list");
|
const list = document.getElementById("module-list");
|
||||||
list.innerHTML = mc.modules.map((m, i) => `
|
list.innerHTML = mc.modules.map((m, i) => `
|
||||||
<label class="module-row">
|
<label class="module-row" draggable="true"
|
||||||
|
ondragstart="dragStart(event, ${i})"
|
||||||
|
ondragover="dragOver(event, ${i})"
|
||||||
|
ondrop="drop(event, ${i})"
|
||||||
|
ondragend="dragEnd()">
|
||||||
|
<span class="drag-handle" title="Drag to rearrange">☰</span>
|
||||||
<input type="radio" name="mod" value="${i}">
|
<input type="radio" name="mod" value="${i}">
|
||||||
<b>${i}</b> ${m.article} — ${m.description}
|
<b>${i}</b> ${m.article} — ${m.description}
|
||||||
<span class="mod-io">${m.input_bits ? m.input_bits + " DI" : ""}
|
<span class="mod-io">${m.input_bits ? m.input_bits + " DI" : ""}
|
||||||
@@ -643,7 +648,12 @@ function renderModuleRows() {
|
|||||||
// local edit view until SAVE CONFIG is pressed
|
// local edit view until SAVE CONFIG is pressed
|
||||||
const list = document.getElementById("module-list");
|
const list = document.getElementById("module-list");
|
||||||
list.innerHTML = MODULE_ARTICLES.map((a, i) => `
|
list.innerHTML = MODULE_ARTICLES.map((a, i) => `
|
||||||
<label class="module-row">
|
<label class="module-row" draggable="true"
|
||||||
|
ondragstart="dragStart(event, ${i})"
|
||||||
|
ondragover="dragOver(event, ${i})"
|
||||||
|
ondrop="drop(event, ${i})"
|
||||||
|
ondragend="dragEnd()">
|
||||||
|
<span class="drag-handle" title="Drag to rearrange">☰</span>
|
||||||
<input type="radio" name="mod" value="${i}">
|
<input type="radio" name="mod" value="${i}">
|
||||||
<b>${i}</b> ${a}
|
<b>${i}</b> ${a}
|
||||||
<span class="row-buttons">
|
<span class="row-buttons">
|
||||||
@@ -666,6 +676,42 @@ async function moveModule(index, delta) {
|
|||||||
await saveModules();
|
await saveModules();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// -- drag-and-drop reordering (FR-11.2.6) ----------------
|
||||||
|
|
||||||
|
let DRAG_FROM = null;
|
||||||
|
|
||||||
|
function dragStart(ev, index) {
|
||||||
|
DRAG_FROM = index;
|
||||||
|
ev.dataTransfer.effectAllowed = "move";
|
||||||
|
ev.dataTransfer.setData("text/plain", String(index));
|
||||||
|
ev.currentTarget.classList.add("dragging");
|
||||||
|
}
|
||||||
|
|
||||||
|
function dragOver(ev, index) {
|
||||||
|
if (DRAG_FROM === null || DRAG_FROM === index) return;
|
||||||
|
ev.preventDefault(); // allow the drop
|
||||||
|
ev.dataTransfer.dropEffect = "move";
|
||||||
|
ev.currentTarget.classList.add("drop-target");
|
||||||
|
}
|
||||||
|
|
||||||
|
async function drop(ev, index) {
|
||||||
|
ev.preventDefault();
|
||||||
|
ev.currentTarget.classList.remove("drop-target");
|
||||||
|
if (DRAG_FROM === null || DRAG_FROM === index) return;
|
||||||
|
// move the dragged module to the drop position (splice semantics:
|
||||||
|
// remove, then insert at the target index)
|
||||||
|
const [moved] = MODULE_ARTICLES.splice(DRAG_FROM, 1);
|
||||||
|
MODULE_ARTICLES.splice(index, 0, moved);
|
||||||
|
DRAG_FROM = null;
|
||||||
|
await saveModules(); // rebuild + persist, like arrows
|
||||||
|
}
|
||||||
|
|
||||||
|
function dragEnd() {
|
||||||
|
DRAG_FROM = null;
|
||||||
|
document.querySelectorAll(".module-row").forEach((el) =>
|
||||||
|
el.classList.remove("dragging", "drop-target"));
|
||||||
|
}
|
||||||
|
|
||||||
// ---------------- tabs ----------------
|
// ---------------- tabs ----------------
|
||||||
|
|
||||||
document.querySelectorAll(".tab").forEach((btn) => {
|
document.querySelectorAll(".tab").forEach((btn) => {
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<title>WAGO 750-362 Simulator</title>
|
<title>WAGO 750-362 Simulator</title>
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
<link rel="stylesheet" href="/static/style.css?v=2">
|
<link rel="stylesheet" href="/static/style.css?v=3">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<header class="topbar">
|
<header class="topbar">
|
||||||
@@ -111,6 +111,6 @@
|
|||||||
</section>
|
</section>
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<script src="/static/app.js?v=2"></script>
|
<script src="/static/app.js?v=3"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
@@ -4,7 +4,7 @@
|
|||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<title>WAGO Simulator — Login</title>
|
<title>WAGO Simulator — Login</title>
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
<link rel="stylesheet" href="/static/style.css?v=2">
|
<link rel="stylesheet" href="/static/style.css?v=3">
|
||||||
</head>
|
</head>
|
||||||
<body class="login-body">
|
<body class="login-body">
|
||||||
<div class="login-card">
|
<div class="login-card">
|
||||||
|
|||||||
@@ -267,6 +267,19 @@ button.mini {
|
|||||||
}
|
}
|
||||||
button.mini:hover:not(:disabled) { background: #dce7f2; }
|
button.mini:hover:not(:disabled) { background: #dce7f2; }
|
||||||
button.mini:disabled { opacity: 0.35; cursor: default; }
|
button.mini:disabled { opacity: 0.35; cursor: default; }
|
||||||
|
|
||||||
|
/* drag-and-drop reordering (FR-11.2.6) */
|
||||||
|
.drag-handle {
|
||||||
|
cursor: grab; color: #9aa4ae; font-size: 0.9rem;
|
||||||
|
padding: 0 3px; user-select: none;
|
||||||
|
}
|
||||||
|
.drag-handle:hover { color: #0062c4; }
|
||||||
|
.module-row.dragging { opacity: 0.45; }
|
||||||
|
.module-row.drop-target {
|
||||||
|
border-color: #0062c4 !important;
|
||||||
|
box-shadow: inset 0 2px 0 #0062c4; /* insertion marker: line on top edge */
|
||||||
|
}
|
||||||
|
.module-row[draggable="true"] { cursor: default; }
|
||||||
#catalog-pick { padding: 6px; border: 1px solid #c5ccd4; border-radius: 4px; flex: 1; }
|
#catalog-pick { padding: 6px; border: 1px solid #c5ccd4; border-radius: 4px; flex: 1; }
|
||||||
.cfg-path { font-size: 0.75rem; color: #6b7684; align-self: center; }
|
.cfg-path { font-size: 0.75rem; color: #6b7684; align-self: center; }
|
||||||
button.primary { background: #2e7d32; }
|
button.primary { background: #2e7d32; }
|
||||||
|
|||||||
Reference in New Issue
Block a user