strapi-plugin-bulk-updater 1.4.3 → 1.4.9
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/_chunks/{BulkUpdater-mSvmiLwc.js → BulkUpdater-C0uPoso2.js} +1899 -481
- package/dist/_chunks/BulkUpdater-C0uPoso2.js.map +1 -0
- package/dist/_chunks/{BulkUpdater-CbQk_OQG.mjs → BulkUpdater-CHdA0546.mjs} +1902 -484
- package/dist/_chunks/BulkUpdater-CHdA0546.mjs.map +1 -0
- package/dist/admin/index.js +1 -1
- package/dist/admin/index.mjs +1 -1
- package/dist/server/index.js +1687 -677
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +1687 -677
- package/dist/server/index.mjs.map +1 -1
- package/package.json +3 -3
- package/dist/_chunks/BulkUpdater-CbQk_OQG.mjs.map +0 -1
- package/dist/_chunks/BulkUpdater-mSvmiLwc.js.map +0 -1
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { jsxs, jsx, Fragment } from "react/jsx-runtime";
|
|
2
2
|
import React__default, { useState, useEffect, useMemo, useRef } from "react";
|
|
3
3
|
import { useFetchClient, useNotification } from "@strapi/strapi/admin";
|
|
4
|
-
import { Box, Flex, Typography, Button, SingleSelect, SingleSelectOption, Badge, Checkbox, Alert, Table, Thead, Tr, Th, Tbody, Td,
|
|
5
|
-
import { ArrowClockwise, Download, Upload,
|
|
4
|
+
import { Box, Flex, Typography, Button, SingleSelect, SingleSelectOption, Badge, Checkbox, Alert, Table, Thead, Tr, Th, Tbody, Td, TextInput, Loader, ComboboxOption, Field, Combobox } from "@strapi/design-system";
|
|
5
|
+
import { ArrowClockwise, Download, Upload, ChevronLeft, ChevronRight, Eye, Check, Cog, Play } from "@strapi/icons";
|
|
6
6
|
import { i as isAbortError, V as ValidationRulesTab } from "./ValidationRulesTab-BtOCWK8E.mjs";
|
|
7
7
|
function parseCsvRows(csvText) {
|
|
8
8
|
if (!csvText) return [];
|
|
@@ -142,7 +142,7 @@ function CsvManagerTab() {
|
|
|
142
142
|
const [collections, setCollections] = useState([]);
|
|
143
143
|
const [loadingCollections, setLoadingCollections] = useState(true);
|
|
144
144
|
const [selectedUid, setSelectedUid] = useState("");
|
|
145
|
-
const [exportLimit, setExportLimit] = useState(
|
|
145
|
+
const [exportLimit, setExportLimit] = useState(0);
|
|
146
146
|
const [exportOnlyViolations, setExportOnlyViolations] = useState(false);
|
|
147
147
|
const [rules, setRules] = useState([]);
|
|
148
148
|
const [selectedRuleId, setSelectedRuleId] = useState("");
|
|
@@ -150,9 +150,20 @@ function CsvManagerTab() {
|
|
|
150
150
|
const [publishOnImport, setPublishOnImport] = useState(true);
|
|
151
151
|
const [csvRawText, setCsvRawText] = useState("");
|
|
152
152
|
const [fileName, setFileName] = useState("");
|
|
153
|
-
const [
|
|
153
|
+
const [allParsedRecords, setAllParsedRecords] = useState([]);
|
|
154
|
+
const [previewPage, setPreviewPage] = useState(1);
|
|
155
|
+
const [previewPageSize, setPreviewPageSize] = useState(10);
|
|
154
156
|
const [importing, setImporting] = useState(false);
|
|
157
|
+
const [importProgress, setImportProgress] = useState(null);
|
|
155
158
|
const [importResult, setImportResult] = useState(null);
|
|
159
|
+
const [executionWindow, setExecutionWindow] = useState(null);
|
|
160
|
+
const [preflightLoading, setPreflightLoading] = useState(false);
|
|
161
|
+
const [preflightReport, setPreflightReport] = useState(null);
|
|
162
|
+
const [showConfirmModal, setShowConfirmModal] = useState(false);
|
|
163
|
+
const [makerNotesInput, setMakerNotesInput] = useState("");
|
|
164
|
+
const [submittingBatch, setSubmittingBatch] = useState(false);
|
|
165
|
+
const [publishStrategy, setPublishStrategy] = useState("safe");
|
|
166
|
+
const [unreviewedConsent, setUnreviewedConsent] = useState(false);
|
|
156
167
|
useEffect(() => {
|
|
157
168
|
fetchInitialData();
|
|
158
169
|
}, []);
|
|
@@ -163,6 +174,9 @@ function CsvManagerTab() {
|
|
|
163
174
|
get("/bulk-updater/models"),
|
|
164
175
|
get("/bulk-updater/validation-rules")
|
|
165
176
|
]);
|
|
177
|
+
if (modelsRes.data?.executionWindow) {
|
|
178
|
+
setExecutionWindow(modelsRes.data.executionWindow);
|
|
179
|
+
}
|
|
166
180
|
if (modelsRes.data?.collections) {
|
|
167
181
|
setCollections(modelsRes.data.collections);
|
|
168
182
|
if (modelsRes.data.collections.length > 0) {
|
|
@@ -213,7 +227,7 @@ function CsvManagerTab() {
|
|
|
213
227
|
downloadCsvFile(csvStr, filename);
|
|
214
228
|
toggleNotification({
|
|
215
229
|
type: "success",
|
|
216
|
-
message:
|
|
230
|
+
message: `Collection exported successfully (${res.data?.count ?? 0} records)`
|
|
217
231
|
});
|
|
218
232
|
} catch (err) {
|
|
219
233
|
if (isAbortError(err)) return;
|
|
@@ -266,34 +280,95 @@ function CsvManagerTab() {
|
|
|
266
280
|
if (!file) return;
|
|
267
281
|
setFileName(file.name);
|
|
268
282
|
setImportResult(null);
|
|
283
|
+
setImportProgress(null);
|
|
269
284
|
const reader = new FileReader();
|
|
270
285
|
reader.onload = (event) => {
|
|
271
286
|
const text = event.target?.result;
|
|
272
287
|
setCsvRawText(text);
|
|
273
288
|
try {
|
|
274
289
|
const records = parseCsv(text);
|
|
275
|
-
|
|
290
|
+
setAllParsedRecords(records);
|
|
291
|
+
setPreviewPage(1);
|
|
276
292
|
} catch (err) {
|
|
277
|
-
|
|
293
|
+
setAllParsedRecords([]);
|
|
278
294
|
}
|
|
279
295
|
};
|
|
280
296
|
reader.readAsText(file);
|
|
281
297
|
};
|
|
282
298
|
const handleExecuteImport = async () => {
|
|
283
|
-
if (!selectedUid ||
|
|
299
|
+
if (!selectedUid || allParsedRecords.length === 0) return;
|
|
300
|
+
const totalRows = allParsedRecords.length;
|
|
301
|
+
const CHUNK_SIZE = 100;
|
|
302
|
+
const totalChunks = Math.ceil(totalRows / CHUNK_SIZE);
|
|
303
|
+
const batchId = `csv_batch_${Date.now()}_${Math.random().toString(36).substring(2, 7)}`;
|
|
284
304
|
try {
|
|
285
305
|
setImporting(true);
|
|
286
306
|
setImportResult(null);
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
307
|
+
let liveCreated = 0;
|
|
308
|
+
let liveUpdated = 0;
|
|
309
|
+
let liveSkipped = 0;
|
|
310
|
+
let liveErrors = 0;
|
|
311
|
+
let finalResultData = null;
|
|
312
|
+
setImportProgress({
|
|
313
|
+
currentChunk: 0,
|
|
314
|
+
totalChunks,
|
|
315
|
+
percent: 0,
|
|
316
|
+
processedRows: 0,
|
|
317
|
+
totalRows,
|
|
318
|
+
liveCreated: 0,
|
|
319
|
+
liveUpdated: 0,
|
|
320
|
+
liveSkipped: 0,
|
|
321
|
+
liveErrors: 0
|
|
292
322
|
});
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
const
|
|
296
|
-
|
|
323
|
+
for (let chunkIdx = 0; chunkIdx < totalChunks; chunkIdx++) {
|
|
324
|
+
const startIdx = chunkIdx * CHUNK_SIZE;
|
|
325
|
+
const endIdx = Math.min(startIdx + CHUNK_SIZE, totalRows);
|
|
326
|
+
const chunkRows = allParsedRecords.slice(startIdx, endIdx);
|
|
327
|
+
const isFirst = chunkIdx === 0;
|
|
328
|
+
const isLast = chunkIdx === totalChunks - 1;
|
|
329
|
+
const startRowNumber = startIdx + 2;
|
|
330
|
+
const res = await post("/bulk-updater/csv/import-chunk", {
|
|
331
|
+
uid: selectedUid,
|
|
332
|
+
rows: chunkRows,
|
|
333
|
+
batchId,
|
|
334
|
+
isFirstChunk: isFirst,
|
|
335
|
+
isLastChunk: isLast,
|
|
336
|
+
startRowNumber,
|
|
337
|
+
mode: importMode,
|
|
338
|
+
publish: publishOnImport,
|
|
339
|
+
publishStrategy,
|
|
340
|
+
unreviewedConsent
|
|
341
|
+
});
|
|
342
|
+
if (!res.data || !res.data.success) {
|
|
343
|
+
throw new Error(res.data?.error || `Chunk ${chunkIdx + 1} failed to process`);
|
|
344
|
+
}
|
|
345
|
+
const chunkStats = res.data.chunkStats;
|
|
346
|
+
if (chunkStats) {
|
|
347
|
+
liveCreated += chunkStats.created || 0;
|
|
348
|
+
liveUpdated += chunkStats.updated || 0;
|
|
349
|
+
liveSkipped += chunkStats.skipped || 0;
|
|
350
|
+
liveErrors += chunkStats.errors?.length || 0;
|
|
351
|
+
}
|
|
352
|
+
const currentProgressPercent = Math.round((chunkIdx + 1) / totalChunks * 100);
|
|
353
|
+
setImportProgress({
|
|
354
|
+
currentChunk: chunkIdx + 1,
|
|
355
|
+
totalChunks,
|
|
356
|
+
percent: currentProgressPercent,
|
|
357
|
+
processedRows: endIdx,
|
|
358
|
+
totalRows,
|
|
359
|
+
liveCreated,
|
|
360
|
+
liveUpdated,
|
|
361
|
+
liveSkipped,
|
|
362
|
+
liveErrors
|
|
363
|
+
});
|
|
364
|
+
if (isLast) {
|
|
365
|
+
finalResultData = res.data;
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
if (finalResultData && finalResultData.stats) {
|
|
369
|
+
setImportResult(finalResultData);
|
|
370
|
+
const stats = finalResultData.stats;
|
|
371
|
+
let notifMsg = `CSV Import complete: ${stats.created} created, ${stats.updated} updated across ${stats.total} records.`;
|
|
297
372
|
if (stats.newWithoutDocId && stats.newWithoutDocId > 0) {
|
|
298
373
|
notifMsg += ` (${stats.newWithoutDocId} new entries created due to omitted documentId)`;
|
|
299
374
|
}
|
|
@@ -301,348 +376,1018 @@ function CsvManagerTab() {
|
|
|
301
376
|
type: "success",
|
|
302
377
|
message: notifMsg
|
|
303
378
|
});
|
|
304
|
-
} else {
|
|
305
|
-
throw new Error(res.data?.error || "Import failed");
|
|
306
379
|
}
|
|
307
380
|
} catch (err) {
|
|
308
381
|
if (isAbortError(err)) return;
|
|
309
382
|
toggleNotification({
|
|
310
383
|
type: "danger",
|
|
311
|
-
message: err.message || "Error processing CSV import"
|
|
384
|
+
message: err.message || "Error processing CSV import batch"
|
|
312
385
|
});
|
|
313
386
|
} finally {
|
|
314
387
|
setImporting(false);
|
|
315
388
|
}
|
|
316
389
|
};
|
|
390
|
+
const handleRunPreflight = async () => {
|
|
391
|
+
if (!selectedUid || allParsedRecords.length === 0) return;
|
|
392
|
+
try {
|
|
393
|
+
setPreflightLoading(true);
|
|
394
|
+
const res = await post("/bulk-updater/csv/validate-preflight", {
|
|
395
|
+
uid: selectedUid,
|
|
396
|
+
rows: allParsedRecords,
|
|
397
|
+
mode: importMode
|
|
398
|
+
});
|
|
399
|
+
if (res.data && res.data.success) {
|
|
400
|
+
setPreflightReport(res.data);
|
|
401
|
+
if (res.data.hasErrors) {
|
|
402
|
+
toggleNotification({
|
|
403
|
+
type: "warning",
|
|
404
|
+
message: `Pre-flight validation: ${res.data.totalErrorCount} error(s) and ${res.data.totalWarningCount} warning(s) detected.`
|
|
405
|
+
});
|
|
406
|
+
} else if (res.data.hasWarnings) {
|
|
407
|
+
toggleNotification({
|
|
408
|
+
type: "warning",
|
|
409
|
+
message: `Pre-flight validation passed with ${res.data.totalWarningCount} warning(s).`
|
|
410
|
+
});
|
|
411
|
+
} else {
|
|
412
|
+
toggleNotification({
|
|
413
|
+
type: "success",
|
|
414
|
+
message: `Pre-flight validation passed! All ${res.data.validRows} rows are ready for import.`
|
|
415
|
+
});
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
} catch (err) {
|
|
419
|
+
if (isAbortError(err)) return;
|
|
420
|
+
toggleNotification({
|
|
421
|
+
type: "danger",
|
|
422
|
+
message: err.message || "Failed running pre-flight validation"
|
|
423
|
+
});
|
|
424
|
+
} finally {
|
|
425
|
+
setPreflightLoading(false);
|
|
426
|
+
}
|
|
427
|
+
};
|
|
428
|
+
const submitBatchWithMode = async (executionMode, forceImmediate = false) => {
|
|
429
|
+
if (!selectedUid || allParsedRecords.length === 0) return;
|
|
430
|
+
if (executionMode === "immediate") {
|
|
431
|
+
setShowConfirmModal(false);
|
|
432
|
+
await handleExecuteImport();
|
|
433
|
+
return;
|
|
434
|
+
}
|
|
435
|
+
try {
|
|
436
|
+
setSubmittingBatch(true);
|
|
437
|
+
const res = await post("/bulk-updater/csv/submit-batch", {
|
|
438
|
+
uid: selectedUid,
|
|
439
|
+
rows: allParsedRecords,
|
|
440
|
+
executionMode,
|
|
441
|
+
makerNotes: makerNotesInput,
|
|
442
|
+
forceImmediate,
|
|
443
|
+
mode: importMode,
|
|
444
|
+
publish: publishOnImport,
|
|
445
|
+
publishStrategy,
|
|
446
|
+
unreviewedConsent,
|
|
447
|
+
unreviewedCount: preflightReport?.lifecycleStats?.unreviewedCount || 0
|
|
448
|
+
});
|
|
449
|
+
setShowConfirmModal(false);
|
|
450
|
+
if (res.data && res.data.pending) {
|
|
451
|
+
setMakerNotesInput("");
|
|
452
|
+
toggleNotification({
|
|
453
|
+
type: "success",
|
|
454
|
+
message: res.data.message || "CSV batch submitted for Checker authorization."
|
|
455
|
+
});
|
|
456
|
+
} else if (res.data && res.data.executeNow) {
|
|
457
|
+
await handleExecuteImport();
|
|
458
|
+
}
|
|
459
|
+
} catch (err) {
|
|
460
|
+
if (isAbortError(err)) return;
|
|
461
|
+
toggleNotification({
|
|
462
|
+
type: "danger",
|
|
463
|
+
message: err.message || "Failed submitting CSV batch"
|
|
464
|
+
});
|
|
465
|
+
} finally {
|
|
466
|
+
setSubmittingBatch(false);
|
|
467
|
+
}
|
|
468
|
+
};
|
|
317
469
|
const selectedCol = collections.find((c) => c.uid === selectedUid);
|
|
318
|
-
return /* @__PURE__ */
|
|
319
|
-
/* @__PURE__ */ jsxs(Flex, {
|
|
320
|
-
/* @__PURE__ */ jsxs(
|
|
321
|
-
/* @__PURE__ */
|
|
322
|
-
|
|
470
|
+
return /* @__PURE__ */ jsxs(Box, { padding: 6, background: "neutral0", hasRadius: true, shadow: "filterShadow", children: [
|
|
471
|
+
/* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "stretch", gap: 6, children: [
|
|
472
|
+
/* @__PURE__ */ jsxs(Flex, { justifyContent: "space-between", alignItems: "center", children: [
|
|
473
|
+
/* @__PURE__ */ jsxs(Box, { children: [
|
|
474
|
+
/* @__PURE__ */ jsx(Typography, { variant: "beta", tag: "h2", fontWeight: "bold", children: "CSV Export & Import Center" }),
|
|
475
|
+
/* @__PURE__ */ jsx(Typography, { variant: "pi", textColor: "neutral600", children: "Export all records (including 10,000+ datasets), filtered subsets, or rule violations into CSV. Correct or add records in spreadsheets and re-upload with high-performance chunked batch processing." })
|
|
476
|
+
] }),
|
|
477
|
+
/* @__PURE__ */ jsx(Button, { variant: "secondary", startIcon: /* @__PURE__ */ jsx(ArrowClockwise, {}), onClick: fetchInitialData, children: "Refresh" })
|
|
323
478
|
] }),
|
|
324
|
-
/* @__PURE__ */ jsx(
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
479
|
+
/* @__PURE__ */ jsx(Box, { padding: 4, background: "neutral100", hasRadius: true, children: /* @__PURE__ */ jsxs(Flex, { gap: 4, alignItems: "flex-end", children: [
|
|
480
|
+
/* @__PURE__ */ jsxs(Box, { style: { flex: 1 }, children: [
|
|
481
|
+
/* @__PURE__ */ jsx(Typography, { variant: "pi", fontWeight: "bold", textColor: "neutral800", marginBottom: 2, children: "Target Collection Type" }),
|
|
482
|
+
/* @__PURE__ */ jsx(
|
|
483
|
+
SingleSelect,
|
|
484
|
+
{
|
|
485
|
+
value: selectedUid,
|
|
486
|
+
onChange: (val) => {
|
|
487
|
+
setSelectedUid(val);
|
|
488
|
+
setImportResult(null);
|
|
489
|
+
setImportProgress(null);
|
|
490
|
+
},
|
|
491
|
+
disabled: loadingCollections,
|
|
492
|
+
placeholder: "Select a collection...",
|
|
493
|
+
children: collections.map((col) => /* @__PURE__ */ jsxs(SingleSelectOption, { value: col.uid, children: [
|
|
494
|
+
col.displayName,
|
|
495
|
+
" (",
|
|
496
|
+
col.totalEntries ?? 0,
|
|
497
|
+
" records)"
|
|
498
|
+
] }, col.uid))
|
|
499
|
+
}
|
|
500
|
+
)
|
|
501
|
+
] }),
|
|
329
502
|
/* @__PURE__ */ jsx(
|
|
330
|
-
SingleSelect,
|
|
331
|
-
{
|
|
332
|
-
value: selectedUid,
|
|
333
|
-
onChange: (val) => {
|
|
334
|
-
setSelectedUid(val);
|
|
335
|
-
setImportResult(null);
|
|
336
|
-
},
|
|
337
|
-
disabled: loadingCollections,
|
|
338
|
-
placeholder: "Select a collection...",
|
|
339
|
-
children: collections.map((col) => /* @__PURE__ */ jsxs(SingleSelectOption, { value: col.uid, children: [
|
|
340
|
-
col.displayName,
|
|
341
|
-
" (",
|
|
342
|
-
col.totalEntries ?? 0,
|
|
343
|
-
" records)"
|
|
344
|
-
] }, col.uid))
|
|
345
|
-
}
|
|
346
|
-
)
|
|
347
|
-
] }),
|
|
348
|
-
/* @__PURE__ */ jsx(
|
|
349
|
-
Button,
|
|
350
|
-
{
|
|
351
|
-
variant: "tertiary",
|
|
352
|
-
startIcon: /* @__PURE__ */ jsx(Download, {}),
|
|
353
|
-
onClick: handleDownloadTemplate,
|
|
354
|
-
disabled: !selectedUid,
|
|
355
|
-
children: "Download Sample CSV Template"
|
|
356
|
-
}
|
|
357
|
-
)
|
|
358
|
-
] }) }),
|
|
359
|
-
/* @__PURE__ */ jsxs(Box, { padding: 5, background: "neutral100", hasRadius: true, children: [
|
|
360
|
-
/* @__PURE__ */ jsx(Typography, { variant: "delta", tag: "h3", fontWeight: "bold", marginBottom: 2, children: "1. Export Data to CSV" }),
|
|
361
|
-
/* @__PURE__ */ jsx(Typography, { variant: "pi", textColor: "neutral600", marginBottom: 4, children: "Extract entire collections or pinpoint records violating validation quotas." }),
|
|
362
|
-
/* @__PURE__ */ jsxs(Flex, { gap: 4, wrap: "wrap", alignItems: "center", marginTop: 3, children: [
|
|
363
|
-
/* @__PURE__ */ jsxs(
|
|
364
503
|
Button,
|
|
365
504
|
{
|
|
366
|
-
variant: "
|
|
505
|
+
variant: "tertiary",
|
|
367
506
|
startIcon: /* @__PURE__ */ jsx(Download, {}),
|
|
368
|
-
onClick:
|
|
507
|
+
onClick: handleDownloadTemplate,
|
|
369
508
|
disabled: !selectedUid,
|
|
370
|
-
children:
|
|
371
|
-
"Export All ",
|
|
372
|
-
selectedCol?.displayName || "Collection",
|
|
373
|
-
" Records (.csv)"
|
|
374
|
-
]
|
|
509
|
+
children: "Download Sample CSV Template"
|
|
375
510
|
}
|
|
376
|
-
)
|
|
377
|
-
|
|
378
|
-
|
|
511
|
+
)
|
|
512
|
+
] }) }),
|
|
513
|
+
/* @__PURE__ */ jsxs(Box, { padding: 5, background: "neutral100", hasRadius: true, children: [
|
|
514
|
+
/* @__PURE__ */ jsx(Typography, { variant: "delta", tag: "h3", fontWeight: "bold", marginBottom: 2, children: "1. Export Data to CSV" }),
|
|
515
|
+
/* @__PURE__ */ jsx(Typography, { variant: "pi", textColor: "neutral600", marginBottom: 4, children: "Extract entire collections without artificial limits (streams 10,000+ records in paged chunks) or pinpoint records violating validation quotas." }),
|
|
516
|
+
/* @__PURE__ */ jsxs(Flex, { gap: 4, wrap: "wrap", alignItems: "center", marginTop: 3, children: [
|
|
517
|
+
/* @__PURE__ */ jsx(Box, { style: { width: 220 }, children: /* @__PURE__ */ jsxs(
|
|
379
518
|
SingleSelect,
|
|
380
519
|
{
|
|
381
|
-
value:
|
|
382
|
-
onChange: (val) =>
|
|
383
|
-
placeholder: "
|
|
384
|
-
children:
|
|
385
|
-
"
|
|
386
|
-
|
|
387
|
-
|
|
520
|
+
value: String(exportLimit),
|
|
521
|
+
onChange: (val) => setExportLimit(Number(val)),
|
|
522
|
+
placeholder: "Export Limit",
|
|
523
|
+
children: [
|
|
524
|
+
/* @__PURE__ */ jsx(SingleSelectOption, { value: "0", children: "All Records (No Limit)" }),
|
|
525
|
+
/* @__PURE__ */ jsx(SingleSelectOption, { value: "10000", children: "Up to 10,000 Records" }),
|
|
526
|
+
/* @__PURE__ */ jsx(SingleSelectOption, { value: "5000", children: "Up to 5,000 Records" }),
|
|
527
|
+
/* @__PURE__ */ jsx(SingleSelectOption, { value: "1000", children: "Up to 1,000 Records" })
|
|
528
|
+
]
|
|
388
529
|
}
|
|
389
|
-
),
|
|
390
|
-
/* @__PURE__ */
|
|
530
|
+
) }),
|
|
531
|
+
/* @__PURE__ */ jsxs(
|
|
391
532
|
Button,
|
|
392
533
|
{
|
|
393
|
-
variant: "
|
|
534
|
+
variant: "default",
|
|
394
535
|
startIcon: /* @__PURE__ */ jsx(Download, {}),
|
|
395
|
-
onClick:
|
|
396
|
-
disabled: !
|
|
397
|
-
children:
|
|
536
|
+
onClick: handleExportCollection,
|
|
537
|
+
disabled: !selectedUid,
|
|
538
|
+
children: [
|
|
539
|
+
"Export ",
|
|
540
|
+
exportLimit === 0 ? "All" : `${exportLimit}`,
|
|
541
|
+
" ",
|
|
542
|
+
selectedCol?.displayName || "Collection",
|
|
543
|
+
" Records (.csv)"
|
|
544
|
+
]
|
|
398
545
|
}
|
|
399
|
-
)
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
546
|
+
),
|
|
547
|
+
rules.length > 0 && /* @__PURE__ */ jsxs(Flex, { gap: 2, alignItems: "center", style: { marginLeft: "auto" }, children: [
|
|
548
|
+
/* @__PURE__ */ jsx(
|
|
549
|
+
SingleSelect,
|
|
550
|
+
{
|
|
551
|
+
value: selectedRuleId,
|
|
552
|
+
onChange: (val) => setSelectedRuleId(val),
|
|
553
|
+
placeholder: "Select Quota Rule...",
|
|
554
|
+
children: rules.map((r) => /* @__PURE__ */ jsxs(SingleSelectOption, { value: r.id, children: [
|
|
555
|
+
"Rule: ",
|
|
556
|
+
r.name
|
|
557
|
+
] }, r.id))
|
|
558
|
+
}
|
|
559
|
+
),
|
|
560
|
+
/* @__PURE__ */ jsx(
|
|
561
|
+
Button,
|
|
562
|
+
{
|
|
563
|
+
variant: "danger-light",
|
|
564
|
+
startIcon: /* @__PURE__ */ jsx(Download, {}),
|
|
565
|
+
onClick: handleExportViolations,
|
|
566
|
+
disabled: !selectedRuleId,
|
|
567
|
+
children: "Export Violators CSV"
|
|
568
|
+
}
|
|
569
|
+
)
|
|
416
570
|
] })
|
|
417
|
-
] }),
|
|
418
|
-
/* @__PURE__ */ jsxs(Box, { children: [
|
|
419
|
-
/* @__PURE__ */ jsx(Typography, { variant: "pi", fontWeight: "bold", textColor: "neutral800", marginBottom: 1, display: "block", children: "Publish Options" }),
|
|
420
|
-
/* @__PURE__ */ jsx(
|
|
421
|
-
Checkbox,
|
|
422
|
-
{
|
|
423
|
-
checked: publishOnImport,
|
|
424
|
-
onValueChange: (val) => setPublishOnImport(val),
|
|
425
|
-
children: "Auto-publish on import"
|
|
426
|
-
}
|
|
427
|
-
)
|
|
428
571
|
] })
|
|
429
572
|
] }),
|
|
430
|
-
/* @__PURE__ */ jsxs(
|
|
431
|
-
|
|
432
|
-
{
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
573
|
+
/* @__PURE__ */ jsxs(Box, { padding: 5, background: "neutral100", hasRadius: true, children: [
|
|
574
|
+
/* @__PURE__ */ jsx(Typography, { variant: "delta", tag: "h3", fontWeight: "bold", marginBottom: 2, children: "2. Import & Batch Override CSV" }),
|
|
575
|
+
/* @__PURE__ */ jsx(Typography, { variant: "pi", textColor: "neutral600", marginBottom: 4, children: "Upload an updated CSV file (supports 10,000+ records via chunked streaming) to bulk update existing records or insert new records." }),
|
|
576
|
+
/* @__PURE__ */ jsxs(Flex, { justifyContent: "space-between", alignItems: "center", marginBottom: 4, wrap: "wrap", gap: 4, children: [
|
|
577
|
+
/* @__PURE__ */ jsxs(Box, { children: [
|
|
578
|
+
/* @__PURE__ */ jsx(Typography, { variant: "pi", fontWeight: "bold", textColor: "neutral800", marginBottom: 1, display: "block", children: "Operation Mode" }),
|
|
579
|
+
/* @__PURE__ */ jsxs(Flex, { gap: 2, alignItems: "center", wrap: "wrap", children: [
|
|
580
|
+
/* @__PURE__ */ jsx(Badge, { backgroundColor: "primary100", textColor: "primary700", children: "⚡ Smart Auto-Detect" }),
|
|
581
|
+
/* @__PURE__ */ jsxs(Typography, { variant: "pi", textColor: "neutral600", children: [
|
|
582
|
+
"Automatically updates matching records by ",
|
|
583
|
+
/* @__PURE__ */ jsx("code", { children: "documentId" }),
|
|
584
|
+
" and creates new entries when ID is omitted."
|
|
585
|
+
] })
|
|
586
|
+
] })
|
|
587
|
+
] }),
|
|
588
|
+
/* @__PURE__ */ jsxs(Box, { children: [
|
|
589
|
+
/* @__PURE__ */ jsx(Typography, { variant: "pi", fontWeight: "bold", textColor: "neutral800", marginBottom: 1, display: "block", children: "Publish Options" }),
|
|
442
590
|
/* @__PURE__ */ jsx(
|
|
443
|
-
|
|
591
|
+
Checkbox,
|
|
444
592
|
{
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
style: { display: "none" },
|
|
449
|
-
onChange: handleFileUpload
|
|
593
|
+
checked: publishOnImport,
|
|
594
|
+
onValueChange: (val) => setPublishOnImport(val),
|
|
595
|
+
children: "Auto-publish on import"
|
|
450
596
|
}
|
|
451
|
-
)
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
597
|
+
)
|
|
598
|
+
] })
|
|
599
|
+
] }),
|
|
600
|
+
/* @__PURE__ */ jsxs(
|
|
601
|
+
Box,
|
|
602
|
+
{
|
|
603
|
+
padding: 6,
|
|
604
|
+
background: "neutral0",
|
|
605
|
+
hasRadius: true,
|
|
606
|
+
style: {
|
|
607
|
+
border: "2px dashed #dcdce4",
|
|
608
|
+
textAlign: "center",
|
|
609
|
+
cursor: "pointer"
|
|
610
|
+
},
|
|
611
|
+
children: [
|
|
612
|
+
/* @__PURE__ */ jsx(
|
|
613
|
+
"input",
|
|
614
|
+
{
|
|
615
|
+
type: "file",
|
|
616
|
+
accept: ".csv",
|
|
617
|
+
id: "csv-file-input",
|
|
618
|
+
style: { display: "none" },
|
|
619
|
+
onChange: handleFileUpload
|
|
620
|
+
}
|
|
621
|
+
),
|
|
622
|
+
/* @__PURE__ */ jsxs("label", { htmlFor: "csv-file-input", style: { cursor: "pointer", display: "block" }, children: [
|
|
623
|
+
/* @__PURE__ */ jsx(Upload, { style: { width: 32, height: 32, margin: "0 auto 8px", color: "#4945ff" } }),
|
|
624
|
+
/* @__PURE__ */ jsx(Typography, { variant: "delta", fontWeight: "bold", display: "block", children: fileName ? `Selected: ${fileName}` : "Click here or drag a .csv file to upload" }),
|
|
625
|
+
/* @__PURE__ */ jsx(Typography, { variant: "pi", textColor: "neutral500", children: "UTF-8 encoded CSV matching collection schema headers" })
|
|
626
|
+
] })
|
|
627
|
+
]
|
|
628
|
+
}
|
|
629
|
+
),
|
|
630
|
+
allParsedRecords.length > 0 && (() => {
|
|
631
|
+
const totalRows = allParsedRecords.length;
|
|
632
|
+
const missingDocIdCount = allParsedRecords.filter((row) => !extractDocId(row)).length;
|
|
633
|
+
const updateCount = totalRows - missingDocIdCount;
|
|
634
|
+
const headers = Object.keys(allParsedRecords[0]);
|
|
635
|
+
const totalPages = Math.ceil(totalRows / previewPageSize) || 1;
|
|
636
|
+
const safePage = Math.min(Math.max(1, previewPage), totalPages);
|
|
637
|
+
const startIndex = (safePage - 1) * previewPageSize;
|
|
638
|
+
const endIndex = Math.min(startIndex + previewPageSize, totalRows);
|
|
639
|
+
const displayedRows = allParsedRecords.slice(startIndex, endIndex);
|
|
640
|
+
return /* @__PURE__ */ jsxs(Box, { marginTop: 4, background: "neutral0", padding: 4, hasRadius: true, children: [
|
|
641
|
+
/* @__PURE__ */ jsxs(Flex, { justifyContent: "space-between", alignItems: "center", marginBottom: 3, wrap: "wrap", gap: 2, children: [
|
|
642
|
+
/* @__PURE__ */ jsxs(Box, { children: [
|
|
643
|
+
/* @__PURE__ */ jsxs(Typography, { variant: "sigma", textColor: "neutral700", children: [
|
|
644
|
+
"FILE PREVIEW — ",
|
|
645
|
+
totalRows.toLocaleString(),
|
|
646
|
+
" RECORDS DETECTED IN CSV"
|
|
647
|
+
] }),
|
|
648
|
+
/* @__PURE__ */ jsxs(Typography, { variant: "pi", textColor: "neutral500", display: "block", children: [
|
|
649
|
+
totalRows.toLocaleString(),
|
|
650
|
+
" total row",
|
|
651
|
+
totalRows > 1 ? "s" : "",
|
|
652
|
+
" •",
|
|
653
|
+
" ",
|
|
654
|
+
updateCount > 0 ? `${updateCount.toLocaleString()} updates` : "",
|
|
655
|
+
updateCount > 0 && missingDocIdCount > 0 ? ", " : "",
|
|
656
|
+
missingDocIdCount > 0 ? `${missingDocIdCount.toLocaleString()} new entries (missing documentId)` : ""
|
|
657
|
+
] })
|
|
472
658
|
] }),
|
|
473
|
-
/* @__PURE__ */ jsxs(
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
missingDocIdCount > 0
|
|
659
|
+
/* @__PURE__ */ jsxs(Flex, { gap: 2, children: [
|
|
660
|
+
/* @__PURE__ */ jsxs(Badge, { backgroundColor: "primary100", textColor: "primary700", children: [
|
|
661
|
+
"🔄 ",
|
|
662
|
+
updateCount.toLocaleString(),
|
|
663
|
+
" Updates"
|
|
664
|
+
] }),
|
|
665
|
+
missingDocIdCount > 0 && /* @__PURE__ */ jsxs(Badge, { backgroundColor: "warning100", textColor: "warning700", children: [
|
|
666
|
+
"➕ ",
|
|
667
|
+
missingDocIdCount.toLocaleString(),
|
|
668
|
+
" New (No ID)"
|
|
669
|
+
] })
|
|
480
670
|
] })
|
|
481
671
|
] }),
|
|
482
|
-
/* @__PURE__ */ jsx(
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
672
|
+
preflightReport && /* @__PURE__ */ jsx(
|
|
673
|
+
Box,
|
|
674
|
+
{
|
|
675
|
+
marginBottom: 3,
|
|
676
|
+
padding: 4,
|
|
677
|
+
background: preflightReport.hasErrors ? "danger100" : preflightReport.hasWarnings ? "warning100" : "success100",
|
|
678
|
+
hasRadius: true,
|
|
679
|
+
style: { border: `1px solid ${preflightReport.hasErrors ? "#d9534f" : preflightReport.hasWarnings ? "#f0ad4e" : "#5cb85c"}` },
|
|
680
|
+
children: /* @__PURE__ */ jsxs(Flex, { direction: "column", gap: 2, children: [
|
|
681
|
+
/* @__PURE__ */ jsxs(Flex, { justifyContent: "space-between", alignItems: "center", wrap: "wrap", gap: 2, children: [
|
|
682
|
+
/* @__PURE__ */ jsx(Typography, { fontWeight: "bold", textColor: preflightReport.hasErrors ? "danger700" : preflightReport.hasWarnings ? "warning700" : "success700", children: preflightReport.hasErrors ? `⚠️ Pre-Flight Check: ${preflightReport.totalErrorCount} error(s) detected` : preflightReport.hasWarnings ? `⚡ Pre-Flight Check: ${preflightReport.validRows} valid rows with ${preflightReport.totalWarningCount} warning(s)` : `✅ Pre-Flight Check Passed: All ${preflightReport.validRows} rows are ready for import` }),
|
|
683
|
+
/* @__PURE__ */ jsxs(Flex, { gap: 2, children: [
|
|
684
|
+
/* @__PURE__ */ jsxs(Badge, { backgroundColor: "success100", textColor: "success700", children: [
|
|
685
|
+
"✓ ",
|
|
686
|
+
preflightReport.validRows,
|
|
687
|
+
" Valid Rows"
|
|
688
|
+
] }),
|
|
689
|
+
/* @__PURE__ */ jsxs(Badge, { backgroundColor: "primary100", textColor: "primary700", children: [
|
|
690
|
+
"🔄 ",
|
|
691
|
+
preflightReport.estimatedUpdates,
|
|
692
|
+
" Updates"
|
|
693
|
+
] }),
|
|
694
|
+
/* @__PURE__ */ jsxs(Badge, { backgroundColor: "warning100", textColor: "warning700", children: [
|
|
695
|
+
"➕ ",
|
|
696
|
+
preflightReport.estimatedCreates,
|
|
697
|
+
" New"
|
|
698
|
+
] })
|
|
699
|
+
] })
|
|
700
|
+
] }),
|
|
701
|
+
preflightReport.hasErrors && /* @__PURE__ */ jsxs(Box, { marginTop: 2, background: "neutral0", padding: 3, hasRadius: true, style: { maxHeight: 160, overflowY: "auto" }, children: [
|
|
702
|
+
/* @__PURE__ */ jsxs(Typography, { variant: "pi", fontWeight: "bold", textColor: "danger700", display: "block", marginBottom: 1, children: [
|
|
703
|
+
"Validation Errors (",
|
|
704
|
+
preflightReport.totalErrorCount,
|
|
705
|
+
"):"
|
|
706
|
+
] }),
|
|
707
|
+
preflightReport.errors.map((e, idx) => /* @__PURE__ */ jsxs(Typography, { variant: "pi", textColor: "danger700", display: "block", children: [
|
|
708
|
+
"• Row ",
|
|
709
|
+
e.row,
|
|
710
|
+
": ",
|
|
711
|
+
e.error
|
|
712
|
+
] }, idx))
|
|
713
|
+
] }),
|
|
714
|
+
preflightReport.hasWarnings && /* @__PURE__ */ jsxs(Box, { marginTop: 2, background: "neutral0", padding: 3, hasRadius: true, style: { maxHeight: 140, overflowY: "auto" }, children: [
|
|
715
|
+
/* @__PURE__ */ jsxs(Typography, { variant: "pi", fontWeight: "bold", textColor: "warning700", display: "block", marginBottom: 1, children: [
|
|
716
|
+
"Warnings (",
|
|
717
|
+
preflightReport.totalWarningCount,
|
|
718
|
+
"):"
|
|
719
|
+
] }),
|
|
720
|
+
preflightReport.warnings.map((w, idx) => /* @__PURE__ */ jsxs(Typography, { variant: "pi", textColor: "warning700", display: "block", children: [
|
|
721
|
+
"• Row ",
|
|
722
|
+
w.row,
|
|
723
|
+
": ",
|
|
724
|
+
w.warning
|
|
725
|
+
] }, idx))
|
|
726
|
+
] })
|
|
727
|
+
] })
|
|
728
|
+
}
|
|
729
|
+
),
|
|
730
|
+
missingDocIdCount > 0 && /* @__PURE__ */ jsx(Box, { marginBottom: 3, children: /* @__PURE__ */ jsx(Alert, { variant: "default", title: "Smart Auto-Detect Active", children: /* @__PURE__ */ jsxs(Typography, { variant: "omega", children: [
|
|
731
|
+
missingDocIdCount.toLocaleString(),
|
|
732
|
+
" row",
|
|
733
|
+
missingDocIdCount > 1 ? "s have" : " has",
|
|
734
|
+
" no ",
|
|
735
|
+
/* @__PURE__ */ jsx("code", { children: "documentId" }),
|
|
736
|
+
".",
|
|
737
|
+
" ",
|
|
738
|
+
"Because no documentId is provided, the engine will automatically treat them as new entries and generate new database IDs for them."
|
|
739
|
+
] }) }) }),
|
|
740
|
+
/* @__PURE__ */ jsx(Box, { style: { overflowX: "auto", maxWidth: "100%", border: "1px solid #e0e0e0", borderRadius: 4 }, children: /* @__PURE__ */ jsxs(Table, { colCount: headers.length + 1, rowCount: displayedRows.length + 1, children: [
|
|
741
|
+
/* @__PURE__ */ jsx(Thead, { children: /* @__PURE__ */ jsxs(Tr, { children: [
|
|
742
|
+
/* @__PURE__ */ jsx(Th, { style: { width: 150, minWidth: 150 }, children: /* @__PURE__ */ jsx(Typography, { variant: "sigma", children: "Detected Action" }) }),
|
|
743
|
+
headers.map((h) => /* @__PURE__ */ jsx(Th, { style: { minWidth: 160 }, children: /* @__PURE__ */ jsx(Typography, { variant: "sigma", children: h }) }, h))
|
|
744
|
+
] }) }),
|
|
745
|
+
/* @__PURE__ */ jsx(Tbody, { children: displayedRows.map((row, rIdx) => {
|
|
746
|
+
const hasDocId = !!extractDocId(row);
|
|
747
|
+
const actualRowIndex = startIndex + rIdx + 1;
|
|
748
|
+
return /* @__PURE__ */ jsxs(Tr, { children: [
|
|
749
|
+
/* @__PURE__ */ jsx(Td, { children: /* @__PURE__ */ jsxs(Flex, { direction: "column", gap: 1, children: [
|
|
750
|
+
hasDocId ? /* @__PURE__ */ jsx(Badge, { backgroundColor: "primary100", textColor: "primary700", children: "🔄 Update" }) : /* @__PURE__ */ jsx(Badge, { backgroundColor: "warning100", textColor: "warning700", children: "➕ New Entry" }),
|
|
751
|
+
/* @__PURE__ */ jsxs(Typography, { variant: "pi", textColor: "neutral500", children: [
|
|
752
|
+
"Row #",
|
|
753
|
+
actualRowIndex
|
|
754
|
+
] })
|
|
755
|
+
] }) }),
|
|
756
|
+
headers.map((h) => /* @__PURE__ */ jsx(Td, { style: { verticalAlign: "top", maxWidth: 300 }, children: (h === "documentId" || h === "id") && !row[h]?.trim() ? /* @__PURE__ */ jsx(Typography, { variant: "pi", textColor: "warning700", fontWeight: "bold", children: "(Auto-generate ID)" }) : /* @__PURE__ */ jsx(
|
|
757
|
+
Typography,
|
|
758
|
+
{
|
|
759
|
+
variant: "omega",
|
|
760
|
+
style: {
|
|
761
|
+
display: "-webkit-box",
|
|
762
|
+
WebkitLineClamp: 3,
|
|
763
|
+
WebkitBoxOrient: "vertical",
|
|
764
|
+
overflow: "hidden",
|
|
765
|
+
textOverflow: "ellipsis",
|
|
766
|
+
whiteSpace: "pre-wrap",
|
|
767
|
+
wordBreak: "break-word",
|
|
768
|
+
maxHeight: 65
|
|
769
|
+
},
|
|
770
|
+
title: row[h] || "",
|
|
771
|
+
children: row[h] || "-"
|
|
772
|
+
}
|
|
773
|
+
) }, h))
|
|
774
|
+
] }, rIdx);
|
|
775
|
+
}) })
|
|
505
776
|
] }) }),
|
|
506
|
-
/* @__PURE__ */
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
/* @__PURE__ */ jsx(
|
|
510
|
-
|
|
511
|
-
Typography,
|
|
777
|
+
/* @__PURE__ */ jsxs(Flex, { justifyContent: "space-between", alignItems: "center", marginTop: 3, wrap: "wrap", gap: 3, children: [
|
|
778
|
+
/* @__PURE__ */ jsxs(Flex, { gap: 2, alignItems: "center", children: [
|
|
779
|
+
/* @__PURE__ */ jsx(Typography, { variant: "pi", textColor: "neutral600", children: "Rows per page:" }),
|
|
780
|
+
/* @__PURE__ */ jsx(Box, { style: { width: 80 }, children: /* @__PURE__ */ jsxs(
|
|
781
|
+
SingleSelect,
|
|
512
782
|
{
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
WebkitBoxOrient: "vertical",
|
|
518
|
-
overflow: "hidden",
|
|
519
|
-
textOverflow: "ellipsis",
|
|
520
|
-
whiteSpace: "pre-wrap",
|
|
521
|
-
wordBreak: "break-word",
|
|
522
|
-
maxHeight: 65
|
|
783
|
+
value: String(previewPageSize),
|
|
784
|
+
onChange: (val) => {
|
|
785
|
+
setPreviewPageSize(Number(val));
|
|
786
|
+
setPreviewPage(1);
|
|
523
787
|
},
|
|
524
|
-
|
|
525
|
-
|
|
788
|
+
children: [
|
|
789
|
+
/* @__PURE__ */ jsx(SingleSelectOption, { value: "10", children: "10" }),
|
|
790
|
+
/* @__PURE__ */ jsx(SingleSelectOption, { value: "25", children: "25" }),
|
|
791
|
+
/* @__PURE__ */ jsx(SingleSelectOption, { value: "50", children: "50" }),
|
|
792
|
+
/* @__PURE__ */ jsx(SingleSelectOption, { value: "100", children: "100" })
|
|
793
|
+
]
|
|
526
794
|
}
|
|
527
|
-
) },
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
795
|
+
) }),
|
|
796
|
+
/* @__PURE__ */ jsxs(Typography, { variant: "pi", textColor: "neutral600", children: [
|
|
797
|
+
"Showing ",
|
|
798
|
+
startIndex + 1,
|
|
799
|
+
"–",
|
|
800
|
+
endIndex,
|
|
801
|
+
" of ",
|
|
802
|
+
totalRows.toLocaleString(),
|
|
803
|
+
" rows"
|
|
804
|
+
] })
|
|
805
|
+
] }),
|
|
806
|
+
/* @__PURE__ */ jsxs(Flex, { gap: 2, alignItems: "center", children: [
|
|
807
|
+
/* @__PURE__ */ jsx(
|
|
808
|
+
Button,
|
|
809
|
+
{
|
|
810
|
+
variant: "tertiary",
|
|
811
|
+
size: "S",
|
|
812
|
+
startIcon: /* @__PURE__ */ jsx(ChevronLeft, {}),
|
|
813
|
+
disabled: safePage <= 1 || importing,
|
|
814
|
+
onClick: () => setPreviewPage((p) => Math.max(1, p - 1)),
|
|
815
|
+
children: "Prev"
|
|
816
|
+
}
|
|
817
|
+
),
|
|
818
|
+
/* @__PURE__ */ jsxs(Typography, { variant: "pi", fontWeight: "bold", textColor: "neutral700", children: [
|
|
819
|
+
"Page ",
|
|
820
|
+
safePage,
|
|
821
|
+
" of ",
|
|
822
|
+
totalPages
|
|
823
|
+
] }),
|
|
824
|
+
/* @__PURE__ */ jsx(
|
|
825
|
+
Button,
|
|
826
|
+
{
|
|
827
|
+
variant: "tertiary",
|
|
828
|
+
size: "S",
|
|
829
|
+
endIcon: /* @__PURE__ */ jsx(ChevronRight, {}),
|
|
830
|
+
disabled: safePage >= totalPages || importing,
|
|
831
|
+
onClick: () => setPreviewPage((p) => Math.min(totalPages, p + 1)),
|
|
832
|
+
children: "Next"
|
|
833
|
+
}
|
|
834
|
+
)
|
|
835
|
+
] })
|
|
836
|
+
] }),
|
|
837
|
+
/* @__PURE__ */ jsxs(Flex, { justifyContent: "space-between", alignItems: "center", marginTop: 4, wrap: "wrap", gap: 3, children: [
|
|
838
|
+
/* @__PURE__ */ jsx(
|
|
839
|
+
Button,
|
|
840
|
+
{
|
|
841
|
+
variant: "secondary",
|
|
842
|
+
size: "L",
|
|
843
|
+
startIcon: /* @__PURE__ */ jsx(Eye, {}),
|
|
844
|
+
onClick: handleRunPreflight,
|
|
845
|
+
loading: preflightLoading,
|
|
846
|
+
disabled: importing,
|
|
847
|
+
children: "Run Pre-Flight Dry Run"
|
|
848
|
+
}
|
|
849
|
+
),
|
|
850
|
+
/* @__PURE__ */ jsxs(
|
|
851
|
+
Button,
|
|
852
|
+
{
|
|
853
|
+
variant: "default",
|
|
854
|
+
size: "L",
|
|
855
|
+
startIcon: /* @__PURE__ */ jsx(Check, {}),
|
|
856
|
+
onClick: () => {
|
|
857
|
+
setPublishStrategy("safe");
|
|
858
|
+
setUnreviewedConsent(false);
|
|
859
|
+
setShowConfirmModal(true);
|
|
860
|
+
},
|
|
861
|
+
loading: importing || submittingBatch,
|
|
862
|
+
children: [
|
|
863
|
+
"Review & Import (",
|
|
864
|
+
totalRows.toLocaleString(),
|
|
865
|
+
" Records)..."
|
|
866
|
+
]
|
|
867
|
+
}
|
|
868
|
+
)
|
|
869
|
+
] })
|
|
870
|
+
] });
|
|
871
|
+
})(),
|
|
872
|
+
importProgress && /* @__PURE__ */ jsxs(Box, { marginTop: 4, padding: 4, background: "neutral0", hasRadius: true, style: { border: "1px solid #4945ff" }, children: [
|
|
873
|
+
/* @__PURE__ */ jsxs(Flex, { justifyContent: "space-between", alignItems: "center", marginBottom: 2, children: [
|
|
874
|
+
/* @__PURE__ */ jsx(Typography, { variant: "delta", fontWeight: "bold", textColor: "primary700", children: importing ? `Processing Batch Chunk ${importProgress.currentChunk} of ${importProgress.totalChunks} (${importProgress.percent}%)` : "Batch Import Complete" }),
|
|
875
|
+
/* @__PURE__ */ jsxs(Typography, { variant: "pi", fontWeight: "bold", textColor: "neutral700", children: [
|
|
876
|
+
importProgress.processedRows.toLocaleString(),
|
|
877
|
+
" / ",
|
|
878
|
+
importProgress.totalRows.toLocaleString(),
|
|
879
|
+
" rows processed"
|
|
880
|
+
] })
|
|
881
|
+
] }),
|
|
882
|
+
/* @__PURE__ */ jsx(Box, { style: { width: "100%", height: 10, background: "#e0e0e0", borderRadius: 5, overflow: "hidden", marginBottom: 12 }, children: /* @__PURE__ */ jsx(
|
|
883
|
+
Box,
|
|
533
884
|
{
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
885
|
+
style: {
|
|
886
|
+
width: `${importProgress.percent}%`,
|
|
887
|
+
height: "100%",
|
|
888
|
+
background: importProgress.percent === 100 ? "#2f6846" : "#4945ff",
|
|
889
|
+
transition: "width 0.2s ease-in-out"
|
|
890
|
+
}
|
|
540
891
|
}
|
|
541
|
-
) })
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
{
|
|
547
|
-
variant: importResult.stats.errors.length > 0 ? "warning" : "success",
|
|
548
|
-
title: "CSV Import Results",
|
|
549
|
-
children: [
|
|
550
|
-
/* @__PURE__ */ jsxs(Typography, { variant: "omega", display: "block", marginBottom: 1, children: [
|
|
551
|
-
"Successfully processed: ",
|
|
552
|
-
/* @__PURE__ */ jsxs("strong", { children: [
|
|
553
|
-
importResult.stats.created,
|
|
554
|
-
" created"
|
|
555
|
-
] }),
|
|
556
|
-
importResult.stats.newWithoutDocId > 0 && /* @__PURE__ */ jsxs("span", { children: [
|
|
557
|
-
" (",
|
|
558
|
-
importResult.stats.newWithoutDocId,
|
|
559
|
-
" created as new entries because documentId was omitted)"
|
|
560
|
-
] }),
|
|
561
|
-
", ",
|
|
562
|
-
/* @__PURE__ */ jsxs("strong", { children: [
|
|
563
|
-
importResult.stats.updated,
|
|
564
|
-
" updated"
|
|
565
|
-
] }),
|
|
566
|
-
",",
|
|
567
|
-
" ",
|
|
568
|
-
/* @__PURE__ */ jsxs("strong", { children: [
|
|
569
|
-
importResult.stats.skipped,
|
|
570
|
-
" skipped"
|
|
571
|
-
] }),
|
|
572
|
-
" out of ",
|
|
573
|
-
importResult.stats.total,
|
|
574
|
-
" total rows."
|
|
892
|
+
) }),
|
|
893
|
+
/* @__PURE__ */ jsxs(Flex, { gap: 3, wrap: "wrap", alignItems: "center", children: [
|
|
894
|
+
/* @__PURE__ */ jsxs(Badge, { backgroundColor: "success100", textColor: "success700", children: [
|
|
895
|
+
"Created: ",
|
|
896
|
+
importProgress.liveCreated.toLocaleString()
|
|
575
897
|
] }),
|
|
576
|
-
|
|
577
|
-
"
|
|
578
|
-
|
|
579
|
-
" ",
|
|
580
|
-
importResult.stats.newWithoutDocId,
|
|
581
|
-
" row",
|
|
582
|
-
importResult.stats.newWithoutDocId > 1 ? "s" : "",
|
|
583
|
-
" had no ",
|
|
584
|
-
/* @__PURE__ */ jsx("code", { children: "documentId" }),
|
|
585
|
-
" specified in the CSV. The engine generated brand-new database entries with assigned document IDs. If you export this collection now, you will see their generated document IDs."
|
|
586
|
-
] }) }),
|
|
587
|
-
importResult.stats.errors.length > 0 && /* @__PURE__ */ jsxs(Box, { marginTop: 2, children: [
|
|
588
|
-
/* @__PURE__ */ jsxs(Typography, { variant: "pi", textColor: "danger700", fontWeight: "bold", children: [
|
|
589
|
-
"Errors encountered (",
|
|
590
|
-
importResult.stats.errors.length,
|
|
591
|
-
"):"
|
|
592
|
-
] }),
|
|
593
|
-
/* @__PURE__ */ jsx("ul", { style: { margin: "4px 0 0 16px", padding: 0 }, children: importResult.stats.errors.slice(0, 10).map((err, idx) => /* @__PURE__ */ jsx("li", { style: { marginBottom: "2px" }, children: /* @__PURE__ */ jsxs(Typography, { variant: "pi", textColor: "danger600", children: [
|
|
594
|
-
"Row ",
|
|
595
|
-
err.row,
|
|
596
|
-
": ",
|
|
597
|
-
err.error
|
|
598
|
-
] }) }, idx)) }),
|
|
599
|
-
importResult.stats.errors.length > 10 && /* @__PURE__ */ jsxs(Typography, { variant: "pi", textColor: "neutral600", style: { display: "block", marginTop: 4, fontStyle: "italic" }, children: [
|
|
600
|
-
"...and ",
|
|
601
|
-
importResult.stats.errors.length - 10,
|
|
602
|
-
" more error",
|
|
603
|
-
importResult.stats.errors.length - 10 > 1 ? "s" : ""
|
|
604
|
-
] })
|
|
898
|
+
/* @__PURE__ */ jsxs(Badge, { backgroundColor: "primary100", textColor: "primary700", children: [
|
|
899
|
+
"Updated: ",
|
|
900
|
+
importProgress.liveUpdated.toLocaleString()
|
|
605
901
|
] }),
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
902
|
+
/* @__PURE__ */ jsxs(Badge, { backgroundColor: "neutral150", textColor: "neutral700", children: [
|
|
903
|
+
"Skipped: ",
|
|
904
|
+
importProgress.liveSkipped.toLocaleString()
|
|
905
|
+
] }),
|
|
906
|
+
importProgress.liveErrors > 0 && /* @__PURE__ */ jsxs(Badge, { backgroundColor: "danger100", textColor: "danger700", children: [
|
|
907
|
+
"Errors: ",
|
|
908
|
+
importProgress.liveErrors.toLocaleString()
|
|
909
|
+
] })
|
|
910
|
+
] })
|
|
911
|
+
] }),
|
|
912
|
+
importResult && /* @__PURE__ */ jsx(Box, { marginTop: 4, children: /* @__PURE__ */ jsxs(
|
|
913
|
+
Alert,
|
|
914
|
+
{
|
|
915
|
+
variant: importResult.stats.errors.length > 0 ? "warning" : "success",
|
|
916
|
+
title: "CSV Import Results",
|
|
917
|
+
children: [
|
|
918
|
+
/* @__PURE__ */ jsxs(Typography, { variant: "omega", display: "block", marginBottom: 1, children: [
|
|
919
|
+
"Successfully processed: ",
|
|
920
|
+
/* @__PURE__ */ jsxs("strong", { children: [
|
|
921
|
+
importResult.stats.created.toLocaleString(),
|
|
922
|
+
" created"
|
|
923
|
+
] }),
|
|
924
|
+
importResult.stats.newWithoutDocId > 0 && /* @__PURE__ */ jsxs("span", { children: [
|
|
925
|
+
" (",
|
|
926
|
+
importResult.stats.newWithoutDocId.toLocaleString(),
|
|
927
|
+
" created as new entries because documentId was omitted)"
|
|
928
|
+
] }),
|
|
929
|
+
", ",
|
|
930
|
+
/* @__PURE__ */ jsxs("strong", { children: [
|
|
931
|
+
importResult.stats.updated.toLocaleString(),
|
|
932
|
+
" updated"
|
|
933
|
+
] }),
|
|
934
|
+
",",
|
|
935
|
+
" ",
|
|
936
|
+
/* @__PURE__ */ jsxs("strong", { children: [
|
|
937
|
+
importResult.stats.skipped.toLocaleString(),
|
|
938
|
+
" skipped"
|
|
939
|
+
] }),
|
|
940
|
+
" out of ",
|
|
941
|
+
importResult.stats.total.toLocaleString(),
|
|
942
|
+
" total rows."
|
|
611
943
|
] }),
|
|
612
|
-
/* @__PURE__ */ jsx(Box, {
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
return /* @__PURE__ */ jsxs(Tr, { children: [
|
|
623
|
-
/* @__PURE__ */ jsxs(Td, { children: [
|
|
624
|
-
/* @__PURE__ */ jsx(Typography, { fontWeight: "semiBold", children: d.label || d.documentId }),
|
|
625
|
-
d.documentId && /* @__PURE__ */ jsx(Typography, { variant: "pi", textColor: "neutral500", display: "block", children: d.documentId })
|
|
626
|
-
] }),
|
|
627
|
-
/* @__PURE__ */ jsx(Td, { children: /* @__PURE__ */ jsx(Badge, { backgroundColor: "secondary100", textColor: "secondary700", children: d.attribute || "field" }) }),
|
|
628
|
-
/* @__PURE__ */ jsx(Td, { children: /* @__PURE__ */ jsx(Typography, { textColor: "danger600", children: oldDisplay }) }),
|
|
629
|
-
/* @__PURE__ */ jsx(Td, { children: /* @__PURE__ */ jsx(Typography, { textColor: "success600", fontWeight: "semiBold", children: newDisplay }) })
|
|
630
|
-
] }, idx);
|
|
631
|
-
}) })
|
|
944
|
+
importResult.stats.newWithoutDocId > 0 && /* @__PURE__ */ jsx(Box, { marginTop: 2, padding: 2, background: "neutral100", hasRadius: true, children: /* @__PURE__ */ jsxs(Typography, { variant: "pi", textColor: "neutral700", children: [
|
|
945
|
+
"ℹ️ ",
|
|
946
|
+
/* @__PURE__ */ jsx("strong", { children: "Note on new entries:" }),
|
|
947
|
+
" ",
|
|
948
|
+
importResult.stats.newWithoutDocId,
|
|
949
|
+
" row",
|
|
950
|
+
importResult.stats.newWithoutDocId > 1 ? "s" : "",
|
|
951
|
+
" had no ",
|
|
952
|
+
/* @__PURE__ */ jsx("code", { children: "documentId" }),
|
|
953
|
+
" specified in the CSV. The engine generated brand-new database entries with assigned document IDs. If you export this collection now, you will see their generated document IDs."
|
|
632
954
|
] }) }),
|
|
633
|
-
importResult.stats.
|
|
634
|
-
"
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
955
|
+
importResult.stats.errors.length > 0 && /* @__PURE__ */ jsxs(Box, { marginTop: 2, children: [
|
|
956
|
+
/* @__PURE__ */ jsxs(Typography, { variant: "pi", textColor: "danger700", fontWeight: "bold", children: [
|
|
957
|
+
"Errors encountered (",
|
|
958
|
+
importResult.stats.errors.length,
|
|
959
|
+
"):"
|
|
960
|
+
] }),
|
|
961
|
+
/* @__PURE__ */ jsx("ul", { style: { margin: "4px 0 0 16px", padding: 0 }, children: importResult.stats.errors.slice(0, 10).map((err, idx) => /* @__PURE__ */ jsx("li", { style: { marginBottom: "2px" }, children: /* @__PURE__ */ jsxs(Typography, { variant: "pi", textColor: "danger600", children: [
|
|
962
|
+
"Row ",
|
|
963
|
+
err.row,
|
|
964
|
+
": ",
|
|
965
|
+
err.error
|
|
966
|
+
] }) }, idx)) }),
|
|
967
|
+
importResult.stats.errors.length > 10 && /* @__PURE__ */ jsxs(Typography, { variant: "pi", textColor: "neutral600", style: { display: "block", marginTop: 4, fontStyle: "italic" }, children: [
|
|
968
|
+
"...and ",
|
|
969
|
+
importResult.stats.errors.length - 10,
|
|
970
|
+
" more error",
|
|
971
|
+
importResult.stats.errors.length - 10 > 1 ? "s" : ""
|
|
972
|
+
] })
|
|
973
|
+
] }),
|
|
974
|
+
importResult.stats.diffs && importResult.stats.diffs.length > 0 && /* @__PURE__ */ jsxs(Box, { marginTop: 3, padding: 3, background: "neutral0", hasRadius: true, style: { border: "1px solid #dcdce4" }, children: [
|
|
975
|
+
/* @__PURE__ */ jsxs(Typography, { variant: "sigma", textColor: "neutral800", fontWeight: "bold", display: "block", marginBottom: 2, children: [
|
|
976
|
+
"CHANGES APPLIED (",
|
|
977
|
+
importResult.stats.diffs.length.toLocaleString(),
|
|
978
|
+
"):"
|
|
979
|
+
] }),
|
|
980
|
+
/* @__PURE__ */ jsx(Box, { style: { overflowX: "auto" }, children: /* @__PURE__ */ jsxs(Table, { colCount: 4, rowCount: importResult.stats.diffs.length + 1, children: [
|
|
981
|
+
/* @__PURE__ */ jsx(Thead, { children: /* @__PURE__ */ jsxs(Tr, { children: [
|
|
982
|
+
/* @__PURE__ */ jsx(Th, { children: /* @__PURE__ */ jsx(Typography, { variant: "sigma", children: "Entry / Document" }) }),
|
|
983
|
+
/* @__PURE__ */ jsx(Th, { children: /* @__PURE__ */ jsx(Typography, { variant: "sigma", children: "Attribute" }) }),
|
|
984
|
+
/* @__PURE__ */ jsx(Th, { children: /* @__PURE__ */ jsx(Typography, { variant: "sigma", children: "Previous Value" }) }),
|
|
985
|
+
/* @__PURE__ */ jsx(Th, { children: /* @__PURE__ */ jsx(Typography, { variant: "sigma", children: "Applied Value" }) })
|
|
986
|
+
] }) }),
|
|
987
|
+
/* @__PURE__ */ jsx(Tbody, { children: importResult.stats.diffs.slice(0, 10).map((d, idx) => {
|
|
988
|
+
const oldDisplay = d.oldValue !== null && d.oldValue !== void 0 ? typeof d.oldValue === "object" ? JSON.stringify(d.oldValue) : String(d.oldValue) : "(empty)";
|
|
989
|
+
const newDisplay = d.newValue !== null && d.newValue !== void 0 ? typeof d.newValue === "object" ? JSON.stringify(d.newValue) : String(d.newValue) : "(empty)";
|
|
990
|
+
return /* @__PURE__ */ jsxs(Tr, { children: [
|
|
991
|
+
/* @__PURE__ */ jsxs(Td, { children: [
|
|
992
|
+
/* @__PURE__ */ jsx(Typography, { fontWeight: "semiBold", children: d.label || d.documentId }),
|
|
993
|
+
d.documentId && /* @__PURE__ */ jsx(Typography, { variant: "pi", textColor: "neutral500", display: "block", children: d.documentId })
|
|
994
|
+
] }),
|
|
995
|
+
/* @__PURE__ */ jsx(Td, { children: /* @__PURE__ */ jsx(Badge, { backgroundColor: "secondary100", textColor: "secondary700", children: d.attribute || "field" }) }),
|
|
996
|
+
/* @__PURE__ */ jsx(Td, { children: /* @__PURE__ */ jsx(Typography, { textColor: "danger600", children: oldDisplay }) }),
|
|
997
|
+
/* @__PURE__ */ jsx(Td, { children: /* @__PURE__ */ jsx(Typography, { textColor: "success600", fontWeight: "semiBold", children: newDisplay }) })
|
|
998
|
+
] }, idx);
|
|
999
|
+
}) })
|
|
1000
|
+
] }) }),
|
|
1001
|
+
importResult.stats.diffs.length > 10 && /* @__PURE__ */ jsxs(Typography, { variant: "pi", textColor: "neutral600", style: { display: "block", marginTop: 6, fontStyle: "italic" }, children: [
|
|
1002
|
+
"...and ",
|
|
1003
|
+
importResult.stats.diffs.length - 10,
|
|
1004
|
+
" more change",
|
|
1005
|
+
importResult.stats.diffs.length - 10 > 1 ? "s" : "",
|
|
1006
|
+
" recorded in Audit Trail & Version History."
|
|
1007
|
+
] })
|
|
639
1008
|
] })
|
|
640
|
-
]
|
|
641
|
-
|
|
642
|
-
}
|
|
643
|
-
|
|
644
|
-
] })
|
|
645
|
-
|
|
1009
|
+
]
|
|
1010
|
+
}
|
|
1011
|
+
) })
|
|
1012
|
+
] })
|
|
1013
|
+
] }),
|
|
1014
|
+
showConfirmModal && /* @__PURE__ */ jsx(
|
|
1015
|
+
"div",
|
|
1016
|
+
{
|
|
1017
|
+
style: {
|
|
1018
|
+
position: "fixed",
|
|
1019
|
+
inset: 0,
|
|
1020
|
+
backgroundColor: "rgba(20, 20, 30, 0.65)",
|
|
1021
|
+
backdropFilter: "blur(2px)",
|
|
1022
|
+
display: "flex",
|
|
1023
|
+
alignItems: "center",
|
|
1024
|
+
justifyContent: "center",
|
|
1025
|
+
zIndex: 9999,
|
|
1026
|
+
padding: 16,
|
|
1027
|
+
boxSizing: "border-box",
|
|
1028
|
+
overflowY: "auto"
|
|
1029
|
+
},
|
|
1030
|
+
onClick: () => setShowConfirmModal(false),
|
|
1031
|
+
children: /* @__PURE__ */ jsxs(
|
|
1032
|
+
Box,
|
|
1033
|
+
{
|
|
1034
|
+
background: "neutral0",
|
|
1035
|
+
hasRadius: true,
|
|
1036
|
+
shadow: "popupShadow",
|
|
1037
|
+
style: {
|
|
1038
|
+
maxWidth: 680,
|
|
1039
|
+
width: "100%",
|
|
1040
|
+
maxHeight: "calc(100vh - 48px)",
|
|
1041
|
+
display: "flex",
|
|
1042
|
+
flexDirection: "column",
|
|
1043
|
+
overflow: "hidden",
|
|
1044
|
+
position: "relative",
|
|
1045
|
+
boxShadow: "0 24px 48px rgba(0, 0, 0, 0.32), 0 0 1px rgba(0, 0, 0, 0.2)"
|
|
1046
|
+
},
|
|
1047
|
+
onClick: (e) => e.stopPropagation(),
|
|
1048
|
+
children: [
|
|
1049
|
+
/* @__PURE__ */ jsx(
|
|
1050
|
+
Box,
|
|
1051
|
+
{
|
|
1052
|
+
padding: 5,
|
|
1053
|
+
background: "neutral100",
|
|
1054
|
+
style: {
|
|
1055
|
+
borderBottom: "1px solid rgba(120, 120, 150, 0.2)",
|
|
1056
|
+
flexShrink: 0
|
|
1057
|
+
},
|
|
1058
|
+
children: /* @__PURE__ */ jsx(Flex, { justifyContent: "space-between", alignItems: "center", children: /* @__PURE__ */ jsxs(Box, { children: [
|
|
1059
|
+
/* @__PURE__ */ jsx(Typography, { variant: "delta", fontWeight: "bold", children: "Confirm CSV Bulk Import" }),
|
|
1060
|
+
/* @__PURE__ */ jsx(Typography, { variant: "pi", textColor: "neutral600", display: "block", children: "Review import target, record actions, publishing mode, and execution window policies before proceeding." })
|
|
1061
|
+
] }) })
|
|
1062
|
+
}
|
|
1063
|
+
),
|
|
1064
|
+
/* @__PURE__ */ jsxs(
|
|
1065
|
+
Box,
|
|
1066
|
+
{
|
|
1067
|
+
padding: 5,
|
|
1068
|
+
style: {
|
|
1069
|
+
flex: "1 1 auto",
|
|
1070
|
+
minHeight: 0,
|
|
1071
|
+
overflowY: "auto",
|
|
1072
|
+
WebkitOverflowScrolling: "touch"
|
|
1073
|
+
},
|
|
1074
|
+
children: [
|
|
1075
|
+
/* @__PURE__ */ jsxs(Box, { padding: 4, background: "neutral100", hasRadius: true, marginBottom: 4, children: [
|
|
1076
|
+
/* @__PURE__ */ jsx(Typography, { variant: "sigma", textColor: "neutral600", marginBottom: 2, display: "block", children: "IMPORT DETAILS" }),
|
|
1077
|
+
/* @__PURE__ */ jsxs(Flex, { direction: "column", gap: 2, children: [
|
|
1078
|
+
/* @__PURE__ */ jsxs(Flex, { justifyContent: "space-between", alignItems: "center", children: [
|
|
1079
|
+
/* @__PURE__ */ jsx(Typography, { fontWeight: "semiBold", children: "Target Collection:" }),
|
|
1080
|
+
/* @__PURE__ */ jsx(Badge, { backgroundColor: "primary100", textColor: "primary700", children: selectedCol?.displayName || selectedUid })
|
|
1081
|
+
] }),
|
|
1082
|
+
/* @__PURE__ */ jsxs(Flex, { justifyContent: "space-between", alignItems: "center", children: [
|
|
1083
|
+
/* @__PURE__ */ jsx(Typography, { fontWeight: "semiBold", children: "Total Detected Records:" }),
|
|
1084
|
+
/* @__PURE__ */ jsxs(Typography, { fontWeight: "bold", textColor: "primary600", children: [
|
|
1085
|
+
allParsedRecords.length.toLocaleString(),
|
|
1086
|
+
" records"
|
|
1087
|
+
] })
|
|
1088
|
+
] }),
|
|
1089
|
+
/* @__PURE__ */ jsxs(Flex, { justifyContent: "space-between", alignItems: "center", children: [
|
|
1090
|
+
/* @__PURE__ */ jsx(Typography, { fontWeight: "semiBold", children: "Action Breakdown:" }),
|
|
1091
|
+
/* @__PURE__ */ jsxs(Flex, { gap: 2, children: [
|
|
1092
|
+
/* @__PURE__ */ jsxs(Badge, { backgroundColor: "primary100", textColor: "primary700", children: [
|
|
1093
|
+
"🔄 ",
|
|
1094
|
+
allParsedRecords.filter((r) => !!extractDocId(r)).length.toLocaleString(),
|
|
1095
|
+
" Updates"
|
|
1096
|
+
] }),
|
|
1097
|
+
/* @__PURE__ */ jsxs(Badge, { backgroundColor: "warning100", textColor: "warning700", children: [
|
|
1098
|
+
"➕ ",
|
|
1099
|
+
allParsedRecords.filter((r) => !extractDocId(r)).length.toLocaleString(),
|
|
1100
|
+
" New (No ID)"
|
|
1101
|
+
] })
|
|
1102
|
+
] })
|
|
1103
|
+
] }),
|
|
1104
|
+
/* @__PURE__ */ jsxs(Flex, { justifyContent: "space-between", alignItems: "center", children: [
|
|
1105
|
+
/* @__PURE__ */ jsx(Typography, { fontWeight: "semiBold", children: "Import Mode:" }),
|
|
1106
|
+
/* @__PURE__ */ jsx(Badge, { backgroundColor: "neutral200", textColor: "neutral800", children: importMode === "update" ? "Update Only (Exact Document IDs)" : importMode === "create_or_override" ? "Create or Override" : "Smart Auto-Detect" })
|
|
1107
|
+
] }),
|
|
1108
|
+
/* @__PURE__ */ jsxs(Flex, { justifyContent: "space-between", alignItems: "center", children: [
|
|
1109
|
+
/* @__PURE__ */ jsx(Typography, { fontWeight: "semiBold", children: "Publishing Mode:" }),
|
|
1110
|
+
/* @__PURE__ */ jsx(
|
|
1111
|
+
Badge,
|
|
1112
|
+
{
|
|
1113
|
+
backgroundColor: publishOnImport ? "success100" : "warning100",
|
|
1114
|
+
textColor: publishOnImport ? "success700" : "warning700",
|
|
1115
|
+
children: publishOnImport ? "Publish Immediately" : "Keep as Draft"
|
|
1116
|
+
}
|
|
1117
|
+
)
|
|
1118
|
+
] }),
|
|
1119
|
+
preflightReport && /* @__PURE__ */ jsxs(Flex, { justifyContent: "space-between", alignItems: "center", marginTop: 2, paddingTop: 2, style: { borderTop: "1px solid #eaeaef" }, children: [
|
|
1120
|
+
/* @__PURE__ */ jsx(Typography, { variant: "pi", textColor: "neutral600", children: "Pre-Flight Status:" }),
|
|
1121
|
+
/* @__PURE__ */ jsx(
|
|
1122
|
+
Typography,
|
|
1123
|
+
{
|
|
1124
|
+
variant: "pi",
|
|
1125
|
+
fontWeight: "bold",
|
|
1126
|
+
textColor: preflightReport.hasErrors ? "danger700" : preflightReport.hasWarnings ? "warning700" : "success700",
|
|
1127
|
+
children: preflightReport.hasErrors ? `⚠️ ${preflightReport.totalErrorCount} errors found` : preflightReport.hasWarnings ? `⚡ Passed with ${preflightReport.totalWarningCount} warnings` : "✅ 100% Passed"
|
|
1128
|
+
}
|
|
1129
|
+
)
|
|
1130
|
+
] })
|
|
1131
|
+
] })
|
|
1132
|
+
] }),
|
|
1133
|
+
preflightReport?.lifecycleStats && preflightReport.lifecycleStats.isDraftAndPublish && /* @__PURE__ */ jsxs(Box, { marginBottom: 4, padding: 3, background: "neutral100", hasRadius: true, style: { border: "1px solid rgba(120, 120, 150, 0.15)" }, children: [
|
|
1134
|
+
/* @__PURE__ */ jsxs(Typography, { variant: "sigma", textColor: "neutral600", marginBottom: 2, display: "block", children: [
|
|
1135
|
+
"LIFECYCLE STATUS BREAKDOWN (",
|
|
1136
|
+
preflightReport.lifecycleStats.totalChecked,
|
|
1137
|
+
" Existing Records)"
|
|
1138
|
+
] }),
|
|
1139
|
+
/* @__PURE__ */ jsxs(Flex, { gap: 2, wrap: "wrap", children: [
|
|
1140
|
+
/* @__PURE__ */ jsxs(Badge, { backgroundColor: "success100", textColor: "success700", children: [
|
|
1141
|
+
"✓ Published / Approved: ",
|
|
1142
|
+
preflightReport.lifecycleStats.published
|
|
1143
|
+
] }),
|
|
1144
|
+
preflightReport.lifecycleStats.modified > 0 && /* @__PURE__ */ jsxs(Badge, { backgroundColor: "primary100", textColor: "primary700", children: [
|
|
1145
|
+
"📝 Modified (Unreviewed Revisions): ",
|
|
1146
|
+
preflightReport.lifecycleStats.modified
|
|
1147
|
+
] }),
|
|
1148
|
+
preflightReport.lifecycleStats.draft > 0 && /* @__PURE__ */ jsxs(Badge, { backgroundColor: "neutral200", textColor: "neutral800", children: [
|
|
1149
|
+
"📄 Draft (Never Published): ",
|
|
1150
|
+
preflightReport.lifecycleStats.draft
|
|
1151
|
+
] })
|
|
1152
|
+
] })
|
|
1153
|
+
] }),
|
|
1154
|
+
/* @__PURE__ */ jsx(Box, { padding: 4, hasRadius: true, marginBottom: 4, background: executionWindow?.isBusinessHours ? "warning100" : "success100", children: /* @__PURE__ */ jsxs(Flex, { direction: "column", gap: 1, children: [
|
|
1155
|
+
/* @__PURE__ */ jsx(Flex, { gap: 2, alignItems: "center", children: /* @__PURE__ */ jsx(Typography, { fontWeight: "bold", textColor: executionWindow?.isBusinessHours ? "warning700" : "success700", children: executionWindow?.isBusinessHours ? "⏰ Peak Business Hours Restriction Active" : "✅ Server Off-Peak Window Active" }) }),
|
|
1156
|
+
/* @__PURE__ */ jsx(Typography, { variant: "pi", textColor: executionWindow?.isBusinessHours ? "warning700" : "success700", children: executionWindow?.policyMessage || (executionWindow?.isBusinessHours ? "Server policy restricts bulk operations during peak business hours (09:00 - 18:00). Direct execution is paused to preserve API throughput." : "Currently outside peak business hours. Direct execution is permitted.") })
|
|
1157
|
+
] }) }),
|
|
1158
|
+
/* @__PURE__ */ jsx(
|
|
1159
|
+
Box,
|
|
1160
|
+
{
|
|
1161
|
+
padding: 4,
|
|
1162
|
+
background: "neutral100",
|
|
1163
|
+
hasRadius: true,
|
|
1164
|
+
marginBottom: 4,
|
|
1165
|
+
style: { border: "1px solid rgba(120, 120, 150, 0.15)" },
|
|
1166
|
+
children: /* @__PURE__ */ jsxs(Flex, { gap: 3, alignItems: "flex-start", children: [
|
|
1167
|
+
/* @__PURE__ */ jsx(
|
|
1168
|
+
Checkbox,
|
|
1169
|
+
{
|
|
1170
|
+
checked: publishOnImport,
|
|
1171
|
+
onValueChange: (val) => setPublishOnImport(Boolean(val))
|
|
1172
|
+
}
|
|
1173
|
+
),
|
|
1174
|
+
/* @__PURE__ */ jsxs(Box, { style: { cursor: "pointer" }, onClick: () => setPublishOnImport(!publishOnImport), children: [
|
|
1175
|
+
/* @__PURE__ */ jsx(Typography, { fontWeight: "bold", display: "block", children: "Publish immediately upon checker approval / execution" }),
|
|
1176
|
+
/* @__PURE__ */ jsx(Typography, { variant: "pi", textColor: "neutral600", children: "When checked (default), content types with Draft & Publish enabled will have their updated documents published immediately upon execution. When unchecked, changes remain in Draft for further editorial review." })
|
|
1177
|
+
] })
|
|
1178
|
+
] })
|
|
1179
|
+
}
|
|
1180
|
+
),
|
|
1181
|
+
publishOnImport && (preflightReport?.lifecycleStats?.unreviewedCount ?? 0) > 0 && /* @__PURE__ */ jsxs(
|
|
1182
|
+
Box,
|
|
1183
|
+
{
|
|
1184
|
+
padding: 4,
|
|
1185
|
+
background: "neutral100",
|
|
1186
|
+
hasRadius: true,
|
|
1187
|
+
marginBottom: 4,
|
|
1188
|
+
style: { border: "1px solid #d9d8ff" },
|
|
1189
|
+
children: [
|
|
1190
|
+
/* @__PURE__ */ jsx(Typography, { variant: "sigma", textColor: "neutral600", marginBottom: 3, display: "block", children: "PUBLISHING STRATEGY & GOVERNANCE CONSENT" }),
|
|
1191
|
+
/* @__PURE__ */ jsxs(Flex, { direction: "column", gap: 3, children: [
|
|
1192
|
+
/* @__PURE__ */ jsx(
|
|
1193
|
+
Box,
|
|
1194
|
+
{
|
|
1195
|
+
padding: 3,
|
|
1196
|
+
hasRadius: true,
|
|
1197
|
+
style: {
|
|
1198
|
+
border: publishStrategy === "safe" ? "2px solid #4945ff" : "1px solid #eaeaef",
|
|
1199
|
+
backgroundColor: publishStrategy === "safe" ? "#f0f0ff" : "#ffffff",
|
|
1200
|
+
cursor: "pointer"
|
|
1201
|
+
},
|
|
1202
|
+
onClick: () => {
|
|
1203
|
+
setPublishStrategy("safe");
|
|
1204
|
+
setUnreviewedConsent(false);
|
|
1205
|
+
},
|
|
1206
|
+
children: /* @__PURE__ */ jsxs(Flex, { gap: 2, alignItems: "flex-start", children: [
|
|
1207
|
+
/* @__PURE__ */ jsx(
|
|
1208
|
+
"input",
|
|
1209
|
+
{
|
|
1210
|
+
type: "radio",
|
|
1211
|
+
id: "csv-strategy-safe",
|
|
1212
|
+
name: "csvPublishStrategy",
|
|
1213
|
+
checked: publishStrategy === "safe",
|
|
1214
|
+
onChange: () => {
|
|
1215
|
+
setPublishStrategy("safe");
|
|
1216
|
+
setUnreviewedConsent(false);
|
|
1217
|
+
},
|
|
1218
|
+
style: { marginTop: 3 }
|
|
1219
|
+
}
|
|
1220
|
+
),
|
|
1221
|
+
/* @__PURE__ */ jsxs(Box, { children: [
|
|
1222
|
+
/* @__PURE__ */ jsx(Typography, { fontWeight: "bold", display: "block", children: "🛡️ Safe Publishing (Recommended)" }),
|
|
1223
|
+
/* @__PURE__ */ jsxs(Typography, { variant: "pi", textColor: "neutral600", children: [
|
|
1224
|
+
"Only publish records that are already approved & live (",
|
|
1225
|
+
preflightReport?.lifecycleStats?.published ?? 0,
|
|
1226
|
+
" record",
|
|
1227
|
+
(preflightReport?.lifecycleStats?.published ?? 0) === 1 ? "" : "s",
|
|
1228
|
+
"). The ",
|
|
1229
|
+
preflightReport?.lifecycleStats?.unreviewedCount ?? 0,
|
|
1230
|
+
" unreviewed or draft record(s) will receive the CSV update in Draft mode without publishing unreviewed draft revisions to visitors."
|
|
1231
|
+
] })
|
|
1232
|
+
] })
|
|
1233
|
+
] })
|
|
1234
|
+
}
|
|
1235
|
+
),
|
|
1236
|
+
/* @__PURE__ */ jsx(
|
|
1237
|
+
Box,
|
|
1238
|
+
{
|
|
1239
|
+
padding: 3,
|
|
1240
|
+
hasRadius: true,
|
|
1241
|
+
style: {
|
|
1242
|
+
border: publishStrategy === "all" ? "2px solid #d02b20" : "1px solid #eaeaef",
|
|
1243
|
+
backgroundColor: publishStrategy === "all" ? "#fff5f5" : "#ffffff",
|
|
1244
|
+
cursor: "pointer"
|
|
1245
|
+
},
|
|
1246
|
+
onClick: () => setPublishStrategy("all"),
|
|
1247
|
+
children: /* @__PURE__ */ jsxs(Flex, { gap: 2, alignItems: "flex-start", children: [
|
|
1248
|
+
/* @__PURE__ */ jsx(
|
|
1249
|
+
"input",
|
|
1250
|
+
{
|
|
1251
|
+
type: "radio",
|
|
1252
|
+
id: "csv-strategy-all",
|
|
1253
|
+
name: "csvPublishStrategy",
|
|
1254
|
+
checked: publishStrategy === "all",
|
|
1255
|
+
onChange: () => setPublishStrategy("all"),
|
|
1256
|
+
style: { marginTop: 3 }
|
|
1257
|
+
}
|
|
1258
|
+
),
|
|
1259
|
+
/* @__PURE__ */ jsxs(Box, { children: [
|
|
1260
|
+
/* @__PURE__ */ jsx(Typography, { fontWeight: "bold", textColor: "danger700", display: "block", children: "⚠️ Publish All Imported Records (Includes Unreviewed Drafts)" }),
|
|
1261
|
+
/* @__PURE__ */ jsxs(Typography, { variant: "pi", textColor: "neutral600", children: [
|
|
1262
|
+
"Publish all affected records live to production immediately, pushing all pending unreviewed draft edits in the ",
|
|
1263
|
+
preflightReport?.lifecycleStats?.unreviewedCount ?? 0,
|
|
1264
|
+
" draft/modified record(s) live."
|
|
1265
|
+
] })
|
|
1266
|
+
] })
|
|
1267
|
+
] })
|
|
1268
|
+
}
|
|
1269
|
+
),
|
|
1270
|
+
publishStrategy === "all" && /* @__PURE__ */ jsx(
|
|
1271
|
+
Box,
|
|
1272
|
+
{
|
|
1273
|
+
padding: 3,
|
|
1274
|
+
background: "danger100",
|
|
1275
|
+
hasRadius: true,
|
|
1276
|
+
style: { border: "1px solid #f5c0b8" },
|
|
1277
|
+
children: /* @__PURE__ */ jsxs(Flex, { gap: 3, alignItems: "flex-start", children: [
|
|
1278
|
+
/* @__PURE__ */ jsx(
|
|
1279
|
+
Checkbox,
|
|
1280
|
+
{
|
|
1281
|
+
checked: unreviewedConsent,
|
|
1282
|
+
onValueChange: (checked) => setUnreviewedConsent(Boolean(checked))
|
|
1283
|
+
}
|
|
1284
|
+
),
|
|
1285
|
+
/* @__PURE__ */ jsxs(Box, { style: { cursor: "pointer" }, onClick: () => setUnreviewedConsent(!unreviewedConsent), children: [
|
|
1286
|
+
/* @__PURE__ */ jsx(Typography, { fontWeight: "bold", textColor: "danger700", display: "block", children: "Mandatory Risk Consent Required" }),
|
|
1287
|
+
/* @__PURE__ */ jsxs(Typography, { variant: "pi", textColor: "danger700", children: [
|
|
1288
|
+
"I understand and explicitly consent that ",
|
|
1289
|
+
preflightReport?.lifecycleStats?.unreviewedCount ?? 0,
|
|
1290
|
+
" record(s) with unreviewed draft revisions or saved draft states will be published live to production visitors."
|
|
1291
|
+
] })
|
|
1292
|
+
] })
|
|
1293
|
+
] })
|
|
1294
|
+
}
|
|
1295
|
+
)
|
|
1296
|
+
] })
|
|
1297
|
+
]
|
|
1298
|
+
}
|
|
1299
|
+
),
|
|
1300
|
+
/* @__PURE__ */ jsx(Box, { marginBottom: 2, children: /* @__PURE__ */ jsx(
|
|
1301
|
+
TextInput,
|
|
1302
|
+
{
|
|
1303
|
+
label: "Change Request / Release Notes (Optional)",
|
|
1304
|
+
name: "makerNotes",
|
|
1305
|
+
placeholder: "e.g. REL-5040: Bulk updating catalog attributes via CSV",
|
|
1306
|
+
value: makerNotesInput,
|
|
1307
|
+
onChange: (e) => setMakerNotesInput(e.target.value)
|
|
1308
|
+
}
|
|
1309
|
+
) })
|
|
1310
|
+
]
|
|
1311
|
+
}
|
|
1312
|
+
),
|
|
1313
|
+
(() => {
|
|
1314
|
+
const isConsentRequired = publishOnImport && (preflightReport?.lifecycleStats?.unreviewedCount ?? 0) > 0 && publishStrategy === "all" && !unreviewedConsent;
|
|
1315
|
+
return /* @__PURE__ */ jsx(
|
|
1316
|
+
Box,
|
|
1317
|
+
{
|
|
1318
|
+
padding: 4,
|
|
1319
|
+
background: "neutral100",
|
|
1320
|
+
style: {
|
|
1321
|
+
borderTop: "1px solid rgba(120, 120, 150, 0.2)",
|
|
1322
|
+
flexShrink: 0,
|
|
1323
|
+
position: "sticky",
|
|
1324
|
+
bottom: 0,
|
|
1325
|
+
zIndex: 20,
|
|
1326
|
+
boxShadow: "0 -4px 16px rgba(0, 0, 0, 0.08)"
|
|
1327
|
+
},
|
|
1328
|
+
children: /* @__PURE__ */ jsxs(Flex, { justifyContent: "space-between", alignItems: "center", gap: 3, style: { width: "100%" }, children: [
|
|
1329
|
+
/* @__PURE__ */ jsx(Button, { variant: "tertiary", size: "M", onClick: () => setShowConfirmModal(false), children: "Cancel" }),
|
|
1330
|
+
/* @__PURE__ */ jsxs(Flex, { gap: 2, wrap: "wrap", justifyContent: "flex-end", alignItems: "center", children: [
|
|
1331
|
+
/* @__PURE__ */ jsx(
|
|
1332
|
+
Button,
|
|
1333
|
+
{
|
|
1334
|
+
variant: executionWindow?.isBusinessHours ? "default" : "secondary",
|
|
1335
|
+
size: "M",
|
|
1336
|
+
onClick: () => submitBatchWithMode("maker_checker"),
|
|
1337
|
+
loading: submittingBatch,
|
|
1338
|
+
disabled: isConsentRequired,
|
|
1339
|
+
children: "Submit for Checker Approval"
|
|
1340
|
+
}
|
|
1341
|
+
),
|
|
1342
|
+
executionWindow?.isBusinessHours ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1343
|
+
/* @__PURE__ */ jsxs(
|
|
1344
|
+
Button,
|
|
1345
|
+
{
|
|
1346
|
+
variant: "secondary",
|
|
1347
|
+
size: "M",
|
|
1348
|
+
onClick: () => submitBatchWithMode("queue_offpeak"),
|
|
1349
|
+
loading: submittingBatch,
|
|
1350
|
+
disabled: isConsentRequired,
|
|
1351
|
+
children: [
|
|
1352
|
+
"Queue for Off-Peak (",
|
|
1353
|
+
executionWindow?.offPeakStartTime || "18:00",
|
|
1354
|
+
")"
|
|
1355
|
+
]
|
|
1356
|
+
}
|
|
1357
|
+
),
|
|
1358
|
+
/* @__PURE__ */ jsx(
|
|
1359
|
+
Button,
|
|
1360
|
+
{
|
|
1361
|
+
variant: "danger-light",
|
|
1362
|
+
size: "S",
|
|
1363
|
+
onClick: () => submitBatchWithMode("immediate", true),
|
|
1364
|
+
loading: importing,
|
|
1365
|
+
disabled: isConsentRequired,
|
|
1366
|
+
children: "Force Run Now"
|
|
1367
|
+
}
|
|
1368
|
+
)
|
|
1369
|
+
] }) : /* @__PURE__ */ jsx(
|
|
1370
|
+
Button,
|
|
1371
|
+
{
|
|
1372
|
+
variant: "default",
|
|
1373
|
+
size: "M",
|
|
1374
|
+
onClick: () => submitBatchWithMode("immediate"),
|
|
1375
|
+
loading: importing,
|
|
1376
|
+
disabled: isConsentRequired,
|
|
1377
|
+
children: "Confirm & Execute Now"
|
|
1378
|
+
}
|
|
1379
|
+
)
|
|
1380
|
+
] })
|
|
1381
|
+
] })
|
|
1382
|
+
}
|
|
1383
|
+
);
|
|
1384
|
+
})()
|
|
1385
|
+
]
|
|
1386
|
+
}
|
|
1387
|
+
)
|
|
1388
|
+
}
|
|
1389
|
+
)
|
|
1390
|
+
] });
|
|
646
1391
|
}
|
|
647
1392
|
function formatVal(v) {
|
|
648
1393
|
if (v === null || v === void 0) return "(empty)";
|
|
@@ -1274,7 +2019,8 @@ const BulkUpdatePreviewModal = ({
|
|
|
1274
2019
|
previewData,
|
|
1275
2020
|
attribute,
|
|
1276
2021
|
targetValueDisplay,
|
|
1277
|
-
publishOnApproval = true
|
|
2022
|
+
publishOnApproval = true,
|
|
2023
|
+
lifecycleStats
|
|
1278
2024
|
}) => {
|
|
1279
2025
|
const [filterTab, setFilterTab] = useState("all");
|
|
1280
2026
|
const [searchQuery, setSearchQuery] = useState("");
|
|
@@ -1377,6 +2123,17 @@ const BulkUpdatePreviewModal = ({
|
|
|
1377
2123
|
/* @__PURE__ */ jsx(Typography, { variant: "delta", fontWeight: "semiBold", children: "Inspecting Target Records..." }),
|
|
1378
2124
|
/* @__PURE__ */ jsx(Typography, { variant: "pi", textColor: "neutral600", children: "Computing proposed diffs and verifying against database schema." })
|
|
1379
2125
|
] }) }) : !previewData ? /* @__PURE__ */ jsx(Box, { padding: 6, style: { textAlign: "center" }, children: /* @__PURE__ */ jsx(Typography, { textColor: "neutral600", children: "No preview data available." }) }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
2126
|
+
publishOnApproval && lifecycleStats && lifecycleStats.unreviewedCount > 0 && /* @__PURE__ */ jsx(Box, { marginBottom: 4, padding: 3, background: "warning100", hasRadius: true, style: { border: "1px solid #f5c0b8" }, children: /* @__PURE__ */ jsxs(Flex, { gap: 2, alignItems: "center", children: [
|
|
2127
|
+
/* @__PURE__ */ jsx(Typography, { variant: "pi", fontWeight: "bold", textColor: "warning700", children: "⚠️ Safe Publishing Active:" }),
|
|
2128
|
+
/* @__PURE__ */ jsxs(Typography, { variant: "pi", textColor: "warning700", children: [
|
|
2129
|
+
lifecycleStats.unreviewedCount,
|
|
2130
|
+
" target record(s) contain unreviewed draft changes (",
|
|
2131
|
+
lifecycleStats.draft,
|
|
2132
|
+
" Draft, ",
|
|
2133
|
+
lifecycleStats.modified,
|
|
2134
|
+
" Modified). By default, these will be updated as drafts without publishing unreviewed revisions to production visitors."
|
|
2135
|
+
] })
|
|
2136
|
+
] }) }),
|
|
1380
2137
|
/* @__PURE__ */ jsxs(Flex, { gap: 3, marginBottom: 4, wrap: "wrap", children: [
|
|
1381
2138
|
/* @__PURE__ */ jsxs(
|
|
1382
2139
|
Box,
|
|
@@ -1624,26 +2381,29 @@ function formatComponentName(compUid) {
|
|
|
1624
2381
|
const name = compUid.includes(".") ? compUid.split(".")[1] : compUid;
|
|
1625
2382
|
return name.split(/[-_]/).map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join(" ");
|
|
1626
2383
|
}
|
|
1627
|
-
function getAllNestedValues(obj, path) {
|
|
2384
|
+
function getAllNestedValues(obj, path, availableAttributes) {
|
|
1628
2385
|
if (!obj || !path) return [];
|
|
1629
2386
|
const parsed = parseDynamicZonePath(path);
|
|
1630
2387
|
const parts = parsed.cleanPath.split(".");
|
|
1631
2388
|
const [head, ...tail] = parts;
|
|
1632
|
-
const rootTarget = obj
|
|
2389
|
+
const rootTarget = getPropertyValue(obj, head);
|
|
1633
2390
|
if (Array.isArray(rootTarget)) {
|
|
1634
2391
|
const results = [];
|
|
1635
2392
|
rootTarget.forEach((item, idx) => {
|
|
1636
2393
|
if (!item || typeof item !== "object") return;
|
|
1637
2394
|
if (parsed.targetIndex !== void 0 && idx !== parsed.targetIndex) return;
|
|
1638
2395
|
if (parsed.targetComponentUid && item.__component !== parsed.targetComponentUid) return;
|
|
1639
|
-
const
|
|
1640
|
-
|
|
2396
|
+
const subPath = tail.join(".");
|
|
2397
|
+
const scopedPath = item.__component ? `${head}[${item.__component}].${subPath}` : "";
|
|
2398
|
+
const isSupported = availableAttributes ? availableAttributes.includes(scopedPath) : false;
|
|
2399
|
+
const subVal = tail.length > 0 ? getNestedValue(item, subPath) : item;
|
|
2400
|
+
if (subVal !== void 0 || isSupported) {
|
|
1641
2401
|
results.push({
|
|
1642
2402
|
index: idx,
|
|
1643
2403
|
componentUid: item.__component,
|
|
1644
2404
|
componentName: formatComponentName(item.__component),
|
|
1645
|
-
value: subVal,
|
|
1646
|
-
path: `${head}[#${idx}${item.__component ? ` ${formatComponentName(item.__component)}` : ""}].${
|
|
2405
|
+
value: subVal !== void 0 ? subVal : null,
|
|
2406
|
+
path: `${head}[#${idx}${item.__component ? ` ${formatComponentName(item.__component)}` : ""}].${subPath}`
|
|
1647
2407
|
});
|
|
1648
2408
|
}
|
|
1649
2409
|
});
|
|
@@ -1661,6 +2421,27 @@ function getAllNestedValues(obj, path) {
|
|
|
1661
2421
|
}
|
|
1662
2422
|
return [];
|
|
1663
2423
|
}
|
|
2424
|
+
function getPropertyValue(target, key) {
|
|
2425
|
+
if (!target || typeof target !== "object" || !key) return void 0;
|
|
2426
|
+
if (target[key] !== void 0 && target[key] !== null) return target[key];
|
|
2427
|
+
const camelKey = key.replace(/_([a-z0-9])/g, (_, letter) => letter.toUpperCase());
|
|
2428
|
+
if (target[camelKey] !== void 0 && target[camelKey] !== null) return target[camelKey];
|
|
2429
|
+
const snakeKey = key.replace(/([A-Z])/g, "_$1").toLowerCase();
|
|
2430
|
+
if (target[snakeKey] !== void 0 && target[snakeKey] !== null) return target[snakeKey];
|
|
2431
|
+
const lowerKey = key.toLowerCase();
|
|
2432
|
+
const lowerNoUnderscore = lowerKey.replace(/_/g, "");
|
|
2433
|
+
const matchedKey = Object.keys(target).find((k) => {
|
|
2434
|
+
const kLower = k.toLowerCase();
|
|
2435
|
+
return kLower === lowerKey || kLower.replace(/_/g, "") === lowerNoUnderscore;
|
|
2436
|
+
});
|
|
2437
|
+
if (matchedKey && target[matchedKey] !== void 0 && target[matchedKey] !== null) {
|
|
2438
|
+
return target[matchedKey];
|
|
2439
|
+
}
|
|
2440
|
+
if (key in target) return target[key];
|
|
2441
|
+
if (camelKey in target) return target[camelKey];
|
|
2442
|
+
if (snakeKey in target) return target[snakeKey];
|
|
2443
|
+
return void 0;
|
|
2444
|
+
}
|
|
1664
2445
|
function getNestedValue(obj, path) {
|
|
1665
2446
|
if (!obj || !path) return void 0;
|
|
1666
2447
|
const parsed = parseDynamicZonePath(path);
|
|
@@ -1677,12 +2458,12 @@ function getNestedValue(obj, path) {
|
|
|
1677
2458
|
const item = current[idx];
|
|
1678
2459
|
if (parsed.targetIndex !== void 0 && idx !== parsed.targetIndex) continue;
|
|
1679
2460
|
if (parsed.targetComponentUid && item?.__component !== parsed.targetComponentUid) continue;
|
|
1680
|
-
const found = extract(item
|
|
2461
|
+
const found = extract(getPropertyValue(item, head), tail);
|
|
1681
2462
|
if (found !== void 0 && found !== null) return found;
|
|
1682
2463
|
}
|
|
1683
2464
|
return void 0;
|
|
1684
2465
|
}
|
|
1685
|
-
return extract(current
|
|
2466
|
+
return extract(getPropertyValue(current, head), tail);
|
|
1686
2467
|
}
|
|
1687
2468
|
return extract(obj, parts);
|
|
1688
2469
|
}
|
|
@@ -1707,24 +2488,59 @@ function getAvailableColumnsForCollection(col, selectedAttribute, searchAttribut
|
|
|
1707
2488
|
return;
|
|
1708
2489
|
}
|
|
1709
2490
|
let formattedLabel = attr;
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
formattedLabel =
|
|
1716
|
-
} else if (attr.includes(".")) {
|
|
1717
|
-
formattedLabel = attr.split(".").map((s) => s.charAt(0).toUpperCase() + s.slice(1)).join(" > ");
|
|
2491
|
+
if (attr === "updated_at" || attr === "updatedAt") {
|
|
2492
|
+
formattedLabel = "Updated At";
|
|
2493
|
+
} else if (attr === "created_at" || attr === "createdAt") {
|
|
2494
|
+
formattedLabel = "Created At";
|
|
2495
|
+
} else if (attr === "published_at" || attr === "publishedAt") {
|
|
2496
|
+
formattedLabel = "Published At";
|
|
1718
2497
|
} else {
|
|
1719
|
-
|
|
2498
|
+
const bracketMatch = attr.match(/^([^.[]+)\[([^\]]+)\]\.(.+)$/);
|
|
2499
|
+
if (bracketMatch) {
|
|
2500
|
+
const root = bracketMatch[1].charAt(0).toUpperCase() + bracketMatch[1].slice(1);
|
|
2501
|
+
const comp = formatComponentName(bracketMatch[2]);
|
|
2502
|
+
const sub = bracketMatch[3].split(".").map((s) => s.charAt(0).toUpperCase() + s.slice(1)).join(" > ");
|
|
2503
|
+
formattedLabel = `${root} [${comp}] > ${sub}`;
|
|
2504
|
+
} else if (attr.includes(".")) {
|
|
2505
|
+
formattedLabel = attr.split(".").map((s) => s.charAt(0).toUpperCase() + s.slice(1)).join(" > ");
|
|
2506
|
+
} else {
|
|
2507
|
+
formattedLabel = attr.replace(/_/g, " ").replace(/\b\w/g, (l) => l.toUpperCase());
|
|
2508
|
+
}
|
|
1720
2509
|
}
|
|
1721
2510
|
cols.push({
|
|
1722
2511
|
key: `attr_${attr}`,
|
|
1723
2512
|
label: formattedLabel,
|
|
1724
2513
|
sortable: !col.isSingleType,
|
|
1725
|
-
defaultVisible: ["department", "email", "location"].includes(attr)
|
|
2514
|
+
defaultVisible: ["department", "email", "location", "updated_at", "updatedAt"].includes(attr)
|
|
1726
2515
|
});
|
|
1727
2516
|
});
|
|
2517
|
+
const hasUpdatedAt = candidateAttrs.some((a) => a === "updatedAt" || a === "updated_at");
|
|
2518
|
+
const hasCreatedAt = candidateAttrs.some((a) => a === "createdAt" || a === "created_at");
|
|
2519
|
+
const hasPublishedAt = candidateAttrs.some((a) => a === "publishedAt" || a === "published_at");
|
|
2520
|
+
if (!hasUpdatedAt) {
|
|
2521
|
+
cols.push({
|
|
2522
|
+
key: "attr_updatedAt",
|
|
2523
|
+
label: "Updated At",
|
|
2524
|
+
sortable: !col.isSingleType,
|
|
2525
|
+
defaultVisible: false
|
|
2526
|
+
});
|
|
2527
|
+
}
|
|
2528
|
+
if (!hasCreatedAt) {
|
|
2529
|
+
cols.push({
|
|
2530
|
+
key: "attr_createdAt",
|
|
2531
|
+
label: "Created At",
|
|
2532
|
+
sortable: !col.isSingleType,
|
|
2533
|
+
defaultVisible: false
|
|
2534
|
+
});
|
|
2535
|
+
}
|
|
2536
|
+
if (!hasPublishedAt && col.draftAndPublish) {
|
|
2537
|
+
cols.push({
|
|
2538
|
+
key: "attr_publishedAt",
|
|
2539
|
+
label: "Published At",
|
|
2540
|
+
sortable: !col.isSingleType,
|
|
2541
|
+
defaultVisible: false
|
|
2542
|
+
});
|
|
2543
|
+
}
|
|
1728
2544
|
if (searchAttribute && searchAttribute !== selectedAttribute) {
|
|
1729
2545
|
let formattedSearchLabel = searchAttribute;
|
|
1730
2546
|
const bracketMatch = searchAttribute.match(/^([^.[]+)\[([^\]]+)\]\.(.+)$/);
|
|
@@ -1770,11 +2586,136 @@ function getAvailableColumnsForCollection(col, selectedAttribute, searchAttribut
|
|
|
1770
2586
|
});
|
|
1771
2587
|
return cols;
|
|
1772
2588
|
}
|
|
2589
|
+
function getActiveSortLabel(currentSort, col) {
|
|
2590
|
+
const f = currentSort.field;
|
|
2591
|
+
const o = currentSort.order;
|
|
2592
|
+
const dir = o === "asc" ? "▲" : "▼";
|
|
2593
|
+
if (f === "updatedAt" || f === "updated_at") {
|
|
2594
|
+
return `Updated: ${o === "desc" ? "Newest" : "Oldest"} ${dir}`;
|
|
2595
|
+
}
|
|
2596
|
+
if (f === "createdAt" || f === "created_at") {
|
|
2597
|
+
return `Created: ${o === "desc" ? "Newest" : "Oldest"} ${dir}`;
|
|
2598
|
+
}
|
|
2599
|
+
if (f === "publishedAt" || f === "published_at") {
|
|
2600
|
+
return `Published: ${o === "desc" ? "Newest" : "Oldest"} ${dir}`;
|
|
2601
|
+
}
|
|
2602
|
+
if (f === "id") {
|
|
2603
|
+
return `ID: ${o === "desc" ? "Highest" : "Lowest"} ${dir}`;
|
|
2604
|
+
}
|
|
2605
|
+
let attrLabel = f;
|
|
2606
|
+
if (f.includes(".")) {
|
|
2607
|
+
attrLabel = f.split(".").map((s) => s.charAt(0).toUpperCase() + s.slice(1)).join(" > ");
|
|
2608
|
+
} else {
|
|
2609
|
+
attrLabel = f.replace(/_/g, " ").replace(/\b\w/g, (l) => l.toUpperCase());
|
|
2610
|
+
}
|
|
2611
|
+
return `${attrLabel} (${o === "asc" ? "A → Z" : "Z → A"} ${dir})`;
|
|
2612
|
+
}
|
|
2613
|
+
function getSortOptionsForCollection(col, selectedAttribute, searchAttribute) {
|
|
2614
|
+
const options = [];
|
|
2615
|
+
const hasCustomUpdatedAt = col.attributes?.includes("updated_at");
|
|
2616
|
+
const updatedField = hasCustomUpdatedAt ? "updated_at" : "updatedAt";
|
|
2617
|
+
options.push({
|
|
2618
|
+
field: updatedField,
|
|
2619
|
+
order: "desc",
|
|
2620
|
+
label: "Updated At (Newest First ↓)",
|
|
2621
|
+
columnLabel: "Updated At",
|
|
2622
|
+
group: "timestamps"
|
|
2623
|
+
});
|
|
2624
|
+
options.push({
|
|
2625
|
+
field: updatedField,
|
|
2626
|
+
order: "asc",
|
|
2627
|
+
label: "Updated At (Oldest First ↑)",
|
|
2628
|
+
columnLabel: "Updated At",
|
|
2629
|
+
group: "timestamps"
|
|
2630
|
+
});
|
|
2631
|
+
const hasCustomCreatedAt = col.attributes?.includes("created_at");
|
|
2632
|
+
const createdField = hasCustomCreatedAt ? "created_at" : "createdAt";
|
|
2633
|
+
options.push({
|
|
2634
|
+
field: createdField,
|
|
2635
|
+
order: "desc",
|
|
2636
|
+
label: "Created At (Newest First ↓)",
|
|
2637
|
+
columnLabel: "Created At",
|
|
2638
|
+
group: "timestamps"
|
|
2639
|
+
});
|
|
2640
|
+
options.push({
|
|
2641
|
+
field: createdField,
|
|
2642
|
+
order: "asc",
|
|
2643
|
+
label: "Created At (Oldest First ↑)",
|
|
2644
|
+
columnLabel: "Created At",
|
|
2645
|
+
group: "timestamps"
|
|
2646
|
+
});
|
|
2647
|
+
if (col.draftAndPublish) {
|
|
2648
|
+
const hasCustomPublishedAt = col.attributes?.includes("published_at");
|
|
2649
|
+
const publishedField = hasCustomPublishedAt ? "published_at" : "publishedAt";
|
|
2650
|
+
options.push({
|
|
2651
|
+
field: publishedField,
|
|
2652
|
+
order: "desc",
|
|
2653
|
+
label: "Published At (Newest First ↓)",
|
|
2654
|
+
columnLabel: "Published At",
|
|
2655
|
+
group: "timestamps"
|
|
2656
|
+
});
|
|
2657
|
+
options.push({
|
|
2658
|
+
field: publishedField,
|
|
2659
|
+
order: "asc",
|
|
2660
|
+
label: "Published At (Oldest First ↑)",
|
|
2661
|
+
columnLabel: "Published At",
|
|
2662
|
+
group: "timestamps"
|
|
2663
|
+
});
|
|
2664
|
+
}
|
|
2665
|
+
options.push({
|
|
2666
|
+
field: "id",
|
|
2667
|
+
order: "desc",
|
|
2668
|
+
label: "Entry ID (Highest First ↓)",
|
|
2669
|
+
columnLabel: "ID",
|
|
2670
|
+
group: "system"
|
|
2671
|
+
});
|
|
2672
|
+
options.push({
|
|
2673
|
+
field: "id",
|
|
2674
|
+
order: "asc",
|
|
2675
|
+
label: "Entry ID (Lowest First ↑)",
|
|
2676
|
+
columnLabel: "ID",
|
|
2677
|
+
group: "system"
|
|
2678
|
+
});
|
|
2679
|
+
const systemKeywords = [
|
|
2680
|
+
"createdat",
|
|
2681
|
+
"created_at",
|
|
2682
|
+
"updatedat",
|
|
2683
|
+
"updated_at",
|
|
2684
|
+
"publishedat",
|
|
2685
|
+
"published_at",
|
|
2686
|
+
"id",
|
|
2687
|
+
"documentid"
|
|
2688
|
+
];
|
|
2689
|
+
const attrs = (col.attributes || []).filter((a) => !systemKeywords.includes(a.toLowerCase()));
|
|
2690
|
+
attrs.forEach((attr) => {
|
|
2691
|
+
let formattedLabel = attr;
|
|
2692
|
+
if (attr.includes(".")) {
|
|
2693
|
+
formattedLabel = attr.split(".").map((s) => s.charAt(0).toUpperCase() + s.slice(1)).join(" > ");
|
|
2694
|
+
} else {
|
|
2695
|
+
formattedLabel = attr.replace(/_/g, " ").replace(/\b\w/g, (l) => l.toUpperCase());
|
|
2696
|
+
}
|
|
2697
|
+
options.push({
|
|
2698
|
+
field: attr,
|
|
2699
|
+
order: "asc",
|
|
2700
|
+
label: `${formattedLabel} (A → Z / Lowest ↑)`,
|
|
2701
|
+
columnLabel: formattedLabel,
|
|
2702
|
+
group: "attributes"
|
|
2703
|
+
});
|
|
2704
|
+
options.push({
|
|
2705
|
+
field: attr,
|
|
2706
|
+
order: "desc",
|
|
2707
|
+
label: `${formattedLabel} (Z → A / Highest ↓)`,
|
|
2708
|
+
columnLabel: formattedLabel,
|
|
2709
|
+
group: "attributes"
|
|
2710
|
+
});
|
|
2711
|
+
});
|
|
2712
|
+
return options;
|
|
2713
|
+
}
|
|
1773
2714
|
function renderHeaderCell(colDef, col, currentSort, selectedAttribute, searchAttribute, onSort) {
|
|
1774
2715
|
if (colDef.key === "select") {
|
|
1775
2716
|
return /* @__PURE__ */ jsx(Th, { style: { width: 48 }, children: /* @__PURE__ */ jsx(Typography, { variant: "sigma", children: "Select" }) }, "select");
|
|
1776
2717
|
}
|
|
1777
|
-
const isCurrentSorted = colDef.key === "identifier" && (currentSort.field === "name" || currentSort.field === "title") || colDef.key === "search_attr" && currentSort.field === searchAttribute || colDef.key === "target_attr" && currentSort.field === selectedAttribute || colDef.key.startsWith("attr_") && currentSort.field === colDef.key.replace("attr_", "");
|
|
2718
|
+
const isCurrentSorted = colDef.key === "identifier" && (currentSort.field === "name" || currentSort.field === "title" || currentSort.field === "id") || colDef.key === "search_attr" && currentSort.field === searchAttribute || colDef.key === "target_attr" && currentSort.field === selectedAttribute || colDef.key.startsWith("attr_") && (currentSort.field === colDef.key.replace("attr_", "") || currentSort.field === "updatedAt" && colDef.key === "attr_updated_at" || currentSort.field === "updated_at" && colDef.key === "attr_updatedAt" || currentSort.field === "createdAt" && colDef.key === "attr_created_at" || currentSort.field === "created_at" && colDef.key === "attr_createdAt" || currentSort.field === "publishedAt" && colDef.key === "attr_published_at" || currentSort.field === "published_at" && colDef.key === "attr_publishedAt");
|
|
1778
2719
|
const sortArrow = isCurrentSorted ? currentSort.order === "asc" ? "▲" : "▼" : "⇅";
|
|
1779
2720
|
const handleClick = () => {
|
|
1780
2721
|
if (!colDef.sortable) return;
|
|
@@ -1806,6 +2747,15 @@ function formatDisplayValue(val) {
|
|
|
1806
2747
|
if (val === void 0 || val === null || val === "") {
|
|
1807
2748
|
return "(empty / not set)";
|
|
1808
2749
|
}
|
|
2750
|
+
if (val instanceof Date) {
|
|
2751
|
+
return isNaN(val.getTime()) ? "(invalid date)" : val.toLocaleString();
|
|
2752
|
+
}
|
|
2753
|
+
if (typeof val === "string" && /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}/.test(val)) {
|
|
2754
|
+
const d = new Date(val);
|
|
2755
|
+
if (!isNaN(d.getTime())) {
|
|
2756
|
+
return d.toLocaleString();
|
|
2757
|
+
}
|
|
2758
|
+
}
|
|
1809
2759
|
if (Array.isArray(val)) {
|
|
1810
2760
|
if (val.length === 0) return "(empty / unlinked)";
|
|
1811
2761
|
return val.map(
|
|
@@ -1918,7 +2868,7 @@ function renderCellContent(colDef, entry, col, selectedAttribute, searchAttribut
|
|
|
1918
2868
|
] });
|
|
1919
2869
|
}
|
|
1920
2870
|
case "search_attr": {
|
|
1921
|
-
const matches = getAllNestedValues(entry, searchAttribute);
|
|
2871
|
+
const matches = getAllNestedValues(entry, searchAttribute, col?.attributes);
|
|
1922
2872
|
if (matches.length === 0) {
|
|
1923
2873
|
return /* @__PURE__ */ jsx(Typography, { textColor: "neutral500", style: { fontStyle: "italic" }, children: "(empty / not set)" });
|
|
1924
2874
|
}
|
|
@@ -1986,7 +2936,7 @@ function renderCellContent(colDef, entry, col, selectedAttribute, searchAttribut
|
|
|
1986
2936
|
}) });
|
|
1987
2937
|
}
|
|
1988
2938
|
case "target_attr": {
|
|
1989
|
-
const matches = getAllNestedValues(entry, selectedAttribute);
|
|
2939
|
+
const matches = getAllNestedValues(entry, selectedAttribute, col?.attributes);
|
|
1990
2940
|
if (matches.length === 0) {
|
|
1991
2941
|
return /* @__PURE__ */ jsx(Typography, { textColor: "neutral500", style: { fontStyle: "italic" }, children: "(empty / not set)" });
|
|
1992
2942
|
}
|
|
@@ -2106,9 +3056,11 @@ const BulkUpdater = () => {
|
|
|
2106
3056
|
const [pendingBatchesLoading, setPendingBatchesLoading] = useState(false);
|
|
2107
3057
|
const [approvingBatchId, setApprovingBatchId] = useState(null);
|
|
2108
3058
|
const [rejectingBatchId, setRejectingBatchId] = useState(null);
|
|
2109
|
-
const [executingNowBatchId, setExecutingNowBatchId] = useState(null);
|
|
2110
3059
|
const [makerNotesInput, setMakerNotesInput] = useState("");
|
|
2111
3060
|
const [publishOnApproval, setPublishOnApproval] = useState(true);
|
|
3061
|
+
const [publishStrategy, setPublishStrategy] = useState("safe");
|
|
3062
|
+
const [unreviewedConsent, setUnreviewedConsent] = useState(false);
|
|
3063
|
+
const [publishConsent, setPublishConsent] = useState(false);
|
|
2112
3064
|
const [showProcessingDashboard, setShowProcessingDashboard] = useState(false);
|
|
2113
3065
|
const [dashboardBatchId, setDashboardBatchId] = useState("");
|
|
2114
3066
|
const [dashboardJob, setDashboardJob] = useState(null);
|
|
@@ -2185,10 +3137,32 @@ const BulkUpdater = () => {
|
|
|
2185
3137
|
} catch {
|
|
2186
3138
|
}
|
|
2187
3139
|
};
|
|
3140
|
+
const [searchRelationOptions, setSearchRelationOptions] = useState([]);
|
|
3141
|
+
const [searchRelationOptionsLoading, setSearchRelationOptionsLoading] = useState(false);
|
|
3142
|
+
const fetchSearchRelationOptions = async (targetUid) => {
|
|
3143
|
+
try {
|
|
3144
|
+
setSearchRelationOptionsLoading(true);
|
|
3145
|
+
const res = await get(`/bulk-updater/relation-options?targetUid=${encodeURIComponent(targetUid)}`);
|
|
3146
|
+
if (res.data && res.data.success) {
|
|
3147
|
+
setSearchRelationOptions(res.data.options || []);
|
|
3148
|
+
}
|
|
3149
|
+
} catch {
|
|
3150
|
+
setSearchRelationOptions([]);
|
|
3151
|
+
} finally {
|
|
3152
|
+
setSearchRelationOptionsLoading(false);
|
|
3153
|
+
}
|
|
3154
|
+
};
|
|
2188
3155
|
const [searchAttribute, setSearchAttribute] = useState("");
|
|
2189
3156
|
const [searchAttributeInput, setSearchAttributeInput] = useState("");
|
|
2190
3157
|
const [attributesMeta, setAttributesMeta] = useState({});
|
|
2191
3158
|
const effectiveSearchAttribute = searchAttribute || selectedAttribute;
|
|
3159
|
+
useEffect(() => {
|
|
3160
|
+
if (effectiveSearchAttribute && relationsMeta[effectiveSearchAttribute]) {
|
|
3161
|
+
fetchSearchRelationOptions(relationsMeta[effectiveSearchAttribute].targetUid);
|
|
3162
|
+
} else {
|
|
3163
|
+
setSearchRelationOptions([]);
|
|
3164
|
+
}
|
|
3165
|
+
}, [effectiveSearchAttribute, relationsMeta]);
|
|
2192
3166
|
const [filterOperator, setFilterOperator] = useState("none");
|
|
2193
3167
|
const [filterQuery, setFilterQuery] = useState("");
|
|
2194
3168
|
const [entrySearch, setEntrySearch] = useState("");
|
|
@@ -2207,6 +3181,8 @@ const BulkUpdater = () => {
|
|
|
2207
3181
|
const [collectionColumnVisibility, setCollectionColumnVisibility] = useState({});
|
|
2208
3182
|
const [openColumnPickerUid, setOpenColumnPickerUid] = useState(null);
|
|
2209
3183
|
const [columnSearchTerm, setColumnSearchTerm] = useState("");
|
|
3184
|
+
const [openSortPickerUid, setOpenSortPickerUid] = useState(null);
|
|
3185
|
+
const [sortSearchTerm, setSortSearchTerm] = useState("");
|
|
2210
3186
|
const toggleColumn = (colUid, colKey, availableCols) => {
|
|
2211
3187
|
setCollectionColumnVisibility((prev) => {
|
|
2212
3188
|
const current = prev[colUid] || availableCols.filter((c) => c.defaultVisible).map((c) => c.key);
|
|
@@ -2739,21 +3715,45 @@ const BulkUpdater = () => {
|
|
|
2739
3715
|
}
|
|
2740
3716
|
const checkMatch = (val) => {
|
|
2741
3717
|
const displayStr = formatDisplayValue(val);
|
|
2742
|
-
const isValEmpty = val === void 0 || val === null || displayStr.trim() === "" || displayStr.trim().toLowerCase() === "(not set)" || displayStr.trim().toLowerCase() === "(empty / not set)" || displayStr.trim().toLowerCase() === "(empty / unlinked)";
|
|
2743
|
-
|
|
2744
|
-
|
|
2745
|
-
|
|
2746
|
-
|
|
2747
|
-
|
|
2748
|
-
|
|
2749
|
-
|
|
2750
|
-
|
|
2751
|
-
|
|
2752
|
-
|
|
2753
|
-
|
|
2754
|
-
|
|
2755
|
-
|
|
3718
|
+
const isValEmpty = val === void 0 || val === null || Array.isArray(val) && val.length === 0 || displayStr.trim() === "" || displayStr.trim().toLowerCase() === "(not set)" || displayStr.trim().toLowerCase() === "(empty / not set)" || displayStr.trim().toLowerCase() === "(empty / unlinked)";
|
|
3719
|
+
if (filterOperator === "empty") return isValEmpty;
|
|
3720
|
+
if (filterOperator === "not_empty") return !isValEmpty;
|
|
3721
|
+
if (isValEmpty) return false;
|
|
3722
|
+
const q = filterQuery.trim().toLowerCase();
|
|
3723
|
+
if (!q) return true;
|
|
3724
|
+
const testString = (str) => {
|
|
3725
|
+
if (str === void 0 || str === null) return false;
|
|
3726
|
+
const s = String(str).trim().toLowerCase();
|
|
3727
|
+
switch (filterOperator) {
|
|
3728
|
+
case "equals":
|
|
3729
|
+
return s === q;
|
|
3730
|
+
case "contains":
|
|
3731
|
+
return s.includes(q);
|
|
3732
|
+
case "starts_with":
|
|
3733
|
+
return s.startsWith(q);
|
|
3734
|
+
default:
|
|
3735
|
+
return true;
|
|
3736
|
+
}
|
|
3737
|
+
};
|
|
3738
|
+
const testEntityObject = (obj) => {
|
|
3739
|
+
if (!obj || typeof obj !== "object") return false;
|
|
3740
|
+
if (testString(obj.name)) return true;
|
|
3741
|
+
if (testString(obj.title)) return true;
|
|
3742
|
+
if (testString(obj.email)) return true;
|
|
3743
|
+
if (testString(obj.username)) return true;
|
|
3744
|
+
if (testString(obj.documentId)) return true;
|
|
3745
|
+
if (testString(String(obj.id))) return true;
|
|
3746
|
+
if (testString(obj.slug)) return true;
|
|
3747
|
+
if (testString(formatDisplayValue(obj))) return true;
|
|
3748
|
+
return false;
|
|
3749
|
+
};
|
|
3750
|
+
if (Array.isArray(val)) {
|
|
3751
|
+
return val.some((item) => typeof item === "object" ? testEntityObject(item) : testString(item));
|
|
2756
3752
|
}
|
|
3753
|
+
if (typeof val === "object" && val !== null) {
|
|
3754
|
+
if (testEntityObject(val)) return true;
|
|
3755
|
+
}
|
|
3756
|
+
return testString(displayStr);
|
|
2757
3757
|
};
|
|
2758
3758
|
if (filterOperator === "empty") {
|
|
2759
3759
|
return matches.every((m) => checkMatch(m.value));
|
|
@@ -2865,6 +3865,40 @@ const BulkUpdater = () => {
|
|
|
2865
3865
|
});
|
|
2866
3866
|
return breakdown;
|
|
2867
3867
|
};
|
|
3868
|
+
const selectedLifecycleStats = useMemo(() => {
|
|
3869
|
+
let published = 0;
|
|
3870
|
+
let modified = 0;
|
|
3871
|
+
let draft = 0;
|
|
3872
|
+
let pendingReview = 0;
|
|
3873
|
+
Object.keys(selectedEntries).forEach((key) => {
|
|
3874
|
+
if (!selectedEntries[key]) return;
|
|
3875
|
+
const parts = key.split(KEY_SEP);
|
|
3876
|
+
if (parts.length !== 2) return;
|
|
3877
|
+
const [uid, docId] = parts;
|
|
3878
|
+
const col = collections.find((c) => c.uid === uid) || null;
|
|
3879
|
+
const entry = collectionPages[uid]?.entries?.find((e) => e.documentId === docId || String(e.id) === docId) || col?.entries?.find((e) => e.documentId === docId || String(e.id) === docId);
|
|
3880
|
+
if (col && col.draftAndPublish === false) {
|
|
3881
|
+
published++;
|
|
3882
|
+
} else if (entry) {
|
|
3883
|
+
const { status } = getEntryLifecycleStatus(entry, col, pendingBatches);
|
|
3884
|
+
if (status === "published") published++;
|
|
3885
|
+
else if (status === "modified") modified++;
|
|
3886
|
+
else if (status === "draft") draft++;
|
|
3887
|
+
else if (status === "pending_review") pendingReview++;
|
|
3888
|
+
} else {
|
|
3889
|
+
draft++;
|
|
3890
|
+
}
|
|
3891
|
+
});
|
|
3892
|
+
const unreviewedCount = draft + modified + pendingReview;
|
|
3893
|
+
return {
|
|
3894
|
+
published,
|
|
3895
|
+
modified,
|
|
3896
|
+
draft,
|
|
3897
|
+
pendingReview,
|
|
3898
|
+
unreviewedCount,
|
|
3899
|
+
total: published + modified + draft + pendingReview
|
|
3900
|
+
};
|
|
3901
|
+
}, [selectedEntries, collections, collectionPages, pendingBatches]);
|
|
2868
3902
|
const handleOpenConfirmModal = () => {
|
|
2869
3903
|
if (!selectedAttribute) {
|
|
2870
3904
|
toggleNotification({
|
|
@@ -2881,6 +3915,8 @@ const BulkUpdater = () => {
|
|
|
2881
3915
|
});
|
|
2882
3916
|
return;
|
|
2883
3917
|
}
|
|
3918
|
+
setPublishStrategy("safe");
|
|
3919
|
+
setUnreviewedConsent(false);
|
|
2884
3920
|
setShowConfirmModal(true);
|
|
2885
3921
|
};
|
|
2886
3922
|
const handleOpenPreviewModal = async () => {
|
|
@@ -2896,7 +3932,11 @@ const BulkUpdater = () => {
|
|
|
2896
3932
|
if (selectedEntries[key]) {
|
|
2897
3933
|
const parts = key.split(KEY_SEP);
|
|
2898
3934
|
if (parts.length === 2) {
|
|
2899
|
-
|
|
3935
|
+
const targetObj = { uid: parts[0], documentId: parts[1] };
|
|
3936
|
+
if (selectedDzBlocks[key] && selectedDzBlocks[key].length > 0) {
|
|
3937
|
+
targetObj.dynamicZoneIndexes = selectedDzBlocks[key];
|
|
3938
|
+
}
|
|
3939
|
+
targets.push(targetObj);
|
|
2900
3940
|
}
|
|
2901
3941
|
}
|
|
2902
3942
|
});
|
|
@@ -2971,6 +4011,9 @@ const BulkUpdater = () => {
|
|
|
2971
4011
|
failedCount: 0,
|
|
2972
4012
|
isLive: false,
|
|
2973
4013
|
publishOnApproval,
|
|
4014
|
+
publishStrategy,
|
|
4015
|
+
unreviewedConsent,
|
|
4016
|
+
unreviewedCount: selectedLifecycleStats.unreviewedCount,
|
|
2974
4017
|
results: []
|
|
2975
4018
|
});
|
|
2976
4019
|
const payload = {
|
|
@@ -2982,7 +4025,10 @@ const BulkUpdater = () => {
|
|
|
2982
4025
|
executionMode,
|
|
2983
4026
|
makerNotes: makerNotesInput,
|
|
2984
4027
|
forceImmediate,
|
|
2985
|
-
publishOnApproval
|
|
4028
|
+
publishOnApproval,
|
|
4029
|
+
publishStrategy,
|
|
4030
|
+
unreviewedConsent,
|
|
4031
|
+
unreviewedCount: selectedLifecycleStats.unreviewedCount
|
|
2986
4032
|
};
|
|
2987
4033
|
const res = await post("/bulk-updater/batch-update", payload);
|
|
2988
4034
|
setIsSubmittingBatch(false);
|
|
@@ -3046,6 +4092,20 @@ const BulkUpdater = () => {
|
|
|
3046
4092
|
});
|
|
3047
4093
|
await fetchModels();
|
|
3048
4094
|
await fetchAuditHistory();
|
|
4095
|
+
if (selectedCollectionUid) {
|
|
4096
|
+
loadCollectionPage(
|
|
4097
|
+
selectedCollectionUid,
|
|
4098
|
+
collectionPages[selectedCollectionUid]?.page || 1,
|
|
4099
|
+
void 0,
|
|
4100
|
+
void 0,
|
|
4101
|
+
void 0,
|
|
4102
|
+
filterOperator,
|
|
4103
|
+
filterQuery,
|
|
4104
|
+
entrySearch,
|
|
4105
|
+
false,
|
|
4106
|
+
searchAttribute
|
|
4107
|
+
);
|
|
4108
|
+
}
|
|
3049
4109
|
}
|
|
3050
4110
|
} else {
|
|
3051
4111
|
setIsSubmittingBatch(false);
|
|
@@ -3136,6 +4196,7 @@ const BulkUpdater = () => {
|
|
|
3136
4196
|
});
|
|
3137
4197
|
return;
|
|
3138
4198
|
}
|
|
4199
|
+
setPublishConsent(false);
|
|
3139
4200
|
setShowPublishConfirmModal(true);
|
|
3140
4201
|
};
|
|
3141
4202
|
const executeBatchPublish = async (executionMode, forceImmediate = false) => {
|
|
@@ -3170,13 +4231,17 @@ const BulkUpdater = () => {
|
|
|
3170
4231
|
failedCount: 0,
|
|
3171
4232
|
isLive: true,
|
|
3172
4233
|
publishOnApproval: true,
|
|
4234
|
+
unreviewedConsent: publishConsent,
|
|
4235
|
+
unreviewedCount: selectedLifecycleStats.unreviewedCount,
|
|
3173
4236
|
results: []
|
|
3174
4237
|
});
|
|
3175
4238
|
const payload = {
|
|
3176
4239
|
selectedEntries: targets,
|
|
3177
4240
|
executionMode,
|
|
3178
4241
|
makerNotes: publishMakerNotesInput,
|
|
3179
|
-
forceImmediate
|
|
4242
|
+
forceImmediate,
|
|
4243
|
+
unreviewedConsent: publishConsent,
|
|
4244
|
+
unreviewedCount: selectedLifecycleStats.unreviewedCount
|
|
3180
4245
|
};
|
|
3181
4246
|
const res = await post("/bulk-updater/batch-publish", payload);
|
|
3182
4247
|
setIsSubmittingBatch(false);
|
|
@@ -3757,7 +4822,27 @@ const BulkUpdater = () => {
|
|
|
3757
4822
|
]
|
|
3758
4823
|
}
|
|
3759
4824
|
) }),
|
|
3760
|
-
(filterOperator === "equals" || filterOperator === "contains" || filterOperator === "starts_with") && /* @__PURE__ */ jsx(Box, { style: { flex: 1, minWidth:
|
|
4825
|
+
(filterOperator === "equals" || filterOperator === "contains" || filterOperator === "starts_with") && /* @__PURE__ */ jsx(Box, { style: { flex: 1, minWidth: 200 }, children: effectiveSearchAttribute && relationsMeta[effectiveSearchAttribute] ? /* @__PURE__ */ jsxs(Field.Root, { children: [
|
|
4826
|
+
/* @__PURE__ */ jsx(Field.Label, { children: `Target ${relationsMeta[effectiveSearchAttribute].targetDisplayName} Relation` }),
|
|
4827
|
+
/* @__PURE__ */ jsx(
|
|
4828
|
+
Combobox,
|
|
4829
|
+
{
|
|
4830
|
+
autocomplete: { type: "list", filter: "contains" },
|
|
4831
|
+
placeholder: searchRelationOptionsLoading ? "Loading entities..." : `Search & pick ${relationsMeta[effectiveSearchAttribute].targetDisplayName} or type text...`,
|
|
4832
|
+
value: filterQuery,
|
|
4833
|
+
onClear: () => setFilterQuery(""),
|
|
4834
|
+
onChange: (val) => {
|
|
4835
|
+
if (typeof val === "string") {
|
|
4836
|
+
setFilterQuery(val);
|
|
4837
|
+
}
|
|
4838
|
+
},
|
|
4839
|
+
onInputChange: (e) => {
|
|
4840
|
+
setFilterQuery(e.target.value);
|
|
4841
|
+
},
|
|
4842
|
+
children: searchRelationOptions.map((opt) => /* @__PURE__ */ jsx(ComboboxOption, { value: opt.label, textValue: opt.label, children: opt.label }, opt.documentId))
|
|
4843
|
+
}
|
|
4844
|
+
)
|
|
4845
|
+
] }) : /* @__PURE__ */ jsx(
|
|
3761
4846
|
TextInput,
|
|
3762
4847
|
{
|
|
3763
4848
|
label: effectiveSearchAttribute ? `Value for "${effectiveSearchAttribute}"` : "Value to match",
|
|
@@ -3907,41 +4992,127 @@ const BulkUpdater = () => {
|
|
|
3907
4992
|
) : null
|
|
3908
4993
|
] }),
|
|
3909
4994
|
/* @__PURE__ */ jsxs(Flex, { gap: 3, alignItems: "center", wrap: "wrap", children: [
|
|
3910
|
-
!col.isSingleType && /* @__PURE__ */ jsxs(
|
|
3911
|
-
/* @__PURE__ */ jsx(
|
|
3912
|
-
|
|
3913
|
-
SingleSelect,
|
|
4995
|
+
!col.isSingleType && /* @__PURE__ */ jsxs(Box, { style: { position: "relative", display: "inline-block" }, children: [
|
|
4996
|
+
/* @__PURE__ */ jsx(
|
|
4997
|
+
Button,
|
|
3914
4998
|
{
|
|
4999
|
+
variant: openSortPickerUid === col.uid ? "secondary" : "tertiary",
|
|
3915
5000
|
size: "S",
|
|
3916
|
-
|
|
3917
|
-
|
|
3918
|
-
|
|
3919
|
-
|
|
5001
|
+
onClick: () => {
|
|
5002
|
+
setOpenSortPickerUid(openSortPickerUid === col.uid ? null : col.uid);
|
|
5003
|
+
setSortSearchTerm("");
|
|
5004
|
+
if (openColumnPickerUid === col.uid) setOpenColumnPickerUid(null);
|
|
5005
|
+
},
|
|
5006
|
+
children: /* @__PURE__ */ jsxs(Flex, { gap: 1, alignItems: "center", children: [
|
|
5007
|
+
/* @__PURE__ */ jsx(Typography, { variant: "pi", textColor: "neutral600", fontWeight: "bold", children: "Sort:" }),
|
|
5008
|
+
/* @__PURE__ */ jsx(Typography, { variant: "pi", fontWeight: "semiBold", children: getActiveSortLabel(currentSort) })
|
|
5009
|
+
] })
|
|
5010
|
+
}
|
|
5011
|
+
),
|
|
5012
|
+
openSortPickerUid === col.uid && /* @__PURE__ */ jsxs(
|
|
5013
|
+
Box,
|
|
5014
|
+
{
|
|
5015
|
+
style: {
|
|
5016
|
+
position: "absolute",
|
|
5017
|
+
top: "calc(100% + 6px)",
|
|
5018
|
+
left: 0,
|
|
5019
|
+
zIndex: 220,
|
|
5020
|
+
width: 330,
|
|
5021
|
+
maxHeight: 440,
|
|
5022
|
+
background: "#ffffff",
|
|
5023
|
+
borderRadius: 8,
|
|
5024
|
+
boxShadow: "0 10px 25px rgba(33, 33, 52, 0.18)",
|
|
5025
|
+
border: "1px solid #dcdce4",
|
|
5026
|
+
padding: 12,
|
|
5027
|
+
display: "flex",
|
|
5028
|
+
flexDirection: "column",
|
|
5029
|
+
gap: 8
|
|
3920
5030
|
},
|
|
3921
5031
|
children: [
|
|
3922
|
-
/* @__PURE__ */
|
|
3923
|
-
|
|
3924
|
-
|
|
3925
|
-
|
|
3926
|
-
|
|
3927
|
-
|
|
3928
|
-
|
|
3929
|
-
|
|
3930
|
-
|
|
3931
|
-
|
|
3932
|
-
|
|
3933
|
-
|
|
3934
|
-
col.attributes.includes("name") && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
3935
|
-
/* @__PURE__ */ jsx(SingleSelectOption, { value: "name:asc", children: "Name (A → Z)" }),
|
|
3936
|
-
/* @__PURE__ */ jsx(SingleSelectOption, { value: "name:desc", children: "Name (Z → A)" })
|
|
5032
|
+
/* @__PURE__ */ jsxs(Flex, { justifyContent: "space-between", alignItems: "center", children: [
|
|
5033
|
+
/* @__PURE__ */ jsx(Typography, { variant: "pi", fontWeight: "bold", children: "Sort by Column" }),
|
|
5034
|
+
/* @__PURE__ */ jsx(
|
|
5035
|
+
Button,
|
|
5036
|
+
{
|
|
5037
|
+
variant: "ghost",
|
|
5038
|
+
size: "S",
|
|
5039
|
+
onClick: () => setOpenSortPickerUid(null),
|
|
5040
|
+
style: { padding: "2px 6px", height: "auto", minWidth: "unset" },
|
|
5041
|
+
children: "✕"
|
|
5042
|
+
}
|
|
5043
|
+
)
|
|
3937
5044
|
] }),
|
|
3938
|
-
|
|
3939
|
-
|
|
3940
|
-
|
|
3941
|
-
|
|
5045
|
+
/* @__PURE__ */ jsx(
|
|
5046
|
+
TextInput,
|
|
5047
|
+
{
|
|
5048
|
+
size: "S",
|
|
5049
|
+
placeholder: "Search columns to sort...",
|
|
5050
|
+
value: sortSearchTerm,
|
|
5051
|
+
onChange: (e) => setSortSearchTerm(e.target.value)
|
|
5052
|
+
}
|
|
5053
|
+
),
|
|
5054
|
+
/* @__PURE__ */ jsx(
|
|
5055
|
+
Box,
|
|
5056
|
+
{
|
|
5057
|
+
style: {
|
|
5058
|
+
maxHeight: 320,
|
|
5059
|
+
overflowY: "auto",
|
|
5060
|
+
display: "flex",
|
|
5061
|
+
flexDirection: "column",
|
|
5062
|
+
gap: 4
|
|
5063
|
+
},
|
|
5064
|
+
children: getSortOptionsForCollection(col).filter((opt) => {
|
|
5065
|
+
if (!sortSearchTerm.trim()) return true;
|
|
5066
|
+
const term = sortSearchTerm.toLowerCase().trim();
|
|
5067
|
+
return opt.label.toLowerCase().includes(term) || opt.field.toLowerCase().includes(term);
|
|
5068
|
+
}).map((opt) => {
|
|
5069
|
+
const isSelected = (currentSort.field === opt.field || currentSort.field === "updatedAt" && opt.field === "updated_at" || currentSort.field === "updated_at" && opt.field === "updatedAt" || currentSort.field === "createdAt" && opt.field === "created_at" || currentSort.field === "created_at" && opt.field === "createdAt") && currentSort.order === opt.order;
|
|
5070
|
+
return /* @__PURE__ */ jsxs(
|
|
5071
|
+
Box,
|
|
5072
|
+
{
|
|
5073
|
+
onClick: () => {
|
|
5074
|
+
handleCollectionSortChange(col.uid, opt.field, opt.order);
|
|
5075
|
+
setOpenSortPickerUid(null);
|
|
5076
|
+
setSortSearchTerm("");
|
|
5077
|
+
},
|
|
5078
|
+
style: {
|
|
5079
|
+
padding: "6px 10px",
|
|
5080
|
+
borderRadius: 6,
|
|
5081
|
+
cursor: "pointer",
|
|
5082
|
+
background: isSelected ? "rgba(73, 69, 255, 0.12)" : "transparent",
|
|
5083
|
+
border: isSelected ? "1px solid #4945ff" : "1px solid transparent",
|
|
5084
|
+
display: "flex",
|
|
5085
|
+
alignItems: "center",
|
|
5086
|
+
justifyContent: "space-between",
|
|
5087
|
+
transition: "background 0.15s ease"
|
|
5088
|
+
},
|
|
5089
|
+
onMouseEnter: (e) => {
|
|
5090
|
+
if (!isSelected) e.currentTarget.style.background = "#f6f6f9";
|
|
5091
|
+
},
|
|
5092
|
+
onMouseLeave: (e) => {
|
|
5093
|
+
if (!isSelected) e.currentTarget.style.background = "transparent";
|
|
5094
|
+
},
|
|
5095
|
+
children: [
|
|
5096
|
+
/* @__PURE__ */ jsx(
|
|
5097
|
+
Typography,
|
|
5098
|
+
{
|
|
5099
|
+
variant: "omega",
|
|
5100
|
+
fontWeight: isSelected ? "bold" : "normal",
|
|
5101
|
+
textColor: isSelected ? "primary700" : "neutral800",
|
|
5102
|
+
children: opt.label
|
|
5103
|
+
}
|
|
5104
|
+
),
|
|
5105
|
+
isSelected && /* @__PURE__ */ jsx(Badge, { size: "S", backgroundColor: "primary100", textColor: "primary700", children: "Active" })
|
|
5106
|
+
]
|
|
5107
|
+
},
|
|
5108
|
+
`${opt.field}:${opt.order}`
|
|
5109
|
+
);
|
|
5110
|
+
})
|
|
5111
|
+
}
|
|
5112
|
+
)
|
|
3942
5113
|
]
|
|
3943
5114
|
}
|
|
3944
|
-
)
|
|
5115
|
+
)
|
|
3945
5116
|
] }),
|
|
3946
5117
|
/* @__PURE__ */ jsxs(Box, { style: { position: "relative", display: "inline-block" }, children: [
|
|
3947
5118
|
/* @__PURE__ */ jsxs(
|
|
@@ -3953,6 +5124,7 @@ const BulkUpdater = () => {
|
|
|
3953
5124
|
onClick: () => {
|
|
3954
5125
|
setOpenColumnPickerUid(openColumnPickerUid === col.uid ? null : col.uid);
|
|
3955
5126
|
setColumnSearchTerm("");
|
|
5127
|
+
if (openSortPickerUid === col.uid) setOpenSortPickerUid(null);
|
|
3956
5128
|
},
|
|
3957
5129
|
children: [
|
|
3958
5130
|
"Columns (",
|
|
@@ -4212,10 +5384,13 @@ const BulkUpdater = () => {
|
|
|
4212
5384
|
isDzExpanded && dzFields.map((dzKey) => {
|
|
4213
5385
|
const blocks = entry[dzKey] || [];
|
|
4214
5386
|
const targetParsed = parseDynamicZonePath(selectedAttribute);
|
|
4215
|
-
const
|
|
5387
|
+
const isBlockApplicable = (blockItem) => {
|
|
4216
5388
|
if (!targetParsed.subPath) return true;
|
|
4217
|
-
|
|
4218
|
-
|
|
5389
|
+
const scopedPath = `${dzKey}[${blockItem?.__component}].${targetParsed.subPath}`;
|
|
5390
|
+
const componentSupports = (col?.attributes || attributes || []).includes(scopedPath);
|
|
5391
|
+
return componentSupports || getNestedValue(blockItem, targetParsed.subPath) !== void 0;
|
|
5392
|
+
};
|
|
5393
|
+
const allApplicableIndexes = blocks.map((_, i) => i).filter((i) => isBlockApplicable(blocks[i]));
|
|
4219
5394
|
return /* @__PURE__ */ jsx(Tr, { children: /* @__PURE__ */ jsx(Td, { colSpan: activeColumns.length, style: { padding: "12px 16px", backgroundColor: "rgba(73, 69, 255, 0.02)", borderBottom: "2px solid rgba(73, 69, 255, 0.15)" }, children: /* @__PURE__ */ jsxs(
|
|
4220
5395
|
Box,
|
|
4221
5396
|
{
|
|
@@ -4252,8 +5427,10 @@ const BulkUpdater = () => {
|
|
|
4252
5427
|
/* @__PURE__ */ jsx(Tbody, { children: blocks.map((block, bIdx) => {
|
|
4253
5428
|
const compUid = block.__component;
|
|
4254
5429
|
const compLabel = formatComponentName(compUid);
|
|
5430
|
+
const scopedPath = `${dzKey}[${compUid}].${targetParsed.subPath}`;
|
|
5431
|
+
const componentSupports = (col?.attributes || attributes || []).includes(scopedPath);
|
|
4255
5432
|
const blockVal = targetParsed.subPath ? getNestedValue(block, targetParsed.subPath) : void 0;
|
|
4256
|
-
const hasTargetAttr = blockVal !== void 0;
|
|
5433
|
+
const hasTargetAttr = componentSupports || blockVal !== void 0;
|
|
4257
5434
|
const isBlockChecked = hasTargetAttr && isSelected && (selectedDzBlocks[key] !== void 0 ? selectedDzBlocks[key].includes(bIdx) : true);
|
|
4258
5435
|
return /* @__PURE__ */ jsxs(
|
|
4259
5436
|
Tr,
|
|
@@ -4573,27 +5750,42 @@ const BulkUpdater = () => {
|
|
|
4573
5750
|
)
|
|
4574
5751
|
] })
|
|
4575
5752
|
] }),
|
|
4576
|
-
/* @__PURE__ */
|
|
4577
|
-
/* @__PURE__ */ jsxs(Flex, {
|
|
4578
|
-
/* @__PURE__ */
|
|
4579
|
-
|
|
4580
|
-
|
|
4581
|
-
|
|
4582
|
-
|
|
4583
|
-
|
|
4584
|
-
|
|
4585
|
-
|
|
4586
|
-
|
|
4587
|
-
|
|
4588
|
-
|
|
4589
|
-
|
|
4590
|
-
|
|
4591
|
-
|
|
4592
|
-
|
|
4593
|
-
|
|
5753
|
+
/* @__PURE__ */ jsxs(Box, { marginTop: 4, padding: 4, background: "neutral100", hasRadius: true, style: { border: "1px solid #eaeaef" }, children: [
|
|
5754
|
+
/* @__PURE__ */ jsxs(Flex, { justifyContent: "space-between", alignItems: "center", wrap: "wrap", gap: 3, children: [
|
|
5755
|
+
/* @__PURE__ */ jsxs(Flex, { gap: 2, alignItems: "center", children: [
|
|
5756
|
+
/* @__PURE__ */ jsx(
|
|
5757
|
+
Checkbox,
|
|
5758
|
+
{
|
|
5759
|
+
checked: publishOnApproval,
|
|
5760
|
+
onCheckedChange: (checked) => setPublishOnApproval(Boolean(checked)),
|
|
5761
|
+
children: /* @__PURE__ */ jsx(Typography, { fontWeight: "bold", children: "Auto-Publish after Update" })
|
|
5762
|
+
}
|
|
5763
|
+
),
|
|
5764
|
+
/* @__PURE__ */ jsx(
|
|
5765
|
+
Badge,
|
|
5766
|
+
{
|
|
5767
|
+
backgroundColor: publishOnApproval ? "success100" : "warning100",
|
|
5768
|
+
textColor: publishOnApproval ? "success700" : "warning700",
|
|
5769
|
+
children: publishOnApproval ? "✓ LIVE PUBLISH" : "DRAFT ONLY"
|
|
5770
|
+
}
|
|
5771
|
+
)
|
|
5772
|
+
] }),
|
|
5773
|
+
/* @__PURE__ */ jsx(Typography, { variant: "pi", textColor: "neutral600", children: publishOnApproval ? "When enabled, entries will be published live immediately upon batch execution for draft-enabled content types." : "When disabled, entries will be saved as draft versions without publishing to live visitors." })
|
|
4594
5774
|
] }),
|
|
4595
|
-
/* @__PURE__ */ jsx(
|
|
4596
|
-
|
|
5775
|
+
publishOnApproval && selectedLifecycleStats.unreviewedCount > 0 && /* @__PURE__ */ jsx(Box, { marginTop: 3, padding: 3, background: "warning100", hasRadius: true, style: { border: "1px solid #f5c0b8" }, children: /* @__PURE__ */ jsxs(Flex, { gap: 2, alignItems: "flex-start", children: [
|
|
5776
|
+
/* @__PURE__ */ jsx(Typography, { variant: "pi", fontWeight: "bold", textColor: "warning700", children: "⚠️ Unreviewed Content Alert:" }),
|
|
5777
|
+
/* @__PURE__ */ jsxs(Typography, { variant: "pi", textColor: "warning700", children: [
|
|
5778
|
+
selectedLifecycleStats.unreviewedCount,
|
|
5779
|
+
" of ",
|
|
5780
|
+
totalSelectedCount,
|
|
5781
|
+
" selected record(s) contain unreviewed draft changes (",
|
|
5782
|
+
selectedLifecycleStats.draft,
|
|
5783
|
+
" Draft, ",
|
|
5784
|
+
selectedLifecycleStats.modified,
|
|
5785
|
+
" Modified). Publishing them live will push all unreviewed draft content across all fields to live visitors. You can select safe publishing (recommended) or provide explicit consent at review time."
|
|
5786
|
+
] })
|
|
5787
|
+
] }) })
|
|
5788
|
+
] }),
|
|
4597
5789
|
selectedCol && selectedAttribute && /* @__PURE__ */ jsx(Box, { marginTop: 4, padding: 3, background: "neutral100", hasRadius: true, style: { border: "1px solid #eaeaef" }, children: /* @__PURE__ */ jsx(Flex, { justifyContent: "space-between", alignItems: "center", wrap: "wrap", gap: 3, children: /* @__PURE__ */ jsxs(Flex, { gap: 2, alignItems: "center", wrap: "wrap", children: [
|
|
4598
5790
|
/* @__PURE__ */ jsx(Typography, { variant: "pi", fontWeight: "bold", children: "Target Selection:" }),
|
|
4599
5791
|
/* @__PURE__ */ jsxs(Badge, { backgroundColor: "primary100", textColor: "primary700", children: [
|
|
@@ -4770,6 +5962,7 @@ const BulkUpdater = () => {
|
|
|
4770
5962
|
'"'
|
|
4771
5963
|
] }),
|
|
4772
5964
|
/* @__PURE__ */ jsxs(Flex, { gap: 1, alignItems: "center", marginTop: 1, children: [
|
|
5965
|
+
(batch.payload?.action === "csv_import" || batch.id?.startsWith("csv_")) && /* @__PURE__ */ jsx(Badge, { backgroundColor: "secondary100", textColor: "secondary700", children: "📊 CSV IMPORT" }),
|
|
4773
5966
|
/* @__PURE__ */ jsx(
|
|
4774
5967
|
Badge,
|
|
4775
5968
|
{
|
|
@@ -4778,6 +5971,12 @@ const BulkUpdater = () => {
|
|
|
4778
5971
|
children: batch.summary.publishOnApproval === false ? "DRAFT ONLY" : "AUTO-PUBLISH"
|
|
4779
5972
|
}
|
|
4780
5973
|
),
|
|
5974
|
+
batch.summary.publishStrategy === "safe" && /* @__PURE__ */ jsx(Badge, { backgroundColor: "secondary100", textColor: "secondary700", children: "SAFE PUBLISH" }),
|
|
5975
|
+
batch.summary.publishStrategy === "all" && /* @__PURE__ */ jsx(Badge, { backgroundColor: "warning100", textColor: "warning700", children: "PUBLISH ALL (CONSENTED)" }),
|
|
5976
|
+
Boolean(batch.summary.unreviewedCount) && /* @__PURE__ */ jsxs(Badge, { backgroundColor: "neutral150", textColor: "neutral700", children: [
|
|
5977
|
+
"Unreviewed: ",
|
|
5978
|
+
batch.summary.unreviewedCount
|
|
5979
|
+
] }),
|
|
4781
5980
|
/* @__PURE__ */ jsxs(Typography, { variant: "pi", textColor: "neutral600", children: [
|
|
4782
5981
|
"• ",
|
|
4783
5982
|
batch.summary.totalTargets,
|
|
@@ -4925,7 +6124,9 @@ const BulkUpdater = () => {
|
|
|
4925
6124
|
rec.skippedCount > 0 && /* @__PURE__ */ jsxs(Badge, { backgroundColor: "warning100", textColor: "warning700", style: { marginLeft: 6 }, children: [
|
|
4926
6125
|
rec.skippedCount,
|
|
4927
6126
|
" skipped"
|
|
4928
|
-
] })
|
|
6127
|
+
] }),
|
|
6128
|
+
rec.publishStrategy === "safe" && /* @__PURE__ */ jsx(Badge, { backgroundColor: "secondary100", textColor: "secondary700", style: { marginLeft: 6 }, children: "Safe Publish" }),
|
|
6129
|
+
rec.publishStrategy === "all" && /* @__PURE__ */ jsx(Badge, { backgroundColor: "warning100", textColor: "warning700", style: { marginLeft: 6 }, children: "Publish All (Consented)" })
|
|
4929
6130
|
] }),
|
|
4930
6131
|
/* @__PURE__ */ jsx(Td, { style: { minWidth: 120 }, children: rec.isRolledBack ? /* @__PURE__ */ jsxs(Box, { children: [
|
|
4931
6132
|
/* @__PURE__ */ jsx(Badge, { backgroundColor: "neutral200", textColor: "neutral700", children: "ROLLED BACK" }),
|
|
@@ -5144,6 +6345,31 @@ const BulkUpdater = () => {
|
|
|
5144
6345
|
] })
|
|
5145
6346
|
] })
|
|
5146
6347
|
] }),
|
|
6348
|
+
/* @__PURE__ */ jsxs(Box, { marginBottom: 4, padding: 3, background: "neutral100", hasRadius: true, style: { border: "1px solid rgba(120, 120, 150, 0.15)" }, children: [
|
|
6349
|
+
/* @__PURE__ */ jsxs(Typography, { variant: "sigma", textColor: "neutral600", marginBottom: 2, display: "block", children: [
|
|
6350
|
+
"LIFECYCLE STATUS BREAKDOWN (",
|
|
6351
|
+
totalSelectedCount,
|
|
6352
|
+
" Selected)"
|
|
6353
|
+
] }),
|
|
6354
|
+
/* @__PURE__ */ jsxs(Flex, { gap: 2, wrap: "wrap", children: [
|
|
6355
|
+
/* @__PURE__ */ jsxs(Badge, { backgroundColor: "success100", textColor: "success700", children: [
|
|
6356
|
+
"✓ Published / Approved: ",
|
|
6357
|
+
selectedLifecycleStats.published
|
|
6358
|
+
] }),
|
|
6359
|
+
selectedLifecycleStats.modified > 0 && /* @__PURE__ */ jsxs(Badge, { backgroundColor: "primary100", textColor: "primary700", children: [
|
|
6360
|
+
"📝 Modified (Unreviewed Revisions): ",
|
|
6361
|
+
selectedLifecycleStats.modified
|
|
6362
|
+
] }),
|
|
6363
|
+
selectedLifecycleStats.draft > 0 && /* @__PURE__ */ jsxs(Badge, { backgroundColor: "neutral200", textColor: "neutral800", children: [
|
|
6364
|
+
"📄 Draft (Never Published): ",
|
|
6365
|
+
selectedLifecycleStats.draft
|
|
6366
|
+
] }),
|
|
6367
|
+
selectedLifecycleStats.pendingReview > 0 && /* @__PURE__ */ jsxs(Badge, { backgroundColor: "warning100", textColor: "warning700", children: [
|
|
6368
|
+
"⏳ Pending Review: ",
|
|
6369
|
+
selectedLifecycleStats.pendingReview
|
|
6370
|
+
] })
|
|
6371
|
+
] })
|
|
6372
|
+
] }),
|
|
5147
6373
|
/* @__PURE__ */ jsxs(Box, { marginBottom: 4, children: [
|
|
5148
6374
|
/* @__PURE__ */ jsx(Typography, { variant: "sigma", textColor: "neutral600", marginBottom: 2, display: "block", children: "COLLECTION BREAKDOWN" }),
|
|
5149
6375
|
/* @__PURE__ */ jsx(Flex, { direction: "column", gap: 1, children: Object.entries(getSelectedBreakdown()).map(([name, count]) => /* @__PURE__ */ jsxs(
|
|
@@ -5194,6 +6420,128 @@ const BulkUpdater = () => {
|
|
|
5194
6420
|
] })
|
|
5195
6421
|
}
|
|
5196
6422
|
),
|
|
6423
|
+
publishOnApproval && selectedLifecycleStats.unreviewedCount > 0 && /* @__PURE__ */ jsxs(
|
|
6424
|
+
Box,
|
|
6425
|
+
{
|
|
6426
|
+
padding: 4,
|
|
6427
|
+
background: "neutral100",
|
|
6428
|
+
hasRadius: true,
|
|
6429
|
+
marginBottom: 4,
|
|
6430
|
+
style: { border: "1px solid #d9d8ff" },
|
|
6431
|
+
children: [
|
|
6432
|
+
/* @__PURE__ */ jsx(Typography, { variant: "sigma", textColor: "neutral600", marginBottom: 3, display: "block", children: "PUBLISHING STRATEGY & GOVERNANCE CONSENT" }),
|
|
6433
|
+
/* @__PURE__ */ jsxs(Flex, { direction: "column", gap: 3, children: [
|
|
6434
|
+
/* @__PURE__ */ jsx(
|
|
6435
|
+
Box,
|
|
6436
|
+
{
|
|
6437
|
+
padding: 3,
|
|
6438
|
+
hasRadius: true,
|
|
6439
|
+
style: {
|
|
6440
|
+
border: publishStrategy === "safe" ? "2px solid #4945ff" : "1px solid #eaeaef",
|
|
6441
|
+
backgroundColor: publishStrategy === "safe" ? "#f0f0ff" : "#ffffff",
|
|
6442
|
+
cursor: "pointer"
|
|
6443
|
+
},
|
|
6444
|
+
onClick: () => {
|
|
6445
|
+
setPublishStrategy("safe");
|
|
6446
|
+
setUnreviewedConsent(false);
|
|
6447
|
+
},
|
|
6448
|
+
children: /* @__PURE__ */ jsxs(Flex, { gap: 2, alignItems: "flex-start", children: [
|
|
6449
|
+
/* @__PURE__ */ jsx(
|
|
6450
|
+
"input",
|
|
6451
|
+
{
|
|
6452
|
+
type: "radio",
|
|
6453
|
+
id: "strategy-safe",
|
|
6454
|
+
name: "publishStrategy",
|
|
6455
|
+
checked: publishStrategy === "safe",
|
|
6456
|
+
onChange: () => {
|
|
6457
|
+
setPublishStrategy("safe");
|
|
6458
|
+
setUnreviewedConsent(false);
|
|
6459
|
+
},
|
|
6460
|
+
style: { marginTop: 3 }
|
|
6461
|
+
}
|
|
6462
|
+
),
|
|
6463
|
+
/* @__PURE__ */ jsxs(Box, { children: [
|
|
6464
|
+
/* @__PURE__ */ jsx(Typography, { fontWeight: "bold", display: "block", children: "🛡️ Safe Publishing (Recommended)" }),
|
|
6465
|
+
/* @__PURE__ */ jsxs(Typography, { variant: "pi", textColor: "neutral600", children: [
|
|
6466
|
+
"Only publish records that are already approved & live (",
|
|
6467
|
+
selectedLifecycleStats.published,
|
|
6468
|
+
" record",
|
|
6469
|
+
selectedLifecycleStats.published === 1 ? "" : "s",
|
|
6470
|
+
"). The ",
|
|
6471
|
+
selectedLifecycleStats.unreviewedCount,
|
|
6472
|
+
" unreviewed or draft record(s) will receive the bulk update in Draft mode without publishing unreviewed draft revisions to visitors."
|
|
6473
|
+
] })
|
|
6474
|
+
] })
|
|
6475
|
+
] })
|
|
6476
|
+
}
|
|
6477
|
+
),
|
|
6478
|
+
/* @__PURE__ */ jsx(
|
|
6479
|
+
Box,
|
|
6480
|
+
{
|
|
6481
|
+
padding: 3,
|
|
6482
|
+
hasRadius: true,
|
|
6483
|
+
style: {
|
|
6484
|
+
border: publishStrategy === "all" ? "2px solid #d02b20" : "1px solid #eaeaef",
|
|
6485
|
+
backgroundColor: publishStrategy === "all" ? "#fff5f5" : "#ffffff",
|
|
6486
|
+
cursor: "pointer"
|
|
6487
|
+
},
|
|
6488
|
+
onClick: () => setPublishStrategy("all"),
|
|
6489
|
+
children: /* @__PURE__ */ jsxs(Flex, { gap: 2, alignItems: "flex-start", children: [
|
|
6490
|
+
/* @__PURE__ */ jsx(
|
|
6491
|
+
"input",
|
|
6492
|
+
{
|
|
6493
|
+
type: "radio",
|
|
6494
|
+
id: "strategy-all",
|
|
6495
|
+
name: "publishStrategy",
|
|
6496
|
+
checked: publishStrategy === "all",
|
|
6497
|
+
onChange: () => setPublishStrategy("all"),
|
|
6498
|
+
style: { marginTop: 3 }
|
|
6499
|
+
}
|
|
6500
|
+
),
|
|
6501
|
+
/* @__PURE__ */ jsxs(Box, { children: [
|
|
6502
|
+
/* @__PURE__ */ jsx(Typography, { fontWeight: "bold", textColor: "danger700", display: "block", children: "⚠️ Publish All Selected Records (Includes Unreviewed Drafts)" }),
|
|
6503
|
+
/* @__PURE__ */ jsxs(Typography, { variant: "pi", textColor: "neutral600", children: [
|
|
6504
|
+
"Publish all ",
|
|
6505
|
+
totalSelectedCount,
|
|
6506
|
+
" records live to production immediately, pushing all pending unreviewed draft edits in the ",
|
|
6507
|
+
selectedLifecycleStats.unreviewedCount,
|
|
6508
|
+
" draft/modified record(s) live."
|
|
6509
|
+
] })
|
|
6510
|
+
] })
|
|
6511
|
+
] })
|
|
6512
|
+
}
|
|
6513
|
+
),
|
|
6514
|
+
publishStrategy === "all" && /* @__PURE__ */ jsx(
|
|
6515
|
+
Box,
|
|
6516
|
+
{
|
|
6517
|
+
padding: 3,
|
|
6518
|
+
background: "danger100",
|
|
6519
|
+
hasRadius: true,
|
|
6520
|
+
style: { border: "1px solid #f5c0b8" },
|
|
6521
|
+
children: /* @__PURE__ */ jsxs(Flex, { gap: 3, alignItems: "flex-start", children: [
|
|
6522
|
+
/* @__PURE__ */ jsx(
|
|
6523
|
+
Checkbox,
|
|
6524
|
+
{
|
|
6525
|
+
name: "unreviewedConsent",
|
|
6526
|
+
checked: unreviewedConsent,
|
|
6527
|
+
onCheckedChange: (checked) => setUnreviewedConsent(Boolean(checked))
|
|
6528
|
+
}
|
|
6529
|
+
),
|
|
6530
|
+
/* @__PURE__ */ jsxs(Box, { style: { cursor: "pointer" }, onClick: () => setUnreviewedConsent(!unreviewedConsent), children: [
|
|
6531
|
+
/* @__PURE__ */ jsx(Typography, { fontWeight: "bold", textColor: "danger700", display: "block", children: "Mandatory Risk Consent Required" }),
|
|
6532
|
+
/* @__PURE__ */ jsxs(Typography, { variant: "pi", textColor: "danger700", children: [
|
|
6533
|
+
"I understand and explicitly consent that ",
|
|
6534
|
+
selectedLifecycleStats.unreviewedCount,
|
|
6535
|
+
" record(s) with unreviewed draft revisions or saved draft states will be published live to production visitors."
|
|
6536
|
+
] })
|
|
6537
|
+
] })
|
|
6538
|
+
] })
|
|
6539
|
+
}
|
|
6540
|
+
)
|
|
6541
|
+
] })
|
|
6542
|
+
]
|
|
6543
|
+
}
|
|
6544
|
+
),
|
|
5197
6545
|
/* @__PURE__ */ jsx(Box, { marginBottom: 2, children: /* @__PURE__ */ jsx(
|
|
5198
6546
|
TextInput,
|
|
5199
6547
|
{
|
|
@@ -5220,54 +6568,61 @@ const BulkUpdater = () => {
|
|
|
5220
6568
|
zIndex: 20,
|
|
5221
6569
|
boxShadow: "0 -4px 16px rgba(0, 0, 0, 0.08)"
|
|
5222
6570
|
},
|
|
5223
|
-
children: /* @__PURE__ */ jsxs(Flex, {
|
|
5224
|
-
/* @__PURE__ */ jsx(
|
|
5225
|
-
/* @__PURE__ */ jsxs(Flex, {
|
|
5226
|
-
/* @__PURE__ */ jsx(
|
|
5227
|
-
|
|
5228
|
-
|
|
5229
|
-
variant: executionWindow?.isBusinessHours ? "default" : "secondary",
|
|
5230
|
-
size: "M",
|
|
5231
|
-
onClick: () => executeBatchWithMode("maker_checker"),
|
|
5232
|
-
loading: updating,
|
|
5233
|
-
children: "Submit for Checker Approval"
|
|
5234
|
-
}
|
|
5235
|
-
),
|
|
5236
|
-
executionWindow?.isBusinessHours ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
5237
|
-
/* @__PURE__ */ jsxs(
|
|
6571
|
+
children: /* @__PURE__ */ jsxs(Flex, { direction: "column", gap: 2, style: { width: "100%" }, children: [
|
|
6572
|
+
publishOnApproval && selectedLifecycleStats.unreviewedCount > 0 && publishStrategy === "all" && !unreviewedConsent && /* @__PURE__ */ jsx(Typography, { variant: "pi", textColor: "danger700", fontWeight: "bold", children: "⚠️ Explicit consent is required before publishing records with unreviewed draft revisions." }),
|
|
6573
|
+
/* @__PURE__ */ jsxs(Flex, { justifyContent: "space-between", alignItems: "center", gap: 3, style: { width: "100%" }, children: [
|
|
6574
|
+
/* @__PURE__ */ jsx(Button, { variant: "tertiary", size: "M", onClick: () => setShowConfirmModal(false), children: "Cancel" }),
|
|
6575
|
+
/* @__PURE__ */ jsxs(Flex, { gap: 2, wrap: "wrap", justifyContent: "flex-end", alignItems: "center", children: [
|
|
6576
|
+
/* @__PURE__ */ jsx(
|
|
5238
6577
|
Button,
|
|
5239
6578
|
{
|
|
5240
|
-
variant: "secondary",
|
|
6579
|
+
variant: executionWindow?.isBusinessHours ? "default" : "secondary",
|
|
5241
6580
|
size: "M",
|
|
5242
|
-
onClick: () => executeBatchWithMode("
|
|
6581
|
+
onClick: () => executeBatchWithMode("maker_checker"),
|
|
5243
6582
|
loading: updating,
|
|
5244
|
-
|
|
5245
|
-
|
|
5246
|
-
executionWindow?.offPeakStartTime || "18:00",
|
|
5247
|
-
")"
|
|
5248
|
-
]
|
|
6583
|
+
disabled: updating || publishOnApproval && selectedLifecycleStats.unreviewedCount > 0 && publishStrategy === "all" && !unreviewedConsent,
|
|
6584
|
+
children: "Submit for Checker Approval"
|
|
5249
6585
|
}
|
|
5250
6586
|
),
|
|
5251
|
-
/* @__PURE__ */
|
|
6587
|
+
executionWindow?.isBusinessHours ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
6588
|
+
/* @__PURE__ */ jsxs(
|
|
6589
|
+
Button,
|
|
6590
|
+
{
|
|
6591
|
+
variant: "secondary",
|
|
6592
|
+
size: "M",
|
|
6593
|
+
onClick: () => executeBatchWithMode("queue_offpeak"),
|
|
6594
|
+
loading: updating,
|
|
6595
|
+
disabled: updating || publishOnApproval && selectedLifecycleStats.unreviewedCount > 0 && publishStrategy === "all" && !unreviewedConsent,
|
|
6596
|
+
children: [
|
|
6597
|
+
"Queue for Off-Peak (",
|
|
6598
|
+
executionWindow?.offPeakStartTime || "18:00",
|
|
6599
|
+
")"
|
|
6600
|
+
]
|
|
6601
|
+
}
|
|
6602
|
+
),
|
|
6603
|
+
/* @__PURE__ */ jsx(
|
|
6604
|
+
Button,
|
|
6605
|
+
{
|
|
6606
|
+
variant: "danger-light",
|
|
6607
|
+
size: "S",
|
|
6608
|
+
onClick: () => executeBatchWithMode("immediate", true),
|
|
6609
|
+
loading: updating,
|
|
6610
|
+
disabled: updating || publishOnApproval && selectedLifecycleStats.unreviewedCount > 0 && publishStrategy === "all" && !unreviewedConsent,
|
|
6611
|
+
children: "Force Run Now"
|
|
6612
|
+
}
|
|
6613
|
+
)
|
|
6614
|
+
] }) : /* @__PURE__ */ jsx(
|
|
5252
6615
|
Button,
|
|
5253
6616
|
{
|
|
5254
|
-
variant: "
|
|
5255
|
-
size: "
|
|
5256
|
-
onClick: () => executeBatchWithMode("immediate"
|
|
6617
|
+
variant: "default",
|
|
6618
|
+
size: "M",
|
|
6619
|
+
onClick: () => executeBatchWithMode("immediate"),
|
|
5257
6620
|
loading: updating,
|
|
5258
|
-
|
|
6621
|
+
disabled: updating || publishOnApproval && selectedLifecycleStats.unreviewedCount > 0 && publishStrategy === "all" && !unreviewedConsent,
|
|
6622
|
+
children: "Confirm & Execute Now"
|
|
5259
6623
|
}
|
|
5260
6624
|
)
|
|
5261
|
-
] })
|
|
5262
|
-
Button,
|
|
5263
|
-
{
|
|
5264
|
-
variant: "default",
|
|
5265
|
-
size: "M",
|
|
5266
|
-
onClick: () => executeBatchWithMode("immediate"),
|
|
5267
|
-
loading: updating,
|
|
5268
|
-
children: "Confirm & Execute Now"
|
|
5269
|
-
}
|
|
5270
|
-
)
|
|
6625
|
+
] })
|
|
5271
6626
|
] })
|
|
5272
6627
|
] })
|
|
5273
6628
|
}
|
|
@@ -5342,6 +6697,27 @@ const BulkUpdater = () => {
|
|
|
5342
6697
|
gap: 16
|
|
5343
6698
|
},
|
|
5344
6699
|
children: [
|
|
6700
|
+
/* @__PURE__ */ jsxs(Box, { padding: 3, background: "neutral100", hasRadius: true, style: { border: "1px solid #eaeaef" }, children: [
|
|
6701
|
+
/* @__PURE__ */ jsxs(Typography, { variant: "sigma", textColor: "neutral600", marginBottom: 2, display: "block", children: [
|
|
6702
|
+
"LIFECYCLE STATUS BREAKDOWN (",
|
|
6703
|
+
totalSelectedCount,
|
|
6704
|
+
" Selected)"
|
|
6705
|
+
] }),
|
|
6706
|
+
/* @__PURE__ */ jsxs(Flex, { gap: 2, wrap: "wrap", children: [
|
|
6707
|
+
/* @__PURE__ */ jsxs(Badge, { backgroundColor: "success100", textColor: "success700", children: [
|
|
6708
|
+
"✓ Published: ",
|
|
6709
|
+
selectedLifecycleStats.published
|
|
6710
|
+
] }),
|
|
6711
|
+
selectedLifecycleStats.modified > 0 && /* @__PURE__ */ jsxs(Badge, { backgroundColor: "primary100", textColor: "primary700", children: [
|
|
6712
|
+
"📝 Modified (Unreviewed Revisions): ",
|
|
6713
|
+
selectedLifecycleStats.modified
|
|
6714
|
+
] }),
|
|
6715
|
+
selectedLifecycleStats.draft > 0 && /* @__PURE__ */ jsxs(Badge, { backgroundColor: "neutral200", textColor: "neutral800", children: [
|
|
6716
|
+
"📄 Draft (Never Published): ",
|
|
6717
|
+
selectedLifecycleStats.draft
|
|
6718
|
+
] })
|
|
6719
|
+
] })
|
|
6720
|
+
] }),
|
|
5345
6721
|
/* @__PURE__ */ jsxs(Box, { padding: 4, background: "neutral100", hasRadius: true, style: { border: "1px solid #eaeaef" }, children: [
|
|
5346
6722
|
/* @__PURE__ */ jsx(Typography, { variant: "omega", fontWeight: "bold", children: "Collection Breakdown:" }),
|
|
5347
6723
|
/* @__PURE__ */ jsx(Box, { marginTop: 2, children: collections.filter(
|
|
@@ -5380,6 +6756,37 @@ const BulkUpdater = () => {
|
|
|
5380
6756
|
);
|
|
5381
6757
|
}) })
|
|
5382
6758
|
] }),
|
|
6759
|
+
selectedLifecycleStats.unreviewedCount > 0 && /* @__PURE__ */ jsx(
|
|
6760
|
+
Box,
|
|
6761
|
+
{
|
|
6762
|
+
padding: 4,
|
|
6763
|
+
background: "danger100",
|
|
6764
|
+
hasRadius: true,
|
|
6765
|
+
style: { border: "1px solid #f5c0b8" },
|
|
6766
|
+
children: /* @__PURE__ */ jsxs(Flex, { gap: 3, alignItems: "flex-start", children: [
|
|
6767
|
+
/* @__PURE__ */ jsx(
|
|
6768
|
+
Checkbox,
|
|
6769
|
+
{
|
|
6770
|
+
name: "publishConsent",
|
|
6771
|
+
checked: publishConsent,
|
|
6772
|
+
onCheckedChange: (checked) => setPublishConsent(Boolean(checked))
|
|
6773
|
+
}
|
|
6774
|
+
),
|
|
6775
|
+
/* @__PURE__ */ jsxs(Box, { style: { cursor: "pointer" }, onClick: () => setPublishConsent(!publishConsent), children: [
|
|
6776
|
+
/* @__PURE__ */ jsx(Typography, { fontWeight: "bold", textColor: "danger700", display: "block", children: "Mandatory Risk Consent Required" }),
|
|
6777
|
+
/* @__PURE__ */ jsxs(Typography, { variant: "pi", textColor: "danger700", children: [
|
|
6778
|
+
"I understand and explicitly consent that ",
|
|
6779
|
+
selectedLifecycleStats.unreviewedCount,
|
|
6780
|
+
" record(s) contain unreviewed draft changes (",
|
|
6781
|
+
selectedLifecycleStats.draft,
|
|
6782
|
+
" Draft, ",
|
|
6783
|
+
selectedLifecycleStats.modified,
|
|
6784
|
+
" Modified) and will be published live to production visitors."
|
|
6785
|
+
] })
|
|
6786
|
+
] })
|
|
6787
|
+
] })
|
|
6788
|
+
}
|
|
6789
|
+
),
|
|
5383
6790
|
executionWindow?.isBusinessHours && /* @__PURE__ */ jsxs(
|
|
5384
6791
|
Box,
|
|
5385
6792
|
{
|
|
@@ -5424,54 +6831,61 @@ const BulkUpdater = () => {
|
|
|
5424
6831
|
flexShrink: 0,
|
|
5425
6832
|
boxShadow: "0 -4px 16px rgba(0, 0, 0, 0.08)"
|
|
5426
6833
|
},
|
|
5427
|
-
children: /* @__PURE__ */ jsxs(Flex, {
|
|
5428
|
-
/* @__PURE__ */ jsx(
|
|
5429
|
-
/* @__PURE__ */ jsxs(Flex, {
|
|
5430
|
-
/* @__PURE__ */ jsx(
|
|
5431
|
-
|
|
5432
|
-
|
|
5433
|
-
variant: executionWindow?.isBusinessHours ? "default" : "secondary",
|
|
5434
|
-
size: "M",
|
|
5435
|
-
onClick: () => executeBatchPublish("maker_checker"),
|
|
5436
|
-
loading: publishing,
|
|
5437
|
-
children: "Submit for Checker Approval"
|
|
5438
|
-
}
|
|
5439
|
-
),
|
|
5440
|
-
executionWindow?.isBusinessHours ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
5441
|
-
/* @__PURE__ */ jsxs(
|
|
6834
|
+
children: /* @__PURE__ */ jsxs(Flex, { direction: "column", gap: 2, style: { width: "100%" }, children: [
|
|
6835
|
+
selectedLifecycleStats.unreviewedCount > 0 && !publishConsent && /* @__PURE__ */ jsx(Typography, { variant: "pi", textColor: "danger700", fontWeight: "bold", children: "⚠️ Please check the mandatory consent box above to confirm publishing unreviewed draft records." }),
|
|
6836
|
+
/* @__PURE__ */ jsxs(Flex, { justifyContent: "space-between", alignItems: "center", gap: 3, style: { width: "100%" }, children: [
|
|
6837
|
+
/* @__PURE__ */ jsx(Button, { variant: "tertiary", size: "M", onClick: () => setShowPublishConfirmModal(false), children: "Cancel" }),
|
|
6838
|
+
/* @__PURE__ */ jsxs(Flex, { gap: 2, wrap: "wrap", justifyContent: "flex-end", alignItems: "center", children: [
|
|
6839
|
+
/* @__PURE__ */ jsx(
|
|
5442
6840
|
Button,
|
|
5443
6841
|
{
|
|
5444
|
-
variant: "secondary",
|
|
6842
|
+
variant: executionWindow?.isBusinessHours ? "default" : "secondary",
|
|
5445
6843
|
size: "M",
|
|
5446
|
-
onClick: () => executeBatchPublish("
|
|
6844
|
+
onClick: () => executeBatchPublish("maker_checker"),
|
|
5447
6845
|
loading: publishing,
|
|
5448
|
-
|
|
5449
|
-
|
|
5450
|
-
executionWindow?.offPeakStartTime || "18:00",
|
|
5451
|
-
")"
|
|
5452
|
-
]
|
|
6846
|
+
disabled: publishing || selectedLifecycleStats.unreviewedCount > 0 && !publishConsent,
|
|
6847
|
+
children: "Submit for Checker Approval"
|
|
5453
6848
|
}
|
|
5454
6849
|
),
|
|
5455
|
-
/* @__PURE__ */
|
|
6850
|
+
executionWindow?.isBusinessHours ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
6851
|
+
/* @__PURE__ */ jsxs(
|
|
6852
|
+
Button,
|
|
6853
|
+
{
|
|
6854
|
+
variant: "secondary",
|
|
6855
|
+
size: "M",
|
|
6856
|
+
onClick: () => executeBatchPublish("queue_offpeak"),
|
|
6857
|
+
loading: publishing,
|
|
6858
|
+
disabled: publishing || selectedLifecycleStats.unreviewedCount > 0 && !publishConsent,
|
|
6859
|
+
children: [
|
|
6860
|
+
"Queue for Off-Peak (",
|
|
6861
|
+
executionWindow?.offPeakStartTime || "18:00",
|
|
6862
|
+
")"
|
|
6863
|
+
]
|
|
6864
|
+
}
|
|
6865
|
+
),
|
|
6866
|
+
/* @__PURE__ */ jsx(
|
|
6867
|
+
Button,
|
|
6868
|
+
{
|
|
6869
|
+
variant: "danger-light",
|
|
6870
|
+
size: "S",
|
|
6871
|
+
onClick: () => executeBatchPublish("immediate", true),
|
|
6872
|
+
loading: publishing,
|
|
6873
|
+
disabled: publishing || selectedLifecycleStats.unreviewedCount > 0 && !publishConsent,
|
|
6874
|
+
children: "Force Publish Now"
|
|
6875
|
+
}
|
|
6876
|
+
)
|
|
6877
|
+
] }) : /* @__PURE__ */ jsx(
|
|
5456
6878
|
Button,
|
|
5457
6879
|
{
|
|
5458
|
-
variant: "
|
|
5459
|
-
size: "
|
|
5460
|
-
onClick: () => executeBatchPublish("immediate"
|
|
6880
|
+
variant: "default",
|
|
6881
|
+
size: "M",
|
|
6882
|
+
onClick: () => executeBatchPublish("immediate"),
|
|
5461
6883
|
loading: publishing,
|
|
5462
|
-
|
|
6884
|
+
disabled: publishing || selectedLifecycleStats.unreviewedCount > 0 && !publishConsent,
|
|
6885
|
+
children: "Confirm & Publish Now"
|
|
5463
6886
|
}
|
|
5464
6887
|
)
|
|
5465
|
-
] })
|
|
5466
|
-
Button,
|
|
5467
|
-
{
|
|
5468
|
-
variant: "default",
|
|
5469
|
-
size: "M",
|
|
5470
|
-
onClick: () => executeBatchPublish("immediate"),
|
|
5471
|
-
loading: publishing,
|
|
5472
|
-
children: "Confirm & Publish Now"
|
|
5473
|
-
}
|
|
5474
|
-
)
|
|
6888
|
+
] })
|
|
5475
6889
|
] })
|
|
5476
6890
|
] })
|
|
5477
6891
|
}
|
|
@@ -5494,6 +6908,7 @@ const BulkUpdater = () => {
|
|
|
5494
6908
|
previewData,
|
|
5495
6909
|
attribute: selectedAttribute,
|
|
5496
6910
|
publishOnApproval,
|
|
6911
|
+
lifecycleStats: selectedLifecycleStats,
|
|
5497
6912
|
targetValueDisplay: relationsMeta[selectedAttribute] ? selectedRelationDocId === "__clear__" ? "Clear / Unlink Relation" : relationOptions.find((o) => o.documentId === selectedRelationDocId)?.label || selectedRelationDocId || "(none)" : useRegex ? `Replace /${regexPattern}/g with "${attributeValue}"` : attributeValue
|
|
5498
6913
|
}
|
|
5499
6914
|
),
|
|
@@ -5515,10 +6930,13 @@ export {
|
|
|
5515
6930
|
BulkUpdater as default,
|
|
5516
6931
|
formatComponentName,
|
|
5517
6932
|
formatDisplayValue,
|
|
6933
|
+
getActiveSortLabel,
|
|
5518
6934
|
getAllNestedValues,
|
|
5519
6935
|
getAvailableColumnsForCollection,
|
|
5520
6936
|
getEntryLifecycleStatus,
|
|
5521
6937
|
getNestedValue,
|
|
6938
|
+
getPropertyValue,
|
|
6939
|
+
getSortOptionsForCollection,
|
|
5522
6940
|
parseDynamicZonePath
|
|
5523
6941
|
};
|
|
5524
|
-
//# sourceMappingURL=BulkUpdater-
|
|
6942
|
+
//# sourceMappingURL=BulkUpdater-CHdA0546.mjs.map
|