lisichatbot 1.2.0 β†’ 1.2.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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/index.js +113 -15
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisichatbot",
3
- "version": "1.2.0",
3
+ "version": "1.2.3",
4
4
  "type": "module",
5
5
  "main": "./src/index.js",
6
6
  "exports": {
package/src/index.js CHANGED
@@ -15,7 +15,9 @@ let chatState = {
15
15
  step: 0,
16
16
  data: {},
17
17
  history: [],
18
- currentSelection: null
18
+ currentSelection: null,
19
+ returnToStep: null, // Track where to return after editing
20
+ completed: false // Track if flow is completed
19
21
  };
20
22
 
21
23
  let elements = {
@@ -88,6 +90,17 @@ function addMessage(content, type = 'bot', hasInput = false, stepNumber = null)
88
90
  // Add step number if provided
89
91
  if (stepNumber !== null) {
90
92
  clone.setAttribute('data-chat-step', stepNumber);
93
+
94
+ // Mark all previous instances of this step as NOT latest
95
+ const previousInstances = elements.messages.querySelectorAll(
96
+ `[data-chat-element="${type}-message-wrapper"][data-chat-step="${stepNumber}"]`
97
+ );
98
+ previousInstances.forEach(prev => {
99
+ prev.removeAttribute('data-chat-latest');
100
+ });
101
+
102
+ // Mark this as the latest instance of this step
103
+ clone.setAttribute('data-chat-latest', 'true');
91
104
  }
92
105
 
93
106
  // Find text element in clone and set content
@@ -110,18 +123,28 @@ function addMessage(content, type = 'bot', hasInput = false, stepNumber = null)
110
123
  editIcon.style.setProperty('display', 'none', 'important');
111
124
  console.log(' βœ“ Edit icon hidden (display: none !important)');
112
125
 
113
- // Only show if this step has input AND it's a PREVIOUS step (not current)
114
- if (hasInput && stepNumber !== null && stepNumber < chatState.step) {
126
+ // Check if this is the latest instance (it should be since we just marked it)
127
+ const isLatest = clone.hasAttribute('data-chat-latest');
128
+
129
+ // Only show if this step has input AND it's a PREVIOUS step AND it's the latest instance
130
+ if (hasInput && stepNumber !== null && stepNumber < chatState.step && isLatest) {
115
131
  editIcon.setAttribute('data-chat-step', stepNumber);
116
132
  editIcon.onclick = (e) => {
117
133
  e.stopPropagation();
134
+ e.preventDefault();
135
+ console.log(`\nπŸ–±οΈ EDIT ICON CLICKED - Step ${stepNumber}`);
136
+ console.log(` Current step: ${chatState.step}`);
137
+ console.log(` Calling editStep(${stepNumber})...`);
118
138
  editStep(stepNumber);
119
139
  };
120
140
  editIcon.style.setProperty('display', 'block', 'important');
121
141
  editIcon.style.setProperty('margin-left', '8px', 'important');
122
- console.log(` ✏️ Edit icon SHOWN (step ${stepNumber} is previous step with input)`);
142
+ editIcon.style.setProperty('cursor', 'pointer', 'important');
143
+ console.log(` ✏️ Edit icon SHOWN (step ${stepNumber} is latest previous step with input)`);
123
144
  } else if (hasInput && stepNumber === chatState.step) {
124
145
  console.log(` ⏸️ Edit icon HIDDEN (step ${stepNumber} is CURRENT step)`);
146
+ } else if (!isLatest && hasInput && stepNumber < chatState.step) {
147
+ console.log(` πŸ“œ Edit icon HIDDEN (step ${stepNumber} is OLD instance)`);
125
148
  } else {
126
149
  console.log(` βšͺ Edit icon HIDDEN (step ${stepNumber || 'N/A'} has no input)`);
127
150
  }
@@ -149,8 +172,10 @@ function addMessage(content, type = 'bot', hasInput = false, stepNumber = null)
149
172
  editIconAfterAppend.style.setProperty('display', 'none', 'important');
150
173
  editIconAfterAppend.style.setProperty('margin-left', '8px', 'important');
151
174
 
152
- // Only show if has input AND it's a previous step
153
- if (hasInput && stepNumber !== null && stepNumber < chatState.step) {
175
+ const isLatest = clone.hasAttribute('data-chat-latest');
176
+
177
+ // Only show if has input AND it's a previous step AND it's latest instance
178
+ if (hasInput && stepNumber !== null && stepNumber < chatState.step && isLatest) {
154
179
  editIconAfterAppend.style.setProperty('display', 'block', 'important');
155
180
 
156
181
  // Debug: Check spacing
@@ -174,24 +199,46 @@ function updateEditIcons() {
174
199
  // Find all rendered bot message wrappers
175
200
  const allBotMessages = elements.messages.querySelectorAll('[data-chat-element="bot-message-wrapper"]');
176
201
 
177
- console.log(`\nπŸ”„ Updating edit icons - Current step: ${chatState.step}`);
202
+ console.log(`\nπŸ”„ Updating edit icons - Current step: ${chatState.step}, Completed: ${chatState.completed}`);
178
203
 
179
204
  allBotMessages.forEach(wrapper => {
180
205
  const stepNumber = parseInt(wrapper.getAttribute('data-chat-step'));
181
206
  const editIcon = wrapper.querySelector('[data-chat-element="bot-edit-icon"]');
207
+ const isLatest = wrapper.hasAttribute('data-chat-latest');
182
208
 
183
209
  if (editIcon && !isNaN(stepNumber)) {
184
210
  // Check if this step has input by looking at the flow
185
211
  const stepData = flowData.flow[stepNumber];
186
212
  const hasInput = stepData && !!stepData.input;
187
213
 
188
- // Show icon if: has input AND is previous step
189
- if (hasInput && stepNumber < chatState.step) {
214
+ // Hide ALL icons if flow is completed
215
+ if (chatState.completed) {
216
+ editIcon.style.setProperty('display', 'none', 'important');
217
+ console.log(` 🏁 Step ${stepNumber}: Icon HIDDEN (flow completed)`);
218
+ return;
219
+ }
220
+
221
+ // Only show icon if: has input AND is previous step AND is latest instance
222
+ if (hasInput && stepNumber < chatState.step && isLatest) {
223
+ // Set onclick handler
224
+ editIcon.onclick = (e) => {
225
+ e.stopPropagation();
226
+ e.preventDefault();
227
+ console.log(`\nπŸ–±οΈ EDIT ICON CLICKED (from updateEditIcons) - Step ${stepNumber}`);
228
+ console.log(` Current step: ${chatState.step}`);
229
+ console.log(` Calling editStep(${stepNumber})...`);
230
+ editStep(stepNumber);
231
+ };
232
+ editIcon.setAttribute('data-chat-step', stepNumber);
190
233
  editIcon.style.setProperty('display', 'block', 'important');
191
- console.log(` ✏️ Step ${stepNumber}: Icon SHOWN (previous step)`);
234
+ editIcon.style.setProperty('cursor', 'pointer', 'important');
235
+ editIcon.style.setProperty('margin-left', '8px', 'important');
236
+ console.log(` ✏️ Step ${stepNumber}: Icon SHOWN (latest previous step)`);
192
237
  } else {
193
238
  editIcon.style.setProperty('display', 'none', 'important');
194
- if (stepNumber === chatState.step) {
239
+ if (!isLatest && hasInput && stepNumber < chatState.step) {
240
+ console.log(` πŸ“œ Step ${stepNumber}: Icon HIDDEN (old instance)`);
241
+ } else if (stepNumber === chatState.step) {
195
242
  console.log(` ⏸️ Step ${stepNumber}: Icon HIDDEN (current step)`);
196
243
  } else if (!hasInput) {
197
244
  console.log(` βšͺ Step ${stepNumber}: Icon HIDDEN (no input)`);
@@ -535,7 +582,29 @@ async function handleNext() {
535
582
  chatState.currentSelection = null;
536
583
  disableNextButton();
537
584
 
538
- // Move to next step
585
+ // Check if we should return to a saved step (after editing)
586
+ if (chatState.returnToStep !== null) {
587
+ const targetStep = chatState.returnToStep;
588
+ console.log(`\nπŸ”™ Returning to saved step ${targetStep} (edited step complete)`);
589
+ chatState.returnToStep = null; // Clear the return step
590
+
591
+ // Check if target step is valid
592
+ if (targetStep >= 0 && targetStep < flowData.flow.length) {
593
+ chatState.step = targetStep;
594
+ console.log(` βœ… Jumped to step ${targetStep}`);
595
+
596
+ // Update edit icons for the new position
597
+ updateEditIcons();
598
+
599
+ // Show the step we returned to
600
+ await showNextStep();
601
+ return;
602
+ } else {
603
+ console.log(` ⚠️ Invalid return step ${targetStep}, continuing normally`);
604
+ }
605
+ }
606
+
607
+ // Normal flow: Move to next step
539
608
  chatState.step++;
540
609
 
541
610
  // Update edit icons for all previous steps
@@ -635,6 +704,13 @@ async function showNextStep() {
635
704
  function handleCompletion() {
636
705
  console.log('βœ… Flow completed. Data:', chatState.data);
637
706
 
707
+ // Mark flow as completed
708
+ chatState.completed = true;
709
+ console.log(' 🏁 Flow marked as completed');
710
+
711
+ // Hide all edit icons
712
+ updateEditIcons();
713
+
638
714
  // Hide Next button
639
715
  if (elements.nextBtn) {
640
716
  elements.nextBtn.style.display = 'none';
@@ -762,39 +838,61 @@ function reset() {
762
838
  }
763
839
 
764
840
  function goToStep(stepNumber) {
841
+ console.log(`\n🎯 goToStep() called with stepNumber: ${stepNumber}`);
842
+ console.log(` Current step before: ${chatState.step}`);
843
+
765
844
  if (stepNumber < 0 || stepNumber >= flowData.flow.length) {
766
845
  console.error('Invalid step number:', stepNumber);
767
846
  return;
768
847
  }
769
848
 
849
+ console.log(` Setting chatState.step to ${stepNumber}`);
770
850
  chatState.step = stepNumber;
771
851
  chatState.currentSelection = null;
772
852
 
773
- if (elements.messages) {
774
- elements.messages.innerHTML = '';
775
- }
853
+ // DON'T clear messages - keep chat history visible!
854
+ // User can see their previous answers
855
+ console.log(` Keeping messages visible (not clearing)...`);
776
856
 
857
+ console.log(` Disabling next button and calling showNextStep()...`);
777
858
  disableNextButton();
778
859
  showNextStep();
779
860
  }
780
861
 
781
862
  function editStep(stepNumber) {
863
+ console.log(`\nπŸ“ editStep() called with stepNumber: ${stepNumber}`);
864
+ console.log(` Current step before edit: ${chatState.step}`);
865
+
782
866
  if (stepNumber < 0 || stepNumber >= flowData.flow.length) {
783
867
  console.error('Invalid step number:', stepNumber);
784
868
  return;
785
869
  }
786
870
 
871
+ // Save where we are now so we can return after editing
872
+ chatState.returnToStep = chatState.step;
873
+ console.log(` πŸ’Ύ Saved return step: ${chatState.returnToStep}`);
874
+
875
+ // Reset completed flag since we're editing
876
+ if (chatState.completed) {
877
+ chatState.completed = false;
878
+ console.log(` πŸ”“ Flow unmarked as completed (editing)`);
879
+ }
880
+
881
+ console.log(` Clearing history from step ${stepNumber} forward...`);
787
882
  // Clear history from this step forward
788
883
  chatState.history = chatState.history.filter(h => h.step < stepNumber);
789
884
 
885
+ console.log(` Resetting data for step ${stepNumber} and beyond...`);
790
886
  // Reset data for this field and beyond
791
887
  const stepsToReset = flowData.flow.slice(stepNumber);
792
888
  stepsToReset.forEach(step => {
793
889
  if (step.input && step.input.field) {
890
+ console.log(` Deleting field: ${step.input.field}`);
794
891
  delete chatState.data[step.input.field];
795
892
  }
796
893
  });
797
894
 
895
+ console.log(` Calling goToStep(${stepNumber})...`);
798
896
  // Go to that step
799
897
  goToStep(stepNumber);
800
898
  }