@streamoid/catalogix-chat 0.2.6 → 0.2.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.js +92 -23
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -2444,16 +2444,29 @@ import {
2444
2444
  Search as Search3,
2445
2445
  ArrowRight,
2446
2446
  ArrowLeft as ArrowLeft2,
2447
- Send
2447
+ Send,
2448
+ AlertTriangle
2448
2449
  } from "lucide-react";
2449
- import { jsx as jsx21, jsxs as jsxs10 } from "react/jsx-runtime";
2450
+ import { Fragment as Fragment4, jsx as jsx21, jsxs as jsxs10 } from "react/jsx-runtime";
2450
2451
  function getAllAttributes(mpAttributes) {
2451
2452
  return Object.values(mpAttributes).flat();
2452
2453
  }
2454
+ function hasIncompleteLovValues(item, valuesOntologyAttributes, uniqueValues) {
2455
+ if (!item.isConfirmed || item.isIgnored) return false;
2456
+ for (const attr of item.mappedCols) {
2457
+ if (!valuesOntologyAttributes.includes(attr)) continue;
2458
+ const rawVals = uniqueValues[item.feedCol] || [];
2459
+ if (rawVals.length === 0) continue;
2460
+ const mapped = item.mappedValues[attr] || {};
2461
+ if (rawVals.some((v) => mapped[v] == null)) return true;
2462
+ }
2463
+ return false;
2464
+ }
2453
2465
  function AttributeRow({
2454
2466
  item,
2455
2467
  index,
2456
2468
  allAttributes,
2469
+ needsValueAttention,
2457
2470
  onMap,
2458
2471
  onConfirm,
2459
2472
  onIgnore,
@@ -2467,11 +2480,15 @@ function AttributeRow({
2467
2480
  return allAttributes.filter((a) => !mapped.has(a));
2468
2481
  }, [allAttributes, item.mappedCols, item.customCols]);
2469
2482
  if (item.isConfirmed) {
2470
- return /* @__PURE__ */ jsxs10("div", { className: "flex items-center gap-2 py-1.5 group", children: [
2471
- /* @__PURE__ */ jsx21(Check2, { className: "size-3 shrink-0 text-emerald-600 dark:text-emerald-400" }),
2483
+ return /* @__PURE__ */ jsxs10("div", { className: cn(
2484
+ "flex items-center gap-2 py-1.5 group",
2485
+ needsValueAttention && "border-l-2 border-amber-500/60 pl-2"
2486
+ ), children: [
2487
+ needsValueAttention ? /* @__PURE__ */ jsx21(AlertTriangle, { className: "size-3 shrink-0 text-amber-500" }) : /* @__PURE__ */ jsx21(Check2, { className: "size-3 shrink-0 text-emerald-600 dark:text-emerald-400" }),
2472
2488
  /* @__PURE__ */ jsx21("span", { className: "text-xs font-medium truncate", children: item.feedCol }),
2473
2489
  /* @__PURE__ */ jsx21(ChevronRight2, { className: "size-3 shrink-0 text-muted-foreground" }),
2474
2490
  /* @__PURE__ */ jsx21("span", { className: "text-xs text-muted-foreground truncate", children: [...item.mappedCols, ...item.customCols].join(", ") }),
2491
+ needsValueAttention && /* @__PURE__ */ jsx21(Badge, { variant: "outline", className: "text-[10px] h-4 px-1 border-amber-500/50 text-amber-600 dark:text-amber-400 shrink-0", children: "values needed" }),
2475
2492
  /* @__PURE__ */ jsx21(
2476
2493
  "button",
2477
2494
  {
@@ -2705,6 +2722,37 @@ function MapAttributesChat({
2705
2722
  }
2706
2723
  return true;
2707
2724
  }, [data, valuesOntologyAttributes, uniqueValues]);
2725
+ const lovAttentionSet = useMemo5(() => {
2726
+ const set = /* @__PURE__ */ new Set();
2727
+ data.forEach((item, idx) => {
2728
+ if (hasIncompleteLovValues(item, valuesOntologyAttributes, uniqueValues)) {
2729
+ set.add(idx);
2730
+ }
2731
+ });
2732
+ return set;
2733
+ }, [data, valuesOntologyAttributes, uniqueValues]);
2734
+ const attentionSummary = useMemo5(() => {
2735
+ const unmappedCount = data.filter(
2736
+ (i) => !i.isConfirmed && !i.isIgnored
2737
+ ).length;
2738
+ const lovIncompleteCount = lovAttentionSet.size;
2739
+ return { unmappedCount, lovIncompleteCount };
2740
+ }, [data, lovAttentionSet]);
2741
+ const sortedIndices = useMemo5(() => {
2742
+ const indices = data.map((_, i) => i);
2743
+ indices.sort((a, b) => {
2744
+ const itemA = data[a];
2745
+ const itemB = data[b];
2746
+ const priorityOf = (item, idx) => {
2747
+ if (!item.isConfirmed && !item.isIgnored) return 0;
2748
+ if (lovAttentionSet.has(idx)) return 1;
2749
+ if (item.isConfirmed) return 2;
2750
+ return 3;
2751
+ };
2752
+ return priorityOf(itemA, a) - priorityOf(itemB, b);
2753
+ });
2754
+ return indices;
2755
+ }, [data, lovAttentionSet]);
2708
2756
  const handleMap = useCallback5((index, attribute) => {
2709
2757
  setData((prev) => {
2710
2758
  const next = [...prev];
@@ -2784,27 +2832,48 @@ function MapAttributesChat({
2784
2832
  /* @__PURE__ */ jsx21("h3", { className: "text-sm font-semibold tracking-tight", children: step === "attributes" ? "Map Attributes" : "Map Values" }),
2785
2833
  /* @__PURE__ */ jsx21("p", { className: "text-xs text-muted-foreground leading-snug", children: step === "attributes" ? "Match each feed column to a marketplace attribute" : "Normalize values for controlled-vocabulary attributes" })
2786
2834
  ] }),
2787
- step === "attributes" && /* @__PURE__ */ jsxs10("div", { className: "flex items-center gap-2", children: [
2788
- /* @__PURE__ */ jsx21("div", { className: "h-1 flex-1 overflow-hidden rounded-full bg-muted", children: /* @__PURE__ */ jsx21(
2789
- "div",
2790
- {
2791
- className: "h-full rounded-full bg-primary transition-all",
2792
- style: { width: `${progress.percent}%` }
2793
- }
2794
- ) }),
2795
- /* @__PURE__ */ jsxs10("span", { className: "text-[11px] text-muted-foreground tabular-nums shrink-0", children: [
2796
- progress.done,
2797
- "/",
2798
- progress.total
2835
+ step === "attributes" && /* @__PURE__ */ jsxs10(Fragment4, { children: [
2836
+ /* @__PURE__ */ jsxs10("div", { className: "flex items-center gap-2", children: [
2837
+ /* @__PURE__ */ jsx21("div", { className: "h-1 flex-1 overflow-hidden rounded-full bg-muted", children: /* @__PURE__ */ jsx21(
2838
+ "div",
2839
+ {
2840
+ className: "h-full rounded-full bg-primary transition-all",
2841
+ style: { width: `${progress.percent}%` }
2842
+ }
2843
+ ) }),
2844
+ /* @__PURE__ */ jsxs10("span", { className: "text-[11px] text-muted-foreground tabular-nums shrink-0", children: [
2845
+ progress.done,
2846
+ "/",
2847
+ progress.total
2848
+ ] })
2849
+ ] }),
2850
+ (attentionSummary.unmappedCount > 0 || attentionSummary.lovIncompleteCount > 0) && /* @__PURE__ */ jsxs10("div", { className: "flex items-start gap-1.5 rounded-md bg-amber-500/10 border border-amber-500/20 px-2.5 py-1.5", children: [
2851
+ /* @__PURE__ */ jsx21(AlertTriangle, { className: "size-3 mt-0.5 shrink-0 text-amber-500" }),
2852
+ /* @__PURE__ */ jsxs10("div", { className: "text-[11px] text-amber-700 dark:text-amber-400 leading-snug", children: [
2853
+ attentionSummary.unmappedCount > 0 && /* @__PURE__ */ jsxs10("span", { children: [
2854
+ attentionSummary.unmappedCount,
2855
+ " attribute",
2856
+ attentionSummary.unmappedCount > 1 ? "s" : "",
2857
+ " unmapped"
2858
+ ] }),
2859
+ attentionSummary.unmappedCount > 0 && attentionSummary.lovIncompleteCount > 0 && /* @__PURE__ */ jsx21("span", { children: " \xB7 " }),
2860
+ attentionSummary.lovIncompleteCount > 0 && /* @__PURE__ */ jsxs10("span", { children: [
2861
+ attentionSummary.lovIncompleteCount,
2862
+ " attribute",
2863
+ attentionSummary.lovIncompleteCount > 1 ? "s" : "",
2864
+ " need value mapping"
2865
+ ] })
2866
+ ] })
2799
2867
  ] })
2800
2868
  ] })
2801
2869
  ] }),
2802
- /* @__PURE__ */ jsx21("div", { className: "px-4 overflow-y-auto flex-1 min-h-0", children: step === "attributes" ? /* @__PURE__ */ jsx21("div", { className: "divide-y divide-border/50", children: data.map((item, idx) => /* @__PURE__ */ jsx21(
2870
+ /* @__PURE__ */ jsx21("div", { className: "px-4 overflow-y-auto flex-1 min-h-0", children: step === "attributes" ? /* @__PURE__ */ jsx21("div", { className: "divide-y divide-border/50", children: sortedIndices.map((idx) => /* @__PURE__ */ jsx21(
2803
2871
  AttributeRow,
2804
2872
  {
2805
- item,
2873
+ item: data[idx],
2806
2874
  index: idx,
2807
2875
  allAttributes,
2876
+ needsValueAttention: lovAttentionSet.has(idx),
2808
2877
  onMap: handleMap,
2809
2878
  onConfirm: handleConfirm,
2810
2879
  onIgnore: handleIgnore,
@@ -3329,7 +3398,7 @@ function BooleanField({
3329
3398
  }
3330
3399
 
3331
3400
  // src/Automations/ProductAutomation.tsx
3332
- import { Fragment as Fragment4, jsx as jsx23, jsxs as jsxs12 } from "react/jsx-runtime";
3401
+ import { Fragment as Fragment5, jsx as jsx23, jsxs as jsxs12 } from "react/jsx-runtime";
3333
3402
  function ProductAutomation({
3334
3403
  storeId,
3335
3404
  workspaceId,
@@ -3609,10 +3678,10 @@ function ProductAutomation({
3609
3678
  onClick: handleRun,
3610
3679
  disabled: !isRunAllowed() || applying,
3611
3680
  className: "flex-1",
3612
- children: applying ? /* @__PURE__ */ jsxs12(Fragment4, { children: [
3681
+ children: applying ? /* @__PURE__ */ jsxs12(Fragment5, { children: [
3613
3682
  /* @__PURE__ */ jsx23(Loader26, { className: "size-4 animate-spin" }),
3614
3683
  "Applying..."
3615
- ] }) : /* @__PURE__ */ jsxs12(Fragment4, { children: [
3684
+ ] }) : /* @__PURE__ */ jsxs12(Fragment5, { children: [
3616
3685
  /* @__PURE__ */ jsx23(Play, { className: "size-4" }),
3617
3686
  "Run Automation"
3618
3687
  ] })
@@ -3656,7 +3725,7 @@ function formatTimeSaved(totalSeconds) {
3656
3725
  // src/Automations/StoreAutomation.tsx
3657
3726
  import { useState as useState10, useEffect as useEffect6, useCallback as useCallback8, useRef as useRef6 } from "react";
3658
3727
  import { ArrowLeft as ArrowLeft4, Settings } from "lucide-react";
3659
- import { Fragment as Fragment5, jsx as jsx24, jsxs as jsxs13 } from "react/jsx-runtime";
3728
+ import { Fragment as Fragment6, jsx as jsx24, jsxs as jsxs13 } from "react/jsx-runtime";
3660
3729
  function StoreAutomation({
3661
3730
  storeId,
3662
3731
  channelsWithVersion,
@@ -3904,7 +3973,7 @@ function AutomationConfigEditor({
3904
3973
  onConfigChange: handleConfigChange
3905
3974
  }
3906
3975
  ) : /* @__PURE__ */ jsx24("p", { className: "py-4 text-center text-sm text-muted-foreground", children: "Enable this automation to configure it." }) }),
3907
- automation.preview && /* @__PURE__ */ jsxs13(Fragment5, { children: [
3976
+ automation.preview && /* @__PURE__ */ jsxs13(Fragment6, { children: [
3908
3977
  /* @__PURE__ */ jsx24(Separator2, {}),
3909
3978
  /* @__PURE__ */ jsxs13("div", { className: "space-y-2 rounded-lg bg-muted/50 p-3 text-sm", children: [
3910
3979
  automation.preview.info_text.map((text, i) => /* @__PURE__ */ jsx24("p", { className: "text-muted-foreground", children: text }, i)),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@streamoid/catalogix-chat",
3
- "version": "0.2.6",
3
+ "version": "0.2.7",
4
4
  "description": "Catalogix chat components for the Streamoid chat host — store creation, product selection, automations",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",