@streamoid/catalogix-chat 0.2.17 → 0.2.19
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.d.ts +45 -1
- package/dist/index.js +730 -209
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1717,16 +1717,24 @@ function SelectProducts({
|
|
|
1717
1717
|
}));
|
|
1718
1718
|
}, []);
|
|
1719
1719
|
if (isSubmitted) {
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
/* @__PURE__ */ jsx16("
|
|
1720
|
+
const vals = localSubmittedValues;
|
|
1721
|
+
const uuids = Array.isArray(vals?.product_uuids) ? vals.product_uuids : [];
|
|
1722
|
+
const codes = Array.isArray(vals?.product_codes) ? vals.product_codes : [];
|
|
1723
|
+
const count = uuids.length || codes.length;
|
|
1724
|
+
return /* @__PURE__ */ jsx16("div", { className: "max-w-[50%] py-2 animate-in fade-in duration-300", children: /* @__PURE__ */ jsxs7("div", { className: "rounded-md border p-2.5 flex items-start gap-2 bg-emerald-50/50 border-emerald-200 dark:bg-muted/20 dark:border-border", children: [
|
|
1725
|
+
/* @__PURE__ */ jsx16("div", { className: "mt-px text-emerald-500", children: /* @__PURE__ */ jsx16(CheckCircle, { className: "w-4 h-4" }) }),
|
|
1726
|
+
/* @__PURE__ */ jsxs7("div", { className: "flex-1 min-w-0", children: [
|
|
1727
|
+
/* @__PURE__ */ jsx16("p", { className: "text-xs font-medium leading-tight", children: "Submitted \u2014 Product Selection" }),
|
|
1728
|
+
count > 0 && /* @__PURE__ */ jsxs7("div", { className: "mt-1 text-[11px] leading-snug", children: [
|
|
1729
|
+
/* @__PURE__ */ jsx16("span", { className: "font-medium text-muted-foreground", children: "Products:" }),
|
|
1730
|
+
" ",
|
|
1731
|
+
/* @__PURE__ */ jsxs7("span", { className: "text-foreground/80", children: [
|
|
1732
|
+
count,
|
|
1733
|
+
" selected"
|
|
1734
|
+
] })
|
|
1735
|
+
] })
|
|
1728
1736
|
] })
|
|
1729
|
-
] });
|
|
1737
|
+
] }) });
|
|
1730
1738
|
}
|
|
1731
1739
|
if (!storeId || !workspaceId) {
|
|
1732
1740
|
return /* @__PURE__ */ jsx16(Card, { className: "p-6 text-center text-muted-foreground", children: "Store context missing. Please start from a store selection step." });
|
|
@@ -3069,9 +3077,482 @@ function MapAttributesChat({
|
|
|
3069
3077
|
] });
|
|
3070
3078
|
}
|
|
3071
3079
|
|
|
3080
|
+
// src/EditFeed/index.tsx
|
|
3081
|
+
import React8, { useState as useState8, useMemo as useMemo6, useCallback as useCallback6 } from "react";
|
|
3082
|
+
import {
|
|
3083
|
+
AlertTriangle as AlertTriangle2,
|
|
3084
|
+
Check as Check3,
|
|
3085
|
+
ChevronDown as ChevronDown3,
|
|
3086
|
+
ChevronRight as ChevronRight3,
|
|
3087
|
+
Pencil as Pencil3,
|
|
3088
|
+
Info as Info2,
|
|
3089
|
+
Loader2 as Loader26,
|
|
3090
|
+
X as X2,
|
|
3091
|
+
RefreshCw
|
|
3092
|
+
} from "lucide-react";
|
|
3093
|
+
import { jsx as jsx22, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
3094
|
+
function buildErrorMap(criticalIssues, columns) {
|
|
3095
|
+
const map = /* @__PURE__ */ new Map();
|
|
3096
|
+
for (const issue of criticalIssues) {
|
|
3097
|
+
const sku = String(issue.skuCode);
|
|
3098
|
+
if (!map.has(sku)) map.set(sku, /* @__PURE__ */ new Map());
|
|
3099
|
+
const errStr = String(issue.errorMessage);
|
|
3100
|
+
const colEntries = errStr.match(/'(\d+)':\s*'([^']+)'/g);
|
|
3101
|
+
if (colEntries) {
|
|
3102
|
+
for (const entry of colEntries) {
|
|
3103
|
+
const m = entry.match(/'(\d+)':\s*'([^']+)'/);
|
|
3104
|
+
if (m) {
|
|
3105
|
+
const colIdx = parseInt(m[1], 10) - 1;
|
|
3106
|
+
const msg = m[2];
|
|
3107
|
+
const colName = columns[colIdx] ?? `Column ${m[1]}`;
|
|
3108
|
+
map.get(sku).set(colName, msg);
|
|
3109
|
+
}
|
|
3110
|
+
}
|
|
3111
|
+
} else if (issue.columnNumber) {
|
|
3112
|
+
const colIdx = parseInt(issue.columnNumber, 10) - 1;
|
|
3113
|
+
const colName = columns[colIdx] ?? `Column ${issue.columnNumber}`;
|
|
3114
|
+
map.get(sku).set(colName, errStr);
|
|
3115
|
+
}
|
|
3116
|
+
}
|
|
3117
|
+
return map;
|
|
3118
|
+
}
|
|
3119
|
+
function buildDataIssueMap(issues) {
|
|
3120
|
+
const map = /* @__PURE__ */ new Map();
|
|
3121
|
+
for (const di of issues) {
|
|
3122
|
+
if (di.skuCode && di.missingAttributes) {
|
|
3123
|
+
map.set(String(di.skuCode), di.missingAttributes);
|
|
3124
|
+
}
|
|
3125
|
+
}
|
|
3126
|
+
return map;
|
|
3127
|
+
}
|
|
3128
|
+
function rowsToCsvBlob(rows, columns) {
|
|
3129
|
+
const escape = (v) => {
|
|
3130
|
+
if (v.includes(",") || v.includes('"') || v.includes("\n")) {
|
|
3131
|
+
return `"${v.replace(/"/g, '""')}"`;
|
|
3132
|
+
}
|
|
3133
|
+
return v;
|
|
3134
|
+
};
|
|
3135
|
+
const lines = [columns.map(escape).join(",")];
|
|
3136
|
+
for (const row of rows) {
|
|
3137
|
+
lines.push(columns.map((c) => escape(row[c] ?? "")).join(","));
|
|
3138
|
+
}
|
|
3139
|
+
return new Blob([lines.join("\n")], { type: "text/csv" });
|
|
3140
|
+
}
|
|
3141
|
+
async function uploadCorrectedCsv(storeId, csvBlob, fileName) {
|
|
3142
|
+
const { catalogixBaseUrl } = getApiConfig();
|
|
3143
|
+
const form = new FormData();
|
|
3144
|
+
form.append("file_type", "csv");
|
|
3145
|
+
form.append("file_data", csvBlob, fileName);
|
|
3146
|
+
form.append("data", JSON.stringify({ fileName, size: csvBlob.size / 1024 }));
|
|
3147
|
+
const resp = await fetch(
|
|
3148
|
+
`${catalogixBaseUrl}/api/v1/store/${storeId}/feed/onboard`,
|
|
3149
|
+
{ method: "POST", credentials: "include", body: form }
|
|
3150
|
+
);
|
|
3151
|
+
if (!resp.ok) throw new Error(`Upload failed: ${resp.status}`);
|
|
3152
|
+
const json = await resp.json();
|
|
3153
|
+
return json.data.download_url;
|
|
3154
|
+
}
|
|
3155
|
+
async function validateFeed(storeId, fileUrl, feedFileType, clientFeedUrl, userId, mappingObj, sourceMp, marketplaceOv, reValidate) {
|
|
3156
|
+
const { catalogixBaseUrl } = getApiConfig();
|
|
3157
|
+
const params = new URLSearchParams({
|
|
3158
|
+
file_url: fileUrl,
|
|
3159
|
+
feed_format: feedFileType,
|
|
3160
|
+
client_feed_url: clientFeedUrl,
|
|
3161
|
+
catalogix_user_id: userId,
|
|
3162
|
+
re_validate: String(reValidate)
|
|
3163
|
+
});
|
|
3164
|
+
return fetchJson(
|
|
3165
|
+
`${catalogixBaseUrl}/api/v1/feed/${storeId}/validate/v2?${params}`,
|
|
3166
|
+
{
|
|
3167
|
+
method: "POST",
|
|
3168
|
+
headers: { "Content-Type": "application/json" },
|
|
3169
|
+
body: JSON.stringify({
|
|
3170
|
+
mapping: {
|
|
3171
|
+
...mappingObj,
|
|
3172
|
+
catalogix_user_id: userId,
|
|
3173
|
+
mp: sourceMp,
|
|
3174
|
+
template: reValidate ? null : "",
|
|
3175
|
+
source_ov: reValidate ? marketplaceOv : String(marketplaceOv)
|
|
3176
|
+
}
|
|
3177
|
+
})
|
|
3178
|
+
}
|
|
3179
|
+
);
|
|
3180
|
+
}
|
|
3181
|
+
async function fetchValidationErrors(issueFilesUrl) {
|
|
3182
|
+
const { catalogixBaseUrl } = getApiConfig();
|
|
3183
|
+
const params = new URLSearchParams({ excelUrl: issueFilesUrl });
|
|
3184
|
+
return fetchJson(
|
|
3185
|
+
`${catalogixBaseUrl}/api/v1/format-sheet-data-for-mapping?${params}`
|
|
3186
|
+
);
|
|
3187
|
+
}
|
|
3188
|
+
function EditableCell2({
|
|
3189
|
+
value,
|
|
3190
|
+
hasError,
|
|
3191
|
+
errorMessage,
|
|
3192
|
+
onChange,
|
|
3193
|
+
readOnly
|
|
3194
|
+
}) {
|
|
3195
|
+
const [editing, setEditing] = useState8(false);
|
|
3196
|
+
const [draft, setDraft] = useState8(value);
|
|
3197
|
+
const commit = useCallback6(() => {
|
|
3198
|
+
setEditing(false);
|
|
3199
|
+
if (draft !== value) onChange(draft);
|
|
3200
|
+
}, [draft, value, onChange]);
|
|
3201
|
+
if (readOnly || !hasError) {
|
|
3202
|
+
return /* @__PURE__ */ jsxs11(
|
|
3203
|
+
"div",
|
|
3204
|
+
{
|
|
3205
|
+
className: cn(
|
|
3206
|
+
"px-2 py-1 text-sm truncate max-w-[200px]",
|
|
3207
|
+
hasError && "text-destructive font-medium"
|
|
3208
|
+
),
|
|
3209
|
+
title: value,
|
|
3210
|
+
children: [
|
|
3211
|
+
value,
|
|
3212
|
+
hasError && errorMessage && /* @__PURE__ */ jsx22("div", { className: "text-[10px] text-destructive/80 mt-0.5 whitespace-normal leading-tight", children: errorMessage })
|
|
3213
|
+
]
|
|
3214
|
+
}
|
|
3215
|
+
);
|
|
3216
|
+
}
|
|
3217
|
+
if (editing) {
|
|
3218
|
+
return /* @__PURE__ */ jsx22(
|
|
3219
|
+
Input,
|
|
3220
|
+
{
|
|
3221
|
+
autoFocus: true,
|
|
3222
|
+
value: draft,
|
|
3223
|
+
onChange: (e) => setDraft(e.target.value),
|
|
3224
|
+
onBlur: commit,
|
|
3225
|
+
onKeyDown: (e) => {
|
|
3226
|
+
if (e.key === "Enter") commit();
|
|
3227
|
+
if (e.key === "Escape") {
|
|
3228
|
+
setDraft(value);
|
|
3229
|
+
setEditing(false);
|
|
3230
|
+
}
|
|
3231
|
+
},
|
|
3232
|
+
className: cn(
|
|
3233
|
+
"h-7 text-sm rounded px-1.5",
|
|
3234
|
+
hasError && "border-destructive focus-visible:ring-destructive/30"
|
|
3235
|
+
)
|
|
3236
|
+
}
|
|
3237
|
+
);
|
|
3238
|
+
}
|
|
3239
|
+
return /* @__PURE__ */ jsxs11(
|
|
3240
|
+
"div",
|
|
3241
|
+
{
|
|
3242
|
+
className: cn(
|
|
3243
|
+
"group relative flex items-center gap-1 cursor-pointer rounded px-2 py-1 text-sm",
|
|
3244
|
+
hasError ? "bg-destructive/10 border border-destructive/40 text-destructive font-medium" : "hover:bg-muted/60"
|
|
3245
|
+
),
|
|
3246
|
+
onClick: () => {
|
|
3247
|
+
setDraft(value);
|
|
3248
|
+
setEditing(true);
|
|
3249
|
+
},
|
|
3250
|
+
title: errorMessage || "Click to edit",
|
|
3251
|
+
children: [
|
|
3252
|
+
/* @__PURE__ */ jsx22("span", { className: "truncate max-w-[160px]", children: value }),
|
|
3253
|
+
/* @__PURE__ */ jsx22(Pencil3, { className: "h-3 w-3 shrink-0 opacity-0 group-hover:opacity-70 transition-opacity" }),
|
|
3254
|
+
hasError && errorMessage && /* @__PURE__ */ jsx22("div", { className: "absolute left-0 top-full z-10 mt-1 hidden group-hover:block", children: /* @__PURE__ */ jsx22("div", { className: "rounded bg-destructive px-2 py-1 text-[10px] text-destructive-foreground shadow-md max-w-[260px] whitespace-normal", children: errorMessage }) })
|
|
3255
|
+
]
|
|
3256
|
+
}
|
|
3257
|
+
);
|
|
3258
|
+
}
|
|
3259
|
+
function MissingAttributesBanner({ text }) {
|
|
3260
|
+
const [open, setOpen] = useState8(false);
|
|
3261
|
+
const attrs = text.split(",").map((s) => s.trim().replace(/^'|'$/g, ""));
|
|
3262
|
+
const preview = attrs.slice(0, 3);
|
|
3263
|
+
return /* @__PURE__ */ jsxs11("div", { className: "text-xs text-muted-foreground px-2 py-1.5 border-t border-dashed bg-muted/30", children: [
|
|
3264
|
+
/* @__PURE__ */ jsxs11(
|
|
3265
|
+
"button",
|
|
3266
|
+
{
|
|
3267
|
+
type: "button",
|
|
3268
|
+
className: "flex items-center gap-1 hover:text-foreground transition-colors",
|
|
3269
|
+
onClick: () => setOpen((v) => !v),
|
|
3270
|
+
children: [
|
|
3271
|
+
/* @__PURE__ */ jsx22(Info2, { className: "h-3 w-3" }),
|
|
3272
|
+
/* @__PURE__ */ jsx22("span", { className: "font-medium", children: "Missing attributes:" }),
|
|
3273
|
+
!open && /* @__PURE__ */ jsxs11("span", { children: [
|
|
3274
|
+
preview.join(", "),
|
|
3275
|
+
attrs.length > 3 && ` +${attrs.length - 3} more`
|
|
3276
|
+
] }),
|
|
3277
|
+
open ? /* @__PURE__ */ jsx22(ChevronDown3, { className: "h-3 w-3" }) : /* @__PURE__ */ jsx22(ChevronRight3, { className: "h-3 w-3" })
|
|
3278
|
+
]
|
|
3279
|
+
}
|
|
3280
|
+
),
|
|
3281
|
+
open && /* @__PURE__ */ jsx22("div", { className: "flex flex-wrap gap-1 mt-1.5", children: attrs.map((a) => /* @__PURE__ */ jsx22(Badge, { variant: "secondary", className: "text-[10px] font-normal", children: a }, a)) })
|
|
3282
|
+
] });
|
|
3283
|
+
}
|
|
3284
|
+
function SubmittedSummary({
|
|
3285
|
+
submittedValues
|
|
3286
|
+
}) {
|
|
3287
|
+
const cancelled = !!submittedValues?.cancelled;
|
|
3288
|
+
return /* @__PURE__ */ jsxs11(Card, { className: "p-4", children: [
|
|
3289
|
+
/* @__PURE__ */ jsxs11("div", { className: "flex items-center gap-2 mb-2", children: [
|
|
3290
|
+
cancelled ? /* @__PURE__ */ jsx22(X2, { className: "h-4 w-4 text-muted-foreground" }) : /* @__PURE__ */ jsx22(Check3, { className: "h-4 w-4 text-green-600" }),
|
|
3291
|
+
/* @__PURE__ */ jsx22("span", { className: "font-medium text-sm", children: cancelled ? "Feed correction cancelled" : "Feed corrections validated" })
|
|
3292
|
+
] }),
|
|
3293
|
+
!cancelled && !!submittedValues?.transformedUrl && /* @__PURE__ */ jsx22("p", { className: "text-xs text-muted-foreground", children: "Validation passed. Proceeding with upload." })
|
|
3294
|
+
] });
|
|
3295
|
+
}
|
|
3296
|
+
function EditFeed({
|
|
3297
|
+
criticalIssues: initialCriticalIssues,
|
|
3298
|
+
rawErrorData: initialRawErrorData,
|
|
3299
|
+
dataIssuesRaw: initialDataIssuesRaw,
|
|
3300
|
+
columns: initialColumns,
|
|
3301
|
+
skuField,
|
|
3302
|
+
storeId,
|
|
3303
|
+
feedFileType,
|
|
3304
|
+
downloadUrl,
|
|
3305
|
+
userId,
|
|
3306
|
+
mappingObj,
|
|
3307
|
+
sourceMp,
|
|
3308
|
+
marketplaceOv,
|
|
3309
|
+
transformedUrl: initialTransformedUrl,
|
|
3310
|
+
submitted,
|
|
3311
|
+
submittedValues,
|
|
3312
|
+
onSubmit
|
|
3313
|
+
}) {
|
|
3314
|
+
if (submitted && submittedValues) {
|
|
3315
|
+
return /* @__PURE__ */ jsx22(SubmittedSummary, { submittedValues });
|
|
3316
|
+
}
|
|
3317
|
+
const [rows, setRows] = useState8(
|
|
3318
|
+
() => initialRawErrorData.map((r) => {
|
|
3319
|
+
const out = {};
|
|
3320
|
+
for (const [k, v] of Object.entries(r)) {
|
|
3321
|
+
if (k !== "row_number") out[k] = String(v ?? "");
|
|
3322
|
+
}
|
|
3323
|
+
return out;
|
|
3324
|
+
})
|
|
3325
|
+
);
|
|
3326
|
+
const [criticalIssues, setCriticalIssues] = useState8(initialCriticalIssues);
|
|
3327
|
+
const [dataIssuesRaw, setDataIssuesRaw] = useState8(initialDataIssuesRaw);
|
|
3328
|
+
const [columns] = useState8(
|
|
3329
|
+
initialColumns.length > 0 ? initialColumns.filter((c) => c !== "row_number") : initialRawErrorData.length > 0 ? Object.keys(initialRawErrorData[0]).filter((c) => c !== "row_number") : []
|
|
3330
|
+
);
|
|
3331
|
+
const [editedCells, setEditedCells] = useState8(/* @__PURE__ */ new Set());
|
|
3332
|
+
const [isLoading, setIsLoading] = useState8(false);
|
|
3333
|
+
const [statusMsg, setStatusMsg] = useState8("");
|
|
3334
|
+
const [errorMsg, setErrorMsg] = useState8("");
|
|
3335
|
+
const [transformedUrl] = useState8(initialTransformedUrl);
|
|
3336
|
+
const errorMap = useMemo6(
|
|
3337
|
+
() => buildErrorMap(criticalIssues, columns),
|
|
3338
|
+
[criticalIssues, columns]
|
|
3339
|
+
);
|
|
3340
|
+
const dataIssueMap = useMemo6(
|
|
3341
|
+
() => buildDataIssueMap(dataIssuesRaw),
|
|
3342
|
+
[dataIssuesRaw]
|
|
3343
|
+
);
|
|
3344
|
+
const errorCount = useMemo6(() => {
|
|
3345
|
+
let count = 0;
|
|
3346
|
+
for (const [, colMap] of errorMap) count += colMap.size;
|
|
3347
|
+
return count;
|
|
3348
|
+
}, [errorMap]);
|
|
3349
|
+
const handleCellChange = useCallback6(
|
|
3350
|
+
(rowIdx, col, val) => {
|
|
3351
|
+
setRows((prev) => {
|
|
3352
|
+
const next = [...prev];
|
|
3353
|
+
next[rowIdx] = { ...next[rowIdx], [col]: val };
|
|
3354
|
+
return next;
|
|
3355
|
+
});
|
|
3356
|
+
setEditedCells((prev) => new Set(prev).add(`${rowIdx}:${col}`));
|
|
3357
|
+
},
|
|
3358
|
+
[]
|
|
3359
|
+
);
|
|
3360
|
+
const handleCancel = useCallback6(() => {
|
|
3361
|
+
onSubmit({ cancelled: true }, "Feed correction cancelled.");
|
|
3362
|
+
}, [onSubmit]);
|
|
3363
|
+
const handleFixAndRevalidate = useCallback6(async () => {
|
|
3364
|
+
setIsLoading(true);
|
|
3365
|
+
setErrorMsg("");
|
|
3366
|
+
try {
|
|
3367
|
+
setStatusMsg("Building corrected CSV...");
|
|
3368
|
+
const csvBlob = rowsToCsvBlob(rows, columns);
|
|
3369
|
+
const fileName = `corrected_${Date.now()}.csv`;
|
|
3370
|
+
setStatusMsg("Uploading corrected feed...");
|
|
3371
|
+
const newFileUrl = await uploadCorrectedCsv(storeId, csvBlob, fileName);
|
|
3372
|
+
setStatusMsg("Re-validating feed...");
|
|
3373
|
+
const result = await validateFeed(
|
|
3374
|
+
storeId,
|
|
3375
|
+
newFileUrl,
|
|
3376
|
+
feedFileType,
|
|
3377
|
+
downloadUrl,
|
|
3378
|
+
userId,
|
|
3379
|
+
mappingObj,
|
|
3380
|
+
sourceMp,
|
|
3381
|
+
marketplaceOv,
|
|
3382
|
+
true
|
|
3383
|
+
);
|
|
3384
|
+
const data = result.data;
|
|
3385
|
+
if (data.validation) {
|
|
3386
|
+
setStatusMsg("Validation passed!");
|
|
3387
|
+
onSubmit(
|
|
3388
|
+
{ transformedUrl: data.transformed_url },
|
|
3389
|
+
"Feed corrections validated successfully."
|
|
3390
|
+
);
|
|
3391
|
+
return;
|
|
3392
|
+
}
|
|
3393
|
+
setStatusMsg("Validation still failing \u2014 fetching new errors...");
|
|
3394
|
+
const issueUrl = data.errors?.issue_files_url;
|
|
3395
|
+
if (issueUrl) {
|
|
3396
|
+
const errResp = await fetchValidationErrors(issueUrl);
|
|
3397
|
+
const newRaw = errResp.data.raw_error_data ?? [];
|
|
3398
|
+
const newRows = newRaw.map((r) => {
|
|
3399
|
+
const out = {};
|
|
3400
|
+
for (const [k, v] of Object.entries(r)) {
|
|
3401
|
+
if (k !== "row_number") out[k] = String(v ?? "");
|
|
3402
|
+
}
|
|
3403
|
+
return out;
|
|
3404
|
+
});
|
|
3405
|
+
setRows(newRows);
|
|
3406
|
+
setEditedCells(/* @__PURE__ */ new Set());
|
|
3407
|
+
const newCritical = (errResp.data.critical_issues ?? []).map(
|
|
3408
|
+
(ci) => {
|
|
3409
|
+
let errMsgRaw = String(ci.error_message ?? "");
|
|
3410
|
+
errMsgRaw = errMsgRaw.replace(/^[{' ]+|[}' ]+$/g, "");
|
|
3411
|
+
return {
|
|
3412
|
+
rowNumber: ci["Row Number"],
|
|
3413
|
+
columnNumber: ci["Column Number"],
|
|
3414
|
+
skuCode: String(ci["SKU Code"] ?? ""),
|
|
3415
|
+
errorMessage: errMsgRaw
|
|
3416
|
+
};
|
|
3417
|
+
}
|
|
3418
|
+
);
|
|
3419
|
+
setCriticalIssues(newCritical);
|
|
3420
|
+
const newDataIssues = (errResp.data.data_issues_raw ?? []).map(
|
|
3421
|
+
(di) => ({
|
|
3422
|
+
rowNumber: String(di["Row Number"] ?? ""),
|
|
3423
|
+
skuCode: String(di["SKU Code"] ?? ""),
|
|
3424
|
+
missingAttributes: String(
|
|
3425
|
+
di["Attribute Required For Listing"] ?? ""
|
|
3426
|
+
)
|
|
3427
|
+
})
|
|
3428
|
+
);
|
|
3429
|
+
setDataIssuesRaw(newDataIssues);
|
|
3430
|
+
setErrorMsg(
|
|
3431
|
+
"Validation still has errors. Please fix the remaining issues and try again."
|
|
3432
|
+
);
|
|
3433
|
+
} else {
|
|
3434
|
+
setErrorMsg(
|
|
3435
|
+
"Validation failed but no detailed error info was returned."
|
|
3436
|
+
);
|
|
3437
|
+
}
|
|
3438
|
+
} catch (err) {
|
|
3439
|
+
setErrorMsg(
|
|
3440
|
+
`Error: ${err instanceof Error ? err.message : String(err)}`
|
|
3441
|
+
);
|
|
3442
|
+
} finally {
|
|
3443
|
+
setIsLoading(false);
|
|
3444
|
+
setStatusMsg("");
|
|
3445
|
+
}
|
|
3446
|
+
}, [
|
|
3447
|
+
rows,
|
|
3448
|
+
columns,
|
|
3449
|
+
storeId,
|
|
3450
|
+
feedFileType,
|
|
3451
|
+
downloadUrl,
|
|
3452
|
+
userId,
|
|
3453
|
+
mappingObj,
|
|
3454
|
+
sourceMp,
|
|
3455
|
+
marketplaceOv,
|
|
3456
|
+
onSubmit
|
|
3457
|
+
]);
|
|
3458
|
+
return /* @__PURE__ */ jsxs11("div", { className: "flex flex-col gap-3 h-full", children: [
|
|
3459
|
+
/* @__PURE__ */ jsx22("div", { className: "flex items-center justify-between px-1", children: /* @__PURE__ */ jsxs11("div", { className: "flex items-center gap-2", children: [
|
|
3460
|
+
/* @__PURE__ */ jsx22(AlertTriangle2, { className: "h-4 w-4 text-destructive" }),
|
|
3461
|
+
/* @__PURE__ */ jsx22("span", { className: "font-medium text-sm", children: "Feed Validation Issues" }),
|
|
3462
|
+
/* @__PURE__ */ jsxs11(Badge, { variant: "destructive", className: "text-[10px]", children: [
|
|
3463
|
+
errorCount,
|
|
3464
|
+
" error",
|
|
3465
|
+
errorCount !== 1 ? "s" : ""
|
|
3466
|
+
] }),
|
|
3467
|
+
editedCells.size > 0 && /* @__PURE__ */ jsxs11(Badge, { variant: "secondary", className: "text-[10px]", children: [
|
|
3468
|
+
editedCells.size,
|
|
3469
|
+
" edited"
|
|
3470
|
+
] })
|
|
3471
|
+
] }) }),
|
|
3472
|
+
/* @__PURE__ */ jsx22("p", { className: "text-xs text-muted-foreground px-1", children: "Click on the highlighted cells to edit their values, then submit to re-validate." }),
|
|
3473
|
+
statusMsg && /* @__PURE__ */ jsxs11("div", { className: "flex items-center gap-2 px-2 py-1.5 rounded bg-muted text-xs text-muted-foreground", children: [
|
|
3474
|
+
/* @__PURE__ */ jsx22(Loader26, { className: "h-3 w-3 animate-spin" }),
|
|
3475
|
+
statusMsg
|
|
3476
|
+
] }),
|
|
3477
|
+
errorMsg && /* @__PURE__ */ jsxs11("div", { className: "flex items-center gap-2 px-2 py-1.5 rounded bg-destructive/10 text-xs text-destructive", children: [
|
|
3478
|
+
/* @__PURE__ */ jsx22(AlertTriangle2, { className: "h-3 w-3 shrink-0" }),
|
|
3479
|
+
errorMsg
|
|
3480
|
+
] }),
|
|
3481
|
+
/* @__PURE__ */ jsx22("div", { className: "flex-1 overflow-auto border rounded-md", children: /* @__PURE__ */ jsxs11(Table, { children: [
|
|
3482
|
+
/* @__PURE__ */ jsx22(TableHeader, { className: "sticky top-0 bg-muted/80 backdrop-blur-sm z-10", children: /* @__PURE__ */ jsxs11(TableRow, { children: [
|
|
3483
|
+
/* @__PURE__ */ jsx22(TableHead, { className: "w-8 text-center", children: "#" }),
|
|
3484
|
+
columns.map((col) => /* @__PURE__ */ jsx22(TableHead, { children: col }, col))
|
|
3485
|
+
] }) }),
|
|
3486
|
+
/* @__PURE__ */ jsxs11(TableBody, { children: [
|
|
3487
|
+
rows.map((row, rowIdx) => {
|
|
3488
|
+
const sku = row[skuField] ?? "";
|
|
3489
|
+
const rowErrors = errorMap.get(sku);
|
|
3490
|
+
const missingAttrs = dataIssueMap.get(sku);
|
|
3491
|
+
return /* @__PURE__ */ jsxs11(React8.Fragment, { children: [
|
|
3492
|
+
/* @__PURE__ */ jsxs11(TableRow, { className: cn(rowErrors && "bg-destructive/5"), children: [
|
|
3493
|
+
/* @__PURE__ */ jsx22(TableCell, { className: "text-center text-xs text-muted-foreground", children: rowIdx + 1 }),
|
|
3494
|
+
columns.map((col) => {
|
|
3495
|
+
const cellErr = rowErrors?.get(col);
|
|
3496
|
+
return /* @__PURE__ */ jsx22(TableCell, { className: "p-0.5", children: /* @__PURE__ */ jsx22(
|
|
3497
|
+
EditableCell2,
|
|
3498
|
+
{
|
|
3499
|
+
value: row[col] ?? "",
|
|
3500
|
+
hasError: !!cellErr,
|
|
3501
|
+
errorMessage: cellErr,
|
|
3502
|
+
onChange: (val) => handleCellChange(rowIdx, col, val),
|
|
3503
|
+
readOnly: isLoading
|
|
3504
|
+
}
|
|
3505
|
+
) }, col);
|
|
3506
|
+
})
|
|
3507
|
+
] }),
|
|
3508
|
+
missingAttrs && /* @__PURE__ */ jsx22("tr", { children: /* @__PURE__ */ jsx22("td", { colSpan: columns.length + 1, children: /* @__PURE__ */ jsx22(MissingAttributesBanner, { text: missingAttrs }) }) })
|
|
3509
|
+
] }, rowIdx);
|
|
3510
|
+
}),
|
|
3511
|
+
rows.length === 0 && /* @__PURE__ */ jsx22(TableRow, { children: /* @__PURE__ */ jsx22(
|
|
3512
|
+
TableCell,
|
|
3513
|
+
{
|
|
3514
|
+
colSpan: columns.length + 1,
|
|
3515
|
+
className: "text-center text-muted-foreground py-8",
|
|
3516
|
+
children: "No error rows to display."
|
|
3517
|
+
}
|
|
3518
|
+
) })
|
|
3519
|
+
] })
|
|
3520
|
+
] }) }),
|
|
3521
|
+
/* @__PURE__ */ jsxs11("div", { className: "flex items-center justify-end gap-2 pt-1", children: [
|
|
3522
|
+
/* @__PURE__ */ jsxs11(
|
|
3523
|
+
Button,
|
|
3524
|
+
{
|
|
3525
|
+
variant: "outline",
|
|
3526
|
+
size: "sm",
|
|
3527
|
+
className: "gap-1.5",
|
|
3528
|
+
onClick: handleCancel,
|
|
3529
|
+
disabled: isLoading,
|
|
3530
|
+
children: [
|
|
3531
|
+
/* @__PURE__ */ jsx22(X2, { className: "h-3.5 w-3.5" }),
|
|
3532
|
+
"Cancel"
|
|
3533
|
+
]
|
|
3534
|
+
}
|
|
3535
|
+
),
|
|
3536
|
+
/* @__PURE__ */ jsxs11(
|
|
3537
|
+
Button,
|
|
3538
|
+
{
|
|
3539
|
+
onClick: handleFixAndRevalidate,
|
|
3540
|
+
size: "sm",
|
|
3541
|
+
className: "gap-1.5",
|
|
3542
|
+
disabled: isLoading,
|
|
3543
|
+
children: [
|
|
3544
|
+
isLoading ? /* @__PURE__ */ jsx22(Loader26, { className: "h-3.5 w-3.5 animate-spin" }) : /* @__PURE__ */ jsx22(RefreshCw, { className: "h-3.5 w-3.5" }),
|
|
3545
|
+
"Fix & Re-validate"
|
|
3546
|
+
]
|
|
3547
|
+
}
|
|
3548
|
+
)
|
|
3549
|
+
] })
|
|
3550
|
+
] });
|
|
3551
|
+
}
|
|
3552
|
+
|
|
3072
3553
|
// src/Automations/ProductAutomation.tsx
|
|
3073
|
-
import { useState as
|
|
3074
|
-
import { ArrowLeft as ArrowLeft3, Search as Search4, Loader2 as
|
|
3554
|
+
import { useState as useState10, useEffect as useEffect6, useCallback as useCallback8, useRef as useRef5 } from "react";
|
|
3555
|
+
import { ArrowLeft as ArrowLeft3, Search as Search4, Loader2 as Loader28, ChevronDown as ChevronDown4, Play } from "lucide-react";
|
|
3075
3556
|
|
|
3076
3557
|
// src/Automations/api.ts
|
|
3077
3558
|
async function fetchAutomationList(storeId, tag, includeGroupings = false) {
|
|
@@ -3197,9 +3678,9 @@ function parseLovResponse(response, curl, configs) {
|
|
|
3197
3678
|
}
|
|
3198
3679
|
|
|
3199
3680
|
// src/Automations/SchemaFieldRenderer.tsx
|
|
3200
|
-
import { useCallback as
|
|
3201
|
-
import { Check as
|
|
3202
|
-
import { jsx as
|
|
3681
|
+
import { useCallback as useCallback7, useState as useState9 } from "react";
|
|
3682
|
+
import { Check as Check4, ChevronsUpDown as ChevronsUpDown2, Loader2 as Loader27, X as X3 } from "lucide-react";
|
|
3683
|
+
import { jsx as jsx23, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
3203
3684
|
function SchemaFieldRenderer({
|
|
3204
3685
|
schema,
|
|
3205
3686
|
configs,
|
|
@@ -3207,12 +3688,12 @@ function SchemaFieldRenderer({
|
|
|
3207
3688
|
loadingOptions,
|
|
3208
3689
|
onConfigChange
|
|
3209
3690
|
}) {
|
|
3210
|
-
return /* @__PURE__ */
|
|
3691
|
+
return /* @__PURE__ */ jsx23("div", { className: "space-y-4", children: schema.map((item, idx) => {
|
|
3211
3692
|
if (!shouldRenderAttribute(item.render_if, configs)) return null;
|
|
3212
3693
|
if (item.fieldtype === "object_array" && item.mapping_parameters) {
|
|
3213
|
-
return /* @__PURE__ */
|
|
3694
|
+
return /* @__PURE__ */ jsx23("div", { className: "space-y-3", children: item.mapping_parameters.map((sub, subIdx) => {
|
|
3214
3695
|
const value = configs[item.payload_key]?.[0] != null ? configs[item.payload_key][0]?.[sub.payload_key] : void 0;
|
|
3215
|
-
return /* @__PURE__ */
|
|
3696
|
+
return /* @__PURE__ */ jsx23(
|
|
3216
3697
|
FieldSwitch,
|
|
3217
3698
|
{
|
|
3218
3699
|
item: sub,
|
|
@@ -3226,7 +3707,7 @@ function SchemaFieldRenderer({
|
|
|
3226
3707
|
);
|
|
3227
3708
|
}) }, idx);
|
|
3228
3709
|
}
|
|
3229
|
-
return /* @__PURE__ */
|
|
3710
|
+
return /* @__PURE__ */ jsx23(
|
|
3230
3711
|
FieldSwitch,
|
|
3231
3712
|
{
|
|
3232
3713
|
item,
|
|
@@ -3251,7 +3732,7 @@ function FieldSwitch({
|
|
|
3251
3732
|
if (!shouldRenderAttribute(item.render_if, configs)) return null;
|
|
3252
3733
|
switch (item.fieldtype) {
|
|
3253
3734
|
case "freetext":
|
|
3254
|
-
return /* @__PURE__ */
|
|
3735
|
+
return /* @__PURE__ */ jsx23(
|
|
3255
3736
|
FreetextField,
|
|
3256
3737
|
{
|
|
3257
3738
|
item,
|
|
@@ -3260,7 +3741,7 @@ function FieldSwitch({
|
|
|
3260
3741
|
}
|
|
3261
3742
|
);
|
|
3262
3743
|
case "freetext_list":
|
|
3263
|
-
return /* @__PURE__ */
|
|
3744
|
+
return /* @__PURE__ */ jsx23(
|
|
3264
3745
|
FreetextListField,
|
|
3265
3746
|
{
|
|
3266
3747
|
item,
|
|
@@ -3269,7 +3750,7 @@ function FieldSwitch({
|
|
|
3269
3750
|
}
|
|
3270
3751
|
);
|
|
3271
3752
|
case "lov_singleselect":
|
|
3272
|
-
return /* @__PURE__ */
|
|
3753
|
+
return /* @__PURE__ */ jsx23(
|
|
3273
3754
|
SingleSelectField,
|
|
3274
3755
|
{
|
|
3275
3756
|
item,
|
|
@@ -3280,7 +3761,7 @@ function FieldSwitch({
|
|
|
3280
3761
|
}
|
|
3281
3762
|
);
|
|
3282
3763
|
case "lov_multipleselect":
|
|
3283
|
-
return /* @__PURE__ */
|
|
3764
|
+
return /* @__PURE__ */ jsx23(
|
|
3284
3765
|
MultiSelectField,
|
|
3285
3766
|
{
|
|
3286
3767
|
item,
|
|
@@ -3291,7 +3772,7 @@ function FieldSwitch({
|
|
|
3291
3772
|
}
|
|
3292
3773
|
);
|
|
3293
3774
|
case "image_singleselect":
|
|
3294
|
-
return /* @__PURE__ */
|
|
3775
|
+
return /* @__PURE__ */ jsx23(
|
|
3295
3776
|
ImageSelectField,
|
|
3296
3777
|
{
|
|
3297
3778
|
item,
|
|
@@ -3300,7 +3781,7 @@ function FieldSwitch({
|
|
|
3300
3781
|
}
|
|
3301
3782
|
);
|
|
3302
3783
|
case "boolean":
|
|
3303
|
-
return /* @__PURE__ */
|
|
3784
|
+
return /* @__PURE__ */ jsx23(
|
|
3304
3785
|
BooleanField,
|
|
3305
3786
|
{
|
|
3306
3787
|
item,
|
|
@@ -3317,13 +3798,13 @@ function FreetextField({
|
|
|
3317
3798
|
value,
|
|
3318
3799
|
onChange
|
|
3319
3800
|
}) {
|
|
3320
|
-
return /* @__PURE__ */
|
|
3321
|
-
/* @__PURE__ */
|
|
3801
|
+
return /* @__PURE__ */ jsxs12("div", { className: "space-y-1.5", children: [
|
|
3802
|
+
/* @__PURE__ */ jsxs12(Label, { children: [
|
|
3322
3803
|
item.title,
|
|
3323
|
-
item.required && /* @__PURE__ */
|
|
3804
|
+
item.required && /* @__PURE__ */ jsx23("span", { className: "text-destructive", children: " *" })
|
|
3324
3805
|
] }),
|
|
3325
|
-
item.description && /* @__PURE__ */
|
|
3326
|
-
/* @__PURE__ */
|
|
3806
|
+
item.description && /* @__PURE__ */ jsx23("p", { className: "text-xs text-muted-foreground", children: item.description }),
|
|
3807
|
+
/* @__PURE__ */ jsx23(
|
|
3327
3808
|
Input,
|
|
3328
3809
|
{
|
|
3329
3810
|
value: value ?? "",
|
|
@@ -3339,7 +3820,7 @@ function FreetextListField({
|
|
|
3339
3820
|
value,
|
|
3340
3821
|
onChange
|
|
3341
3822
|
}) {
|
|
3342
|
-
const [draft, setDraft] =
|
|
3823
|
+
const [draft, setDraft] = useState9("");
|
|
3343
3824
|
const keywords = value ?? [];
|
|
3344
3825
|
const addKeyword = () => {
|
|
3345
3826
|
const trimmed = draft.trim();
|
|
@@ -3348,14 +3829,14 @@ function FreetextListField({
|
|
|
3348
3829
|
setDraft("");
|
|
3349
3830
|
}
|
|
3350
3831
|
};
|
|
3351
|
-
return /* @__PURE__ */
|
|
3352
|
-
/* @__PURE__ */
|
|
3832
|
+
return /* @__PURE__ */ jsxs12("div", { className: "space-y-1.5", children: [
|
|
3833
|
+
/* @__PURE__ */ jsxs12(Label, { children: [
|
|
3353
3834
|
item.title,
|
|
3354
|
-
item.required && /* @__PURE__ */
|
|
3835
|
+
item.required && /* @__PURE__ */ jsx23("span", { className: "text-destructive", children: " *" })
|
|
3355
3836
|
] }),
|
|
3356
|
-
item.description && /* @__PURE__ */
|
|
3357
|
-
/* @__PURE__ */
|
|
3358
|
-
/* @__PURE__ */
|
|
3837
|
+
item.description && /* @__PURE__ */ jsx23("p", { className: "text-xs text-muted-foreground", children: item.description }),
|
|
3838
|
+
/* @__PURE__ */ jsxs12("div", { className: "flex gap-2", children: [
|
|
3839
|
+
/* @__PURE__ */ jsx23(
|
|
3359
3840
|
Input,
|
|
3360
3841
|
{
|
|
3361
3842
|
value: draft,
|
|
@@ -3364,17 +3845,17 @@ function FreetextListField({
|
|
|
3364
3845
|
placeholder: "Type and press Enter"
|
|
3365
3846
|
}
|
|
3366
3847
|
),
|
|
3367
|
-
/* @__PURE__ */
|
|
3848
|
+
/* @__PURE__ */ jsx23(Button, { variant: "outline", size: "sm", onClick: addKeyword, type: "button", children: "Add" })
|
|
3368
3849
|
] }),
|
|
3369
|
-
keywords.length > 0 && /* @__PURE__ */
|
|
3850
|
+
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: [
|
|
3370
3851
|
kw,
|
|
3371
|
-
/* @__PURE__ */
|
|
3852
|
+
/* @__PURE__ */ jsx23(
|
|
3372
3853
|
"button",
|
|
3373
3854
|
{
|
|
3374
3855
|
type: "button",
|
|
3375
3856
|
onClick: () => onChange(keywords.filter((k) => k !== kw)),
|
|
3376
3857
|
className: "ml-0.5 rounded-full hover:bg-muted",
|
|
3377
|
-
children: /* @__PURE__ */
|
|
3858
|
+
children: /* @__PURE__ */ jsx23(X3, { className: "size-3" })
|
|
3378
3859
|
}
|
|
3379
3860
|
)
|
|
3380
3861
|
] }, kw)) })
|
|
@@ -3389,23 +3870,23 @@ function SingleSelectField({
|
|
|
3389
3870
|
}) {
|
|
3390
3871
|
const strOptions = Array.isArray(lovOptions) ? lovOptions.map(String) : [];
|
|
3391
3872
|
const strValue = value != null ? String(value) : "";
|
|
3392
|
-
return /* @__PURE__ */
|
|
3393
|
-
/* @__PURE__ */
|
|
3873
|
+
return /* @__PURE__ */ jsxs12("div", { className: "space-y-1.5", children: [
|
|
3874
|
+
/* @__PURE__ */ jsxs12(Label, { children: [
|
|
3394
3875
|
item.title,
|
|
3395
|
-
item.required && /* @__PURE__ */
|
|
3876
|
+
item.required && /* @__PURE__ */ jsx23("span", { className: "text-destructive", children: " *" })
|
|
3396
3877
|
] }),
|
|
3397
|
-
item.description && /* @__PURE__ */
|
|
3398
|
-
loading ? /* @__PURE__ */
|
|
3399
|
-
/* @__PURE__ */
|
|
3878
|
+
item.description && /* @__PURE__ */ jsx23("p", { className: "text-xs text-muted-foreground", children: item.description }),
|
|
3879
|
+
loading ? /* @__PURE__ */ jsxs12("div", { className: "flex items-center gap-2 text-sm text-muted-foreground", children: [
|
|
3880
|
+
/* @__PURE__ */ jsx23(Loader27, { className: "size-4 animate-spin" }),
|
|
3400
3881
|
"Loading options..."
|
|
3401
|
-
] }) : /* @__PURE__ */
|
|
3882
|
+
] }) : /* @__PURE__ */ jsxs12(
|
|
3402
3883
|
Select,
|
|
3403
3884
|
{
|
|
3404
3885
|
value: strValue,
|
|
3405
3886
|
onValueChange: (v) => onChange(item.valuetype === "integer" ? Number(v) : v),
|
|
3406
3887
|
children: [
|
|
3407
|
-
/* @__PURE__ */
|
|
3408
|
-
/* @__PURE__ */
|
|
3888
|
+
/* @__PURE__ */ jsx23(SelectTrigger, { children: /* @__PURE__ */ jsx23(SelectValue, { placeholder: "Select..." }) }),
|
|
3889
|
+
/* @__PURE__ */ jsx23(SelectContent, { children: strOptions.map((opt) => /* @__PURE__ */ jsx23(SelectItem, { value: opt, children: opt }, opt)) })
|
|
3409
3890
|
]
|
|
3410
3891
|
}
|
|
3411
3892
|
)
|
|
@@ -3418,10 +3899,10 @@ function MultiSelectField({
|
|
|
3418
3899
|
loading,
|
|
3419
3900
|
onChange
|
|
3420
3901
|
}) {
|
|
3421
|
-
const [open, setOpen] =
|
|
3902
|
+
const [open, setOpen] = useState9(false);
|
|
3422
3903
|
const selected = value ?? [];
|
|
3423
3904
|
const strOptions = Array.isArray(lovOptions) ? lovOptions.map(String) : [];
|
|
3424
|
-
const toggle =
|
|
3905
|
+
const toggle = useCallback7(
|
|
3425
3906
|
(opt) => {
|
|
3426
3907
|
onChange(
|
|
3427
3908
|
selected.includes(opt) ? selected.filter((s) => s !== opt) : [...selected, opt]
|
|
@@ -3429,41 +3910,41 @@ function MultiSelectField({
|
|
|
3429
3910
|
},
|
|
3430
3911
|
[selected, onChange]
|
|
3431
3912
|
);
|
|
3432
|
-
return /* @__PURE__ */
|
|
3433
|
-
/* @__PURE__ */
|
|
3913
|
+
return /* @__PURE__ */ jsxs12("div", { className: "space-y-1.5", children: [
|
|
3914
|
+
/* @__PURE__ */ jsxs12(Label, { children: [
|
|
3434
3915
|
item.title,
|
|
3435
|
-
item.required && /* @__PURE__ */
|
|
3916
|
+
item.required && /* @__PURE__ */ jsx23("span", { className: "text-destructive", children: " *" })
|
|
3436
3917
|
] }),
|
|
3437
|
-
item.description && /* @__PURE__ */
|
|
3438
|
-
loading ? /* @__PURE__ */
|
|
3439
|
-
/* @__PURE__ */
|
|
3918
|
+
item.description && /* @__PURE__ */ jsx23("p", { className: "text-xs text-muted-foreground", children: item.description }),
|
|
3919
|
+
loading ? /* @__PURE__ */ jsxs12("div", { className: "flex items-center gap-2 text-sm text-muted-foreground", children: [
|
|
3920
|
+
/* @__PURE__ */ jsx23(Loader27, { className: "size-4 animate-spin" }),
|
|
3440
3921
|
"Loading options..."
|
|
3441
|
-
] }) : /* @__PURE__ */
|
|
3442
|
-
/* @__PURE__ */
|
|
3922
|
+
] }) : /* @__PURE__ */ jsxs12(Popover, { open, onOpenChange: setOpen, children: [
|
|
3923
|
+
/* @__PURE__ */ jsx23(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs12(
|
|
3443
3924
|
Button,
|
|
3444
3925
|
{
|
|
3445
3926
|
variant: "outline",
|
|
3446
3927
|
className: "w-full justify-between font-normal",
|
|
3447
3928
|
children: [
|
|
3448
|
-
selected.length > 0 ? /* @__PURE__ */
|
|
3449
|
-
/* @__PURE__ */
|
|
3929
|
+
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..." }),
|
|
3930
|
+
/* @__PURE__ */ jsx23(ChevronsUpDown2, { className: "ml-2 size-4 shrink-0 opacity-50" })
|
|
3450
3931
|
]
|
|
3451
3932
|
}
|
|
3452
3933
|
) }),
|
|
3453
|
-
/* @__PURE__ */
|
|
3454
|
-
/* @__PURE__ */
|
|
3455
|
-
/* @__PURE__ */
|
|
3456
|
-
/* @__PURE__ */
|
|
3457
|
-
/* @__PURE__ */
|
|
3934
|
+
/* @__PURE__ */ jsx23(PopoverContent, { className: "w-[260px] p-0", align: "start", children: /* @__PURE__ */ jsxs12(Command, { children: [
|
|
3935
|
+
/* @__PURE__ */ jsx23(CommandInput, { placeholder: "Search..." }),
|
|
3936
|
+
/* @__PURE__ */ jsxs12(CommandList, { children: [
|
|
3937
|
+
/* @__PURE__ */ jsx23(CommandEmpty, { children: "No match." }),
|
|
3938
|
+
/* @__PURE__ */ jsx23(CommandGroup, { children: strOptions.map((opt) => {
|
|
3458
3939
|
const isSelected = selected.includes(opt);
|
|
3459
|
-
return /* @__PURE__ */
|
|
3940
|
+
return /* @__PURE__ */ jsxs12(
|
|
3460
3941
|
CommandItem,
|
|
3461
3942
|
{
|
|
3462
3943
|
value: opt,
|
|
3463
3944
|
onSelect: () => toggle(opt),
|
|
3464
3945
|
children: [
|
|
3465
|
-
/* @__PURE__ */
|
|
3466
|
-
|
|
3946
|
+
/* @__PURE__ */ jsx23(
|
|
3947
|
+
Check4,
|
|
3467
3948
|
{
|
|
3468
3949
|
className: cn(
|
|
3469
3950
|
"mr-2 size-4",
|
|
@@ -3488,12 +3969,12 @@ function ImageSelectField({
|
|
|
3488
3969
|
onChange
|
|
3489
3970
|
}) {
|
|
3490
3971
|
const images = item.lov ?? [];
|
|
3491
|
-
return /* @__PURE__ */
|
|
3492
|
-
/* @__PURE__ */
|
|
3972
|
+
return /* @__PURE__ */ jsxs12("div", { className: "space-y-1.5", children: [
|
|
3973
|
+
/* @__PURE__ */ jsxs12(Label, { children: [
|
|
3493
3974
|
item.title,
|
|
3494
|
-
item.required && /* @__PURE__ */
|
|
3975
|
+
item.required && /* @__PURE__ */ jsx23("span", { className: "text-destructive", children: " *" })
|
|
3495
3976
|
] }),
|
|
3496
|
-
/* @__PURE__ */
|
|
3977
|
+
/* @__PURE__ */ jsx23("div", { className: "flex flex-wrap gap-3", children: images.map((url) => /* @__PURE__ */ jsxs12(
|
|
3497
3978
|
"button",
|
|
3498
3979
|
{
|
|
3499
3980
|
type: "button",
|
|
@@ -3503,8 +3984,8 @@ function ImageSelectField({
|
|
|
3503
3984
|
value === url ? "border-primary ring-2 ring-primary/30" : "border-border hover:border-primary/50"
|
|
3504
3985
|
),
|
|
3505
3986
|
children: [
|
|
3506
|
-
/* @__PURE__ */
|
|
3507
|
-
value === url && /* @__PURE__ */
|
|
3987
|
+
/* @__PURE__ */ jsx23("img", { src: url, alt: "", className: "size-20 object-cover" }),
|
|
3988
|
+
value === url && /* @__PURE__ */ jsx23("div", { className: "absolute right-1 top-1 rounded-full bg-primary p-0.5 text-primary-foreground", children: /* @__PURE__ */ jsx23(Check4, { className: "size-3" }) })
|
|
3508
3989
|
]
|
|
3509
3990
|
},
|
|
3510
3991
|
url
|
|
@@ -3516,23 +3997,23 @@ function BooleanField({
|
|
|
3516
3997
|
value,
|
|
3517
3998
|
onChange
|
|
3518
3999
|
}) {
|
|
3519
|
-
return /* @__PURE__ */
|
|
3520
|
-
/* @__PURE__ */
|
|
4000
|
+
return /* @__PURE__ */ jsxs12("div", { className: "flex items-center gap-2 py-1", children: [
|
|
4001
|
+
/* @__PURE__ */ jsx23(
|
|
3521
4002
|
Checkbox,
|
|
3522
4003
|
{
|
|
3523
4004
|
checked: !!value,
|
|
3524
4005
|
onCheckedChange: (checked) => onChange(!!checked)
|
|
3525
4006
|
}
|
|
3526
4007
|
),
|
|
3527
|
-
/* @__PURE__ */
|
|
4008
|
+
/* @__PURE__ */ jsxs12(Label, { className: "cursor-pointer", onClick: () => onChange(!value), children: [
|
|
3528
4009
|
item.title,
|
|
3529
|
-
item.required && /* @__PURE__ */
|
|
4010
|
+
item.required && /* @__PURE__ */ jsx23("span", { className: "text-destructive", children: " *" })
|
|
3530
4011
|
] })
|
|
3531
4012
|
] });
|
|
3532
4013
|
}
|
|
3533
4014
|
|
|
3534
4015
|
// src/Automations/ProductAutomation.tsx
|
|
3535
|
-
import { Fragment as Fragment5, jsx as
|
|
4016
|
+
import { Fragment as Fragment5, jsx as jsx24, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
3536
4017
|
function ProductAutomation({
|
|
3537
4018
|
storeId,
|
|
3538
4019
|
workspaceId,
|
|
@@ -3548,17 +4029,17 @@ function ProductAutomation({
|
|
|
3548
4029
|
onSubmit,
|
|
3549
4030
|
onAutomationApplied
|
|
3550
4031
|
}) {
|
|
3551
|
-
const [loading, setLoading] =
|
|
3552
|
-
const [automationGroups, setAutomationGroups] =
|
|
3553
|
-
const [expandedGroups, setExpandedGroups] =
|
|
3554
|
-
const [searchQuery, setSearchQuery] =
|
|
3555
|
-
const [selected, setSelected] =
|
|
3556
|
-
const [schema, setSchema] =
|
|
3557
|
-
const [configs, setConfigs] =
|
|
3558
|
-
const [options, setOptions] =
|
|
3559
|
-
const [loadingOptions, setLoadingOptions] =
|
|
3560
|
-
const [schemaLoading, setSchemaLoading] =
|
|
3561
|
-
const [applying, setApplying] =
|
|
4032
|
+
const [loading, setLoading] = useState10(true);
|
|
4033
|
+
const [automationGroups, setAutomationGroups] = useState10({});
|
|
4034
|
+
const [expandedGroups, setExpandedGroups] = useState10([]);
|
|
4035
|
+
const [searchQuery, setSearchQuery] = useState10("");
|
|
4036
|
+
const [selected, setSelected] = useState10(null);
|
|
4037
|
+
const [schema, setSchema] = useState10([]);
|
|
4038
|
+
const [configs, setConfigs] = useState10({});
|
|
4039
|
+
const [options, setOptions] = useState10({});
|
|
4040
|
+
const [loadingOptions, setLoadingOptions] = useState10({});
|
|
4041
|
+
const [schemaLoading, setSchemaLoading] = useState10(false);
|
|
4042
|
+
const [applying, setApplying] = useState10(false);
|
|
3562
4043
|
const configsRef = useRef5(configs);
|
|
3563
4044
|
configsRef.current = configs;
|
|
3564
4045
|
const optionsRef = useRef5(options);
|
|
@@ -3629,7 +4110,7 @@ function ProductAutomation({
|
|
|
3629
4110
|
}
|
|
3630
4111
|
}
|
|
3631
4112
|
}, [schema, configs, channelsWithVersion]);
|
|
3632
|
-
const handleConfigChange =
|
|
4113
|
+
const handleConfigChange = useCallback8(
|
|
3633
4114
|
(key, value, item) => {
|
|
3634
4115
|
setConfigs((prev) => {
|
|
3635
4116
|
const parentItem = schema.find(
|
|
@@ -3655,7 +4136,7 @@ function ProductAutomation({
|
|
|
3655
4136
|
},
|
|
3656
4137
|
[schema]
|
|
3657
4138
|
);
|
|
3658
|
-
const isRunAllowed =
|
|
4139
|
+
const isRunAllowed = useCallback8(() => {
|
|
3659
4140
|
for (const item of schema) {
|
|
3660
4141
|
if (!shouldRenderAttribute(item.render_if, configs)) continue;
|
|
3661
4142
|
if (item.required) {
|
|
@@ -3705,18 +4186,18 @@ function ProductAutomation({
|
|
|
3705
4186
|
const filtered = searchQuery ? unique.filter(
|
|
3706
4187
|
(a) => a.display_name?.toLowerCase().includes(searchQuery.toLowerCase()) || a.automation.toLowerCase().includes(searchQuery.toLowerCase())
|
|
3707
4188
|
) : null;
|
|
3708
|
-
return /* @__PURE__ */
|
|
3709
|
-
/* @__PURE__ */
|
|
3710
|
-
/* @__PURE__ */
|
|
3711
|
-
/* @__PURE__ */
|
|
3712
|
-
/* @__PURE__ */
|
|
4189
|
+
return /* @__PURE__ */ jsxs13("div", { className: "flex h-full flex-col gap-3 p-3", children: [
|
|
4190
|
+
/* @__PURE__ */ jsxs13("div", { className: "flex items-center gap-2", children: [
|
|
4191
|
+
/* @__PURE__ */ jsx24(Button, { variant: "ghost", size: "icon", onClick: onClose, children: /* @__PURE__ */ jsx24(ArrowLeft3, { className: "size-4" }) }),
|
|
4192
|
+
/* @__PURE__ */ jsx24("h3", { className: "text-base font-semibold", children: "Automations" }),
|
|
4193
|
+
/* @__PURE__ */ jsxs13(Badge, { variant: "secondary", children: [
|
|
3713
4194
|
productsCount,
|
|
3714
4195
|
" products"
|
|
3715
4196
|
] })
|
|
3716
4197
|
] }),
|
|
3717
|
-
/* @__PURE__ */
|
|
3718
|
-
/* @__PURE__ */
|
|
3719
|
-
/* @__PURE__ */
|
|
4198
|
+
/* @__PURE__ */ jsxs13("div", { className: "relative", children: [
|
|
4199
|
+
/* @__PURE__ */ jsx24(Search4, { className: "absolute left-2.5 top-1/2 size-4 -translate-y-1/2 text-muted-foreground" }),
|
|
4200
|
+
/* @__PURE__ */ jsx24(
|
|
3720
4201
|
Input,
|
|
3721
4202
|
{
|
|
3722
4203
|
placeholder: "Search automations...",
|
|
@@ -3726,12 +4207,12 @@ function ProductAutomation({
|
|
|
3726
4207
|
}
|
|
3727
4208
|
)
|
|
3728
4209
|
] }),
|
|
3729
|
-
/* @__PURE__ */
|
|
3730
|
-
/* @__PURE__ */
|
|
3731
|
-
/* @__PURE__ */
|
|
3732
|
-
/* @__PURE__ */
|
|
4210
|
+
/* @__PURE__ */ jsxs13("div", { className: "flex items-center gap-4 border-b px-2 pb-2 text-xs font-medium text-muted-foreground", children: [
|
|
4211
|
+
/* @__PURE__ */ jsx24("span", { className: "flex-[5]", children: "Automation" }),
|
|
4212
|
+
/* @__PURE__ */ jsx24("span", { className: "flex-[1.5] text-center", children: "Est. Time" }),
|
|
4213
|
+
/* @__PURE__ */ jsx24("span", { className: "flex-[1.5] text-center", children: "Credits" })
|
|
3733
4214
|
] }),
|
|
3734
|
-
/* @__PURE__ */
|
|
4215
|
+
/* @__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(
|
|
3735
4216
|
AutomationRow,
|
|
3736
4217
|
{
|
|
3737
4218
|
item,
|
|
@@ -3739,8 +4220,8 @@ function ProductAutomation({
|
|
|
3739
4220
|
onClick: () => setSelected(item)
|
|
3740
4221
|
},
|
|
3741
4222
|
item.automation
|
|
3742
|
-
)) : Object.keys(automationGroups).sort().map((group) => /* @__PURE__ */
|
|
3743
|
-
/* @__PURE__ */
|
|
4223
|
+
)) : Object.keys(automationGroups).sort().map((group) => /* @__PURE__ */ jsxs13("div", { children: [
|
|
4224
|
+
/* @__PURE__ */ jsxs13(
|
|
3744
4225
|
"button",
|
|
3745
4226
|
{
|
|
3746
4227
|
type: "button",
|
|
@@ -3750,8 +4231,8 @@ function ProductAutomation({
|
|
|
3750
4231
|
className: "flex w-full items-center justify-between px-2 py-2 text-sm font-semibold text-muted-foreground hover:text-foreground",
|
|
3751
4232
|
children: [
|
|
3752
4233
|
group,
|
|
3753
|
-
/* @__PURE__ */
|
|
3754
|
-
|
|
4234
|
+
/* @__PURE__ */ jsx24(
|
|
4235
|
+
ChevronDown4,
|
|
3755
4236
|
{
|
|
3756
4237
|
className: cn(
|
|
3757
4238
|
"size-4 transition-transform",
|
|
@@ -3762,7 +4243,7 @@ function ProductAutomation({
|
|
|
3762
4243
|
]
|
|
3763
4244
|
}
|
|
3764
4245
|
),
|
|
3765
|
-
expandedGroups.includes(group) && automationGroups[group].map((item) => /* @__PURE__ */
|
|
4246
|
+
expandedGroups.includes(group) && automationGroups[group].map((item) => /* @__PURE__ */ jsx24(
|
|
3766
4247
|
AutomationRow,
|
|
3767
4248
|
{
|
|
3768
4249
|
item,
|
|
@@ -3774,15 +4255,15 @@ function ProductAutomation({
|
|
|
3774
4255
|
] }, group)) })
|
|
3775
4256
|
] });
|
|
3776
4257
|
}
|
|
3777
|
-
return /* @__PURE__ */
|
|
3778
|
-
/* @__PURE__ */
|
|
3779
|
-
/* @__PURE__ */
|
|
3780
|
-
/* @__PURE__ */
|
|
4258
|
+
return /* @__PURE__ */ jsxs13("div", { className: "flex h-full flex-col gap-3 p-3", children: [
|
|
4259
|
+
/* @__PURE__ */ jsxs13("div", { className: "flex items-center gap-2", children: [
|
|
4260
|
+
/* @__PURE__ */ jsx24(Button, { variant: "ghost", size: "icon", onClick: () => setSelected(null), children: /* @__PURE__ */ jsx24(ArrowLeft3, { className: "size-4" }) }),
|
|
4261
|
+
/* @__PURE__ */ jsx24("h3", { className: "text-base font-semibold", children: selected.display_name })
|
|
3781
4262
|
] }),
|
|
3782
|
-
selected.preview && /* @__PURE__ */
|
|
3783
|
-
selected.preview.info_text.map((text, i) => /* @__PURE__ */
|
|
3784
|
-
selected.preview.media.length > 0 && /* @__PURE__ */
|
|
3785
|
-
(m, i) => m.type === "image" ? /* @__PURE__ */
|
|
4263
|
+
selected.preview && /* @__PURE__ */ jsxs13("div", { className: "space-y-2 rounded-lg bg-muted/50 p-3 text-sm", children: [
|
|
4264
|
+
selected.preview.info_text.map((text, i) => /* @__PURE__ */ jsx24("p", { className: "text-muted-foreground", children: text }, i)),
|
|
4265
|
+
selected.preview.media.length > 0 && /* @__PURE__ */ jsx24("div", { className: "flex flex-wrap gap-2 pt-1", children: selected.preview.media.map(
|
|
4266
|
+
(m, i) => m.type === "image" ? /* @__PURE__ */ jsx24(
|
|
3786
4267
|
"img",
|
|
3787
4268
|
{
|
|
3788
4269
|
src: m.src,
|
|
@@ -3793,8 +4274,8 @@ function ProductAutomation({
|
|
|
3793
4274
|
) : null
|
|
3794
4275
|
) })
|
|
3795
4276
|
] }),
|
|
3796
|
-
/* @__PURE__ */
|
|
3797
|
-
/* @__PURE__ */
|
|
4277
|
+
/* @__PURE__ */ jsx24(Separator2, {}),
|
|
4278
|
+
/* @__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(
|
|
3798
4279
|
SchemaFieldRenderer,
|
|
3799
4280
|
{
|
|
3800
4281
|
schema,
|
|
@@ -3804,26 +4285,26 @@ function ProductAutomation({
|
|
|
3804
4285
|
onConfigChange: handleConfigChange
|
|
3805
4286
|
}
|
|
3806
4287
|
) }),
|
|
3807
|
-
/* @__PURE__ */
|
|
3808
|
-
/* @__PURE__ */
|
|
3809
|
-
/* @__PURE__ */
|
|
4288
|
+
/* @__PURE__ */ jsx24(Separator2, {}),
|
|
4289
|
+
/* @__PURE__ */ jsxs13("div", { className: "flex items-center gap-2", children: [
|
|
4290
|
+
/* @__PURE__ */ jsx24(
|
|
3810
4291
|
Button,
|
|
3811
4292
|
{
|
|
3812
4293
|
onClick: handleRun,
|
|
3813
4294
|
disabled: !isRunAllowed() || applying,
|
|
3814
4295
|
className: "flex-1",
|
|
3815
|
-
children: applying ? /* @__PURE__ */
|
|
3816
|
-
/* @__PURE__ */
|
|
4296
|
+
children: applying ? /* @__PURE__ */ jsxs13(Fragment5, { children: [
|
|
4297
|
+
/* @__PURE__ */ jsx24(Loader28, { className: "size-4 animate-spin" }),
|
|
3817
4298
|
"Applying..."
|
|
3818
|
-
] }) : /* @__PURE__ */
|
|
3819
|
-
/* @__PURE__ */
|
|
4299
|
+
] }) : /* @__PURE__ */ jsxs13(Fragment5, { children: [
|
|
4300
|
+
/* @__PURE__ */ jsx24(Play, { className: "size-4" }),
|
|
3820
4301
|
"Run Automation"
|
|
3821
4302
|
] })
|
|
3822
4303
|
}
|
|
3823
4304
|
),
|
|
3824
|
-
/* @__PURE__ */
|
|
4305
|
+
/* @__PURE__ */ jsx24(Button, { variant: "outline", onClick: () => setSelected(null), children: "Cancel" })
|
|
3825
4306
|
] }),
|
|
3826
|
-
/* @__PURE__ */
|
|
4307
|
+
/* @__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." })
|
|
3827
4308
|
] });
|
|
3828
4309
|
}
|
|
3829
4310
|
function AutomationRow({
|
|
@@ -3833,19 +4314,19 @@ function AutomationRow({
|
|
|
3833
4314
|
}) {
|
|
3834
4315
|
const estTime = item.estimate_time_saved ? formatTimeSaved(item.estimate_time_saved * productsCount) : "\u2014";
|
|
3835
4316
|
const credits = item.credits ? Math.ceil(item.credits * productsCount) : 0;
|
|
3836
|
-
return /* @__PURE__ */
|
|
4317
|
+
return /* @__PURE__ */ jsxs13(
|
|
3837
4318
|
"button",
|
|
3838
4319
|
{
|
|
3839
4320
|
type: "button",
|
|
3840
4321
|
onClick,
|
|
3841
4322
|
className: "flex w-full items-center gap-4 rounded-md px-2 py-2.5 text-left hover:bg-accent",
|
|
3842
4323
|
children: [
|
|
3843
|
-
/* @__PURE__ */
|
|
3844
|
-
/* @__PURE__ */
|
|
3845
|
-
item.description && /* @__PURE__ */
|
|
4324
|
+
/* @__PURE__ */ jsxs13("div", { className: "flex-[5] min-w-0", children: [
|
|
4325
|
+
/* @__PURE__ */ jsx24("div", { className: "text-sm font-medium", children: item.display_name }),
|
|
4326
|
+
item.description && /* @__PURE__ */ jsx24("div", { className: "truncate text-xs text-muted-foreground", children: item.description })
|
|
3846
4327
|
] }),
|
|
3847
|
-
/* @__PURE__ */
|
|
3848
|
-
/* @__PURE__ */
|
|
4328
|
+
/* @__PURE__ */ jsx24("div", { className: "flex-[1.5] text-center text-xs text-muted-foreground", children: estTime }),
|
|
4329
|
+
/* @__PURE__ */ jsx24("div", { className: "flex-[1.5] text-center text-xs text-muted-foreground", children: credits })
|
|
3849
4330
|
]
|
|
3850
4331
|
}
|
|
3851
4332
|
);
|
|
@@ -3857,9 +4338,9 @@ function formatTimeSaved(totalSeconds) {
|
|
|
3857
4338
|
}
|
|
3858
4339
|
|
|
3859
4340
|
// src/Automations/StoreAutomation.tsx
|
|
3860
|
-
import { useState as
|
|
4341
|
+
import { useState as useState11, useEffect as useEffect7, useCallback as useCallback9, useRef as useRef6 } from "react";
|
|
3861
4342
|
import { ArrowLeft as ArrowLeft4, Settings } from "lucide-react";
|
|
3862
|
-
import { Fragment as Fragment6, jsx as
|
|
4343
|
+
import { Fragment as Fragment6, jsx as jsx25, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
3863
4344
|
function StoreAutomation({
|
|
3864
4345
|
storeId,
|
|
3865
4346
|
channelsWithVersion,
|
|
@@ -3867,10 +4348,10 @@ function StoreAutomation({
|
|
|
3867
4348
|
onSubmit,
|
|
3868
4349
|
onClose
|
|
3869
4350
|
}) {
|
|
3870
|
-
const [loading, setLoading] =
|
|
3871
|
-
const [automations, setAutomations] =
|
|
3872
|
-
const [selectedConfigs, setSelectedConfigs] =
|
|
3873
|
-
const [selectedAutomation, setSelectedAutomation] =
|
|
4351
|
+
const [loading, setLoading] = useState11(true);
|
|
4352
|
+
const [automations, setAutomations] = useState11([]);
|
|
4353
|
+
const [selectedConfigs, setSelectedConfigs] = useState11({ ...enabledAutomations });
|
|
4354
|
+
const [selectedAutomation, setSelectedAutomation] = useState11(null);
|
|
3874
4355
|
useEffect7(() => {
|
|
3875
4356
|
setLoading(true);
|
|
3876
4357
|
fetchAutomationList(storeId, "default").then((data) => {
|
|
@@ -3883,7 +4364,7 @@ function StoreAutomation({
|
|
|
3883
4364
|
);
|
|
3884
4365
|
}).catch(console.error).finally(() => setLoading(false));
|
|
3885
4366
|
}, [storeId, enabledAutomations]);
|
|
3886
|
-
const toggleAutomation =
|
|
4367
|
+
const toggleAutomation = useCallback9((automationName) => {
|
|
3887
4368
|
setAutomations(
|
|
3888
4369
|
(prev) => prev.map(
|
|
3889
4370
|
(a) => a.automation === automationName ? { ...a, isEnabled: !a.isEnabled } : a
|
|
@@ -3916,7 +4397,7 @@ function StoreAutomation({
|
|
|
3916
4397
|
setSelectedAutomation(null);
|
|
3917
4398
|
};
|
|
3918
4399
|
if (selectedAutomation) {
|
|
3919
|
-
return /* @__PURE__ */
|
|
4400
|
+
return /* @__PURE__ */ jsx25(
|
|
3920
4401
|
AutomationConfigEditor,
|
|
3921
4402
|
{
|
|
3922
4403
|
storeId,
|
|
@@ -3928,46 +4409,46 @@ function StoreAutomation({
|
|
|
3928
4409
|
}
|
|
3929
4410
|
);
|
|
3930
4411
|
}
|
|
3931
|
-
return /* @__PURE__ */
|
|
3932
|
-
/* @__PURE__ */
|
|
3933
|
-
onClose && /* @__PURE__ */
|
|
3934
|
-
/* @__PURE__ */
|
|
4412
|
+
return /* @__PURE__ */ jsxs14("div", { className: "flex h-full flex-col gap-3 p-3", children: [
|
|
4413
|
+
/* @__PURE__ */ jsxs14("div", { className: "flex items-center gap-2", children: [
|
|
4414
|
+
onClose && /* @__PURE__ */ jsx25(Button, { variant: "ghost", size: "icon", onClick: onClose, children: /* @__PURE__ */ jsx25(ArrowLeft4, { className: "size-4" }) }),
|
|
4415
|
+
/* @__PURE__ */ jsx25("h3", { className: "text-base font-semibold", children: "Default Store Automations" })
|
|
3935
4416
|
] }),
|
|
3936
|
-
/* @__PURE__ */
|
|
3937
|
-
loading ? /* @__PURE__ */
|
|
3938
|
-
/* @__PURE__ */
|
|
3939
|
-
/* @__PURE__ */
|
|
3940
|
-
/* @__PURE__ */
|
|
3941
|
-
/* @__PURE__ */
|
|
3942
|
-
/* @__PURE__ */
|
|
3943
|
-
/* @__PURE__ */
|
|
4417
|
+
/* @__PURE__ */ jsx25(Separator2, {}),
|
|
4418
|
+
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: [
|
|
4419
|
+
/* @__PURE__ */ jsx25(TableHeader, { children: /* @__PURE__ */ jsxs14(TableRow, { children: [
|
|
4420
|
+
/* @__PURE__ */ jsx25(TableHead, { children: "Automation" }),
|
|
4421
|
+
/* @__PURE__ */ jsx25(TableHead, { className: "w-24 text-center", children: "Avg. Time" }),
|
|
4422
|
+
/* @__PURE__ */ jsx25(TableHead, { className: "w-28 text-center", children: "Credits/Prd" }),
|
|
4423
|
+
/* @__PURE__ */ jsx25(TableHead, { className: "w-28 text-center", children: "Status" }),
|
|
4424
|
+
/* @__PURE__ */ jsx25(TableHead, { className: "w-12" })
|
|
3944
4425
|
] }) }),
|
|
3945
|
-
/* @__PURE__ */
|
|
4426
|
+
/* @__PURE__ */ jsx25(TableBody, { children: automations.map((a) => /* @__PURE__ */ jsxs14(
|
|
3946
4427
|
TableRow,
|
|
3947
4428
|
{
|
|
3948
4429
|
className: "cursor-pointer",
|
|
3949
4430
|
onClick: () => setSelectedAutomation(a),
|
|
3950
4431
|
children: [
|
|
3951
|
-
/* @__PURE__ */
|
|
3952
|
-
/* @__PURE__ */
|
|
3953
|
-
a.description && /* @__PURE__ */
|
|
4432
|
+
/* @__PURE__ */ jsxs14(TableCell, { children: [
|
|
4433
|
+
/* @__PURE__ */ jsx25("div", { className: "text-sm font-medium", children: a.display_name }),
|
|
4434
|
+
a.description && /* @__PURE__ */ jsx25("div", { className: "text-xs text-muted-foreground", children: a.description })
|
|
3954
4435
|
] }),
|
|
3955
|
-
/* @__PURE__ */
|
|
3956
|
-
/* @__PURE__ */
|
|
3957
|
-
/* @__PURE__ */
|
|
4436
|
+
/* @__PURE__ */ jsx25(TableCell, { className: "text-center text-xs", children: a.estimate_run_time ?? "\u2014" }),
|
|
4437
|
+
/* @__PURE__ */ jsx25(TableCell, { className: "text-center text-xs", children: a.credits ?? "\u2014" }),
|
|
4438
|
+
/* @__PURE__ */ jsx25(TableCell, { className: "text-center", children: /* @__PURE__ */ jsxs14(
|
|
3958
4439
|
"div",
|
|
3959
4440
|
{
|
|
3960
4441
|
className: "flex items-center justify-center gap-2",
|
|
3961
4442
|
onClick: (e) => e.stopPropagation(),
|
|
3962
4443
|
children: [
|
|
3963
|
-
/* @__PURE__ */
|
|
4444
|
+
/* @__PURE__ */ jsx25(
|
|
3964
4445
|
Switch,
|
|
3965
4446
|
{
|
|
3966
4447
|
checked: a.isEnabled,
|
|
3967
4448
|
onCheckedChange: () => toggleAutomation(a.automation)
|
|
3968
4449
|
}
|
|
3969
4450
|
),
|
|
3970
|
-
/* @__PURE__ */
|
|
4451
|
+
/* @__PURE__ */ jsx25(
|
|
3971
4452
|
Badge,
|
|
3972
4453
|
{
|
|
3973
4454
|
variant: a.isEnabled ? "default" : "secondary",
|
|
@@ -3978,16 +4459,16 @@ function StoreAutomation({
|
|
|
3978
4459
|
]
|
|
3979
4460
|
}
|
|
3980
4461
|
) }),
|
|
3981
|
-
/* @__PURE__ */
|
|
4462
|
+
/* @__PURE__ */ jsx25(TableCell, { children: /* @__PURE__ */ jsx25(Settings, { className: "size-4 text-muted-foreground" }) })
|
|
3982
4463
|
]
|
|
3983
4464
|
},
|
|
3984
4465
|
a.automation
|
|
3985
4466
|
)) })
|
|
3986
4467
|
] }) }),
|
|
3987
|
-
/* @__PURE__ */
|
|
3988
|
-
/* @__PURE__ */
|
|
3989
|
-
onClose && /* @__PURE__ */
|
|
3990
|
-
/* @__PURE__ */
|
|
4468
|
+
/* @__PURE__ */ jsx25(Separator2, {}),
|
|
4469
|
+
/* @__PURE__ */ jsxs14("div", { className: "flex justify-end gap-2", children: [
|
|
4470
|
+
onClose && /* @__PURE__ */ jsx25(Button, { variant: "outline", onClick: onClose, children: "Cancel" }),
|
|
4471
|
+
/* @__PURE__ */ jsx25(Button, { onClick: handleSave, children: "Save Changes" })
|
|
3991
4472
|
] })
|
|
3992
4473
|
] });
|
|
3993
4474
|
}
|
|
@@ -3999,13 +4480,13 @@ function AutomationConfigEditor({
|
|
|
3999
4480
|
onClose,
|
|
4000
4481
|
onToggle
|
|
4001
4482
|
}) {
|
|
4002
|
-
const [schemaLoading, setSchemaLoading] =
|
|
4003
|
-
const [schema, setSchema] =
|
|
4004
|
-
const [configs, setConfigs] =
|
|
4483
|
+
const [schemaLoading, setSchemaLoading] = useState11(false);
|
|
4484
|
+
const [schema, setSchema] = useState11([]);
|
|
4485
|
+
const [configs, setConfigs] = useState11(
|
|
4005
4486
|
initialConfigs ?? {}
|
|
4006
4487
|
);
|
|
4007
|
-
const [options, setOptions] =
|
|
4008
|
-
const [loadingOptions, setLoadingOptions] =
|
|
4488
|
+
const [options, setOptions] = useState11({});
|
|
4489
|
+
const [loadingOptions, setLoadingOptions] = useState11({});
|
|
4009
4490
|
const configsRef = useRef6(configs);
|
|
4010
4491
|
configsRef.current = configs;
|
|
4011
4492
|
const optionsRef = useRef6(options);
|
|
@@ -4052,7 +4533,7 @@ function AutomationConfigEditor({
|
|
|
4052
4533
|
}
|
|
4053
4534
|
}
|
|
4054
4535
|
}, [schema, configs, channelsWithVersion]);
|
|
4055
|
-
const handleConfigChange =
|
|
4536
|
+
const handleConfigChange = useCallback9(
|
|
4056
4537
|
(key, value, item) => {
|
|
4057
4538
|
setConfigs((prev) => ({ ...prev, [key]: value }));
|
|
4058
4539
|
if (item.linked?.length) {
|
|
@@ -4068,36 +4549,36 @@ function AutomationConfigEditor({
|
|
|
4068
4549
|
},
|
|
4069
4550
|
[]
|
|
4070
4551
|
);
|
|
4071
|
-
return /* @__PURE__ */
|
|
4072
|
-
/* @__PURE__ */
|
|
4073
|
-
/* @__PURE__ */
|
|
4552
|
+
return /* @__PURE__ */ jsxs14("div", { className: "flex h-full flex-col gap-3 p-3", children: [
|
|
4553
|
+
/* @__PURE__ */ jsxs14("div", { className: "flex items-center gap-2", children: [
|
|
4554
|
+
/* @__PURE__ */ jsx25(
|
|
4074
4555
|
Button,
|
|
4075
4556
|
{
|
|
4076
4557
|
variant: "ghost",
|
|
4077
4558
|
size: "icon",
|
|
4078
4559
|
onClick: () => onClose(automation, configs),
|
|
4079
|
-
children: /* @__PURE__ */
|
|
4560
|
+
children: /* @__PURE__ */ jsx25(ArrowLeft4, { className: "size-4" })
|
|
4080
4561
|
}
|
|
4081
4562
|
),
|
|
4082
|
-
/* @__PURE__ */
|
|
4563
|
+
/* @__PURE__ */ jsx25("h3", { className: "text-base font-semibold", children: automation.display_name })
|
|
4083
4564
|
] }),
|
|
4084
|
-
/* @__PURE__ */
|
|
4085
|
-
/* @__PURE__ */
|
|
4565
|
+
/* @__PURE__ */ jsxs14("div", { className: "flex gap-4 text-sm", children: [
|
|
4566
|
+
/* @__PURE__ */ jsxs14("div", { className: "text-muted-foreground", children: [
|
|
4086
4567
|
"Est. time: ",
|
|
4087
|
-
/* @__PURE__ */
|
|
4568
|
+
/* @__PURE__ */ jsx25("span", { className: "text-foreground", children: automation.estimate_run_time ?? "\u2014" })
|
|
4088
4569
|
] }),
|
|
4089
|
-
/* @__PURE__ */
|
|
4570
|
+
/* @__PURE__ */ jsxs14("div", { className: "text-muted-foreground", children: [
|
|
4090
4571
|
"Credits/prd: ",
|
|
4091
|
-
/* @__PURE__ */
|
|
4572
|
+
/* @__PURE__ */ jsx25("span", { className: "text-foreground", children: automation.credits ?? "\u2014" })
|
|
4092
4573
|
] })
|
|
4093
4574
|
] }),
|
|
4094
|
-
/* @__PURE__ */
|
|
4095
|
-
/* @__PURE__ */
|
|
4096
|
-
/* @__PURE__ */
|
|
4097
|
-
/* @__PURE__ */
|
|
4575
|
+
/* @__PURE__ */ jsx25(Separator2, {}),
|
|
4576
|
+
/* @__PURE__ */ jsxs14("div", { className: "flex items-center gap-2", children: [
|
|
4577
|
+
/* @__PURE__ */ jsx25("span", { className: "text-sm font-medium", children: automation.isEnabled ? "Enabled" : "Disabled" }),
|
|
4578
|
+
/* @__PURE__ */ jsx25(Switch, { checked: automation.isEnabled, onCheckedChange: onToggle })
|
|
4098
4579
|
] }),
|
|
4099
|
-
/* @__PURE__ */
|
|
4100
|
-
/* @__PURE__ */
|
|
4580
|
+
/* @__PURE__ */ jsx25(Separator2, {}),
|
|
4581
|
+
/* @__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(
|
|
4101
4582
|
SchemaFieldRenderer,
|
|
4102
4583
|
{
|
|
4103
4584
|
schema,
|
|
@@ -4106,13 +4587,13 @@ function AutomationConfigEditor({
|
|
|
4106
4587
|
loadingOptions,
|
|
4107
4588
|
onConfigChange: handleConfigChange
|
|
4108
4589
|
}
|
|
4109
|
-
) : /* @__PURE__ */
|
|
4110
|
-
automation.preview && /* @__PURE__ */
|
|
4111
|
-
/* @__PURE__ */
|
|
4112
|
-
/* @__PURE__ */
|
|
4113
|
-
automation.preview.info_text.map((text, i) => /* @__PURE__ */
|
|
4114
|
-
automation.preview.media.length > 0 && /* @__PURE__ */
|
|
4115
|
-
(m, i) => m.type === "image" ? /* @__PURE__ */
|
|
4590
|
+
) : /* @__PURE__ */ jsx25("p", { className: "py-4 text-center text-sm text-muted-foreground", children: "Enable this automation to configure it." }) }),
|
|
4591
|
+
automation.preview && /* @__PURE__ */ jsxs14(Fragment6, { children: [
|
|
4592
|
+
/* @__PURE__ */ jsx25(Separator2, {}),
|
|
4593
|
+
/* @__PURE__ */ jsxs14("div", { className: "space-y-2 rounded-lg bg-muted/50 p-3 text-sm", children: [
|
|
4594
|
+
automation.preview.info_text.map((text, i) => /* @__PURE__ */ jsx25("p", { className: "text-muted-foreground", children: text }, i)),
|
|
4595
|
+
automation.preview.media.length > 0 && /* @__PURE__ */ jsx25("div", { className: "flex flex-wrap gap-2 pt-1", children: automation.preview.media.map(
|
|
4596
|
+
(m, i) => m.type === "image" ? /* @__PURE__ */ jsx25(
|
|
4116
4597
|
"img",
|
|
4117
4598
|
{
|
|
4118
4599
|
src: m.src,
|
|
@@ -4128,7 +4609,7 @@ function AutomationConfigEditor({
|
|
|
4128
4609
|
}
|
|
4129
4610
|
|
|
4130
4611
|
// src/CatalogixChat.tsx
|
|
4131
|
-
import { jsx as
|
|
4612
|
+
import { jsx as jsx26, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
4132
4613
|
var SECTION_MAP = {
|
|
4133
4614
|
"catalogix:create-store": "create_store",
|
|
4134
4615
|
create_or_select_store: "create_store",
|
|
@@ -4137,7 +4618,9 @@ var SECTION_MAP = {
|
|
|
4137
4618
|
"catalogix:automations": "automations",
|
|
4138
4619
|
trigger_automation: "trigger_automation",
|
|
4139
4620
|
"catalogix:map-attributes": "map_attributes",
|
|
4140
|
-
map_attributes: "map_attributes"
|
|
4621
|
+
map_attributes: "map_attributes",
|
|
4622
|
+
"catalogix:edit-feed": "edit_feed",
|
|
4623
|
+
edit_feed: "edit_feed"
|
|
4141
4624
|
};
|
|
4142
4625
|
function CatalogixChat(props) {
|
|
4143
4626
|
const { uiProps, meta, onSubmit, workspaceId, userId } = props;
|
|
@@ -4158,7 +4641,7 @@ function CatalogixChat(props) {
|
|
|
4158
4641
|
configureApi({ catalogixBaseUrl });
|
|
4159
4642
|
}, [catalogixBaseUrl]);
|
|
4160
4643
|
if (section === "select_products") {
|
|
4161
|
-
return /* @__PURE__ */
|
|
4644
|
+
return /* @__PURE__ */ jsx26(
|
|
4162
4645
|
SelectProducts,
|
|
4163
4646
|
{
|
|
4164
4647
|
workspaceId,
|
|
@@ -4174,7 +4657,7 @@ function CatalogixChat(props) {
|
|
|
4174
4657
|
);
|
|
4175
4658
|
}
|
|
4176
4659
|
if (section === "create_store") {
|
|
4177
|
-
return /* @__PURE__ */
|
|
4660
|
+
return /* @__PURE__ */ jsx26(
|
|
4178
4661
|
CreateStore,
|
|
4179
4662
|
{
|
|
4180
4663
|
workspaceId,
|
|
@@ -4188,7 +4671,7 @@ function CatalogixChat(props) {
|
|
|
4188
4671
|
);
|
|
4189
4672
|
}
|
|
4190
4673
|
if (section === "map_attributes") {
|
|
4191
|
-
return /* @__PURE__ */
|
|
4674
|
+
return /* @__PURE__ */ jsx26(
|
|
4192
4675
|
MapAttributesChat,
|
|
4193
4676
|
{
|
|
4194
4677
|
mappingData: uiProps.mappingData ?? [],
|
|
@@ -4205,8 +4688,31 @@ function CatalogixChat(props) {
|
|
|
4205
4688
|
}
|
|
4206
4689
|
);
|
|
4207
4690
|
}
|
|
4691
|
+
if (section === "edit_feed") {
|
|
4692
|
+
return /* @__PURE__ */ jsx26(
|
|
4693
|
+
EditFeed,
|
|
4694
|
+
{
|
|
4695
|
+
criticalIssues: uiProps.criticalIssues ?? [],
|
|
4696
|
+
rawErrorData: uiProps.rawErrorData ?? [],
|
|
4697
|
+
dataIssuesRaw: uiProps.dataIssuesRaw ?? [],
|
|
4698
|
+
columns: uiProps.columns ?? [],
|
|
4699
|
+
skuField: uiProps.skuField ?? "SKU Code",
|
|
4700
|
+
storeId: uiProps.storeId ?? storeId,
|
|
4701
|
+
feedFileType: uiProps.feedFileType ?? "csv",
|
|
4702
|
+
downloadUrl: uiProps.downloadUrl ?? "",
|
|
4703
|
+
userId: uiProps.userId ?? userId,
|
|
4704
|
+
mappingObj: uiProps.mappingObj ?? {},
|
|
4705
|
+
sourceMp: uiProps.sourceMp ?? "SMP",
|
|
4706
|
+
marketplaceOv: uiProps.marketplaceOv ?? 34,
|
|
4707
|
+
transformedUrl: uiProps.transformedUrl ?? "",
|
|
4708
|
+
submitted: props.submitted,
|
|
4709
|
+
submittedValues: props.submittedValues,
|
|
4710
|
+
onSubmit: (values, msg) => onSubmit(values, msg)
|
|
4711
|
+
}
|
|
4712
|
+
);
|
|
4713
|
+
}
|
|
4208
4714
|
if (section === "trigger_automation") {
|
|
4209
|
-
return /* @__PURE__ */
|
|
4715
|
+
return /* @__PURE__ */ jsx26(
|
|
4210
4716
|
ProductAutomation,
|
|
4211
4717
|
{
|
|
4212
4718
|
storeId,
|
|
@@ -4226,7 +4732,7 @@ function CatalogixChat(props) {
|
|
|
4226
4732
|
);
|
|
4227
4733
|
}
|
|
4228
4734
|
if (section === "automations") {
|
|
4229
|
-
return /* @__PURE__ */
|
|
4735
|
+
return /* @__PURE__ */ jsx26(
|
|
4230
4736
|
StoreAutomation,
|
|
4231
4737
|
{
|
|
4232
4738
|
storeId,
|
|
@@ -4237,11 +4743,11 @@ function CatalogixChat(props) {
|
|
|
4237
4743
|
}
|
|
4238
4744
|
);
|
|
4239
4745
|
}
|
|
4240
|
-
return /* @__PURE__ */
|
|
4241
|
-
/* @__PURE__ */
|
|
4746
|
+
return /* @__PURE__ */ jsx26("div", { className: "p-4 text-sm text-muted-foreground", children: /* @__PURE__ */ jsxs15("p", { children: [
|
|
4747
|
+
/* @__PURE__ */ jsx26("strong", { children: "Catalogix" }),
|
|
4242
4748
|
" \u2014 unknown section:",
|
|
4243
4749
|
" ",
|
|
4244
|
-
/* @__PURE__ */
|
|
4750
|
+
/* @__PURE__ */ jsx26("code", { children: section || "(none)" })
|
|
4245
4751
|
] }) });
|
|
4246
4752
|
}
|
|
4247
4753
|
|
|
@@ -4301,11 +4807,26 @@ var catalogixManifest = [
|
|
|
4301
4807
|
position: "relative",
|
|
4302
4808
|
width: "100%"
|
|
4303
4809
|
}
|
|
4810
|
+
},
|
|
4811
|
+
{
|
|
4812
|
+
name: "catalogix:edit-feed",
|
|
4813
|
+
aliases: ["edit_feed"],
|
|
4814
|
+
service: "catalogix",
|
|
4815
|
+
description: "Edit feed cell values to fix validation errors",
|
|
4816
|
+
containerStyle: {
|
|
4817
|
+
overflow: "auto",
|
|
4818
|
+
marginTop: "8px",
|
|
4819
|
+
paddingBottom: "16px",
|
|
4820
|
+
height: "600px",
|
|
4821
|
+
position: "relative",
|
|
4822
|
+
width: "100%"
|
|
4823
|
+
}
|
|
4304
4824
|
}
|
|
4305
4825
|
];
|
|
4306
4826
|
export {
|
|
4307
4827
|
CatalogixChat,
|
|
4308
4828
|
CreateStore,
|
|
4829
|
+
EditFeed,
|
|
4309
4830
|
MapAttributesChat,
|
|
4310
4831
|
ProductAutomation,
|
|
4311
4832
|
SelectProducts,
|