Merge PR #8786: fix(collab-web): render the user-added note in ask tool cards (@Liangzhi233)

This commit is contained in:
can1357
2026-08-19 01:36:58 +02:00
3 changed files with 74 additions and 0 deletions
+4
View File
@@ -2,6 +2,10 @@
## [Unreleased]
### Fixed
- The ask tool card now renders the note the user attached to their answer; previously it was dropped from HTML exports and the collab guest view.
## [17.2.10] - 2026-08-06
### Changed
@@ -22,6 +22,8 @@ interface AskAnswer {
id?: string;
selectedOptions: string[];
customInput?: string;
/** Free-form note the user attached to the answer via the rich ask dialog. */
note?: string;
timedOut?: boolean;
}
@@ -106,6 +108,7 @@ function answerOf(rec: Record<string, unknown>): AskAnswer {
id: str(rec.id) ?? undefined,
selectedOptions,
customInput: str(rec.customInput) ?? undefined,
note: str(rec.note) ?? undefined,
timedOut: rec.timedOut === true,
};
}
@@ -187,6 +190,11 @@ function QuestionBlock({ q, answer }: { q: AskQuestion; answer: AskAnswer | unde
<span className="tv-ok-text">{answer.customInput}</span>
</Row>
)}
{answer?.note !== undefined && (
<Row k="note:">
<span className="tv-muted">{answer.note}</span>
</Row>
)}
{answer && answer.selectedOptions.length === 0 && answer.customInput === undefined && (
<Row k="—">
<span className="tv-warn-text">no selection</span>
@@ -152,3 +152,65 @@ describe("ToolView xd:// dispatches", () => {
expect(html).not.toContain("tv-out-title");
});
});
describe("ToolView ask renderer", () => {
const questions = [
{
id: "auth",
question: "Which auth method?",
options: [{ label: "JWT" }, { label: "OAuth2" }],
},
];
it("renders the user-added note from a single-question answer", () => {
const html = renderToStaticMarkup(
<ToolView
name="ask"
defaultOpen
args={{ questions }}
result={{
content: [{ type: "text", text: "OAuth2 User added note: keep the redirect short-lived" }],
details: {
question: "Which auth method?",
options: ["JWT", "OAuth2"],
multi: false,
selectedOptions: ["OAuth2"],
note: "keep the redirect short-lived",
},
}}
/>,
);
expect(html).toContain('<span>OAuth2</span>');
expect(html).toContain("keep the redirect short-lived");
});
it("renders per-question notes from results[] answers", () => {
const html = renderToStaticMarkup(
<ToolView
name="ask"
defaultOpen
args={{
questions: [
{ id: "db", question: "Storage backend?", options: [{ label: "SQLite" }, { label: "Postgres" }] },
{ id: "cache", question: "Cache?", options: [{ label: "Redis" }, { label: "None" }] },
],
}}
result={{
content: [{ type: "text", text: "User answers:" }],
details: {
results: [
{ id: "db", question: "Storage backend?", multi: false, selectedOptions: ["Postgres"], note: "managed instance" },
{ id: "cache", question: "Cache?", multi: false, selectedOptions: ["Redis"] },
],
},
}}
/>,
);
expect(html).toContain('<span>Postgres</span>');
expect(html).toContain("managed instance");
// The cache question answered without a note must not leak the db note.
expect(html.match(/managed instance/g)?.length).toBe(1);
});
});