diff --git a/.changeset/fn-7369-confirm-other.md b/.changeset/fn-7369-confirm-other.md new file mode 100644 index 0000000000..d7cf313df3 --- /dev/null +++ b/.changeset/fn-7369-confirm-other.md @@ -0,0 +1,7 @@ +--- +"@runfusion/fusion": patch +--- + +summary: Let Planning Mode Yes/No questions accept a custom Other answer. +category: fix +dev: Extends confirm-question handling to preserve user-authored alternatives via `_other`. diff --git a/packages/dashboard/app/components/PlanningModeModal.css b/packages/dashboard/app/components/PlanningModeModal.css index 7f86b2161a..d09d11d632 100644 --- a/packages/dashboard/app/components/PlanningModeModal.css +++ b/packages/dashboard/app/components/PlanningModeModal.css @@ -1033,6 +1033,12 @@ An empty footer must NOT reserve vertical space or paint its divider band. When gap: var(--space-sm); } +.planning-confirm-answer { + display: flex; + flex-direction: column; + gap: var(--space-sm); +} + .planning-confirm-group { display: flex; gap: var(--space-md); @@ -1732,6 +1738,10 @@ Tablet embedded Planning keeps the desktop two-pane shell, so the summary footer } /* Confirm buttons: mobile-friendly sizing */ + .planning-confirm-group { + flex-direction: column; + } + .planning-confirm-btn { min-height: 36px; padding: var(--space-sm) var(--space-md); diff --git a/packages/dashboard/app/components/PlanningModeModal.tsx b/packages/dashboard/app/components/PlanningModeModal.tsx index 8012151ab7..37c3572e63 100644 --- a/packages/dashboard/app/components/PlanningModeModal.tsx +++ b/packages/dashboard/app/components/PlanningModeModal.tsx @@ -2465,7 +2465,14 @@ function QuestionForm({ question: rawQuestion, progress, historyEntries, onSubmi if (question.type === "text") { nextResponse = { [question.id]: textValue }; } else if (question.type === "confirm") { - nextResponse = { [question.id]: response[question.id] === true }; + const trimmedOther = otherValue.trim(); + /* + FNXC:PlanningInterview 2026-07-01-00:00: + GitHub #1832 requires Yes/No Planning Mode questions to offer an Other path so users can replace a forced boolean with their own answer. Reuse the reserved `_other` payload shape used by structured selection questions instead of inventing a confirm-only custom-answer contract. + */ + nextResponse = isOtherSelected && trimmedOther.length > 0 + ? { [PLANNING_OTHER_RESPONSE_KEY]: trimmedOther } + : { [question.id]: response[question.id] === true }; } else if (question.type === "single_select") { const trimmedOther = otherValue.trim(); /* @@ -2522,7 +2529,7 @@ function QuestionForm({ question: rawQuestion, progress, historyEntries, onSubmi */ return (Array.isArray(response[question.id] as unknown) && (response[question.id] as unknown[]).length > 0) || (isOtherSelected && otherValue.trim().length > 0); case "confirm": - return response[question.id] !== undefined; + return response[question.id] !== undefined || (isOtherSelected && otherValue.trim().length > 0); default: return true; } @@ -2687,21 +2694,54 @@ function QuestionForm({ question: rawQuestion, progress, historyEntries, onSubmi )} {question.type === "confirm" && ( -
- - +
+
+ + + +
+ {isOtherSelected && ( +
+