lisichatbot 1.4.1 → 1.4.3
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/package.json +1 -1
- package/src/index.js +113 -14
package/package.json
CHANGED
package/src/index.js
CHANGED
|
@@ -1094,7 +1094,52 @@ function handleCustomSelectClick(element, field, customConfig) {
|
|
|
1094
1094
|
|
|
1095
1095
|
console.log(`Custom-select clicked:`, { field, name: optionName, isCustom });
|
|
1096
1096
|
|
|
1097
|
+
// ✅ FIX: Check if this option is already selected - allow deselection
|
|
1098
|
+
const isAlreadySelected = element.classList.contains('cf-checked');
|
|
1099
|
+
|
|
1097
1100
|
const allOptions = document.querySelectorAll(`[data-field="${field}"][data-chat-element="single-select-input"]`);
|
|
1101
|
+
|
|
1102
|
+
if (isAlreadySelected) {
|
|
1103
|
+
// ✅ Deselect the currently selected option
|
|
1104
|
+
console.log(` 🔄 Deselecting "${optionName}"`);
|
|
1105
|
+
|
|
1106
|
+
element.classList.remove('cf-checked');
|
|
1107
|
+
element.style.setProperty('background-color', 'transparent', 'important');
|
|
1108
|
+
const tickIcon = element.querySelector('[data-chat-input-element="tick-icon"]');
|
|
1109
|
+
if (tickIcon) tickIcon.style.setProperty('display', 'none', 'important');
|
|
1110
|
+
|
|
1111
|
+
// Hide range wrapper if custom was deselected
|
|
1112
|
+
if (isCustom) {
|
|
1113
|
+
const rangeWrapper = document.querySelector(`[data-chat-element="range-wrapper"][data-field="${field}"]`);
|
|
1114
|
+
if (rangeWrapper) {
|
|
1115
|
+
rangeWrapper.style.display = 'none';
|
|
1116
|
+
}
|
|
1117
|
+
}
|
|
1118
|
+
|
|
1119
|
+
// Clear data
|
|
1120
|
+
delete chatState.data[field];
|
|
1121
|
+
chatState.currentSelection = null;
|
|
1122
|
+
|
|
1123
|
+
console.log(` ❌ Deselected "${optionName}" - No selection`);
|
|
1124
|
+
|
|
1125
|
+
// ✅ Check if input is required - disable button if nothing selected
|
|
1126
|
+
const currentStep = flowData.flow[chatState.step];
|
|
1127
|
+
const inputRequired = currentStep.inputRequired === true;
|
|
1128
|
+
|
|
1129
|
+
if (inputRequired) {
|
|
1130
|
+
disableNextButton();
|
|
1131
|
+
console.log(' 🔒 Input required - Next button disabled');
|
|
1132
|
+
} else {
|
|
1133
|
+
enableNextButton();
|
|
1134
|
+
console.log(' 🔓 Input not required - Next button still enabled');
|
|
1135
|
+
}
|
|
1136
|
+
|
|
1137
|
+
return; // Exit early
|
|
1138
|
+
}
|
|
1139
|
+
|
|
1140
|
+
// ✅ Select this option (deselect others first)
|
|
1141
|
+
console.log(` ✅ Selecting "${optionName}"`);
|
|
1142
|
+
|
|
1098
1143
|
allOptions.forEach(opt => {
|
|
1099
1144
|
opt.classList.remove('cf-checked');
|
|
1100
1145
|
opt.style.setProperty('background-color', 'transparent', 'important');
|
|
@@ -1542,27 +1587,63 @@ function handleOptionClick(element, field, isSingleSelect) {
|
|
|
1542
1587
|
}
|
|
1543
1588
|
|
|
1544
1589
|
if (isSingleSelect) {
|
|
1590
|
+
// ✅ FIX: Check if this option is already selected - allow deselection
|
|
1591
|
+
const isAlreadySelected = element.classList.contains('cf-checked');
|
|
1592
|
+
|
|
1545
1593
|
const selector = `[data-field="${field}"][data-chat-element="${inputType}"]`;
|
|
1546
1594
|
const allOptions = document.querySelectorAll(selector);
|
|
1547
1595
|
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1596
|
+
if (isAlreadySelected) {
|
|
1597
|
+
// ✅ Deselect the currently selected option
|
|
1598
|
+
console.log(` 🔄 Deselecting "${optionName}"`);
|
|
1551
1599
|
|
|
1552
|
-
|
|
1553
|
-
|
|
1600
|
+
element.classList.remove('cf-checked');
|
|
1601
|
+
element.style.setProperty('background-color', 'transparent', 'important');
|
|
1602
|
+
if (tickIcon) tickIcon.style.setProperty('display', 'none', 'important');
|
|
1603
|
+
if (input) input.checked = false;
|
|
1554
1604
|
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1605
|
+
// Clear data
|
|
1606
|
+
delete chatState.data[field];
|
|
1607
|
+
chatState.currentSelection = null;
|
|
1608
|
+
|
|
1609
|
+
console.log(` ❌ Deselected "${optionName}" - No selection`);
|
|
1610
|
+
|
|
1611
|
+
// ✅ Check if input is required - disable button if nothing selected
|
|
1612
|
+
const currentStep = flowData.flow[chatState.step];
|
|
1613
|
+
const inputRequired = currentStep.inputRequired === true;
|
|
1614
|
+
|
|
1615
|
+
if (inputRequired) {
|
|
1616
|
+
disableNextButton();
|
|
1617
|
+
console.log(' 🔒 Input required - Next button disabled');
|
|
1618
|
+
} else {
|
|
1619
|
+
enableNextButton();
|
|
1620
|
+
console.log(' 🔓 Input not required - Next button still enabled');
|
|
1621
|
+
}
|
|
1622
|
+
} else {
|
|
1623
|
+
// ✅ Select this option (deselect others first)
|
|
1624
|
+
console.log(` ✅ Selecting "${optionName}"`);
|
|
1625
|
+
|
|
1626
|
+
allOptions.forEach(opt => {
|
|
1627
|
+
opt.classList.remove('cf-checked');
|
|
1628
|
+
opt.style.setProperty('background-color', 'transparent', 'important');
|
|
1629
|
+
|
|
1630
|
+
const otherTick = opt.querySelector('[data-chat-input-element="tick-icon"]');
|
|
1631
|
+
const otherInput = opt.querySelector('[data-chat-input-element="input"]');
|
|
1632
|
+
|
|
1633
|
+
if (otherTick) otherTick.style.setProperty('display', 'none', 'important');
|
|
1634
|
+
if (otherInput) otherInput.checked = false;
|
|
1635
|
+
});
|
|
1558
1636
|
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1637
|
+
element.classList.add('cf-checked');
|
|
1638
|
+
element.style.setProperty('background-color', config.selectedBackground, 'important');
|
|
1639
|
+
if (tickIcon) tickIcon.style.setProperty('display', 'block', 'important');
|
|
1640
|
+
if (input) input.checked = true;
|
|
1563
1641
|
|
|
1564
|
-
|
|
1565
|
-
|
|
1642
|
+
chatState.data[field] = value;
|
|
1643
|
+
chatState.currentSelection = { field, value, name: optionName };
|
|
1644
|
+
|
|
1645
|
+
enableNextButton();
|
|
1646
|
+
}
|
|
1566
1647
|
|
|
1567
1648
|
} else {
|
|
1568
1649
|
const isChecked = !element.classList.contains('cf-checked');
|
|
@@ -1734,6 +1815,21 @@ async function handleNext() {
|
|
|
1734
1815
|
}
|
|
1735
1816
|
}
|
|
1736
1817
|
|
|
1818
|
+
// ✅ FIX: Remove old user message for this step (if exists)
|
|
1819
|
+
// This handles cases where user edits and changes/deselects their answer
|
|
1820
|
+
const existingUserMessage = elements.messages.querySelector(
|
|
1821
|
+
`[data-chat-element="user-message-wrapper"][data-chat-step="${chatState.step}"]`
|
|
1822
|
+
);
|
|
1823
|
+
if (existingUserMessage) {
|
|
1824
|
+
existingUserMessage.remove();
|
|
1825
|
+
console.log(` 🗑️ Removed old user message for step ${chatState.step}`);
|
|
1826
|
+
}
|
|
1827
|
+
|
|
1828
|
+
// ✅ FIX: Remove from history for this step
|
|
1829
|
+
chatState.history = chatState.history.filter(h => h.step !== chatState.step);
|
|
1830
|
+
console.log(` 🗑️ Cleared history for step ${chatState.step}`);
|
|
1831
|
+
|
|
1832
|
+
// ✅ Only add new user message if there's a selection
|
|
1737
1833
|
if (chatState.currentSelection) {
|
|
1738
1834
|
const inputConfig = currentStep.input || {};
|
|
1739
1835
|
const valueType = inputConfig.selectedInputValueType;
|
|
@@ -1753,6 +1849,7 @@ async function handleNext() {
|
|
|
1753
1849
|
if (suffix) displayName = `${displayName} ${suffix}`;
|
|
1754
1850
|
|
|
1755
1851
|
addMessage(displayName, 'user', false, chatState.step);
|
|
1852
|
+
console.log(` ✅ Added new user message: "${displayName}"`);
|
|
1756
1853
|
|
|
1757
1854
|
chatState.history.push({
|
|
1758
1855
|
step: chatState.step,
|
|
@@ -1760,6 +1857,8 @@ async function handleNext() {
|
|
|
1760
1857
|
value: chatState.currentSelection.value,
|
|
1761
1858
|
name: displayName
|
|
1762
1859
|
});
|
|
1860
|
+
} else {
|
|
1861
|
+
console.log(` ℹ️ No selection - no user message added (deselected or optional empty)`);
|
|
1763
1862
|
}
|
|
1764
1863
|
|
|
1765
1864
|
chatState.currentSelection = null;
|