lisichatbot 1.3.8 → 1.4.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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/index.js +120 -26
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisichatbot",
3
- "version": "1.3.8",
3
+ "version": "1.4.0",
4
4
  "type": "module",
5
5
  "main": "./src/index.js",
6
6
  "exports": {
package/src/index.js CHANGED
@@ -58,16 +58,18 @@ function scrollToBottom() {
58
58
  function enableNextButton() {
59
59
  if (elements.nextBtn) {
60
60
  elements.nextBtn.disabled = false;
61
- elements.nextBtn.style.opacity = '1';
62
- elements.nextBtn.style.cursor = 'pointer';
61
+ elements.nextBtn.style.setProperty('opacity', '1', 'important');
62
+ elements.nextBtn.style.setProperty('cursor', 'pointer', 'important');
63
+ console.log(' ✅ Next button ENABLED (opacity: 1, cursor: pointer)');
63
64
  }
64
65
  }
65
66
 
66
67
  function disableNextButton() {
67
68
  if (elements.nextBtn) {
68
69
  elements.nextBtn.disabled = true;
69
- elements.nextBtn.style.opacity = '0.5';
70
- elements.nextBtn.style.cursor = 'not-allowed';
70
+ elements.nextBtn.style.setProperty('opacity', '0.5', 'important');
71
+ elements.nextBtn.style.setProperty('cursor', 'not-allowed', 'important');
72
+ console.log(' 🔒 Next button DISABLED (opacity: 0.5, cursor: not-allowed)');
71
73
  }
72
74
  }
73
75
 
@@ -1275,9 +1277,19 @@ function renderTextInput(field, inputType = 'text', inputConfig = {}) {
1275
1277
  }
1276
1278
  }
1277
1279
 
1278
- if (existingValue !== undefined && existingValue !== null) {
1280
+ // FIX: Handle pre-filled values for both validation and non-validation cases
1281
+ const hasValue = existingValue !== undefined && existingValue !== null && existingValue !== '';
1282
+
1283
+ if (hasValue) {
1279
1284
  inputElement.value = existingValue;
1280
- console.log(` ✅ Pre-filled with: ${existingValue}`);
1285
+ console.log(` ✅ Pre-filled with: "${existingValue}"`);
1286
+
1287
+ // Set currentSelection for pre-filled value
1288
+ chatState.currentSelection = {
1289
+ field,
1290
+ value: existingValue,
1291
+ name: existingValue.toString()
1292
+ };
1281
1293
 
1282
1294
  if (hasValidation) {
1283
1295
  const value = parseFloat(existingValue);
@@ -1290,23 +1302,50 @@ function renderTextInput(field, inputType = 'text', inputConfig = {}) {
1290
1302
 
1291
1303
  if (isValid) {
1292
1304
  enableNextButton();
1293
- console.log(` ✅ Pre-filled value is valid: ${value}`);
1305
+ console.log(` ✅ Pre-filled number is valid - Next button enabled`);
1294
1306
  } else {
1295
1307
  disableNextButton();
1296
- console.log(` ❌ Pre-filled value is invalid: ${value}`);
1308
+ console.log(` ❌ Pre-filled number is invalid - Next button disabled`);
1297
1309
  }
1310
+ } else {
1311
+ // ✅ FIX: Enable button for pre-filled text input
1312
+ enableNextButton();
1313
+ console.log(` ✅ Pre-filled text - Next button enabled`);
1298
1314
  }
1299
1315
  } else {
1316
+ // ✅ No pre-filled value - set initial button state
1300
1317
  inputElement.value = '';
1318
+
1319
+ const currentStep = flowData.flow[chatState.step];
1320
+ const inputRequired = currentStep.inputRequired === true;
1321
+
1322
+ if (inputRequired || hasValidation) {
1323
+ disableNextButton();
1324
+ console.log(` 🔒 Empty input (required or has validation) - Next button disabled`);
1325
+ } else {
1326
+ enableNextButton();
1327
+ console.log(` 🔓 Empty input (optional, no validation) - Next button enabled`);
1328
+ }
1301
1329
  }
1302
1330
 
1303
1331
  inputElement.type = inputType === 'number' ? 'number' : 'text';
1304
1332
 
1305
1333
  inputElement.oninput = (e) => {
1306
- const value = inputType === 'number' ? parseFloat(e.target.value) : e.target.value;
1334
+ const rawValue = e.target.value;
1335
+ const value = inputType === 'number' ? parseFloat(rawValue) : rawValue;
1336
+
1337
+ // ✅ FIX: Only set data and currentSelection if value is valid
1338
+ const isEmpty = rawValue === '' || (inputType === 'number' && isNaN(value));
1339
+ const isEmptyText = inputType === 'text' && (!rawValue || rawValue.trim() === '');
1307
1340
 
1308
- chatState.data[field] = value;
1309
- chatState.currentSelection = { field, value, name: value };
1341
+ if (!isEmpty && !isEmptyText) {
1342
+ chatState.data[field] = value;
1343
+ chatState.currentSelection = { field, value, name: value.toString() };
1344
+ } else {
1345
+ // Clear data and selection for empty values
1346
+ delete chatState.data[field];
1347
+ chatState.currentSelection = null;
1348
+ }
1310
1349
 
1311
1350
  if (hasValidation) {
1312
1351
  const min = inputConfig.min;
@@ -1315,7 +1354,7 @@ function renderTextInput(field, inputType = 'text', inputConfig = {}) {
1315
1354
  let isValid = true;
1316
1355
  let errorMessage = '';
1317
1356
 
1318
- if (value === '' || isNaN(value)) {
1357
+ if (rawValue === '' || (inputType === 'number' && isNaN(value))) {
1319
1358
  isValid = false;
1320
1359
  errorMessage = 'Please enter a valid number';
1321
1360
  } else if (min !== undefined && value < min) {
@@ -1328,13 +1367,51 @@ function renderTextInput(field, inputType = 'text', inputConfig = {}) {
1328
1367
 
1329
1368
  if (isValid) {
1330
1369
  enableNextButton();
1331
- console.log(` ✅ Number input valid: ${value}`);
1370
+ console.log(` ✅ Number input valid: ${value} - Next button enabled`);
1332
1371
  } else {
1333
1372
  disableNextButton();
1334
- console.log(` ❌ Number input invalid: ${errorMessage}`);
1373
+ console.log(` ❌ Number input invalid: ${errorMessage} - Next button disabled`);
1335
1374
  }
1336
1375
  } else {
1337
- console.log(` 📝 Input updated: ${value} (no validation)`);
1376
+ // FIX: Handle number inputs without validation
1377
+ if (inputType === 'number') {
1378
+ // For number inputs, check if value is valid
1379
+ if (rawValue === '' || isNaN(value)) {
1380
+ // Empty or NaN
1381
+ const currentStep = flowData.flow[chatState.step];
1382
+ const inputRequired = currentStep.inputRequired === true;
1383
+
1384
+ if (inputRequired) {
1385
+ disableNextButton();
1386
+ console.log(` 🔒 Number input empty/NaN and required - Next button disabled`);
1387
+ } else {
1388
+ enableNextButton();
1389
+ console.log(` 🔓 Number input empty/NaN but not required - Next button enabled`);
1390
+ }
1391
+ } else {
1392
+ // Has valid number value
1393
+ enableNextButton();
1394
+ console.log(` ✅ Number input has value: ${value} - Next button enabled`);
1395
+ }
1396
+ } else {
1397
+ // Text input logic
1398
+ if (rawValue && rawValue.trim() !== '') {
1399
+ enableNextButton();
1400
+ console.log(` ✅ Text input has value - Next button enabled`);
1401
+ } else {
1402
+ // ✅ Check if input is required
1403
+ const currentStep = flowData.flow[chatState.step];
1404
+ const inputRequired = currentStep.inputRequired === true;
1405
+
1406
+ if (inputRequired) {
1407
+ disableNextButton();
1408
+ console.log(` 🔒 Text input empty and required - Next button disabled`);
1409
+ } else {
1410
+ enableNextButton();
1411
+ console.log(` 🔓 Text input empty but not required - Next button enabled`);
1412
+ }
1413
+ }
1414
+ }
1338
1415
  }
1339
1416
  };
1340
1417
  }
@@ -1472,6 +1549,33 @@ async function handleNext() {
1472
1549
  console.log('Selection required but none made');
1473
1550
  return;
1474
1551
  }
1552
+
1553
+ // ✅ FIX: Validate text/number inputs when required
1554
+ if (currentStep.input && inputRequired) {
1555
+ const inputType = currentStep.inputType || 'single-select';
1556
+
1557
+ if (inputType === 'text' || inputType === 'number') {
1558
+ const field = currentStep.input.field;
1559
+ const value = chatState.data[field];
1560
+
1561
+ // Check for empty or invalid values
1562
+ if (inputType === 'text') {
1563
+ if (value === undefined || value === null || value === '' || (typeof value === 'string' && value.trim() === '')) {
1564
+ console.log('❌ Text input required but empty - cannot proceed');
1565
+ disableNextButton();
1566
+ return;
1567
+ }
1568
+ } else if (inputType === 'number') {
1569
+ if (value === undefined || value === null || value === '' || isNaN(value)) {
1570
+ console.log('❌ Number input required but empty/NaN - cannot proceed');
1571
+ disableNextButton();
1572
+ return;
1573
+ }
1574
+ }
1575
+
1576
+ console.log(`✅ ${inputType} input validation passed:`, value);
1577
+ }
1578
+ }
1475
1579
 
1476
1580
  if (currentStep.inputType === 'single-select-custom' && currentStep.input) {
1477
1581
  const field = currentStep.input.field;
@@ -1655,18 +1759,8 @@ async function showNextStep() {
1655
1759
  const inputType = nextStep.inputType || 'single-select';
1656
1760
 
1657
1761
  if (inputType === 'text' || inputType === 'number') {
1762
+ // ✅ renderTextInput handles ALL button state logic (pre-filled, typing, validation)
1658
1763
  renderTextInput(nextStep.input.field, inputType, nextStep.input);
1659
-
1660
- const hasValidation = inputType === 'number' &&
1661
- (nextStep.input.min !== undefined || nextStep.input.max !== undefined);
1662
-
1663
- if (inputRequired || hasValidation) {
1664
- disableNextButton();
1665
- console.log(' 🔒 Next button disabled initially (input required or validation enabled)');
1666
- } else {
1667
- enableNextButton();
1668
- console.log(' 🔓 Next button enabled (optional input, no validation)');
1669
- }
1670
1764
  } else if (inputType === 'multi-select-color') {
1671
1765
  renderColorOptions(nextStep.input.options, nextStep.input.field);
1672
1766