@xinghunm/ai-chat 1.0.2 → 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 +17 -2
- package/dist/index.d.ts +17 -2
- package/dist/index.js +586 -215
- package/dist/index.mjs +606 -231
- 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
|
|
@@ -695,7 +698,7 @@ var AiChatProvider = (props) => {
|
|
|
695
698
|
};
|
|
696
699
|
|
|
697
700
|
// src/components/chat-thread/index.tsx
|
|
698
|
-
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";
|
|
699
702
|
import styled9 from "@emotion/styled";
|
|
700
703
|
|
|
701
704
|
// src/context/use-chat-context.ts
|
|
@@ -1485,31 +1488,126 @@ var Value = styled3.span`
|
|
|
1485
1488
|
`;
|
|
1486
1489
|
|
|
1487
1490
|
// src/components/chat-thread/components/questionnaire-card.tsx
|
|
1488
|
-
import {
|
|
1491
|
+
import {
|
|
1492
|
+
useEffect as useEffect3,
|
|
1493
|
+
useRef as useRef3,
|
|
1494
|
+
useState as useState2
|
|
1495
|
+
} from "react";
|
|
1489
1496
|
import styled4 from "@emotion/styled";
|
|
1490
|
-
import {
|
|
1497
|
+
import { InputField } from "@xinghunm/compass-ui";
|
|
1498
|
+
|
|
1499
|
+
// src/components/chat-thread/components/questionnaire-card-helpers.ts
|
|
1491
1500
|
var OTHER_OPTION_VALUE = "__other__";
|
|
1492
|
-
var
|
|
1493
|
-
submitting: "Submitting...",
|
|
1494
|
-
submitted: "Selection submitted. Waiting for the plan to continue...",
|
|
1495
|
-
validationPrefix: "Please complete:",
|
|
1496
|
-
submitFailed: "Failed to submit. Please try again."
|
|
1497
|
-
};
|
|
1498
|
-
var createInitialAnswers = (questionnaire) => ({
|
|
1499
|
-
...questionnaire.answers ?? {}
|
|
1500
|
-
});
|
|
1501
|
+
var getQuestionnaireQuestion = (questionnaire) => questionnaire.question;
|
|
1501
1502
|
var getMultiSelectAnswerValues = (answer) => Array.isArray(answer) ? answer : [];
|
|
1502
|
-
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) => {
|
|
1503
1601
|
if (typeof answer !== "string") {
|
|
1504
1602
|
return {
|
|
1505
1603
|
selectedValue: void 0,
|
|
1506
|
-
otherValue:
|
|
1604
|
+
otherValue: otherDraft
|
|
1507
1605
|
};
|
|
1508
1606
|
}
|
|
1509
|
-
const matchesOption = question.options.some((option) => option.value === answer);
|
|
1607
|
+
const matchesOption = answer !== OTHER_OPTION_VALUE && question.options.some((option) => option.value === answer);
|
|
1510
1608
|
return {
|
|
1511
1609
|
selectedValue: matchesOption ? answer : question.allowOther ? OTHER_OPTION_VALUE : void 0,
|
|
1512
|
-
otherValue:
|
|
1610
|
+
otherValue: otherDraft
|
|
1513
1611
|
};
|
|
1514
1612
|
};
|
|
1515
1613
|
var updateAnswerValue = (current, questionId, value) => ({
|
|
@@ -1521,6 +1619,17 @@ var toggleMultiSelectAnswer = (current, questionId, optionValue) => {
|
|
|
1521
1619
|
const nextValues = currentValues.includes(optionValue) ? currentValues.filter((value) => value !== optionValue) : [...currentValues, optionValue];
|
|
1522
1620
|
return updateAnswerValue(current, questionId, nextValues);
|
|
1523
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
|
+
};
|
|
1524
1633
|
var getTextInputValue = (answer) => typeof answer === "string" ? String(answer) : "";
|
|
1525
1634
|
var getNumberInputValue = (answer) => typeof answer === "number" || typeof answer === "string" ? String(answer) : "";
|
|
1526
1635
|
var getOptionChoiceLabel = (index) => {
|
|
@@ -1529,20 +1638,49 @@ var getOptionChoiceLabel = (index) => {
|
|
|
1529
1638
|
}
|
|
1530
1639
|
return String(index + 1);
|
|
1531
1640
|
};
|
|
1532
|
-
var
|
|
1533
|
-
|
|
1641
|
+
var normalizeQuestionAnswer = (question, answer, otherDraft = "") => {
|
|
1642
|
+
if (answer === void 0) {
|
|
1643
|
+
return void 0;
|
|
1644
|
+
}
|
|
1534
1645
|
switch (question.kind) {
|
|
1535
|
-
case "boolean":
|
|
1536
|
-
return typeof answer !== "boolean";
|
|
1537
1646
|
case "multi_select":
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
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
|
+
})();
|
|
1542
1667
|
case "single_select":
|
|
1543
|
-
|
|
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;
|
|
1544
1682
|
default:
|
|
1545
|
-
return
|
|
1683
|
+
return answer;
|
|
1546
1684
|
}
|
|
1547
1685
|
};
|
|
1548
1686
|
var formatQuestionAnswer = (question, answer) => {
|
|
@@ -1570,80 +1708,221 @@ var formatQuestionAnswer = (question, answer) => {
|
|
|
1570
1708
|
return String(answer);
|
|
1571
1709
|
}
|
|
1572
1710
|
};
|
|
1573
|
-
var
|
|
1711
|
+
var buildQuestionSubmissionDetail = (question, answer) => {
|
|
1574
1712
|
if (answer === void 0) {
|
|
1575
1713
|
return void 0;
|
|
1576
1714
|
}
|
|
1577
1715
|
switch (question.kind) {
|
|
1578
|
-
case "
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
return
|
|
1585
|
-
|
|
1586
|
-
|
|
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
|
+
}
|
|
1587
1749
|
default:
|
|
1588
|
-
return
|
|
1750
|
+
return {
|
|
1751
|
+
questionId: question.id,
|
|
1752
|
+
kind: question.kind,
|
|
1753
|
+
value: answer
|
|
1754
|
+
};
|
|
1589
1755
|
}
|
|
1590
1756
|
};
|
|
1757
|
+
var getMissingRequiredQuestions = (questionnaire, answers, otherDrafts) => {
|
|
1758
|
+
const question = getQuestionnaireQuestion(questionnaire);
|
|
1759
|
+
if (!question || !question.required) {
|
|
1760
|
+
return [];
|
|
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();
|
|
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
|
+
);
|
|
1591
1859
|
var QuestionnaireCardInner = ({
|
|
1592
1860
|
questionnaire,
|
|
1593
1861
|
interactive = false,
|
|
1594
1862
|
onSubmit,
|
|
1595
1863
|
labels
|
|
1596
1864
|
}) => {
|
|
1865
|
+
const questionnaireRef = useRef3(questionnaire);
|
|
1866
|
+
const otherInputRefs = useRef3({});
|
|
1597
1867
|
const [answers, setAnswers] = useState2(
|
|
1598
1868
|
() => createInitialAnswers(questionnaire)
|
|
1599
1869
|
);
|
|
1870
|
+
const [otherDrafts, setOtherDrafts] = useState2(
|
|
1871
|
+
() => createInitialOtherDrafts(questionnaire)
|
|
1872
|
+
);
|
|
1600
1873
|
const [errorMessage, setErrorMessage] = useState2(null);
|
|
1601
1874
|
const [isSubmitting, setIsSubmitting] = useState2(false);
|
|
1602
1875
|
const [isSubmitted, setIsSubmitted] = useState2(false);
|
|
1876
|
+
const [pendingFocusQuestionId, setPendingFocusQuestionId] = useState2(null);
|
|
1603
1877
|
const resolvedLabels = {
|
|
1604
1878
|
...DEFAULT_QUESTIONNAIRE_CARD_LABELS,
|
|
1605
1879
|
...labels
|
|
1606
1880
|
};
|
|
1607
1881
|
const hasExternalFailureStatus = questionnaire.status === "expired" || questionnaire.status === "failed";
|
|
1882
|
+
const question = getQuestionnaireQuestion(questionnaire);
|
|
1608
1883
|
const visibleErrorMessage = questionnaire.statusMessage ?? errorMessage;
|
|
1609
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]);
|
|
1610
1901
|
const handleSubmit = async () => {
|
|
1611
1902
|
if (isSubmitting || isSubmitted) {
|
|
1612
1903
|
return;
|
|
1613
1904
|
}
|
|
1614
|
-
const missingQuestions = questionnaire
|
|
1615
|
-
(question) => question.required && isMissingRequiredAnswer(question, answers)
|
|
1616
|
-
);
|
|
1905
|
+
const missingQuestions = getMissingRequiredQuestions(questionnaire, answers, otherDrafts);
|
|
1617
1906
|
if (missingQuestions.length > 0) {
|
|
1618
1907
|
setErrorMessage(
|
|
1619
|
-
`${resolvedLabels.validationPrefix} ${missingQuestions.map((
|
|
1908
|
+
`${resolvedLabels.validationPrefix} ${missingQuestions.map((question2) => question2.label).join(", ")}`
|
|
1620
1909
|
);
|
|
1621
1910
|
return;
|
|
1622
1911
|
}
|
|
1623
1912
|
setErrorMessage(null);
|
|
1624
1913
|
setIsSubmitting(true);
|
|
1625
|
-
const normalizedAnswers =
|
|
1626
|
-
questionnaire
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
})
|
|
1914
|
+
const { normalizedAnswers, submissionDetails, content } = prepareQuestionnaireSubmission(
|
|
1915
|
+
questionnaire,
|
|
1916
|
+
answers,
|
|
1917
|
+
otherDrafts
|
|
1630
1918
|
);
|
|
1631
|
-
const contentLines = [
|
|
1632
|
-
questionnaire.title ?? "Questionnaire responses",
|
|
1633
|
-
...questionnaire.questions.flatMap((question) => {
|
|
1634
|
-
const value = normalizedAnswers[question.id];
|
|
1635
|
-
if (value === void 0) {
|
|
1636
|
-
return [];
|
|
1637
|
-
}
|
|
1638
|
-
return [`- ${question.label}: ${formatQuestionAnswer(question, value)}`];
|
|
1639
|
-
})
|
|
1640
|
-
];
|
|
1641
1919
|
try {
|
|
1642
1920
|
await onSubmit?.({
|
|
1643
1921
|
questionnaireId: questionnaire.questionnaireId,
|
|
1644
1922
|
...questionnaire.blockKey ? { blockKey: questionnaire.blockKey } : {},
|
|
1645
1923
|
answers: normalizedAnswers,
|
|
1646
|
-
|
|
1924
|
+
details: submissionDetails,
|
|
1925
|
+
content
|
|
1647
1926
|
});
|
|
1648
1927
|
setIsSubmitted(true);
|
|
1649
1928
|
} catch (error) {
|
|
@@ -1652,125 +1931,156 @@ var QuestionnaireCardInner = ({
|
|
|
1652
1931
|
setIsSubmitting(false);
|
|
1653
1932
|
}
|
|
1654
1933
|
};
|
|
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
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
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
|
+
}
|
|
1717
2004
|
case "single_select": {
|
|
1718
|
-
const singleSelectDraft = getSingleSelectDraftState(
|
|
2005
|
+
const singleSelectDraft = getSingleSelectDraftState(
|
|
2006
|
+
questionToRender,
|
|
2007
|
+
answers[questionToRender.id],
|
|
2008
|
+
otherDrafts[questionToRender.id] ?? ""
|
|
2009
|
+
);
|
|
1719
2010
|
return /* @__PURE__ */ jsx5(QuestionBody, { children: /* @__PURE__ */ jsxs3(OptionList, { children: [
|
|
1720
|
-
|
|
2011
|
+
questionToRender.options.map((option, index) => {
|
|
1721
2012
|
const isSelected = singleSelectDraft.selectedValue === option.value;
|
|
1722
|
-
return
|
|
1723
|
-
|
|
1724
|
-
optionLabel: option.label,
|
|
1725
|
-
index,
|
|
1726
|
-
isSelected,
|
|
1727
|
-
onClick: () => setAnswers((current) => updateAnswerValue(current, question.id, option.value))
|
|
1728
|
-
});
|
|
1729
|
-
}),
|
|
1730
|
-
question.allowOther ? renderOptionChoice({
|
|
1731
|
-
questionId: question.id,
|
|
1732
|
-
optionLabel: "Other",
|
|
1733
|
-
index: question.options.length,
|
|
1734
|
-
isSelected: singleSelectDraft.selectedValue === OTHER_OPTION_VALUE,
|
|
1735
|
-
tone: "other",
|
|
1736
|
-
onClick: () => setAnswers(
|
|
1737
|
-
(current) => updateAnswerValue(current, question.id, singleSelectDraft.otherValue)
|
|
1738
|
-
),
|
|
1739
|
-
inlineInput: singleSelectDraft.selectedValue === OTHER_OPTION_VALUE ? /* @__PURE__ */ jsx5(
|
|
1740
|
-
InlineOtherInput,
|
|
2013
|
+
return /* @__PURE__ */ jsx5(
|
|
2014
|
+
OptionChoice,
|
|
1741
2015
|
{
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
onClick: (
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
|
|
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);
|
|
1757
2040
|
}
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
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
|
|
1761
2069
|
] }) });
|
|
1762
2070
|
}
|
|
1763
2071
|
case "text":
|
|
1764
2072
|
return /* @__PURE__ */ jsx5(QuestionBody, { children: /* @__PURE__ */ jsx5(
|
|
1765
2073
|
TextInput,
|
|
1766
2074
|
{
|
|
1767
|
-
"data-testid": `question-input-${
|
|
2075
|
+
"data-testid": `question-input-${questionToRender.id}`,
|
|
1768
2076
|
type: "text",
|
|
1769
|
-
value: getTextInputValue(answers[
|
|
1770
|
-
placeholder:
|
|
2077
|
+
value: getTextInputValue(answers[questionToRender.id]),
|
|
2078
|
+
placeholder: questionToRender.placeholder,
|
|
1771
2079
|
readOnly: isInteractionLocked,
|
|
1772
2080
|
onChange: (event) => {
|
|
1773
|
-
setAnswers(
|
|
2081
|
+
setAnswers(
|
|
2082
|
+
(current) => updateAnswerValue(current, questionToRender.id, event.target.value)
|
|
2083
|
+
);
|
|
1774
2084
|
}
|
|
1775
2085
|
}
|
|
1776
2086
|
) });
|
|
@@ -1779,55 +2089,63 @@ var QuestionnaireCardInner = ({
|
|
|
1779
2089
|
/* @__PURE__ */ jsx5(
|
|
1780
2090
|
TextInput,
|
|
1781
2091
|
{
|
|
1782
|
-
"data-testid": `question-input-${
|
|
2092
|
+
"data-testid": `question-input-${questionToRender.id}`,
|
|
1783
2093
|
type: "number",
|
|
1784
|
-
value: getNumberInputValue(answers[
|
|
1785
|
-
placeholder:
|
|
2094
|
+
value: getNumberInputValue(answers[questionToRender.id]),
|
|
2095
|
+
placeholder: questionToRender.placeholder,
|
|
1786
2096
|
readOnly: isInteractionLocked,
|
|
1787
2097
|
onChange: (event) => {
|
|
1788
2098
|
setAnswers(
|
|
1789
2099
|
(current) => updateAnswerValue(
|
|
1790
2100
|
current,
|
|
1791
|
-
|
|
2101
|
+
questionToRender.id,
|
|
1792
2102
|
event.target.value === "" ? void 0 : Number(event.target.value)
|
|
1793
2103
|
)
|
|
1794
2104
|
);
|
|
1795
2105
|
}
|
|
1796
2106
|
}
|
|
1797
2107
|
),
|
|
1798
|
-
|
|
2108
|
+
questionToRender.unit ? /* @__PURE__ */ jsx5(Unit, { children: questionToRender.unit }) : null
|
|
1799
2109
|
] }) });
|
|
1800
2110
|
case "boolean":
|
|
1801
2111
|
return /* @__PURE__ */ jsx5(QuestionBody, { children: /* @__PURE__ */ jsxs3(OptionList, { children: [
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
|
|
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
|
+
)
|
|
1816
2134
|
] }) });
|
|
1817
2135
|
default:
|
|
1818
2136
|
return null;
|
|
1819
2137
|
}
|
|
1820
2138
|
};
|
|
1821
2139
|
return /* @__PURE__ */ jsxs3(Card4, { "data-testid": "questionnaire-card", children: [
|
|
1822
|
-
questionnaire.title ? /* @__PURE__ */ jsx5(Title3, { children: questionnaire.title }) : null,
|
|
1823
2140
|
questionnaire.description ? /* @__PURE__ */ jsx5(Description, { children: questionnaire.description }) : null,
|
|
1824
|
-
/* @__PURE__ */ jsx5(QuestionList, { children:
|
|
2141
|
+
/* @__PURE__ */ jsx5(QuestionList, { children: /* @__PURE__ */ jsxs3(QuestionCard, { children: [
|
|
1825
2142
|
/* @__PURE__ */ jsxs3(QuestionLabel, { children: [
|
|
1826
2143
|
question.label,
|
|
1827
2144
|
question.required ? /* @__PURE__ */ jsx5(Required, { children: "*" }) : null
|
|
1828
2145
|
] }),
|
|
2146
|
+
question.kind === "multi_select" ? /* @__PURE__ */ jsx5(QuestionHint, { children: resolvedLabels.multiSelectHint }) : null,
|
|
1829
2147
|
renderQuestion(question)
|
|
1830
|
-
] }, question.id)
|
|
2148
|
+
] }, question.id) }),
|
|
1831
2149
|
visibleErrorMessage ? /* @__PURE__ */ jsx5(ErrorMessage, { "data-testid": "questionnaire-error", children: visibleErrorMessage }) : null,
|
|
1832
2150
|
isSubmitted ? /* @__PURE__ */ jsx5(SuccessMessage, { "data-testid": "questionnaire-success", children: resolvedLabels.submitted }) : interactive && !hasExternalFailureStatus ? /* @__PURE__ */ jsx5(
|
|
1833
2151
|
SubmitButton,
|
|
@@ -1843,12 +2161,6 @@ var QuestionnaireCardInner = ({
|
|
|
1843
2161
|
) : null
|
|
1844
2162
|
] });
|
|
1845
2163
|
};
|
|
1846
|
-
var getQuestionnaireStateKey = (questionnaire) => JSON.stringify([
|
|
1847
|
-
questionnaire.questionnaireId,
|
|
1848
|
-
questionnaire.questions,
|
|
1849
|
-
questionnaire.status,
|
|
1850
|
-
questionnaire.statusMessage
|
|
1851
|
-
]);
|
|
1852
2164
|
var QuestionnaireCard = (props) => /* @__PURE__ */ jsx5(QuestionnaireCardInner, { ...props }, getQuestionnaireStateKey(props.questionnaire));
|
|
1853
2165
|
var Card4 = styled4.section`
|
|
1854
2166
|
display: grid;
|
|
@@ -1858,11 +2170,6 @@ var Card4 = styled4.section`
|
|
|
1858
2170
|
border: 1px solid rgba(255, 255, 255, 0.08);
|
|
1859
2171
|
background: rgba(255, 255, 255, 0.03);
|
|
1860
2172
|
`;
|
|
1861
|
-
var Title3 = styled4.strong`
|
|
1862
|
-
color: rgba(255, 255, 255, 0.94);
|
|
1863
|
-
font-size: 16px;
|
|
1864
|
-
line-height: 1.4;
|
|
1865
|
-
`;
|
|
1866
2173
|
var Description = styled4.p`
|
|
1867
2174
|
margin: 0;
|
|
1868
2175
|
color: rgba(255, 255, 255, 0.72);
|
|
@@ -1881,13 +2188,18 @@ var QuestionCard = styled4.div`
|
|
|
1881
2188
|
`;
|
|
1882
2189
|
var QuestionLabel = styled4.div`
|
|
1883
2190
|
color: rgba(255, 255, 255, 0.9);
|
|
1884
|
-
font-size:
|
|
2191
|
+
font-size: 14px;
|
|
1885
2192
|
font-weight: 600;
|
|
1886
2193
|
`;
|
|
1887
2194
|
var Required = styled4.span`
|
|
1888
2195
|
margin-left: 4px;
|
|
1889
2196
|
color: rgba(255, 122, 122, 0.9);
|
|
1890
2197
|
`;
|
|
2198
|
+
var QuestionHint = styled4.div`
|
|
2199
|
+
color: rgba(132, 180, 255, 0.9);
|
|
2200
|
+
font-size: 12px;
|
|
2201
|
+
line-height: 1.4;
|
|
2202
|
+
`;
|
|
1891
2203
|
var QuestionBody = styled4.div`
|
|
1892
2204
|
display: grid;
|
|
1893
2205
|
gap: 10px;
|
|
@@ -1905,7 +2217,7 @@ var OptionChoiceItem = styled4.div`
|
|
|
1905
2217
|
border: 1px solid rgba(255, 255, 255, 0.1);
|
|
1906
2218
|
border-radius: 14px;
|
|
1907
2219
|
background: rgba(255, 255, 255, 0.03);
|
|
1908
|
-
padding: 12px
|
|
2220
|
+
padding: 2px 12px;
|
|
1909
2221
|
color: rgba(255, 255, 255, 0.9);
|
|
1910
2222
|
cursor: pointer;
|
|
1911
2223
|
transition:
|
|
@@ -1956,8 +2268,11 @@ var OptionChoiceMarker = styled4.span`
|
|
|
1956
2268
|
}
|
|
1957
2269
|
`;
|
|
1958
2270
|
var OptionChoiceContent = styled4.span`
|
|
1959
|
-
display:
|
|
1960
|
-
|
|
2271
|
+
display: flex;
|
|
2272
|
+
flex-direction: column;
|
|
2273
|
+
justify-content: center;
|
|
2274
|
+
gap: 4px;
|
|
2275
|
+
min-height: 40px;
|
|
1961
2276
|
min-width: 0;
|
|
1962
2277
|
flex: 1;
|
|
1963
2278
|
`;
|
|
@@ -1980,8 +2295,37 @@ var TextInput = styled4.input`
|
|
|
1980
2295
|
color: rgba(255, 255, 255, 0.34);
|
|
1981
2296
|
}
|
|
1982
2297
|
`;
|
|
1983
|
-
var InlineOtherInput = styled4(
|
|
2298
|
+
var InlineOtherInput = styled4(InputField)`
|
|
2299
|
+
width: 100%;
|
|
1984
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
|
+
}
|
|
1985
2329
|
`;
|
|
1986
2330
|
var NumberInputRow = styled4.div`
|
|
1987
2331
|
display: flex;
|
|
@@ -2067,7 +2411,7 @@ var Detail = styled5.li`
|
|
|
2067
2411
|
|
|
2068
2412
|
// src/components/chat-thread/components/image-viewer.tsx
|
|
2069
2413
|
import styled6 from "@emotion/styled";
|
|
2070
|
-
import { useEffect as
|
|
2414
|
+
import { useEffect as useEffect4, useRef as useRef4 } from "react";
|
|
2071
2415
|
import { jsx as jsx7 } from "@emotion/react/jsx-runtime";
|
|
2072
2416
|
var Overlay = styled6.div`
|
|
2073
2417
|
position: fixed;
|
|
@@ -2086,8 +2430,8 @@ var Img = styled6.img`
|
|
|
2086
2430
|
border-radius: 4px;
|
|
2087
2431
|
`;
|
|
2088
2432
|
var ImageViewer = ({ src, alt, onClose }) => {
|
|
2089
|
-
const overlayRef =
|
|
2090
|
-
|
|
2433
|
+
const overlayRef = useRef4(null);
|
|
2434
|
+
useEffect4(() => {
|
|
2091
2435
|
const handleKey = (e) => {
|
|
2092
2436
|
if (e.key === "Escape")
|
|
2093
2437
|
onClose();
|
|
@@ -2095,7 +2439,7 @@ var ImageViewer = ({ src, alt, onClose }) => {
|
|
|
2095
2439
|
document.addEventListener("keydown", handleKey);
|
|
2096
2440
|
return () => document.removeEventListener("keydown", handleKey);
|
|
2097
2441
|
}, [onClose]);
|
|
2098
|
-
|
|
2442
|
+
useEffect4(() => {
|
|
2099
2443
|
overlayRef.current?.focus();
|
|
2100
2444
|
}, []);
|
|
2101
2445
|
const stopPropagation = (e) => e.stopPropagation();
|
|
@@ -2290,9 +2634,7 @@ var arePlanQuestionsEqual = (previousQuestion, nextQuestion) => {
|
|
|
2290
2634
|
return false;
|
|
2291
2635
|
}
|
|
2292
2636
|
};
|
|
2293
|
-
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.
|
|
2294
|
-
(question, index) => arePlanQuestionsEqual(question, nextQuestionnaire.questions[index])
|
|
2295
|
-
) && 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);
|
|
2296
2638
|
var areMessageBlocksEqual = (previousBlocks, nextBlocks) => {
|
|
2297
2639
|
if (previousBlocks === nextBlocks) {
|
|
2298
2640
|
return true;
|
|
@@ -2446,7 +2788,10 @@ var ChatMessageItemView = ({
|
|
|
2446
2788
|
submitting: labels.questionnaireSubmitting,
|
|
2447
2789
|
submitted: labels.questionnaireSubmitted,
|
|
2448
2790
|
validationPrefix: labels.questionnaireValidationPrefix,
|
|
2449
|
-
submitFailed: labels.questionnaireSubmitFailed
|
|
2791
|
+
submitFailed: labels.questionnaireSubmitFailed,
|
|
2792
|
+
multiSelectHint: labels.questionnaireMultiSelectHint,
|
|
2793
|
+
otherOptionLabel: labels.questionnaireOtherOptionLabel,
|
|
2794
|
+
otherPlaceholder: labels.questionnaireOtherPlaceholder
|
|
2450
2795
|
},
|
|
2451
2796
|
onSubmit: canSubmitQuestionnaire ? (submission) => onQuestionnaireSubmit({
|
|
2452
2797
|
...submission,
|
|
@@ -2705,8 +3050,34 @@ var CollapseToggle = styled7.button`
|
|
|
2705
3050
|
`;
|
|
2706
3051
|
var Content = styled7.div`
|
|
2707
3052
|
color: rgba(255, 255, 255, 0.92);
|
|
3053
|
+
font-size: 14px;
|
|
2708
3054
|
line-height: 1.6;
|
|
2709
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
|
+
|
|
2710
3081
|
p {
|
|
2711
3082
|
margin: 0;
|
|
2712
3083
|
}
|
|
@@ -2718,7 +3089,7 @@ var Content = styled7.div`
|
|
|
2718
3089
|
table {
|
|
2719
3090
|
width: 100%;
|
|
2720
3091
|
border-collapse: collapse;
|
|
2721
|
-
margin: 0;
|
|
3092
|
+
margin: 8px 0 0;
|
|
2722
3093
|
overflow: hidden;
|
|
2723
3094
|
border-radius: 14px;
|
|
2724
3095
|
border: 1px solid rgba(255, 255, 255, 0.08);
|
|
@@ -2742,6 +3113,10 @@ var Content = styled7.div`
|
|
|
2742
3113
|
tbody tr:last-of-type td {
|
|
2743
3114
|
border-bottom: none;
|
|
2744
3115
|
}
|
|
3116
|
+
ul,
|
|
3117
|
+
ol {
|
|
3118
|
+
margin: 0 0 8px;
|
|
3119
|
+
}
|
|
2745
3120
|
`;
|
|
2746
3121
|
var ContentStack = styled7.div`
|
|
2747
3122
|
display: flex;
|
|
@@ -3020,7 +3395,7 @@ var ChatThreadView = ({
|
|
|
3020
3395
|
onQuestionnaireSubmit,
|
|
3021
3396
|
renderMessageBlock
|
|
3022
3397
|
}) => {
|
|
3023
|
-
const containerRef =
|
|
3398
|
+
const containerRef = useRef5(null);
|
|
3024
3399
|
const conversationTurns = useMemo4(
|
|
3025
3400
|
() => groupConversationTurns(historyMessages, streamingMessage),
|
|
3026
3401
|
[historyMessages, streamingMessage]
|
|
@@ -3028,8 +3403,8 @@ var ChatThreadView = ({
|
|
|
3028
3403
|
const latestTurn = conversationTurns[conversationTurns.length - 1];
|
|
3029
3404
|
const previousTurns = conversationTurns.slice(0, -1);
|
|
3030
3405
|
const latestUserMessageId = latestTurn?.userMessage?.id;
|
|
3031
|
-
const latestUserMessageRef =
|
|
3032
|
-
const reservedSpaceFrameRef =
|
|
3406
|
+
const latestUserMessageRef = useRef5(null);
|
|
3407
|
+
const reservedSpaceFrameRef = useRef5(null);
|
|
3033
3408
|
const [latestTurnMinHeight, setLatestTurnMinHeight] = useState4(0);
|
|
3034
3409
|
const measureLatestTurnMinHeight = useCallback3(() => {
|
|
3035
3410
|
const container = containerRef.current;
|
|
@@ -3317,7 +3692,7 @@ var RetryButton = styled9.button`
|
|
|
3317
3692
|
`;
|
|
3318
3693
|
|
|
3319
3694
|
// src/components/chat-composer/index.tsx
|
|
3320
|
-
import { useEffect as
|
|
3695
|
+
import { useEffect as useEffect7, useLayoutEffect as useLayoutEffect3, useRef as useRef8, useState as useState8 } from "react";
|
|
3321
3696
|
import styled14 from "@emotion/styled";
|
|
3322
3697
|
|
|
3323
3698
|
// src/components/chat-composer/lib/chat-composer.ts
|
|
@@ -3429,10 +3804,10 @@ var resolveSendSession = ({
|
|
|
3429
3804
|
};
|
|
3430
3805
|
|
|
3431
3806
|
// src/components/chat-composer/hooks/use-chat-composer.ts
|
|
3432
|
-
import { useCallback as useCallback4, useEffect as
|
|
3807
|
+
import { useCallback as useCallback4, useEffect as useEffect6, useRef as useRef7, useState as useState6 } from "react";
|
|
3433
3808
|
|
|
3434
3809
|
// src/components/chat-composer/hooks/use-composer-attachments.ts
|
|
3435
|
-
import { useEffect as
|
|
3810
|
+
import { useEffect as useEffect5, useRef as useRef6, useState as useState5 } from "react";
|
|
3436
3811
|
var SUPPORTED_IMAGE_MIME_TYPES = /* @__PURE__ */ new Set(["image/png", "image/jpeg", "image/webp"]);
|
|
3437
3812
|
var MAX_COMPOSER_ATTACHMENTS = 10;
|
|
3438
3813
|
var createObjectUrl = (file) => typeof URL !== "undefined" && typeof URL.createObjectURL === "function" ? URL.createObjectURL(file) : "";
|
|
@@ -3447,11 +3822,11 @@ var releaseComposerAttachments = (attachments) => {
|
|
|
3447
3822
|
};
|
|
3448
3823
|
var useComposerAttachments = () => {
|
|
3449
3824
|
const [attachments, setAttachments] = useState5([]);
|
|
3450
|
-
const attachmentsRef =
|
|
3451
|
-
|
|
3825
|
+
const attachmentsRef = useRef6([]);
|
|
3826
|
+
useEffect5(() => {
|
|
3452
3827
|
attachmentsRef.current = attachments;
|
|
3453
3828
|
}, [attachments]);
|
|
3454
|
-
|
|
3829
|
+
useEffect5(
|
|
3455
3830
|
() => () => {
|
|
3456
3831
|
releaseComposerAttachments(attachmentsRef.current);
|
|
3457
3832
|
},
|
|
@@ -3579,7 +3954,7 @@ var useChatComposer = () => {
|
|
|
3579
3954
|
setIsModelsLoading(false);
|
|
3580
3955
|
}
|
|
3581
3956
|
}, [transport]);
|
|
3582
|
-
|
|
3957
|
+
useEffect6(() => {
|
|
3583
3958
|
void fetchModels();
|
|
3584
3959
|
}, [fetchModels]);
|
|
3585
3960
|
const hasModels = availableModels.length > 0;
|
|
@@ -3588,22 +3963,22 @@ var useChatComposer = () => {
|
|
|
3588
3963
|
const [selectedMode, setSelectedModeLocal] = useState6(DEFAULT_CHAT_AGENT_MODE);
|
|
3589
3964
|
const [attachmentNotice, setAttachmentNotice] = useState6(null);
|
|
3590
3965
|
const { attachments, appendFiles, removeAttachment, takeMessageAttachments } = useComposerAttachments();
|
|
3591
|
-
const abortControllerRef =
|
|
3592
|
-
const stopRequestRef =
|
|
3593
|
-
const lastRequestRef =
|
|
3594
|
-
|
|
3966
|
+
const abortControllerRef = useRef7(null);
|
|
3967
|
+
const stopRequestRef = useRef7(null);
|
|
3968
|
+
const lastRequestRef = useRef7(null);
|
|
3969
|
+
useEffect6(() => {
|
|
3595
3970
|
setSelectedModel(
|
|
3596
3971
|
(current) => resolveSelectedChatModel({ currentModel: current, availableModels, isModelsLoading })
|
|
3597
3972
|
);
|
|
3598
3973
|
}, [availableModels, isModelsLoading]);
|
|
3599
|
-
|
|
3974
|
+
useEffect6(() => {
|
|
3600
3975
|
if (activeSession) {
|
|
3601
3976
|
setSelectedModeLocal(activeSession.mode ?? DEFAULT_CHAT_AGENT_MODE);
|
|
3602
3977
|
return;
|
|
3603
3978
|
}
|
|
3604
3979
|
setSelectedModeLocal(preferredMode ?? DEFAULT_CHAT_AGENT_MODE);
|
|
3605
3980
|
}, [activeSession, preferredMode]);
|
|
3606
|
-
|
|
3981
|
+
useEffect6(() => {
|
|
3607
3982
|
if (!attachmentNotice)
|
|
3608
3983
|
return;
|
|
3609
3984
|
const timeoutId = window.setTimeout(
|
|
@@ -4434,8 +4809,8 @@ var ChatComposerView = ({
|
|
|
4434
4809
|
onStop,
|
|
4435
4810
|
onSend
|
|
4436
4811
|
}) => {
|
|
4437
|
-
const imageInputRef =
|
|
4438
|
-
const inputRef =
|
|
4812
|
+
const imageInputRef = useRef8(null);
|
|
4813
|
+
const inputRef = useRef8(null);
|
|
4439
4814
|
const [isComposerExpandable, setIsComposerExpandable] = useState8(false);
|
|
4440
4815
|
const [isComposerExpanded, setIsComposerExpanded] = useState8(false);
|
|
4441
4816
|
const canSend = canSendChatMessage({
|
|
@@ -4586,7 +4961,7 @@ var ChatComposer = () => {
|
|
|
4586
4961
|
const { labels, sendRef, retryRef, enableImageAttachments } = useChatContext();
|
|
4587
4962
|
const { state, actions } = useChatComposer();
|
|
4588
4963
|
const { send, retry } = actions;
|
|
4589
|
-
|
|
4964
|
+
useEffect7(() => {
|
|
4590
4965
|
sendRef.current = send;
|
|
4591
4966
|
retryRef.current = async () => {
|
|
4592
4967
|
retry();
|
|
@@ -4860,7 +5235,7 @@ var ChatConversationList = () => {
|
|
|
4860
5235
|
};
|
|
4861
5236
|
return /* @__PURE__ */ jsxs12(Container3, { children: [
|
|
4862
5237
|
/* @__PURE__ */ jsxs12(Toolbar, { children: [
|
|
4863
|
-
/* @__PURE__ */ jsx17(
|
|
5238
|
+
/* @__PURE__ */ jsx17(Title3, { children: "Sessions" }),
|
|
4864
5239
|
/* @__PURE__ */ jsx17(CreateButton, { type: "button", "data-testid": "chat-create-session", onClick: handleCreateSession, children: labels.newChat })
|
|
4865
5240
|
] }),
|
|
4866
5241
|
/* @__PURE__ */ jsx17(List2, { "data-testid": "chat-session-list", children: sessions.map((session) => /* @__PURE__ */ jsx17(
|
|
@@ -4889,7 +5264,7 @@ var Toolbar = styled16.div`
|
|
|
4889
5264
|
flex-direction: column;
|
|
4890
5265
|
gap: 12px;
|
|
4891
5266
|
`;
|
|
4892
|
-
var
|
|
5267
|
+
var Title3 = styled16.h2`
|
|
4893
5268
|
margin: 0;
|
|
4894
5269
|
font-size: 14px;
|
|
4895
5270
|
color: var(--text-secondary);
|