diff --git a/mcp-server/src/state.js b/mcp-server/src/state.js
index 9bba339..3461d7c 100644
--- a/mcp-server/src/state.js
+++ b/mcp-server/src/state.js
@@ -294,8 +294,18 @@ export class FlowState {
// Auto-create connections for conditional branches
if (hs.action === "conditional" && Array.isArray(hs.conditions)) {
hs.conditions.forEach((cond, i) => {
- if (cond.targetScreenId) {
- this._addHotspotConnection(screenId, cond.targetScreenId, hs.id, "navigate", `condition-${i}`);
+ const branchAction = cond.action || "navigate";
+ if ((branchAction === "navigate" || branchAction === "modal") && cond.targetScreenId) {
+ this._addHotspotConnection(screenId, cond.targetScreenId, hs.id, branchAction, `condition-${i}`);
+ }
+ // API success/error follow-up connections
+ if (branchAction === "api") {
+ if (cond.onSuccessTargetId && (cond.onSuccessAction === "navigate" || cond.onSuccessAction === "modal")) {
+ this._addHotspotConnection(screenId, cond.onSuccessTargetId, hs.id, cond.onSuccessAction, `condition-${i}-api-success`);
+ }
+ if (cond.onErrorTargetId && (cond.onErrorAction === "navigate" || cond.onErrorAction === "modal")) {
+ this._addHotspotConnection(screenId, cond.onErrorTargetId, hs.id, cond.onErrorAction, `condition-${i}-api-error`);
+ }
}
});
}
diff --git a/mcp-server/src/tools/hotspot-tools.js b/mcp-server/src/tools/hotspot-tools.js
index d5dfa29..4269be1 100644
--- a/mcp-server/src/tools/hotspot-tools.js
+++ b/mcp-server/src/tools/hotspot-tools.js
@@ -53,11 +53,23 @@ export const hotspotTools = [
items: {
type: "object",
properties: {
- label: { type: "string" },
- targetScreenId: { type: "string" },
+ label: { type: "string", description: "Condition description" },
+ action: {
+ type: "string",
+ enum: ["navigate", "back", "modal", "api", "custom"],
+ description: "Action for this branch (default: navigate)",
+ },
+ targetScreenId: { type: "string", description: "Target screen for navigate/modal" },
+ customDescription: { type: "string", description: "Description for custom action" },
+ apiEndpoint: { type: "string", description: "API endpoint for api action" },
+ apiMethod: { type: "string", enum: ["GET", "POST", "PUT", "DELETE", "PATCH"] },
+ onSuccessAction: { type: "string", enum: ["navigate", "back", "modal", "custom", ""] },
+ onSuccessTargetId: { type: "string" },
+ onErrorAction: { type: "string", enum: ["navigate", "back", "modal", "custom", ""] },
+ onErrorTargetId: { type: "string" },
},
},
- description: "Condition branches for 'conditional' action",
+ description: "Condition branches for 'conditional' action. Each branch can have its own action type.",
},
onSuccessAction: { type: "string", enum: ["navigate", "back", "modal", "custom", ""] },
onSuccessTargetId: { type: "string" },
diff --git a/src/Drawd.jsx b/src/Drawd.jsx
index c0d27bb..821d244 100644
--- a/src/Drawd.jsx
+++ b/src/Drawd.jsx
@@ -275,7 +275,7 @@ export default function Drawd({ initialRoomCode }) {
setConditionalPrompt, setEditingConditionGroup,
setConnectionTypePrompt,
setHotspotModal, setConnectionEditModal,
- quickConnectHotspot, addConnection, addToConditionalGroup,
+ quickConnectHotspot, addConnection, addToConditionalGroup, convertToConditionalGroup,
onStartConnect,
activeTool, captureDragSnapshot,
handleDragStart, handleMultiDragStart,
diff --git a/src/components/HotspotModal.jsx b/src/components/HotspotModal.jsx
index 7760e52..9d18578 100644
--- a/src/components/HotspotModal.jsx
+++ b/src/components/HotspotModal.jsx
@@ -123,9 +123,15 @@ export function HotspotModal({ screen, hotspot, connection, screens, documents =
const [conditions, setConditions] = useState(
hotspot?.conditions?.length > 0
? hotspot.conditions
- : [{ id: generateId(), label: "", targetScreenId: "" }]
+ : [{ id: generateId(), label: "", targetScreenId: "", action: "navigate", dataFlow: [] }]
);
+ const updateCondition = (index, patch) => {
+ const updated = [...conditions];
+ updated[index] = { ...updated[index], ...patch };
+ setConditions(updated);
+ };
+
// Transition (read from associated connection when opened via double-click)
const [transitionType, setTransitionType] = useState(connection?.transitionType || "");
const [transitionLabel, setTransitionLabel] = useState(connection?.transitionLabel || "");
@@ -308,7 +314,15 @@ export function HotspotModal({ screen, hotspot, connection, screens, documents =
dataFlow: (action === "navigate" || action === "modal") ? dataFlow : [],
onSuccessDataFlow: action === "api" ? onSuccessDataFlow : [],
onErrorDataFlow: action === "api" ? onErrorDataFlow : [],
- conditions: action === "conditional" ? conditions : [],
+ conditions: action === "conditional" ? conditions.map((cond) => ({
+ ...cond,
+ action: cond.action || "navigate",
+ targetScreenId: (cond.action === "navigate" || cond.action === "modal" || !cond.action)
+ ? (cond.targetScreenId || "") : "",
+ customDescription: cond.action === "custom" ? (cond.customDescription || "") : "",
+ dataFlow: (cond.action === "navigate" || cond.action === "modal" || !cond.action)
+ ? (cond.dataFlow || []) : [],
+ })) : [],
x, y, w, h,
transitionType,
transitionLabel: transitionType === "custom" ? transitionLabel : "",
@@ -403,76 +417,171 @@ export function HotspotModal({ screen, hotspot, connection, screens, documents =
{conditions.map((cond, i) => (
-
-
+
+
-
{conditions.length > 1 && (
-
+ style={{ background: "none", border: "none", color: COLORS.danger, cursor: "pointer", fontSize: 16, padding: "6px", marginBottom: 6 }}
+ >✕
)}
-
- {
- const updated = [...conditions];
- updated[i] = { ...updated[i], dataFlow: newDataFlow };
- setConditions(updated);
- }}
- />
-
+
+
+
+ {(cond.action === "navigate" || cond.action === "modal" || !cond.action) && (
+ <>
+
+
+ updateCondition(i, { dataFlow: val })}
+ />
+
+ >
+ )}
+
+ {cond.action === "custom" && (
+
+ )}
+
+ {(cond.action === "api") && (
+
+
+
+
+
+
+
+ {documents.length > 0 && (
+
+ )}
+
updateCondition(i, { onSuccessAction: val })}
+ targetId={cond.onSuccessTargetId || ""}
+ setTargetId={(val) => updateCondition(i, { onSuccessTargetId: val })}
+ customDesc={cond.onSuccessCustomDesc || ""}
+ setCustomDesc={(val) => updateCondition(i, { onSuccessCustomDesc: val })}
+ otherScreens={otherScreens}
+ dataFlow={cond.onSuccessDataFlow || []}
+ onDataFlowChange={(val) => updateCondition(i, { onSuccessDataFlow: val })}
+ />
+ updateCondition(i, { onErrorAction: val })}
+ targetId={cond.onErrorTargetId || ""}
+ setTargetId={(val) => updateCondition(i, { onErrorTargetId: val })}
+ customDesc={cond.onErrorCustomDesc || ""}
+ setCustomDesc={(val) => updateCondition(i, { onErrorCustomDesc: val })}
+ otherScreens={otherScreens}
+ dataFlow={cond.onErrorDataFlow || []}
+ onDataFlowChange={(val) => updateCondition(i, { onErrorDataFlow: val })}
+ />
+
+ )}
))}