diff --git a/frontend/app.js b/frontend/app.js index 9dd02a3..1a6c923 100644 --- a/frontend/app.js +++ b/frontend/app.js @@ -143,6 +143,7 @@ const el = { copyReproBtn: document.getElementById("copyReproBtn"), autoLayoutBtn: document.getElementById("autoLayoutBtn"), autoTidyBtn: document.getElementById("autoTidyBtn"), + unlockAllBtn: document.getElementById("unlockAllBtn"), themeToggleBtn: document.getElementById("themeToggleBtn"), shortcutsBtn: document.getElementById("shortcutsBtn"), undoBtn: document.getElementById("undoBtn"), @@ -1780,6 +1781,7 @@ function bindSvgInteractions() { const dragRefsRaw = state.selectedRefs.length ? [...state.selectedRefs] : [ref]; const dragRefs = dragRefsRaw.filter((r) => !instanceByRef(r)?.placement?.locked); if (!dragRefs.length) { + el.jsonFeedback.textContent = `${ref} is locked. Uncheck 'Locked' on the component or use 'Unlock All'.`; return; } const baseByRef = {}; @@ -2494,7 +2496,7 @@ async function runLayoutAction(path) { const out = await apiPost(path, { payload: state.model, options: compileOptions({ - respect_locks: true + respect_locks: path.includes("/tidy") }) }); @@ -2768,7 +2770,6 @@ function setupEvents() { pushHistory("rotate"); const current = Number(inst.placement.rotation ?? 0); inst.placement.rotation = ((Math.round(current / 90) * 90 + 90) % 360 + 360) % 360; - inst.placement.locked = true; renderSelected(); el.jsonFeedback.textContent = "Component rotated."; queueCompile(true, "rotate"); @@ -3416,7 +3417,6 @@ function setupEvents() { if (inst) { inst.placement.x = pos.x; inst.placement.y = pos.y; - inst.placement.locked = true; } } await compileModel(state.model, { source: "drag", keepView: true, preservePlacement: true }); @@ -3465,7 +3465,6 @@ function setupEvents() { } const current = Number(inst.placement.rotation ?? 0); inst.placement.rotation = ((Math.round(current / 90) * 90 + 90) % 360 + 360) % 360; - inst.placement.locked = true; } compileModel(state.model, { source: "rotate", keepView: true, preservePlacement: true }); evt.preventDefault(); @@ -3739,6 +3738,26 @@ function setupEvents() { await runLayoutAction("/layout/tidy"); }); + el.unlockAllBtn?.addEventListener("click", async () => { + if (!state.model) { + return; + } + pushHistory("unlock-all"); + let changed = 0; + for (const inst of state.model.instances ?? []) { + if (inst?.placement?.locked) { + inst.placement.locked = false; + changed += 1; + } + } + if (!changed) { + el.jsonFeedback.textContent = "All components are already unlocked."; + return; + } + el.jsonFeedback.textContent = `Unlocked ${changed} component${changed === 1 ? "" : "s"}.`; + await compileModel(state.model, { keepView: true, source: "unlock-all", preservePlacement: true }); + }); + el.themeToggleBtn?.addEventListener("click", () => { applyTheme(state.theme === "dark" ? "light" : "dark"); }); diff --git a/frontend/index.html b/frontend/index.html index 9757b63..c00b494 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -20,6 +20,7 @@ +