@streamoid/catalogix-chat 0.2.18 → 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 +713 -200
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -3077,9 +3077,482 @@ 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__ */ 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
|
+
|
|
3080
3553
|
// src/Automations/ProductAutomation.tsx
|
|
3081
|
-
import { useState as
|
|
3082
|
-
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";
|
|
3083
3556
|
|
|
3084
3557
|
// src/Automations/api.ts
|
|
3085
3558
|
async function fetchAutomationList(storeId, tag, includeGroupings = false) {
|
|
@@ -3205,9 +3678,9 @@ function parseLovResponse(response, curl, configs) {
|
|
|
3205
3678
|
}
|
|
3206
3679
|
|
|
3207
3680
|
// src/Automations/SchemaFieldRenderer.tsx
|
|
3208
|
-
import { useCallback as
|
|
3209
|
-
import { Check as
|
|
3210
|
-
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";
|
|
3211
3684
|
function SchemaFieldRenderer({
|
|
3212
3685
|
schema,
|
|
3213
3686
|
configs,
|
|
@@ -3215,12 +3688,12 @@ function SchemaFieldRenderer({
|
|
|
3215
3688
|
loadingOptions,
|
|
3216
3689
|
onConfigChange
|
|
3217
3690
|
}) {
|
|
3218
|
-
return /* @__PURE__ */
|
|
3691
|
+
return /* @__PURE__ */ jsx23("div", { className: "space-y-4", children: schema.map((item, idx) => {
|
|
3219
3692
|
if (!shouldRenderAttribute(item.render_if, configs)) return null;
|
|
3220
3693
|
if (item.fieldtype === "object_array" && item.mapping_parameters) {
|
|
3221
|
-
return /* @__PURE__ */
|
|
3694
|
+
return /* @__PURE__ */ jsx23("div", { className: "space-y-3", children: item.mapping_parameters.map((sub, subIdx) => {
|
|
3222
3695
|
const value = configs[item.payload_key]?.[0] != null ? configs[item.payload_key][0]?.[sub.payload_key] : void 0;
|
|
3223
|
-
return /* @__PURE__ */
|
|
3696
|
+
return /* @__PURE__ */ jsx23(
|
|
3224
3697
|
FieldSwitch,
|
|
3225
3698
|
{
|
|
3226
3699
|
item: sub,
|
|
@@ -3234,7 +3707,7 @@ function SchemaFieldRenderer({
|
|
|
3234
3707
|
);
|
|
3235
3708
|
}) }, idx);
|
|
3236
3709
|
}
|
|
3237
|
-
return /* @__PURE__ */
|
|
3710
|
+
return /* @__PURE__ */ jsx23(
|
|
3238
3711
|
FieldSwitch,
|
|
3239
3712
|
{
|
|
3240
3713
|
item,
|
|
@@ -3259,7 +3732,7 @@ function FieldSwitch({
|
|
|
3259
3732
|
if (!shouldRenderAttribute(item.render_if, configs)) return null;
|
|
3260
3733
|
switch (item.fieldtype) {
|
|
3261
3734
|
case "freetext":
|
|
3262
|
-
return /* @__PURE__ */
|
|
3735
|
+
return /* @__PURE__ */ jsx23(
|
|
3263
3736
|
FreetextField,
|
|
3264
3737
|
{
|
|
3265
3738
|
item,
|
|
@@ -3268,7 +3741,7 @@ function FieldSwitch({
|
|
|
3268
3741
|
}
|
|
3269
3742
|
);
|
|
3270
3743
|
case "freetext_list":
|
|
3271
|
-
return /* @__PURE__ */
|
|
3744
|
+
return /* @__PURE__ */ jsx23(
|
|
3272
3745
|
FreetextListField,
|
|
3273
3746
|
{
|
|
3274
3747
|
item,
|
|
@@ -3277,7 +3750,7 @@ function FieldSwitch({
|
|
|
3277
3750
|
}
|
|
3278
3751
|
);
|
|
3279
3752
|
case "lov_singleselect":
|
|
3280
|
-
return /* @__PURE__ */
|
|
3753
|
+
return /* @__PURE__ */ jsx23(
|
|
3281
3754
|
SingleSelectField,
|
|
3282
3755
|
{
|
|
3283
3756
|
item,
|
|
@@ -3288,7 +3761,7 @@ function FieldSwitch({
|
|
|
3288
3761
|
}
|
|
3289
3762
|
);
|
|
3290
3763
|
case "lov_multipleselect":
|
|
3291
|
-
return /* @__PURE__ */
|
|
3764
|
+
return /* @__PURE__ */ jsx23(
|
|
3292
3765
|
MultiSelectField,
|
|
3293
3766
|
{
|
|
3294
3767
|
item,
|
|
@@ -3299,7 +3772,7 @@ function FieldSwitch({
|
|
|
3299
3772
|
}
|
|
3300
3773
|
);
|
|
3301
3774
|
case "image_singleselect":
|
|
3302
|
-
return /* @__PURE__ */
|
|
3775
|
+
return /* @__PURE__ */ jsx23(
|
|
3303
3776
|
ImageSelectField,
|
|
3304
3777
|
{
|
|
3305
3778
|
item,
|
|
@@ -3308,7 +3781,7 @@ function FieldSwitch({
|
|
|
3308
3781
|
}
|
|
3309
3782
|
);
|
|
3310
3783
|
case "boolean":
|
|
3311
|
-
return /* @__PURE__ */
|
|
3784
|
+
return /* @__PURE__ */ jsx23(
|
|
3312
3785
|
BooleanField,
|
|
3313
3786
|
{
|
|
3314
3787
|
item,
|
|
@@ -3325,13 +3798,13 @@ function FreetextField({
|
|
|
3325
3798
|
value,
|
|
3326
3799
|
onChange
|
|
3327
3800
|
}) {
|
|
3328
|
-
return /* @__PURE__ */
|
|
3329
|
-
/* @__PURE__ */
|
|
3801
|
+
return /* @__PURE__ */ jsxs12("div", { className: "space-y-1.5", children: [
|
|
3802
|
+
/* @__PURE__ */ jsxs12(Label, { children: [
|
|
3330
3803
|
item.title,
|
|
3331
|
-
item.required && /* @__PURE__ */
|
|
3804
|
+
item.required && /* @__PURE__ */ jsx23("span", { className: "text-destructive", children: " *" })
|
|
3332
3805
|
] }),
|
|
3333
|
-
item.description && /* @__PURE__ */
|
|
3334
|
-
/* @__PURE__ */
|
|
3806
|
+
item.description && /* @__PURE__ */ jsx23("p", { className: "text-xs text-muted-foreground", children: item.description }),
|
|
3807
|
+
/* @__PURE__ */ jsx23(
|
|
3335
3808
|
Input,
|
|
3336
3809
|
{
|
|
3337
3810
|
value: value ?? "",
|
|
@@ -3347,7 +3820,7 @@ function FreetextListField({
|
|
|
3347
3820
|
value,
|
|
3348
3821
|
onChange
|
|
3349
3822
|
}) {
|
|
3350
|
-
const [draft, setDraft] =
|
|
3823
|
+
const [draft, setDraft] = useState9("");
|
|
3351
3824
|
const keywords = value ?? [];
|
|
3352
3825
|
const addKeyword = () => {
|
|
3353
3826
|
const trimmed = draft.trim();
|
|
@@ -3356,14 +3829,14 @@ function FreetextListField({
|
|
|
3356
3829
|
setDraft("");
|
|
3357
3830
|
}
|
|
3358
3831
|
};
|
|
3359
|
-
return /* @__PURE__ */
|
|
3360
|
-
/* @__PURE__ */
|
|
3832
|
+
return /* @__PURE__ */ jsxs12("div", { className: "space-y-1.5", children: [
|
|
3833
|
+
/* @__PURE__ */ jsxs12(Label, { children: [
|
|
3361
3834
|
item.title,
|
|
3362
|
-
item.required && /* @__PURE__ */
|
|
3835
|
+
item.required && /* @__PURE__ */ jsx23("span", { className: "text-destructive", children: " *" })
|
|
3363
3836
|
] }),
|
|
3364
|
-
item.description && /* @__PURE__ */
|
|
3365
|
-
/* @__PURE__ */
|
|
3366
|
-
/* @__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(
|
|
3367
3840
|
Input,
|
|
3368
3841
|
{
|
|
3369
3842
|
value: draft,
|
|
@@ -3372,17 +3845,17 @@ function FreetextListField({
|
|
|
3372
3845
|
placeholder: "Type and press Enter"
|
|
3373
3846
|
}
|
|
3374
3847
|
),
|
|
3375
|
-
/* @__PURE__ */
|
|
3848
|
+
/* @__PURE__ */ jsx23(Button, { variant: "outline", size: "sm", onClick: addKeyword, type: "button", children: "Add" })
|
|
3376
3849
|
] }),
|
|
3377
|
-
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: [
|
|
3378
3851
|
kw,
|
|
3379
|
-
/* @__PURE__ */
|
|
3852
|
+
/* @__PURE__ */ jsx23(
|
|
3380
3853
|
"button",
|
|
3381
3854
|
{
|
|
3382
3855
|
type: "button",
|
|
3383
3856
|
onClick: () => onChange(keywords.filter((k) => k !== kw)),
|
|
3384
3857
|
className: "ml-0.5 rounded-full hover:bg-muted",
|
|
3385
|
-
children: /* @__PURE__ */
|
|
3858
|
+
children: /* @__PURE__ */ jsx23(X3, { className: "size-3" })
|
|
3386
3859
|
}
|
|
3387
3860
|
)
|
|
3388
3861
|
] }, kw)) })
|
|
@@ -3397,23 +3870,23 @@ function SingleSelectField({
|
|
|
3397
3870
|
}) {
|
|
3398
3871
|
const strOptions = Array.isArray(lovOptions) ? lovOptions.map(String) : [];
|
|
3399
3872
|
const strValue = value != null ? String(value) : "";
|
|
3400
|
-
return /* @__PURE__ */
|
|
3401
|
-
/* @__PURE__ */
|
|
3873
|
+
return /* @__PURE__ */ jsxs12("div", { className: "space-y-1.5", children: [
|
|
3874
|
+
/* @__PURE__ */ jsxs12(Label, { children: [
|
|
3402
3875
|
item.title,
|
|
3403
|
-
item.required && /* @__PURE__ */
|
|
3876
|
+
item.required && /* @__PURE__ */ jsx23("span", { className: "text-destructive", children: " *" })
|
|
3404
3877
|
] }),
|
|
3405
|
-
item.description && /* @__PURE__ */
|
|
3406
|
-
loading ? /* @__PURE__ */
|
|
3407
|
-
/* @__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" }),
|
|
3408
3881
|
"Loading options..."
|
|
3409
|
-
] }) : /* @__PURE__ */
|
|
3882
|
+
] }) : /* @__PURE__ */ jsxs12(
|
|
3410
3883
|
Select,
|
|
3411
3884
|
{
|
|
3412
3885
|
value: strValue,
|
|
3413
3886
|
onValueChange: (v) => onChange(item.valuetype === "integer" ? Number(v) : v),
|
|
3414
3887
|
children: [
|
|
3415
|
-
/* @__PURE__ */
|
|
3416
|
-
/* @__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)) })
|
|
3417
3890
|
]
|
|
3418
3891
|
}
|
|
3419
3892
|
)
|
|
@@ -3426,10 +3899,10 @@ function MultiSelectField({
|
|
|
3426
3899
|
loading,
|
|
3427
3900
|
onChange
|
|
3428
3901
|
}) {
|
|
3429
|
-
const [open, setOpen] =
|
|
3902
|
+
const [open, setOpen] = useState9(false);
|
|
3430
3903
|
const selected = value ?? [];
|
|
3431
3904
|
const strOptions = Array.isArray(lovOptions) ? lovOptions.map(String) : [];
|
|
3432
|
-
const toggle =
|
|
3905
|
+
const toggle = useCallback7(
|
|
3433
3906
|
(opt) => {
|
|
3434
3907
|
onChange(
|
|
3435
3908
|
selected.includes(opt) ? selected.filter((s) => s !== opt) : [...selected, opt]
|
|
@@ -3437,41 +3910,41 @@ function MultiSelectField({
|
|
|
3437
3910
|
},
|
|
3438
3911
|
[selected, onChange]
|
|
3439
3912
|
);
|
|
3440
|
-
return /* @__PURE__ */
|
|
3441
|
-
/* @__PURE__ */
|
|
3913
|
+
return /* @__PURE__ */ jsxs12("div", { className: "space-y-1.5", children: [
|
|
3914
|
+
/* @__PURE__ */ jsxs12(Label, { children: [
|
|
3442
3915
|
item.title,
|
|
3443
|
-
item.required && /* @__PURE__ */
|
|
3916
|
+
item.required && /* @__PURE__ */ jsx23("span", { className: "text-destructive", children: " *" })
|
|
3444
3917
|
] }),
|
|
3445
|
-
item.description && /* @__PURE__ */
|
|
3446
|
-
loading ? /* @__PURE__ */
|
|
3447
|
-
/* @__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" }),
|
|
3448
3921
|
"Loading options..."
|
|
3449
|
-
] }) : /* @__PURE__ */
|
|
3450
|
-
/* @__PURE__ */
|
|
3922
|
+
] }) : /* @__PURE__ */ jsxs12(Popover, { open, onOpenChange: setOpen, children: [
|
|
3923
|
+
/* @__PURE__ */ jsx23(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs12(
|
|
3451
3924
|
Button,
|
|
3452
3925
|
{
|
|
3453
3926
|
variant: "outline",
|
|
3454
3927
|
className: "w-full justify-between font-normal",
|
|
3455
3928
|
children: [
|
|
3456
|
-
selected.length > 0 ? /* @__PURE__ */
|
|
3457
|
-
/* @__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" })
|
|
3458
3931
|
]
|
|
3459
3932
|
}
|
|
3460
3933
|
) }),
|
|
3461
|
-
/* @__PURE__ */
|
|
3462
|
-
/* @__PURE__ */
|
|
3463
|
-
/* @__PURE__ */
|
|
3464
|
-
/* @__PURE__ */
|
|
3465
|
-
/* @__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) => {
|
|
3466
3939
|
const isSelected = selected.includes(opt);
|
|
3467
|
-
return /* @__PURE__ */
|
|
3940
|
+
return /* @__PURE__ */ jsxs12(
|
|
3468
3941
|
CommandItem,
|
|
3469
3942
|
{
|
|
3470
3943
|
value: opt,
|
|
3471
3944
|
onSelect: () => toggle(opt),
|
|
3472
3945
|
children: [
|
|
3473
|
-
/* @__PURE__ */
|
|
3474
|
-
|
|
3946
|
+
/* @__PURE__ */ jsx23(
|
|
3947
|
+
Check4,
|
|
3475
3948
|
{
|
|
3476
3949
|
className: cn(
|
|
3477
3950
|
"mr-2 size-4",
|
|
@@ -3496,12 +3969,12 @@ function ImageSelectField({
|
|
|
3496
3969
|
onChange
|
|
3497
3970
|
}) {
|
|
3498
3971
|
const images = item.lov ?? [];
|
|
3499
|
-
return /* @__PURE__ */
|
|
3500
|
-
/* @__PURE__ */
|
|
3972
|
+
return /* @__PURE__ */ jsxs12("div", { className: "space-y-1.5", children: [
|
|
3973
|
+
/* @__PURE__ */ jsxs12(Label, { children: [
|
|
3501
3974
|
item.title,
|
|
3502
|
-
item.required && /* @__PURE__ */
|
|
3975
|
+
item.required && /* @__PURE__ */ jsx23("span", { className: "text-destructive", children: " *" })
|
|
3503
3976
|
] }),
|
|
3504
|
-
/* @__PURE__ */
|
|
3977
|
+
/* @__PURE__ */ jsx23("div", { className: "flex flex-wrap gap-3", children: images.map((url) => /* @__PURE__ */ jsxs12(
|
|
3505
3978
|
"button",
|
|
3506
3979
|
{
|
|
3507
3980
|
type: "button",
|
|
@@ -3511,8 +3984,8 @@ function ImageSelectField({
|
|
|
3511
3984
|
value === url ? "border-primary ring-2 ring-primary/30" : "border-border hover:border-primary/50"
|
|
3512
3985
|
),
|
|
3513
3986
|
children: [
|
|
3514
|
-
/* @__PURE__ */
|
|
3515
|
-
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" }) })
|
|
3516
3989
|
]
|
|
3517
3990
|
},
|
|
3518
3991
|
url
|
|
@@ -3524,23 +3997,23 @@ function BooleanField({
|
|
|
3524
3997
|
value,
|
|
3525
3998
|
onChange
|
|
3526
3999
|
}) {
|
|
3527
|
-
return /* @__PURE__ */
|
|
3528
|
-
/* @__PURE__ */
|
|
4000
|
+
return /* @__PURE__ */ jsxs12("div", { className: "flex items-center gap-2 py-1", children: [
|
|
4001
|
+
/* @__PURE__ */ jsx23(
|
|
3529
4002
|
Checkbox,
|
|
3530
4003
|
{
|
|
3531
4004
|
checked: !!value,
|
|
3532
4005
|
onCheckedChange: (checked) => onChange(!!checked)
|
|
3533
4006
|
}
|
|
3534
4007
|
),
|
|
3535
|
-
/* @__PURE__ */
|
|
4008
|
+
/* @__PURE__ */ jsxs12(Label, { className: "cursor-pointer", onClick: () => onChange(!value), children: [
|
|
3536
4009
|
item.title,
|
|
3537
|
-
item.required && /* @__PURE__ */
|
|
4010
|
+
item.required && /* @__PURE__ */ jsx23("span", { className: "text-destructive", children: " *" })
|
|
3538
4011
|
] })
|
|
3539
4012
|
] });
|
|
3540
4013
|
}
|
|
3541
4014
|
|
|
3542
4015
|
// src/Automations/ProductAutomation.tsx
|
|
3543
|
-
import { Fragment as Fragment5, jsx as
|
|
4016
|
+
import { Fragment as Fragment5, jsx as jsx24, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
3544
4017
|
function ProductAutomation({
|
|
3545
4018
|
storeId,
|
|
3546
4019
|
workspaceId,
|
|
@@ -3556,17 +4029,17 @@ function ProductAutomation({
|
|
|
3556
4029
|
onSubmit,
|
|
3557
4030
|
onAutomationApplied
|
|
3558
4031
|
}) {
|
|
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] =
|
|
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);
|
|
3570
4043
|
const configsRef = useRef5(configs);
|
|
3571
4044
|
configsRef.current = configs;
|
|
3572
4045
|
const optionsRef = useRef5(options);
|
|
@@ -3637,7 +4110,7 @@ function ProductAutomation({
|
|
|
3637
4110
|
}
|
|
3638
4111
|
}
|
|
3639
4112
|
}, [schema, configs, channelsWithVersion]);
|
|
3640
|
-
const handleConfigChange =
|
|
4113
|
+
const handleConfigChange = useCallback8(
|
|
3641
4114
|
(key, value, item) => {
|
|
3642
4115
|
setConfigs((prev) => {
|
|
3643
4116
|
const parentItem = schema.find(
|
|
@@ -3663,7 +4136,7 @@ function ProductAutomation({
|
|
|
3663
4136
|
},
|
|
3664
4137
|
[schema]
|
|
3665
4138
|
);
|
|
3666
|
-
const isRunAllowed =
|
|
4139
|
+
const isRunAllowed = useCallback8(() => {
|
|
3667
4140
|
for (const item of schema) {
|
|
3668
4141
|
if (!shouldRenderAttribute(item.render_if, configs)) continue;
|
|
3669
4142
|
if (item.required) {
|
|
@@ -3713,18 +4186,18 @@ function ProductAutomation({
|
|
|
3713
4186
|
const filtered = searchQuery ? unique.filter(
|
|
3714
4187
|
(a) => a.display_name?.toLowerCase().includes(searchQuery.toLowerCase()) || a.automation.toLowerCase().includes(searchQuery.toLowerCase())
|
|
3715
4188
|
) : null;
|
|
3716
|
-
return /* @__PURE__ */
|
|
3717
|
-
/* @__PURE__ */
|
|
3718
|
-
/* @__PURE__ */
|
|
3719
|
-
/* @__PURE__ */
|
|
3720
|
-
/* @__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: [
|
|
3721
4194
|
productsCount,
|
|
3722
4195
|
" products"
|
|
3723
4196
|
] })
|
|
3724
4197
|
] }),
|
|
3725
|
-
/* @__PURE__ */
|
|
3726
|
-
/* @__PURE__ */
|
|
3727
|
-
/* @__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(
|
|
3728
4201
|
Input,
|
|
3729
4202
|
{
|
|
3730
4203
|
placeholder: "Search automations...",
|
|
@@ -3734,12 +4207,12 @@ function ProductAutomation({
|
|
|
3734
4207
|
}
|
|
3735
4208
|
)
|
|
3736
4209
|
] }),
|
|
3737
|
-
/* @__PURE__ */
|
|
3738
|
-
/* @__PURE__ */
|
|
3739
|
-
/* @__PURE__ */
|
|
3740
|
-
/* @__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" })
|
|
3741
4214
|
] }),
|
|
3742
|
-
/* @__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(
|
|
3743
4216
|
AutomationRow,
|
|
3744
4217
|
{
|
|
3745
4218
|
item,
|
|
@@ -3747,8 +4220,8 @@ function ProductAutomation({
|
|
|
3747
4220
|
onClick: () => setSelected(item)
|
|
3748
4221
|
},
|
|
3749
4222
|
item.automation
|
|
3750
|
-
)) : Object.keys(automationGroups).sort().map((group) => /* @__PURE__ */
|
|
3751
|
-
/* @__PURE__ */
|
|
4223
|
+
)) : Object.keys(automationGroups).sort().map((group) => /* @__PURE__ */ jsxs13("div", { children: [
|
|
4224
|
+
/* @__PURE__ */ jsxs13(
|
|
3752
4225
|
"button",
|
|
3753
4226
|
{
|
|
3754
4227
|
type: "button",
|
|
@@ -3758,8 +4231,8 @@ function ProductAutomation({
|
|
|
3758
4231
|
className: "flex w-full items-center justify-between px-2 py-2 text-sm font-semibold text-muted-foreground hover:text-foreground",
|
|
3759
4232
|
children: [
|
|
3760
4233
|
group,
|
|
3761
|
-
/* @__PURE__ */
|
|
3762
|
-
|
|
4234
|
+
/* @__PURE__ */ jsx24(
|
|
4235
|
+
ChevronDown4,
|
|
3763
4236
|
{
|
|
3764
4237
|
className: cn(
|
|
3765
4238
|
"size-4 transition-transform",
|
|
@@ -3770,7 +4243,7 @@ function ProductAutomation({
|
|
|
3770
4243
|
]
|
|
3771
4244
|
}
|
|
3772
4245
|
),
|
|
3773
|
-
expandedGroups.includes(group) && automationGroups[group].map((item) => /* @__PURE__ */
|
|
4246
|
+
expandedGroups.includes(group) && automationGroups[group].map((item) => /* @__PURE__ */ jsx24(
|
|
3774
4247
|
AutomationRow,
|
|
3775
4248
|
{
|
|
3776
4249
|
item,
|
|
@@ -3782,15 +4255,15 @@ function ProductAutomation({
|
|
|
3782
4255
|
] }, group)) })
|
|
3783
4256
|
] });
|
|
3784
4257
|
}
|
|
3785
|
-
return /* @__PURE__ */
|
|
3786
|
-
/* @__PURE__ */
|
|
3787
|
-
/* @__PURE__ */
|
|
3788
|
-
/* @__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 })
|
|
3789
4262
|
] }),
|
|
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__ */
|
|
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(
|
|
3794
4267
|
"img",
|
|
3795
4268
|
{
|
|
3796
4269
|
src: m.src,
|
|
@@ -3801,8 +4274,8 @@ function ProductAutomation({
|
|
|
3801
4274
|
) : null
|
|
3802
4275
|
) })
|
|
3803
4276
|
] }),
|
|
3804
|
-
/* @__PURE__ */
|
|
3805
|
-
/* @__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(
|
|
3806
4279
|
SchemaFieldRenderer,
|
|
3807
4280
|
{
|
|
3808
4281
|
schema,
|
|
@@ -3812,26 +4285,26 @@ function ProductAutomation({
|
|
|
3812
4285
|
onConfigChange: handleConfigChange
|
|
3813
4286
|
}
|
|
3814
4287
|
) }),
|
|
3815
|
-
/* @__PURE__ */
|
|
3816
|
-
/* @__PURE__ */
|
|
3817
|
-
/* @__PURE__ */
|
|
4288
|
+
/* @__PURE__ */ jsx24(Separator2, {}),
|
|
4289
|
+
/* @__PURE__ */ jsxs13("div", { className: "flex items-center gap-2", children: [
|
|
4290
|
+
/* @__PURE__ */ jsx24(
|
|
3818
4291
|
Button,
|
|
3819
4292
|
{
|
|
3820
4293
|
onClick: handleRun,
|
|
3821
4294
|
disabled: !isRunAllowed() || applying,
|
|
3822
4295
|
className: "flex-1",
|
|
3823
|
-
children: applying ? /* @__PURE__ */
|
|
3824
|
-
/* @__PURE__ */
|
|
4296
|
+
children: applying ? /* @__PURE__ */ jsxs13(Fragment5, { children: [
|
|
4297
|
+
/* @__PURE__ */ jsx24(Loader28, { className: "size-4 animate-spin" }),
|
|
3825
4298
|
"Applying..."
|
|
3826
|
-
] }) : /* @__PURE__ */
|
|
3827
|
-
/* @__PURE__ */
|
|
4299
|
+
] }) : /* @__PURE__ */ jsxs13(Fragment5, { children: [
|
|
4300
|
+
/* @__PURE__ */ jsx24(Play, { className: "size-4" }),
|
|
3828
4301
|
"Run Automation"
|
|
3829
4302
|
] })
|
|
3830
4303
|
}
|
|
3831
4304
|
),
|
|
3832
|
-
/* @__PURE__ */
|
|
4305
|
+
/* @__PURE__ */ jsx24(Button, { variant: "outline", onClick: () => setSelected(null), children: "Cancel" })
|
|
3833
4306
|
] }),
|
|
3834
|
-
/* @__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." })
|
|
3835
4308
|
] });
|
|
3836
4309
|
}
|
|
3837
4310
|
function AutomationRow({
|
|
@@ -3841,19 +4314,19 @@ function AutomationRow({
|
|
|
3841
4314
|
}) {
|
|
3842
4315
|
const estTime = item.estimate_time_saved ? formatTimeSaved(item.estimate_time_saved * productsCount) : "\u2014";
|
|
3843
4316
|
const credits = item.credits ? Math.ceil(item.credits * productsCount) : 0;
|
|
3844
|
-
return /* @__PURE__ */
|
|
4317
|
+
return /* @__PURE__ */ jsxs13(
|
|
3845
4318
|
"button",
|
|
3846
4319
|
{
|
|
3847
4320
|
type: "button",
|
|
3848
4321
|
onClick,
|
|
3849
4322
|
className: "flex w-full items-center gap-4 rounded-md px-2 py-2.5 text-left hover:bg-accent",
|
|
3850
4323
|
children: [
|
|
3851
|
-
/* @__PURE__ */
|
|
3852
|
-
/* @__PURE__ */
|
|
3853
|
-
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 })
|
|
3854
4327
|
] }),
|
|
3855
|
-
/* @__PURE__ */
|
|
3856
|
-
/* @__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 })
|
|
3857
4330
|
]
|
|
3858
4331
|
}
|
|
3859
4332
|
);
|
|
@@ -3865,9 +4338,9 @@ function formatTimeSaved(totalSeconds) {
|
|
|
3865
4338
|
}
|
|
3866
4339
|
|
|
3867
4340
|
// src/Automations/StoreAutomation.tsx
|
|
3868
|
-
import { useState as
|
|
4341
|
+
import { useState as useState11, useEffect as useEffect7, useCallback as useCallback9, useRef as useRef6 } from "react";
|
|
3869
4342
|
import { ArrowLeft as ArrowLeft4, Settings } from "lucide-react";
|
|
3870
|
-
import { Fragment as Fragment6, jsx as
|
|
4343
|
+
import { Fragment as Fragment6, jsx as jsx25, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
3871
4344
|
function StoreAutomation({
|
|
3872
4345
|
storeId,
|
|
3873
4346
|
channelsWithVersion,
|
|
@@ -3875,10 +4348,10 @@ function StoreAutomation({
|
|
|
3875
4348
|
onSubmit,
|
|
3876
4349
|
onClose
|
|
3877
4350
|
}) {
|
|
3878
|
-
const [loading, setLoading] =
|
|
3879
|
-
const [automations, setAutomations] =
|
|
3880
|
-
const [selectedConfigs, setSelectedConfigs] =
|
|
3881
|
-
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);
|
|
3882
4355
|
useEffect7(() => {
|
|
3883
4356
|
setLoading(true);
|
|
3884
4357
|
fetchAutomationList(storeId, "default").then((data) => {
|
|
@@ -3891,7 +4364,7 @@ function StoreAutomation({
|
|
|
3891
4364
|
);
|
|
3892
4365
|
}).catch(console.error).finally(() => setLoading(false));
|
|
3893
4366
|
}, [storeId, enabledAutomations]);
|
|
3894
|
-
const toggleAutomation =
|
|
4367
|
+
const toggleAutomation = useCallback9((automationName) => {
|
|
3895
4368
|
setAutomations(
|
|
3896
4369
|
(prev) => prev.map(
|
|
3897
4370
|
(a) => a.automation === automationName ? { ...a, isEnabled: !a.isEnabled } : a
|
|
@@ -3924,7 +4397,7 @@ function StoreAutomation({
|
|
|
3924
4397
|
setSelectedAutomation(null);
|
|
3925
4398
|
};
|
|
3926
4399
|
if (selectedAutomation) {
|
|
3927
|
-
return /* @__PURE__ */
|
|
4400
|
+
return /* @__PURE__ */ jsx25(
|
|
3928
4401
|
AutomationConfigEditor,
|
|
3929
4402
|
{
|
|
3930
4403
|
storeId,
|
|
@@ -3936,46 +4409,46 @@ function StoreAutomation({
|
|
|
3936
4409
|
}
|
|
3937
4410
|
);
|
|
3938
4411
|
}
|
|
3939
|
-
return /* @__PURE__ */
|
|
3940
|
-
/* @__PURE__ */
|
|
3941
|
-
onClose && /* @__PURE__ */
|
|
3942
|
-
/* @__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" })
|
|
3943
4416
|
] }),
|
|
3944
|
-
/* @__PURE__ */
|
|
3945
|
-
loading ? /* @__PURE__ */
|
|
3946
|
-
/* @__PURE__ */
|
|
3947
|
-
/* @__PURE__ */
|
|
3948
|
-
/* @__PURE__ */
|
|
3949
|
-
/* @__PURE__ */
|
|
3950
|
-
/* @__PURE__ */
|
|
3951
|
-
/* @__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" })
|
|
3952
4425
|
] }) }),
|
|
3953
|
-
/* @__PURE__ */
|
|
4426
|
+
/* @__PURE__ */ jsx25(TableBody, { children: automations.map((a) => /* @__PURE__ */ jsxs14(
|
|
3954
4427
|
TableRow,
|
|
3955
4428
|
{
|
|
3956
4429
|
className: "cursor-pointer",
|
|
3957
4430
|
onClick: () => setSelectedAutomation(a),
|
|
3958
4431
|
children: [
|
|
3959
|
-
/* @__PURE__ */
|
|
3960
|
-
/* @__PURE__ */
|
|
3961
|
-
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 })
|
|
3962
4435
|
] }),
|
|
3963
|
-
/* @__PURE__ */
|
|
3964
|
-
/* @__PURE__ */
|
|
3965
|
-
/* @__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(
|
|
3966
4439
|
"div",
|
|
3967
4440
|
{
|
|
3968
4441
|
className: "flex items-center justify-center gap-2",
|
|
3969
4442
|
onClick: (e) => e.stopPropagation(),
|
|
3970
4443
|
children: [
|
|
3971
|
-
/* @__PURE__ */
|
|
4444
|
+
/* @__PURE__ */ jsx25(
|
|
3972
4445
|
Switch,
|
|
3973
4446
|
{
|
|
3974
4447
|
checked: a.isEnabled,
|
|
3975
4448
|
onCheckedChange: () => toggleAutomation(a.automation)
|
|
3976
4449
|
}
|
|
3977
4450
|
),
|
|
3978
|
-
/* @__PURE__ */
|
|
4451
|
+
/* @__PURE__ */ jsx25(
|
|
3979
4452
|
Badge,
|
|
3980
4453
|
{
|
|
3981
4454
|
variant: a.isEnabled ? "default" : "secondary",
|
|
@@ -3986,16 +4459,16 @@ function StoreAutomation({
|
|
|
3986
4459
|
]
|
|
3987
4460
|
}
|
|
3988
4461
|
) }),
|
|
3989
|
-
/* @__PURE__ */
|
|
4462
|
+
/* @__PURE__ */ jsx25(TableCell, { children: /* @__PURE__ */ jsx25(Settings, { className: "size-4 text-muted-foreground" }) })
|
|
3990
4463
|
]
|
|
3991
4464
|
},
|
|
3992
4465
|
a.automation
|
|
3993
4466
|
)) })
|
|
3994
4467
|
] }) }),
|
|
3995
|
-
/* @__PURE__ */
|
|
3996
|
-
/* @__PURE__ */
|
|
3997
|
-
onClose && /* @__PURE__ */
|
|
3998
|
-
/* @__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" })
|
|
3999
4472
|
] })
|
|
4000
4473
|
] });
|
|
4001
4474
|
}
|
|
@@ -4007,13 +4480,13 @@ function AutomationConfigEditor({
|
|
|
4007
4480
|
onClose,
|
|
4008
4481
|
onToggle
|
|
4009
4482
|
}) {
|
|
4010
|
-
const [schemaLoading, setSchemaLoading] =
|
|
4011
|
-
const [schema, setSchema] =
|
|
4012
|
-
const [configs, setConfigs] =
|
|
4483
|
+
const [schemaLoading, setSchemaLoading] = useState11(false);
|
|
4484
|
+
const [schema, setSchema] = useState11([]);
|
|
4485
|
+
const [configs, setConfigs] = useState11(
|
|
4013
4486
|
initialConfigs ?? {}
|
|
4014
4487
|
);
|
|
4015
|
-
const [options, setOptions] =
|
|
4016
|
-
const [loadingOptions, setLoadingOptions] =
|
|
4488
|
+
const [options, setOptions] = useState11({});
|
|
4489
|
+
const [loadingOptions, setLoadingOptions] = useState11({});
|
|
4017
4490
|
const configsRef = useRef6(configs);
|
|
4018
4491
|
configsRef.current = configs;
|
|
4019
4492
|
const optionsRef = useRef6(options);
|
|
@@ -4060,7 +4533,7 @@ function AutomationConfigEditor({
|
|
|
4060
4533
|
}
|
|
4061
4534
|
}
|
|
4062
4535
|
}, [schema, configs, channelsWithVersion]);
|
|
4063
|
-
const handleConfigChange =
|
|
4536
|
+
const handleConfigChange = useCallback9(
|
|
4064
4537
|
(key, value, item) => {
|
|
4065
4538
|
setConfigs((prev) => ({ ...prev, [key]: value }));
|
|
4066
4539
|
if (item.linked?.length) {
|
|
@@ -4076,36 +4549,36 @@ function AutomationConfigEditor({
|
|
|
4076
4549
|
},
|
|
4077
4550
|
[]
|
|
4078
4551
|
);
|
|
4079
|
-
return /* @__PURE__ */
|
|
4080
|
-
/* @__PURE__ */
|
|
4081
|
-
/* @__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(
|
|
4082
4555
|
Button,
|
|
4083
4556
|
{
|
|
4084
4557
|
variant: "ghost",
|
|
4085
4558
|
size: "icon",
|
|
4086
4559
|
onClick: () => onClose(automation, configs),
|
|
4087
|
-
children: /* @__PURE__ */
|
|
4560
|
+
children: /* @__PURE__ */ jsx25(ArrowLeft4, { className: "size-4" })
|
|
4088
4561
|
}
|
|
4089
4562
|
),
|
|
4090
|
-
/* @__PURE__ */
|
|
4563
|
+
/* @__PURE__ */ jsx25("h3", { className: "text-base font-semibold", children: automation.display_name })
|
|
4091
4564
|
] }),
|
|
4092
|
-
/* @__PURE__ */
|
|
4093
|
-
/* @__PURE__ */
|
|
4565
|
+
/* @__PURE__ */ jsxs14("div", { className: "flex gap-4 text-sm", children: [
|
|
4566
|
+
/* @__PURE__ */ jsxs14("div", { className: "text-muted-foreground", children: [
|
|
4094
4567
|
"Est. time: ",
|
|
4095
|
-
/* @__PURE__ */
|
|
4568
|
+
/* @__PURE__ */ jsx25("span", { className: "text-foreground", children: automation.estimate_run_time ?? "\u2014" })
|
|
4096
4569
|
] }),
|
|
4097
|
-
/* @__PURE__ */
|
|
4570
|
+
/* @__PURE__ */ jsxs14("div", { className: "text-muted-foreground", children: [
|
|
4098
4571
|
"Credits/prd: ",
|
|
4099
|
-
/* @__PURE__ */
|
|
4572
|
+
/* @__PURE__ */ jsx25("span", { className: "text-foreground", children: automation.credits ?? "\u2014" })
|
|
4100
4573
|
] })
|
|
4101
4574
|
] }),
|
|
4102
|
-
/* @__PURE__ */
|
|
4103
|
-
/* @__PURE__ */
|
|
4104
|
-
/* @__PURE__ */
|
|
4105
|
-
/* @__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 })
|
|
4106
4579
|
] }),
|
|
4107
|
-
/* @__PURE__ */
|
|
4108
|
-
/* @__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(
|
|
4109
4582
|
SchemaFieldRenderer,
|
|
4110
4583
|
{
|
|
4111
4584
|
schema,
|
|
@@ -4114,13 +4587,13 @@ function AutomationConfigEditor({
|
|
|
4114
4587
|
loadingOptions,
|
|
4115
4588
|
onConfigChange: handleConfigChange
|
|
4116
4589
|
}
|
|
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__ */
|
|
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(
|
|
4124
4597
|
"img",
|
|
4125
4598
|
{
|
|
4126
4599
|
src: m.src,
|
|
@@ -4136,7 +4609,7 @@ function AutomationConfigEditor({
|
|
|
4136
4609
|
}
|
|
4137
4610
|
|
|
4138
4611
|
// src/CatalogixChat.tsx
|
|
4139
|
-
import { jsx as
|
|
4612
|
+
import { jsx as jsx26, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
4140
4613
|
var SECTION_MAP = {
|
|
4141
4614
|
"catalogix:create-store": "create_store",
|
|
4142
4615
|
create_or_select_store: "create_store",
|
|
@@ -4145,7 +4618,9 @@ var SECTION_MAP = {
|
|
|
4145
4618
|
"catalogix:automations": "automations",
|
|
4146
4619
|
trigger_automation: "trigger_automation",
|
|
4147
4620
|
"catalogix:map-attributes": "map_attributes",
|
|
4148
|
-
map_attributes: "map_attributes"
|
|
4621
|
+
map_attributes: "map_attributes",
|
|
4622
|
+
"catalogix:edit-feed": "edit_feed",
|
|
4623
|
+
edit_feed: "edit_feed"
|
|
4149
4624
|
};
|
|
4150
4625
|
function CatalogixChat(props) {
|
|
4151
4626
|
const { uiProps, meta, onSubmit, workspaceId, userId } = props;
|
|
@@ -4166,7 +4641,7 @@ function CatalogixChat(props) {
|
|
|
4166
4641
|
configureApi({ catalogixBaseUrl });
|
|
4167
4642
|
}, [catalogixBaseUrl]);
|
|
4168
4643
|
if (section === "select_products") {
|
|
4169
|
-
return /* @__PURE__ */
|
|
4644
|
+
return /* @__PURE__ */ jsx26(
|
|
4170
4645
|
SelectProducts,
|
|
4171
4646
|
{
|
|
4172
4647
|
workspaceId,
|
|
@@ -4182,7 +4657,7 @@ function CatalogixChat(props) {
|
|
|
4182
4657
|
);
|
|
4183
4658
|
}
|
|
4184
4659
|
if (section === "create_store") {
|
|
4185
|
-
return /* @__PURE__ */
|
|
4660
|
+
return /* @__PURE__ */ jsx26(
|
|
4186
4661
|
CreateStore,
|
|
4187
4662
|
{
|
|
4188
4663
|
workspaceId,
|
|
@@ -4196,7 +4671,7 @@ function CatalogixChat(props) {
|
|
|
4196
4671
|
);
|
|
4197
4672
|
}
|
|
4198
4673
|
if (section === "map_attributes") {
|
|
4199
|
-
return /* @__PURE__ */
|
|
4674
|
+
return /* @__PURE__ */ jsx26(
|
|
4200
4675
|
MapAttributesChat,
|
|
4201
4676
|
{
|
|
4202
4677
|
mappingData: uiProps.mappingData ?? [],
|
|
@@ -4213,8 +4688,31 @@ function CatalogixChat(props) {
|
|
|
4213
4688
|
}
|
|
4214
4689
|
);
|
|
4215
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
|
+
}
|
|
4216
4714
|
if (section === "trigger_automation") {
|
|
4217
|
-
return /* @__PURE__ */
|
|
4715
|
+
return /* @__PURE__ */ jsx26(
|
|
4218
4716
|
ProductAutomation,
|
|
4219
4717
|
{
|
|
4220
4718
|
storeId,
|
|
@@ -4234,7 +4732,7 @@ function CatalogixChat(props) {
|
|
|
4234
4732
|
);
|
|
4235
4733
|
}
|
|
4236
4734
|
if (section === "automations") {
|
|
4237
|
-
return /* @__PURE__ */
|
|
4735
|
+
return /* @__PURE__ */ jsx26(
|
|
4238
4736
|
StoreAutomation,
|
|
4239
4737
|
{
|
|
4240
4738
|
storeId,
|
|
@@ -4245,11 +4743,11 @@ function CatalogixChat(props) {
|
|
|
4245
4743
|
}
|
|
4246
4744
|
);
|
|
4247
4745
|
}
|
|
4248
|
-
return /* @__PURE__ */
|
|
4249
|
-
/* @__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" }),
|
|
4250
4748
|
" \u2014 unknown section:",
|
|
4251
4749
|
" ",
|
|
4252
|
-
/* @__PURE__ */
|
|
4750
|
+
/* @__PURE__ */ jsx26("code", { children: section || "(none)" })
|
|
4253
4751
|
] }) });
|
|
4254
4752
|
}
|
|
4255
4753
|
|
|
@@ -4309,11 +4807,26 @@ var catalogixManifest = [
|
|
|
4309
4807
|
position: "relative",
|
|
4310
4808
|
width: "100%"
|
|
4311
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
|
+
}
|
|
4312
4824
|
}
|
|
4313
4825
|
];
|
|
4314
4826
|
export {
|
|
4315
4827
|
CatalogixChat,
|
|
4316
4828
|
CreateStore,
|
|
4829
|
+
EditFeed,
|
|
4317
4830
|
MapAttributesChat,
|
|
4318
4831
|
ProductAutomation,
|
|
4319
4832
|
SelectProducts,
|