@superleapai/flow-ui 2.5.14 → 2.5.16

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.
@@ -2,6 +2,7 @@
2
2
  * Date-time-picker Component (vanilla JS)
3
3
  * Combines calendar grid, optional time picker, and quick actions (Today, Tomorrow, No date).
4
4
  * Uses Popover, Button, Select, TimePicker; depends on date-time-picker-utils.js.
5
+ * Value API: Unix epoch milliseconds (number) or undefined — not Date instances.
5
6
  */
6
7
 
7
8
  (function (global) {
@@ -35,6 +36,13 @@
35
36
  return Array.prototype.filter.call(arguments, Boolean).join(" ");
36
37
  }
37
38
 
39
+ /** @param {unknown} v @returns {number|undefined} epoch ms, or undefined if missing/invalid */
40
+ function normalizeEpoch(v) {
41
+ if (v == null || v === "") return undefined;
42
+ if (typeof v === "number" && !Number.isNaN(v)) return v;
43
+ return undefined;
44
+ }
45
+
38
46
  // Mirror input wrapper variant + size behaviour for visual consistency
39
47
  var TRIGGER_WRAPPER_CLASS = {
40
48
  base:
@@ -280,8 +288,8 @@
280
288
  /**
281
289
  * Create date-time-picker component
282
290
  * @param {Object} config
283
- * @param {Date} [config.value] - Current value
284
- * @param {Function} [config.onChange] - (date: Date | undefined) => void
291
+ * @param {number} [config.value] - Current instant as Unix epoch milliseconds
292
+ * @param {Function} [config.onChange] - (epochMs: number | undefined) => void
285
293
  * @param {boolean} [config.disabled]
286
294
  * @param {12|24} [config.hourCycle=12]
287
295
  * @param {number} [config.yearRange=50]
@@ -305,7 +313,7 @@
305
313
  throw new Error("Popover and Button required");
306
314
  }
307
315
 
308
- var value = config.value;
316
+ var value = normalizeEpoch(config.value);
309
317
  var onChange = config.onChange;
310
318
  var disabled = !!config.disabled;
311
319
  var hourCycle = config.hourCycle === 24 ? 24 : 12;
@@ -318,7 +326,13 @@
318
326
  var toDate = config.toDate;
319
327
  var align = config.align || "start";
320
328
 
321
- var validDate = Utils.getValidDate(value, fromDate, toDate);
329
+ var validDate =
330
+ value != null ? Utils.getValidDate(new Date(value), fromDate, toDate) : undefined;
331
+ if (value != null && validDate) {
332
+ value = validDate.getTime();
333
+ } else if (value != null && !validDate) {
334
+ value = undefined;
335
+ }
322
336
  var displayMonth = validDate ? new Date(validDate.getTime()) : new Date();
323
337
 
324
338
  var triggerWrapper = document.createElement("div");
@@ -362,7 +376,12 @@
362
376
  container.appendChild(triggerWrapper);
363
377
 
364
378
  function updateTriggerText() {
365
- validDate = Utils.getValidDate(value, fromDate, toDate);
379
+ if (value == null) {
380
+ validDate = undefined;
381
+ } else {
382
+ validDate = Utils.getValidDate(new Date(value), fromDate, toDate);
383
+ if (validDate) value = validDate.getTime();
384
+ }
366
385
  formatted = Utils.formatDateTime(validDate, hourCycle, granularity);
367
386
  triggerText.textContent = formatted || placeholder;
368
387
  triggerText.classList.toggle("text-typography-quaternary-text", !formatted);
@@ -393,14 +412,15 @@
393
412
  out.setHours(validDate.getHours(), validDate.getMinutes(), validDate.getSeconds(), 0);
394
413
  }
395
414
  }
396
- value = Utils.getValidDate(out, fromDate, toDate);
397
- validDate = value;
415
+ var picked = Utils.getValidDate(out, fromDate, toDate);
416
+ validDate = picked;
417
+ value = picked != null ? picked.getTime() : undefined;
398
418
  updateTriggerText();
399
419
  if (onChange) onChange(value);
400
420
  setMonth(out);
401
421
  if (captionEl && captionEl.setMonth) captionEl.setMonth(displayMonth);
402
422
  if (timePickerEl && timePickerEl.updateValue) {
403
- timePickerEl.updateValue(Utils.getTimeString(value));
423
+ timePickerEl.updateValue(Utils.getTimeString(validDate));
404
424
  }
405
425
  refreshCalendar();
406
426
  }
@@ -494,10 +514,11 @@
494
514
  isTimeDropdownOpen = false;
495
515
  },
496
516
  onChange: function (timeStr) {
497
- var base = value ? new Date(value.getTime()) : new Date();
517
+ var base = value != null ? new Date(value) : new Date();
498
518
  Utils.setTimeFromString(base, timeStr);
499
- value = Utils.getValidDate(base, fromDate, toDate);
500
- validDate = value;
519
+ var next = Utils.getValidDate(base, fromDate, toDate);
520
+ validDate = next;
521
+ value = next != null ? next.getTime() : undefined;
501
522
  updateTriggerText();
502
523
  if (onChange) onChange(value);
503
524
  },
@@ -532,14 +553,15 @@
532
553
  return;
533
554
  }
534
555
  var t = granularity === "day" ? Utils.startOfDay(new Date()) : new Date();
535
- value = Utils.getValidDate(t, fromDate, toDate);
536
- validDate = value;
537
- setMonth(value || new Date());
556
+ var todayValid = Utils.getValidDate(t, fromDate, toDate);
557
+ validDate = todayValid;
558
+ value = todayValid != null ? todayValid.getTime() : undefined;
559
+ setMonth(value != null ? new Date(value) : new Date());
538
560
  updateTriggerText();
539
561
  if (onChange) onChange(value);
540
562
  refreshCalendar();
541
- if (timePickerEl && timePickerEl.updateValue && value) {
542
- timePickerEl.updateValue(Utils.getTimeString(value));
563
+ if (timePickerEl && timePickerEl.updateValue && validDate) {
564
+ timePickerEl.updateValue(Utils.getTimeString(validDate));
543
565
  }
544
566
  },
545
567
  });
@@ -558,14 +580,15 @@
558
580
  }
559
581
  var t = Utils.addDays(new Date(), 1);
560
582
  t = granularity === "day" ? Utils.startOfDay(t) : t;
561
- value = Utils.getValidDate(t, fromDate, toDate);
562
- validDate = value;
563
- setMonth(value || new Date());
583
+ var tomorrowValid = Utils.getValidDate(t, fromDate, toDate);
584
+ validDate = tomorrowValid;
585
+ value = tomorrowValid != null ? tomorrowValid.getTime() : undefined;
586
+ setMonth(value != null ? new Date(value) : new Date());
564
587
  updateTriggerText();
565
588
  if (onChange) onChange(value);
566
589
  refreshCalendar();
567
- if (timePickerEl && timePickerEl.updateValue && value) {
568
- timePickerEl.updateValue(Utils.getTimeString(value));
590
+ if (timePickerEl && timePickerEl.updateValue && validDate) {
591
+ timePickerEl.updateValue(Utils.getTimeString(validDate));
569
592
  }
570
593
  },
571
594
  });
@@ -644,8 +667,14 @@
644
667
  return value;
645
668
  };
646
669
  container.setValue = function (v) {
647
- value = v;
648
- validDate = Utils.getValidDate(value, fromDate, toDate);
670
+ value = normalizeEpoch(v);
671
+ validDate =
672
+ value != null ? Utils.getValidDate(new Date(value), fromDate, toDate) : undefined;
673
+ if (value != null && validDate) {
674
+ value = validDate.getTime();
675
+ } else if (value != null && !validDate) {
676
+ value = undefined;
677
+ }
649
678
  displayMonth = validDate ? new Date(validDate.getTime()) : new Date();
650
679
  updateTriggerText();
651
680
  };
package/core/flow.js CHANGED
@@ -417,7 +417,7 @@
417
417
  * @param {Object} config - Configuration object
418
418
  * @param {string} config.label - Field label
419
419
  * @param {string} config.fieldId - State key for this field
420
- * @param {Date|string|null} config.value - Initial value (Date or ISO string)
420
+ * @param {Date|string|number|null} config.value - Initial value (Date, ISO string, or epoch ms)
421
421
  * @param {string} config.placeholder - Placeholder text
422
422
  * @param {boolean} config.required - Whether field is required
423
423
  * @param {Function} config.onChange - Optional change handler
@@ -453,22 +453,34 @@
453
453
 
454
454
  if (getComponent("DateTimePicker") && getComponent("DateTimePicker").create) {
455
455
  const raw = get(fieldId);
456
- let currentValue;
457
- if (initialValue instanceof Date) {
458
- currentValue = initialValue;
456
+ let currentValueMs;
457
+ if (typeof initialValue === "number" && !Number.isNaN(initialValue)) {
458
+ currentValueMs = initialValue;
459
+ } else if (initialValue instanceof Date) {
460
+ currentValueMs = initialValue.getTime();
461
+ } else if (typeof initialValue === "string" && initialValue.trim() !== "") {
462
+ try {
463
+ const d = new Date(initialValue);
464
+ currentValueMs = Number.isNaN(d.getTime()) ? undefined : d.getTime();
465
+ } catch (e) {
466
+ currentValueMs = undefined;
467
+ }
459
468
  } else if (raw === null || raw === undefined || raw === "") {
460
- currentValue = undefined;
469
+ currentValueMs = undefined;
461
470
  } else {
462
471
  try {
463
- currentValue = typeof raw === "string" ? new Date(raw) : raw;
464
- if (Number.isNaN(currentValue.getTime())) currentValue = undefined;
472
+ const parsed = typeof raw === "string" ? new Date(raw) : raw;
473
+ currentValueMs =
474
+ parsed && typeof parsed.getTime === "function" && !Number.isNaN(parsed.getTime())
475
+ ? parsed.getTime()
476
+ : undefined;
465
477
  } catch (e) {
466
- currentValue = undefined;
478
+ currentValueMs = undefined;
467
479
  }
468
480
  }
469
481
 
470
482
  const picker = getComponent("DateTimePicker").create({
471
- value: currentValue,
483
+ value: currentValueMs,
472
484
  placeholder: placeholder || `Pick ${label.toLowerCase()}`,
473
485
  disabled,
474
486
  hourCycle,
@@ -477,9 +489,9 @@
477
489
  variant,
478
490
  fromDate,
479
491
  toDate,
480
- onChange: (date) => {
481
- set(fieldId, date ? date.toISOString() : null);
482
- if (onChange) onChange(date);
492
+ onChange: (epochMs) => {
493
+ set(fieldId, epochMs != null ? new Date(epochMs).toISOString() : null);
494
+ if (onChange) onChange(epochMs != null ? new Date(epochMs) : undefined);
483
495
  },
484
496
  });
485
497
 
@@ -13,79 +13,15 @@
13
13
  var _config = null;
14
14
  var _sdkInstance = null;
15
15
 
16
- /**
17
- * Default config merged with user config when calling init().
18
- * Matches SuperLeapSDK constructor defaults (sdk.js).
19
- */
20
- var DEFAULT_CONFIG = {
21
- apiKey: "NWM2MGEZMDMTYME2YI0ZYZDHLTLKNWQTNDM3NDNIZDU3YTQ1",
22
- baseUrl: "https://razorpay-sandbox.superleap.dev/api/v1",
23
- clientId: "",
24
- clientSecret: "",
25
- cache: {
26
- enabled: true,
27
- maxSize: 1000,
28
- defaultTTL: 5 * 60 * 1000,
29
- ttl: {
30
- schema: 30 * 60 * 1000,
31
- records: 2 * 60 * 1000,
32
- count: 60 * 1000,
33
- user: 10 * 60 * 1000,
34
- },
35
- },
36
- };
37
-
38
- /**
39
- * Deep-merge source into target (only own enumerable properties; arrays replaced, not merged).
40
- */
41
- function mergeConfig(target, source) {
42
- if (!source || typeof source !== "object") return target;
43
- var result = {};
44
- var key;
45
- for (key in target) {
46
- if (Object.prototype.hasOwnProperty.call(target, key)) {
47
- result[key] = target[key];
48
- }
49
- }
50
- for (key in source) {
51
- if (Object.prototype.hasOwnProperty.call(source, key)) {
52
- var s = source[key];
53
- var t = result[key];
54
- if (
55
- t &&
56
- s &&
57
- typeof t === "object" &&
58
- typeof s === "object" &&
59
- !Array.isArray(t) &&
60
- !Array.isArray(s)
61
- ) {
62
- result[key] = mergeConfig(t, s);
63
- } else {
64
- result[key] = s;
65
- }
66
- }
67
- }
68
- return result;
69
- }
70
-
71
16
  /**
72
17
  * Initialize the client with API config. Call this before using record-select or other SDK-dependent components.
73
- * Config is merged with defaults; you can pass only baseUrl and apiKey.
74
18
  *
75
19
  * @param {Object} config - Options passed to createSuperLeapSDK (same as SuperLeapSDK constructor in sdk.js)
76
- * @param {string} [config.apiKey] - Bearer token for authentication
77
- * @param {string} [config.baseUrl] - Base URL for API (default: "https://app.superleap.dev/api/v1")
20
+ * @param {string} config.apiKey - Bearer token for authentication
21
+ * @param {string} config.baseUrl - Base URL for API
78
22
  * @param {string} [config.clientId] - Client ID (if using client credentials)
79
23
  * @param {string} [config.clientSecret] - Client secret (if using client credentials)
80
24
  * @param {Object} [config.cache] - Cache configuration
81
- * @param {boolean} [config.cache.enabled] - Enable caching (default: true)
82
- * @param {number} [config.cache.maxSize] - Max cache entries (default: 1000)
83
- * @param {number} [config.cache.defaultTTL] - Default TTL in ms (default: 5 minutes)
84
- * @param {Object} [config.cache.ttl] - TTL per operation
85
- * @param {number} [config.cache.ttl.schema] - Schema cache TTL (default: 30 min)
86
- * @param {number} [config.cache.ttl.records] - Record query cache TTL (default: 2 min)
87
- * @param {number} [config.cache.ttl.count] - Count query cache TTL (default: 1 min)
88
- * @param {number} [config.cache.ttl.user] - User/me cache TTL (default: 10 min)
89
25
  */
90
26
  function init(config) {
91
27
  if (config == null) {
@@ -94,7 +30,7 @@
94
30
  return;
95
31
  }
96
32
 
97
- _config = mergeConfig(DEFAULT_CONFIG, config);
33
+ _config = config;
98
34
 
99
35
  // Create SDK instance using the SDK factory if available
100
36
  if (typeof global.createSuperLeapSDK === "function") {
@@ -128,15 +64,6 @@
128
64
  return _config != null && _sdkInstance != null;
129
65
  }
130
66
 
131
- /**
132
- * Return the default config object (for reference or to override specific keys).
133
- *
134
- * @returns {Object}
135
- */
136
- function getDefaultConfig() {
137
- return mergeConfig({}, DEFAULT_CONFIG);
138
- }
139
-
140
67
  /**
141
68
  * Return the current base URL (from merged config after init).
142
69
  * Used by file-input and other components that build API URLs.
@@ -152,7 +79,6 @@
152
79
  init: init,
153
80
  getSdk: getSdk,
154
81
  isAvailable: isAvailable,
155
- getDefaultConfig: getDefaultConfig,
156
82
  getBaseUrl: getBaseUrl,
157
83
  };
158
84