@streamoid/catalogix-chat 0.2.20 → 0.2.22
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 +2 -1
- package/dist/index.js +99 -127
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -186,11 +186,12 @@ interface EditFeedProps {
|
|
|
186
186
|
sourceMp: string;
|
|
187
187
|
marketplaceOv: number | string;
|
|
188
188
|
transformedUrl: string;
|
|
189
|
+
mappingKey: string;
|
|
189
190
|
submitted?: boolean;
|
|
190
191
|
submittedValues?: Record<string, unknown>;
|
|
191
192
|
onSubmit: (values: Record<string, unknown>, message?: string) => void;
|
|
192
193
|
}
|
|
193
|
-
declare function EditFeed({ criticalIssues: initialCriticalIssues, rawErrorData: initialRawErrorData, dataIssuesRaw: initialDataIssuesRaw, columns: initialColumns, skuField, storeId, feedFileType, downloadUrl, userId, mappingObj, sourceMp, marketplaceOv, transformedUrl: initialTransformedUrl, submitted, submittedValues, onSubmit, }: EditFeedProps): react_jsx_runtime.JSX.Element;
|
|
194
|
+
declare function EditFeed({ criticalIssues: initialCriticalIssues, rawErrorData: initialRawErrorData, dataIssuesRaw: initialDataIssuesRaw, columns: initialColumns, skuField, storeId, feedFileType, downloadUrl, userId, mappingObj, sourceMp, marketplaceOv, transformedUrl: initialTransformedUrl, mappingKey, submitted, submittedValues, onSubmit, }: EditFeedProps): react_jsx_runtime.JSX.Element;
|
|
194
195
|
|
|
195
196
|
interface ProductAutomationProps {
|
|
196
197
|
storeId: string;
|
package/dist/index.js
CHANGED
|
@@ -3085,7 +3085,7 @@ import {
|
|
|
3085
3085
|
ChevronDown as ChevronDown3,
|
|
3086
3086
|
ChevronRight as ChevronRight3,
|
|
3087
3087
|
Pencil as Pencil3,
|
|
3088
|
-
|
|
3088
|
+
Send as Send2,
|
|
3089
3089
|
Loader2 as Loader26,
|
|
3090
3090
|
X as X2,
|
|
3091
3091
|
RefreshCw
|
|
@@ -3125,66 +3125,33 @@ function buildDataIssueMap(issues) {
|
|
|
3125
3125
|
}
|
|
3126
3126
|
return map;
|
|
3127
3127
|
}
|
|
3128
|
-
function
|
|
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) {
|
|
3128
|
+
async function validateRow(storeId, mappingKey, rowData) {
|
|
3142
3129
|
const { catalogixBaseUrl } = getApiConfig();
|
|
3143
|
-
const
|
|
3144
|
-
|
|
3145
|
-
|
|
3146
|
-
|
|
3147
|
-
|
|
3148
|
-
|
|
3149
|
-
|
|
3130
|
+
const params = new URLSearchParams({ mapping_key: mappingKey });
|
|
3131
|
+
return fetchJson(
|
|
3132
|
+
`${catalogixBaseUrl}/api/v1/feed/${storeId}/validate/row?${params}`,
|
|
3133
|
+
{
|
|
3134
|
+
method: "POST",
|
|
3135
|
+
headers: { "Content-Type": "application/json" },
|
|
3136
|
+
body: JSON.stringify([rowData])
|
|
3137
|
+
}
|
|
3150
3138
|
);
|
|
3151
|
-
if (!resp.ok) throw new Error(`Upload failed: ${resp.status}`);
|
|
3152
|
-
const json = await resp.json();
|
|
3153
|
-
return json.data.download_url;
|
|
3154
3139
|
}
|
|
3155
|
-
async function
|
|
3140
|
+
async function mergeFeed(fileUrl, feedFormat, changes) {
|
|
3156
3141
|
const { catalogixBaseUrl } = getApiConfig();
|
|
3157
3142
|
const params = new URLSearchParams({
|
|
3158
3143
|
file_url: fileUrl,
|
|
3159
|
-
feed_format:
|
|
3160
|
-
client_feed_url: clientFeedUrl,
|
|
3161
|
-
catalogix_user_id: userId,
|
|
3162
|
-
re_validate: String(reValidate)
|
|
3144
|
+
feed_format: feedFormat
|
|
3163
3145
|
});
|
|
3164
3146
|
return fetchJson(
|
|
3165
|
-
`${catalogixBaseUrl}/api/v1/feed
|
|
3147
|
+
`${catalogixBaseUrl}/api/v1/feed/merge?${params}`,
|
|
3166
3148
|
{
|
|
3167
3149
|
method: "POST",
|
|
3168
3150
|
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
|
-
})
|
|
3151
|
+
body: JSON.stringify(changes)
|
|
3178
3152
|
}
|
|
3179
3153
|
);
|
|
3180
3154
|
}
|
|
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
3155
|
function EditableCell2({
|
|
3189
3156
|
value,
|
|
3190
3157
|
hasError,
|
|
@@ -3198,7 +3165,7 @@ function EditableCell2({
|
|
|
3198
3165
|
setEditing(false);
|
|
3199
3166
|
if (draft !== value) onChange(draft);
|
|
3200
3167
|
}, [draft, value, onChange]);
|
|
3201
|
-
if (readOnly
|
|
3168
|
+
if (readOnly) {
|
|
3202
3169
|
return /* @__PURE__ */ jsxs11(
|
|
3203
3170
|
"div",
|
|
3204
3171
|
{
|
|
@@ -3256,19 +3223,19 @@ function EditableCell2({
|
|
|
3256
3223
|
}
|
|
3257
3224
|
);
|
|
3258
3225
|
}
|
|
3259
|
-
function MissingAttributesBanner({ text }) {
|
|
3260
|
-
const [open, setOpen] = useState8(
|
|
3226
|
+
function MissingAttributesBanner({ text, defaultOpen = false }) {
|
|
3227
|
+
const [open, setOpen] = useState8(defaultOpen);
|
|
3261
3228
|
const attrs = text.split(",").map((s) => s.trim().replace(/^'|'$/g, ""));
|
|
3262
3229
|
const preview = attrs.slice(0, 3);
|
|
3263
|
-
return /* @__PURE__ */ jsxs11("div", { className: "text-xs
|
|
3230
|
+
return /* @__PURE__ */ jsxs11("div", { className: "text-xs px-2 py-1.5 border-t border-dashed border-amber-300/60 bg-amber-50/40 dark:bg-amber-950/20 text-amber-700 dark:text-amber-400", children: [
|
|
3264
3231
|
/* @__PURE__ */ jsxs11(
|
|
3265
3232
|
"button",
|
|
3266
3233
|
{
|
|
3267
3234
|
type: "button",
|
|
3268
|
-
className: "flex items-center gap-1 hover:text-
|
|
3235
|
+
className: "flex items-center gap-1 hover:text-amber-900 dark:hover:text-amber-300 transition-colors",
|
|
3269
3236
|
onClick: () => setOpen((v) => !v),
|
|
3270
3237
|
children: [
|
|
3271
|
-
/* @__PURE__ */ jsx22(
|
|
3238
|
+
/* @__PURE__ */ jsx22(AlertTriangle2, { className: "h-3 w-3" }),
|
|
3272
3239
|
/* @__PURE__ */ jsx22("span", { className: "font-medium", children: "Missing attributes:" }),
|
|
3273
3240
|
!open && /* @__PURE__ */ jsxs11("span", { children: [
|
|
3274
3241
|
preview.join(", "),
|
|
@@ -3310,6 +3277,7 @@ function EditFeed({
|
|
|
3310
3277
|
sourceMp,
|
|
3311
3278
|
marketplaceOv,
|
|
3312
3279
|
transformedUrl: initialTransformedUrl,
|
|
3280
|
+
mappingKey,
|
|
3313
3281
|
submitted,
|
|
3314
3282
|
submittedValues,
|
|
3315
3283
|
onSubmit
|
|
@@ -3326,6 +3294,9 @@ function EditFeed({
|
|
|
3326
3294
|
return out;
|
|
3327
3295
|
})
|
|
3328
3296
|
);
|
|
3297
|
+
const [rowNumbers, setRowNumbers] = useState8(
|
|
3298
|
+
() => initialRawErrorData.map((r) => Number(r.row_number ?? 0))
|
|
3299
|
+
);
|
|
3329
3300
|
const [criticalIssues, setCriticalIssues] = useState8(initialCriticalIssues);
|
|
3330
3301
|
const [dataIssuesRaw, setDataIssuesRaw] = useState8(initialDataIssuesRaw);
|
|
3331
3302
|
const [columns] = useState8(
|
|
@@ -3367,77 +3338,71 @@ function EditFeed({
|
|
|
3367
3338
|
setIsLoading(true);
|
|
3368
3339
|
setErrorMsg("");
|
|
3369
3340
|
try {
|
|
3370
|
-
|
|
3371
|
-
const
|
|
3372
|
-
|
|
3373
|
-
|
|
3374
|
-
|
|
3375
|
-
|
|
3376
|
-
|
|
3377
|
-
|
|
3378
|
-
|
|
3379
|
-
|
|
3380
|
-
|
|
3381
|
-
|
|
3382
|
-
|
|
3383
|
-
|
|
3384
|
-
|
|
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
|
-
);
|
|
3341
|
+
const editedRowIndices = /* @__PURE__ */ new Set();
|
|
3342
|
+
for (const key of editedCells) {
|
|
3343
|
+
const idx = parseInt(key.split(":")[0], 10);
|
|
3344
|
+
editedRowIndices.add(idx);
|
|
3345
|
+
}
|
|
3346
|
+
if (editedRowIndices.size === 0) {
|
|
3347
|
+
if (errorCount === 0) {
|
|
3348
|
+
onSubmit(
|
|
3349
|
+
{ transformedUrl },
|
|
3350
|
+
"No critical errors. Proceeding with current feed."
|
|
3351
|
+
);
|
|
3352
|
+
return;
|
|
3353
|
+
}
|
|
3354
|
+
setErrorMsg("No cells have been edited. Please fix the highlighted values first.");
|
|
3355
|
+
setIsLoading(false);
|
|
3394
3356
|
return;
|
|
3395
3357
|
}
|
|
3396
|
-
|
|
3397
|
-
const
|
|
3398
|
-
|
|
3399
|
-
|
|
3400
|
-
const
|
|
3401
|
-
const
|
|
3402
|
-
|
|
3403
|
-
|
|
3404
|
-
|
|
3358
|
+
const failedRows = [];
|
|
3359
|
+
for (const rowIdx of editedRowIndices) {
|
|
3360
|
+
const rowNum = rowNumbers[rowIdx];
|
|
3361
|
+
setStatusMsg(`Validating row ${rowIdx + 1} of ${rows.length}...`);
|
|
3362
|
+
const fullRowData = { ...rows[rowIdx], row_number: rowNum };
|
|
3363
|
+
const result = await validateRow(storeId, mappingKey, fullRowData);
|
|
3364
|
+
if (!result.data.validation) {
|
|
3365
|
+
failedRows.push({ rowIdx, errors: result.data.errors });
|
|
3366
|
+
}
|
|
3367
|
+
}
|
|
3368
|
+
if (failedRows.length > 0) {
|
|
3369
|
+
const newCritical = [];
|
|
3370
|
+
for (const { rowIdx, errors } of failedRows) {
|
|
3371
|
+
const sku = rows[rowIdx][skuField] ?? "";
|
|
3372
|
+
for (const err of errors) {
|
|
3373
|
+
if (err["Invalid Value"] || err["Invalid Attribute"]) {
|
|
3374
|
+
newCritical.push({
|
|
3375
|
+
rowNumber: rowNumbers[rowIdx],
|
|
3376
|
+
columnNumber: err["Column Number"] || void 0,
|
|
3377
|
+
skuCode: err["SKU Code"] || sku,
|
|
3378
|
+
errorMessage: [err["Invalid Attribute"], err["Invalid Value"]].filter(Boolean).join(": ")
|
|
3379
|
+
});
|
|
3380
|
+
}
|
|
3405
3381
|
}
|
|
3406
|
-
|
|
3407
|
-
|
|
3408
|
-
setRows(newRows);
|
|
3382
|
+
}
|
|
3383
|
+
if (newCritical.length > 0) setCriticalIssues(newCritical);
|
|
3409
3384
|
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
3385
|
setErrorMsg(
|
|
3438
|
-
|
|
3386
|
+
`${failedRows.length} row(s) still have errors. Please fix the remaining issues and try again.`
|
|
3439
3387
|
);
|
|
3388
|
+
return;
|
|
3389
|
+
}
|
|
3390
|
+
setStatusMsg("Merging corrections into feed...");
|
|
3391
|
+
const changes = {};
|
|
3392
|
+
for (const key of editedCells) {
|
|
3393
|
+
const [idxStr, col] = [key.split(":")[0], key.slice(key.indexOf(":") + 1)];
|
|
3394
|
+
const rowIdx = parseInt(idxStr, 10);
|
|
3395
|
+
const rowNum = String(rowNumbers[rowIdx]);
|
|
3396
|
+
if (!changes[rowNum]) changes[rowNum] = {};
|
|
3397
|
+
changes[rowNum][col] = rows[rowIdx][col] ?? "";
|
|
3440
3398
|
}
|
|
3399
|
+
const mergeResult = await mergeFeed(transformedUrl, feedFileType, changes);
|
|
3400
|
+
const newFileUrl = mergeResult.data.new_file_url;
|
|
3401
|
+
setStatusMsg("Validation passed!");
|
|
3402
|
+
onSubmit(
|
|
3403
|
+
{ transformedUrl: newFileUrl },
|
|
3404
|
+
"Feed corrections validated successfully."
|
|
3405
|
+
);
|
|
3441
3406
|
} catch (err) {
|
|
3442
3407
|
setErrorMsg(
|
|
3443
3408
|
`Error: ${err instanceof Error ? err.message : String(err)}`
|
|
@@ -3448,31 +3413,37 @@ function EditFeed({
|
|
|
3448
3413
|
}
|
|
3449
3414
|
}, [
|
|
3450
3415
|
rows,
|
|
3416
|
+
rowNumbers,
|
|
3451
3417
|
columns,
|
|
3418
|
+
editedCells,
|
|
3419
|
+
errorCount,
|
|
3452
3420
|
storeId,
|
|
3453
3421
|
feedFileType,
|
|
3454
|
-
|
|
3455
|
-
|
|
3456
|
-
|
|
3457
|
-
sourceMp,
|
|
3458
|
-
marketplaceOv,
|
|
3422
|
+
mappingKey,
|
|
3423
|
+
transformedUrl,
|
|
3424
|
+
skuField,
|
|
3459
3425
|
onSubmit
|
|
3460
3426
|
]);
|
|
3461
3427
|
return /* @__PURE__ */ jsxs11("div", { className: "flex flex-col gap-3", children: [
|
|
3462
3428
|
/* @__PURE__ */ jsx22("div", { className: "flex items-center justify-between px-1", children: /* @__PURE__ */ jsxs11("div", { className: "flex items-center gap-2", children: [
|
|
3463
3429
|
/* @__PURE__ */ jsx22(AlertTriangle2, { className: "h-4 w-4 text-destructive" }),
|
|
3464
3430
|
/* @__PURE__ */ jsx22("span", { className: "font-medium text-sm", children: "Feed Validation Issues" }),
|
|
3465
|
-
/* @__PURE__ */ jsxs11(Badge, { variant: "destructive", className: "text-[10px]", children: [
|
|
3431
|
+
errorCount > 0 && /* @__PURE__ */ jsxs11(Badge, { variant: "destructive", className: "text-[10px]", children: [
|
|
3466
3432
|
errorCount,
|
|
3467
3433
|
" error",
|
|
3468
3434
|
errorCount !== 1 ? "s" : ""
|
|
3469
3435
|
] }),
|
|
3436
|
+
dataIssuesRaw.length > 0 && /* @__PURE__ */ jsxs11(Badge, { variant: "outline", className: "text-[10px] border-amber-400 text-amber-600 dark:text-amber-400", children: [
|
|
3437
|
+
dataIssuesRaw.length,
|
|
3438
|
+
" warning",
|
|
3439
|
+
dataIssuesRaw.length !== 1 ? "s" : ""
|
|
3440
|
+
] }),
|
|
3470
3441
|
editedCells.size > 0 && /* @__PURE__ */ jsxs11(Badge, { variant: "secondary", className: "text-[10px]", children: [
|
|
3471
3442
|
editedCells.size,
|
|
3472
3443
|
" edited"
|
|
3473
3444
|
] })
|
|
3474
3445
|
] }) }),
|
|
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." }),
|
|
3446
|
+
/* @__PURE__ */ jsx22("p", { className: "text-xs text-muted-foreground px-1", children: errorCount > 0 ? "Click on the highlighted cells to edit their values, then submit to re-validate." : "No critical errors found. Review the warnings below and edit values if needed, or proceed." }),
|
|
3476
3447
|
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
3448
|
/* @__PURE__ */ jsx22(Loader26, { className: "h-3 w-3 animate-spin" }),
|
|
3478
3449
|
statusMsg
|
|
@@ -3508,7 +3479,7 @@ function EditFeed({
|
|
|
3508
3479
|
) }, col);
|
|
3509
3480
|
})
|
|
3510
3481
|
] }),
|
|
3511
|
-
missingAttrs && /* @__PURE__ */ jsx22("tr", { children: /* @__PURE__ */ jsx22("td", { colSpan: columns.length + 1, children: /* @__PURE__ */ jsx22(MissingAttributesBanner, { text: missingAttrs }) }) })
|
|
3482
|
+
missingAttrs && /* @__PURE__ */ jsx22("tr", { children: /* @__PURE__ */ jsx22("td", { colSpan: columns.length + 1, children: /* @__PURE__ */ jsx22(MissingAttributesBanner, { text: missingAttrs, defaultOpen: errorCount === 0 }) }) })
|
|
3512
3483
|
] }, rowIdx);
|
|
3513
3484
|
}),
|
|
3514
3485
|
rows.length === 0 && /* @__PURE__ */ jsx22(TableRow, { children: /* @__PURE__ */ jsx22(
|
|
@@ -3544,8 +3515,8 @@ function EditFeed({
|
|
|
3544
3515
|
className: "gap-1.5",
|
|
3545
3516
|
disabled: isLoading,
|
|
3546
3517
|
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"
|
|
3518
|
+
isLoading ? /* @__PURE__ */ jsx22(Loader26, { className: "h-3.5 w-3.5 animate-spin" }) : errorCount > 0 ? /* @__PURE__ */ jsx22(RefreshCw, { className: "h-3.5 w-3.5" }) : /* @__PURE__ */ jsx22(Send2, { className: "h-3.5 w-3.5" }),
|
|
3519
|
+
errorCount > 0 ? "Fix & Re-validate" : editedCells.size > 0 ? "Fix & Re-validate" : "Proceed"
|
|
3549
3520
|
]
|
|
3550
3521
|
}
|
|
3551
3522
|
)
|
|
@@ -4708,6 +4679,7 @@ function CatalogixChat(props) {
|
|
|
4708
4679
|
sourceMp: uiProps.sourceMp ?? "SMP",
|
|
4709
4680
|
marketplaceOv: uiProps.marketplaceOv ?? 34,
|
|
4710
4681
|
transformedUrl: uiProps.transformedUrl ?? "",
|
|
4682
|
+
mappingKey: uiProps.mappingKey ?? "",
|
|
4711
4683
|
submitted: props.submitted,
|
|
4712
4684
|
submittedValues: props.submittedValues,
|
|
4713
4685
|
onSubmit: (values, msg) => onSubmit(values, msg)
|
package/package.json
CHANGED