@commercelayer/app-elements 6.0.2 → 6.1.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.
@@ -1,1403 +0,0 @@
1
- "use client";
2
- import { t as S, b as H, d as Z, j as e, i as V, g as G, e as Q, I as f, f as y, h as $, D as z, k as R, l as p, B as J, n as P, o as w, p as U, u as ee, q as te, r as ne, s as ae, v as _, w as le, C as se } from "./main-1tcoF6bR.js";
3
- import I, { useReducer as re, useCallback as N, useMemo as ie, createContext as ue, useContext as ce, useState as g, useEffect as v, useRef as oe } from "react";
4
- import "react-hook-form";
5
- import { p as k } from "./parseISO-Di2ADkp1.js";
6
- function A(t, n) {
7
- const a = t.match(
8
- /(\d{4})-(\d{2})-(\d{2})[T ](\d{2}):(\d{2}):(\d{2})(?:\.(\d{0,7}))?(?:Z|(.)(\d{2}):?(\d{2})?)?/
9
- );
10
- return a ? S(
11
- Date.UTC(
12
- +a[1],
13
- +a[2] - 1,
14
- +a[3],
15
- +a[4] - (+a[9] || 0) * (a[8] == "-" ? -1 : 1),
16
- +a[5] - (+a[10] || 0) * (a[8] == "-" ? -1 : 1),
17
- +a[6],
18
- +((a[7] || "0") + "00").substring(0, 3)
19
- ),
20
- n?.in
21
- ) : S(NaN, n?.in);
22
- }
23
- function q(t, n, a) {
24
- return t == null ? t : H(t, n, a);
25
- }
26
- function D(t, n) {
27
- return t == null ? !0 : Z(t, n);
28
- }
29
- const K = ue(
30
- void 0
31
- );
32
- function de(t, n) {
33
- switch (n.type) {
34
- case "SET_PATH": {
35
- const a = { ...t.value };
36
- if (n.value === null)
37
- if (/\.\d+$/.test(n.path)) {
38
- const r = n.path.replace(/\.\d+$/, ""), u = parseInt(n.path.match(/\d+$/)?.[0] ?? "0", 10), s = G(a, r);
39
- Array.isArray(s) && (s.splice(u, 1), q(a, r, s), s.length === 0 && r.endsWith(".nested.conditions") && D(a, r.replace(/\.conditions$/, "")));
40
- } else
41
- D(a, n.path);
42
- else
43
- q(a, n.path, n.value);
44
- return {
45
- ...t,
46
- value: a
47
- };
48
- }
49
- case "SET_SELECTED_RULE_INDEX":
50
- return {
51
- ...t,
52
- selectedRuleIndex: n.index
53
- };
54
- case "SET_VALUE":
55
- return V(t.value, n.value) ? t : n.value.rules.length === 0 ? {
56
- selectedRuleIndex: 0,
57
- value: {
58
- rules: [
59
- {
60
- name: "Rule name",
61
- // @ts-expect-error Setting `null` is intentional for rendering an empty action
62
- actions: [null],
63
- // @ts-expect-error Setting `null` is intentional for rendering an empty condition
64
- conditions: [null]
65
- }
66
- ]
67
- }
68
- } : {
69
- ...t,
70
- value: n.value
71
- };
72
- default:
73
- return t;
74
- }
75
- }
76
- function me({
77
- children: t,
78
- initialValue: n
79
- }) {
80
- const [a, r] = re(de, {
81
- value: n,
82
- selectedRuleIndex: 0
83
- }), u = N((o, c) => {
84
- r({ type: "SET_PATH", path: o, value: c });
85
- }, []), s = N((o) => {
86
- r({ type: "SET_SELECTED_RULE_INDEX", index: o });
87
- }, []), l = N((o) => {
88
- r({ type: "SET_VALUE", value: o });
89
- }, []), i = ie(
90
- () => ({
91
- state: a,
92
- setPath: u,
93
- setSelectedRuleIndex: s,
94
- setValue: l
95
- }),
96
- [a, u, s, l]
97
- );
98
- return /* @__PURE__ */ e.jsx(K.Provider, { value: i, children: t });
99
- }
100
- function h() {
101
- const t = ce(K);
102
- if (t === void 0)
103
- throw new Error("useRuleEngine must be used within a RuleEngineProvider");
104
- return t;
105
- }
106
- const W = Q([
107
- "blank",
108
- "present",
109
- "null",
110
- "not_null"
111
- ]);
112
- function E(t) {
113
- return null;
114
- }
115
- function fe({
116
- item: t,
117
- pathPrefix: n
118
- }) {
119
- const { setPath: a } = h();
120
- if (t == null)
121
- return null;
122
- switch (t.type) {
123
- case "buy_x_pay_y":
124
- return /* @__PURE__ */ e.jsxs("div", { className: "w-36 flex items-center gap-0.5", children: [
125
- /* @__PURE__ */ e.jsx(
126
- f,
127
- {
128
- name: `${n}.value.x`,
129
- type: "number",
130
- suffix: "X",
131
- defaultValue: t.value?.x,
132
- onChange: (r) => {
133
- a(
134
- `${n}.value.x`,
135
- parseInt(r.currentTarget.value, 10)
136
- );
137
- }
138
- }
139
- ),
140
- /* @__PURE__ */ e.jsx(
141
- f,
142
- {
143
- name: `${n}.value.y`,
144
- type: "number",
145
- suffix: "Y",
146
- defaultValue: t.value?.y,
147
- onChange: (r) => {
148
- a(
149
- `${n}.value.y`,
150
- parseInt(r.currentTarget.value, 10)
151
- );
152
- }
153
- }
154
- )
155
- ] });
156
- case "every_x_discount_y":
157
- return /* @__PURE__ */ e.jsxs("div", { className: "w-36 flex items-center gap-0.5", children: [
158
- /* @__PURE__ */ e.jsx(
159
- f,
160
- {
161
- name: `${n}.value.x`,
162
- type: "number",
163
- suffix: "X",
164
- defaultValue: t.value?.x,
165
- onChange: (r) => {
166
- a(
167
- `${n}.value.x`,
168
- parseInt(r.currentTarget.value, 10)
169
- );
170
- }
171
- }
172
- ),
173
- /* @__PURE__ */ e.jsx(
174
- f,
175
- {
176
- name: `${n}.value.y`,
177
- type: "number",
178
- suffix: "Y",
179
- defaultValue: t.value?.y,
180
- onChange: (r) => {
181
- a(
182
- `${n}.value.y`,
183
- parseInt(r.currentTarget.value, 10)
184
- );
185
- }
186
- }
187
- )
188
- ] });
189
- case "fixed_amount":
190
- case "fixed_price":
191
- return /* @__PURE__ */ e.jsx("div", { className: "w-36", children: /* @__PURE__ */ e.jsx(
192
- f,
193
- {
194
- name: `${n}.value`,
195
- type: "number",
196
- defaultValue: t.value,
197
- min: 0,
198
- suffix: "cents",
199
- onChange: (r) => {
200
- a(
201
- `${n}.value`,
202
- parseInt(r.currentTarget.value, 10)
203
- );
204
- }
205
- }
206
- ) });
207
- case "percentage": {
208
- const r = (t.value * 100).toFixed(2);
209
- return /* @__PURE__ */ e.jsx("div", { className: "w-24", children: /* @__PURE__ */ e.jsx(
210
- f,
211
- {
212
- name: `${n}.value`,
213
- type: "number",
214
- defaultValue: r.endsWith(".00") ? r.slice(0, -3) : r,
215
- min: 0,
216
- max: 100,
217
- suffix: "%",
218
- onChange: (u) => {
219
- a(
220
- `${n}.value`,
221
- parseFloat(u.currentTarget.value) / 100
222
- );
223
- }
224
- }
225
- ) });
226
- }
227
- default:
228
- return E();
229
- }
230
- }
231
- function ge({
232
- item: t,
233
- index: n,
234
- onDelete: a
235
- }) {
236
- const {
237
- setPath: r,
238
- state: { selectedRuleIndex: u }
239
- } = h(), s = {
240
- percentage: "Percentage discount",
241
- fixed_amount: "Fixed amount",
242
- fixed_price: "Fixed price",
243
- buy_x_pay_y: "Buy X, Pay Y",
244
- every_x_discount_y: "Every X, Discount Y"
245
- }, l = `rules.${u}.actions.${n}`;
246
- return /* @__PURE__ */ e.jsx("div", { className: "mb-4 last:mb-0", children: /* @__PURE__ */ e.jsxs("div", { className: "bg-gray-50 rounded-md flex items-center", children: [
247
- /* @__PURE__ */ e.jsxs("div", { className: "flex items-center justify-between gap-2 grow p-2", children: [
248
- /* @__PURE__ */ e.jsx("div", { className: "flex-1", children: /* @__PURE__ */ e.jsx(
249
- y,
250
- {
251
- name: `${l}.type`,
252
- defaultValue: t != null ? {
253
- label: s[t.type],
254
- value: t.type
255
- } : void 0,
256
- initialValues: Object.entries(s).map(
257
- ([i, o]) => ({ value: i, label: o })
258
- ),
259
- onSelect: (i) => {
260
- $(i) && r(`${l}.type`, i.value);
261
- }
262
- }
263
- ) }),
264
- /* @__PURE__ */ e.jsx(fe, { item: t, pathPrefix: l }),
265
- /* @__PURE__ */ e.jsx("div", { className: "text-black font-bold text-sm", children: "ON" }),
266
- /* @__PURE__ */ e.jsx("div", { className: "flex-1", children: /* @__PURE__ */ e.jsx(
267
- f,
268
- {
269
- name: `${l}.selector`,
270
- type: "text",
271
- defaultValue: t?.selector,
272
- onChange: (i) => {
273
- r(`${l}.selector`, i.currentTarget.value);
274
- }
275
- }
276
- ) })
277
- ] }),
278
- a != null && /* @__PURE__ */ e.jsx(
279
- z,
280
- {
281
- className: "w-8 border-l border-gray-100 flex items-center justify-center self-stretch",
282
- dropdownLabel: /* @__PURE__ */ e.jsx(
283
- "button",
284
- {
285
- type: "button",
286
- className: "flex items-center justify-center self-stretch grow",
287
- children: /* @__PURE__ */ e.jsx(p, { name: "dotsThreeVertical", size: 16, weight: "bold" })
288
- }
289
- ),
290
- dropdownItems: /* @__PURE__ */ e.jsx(
291
- R,
292
- {
293
- label: "Delete",
294
- onClick: () => {
295
- r(`${l}`, null), a();
296
- }
297
- }
298
- )
299
- }
300
- )
301
- ] }) });
302
- }
303
- function he({
304
- actions: t
305
- }) {
306
- const [n, a] = g(0), {
307
- setPath: r,
308
- state: { selectedRuleIndex: u }
309
- } = h();
310
- return /* @__PURE__ */ e.jsxs(e.Fragment, { children: [
311
- /* @__PURE__ */ e.jsx("div", { children: t?.map((s, l, i) => /* @__PURE__ */ e.jsx(
312
- ge,
313
- {
314
- item: s,
315
- index: l,
316
- onDelete: i.length > 1 ? () => {
317
- a((o) => o + 1);
318
- } : void 0
319
- },
320
- `${u}-${l}-${n}`
321
- )) }),
322
- /* @__PURE__ */ e.jsx("div", { className: "mt-6", children: /* @__PURE__ */ e.jsxs(
323
- J,
324
- {
325
- size: "small",
326
- variant: "secondary",
327
- alignItems: "center",
328
- onClick: () => {
329
- r(
330
- `rules.${u}.actions.${t?.length ?? 0}`,
331
- void 0
332
- );
333
- },
334
- children: [
335
- /* @__PURE__ */ e.jsx(p, { name: "plusCircle" }),
336
- " Add action"
337
- ]
338
- }
339
- ) })
340
- ] });
341
- }
342
- function X(t) {
343
- const [n, a] = g(void 0);
344
- return v(() => {
345
- t?.field != null && P(t.field).then((r) => {
346
- a(r);
347
- }).catch((r) => {
348
- console.error("Error fetching field info:", r);
349
- });
350
- }, [t?.field]), { infos: n };
351
- }
352
- function Y(t) {
353
- if (typeof t == "string")
354
- return w(A(t)) ? "datetime" : "string";
355
- if (typeof t == "number")
356
- return "integer";
357
- if (typeof t == "boolean")
358
- return "boolean";
359
- if (Array.isArray(t)) {
360
- if (typeof t[0] == "string")
361
- return w(A(t[0])) ? "datetime" : "string";
362
- if (typeof t[0] == "number")
363
- return "integer";
364
- }
365
- return "string";
366
- }
367
- function xe({
368
- item: t,
369
- pathPrefix: n
370
- }) {
371
- const { setPath: a } = h(), { infos: r } = X(t);
372
- let u = r?.field?.type;
373
- return u == null && (u = Y(t?.value)), /* @__PURE__ */ e.jsx(
374
- y,
375
- {
376
- name: `${n}.matcher`,
377
- value: t != null ? {
378
- label: M.find((s) => s.matcher === t.matcher && (u != null && s.fieldTypes.includes(u) || u == null))?.label ?? (t.matcher != null ? `⚠️   ${t.matcher}` : ""),
379
- value: t.matcher
380
- } : void 0,
381
- initialValues: M.filter(({ fieldTypes: s, visible: l }) => l !== !1 && s.includes(u)).map(({ matcher: s, label: l }) => ({ value: s, label: l })),
382
- onSelect: (s) => {
383
- $(s) && (a(`${n}.matcher`, s.value), W.includes(
384
- s.value
385
- ) && a(`${n}.value`, null));
386
- }
387
- }
388
- );
389
- }
390
- const M = [
391
- {
392
- /** Matches if field value equals provided value
393
- * @field Integer, String, Datetime, Boolean
394
- * @value Integer, String, Datetime, Boolean
395
- */
396
- matcher: "eq",
397
- label: "equals",
398
- fieldTypes: ["integer", "string", "datetime", "boolean"]
399
- },
400
- {
401
- /** Matches if field value is not equal to provided value
402
- * @field Integer, String, Datetime, Boolean
403
- * @value Integer, String, Datetime, Boolean
404
- */
405
- matcher: "not_eq",
406
- label: "not equals",
407
- fieldTypes: ["integer", "string", "datetime", "boolean"]
408
- },
409
- {
410
- /** Matches if field value is less than provided value
411
- * @field Integer, Datetime
412
- * @value Integer, Datetime
413
- */
414
- matcher: "lt",
415
- label: "<",
416
- fieldTypes: ["integer", "datetime"]
417
- },
418
- {
419
- /** Matches if field value is less than or equal to provided value
420
- * @field Integer, Datetime
421
- * @value Integer, Datetime
422
- */
423
- matcher: "lteq",
424
- label: "≤",
425
- fieldTypes: ["integer", "datetime"]
426
- },
427
- {
428
- /** Matches if field value is greater than provided value
429
- * @field Integer, Datetime
430
- * @value Integer, Datetime
431
- */
432
- matcher: "gt",
433
- label: ">",
434
- fieldTypes: ["integer", "datetime"]
435
- },
436
- {
437
- /** Matches if field value is greater than or equal to provided value
438
- * @field Integer, Datetime
439
- * @value Integer, Datetime
440
- */
441
- matcher: "gteq",
442
- label: "≥",
443
- fieldTypes: ["integer", "datetime"]
444
- },
445
- {
446
- /** Matches if field value is a multiple of provided value
447
- * @field Integer
448
- * @value Integer
449
- */
450
- matcher: "multiple",
451
- label: "is a multiple of",
452
- fieldTypes: ["integer"]
453
- },
454
- {
455
- /** Matches if field value matches regex pattern
456
- * @field String
457
- * @value String
458
- */
459
- matcher: "matches",
460
- label: "matches regex",
461
- fieldTypes: ["string"]
462
- },
463
- {
464
- /** Matches if field value does not match regex pattern
465
- * @field String
466
- * @value String
467
- */
468
- matcher: "does_not_match",
469
- label: "doesn't match regex",
470
- fieldTypes: ["string"]
471
- },
472
- {
473
- /** Matches if field value starts with provided string
474
- * @field String
475
- * @value String
476
- */
477
- matcher: "start_with",
478
- label: "starts with",
479
- fieldTypes: ["string"]
480
- },
481
- {
482
- /** Matches if field value does not start with provided string
483
- * @field String
484
- * @value String
485
- */
486
- matcher: "not_start_with",
487
- label: "doesn't start with",
488
- fieldTypes: ["string"]
489
- },
490
- {
491
- /** Matches if field value ends with provided string
492
- * @field String
493
- * @value String
494
- */
495
- matcher: "end_with",
496
- label: "ends with",
497
- fieldTypes: ["string"]
498
- },
499
- {
500
- /** Matches if field value does not end with provided string
501
- * @field String
502
- * @value String
503
- */
504
- matcher: "not_end_with",
505
- label: "doesn't end with",
506
- fieldTypes: ["string"]
507
- },
508
- {
509
- /** Matches if field value is between two values (exclusive)
510
- * @field Integer, Datetime
511
- * @value Array
512
- */
513
- matcher: "gt_lt",
514
- label: "> and <",
515
- fieldTypes: ["integer"]
516
- },
517
- {
518
- /** Matches if field value is between two values (inclusive start, exclusive end)
519
- * @field Integer, Datetime
520
- * @value Array
521
- */
522
- matcher: "gteq_lt",
523
- label: "≥ and <",
524
- fieldTypes: ["integer"]
525
- },
526
- {
527
- /** Matches if field value is greater than first and less than or equal to second
528
- * @field Integer, Datetime
529
- * @value Array
530
- */
531
- matcher: "gt_lteq",
532
- label: "> and ≤",
533
- fieldTypes: ["integer"]
534
- },
535
- {
536
- /** Matches if field value is between two values (inclusive)
537
- * @field Integer, Datetime
538
- * @value Array
539
- */
540
- matcher: "gteq_lteq",
541
- label: "≥ and ≤",
542
- fieldTypes: ["integer"]
543
- },
544
- {
545
- /** Matches if field value is between two values (exclusive)
546
- * @field Integer, Datetime
547
- * @value Array
548
- */
549
- matcher: "gt_lt",
550
- label: "date range",
551
- visible: !1,
552
- fieldTypes: ["datetime"]
553
- },
554
- {
555
- /** Matches if field value is between two values (inclusive start, exclusive end)
556
- * @field Integer, Datetime
557
- * @value Array
558
- */
559
- matcher: "gteq_lt",
560
- label: "date range",
561
- visible: !1,
562
- fieldTypes: ["datetime"]
563
- },
564
- {
565
- /** Matches if field value is greater than first and less than or equal to second
566
- * @field Integer, Datetime
567
- * @value Array
568
- */
569
- matcher: "gt_lteq",
570
- label: "date range",
571
- visible: !1,
572
- fieldTypes: ["datetime"]
573
- },
574
- {
575
- /** Matches if field value is between two values (inclusive)
576
- * @field Integer, Datetime
577
- * @value Array
578
- */
579
- matcher: "gteq_lteq",
580
- label: "date range",
581
- visible: !0,
582
- fieldTypes: ["datetime"]
583
- },
584
- {
585
- /** Matches if field value is in provided array
586
- * @field Integer, String, Datetime
587
- * @value Array
588
- */
589
- matcher: "is_in",
590
- label: "is one of",
591
- fieldTypes: ["integer", "string", "datetime"]
592
- },
593
- {
594
- /** Matches if field value is not in provided array
595
- * @field Integer, String, Datetime
596
- * @value Array
597
- */
598
- matcher: "is_not_in",
599
- label: "is not one of",
600
- fieldTypes: ["integer", "string", "datetime"]
601
- },
602
- {
603
- /** Matches objects within arrays that meet specified requirements
604
- * @field Array
605
- * @value Object
606
- */
607
- matcher: "array_match",
608
- label: "is",
609
- fieldTypes: ["integer", "string", "datetime"]
610
- },
611
- {
612
- /** Matches if field value is null or empty string */
613
- matcher: "blank",
614
- label: "is blank",
615
- fieldTypes: ["integer", "string", "datetime", "boolean"]
616
- },
617
- {
618
- /** Matches if field value is null */
619
- matcher: "null",
620
- label: "is null",
621
- fieldTypes: ["integer", "string", "datetime", "boolean"]
622
- },
623
- {
624
- /** Matches if field value is not null */
625
- matcher: "not_null",
626
- label: "is not null",
627
- fieldTypes: ["integer", "string", "datetime", "boolean"]
628
- },
629
- {
630
- /** Matches if field value is not null */
631
- matcher: "present",
632
- label: "is present",
633
- fieldTypes: ["integer", "string", "datetime", "boolean"]
634
- }
635
- ], O = {
636
- in_and: {
637
- label: "all of"
638
- },
639
- in_or: {
640
- label: "at least one of"
641
- },
642
- not_in_and: {
643
- label: "not any of"
644
- },
645
- not_in_or: {
646
- label: "not at least one of"
647
- }
648
- };
649
- function pe({
650
- value: t,
651
- pathPrefix: n
652
- }) {
653
- return (typeof t != "object" || Array.isArray(t) || t === null) && (t = {
654
- in_and: []
655
- }), /* @__PURE__ */ e.jsx("div", { children: Object.entries(t).map(([a, r], u) => /* @__PURE__ */ e.jsx(
656
- be,
657
- {
658
- pathPrefix: n,
659
- defaultValue: r,
660
- initialMatcher: a
661
- },
662
- `${n}.${// biome-ignore lint/suspicious/noArrayIndexKey: Using index as key is acceptable here since items are static
663
- u}`
664
- )) });
665
- }
666
- function be({
667
- initialMatcher: t,
668
- defaultValue: n,
669
- pathPrefix: a
670
- }) {
671
- const [r, u] = g(t), [s, l] = g(t), [i, o] = g(n), { setPath: c } = h();
672
- return v(() => {
673
- r !== s && (c(`${a}.${r}`, null), u(s)), c(`${a}.${s}`, i);
674
- }, [s, i, c]), /* @__PURE__ */ e.jsxs("div", { className: "flex gap-2 last-of-type:mt-2", children: [
675
- /* @__PURE__ */ e.jsx("div", { className: "shrink-0", children: /* @__PURE__ */ e.jsx(
676
- y,
677
- {
678
- defaultValue: [
679
- { value: s, label: O[s].label }
680
- ],
681
- initialValues: Object.entries(O).map(
682
- ([d, { label: m }]) => ({
683
- value: d,
684
- label: m
685
- })
686
- ),
687
- onSelect: (d) => {
688
- $(d) && l(d.value);
689
- }
690
- }
691
- ) }),
692
- /* @__PURE__ */ e.jsx("div", { className: "grow", children: /* @__PURE__ */ e.jsx(
693
- y,
694
- {
695
- isMulti: !0,
696
- isCreatable: !0,
697
- defaultValue: (Array.isArray(i) ? i : []).map((d) => ({
698
- value: d,
699
- label: d.toString()
700
- })),
701
- initialValues: [],
702
- onSelect: (d) => {
703
- U(d) && o(
704
- d.map(
705
- (m) => typeof m.value == "boolean" ? m.value.toString() : m.value
706
- )
707
- );
708
- }
709
- }
710
- ) })
711
- ] });
712
- }
713
- function ye({
714
- value: t,
715
- onChange: n
716
- }) {
717
- const [a, r] = g(
718
- Array.isArray(t) && typeof t[0] == "number" ? t[0] : null
719
- ), [u, s] = g(
720
- Array.isArray(t) && typeof t[1] == "number" ? t[1] : null
721
- );
722
- return /* @__PURE__ */ e.jsxs("div", { className: "flex items-center gap-4", children: [
723
- /* @__PURE__ */ e.jsx("div", { className: "grow", children: /* @__PURE__ */ e.jsx(
724
- f,
725
- {
726
- type: "number",
727
- placeholder: "Min",
728
- value: a ?? "",
729
- onChange: (l) => {
730
- const i = parseInt(l.currentTarget.value, 10);
731
- r(Number.isNaN(i) ? null : i), n([Number.isNaN(i) ? null : i, u]);
732
- }
733
- }
734
- ) }),
735
- /* @__PURE__ */ e.jsx("span", { className: "text-gray-300", children: "to" }),
736
- /* @__PURE__ */ e.jsx("div", { className: "grow", children: /* @__PURE__ */ e.jsx(
737
- f,
738
- {
739
- type: "number",
740
- placeholder: "Max",
741
- value: u ?? "",
742
- onChange: (l) => {
743
- const i = parseInt(l.currentTarget.value, 10);
744
- s(Number.isNaN(i) ? null : i), n([a, Number.isNaN(i) ? null : i]);
745
- }
746
- }
747
- ) })
748
- ] });
749
- }
750
- function ve({
751
- value: t,
752
- onChange: n
753
- }) {
754
- const [a, r] = g(
755
- Array.isArray(t) && typeof t[0] == "string" ? t[0] : null
756
- ), [u, s] = g(
757
- Array.isArray(t) && typeof t[1] == "string" ? t[1] : null
758
- );
759
- return /* @__PURE__ */ e.jsxs("div", { className: "flex items-center gap-4", children: [
760
- /* @__PURE__ */ e.jsx("div", { className: "grow", children: /* @__PURE__ */ e.jsx(
761
- f,
762
- {
763
- type: "text",
764
- placeholder: "Min",
765
- value: a ?? "",
766
- onChange: (l) => {
767
- const i = l.currentTarget.value;
768
- r(i), n([i, u]);
769
- }
770
- }
771
- ) }),
772
- /* @__PURE__ */ e.jsx("span", { className: "text-gray-300", children: "to" }),
773
- /* @__PURE__ */ e.jsx("div", { className: "grow", children: /* @__PURE__ */ e.jsx(
774
- f,
775
- {
776
- type: "text",
777
- placeholder: "Max",
778
- value: u ?? "",
779
- onChange: (l) => {
780
- const i = l.currentTarget.value;
781
- s(i), n([a, i]);
782
- }
783
- }
784
- ) })
785
- ] });
786
- }
787
- function je({
788
- item: t,
789
- pathPrefix: n
790
- }) {
791
- const { setPath: a } = h(), { infos: r } = X(t), { user: u } = ee(), s = `${n}.value`;
792
- if (t == null || W.includes(
793
- t.matcher
794
- ))
795
- return null;
796
- const l = t;
797
- let i = r?.field?.type;
798
- i == null && (i = Y(l.value)), (typeof l.value == "string" && /^{{.*}}$/.test(l.value) || Array.isArray(l.value) && l.value.some(
799
- (c) => typeof c == "string" && /^{{.*}}$/.test(c)
800
- )) && (i = "string");
801
- let o = null;
802
- switch (i) {
803
- case "datetime": {
804
- o = "date";
805
- break;
806
- }
807
- case "boolean": {
808
- o = "boolean";
809
- break;
810
- }
811
- case "string": {
812
- o = "text";
813
- break;
814
- }
815
- case "integer":
816
- case "float": {
817
- o = "number";
818
- break;
819
- }
820
- case "array":
821
- case "json":
822
- case "object":
823
- break;
824
- default: {
825
- o = "text";
826
- break;
827
- }
828
- }
829
- switch (l.matcher) {
830
- case "eq":
831
- case "not_eq":
832
- case "lt":
833
- case "lteq":
834
- case "gt":
835
- case "gteq":
836
- case "multiple":
837
- case "start_with":
838
- case "not_start_with":
839
- case "end_with":
840
- case "not_end_with":
841
- break;
842
- case "matches":
843
- case "does_not_match":
844
- break;
845
- case "gt_lt":
846
- case "gteq_lt":
847
- case "gt_lteq":
848
- case "gteq_lteq": {
849
- o === "number" && (o = "numberRange"), o === "text" && (o = "textRange"), o === "date" && (o = "dateRange");
850
- break;
851
- }
852
- case "is_in":
853
- case "is_not_in": {
854
- o = "tag";
855
- break;
856
- }
857
- case "array_match": {
858
- o = "arrayMatch";
859
- break;
860
- }
861
- default: {
862
- E(l.matcher);
863
- break;
864
- }
865
- }
866
- switch (o) {
867
- case "date": {
868
- const c = k(
869
- typeof l.value == "string" ? l.value : ""
870
- );
871
- return /* @__PURE__ */ e.jsx(
872
- ne,
873
- {
874
- value: w(c) ? c : void 0,
875
- showTimeSelect: !0,
876
- placeholder: "Enter value",
877
- onChange: (d) => {
878
- a(s, d?.toJSON());
879
- },
880
- timezone: u?.timezone
881
- }
882
- );
883
- }
884
- case "dateRange": {
885
- const c = Array.isArray(l.value) ? l.value.map((d) => {
886
- const m = k(typeof d == "string" ? d : "");
887
- return w(m) ? m : null;
888
- }) : [null, null];
889
- return /* @__PURE__ */ e.jsx(
890
- te,
891
- {
892
- value: c,
893
- showTimeSelect: !0,
894
- onChange: (d) => {
895
- a(
896
- `${n}.value`,
897
- d.map((m) => m?.toJSON() ?? null)
898
- );
899
- }
900
- }
901
- );
902
- }
903
- case "numberRange":
904
- return /* @__PURE__ */ e.jsx(
905
- ye,
906
- {
907
- value: l.value,
908
- onChange: (c) => {
909
- a(s, c);
910
- }
911
- }
912
- );
913
- case "textRange":
914
- return /* @__PURE__ */ e.jsx(
915
- ve,
916
- {
917
- value: l.value,
918
- onChange: (c) => {
919
- a(s, c);
920
- }
921
- }
922
- );
923
- case "arrayMatch":
924
- return /* @__PURE__ */ e.jsx(
925
- pe,
926
- {
927
- value: l.value,
928
- pathPrefix: `${n}.value`
929
- }
930
- );
931
- case "tag":
932
- return /* @__PURE__ */ e.jsx(
933
- y,
934
- {
935
- isMulti: !0,
936
- isClearable: !1,
937
- isCreatable: !0,
938
- defaultValue: Array.isArray(l.value) ? l.value.map((c) => ({
939
- label: c.toString(),
940
- value: c
941
- })) : [],
942
- initialValues: [],
943
- onSelect: (c) => {
944
- U(c) && a(
945
- `${n}.value`,
946
- c.map((d) => {
947
- if (i === "integer") {
948
- const m = parseInt(d.value.toString(), 10);
949
- return Number.isNaN(m) ? null : m;
950
- }
951
- return d.value;
952
- }).filter((d) => d != null)
953
- );
954
- }
955
- }
956
- );
957
- case "number":
958
- return /* @__PURE__ */ e.jsx(
959
- f,
960
- {
961
- name: `${n}.value`,
962
- type: "number",
963
- defaultValue: typeof l.value == "number" ? l.value : "",
964
- placeholder: "Enter value",
965
- onChange: (c) => {
966
- a(
967
- `${n}.value`,
968
- parseInt(c.currentTarget.value, 10)
969
- );
970
- }
971
- }
972
- );
973
- case "boolean":
974
- return /* @__PURE__ */ e.jsx(
975
- y,
976
- {
977
- name: `${n}.value`,
978
- defaultValue: typeof l.value == "boolean" ? {
979
- label: l.value ? "Yes" : "No",
980
- value: l.value
981
- } : void 0,
982
- initialValues: [
983
- { label: "Yes", value: !0 },
984
- { label: "No", value: !1 }
985
- ],
986
- onSelect: (c) => {
987
- $(c) && a(s, c.value);
988
- }
989
- }
990
- );
991
- case "text":
992
- case null:
993
- return /* @__PURE__ */ e.jsx(
994
- f,
995
- {
996
- name: `${n}.value`,
997
- type: "text",
998
- defaultValue: typeof l.value == "string" ? l.value : JSON.stringify(l.value),
999
- placeholder: "Enter value",
1000
- onChange: (c) => {
1001
- a(s, c.currentTarget.value);
1002
- }
1003
- }
1004
- );
1005
- default:
1006
- return E();
1007
- }
1008
- }
1009
- function Ne({
1010
- item: t,
1011
- nestingLevel: n,
1012
- pathPrefix: a,
1013
- onDelete: r
1014
- }) {
1015
- const { setPath: u } = h(), s = [];
1016
- return n < 2 && (s[0] ??= [], s[0].push(
1017
- /* @__PURE__ */ e.jsx(
1018
- R,
1019
- {
1020
- label: "Nest conditions",
1021
- onClick: () => {
1022
- u(
1023
- `${a}.nested.conditions.${(t?.nested?.conditions ?? []).length}`,
1024
- void 0
1025
- );
1026
- }
1027
- }
1028
- )
1029
- )), r != null && (s[1] ??= [], s[1].push(
1030
- /* @__PURE__ */ e.jsx(
1031
- R,
1032
- {
1033
- label: "Delete",
1034
- onClick: () => {
1035
- u(`${a}`, null), r();
1036
- }
1037
- }
1038
- )
1039
- )), /* @__PURE__ */ e.jsxs("div", { className: "bg-gray-50 rounded-md flex items-center", children: [
1040
- /* @__PURE__ */ e.jsx("div", { className: "flex items-center justify-between gap-2 grow p-2", children: /* @__PURE__ */ e.jsxs("div", { className: "flex flex-col gap-2 grow", children: [
1041
- /* @__PURE__ */ e.jsxs("div", { className: "flex items-center justify-between gap-2", children: [
1042
- /* @__PURE__ */ e.jsx("div", { className: "flex-1", children: /* @__PURE__ */ e.jsx(
1043
- f,
1044
- {
1045
- name: `${a}.field`,
1046
- type: "text",
1047
- defaultValue: t?.field,
1048
- onChange: (l) => {
1049
- u(`${a}.field`, l.currentTarget.value);
1050
- },
1051
- onBlur: (l) => {
1052
- u(`${a}.field`, l.currentTarget.value);
1053
- }
1054
- }
1055
- ) }),
1056
- /* @__PURE__ */ e.jsx("div", { children: /* @__PURE__ */ e.jsx(xe, { item: t, pathPrefix: a }) })
1057
- ] }),
1058
- /* @__PURE__ */ e.jsx(je, { item: t, pathPrefix: a })
1059
- ] }) }),
1060
- s.length > 0 && /* @__PURE__ */ e.jsx(
1061
- z,
1062
- {
1063
- className: "w-8 border-l border-gray-100 flex items-center justify-center self-stretch",
1064
- dropdownLabel: /* @__PURE__ */ e.jsx(
1065
- "button",
1066
- {
1067
- type: "button",
1068
- className: "flex items-center justify-center self-stretch grow",
1069
- children: /* @__PURE__ */ e.jsx(p, { name: "dotsThreeVertical", size: 16, weight: "bold" })
1070
- }
1071
- ),
1072
- dropdownItems: s.map((l, i, o) => (
1073
- // biome-ignore lint/suspicious/noArrayIndexKey: Using index as key is acceptable here since items are static
1074
- /* @__PURE__ */ e.jsxs(I.Fragment, { children: [
1075
- l.map((c, d) => (
1076
- // biome-ignore lint/suspicious/noArrayIndexKey: Using index as key is acceptable here since items are static
1077
- /* @__PURE__ */ e.jsx(I.Fragment, { children: c }, d)
1078
- )),
1079
- i < o.length - 1 && /* @__PURE__ */ e.jsx(ae, {})
1080
- ] }, i)
1081
- ))
1082
- }
1083
- )
1084
- ] });
1085
- }
1086
- function B({
1087
- item: t,
1088
- children: n,
1089
- nestingLevel: a = 0,
1090
- pathPrefix: r
1091
- }) {
1092
- const {
1093
- state: { selectedRuleIndex: u }
1094
- } = h(), s = t?.conditions_logic?.toLowerCase() ?? "and", { setPath: l } = h(), [i, o] = g(0), c = a > 0;
1095
- return /* @__PURE__ */ e.jsxs(
1096
- "div",
1097
- {
1098
- className: _("query-group", {
1099
- "p-4 border border-gray-200 rounded-md": c
1100
- }),
1101
- children: [
1102
- n,
1103
- t != null && (t.conditions ?? []).length > 0 && /* @__PURE__ */ e.jsxs(e.Fragment, { children: [
1104
- /* @__PURE__ */ e.jsxs(
1105
- "select",
1106
- {
1107
- onChange: (d) => {
1108
- l(
1109
- `${r}.conditions_logic`,
1110
- d.currentTarget.value
1111
- );
1112
- },
1113
- defaultValue: s,
1114
- className: "pl-4 pr-8 py-2 font-bold focus:ring-0 focus:outline-hidden appearance-none bg-gray-50 border border-gray-200 rounded-md text-sm leading-4",
1115
- children: [
1116
- /* @__PURE__ */ e.jsxs("option", { value: "and", children: [
1117
- c ? "Nested in " : "",
1118
- "AND"
1119
- ] }),
1120
- /* @__PURE__ */ e.jsxs("option", { value: "or", children: [
1121
- c ? "Nested in " : "",
1122
- "OR"
1123
- ] })
1124
- ]
1125
- }
1126
- ),
1127
- /* @__PURE__ */ e.jsx("div", { className: "border-l border-gray-200 ml-3 pt-3", children: t?.conditions?.map((d, m, j) => {
1128
- const b = m === j.length - 1;
1129
- return /* @__PURE__ */ e.jsxs(
1130
- "div",
1131
- {
1132
- className: "flex items-center mb-4 last:mb-0 relative",
1133
- children: [
1134
- /* @__PURE__ */ e.jsx(we, { rounded: b }),
1135
- /* @__PURE__ */ e.jsx("div", { className: "ml-4 w-full", children: /* @__PURE__ */ e.jsx(
1136
- B,
1137
- {
1138
- item: d?.nested ?? void 0,
1139
- nestingLevel: d?.nested != null ? a + 1 : 0,
1140
- pathPrefix: `${r}.conditions.${m}.nested`,
1141
- children: /* @__PURE__ */ e.jsx(
1142
- "div",
1143
- {
1144
- className: _({
1145
- "mb-4": d?.nested != null
1146
- }),
1147
- children: /* @__PURE__ */ e.jsx(
1148
- Ne,
1149
- {
1150
- item: d,
1151
- nestingLevel: a,
1152
- pathPrefix: `${r}.conditions.${m}`,
1153
- onDelete: j.length > 1 || a > 0 ? () => {
1154
- o((x) => x + 1);
1155
- } : void 0
1156
- }
1157
- )
1158
- }
1159
- )
1160
- }
1161
- ) })
1162
- ]
1163
- },
1164
- `${u}-${m}-${i}`
1165
- );
1166
- }) })
1167
- ] })
1168
- ]
1169
- }
1170
- );
1171
- }
1172
- function we({
1173
- rounded: t = !1
1174
- }) {
1175
- return t ? /* @__PURE__ */ e.jsxs(e.Fragment, { children: [
1176
- /* @__PURE__ */ e.jsx("div", { className: "absolute -left-px top-1/2 w-px h-1/2 bg-white" }),
1177
- /* @__PURE__ */ e.jsx("div", { className: "absolute -left-px top-1/2 -translate-y-1/2 w-3.5 h-3.5 border-l border-b rounded-es-sm bg-white border-gray-200" })
1178
- ] }) : /* @__PURE__ */ e.jsx("div", { className: "absolute left-0 top-1/2 -translate-y-1/2 w-3.5 h-px bg-gray-200" });
1179
- }
1180
- function _e() {
1181
- const {
1182
- setPath: t,
1183
- state: { value: n, selectedRuleIndex: a }
1184
- } = h(), [r, u] = g(
1185
- n.rules[a]?.name ?? ""
1186
- );
1187
- return v(() => {
1188
- u(n.rules[a]?.name ?? "");
1189
- }, [a]), // biome-ignore lint/a11y/noStaticElementInteractions: This <div> is used with contentEditable
1190
- /* @__PURE__ */ e.jsx(
1191
- "div",
1192
- {
1193
- contentEditable: "plaintext-only",
1194
- suppressContentEditableWarning: !0,
1195
- onInput: (s) => {
1196
- const i = s.currentTarget.innerText.replace(/[\n\s]+/g, " ").trim();
1197
- t(`rules.${a}.name`, i);
1198
- },
1199
- onKeyDown: (s) => {
1200
- s.key === "Enter" && (s.preventDefault(), s.currentTarget.blur());
1201
- },
1202
- onBlur: (s) => {
1203
- const l = s.currentTarget;
1204
- l.innerText = l.innerText.replace(/[\n\s]+/g, " ").trim();
1205
- },
1206
- children: r
1207
- },
1208
- a
1209
- );
1210
- }
1211
- const F = {
1212
- rules: []
1213
- }, T = (t) => {
1214
- try {
1215
- return JSON.parse(t ?? JSON.stringify(F));
1216
- } catch {
1217
- return F;
1218
- }
1219
- }, Te = (t) => {
1220
- try {
1221
- return JSON.parse(t ?? "{}"), !0;
1222
- } catch {
1223
- return !1;
1224
- }
1225
- };
1226
- function ke(t) {
1227
- const [n, a] = g(
1228
- T(t.value ?? t.defaultValue)
1229
- );
1230
- return v(
1231
- function() {
1232
- n.rules.length === 0 && a(T(t.value));
1233
- },
1234
- [t.value]
1235
- ), /* @__PURE__ */ e.jsx(me, { initialValue: { rules: n.rules }, children: /* @__PURE__ */ e.jsx($e, { ...t }) });
1236
- }
1237
- function $e(t) {
1238
- const {
1239
- state: { value: n, selectedRuleIndex: a },
1240
- setSelectedRuleIndex: r,
1241
- setValue: u,
1242
- setPath: s
1243
- } = h(), [l, i] = g(
1244
- t.defaultCodeEditorVisible ?? !1
1245
- ), o = n.rules[a], c = oe(null), [d, m] = g(0);
1246
- v(
1247
- function() {
1248
- V(T(c.current?.getValue()), n) || c.current?.setValue(JSON.stringify(n, null, 2)), t.onChange?.(n);
1249
- },
1250
- [n]
1251
- );
1252
- const j = N(
1253
- (b) => {
1254
- const x = T(b);
1255
- c.current?.hasTextFocus() && Te(b) && !V(x, n) && (u(x), m((C) => C + 1));
1256
- },
1257
- [n]
1258
- );
1259
- return /* @__PURE__ */ e.jsx(
1260
- le,
1261
- {
1262
- hint: t.hint,
1263
- feedback: t.feedback,
1264
- className: "h-full [&>div:first-of-type]:h-full",
1265
- children: /* @__PURE__ */ e.jsxs("section", { className: "flex h-full", children: [
1266
- /* @__PURE__ */ e.jsxs(
1267
- "div",
1268
- {
1269
- className: `shrink-0 basis-3/5 overflow-x-auto relative flex flex-col ${l ? "" : "grow"}`,
1270
- children: [
1271
- /* @__PURE__ */ e.jsxs("header", { className: "w-full bg-white border-b border-gray-200 py-3 px-8 flex text-[13px] gap-4 text-gray-400 font-semibold items-center", children: [
1272
- /* @__PURE__ */ e.jsxs("div", { className: "flex items-center gap-4 flex-wrap", children: [
1273
- n.rules.map((b, x) => {
1274
- const C = `#${(x + 1).toString().padStart(2, "0")}`;
1275
- return /* @__PURE__ */ e.jsx(
1276
- "button",
1277
- {
1278
- type: "button",
1279
- className: _("font-bold", {
1280
- "text-black": a === x
1281
- }),
1282
- onClick: () => {
1283
- r(x);
1284
- },
1285
- children: C
1286
- },
1287
- `${a}-${b.id}`
1288
- );
1289
- }),
1290
- /* @__PURE__ */ e.jsx(
1291
- "button",
1292
- {
1293
- type: "button",
1294
- className: _("font-bold", {
1295
- "text-black": !0
1296
- }),
1297
- onClick: () => {
1298
- s(`rules.${n.rules.length}`, {
1299
- name: "Rule name",
1300
- actions: [null],
1301
- conditions: [null]
1302
- }), r(n.rules.length);
1303
- },
1304
- children: /* @__PURE__ */ e.jsx(p, { name: "plus", size: 16, className: "shrink-0" })
1305
- }
1306
- )
1307
- ] }),
1308
- /* @__PURE__ */ e.jsx("div", { className: "grow flex justify-end", children: /* @__PURE__ */ e.jsx(
1309
- "button",
1310
- {
1311
- type: "button",
1312
- className: "text-blue-600 hover:text-blue-700 focus:outline-hidden focus:ring-2 focus:ring-blue-500",
1313
- onClick: () => {
1314
- i(!l);
1315
- },
1316
- children: /* @__PURE__ */ e.jsx(p, { name: "sidebarSimple", size: 16, color: "#101111" })
1317
- }
1318
- ) })
1319
- ] }),
1320
- /* @__PURE__ */ e.jsxs(Ve, { children: [
1321
- /* @__PURE__ */ e.jsxs("div", { className: "mb-8 flex items-center gap-2", children: [
1322
- /* @__PURE__ */ e.jsx(_e, {}),
1323
- /* @__PURE__ */ e.jsx(p, { name: "pencilSimple", size: 16, className: "shrink-0" })
1324
- ] }),
1325
- /* @__PURE__ */ e.jsx(L, { title: "Actions", icon: "lightning", children: /* @__PURE__ */ e.jsx(he, { actions: o?.actions }) }),
1326
- /* @__PURE__ */ e.jsx(Ce, { children: "when" }),
1327
- /* @__PURE__ */ e.jsxs(L, { title: "Conditions", icon: "treeView", children: [
1328
- /* @__PURE__ */ e.jsx(
1329
- B,
1330
- {
1331
- item: o,
1332
- pathPrefix: `rules.${a}`
1333
- }
1334
- ),
1335
- /* @__PURE__ */ e.jsx("div", { className: "mt-6", children: /* @__PURE__ */ e.jsxs(
1336
- J,
1337
- {
1338
- size: "small",
1339
- variant: "secondary",
1340
- alignItems: "center",
1341
- onClick: () => {
1342
- s(
1343
- `rules.${a}.conditions.${o?.conditions?.length ?? 0}`,
1344
- void 0
1345
- );
1346
- },
1347
- children: [
1348
- /* @__PURE__ */ e.jsx(p, { name: "plusCircle" }),
1349
- " Add condition"
1350
- ]
1351
- }
1352
- ) })
1353
- ] })
1354
- ] })
1355
- ]
1356
- },
1357
- d
1358
- ),
1359
- l && /* @__PURE__ */ e.jsx("div", { className: "shrink-0 basis-2/5", children: /* @__PURE__ */ e.jsx(
1360
- se,
1361
- {
1362
- ref: c,
1363
- name: t.id ?? t.name,
1364
- height: "100%",
1365
- language: "json",
1366
- jsonSchema: "order-rules",
1367
- defaultValue: JSON.stringify(n, null, 2),
1368
- noRounding: !0,
1369
- onChange: j
1370
- }
1371
- ) })
1372
- ] })
1373
- }
1374
- );
1375
- }
1376
- function Ce({ children: t }) {
1377
- return /* @__PURE__ */ e.jsxs("div", { className: "text-gray-500 flex items-center justify-center flex-col", children: [
1378
- /* @__PURE__ */ e.jsx("div", { className: "h-6 w-[2px] bg-gray-200" }),
1379
- /* @__PURE__ */ e.jsx("span", { className: "font-bold my-1 bg-gray-200 px-3 relative uppercase rounded h-[25px] items-center flex text-sm", children: t }),
1380
- /* @__PURE__ */ e.jsx("div", { className: "h-6 w-[2px] bg-gray-200" })
1381
- ] });
1382
- }
1383
- function L({
1384
- children: t,
1385
- title: n,
1386
- icon: a
1387
- }) {
1388
- return /* @__PURE__ */ e.jsxs("div", { className: "rounded-md bg-white shadow-xs", children: [
1389
- /* @__PURE__ */ e.jsxs("div", { className: "flex items-center space-x-4 py-4 border-b border-gray-100", children: [
1390
- /* @__PURE__ */ e.jsx("div", { className: "w-8 h-8 -ml-4 bg-white rounded-full border border-gray-200 flex items-center justify-center shadow-xs shadow-primary-200", children: /* @__PURE__ */ e.jsx(p, { name: a }) }),
1391
- /* @__PURE__ */ e.jsx("h2", { className: "text-lg font-semibold", children: n })
1392
- ] }),
1393
- /* @__PURE__ */ e.jsx("div", { className: "p-6", children: t })
1394
- ] });
1395
- }
1396
- function Ve({
1397
- children: t
1398
- }) {
1399
- return /* @__PURE__ */ e.jsx("div", { className: "h-full w-full bg-gray-50 p-8 bg-[radial-gradient(#d6d6d6_1px,transparent_1px)] bg-size-[16px_16px] overflow-auto", children: /* @__PURE__ */ e.jsx("div", { className: "max-w-[900px] mx-auto", children: t }) });
1400
- }
1401
- export {
1402
- ke as RuleEngine
1403
- };