From 565cd01ca6c16d594705e9bded2afa35936d1299 Mon Sep 17 00:00:00 2001 From: Mitchell R Date: Sat, 23 May 2026 02:35:57 +0200 Subject: [PATCH] feat(smart-url): step builder form in cell editor (add/remove/configure steps inline) --- .../service-admin-http/routes-admin.ts | 34 +++++++++++++++++++ server/src/web-templates/admin-pages.tsx | 32 +++++++++++++++++ 2 files changed, 66 insertions(+) diff --git a/server/src/plugins/service-admin-http/routes-admin.ts b/server/src/plugins/service-admin-http/routes-admin.ts index 3de9ed3..a299578 100644 --- a/server/src/plugins/service-admin-http/routes-admin.ts +++ b/server/src/plugins/service-admin-http/routes-admin.ts @@ -1104,6 +1104,40 @@ export function registerAdminRoutes(app: H3, deps: AdminDeps): void { await resolveOverlaps(deps, layoutId, cellId, axis); } } + + // Parse smart URL steps from the step builder form fields. + const steps: Array> = []; + for (let i = 0; i < 50; i++) { + const stepType = body?.[`step_${i}_type`]; + const stepValue = body?.[`step_${i}_value`]; + if (!stepType) break; + const step: Record = { type: stepType }; + if (stepType === "navigate") step["url"] = stepValue; + else if (stepType === "fill" && stepValue?.includes("=")) { + const eqIdx = stepValue.indexOf("="); + step["selector"] = stepValue.slice(0, eqIdx); + step["value"] = stepValue.slice(eqIdx + 1); + } + else if (stepType === "click" || stepType === "wait_for") step["selector"] = stepValue; + else if (stepType === "wait") step["delay_ms"] = Number(stepValue) || 1000; + else if (stepType === "javascript") step["script"] = stepValue; + steps.push(step); + } + const loginDetect = (body?.["smart_url_login_detect"] ?? "").trim(); + const updatedCell = await deps.repo.getLayoutCellById(cellId); + if (updatedCell) { + const opts = { ...(updatedCell.options ?? {}) }; + if (steps.length > 0) { + opts["smart_url"] = { + steps, + ...(loginDetect ? { login_detect_url: loginDetect } : {}), + }; + } else { + delete opts["smart_url"]; + } + await deps.repo.updateLayoutCell(cellId, { options: JSON.stringify(opts) } as any); + } + notifyKiosks(); if (isHtmxRequest(event)) { diff --git a/server/src/web-templates/admin-pages.tsx b/server/src/web-templates/admin-pages.tsx index e2ef101..3f32d67 100644 --- a/server/src/web-templates/admin-pages.tsx +++ b/server/src/web-templates/admin-pages.tsx @@ -2316,6 +2316,38 @@ export function renderCell( + {/* Smart URL step builder — shown for web/dashboard cells */} +
+ +
+ Auto-login / navigate sequences. Leave empty for direct URL load. +
+
+ {((c.options?.["smart_url"] as any)?.steps ?? []).map((step: any, idx: number) => ( +
+ + + +
+ ))} +
+ ';document.getElementById('steps-${String(c.id)}').appendChild(d)`} + >+ Add Step +
+ + +
+
+