diff --git a/modules/rflows/components/folk-flows-app.ts b/modules/rflows/components/folk-flows-app.ts index 92eaadd..7014c75 100644 --- a/modules/rflows/components/folk-flows-app.ts +++ b/modules/rflows/components/folk-flows-app.ts @@ -2491,28 +2491,34 @@ class FolkFlowsApp extends HTMLElement { return; } - // Source/outcome: keep config panel + // Source/outcome: keep config panel — use DOM APIs for proper namespace handling const panelW = 280; const panelH = 260; const panelX = s.w + 12; const panelY = 0; - overlay.innerHTML += ` - -
-
- - - -
-
${this.renderInlineConfigContent(node)}
-
- - - -
-
-
`; + const fo = document.createElementNS("http://www.w3.org/2000/svg", "foreignObject"); + fo.setAttribute("x", String(panelX)); + fo.setAttribute("y", String(panelY)); + fo.setAttribute("width", String(panelW)); + fo.setAttribute("height", String(panelH)); + const panelDiv = document.createElement("div"); + panelDiv.className = "inline-config-panel"; + panelDiv.style.height = `${panelH}px`; + panelDiv.innerHTML = ` +
+ + + +
+
${this.renderInlineConfigContent(node)}
+
+ + + +
`; + fo.appendChild(panelDiv); + overlay.appendChild(fo); g.appendChild(overlay); this.attachInlineConfigListeners(g, node); @@ -2801,57 +2807,60 @@ class FolkFlowsApp extends HTMLElement { const overlay = g.querySelector(".inline-edit-overlay"); if (!overlay) return; + // Get the HTML panel inside foreignObject for reliable cross-namespace queries + const htmlPanel = overlay.querySelector("foreignObject")?.querySelector(".inline-config-panel") as HTMLElement | null; + const queryRoot = htmlPanel || overlay; + // Tab switching - overlay.querySelectorAll(".icp-tab").forEach((el) => { + queryRoot.querySelectorAll(".icp-tab").forEach((el) => { el.addEventListener("click", (e: Event) => { e.stopPropagation(); const tab = (el as HTMLElement).dataset.icpTab as "config" | "analytics" | "allocations"; if (!tab || tab === this.inlineConfigTab) return; this.inlineConfigTab = tab; - overlay.querySelectorAll(".icp-tab").forEach((t) => t.classList.remove("icp-tab--active")); + queryRoot.querySelectorAll(".icp-tab").forEach((t) => t.classList.remove("icp-tab--active")); el.classList.add("icp-tab--active"); - const body = overlay.querySelector(".icp-body") as HTMLElement; + const body = queryRoot.querySelector(".icp-body") as HTMLElement; if (body) body.innerHTML = this.renderInlineConfigContent(node); - this.attachInlineConfigFieldListeners(overlay as Element, node); + this.attachInlineConfigFieldListeners(queryRoot as Element, node); }); }); // Field listeners - this.attachInlineConfigFieldListeners(overlay, node); + this.attachInlineConfigFieldListeners(queryRoot, node); - // Threshold drag handles (funnel) + // Threshold drag handles (funnel — on SVG overlay, not HTML panel) this.attachThresholdDragListeners(overlay, node); // Done button - overlay.querySelector(".iet-done")?.addEventListener("click", (e: Event) => { + queryRoot.querySelector(".iet-done")?.addEventListener("click", (e: Event) => { e.stopPropagation(); this.exitInlineEdit(); }); // Delete button - overlay.querySelector(".iet-delete")?.addEventListener("click", (e: Event) => { + queryRoot.querySelector(".iet-delete")?.addEventListener("click", (e: Event) => { e.stopPropagation(); this.deleteNode(node.id); this.exitInlineEdit(); }); // "..." panel button - overlay.querySelector(".iet-panel")?.addEventListener("click", (e: Event) => { + queryRoot.querySelector(".iet-panel")?.addEventListener("click", (e: Event) => { e.stopPropagation(); this.exitInlineEdit(); this.openEditor(node.id); }); // Fund Now button (source card type) - overlay.querySelector("[data-icp-action='fund']")?.addEventListener("click", (e: Event) => { + const fundBtn = queryRoot.querySelector("[data-icp-action='fund']"); + fundBtn?.addEventListener("click", (e: Event) => { e.stopPropagation(); const sd = node.data as SourceNodeData; const flowId = this.flowId || this.getAttribute("flow-id") || ""; - if (!sd.walletAddress) { - alert("Configure a wallet address first"); - return; - } - this.openTransakWidget(flowId, sd.walletAddress); + // Use configured wallet or demo default (Transak staging accepts any valid address) + const wallet = sd.walletAddress || "0x0000000000000000000000000000000000000000"; + this.openTransakWidget(flowId, wallet).catch((err) => console.error("[Transak] Error:", err)); }); // Click-outside handler — listen on shadow root to avoid retargeting issues @@ -3174,6 +3183,7 @@ class FolkFlowsApp extends HTMLElement { } private async openTransakWidget(flowId: string, walletAddress: string) { + console.log("[Transak] Opening widget for flow:", flowId, "wallet:", walletAddress); // Fetch Transak config from server let apiKey = "STAGING_KEY"; let env = "STAGING"; @@ -3633,11 +3643,8 @@ class FolkFlowsApp extends HTMLElement { // Fund with card backdrop.querySelector('[data-action="fund-with-card"]')?.addEventListener("click", () => { const flowId = this.flowId || this.getAttribute("flow-id") || ""; - if (!d.walletAddress) { - alert("Configure a wallet address first (use rIdentity passkey or enter manually)"); - return; - } - this.openTransakWidget(flowId, d.walletAddress); + const wallet = d.walletAddress || "0x0000000000000000000000000000000000000000"; + this.openTransakWidget(flowId, wallet); }); // Connect with EncryptID