@xinghunm/ai-chat 1.0.1 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +39 -7
- package/dist/index.d.ts +39 -7
- package/dist/index.js +605 -217
- package/dist/index.mjs +625 -233
- package/package.json +2 -2
package/dist/index.mjs
CHANGED
|
@@ -42,7 +42,10 @@ var DEFAULT_AI_CHAT_LABELS = {
|
|
|
42
42
|
questionnaireSubmitting: "Submitting...",
|
|
43
43
|
questionnaireSubmitted: "Selection submitted. Waiting for the plan to continue...",
|
|
44
44
|
questionnaireValidationPrefix: "Please complete:",
|
|
45
|
-
questionnaireSubmitFailed: "Failed to submit. Please try again."
|
|
45
|
+
questionnaireSubmitFailed: "Failed to submit. Please try again.",
|
|
46
|
+
questionnaireMultiSelectHint: "Multiple choice",
|
|
47
|
+
questionnaireOtherOptionLabel: "Other",
|
|
48
|
+
questionnaireOtherPlaceholder: "Other"
|
|
46
49
|
};
|
|
47
50
|
|
|
48
51
|
// src/store/chat-store.ts
|
|
@@ -77,6 +80,22 @@ var mergeStreamingBlocks = (existingBlocks, incomingBlocks) => {
|
|
|
77
80
|
nextBlocks.push(incomingBlock);
|
|
78
81
|
return;
|
|
79
82
|
}
|
|
83
|
+
if (incomingBlock.type === "questionnaire" && incomingBlock.questionnaire.blockKey) {
|
|
84
|
+
const mergePolicy = incomingBlock.questionnaire.mergePolicy ?? "append";
|
|
85
|
+
if (mergePolicy !== "append") {
|
|
86
|
+
const existingIndex2 = nextBlocks.findIndex(
|
|
87
|
+
(block) => block.type === "questionnaire" && block.questionnaire.blockKey === incomingBlock.questionnaire.blockKey
|
|
88
|
+
);
|
|
89
|
+
if (existingIndex2 !== -1) {
|
|
90
|
+
if (mergePolicy === "replace") {
|
|
91
|
+
nextBlocks[existingIndex2] = incomingBlock;
|
|
92
|
+
}
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
nextBlocks.push(incomingBlock);
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
80
99
|
if (incomingBlock.type !== "questionnaire") {
|
|
81
100
|
nextBlocks.push(incomingBlock);
|
|
82
101
|
return;
|
|
@@ -679,7 +698,7 @@ var AiChatProvider = (props) => {
|
|
|
679
698
|
};
|
|
680
699
|
|
|
681
700
|
// src/components/chat-thread/index.tsx
|
|
682
|
-
import { useCallback as useCallback3, useLayoutEffect as useLayoutEffect2, useMemo as useMemo4, useRef as
|
|
701
|
+
import { useCallback as useCallback3, useLayoutEffect as useLayoutEffect2, useMemo as useMemo4, useRef as useRef5, useState as useState4 } from "react";
|
|
683
702
|
import styled9 from "@emotion/styled";
|
|
684
703
|
|
|
685
704
|
// src/context/use-chat-context.ts
|
|
@@ -977,7 +996,7 @@ var getTimelineBlockKey = (block, index) => {
|
|
|
977
996
|
case "result_summary":
|
|
978
997
|
return `${index}:result_summary:${block.summary.summaryId}:${block.summary.status}`;
|
|
979
998
|
case "questionnaire":
|
|
980
|
-
return `${index}:questionnaire:${block.questionnaire.questionnaireId}`;
|
|
999
|
+
return block.questionnaire.blockKey ? `questionnaire:${block.questionnaire.blockKey}` : `${index}:questionnaire:${block.questionnaire.questionnaireId}`;
|
|
981
1000
|
case "custom":
|
|
982
1001
|
return block.blockKey ? `custom:${block.blockKey}` : `${index}:custom:${block.kind}:${stringifyTimelineKeyPart(block.data)}`;
|
|
983
1002
|
default:
|
|
@@ -1469,31 +1488,126 @@ var Value = styled3.span`
|
|
|
1469
1488
|
`;
|
|
1470
1489
|
|
|
1471
1490
|
// src/components/chat-thread/components/questionnaire-card.tsx
|
|
1472
|
-
import {
|
|
1491
|
+
import {
|
|
1492
|
+
useEffect as useEffect3,
|
|
1493
|
+
useRef as useRef3,
|
|
1494
|
+
useState as useState2
|
|
1495
|
+
} from "react";
|
|
1473
1496
|
import styled4 from "@emotion/styled";
|
|
1474
|
-
import {
|
|
1497
|
+
import { InputField } from "@xinghunm/compass-ui";
|
|
1498
|
+
|
|
1499
|
+
// src/components/chat-thread/components/questionnaire-card-helpers.ts
|
|
1475
1500
|
var OTHER_OPTION_VALUE = "__other__";
|
|
1476
|
-
var
|
|
1477
|
-
submitting: "Submitting...",
|
|
1478
|
-
submitted: "Selection submitted. Waiting for the plan to continue...",
|
|
1479
|
-
validationPrefix: "Please complete:",
|
|
1480
|
-
submitFailed: "Failed to submit. Please try again."
|
|
1481
|
-
};
|
|
1482
|
-
var createInitialAnswers = (questionnaire) => ({
|
|
1483
|
-
...questionnaire.answers ?? {}
|
|
1484
|
-
});
|
|
1501
|
+
var getQuestionnaireQuestion = (questionnaire) => questionnaire.question;
|
|
1485
1502
|
var getMultiSelectAnswerValues = (answer) => Array.isArray(answer) ? answer : [];
|
|
1486
|
-
var
|
|
1503
|
+
var getQuestionOptionValues = (question) => new Set(question.options.map((option) => option.value));
|
|
1504
|
+
var extractSingleSelectOtherDraft = (question, answer) => {
|
|
1505
|
+
if (typeof answer !== "string") {
|
|
1506
|
+
return "";
|
|
1507
|
+
}
|
|
1508
|
+
return getQuestionOptionValues(question).has(answer) ? "" : answer;
|
|
1509
|
+
};
|
|
1510
|
+
var extractMultiSelectOtherDraft = (question, answer) => {
|
|
1511
|
+
if (!Array.isArray(answer)) {
|
|
1512
|
+
return "";
|
|
1513
|
+
}
|
|
1514
|
+
const optionValues = getQuestionOptionValues(question);
|
|
1515
|
+
const customValue = answer.find(
|
|
1516
|
+
(value) => typeof value === "string" && value !== OTHER_OPTION_VALUE && !optionValues.has(value)
|
|
1517
|
+
);
|
|
1518
|
+
return typeof customValue === "string" ? customValue : "";
|
|
1519
|
+
};
|
|
1520
|
+
var createInitialAnswers = (questionnaire) => {
|
|
1521
|
+
const initialAnswers = {};
|
|
1522
|
+
const question = getQuestionnaireQuestion(questionnaire);
|
|
1523
|
+
if (!question) {
|
|
1524
|
+
return initialAnswers;
|
|
1525
|
+
}
|
|
1526
|
+
const answer = questionnaire.answers?.[question.id];
|
|
1527
|
+
switch (question.kind) {
|
|
1528
|
+
case "single_select": {
|
|
1529
|
+
if (typeof answer !== "string") {
|
|
1530
|
+
break;
|
|
1531
|
+
}
|
|
1532
|
+
if (getQuestionOptionValues(question).has(answer)) {
|
|
1533
|
+
initialAnswers[question.id] = answer;
|
|
1534
|
+
break;
|
|
1535
|
+
}
|
|
1536
|
+
if (question.allowOther) {
|
|
1537
|
+
initialAnswers[question.id] = OTHER_OPTION_VALUE;
|
|
1538
|
+
}
|
|
1539
|
+
break;
|
|
1540
|
+
}
|
|
1541
|
+
case "multi_select": {
|
|
1542
|
+
if (!Array.isArray(answer)) {
|
|
1543
|
+
break;
|
|
1544
|
+
}
|
|
1545
|
+
const optionValues = getQuestionOptionValues(question);
|
|
1546
|
+
const selectedValues = [];
|
|
1547
|
+
let hasOtherValue = false;
|
|
1548
|
+
for (const value of answer) {
|
|
1549
|
+
if (typeof value !== "string") {
|
|
1550
|
+
continue;
|
|
1551
|
+
}
|
|
1552
|
+
if (optionValues.has(value)) {
|
|
1553
|
+
selectedValues.push(value);
|
|
1554
|
+
continue;
|
|
1555
|
+
}
|
|
1556
|
+
if (question.allowOther && !hasOtherValue) {
|
|
1557
|
+
selectedValues.push(OTHER_OPTION_VALUE);
|
|
1558
|
+
hasOtherValue = true;
|
|
1559
|
+
}
|
|
1560
|
+
}
|
|
1561
|
+
initialAnswers[question.id] = selectedValues;
|
|
1562
|
+
break;
|
|
1563
|
+
}
|
|
1564
|
+
default:
|
|
1565
|
+
initialAnswers[question.id] = answer;
|
|
1566
|
+
}
|
|
1567
|
+
return initialAnswers;
|
|
1568
|
+
};
|
|
1569
|
+
var createInitialOtherDrafts = (questionnaire) => {
|
|
1570
|
+
const drafts = {};
|
|
1571
|
+
const question = getQuestionnaireQuestion(questionnaire);
|
|
1572
|
+
if (!question) {
|
|
1573
|
+
return drafts;
|
|
1574
|
+
}
|
|
1575
|
+
const answer = questionnaire.answers?.[question.id];
|
|
1576
|
+
switch (question.kind) {
|
|
1577
|
+
case "single_select":
|
|
1578
|
+
if (question.allowOther) {
|
|
1579
|
+
drafts[question.id] = extractSingleSelectOtherDraft(question, answer);
|
|
1580
|
+
}
|
|
1581
|
+
break;
|
|
1582
|
+
case "multi_select":
|
|
1583
|
+
if (question.allowOther) {
|
|
1584
|
+
drafts[question.id] = extractMultiSelectOtherDraft(question, answer);
|
|
1585
|
+
}
|
|
1586
|
+
break;
|
|
1587
|
+
default:
|
|
1588
|
+
break;
|
|
1589
|
+
}
|
|
1590
|
+
return drafts;
|
|
1591
|
+
};
|
|
1592
|
+
var getMultiSelectDraftState = (question, answer, otherDraft) => {
|
|
1593
|
+
const answerValues = getMultiSelectAnswerValues(answer);
|
|
1594
|
+
return {
|
|
1595
|
+
selectedValues: answerValues,
|
|
1596
|
+
otherValue: otherDraft,
|
|
1597
|
+
hasOtherSelected: question.allowOther === true && answerValues.includes(OTHER_OPTION_VALUE)
|
|
1598
|
+
};
|
|
1599
|
+
};
|
|
1600
|
+
var getSingleSelectDraftState = (question, answer, otherDraft) => {
|
|
1487
1601
|
if (typeof answer !== "string") {
|
|
1488
1602
|
return {
|
|
1489
1603
|
selectedValue: void 0,
|
|
1490
|
-
otherValue:
|
|
1604
|
+
otherValue: otherDraft
|
|
1491
1605
|
};
|
|
1492
1606
|
}
|
|
1493
|
-
const matchesOption = question.options.some((option) => option.value === answer);
|
|
1607
|
+
const matchesOption = answer !== OTHER_OPTION_VALUE && question.options.some((option) => option.value === answer);
|
|
1494
1608
|
return {
|
|
1495
1609
|
selectedValue: matchesOption ? answer : question.allowOther ? OTHER_OPTION_VALUE : void 0,
|
|
1496
|
-
otherValue:
|
|
1610
|
+
otherValue: otherDraft
|
|
1497
1611
|
};
|
|
1498
1612
|
};
|
|
1499
1613
|
var updateAnswerValue = (current, questionId, value) => ({
|
|
@@ -1505,6 +1619,17 @@ var toggleMultiSelectAnswer = (current, questionId, optionValue) => {
|
|
|
1505
1619
|
const nextValues = currentValues.includes(optionValue) ? currentValues.filter((value) => value !== optionValue) : [...currentValues, optionValue];
|
|
1506
1620
|
return updateAnswerValue(current, questionId, nextValues);
|
|
1507
1621
|
};
|
|
1622
|
+
var toggleMultiSelectOtherAnswer = (current, question) => {
|
|
1623
|
+
const currentValues = getMultiSelectAnswerValues(current[question.id]);
|
|
1624
|
+
if (currentValues.includes(OTHER_OPTION_VALUE)) {
|
|
1625
|
+
return updateAnswerValue(
|
|
1626
|
+
current,
|
|
1627
|
+
question.id,
|
|
1628
|
+
currentValues.filter((value) => value !== OTHER_OPTION_VALUE)
|
|
1629
|
+
);
|
|
1630
|
+
}
|
|
1631
|
+
return updateAnswerValue(current, question.id, [...currentValues, OTHER_OPTION_VALUE]);
|
|
1632
|
+
};
|
|
1508
1633
|
var getTextInputValue = (answer) => typeof answer === "string" ? String(answer) : "";
|
|
1509
1634
|
var getNumberInputValue = (answer) => typeof answer === "number" || typeof answer === "string" ? String(answer) : "";
|
|
1510
1635
|
var getOptionChoiceLabel = (index) => {
|
|
@@ -1513,20 +1638,49 @@ var getOptionChoiceLabel = (index) => {
|
|
|
1513
1638
|
}
|
|
1514
1639
|
return String(index + 1);
|
|
1515
1640
|
};
|
|
1516
|
-
var
|
|
1517
|
-
|
|
1641
|
+
var normalizeQuestionAnswer = (question, answer, otherDraft = "") => {
|
|
1642
|
+
if (answer === void 0) {
|
|
1643
|
+
return void 0;
|
|
1644
|
+
}
|
|
1518
1645
|
switch (question.kind) {
|
|
1519
|
-
case "boolean":
|
|
1520
|
-
return typeof answer !== "boolean";
|
|
1521
1646
|
case "multi_select":
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1647
|
+
if (!Array.isArray(answer)) {
|
|
1648
|
+
return void 0;
|
|
1649
|
+
}
|
|
1650
|
+
return (() => {
|
|
1651
|
+
const optionValues = getQuestionOptionValues(question);
|
|
1652
|
+
const normalizedOtherDraft = otherDraft.trim();
|
|
1653
|
+
const normalizedValues = answer.flatMap((value) => {
|
|
1654
|
+
if (typeof value !== "string") {
|
|
1655
|
+
return [];
|
|
1656
|
+
}
|
|
1657
|
+
if (optionValues.has(value)) {
|
|
1658
|
+
return [value];
|
|
1659
|
+
}
|
|
1660
|
+
if (!question.allowOther || value !== OTHER_OPTION_VALUE) {
|
|
1661
|
+
return [];
|
|
1662
|
+
}
|
|
1663
|
+
return normalizedOtherDraft === "" ? [] : [normalizedOtherDraft];
|
|
1664
|
+
});
|
|
1665
|
+
return normalizedValues.length > 0 ? normalizedValues : void 0;
|
|
1666
|
+
})();
|
|
1526
1667
|
case "single_select":
|
|
1527
|
-
|
|
1668
|
+
if (answer === OTHER_OPTION_VALUE) {
|
|
1669
|
+
const normalizedOtherDraft = otherDraft.trim();
|
|
1670
|
+
return normalizedOtherDraft === "" ? void 0 : normalizedOtherDraft;
|
|
1671
|
+
}
|
|
1672
|
+
if (typeof answer !== "string" || answer.trim() === "") {
|
|
1673
|
+
return void 0;
|
|
1674
|
+
}
|
|
1675
|
+
return getQuestionOptionValues(question).has(answer) ? answer : void 0;
|
|
1676
|
+
case "text":
|
|
1677
|
+
return typeof answer === "string" && answer.trim() !== "" ? answer : void 0;
|
|
1678
|
+
case "number":
|
|
1679
|
+
return typeof answer === "number" && !Number.isNaN(answer) ? answer : void 0;
|
|
1680
|
+
case "boolean":
|
|
1681
|
+
return typeof answer === "boolean" ? answer : void 0;
|
|
1528
1682
|
default:
|
|
1529
|
-
return
|
|
1683
|
+
return answer;
|
|
1530
1684
|
}
|
|
1531
1685
|
};
|
|
1532
1686
|
var formatQuestionAnswer = (question, answer) => {
|
|
@@ -1554,79 +1708,221 @@ var formatQuestionAnswer = (question, answer) => {
|
|
|
1554
1708
|
return String(answer);
|
|
1555
1709
|
}
|
|
1556
1710
|
};
|
|
1557
|
-
var
|
|
1711
|
+
var buildQuestionSubmissionDetail = (question, answer) => {
|
|
1558
1712
|
if (answer === void 0) {
|
|
1559
1713
|
return void 0;
|
|
1560
1714
|
}
|
|
1561
1715
|
switch (question.kind) {
|
|
1562
|
-
case "
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
return
|
|
1569
|
-
|
|
1570
|
-
|
|
1716
|
+
case "single_select": {
|
|
1717
|
+
if (typeof answer !== "string") {
|
|
1718
|
+
return void 0;
|
|
1719
|
+
}
|
|
1720
|
+
const optionValues = getQuestionOptionValues(question);
|
|
1721
|
+
const trimmedAnswer = answer.trim();
|
|
1722
|
+
return {
|
|
1723
|
+
questionId: question.id,
|
|
1724
|
+
kind: question.kind,
|
|
1725
|
+
value: answer,
|
|
1726
|
+
selectedOptionValues: optionValues.has(answer) ? [answer] : [],
|
|
1727
|
+
otherValue: optionValues.has(answer) || trimmedAnswer === "" ? void 0 : trimmedAnswer
|
|
1728
|
+
};
|
|
1729
|
+
}
|
|
1730
|
+
case "multi_select": {
|
|
1731
|
+
if (!Array.isArray(answer)) {
|
|
1732
|
+
return void 0;
|
|
1733
|
+
}
|
|
1734
|
+
const optionValues = getQuestionOptionValues(question);
|
|
1735
|
+
const selectedOptionValues = answer.filter(
|
|
1736
|
+
(value) => typeof value === "string" && optionValues.has(value)
|
|
1737
|
+
);
|
|
1738
|
+
const otherValue = answer.find(
|
|
1739
|
+
(value) => typeof value === "string" && !optionValues.has(value)
|
|
1740
|
+
);
|
|
1741
|
+
return {
|
|
1742
|
+
questionId: question.id,
|
|
1743
|
+
kind: question.kind,
|
|
1744
|
+
value: answer,
|
|
1745
|
+
selectedOptionValues,
|
|
1746
|
+
otherValue: otherValue?.trim() ? otherValue.trim() : void 0
|
|
1747
|
+
};
|
|
1748
|
+
}
|
|
1571
1749
|
default:
|
|
1572
|
-
return
|
|
1750
|
+
return {
|
|
1751
|
+
questionId: question.id,
|
|
1752
|
+
kind: question.kind,
|
|
1753
|
+
value: answer
|
|
1754
|
+
};
|
|
1755
|
+
}
|
|
1756
|
+
};
|
|
1757
|
+
var getMissingRequiredQuestions = (questionnaire, answers, otherDrafts) => {
|
|
1758
|
+
const question = getQuestionnaireQuestion(questionnaire);
|
|
1759
|
+
if (!question || !question.required) {
|
|
1760
|
+
return [];
|
|
1573
1761
|
}
|
|
1762
|
+
return normalizeQuestionAnswer(question, answers[question.id], otherDrafts[question.id]) === void 0 ? [question] : [];
|
|
1763
|
+
};
|
|
1764
|
+
var prepareQuestionnaireSubmission = (questionnaire, answers, otherDrafts) => {
|
|
1765
|
+
const question = getQuestionnaireQuestion(questionnaire);
|
|
1766
|
+
if (!question) {
|
|
1767
|
+
return {
|
|
1768
|
+
normalizedAnswers: {},
|
|
1769
|
+
submissionDetails: void 0,
|
|
1770
|
+
content: questionnaire.title ?? "Questionnaire responses"
|
|
1771
|
+
};
|
|
1772
|
+
}
|
|
1773
|
+
const value = normalizeQuestionAnswer(question, answers[question.id], otherDrafts[question.id]);
|
|
1774
|
+
const normalizedAnswers = value === void 0 ? {} : { [question.id]: value };
|
|
1775
|
+
const detail = buildQuestionSubmissionDetail(question, normalizedAnswers[question.id]);
|
|
1776
|
+
const submissionDetails = detail === void 0 ? void 0 : { [question.id]: detail };
|
|
1777
|
+
return {
|
|
1778
|
+
normalizedAnswers,
|
|
1779
|
+
submissionDetails,
|
|
1780
|
+
content: [
|
|
1781
|
+
questionnaire.title ?? "Questionnaire responses",
|
|
1782
|
+
...normalizedAnswers[question.id] === void 0 ? [] : [
|
|
1783
|
+
`- ${question.label}: ${formatQuestionAnswer(question, normalizedAnswers[question.id])}`
|
|
1784
|
+
]
|
|
1785
|
+
].join("\n")
|
|
1786
|
+
};
|
|
1787
|
+
};
|
|
1788
|
+
var getQuestionnaireStateKey = (questionnaire) => JSON.stringify([
|
|
1789
|
+
questionnaire.questionnaireId,
|
|
1790
|
+
questionnaire.blockKey,
|
|
1791
|
+
questionnaire.question,
|
|
1792
|
+
questionnaire.status,
|
|
1793
|
+
questionnaire.statusMessage
|
|
1794
|
+
]);
|
|
1795
|
+
|
|
1796
|
+
// src/components/chat-thread/components/questionnaire-card.tsx
|
|
1797
|
+
import { jsx as jsx5, jsxs as jsxs3 } from "@emotion/react/jsx-runtime";
|
|
1798
|
+
var DEFAULT_QUESTIONNAIRE_CARD_LABELS = {
|
|
1799
|
+
submitting: "Submitting...",
|
|
1800
|
+
submitted: "Selection submitted. Waiting for the plan to continue...",
|
|
1801
|
+
validationPrefix: "Please complete:",
|
|
1802
|
+
submitFailed: "Failed to submit. Please try again.",
|
|
1803
|
+
multiSelectHint: "Multiple choice",
|
|
1804
|
+
otherOptionLabel: "Other",
|
|
1805
|
+
otherPlaceholder: "Other"
|
|
1806
|
+
};
|
|
1807
|
+
var stopInputClickPropagation = (event) => {
|
|
1808
|
+
event.stopPropagation();
|
|
1574
1809
|
};
|
|
1810
|
+
var stopInputKeyPropagation = (event) => {
|
|
1811
|
+
event.stopPropagation();
|
|
1812
|
+
};
|
|
1813
|
+
var OptionChoice = ({
|
|
1814
|
+
questionId,
|
|
1815
|
+
optionLabel,
|
|
1816
|
+
index,
|
|
1817
|
+
isSelected,
|
|
1818
|
+
isInteractionLocked,
|
|
1819
|
+
onClick,
|
|
1820
|
+
inlineInput,
|
|
1821
|
+
tone = "default"
|
|
1822
|
+
}) => /* @__PURE__ */ jsxs3(
|
|
1823
|
+
OptionChoiceItem,
|
|
1824
|
+
{
|
|
1825
|
+
role: "button",
|
|
1826
|
+
tabIndex: isInteractionLocked ? -1 : 0,
|
|
1827
|
+
"aria-pressed": isSelected,
|
|
1828
|
+
"data-selected": isSelected,
|
|
1829
|
+
"data-tone": tone,
|
|
1830
|
+
"data-testid": `question-option-${questionId}-${index}`,
|
|
1831
|
+
onClick: (event) => {
|
|
1832
|
+
if (isInteractionLocked) {
|
|
1833
|
+
return;
|
|
1834
|
+
}
|
|
1835
|
+
if (event.target instanceof HTMLElement && event.target.closest("input")) {
|
|
1836
|
+
return;
|
|
1837
|
+
}
|
|
1838
|
+
onClick();
|
|
1839
|
+
},
|
|
1840
|
+
onKeyDown: (event) => {
|
|
1841
|
+
if (isInteractionLocked) {
|
|
1842
|
+
return;
|
|
1843
|
+
}
|
|
1844
|
+
if (event.key !== "Enter" && event.key !== " ") {
|
|
1845
|
+
return;
|
|
1846
|
+
}
|
|
1847
|
+
event.preventDefault();
|
|
1848
|
+
onClick();
|
|
1849
|
+
},
|
|
1850
|
+
children: [
|
|
1851
|
+
/* @__PURE__ */ jsx5(OptionChoiceMarker, { "data-selected": isSelected, children: getOptionChoiceLabel(index) }),
|
|
1852
|
+
/* @__PURE__ */ jsxs3(OptionChoiceContent, { children: [
|
|
1853
|
+
inlineInput ? null : /* @__PURE__ */ jsx5(OptionChoiceLabel, { children: optionLabel }),
|
|
1854
|
+
inlineInput
|
|
1855
|
+
] })
|
|
1856
|
+
]
|
|
1857
|
+
}
|
|
1858
|
+
);
|
|
1575
1859
|
var QuestionnaireCardInner = ({
|
|
1576
1860
|
questionnaire,
|
|
1577
1861
|
interactive = false,
|
|
1578
1862
|
onSubmit,
|
|
1579
1863
|
labels
|
|
1580
1864
|
}) => {
|
|
1865
|
+
const questionnaireRef = useRef3(questionnaire);
|
|
1866
|
+
const otherInputRefs = useRef3({});
|
|
1581
1867
|
const [answers, setAnswers] = useState2(
|
|
1582
1868
|
() => createInitialAnswers(questionnaire)
|
|
1583
1869
|
);
|
|
1870
|
+
const [otherDrafts, setOtherDrafts] = useState2(
|
|
1871
|
+
() => createInitialOtherDrafts(questionnaire)
|
|
1872
|
+
);
|
|
1584
1873
|
const [errorMessage, setErrorMessage] = useState2(null);
|
|
1585
1874
|
const [isSubmitting, setIsSubmitting] = useState2(false);
|
|
1586
1875
|
const [isSubmitted, setIsSubmitted] = useState2(false);
|
|
1876
|
+
const [pendingFocusQuestionId, setPendingFocusQuestionId] = useState2(null);
|
|
1587
1877
|
const resolvedLabels = {
|
|
1588
1878
|
...DEFAULT_QUESTIONNAIRE_CARD_LABELS,
|
|
1589
1879
|
...labels
|
|
1590
1880
|
};
|
|
1591
1881
|
const hasExternalFailureStatus = questionnaire.status === "expired" || questionnaire.status === "failed";
|
|
1882
|
+
const question = getQuestionnaireQuestion(questionnaire);
|
|
1592
1883
|
const visibleErrorMessage = questionnaire.statusMessage ?? errorMessage;
|
|
1593
1884
|
const isInteractionLocked = !interactive || isSubmitting || isSubmitted || hasExternalFailureStatus;
|
|
1885
|
+
questionnaireRef.current = questionnaire;
|
|
1886
|
+
useEffect3(() => {
|
|
1887
|
+
setAnswers(createInitialAnswers(questionnaireRef.current));
|
|
1888
|
+
setOtherDrafts(createInitialOtherDrafts(questionnaireRef.current));
|
|
1889
|
+
}, [questionnaire.answers]);
|
|
1890
|
+
useEffect3(() => {
|
|
1891
|
+
if (!pendingFocusQuestionId || isInteractionLocked) {
|
|
1892
|
+
return;
|
|
1893
|
+
}
|
|
1894
|
+
const inputElement = otherInputRefs.current[pendingFocusQuestionId];
|
|
1895
|
+
if (!inputElement) {
|
|
1896
|
+
return;
|
|
1897
|
+
}
|
|
1898
|
+
inputElement.focus();
|
|
1899
|
+
setPendingFocusQuestionId(null);
|
|
1900
|
+
}, [isInteractionLocked, pendingFocusQuestionId]);
|
|
1594
1901
|
const handleSubmit = async () => {
|
|
1595
1902
|
if (isSubmitting || isSubmitted) {
|
|
1596
1903
|
return;
|
|
1597
1904
|
}
|
|
1598
|
-
const missingQuestions = questionnaire
|
|
1599
|
-
(question) => question.required && isMissingRequiredAnswer(question, answers)
|
|
1600
|
-
);
|
|
1905
|
+
const missingQuestions = getMissingRequiredQuestions(questionnaire, answers, otherDrafts);
|
|
1601
1906
|
if (missingQuestions.length > 0) {
|
|
1602
1907
|
setErrorMessage(
|
|
1603
|
-
`${resolvedLabels.validationPrefix} ${missingQuestions.map((
|
|
1908
|
+
`${resolvedLabels.validationPrefix} ${missingQuestions.map((question2) => question2.label).join(", ")}`
|
|
1604
1909
|
);
|
|
1605
1910
|
return;
|
|
1606
1911
|
}
|
|
1607
1912
|
setErrorMessage(null);
|
|
1608
1913
|
setIsSubmitting(true);
|
|
1609
|
-
const normalizedAnswers =
|
|
1610
|
-
questionnaire
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
})
|
|
1914
|
+
const { normalizedAnswers, submissionDetails, content } = prepareQuestionnaireSubmission(
|
|
1915
|
+
questionnaire,
|
|
1916
|
+
answers,
|
|
1917
|
+
otherDrafts
|
|
1614
1918
|
);
|
|
1615
|
-
const contentLines = [
|
|
1616
|
-
questionnaire.title ?? "Questionnaire responses",
|
|
1617
|
-
...questionnaire.questions.flatMap((question) => {
|
|
1618
|
-
const value = normalizedAnswers[question.id];
|
|
1619
|
-
if (value === void 0) {
|
|
1620
|
-
return [];
|
|
1621
|
-
}
|
|
1622
|
-
return [`- ${question.label}: ${formatQuestionAnswer(question, value)}`];
|
|
1623
|
-
})
|
|
1624
|
-
];
|
|
1625
1919
|
try {
|
|
1626
1920
|
await onSubmit?.({
|
|
1627
1921
|
questionnaireId: questionnaire.questionnaireId,
|
|
1922
|
+
...questionnaire.blockKey ? { blockKey: questionnaire.blockKey } : {},
|
|
1628
1923
|
answers: normalizedAnswers,
|
|
1629
|
-
|
|
1924
|
+
details: submissionDetails,
|
|
1925
|
+
content
|
|
1630
1926
|
});
|
|
1631
1927
|
setIsSubmitted(true);
|
|
1632
1928
|
} catch (error) {
|
|
@@ -1635,125 +1931,156 @@ var QuestionnaireCardInner = ({
|
|
|
1635
1931
|
setIsSubmitting(false);
|
|
1636
1932
|
}
|
|
1637
1933
|
};
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
|
|
1688
|
-
|
|
1689
|
-
|
|
1690
|
-
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
1934
|
+
if (!question) {
|
|
1935
|
+
return null;
|
|
1936
|
+
}
|
|
1937
|
+
const renderQuestion = (questionToRender) => {
|
|
1938
|
+
switch (questionToRender.kind) {
|
|
1939
|
+
case "multi_select": {
|
|
1940
|
+
const multiSelectDraft = getMultiSelectDraftState(
|
|
1941
|
+
questionToRender,
|
|
1942
|
+
answers[questionToRender.id],
|
|
1943
|
+
otherDrafts[questionToRender.id] ?? ""
|
|
1944
|
+
);
|
|
1945
|
+
return /* @__PURE__ */ jsx5(QuestionBody, { children: /* @__PURE__ */ jsxs3(OptionList, { children: [
|
|
1946
|
+
questionToRender.options.map((option, index) => {
|
|
1947
|
+
const isSelected = multiSelectDraft.selectedValues.includes(option.value);
|
|
1948
|
+
return /* @__PURE__ */ jsx5(
|
|
1949
|
+
OptionChoice,
|
|
1950
|
+
{
|
|
1951
|
+
questionId: questionToRender.id,
|
|
1952
|
+
optionLabel: option.label,
|
|
1953
|
+
index,
|
|
1954
|
+
isSelected,
|
|
1955
|
+
isInteractionLocked,
|
|
1956
|
+
onClick: () => setAnswers(
|
|
1957
|
+
(current) => toggleMultiSelectAnswer(current, questionToRender.id, option.value)
|
|
1958
|
+
)
|
|
1959
|
+
},
|
|
1960
|
+
option.value
|
|
1961
|
+
);
|
|
1962
|
+
}),
|
|
1963
|
+
questionToRender.allowOther ? /* @__PURE__ */ jsx5(
|
|
1964
|
+
OptionChoice,
|
|
1965
|
+
{
|
|
1966
|
+
questionId: questionToRender.id,
|
|
1967
|
+
optionLabel: resolvedLabels.otherOptionLabel,
|
|
1968
|
+
index: questionToRender.options.length,
|
|
1969
|
+
isSelected: multiSelectDraft.hasOtherSelected,
|
|
1970
|
+
isInteractionLocked,
|
|
1971
|
+
tone: "other",
|
|
1972
|
+
onClick: () => {
|
|
1973
|
+
if (!multiSelectDraft.hasOtherSelected) {
|
|
1974
|
+
setPendingFocusQuestionId(questionToRender.id);
|
|
1975
|
+
}
|
|
1976
|
+
setAnswers((current) => toggleMultiSelectOtherAnswer(current, questionToRender));
|
|
1977
|
+
},
|
|
1978
|
+
inlineInput: multiSelectDraft.hasOtherSelected ? /* @__PURE__ */ jsx5(
|
|
1979
|
+
InlineOtherInput,
|
|
1980
|
+
{
|
|
1981
|
+
ref: (node) => {
|
|
1982
|
+
otherInputRefs.current[questionToRender.id] = node;
|
|
1983
|
+
},
|
|
1984
|
+
"data-testid": `question-input-${questionToRender.id}`,
|
|
1985
|
+
type: "text",
|
|
1986
|
+
value: multiSelectDraft.otherValue,
|
|
1987
|
+
placeholder: resolvedLabels.otherPlaceholder,
|
|
1988
|
+
readOnly: isInteractionLocked,
|
|
1989
|
+
onClick: stopInputClickPropagation,
|
|
1990
|
+
onKeyDown: stopInputKeyPropagation,
|
|
1991
|
+
onChange: (event) => {
|
|
1992
|
+
setOtherDrafts((current) => ({
|
|
1993
|
+
...current,
|
|
1994
|
+
[questionToRender.id]: event.target.value
|
|
1995
|
+
}));
|
|
1996
|
+
}
|
|
1997
|
+
}
|
|
1998
|
+
) : null
|
|
1999
|
+
},
|
|
2000
|
+
`${questionToRender.id}-other`
|
|
2001
|
+
) : null
|
|
2002
|
+
] }) });
|
|
2003
|
+
}
|
|
1700
2004
|
case "single_select": {
|
|
1701
|
-
const singleSelectDraft = getSingleSelectDraftState(
|
|
2005
|
+
const singleSelectDraft = getSingleSelectDraftState(
|
|
2006
|
+
questionToRender,
|
|
2007
|
+
answers[questionToRender.id],
|
|
2008
|
+
otherDrafts[questionToRender.id] ?? ""
|
|
2009
|
+
);
|
|
1702
2010
|
return /* @__PURE__ */ jsx5(QuestionBody, { children: /* @__PURE__ */ jsxs3(OptionList, { children: [
|
|
1703
|
-
|
|
2011
|
+
questionToRender.options.map((option, index) => {
|
|
1704
2012
|
const isSelected = singleSelectDraft.selectedValue === option.value;
|
|
1705
|
-
return
|
|
1706
|
-
|
|
1707
|
-
optionLabel: option.label,
|
|
1708
|
-
index,
|
|
1709
|
-
isSelected,
|
|
1710
|
-
onClick: () => setAnswers((current) => updateAnswerValue(current, question.id, option.value))
|
|
1711
|
-
});
|
|
1712
|
-
}),
|
|
1713
|
-
question.allowOther ? renderOptionChoice({
|
|
1714
|
-
questionId: question.id,
|
|
1715
|
-
optionLabel: "Other",
|
|
1716
|
-
index: question.options.length,
|
|
1717
|
-
isSelected: singleSelectDraft.selectedValue === OTHER_OPTION_VALUE,
|
|
1718
|
-
tone: "other",
|
|
1719
|
-
onClick: () => setAnswers(
|
|
1720
|
-
(current) => updateAnswerValue(current, question.id, singleSelectDraft.otherValue)
|
|
1721
|
-
),
|
|
1722
|
-
inlineInput: singleSelectDraft.selectedValue === OTHER_OPTION_VALUE ? /* @__PURE__ */ jsx5(
|
|
1723
|
-
InlineOtherInput,
|
|
2013
|
+
return /* @__PURE__ */ jsx5(
|
|
2014
|
+
OptionChoice,
|
|
1724
2015
|
{
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
onClick: (
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
2016
|
+
questionId: questionToRender.id,
|
|
2017
|
+
optionLabel: option.label,
|
|
2018
|
+
index,
|
|
2019
|
+
isSelected,
|
|
2020
|
+
isInteractionLocked,
|
|
2021
|
+
onClick: () => setAnswers(
|
|
2022
|
+
(current) => updateAnswerValue(current, questionToRender.id, option.value)
|
|
2023
|
+
)
|
|
2024
|
+
},
|
|
2025
|
+
option.value
|
|
2026
|
+
);
|
|
2027
|
+
}),
|
|
2028
|
+
questionToRender.allowOther ? /* @__PURE__ */ jsx5(
|
|
2029
|
+
OptionChoice,
|
|
2030
|
+
{
|
|
2031
|
+
questionId: questionToRender.id,
|
|
2032
|
+
optionLabel: resolvedLabels.otherOptionLabel,
|
|
2033
|
+
index: questionToRender.options.length,
|
|
2034
|
+
isSelected: singleSelectDraft.selectedValue === OTHER_OPTION_VALUE,
|
|
2035
|
+
isInteractionLocked,
|
|
2036
|
+
tone: "other",
|
|
2037
|
+
onClick: () => {
|
|
2038
|
+
if (singleSelectDraft.selectedValue !== OTHER_OPTION_VALUE) {
|
|
2039
|
+
setPendingFocusQuestionId(questionToRender.id);
|
|
1740
2040
|
}
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
2041
|
+
setAnswers(
|
|
2042
|
+
(current) => updateAnswerValue(current, questionToRender.id, OTHER_OPTION_VALUE)
|
|
2043
|
+
);
|
|
2044
|
+
},
|
|
2045
|
+
inlineInput: singleSelectDraft.selectedValue === OTHER_OPTION_VALUE ? /* @__PURE__ */ jsx5(
|
|
2046
|
+
InlineOtherInput,
|
|
2047
|
+
{
|
|
2048
|
+
ref: (node) => {
|
|
2049
|
+
otherInputRefs.current[questionToRender.id] = node;
|
|
2050
|
+
},
|
|
2051
|
+
"data-testid": `question-input-${questionToRender.id}`,
|
|
2052
|
+
type: "text",
|
|
2053
|
+
value: singleSelectDraft.otherValue,
|
|
2054
|
+
placeholder: resolvedLabels.otherPlaceholder,
|
|
2055
|
+
readOnly: isInteractionLocked,
|
|
2056
|
+
onClick: stopInputClickPropagation,
|
|
2057
|
+
onKeyDown: stopInputKeyPropagation,
|
|
2058
|
+
onChange: (event) => {
|
|
2059
|
+
setOtherDrafts((current) => ({
|
|
2060
|
+
...current,
|
|
2061
|
+
[questionToRender.id]: event.target.value
|
|
2062
|
+
}));
|
|
2063
|
+
}
|
|
2064
|
+
}
|
|
2065
|
+
) : null
|
|
2066
|
+
},
|
|
2067
|
+
`${questionToRender.id}-other`
|
|
2068
|
+
) : null
|
|
1744
2069
|
] }) });
|
|
1745
2070
|
}
|
|
1746
2071
|
case "text":
|
|
1747
2072
|
return /* @__PURE__ */ jsx5(QuestionBody, { children: /* @__PURE__ */ jsx5(
|
|
1748
2073
|
TextInput,
|
|
1749
2074
|
{
|
|
1750
|
-
"data-testid": `question-input-${
|
|
2075
|
+
"data-testid": `question-input-${questionToRender.id}`,
|
|
1751
2076
|
type: "text",
|
|
1752
|
-
value: getTextInputValue(answers[
|
|
1753
|
-
placeholder:
|
|
2077
|
+
value: getTextInputValue(answers[questionToRender.id]),
|
|
2078
|
+
placeholder: questionToRender.placeholder,
|
|
1754
2079
|
readOnly: isInteractionLocked,
|
|
1755
2080
|
onChange: (event) => {
|
|
1756
|
-
setAnswers(
|
|
2081
|
+
setAnswers(
|
|
2082
|
+
(current) => updateAnswerValue(current, questionToRender.id, event.target.value)
|
|
2083
|
+
);
|
|
1757
2084
|
}
|
|
1758
2085
|
}
|
|
1759
2086
|
) });
|
|
@@ -1762,55 +2089,63 @@ var QuestionnaireCardInner = ({
|
|
|
1762
2089
|
/* @__PURE__ */ jsx5(
|
|
1763
2090
|
TextInput,
|
|
1764
2091
|
{
|
|
1765
|
-
"data-testid": `question-input-${
|
|
2092
|
+
"data-testid": `question-input-${questionToRender.id}`,
|
|
1766
2093
|
type: "number",
|
|
1767
|
-
value: getNumberInputValue(answers[
|
|
1768
|
-
placeholder:
|
|
2094
|
+
value: getNumberInputValue(answers[questionToRender.id]),
|
|
2095
|
+
placeholder: questionToRender.placeholder,
|
|
1769
2096
|
readOnly: isInteractionLocked,
|
|
1770
2097
|
onChange: (event) => {
|
|
1771
2098
|
setAnswers(
|
|
1772
2099
|
(current) => updateAnswerValue(
|
|
1773
2100
|
current,
|
|
1774
|
-
|
|
2101
|
+
questionToRender.id,
|
|
1775
2102
|
event.target.value === "" ? void 0 : Number(event.target.value)
|
|
1776
2103
|
)
|
|
1777
2104
|
);
|
|
1778
2105
|
}
|
|
1779
2106
|
}
|
|
1780
2107
|
),
|
|
1781
|
-
|
|
2108
|
+
questionToRender.unit ? /* @__PURE__ */ jsx5(Unit, { children: questionToRender.unit }) : null
|
|
1782
2109
|
] }) });
|
|
1783
2110
|
case "boolean":
|
|
1784
2111
|
return /* @__PURE__ */ jsx5(QuestionBody, { children: /* @__PURE__ */ jsxs3(OptionList, { children: [
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
|
|
1789
|
-
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
2112
|
+
/* @__PURE__ */ jsx5(
|
|
2113
|
+
OptionChoice,
|
|
2114
|
+
{
|
|
2115
|
+
questionId: questionToRender.id,
|
|
2116
|
+
optionLabel: questionToRender.trueLabel ?? "Yes",
|
|
2117
|
+
index: 0,
|
|
2118
|
+
isSelected: answers[questionToRender.id] === true,
|
|
2119
|
+
isInteractionLocked,
|
|
2120
|
+
onClick: () => setAnswers((current) => updateAnswerValue(current, questionToRender.id, true))
|
|
2121
|
+
}
|
|
2122
|
+
),
|
|
2123
|
+
/* @__PURE__ */ jsx5(
|
|
2124
|
+
OptionChoice,
|
|
2125
|
+
{
|
|
2126
|
+
questionId: questionToRender.id,
|
|
2127
|
+
optionLabel: questionToRender.falseLabel ?? "No",
|
|
2128
|
+
index: 1,
|
|
2129
|
+
isSelected: answers[questionToRender.id] === false,
|
|
2130
|
+
isInteractionLocked,
|
|
2131
|
+
onClick: () => setAnswers((current) => updateAnswerValue(current, questionToRender.id, false))
|
|
2132
|
+
}
|
|
2133
|
+
)
|
|
1799
2134
|
] }) });
|
|
1800
2135
|
default:
|
|
1801
2136
|
return null;
|
|
1802
2137
|
}
|
|
1803
2138
|
};
|
|
1804
2139
|
return /* @__PURE__ */ jsxs3(Card4, { "data-testid": "questionnaire-card", children: [
|
|
1805
|
-
questionnaire.title ? /* @__PURE__ */ jsx5(Title3, { children: questionnaire.title }) : null,
|
|
1806
2140
|
questionnaire.description ? /* @__PURE__ */ jsx5(Description, { children: questionnaire.description }) : null,
|
|
1807
|
-
/* @__PURE__ */ jsx5(QuestionList, { children:
|
|
2141
|
+
/* @__PURE__ */ jsx5(QuestionList, { children: /* @__PURE__ */ jsxs3(QuestionCard, { children: [
|
|
1808
2142
|
/* @__PURE__ */ jsxs3(QuestionLabel, { children: [
|
|
1809
2143
|
question.label,
|
|
1810
2144
|
question.required ? /* @__PURE__ */ jsx5(Required, { children: "*" }) : null
|
|
1811
2145
|
] }),
|
|
2146
|
+
question.kind === "multi_select" ? /* @__PURE__ */ jsx5(QuestionHint, { children: resolvedLabels.multiSelectHint }) : null,
|
|
1812
2147
|
renderQuestion(question)
|
|
1813
|
-
] }, question.id)
|
|
2148
|
+
] }, question.id) }),
|
|
1814
2149
|
visibleErrorMessage ? /* @__PURE__ */ jsx5(ErrorMessage, { "data-testid": "questionnaire-error", children: visibleErrorMessage }) : null,
|
|
1815
2150
|
isSubmitted ? /* @__PURE__ */ jsx5(SuccessMessage, { "data-testid": "questionnaire-success", children: resolvedLabels.submitted }) : interactive && !hasExternalFailureStatus ? /* @__PURE__ */ jsx5(
|
|
1816
2151
|
SubmitButton,
|
|
@@ -1826,12 +2161,6 @@ var QuestionnaireCardInner = ({
|
|
|
1826
2161
|
) : null
|
|
1827
2162
|
] });
|
|
1828
2163
|
};
|
|
1829
|
-
var getQuestionnaireStateKey = (questionnaire) => JSON.stringify([
|
|
1830
|
-
questionnaire.questionnaireId,
|
|
1831
|
-
questionnaire.questions,
|
|
1832
|
-
questionnaire.status,
|
|
1833
|
-
questionnaire.statusMessage
|
|
1834
|
-
]);
|
|
1835
2164
|
var QuestionnaireCard = (props) => /* @__PURE__ */ jsx5(QuestionnaireCardInner, { ...props }, getQuestionnaireStateKey(props.questionnaire));
|
|
1836
2165
|
var Card4 = styled4.section`
|
|
1837
2166
|
display: grid;
|
|
@@ -1841,11 +2170,6 @@ var Card4 = styled4.section`
|
|
|
1841
2170
|
border: 1px solid rgba(255, 255, 255, 0.08);
|
|
1842
2171
|
background: rgba(255, 255, 255, 0.03);
|
|
1843
2172
|
`;
|
|
1844
|
-
var Title3 = styled4.strong`
|
|
1845
|
-
color: rgba(255, 255, 255, 0.94);
|
|
1846
|
-
font-size: 16px;
|
|
1847
|
-
line-height: 1.4;
|
|
1848
|
-
`;
|
|
1849
2173
|
var Description = styled4.p`
|
|
1850
2174
|
margin: 0;
|
|
1851
2175
|
color: rgba(255, 255, 255, 0.72);
|
|
@@ -1864,13 +2188,18 @@ var QuestionCard = styled4.div`
|
|
|
1864
2188
|
`;
|
|
1865
2189
|
var QuestionLabel = styled4.div`
|
|
1866
2190
|
color: rgba(255, 255, 255, 0.9);
|
|
1867
|
-
font-size:
|
|
2191
|
+
font-size: 14px;
|
|
1868
2192
|
font-weight: 600;
|
|
1869
2193
|
`;
|
|
1870
2194
|
var Required = styled4.span`
|
|
1871
2195
|
margin-left: 4px;
|
|
1872
2196
|
color: rgba(255, 122, 122, 0.9);
|
|
1873
2197
|
`;
|
|
2198
|
+
var QuestionHint = styled4.div`
|
|
2199
|
+
color: rgba(132, 180, 255, 0.9);
|
|
2200
|
+
font-size: 12px;
|
|
2201
|
+
line-height: 1.4;
|
|
2202
|
+
`;
|
|
1874
2203
|
var QuestionBody = styled4.div`
|
|
1875
2204
|
display: grid;
|
|
1876
2205
|
gap: 10px;
|
|
@@ -1888,7 +2217,7 @@ var OptionChoiceItem = styled4.div`
|
|
|
1888
2217
|
border: 1px solid rgba(255, 255, 255, 0.1);
|
|
1889
2218
|
border-radius: 14px;
|
|
1890
2219
|
background: rgba(255, 255, 255, 0.03);
|
|
1891
|
-
padding: 12px
|
|
2220
|
+
padding: 2px 12px;
|
|
1892
2221
|
color: rgba(255, 255, 255, 0.9);
|
|
1893
2222
|
cursor: pointer;
|
|
1894
2223
|
transition:
|
|
@@ -1939,8 +2268,11 @@ var OptionChoiceMarker = styled4.span`
|
|
|
1939
2268
|
}
|
|
1940
2269
|
`;
|
|
1941
2270
|
var OptionChoiceContent = styled4.span`
|
|
1942
|
-
display:
|
|
1943
|
-
|
|
2271
|
+
display: flex;
|
|
2272
|
+
flex-direction: column;
|
|
2273
|
+
justify-content: center;
|
|
2274
|
+
gap: 4px;
|
|
2275
|
+
min-height: 40px;
|
|
1944
2276
|
min-width: 0;
|
|
1945
2277
|
flex: 1;
|
|
1946
2278
|
`;
|
|
@@ -1963,8 +2295,37 @@ var TextInput = styled4.input`
|
|
|
1963
2295
|
color: rgba(255, 255, 255, 0.34);
|
|
1964
2296
|
}
|
|
1965
2297
|
`;
|
|
1966
|
-
var InlineOtherInput = styled4(
|
|
2298
|
+
var InlineOtherInput = styled4(InputField)`
|
|
2299
|
+
width: 100%;
|
|
1967
2300
|
margin-top: 0;
|
|
2301
|
+
|
|
2302
|
+
.compass-input-field-wrapper {
|
|
2303
|
+
min-height: 30px;
|
|
2304
|
+
border: 1px solid rgba(255, 255, 255, 0.1);
|
|
2305
|
+
border-radius: 10px;
|
|
2306
|
+
background: rgba(13, 15, 21, 0.55);
|
|
2307
|
+
box-shadow: none;
|
|
2308
|
+
padding: 2px 9px;
|
|
2309
|
+
}
|
|
2310
|
+
|
|
2311
|
+
.compass-input-field-wrapper:hover {
|
|
2312
|
+
border-color: rgba(126, 160, 255, 0.28);
|
|
2313
|
+
}
|
|
2314
|
+
|
|
2315
|
+
.compass-input-field-wrapper:focus-within {
|
|
2316
|
+
border-color: rgba(126, 160, 255, 0.42);
|
|
2317
|
+
box-shadow: 0 0 0 1px rgba(126, 160, 255, 0.14);
|
|
2318
|
+
}
|
|
2319
|
+
|
|
2320
|
+
.compass-input-field-input {
|
|
2321
|
+
color: rgba(255, 255, 255, 0.92);
|
|
2322
|
+
font-size: 13px;
|
|
2323
|
+
line-height: 1.2;
|
|
2324
|
+
}
|
|
2325
|
+
|
|
2326
|
+
.compass-input-field-input::placeholder {
|
|
2327
|
+
color: rgba(255, 255, 255, 0.34);
|
|
2328
|
+
}
|
|
1968
2329
|
`;
|
|
1969
2330
|
var NumberInputRow = styled4.div`
|
|
1970
2331
|
display: flex;
|
|
@@ -2050,7 +2411,7 @@ var Detail = styled5.li`
|
|
|
2050
2411
|
|
|
2051
2412
|
// src/components/chat-thread/components/image-viewer.tsx
|
|
2052
2413
|
import styled6 from "@emotion/styled";
|
|
2053
|
-
import { useEffect as
|
|
2414
|
+
import { useEffect as useEffect4, useRef as useRef4 } from "react";
|
|
2054
2415
|
import { jsx as jsx7 } from "@emotion/react/jsx-runtime";
|
|
2055
2416
|
var Overlay = styled6.div`
|
|
2056
2417
|
position: fixed;
|
|
@@ -2069,8 +2430,8 @@ var Img = styled6.img`
|
|
|
2069
2430
|
border-radius: 4px;
|
|
2070
2431
|
`;
|
|
2071
2432
|
var ImageViewer = ({ src, alt, onClose }) => {
|
|
2072
|
-
const overlayRef =
|
|
2073
|
-
|
|
2433
|
+
const overlayRef = useRef4(null);
|
|
2434
|
+
useEffect4(() => {
|
|
2074
2435
|
const handleKey = (e) => {
|
|
2075
2436
|
if (e.key === "Escape")
|
|
2076
2437
|
onClose();
|
|
@@ -2078,7 +2439,7 @@ var ImageViewer = ({ src, alt, onClose }) => {
|
|
|
2078
2439
|
document.addEventListener("keydown", handleKey);
|
|
2079
2440
|
return () => document.removeEventListener("keydown", handleKey);
|
|
2080
2441
|
}, [onClose]);
|
|
2081
|
-
|
|
2442
|
+
useEffect4(() => {
|
|
2082
2443
|
overlayRef.current?.focus();
|
|
2083
2444
|
}, []);
|
|
2084
2445
|
const stopPropagation = (e) => e.stopPropagation();
|
|
@@ -2273,9 +2634,7 @@ var arePlanQuestionsEqual = (previousQuestion, nextQuestion) => {
|
|
|
2273
2634
|
return false;
|
|
2274
2635
|
}
|
|
2275
2636
|
};
|
|
2276
|
-
var areQuestionnairesEqual = (previousQuestionnaire, nextQuestionnaire) => previousQuestionnaire.questionnaireId === nextQuestionnaire.questionnaireId && previousQuestionnaire.title === nextQuestionnaire.title && previousQuestionnaire.description === nextQuestionnaire.description && previousQuestionnaire.submitLabel === nextQuestionnaire.submitLabel && previousQuestionnaire.status === nextQuestionnaire.status && previousQuestionnaire.statusMessage === nextQuestionnaire.statusMessage && previousQuestionnaire.
|
|
2277
|
-
(question, index) => arePlanQuestionsEqual(question, nextQuestionnaire.questions[index])
|
|
2278
|
-
) && areQuestionAnswerMapsEqual(previousQuestionnaire.answers, nextQuestionnaire.answers);
|
|
2637
|
+
var areQuestionnairesEqual = (previousQuestionnaire, nextQuestionnaire) => previousQuestionnaire.questionnaireId === nextQuestionnaire.questionnaireId && previousQuestionnaire.title === nextQuestionnaire.title && previousQuestionnaire.description === nextQuestionnaire.description && previousQuestionnaire.submitLabel === nextQuestionnaire.submitLabel && previousQuestionnaire.status === nextQuestionnaire.status && previousQuestionnaire.statusMessage === nextQuestionnaire.statusMessage && arePlanQuestionsEqual(previousQuestionnaire.question, nextQuestionnaire.question) && areQuestionAnswerMapsEqual(previousQuestionnaire.answers, nextQuestionnaire.answers);
|
|
2279
2638
|
var areMessageBlocksEqual = (previousBlocks, nextBlocks) => {
|
|
2280
2639
|
if (previousBlocks === nextBlocks) {
|
|
2281
2640
|
return true;
|
|
@@ -2429,14 +2788,17 @@ var ChatMessageItemView = ({
|
|
|
2429
2788
|
submitting: labels.questionnaireSubmitting,
|
|
2430
2789
|
submitted: labels.questionnaireSubmitted,
|
|
2431
2790
|
validationPrefix: labels.questionnaireValidationPrefix,
|
|
2432
|
-
submitFailed: labels.questionnaireSubmitFailed
|
|
2791
|
+
submitFailed: labels.questionnaireSubmitFailed,
|
|
2792
|
+
multiSelectHint: labels.questionnaireMultiSelectHint,
|
|
2793
|
+
otherOptionLabel: labels.questionnaireOtherOptionLabel,
|
|
2794
|
+
otherPlaceholder: labels.questionnaireOtherPlaceholder
|
|
2433
2795
|
},
|
|
2434
2796
|
onSubmit: canSubmitQuestionnaire ? (submission) => onQuestionnaireSubmit({
|
|
2435
2797
|
...submission,
|
|
2436
2798
|
sourceMessageId: message.id
|
|
2437
2799
|
}) : void 0
|
|
2438
2800
|
}
|
|
2439
|
-
) }, `questionnaire-${index}`);
|
|
2801
|
+
) }, block.questionnaire.blockKey ?? `questionnaire-${index}`);
|
|
2440
2802
|
case "custom":
|
|
2441
2803
|
return /* @__PURE__ */ jsx8(Fragment, { children: renderMessageBlock?.({
|
|
2442
2804
|
block,
|
|
@@ -2688,8 +3050,34 @@ var CollapseToggle = styled7.button`
|
|
|
2688
3050
|
`;
|
|
2689
3051
|
var Content = styled7.div`
|
|
2690
3052
|
color: rgba(255, 255, 255, 0.92);
|
|
3053
|
+
font-size: 14px;
|
|
2691
3054
|
line-height: 1.6;
|
|
2692
3055
|
|
|
3056
|
+
h1,
|
|
3057
|
+
h2,
|
|
3058
|
+
h3,
|
|
3059
|
+
h4,
|
|
3060
|
+
h5,
|
|
3061
|
+
h6 {
|
|
3062
|
+
margin: 0;
|
|
3063
|
+
line-height: 2.5;
|
|
3064
|
+
}
|
|
3065
|
+
|
|
3066
|
+
h1 {
|
|
3067
|
+
font-size: 18px;
|
|
3068
|
+
}
|
|
3069
|
+
|
|
3070
|
+
h2 {
|
|
3071
|
+
font-size: 16px;
|
|
3072
|
+
}
|
|
3073
|
+
|
|
3074
|
+
h3,
|
|
3075
|
+
h4,
|
|
3076
|
+
h5,
|
|
3077
|
+
h6 {
|
|
3078
|
+
font-size: 14px;
|
|
3079
|
+
}
|
|
3080
|
+
|
|
2693
3081
|
p {
|
|
2694
3082
|
margin: 0;
|
|
2695
3083
|
}
|
|
@@ -2701,7 +3089,7 @@ var Content = styled7.div`
|
|
|
2701
3089
|
table {
|
|
2702
3090
|
width: 100%;
|
|
2703
3091
|
border-collapse: collapse;
|
|
2704
|
-
margin: 0;
|
|
3092
|
+
margin: 8px 0 0;
|
|
2705
3093
|
overflow: hidden;
|
|
2706
3094
|
border-radius: 14px;
|
|
2707
3095
|
border: 1px solid rgba(255, 255, 255, 0.08);
|
|
@@ -2725,6 +3113,10 @@ var Content = styled7.div`
|
|
|
2725
3113
|
tbody tr:last-of-type td {
|
|
2726
3114
|
border-bottom: none;
|
|
2727
3115
|
}
|
|
3116
|
+
ul,
|
|
3117
|
+
ol {
|
|
3118
|
+
margin: 0 0 8px;
|
|
3119
|
+
}
|
|
2728
3120
|
`;
|
|
2729
3121
|
var ContentStack = styled7.div`
|
|
2730
3122
|
display: flex;
|
|
@@ -3003,7 +3395,7 @@ var ChatThreadView = ({
|
|
|
3003
3395
|
onQuestionnaireSubmit,
|
|
3004
3396
|
renderMessageBlock
|
|
3005
3397
|
}) => {
|
|
3006
|
-
const containerRef =
|
|
3398
|
+
const containerRef = useRef5(null);
|
|
3007
3399
|
const conversationTurns = useMemo4(
|
|
3008
3400
|
() => groupConversationTurns(historyMessages, streamingMessage),
|
|
3009
3401
|
[historyMessages, streamingMessage]
|
|
@@ -3011,8 +3403,8 @@ var ChatThreadView = ({
|
|
|
3011
3403
|
const latestTurn = conversationTurns[conversationTurns.length - 1];
|
|
3012
3404
|
const previousTurns = conversationTurns.slice(0, -1);
|
|
3013
3405
|
const latestUserMessageId = latestTurn?.userMessage?.id;
|
|
3014
|
-
const latestUserMessageRef =
|
|
3015
|
-
const reservedSpaceFrameRef =
|
|
3406
|
+
const latestUserMessageRef = useRef5(null);
|
|
3407
|
+
const reservedSpaceFrameRef = useRef5(null);
|
|
3016
3408
|
const [latestTurnMinHeight, setLatestTurnMinHeight] = useState4(0);
|
|
3017
3409
|
const measureLatestTurnMinHeight = useCallback3(() => {
|
|
3018
3410
|
const container = containerRef.current;
|
|
@@ -3300,7 +3692,7 @@ var RetryButton = styled9.button`
|
|
|
3300
3692
|
`;
|
|
3301
3693
|
|
|
3302
3694
|
// src/components/chat-composer/index.tsx
|
|
3303
|
-
import { useEffect as
|
|
3695
|
+
import { useEffect as useEffect7, useLayoutEffect as useLayoutEffect3, useRef as useRef8, useState as useState8 } from "react";
|
|
3304
3696
|
import styled14 from "@emotion/styled";
|
|
3305
3697
|
|
|
3306
3698
|
// src/components/chat-composer/lib/chat-composer.ts
|
|
@@ -3412,10 +3804,10 @@ var resolveSendSession = ({
|
|
|
3412
3804
|
};
|
|
3413
3805
|
|
|
3414
3806
|
// src/components/chat-composer/hooks/use-chat-composer.ts
|
|
3415
|
-
import { useCallback as useCallback4, useEffect as
|
|
3807
|
+
import { useCallback as useCallback4, useEffect as useEffect6, useRef as useRef7, useState as useState6 } from "react";
|
|
3416
3808
|
|
|
3417
3809
|
// src/components/chat-composer/hooks/use-composer-attachments.ts
|
|
3418
|
-
import { useEffect as
|
|
3810
|
+
import { useEffect as useEffect5, useRef as useRef6, useState as useState5 } from "react";
|
|
3419
3811
|
var SUPPORTED_IMAGE_MIME_TYPES = /* @__PURE__ */ new Set(["image/png", "image/jpeg", "image/webp"]);
|
|
3420
3812
|
var MAX_COMPOSER_ATTACHMENTS = 10;
|
|
3421
3813
|
var createObjectUrl = (file) => typeof URL !== "undefined" && typeof URL.createObjectURL === "function" ? URL.createObjectURL(file) : "";
|
|
@@ -3430,11 +3822,11 @@ var releaseComposerAttachments = (attachments) => {
|
|
|
3430
3822
|
};
|
|
3431
3823
|
var useComposerAttachments = () => {
|
|
3432
3824
|
const [attachments, setAttachments] = useState5([]);
|
|
3433
|
-
const attachmentsRef =
|
|
3434
|
-
|
|
3825
|
+
const attachmentsRef = useRef6([]);
|
|
3826
|
+
useEffect5(() => {
|
|
3435
3827
|
attachmentsRef.current = attachments;
|
|
3436
3828
|
}, [attachments]);
|
|
3437
|
-
|
|
3829
|
+
useEffect5(
|
|
3438
3830
|
() => () => {
|
|
3439
3831
|
releaseComposerAttachments(attachmentsRef.current);
|
|
3440
3832
|
},
|
|
@@ -3562,7 +3954,7 @@ var useChatComposer = () => {
|
|
|
3562
3954
|
setIsModelsLoading(false);
|
|
3563
3955
|
}
|
|
3564
3956
|
}, [transport]);
|
|
3565
|
-
|
|
3957
|
+
useEffect6(() => {
|
|
3566
3958
|
void fetchModels();
|
|
3567
3959
|
}, [fetchModels]);
|
|
3568
3960
|
const hasModels = availableModels.length > 0;
|
|
@@ -3571,22 +3963,22 @@ var useChatComposer = () => {
|
|
|
3571
3963
|
const [selectedMode, setSelectedModeLocal] = useState6(DEFAULT_CHAT_AGENT_MODE);
|
|
3572
3964
|
const [attachmentNotice, setAttachmentNotice] = useState6(null);
|
|
3573
3965
|
const { attachments, appendFiles, removeAttachment, takeMessageAttachments } = useComposerAttachments();
|
|
3574
|
-
const abortControllerRef =
|
|
3575
|
-
const stopRequestRef =
|
|
3576
|
-
const lastRequestRef =
|
|
3577
|
-
|
|
3966
|
+
const abortControllerRef = useRef7(null);
|
|
3967
|
+
const stopRequestRef = useRef7(null);
|
|
3968
|
+
const lastRequestRef = useRef7(null);
|
|
3969
|
+
useEffect6(() => {
|
|
3578
3970
|
setSelectedModel(
|
|
3579
3971
|
(current) => resolveSelectedChatModel({ currentModel: current, availableModels, isModelsLoading })
|
|
3580
3972
|
);
|
|
3581
3973
|
}, [availableModels, isModelsLoading]);
|
|
3582
|
-
|
|
3974
|
+
useEffect6(() => {
|
|
3583
3975
|
if (activeSession) {
|
|
3584
3976
|
setSelectedModeLocal(activeSession.mode ?? DEFAULT_CHAT_AGENT_MODE);
|
|
3585
3977
|
return;
|
|
3586
3978
|
}
|
|
3587
3979
|
setSelectedModeLocal(preferredMode ?? DEFAULT_CHAT_AGENT_MODE);
|
|
3588
3980
|
}, [activeSession, preferredMode]);
|
|
3589
|
-
|
|
3981
|
+
useEffect6(() => {
|
|
3590
3982
|
if (!attachmentNotice)
|
|
3591
3983
|
return;
|
|
3592
3984
|
const timeoutId = window.setTimeout(
|
|
@@ -4417,8 +4809,8 @@ var ChatComposerView = ({
|
|
|
4417
4809
|
onStop,
|
|
4418
4810
|
onSend
|
|
4419
4811
|
}) => {
|
|
4420
|
-
const imageInputRef =
|
|
4421
|
-
const inputRef =
|
|
4812
|
+
const imageInputRef = useRef8(null);
|
|
4813
|
+
const inputRef = useRef8(null);
|
|
4422
4814
|
const [isComposerExpandable, setIsComposerExpandable] = useState8(false);
|
|
4423
4815
|
const [isComposerExpanded, setIsComposerExpanded] = useState8(false);
|
|
4424
4816
|
const canSend = canSendChatMessage({
|
|
@@ -4569,7 +4961,7 @@ var ChatComposer = () => {
|
|
|
4569
4961
|
const { labels, sendRef, retryRef, enableImageAttachments } = useChatContext();
|
|
4570
4962
|
const { state, actions } = useChatComposer();
|
|
4571
4963
|
const { send, retry } = actions;
|
|
4572
|
-
|
|
4964
|
+
useEffect7(() => {
|
|
4573
4965
|
sendRef.current = send;
|
|
4574
4966
|
retryRef.current = async () => {
|
|
4575
4967
|
retry();
|
|
@@ -4843,7 +5235,7 @@ var ChatConversationList = () => {
|
|
|
4843
5235
|
};
|
|
4844
5236
|
return /* @__PURE__ */ jsxs12(Container3, { children: [
|
|
4845
5237
|
/* @__PURE__ */ jsxs12(Toolbar, { children: [
|
|
4846
|
-
/* @__PURE__ */ jsx17(
|
|
5238
|
+
/* @__PURE__ */ jsx17(Title3, { children: "Sessions" }),
|
|
4847
5239
|
/* @__PURE__ */ jsx17(CreateButton, { type: "button", "data-testid": "chat-create-session", onClick: handleCreateSession, children: labels.newChat })
|
|
4848
5240
|
] }),
|
|
4849
5241
|
/* @__PURE__ */ jsx17(List2, { "data-testid": "chat-session-list", children: sessions.map((session) => /* @__PURE__ */ jsx17(
|
|
@@ -4872,7 +5264,7 @@ var Toolbar = styled16.div`
|
|
|
4872
5264
|
flex-direction: column;
|
|
4873
5265
|
gap: 12px;
|
|
4874
5266
|
`;
|
|
4875
|
-
var
|
|
5267
|
+
var Title3 = styled16.h2`
|
|
4876
5268
|
margin: 0;
|
|
4877
5269
|
font-size: 14px;
|
|
4878
5270
|
color: var(--text-secondary);
|