strapi-plugin-bulk-updater 1.3.1 → 1.3.6

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.
@@ -8,6 +8,93 @@ const icons = require("@strapi/icons");
8
8
  const ValidationRulesTab = require("./ValidationRulesTab-BLZWPGrZ.js");
9
9
  const _interopDefault = (e) => e && e.__esModule ? e : { default: e };
10
10
  const React__default = /* @__PURE__ */ _interopDefault(React);
11
+ function parseCsvRows(csvText) {
12
+ if (!csvText) return [];
13
+ let text = csvText;
14
+ if (text.charCodeAt(0) === 65279) {
15
+ text = text.slice(1);
16
+ }
17
+ const rows = [];
18
+ let currentRow = [];
19
+ let currentCell = "";
20
+ let inQuotes = false;
21
+ let cellIsQuoted = false;
22
+ for (let i = 0; i < text.length; i++) {
23
+ const char = text[i];
24
+ const nextChar = text[i + 1];
25
+ if (inQuotes) {
26
+ if (char === '"') {
27
+ if (nextChar === '"') {
28
+ currentCell += '"';
29
+ i++;
30
+ } else {
31
+ inQuotes = false;
32
+ }
33
+ } else {
34
+ currentCell += char;
35
+ }
36
+ } else {
37
+ if (char === '"' && !cellIsQuoted && currentCell.trim() === "") {
38
+ inQuotes = true;
39
+ cellIsQuoted = true;
40
+ currentCell = "";
41
+ } else if (char === ",") {
42
+ currentRow.push(cellIsQuoted ? currentCell : currentCell.trim());
43
+ currentCell = "";
44
+ cellIsQuoted = false;
45
+ } else if (char === "\r") {
46
+ if (nextChar === "\n") {
47
+ i++;
48
+ }
49
+ currentRow.push(cellIsQuoted ? currentCell : currentCell.trim());
50
+ if (currentRow.length > 1 || currentRow.length === 1 && currentRow[0] !== "") {
51
+ rows.push(currentRow);
52
+ }
53
+ currentRow = [];
54
+ currentCell = "";
55
+ cellIsQuoted = false;
56
+ } else if (char === "\n") {
57
+ currentRow.push(cellIsQuoted ? currentCell : currentCell.trim());
58
+ if (currentRow.length > 1 || currentRow.length === 1 && currentRow[0] !== "") {
59
+ rows.push(currentRow);
60
+ }
61
+ currentRow = [];
62
+ currentCell = "";
63
+ cellIsQuoted = false;
64
+ } else {
65
+ if (!(cellIsQuoted && !inQuotes && (char === " " || char === " "))) {
66
+ currentCell += char;
67
+ }
68
+ }
69
+ }
70
+ }
71
+ if (currentCell !== "" || cellIsQuoted || currentRow.length > 0) {
72
+ currentRow.push(cellIsQuoted ? currentCell : currentCell.trim());
73
+ if (currentRow.length > 1 || currentRow.length === 1 && currentRow[0] !== "") {
74
+ rows.push(currentRow);
75
+ }
76
+ }
77
+ return rows;
78
+ }
79
+ function parseCsv(csvText) {
80
+ const rows = parseCsvRows(csvText);
81
+ if (rows.length < 2) return [];
82
+ const headers = rows[0].map((h) => h.trim());
83
+ const records = [];
84
+ for (let i = 1; i < rows.length; i++) {
85
+ const row = rows[i];
86
+ const record = {};
87
+ headers.forEach((h, idx) => {
88
+ let val = row[idx] !== void 0 ? row[idx] : "";
89
+ if (typeof val === "string" && /^'[=+@-]/.test(val)) {
90
+ val = val.substring(1);
91
+ }
92
+ record[h] = val;
93
+ });
94
+ records.push(record);
95
+ }
96
+ return records;
97
+ }
11
98
  function CsvManagerTab() {
12
99
  const { get, post } = admin.useFetchClient();
13
100
  const { toggleNotification } = admin.useNotification();
@@ -139,20 +226,8 @@ function CsvManagerTab() {
139
226
  const text = event.target?.result;
140
227
  setCsvRawText(text);
141
228
  try {
142
- const lines = text.split(/\r?\n/).filter((l) => l.trim().length > 0);
143
- if (lines.length > 0) {
144
- const headers = lines[0].split(",").map((h) => h.replace(/^"|"$/g, "").trim());
145
- const previewRows = [];
146
- for (let i = 1; i < Math.min(lines.length, 6); i++) {
147
- const vals = lines[i].split(",").map((v) => v.replace(/^"|"$/g, "").trim());
148
- const row = {};
149
- headers.forEach((h, idx) => {
150
- row[h] = vals[idx] || "";
151
- });
152
- previewRows.push(row);
153
- }
154
- setParsedPreview(previewRows);
155
- }
229
+ const records = parseCsv(text);
230
+ setParsedPreview(records.slice(0, 10));
156
231
  } catch (err) {
157
232
  setParsedPreview([]);
158
233
  }
@@ -282,53 +357,20 @@ function CsvManagerTab() {
282
357
  /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { padding: 5, background: "neutral100", hasRadius: true, children: [
283
358
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "delta", tag: "h3", fontWeight: "bold", marginBottom: 2, children: "2. Import & Batch Override CSV" }),
284
359
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", textColor: "neutral600", marginBottom: 4, children: "Upload an updated CSV file to bulk update existing records or insert new records." }),
285
- /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 6, marginBottom: 4, wrap: "wrap", children: [
360
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { justifyContent: "space-between", alignItems: "center", marginBottom: 4, wrap: "wrap", gap: 4, children: [
286
361
  /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { children: [
287
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", fontWeight: "bold", textColor: "neutral800", marginBottom: 2, children: "Operation Mode" }),
288
- /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 4, wrap: "wrap", children: [
289
- /* @__PURE__ */ jsxRuntime.jsxs("label", { style: { display: "flex", alignItems: "center", gap: 6, cursor: "pointer" }, children: [
290
- /* @__PURE__ */ jsxRuntime.jsx(
291
- "input",
292
- {
293
- type: "radio",
294
- name: "importMode",
295
- value: "auto",
296
- checked: importMode === "auto",
297
- onChange: () => setImportMode("auto")
298
- }
299
- ),
300
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "omega", fontWeight: importMode === "auto" ? "bold" : "normal", children: "Smart Auto-Detect (Auto-updates matching documentId, creates new if missing)" })
301
- ] }),
302
- /* @__PURE__ */ jsxRuntime.jsxs("label", { style: { display: "flex", alignItems: "center", gap: 6, cursor: "pointer" }, children: [
303
- /* @__PURE__ */ jsxRuntime.jsx(
304
- "input",
305
- {
306
- type: "radio",
307
- name: "importMode",
308
- value: "update",
309
- checked: importMode === "update",
310
- onChange: () => setImportMode("update")
311
- }
312
- ),
313
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "omega", fontWeight: importMode === "update" ? "bold" : "normal", children: "Update Existing Only (Requires documentId)" })
314
- ] }),
315
- /* @__PURE__ */ jsxRuntime.jsxs("label", { style: { display: "flex", alignItems: "center", gap: 6, cursor: "pointer" }, children: [
316
- /* @__PURE__ */ jsxRuntime.jsx(
317
- "input",
318
- {
319
- type: "radio",
320
- name: "importMode",
321
- value: "create_or_override",
322
- checked: importMode === "create_or_override",
323
- onChange: () => setImportMode("create_or_override")
324
- }
325
- ),
326
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "omega", fontWeight: importMode === "create_or_override" ? "bold" : "normal", children: "Add / Override (Inserts new or replaces existing)" })
362
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", fontWeight: "bold", textColor: "neutral800", marginBottom: 1, display: "block", children: "Operation Mode" }),
363
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, alignItems: "center", wrap: "wrap", children: [
364
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Badge, { backgroundColor: "primary100", textColor: "primary700", children: "⚡ Smart Auto-Detect" }),
365
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Typography, { variant: "pi", textColor: "neutral600", children: [
366
+ "Automatically updates matching records by ",
367
+ /* @__PURE__ */ jsxRuntime.jsx("code", { children: "documentId" }),
368
+ " and creates new entries when ID is omitted."
327
369
  ] })
328
370
  ] })
329
371
  ] }),
330
- /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { style: { marginLeft: "auto" }, children: [
331
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", fontWeight: "bold", textColor: "neutral800", marginBottom: 2, children: "Publish Options" }),
372
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { children: [
373
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", fontWeight: "bold", textColor: "neutral800", marginBottom: 1, display: "block", children: "Publish Options" }),
332
374
  /* @__PURE__ */ jsxRuntime.jsx(
333
375
  designSystem.Checkbox,
334
376
  {
@@ -396,8 +438,8 @@ function CsvManagerTab() {
396
438
  missingDocIdCount > 0 && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { marginBottom: 3, children: /* @__PURE__ */ jsxRuntime.jsx(
397
439
  designSystem.Alert,
398
440
  {
399
- variant: importMode === "update" ? "warning" : "default",
400
- title: importMode === "update" ? "Warning: Missing Document IDs" : "Smart Auto-Detect Active",
441
+ variant: "default",
442
+ title: "Smart Auto-Detect Active",
401
443
  children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Typography, { variant: "omega", children: [
402
444
  missingDocIdCount,
403
445
  " row",
@@ -406,23 +448,40 @@ function CsvManagerTab() {
406
448
  /* @__PURE__ */ jsxRuntime.jsx("code", { children: "documentId" }),
407
449
  ".",
408
450
  " ",
409
- importMode === "auto" ? "Because no documentId is provided, the engine will automatically treat them as new entries and generate new database IDs for them." : importMode === "update" ? 'In "Update Existing Only" mode, rows without a documentId will be skipped. Switch to "Smart Auto-Detect" to automatically create them as new entries.' : "These will be created as new entries."
451
+ "Because no documentId is provided, the engine will automatically treat them as new entries and generate new database IDs for them."
410
452
  ] })
411
453
  }
412
454
  ) }),
413
- /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Table, { colCount: headers.length + 1, rowCount: parsedPreview.length + 1, children: [
455
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { style: { overflowX: "auto", maxWidth: "100%", border: "1px solid #e0e0e0", borderRadius: 4 }, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Table, { colCount: headers.length + 1, rowCount: parsedPreview.length + 1, children: [
414
456
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Thead, { children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Tr, { children: [
415
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Th, { style: { width: 140 }, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "sigma", children: "Detected Action" }) }),
416
- headers.map((h) => /* @__PURE__ */ jsxRuntime.jsx(designSystem.Th, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "sigma", children: h }) }, h))
457
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Th, { style: { width: 150, minWidth: 150 }, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "sigma", children: "Detected Action" }) }),
458
+ headers.map((h) => /* @__PURE__ */ jsxRuntime.jsx(designSystem.Th, { style: { minWidth: 160 }, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "sigma", children: h }) }, h))
417
459
  ] }) }),
418
460
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Tbody, { children: parsedPreview.map((row, rIdx) => {
419
461
  const hasDocId = !!(row.documentId || row.id || "").trim();
420
462
  return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Tr, { children: [
421
463
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { children: hasDocId ? /* @__PURE__ */ jsxRuntime.jsx(designSystem.Badge, { backgroundColor: "primary100", textColor: "primary700", children: "🔄 Match / Update" }) : /* @__PURE__ */ jsxRuntime.jsx(designSystem.Badge, { backgroundColor: "warning100", textColor: "warning700", children: "➕ New Entry" }) }),
422
- headers.map((h) => /* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { children: (h === "documentId" || h === "id") && !row[h]?.trim() ? /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", textColor: "warning700", fontWeight: "bold", children: "(Auto-generate ID)" }) : /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "omega", children: row[h] || "-" }) }, h))
464
+ headers.map((h) => /* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { style: { verticalAlign: "top", maxWidth: 300 }, children: (h === "documentId" || h === "id") && !row[h]?.trim() ? /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", textColor: "warning700", fontWeight: "bold", children: "(Auto-generate ID)" }) : /* @__PURE__ */ jsxRuntime.jsx(
465
+ designSystem.Typography,
466
+ {
467
+ variant: "omega",
468
+ style: {
469
+ display: "-webkit-box",
470
+ WebkitLineClamp: 3,
471
+ WebkitBoxOrient: "vertical",
472
+ overflow: "hidden",
473
+ textOverflow: "ellipsis",
474
+ whiteSpace: "pre-wrap",
475
+ wordBreak: "break-word",
476
+ maxHeight: 65
477
+ },
478
+ title: row[h] || "",
479
+ children: row[h] || "-"
480
+ }
481
+ ) }, h))
423
482
  ] }, rIdx);
424
483
  }) })
425
- ] }),
484
+ ] }) }),
426
485
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { justifyContent: "flex-end", marginTop: 4, children: /* @__PURE__ */ jsxRuntime.jsx(
427
486
  designSystem.Button,
428
487
  {
@@ -431,7 +490,7 @@ function CsvManagerTab() {
431
490
  startIcon: /* @__PURE__ */ jsxRuntime.jsx(icons.Check, {}),
432
491
  onClick: handleExecuteImport,
433
492
  loading: importing,
434
- children: importMode === "auto" ? "Execute Smart Import (Auto-Detect)" : importMode === "update" ? "Execute Bulk Update" : "Execute Add / Override"
493
+ children: "Execute Smart Import (Auto-Detect)"
435
494
  }
436
495
  ) })
437
496
  ] });
@@ -1689,6 +1748,16 @@ const BulkUpdater = () => {
1689
1748
  const [bulkExporting, setBulkExporting] = React.useState(false);
1690
1749
  const MODELS_CACHE_KEY = "strapi_bulk_updater_models_cache";
1691
1750
  const LAST_ATTR_KEY = "strapi_bulk_updater_last_attr";
1751
+ const LAST_COLLECTION_KEY = "strapi_bulk_updater_last_collection";
1752
+ const getInitialCollectionUid = () => {
1753
+ try {
1754
+ const stored = localStorage.getItem(LAST_COLLECTION_KEY);
1755
+ if (stored) return stored;
1756
+ } catch {
1757
+ }
1758
+ return "";
1759
+ };
1760
+ const [selectedCollectionUid, setSelectedCollectionUid] = React.useState(getInitialCollectionUid);
1692
1761
  const getInitialAttribute = () => {
1693
1762
  try {
1694
1763
  const stored = localStorage.getItem(LAST_ATTR_KEY);
@@ -1747,7 +1816,7 @@ const BulkUpdater = () => {
1747
1816
  const [filterOperator, setFilterOperator] = React.useState("none");
1748
1817
  const [filterQuery, setFilterQuery] = React.useState("");
1749
1818
  const [entrySearch, setEntrySearch] = React.useState("");
1750
- const isFilterActive = Boolean(searchAttribute && searchAttribute !== selectedAttribute) || filterOperator !== "none" && (["empty", "not_empty"].includes(filterOperator) || Boolean(filterQuery.trim())) || Boolean(entrySearch.trim());
1819
+ const isFilterActive = Boolean(searchAttribute && searchAttribute !== selectedAttribute) || filterOperator !== "none" && (["empty", "not_empty"].includes(filterOperator) || Boolean(filterQuery.trim())) || Boolean(entrySearch.trim()) || Boolean(useRegex && regexPattern.trim());
1751
1820
  const [lastResults, setLastResults] = React.useState(null);
1752
1821
  const [updateSummary, setUpdateSummary] = React.useState(null);
1753
1822
  const [collectionPages, setCollectionPages] = React.useState({});
@@ -1760,6 +1829,7 @@ const BulkUpdater = () => {
1760
1829
  const [collectionSorts, setCollectionSorts] = React.useState({});
1761
1830
  const [collectionColumnVisibility, setCollectionColumnVisibility] = React.useState({});
1762
1831
  const [openColumnPickerUid, setOpenColumnPickerUid] = React.useState(null);
1832
+ const [columnSearchTerm, setColumnSearchTerm] = React.useState("");
1763
1833
  const toggleColumn = (colUid, colKey, availableCols) => {
1764
1834
  setCollectionColumnVisibility((prev) => {
1765
1835
  const current = prev[colUid] || availableCols.filter((c) => c.defaultVisible).map((c) => c.key);
@@ -1830,12 +1900,29 @@ const BulkUpdater = () => {
1830
1900
  if (data.attributesMeta) {
1831
1901
  setAttributesMeta(data.attributesMeta);
1832
1902
  }
1903
+ let resolvedColUid = selectedCollectionUid;
1904
+ let storedCol = null;
1905
+ try {
1906
+ storedCol = localStorage.getItem(LAST_COLLECTION_KEY);
1907
+ } catch {
1908
+ }
1909
+ if (!resolvedColUid || !cols.some((c) => c.uid === resolvedColUid)) {
1910
+ resolvedColUid = storedCol && cols.some((c) => c.uid === storedCol) ? storedCol : cols[0]?.uid || "";
1911
+ }
1912
+ setSelectedCollectionUid(resolvedColUid);
1913
+ try {
1914
+ if (resolvedColUid) localStorage.setItem(LAST_COLLECTION_KEY, resolvedColUid);
1915
+ } catch {
1916
+ }
1917
+ const activeCol = cols.find((c) => c.uid === resolvedColUid) || cols[0];
1918
+ const activeAttrs = activeCol?.attributes || [];
1919
+ setAttributes(activeAttrs);
1833
1920
  let storedAttr = null;
1834
1921
  try {
1835
1922
  storedAttr = localStorage.getItem(LAST_ATTR_KEY);
1836
1923
  } catch {
1837
1924
  }
1838
- const resolvedAttr = storedAttr && attrs.includes(storedAttr) ? storedAttr : selectedAttribute && attrs.includes(selectedAttribute) ? selectedAttribute : "";
1925
+ const resolvedAttr = storedAttr && activeAttrs.includes(storedAttr) ? storedAttr : selectedAttribute && activeAttrs.includes(selectedAttribute) ? selectedAttribute : activeAttrs[0] || "";
1839
1926
  setSelectedAttribute(resolvedAttr);
1840
1927
  if (resolvedAttr && data.relationsMeta && data.relationsMeta[resolvedAttr]) {
1841
1928
  fetchRelationOptions(data.relationsMeta[resolvedAttr].targetUid);
@@ -2018,36 +2105,60 @@ const BulkUpdater = () => {
2018
2105
  return;
2019
2106
  }
2020
2107
  const timer = setTimeout(() => {
2021
- if (collections.length > 0) {
2022
- const isFilterActiveNow = Boolean(searchAttribute && searchAttribute !== selectedAttribute) || filterOperator !== "none" && (["empty", "not_empty"].includes(filterOperator) || Boolean(filterQuery.trim())) || Boolean(entrySearch.trim());
2108
+ if (selectedCollectionUid) {
2109
+ const isFilterActiveNow = Boolean(searchAttribute && searchAttribute !== selectedAttribute) || filterOperator !== "none" && (["empty", "not_empty"].includes(filterOperator) || Boolean(filterQuery.trim())) || Boolean(entrySearch.trim()) || Boolean(useRegex && regexPattern.trim());
2023
2110
  if (isFilterActiveNow) {
2024
2111
  setSelectedEntries({});
2025
2112
  }
2026
- const targetSearchAttr = searchAttribute || selectedAttribute;
2027
- const targetCols = collections.filter((col) => {
2028
- if (visibleTypeUids[col.uid] === false) return false;
2029
- if (filterOperator !== "none" && targetSearchAttr && !col.attributes.includes(targetSearchAttr)) return false;
2030
- return true;
2031
- });
2032
- targetCols.forEach((col) => {
2033
- loadCollectionPage(
2034
- col.uid,
2035
- 1,
2036
- void 0,
2037
- void 0,
2038
- void 0,
2039
- filterOperator,
2040
- filterQuery,
2041
- entrySearch,
2042
- true,
2043
- searchAttribute
2044
- );
2045
- });
2113
+ loadCollectionPage(
2114
+ selectedCollectionUid,
2115
+ 1,
2116
+ void 0,
2117
+ void 0,
2118
+ void 0,
2119
+ filterOperator,
2120
+ filterQuery,
2121
+ entrySearch,
2122
+ true,
2123
+ searchAttribute
2124
+ );
2046
2125
  }
2047
2126
  }, 350);
2048
2127
  return () => clearTimeout(timer);
2049
- }, [searchAttribute, filterOperator, filterQuery, entrySearch]);
2128
+ }, [selectedCollectionUid, searchAttribute, filterOperator, filterQuery, entrySearch, useRegex, regexPattern]);
2050
2129
  const KEY_SEP = "@@@";
2130
+ const selectedCol = React.useMemo(() => {
2131
+ if (!collections.length) return null;
2132
+ return collections.find((c) => c.uid === selectedCollectionUid) || collections[0] || null;
2133
+ }, [collections, selectedCollectionUid]);
2134
+ const handleCollectionChange = (newUid) => {
2135
+ if (newUid === selectedCollectionUid) return;
2136
+ setSelectedCollectionUid(newUid);
2137
+ try {
2138
+ localStorage.setItem(LAST_COLLECTION_KEY, newUid);
2139
+ } catch {
2140
+ }
2141
+ setSelectedEntries({});
2142
+ setSearchAttribute("");
2143
+ setSearchAttributeSearch("");
2144
+ const targetCol = collections.find((c) => c.uid === newUid);
2145
+ const colAttrs = targetCol?.attributes || [];
2146
+ setAttributes(colAttrs);
2147
+ if (!colAttrs.includes(selectedAttribute)) {
2148
+ const newAttr = colAttrs[0] || "";
2149
+ setSelectedAttribute(newAttr);
2150
+ try {
2151
+ localStorage.setItem(LAST_ATTR_KEY, newAttr);
2152
+ } catch {
2153
+ }
2154
+ if (newAttr && relationsMeta[newAttr]) {
2155
+ fetchRelationOptions(relationsMeta[newAttr].targetUid);
2156
+ } else {
2157
+ setSelectedRelationDocId("");
2158
+ }
2159
+ }
2160
+ loadCollectionPage(newUid, 1, void 0, void 0, void 0, filterOperator, filterQuery, entrySearch, true, "");
2161
+ };
2051
2162
  const handleAttributeChange = (newAttr) => {
2052
2163
  if (newAttr !== selectedAttribute) {
2053
2164
  setSelectedAttribute(newAttr);
@@ -2070,56 +2181,23 @@ const BulkUpdater = () => {
2070
2181
  } else {
2071
2182
  setRelationOptions([]);
2072
2183
  }
2073
- if (newAttr) {
2074
- const collectionsToLoad = collections.filter(
2075
- (col) => visibleTypeUids[col.uid] !== false && col.attributes.includes(newAttr) && (!collectionPages[col.uid]?.entries || collectionPages[col.uid].entries.length === 0)
2076
- );
2077
- collectionsToLoad.forEach((col) => {
2078
- loadCollectionPage(col.uid, 1);
2079
- });
2184
+ if (newAttr && selectedCollectionUid) {
2185
+ loadCollectionPage(selectedCollectionUid, 1);
2080
2186
  }
2081
2187
  }
2082
2188
  };
2083
- const filteredCollections = collections.filter(
2084
- (c) => visibleTypeUids[c.uid] !== false && (!collectionSearch.trim() || c.displayName.toLowerCase().includes(collectionSearch.toLowerCase().trim()) || c.uid.toLowerCase().includes(collectionSearch.toLowerCase().trim()))
2085
- );
2086
- const supportedCollections = React.useMemo(() => {
2087
- return collections.filter((c) => c.attributes.includes(selectedAttribute));
2088
- }, [collections, selectedAttribute]);
2089
- const unsupportedCollections = React.useMemo(() => {
2090
- return collections.filter((c) => !c.attributes.includes(selectedAttribute));
2091
- }, [collections, selectedAttribute]);
2092
- const handleFocusOnlySupported = () => {
2093
- const newVis = {};
2094
- collections.forEach((c) => {
2095
- newVis[c.uid] = c.attributes.includes(selectedAttribute);
2096
- });
2097
- setVisibleTypeUids(newVis);
2098
- toggleNotification({
2099
- type: "info",
2100
- message: `Workspace focused: Showing ${supportedCollections.length} of ${collections.length} collections supporting "${selectedAttribute}".`
2101
- });
2102
- };
2103
- const handleShowAllTypes = () => {
2104
- const newVis = {};
2105
- collections.forEach((c) => {
2106
- newVis[c.uid] = true;
2107
- });
2108
- setVisibleTypeUids(newVis);
2109
- };
2110
- const handleHideAllTypes = () => {
2111
- const newVis = {};
2112
- collections.forEach((c) => {
2113
- newVis[c.uid] = false;
2114
- });
2115
- setVisibleTypeUids(newVis);
2116
- };
2189
+ const filteredCollections = React.useMemo(() => {
2190
+ return selectedCol ? [selectedCol] : [];
2191
+ }, [selectedCol]);
2117
2192
  const [attributeSearch, setAttributeSearch] = React.useState("");
2118
2193
  const [searchAttributeSearch, setSearchAttributeSearch] = React.useState("");
2119
2194
  const getAttrDepth = (attr) => attributesMeta[attr]?.depth ?? (attr.includes(".") ? attr.split(".").length - 1 : 0);
2195
+ const availableColAttributes = React.useMemo(() => {
2196
+ return selectedCol?.attributes || attributes || [];
2197
+ }, [selectedCol, attributes]);
2120
2198
  const depthFilteredAttributes = React.useMemo(() => {
2121
- return attributes.filter((attr) => getAttrDepth(attr) <= componentDepth);
2122
- }, [attributes, componentDepth, attributesMeta]);
2199
+ return availableColAttributes.filter((attr) => getAttrDepth(attr) <= componentDepth);
2200
+ }, [availableColAttributes, componentDepth, attributesMeta]);
2123
2201
  const filteredAttributes = React.useMemo(() => {
2124
2202
  if (!attributeSearch.trim()) {
2125
2203
  return depthFilteredAttributes;
@@ -2228,15 +2306,6 @@ const BulkUpdater = () => {
2228
2306
  });
2229
2307
  }
2230
2308
  };
2231
- const handleGlobalPageSizeChange = (newSize) => {
2232
- const capped = Math.min(500, Math.max(1, newSize));
2233
- setDefaultPageSize(capped);
2234
- collections.forEach((col) => {
2235
- if (!col.isSingleType) {
2236
- loadCollectionPage(col.uid, 1, capped);
2237
- }
2238
- });
2239
- };
2240
2309
  const handleCollectionPageSizeChange = (colUid, newSize) => {
2241
2310
  const capped = Math.min(500, Math.max(1, newSize));
2242
2311
  loadCollectionPage(colUid, 1, capped);
@@ -2261,6 +2330,16 @@ const BulkUpdater = () => {
2261
2330
  }));
2262
2331
  };
2263
2332
  const entryMatchesFilter = (entry, attr) => {
2333
+ if (useRegex && regexPattern.trim()) {
2334
+ try {
2335
+ const regex = new RegExp(regexPattern, "i");
2336
+ const targetSearchVal = formatDisplayValue(getNestedValue(entry, attr));
2337
+ if (!regex.test(targetSearchVal)) {
2338
+ return false;
2339
+ }
2340
+ } catch {
2341
+ }
2342
+ }
2264
2343
  if (filterOperator === "none") return true;
2265
2344
  const val = getNestedValue(entry, attr);
2266
2345
  const displayStr = formatDisplayValue(val);
@@ -2323,6 +2402,7 @@ const BulkUpdater = () => {
2323
2402
  setFilterOperator("none");
2324
2403
  setFilterQuery("");
2325
2404
  setEntrySearch("");
2405
+ setRegexPattern("");
2326
2406
  setSelectedEntries({});
2327
2407
  collections.forEach((col) => {
2328
2408
  loadCollectionPage(col.uid, 1, void 0, void 0, void 0, "none", "", "", false, "");
@@ -3111,41 +3191,79 @@ const BulkUpdater = () => {
3111
3191
  ] })
3112
3192
  }
3113
3193
  ) : activeTab === "editor" ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
3114
- /* @__PURE__ */ jsxRuntime.jsxs(
3194
+ /* @__PURE__ */ jsxRuntime.jsx(
3115
3195
  designSystem.Box,
3116
3196
  {
3117
- padding: 6,
3197
+ padding: 4,
3118
3198
  background: "neutral0",
3119
3199
  shadow: "filterShadow",
3120
3200
  hasRadius: true,
3121
- marginBottom: 6,
3201
+ marginBottom: 5,
3122
3202
  style: { width: "100%", maxWidth: "100%", minWidth: 0, boxSizing: "border-box" },
3123
- children: [
3124
- /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { justifyContent: "space-between", alignItems: "center", marginBottom: 4, wrap: "wrap", gap: 3, children: [
3125
- /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { children: [
3126
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "delta", tag: "h2", fontWeight: "semiBold", children: "1. Configure Attribute Update" }),
3127
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", textColor: "neutral600", children: "Select the target attribute to update across collections." })
3128
- ] }),
3129
- /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, alignItems: "center", wrap: "wrap", children: [
3130
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", textColor: "neutral700", fontWeight: "bold", children: "Component Nesting Depth:" }),
3131
- [1, 2, 3, 4, 5].map((lvl) => /* @__PURE__ */ jsxRuntime.jsxs(
3132
- designSystem.Button,
3203
+ children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { justifyContent: "space-between", alignItems: "center", wrap: "wrap", gap: 3, children: [
3204
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 3, alignItems: "center", wrap: "wrap", style: { flex: 1, minWidth: 280 }, children: [
3205
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { style: { width: 340, minWidth: 260 }, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Field.Root, { children: [
3206
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Label, { children: "Target Collection Type" }),
3207
+ /* @__PURE__ */ jsxRuntime.jsx(
3208
+ designSystem.Combobox,
3133
3209
  {
3134
- variant: componentDepth === lvl ? "default" : "tertiary",
3135
- size: "S",
3136
- onClick: () => handleComponentDepthChange(lvl),
3137
- title: `Discover nested component attributes up to Level ${lvl}`,
3138
- children: [
3139
- "Level ",
3140
- lvl
3141
- ]
3210
+ autocomplete: "none",
3211
+ placeholder: "Select Collection Type...",
3212
+ value: selectedCollectionUid || void 0,
3213
+ onChange: (val) => {
3214
+ if (val && typeof val === "string") {
3215
+ handleCollectionChange(val);
3216
+ }
3217
+ },
3218
+ children: collections.map((col) => /* @__PURE__ */ jsxRuntime.jsx(designSystem.ComboboxOption, { value: col.uid, textValue: `${col.displayName} (${col.uid})`, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { justifyContent: "space-between", alignItems: "center", style: { width: "100%" }, children: [
3219
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", fontWeight: "bold", children: col.displayName }),
3220
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { gap: 1, alignItems: "center", children: col.isSingleType ? /* @__PURE__ */ jsxRuntime.jsx(designSystem.Badge, { backgroundColor: "secondary100", textColor: "secondary700", size: "S", children: "Single" }) : /* @__PURE__ */ jsxRuntime.jsx(designSystem.Badge, { backgroundColor: "neutral150", textColor: "neutral700", size: "S", children: col.totalEntries !== void 0 ? `${col.totalEntries} entries` : "" }) })
3221
+ ] }) }, col.uid))
3142
3222
  },
3143
- `depth_cfg_${lvl}`
3144
- ))
3223
+ `top-col-${selectedCollectionUid}`
3224
+ )
3225
+ ] }) }),
3226
+ selectedCol && /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, alignItems: "center", wrap: "wrap", style: { paddingTop: 20 }, children: [
3227
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Badge, { backgroundColor: "primary100", textColor: "primary700", children: selectedCol.isSingleType ? "SINGLE TYPE" : "COLLECTION" }),
3228
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Badge, { backgroundColor: "neutral150", textColor: "neutral700", children: selectedCol.isSingleType ? "1 single entry" : `${collectionPages[selectedCol.uid]?.total ?? selectedCol.totalEntries ?? selectedCol.entries?.length ?? 0} records` })
3145
3229
  ] })
3146
3230
  ] }),
3147
- /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 4, alignItems: "flex-end", wrap: "wrap", children: [
3148
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { style: { minWidth: 280, flex: 1, maxWidth: 440 }, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Field.Root, { children: [
3231
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, alignItems: "center", wrap: "wrap", children: [
3232
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", textColor: "neutral700", fontWeight: "bold", children: "Component Nesting Depth:" }),
3233
+ [1, 2, 3, 4, 5].map((lvl) => /* @__PURE__ */ jsxRuntime.jsxs(
3234
+ designSystem.Button,
3235
+ {
3236
+ variant: componentDepth === lvl ? "default" : "tertiary",
3237
+ size: "S",
3238
+ onClick: () => handleComponentDepthChange(lvl),
3239
+ title: `Discover nested component attributes up to Level ${lvl}`,
3240
+ children: [
3241
+ "Level ",
3242
+ lvl
3243
+ ]
3244
+ },
3245
+ `depth_cfg_${lvl}`
3246
+ ))
3247
+ ] })
3248
+ ] })
3249
+ }
3250
+ ),
3251
+ /* @__PURE__ */ jsxRuntime.jsxs(
3252
+ designSystem.Box,
3253
+ {
3254
+ padding: 6,
3255
+ background: "neutral0",
3256
+ shadow: "filterShadow",
3257
+ hasRadius: true,
3258
+ marginBottom: 6,
3259
+ style: { width: "100%", maxWidth: "100%", minWidth: 0, boxSizing: "border-box" },
3260
+ children: [
3261
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { justifyContent: "space-between", alignItems: "center", marginBottom: 4, wrap: "wrap", gap: 3, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { children: [
3262
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "delta", tag: "h2", fontWeight: "semiBold", children: "1. Configure Attribute Update" }),
3263
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", textColor: "neutral600", children: "Select the target attribute to update and configure the replacement value." })
3264
+ ] }) }),
3265
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 3, alignItems: "flex-end", wrap: "wrap", children: [
3266
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { style: { width: 280, minWidth: 230 }, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Field.Root, { children: [
3149
3267
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Label, { children: "Attribute to Update" }),
3150
3268
  /* @__PURE__ */ jsxRuntime.jsx(
3151
3269
  designSystem.Combobox,
@@ -3175,7 +3293,8 @@ const BulkUpdater = () => {
3175
3293
  }
3176
3294
  },
3177
3295
  children: memoizedComboboxOptions
3178
- }
3296
+ },
3297
+ `update-attr-${selectedCollectionUid}-${selectedAttribute}`
3179
3298
  )
3180
3299
  ] }) }),
3181
3300
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { style: { flex: 1, minWidth: 340 }, children: relationsMeta[selectedAttribute] ? /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", gap: 1, style: { width: "100%" }, children: [
@@ -3344,103 +3463,24 @@ const BulkUpdater = () => {
3344
3463
  ] }),
3345
3464
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.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." })
3346
3465
  ] }) }),
3347
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { marginTop: 4, padding: 4, background: "neutral100", hasRadius: true, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { justifyContent: "space-between", alignItems: "center", wrap: "wrap", gap: 3, children: [
3348
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { gap: 2, alignItems: "center", children: /* @__PURE__ */ jsxRuntime.jsx(
3349
- designSystem.Checkbox,
3350
- {
3351
- checked: useRegex,
3352
- onCheckedChange: (checked) => setUseRegex(Boolean(checked)),
3353
- children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { fontWeight: "bold", children: "Enable Regex Find & Replace" })
3354
- }
3355
- ) }),
3356
- useRegex && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { style: { flex: 1, minWidth: 240 }, children: /* @__PURE__ */ jsxRuntime.jsx(
3357
- designSystem.TextInput,
3358
- {
3359
- placeholder: "Regex pattern (e.g. \\b(OldName)\\b)...",
3360
- value: regexPattern,
3361
- onChange: (e) => setRegexPattern(e.target.value)
3362
- }
3363
- ) })
3364
- ] }) }),
3365
- selectedAttribute && /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { marginTop: 4, padding: 4, background: "neutral100", hasRadius: true, style: { border: "1px solid #eaeaef" }, children: [
3366
- /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { justifyContent: "space-between", alignItems: "center", wrap: "wrap", gap: 3, children: [
3367
- /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, alignItems: "center", wrap: "wrap", children: [
3368
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", fontWeight: "bold", children: "Attribute Info:" }),
3369
- /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Typography, { variant: "pi", children: [
3370
- "Targeting attribute ",
3371
- /* @__PURE__ */ jsxRuntime.jsx("strong", { children: /* @__PURE__ */ jsxRuntime.jsx("code", { children: selectedAttribute }) })
3372
- ] }),
3373
- /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Badge, { backgroundColor: "success100", textColor: "success700", children: [
3374
- "✓ Supported in ",
3375
- supportedCollections.length,
3376
- " of ",
3377
- collections.length,
3378
- " Collections"
3379
- ] }),
3380
- unsupportedCollections.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Badge, { backgroundColor: "neutral200", textColor: "neutral700", children: [
3381
- "— Not in schema: ",
3382
- unsupportedCollections.length
3383
- ] })
3384
- ] }),
3385
- /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, alignItems: "center", children: [
3386
- /* @__PURE__ */ jsxRuntime.jsxs(
3387
- designSystem.Button,
3388
- {
3389
- variant: "secondary",
3390
- size: "S",
3391
- onClick: handleFocusOnlySupported,
3392
- children: [
3393
- "Focus Workspace: Show Supported Only (",
3394
- supportedCollections.length,
3395
- ")"
3396
- ]
3397
- }
3398
- ),
3399
- /* @__PURE__ */ jsxRuntime.jsx(
3400
- designSystem.Button,
3401
- {
3402
- variant: "tertiary",
3403
- size: "S",
3404
- onClick: () => setAttributeInfoExpanded((prev) => !prev),
3405
- children: attributeInfoExpanded ? "Hide Schema Breakdown ▲" : "Inspect Breakdown ▼"
3406
- }
3407
- )
3408
- ] })
3466
+ selectedCol && selectedAttribute && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { marginTop: 4, padding: 3, background: "neutral100", hasRadius: true, style: { border: "1px solid #eaeaef" }, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { justifyContent: "space-between", alignItems: "center", wrap: "wrap", gap: 3, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, alignItems: "center", wrap: "wrap", children: [
3467
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", fontWeight: "bold", children: "Target Selection:" }),
3468
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Badge, { backgroundColor: "primary100", textColor: "primary700", children: [
3469
+ "Collection: ",
3470
+ selectedCol.displayName
3409
3471
  ] }),
3410
- attributeInfoExpanded && /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { marginTop: 3, paddingTop: 3, style: { borderTop: "1px solid #dcdce4" }, children: [
3411
- /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { justifyContent: "space-between", alignItems: "center", marginBottom: 3, wrap: "wrap", gap: 2, children: [
3412
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", textColor: "neutral600", children: "Showing collection types schema compatibility. Type to filter:" }),
3413
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { style: { width: 220 }, children: /* @__PURE__ */ jsxRuntime.jsx(
3414
- designSystem.TextInput,
3415
- {
3416
- placeholder: "Filter collection name...",
3417
- size: "S",
3418
- value: attributeInfoSearch,
3419
- onChange: (e) => setAttributeInfoSearch(e.target.value)
3420
- }
3421
- ) })
3422
- ] }),
3423
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { wrap: "wrap", gap: 2, alignItems: "center", style: { maxHeight: 180, overflowY: "auto" }, children: collections.filter(
3424
- (c) => !attributeInfoSearch.trim() || c.displayName.toLowerCase().includes(attributeInfoSearch.toLowerCase().trim()) || c.uid.toLowerCase().includes(attributeInfoSearch.toLowerCase().trim())
3425
- ).map((c) => {
3426
- const hasAttr = c.attributes.includes(selectedAttribute);
3427
- return /* @__PURE__ */ jsxRuntime.jsxs(
3428
- designSystem.Badge,
3429
- {
3430
- backgroundColor: hasAttr ? "success100" : "neutral200",
3431
- textColor: hasAttr ? "success700" : "neutral600",
3432
- size: "S",
3433
- children: [
3434
- c.displayName,
3435
- ": ",
3436
- hasAttr ? "✓ Supported" : "— Not in schema"
3437
- ]
3438
- },
3439
- c.uid
3440
- );
3441
- }) })
3442
- ] })
3443
- ] })
3472
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Badge, { backgroundColor: "secondary100", textColor: "secondary700", children: [
3473
+ "Attribute: ",
3474
+ selectedAttribute,
3475
+ " ",
3476
+ attributesMeta[selectedAttribute]?.type ? `(${attributesMeta[selectedAttribute].type})` : ""
3477
+ ] }),
3478
+ attributesMeta[selectedAttribute]?.depth ? /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Badge, { backgroundColor: "neutral200", textColor: "neutral700", children: [
3479
+ "Nesting Level: L",
3480
+ attributesMeta[selectedAttribute].depth
3481
+ ] }) : null,
3482
+ selectedCol.draftAndPublish ? /* @__PURE__ */ jsxRuntime.jsx(designSystem.Badge, { backgroundColor: "success100", textColor: "success700", children: "Draft & Publish Enabled" }) : /* @__PURE__ */ jsxRuntime.jsx(designSystem.Badge, { backgroundColor: "warning100", textColor: "warning700", children: "Direct Publish Only" })
3483
+ ] }) }) })
3444
3484
  ]
3445
3485
  }
3446
3486
  ),
@@ -3457,7 +3497,11 @@ const BulkUpdater = () => {
3457
3497
  /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { justifyContent: "space-between", alignItems: "center", marginBottom: 4, wrap: "wrap", gap: 3, children: [
3458
3498
  /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { children: [
3459
3499
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "delta", tag: "h2", fontWeight: "semiBold", children: "2. Select Targets" }),
3460
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", textColor: "neutral600", children: "Pick entire collection types or individual entries to apply the update to." })
3500
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Typography, { variant: "pi", textColor: "neutral600", children: [
3501
+ "Search and select entries to apply the update to within ",
3502
+ selectedCol ? selectedCol.displayName : "the selected collection",
3503
+ "."
3504
+ ] })
3461
3505
  ] }),
3462
3506
  /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, children: [
3463
3507
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { variant: "secondary", size: "S", onClick: selectAll, children: "Select All" }),
@@ -3489,27 +3533,7 @@ const BulkUpdater = () => {
3489
3533
  selectedAttribute
3490
3534
  ] })
3491
3535
  ] }),
3492
- /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, alignItems: "center", wrap: "wrap", children: [
3493
- /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 1, alignItems: "center", children: [
3494
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", textColor: "neutral600", children: "Depth:" }),
3495
- [1, 2, 3, 4, 5].map((lvl) => /* @__PURE__ */ jsxRuntime.jsxs(
3496
- designSystem.Button,
3497
- {
3498
- variant: componentDepth === lvl ? "default" : "tertiary",
3499
- size: "S",
3500
- onClick: () => handleComponentDepthChange(lvl),
3501
- title: `Show component attributes up to Level ${lvl}`,
3502
- style: { minWidth: 26, padding: "2px 6px" },
3503
- children: [
3504
- "L",
3505
- lvl
3506
- ]
3507
- },
3508
- `s2_depth_${lvl}`
3509
- ))
3510
- ] }),
3511
- isFilterActive && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { variant: "ghost", size: "S", onClick: clearFilter, children: "Clear Search & Filter" })
3512
- ] })
3536
+ isFilterActive && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { variant: "ghost", size: "S", onClick: clearFilter, children: "Clear Search & Filter" })
3513
3537
  ] }),
3514
3538
  /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 3, alignItems: "flex-end", wrap: "wrap", children: [
3515
3539
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { style: { width: 280, minWidth: 230 }, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Field.Root, { children: [
@@ -3540,7 +3564,8 @@ const BulkUpdater = () => {
3540
3564
  }
3541
3565
  },
3542
3566
  children: memoizedSearchComboboxOptions
3543
- }
3567
+ },
3568
+ `search-attr-${selectedCollectionUid}-${searchAttribute}`
3544
3569
  )
3545
3570
  ] }) }),
3546
3571
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { style: { width: 200, minWidth: 170 }, children: /* @__PURE__ */ jsxRuntime.jsxs(
@@ -3600,164 +3625,48 @@ const BulkUpdater = () => {
3600
3625
  )
3601
3626
  ] })
3602
3627
  ] }),
3603
- isFilterActive && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { gap: 2, alignItems: "center", marginTop: 1, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Badge, { backgroundColor: "success100", textColor: "success700", size: "S", children: "✓ Filter active: Showing only matching entries. All returned matching records are pre-selected." }) })
3604
- ] })
3605
- }
3606
- ),
3607
- collections.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs(
3608
- designSystem.Box,
3609
- {
3610
- padding: 4,
3611
- background: "neutral100",
3612
- hasRadius: true,
3613
- marginBottom: 4,
3614
- style: { width: "100%", maxWidth: "100%", boxSizing: "border-box", border: "1px solid #eaeaef" },
3615
- children: [
3616
- /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { justifyContent: "space-between", alignItems: "center", wrap: "wrap", gap: 3, marginBottom: 3, children: [
3617
- /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, alignItems: "center", wrap: "wrap", children: [
3618
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "omega", fontWeight: "bold", children: "Filter Visible Content Types:" }),
3619
- /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Badge, { backgroundColor: "primary100", textColor: "primary700", children: [
3620
- filteredCollections.length,
3621
- " of ",
3622
- collections.length,
3623
- " visible"
3628
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { marginTop: 3, paddingTop: 3, style: { borderTop: "1px solid #dcdce4" }, children: [
3629
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { justifyContent: "space-between", alignItems: "center", wrap: "wrap", gap: 3, children: [
3630
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, alignItems: "center", children: [
3631
+ /* @__PURE__ */ jsxRuntime.jsx(
3632
+ designSystem.Checkbox,
3633
+ {
3634
+ checked: useRegex,
3635
+ onCheckedChange: (checked) => setUseRegex(Boolean(checked)),
3636
+ children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { fontWeight: "bold", children: "Enable Regex Search & Replace" })
3637
+ }
3638
+ ),
3639
+ /* @__PURE__ */ jsxRuntime.jsx(
3640
+ designSystem.Badge,
3641
+ {
3642
+ backgroundColor: useRegex ? "secondary100" : "neutral200",
3643
+ textColor: useRegex ? "secondary700" : "neutral600",
3644
+ size: "S",
3645
+ children: useRegex ? "REGEX SEARCH ACTIVE" : "REGEX OFF"
3646
+ }
3647
+ )
3624
3648
  ] }),
3625
- /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Badge, { backgroundColor: "success100", textColor: "success700", children: [
3626
- supportedCollections.filter((c) => visibleTypeUids[c.uid] !== false).length,
3627
- " of ",
3628
- supportedCollections.length,
3629
- " supported visible"
3630
- ] })
3631
- ] }),
3632
- /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, alignItems: "center", wrap: "wrap", children: [
3633
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { style: { width: 220 }, children: /* @__PURE__ */ jsxRuntime.jsx(
3649
+ useRegex && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { style: { flex: 1, minWidth: 260 }, children: /* @__PURE__ */ jsxRuntime.jsx(
3634
3650
  designSystem.TextInput,
3635
3651
  {
3636
- placeholder: "Search types...",
3637
- size: "S",
3638
- value: typeVisibilitySearch,
3639
- onChange: (e) => setTypeVisibilitySearch(e.target.value)
3640
- }
3641
- ) }),
3642
- /* @__PURE__ */ jsxRuntime.jsxs(
3643
- designSystem.Button,
3644
- {
3645
- variant: "secondary",
3646
- size: "S",
3647
- onClick: handleFocusOnlySupported,
3648
- children: [
3649
- "Show Supported Only (",
3650
- supportedCollections.length,
3651
- ")"
3652
- ]
3653
- }
3654
- ),
3655
- /* @__PURE__ */ jsxRuntime.jsx(
3656
- designSystem.Button,
3657
- {
3658
- variant: "tertiary",
3659
- size: "S",
3660
- onClick: handleShowAllTypes,
3661
- children: "Show All"
3652
+ placeholder: `Regex pattern to search in "${effectiveSearchAttribute || "target"}" (e.g. \\b(OldName)\\b)...`,
3653
+ value: regexPattern,
3654
+ onChange: (e) => setRegexPattern(e.target.value)
3662
3655
  }
3663
- ),
3664
- /* @__PURE__ */ jsxRuntime.jsx(
3665
- designSystem.Button,
3666
- {
3667
- variant: "tertiary",
3668
- size: "S",
3669
- onClick: handleHideAllTypes,
3670
- children: "Hide All"
3671
- }
3672
- )
3656
+ ) })
3657
+ ] }),
3658
+ useRegex && /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Typography, { variant: "pi", textColor: "neutral600", marginTop: 1, children: [
3659
+ "Searches ",
3660
+ effectiveSearchAttribute ? /* @__PURE__ */ jsxRuntime.jsx("strong", { children: effectiveSearchAttribute }) : "target entries",
3661
+ " for text matching this regular expression pattern. Matches will be substituted with the Replacement Value configured in Section 1."
3673
3662
  ] })
3674
3663
  ] }),
3675
- /* @__PURE__ */ jsxRuntime.jsx(
3676
- designSystem.Box,
3677
- {
3678
- style: {
3679
- maxHeight: 220,
3680
- overflowY: "auto",
3681
- padding: 8,
3682
- background: "#ffffff",
3683
- borderRadius: 4,
3684
- border: "1px solid #dcdce4",
3685
- display: "grid",
3686
- gridTemplateColumns: "repeat(auto-fill, minmax(260px, 1fr))",
3687
- gap: 8
3688
- },
3689
- children: collections.filter(
3690
- (col) => !typeVisibilitySearch.trim() || col.displayName.toLowerCase().includes(typeVisibilitySearch.toLowerCase().trim()) || col.uid.toLowerCase().includes(typeVisibilitySearch.toLowerCase().trim())
3691
- ).map((col) => {
3692
- const isVisible = visibleTypeUids[col.uid] !== false;
3693
- const hasAttr = selectedAttribute ? col.attributes.includes(selectedAttribute) : false;
3694
- return /* @__PURE__ */ jsxRuntime.jsx(
3695
- designSystem.Box,
3696
- {
3697
- padding: 2,
3698
- paddingLeft: 3,
3699
- paddingRight: 3,
3700
- background: isVisible ? "#f0f0ff" : "#f6f6f9",
3701
- hasRadius: true,
3702
- style: {
3703
- border: isVisible ? "1px solid #4945ff" : "1px solid #eaeaef",
3704
- transition: "all 0.15s ease"
3705
- },
3706
- children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { justifyContent: "space-between", alignItems: "center", gap: 2, children: [
3707
- /* @__PURE__ */ jsxRuntime.jsx(
3708
- designSystem.Checkbox,
3709
- {
3710
- checked: isVisible,
3711
- onCheckedChange: (checked) => setVisibleTypeUids((prev) => ({ ...prev, [col.uid]: Boolean(checked) })),
3712
- children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", fontWeight: isVisible ? "bold" : "regular", children: col.displayName })
3713
- }
3714
- ),
3715
- /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 1, alignItems: "center", children: [
3716
- col.isSingleType ? /* @__PURE__ */ jsxRuntime.jsx(designSystem.Badge, { backgroundColor: "secondary100", textColor: "secondary700", size: "S", children: "Single" }) : null,
3717
- hasAttr ? /* @__PURE__ */ jsxRuntime.jsx(designSystem.Badge, { backgroundColor: "success100", textColor: "success700", size: "S", children: "✓ Supports" }) : /* @__PURE__ */ jsxRuntime.jsx(designSystem.Badge, { backgroundColor: "neutral150", textColor: "neutral600", size: "S", children: "—" })
3718
- ] })
3719
- ] })
3720
- },
3721
- col.uid
3722
- );
3723
- })
3724
- }
3725
- )
3726
- ]
3664
+ isFilterActive && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { gap: 2, alignItems: "center", marginTop: 1, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Badge, { backgroundColor: "success100", textColor: "success700", size: "S", children: "✓ Filter active: Showing only matching entries. All returned matching records are pre-selected." }) })
3665
+ ] })
3727
3666
  }
3728
3667
  ),
3729
- /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { justifyContent: "space-between", alignItems: "center", marginBottom: 4, wrap: "wrap", gap: 3, children: [
3730
- collections.length > 1 && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { style: { flex: 1, maxWidth: 360, minWidth: 220 }, children: /* @__PURE__ */ jsxRuntime.jsx(
3731
- designSystem.TextInput,
3732
- {
3733
- label: "Search Content Types",
3734
- placeholder: "Search by name or UID...",
3735
- value: collectionSearch,
3736
- onChange: (e) => setCollectionSearch(e.target.value)
3737
- }
3738
- ) }),
3739
- /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, alignItems: "center", style: { marginLeft: "auto" }, children: [
3740
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", textColor: "neutral600", children: "Default page size (max 500):" }),
3741
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { style: { width: 130 }, children: /* @__PURE__ */ jsxRuntime.jsxs(
3742
- designSystem.SingleSelect,
3743
- {
3744
- size: "S",
3745
- value: String(defaultPageSize),
3746
- onChange: (val) => handleGlobalPageSizeChange(Number(val)),
3747
- children: [
3748
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: "5", children: "5 / page" }),
3749
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: "10", children: "10 / page" }),
3750
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: "25", children: "25 / page" }),
3751
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: "50", children: "50 / page" }),
3752
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: "100", children: "100 / page" }),
3753
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: "250", children: "250 / page" }),
3754
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: "500", children: "500 / page" })
3755
- ]
3756
- }
3757
- ) })
3758
- ] })
3759
- ] }),
3760
- filteredCollections.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { padding: 6, background: "neutral100", hasRadius: true, style: { textAlign: "center" }, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", textColor: "neutral600", children: "No content types match the visibility or search filters." }) }) : filteredCollections.map((col) => {
3668
+ !selectedCol ? /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { padding: 6, background: "neutral100", hasRadius: true, style: { textAlign: "center" }, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", textColor: "neutral600", children: "Please select a collection type above to display entries." }) }) : (() => {
3669
+ const col = selectedCol;
3761
3670
  const pageState = collectionPages[col.uid];
3762
3671
  const entries = pageState ? pageState.entries : col.entries || [];
3763
3672
  const totalEntries = pageState ? pageState.total : col.totalEntries !== void 0 ? col.totalEntries : entries.length;
@@ -3846,21 +3755,174 @@ const BulkUpdater = () => {
3846
3755
  }
3847
3756
  ) })
3848
3757
  ] }),
3849
- /* @__PURE__ */ jsxRuntime.jsxs(
3850
- designSystem.Button,
3851
- {
3852
- variant: openColumnPickerUid === col.uid ? "secondary" : "tertiary",
3853
- size: "S",
3854
- onClick: () => setOpenColumnPickerUid(openColumnPickerUid === col.uid ? null : col.uid),
3855
- children: [
3856
- "Columns (",
3857
- activeColumns.filter((c) => !c.isPermanent).length,
3858
- "/",
3859
- availableColumns.filter((c) => !c.isPermanent).length,
3860
- ")"
3861
- ]
3862
- }
3863
- ),
3758
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { style: { position: "relative", display: "inline-block" }, children: [
3759
+ /* @__PURE__ */ jsxRuntime.jsxs(
3760
+ designSystem.Button,
3761
+ {
3762
+ variant: openColumnPickerUid === col.uid ? "secondary" : "tertiary",
3763
+ size: "S",
3764
+ startIcon: /* @__PURE__ */ jsxRuntime.jsx(icons.Cog, {}),
3765
+ onClick: () => {
3766
+ setOpenColumnPickerUid(openColumnPickerUid === col.uid ? null : col.uid);
3767
+ setColumnSearchTerm("");
3768
+ },
3769
+ children: [
3770
+ "Columns (",
3771
+ activeColumns.filter((c) => !c.isPermanent).length,
3772
+ "/",
3773
+ availableColumns.filter((c) => !c.isPermanent).length,
3774
+ ")"
3775
+ ]
3776
+ }
3777
+ ),
3778
+ openColumnPickerUid === col.uid && /* @__PURE__ */ jsxRuntime.jsxs(
3779
+ designSystem.Box,
3780
+ {
3781
+ style: {
3782
+ position: "absolute",
3783
+ top: "calc(100% + 6px)",
3784
+ right: 0,
3785
+ zIndex: 200,
3786
+ width: 320,
3787
+ maxHeight: 420,
3788
+ background: "#ffffff",
3789
+ borderRadius: 8,
3790
+ boxShadow: "0 10px 25px rgba(33, 33, 52, 0.18)",
3791
+ border: "1px solid #dcdce4",
3792
+ padding: 12,
3793
+ display: "flex",
3794
+ flexDirection: "column",
3795
+ gap: 8
3796
+ },
3797
+ children: [
3798
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { justifyContent: "space-between", alignItems: "center", children: [
3799
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", fontWeight: "bold", children: "Configure Columns" }),
3800
+ /* @__PURE__ */ jsxRuntime.jsx(
3801
+ designSystem.Button,
3802
+ {
3803
+ variant: "ghost",
3804
+ size: "S",
3805
+ onClick: () => setOpenColumnPickerUid(null),
3806
+ style: { padding: "2px 6px", height: "auto", minWidth: "unset" },
3807
+ children: "✕"
3808
+ }
3809
+ )
3810
+ ] }),
3811
+ /* @__PURE__ */ jsxRuntime.jsx(
3812
+ designSystem.TextInput,
3813
+ {
3814
+ size: "S",
3815
+ placeholder: "Search columns...",
3816
+ value: columnSearchTerm,
3817
+ onChange: (e) => setColumnSearchTerm(e.target.value)
3818
+ }
3819
+ ),
3820
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { justifyContent: "space-between", alignItems: "center", style: { borderBottom: "1px solid #f0f0f5", paddingBottom: 6 }, children: [
3821
+ /* @__PURE__ */ jsxRuntime.jsx(
3822
+ designSystem.Button,
3823
+ {
3824
+ variant: "ghost",
3825
+ size: "S",
3826
+ onClick: () => showAllColumns(col.uid, availableColumns),
3827
+ style: { fontSize: 11, padding: 0 },
3828
+ children: "Show All"
3829
+ }
3830
+ ),
3831
+ /* @__PURE__ */ jsxRuntime.jsx(
3832
+ designSystem.Button,
3833
+ {
3834
+ variant: "ghost",
3835
+ size: "S",
3836
+ onClick: () => {
3837
+ setCollectionColumnVisibility((prev) => ({
3838
+ ...prev,
3839
+ [col.uid]: []
3840
+ }));
3841
+ },
3842
+ style: { fontSize: 11, padding: 0 },
3843
+ children: "Hide All"
3844
+ }
3845
+ ),
3846
+ /* @__PURE__ */ jsxRuntime.jsx(
3847
+ designSystem.Button,
3848
+ {
3849
+ variant: "ghost",
3850
+ size: "S",
3851
+ onClick: () => resetDefaultColumns(col.uid, availableColumns),
3852
+ style: { fontSize: 11, padding: 0 },
3853
+ children: "Reset"
3854
+ }
3855
+ )
3856
+ ] }),
3857
+ /* @__PURE__ */ jsxRuntime.jsx(
3858
+ designSystem.Box,
3859
+ {
3860
+ style: {
3861
+ maxHeight: 250,
3862
+ overflowY: "auto",
3863
+ display: "flex",
3864
+ flexDirection: "column",
3865
+ gap: 4
3866
+ },
3867
+ children: availableColumns.filter((c) => {
3868
+ if (!columnSearchTerm.trim()) return true;
3869
+ const term = columnSearchTerm.toLowerCase().trim();
3870
+ return c.label.toLowerCase().includes(term) || c.key.toLowerCase().includes(term);
3871
+ }).map((c) => {
3872
+ const isChecked = activeColumns.some((ac) => ac.key === c.key);
3873
+ const isNested = c.key.includes(".");
3874
+ const depth = isNested ? c.key.split(".").length - 1 : 0;
3875
+ return /* @__PURE__ */ jsxRuntime.jsxs(
3876
+ designSystem.Flex,
3877
+ {
3878
+ justifyContent: "space-between",
3879
+ alignItems: "center",
3880
+ style: {
3881
+ padding: "4px 6px",
3882
+ borderRadius: 4,
3883
+ background: isChecked ? "#f0f0ff" : "transparent"
3884
+ },
3885
+ children: [
3886
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { style: { minWidth: 0, flex: 1, overflow: "hidden" }, children: /* @__PURE__ */ jsxRuntime.jsx(
3887
+ designSystem.Checkbox,
3888
+ {
3889
+ checked: isChecked,
3890
+ disabled: c.isPermanent,
3891
+ onCheckedChange: () => {
3892
+ if (!c.isPermanent) {
3893
+ toggleColumn(col.uid, c.key, availableColumns);
3894
+ }
3895
+ },
3896
+ children: /* @__PURE__ */ jsxRuntime.jsx(
3897
+ designSystem.Typography,
3898
+ {
3899
+ variant: "pi",
3900
+ ellipsis: true,
3901
+ style: {
3902
+ color: c.isPermanent ? "#8e8ea9" : "#272833",
3903
+ fontWeight: isChecked ? 600 : 400
3904
+ },
3905
+ title: c.key,
3906
+ children: c.label
3907
+ }
3908
+ )
3909
+ }
3910
+ ) }),
3911
+ c.isPermanent ? /* @__PURE__ */ jsxRuntime.jsx(designSystem.Badge, { size: "S", backgroundColor: "neutral150", textColor: "neutral700", children: "Fixed" }) : depth > 0 ? /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Badge, { size: "S", backgroundColor: "secondary100", textColor: "secondary700", children: [
3912
+ "L",
3913
+ depth
3914
+ ] }) : null
3915
+ ]
3916
+ },
3917
+ c.key
3918
+ );
3919
+ })
3920
+ }
3921
+ )
3922
+ ]
3923
+ }
3924
+ )
3925
+ ] }),
3864
3926
  /* @__PURE__ */ jsxRuntime.jsx(
3865
3927
  designSystem.Button,
3866
3928
  {
@@ -3918,66 +3980,6 @@ const BulkUpdater = () => {
3918
3980
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", textColor: "neutral500", children: col.isSingleType ? "1 single entry" : isFilterActive ? `${totalEntries} matching entries in DB` : `${totalEntries} entries` })
3919
3981
  ] })
3920
3982
  ] }),
3921
- openColumnPickerUid === col.uid && /* @__PURE__ */ jsxRuntime.jsx(
3922
- designSystem.Box,
3923
- {
3924
- padding: 3,
3925
- marginBottom: 3,
3926
- background: "neutral100",
3927
- hasRadius: true,
3928
- borderColor: "neutral200",
3929
- style: { border: "1px solid #dcdce4" },
3930
- children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { justifyContent: "space-between", alignItems: "center", wrap: "wrap", gap: 3, children: [
3931
- /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 3, alignItems: "center", wrap: "wrap", children: [
3932
- /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Typography, { variant: "pi", fontWeight: "bold", textColor: "neutral700", children: [
3933
- "Columns for ",
3934
- col.displayName,
3935
- ":"
3936
- ] }),
3937
- availableColumns.filter((c) => !c.isPermanent).map((c) => {
3938
- const isChecked = activeColumns.some((ac) => ac.key === c.key);
3939
- return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { children: /* @__PURE__ */ jsxRuntime.jsx(
3940
- designSystem.Checkbox,
3941
- {
3942
- checked: isChecked,
3943
- onCheckedChange: () => toggleColumn(col.uid, c.key, availableColumns),
3944
- children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", children: c.label })
3945
- }
3946
- ) }, c.key);
3947
- })
3948
- ] }),
3949
- /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, children: [
3950
- /* @__PURE__ */ jsxRuntime.jsx(
3951
- designSystem.Button,
3952
- {
3953
- variant: "tertiary",
3954
- size: "S",
3955
- onClick: () => showAllColumns(col.uid, availableColumns),
3956
- children: "Show All"
3957
- }
3958
- ),
3959
- /* @__PURE__ */ jsxRuntime.jsx(
3960
- designSystem.Button,
3961
- {
3962
- variant: "tertiary",
3963
- size: "S",
3964
- onClick: () => resetDefaultColumns(col.uid, availableColumns),
3965
- children: "Reset"
3966
- }
3967
- ),
3968
- /* @__PURE__ */ jsxRuntime.jsx(
3969
- designSystem.Button,
3970
- {
3971
- variant: "ghost",
3972
- size: "S",
3973
- onClick: () => setOpenColumnPickerUid(null),
3974
- children: "Close"
3975
- }
3976
- )
3977
- ] })
3978
- ] })
3979
- }
3980
- ),
3981
3983
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { className: "bulk-updater-table-container", style: { width: "100%", maxWidth: "100%", minWidth: 0, overflowX: "auto" }, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Table, { colCount: activeColumns.length, rowCount: visibleEntries.length + 1, style: { width: "100%" }, children: [
3982
3984
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Thead, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Tr, { children: activeColumns.map(
3983
3985
  (colDef) => renderHeaderCell(colDef, col, currentSort, selectedAttribute, searchAttribute, handleHeaderSortClick)
@@ -4089,7 +4091,7 @@ const BulkUpdater = () => {
4089
4091
  },
4090
4092
  col.uid
4091
4093
  );
4092
- })
4094
+ })()
4093
4095
  ]
4094
4096
  }
4095
4097
  ),
@@ -4972,4 +4974,4 @@ exports.default = BulkUpdater;
4972
4974
  exports.formatDisplayValue = formatDisplayValue;
4973
4975
  exports.getAvailableColumnsForCollection = getAvailableColumnsForCollection;
4974
4976
  exports.getNestedValue = getNestedValue;
4975
- //# sourceMappingURL=BulkUpdater-CRvwX326.js.map
4977
+ //# sourceMappingURL=BulkUpdater-CXDs0Dws.js.map