@streamoid/catalogix-chat 0.2.3 → 0.2.4

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.
package/dist/index.js CHANGED
@@ -2434,9 +2434,589 @@ function CreateStore({
2434
2434
  ] });
2435
2435
  }
2436
2436
 
2437
+ // src/MapAttributes/index.tsx
2438
+ import React7, { useState as useState7, useMemo as useMemo5, useCallback as useCallback5 } from "react";
2439
+ import {
2440
+ Check as Check2,
2441
+ X,
2442
+ ChevronRight as ChevronRight2,
2443
+ Pencil as Pencil2,
2444
+ Search as Search3,
2445
+ ArrowRight,
2446
+ ArrowLeft as ArrowLeft2
2447
+ } from "lucide-react";
2448
+
2449
+ // src/ui/scroll-area.tsx
2450
+ import * as ScrollAreaPrimitive from "@radix-ui/react-scroll-area";
2451
+ import { jsx as jsx21, jsxs as jsxs10 } from "react/jsx-runtime";
2452
+ function ScrollArea({
2453
+ className,
2454
+ children,
2455
+ ...props
2456
+ }) {
2457
+ return /* @__PURE__ */ jsxs10(
2458
+ ScrollAreaPrimitive.Root,
2459
+ {
2460
+ "data-slot": "scroll-area",
2461
+ className: cn("relative", className),
2462
+ ...props,
2463
+ children: [
2464
+ /* @__PURE__ */ jsx21(
2465
+ ScrollAreaPrimitive.Viewport,
2466
+ {
2467
+ "data-slot": "scroll-area-viewport",
2468
+ className: "focus-visible:ring-ring/50 size-full rounded-[inherit] transition-[color,box-shadow] outline-none focus-visible:ring-[3px] focus-visible:outline-1",
2469
+ children
2470
+ }
2471
+ ),
2472
+ /* @__PURE__ */ jsx21(ScrollBar, {}),
2473
+ /* @__PURE__ */ jsx21(ScrollAreaPrimitive.Corner, {})
2474
+ ]
2475
+ }
2476
+ );
2477
+ }
2478
+ function ScrollBar({
2479
+ className,
2480
+ orientation = "vertical",
2481
+ ...props
2482
+ }) {
2483
+ return /* @__PURE__ */ jsx21(
2484
+ ScrollAreaPrimitive.ScrollAreaScrollbar,
2485
+ {
2486
+ "data-slot": "scroll-area-scrollbar",
2487
+ orientation,
2488
+ className: cn(
2489
+ "flex touch-none p-px transition-colors select-none",
2490
+ orientation === "vertical" && "h-full w-2.5 border-l border-l-transparent",
2491
+ orientation === "horizontal" && "h-2.5 flex-col border-t border-t-transparent",
2492
+ className
2493
+ ),
2494
+ ...props,
2495
+ children: /* @__PURE__ */ jsx21(
2496
+ ScrollAreaPrimitive.ScrollAreaThumb,
2497
+ {
2498
+ "data-slot": "scroll-area-thumb",
2499
+ className: "bg-border relative flex-1 rounded-full"
2500
+ }
2501
+ )
2502
+ }
2503
+ );
2504
+ }
2505
+
2506
+ // src/MapAttributes/index.tsx
2507
+ import { jsx as jsx22, jsxs as jsxs11 } from "react/jsx-runtime";
2508
+ function getAllAttributes(mpAttributes) {
2509
+ return Object.values(mpAttributes).flat();
2510
+ }
2511
+ function getColumnLabel(index) {
2512
+ const letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
2513
+ if (index < 26) return `Column ${letters[index]}`;
2514
+ return `Column ${index + 1}`;
2515
+ }
2516
+ function SingleAttributeRow({
2517
+ item,
2518
+ index,
2519
+ allAttributes,
2520
+ allMappedAttributes,
2521
+ onMap,
2522
+ onConfirm,
2523
+ onIgnore,
2524
+ onEdit,
2525
+ onUnmap
2526
+ }) {
2527
+ const [popoverOpen, setPopoverOpen] = useState7(false);
2528
+ const hasMappedCols = item.mappedCols.length > 0 || item.customCols.length > 0;
2529
+ const availableAttributes = useMemo5(() => {
2530
+ const mapped = /* @__PURE__ */ new Set([...item.mappedCols, ...item.customCols]);
2531
+ return allAttributes.filter((a) => !mapped.has(a));
2532
+ }, [allAttributes, item.mappedCols, item.customCols]);
2533
+ if (item.isConfirmed) {
2534
+ return /* @__PURE__ */ jsxs11("div", { className: "flex items-center gap-3 rounded-lg border border-green-200 bg-green-50/50 px-3 py-2", children: [
2535
+ /* @__PURE__ */ jsx22("div", { className: "min-w-0 flex-1", children: /* @__PURE__ */ jsxs11("div", { className: "flex items-center gap-2", children: [
2536
+ /* @__PURE__ */ jsx22("span", { className: "truncate text-sm font-medium", children: item.feedCol }),
2537
+ /* @__PURE__ */ jsx22(ChevronRight2, { className: "size-3.5 shrink-0 text-muted-foreground" }),
2538
+ /* @__PURE__ */ jsx22("span", { className: "truncate text-sm text-green-700", children: [...item.mappedCols, ...item.customCols].join(", ") })
2539
+ ] }) }),
2540
+ /* @__PURE__ */ jsxs11("div", { className: "flex items-center gap-2", children: [
2541
+ /* @__PURE__ */ jsxs11(
2542
+ Badge,
2543
+ {
2544
+ variant: "secondary",
2545
+ className: "gap-1 bg-green-100 text-green-700",
2546
+ children: [
2547
+ /* @__PURE__ */ jsx22(Check2, { className: "size-3" }),
2548
+ "Confirmed"
2549
+ ]
2550
+ }
2551
+ ),
2552
+ /* @__PURE__ */ jsx22(Button, { variant: "ghost", size: "sm", onClick: () => onEdit(index), children: /* @__PURE__ */ jsx22(Pencil2, { className: "size-3.5" }) })
2553
+ ] })
2554
+ ] });
2555
+ }
2556
+ if (item.isIgnored) {
2557
+ return /* @__PURE__ */ jsxs11("div", { className: "flex items-center gap-3 rounded-lg border border-red-200 bg-red-50/50 px-3 py-2", children: [
2558
+ /* @__PURE__ */ jsx22("div", { className: "min-w-0 flex-1", children: /* @__PURE__ */ jsx22("span", { className: "truncate text-sm font-medium text-muted-foreground", children: item.feedCol }) }),
2559
+ /* @__PURE__ */ jsxs11("div", { className: "flex items-center gap-2", children: [
2560
+ /* @__PURE__ */ jsxs11(Badge, { variant: "secondary", className: "gap-1 bg-red-100 text-red-700", children: [
2561
+ /* @__PURE__ */ jsx22(X, { className: "size-3" }),
2562
+ "Ignored"
2563
+ ] }),
2564
+ /* @__PURE__ */ jsx22(Button, { variant: "ghost", size: "sm", onClick: () => onEdit(index), children: /* @__PURE__ */ jsx22(Pencil2, { className: "size-3.5" }) })
2565
+ ] })
2566
+ ] });
2567
+ }
2568
+ return /* @__PURE__ */ jsxs11("div", { className: "space-y-2 rounded-lg border px-3 py-3", children: [
2569
+ /* @__PURE__ */ jsx22("div", { className: "flex items-start justify-between gap-2", children: /* @__PURE__ */ jsxs11("div", { className: "min-w-0 flex-1 space-y-1", children: [
2570
+ /* @__PURE__ */ jsx22("div", { className: "flex items-center gap-2", children: /* @__PURE__ */ jsx22("span", { className: "text-xs font-medium text-muted-foreground", children: getColumnLabel(index) }) }),
2571
+ /* @__PURE__ */ jsx22("p", { className: "text-sm font-medium", children: item.feedCol }),
2572
+ item.rows.length > 0 && /* @__PURE__ */ jsx22("div", { className: "flex flex-wrap gap-1", children: item.rows.slice(0, 3).map((val, i) => /* @__PURE__ */ jsx22(Badge, { variant: "outline", className: "text-xs font-normal", children: val || "\u2014" }, i)) })
2573
+ ] }) }),
2574
+ /* @__PURE__ */ jsxs11("div", { className: "space-y-1.5", children: [
2575
+ item.mappedCols.map((col, attrIdx) => /* @__PURE__ */ jsxs11("div", { className: "flex items-center gap-2", children: [
2576
+ /* @__PURE__ */ jsx22(ChevronRight2, { className: "size-3.5 shrink-0 text-muted-foreground" }),
2577
+ /* @__PURE__ */ jsxs11(Badge, { variant: "secondary", className: "gap-1", children: [
2578
+ col,
2579
+ /* @__PURE__ */ jsx22(
2580
+ "button",
2581
+ {
2582
+ type: "button",
2583
+ onClick: () => onUnmap(index, attrIdx),
2584
+ className: "ml-0.5 rounded-full hover:bg-muted",
2585
+ children: /* @__PURE__ */ jsx22(X, { className: "size-3" })
2586
+ }
2587
+ )
2588
+ ] })
2589
+ ] }, attrIdx)),
2590
+ /* @__PURE__ */ jsxs11("div", { className: "flex items-center gap-2", children: [
2591
+ /* @__PURE__ */ jsx22(ChevronRight2, { className: "size-3.5 shrink-0 text-muted-foreground" }),
2592
+ /* @__PURE__ */ jsxs11(Popover, { open: popoverOpen, onOpenChange: setPopoverOpen, children: [
2593
+ /* @__PURE__ */ jsx22(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs11(
2594
+ Button,
2595
+ {
2596
+ variant: "outline",
2597
+ size: "sm",
2598
+ className: "h-8 w-full max-w-[280px] justify-start text-xs font-normal",
2599
+ children: [
2600
+ /* @__PURE__ */ jsx22(Search3, { className: "mr-1.5 size-3.5 text-muted-foreground" }),
2601
+ hasMappedCols ? "Add another mapping..." : "Lookup matching fields"
2602
+ ]
2603
+ }
2604
+ ) }),
2605
+ /* @__PURE__ */ jsx22(PopoverContent, { className: "w-[280px] p-0", align: "start", children: /* @__PURE__ */ jsxs11(Command, { children: [
2606
+ /* @__PURE__ */ jsx22(CommandInput, { placeholder: "Search attributes..." }),
2607
+ /* @__PURE__ */ jsxs11(CommandList, { children: [
2608
+ /* @__PURE__ */ jsx22(CommandEmpty, { children: "No attributes found." }),
2609
+ /* @__PURE__ */ jsx22(CommandGroup, { children: availableAttributes.map((attr) => {
2610
+ const alreadyMappedElsewhere = allMappedAttributes.has(attr);
2611
+ return /* @__PURE__ */ jsxs11(
2612
+ CommandItem,
2613
+ {
2614
+ value: attr,
2615
+ onSelect: () => {
2616
+ onMap(index, attr);
2617
+ setPopoverOpen(false);
2618
+ },
2619
+ children: [
2620
+ /* @__PURE__ */ jsx22("span", { className: cn(alreadyMappedElsewhere && "text-muted-foreground"), children: attr }),
2621
+ alreadyMappedElsewhere && /* @__PURE__ */ jsx22(Check2, { className: "ml-auto size-3 text-green-600" })
2622
+ ]
2623
+ },
2624
+ attr
2625
+ );
2626
+ }) })
2627
+ ] })
2628
+ ] }) })
2629
+ ] })
2630
+ ] })
2631
+ ] }),
2632
+ /* @__PURE__ */ jsxs11("div", { className: "flex items-center gap-2 pt-1", children: [
2633
+ /* @__PURE__ */ jsx22(
2634
+ Button,
2635
+ {
2636
+ variant: "ghost",
2637
+ size: "sm",
2638
+ className: "text-xs",
2639
+ onClick: () => onIgnore(index),
2640
+ children: "Ignore Column"
2641
+ }
2642
+ ),
2643
+ hasMappedCols && /* @__PURE__ */ jsx22(
2644
+ Button,
2645
+ {
2646
+ size: "sm",
2647
+ className: "text-xs",
2648
+ onClick: () => onConfirm(index),
2649
+ children: "Confirm Mapping"
2650
+ }
2651
+ )
2652
+ ] })
2653
+ ] });
2654
+ }
2655
+ function ValueMappingPanel({
2656
+ data,
2657
+ valuesOntologyAttributes,
2658
+ uniqueValues,
2659
+ onValueChange
2660
+ }) {
2661
+ const [selectedAttrIndex, setSelectedAttrIndex] = useState7(null);
2662
+ const lovItems = useMemo5(() => {
2663
+ const items = [];
2664
+ data.forEach((item, itemIndex) => {
2665
+ if (item.isIgnored || !item.isConfirmed) return;
2666
+ item.mappedCols.forEach((attr) => {
2667
+ if (!valuesOntologyAttributes.includes(attr)) return;
2668
+ const rawVals = uniqueValues[item.feedCol] || [];
2669
+ if (rawVals.length === 0) return;
2670
+ const existing = item.mappedValues[attr] || {};
2671
+ const valueMap = {};
2672
+ rawVals.forEach((v) => {
2673
+ valueMap[v] = existing[v] ?? null;
2674
+ });
2675
+ items.push({
2676
+ itemIndex,
2677
+ feedCol: item.feedCol,
2678
+ attribute: attr,
2679
+ rawValues: rawVals,
2680
+ mappedValues: valueMap,
2681
+ totalCount: rawVals.length,
2682
+ mappedCount: Object.values(valueMap).filter((v) => v !== null).length
2683
+ });
2684
+ });
2685
+ });
2686
+ return items;
2687
+ }, [data, valuesOntologyAttributes, uniqueValues]);
2688
+ const needsMapping = lovItems.filter((i) => i.mappedCount < i.totalCount);
2689
+ const complete = lovItems.filter((i) => i.mappedCount >= i.totalCount);
2690
+ const selected = selectedAttrIndex !== null ? lovItems[selectedAttrIndex] : null;
2691
+ if (lovItems.length === 0) {
2692
+ return /* @__PURE__ */ jsx22("div", { className: "flex items-center justify-center py-8 text-sm text-muted-foreground", children: "No value mapping required \u2014 all attributes are free-text." });
2693
+ }
2694
+ return /* @__PURE__ */ jsxs11("div", { className: "flex gap-3", style: { minHeight: 300 }, children: [
2695
+ /* @__PURE__ */ jsxs11("div", { className: "w-[45%] space-y-3", children: [
2696
+ needsMapping.length > 0 && /* @__PURE__ */ jsxs11("div", { className: "space-y-1", children: [
2697
+ /* @__PURE__ */ jsxs11("p", { className: "text-xs font-medium text-amber-600", children: [
2698
+ "Mapping Required (",
2699
+ needsMapping.length,
2700
+ ")"
2701
+ ] }),
2702
+ needsMapping.map((item, i) => {
2703
+ const globalIdx = lovItems.indexOf(item);
2704
+ return /* @__PURE__ */ jsxs11(
2705
+ "button",
2706
+ {
2707
+ type: "button",
2708
+ onClick: () => setSelectedAttrIndex(globalIdx),
2709
+ className: cn(
2710
+ "flex w-full flex-col items-start rounded-md border px-2.5 py-2 text-left text-xs transition-colors",
2711
+ selectedAttrIndex === globalIdx ? "border-primary bg-primary/5" : "hover:bg-accent"
2712
+ ),
2713
+ children: [
2714
+ /* @__PURE__ */ jsxs11("span", { className: "flex items-center gap-1 font-medium", children: [
2715
+ item.feedCol,
2716
+ /* @__PURE__ */ jsx22(ChevronRight2, { className: "size-3 text-muted-foreground" }),
2717
+ item.attribute
2718
+ ] }),
2719
+ /* @__PURE__ */ jsxs11("span", { className: "text-amber-600", children: [
2720
+ "Mapping required (",
2721
+ item.mappedCount,
2722
+ "/",
2723
+ item.totalCount,
2724
+ ")"
2725
+ ] })
2726
+ ]
2727
+ },
2728
+ `need-${i}`
2729
+ );
2730
+ })
2731
+ ] }),
2732
+ complete.length > 0 && /* @__PURE__ */ jsxs11("div", { className: "space-y-1", children: [
2733
+ /* @__PURE__ */ jsxs11("p", { className: "text-xs font-medium text-green-600", children: [
2734
+ "Mapping Complete (",
2735
+ complete.length,
2736
+ ")"
2737
+ ] }),
2738
+ complete.map((item, i) => {
2739
+ const globalIdx = lovItems.indexOf(item);
2740
+ return /* @__PURE__ */ jsxs11(
2741
+ "button",
2742
+ {
2743
+ type: "button",
2744
+ onClick: () => setSelectedAttrIndex(globalIdx),
2745
+ className: cn(
2746
+ "flex w-full flex-col items-start rounded-md border px-2.5 py-2 text-left text-xs transition-colors",
2747
+ selectedAttrIndex === globalIdx ? "border-primary bg-primary/5" : "hover:bg-accent"
2748
+ ),
2749
+ children: [
2750
+ /* @__PURE__ */ jsxs11("span", { className: "flex items-center gap-1 font-medium", children: [
2751
+ item.feedCol,
2752
+ /* @__PURE__ */ jsx22(ChevronRight2, { className: "size-3 text-muted-foreground" }),
2753
+ item.attribute
2754
+ ] }),
2755
+ /* @__PURE__ */ jsxs11("span", { className: "text-green-600", children: [
2756
+ "All values mapped (",
2757
+ item.mappedCount,
2758
+ "/",
2759
+ item.totalCount,
2760
+ ")"
2761
+ ] })
2762
+ ]
2763
+ },
2764
+ `done-${i}`
2765
+ );
2766
+ })
2767
+ ] })
2768
+ ] }),
2769
+ /* @__PURE__ */ jsx22("div", { className: "flex-1 rounded-lg border", children: selected ? /* @__PURE__ */ jsxs11("div", { className: "space-y-2 p-3", children: [
2770
+ /* @__PURE__ */ jsxs11("div", { className: "flex items-center justify-between", children: [
2771
+ /* @__PURE__ */ jsxs11("p", { className: "text-sm font-medium", children: [
2772
+ selected.feedCol,
2773
+ " ",
2774
+ /* @__PURE__ */ jsx22(ChevronRight2, { className: "inline size-3 text-muted-foreground" }),
2775
+ " ",
2776
+ selected.attribute
2777
+ ] }),
2778
+ /* @__PURE__ */ jsxs11(Badge, { variant: "outline", className: "text-xs", children: [
2779
+ selected.mappedCount,
2780
+ "/",
2781
+ selected.totalCount
2782
+ ] })
2783
+ ] }),
2784
+ /* @__PURE__ */ jsx22(Separator2, {}),
2785
+ /* @__PURE__ */ jsxs11("div", { className: "grid grid-cols-[1fr_auto_1fr] items-center gap-x-2 gap-y-1.5 text-xs", children: [
2786
+ /* @__PURE__ */ jsx22("span", { className: "font-medium text-muted-foreground", children: "Source Value" }),
2787
+ /* @__PURE__ */ jsx22("span", {}),
2788
+ /* @__PURE__ */ jsx22("span", { className: "font-medium text-muted-foreground", children: "Target Value" }),
2789
+ selected.rawValues.map((raw) => {
2790
+ const mapped = selected.mappedValues[raw];
2791
+ return /* @__PURE__ */ jsxs11(React7.Fragment, { children: [
2792
+ /* @__PURE__ */ jsx22("span", { className: "truncate rounded bg-muted px-2 py-1", children: raw }),
2793
+ /* @__PURE__ */ jsx22(ArrowRight, { className: "size-3 text-muted-foreground" }),
2794
+ /* @__PURE__ */ jsxs11(
2795
+ Select,
2796
+ {
2797
+ value: mapped ?? "__unmapped__",
2798
+ onValueChange: (v) => {
2799
+ const val = v === "__skip__" ? null : v;
2800
+ onValueChange(
2801
+ selected.itemIndex,
2802
+ selected.attribute,
2803
+ raw,
2804
+ val
2805
+ );
2806
+ },
2807
+ children: [
2808
+ /* @__PURE__ */ jsx22(SelectTrigger, { className: "h-7 text-xs", children: /* @__PURE__ */ jsx22(SelectValue, { placeholder: "Select value..." }) }),
2809
+ /* @__PURE__ */ jsxs11(SelectContent, { children: [
2810
+ /* @__PURE__ */ jsx22(SelectItem, { value: "__unmapped__", children: /* @__PURE__ */ jsx22("span", { className: "text-muted-foreground", children: "Select value..." }) }),
2811
+ /* @__PURE__ */ jsx22(SelectItem, { value: "__skip__", children: /* @__PURE__ */ jsx22("span", { className: "italic text-muted-foreground", children: "Skip" }) }),
2812
+ selected.rawValues.map((v) => /* @__PURE__ */ jsx22(SelectItem, { value: v, children: v }, v))
2813
+ ] })
2814
+ ]
2815
+ }
2816
+ )
2817
+ ] }, raw);
2818
+ })
2819
+ ] })
2820
+ ] }) : /* @__PURE__ */ jsx22("div", { className: "flex h-full items-center justify-center p-6 text-sm text-muted-foreground", children: "Select an attribute to map its values" }) })
2821
+ ] });
2822
+ }
2823
+ function MapAttributesChat({
2824
+ mappingData: initialData,
2825
+ mpAttributes,
2826
+ valuesOntologyAttributes,
2827
+ columns,
2828
+ uniqueValues,
2829
+ submitted,
2830
+ submittedValues,
2831
+ onSubmit
2832
+ }) {
2833
+ const [data, setData] = useState7(
2834
+ () => initialData.map((item) => ({ ...item }))
2835
+ );
2836
+ const [step, setStep] = useState7("attributes");
2837
+ const allAttributes = useMemo5(
2838
+ () => getAllAttributes(mpAttributes),
2839
+ [mpAttributes]
2840
+ );
2841
+ const allMappedAttributes = useMemo5(() => {
2842
+ const set = /* @__PURE__ */ new Set();
2843
+ data.forEach((item) => {
2844
+ if (!item.isIgnored) {
2845
+ item.mappedCols.forEach((c) => set.add(c));
2846
+ item.customCols.forEach((c) => set.add(c));
2847
+ }
2848
+ });
2849
+ return set;
2850
+ }, [data]);
2851
+ const progress = useMemo5(() => {
2852
+ const total = data.length;
2853
+ const done = data.filter((i) => i.isConfirmed || i.isIgnored).length;
2854
+ return { total, done, percent: total > 0 ? done / total * 100 : 0 };
2855
+ }, [data]);
2856
+ const hasLovAttributes = useMemo5(
2857
+ () => data.some(
2858
+ (item) => item.isConfirmed && item.mappedCols.some((c) => valuesOntologyAttributes.includes(c))
2859
+ ),
2860
+ [data, valuesOntologyAttributes]
2861
+ );
2862
+ const handleMap = useCallback5((index, attribute) => {
2863
+ setData((prev) => {
2864
+ const next = [...prev];
2865
+ const item = { ...next[index] };
2866
+ item.mappedCols = [...item.mappedCols, attribute];
2867
+ next[index] = item;
2868
+ return next;
2869
+ });
2870
+ }, []);
2871
+ const handleUnmap = useCallback5((index, attrIndex) => {
2872
+ setData((prev) => {
2873
+ const next = [...prev];
2874
+ const item = { ...next[index] };
2875
+ item.mappedCols = item.mappedCols.filter((_, i) => i !== attrIndex);
2876
+ next[index] = item;
2877
+ return next;
2878
+ });
2879
+ }, []);
2880
+ const handleConfirm = useCallback5((index) => {
2881
+ setData((prev) => {
2882
+ const next = [...prev];
2883
+ next[index] = { ...next[index], isConfirmed: true, isIgnored: false };
2884
+ return next;
2885
+ });
2886
+ }, []);
2887
+ const handleIgnore = useCallback5((index) => {
2888
+ setData((prev) => {
2889
+ const next = [...prev];
2890
+ next[index] = { ...next[index], isIgnored: true, isConfirmed: false };
2891
+ return next;
2892
+ });
2893
+ }, []);
2894
+ const handleEdit = useCallback5((index) => {
2895
+ setData((prev) => {
2896
+ const next = [...prev];
2897
+ next[index] = { ...next[index], isConfirmed: false, isIgnored: false };
2898
+ return next;
2899
+ });
2900
+ }, []);
2901
+ const handleValueChange = useCallback5(
2902
+ (itemIndex, attribute, rawValue, mappedValue) => {
2903
+ setData((prev) => {
2904
+ const next = [...prev];
2905
+ const item = { ...next[itemIndex] };
2906
+ const attrValues = { ...item.mappedValues[attribute] || {} };
2907
+ attrValues[rawValue] = mappedValue;
2908
+ item.mappedValues = { ...item.mappedValues, [attribute]: attrValues };
2909
+ next[itemIndex] = item;
2910
+ return next;
2911
+ });
2912
+ },
2913
+ []
2914
+ );
2915
+ const handleSubmit = useCallback5(() => {
2916
+ onSubmit(data);
2917
+ }, [data, onSubmit]);
2918
+ if (submitted) {
2919
+ return /* @__PURE__ */ jsxs11("div", { className: "space-y-2 rounded-lg border bg-muted/30 p-4", children: [
2920
+ /* @__PURE__ */ jsxs11("div", { className: "flex items-center gap-2", children: [
2921
+ /* @__PURE__ */ jsx22(Check2, { className: "size-4 text-green-600" }),
2922
+ /* @__PURE__ */ jsx22("p", { className: "text-sm font-medium", children: "Attribute mapping confirmed" })
2923
+ ] }),
2924
+ /* @__PURE__ */ jsxs11("p", { className: "text-xs text-muted-foreground", children: [
2925
+ progress.done,
2926
+ "/",
2927
+ progress.total,
2928
+ " columns mapped"
2929
+ ] })
2930
+ ] });
2931
+ }
2932
+ return /* @__PURE__ */ jsxs11("div", { className: "flex flex-col gap-3 p-3", children: [
2933
+ /* @__PURE__ */ jsxs11("div", { className: "flex items-center justify-between", children: [
2934
+ /* @__PURE__ */ jsxs11("div", { className: "space-y-0.5", children: [
2935
+ /* @__PURE__ */ jsx22("h3", { className: "text-sm font-semibold", children: step === "attributes" ? "Map Attributes" : "Map Values" }),
2936
+ /* @__PURE__ */ jsx22("p", { className: "text-xs text-muted-foreground", children: step === "attributes" ? "Match each feed column to a marketplace attribute" : "Normalize values for controlled-vocabulary attributes" })
2937
+ ] }),
2938
+ step === "attributes" && /* @__PURE__ */ jsxs11(Badge, { variant: "outline", className: "tabular-nums", children: [
2939
+ progress.done,
2940
+ "/",
2941
+ progress.total
2942
+ ] })
2943
+ ] }),
2944
+ step === "attributes" && /* @__PURE__ */ jsx22("div", { className: "h-1.5 w-full overflow-hidden rounded-full bg-muted", children: /* @__PURE__ */ jsx22(
2945
+ "div",
2946
+ {
2947
+ className: "h-full rounded-full bg-primary transition-all",
2948
+ style: { width: `${progress.percent}%` }
2949
+ }
2950
+ ) }),
2951
+ /* @__PURE__ */ jsx22(Separator2, {}),
2952
+ /* @__PURE__ */ jsx22(ScrollArea, { className: "max-h-[420px]", children: step === "attributes" ? /* @__PURE__ */ jsx22("div", { className: "space-y-2 pr-3", children: data.map((item, idx) => /* @__PURE__ */ jsx22(
2953
+ SingleAttributeRow,
2954
+ {
2955
+ item,
2956
+ index: idx,
2957
+ allAttributes,
2958
+ allMappedAttributes,
2959
+ onMap: handleMap,
2960
+ onConfirm: handleConfirm,
2961
+ onIgnore: handleIgnore,
2962
+ onEdit: handleEdit,
2963
+ onUnmap: handleUnmap
2964
+ },
2965
+ idx
2966
+ )) }) : /* @__PURE__ */ jsx22(
2967
+ ValueMappingPanel,
2968
+ {
2969
+ data,
2970
+ valuesOntologyAttributes,
2971
+ uniqueValues,
2972
+ onValueChange: handleValueChange
2973
+ }
2974
+ ) }),
2975
+ /* @__PURE__ */ jsx22(Separator2, {}),
2976
+ /* @__PURE__ */ jsxs11("div", { className: "flex items-center justify-between", children: [
2977
+ step === "values" ? /* @__PURE__ */ jsxs11(
2978
+ Button,
2979
+ {
2980
+ variant: "outline",
2981
+ size: "sm",
2982
+ onClick: () => setStep("attributes"),
2983
+ children: [
2984
+ /* @__PURE__ */ jsx22(ArrowLeft2, { className: "mr-1.5 size-3.5" }),
2985
+ "Back"
2986
+ ]
2987
+ }
2988
+ ) : /* @__PURE__ */ jsx22("div", {}),
2989
+ /* @__PURE__ */ jsxs11("div", { className: "flex gap-2", children: [
2990
+ step === "attributes" && hasLovAttributes && /* @__PURE__ */ jsxs11(
2991
+ Button,
2992
+ {
2993
+ variant: "outline",
2994
+ size: "sm",
2995
+ onClick: () => setStep("values"),
2996
+ disabled: progress.done < progress.total,
2997
+ children: [
2998
+ "Map Values",
2999
+ /* @__PURE__ */ jsx22(ArrowRight, { className: "ml-1.5 size-3.5" })
3000
+ ]
3001
+ }
3002
+ ),
3003
+ /* @__PURE__ */ jsx22(
3004
+ Button,
3005
+ {
3006
+ size: "sm",
3007
+ onClick: handleSubmit,
3008
+ disabled: progress.done < progress.total,
3009
+ children: "Save Mapping"
3010
+ }
3011
+ )
3012
+ ] })
3013
+ ] })
3014
+ ] });
3015
+ }
3016
+
2437
3017
  // src/Automations/ProductAutomation.tsx
2438
- import { useState as useState8, useEffect as useEffect5, useCallback as useCallback6, useRef as useRef5 } from "react";
2439
- import { ArrowLeft as ArrowLeft2, Search as Search3, Loader2 as Loader26, ChevronDown as ChevronDown2, Play } from "lucide-react";
3018
+ import { useState as useState9, useEffect as useEffect5, useCallback as useCallback7, useRef as useRef5 } from "react";
3019
+ import { ArrowLeft as ArrowLeft3, Search as Search4, Loader2 as Loader26, ChevronDown as ChevronDown3, Play } from "lucide-react";
2440
3020
 
2441
3021
  // src/Automations/api.ts
2442
3022
  async function fetchAutomationList(storeId, tag, includeGroupings = false) {
@@ -2562,9 +3142,9 @@ function parseLovResponse(response, curl, configs) {
2562
3142
  }
2563
3143
 
2564
3144
  // src/Automations/SchemaFieldRenderer.tsx
2565
- import { useCallback as useCallback5, useState as useState7 } from "react";
2566
- import { Check as Check2, ChevronsUpDown as ChevronsUpDown2, Loader2 as Loader25, X } from "lucide-react";
2567
- import { jsx as jsx21, jsxs as jsxs10 } from "react/jsx-runtime";
3145
+ import { useCallback as useCallback6, useState as useState8 } from "react";
3146
+ import { Check as Check3, ChevronsUpDown as ChevronsUpDown2, Loader2 as Loader25, X as X2 } from "lucide-react";
3147
+ import { jsx as jsx23, jsxs as jsxs12 } from "react/jsx-runtime";
2568
3148
  function SchemaFieldRenderer({
2569
3149
  schema,
2570
3150
  configs,
@@ -2572,12 +3152,12 @@ function SchemaFieldRenderer({
2572
3152
  loadingOptions,
2573
3153
  onConfigChange
2574
3154
  }) {
2575
- return /* @__PURE__ */ jsx21("div", { className: "space-y-4", children: schema.map((item, idx) => {
3155
+ return /* @__PURE__ */ jsx23("div", { className: "space-y-4", children: schema.map((item, idx) => {
2576
3156
  if (!shouldRenderAttribute(item.render_if, configs)) return null;
2577
3157
  if (item.fieldtype === "object_array" && item.mapping_parameters) {
2578
- return /* @__PURE__ */ jsx21("div", { className: "space-y-3", children: item.mapping_parameters.map((sub, subIdx) => {
3158
+ return /* @__PURE__ */ jsx23("div", { className: "space-y-3", children: item.mapping_parameters.map((sub, subIdx) => {
2579
3159
  const value = configs[item.payload_key]?.[0] != null ? configs[item.payload_key][0]?.[sub.payload_key] : void 0;
2580
- return /* @__PURE__ */ jsx21(
3160
+ return /* @__PURE__ */ jsx23(
2581
3161
  FieldSwitch,
2582
3162
  {
2583
3163
  item: sub,
@@ -2591,7 +3171,7 @@ function SchemaFieldRenderer({
2591
3171
  );
2592
3172
  }) }, idx);
2593
3173
  }
2594
- return /* @__PURE__ */ jsx21(
3174
+ return /* @__PURE__ */ jsx23(
2595
3175
  FieldSwitch,
2596
3176
  {
2597
3177
  item,
@@ -2616,7 +3196,7 @@ function FieldSwitch({
2616
3196
  if (!shouldRenderAttribute(item.render_if, configs)) return null;
2617
3197
  switch (item.fieldtype) {
2618
3198
  case "freetext":
2619
- return /* @__PURE__ */ jsx21(
3199
+ return /* @__PURE__ */ jsx23(
2620
3200
  FreetextField,
2621
3201
  {
2622
3202
  item,
@@ -2625,7 +3205,7 @@ function FieldSwitch({
2625
3205
  }
2626
3206
  );
2627
3207
  case "freetext_list":
2628
- return /* @__PURE__ */ jsx21(
3208
+ return /* @__PURE__ */ jsx23(
2629
3209
  FreetextListField,
2630
3210
  {
2631
3211
  item,
@@ -2634,7 +3214,7 @@ function FieldSwitch({
2634
3214
  }
2635
3215
  );
2636
3216
  case "lov_singleselect":
2637
- return /* @__PURE__ */ jsx21(
3217
+ return /* @__PURE__ */ jsx23(
2638
3218
  SingleSelectField,
2639
3219
  {
2640
3220
  item,
@@ -2645,7 +3225,7 @@ function FieldSwitch({
2645
3225
  }
2646
3226
  );
2647
3227
  case "lov_multipleselect":
2648
- return /* @__PURE__ */ jsx21(
3228
+ return /* @__PURE__ */ jsx23(
2649
3229
  MultiSelectField,
2650
3230
  {
2651
3231
  item,
@@ -2656,7 +3236,7 @@ function FieldSwitch({
2656
3236
  }
2657
3237
  );
2658
3238
  case "image_singleselect":
2659
- return /* @__PURE__ */ jsx21(
3239
+ return /* @__PURE__ */ jsx23(
2660
3240
  ImageSelectField,
2661
3241
  {
2662
3242
  item,
@@ -2665,7 +3245,7 @@ function FieldSwitch({
2665
3245
  }
2666
3246
  );
2667
3247
  case "boolean":
2668
- return /* @__PURE__ */ jsx21(
3248
+ return /* @__PURE__ */ jsx23(
2669
3249
  BooleanField,
2670
3250
  {
2671
3251
  item,
@@ -2682,13 +3262,13 @@ function FreetextField({
2682
3262
  value,
2683
3263
  onChange
2684
3264
  }) {
2685
- return /* @__PURE__ */ jsxs10("div", { className: "space-y-1.5", children: [
2686
- /* @__PURE__ */ jsxs10(Label, { children: [
3265
+ return /* @__PURE__ */ jsxs12("div", { className: "space-y-1.5", children: [
3266
+ /* @__PURE__ */ jsxs12(Label, { children: [
2687
3267
  item.title,
2688
- item.required && /* @__PURE__ */ jsx21("span", { className: "text-destructive", children: " *" })
3268
+ item.required && /* @__PURE__ */ jsx23("span", { className: "text-destructive", children: " *" })
2689
3269
  ] }),
2690
- item.description && /* @__PURE__ */ jsx21("p", { className: "text-xs text-muted-foreground", children: item.description }),
2691
- /* @__PURE__ */ jsx21(
3270
+ item.description && /* @__PURE__ */ jsx23("p", { className: "text-xs text-muted-foreground", children: item.description }),
3271
+ /* @__PURE__ */ jsx23(
2692
3272
  Input,
2693
3273
  {
2694
3274
  value: value ?? "",
@@ -2704,7 +3284,7 @@ function FreetextListField({
2704
3284
  value,
2705
3285
  onChange
2706
3286
  }) {
2707
- const [draft, setDraft] = useState7("");
3287
+ const [draft, setDraft] = useState8("");
2708
3288
  const keywords = value ?? [];
2709
3289
  const addKeyword = () => {
2710
3290
  const trimmed = draft.trim();
@@ -2713,14 +3293,14 @@ function FreetextListField({
2713
3293
  setDraft("");
2714
3294
  }
2715
3295
  };
2716
- return /* @__PURE__ */ jsxs10("div", { className: "space-y-1.5", children: [
2717
- /* @__PURE__ */ jsxs10(Label, { children: [
3296
+ return /* @__PURE__ */ jsxs12("div", { className: "space-y-1.5", children: [
3297
+ /* @__PURE__ */ jsxs12(Label, { children: [
2718
3298
  item.title,
2719
- item.required && /* @__PURE__ */ jsx21("span", { className: "text-destructive", children: " *" })
3299
+ item.required && /* @__PURE__ */ jsx23("span", { className: "text-destructive", children: " *" })
2720
3300
  ] }),
2721
- item.description && /* @__PURE__ */ jsx21("p", { className: "text-xs text-muted-foreground", children: item.description }),
2722
- /* @__PURE__ */ jsxs10("div", { className: "flex gap-2", children: [
2723
- /* @__PURE__ */ jsx21(
3301
+ item.description && /* @__PURE__ */ jsx23("p", { className: "text-xs text-muted-foreground", children: item.description }),
3302
+ /* @__PURE__ */ jsxs12("div", { className: "flex gap-2", children: [
3303
+ /* @__PURE__ */ jsx23(
2724
3304
  Input,
2725
3305
  {
2726
3306
  value: draft,
@@ -2729,17 +3309,17 @@ function FreetextListField({
2729
3309
  placeholder: "Type and press Enter"
2730
3310
  }
2731
3311
  ),
2732
- /* @__PURE__ */ jsx21(Button, { variant: "outline", size: "sm", onClick: addKeyword, type: "button", children: "Add" })
3312
+ /* @__PURE__ */ jsx23(Button, { variant: "outline", size: "sm", onClick: addKeyword, type: "button", children: "Add" })
2733
3313
  ] }),
2734
- keywords.length > 0 && /* @__PURE__ */ jsx21("div", { className: "flex flex-wrap gap-1.5 pt-1", children: keywords.map((kw) => /* @__PURE__ */ jsxs10(Badge, { variant: "secondary", className: "gap-1 pr-1", children: [
3314
+ keywords.length > 0 && /* @__PURE__ */ jsx23("div", { className: "flex flex-wrap gap-1.5 pt-1", children: keywords.map((kw) => /* @__PURE__ */ jsxs12(Badge, { variant: "secondary", className: "gap-1 pr-1", children: [
2735
3315
  kw,
2736
- /* @__PURE__ */ jsx21(
3316
+ /* @__PURE__ */ jsx23(
2737
3317
  "button",
2738
3318
  {
2739
3319
  type: "button",
2740
3320
  onClick: () => onChange(keywords.filter((k) => k !== kw)),
2741
3321
  className: "ml-0.5 rounded-full hover:bg-muted",
2742
- children: /* @__PURE__ */ jsx21(X, { className: "size-3" })
3322
+ children: /* @__PURE__ */ jsx23(X2, { className: "size-3" })
2743
3323
  }
2744
3324
  )
2745
3325
  ] }, kw)) })
@@ -2754,23 +3334,23 @@ function SingleSelectField({
2754
3334
  }) {
2755
3335
  const strOptions = Array.isArray(lovOptions) ? lovOptions.map(String) : [];
2756
3336
  const strValue = value != null ? String(value) : "";
2757
- return /* @__PURE__ */ jsxs10("div", { className: "space-y-1.5", children: [
2758
- /* @__PURE__ */ jsxs10(Label, { children: [
3337
+ return /* @__PURE__ */ jsxs12("div", { className: "space-y-1.5", children: [
3338
+ /* @__PURE__ */ jsxs12(Label, { children: [
2759
3339
  item.title,
2760
- item.required && /* @__PURE__ */ jsx21("span", { className: "text-destructive", children: " *" })
3340
+ item.required && /* @__PURE__ */ jsx23("span", { className: "text-destructive", children: " *" })
2761
3341
  ] }),
2762
- item.description && /* @__PURE__ */ jsx21("p", { className: "text-xs text-muted-foreground", children: item.description }),
2763
- loading ? /* @__PURE__ */ jsxs10("div", { className: "flex items-center gap-2 text-sm text-muted-foreground", children: [
2764
- /* @__PURE__ */ jsx21(Loader25, { className: "size-4 animate-spin" }),
3342
+ item.description && /* @__PURE__ */ jsx23("p", { className: "text-xs text-muted-foreground", children: item.description }),
3343
+ loading ? /* @__PURE__ */ jsxs12("div", { className: "flex items-center gap-2 text-sm text-muted-foreground", children: [
3344
+ /* @__PURE__ */ jsx23(Loader25, { className: "size-4 animate-spin" }),
2765
3345
  "Loading options..."
2766
- ] }) : /* @__PURE__ */ jsxs10(
3346
+ ] }) : /* @__PURE__ */ jsxs12(
2767
3347
  Select,
2768
3348
  {
2769
3349
  value: strValue,
2770
3350
  onValueChange: (v) => onChange(item.valuetype === "integer" ? Number(v) : v),
2771
3351
  children: [
2772
- /* @__PURE__ */ jsx21(SelectTrigger, { children: /* @__PURE__ */ jsx21(SelectValue, { placeholder: "Select..." }) }),
2773
- /* @__PURE__ */ jsx21(SelectContent, { children: strOptions.map((opt) => /* @__PURE__ */ jsx21(SelectItem, { value: opt, children: opt }, opt)) })
3352
+ /* @__PURE__ */ jsx23(SelectTrigger, { children: /* @__PURE__ */ jsx23(SelectValue, { placeholder: "Select..." }) }),
3353
+ /* @__PURE__ */ jsx23(SelectContent, { children: strOptions.map((opt) => /* @__PURE__ */ jsx23(SelectItem, { value: opt, children: opt }, opt)) })
2774
3354
  ]
2775
3355
  }
2776
3356
  )
@@ -2783,10 +3363,10 @@ function MultiSelectField({
2783
3363
  loading,
2784
3364
  onChange
2785
3365
  }) {
2786
- const [open, setOpen] = useState7(false);
3366
+ const [open, setOpen] = useState8(false);
2787
3367
  const selected = value ?? [];
2788
3368
  const strOptions = Array.isArray(lovOptions) ? lovOptions.map(String) : [];
2789
- const toggle = useCallback5(
3369
+ const toggle = useCallback6(
2790
3370
  (opt) => {
2791
3371
  onChange(
2792
3372
  selected.includes(opt) ? selected.filter((s) => s !== opt) : [...selected, opt]
@@ -2794,41 +3374,41 @@ function MultiSelectField({
2794
3374
  },
2795
3375
  [selected, onChange]
2796
3376
  );
2797
- return /* @__PURE__ */ jsxs10("div", { className: "space-y-1.5", children: [
2798
- /* @__PURE__ */ jsxs10(Label, { children: [
3377
+ return /* @__PURE__ */ jsxs12("div", { className: "space-y-1.5", children: [
3378
+ /* @__PURE__ */ jsxs12(Label, { children: [
2799
3379
  item.title,
2800
- item.required && /* @__PURE__ */ jsx21("span", { className: "text-destructive", children: " *" })
3380
+ item.required && /* @__PURE__ */ jsx23("span", { className: "text-destructive", children: " *" })
2801
3381
  ] }),
2802
- item.description && /* @__PURE__ */ jsx21("p", { className: "text-xs text-muted-foreground", children: item.description }),
2803
- loading ? /* @__PURE__ */ jsxs10("div", { className: "flex items-center gap-2 text-sm text-muted-foreground", children: [
2804
- /* @__PURE__ */ jsx21(Loader25, { className: "size-4 animate-spin" }),
3382
+ item.description && /* @__PURE__ */ jsx23("p", { className: "text-xs text-muted-foreground", children: item.description }),
3383
+ loading ? /* @__PURE__ */ jsxs12("div", { className: "flex items-center gap-2 text-sm text-muted-foreground", children: [
3384
+ /* @__PURE__ */ jsx23(Loader25, { className: "size-4 animate-spin" }),
2805
3385
  "Loading options..."
2806
- ] }) : /* @__PURE__ */ jsxs10(Popover, { open, onOpenChange: setOpen, children: [
2807
- /* @__PURE__ */ jsx21(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs10(
3386
+ ] }) : /* @__PURE__ */ jsxs12(Popover, { open, onOpenChange: setOpen, children: [
3387
+ /* @__PURE__ */ jsx23(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs12(
2808
3388
  Button,
2809
3389
  {
2810
3390
  variant: "outline",
2811
3391
  className: "w-full justify-between font-normal",
2812
3392
  children: [
2813
- selected.length > 0 ? /* @__PURE__ */ jsx21("div", { className: "flex flex-wrap gap-1", children: selected.map((s) => /* @__PURE__ */ jsx21(Badge, { variant: "secondary", className: "text-xs", children: s }, s)) }) : /* @__PURE__ */ jsx21("span", { className: "text-muted-foreground", children: "Select..." }),
2814
- /* @__PURE__ */ jsx21(ChevronsUpDown2, { className: "ml-2 size-4 shrink-0 opacity-50" })
3393
+ selected.length > 0 ? /* @__PURE__ */ jsx23("div", { className: "flex flex-wrap gap-1", children: selected.map((s) => /* @__PURE__ */ jsx23(Badge, { variant: "secondary", className: "text-xs", children: s }, s)) }) : /* @__PURE__ */ jsx23("span", { className: "text-muted-foreground", children: "Select..." }),
3394
+ /* @__PURE__ */ jsx23(ChevronsUpDown2, { className: "ml-2 size-4 shrink-0 opacity-50" })
2815
3395
  ]
2816
3396
  }
2817
3397
  ) }),
2818
- /* @__PURE__ */ jsx21(PopoverContent, { className: "w-[260px] p-0", align: "start", children: /* @__PURE__ */ jsxs10(Command, { children: [
2819
- /* @__PURE__ */ jsx21(CommandInput, { placeholder: "Search..." }),
2820
- /* @__PURE__ */ jsxs10(CommandList, { children: [
2821
- /* @__PURE__ */ jsx21(CommandEmpty, { children: "No match." }),
2822
- /* @__PURE__ */ jsx21(CommandGroup, { children: strOptions.map((opt) => {
3398
+ /* @__PURE__ */ jsx23(PopoverContent, { className: "w-[260px] p-0", align: "start", children: /* @__PURE__ */ jsxs12(Command, { children: [
3399
+ /* @__PURE__ */ jsx23(CommandInput, { placeholder: "Search..." }),
3400
+ /* @__PURE__ */ jsxs12(CommandList, { children: [
3401
+ /* @__PURE__ */ jsx23(CommandEmpty, { children: "No match." }),
3402
+ /* @__PURE__ */ jsx23(CommandGroup, { children: strOptions.map((opt) => {
2823
3403
  const isSelected = selected.includes(opt);
2824
- return /* @__PURE__ */ jsxs10(
3404
+ return /* @__PURE__ */ jsxs12(
2825
3405
  CommandItem,
2826
3406
  {
2827
3407
  value: opt,
2828
3408
  onSelect: () => toggle(opt),
2829
3409
  children: [
2830
- /* @__PURE__ */ jsx21(
2831
- Check2,
3410
+ /* @__PURE__ */ jsx23(
3411
+ Check3,
2832
3412
  {
2833
3413
  className: cn(
2834
3414
  "mr-2 size-4",
@@ -2853,12 +3433,12 @@ function ImageSelectField({
2853
3433
  onChange
2854
3434
  }) {
2855
3435
  const images = item.lov ?? [];
2856
- return /* @__PURE__ */ jsxs10("div", { className: "space-y-1.5", children: [
2857
- /* @__PURE__ */ jsxs10(Label, { children: [
3436
+ return /* @__PURE__ */ jsxs12("div", { className: "space-y-1.5", children: [
3437
+ /* @__PURE__ */ jsxs12(Label, { children: [
2858
3438
  item.title,
2859
- item.required && /* @__PURE__ */ jsx21("span", { className: "text-destructive", children: " *" })
3439
+ item.required && /* @__PURE__ */ jsx23("span", { className: "text-destructive", children: " *" })
2860
3440
  ] }),
2861
- /* @__PURE__ */ jsx21("div", { className: "flex flex-wrap gap-3", children: images.map((url) => /* @__PURE__ */ jsxs10(
3441
+ /* @__PURE__ */ jsx23("div", { className: "flex flex-wrap gap-3", children: images.map((url) => /* @__PURE__ */ jsxs12(
2862
3442
  "button",
2863
3443
  {
2864
3444
  type: "button",
@@ -2868,8 +3448,8 @@ function ImageSelectField({
2868
3448
  value === url ? "border-primary ring-2 ring-primary/30" : "border-border hover:border-primary/50"
2869
3449
  ),
2870
3450
  children: [
2871
- /* @__PURE__ */ jsx21("img", { src: url, alt: "", className: "size-20 object-cover" }),
2872
- value === url && /* @__PURE__ */ jsx21("div", { className: "absolute right-1 top-1 rounded-full bg-primary p-0.5 text-primary-foreground", children: /* @__PURE__ */ jsx21(Check2, { className: "size-3" }) })
3451
+ /* @__PURE__ */ jsx23("img", { src: url, alt: "", className: "size-20 object-cover" }),
3452
+ value === url && /* @__PURE__ */ jsx23("div", { className: "absolute right-1 top-1 rounded-full bg-primary p-0.5 text-primary-foreground", children: /* @__PURE__ */ jsx23(Check3, { className: "size-3" }) })
2873
3453
  ]
2874
3454
  },
2875
3455
  url
@@ -2881,23 +3461,23 @@ function BooleanField({
2881
3461
  value,
2882
3462
  onChange
2883
3463
  }) {
2884
- return /* @__PURE__ */ jsxs10("div", { className: "flex items-center gap-2 py-1", children: [
2885
- /* @__PURE__ */ jsx21(
3464
+ return /* @__PURE__ */ jsxs12("div", { className: "flex items-center gap-2 py-1", children: [
3465
+ /* @__PURE__ */ jsx23(
2886
3466
  Checkbox,
2887
3467
  {
2888
3468
  checked: !!value,
2889
3469
  onCheckedChange: (checked) => onChange(!!checked)
2890
3470
  }
2891
3471
  ),
2892
- /* @__PURE__ */ jsxs10(Label, { className: "cursor-pointer", onClick: () => onChange(!value), children: [
3472
+ /* @__PURE__ */ jsxs12(Label, { className: "cursor-pointer", onClick: () => onChange(!value), children: [
2893
3473
  item.title,
2894
- item.required && /* @__PURE__ */ jsx21("span", { className: "text-destructive", children: " *" })
3474
+ item.required && /* @__PURE__ */ jsx23("span", { className: "text-destructive", children: " *" })
2895
3475
  ] })
2896
3476
  ] });
2897
3477
  }
2898
3478
 
2899
3479
  // src/Automations/ProductAutomation.tsx
2900
- import { Fragment as Fragment4, jsx as jsx22, jsxs as jsxs11 } from "react/jsx-runtime";
3480
+ import { Fragment as Fragment4, jsx as jsx24, jsxs as jsxs13 } from "react/jsx-runtime";
2901
3481
  function ProductAutomation({
2902
3482
  storeId,
2903
3483
  workspaceId,
@@ -2913,17 +3493,17 @@ function ProductAutomation({
2913
3493
  onSubmit,
2914
3494
  onAutomationApplied
2915
3495
  }) {
2916
- const [loading, setLoading] = useState8(true);
2917
- const [automationGroups, setAutomationGroups] = useState8({});
2918
- const [expandedGroups, setExpandedGroups] = useState8([]);
2919
- const [searchQuery, setSearchQuery] = useState8("");
2920
- const [selected, setSelected] = useState8(null);
2921
- const [schema, setSchema] = useState8([]);
2922
- const [configs, setConfigs] = useState8({});
2923
- const [options, setOptions] = useState8({});
2924
- const [loadingOptions, setLoadingOptions] = useState8({});
2925
- const [schemaLoading, setSchemaLoading] = useState8(false);
2926
- const [applying, setApplying] = useState8(false);
3496
+ const [loading, setLoading] = useState9(true);
3497
+ const [automationGroups, setAutomationGroups] = useState9({});
3498
+ const [expandedGroups, setExpandedGroups] = useState9([]);
3499
+ const [searchQuery, setSearchQuery] = useState9("");
3500
+ const [selected, setSelected] = useState9(null);
3501
+ const [schema, setSchema] = useState9([]);
3502
+ const [configs, setConfigs] = useState9({});
3503
+ const [options, setOptions] = useState9({});
3504
+ const [loadingOptions, setLoadingOptions] = useState9({});
3505
+ const [schemaLoading, setSchemaLoading] = useState9(false);
3506
+ const [applying, setApplying] = useState9(false);
2927
3507
  const configsRef = useRef5(configs);
2928
3508
  configsRef.current = configs;
2929
3509
  const optionsRef = useRef5(options);
@@ -2994,7 +3574,7 @@ function ProductAutomation({
2994
3574
  }
2995
3575
  }
2996
3576
  }, [schema, configs, channelsWithVersion]);
2997
- const handleConfigChange = useCallback6(
3577
+ const handleConfigChange = useCallback7(
2998
3578
  (key, value, item) => {
2999
3579
  setConfigs((prev) => {
3000
3580
  const parentItem = schema.find(
@@ -3020,7 +3600,7 @@ function ProductAutomation({
3020
3600
  },
3021
3601
  [schema]
3022
3602
  );
3023
- const isRunAllowed = useCallback6(() => {
3603
+ const isRunAllowed = useCallback7(() => {
3024
3604
  for (const item of schema) {
3025
3605
  if (!shouldRenderAttribute(item.render_if, configs)) continue;
3026
3606
  if (item.required) {
@@ -3070,18 +3650,18 @@ function ProductAutomation({
3070
3650
  const filtered = searchQuery ? unique.filter(
3071
3651
  (a) => a.display_name?.toLowerCase().includes(searchQuery.toLowerCase()) || a.automation.toLowerCase().includes(searchQuery.toLowerCase())
3072
3652
  ) : null;
3073
- return /* @__PURE__ */ jsxs11("div", { className: "flex h-full flex-col gap-3 p-3", children: [
3074
- /* @__PURE__ */ jsxs11("div", { className: "flex items-center gap-2", children: [
3075
- /* @__PURE__ */ jsx22(Button, { variant: "ghost", size: "icon", onClick: onClose, children: /* @__PURE__ */ jsx22(ArrowLeft2, { className: "size-4" }) }),
3076
- /* @__PURE__ */ jsx22("h3", { className: "text-base font-semibold", children: "Automations" }),
3077
- /* @__PURE__ */ jsxs11(Badge, { variant: "secondary", children: [
3653
+ return /* @__PURE__ */ jsxs13("div", { className: "flex h-full flex-col gap-3 p-3", children: [
3654
+ /* @__PURE__ */ jsxs13("div", { className: "flex items-center gap-2", children: [
3655
+ /* @__PURE__ */ jsx24(Button, { variant: "ghost", size: "icon", onClick: onClose, children: /* @__PURE__ */ jsx24(ArrowLeft3, { className: "size-4" }) }),
3656
+ /* @__PURE__ */ jsx24("h3", { className: "text-base font-semibold", children: "Automations" }),
3657
+ /* @__PURE__ */ jsxs13(Badge, { variant: "secondary", children: [
3078
3658
  productsCount,
3079
3659
  " products"
3080
3660
  ] })
3081
3661
  ] }),
3082
- /* @__PURE__ */ jsxs11("div", { className: "relative", children: [
3083
- /* @__PURE__ */ jsx22(Search3, { className: "absolute left-2.5 top-1/2 size-4 -translate-y-1/2 text-muted-foreground" }),
3084
- /* @__PURE__ */ jsx22(
3662
+ /* @__PURE__ */ jsxs13("div", { className: "relative", children: [
3663
+ /* @__PURE__ */ jsx24(Search4, { className: "absolute left-2.5 top-1/2 size-4 -translate-y-1/2 text-muted-foreground" }),
3664
+ /* @__PURE__ */ jsx24(
3085
3665
  Input,
3086
3666
  {
3087
3667
  placeholder: "Search automations...",
@@ -3091,12 +3671,12 @@ function ProductAutomation({
3091
3671
  }
3092
3672
  )
3093
3673
  ] }),
3094
- /* @__PURE__ */ jsxs11("div", { className: "flex items-center gap-4 border-b px-2 pb-2 text-xs font-medium text-muted-foreground", children: [
3095
- /* @__PURE__ */ jsx22("span", { className: "flex-[5]", children: "Automation" }),
3096
- /* @__PURE__ */ jsx22("span", { className: "flex-[1.5] text-center", children: "Est. Time" }),
3097
- /* @__PURE__ */ jsx22("span", { className: "flex-[1.5] text-center", children: "Credits" })
3674
+ /* @__PURE__ */ jsxs13("div", { className: "flex items-center gap-4 border-b px-2 pb-2 text-xs font-medium text-muted-foreground", children: [
3675
+ /* @__PURE__ */ jsx24("span", { className: "flex-[5]", children: "Automation" }),
3676
+ /* @__PURE__ */ jsx24("span", { className: "flex-[1.5] text-center", children: "Est. Time" }),
3677
+ /* @__PURE__ */ jsx24("span", { className: "flex-[1.5] text-center", children: "Credits" })
3098
3678
  ] }),
3099
- /* @__PURE__ */ jsx22("div", { className: "flex-1 overflow-y-auto", children: loading ? /* @__PURE__ */ jsx22("div", { className: "space-y-3 p-2", children: Array.from({ length: 6 }).map((_, i) => /* @__PURE__ */ jsx22(Skeleton, { className: "h-14 w-full rounded-md" }, i)) }) : filtered ? filtered.map((item) => /* @__PURE__ */ jsx22(
3679
+ /* @__PURE__ */ jsx24("div", { className: "flex-1 overflow-y-auto", children: loading ? /* @__PURE__ */ jsx24("div", { className: "space-y-3 p-2", children: Array.from({ length: 6 }).map((_, i) => /* @__PURE__ */ jsx24(Skeleton, { className: "h-14 w-full rounded-md" }, i)) }) : filtered ? filtered.map((item) => /* @__PURE__ */ jsx24(
3100
3680
  AutomationRow,
3101
3681
  {
3102
3682
  item,
@@ -3104,8 +3684,8 @@ function ProductAutomation({
3104
3684
  onClick: () => setSelected(item)
3105
3685
  },
3106
3686
  item.automation
3107
- )) : Object.keys(automationGroups).sort().map((group) => /* @__PURE__ */ jsxs11("div", { children: [
3108
- /* @__PURE__ */ jsxs11(
3687
+ )) : Object.keys(automationGroups).sort().map((group) => /* @__PURE__ */ jsxs13("div", { children: [
3688
+ /* @__PURE__ */ jsxs13(
3109
3689
  "button",
3110
3690
  {
3111
3691
  type: "button",
@@ -3115,8 +3695,8 @@ function ProductAutomation({
3115
3695
  className: "flex w-full items-center justify-between px-2 py-2 text-sm font-semibold text-muted-foreground hover:text-foreground",
3116
3696
  children: [
3117
3697
  group,
3118
- /* @__PURE__ */ jsx22(
3119
- ChevronDown2,
3698
+ /* @__PURE__ */ jsx24(
3699
+ ChevronDown3,
3120
3700
  {
3121
3701
  className: cn(
3122
3702
  "size-4 transition-transform",
@@ -3127,7 +3707,7 @@ function ProductAutomation({
3127
3707
  ]
3128
3708
  }
3129
3709
  ),
3130
- expandedGroups.includes(group) && automationGroups[group].map((item) => /* @__PURE__ */ jsx22(
3710
+ expandedGroups.includes(group) && automationGroups[group].map((item) => /* @__PURE__ */ jsx24(
3131
3711
  AutomationRow,
3132
3712
  {
3133
3713
  item,
@@ -3139,15 +3719,15 @@ function ProductAutomation({
3139
3719
  ] }, group)) })
3140
3720
  ] });
3141
3721
  }
3142
- return /* @__PURE__ */ jsxs11("div", { className: "flex h-full flex-col gap-3 p-3", children: [
3143
- /* @__PURE__ */ jsxs11("div", { className: "flex items-center gap-2", children: [
3144
- /* @__PURE__ */ jsx22(Button, { variant: "ghost", size: "icon", onClick: () => setSelected(null), children: /* @__PURE__ */ jsx22(ArrowLeft2, { className: "size-4" }) }),
3145
- /* @__PURE__ */ jsx22("h3", { className: "text-base font-semibold", children: selected.display_name })
3722
+ return /* @__PURE__ */ jsxs13("div", { className: "flex h-full flex-col gap-3 p-3", children: [
3723
+ /* @__PURE__ */ jsxs13("div", { className: "flex items-center gap-2", children: [
3724
+ /* @__PURE__ */ jsx24(Button, { variant: "ghost", size: "icon", onClick: () => setSelected(null), children: /* @__PURE__ */ jsx24(ArrowLeft3, { className: "size-4" }) }),
3725
+ /* @__PURE__ */ jsx24("h3", { className: "text-base font-semibold", children: selected.display_name })
3146
3726
  ] }),
3147
- selected.preview && /* @__PURE__ */ jsxs11("div", { className: "space-y-2 rounded-lg bg-muted/50 p-3 text-sm", children: [
3148
- selected.preview.info_text.map((text, i) => /* @__PURE__ */ jsx22("p", { className: "text-muted-foreground", children: text }, i)),
3149
- selected.preview.media.length > 0 && /* @__PURE__ */ jsx22("div", { className: "flex flex-wrap gap-2 pt-1", children: selected.preview.media.map(
3150
- (m, i) => m.type === "image" ? /* @__PURE__ */ jsx22(
3727
+ selected.preview && /* @__PURE__ */ jsxs13("div", { className: "space-y-2 rounded-lg bg-muted/50 p-3 text-sm", children: [
3728
+ selected.preview.info_text.map((text, i) => /* @__PURE__ */ jsx24("p", { className: "text-muted-foreground", children: text }, i)),
3729
+ selected.preview.media.length > 0 && /* @__PURE__ */ jsx24("div", { className: "flex flex-wrap gap-2 pt-1", children: selected.preview.media.map(
3730
+ (m, i) => m.type === "image" ? /* @__PURE__ */ jsx24(
3151
3731
  "img",
3152
3732
  {
3153
3733
  src: m.src,
@@ -3158,8 +3738,8 @@ function ProductAutomation({
3158
3738
  ) : null
3159
3739
  ) })
3160
3740
  ] }),
3161
- /* @__PURE__ */ jsx22(Separator2, {}),
3162
- /* @__PURE__ */ jsx22("div", { className: "flex-1 overflow-y-auto", children: schemaLoading ? /* @__PURE__ */ jsx22("div", { className: "space-y-3 p-2", children: Array.from({ length: 4 }).map((_, i) => /* @__PURE__ */ jsx22(Skeleton, { className: "h-12 w-full rounded-md" }, i)) }) : /* @__PURE__ */ jsx22(
3741
+ /* @__PURE__ */ jsx24(Separator2, {}),
3742
+ /* @__PURE__ */ jsx24("div", { className: "flex-1 overflow-y-auto", children: schemaLoading ? /* @__PURE__ */ jsx24("div", { className: "space-y-3 p-2", children: Array.from({ length: 4 }).map((_, i) => /* @__PURE__ */ jsx24(Skeleton, { className: "h-12 w-full rounded-md" }, i)) }) : /* @__PURE__ */ jsx24(
3163
3743
  SchemaFieldRenderer,
3164
3744
  {
3165
3745
  schema,
@@ -3169,26 +3749,26 @@ function ProductAutomation({
3169
3749
  onConfigChange: handleConfigChange
3170
3750
  }
3171
3751
  ) }),
3172
- /* @__PURE__ */ jsx22(Separator2, {}),
3173
- /* @__PURE__ */ jsxs11("div", { className: "flex items-center gap-2", children: [
3174
- /* @__PURE__ */ jsx22(
3752
+ /* @__PURE__ */ jsx24(Separator2, {}),
3753
+ /* @__PURE__ */ jsxs13("div", { className: "flex items-center gap-2", children: [
3754
+ /* @__PURE__ */ jsx24(
3175
3755
  Button,
3176
3756
  {
3177
3757
  onClick: handleRun,
3178
3758
  disabled: !isRunAllowed() || applying,
3179
3759
  className: "flex-1",
3180
- children: applying ? /* @__PURE__ */ jsxs11(Fragment4, { children: [
3181
- /* @__PURE__ */ jsx22(Loader26, { className: "size-4 animate-spin" }),
3760
+ children: applying ? /* @__PURE__ */ jsxs13(Fragment4, { children: [
3761
+ /* @__PURE__ */ jsx24(Loader26, { className: "size-4 animate-spin" }),
3182
3762
  "Applying..."
3183
- ] }) : /* @__PURE__ */ jsxs11(Fragment4, { children: [
3184
- /* @__PURE__ */ jsx22(Play, { className: "size-4" }),
3763
+ ] }) : /* @__PURE__ */ jsxs13(Fragment4, { children: [
3764
+ /* @__PURE__ */ jsx24(Play, { className: "size-4" }),
3185
3765
  "Run Automation"
3186
3766
  ] })
3187
3767
  }
3188
3768
  ),
3189
- /* @__PURE__ */ jsx22(Button, { variant: "outline", onClick: () => setSelected(null), children: "Cancel" })
3769
+ /* @__PURE__ */ jsx24(Button, { variant: "outline", onClick: () => setSelected(null), children: "Cancel" })
3190
3770
  ] }),
3191
- /* @__PURE__ */ jsx22("p", { className: "text-center text-xs text-muted-foreground", children: "By applying, you will override existing automations for the selected products with this new run." })
3771
+ /* @__PURE__ */ jsx24("p", { className: "text-center text-xs text-muted-foreground", children: "By applying, you will override existing automations for the selected products with this new run." })
3192
3772
  ] });
3193
3773
  }
3194
3774
  function AutomationRow({
@@ -3198,19 +3778,19 @@ function AutomationRow({
3198
3778
  }) {
3199
3779
  const estTime = item.estimate_time_saved ? formatTimeSaved(item.estimate_time_saved * productsCount) : "\u2014";
3200
3780
  const credits = item.credits ? Math.ceil(item.credits * productsCount) : 0;
3201
- return /* @__PURE__ */ jsxs11(
3781
+ return /* @__PURE__ */ jsxs13(
3202
3782
  "button",
3203
3783
  {
3204
3784
  type: "button",
3205
3785
  onClick,
3206
3786
  className: "flex w-full items-center gap-4 rounded-md px-2 py-2.5 text-left hover:bg-accent",
3207
3787
  children: [
3208
- /* @__PURE__ */ jsxs11("div", { className: "flex-[5] min-w-0", children: [
3209
- /* @__PURE__ */ jsx22("div", { className: "text-sm font-medium", children: item.display_name }),
3210
- item.description && /* @__PURE__ */ jsx22("div", { className: "truncate text-xs text-muted-foreground", children: item.description })
3788
+ /* @__PURE__ */ jsxs13("div", { className: "flex-[5] min-w-0", children: [
3789
+ /* @__PURE__ */ jsx24("div", { className: "text-sm font-medium", children: item.display_name }),
3790
+ item.description && /* @__PURE__ */ jsx24("div", { className: "truncate text-xs text-muted-foreground", children: item.description })
3211
3791
  ] }),
3212
- /* @__PURE__ */ jsx22("div", { className: "flex-[1.5] text-center text-xs text-muted-foreground", children: estTime }),
3213
- /* @__PURE__ */ jsx22("div", { className: "flex-[1.5] text-center text-xs text-muted-foreground", children: credits })
3792
+ /* @__PURE__ */ jsx24("div", { className: "flex-[1.5] text-center text-xs text-muted-foreground", children: estTime }),
3793
+ /* @__PURE__ */ jsx24("div", { className: "flex-[1.5] text-center text-xs text-muted-foreground", children: credits })
3214
3794
  ]
3215
3795
  }
3216
3796
  );
@@ -3222,9 +3802,9 @@ function formatTimeSaved(totalSeconds) {
3222
3802
  }
3223
3803
 
3224
3804
  // src/Automations/StoreAutomation.tsx
3225
- import { useState as useState9, useEffect as useEffect6, useCallback as useCallback7, useRef as useRef6 } from "react";
3226
- import { ArrowLeft as ArrowLeft3, Settings } from "lucide-react";
3227
- import { Fragment as Fragment5, jsx as jsx23, jsxs as jsxs12 } from "react/jsx-runtime";
3805
+ import { useState as useState10, useEffect as useEffect6, useCallback as useCallback8, useRef as useRef6 } from "react";
3806
+ import { ArrowLeft as ArrowLeft4, Settings } from "lucide-react";
3807
+ import { Fragment as Fragment5, jsx as jsx25, jsxs as jsxs14 } from "react/jsx-runtime";
3228
3808
  function StoreAutomation({
3229
3809
  storeId,
3230
3810
  channelsWithVersion,
@@ -3232,10 +3812,10 @@ function StoreAutomation({
3232
3812
  onSubmit,
3233
3813
  onClose
3234
3814
  }) {
3235
- const [loading, setLoading] = useState9(true);
3236
- const [automations, setAutomations] = useState9([]);
3237
- const [selectedConfigs, setSelectedConfigs] = useState9({ ...enabledAutomations });
3238
- const [selectedAutomation, setSelectedAutomation] = useState9(null);
3815
+ const [loading, setLoading] = useState10(true);
3816
+ const [automations, setAutomations] = useState10([]);
3817
+ const [selectedConfigs, setSelectedConfigs] = useState10({ ...enabledAutomations });
3818
+ const [selectedAutomation, setSelectedAutomation] = useState10(null);
3239
3819
  useEffect6(() => {
3240
3820
  setLoading(true);
3241
3821
  fetchAutomationList(storeId, "default").then((data) => {
@@ -3248,7 +3828,7 @@ function StoreAutomation({
3248
3828
  );
3249
3829
  }).catch(console.error).finally(() => setLoading(false));
3250
3830
  }, [storeId, enabledAutomations]);
3251
- const toggleAutomation = useCallback7((automationName) => {
3831
+ const toggleAutomation = useCallback8((automationName) => {
3252
3832
  setAutomations(
3253
3833
  (prev) => prev.map(
3254
3834
  (a) => a.automation === automationName ? { ...a, isEnabled: !a.isEnabled } : a
@@ -3281,7 +3861,7 @@ function StoreAutomation({
3281
3861
  setSelectedAutomation(null);
3282
3862
  };
3283
3863
  if (selectedAutomation) {
3284
- return /* @__PURE__ */ jsx23(
3864
+ return /* @__PURE__ */ jsx25(
3285
3865
  AutomationConfigEditor,
3286
3866
  {
3287
3867
  storeId,
@@ -3293,46 +3873,46 @@ function StoreAutomation({
3293
3873
  }
3294
3874
  );
3295
3875
  }
3296
- return /* @__PURE__ */ jsxs12("div", { className: "flex h-full flex-col gap-3 p-3", children: [
3297
- /* @__PURE__ */ jsxs12("div", { className: "flex items-center gap-2", children: [
3298
- onClose && /* @__PURE__ */ jsx23(Button, { variant: "ghost", size: "icon", onClick: onClose, children: /* @__PURE__ */ jsx23(ArrowLeft3, { className: "size-4" }) }),
3299
- /* @__PURE__ */ jsx23("h3", { className: "text-base font-semibold", children: "Default Store Automations" })
3876
+ return /* @__PURE__ */ jsxs14("div", { className: "flex h-full flex-col gap-3 p-3", children: [
3877
+ /* @__PURE__ */ jsxs14("div", { className: "flex items-center gap-2", children: [
3878
+ onClose && /* @__PURE__ */ jsx25(Button, { variant: "ghost", size: "icon", onClick: onClose, children: /* @__PURE__ */ jsx25(ArrowLeft4, { className: "size-4" }) }),
3879
+ /* @__PURE__ */ jsx25("h3", { className: "text-base font-semibold", children: "Default Store Automations" })
3300
3880
  ] }),
3301
- /* @__PURE__ */ jsx23(Separator2, {}),
3302
- loading ? /* @__PURE__ */ jsx23("div", { className: "space-y-3 p-2", children: Array.from({ length: 5 }).map((_, i) => /* @__PURE__ */ jsx23(Skeleton, { className: "h-14 w-full rounded-md" }, i)) }) : /* @__PURE__ */ jsx23("div", { className: "flex-1 overflow-y-auto", children: /* @__PURE__ */ jsxs12(Table, { children: [
3303
- /* @__PURE__ */ jsx23(TableHeader, { children: /* @__PURE__ */ jsxs12(TableRow, { children: [
3304
- /* @__PURE__ */ jsx23(TableHead, { children: "Automation" }),
3305
- /* @__PURE__ */ jsx23(TableHead, { className: "w-24 text-center", children: "Avg. Time" }),
3306
- /* @__PURE__ */ jsx23(TableHead, { className: "w-28 text-center", children: "Credits/Prd" }),
3307
- /* @__PURE__ */ jsx23(TableHead, { className: "w-28 text-center", children: "Status" }),
3308
- /* @__PURE__ */ jsx23(TableHead, { className: "w-12" })
3881
+ /* @__PURE__ */ jsx25(Separator2, {}),
3882
+ loading ? /* @__PURE__ */ jsx25("div", { className: "space-y-3 p-2", children: Array.from({ length: 5 }).map((_, i) => /* @__PURE__ */ jsx25(Skeleton, { className: "h-14 w-full rounded-md" }, i)) }) : /* @__PURE__ */ jsx25("div", { className: "flex-1 overflow-y-auto", children: /* @__PURE__ */ jsxs14(Table, { children: [
3883
+ /* @__PURE__ */ jsx25(TableHeader, { children: /* @__PURE__ */ jsxs14(TableRow, { children: [
3884
+ /* @__PURE__ */ jsx25(TableHead, { children: "Automation" }),
3885
+ /* @__PURE__ */ jsx25(TableHead, { className: "w-24 text-center", children: "Avg. Time" }),
3886
+ /* @__PURE__ */ jsx25(TableHead, { className: "w-28 text-center", children: "Credits/Prd" }),
3887
+ /* @__PURE__ */ jsx25(TableHead, { className: "w-28 text-center", children: "Status" }),
3888
+ /* @__PURE__ */ jsx25(TableHead, { className: "w-12" })
3309
3889
  ] }) }),
3310
- /* @__PURE__ */ jsx23(TableBody, { children: automations.map((a) => /* @__PURE__ */ jsxs12(
3890
+ /* @__PURE__ */ jsx25(TableBody, { children: automations.map((a) => /* @__PURE__ */ jsxs14(
3311
3891
  TableRow,
3312
3892
  {
3313
3893
  className: "cursor-pointer",
3314
3894
  onClick: () => setSelectedAutomation(a),
3315
3895
  children: [
3316
- /* @__PURE__ */ jsxs12(TableCell, { children: [
3317
- /* @__PURE__ */ jsx23("div", { className: "text-sm font-medium", children: a.display_name }),
3318
- a.description && /* @__PURE__ */ jsx23("div", { className: "text-xs text-muted-foreground", children: a.description })
3896
+ /* @__PURE__ */ jsxs14(TableCell, { children: [
3897
+ /* @__PURE__ */ jsx25("div", { className: "text-sm font-medium", children: a.display_name }),
3898
+ a.description && /* @__PURE__ */ jsx25("div", { className: "text-xs text-muted-foreground", children: a.description })
3319
3899
  ] }),
3320
- /* @__PURE__ */ jsx23(TableCell, { className: "text-center text-xs", children: a.estimate_run_time ?? "\u2014" }),
3321
- /* @__PURE__ */ jsx23(TableCell, { className: "text-center text-xs", children: a.credits ?? "\u2014" }),
3322
- /* @__PURE__ */ jsx23(TableCell, { className: "text-center", children: /* @__PURE__ */ jsxs12(
3900
+ /* @__PURE__ */ jsx25(TableCell, { className: "text-center text-xs", children: a.estimate_run_time ?? "\u2014" }),
3901
+ /* @__PURE__ */ jsx25(TableCell, { className: "text-center text-xs", children: a.credits ?? "\u2014" }),
3902
+ /* @__PURE__ */ jsx25(TableCell, { className: "text-center", children: /* @__PURE__ */ jsxs14(
3323
3903
  "div",
3324
3904
  {
3325
3905
  className: "flex items-center justify-center gap-2",
3326
3906
  onClick: (e) => e.stopPropagation(),
3327
3907
  children: [
3328
- /* @__PURE__ */ jsx23(
3908
+ /* @__PURE__ */ jsx25(
3329
3909
  Switch,
3330
3910
  {
3331
3911
  checked: a.isEnabled,
3332
3912
  onCheckedChange: () => toggleAutomation(a.automation)
3333
3913
  }
3334
3914
  ),
3335
- /* @__PURE__ */ jsx23(
3915
+ /* @__PURE__ */ jsx25(
3336
3916
  Badge,
3337
3917
  {
3338
3918
  variant: a.isEnabled ? "default" : "secondary",
@@ -3343,16 +3923,16 @@ function StoreAutomation({
3343
3923
  ]
3344
3924
  }
3345
3925
  ) }),
3346
- /* @__PURE__ */ jsx23(TableCell, { children: /* @__PURE__ */ jsx23(Settings, { className: "size-4 text-muted-foreground" }) })
3926
+ /* @__PURE__ */ jsx25(TableCell, { children: /* @__PURE__ */ jsx25(Settings, { className: "size-4 text-muted-foreground" }) })
3347
3927
  ]
3348
3928
  },
3349
3929
  a.automation
3350
3930
  )) })
3351
3931
  ] }) }),
3352
- /* @__PURE__ */ jsx23(Separator2, {}),
3353
- /* @__PURE__ */ jsxs12("div", { className: "flex justify-end gap-2", children: [
3354
- onClose && /* @__PURE__ */ jsx23(Button, { variant: "outline", onClick: onClose, children: "Cancel" }),
3355
- /* @__PURE__ */ jsx23(Button, { onClick: handleSave, children: "Save Changes" })
3932
+ /* @__PURE__ */ jsx25(Separator2, {}),
3933
+ /* @__PURE__ */ jsxs14("div", { className: "flex justify-end gap-2", children: [
3934
+ onClose && /* @__PURE__ */ jsx25(Button, { variant: "outline", onClick: onClose, children: "Cancel" }),
3935
+ /* @__PURE__ */ jsx25(Button, { onClick: handleSave, children: "Save Changes" })
3356
3936
  ] })
3357
3937
  ] });
3358
3938
  }
@@ -3364,13 +3944,13 @@ function AutomationConfigEditor({
3364
3944
  onClose,
3365
3945
  onToggle
3366
3946
  }) {
3367
- const [schemaLoading, setSchemaLoading] = useState9(false);
3368
- const [schema, setSchema] = useState9([]);
3369
- const [configs, setConfigs] = useState9(
3947
+ const [schemaLoading, setSchemaLoading] = useState10(false);
3948
+ const [schema, setSchema] = useState10([]);
3949
+ const [configs, setConfigs] = useState10(
3370
3950
  initialConfigs ?? {}
3371
3951
  );
3372
- const [options, setOptions] = useState9({});
3373
- const [loadingOptions, setLoadingOptions] = useState9({});
3952
+ const [options, setOptions] = useState10({});
3953
+ const [loadingOptions, setLoadingOptions] = useState10({});
3374
3954
  const configsRef = useRef6(configs);
3375
3955
  configsRef.current = configs;
3376
3956
  const optionsRef = useRef6(options);
@@ -3417,7 +3997,7 @@ function AutomationConfigEditor({
3417
3997
  }
3418
3998
  }
3419
3999
  }, [schema, configs, channelsWithVersion]);
3420
- const handleConfigChange = useCallback7(
4000
+ const handleConfigChange = useCallback8(
3421
4001
  (key, value, item) => {
3422
4002
  setConfigs((prev) => ({ ...prev, [key]: value }));
3423
4003
  if (item.linked?.length) {
@@ -3433,36 +4013,36 @@ function AutomationConfigEditor({
3433
4013
  },
3434
4014
  []
3435
4015
  );
3436
- return /* @__PURE__ */ jsxs12("div", { className: "flex h-full flex-col gap-3 p-3", children: [
3437
- /* @__PURE__ */ jsxs12("div", { className: "flex items-center gap-2", children: [
3438
- /* @__PURE__ */ jsx23(
4016
+ return /* @__PURE__ */ jsxs14("div", { className: "flex h-full flex-col gap-3 p-3", children: [
4017
+ /* @__PURE__ */ jsxs14("div", { className: "flex items-center gap-2", children: [
4018
+ /* @__PURE__ */ jsx25(
3439
4019
  Button,
3440
4020
  {
3441
4021
  variant: "ghost",
3442
4022
  size: "icon",
3443
4023
  onClick: () => onClose(automation, configs),
3444
- children: /* @__PURE__ */ jsx23(ArrowLeft3, { className: "size-4" })
4024
+ children: /* @__PURE__ */ jsx25(ArrowLeft4, { className: "size-4" })
3445
4025
  }
3446
4026
  ),
3447
- /* @__PURE__ */ jsx23("h3", { className: "text-base font-semibold", children: automation.display_name })
4027
+ /* @__PURE__ */ jsx25("h3", { className: "text-base font-semibold", children: automation.display_name })
3448
4028
  ] }),
3449
- /* @__PURE__ */ jsxs12("div", { className: "flex gap-4 text-sm", children: [
3450
- /* @__PURE__ */ jsxs12("div", { className: "text-muted-foreground", children: [
4029
+ /* @__PURE__ */ jsxs14("div", { className: "flex gap-4 text-sm", children: [
4030
+ /* @__PURE__ */ jsxs14("div", { className: "text-muted-foreground", children: [
3451
4031
  "Est. time: ",
3452
- /* @__PURE__ */ jsx23("span", { className: "text-foreground", children: automation.estimate_run_time ?? "\u2014" })
4032
+ /* @__PURE__ */ jsx25("span", { className: "text-foreground", children: automation.estimate_run_time ?? "\u2014" })
3453
4033
  ] }),
3454
- /* @__PURE__ */ jsxs12("div", { className: "text-muted-foreground", children: [
4034
+ /* @__PURE__ */ jsxs14("div", { className: "text-muted-foreground", children: [
3455
4035
  "Credits/prd: ",
3456
- /* @__PURE__ */ jsx23("span", { className: "text-foreground", children: automation.credits ?? "\u2014" })
4036
+ /* @__PURE__ */ jsx25("span", { className: "text-foreground", children: automation.credits ?? "\u2014" })
3457
4037
  ] })
3458
4038
  ] }),
3459
- /* @__PURE__ */ jsx23(Separator2, {}),
3460
- /* @__PURE__ */ jsxs12("div", { className: "flex items-center gap-2", children: [
3461
- /* @__PURE__ */ jsx23("span", { className: "text-sm font-medium", children: automation.isEnabled ? "Enabled" : "Disabled" }),
3462
- /* @__PURE__ */ jsx23(Switch, { checked: automation.isEnabled, onCheckedChange: onToggle })
4039
+ /* @__PURE__ */ jsx25(Separator2, {}),
4040
+ /* @__PURE__ */ jsxs14("div", { className: "flex items-center gap-2", children: [
4041
+ /* @__PURE__ */ jsx25("span", { className: "text-sm font-medium", children: automation.isEnabled ? "Enabled" : "Disabled" }),
4042
+ /* @__PURE__ */ jsx25(Switch, { checked: automation.isEnabled, onCheckedChange: onToggle })
3463
4043
  ] }),
3464
- /* @__PURE__ */ jsx23(Separator2, {}),
3465
- /* @__PURE__ */ jsx23("div", { className: "flex-1 overflow-y-auto", children: automation.isEnabled ? schemaLoading ? /* @__PURE__ */ jsx23("div", { className: "space-y-3 p-2", children: Array.from({ length: 4 }).map((_, i) => /* @__PURE__ */ jsx23(Skeleton, { className: "h-12 w-full rounded-md" }, i)) }) : /* @__PURE__ */ jsx23(
4044
+ /* @__PURE__ */ jsx25(Separator2, {}),
4045
+ /* @__PURE__ */ jsx25("div", { className: "flex-1 overflow-y-auto", children: automation.isEnabled ? schemaLoading ? /* @__PURE__ */ jsx25("div", { className: "space-y-3 p-2", children: Array.from({ length: 4 }).map((_, i) => /* @__PURE__ */ jsx25(Skeleton, { className: "h-12 w-full rounded-md" }, i)) }) : /* @__PURE__ */ jsx25(
3466
4046
  SchemaFieldRenderer,
3467
4047
  {
3468
4048
  schema,
@@ -3471,13 +4051,13 @@ function AutomationConfigEditor({
3471
4051
  loadingOptions,
3472
4052
  onConfigChange: handleConfigChange
3473
4053
  }
3474
- ) : /* @__PURE__ */ jsx23("p", { className: "py-4 text-center text-sm text-muted-foreground", children: "Enable this automation to configure it." }) }),
3475
- automation.preview && /* @__PURE__ */ jsxs12(Fragment5, { children: [
3476
- /* @__PURE__ */ jsx23(Separator2, {}),
3477
- /* @__PURE__ */ jsxs12("div", { className: "space-y-2 rounded-lg bg-muted/50 p-3 text-sm", children: [
3478
- automation.preview.info_text.map((text, i) => /* @__PURE__ */ jsx23("p", { className: "text-muted-foreground", children: text }, i)),
3479
- automation.preview.media.length > 0 && /* @__PURE__ */ jsx23("div", { className: "flex flex-wrap gap-2 pt-1", children: automation.preview.media.map(
3480
- (m, i) => m.type === "image" ? /* @__PURE__ */ jsx23(
4054
+ ) : /* @__PURE__ */ jsx25("p", { className: "py-4 text-center text-sm text-muted-foreground", children: "Enable this automation to configure it." }) }),
4055
+ automation.preview && /* @__PURE__ */ jsxs14(Fragment5, { children: [
4056
+ /* @__PURE__ */ jsx25(Separator2, {}),
4057
+ /* @__PURE__ */ jsxs14("div", { className: "space-y-2 rounded-lg bg-muted/50 p-3 text-sm", children: [
4058
+ automation.preview.info_text.map((text, i) => /* @__PURE__ */ jsx25("p", { className: "text-muted-foreground", children: text }, i)),
4059
+ automation.preview.media.length > 0 && /* @__PURE__ */ jsx25("div", { className: "flex flex-wrap gap-2 pt-1", children: automation.preview.media.map(
4060
+ (m, i) => m.type === "image" ? /* @__PURE__ */ jsx25(
3481
4061
  "img",
3482
4062
  {
3483
4063
  src: m.src,
@@ -3493,14 +4073,16 @@ function AutomationConfigEditor({
3493
4073
  }
3494
4074
 
3495
4075
  // src/CatalogixChat.tsx
3496
- import { jsx as jsx24, jsxs as jsxs13 } from "react/jsx-runtime";
4076
+ import { jsx as jsx26, jsxs as jsxs15 } from "react/jsx-runtime";
3497
4077
  var SECTION_MAP = {
3498
4078
  "catalogix:create-store": "create_store",
3499
4079
  create_or_select_store: "create_store",
3500
4080
  "catalogix:select-products": "select_products",
3501
4081
  select_products: "select_products",
3502
4082
  "catalogix:automations": "automations",
3503
- trigger_automation: "trigger_automation"
4083
+ trigger_automation: "trigger_automation",
4084
+ "catalogix:map-attributes": "map_attributes",
4085
+ map_attributes: "map_attributes"
3504
4086
  };
3505
4087
  function CatalogixChat(props) {
3506
4088
  const { uiProps, meta, onSubmit, workspaceId, userId } = props;
@@ -3521,7 +4103,7 @@ function CatalogixChat(props) {
3521
4103
  configureApi({ catalogixBaseUrl });
3522
4104
  }, [catalogixBaseUrl]);
3523
4105
  if (section === "select_products") {
3524
- return /* @__PURE__ */ jsx24(
4106
+ return /* @__PURE__ */ jsx26(
3525
4107
  SelectProducts,
3526
4108
  {
3527
4109
  workspaceId,
@@ -3537,7 +4119,7 @@ function CatalogixChat(props) {
3537
4119
  );
3538
4120
  }
3539
4121
  if (section === "create_store") {
3540
- return /* @__PURE__ */ jsx24(
4122
+ return /* @__PURE__ */ jsx26(
3541
4123
  CreateStore,
3542
4124
  {
3543
4125
  workspaceId,
@@ -3550,8 +4132,24 @@ function CatalogixChat(props) {
3550
4132
  }
3551
4133
  );
3552
4134
  }
4135
+ if (section === "map_attributes") {
4136
+ return /* @__PURE__ */ jsx26(
4137
+ MapAttributesChat,
4138
+ {
4139
+ mappingData: uiProps.mappingData ?? [],
4140
+ mpAttributes: uiProps.mpAttributes ?? {},
4141
+ valuesOntologyAttributes: uiProps.valuesOntologyAttributes ?? [],
4142
+ columns: uiProps.columns ?? [],
4143
+ uniqueValues: uiProps.uniqueValues ?? {},
4144
+ storeId,
4145
+ submitted: props.submitted,
4146
+ submittedValues: props.submittedValues,
4147
+ onSubmit: (mapping) => onSubmit(mapping, "Attribute mapping confirmed.")
4148
+ }
4149
+ );
4150
+ }
3553
4151
  if (section === "trigger_automation") {
3554
- return /* @__PURE__ */ jsx24(
4152
+ return /* @__PURE__ */ jsx26(
3555
4153
  ProductAutomation,
3556
4154
  {
3557
4155
  storeId,
@@ -3571,7 +4169,7 @@ function CatalogixChat(props) {
3571
4169
  );
3572
4170
  }
3573
4171
  if (section === "automations") {
3574
- return /* @__PURE__ */ jsx24(
4172
+ return /* @__PURE__ */ jsx26(
3575
4173
  StoreAutomation,
3576
4174
  {
3577
4175
  storeId,
@@ -3582,11 +4180,11 @@ function CatalogixChat(props) {
3582
4180
  }
3583
4181
  );
3584
4182
  }
3585
- return /* @__PURE__ */ jsx24("div", { className: "p-4 text-sm text-muted-foreground", children: /* @__PURE__ */ jsxs13("p", { children: [
3586
- /* @__PURE__ */ jsx24("strong", { children: "Catalogix" }),
4183
+ return /* @__PURE__ */ jsx26("div", { className: "p-4 text-sm text-muted-foreground", children: /* @__PURE__ */ jsxs15("p", { children: [
4184
+ /* @__PURE__ */ jsx26("strong", { children: "Catalogix" }),
3587
4185
  " \u2014 unknown section:",
3588
4186
  " ",
3589
- /* @__PURE__ */ jsx24("code", { children: section || "(none)" })
4187
+ /* @__PURE__ */ jsx26("code", { children: section || "(none)" })
3590
4188
  ] }) });
3591
4189
  }
3592
4190
 
@@ -3632,11 +4230,26 @@ var catalogixManifest = [
3632
4230
  position: "relative",
3633
4231
  width: "100%"
3634
4232
  }
4233
+ },
4234
+ {
4235
+ name: "catalogix:map-attributes",
4236
+ aliases: ["map_attributes"],
4237
+ service: "catalogix",
4238
+ description: "Review and fix attribute mappings",
4239
+ containerStyle: {
4240
+ overflow: "auto",
4241
+ marginTop: "8px",
4242
+ paddingBottom: "16px",
4243
+ height: "600px",
4244
+ position: "relative",
4245
+ width: "100%"
4246
+ }
3635
4247
  }
3636
4248
  ];
3637
4249
  export {
3638
4250
  CatalogixChat,
3639
4251
  CreateStore,
4252
+ MapAttributesChat,
3640
4253
  ProductAutomation,
3641
4254
  SelectProducts,
3642
4255
  StoreAutomation,