@inspirer-dev/crm-dashboard 1.0.48 → 1.0.50

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.
@@ -64,24 +64,35 @@ const StepFlowBuilderInner = forwardRef<HTMLDivElement, StepFlowBuilderProps>(
64
64
 
65
65
  const currentSegment = useMemo<EntrySegment | null>(() => {
66
66
  const values = form?.values as Record<string, unknown> | undefined;
67
- const entrySegmentValue = values?.entrySegment as ConnectDisconnect | undefined;
67
+ const entrySegmentValue = values?.entrySegment as ConnectDisconnect | SegmentItem | undefined;
68
68
 
69
69
  if (!entrySegmentValue) {
70
70
  return initialSegment;
71
71
  }
72
72
 
73
- const { connect = [], disconnect = [] } = entrySegmentValue;
73
+ // Handle connect/disconnect structure (user changed the segment in UI)
74
+ if ('connect' in entrySegmentValue || 'disconnect' in entrySegmentValue) {
75
+ const { connect = [], disconnect = [] } = entrySegmentValue as ConnectDisconnect;
74
76
 
75
- if (connect.length > 0) {
76
- const seg = connect[0];
77
- return { id: seg.id!, name: seg.name || `Segment #${seg.id}` };
78
- }
77
+ if (connect.length > 0) {
78
+ const seg = connect[0];
79
+ return { id: seg.id!, name: seg.name || `Segment #${seg.id}` };
80
+ }
79
81
 
80
- if (disconnect.length > 0 && initialSegment) {
81
- const disconnectedId = disconnect[0]?.id;
82
- if (disconnectedId === initialSegment.id) {
83
- return null;
82
+ if (disconnect.length > 0 && initialSegment) {
83
+ const disconnectedId = disconnect[0]?.id;
84
+ if (disconnectedId === initialSegment.id) {
85
+ return null;
86
+ }
84
87
  }
88
+
89
+ return initialSegment;
90
+ }
91
+
92
+ // Handle direct segment object (loaded from server)
93
+ const segmentObj = entrySegmentValue as SegmentItem;
94
+ if (segmentObj.id) {
95
+ return { id: segmentObj.id, name: segmentObj.name || `Segment #${segmentObj.id}` };
85
96
  }
86
97
 
87
98
  return initialSegment;
@@ -362,14 +362,26 @@ const SectionHeader: React.FC<{
362
362
  const TriggerConfigField = forwardRef<HTMLDivElement, TriggerConfigFieldProps>(
363
363
  ({ name, value, onChange, intlLabel, disabled, error, required, hint }, ref) => {
364
364
  const [config, setConfig] = useState<TriggerConfig>(() => parseConfig(value));
365
- const [eventSearchText, setEventSearchText] = useState('');
365
+ const [inputText, setInputText] = useState(() => {
366
+ const parsed = parseConfig(value);
367
+ return parsed.eventName ? getEventLabel(parsed.eventName) : '';
368
+ });
366
369
  const colors = useThemeColors();
367
370
 
368
371
  useEffect(() => {
369
372
  const parsed = parseConfig(value);
370
373
  setConfig(parsed);
374
+ setInputText(parsed.eventName ? getEventLabel(parsed.eventName) : '');
371
375
  }, [value]);
372
376
 
377
+ const isSearching = useMemo(() => {
378
+ if (!inputText) return false;
379
+ if (config.eventName) {
380
+ return inputText !== getEventLabel(config.eventName);
381
+ }
382
+ return true;
383
+ }, [inputText, config.eventName]);
384
+
373
385
  const handleUpdate = (updates: Partial<TriggerConfig>) => {
374
386
  const newConfig = { ...config, ...updates };
375
387
  setConfig(newConfig);
@@ -472,29 +484,29 @@ const TriggerConfigField = forwardRef<HTMLDivElement, TriggerConfigFieldProps>(
472
484
  <Combobox
473
485
  placeholder="Search events..."
474
486
  value={config.eventName || ''}
475
- textValue={config.eventName ? getEventLabel(config.eventName) : ''}
487
+ textValue={inputText}
476
488
  onChange={(val: string) => {
477
489
  handleUpdate({ eventName: val });
478
- setEventSearchText('');
490
+ setInputText(getEventLabel(val));
479
491
  }}
480
- onTextValueChange={(text: string) => setEventSearchText(text)}
492
+ onTextValueChange={(text: string) => setInputText(text)}
481
493
  onClear={() => {
482
494
  handleUpdate({ eventName: '' });
483
- setEventSearchText('');
495
+ setInputText('');
484
496
  }}
485
497
  disabled={disabled}
486
498
  creatable
487
499
  createMessage={(v: string) => `Use custom event: "${v}"`}
488
500
  onCreateOption={(v: string) => {
489
501
  handleUpdate({ eventName: v });
490
- setEventSearchText('');
502
+ setInputText(v);
491
503
  }}
492
504
  >
493
505
  {Object.entries(ANALYTICS_EVENTS).flatMap(([category, events]) =>
494
506
  events
495
507
  .filter((event) => {
496
- if (!eventSearchText) return true;
497
- const search = eventSearchText.toLowerCase();
508
+ if (!isSearching) return true;
509
+ const search = inputText.toLowerCase();
498
510
  return (
499
511
  event.label.toLowerCase().includes(search) ||
500
512
  event.value.toLowerCase().includes(search) ||
@@ -284,12 +284,23 @@ const SectionHeader = ({ icon, title, color }) => /* @__PURE__ */ jsxRuntime.jsx
284
284
  const TriggerConfigField = React.forwardRef(
285
285
  ({ name, value, onChange, intlLabel, disabled, error, required, hint }, ref) => {
286
286
  const [config, setConfig] = React.useState(() => parseConfig(value));
287
- const [eventSearchText, setEventSearchText] = React.useState("");
287
+ const [inputText, setInputText] = React.useState(() => {
288
+ const parsed = parseConfig(value);
289
+ return parsed.eventName ? getEventLabel(parsed.eventName) : "";
290
+ });
288
291
  const colors = useThemeColors();
289
292
  React.useEffect(() => {
290
293
  const parsed = parseConfig(value);
291
294
  setConfig(parsed);
295
+ setInputText(parsed.eventName ? getEventLabel(parsed.eventName) : "");
292
296
  }, [value]);
297
+ const isSearching = React.useMemo(() => {
298
+ if (!inputText) return false;
299
+ if (config.eventName) {
300
+ return inputText !== getEventLabel(config.eventName);
301
+ }
302
+ return true;
303
+ }, [inputText, config.eventName]);
293
304
  const handleUpdate = (updates) => {
294
305
  const newConfig = { ...config, ...updates };
295
306
  setConfig(newConfig);
@@ -395,27 +406,27 @@ const TriggerConfigField = React.forwardRef(
395
406
  {
396
407
  placeholder: "Search events...",
397
408
  value: config.eventName || "",
398
- textValue: config.eventName ? getEventLabel(config.eventName) : "",
409
+ textValue: inputText,
399
410
  onChange: (val) => {
400
411
  handleUpdate({ eventName: val });
401
- setEventSearchText("");
412
+ setInputText(getEventLabel(val));
402
413
  },
403
- onTextValueChange: (text) => setEventSearchText(text),
414
+ onTextValueChange: (text) => setInputText(text),
404
415
  onClear: () => {
405
416
  handleUpdate({ eventName: "" });
406
- setEventSearchText("");
417
+ setInputText("");
407
418
  },
408
419
  disabled,
409
420
  creatable: true,
410
421
  createMessage: (v) => `Use custom event: "${v}"`,
411
422
  onCreateOption: (v) => {
412
423
  handleUpdate({ eventName: v });
413
- setEventSearchText("");
424
+ setInputText(v);
414
425
  },
415
426
  children: Object.entries(ANALYTICS_EVENTS).flatMap(
416
427
  ([category, events]) => events.filter((event) => {
417
- if (!eventSearchText) return true;
418
- const search = eventSearchText.toLowerCase();
428
+ if (!isSearching) return true;
429
+ const search = inputText.toLowerCase();
419
430
  return event.label.toLowerCase().includes(search) || event.value.toLowerCase().includes(search) || category.toLowerCase().includes(search);
420
431
  }).map((event) => /* @__PURE__ */ jsxRuntime.jsx(designSystem.ComboboxOption, { value: event.value, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, alignItems: "center", children: [
421
432
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Badge, { size: "S", backgroundColor: "neutral150", textColor: "neutral600", children: category }),
@@ -282,12 +282,23 @@ const SectionHeader = ({ icon, title, color }) => /* @__PURE__ */ jsxs(Flex, { g
282
282
  const TriggerConfigField = forwardRef(
283
283
  ({ name, value, onChange, intlLabel, disabled, error, required, hint }, ref) => {
284
284
  const [config, setConfig] = useState(() => parseConfig(value));
285
- const [eventSearchText, setEventSearchText] = useState("");
285
+ const [inputText, setInputText] = useState(() => {
286
+ const parsed = parseConfig(value);
287
+ return parsed.eventName ? getEventLabel(parsed.eventName) : "";
288
+ });
286
289
  const colors = useThemeColors();
287
290
  useEffect(() => {
288
291
  const parsed = parseConfig(value);
289
292
  setConfig(parsed);
293
+ setInputText(parsed.eventName ? getEventLabel(parsed.eventName) : "");
290
294
  }, [value]);
295
+ const isSearching = useMemo(() => {
296
+ if (!inputText) return false;
297
+ if (config.eventName) {
298
+ return inputText !== getEventLabel(config.eventName);
299
+ }
300
+ return true;
301
+ }, [inputText, config.eventName]);
291
302
  const handleUpdate = (updates) => {
292
303
  const newConfig = { ...config, ...updates };
293
304
  setConfig(newConfig);
@@ -393,27 +404,27 @@ const TriggerConfigField = forwardRef(
393
404
  {
394
405
  placeholder: "Search events...",
395
406
  value: config.eventName || "",
396
- textValue: config.eventName ? getEventLabel(config.eventName) : "",
407
+ textValue: inputText,
397
408
  onChange: (val) => {
398
409
  handleUpdate({ eventName: val });
399
- setEventSearchText("");
410
+ setInputText(getEventLabel(val));
400
411
  },
401
- onTextValueChange: (text) => setEventSearchText(text),
412
+ onTextValueChange: (text) => setInputText(text),
402
413
  onClear: () => {
403
414
  handleUpdate({ eventName: "" });
404
- setEventSearchText("");
415
+ setInputText("");
405
416
  },
406
417
  disabled,
407
418
  creatable: true,
408
419
  createMessage: (v) => `Use custom event: "${v}"`,
409
420
  onCreateOption: (v) => {
410
421
  handleUpdate({ eventName: v });
411
- setEventSearchText("");
422
+ setInputText(v);
412
423
  },
413
424
  children: Object.entries(ANALYTICS_EVENTS).flatMap(
414
425
  ([category, events]) => events.filter((event) => {
415
- if (!eventSearchText) return true;
416
- const search = eventSearchText.toLowerCase();
426
+ if (!isSearching) return true;
427
+ const search = inputText.toLowerCase();
417
428
  return event.label.toLowerCase().includes(search) || event.value.toLowerCase().includes(search) || category.toLowerCase().includes(search);
418
429
  }).map((event) => /* @__PURE__ */ jsx(ComboboxOption, { value: event.value, children: /* @__PURE__ */ jsxs(Flex, { gap: 2, alignItems: "center", children: [
419
430
  /* @__PURE__ */ jsx(Badge, { size: "S", backgroundColor: "neutral150", textColor: "neutral600", children: category }),
@@ -3690,16 +3690,23 @@ const StepFlowBuilderInner = forwardRef(
3690
3690
  if (!entrySegmentValue) {
3691
3691
  return initialSegment;
3692
3692
  }
3693
- const { connect = [], disconnect = [] } = entrySegmentValue;
3694
- if (connect.length > 0) {
3695
- const seg = connect[0];
3696
- return { id: seg.id, name: seg.name || `Segment #${seg.id}` };
3697
- }
3698
- if (disconnect.length > 0 && initialSegment) {
3699
- const disconnectedId = disconnect[0]?.id;
3700
- if (disconnectedId === initialSegment.id) {
3701
- return null;
3693
+ if ("connect" in entrySegmentValue || "disconnect" in entrySegmentValue) {
3694
+ const { connect = [], disconnect = [] } = entrySegmentValue;
3695
+ if (connect.length > 0) {
3696
+ const seg = connect[0];
3697
+ return { id: seg.id, name: seg.name || `Segment #${seg.id}` };
3698
+ }
3699
+ if (disconnect.length > 0 && initialSegment) {
3700
+ const disconnectedId = disconnect[0]?.id;
3701
+ if (disconnectedId === initialSegment.id) {
3702
+ return null;
3703
+ }
3702
3704
  }
3705
+ return initialSegment;
3706
+ }
3707
+ const segmentObj = entrySegmentValue;
3708
+ if (segmentObj.id) {
3709
+ return { id: segmentObj.id, name: segmentObj.name || `Segment #${segmentObj.id}` };
3703
3710
  }
3704
3711
  return initialSegment;
3705
3712
  }, [form?.values, initialSegment]);
@@ -3695,16 +3695,23 @@ const StepFlowBuilderInner = React.forwardRef(
3695
3695
  if (!entrySegmentValue) {
3696
3696
  return initialSegment;
3697
3697
  }
3698
- const { connect = [], disconnect = [] } = entrySegmentValue;
3699
- if (connect.length > 0) {
3700
- const seg = connect[0];
3701
- return { id: seg.id, name: seg.name || `Segment #${seg.id}` };
3702
- }
3703
- if (disconnect.length > 0 && initialSegment) {
3704
- const disconnectedId = disconnect[0]?.id;
3705
- if (disconnectedId === initialSegment.id) {
3706
- return null;
3698
+ if ("connect" in entrySegmentValue || "disconnect" in entrySegmentValue) {
3699
+ const { connect = [], disconnect = [] } = entrySegmentValue;
3700
+ if (connect.length > 0) {
3701
+ const seg = connect[0];
3702
+ return { id: seg.id, name: seg.name || `Segment #${seg.id}` };
3703
+ }
3704
+ if (disconnect.length > 0 && initialSegment) {
3705
+ const disconnectedId = disconnect[0]?.id;
3706
+ if (disconnectedId === initialSegment.id) {
3707
+ return null;
3708
+ }
3707
3709
  }
3710
+ return initialSegment;
3711
+ }
3712
+ const segmentObj = entrySegmentValue;
3713
+ if (segmentObj.id) {
3714
+ return { id: segmentObj.id, name: segmentObj.name || `Segment #${segmentObj.id}` };
3708
3715
  }
3709
3716
  return initialSegment;
3710
3717
  }, [form?.values, initialSegment]);
@@ -59,7 +59,7 @@ const index = {
59
59
  components: {
60
60
  Input: async () => Promise.resolve().then(() => require(
61
61
  /* webpackChunkName: "crm-trigger-config" */
62
- "../_chunks/index-DjnVmHyN.js"
62
+ "../_chunks/index-BYpmngrF.js"
63
63
  ))
64
64
  },
65
65
  options: {
@@ -131,7 +131,7 @@ const index = {
131
131
  components: {
132
132
  Input: async () => Promise.resolve().then(() => require(
133
133
  /* webpackChunkName: "crm-step-flow-builder" */
134
- "../_chunks/index-BTWaGKSy.js"
134
+ "../_chunks/index-D0bqpjSi.js"
135
135
  ))
136
136
  },
137
137
  options: {
@@ -58,7 +58,7 @@ const index = {
58
58
  components: {
59
59
  Input: async () => import(
60
60
  /* webpackChunkName: "crm-trigger-config" */
61
- "../_chunks/index-yAympWN-.mjs"
61
+ "../_chunks/index-BbpoY4tS.mjs"
62
62
  )
63
63
  },
64
64
  options: {
@@ -130,7 +130,7 @@ const index = {
130
130
  components: {
131
131
  Input: async () => import(
132
132
  /* webpackChunkName: "crm-step-flow-builder" */
133
- "../_chunks/index-DKxcYOsi.mjs"
133
+ "../_chunks/index-D0NPKIXd.mjs"
134
134
  )
135
135
  },
136
136
  options: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inspirer-dev/crm-dashboard",
3
- "version": "1.0.48",
3
+ "version": "1.0.50",
4
4
  "description": "CRM Dashboard and Tools",
5
5
  "strapi": {
6
6
  "name": "crm-dashboard",