@streamoid/catalogix-chat 0.2.18 → 0.2.20
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 +716 -200
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -3077,9 +3077,485 @@ function MapAttributesChat({
|
|
|
3077
3077
|
] });
|
|
3078
3078
|
}
|
|
3079
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__ */ jsx22("div", { className: "max-w-[50%] py-2 animate-in fade-in duration-300", children: /* @__PURE__ */ jsxs11("div", { className: cn(
|
|
3289
|
+
"rounded-md border p-2.5 flex items-start gap-2",
|
|
3290
|
+
cancelled ? "bg-muted/20 border-border" : "bg-emerald-50/50 border-emerald-200 dark:bg-muted/20 dark:border-border"
|
|
3291
|
+
), children: [
|
|
3292
|
+
/* @__PURE__ */ jsx22("div", { className: cn("mt-px", cancelled ? "text-muted-foreground" : "text-emerald-500"), children: cancelled ? /* @__PURE__ */ jsx22(X2, { className: "w-4 h-4" }) : /* @__PURE__ */ jsx22(Check3, { className: "w-4 h-4" }) }),
|
|
3293
|
+
/* @__PURE__ */ jsxs11("div", { className: "flex-1 min-w-0", children: [
|
|
3294
|
+
/* @__PURE__ */ jsx22("p", { className: "text-xs font-medium leading-tight", children: cancelled ? "Feed correction cancelled" : "Submitted \u2014 Feed Corrections" }),
|
|
3295
|
+
!cancelled && !!submittedValues?.transformedUrl && /* @__PURE__ */ jsx22("p", { className: "mt-1 text-[11px] leading-snug text-muted-foreground", children: "Validation passed. Proceeding with upload." })
|
|
3296
|
+
] })
|
|
3297
|
+
] }) });
|
|
3298
|
+
}
|
|
3299
|
+
function EditFeed({
|
|
3300
|
+
criticalIssues: initialCriticalIssues,
|
|
3301
|
+
rawErrorData: initialRawErrorData,
|
|
3302
|
+
dataIssuesRaw: initialDataIssuesRaw,
|
|
3303
|
+
columns: initialColumns,
|
|
3304
|
+
skuField,
|
|
3305
|
+
storeId,
|
|
3306
|
+
feedFileType,
|
|
3307
|
+
downloadUrl,
|
|
3308
|
+
userId,
|
|
3309
|
+
mappingObj,
|
|
3310
|
+
sourceMp,
|
|
3311
|
+
marketplaceOv,
|
|
3312
|
+
transformedUrl: initialTransformedUrl,
|
|
3313
|
+
submitted,
|
|
3314
|
+
submittedValues,
|
|
3315
|
+
onSubmit
|
|
3316
|
+
}) {
|
|
3317
|
+
if (submitted && submittedValues) {
|
|
3318
|
+
return /* @__PURE__ */ jsx22(SubmittedSummary, { submittedValues });
|
|
3319
|
+
}
|
|
3320
|
+
const [rows, setRows] = useState8(
|
|
3321
|
+
() => initialRawErrorData.map((r) => {
|
|
3322
|
+
const out = {};
|
|
3323
|
+
for (const [k, v] of Object.entries(r)) {
|
|
3324
|
+
if (k !== "row_number") out[k] = String(v ?? "");
|
|
3325
|
+
}
|
|
3326
|
+
return out;
|
|
3327
|
+
})
|
|
3328
|
+
);
|
|
3329
|
+
const [criticalIssues, setCriticalIssues] = useState8(initialCriticalIssues);
|
|
3330
|
+
const [dataIssuesRaw, setDataIssuesRaw] = useState8(initialDataIssuesRaw);
|
|
3331
|
+
const [columns] = useState8(
|
|
3332
|
+
initialColumns.length > 0 ? initialColumns.filter((c) => c !== "row_number") : initialRawErrorData.length > 0 ? Object.keys(initialRawErrorData[0]).filter((c) => c !== "row_number") : []
|
|
3333
|
+
);
|
|
3334
|
+
const [editedCells, setEditedCells] = useState8(/* @__PURE__ */ new Set());
|
|
3335
|
+
const [isLoading, setIsLoading] = useState8(false);
|
|
3336
|
+
const [statusMsg, setStatusMsg] = useState8("");
|
|
3337
|
+
const [errorMsg, setErrorMsg] = useState8("");
|
|
3338
|
+
const [transformedUrl] = useState8(initialTransformedUrl);
|
|
3339
|
+
const errorMap = useMemo6(
|
|
3340
|
+
() => buildErrorMap(criticalIssues, columns),
|
|
3341
|
+
[criticalIssues, columns]
|
|
3342
|
+
);
|
|
3343
|
+
const dataIssueMap = useMemo6(
|
|
3344
|
+
() => buildDataIssueMap(dataIssuesRaw),
|
|
3345
|
+
[dataIssuesRaw]
|
|
3346
|
+
);
|
|
3347
|
+
const errorCount = useMemo6(() => {
|
|
3348
|
+
let count = 0;
|
|
3349
|
+
for (const [, colMap] of errorMap) count += colMap.size;
|
|
3350
|
+
return count;
|
|
3351
|
+
}, [errorMap]);
|
|
3352
|
+
const handleCellChange = useCallback6(
|
|
3353
|
+
(rowIdx, col, val) => {
|
|
3354
|
+
setRows((prev) => {
|
|
3355
|
+
const next = [...prev];
|
|
3356
|
+
next[rowIdx] = { ...next[rowIdx], [col]: val };
|
|
3357
|
+
return next;
|
|
3358
|
+
});
|
|
3359
|
+
setEditedCells((prev) => new Set(prev).add(`${rowIdx}:${col}`));
|
|
3360
|
+
},
|
|
3361
|
+
[]
|
|
3362
|
+
);
|
|
3363
|
+
const handleCancel = useCallback6(() => {
|
|
3364
|
+
onSubmit({ cancelled: true }, "Feed correction cancelled.");
|
|
3365
|
+
}, [onSubmit]);
|
|
3366
|
+
const handleFixAndRevalidate = useCallback6(async () => {
|
|
3367
|
+
setIsLoading(true);
|
|
3368
|
+
setErrorMsg("");
|
|
3369
|
+
try {
|
|
3370
|
+
setStatusMsg("Building corrected CSV...");
|
|
3371
|
+
const csvBlob = rowsToCsvBlob(rows, columns);
|
|
3372
|
+
const fileName = `corrected_${Date.now()}.csv`;
|
|
3373
|
+
setStatusMsg("Uploading corrected feed...");
|
|
3374
|
+
const newFileUrl = await uploadCorrectedCsv(storeId, csvBlob, fileName);
|
|
3375
|
+
setStatusMsg("Re-validating feed...");
|
|
3376
|
+
const result = await validateFeed(
|
|
3377
|
+
storeId,
|
|
3378
|
+
newFileUrl,
|
|
3379
|
+
feedFileType,
|
|
3380
|
+
downloadUrl,
|
|
3381
|
+
userId,
|
|
3382
|
+
mappingObj,
|
|
3383
|
+
sourceMp,
|
|
3384
|
+
marketplaceOv,
|
|
3385
|
+
true
|
|
3386
|
+
);
|
|
3387
|
+
const data = result.data;
|
|
3388
|
+
if (data.validation) {
|
|
3389
|
+
setStatusMsg("Validation passed!");
|
|
3390
|
+
onSubmit(
|
|
3391
|
+
{ transformedUrl: data.transformed_url },
|
|
3392
|
+
"Feed corrections validated successfully."
|
|
3393
|
+
);
|
|
3394
|
+
return;
|
|
3395
|
+
}
|
|
3396
|
+
setStatusMsg("Validation still failing \u2014 fetching new errors...");
|
|
3397
|
+
const issueUrl = data.errors?.issue_files_url;
|
|
3398
|
+
if (issueUrl) {
|
|
3399
|
+
const errResp = await fetchValidationErrors(issueUrl);
|
|
3400
|
+
const newRaw = errResp.data.raw_error_data ?? [];
|
|
3401
|
+
const newRows = newRaw.map((r) => {
|
|
3402
|
+
const out = {};
|
|
3403
|
+
for (const [k, v] of Object.entries(r)) {
|
|
3404
|
+
if (k !== "row_number") out[k] = String(v ?? "");
|
|
3405
|
+
}
|
|
3406
|
+
return out;
|
|
3407
|
+
});
|
|
3408
|
+
setRows(newRows);
|
|
3409
|
+
setEditedCells(/* @__PURE__ */ new Set());
|
|
3410
|
+
const newCritical = (errResp.data.critical_issues ?? []).map(
|
|
3411
|
+
(ci) => {
|
|
3412
|
+
let errMsgRaw = String(ci.error_message ?? "");
|
|
3413
|
+
errMsgRaw = errMsgRaw.replace(/^[{' ]+|[}' ]+$/g, "");
|
|
3414
|
+
return {
|
|
3415
|
+
rowNumber: ci["Row Number"],
|
|
3416
|
+
columnNumber: ci["Column Number"],
|
|
3417
|
+
skuCode: String(ci["SKU Code"] ?? ""),
|
|
3418
|
+
errorMessage: errMsgRaw
|
|
3419
|
+
};
|
|
3420
|
+
}
|
|
3421
|
+
);
|
|
3422
|
+
setCriticalIssues(newCritical);
|
|
3423
|
+
const newDataIssues = (errResp.data.data_issues_raw ?? []).map(
|
|
3424
|
+
(di) => ({
|
|
3425
|
+
rowNumber: String(di["Row Number"] ?? ""),
|
|
3426
|
+
skuCode: String(di["SKU Code"] ?? ""),
|
|
3427
|
+
missingAttributes: String(
|
|
3428
|
+
di["Attribute Required For Listing"] ?? ""
|
|
3429
|
+
)
|
|
3430
|
+
})
|
|
3431
|
+
);
|
|
3432
|
+
setDataIssuesRaw(newDataIssues);
|
|
3433
|
+
setErrorMsg(
|
|
3434
|
+
"Validation still has errors. Please fix the remaining issues and try again."
|
|
3435
|
+
);
|
|
3436
|
+
} else {
|
|
3437
|
+
setErrorMsg(
|
|
3438
|
+
"Validation failed but no detailed error info was returned."
|
|
3439
|
+
);
|
|
3440
|
+
}
|
|
3441
|
+
} catch (err) {
|
|
3442
|
+
setErrorMsg(
|
|
3443
|
+
`Error: ${err instanceof Error ? err.message : String(err)}`
|
|
3444
|
+
);
|
|
3445
|
+
} finally {
|
|
3446
|
+
setIsLoading(false);
|
|
3447
|
+
setStatusMsg("");
|
|
3448
|
+
}
|
|
3449
|
+
}, [
|
|
3450
|
+
rows,
|
|
3451
|
+
columns,
|
|
3452
|
+
storeId,
|
|
3453
|
+
feedFileType,
|
|
3454
|
+
downloadUrl,
|
|
3455
|
+
userId,
|
|
3456
|
+
mappingObj,
|
|
3457
|
+
sourceMp,
|
|
3458
|
+
marketplaceOv,
|
|
3459
|
+
onSubmit
|
|
3460
|
+
]);
|
|
3461
|
+
return /* @__PURE__ */ jsxs11("div", { className: "flex flex-col gap-3", children: [
|
|
3462
|
+
/* @__PURE__ */ jsx22("div", { className: "flex items-center justify-between px-1", children: /* @__PURE__ */ jsxs11("div", { className: "flex items-center gap-2", children: [
|
|
3463
|
+
/* @__PURE__ */ jsx22(AlertTriangle2, { className: "h-4 w-4 text-destructive" }),
|
|
3464
|
+
/* @__PURE__ */ jsx22("span", { className: "font-medium text-sm", children: "Feed Validation Issues" }),
|
|
3465
|
+
/* @__PURE__ */ jsxs11(Badge, { variant: "destructive", className: "text-[10px]", children: [
|
|
3466
|
+
errorCount,
|
|
3467
|
+
" error",
|
|
3468
|
+
errorCount !== 1 ? "s" : ""
|
|
3469
|
+
] }),
|
|
3470
|
+
editedCells.size > 0 && /* @__PURE__ */ jsxs11(Badge, { variant: "secondary", className: "text-[10px]", children: [
|
|
3471
|
+
editedCells.size,
|
|
3472
|
+
" edited"
|
|
3473
|
+
] })
|
|
3474
|
+
] }) }),
|
|
3475
|
+
/* @__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." }),
|
|
3476
|
+
statusMsg && /* @__PURE__ */ jsxs11("div", { className: "flex items-center gap-2 px-2 py-1.5 rounded bg-muted text-xs text-muted-foreground", children: [
|
|
3477
|
+
/* @__PURE__ */ jsx22(Loader26, { className: "h-3 w-3 animate-spin" }),
|
|
3478
|
+
statusMsg
|
|
3479
|
+
] }),
|
|
3480
|
+
errorMsg && /* @__PURE__ */ jsxs11("div", { className: "flex items-center gap-2 px-2 py-1.5 rounded bg-destructive/10 text-xs text-destructive", children: [
|
|
3481
|
+
/* @__PURE__ */ jsx22(AlertTriangle2, { className: "h-3 w-3 shrink-0" }),
|
|
3482
|
+
errorMsg
|
|
3483
|
+
] }),
|
|
3484
|
+
/* @__PURE__ */ jsx22("div", { className: "overflow-auto border rounded-md max-h-[400px]", children: /* @__PURE__ */ jsxs11(Table, { children: [
|
|
3485
|
+
/* @__PURE__ */ jsx22(TableHeader, { className: "sticky top-0 bg-muted/80 backdrop-blur-sm z-10", children: /* @__PURE__ */ jsxs11(TableRow, { children: [
|
|
3486
|
+
/* @__PURE__ */ jsx22(TableHead, { className: "w-8 text-center", children: "#" }),
|
|
3487
|
+
columns.map((col) => /* @__PURE__ */ jsx22(TableHead, { children: col }, col))
|
|
3488
|
+
] }) }),
|
|
3489
|
+
/* @__PURE__ */ jsxs11(TableBody, { children: [
|
|
3490
|
+
rows.map((row, rowIdx) => {
|
|
3491
|
+
const sku = row[skuField] ?? "";
|
|
3492
|
+
const rowErrors = errorMap.get(sku);
|
|
3493
|
+
const missingAttrs = dataIssueMap.get(sku);
|
|
3494
|
+
return /* @__PURE__ */ jsxs11(React8.Fragment, { children: [
|
|
3495
|
+
/* @__PURE__ */ jsxs11(TableRow, { className: cn(rowErrors && "bg-destructive/5"), children: [
|
|
3496
|
+
/* @__PURE__ */ jsx22(TableCell, { className: "text-center text-xs text-muted-foreground", children: rowIdx + 1 }),
|
|
3497
|
+
columns.map((col) => {
|
|
3498
|
+
const cellErr = rowErrors?.get(col);
|
|
3499
|
+
return /* @__PURE__ */ jsx22(TableCell, { className: "p-0.5", children: /* @__PURE__ */ jsx22(
|
|
3500
|
+
EditableCell2,
|
|
3501
|
+
{
|
|
3502
|
+
value: row[col] ?? "",
|
|
3503
|
+
hasError: !!cellErr,
|
|
3504
|
+
errorMessage: cellErr,
|
|
3505
|
+
onChange: (val) => handleCellChange(rowIdx, col, val),
|
|
3506
|
+
readOnly: isLoading
|
|
3507
|
+
}
|
|
3508
|
+
) }, col);
|
|
3509
|
+
})
|
|
3510
|
+
] }),
|
|
3511
|
+
missingAttrs && /* @__PURE__ */ jsx22("tr", { children: /* @__PURE__ */ jsx22("td", { colSpan: columns.length + 1, children: /* @__PURE__ */ jsx22(MissingAttributesBanner, { text: missingAttrs }) }) })
|
|
3512
|
+
] }, rowIdx);
|
|
3513
|
+
}),
|
|
3514
|
+
rows.length === 0 && /* @__PURE__ */ jsx22(TableRow, { children: /* @__PURE__ */ jsx22(
|
|
3515
|
+
TableCell,
|
|
3516
|
+
{
|
|
3517
|
+
colSpan: columns.length + 1,
|
|
3518
|
+
className: "text-center text-muted-foreground py-8",
|
|
3519
|
+
children: "No error rows to display."
|
|
3520
|
+
}
|
|
3521
|
+
) })
|
|
3522
|
+
] })
|
|
3523
|
+
] }) }),
|
|
3524
|
+
/* @__PURE__ */ jsxs11("div", { className: "flex items-center justify-end gap-2 pt-1", children: [
|
|
3525
|
+
/* @__PURE__ */ jsxs11(
|
|
3526
|
+
Button,
|
|
3527
|
+
{
|
|
3528
|
+
variant: "outline",
|
|
3529
|
+
size: "sm",
|
|
3530
|
+
className: "gap-1.5",
|
|
3531
|
+
onClick: handleCancel,
|
|
3532
|
+
disabled: isLoading,
|
|
3533
|
+
children: [
|
|
3534
|
+
/* @__PURE__ */ jsx22(X2, { className: "h-3.5 w-3.5" }),
|
|
3535
|
+
"Cancel"
|
|
3536
|
+
]
|
|
3537
|
+
}
|
|
3538
|
+
),
|
|
3539
|
+
/* @__PURE__ */ jsxs11(
|
|
3540
|
+
Button,
|
|
3541
|
+
{
|
|
3542
|
+
onClick: handleFixAndRevalidate,
|
|
3543
|
+
size: "sm",
|
|
3544
|
+
className: "gap-1.5",
|
|
3545
|
+
disabled: isLoading,
|
|
3546
|
+
children: [
|
|
3547
|
+
isLoading ? /* @__PURE__ */ jsx22(Loader26, { className: "h-3.5 w-3.5 animate-spin" }) : /* @__PURE__ */ jsx22(RefreshCw, { className: "h-3.5 w-3.5" }),
|
|
3548
|
+
"Fix & Re-validate"
|
|
3549
|
+
]
|
|
3550
|
+
}
|
|
3551
|
+
)
|
|
3552
|
+
] })
|
|
3553
|
+
] });
|
|
3554
|
+
}
|
|
3555
|
+
|
|
3080
3556
|
// src/Automations/ProductAutomation.tsx
|
|
3081
|
-
import { useState as
|
|
3082
|
-
import { ArrowLeft as ArrowLeft3, Search as Search4, Loader2 as
|
|
3557
|
+
import { useState as useState10, useEffect as useEffect6, useCallback as useCallback8, useRef as useRef5 } from "react";
|
|
3558
|
+
import { ArrowLeft as ArrowLeft3, Search as Search4, Loader2 as Loader28, ChevronDown as ChevronDown4, Play } from "lucide-react";
|
|
3083
3559
|
|
|
3084
3560
|
// src/Automations/api.ts
|
|
3085
3561
|
async function fetchAutomationList(storeId, tag, includeGroupings = false) {
|
|
@@ -3205,9 +3681,9 @@ function parseLovResponse(response, curl, configs) {
|
|
|
3205
3681
|
}
|
|
3206
3682
|
|
|
3207
3683
|
// src/Automations/SchemaFieldRenderer.tsx
|
|
3208
|
-
import { useCallback as
|
|
3209
|
-
import { Check as
|
|
3210
|
-
import { jsx as
|
|
3684
|
+
import { useCallback as useCallback7, useState as useState9 } from "react";
|
|
3685
|
+
import { Check as Check4, ChevronsUpDown as ChevronsUpDown2, Loader2 as Loader27, X as X3 } from "lucide-react";
|
|
3686
|
+
import { jsx as jsx23, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
3211
3687
|
function SchemaFieldRenderer({
|
|
3212
3688
|
schema,
|
|
3213
3689
|
configs,
|
|
@@ -3215,12 +3691,12 @@ function SchemaFieldRenderer({
|
|
|
3215
3691
|
loadingOptions,
|
|
3216
3692
|
onConfigChange
|
|
3217
3693
|
}) {
|
|
3218
|
-
return /* @__PURE__ */
|
|
3694
|
+
return /* @__PURE__ */ jsx23("div", { className: "space-y-4", children: schema.map((item, idx) => {
|
|
3219
3695
|
if (!shouldRenderAttribute(item.render_if, configs)) return null;
|
|
3220
3696
|
if (item.fieldtype === "object_array" && item.mapping_parameters) {
|
|
3221
|
-
return /* @__PURE__ */
|
|
3697
|
+
return /* @__PURE__ */ jsx23("div", { className: "space-y-3", children: item.mapping_parameters.map((sub, subIdx) => {
|
|
3222
3698
|
const value = configs[item.payload_key]?.[0] != null ? configs[item.payload_key][0]?.[sub.payload_key] : void 0;
|
|
3223
|
-
return /* @__PURE__ */
|
|
3699
|
+
return /* @__PURE__ */ jsx23(
|
|
3224
3700
|
FieldSwitch,
|
|
3225
3701
|
{
|
|
3226
3702
|
item: sub,
|
|
@@ -3234,7 +3710,7 @@ function SchemaFieldRenderer({
|
|
|
3234
3710
|
);
|
|
3235
3711
|
}) }, idx);
|
|
3236
3712
|
}
|
|
3237
|
-
return /* @__PURE__ */
|
|
3713
|
+
return /* @__PURE__ */ jsx23(
|
|
3238
3714
|
FieldSwitch,
|
|
3239
3715
|
{
|
|
3240
3716
|
item,
|
|
@@ -3259,7 +3735,7 @@ function FieldSwitch({
|
|
|
3259
3735
|
if (!shouldRenderAttribute(item.render_if, configs)) return null;
|
|
3260
3736
|
switch (item.fieldtype) {
|
|
3261
3737
|
case "freetext":
|
|
3262
|
-
return /* @__PURE__ */
|
|
3738
|
+
return /* @__PURE__ */ jsx23(
|
|
3263
3739
|
FreetextField,
|
|
3264
3740
|
{
|
|
3265
3741
|
item,
|
|
@@ -3268,7 +3744,7 @@ function FieldSwitch({
|
|
|
3268
3744
|
}
|
|
3269
3745
|
);
|
|
3270
3746
|
case "freetext_list":
|
|
3271
|
-
return /* @__PURE__ */
|
|
3747
|
+
return /* @__PURE__ */ jsx23(
|
|
3272
3748
|
FreetextListField,
|
|
3273
3749
|
{
|
|
3274
3750
|
item,
|
|
@@ -3277,7 +3753,7 @@ function FieldSwitch({
|
|
|
3277
3753
|
}
|
|
3278
3754
|
);
|
|
3279
3755
|
case "lov_singleselect":
|
|
3280
|
-
return /* @__PURE__ */
|
|
3756
|
+
return /* @__PURE__ */ jsx23(
|
|
3281
3757
|
SingleSelectField,
|
|
3282
3758
|
{
|
|
3283
3759
|
item,
|
|
@@ -3288,7 +3764,7 @@ function FieldSwitch({
|
|
|
3288
3764
|
}
|
|
3289
3765
|
);
|
|
3290
3766
|
case "lov_multipleselect":
|
|
3291
|
-
return /* @__PURE__ */
|
|
3767
|
+
return /* @__PURE__ */ jsx23(
|
|
3292
3768
|
MultiSelectField,
|
|
3293
3769
|
{
|
|
3294
3770
|
item,
|
|
@@ -3299,7 +3775,7 @@ function FieldSwitch({
|
|
|
3299
3775
|
}
|
|
3300
3776
|
);
|
|
3301
3777
|
case "image_singleselect":
|
|
3302
|
-
return /* @__PURE__ */
|
|
3778
|
+
return /* @__PURE__ */ jsx23(
|
|
3303
3779
|
ImageSelectField,
|
|
3304
3780
|
{
|
|
3305
3781
|
item,
|
|
@@ -3308,7 +3784,7 @@ function FieldSwitch({
|
|
|
3308
3784
|
}
|
|
3309
3785
|
);
|
|
3310
3786
|
case "boolean":
|
|
3311
|
-
return /* @__PURE__ */
|
|
3787
|
+
return /* @__PURE__ */ jsx23(
|
|
3312
3788
|
BooleanField,
|
|
3313
3789
|
{
|
|
3314
3790
|
item,
|
|
@@ -3325,13 +3801,13 @@ function FreetextField({
|
|
|
3325
3801
|
value,
|
|
3326
3802
|
onChange
|
|
3327
3803
|
}) {
|
|
3328
|
-
return /* @__PURE__ */
|
|
3329
|
-
/* @__PURE__ */
|
|
3804
|
+
return /* @__PURE__ */ jsxs12("div", { className: "space-y-1.5", children: [
|
|
3805
|
+
/* @__PURE__ */ jsxs12(Label, { children: [
|
|
3330
3806
|
item.title,
|
|
3331
|
-
item.required && /* @__PURE__ */
|
|
3807
|
+
item.required && /* @__PURE__ */ jsx23("span", { className: "text-destructive", children: " *" })
|
|
3332
3808
|
] }),
|
|
3333
|
-
item.description && /* @__PURE__ */
|
|
3334
|
-
/* @__PURE__ */
|
|
3809
|
+
item.description && /* @__PURE__ */ jsx23("p", { className: "text-xs text-muted-foreground", children: item.description }),
|
|
3810
|
+
/* @__PURE__ */ jsx23(
|
|
3335
3811
|
Input,
|
|
3336
3812
|
{
|
|
3337
3813
|
value: value ?? "",
|
|
@@ -3347,7 +3823,7 @@ function FreetextListField({
|
|
|
3347
3823
|
value,
|
|
3348
3824
|
onChange
|
|
3349
3825
|
}) {
|
|
3350
|
-
const [draft, setDraft] =
|
|
3826
|
+
const [draft, setDraft] = useState9("");
|
|
3351
3827
|
const keywords = value ?? [];
|
|
3352
3828
|
const addKeyword = () => {
|
|
3353
3829
|
const trimmed = draft.trim();
|
|
@@ -3356,14 +3832,14 @@ function FreetextListField({
|
|
|
3356
3832
|
setDraft("");
|
|
3357
3833
|
}
|
|
3358
3834
|
};
|
|
3359
|
-
return /* @__PURE__ */
|
|
3360
|
-
/* @__PURE__ */
|
|
3835
|
+
return /* @__PURE__ */ jsxs12("div", { className: "space-y-1.5", children: [
|
|
3836
|
+
/* @__PURE__ */ jsxs12(Label, { children: [
|
|
3361
3837
|
item.title,
|
|
3362
|
-
item.required && /* @__PURE__ */
|
|
3838
|
+
item.required && /* @__PURE__ */ jsx23("span", { className: "text-destructive", children: " *" })
|
|
3363
3839
|
] }),
|
|
3364
|
-
item.description && /* @__PURE__ */
|
|
3365
|
-
/* @__PURE__ */
|
|
3366
|
-
/* @__PURE__ */
|
|
3840
|
+
item.description && /* @__PURE__ */ jsx23("p", { className: "text-xs text-muted-foreground", children: item.description }),
|
|
3841
|
+
/* @__PURE__ */ jsxs12("div", { className: "flex gap-2", children: [
|
|
3842
|
+
/* @__PURE__ */ jsx23(
|
|
3367
3843
|
Input,
|
|
3368
3844
|
{
|
|
3369
3845
|
value: draft,
|
|
@@ -3372,17 +3848,17 @@ function FreetextListField({
|
|
|
3372
3848
|
placeholder: "Type and press Enter"
|
|
3373
3849
|
}
|
|
3374
3850
|
),
|
|
3375
|
-
/* @__PURE__ */
|
|
3851
|
+
/* @__PURE__ */ jsx23(Button, { variant: "outline", size: "sm", onClick: addKeyword, type: "button", children: "Add" })
|
|
3376
3852
|
] }),
|
|
3377
|
-
keywords.length > 0 && /* @__PURE__ */
|
|
3853
|
+
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: [
|
|
3378
3854
|
kw,
|
|
3379
|
-
/* @__PURE__ */
|
|
3855
|
+
/* @__PURE__ */ jsx23(
|
|
3380
3856
|
"button",
|
|
3381
3857
|
{
|
|
3382
3858
|
type: "button",
|
|
3383
3859
|
onClick: () => onChange(keywords.filter((k) => k !== kw)),
|
|
3384
3860
|
className: "ml-0.5 rounded-full hover:bg-muted",
|
|
3385
|
-
children: /* @__PURE__ */
|
|
3861
|
+
children: /* @__PURE__ */ jsx23(X3, { className: "size-3" })
|
|
3386
3862
|
}
|
|
3387
3863
|
)
|
|
3388
3864
|
] }, kw)) })
|
|
@@ -3397,23 +3873,23 @@ function SingleSelectField({
|
|
|
3397
3873
|
}) {
|
|
3398
3874
|
const strOptions = Array.isArray(lovOptions) ? lovOptions.map(String) : [];
|
|
3399
3875
|
const strValue = value != null ? String(value) : "";
|
|
3400
|
-
return /* @__PURE__ */
|
|
3401
|
-
/* @__PURE__ */
|
|
3876
|
+
return /* @__PURE__ */ jsxs12("div", { className: "space-y-1.5", children: [
|
|
3877
|
+
/* @__PURE__ */ jsxs12(Label, { children: [
|
|
3402
3878
|
item.title,
|
|
3403
|
-
item.required && /* @__PURE__ */
|
|
3879
|
+
item.required && /* @__PURE__ */ jsx23("span", { className: "text-destructive", children: " *" })
|
|
3404
3880
|
] }),
|
|
3405
|
-
item.description && /* @__PURE__ */
|
|
3406
|
-
loading ? /* @__PURE__ */
|
|
3407
|
-
/* @__PURE__ */
|
|
3881
|
+
item.description && /* @__PURE__ */ jsx23("p", { className: "text-xs text-muted-foreground", children: item.description }),
|
|
3882
|
+
loading ? /* @__PURE__ */ jsxs12("div", { className: "flex items-center gap-2 text-sm text-muted-foreground", children: [
|
|
3883
|
+
/* @__PURE__ */ jsx23(Loader27, { className: "size-4 animate-spin" }),
|
|
3408
3884
|
"Loading options..."
|
|
3409
|
-
] }) : /* @__PURE__ */
|
|
3885
|
+
] }) : /* @__PURE__ */ jsxs12(
|
|
3410
3886
|
Select,
|
|
3411
3887
|
{
|
|
3412
3888
|
value: strValue,
|
|
3413
3889
|
onValueChange: (v) => onChange(item.valuetype === "integer" ? Number(v) : v),
|
|
3414
3890
|
children: [
|
|
3415
|
-
/* @__PURE__ */
|
|
3416
|
-
/* @__PURE__ */
|
|
3891
|
+
/* @__PURE__ */ jsx23(SelectTrigger, { children: /* @__PURE__ */ jsx23(SelectValue, { placeholder: "Select..." }) }),
|
|
3892
|
+
/* @__PURE__ */ jsx23(SelectContent, { children: strOptions.map((opt) => /* @__PURE__ */ jsx23(SelectItem, { value: opt, children: opt }, opt)) })
|
|
3417
3893
|
]
|
|
3418
3894
|
}
|
|
3419
3895
|
)
|
|
@@ -3426,10 +3902,10 @@ function MultiSelectField({
|
|
|
3426
3902
|
loading,
|
|
3427
3903
|
onChange
|
|
3428
3904
|
}) {
|
|
3429
|
-
const [open, setOpen] =
|
|
3905
|
+
const [open, setOpen] = useState9(false);
|
|
3430
3906
|
const selected = value ?? [];
|
|
3431
3907
|
const strOptions = Array.isArray(lovOptions) ? lovOptions.map(String) : [];
|
|
3432
|
-
const toggle =
|
|
3908
|
+
const toggle = useCallback7(
|
|
3433
3909
|
(opt) => {
|
|
3434
3910
|
onChange(
|
|
3435
3911
|
selected.includes(opt) ? selected.filter((s) => s !== opt) : [...selected, opt]
|
|
@@ -3437,41 +3913,41 @@ function MultiSelectField({
|
|
|
3437
3913
|
},
|
|
3438
3914
|
[selected, onChange]
|
|
3439
3915
|
);
|
|
3440
|
-
return /* @__PURE__ */
|
|
3441
|
-
/* @__PURE__ */
|
|
3916
|
+
return /* @__PURE__ */ jsxs12("div", { className: "space-y-1.5", children: [
|
|
3917
|
+
/* @__PURE__ */ jsxs12(Label, { children: [
|
|
3442
3918
|
item.title,
|
|
3443
|
-
item.required && /* @__PURE__ */
|
|
3919
|
+
item.required && /* @__PURE__ */ jsx23("span", { className: "text-destructive", children: " *" })
|
|
3444
3920
|
] }),
|
|
3445
|
-
item.description && /* @__PURE__ */
|
|
3446
|
-
loading ? /* @__PURE__ */
|
|
3447
|
-
/* @__PURE__ */
|
|
3921
|
+
item.description && /* @__PURE__ */ jsx23("p", { className: "text-xs text-muted-foreground", children: item.description }),
|
|
3922
|
+
loading ? /* @__PURE__ */ jsxs12("div", { className: "flex items-center gap-2 text-sm text-muted-foreground", children: [
|
|
3923
|
+
/* @__PURE__ */ jsx23(Loader27, { className: "size-4 animate-spin" }),
|
|
3448
3924
|
"Loading options..."
|
|
3449
|
-
] }) : /* @__PURE__ */
|
|
3450
|
-
/* @__PURE__ */
|
|
3925
|
+
] }) : /* @__PURE__ */ jsxs12(Popover, { open, onOpenChange: setOpen, children: [
|
|
3926
|
+
/* @__PURE__ */ jsx23(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs12(
|
|
3451
3927
|
Button,
|
|
3452
3928
|
{
|
|
3453
3929
|
variant: "outline",
|
|
3454
3930
|
className: "w-full justify-between font-normal",
|
|
3455
3931
|
children: [
|
|
3456
|
-
selected.length > 0 ? /* @__PURE__ */
|
|
3457
|
-
/* @__PURE__ */
|
|
3932
|
+
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..." }),
|
|
3933
|
+
/* @__PURE__ */ jsx23(ChevronsUpDown2, { className: "ml-2 size-4 shrink-0 opacity-50" })
|
|
3458
3934
|
]
|
|
3459
3935
|
}
|
|
3460
3936
|
) }),
|
|
3461
|
-
/* @__PURE__ */
|
|
3462
|
-
/* @__PURE__ */
|
|
3463
|
-
/* @__PURE__ */
|
|
3464
|
-
/* @__PURE__ */
|
|
3465
|
-
/* @__PURE__ */
|
|
3937
|
+
/* @__PURE__ */ jsx23(PopoverContent, { className: "w-[260px] p-0", align: "start", children: /* @__PURE__ */ jsxs12(Command, { children: [
|
|
3938
|
+
/* @__PURE__ */ jsx23(CommandInput, { placeholder: "Search..." }),
|
|
3939
|
+
/* @__PURE__ */ jsxs12(CommandList, { children: [
|
|
3940
|
+
/* @__PURE__ */ jsx23(CommandEmpty, { children: "No match." }),
|
|
3941
|
+
/* @__PURE__ */ jsx23(CommandGroup, { children: strOptions.map((opt) => {
|
|
3466
3942
|
const isSelected = selected.includes(opt);
|
|
3467
|
-
return /* @__PURE__ */
|
|
3943
|
+
return /* @__PURE__ */ jsxs12(
|
|
3468
3944
|
CommandItem,
|
|
3469
3945
|
{
|
|
3470
3946
|
value: opt,
|
|
3471
3947
|
onSelect: () => toggle(opt),
|
|
3472
3948
|
children: [
|
|
3473
|
-
/* @__PURE__ */
|
|
3474
|
-
|
|
3949
|
+
/* @__PURE__ */ jsx23(
|
|
3950
|
+
Check4,
|
|
3475
3951
|
{
|
|
3476
3952
|
className: cn(
|
|
3477
3953
|
"mr-2 size-4",
|
|
@@ -3496,12 +3972,12 @@ function ImageSelectField({
|
|
|
3496
3972
|
onChange
|
|
3497
3973
|
}) {
|
|
3498
3974
|
const images = item.lov ?? [];
|
|
3499
|
-
return /* @__PURE__ */
|
|
3500
|
-
/* @__PURE__ */
|
|
3975
|
+
return /* @__PURE__ */ jsxs12("div", { className: "space-y-1.5", children: [
|
|
3976
|
+
/* @__PURE__ */ jsxs12(Label, { children: [
|
|
3501
3977
|
item.title,
|
|
3502
|
-
item.required && /* @__PURE__ */
|
|
3978
|
+
item.required && /* @__PURE__ */ jsx23("span", { className: "text-destructive", children: " *" })
|
|
3503
3979
|
] }),
|
|
3504
|
-
/* @__PURE__ */
|
|
3980
|
+
/* @__PURE__ */ jsx23("div", { className: "flex flex-wrap gap-3", children: images.map((url) => /* @__PURE__ */ jsxs12(
|
|
3505
3981
|
"button",
|
|
3506
3982
|
{
|
|
3507
3983
|
type: "button",
|
|
@@ -3511,8 +3987,8 @@ function ImageSelectField({
|
|
|
3511
3987
|
value === url ? "border-primary ring-2 ring-primary/30" : "border-border hover:border-primary/50"
|
|
3512
3988
|
),
|
|
3513
3989
|
children: [
|
|
3514
|
-
/* @__PURE__ */
|
|
3515
|
-
value === url && /* @__PURE__ */
|
|
3990
|
+
/* @__PURE__ */ jsx23("img", { src: url, alt: "", className: "size-20 object-cover" }),
|
|
3991
|
+
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" }) })
|
|
3516
3992
|
]
|
|
3517
3993
|
},
|
|
3518
3994
|
url
|
|
@@ -3524,23 +4000,23 @@ function BooleanField({
|
|
|
3524
4000
|
value,
|
|
3525
4001
|
onChange
|
|
3526
4002
|
}) {
|
|
3527
|
-
return /* @__PURE__ */
|
|
3528
|
-
/* @__PURE__ */
|
|
4003
|
+
return /* @__PURE__ */ jsxs12("div", { className: "flex items-center gap-2 py-1", children: [
|
|
4004
|
+
/* @__PURE__ */ jsx23(
|
|
3529
4005
|
Checkbox,
|
|
3530
4006
|
{
|
|
3531
4007
|
checked: !!value,
|
|
3532
4008
|
onCheckedChange: (checked) => onChange(!!checked)
|
|
3533
4009
|
}
|
|
3534
4010
|
),
|
|
3535
|
-
/* @__PURE__ */
|
|
4011
|
+
/* @__PURE__ */ jsxs12(Label, { className: "cursor-pointer", onClick: () => onChange(!value), children: [
|
|
3536
4012
|
item.title,
|
|
3537
|
-
item.required && /* @__PURE__ */
|
|
4013
|
+
item.required && /* @__PURE__ */ jsx23("span", { className: "text-destructive", children: " *" })
|
|
3538
4014
|
] })
|
|
3539
4015
|
] });
|
|
3540
4016
|
}
|
|
3541
4017
|
|
|
3542
4018
|
// src/Automations/ProductAutomation.tsx
|
|
3543
|
-
import { Fragment as Fragment5, jsx as
|
|
4019
|
+
import { Fragment as Fragment5, jsx as jsx24, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
3544
4020
|
function ProductAutomation({
|
|
3545
4021
|
storeId,
|
|
3546
4022
|
workspaceId,
|
|
@@ -3556,17 +4032,17 @@ function ProductAutomation({
|
|
|
3556
4032
|
onSubmit,
|
|
3557
4033
|
onAutomationApplied
|
|
3558
4034
|
}) {
|
|
3559
|
-
const [loading, setLoading] =
|
|
3560
|
-
const [automationGroups, setAutomationGroups] =
|
|
3561
|
-
const [expandedGroups, setExpandedGroups] =
|
|
3562
|
-
const [searchQuery, setSearchQuery] =
|
|
3563
|
-
const [selected, setSelected] =
|
|
3564
|
-
const [schema, setSchema] =
|
|
3565
|
-
const [configs, setConfigs] =
|
|
3566
|
-
const [options, setOptions] =
|
|
3567
|
-
const [loadingOptions, setLoadingOptions] =
|
|
3568
|
-
const [schemaLoading, setSchemaLoading] =
|
|
3569
|
-
const [applying, setApplying] =
|
|
4035
|
+
const [loading, setLoading] = useState10(true);
|
|
4036
|
+
const [automationGroups, setAutomationGroups] = useState10({});
|
|
4037
|
+
const [expandedGroups, setExpandedGroups] = useState10([]);
|
|
4038
|
+
const [searchQuery, setSearchQuery] = useState10("");
|
|
4039
|
+
const [selected, setSelected] = useState10(null);
|
|
4040
|
+
const [schema, setSchema] = useState10([]);
|
|
4041
|
+
const [configs, setConfigs] = useState10({});
|
|
4042
|
+
const [options, setOptions] = useState10({});
|
|
4043
|
+
const [loadingOptions, setLoadingOptions] = useState10({});
|
|
4044
|
+
const [schemaLoading, setSchemaLoading] = useState10(false);
|
|
4045
|
+
const [applying, setApplying] = useState10(false);
|
|
3570
4046
|
const configsRef = useRef5(configs);
|
|
3571
4047
|
configsRef.current = configs;
|
|
3572
4048
|
const optionsRef = useRef5(options);
|
|
@@ -3637,7 +4113,7 @@ function ProductAutomation({
|
|
|
3637
4113
|
}
|
|
3638
4114
|
}
|
|
3639
4115
|
}, [schema, configs, channelsWithVersion]);
|
|
3640
|
-
const handleConfigChange =
|
|
4116
|
+
const handleConfigChange = useCallback8(
|
|
3641
4117
|
(key, value, item) => {
|
|
3642
4118
|
setConfigs((prev) => {
|
|
3643
4119
|
const parentItem = schema.find(
|
|
@@ -3663,7 +4139,7 @@ function ProductAutomation({
|
|
|
3663
4139
|
},
|
|
3664
4140
|
[schema]
|
|
3665
4141
|
);
|
|
3666
|
-
const isRunAllowed =
|
|
4142
|
+
const isRunAllowed = useCallback8(() => {
|
|
3667
4143
|
for (const item of schema) {
|
|
3668
4144
|
if (!shouldRenderAttribute(item.render_if, configs)) continue;
|
|
3669
4145
|
if (item.required) {
|
|
@@ -3713,18 +4189,18 @@ function ProductAutomation({
|
|
|
3713
4189
|
const filtered = searchQuery ? unique.filter(
|
|
3714
4190
|
(a) => a.display_name?.toLowerCase().includes(searchQuery.toLowerCase()) || a.automation.toLowerCase().includes(searchQuery.toLowerCase())
|
|
3715
4191
|
) : null;
|
|
3716
|
-
return /* @__PURE__ */
|
|
3717
|
-
/* @__PURE__ */
|
|
3718
|
-
/* @__PURE__ */
|
|
3719
|
-
/* @__PURE__ */
|
|
3720
|
-
/* @__PURE__ */
|
|
4192
|
+
return /* @__PURE__ */ jsxs13("div", { className: "flex h-full flex-col gap-3 p-3", children: [
|
|
4193
|
+
/* @__PURE__ */ jsxs13("div", { className: "flex items-center gap-2", children: [
|
|
4194
|
+
/* @__PURE__ */ jsx24(Button, { variant: "ghost", size: "icon", onClick: onClose, children: /* @__PURE__ */ jsx24(ArrowLeft3, { className: "size-4" }) }),
|
|
4195
|
+
/* @__PURE__ */ jsx24("h3", { className: "text-base font-semibold", children: "Automations" }),
|
|
4196
|
+
/* @__PURE__ */ jsxs13(Badge, { variant: "secondary", children: [
|
|
3721
4197
|
productsCount,
|
|
3722
4198
|
" products"
|
|
3723
4199
|
] })
|
|
3724
4200
|
] }),
|
|
3725
|
-
/* @__PURE__ */
|
|
3726
|
-
/* @__PURE__ */
|
|
3727
|
-
/* @__PURE__ */
|
|
4201
|
+
/* @__PURE__ */ jsxs13("div", { className: "relative", children: [
|
|
4202
|
+
/* @__PURE__ */ jsx24(Search4, { className: "absolute left-2.5 top-1/2 size-4 -translate-y-1/2 text-muted-foreground" }),
|
|
4203
|
+
/* @__PURE__ */ jsx24(
|
|
3728
4204
|
Input,
|
|
3729
4205
|
{
|
|
3730
4206
|
placeholder: "Search automations...",
|
|
@@ -3734,12 +4210,12 @@ function ProductAutomation({
|
|
|
3734
4210
|
}
|
|
3735
4211
|
)
|
|
3736
4212
|
] }),
|
|
3737
|
-
/* @__PURE__ */
|
|
3738
|
-
/* @__PURE__ */
|
|
3739
|
-
/* @__PURE__ */
|
|
3740
|
-
/* @__PURE__ */
|
|
4213
|
+
/* @__PURE__ */ jsxs13("div", { className: "flex items-center gap-4 border-b px-2 pb-2 text-xs font-medium text-muted-foreground", children: [
|
|
4214
|
+
/* @__PURE__ */ jsx24("span", { className: "flex-[5]", children: "Automation" }),
|
|
4215
|
+
/* @__PURE__ */ jsx24("span", { className: "flex-[1.5] text-center", children: "Est. Time" }),
|
|
4216
|
+
/* @__PURE__ */ jsx24("span", { className: "flex-[1.5] text-center", children: "Credits" })
|
|
3741
4217
|
] }),
|
|
3742
|
-
/* @__PURE__ */
|
|
4218
|
+
/* @__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(
|
|
3743
4219
|
AutomationRow,
|
|
3744
4220
|
{
|
|
3745
4221
|
item,
|
|
@@ -3747,8 +4223,8 @@ function ProductAutomation({
|
|
|
3747
4223
|
onClick: () => setSelected(item)
|
|
3748
4224
|
},
|
|
3749
4225
|
item.automation
|
|
3750
|
-
)) : Object.keys(automationGroups).sort().map((group) => /* @__PURE__ */
|
|
3751
|
-
/* @__PURE__ */
|
|
4226
|
+
)) : Object.keys(automationGroups).sort().map((group) => /* @__PURE__ */ jsxs13("div", { children: [
|
|
4227
|
+
/* @__PURE__ */ jsxs13(
|
|
3752
4228
|
"button",
|
|
3753
4229
|
{
|
|
3754
4230
|
type: "button",
|
|
@@ -3758,8 +4234,8 @@ function ProductAutomation({
|
|
|
3758
4234
|
className: "flex w-full items-center justify-between px-2 py-2 text-sm font-semibold text-muted-foreground hover:text-foreground",
|
|
3759
4235
|
children: [
|
|
3760
4236
|
group,
|
|
3761
|
-
/* @__PURE__ */
|
|
3762
|
-
|
|
4237
|
+
/* @__PURE__ */ jsx24(
|
|
4238
|
+
ChevronDown4,
|
|
3763
4239
|
{
|
|
3764
4240
|
className: cn(
|
|
3765
4241
|
"size-4 transition-transform",
|
|
@@ -3770,7 +4246,7 @@ function ProductAutomation({
|
|
|
3770
4246
|
]
|
|
3771
4247
|
}
|
|
3772
4248
|
),
|
|
3773
|
-
expandedGroups.includes(group) && automationGroups[group].map((item) => /* @__PURE__ */
|
|
4249
|
+
expandedGroups.includes(group) && automationGroups[group].map((item) => /* @__PURE__ */ jsx24(
|
|
3774
4250
|
AutomationRow,
|
|
3775
4251
|
{
|
|
3776
4252
|
item,
|
|
@@ -3782,15 +4258,15 @@ function ProductAutomation({
|
|
|
3782
4258
|
] }, group)) })
|
|
3783
4259
|
] });
|
|
3784
4260
|
}
|
|
3785
|
-
return /* @__PURE__ */
|
|
3786
|
-
/* @__PURE__ */
|
|
3787
|
-
/* @__PURE__ */
|
|
3788
|
-
/* @__PURE__ */
|
|
4261
|
+
return /* @__PURE__ */ jsxs13("div", { className: "flex h-full flex-col gap-3 p-3", children: [
|
|
4262
|
+
/* @__PURE__ */ jsxs13("div", { className: "flex items-center gap-2", children: [
|
|
4263
|
+
/* @__PURE__ */ jsx24(Button, { variant: "ghost", size: "icon", onClick: () => setSelected(null), children: /* @__PURE__ */ jsx24(ArrowLeft3, { className: "size-4" }) }),
|
|
4264
|
+
/* @__PURE__ */ jsx24("h3", { className: "text-base font-semibold", children: selected.display_name })
|
|
3789
4265
|
] }),
|
|
3790
|
-
selected.preview && /* @__PURE__ */
|
|
3791
|
-
selected.preview.info_text.map((text, i) => /* @__PURE__ */
|
|
3792
|
-
selected.preview.media.length > 0 && /* @__PURE__ */
|
|
3793
|
-
(m, i) => m.type === "image" ? /* @__PURE__ */
|
|
4266
|
+
selected.preview && /* @__PURE__ */ jsxs13("div", { className: "space-y-2 rounded-lg bg-muted/50 p-3 text-sm", children: [
|
|
4267
|
+
selected.preview.info_text.map((text, i) => /* @__PURE__ */ jsx24("p", { className: "text-muted-foreground", children: text }, i)),
|
|
4268
|
+
selected.preview.media.length > 0 && /* @__PURE__ */ jsx24("div", { className: "flex flex-wrap gap-2 pt-1", children: selected.preview.media.map(
|
|
4269
|
+
(m, i) => m.type === "image" ? /* @__PURE__ */ jsx24(
|
|
3794
4270
|
"img",
|
|
3795
4271
|
{
|
|
3796
4272
|
src: m.src,
|
|
@@ -3801,8 +4277,8 @@ function ProductAutomation({
|
|
|
3801
4277
|
) : null
|
|
3802
4278
|
) })
|
|
3803
4279
|
] }),
|
|
3804
|
-
/* @__PURE__ */
|
|
3805
|
-
/* @__PURE__ */
|
|
4280
|
+
/* @__PURE__ */ jsx24(Separator2, {}),
|
|
4281
|
+
/* @__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(
|
|
3806
4282
|
SchemaFieldRenderer,
|
|
3807
4283
|
{
|
|
3808
4284
|
schema,
|
|
@@ -3812,26 +4288,26 @@ function ProductAutomation({
|
|
|
3812
4288
|
onConfigChange: handleConfigChange
|
|
3813
4289
|
}
|
|
3814
4290
|
) }),
|
|
3815
|
-
/* @__PURE__ */
|
|
3816
|
-
/* @__PURE__ */
|
|
3817
|
-
/* @__PURE__ */
|
|
4291
|
+
/* @__PURE__ */ jsx24(Separator2, {}),
|
|
4292
|
+
/* @__PURE__ */ jsxs13("div", { className: "flex items-center gap-2", children: [
|
|
4293
|
+
/* @__PURE__ */ jsx24(
|
|
3818
4294
|
Button,
|
|
3819
4295
|
{
|
|
3820
4296
|
onClick: handleRun,
|
|
3821
4297
|
disabled: !isRunAllowed() || applying,
|
|
3822
4298
|
className: "flex-1",
|
|
3823
|
-
children: applying ? /* @__PURE__ */
|
|
3824
|
-
/* @__PURE__ */
|
|
4299
|
+
children: applying ? /* @__PURE__ */ jsxs13(Fragment5, { children: [
|
|
4300
|
+
/* @__PURE__ */ jsx24(Loader28, { className: "size-4 animate-spin" }),
|
|
3825
4301
|
"Applying..."
|
|
3826
|
-
] }) : /* @__PURE__ */
|
|
3827
|
-
/* @__PURE__ */
|
|
4302
|
+
] }) : /* @__PURE__ */ jsxs13(Fragment5, { children: [
|
|
4303
|
+
/* @__PURE__ */ jsx24(Play, { className: "size-4" }),
|
|
3828
4304
|
"Run Automation"
|
|
3829
4305
|
] })
|
|
3830
4306
|
}
|
|
3831
4307
|
),
|
|
3832
|
-
/* @__PURE__ */
|
|
4308
|
+
/* @__PURE__ */ jsx24(Button, { variant: "outline", onClick: () => setSelected(null), children: "Cancel" })
|
|
3833
4309
|
] }),
|
|
3834
|
-
/* @__PURE__ */
|
|
4310
|
+
/* @__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." })
|
|
3835
4311
|
] });
|
|
3836
4312
|
}
|
|
3837
4313
|
function AutomationRow({
|
|
@@ -3841,19 +4317,19 @@ function AutomationRow({
|
|
|
3841
4317
|
}) {
|
|
3842
4318
|
const estTime = item.estimate_time_saved ? formatTimeSaved(item.estimate_time_saved * productsCount) : "\u2014";
|
|
3843
4319
|
const credits = item.credits ? Math.ceil(item.credits * productsCount) : 0;
|
|
3844
|
-
return /* @__PURE__ */
|
|
4320
|
+
return /* @__PURE__ */ jsxs13(
|
|
3845
4321
|
"button",
|
|
3846
4322
|
{
|
|
3847
4323
|
type: "button",
|
|
3848
4324
|
onClick,
|
|
3849
4325
|
className: "flex w-full items-center gap-4 rounded-md px-2 py-2.5 text-left hover:bg-accent",
|
|
3850
4326
|
children: [
|
|
3851
|
-
/* @__PURE__ */
|
|
3852
|
-
/* @__PURE__ */
|
|
3853
|
-
item.description && /* @__PURE__ */
|
|
4327
|
+
/* @__PURE__ */ jsxs13("div", { className: "flex-[5] min-w-0", children: [
|
|
4328
|
+
/* @__PURE__ */ jsx24("div", { className: "text-sm font-medium", children: item.display_name }),
|
|
4329
|
+
item.description && /* @__PURE__ */ jsx24("div", { className: "truncate text-xs text-muted-foreground", children: item.description })
|
|
3854
4330
|
] }),
|
|
3855
|
-
/* @__PURE__ */
|
|
3856
|
-
/* @__PURE__ */
|
|
4331
|
+
/* @__PURE__ */ jsx24("div", { className: "flex-[1.5] text-center text-xs text-muted-foreground", children: estTime }),
|
|
4332
|
+
/* @__PURE__ */ jsx24("div", { className: "flex-[1.5] text-center text-xs text-muted-foreground", children: credits })
|
|
3857
4333
|
]
|
|
3858
4334
|
}
|
|
3859
4335
|
);
|
|
@@ -3865,9 +4341,9 @@ function formatTimeSaved(totalSeconds) {
|
|
|
3865
4341
|
}
|
|
3866
4342
|
|
|
3867
4343
|
// src/Automations/StoreAutomation.tsx
|
|
3868
|
-
import { useState as
|
|
4344
|
+
import { useState as useState11, useEffect as useEffect7, useCallback as useCallback9, useRef as useRef6 } from "react";
|
|
3869
4345
|
import { ArrowLeft as ArrowLeft4, Settings } from "lucide-react";
|
|
3870
|
-
import { Fragment as Fragment6, jsx as
|
|
4346
|
+
import { Fragment as Fragment6, jsx as jsx25, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
3871
4347
|
function StoreAutomation({
|
|
3872
4348
|
storeId,
|
|
3873
4349
|
channelsWithVersion,
|
|
@@ -3875,10 +4351,10 @@ function StoreAutomation({
|
|
|
3875
4351
|
onSubmit,
|
|
3876
4352
|
onClose
|
|
3877
4353
|
}) {
|
|
3878
|
-
const [loading, setLoading] =
|
|
3879
|
-
const [automations, setAutomations] =
|
|
3880
|
-
const [selectedConfigs, setSelectedConfigs] =
|
|
3881
|
-
const [selectedAutomation, setSelectedAutomation] =
|
|
4354
|
+
const [loading, setLoading] = useState11(true);
|
|
4355
|
+
const [automations, setAutomations] = useState11([]);
|
|
4356
|
+
const [selectedConfigs, setSelectedConfigs] = useState11({ ...enabledAutomations });
|
|
4357
|
+
const [selectedAutomation, setSelectedAutomation] = useState11(null);
|
|
3882
4358
|
useEffect7(() => {
|
|
3883
4359
|
setLoading(true);
|
|
3884
4360
|
fetchAutomationList(storeId, "default").then((data) => {
|
|
@@ -3891,7 +4367,7 @@ function StoreAutomation({
|
|
|
3891
4367
|
);
|
|
3892
4368
|
}).catch(console.error).finally(() => setLoading(false));
|
|
3893
4369
|
}, [storeId, enabledAutomations]);
|
|
3894
|
-
const toggleAutomation =
|
|
4370
|
+
const toggleAutomation = useCallback9((automationName) => {
|
|
3895
4371
|
setAutomations(
|
|
3896
4372
|
(prev) => prev.map(
|
|
3897
4373
|
(a) => a.automation === automationName ? { ...a, isEnabled: !a.isEnabled } : a
|
|
@@ -3924,7 +4400,7 @@ function StoreAutomation({
|
|
|
3924
4400
|
setSelectedAutomation(null);
|
|
3925
4401
|
};
|
|
3926
4402
|
if (selectedAutomation) {
|
|
3927
|
-
return /* @__PURE__ */
|
|
4403
|
+
return /* @__PURE__ */ jsx25(
|
|
3928
4404
|
AutomationConfigEditor,
|
|
3929
4405
|
{
|
|
3930
4406
|
storeId,
|
|
@@ -3936,46 +4412,46 @@ function StoreAutomation({
|
|
|
3936
4412
|
}
|
|
3937
4413
|
);
|
|
3938
4414
|
}
|
|
3939
|
-
return /* @__PURE__ */
|
|
3940
|
-
/* @__PURE__ */
|
|
3941
|
-
onClose && /* @__PURE__ */
|
|
3942
|
-
/* @__PURE__ */
|
|
4415
|
+
return /* @__PURE__ */ jsxs14("div", { className: "flex h-full flex-col gap-3 p-3", children: [
|
|
4416
|
+
/* @__PURE__ */ jsxs14("div", { className: "flex items-center gap-2", children: [
|
|
4417
|
+
onClose && /* @__PURE__ */ jsx25(Button, { variant: "ghost", size: "icon", onClick: onClose, children: /* @__PURE__ */ jsx25(ArrowLeft4, { className: "size-4" }) }),
|
|
4418
|
+
/* @__PURE__ */ jsx25("h3", { className: "text-base font-semibold", children: "Default Store Automations" })
|
|
3943
4419
|
] }),
|
|
3944
|
-
/* @__PURE__ */
|
|
3945
|
-
loading ? /* @__PURE__ */
|
|
3946
|
-
/* @__PURE__ */
|
|
3947
|
-
/* @__PURE__ */
|
|
3948
|
-
/* @__PURE__ */
|
|
3949
|
-
/* @__PURE__ */
|
|
3950
|
-
/* @__PURE__ */
|
|
3951
|
-
/* @__PURE__ */
|
|
4420
|
+
/* @__PURE__ */ jsx25(Separator2, {}),
|
|
4421
|
+
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: [
|
|
4422
|
+
/* @__PURE__ */ jsx25(TableHeader, { children: /* @__PURE__ */ jsxs14(TableRow, { children: [
|
|
4423
|
+
/* @__PURE__ */ jsx25(TableHead, { children: "Automation" }),
|
|
4424
|
+
/* @__PURE__ */ jsx25(TableHead, { className: "w-24 text-center", children: "Avg. Time" }),
|
|
4425
|
+
/* @__PURE__ */ jsx25(TableHead, { className: "w-28 text-center", children: "Credits/Prd" }),
|
|
4426
|
+
/* @__PURE__ */ jsx25(TableHead, { className: "w-28 text-center", children: "Status" }),
|
|
4427
|
+
/* @__PURE__ */ jsx25(TableHead, { className: "w-12" })
|
|
3952
4428
|
] }) }),
|
|
3953
|
-
/* @__PURE__ */
|
|
4429
|
+
/* @__PURE__ */ jsx25(TableBody, { children: automations.map((a) => /* @__PURE__ */ jsxs14(
|
|
3954
4430
|
TableRow,
|
|
3955
4431
|
{
|
|
3956
4432
|
className: "cursor-pointer",
|
|
3957
4433
|
onClick: () => setSelectedAutomation(a),
|
|
3958
4434
|
children: [
|
|
3959
|
-
/* @__PURE__ */
|
|
3960
|
-
/* @__PURE__ */
|
|
3961
|
-
a.description && /* @__PURE__ */
|
|
4435
|
+
/* @__PURE__ */ jsxs14(TableCell, { children: [
|
|
4436
|
+
/* @__PURE__ */ jsx25("div", { className: "text-sm font-medium", children: a.display_name }),
|
|
4437
|
+
a.description && /* @__PURE__ */ jsx25("div", { className: "text-xs text-muted-foreground", children: a.description })
|
|
3962
4438
|
] }),
|
|
3963
|
-
/* @__PURE__ */
|
|
3964
|
-
/* @__PURE__ */
|
|
3965
|
-
/* @__PURE__ */
|
|
4439
|
+
/* @__PURE__ */ jsx25(TableCell, { className: "text-center text-xs", children: a.estimate_run_time ?? "\u2014" }),
|
|
4440
|
+
/* @__PURE__ */ jsx25(TableCell, { className: "text-center text-xs", children: a.credits ?? "\u2014" }),
|
|
4441
|
+
/* @__PURE__ */ jsx25(TableCell, { className: "text-center", children: /* @__PURE__ */ jsxs14(
|
|
3966
4442
|
"div",
|
|
3967
4443
|
{
|
|
3968
4444
|
className: "flex items-center justify-center gap-2",
|
|
3969
4445
|
onClick: (e) => e.stopPropagation(),
|
|
3970
4446
|
children: [
|
|
3971
|
-
/* @__PURE__ */
|
|
4447
|
+
/* @__PURE__ */ jsx25(
|
|
3972
4448
|
Switch,
|
|
3973
4449
|
{
|
|
3974
4450
|
checked: a.isEnabled,
|
|
3975
4451
|
onCheckedChange: () => toggleAutomation(a.automation)
|
|
3976
4452
|
}
|
|
3977
4453
|
),
|
|
3978
|
-
/* @__PURE__ */
|
|
4454
|
+
/* @__PURE__ */ jsx25(
|
|
3979
4455
|
Badge,
|
|
3980
4456
|
{
|
|
3981
4457
|
variant: a.isEnabled ? "default" : "secondary",
|
|
@@ -3986,16 +4462,16 @@ function StoreAutomation({
|
|
|
3986
4462
|
]
|
|
3987
4463
|
}
|
|
3988
4464
|
) }),
|
|
3989
|
-
/* @__PURE__ */
|
|
4465
|
+
/* @__PURE__ */ jsx25(TableCell, { children: /* @__PURE__ */ jsx25(Settings, { className: "size-4 text-muted-foreground" }) })
|
|
3990
4466
|
]
|
|
3991
4467
|
},
|
|
3992
4468
|
a.automation
|
|
3993
4469
|
)) })
|
|
3994
4470
|
] }) }),
|
|
3995
|
-
/* @__PURE__ */
|
|
3996
|
-
/* @__PURE__ */
|
|
3997
|
-
onClose && /* @__PURE__ */
|
|
3998
|
-
/* @__PURE__ */
|
|
4471
|
+
/* @__PURE__ */ jsx25(Separator2, {}),
|
|
4472
|
+
/* @__PURE__ */ jsxs14("div", { className: "flex justify-end gap-2", children: [
|
|
4473
|
+
onClose && /* @__PURE__ */ jsx25(Button, { variant: "outline", onClick: onClose, children: "Cancel" }),
|
|
4474
|
+
/* @__PURE__ */ jsx25(Button, { onClick: handleSave, children: "Save Changes" })
|
|
3999
4475
|
] })
|
|
4000
4476
|
] });
|
|
4001
4477
|
}
|
|
@@ -4007,13 +4483,13 @@ function AutomationConfigEditor({
|
|
|
4007
4483
|
onClose,
|
|
4008
4484
|
onToggle
|
|
4009
4485
|
}) {
|
|
4010
|
-
const [schemaLoading, setSchemaLoading] =
|
|
4011
|
-
const [schema, setSchema] =
|
|
4012
|
-
const [configs, setConfigs] =
|
|
4486
|
+
const [schemaLoading, setSchemaLoading] = useState11(false);
|
|
4487
|
+
const [schema, setSchema] = useState11([]);
|
|
4488
|
+
const [configs, setConfigs] = useState11(
|
|
4013
4489
|
initialConfigs ?? {}
|
|
4014
4490
|
);
|
|
4015
|
-
const [options, setOptions] =
|
|
4016
|
-
const [loadingOptions, setLoadingOptions] =
|
|
4491
|
+
const [options, setOptions] = useState11({});
|
|
4492
|
+
const [loadingOptions, setLoadingOptions] = useState11({});
|
|
4017
4493
|
const configsRef = useRef6(configs);
|
|
4018
4494
|
configsRef.current = configs;
|
|
4019
4495
|
const optionsRef = useRef6(options);
|
|
@@ -4060,7 +4536,7 @@ function AutomationConfigEditor({
|
|
|
4060
4536
|
}
|
|
4061
4537
|
}
|
|
4062
4538
|
}, [schema, configs, channelsWithVersion]);
|
|
4063
|
-
const handleConfigChange =
|
|
4539
|
+
const handleConfigChange = useCallback9(
|
|
4064
4540
|
(key, value, item) => {
|
|
4065
4541
|
setConfigs((prev) => ({ ...prev, [key]: value }));
|
|
4066
4542
|
if (item.linked?.length) {
|
|
@@ -4076,36 +4552,36 @@ function AutomationConfigEditor({
|
|
|
4076
4552
|
},
|
|
4077
4553
|
[]
|
|
4078
4554
|
);
|
|
4079
|
-
return /* @__PURE__ */
|
|
4080
|
-
/* @__PURE__ */
|
|
4081
|
-
/* @__PURE__ */
|
|
4555
|
+
return /* @__PURE__ */ jsxs14("div", { className: "flex h-full flex-col gap-3 p-3", children: [
|
|
4556
|
+
/* @__PURE__ */ jsxs14("div", { className: "flex items-center gap-2", children: [
|
|
4557
|
+
/* @__PURE__ */ jsx25(
|
|
4082
4558
|
Button,
|
|
4083
4559
|
{
|
|
4084
4560
|
variant: "ghost",
|
|
4085
4561
|
size: "icon",
|
|
4086
4562
|
onClick: () => onClose(automation, configs),
|
|
4087
|
-
children: /* @__PURE__ */
|
|
4563
|
+
children: /* @__PURE__ */ jsx25(ArrowLeft4, { className: "size-4" })
|
|
4088
4564
|
}
|
|
4089
4565
|
),
|
|
4090
|
-
/* @__PURE__ */
|
|
4566
|
+
/* @__PURE__ */ jsx25("h3", { className: "text-base font-semibold", children: automation.display_name })
|
|
4091
4567
|
] }),
|
|
4092
|
-
/* @__PURE__ */
|
|
4093
|
-
/* @__PURE__ */
|
|
4568
|
+
/* @__PURE__ */ jsxs14("div", { className: "flex gap-4 text-sm", children: [
|
|
4569
|
+
/* @__PURE__ */ jsxs14("div", { className: "text-muted-foreground", children: [
|
|
4094
4570
|
"Est. time: ",
|
|
4095
|
-
/* @__PURE__ */
|
|
4571
|
+
/* @__PURE__ */ jsx25("span", { className: "text-foreground", children: automation.estimate_run_time ?? "\u2014" })
|
|
4096
4572
|
] }),
|
|
4097
|
-
/* @__PURE__ */
|
|
4573
|
+
/* @__PURE__ */ jsxs14("div", { className: "text-muted-foreground", children: [
|
|
4098
4574
|
"Credits/prd: ",
|
|
4099
|
-
/* @__PURE__ */
|
|
4575
|
+
/* @__PURE__ */ jsx25("span", { className: "text-foreground", children: automation.credits ?? "\u2014" })
|
|
4100
4576
|
] })
|
|
4101
4577
|
] }),
|
|
4102
|
-
/* @__PURE__ */
|
|
4103
|
-
/* @__PURE__ */
|
|
4104
|
-
/* @__PURE__ */
|
|
4105
|
-
/* @__PURE__ */
|
|
4578
|
+
/* @__PURE__ */ jsx25(Separator2, {}),
|
|
4579
|
+
/* @__PURE__ */ jsxs14("div", { className: "flex items-center gap-2", children: [
|
|
4580
|
+
/* @__PURE__ */ jsx25("span", { className: "text-sm font-medium", children: automation.isEnabled ? "Enabled" : "Disabled" }),
|
|
4581
|
+
/* @__PURE__ */ jsx25(Switch, { checked: automation.isEnabled, onCheckedChange: onToggle })
|
|
4106
4582
|
] }),
|
|
4107
|
-
/* @__PURE__ */
|
|
4108
|
-
/* @__PURE__ */
|
|
4583
|
+
/* @__PURE__ */ jsx25(Separator2, {}),
|
|
4584
|
+
/* @__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(
|
|
4109
4585
|
SchemaFieldRenderer,
|
|
4110
4586
|
{
|
|
4111
4587
|
schema,
|
|
@@ -4114,13 +4590,13 @@ function AutomationConfigEditor({
|
|
|
4114
4590
|
loadingOptions,
|
|
4115
4591
|
onConfigChange: handleConfigChange
|
|
4116
4592
|
}
|
|
4117
|
-
) : /* @__PURE__ */
|
|
4118
|
-
automation.preview && /* @__PURE__ */
|
|
4119
|
-
/* @__PURE__ */
|
|
4120
|
-
/* @__PURE__ */
|
|
4121
|
-
automation.preview.info_text.map((text, i) => /* @__PURE__ */
|
|
4122
|
-
automation.preview.media.length > 0 && /* @__PURE__ */
|
|
4123
|
-
(m, i) => m.type === "image" ? /* @__PURE__ */
|
|
4593
|
+
) : /* @__PURE__ */ jsx25("p", { className: "py-4 text-center text-sm text-muted-foreground", children: "Enable this automation to configure it." }) }),
|
|
4594
|
+
automation.preview && /* @__PURE__ */ jsxs14(Fragment6, { children: [
|
|
4595
|
+
/* @__PURE__ */ jsx25(Separator2, {}),
|
|
4596
|
+
/* @__PURE__ */ jsxs14("div", { className: "space-y-2 rounded-lg bg-muted/50 p-3 text-sm", children: [
|
|
4597
|
+
automation.preview.info_text.map((text, i) => /* @__PURE__ */ jsx25("p", { className: "text-muted-foreground", children: text }, i)),
|
|
4598
|
+
automation.preview.media.length > 0 && /* @__PURE__ */ jsx25("div", { className: "flex flex-wrap gap-2 pt-1", children: automation.preview.media.map(
|
|
4599
|
+
(m, i) => m.type === "image" ? /* @__PURE__ */ jsx25(
|
|
4124
4600
|
"img",
|
|
4125
4601
|
{
|
|
4126
4602
|
src: m.src,
|
|
@@ -4136,7 +4612,7 @@ function AutomationConfigEditor({
|
|
|
4136
4612
|
}
|
|
4137
4613
|
|
|
4138
4614
|
// src/CatalogixChat.tsx
|
|
4139
|
-
import { jsx as
|
|
4615
|
+
import { jsx as jsx26, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
4140
4616
|
var SECTION_MAP = {
|
|
4141
4617
|
"catalogix:create-store": "create_store",
|
|
4142
4618
|
create_or_select_store: "create_store",
|
|
@@ -4145,7 +4621,9 @@ var SECTION_MAP = {
|
|
|
4145
4621
|
"catalogix:automations": "automations",
|
|
4146
4622
|
trigger_automation: "trigger_automation",
|
|
4147
4623
|
"catalogix:map-attributes": "map_attributes",
|
|
4148
|
-
map_attributes: "map_attributes"
|
|
4624
|
+
map_attributes: "map_attributes",
|
|
4625
|
+
"catalogix:edit-feed": "edit_feed",
|
|
4626
|
+
edit_feed: "edit_feed"
|
|
4149
4627
|
};
|
|
4150
4628
|
function CatalogixChat(props) {
|
|
4151
4629
|
const { uiProps, meta, onSubmit, workspaceId, userId } = props;
|
|
@@ -4166,7 +4644,7 @@ function CatalogixChat(props) {
|
|
|
4166
4644
|
configureApi({ catalogixBaseUrl });
|
|
4167
4645
|
}, [catalogixBaseUrl]);
|
|
4168
4646
|
if (section === "select_products") {
|
|
4169
|
-
return /* @__PURE__ */
|
|
4647
|
+
return /* @__PURE__ */ jsx26(
|
|
4170
4648
|
SelectProducts,
|
|
4171
4649
|
{
|
|
4172
4650
|
workspaceId,
|
|
@@ -4182,7 +4660,7 @@ function CatalogixChat(props) {
|
|
|
4182
4660
|
);
|
|
4183
4661
|
}
|
|
4184
4662
|
if (section === "create_store") {
|
|
4185
|
-
return /* @__PURE__ */
|
|
4663
|
+
return /* @__PURE__ */ jsx26(
|
|
4186
4664
|
CreateStore,
|
|
4187
4665
|
{
|
|
4188
4666
|
workspaceId,
|
|
@@ -4196,7 +4674,7 @@ function CatalogixChat(props) {
|
|
|
4196
4674
|
);
|
|
4197
4675
|
}
|
|
4198
4676
|
if (section === "map_attributes") {
|
|
4199
|
-
return /* @__PURE__ */
|
|
4677
|
+
return /* @__PURE__ */ jsx26(
|
|
4200
4678
|
MapAttributesChat,
|
|
4201
4679
|
{
|
|
4202
4680
|
mappingData: uiProps.mappingData ?? [],
|
|
@@ -4213,8 +4691,31 @@ function CatalogixChat(props) {
|
|
|
4213
4691
|
}
|
|
4214
4692
|
);
|
|
4215
4693
|
}
|
|
4694
|
+
if (section === "edit_feed") {
|
|
4695
|
+
return /* @__PURE__ */ jsx26(
|
|
4696
|
+
EditFeed,
|
|
4697
|
+
{
|
|
4698
|
+
criticalIssues: uiProps.criticalIssues ?? [],
|
|
4699
|
+
rawErrorData: uiProps.rawErrorData ?? [],
|
|
4700
|
+
dataIssuesRaw: uiProps.dataIssuesRaw ?? [],
|
|
4701
|
+
columns: uiProps.columns ?? [],
|
|
4702
|
+
skuField: uiProps.skuField ?? "SKU Code",
|
|
4703
|
+
storeId: uiProps.storeId ?? storeId,
|
|
4704
|
+
feedFileType: uiProps.feedFileType ?? "csv",
|
|
4705
|
+
downloadUrl: uiProps.downloadUrl ?? "",
|
|
4706
|
+
userId: uiProps.userId ?? userId,
|
|
4707
|
+
mappingObj: uiProps.mappingObj ?? {},
|
|
4708
|
+
sourceMp: uiProps.sourceMp ?? "SMP",
|
|
4709
|
+
marketplaceOv: uiProps.marketplaceOv ?? 34,
|
|
4710
|
+
transformedUrl: uiProps.transformedUrl ?? "",
|
|
4711
|
+
submitted: props.submitted,
|
|
4712
|
+
submittedValues: props.submittedValues,
|
|
4713
|
+
onSubmit: (values, msg) => onSubmit(values, msg)
|
|
4714
|
+
}
|
|
4715
|
+
);
|
|
4716
|
+
}
|
|
4216
4717
|
if (section === "trigger_automation") {
|
|
4217
|
-
return /* @__PURE__ */
|
|
4718
|
+
return /* @__PURE__ */ jsx26(
|
|
4218
4719
|
ProductAutomation,
|
|
4219
4720
|
{
|
|
4220
4721
|
storeId,
|
|
@@ -4234,7 +4735,7 @@ function CatalogixChat(props) {
|
|
|
4234
4735
|
);
|
|
4235
4736
|
}
|
|
4236
4737
|
if (section === "automations") {
|
|
4237
|
-
return /* @__PURE__ */
|
|
4738
|
+
return /* @__PURE__ */ jsx26(
|
|
4238
4739
|
StoreAutomation,
|
|
4239
4740
|
{
|
|
4240
4741
|
storeId,
|
|
@@ -4245,11 +4746,11 @@ function CatalogixChat(props) {
|
|
|
4245
4746
|
}
|
|
4246
4747
|
);
|
|
4247
4748
|
}
|
|
4248
|
-
return /* @__PURE__ */
|
|
4249
|
-
/* @__PURE__ */
|
|
4749
|
+
return /* @__PURE__ */ jsx26("div", { className: "p-4 text-sm text-muted-foreground", children: /* @__PURE__ */ jsxs15("p", { children: [
|
|
4750
|
+
/* @__PURE__ */ jsx26("strong", { children: "Catalogix" }),
|
|
4250
4751
|
" \u2014 unknown section:",
|
|
4251
4752
|
" ",
|
|
4252
|
-
/* @__PURE__ */
|
|
4753
|
+
/* @__PURE__ */ jsx26("code", { children: section || "(none)" })
|
|
4253
4754
|
] }) });
|
|
4254
4755
|
}
|
|
4255
4756
|
|
|
@@ -4309,11 +4810,26 @@ var catalogixManifest = [
|
|
|
4309
4810
|
position: "relative",
|
|
4310
4811
|
width: "100%"
|
|
4311
4812
|
}
|
|
4813
|
+
},
|
|
4814
|
+
{
|
|
4815
|
+
name: "catalogix:edit-feed",
|
|
4816
|
+
aliases: ["edit_feed"],
|
|
4817
|
+
service: "catalogix",
|
|
4818
|
+
description: "Edit feed cell values to fix validation errors",
|
|
4819
|
+
containerStyle: {
|
|
4820
|
+
overflow: "auto",
|
|
4821
|
+
marginTop: "8px",
|
|
4822
|
+
paddingBottom: "16px",
|
|
4823
|
+
maxHeight: "600px",
|
|
4824
|
+
position: "relative",
|
|
4825
|
+
width: "100%"
|
|
4826
|
+
}
|
|
4312
4827
|
}
|
|
4313
4828
|
];
|
|
4314
4829
|
export {
|
|
4315
4830
|
CatalogixChat,
|
|
4316
4831
|
CreateStore,
|
|
4832
|
+
EditFeed,
|
|
4317
4833
|
MapAttributesChat,
|
|
4318
4834
|
ProductAutomation,
|
|
4319
4835
|
SelectProducts,
|