/**
* A questionnaire, as the decisions pane shows it.
*
* The definition is immutable and the answer is owned by the server's record,
* so this never writes to the document — an agent rewriting the plan cannot
* overwrite a decision. What the plan node carries is a projection, kept so
* the source reads correctly on its own.
*/
import { QuestionView, useQuestionnaire } from "@chopin/question/react";
import type { Transport } from "@chopin/question/react";
import type { Answer } from "@chopin/question";
import type { Questionnaire, QuestionnaireNode } from "@chopin/dialect";
/** The plan stores the chosen text; the shared view wants answer records. */
function answers(value: Questionnaire): Answer[] | undefined {
if (value.questions.some(question => question.answer === undefined)) return undefined;
return value.questions.map(question => ({
question: question.prompt,
custom: question.answer ?? "",
}));
}
/** The document calls the question text `prompt`; the domain calls it `question`. */
function definition(value: Questionnaire) {
return {
questions: value.questions.map(question => ({
id: question.id,
header: question.header,
question: question.prompt,
multiple: question.multiple,
options: question.options.map(option => ({
id: option.id,
label: option.label,
description: option.description ?? "",
})),
})),
};
}
export type Relation = "subject" | "result";
export type QuestionnaireCardProps = {
value: Questionnaire;
wire?: Transport;
connected?: boolean;
/** How much prose each question and answer resolves to. */
relations?: { [question: string]: { subject: number; result: number } };
onRelationEnter?: (question: string, relation: Relation) => void;
onRelationLeave?: (question: string, relation: Relation) => void;
};
export function QuestionnaireCard(
{ connected = false, onRelationEnter, onRelationLeave, relations, value, wire }:
QuestionnaireCardProps,
) {
let resolved = answers(value);
let pointing = { relations, onRelationEnter, onRelationLeave };
return resolved
?