@firecms/core 3.0.0-canary.289 → 3.0.0-canary.290

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.umd.js CHANGED
@@ -1,6 +1,6 @@
1
1
  (function(global, factory) {
2
- typeof exports === "object" && typeof module !== "undefined" ? factory(exports, require("react/jsx-runtime"), require("react-compiler-runtime"), require("react"), require("@firecms/ui"), require("notistack"), require("object-hash"), require("@firecms/formex"), require("react-router-dom"), require("fuse.js"), require("react-fast-compare"), require("date-fns"), require("date-fns/locale"), require("react-use-measure"), require("yup"), require("react-window"), require("@dnd-kit/core"), require("@dnd-kit/sortable"), require("@dnd-kit/utilities"), require("@dnd-kit/modifiers"), require("react-dropzone"), require("react-image-file-resizer"), require("@firecms/editor"), require("prism-react-renderer"), require("react-router"), require("@radix-ui/react-portal")) : typeof define === "function" && define.amd ? define(["exports", "react/jsx-runtime", "react-compiler-runtime", "react", "@firecms/ui", "notistack", "object-hash", "@firecms/formex", "react-router-dom", "fuse.js", "react-fast-compare", "date-fns", "date-fns/locale", "react-use-measure", "yup", "react-window", "@dnd-kit/core", "@dnd-kit/sortable", "@dnd-kit/utilities", "@dnd-kit/modifiers", "react-dropzone", "react-image-file-resizer", "@firecms/editor", "prism-react-renderer", "react-router", "@radix-ui/react-portal"], factory) : (global = typeof globalThis !== "undefined" ? globalThis : global || self, factory(global["FireCMS Core"] = {}, global.jsxRuntime, global.reactCompilerRuntime, global.React, global.ui, global.notistack, global.hash, global.formex, global.reactRouterDom, global.Fuse, global.equal, global.dateFns, global.locales, global.useMeasure, global.yup, global.reactWindow, global.core, global.sortable, global.utilities, global.modifiers, global.reactDropzone, global.Resizer, global.editor, global.prismReactRenderer, global.reactRouter, global.Portal));
3
- })(this, (function(exports2, jsxRuntime, reactCompilerRuntime, React, ui, notistack, hash, formex, reactRouterDom, Fuse, equal, dateFns, locales, useMeasure, yup, reactWindow, core, sortable, utilities, modifiers, reactDropzone, Resizer, editor, prismReactRenderer, reactRouter, Portal) {
2
+ typeof exports === "object" && typeof module !== "undefined" ? factory(exports, require("react/jsx-runtime"), require("react-compiler-runtime"), require("react"), require("@firecms/ui"), require("notistack"), require("object-hash"), require("@firecms/formex"), require("react-router-dom"), require("fuse.js"), require("react-fast-compare"), require("date-fns"), require("date-fns/locale"), require("react-use-measure"), require("yup"), require("react-window"), require("@dnd-kit/core"), require("@dnd-kit/sortable"), require("@dnd-kit/utilities"), require("@dnd-kit/modifiers"), require("react-dropzone"), require("compressorjs"), require("@firecms/editor"), require("prism-react-renderer"), require("react-router"), require("@radix-ui/react-portal")) : typeof define === "function" && define.amd ? define(["exports", "react/jsx-runtime", "react-compiler-runtime", "react", "@firecms/ui", "notistack", "object-hash", "@firecms/formex", "react-router-dom", "fuse.js", "react-fast-compare", "date-fns", "date-fns/locale", "react-use-measure", "yup", "react-window", "@dnd-kit/core", "@dnd-kit/sortable", "@dnd-kit/utilities", "@dnd-kit/modifiers", "react-dropzone", "compressorjs", "@firecms/editor", "prism-react-renderer", "react-router", "@radix-ui/react-portal"], factory) : (global = typeof globalThis !== "undefined" ? globalThis : global || self, factory(global["FireCMS Core"] = {}, global.jsxRuntime, global.reactCompilerRuntime, global.React, global.ui, global.notistack, global.hash, global.formex, global.reactRouterDom, global.Fuse, global.equal, global.dateFns, global.locales, global.useMeasure, global.yup, global.reactWindow, global.core, global.sortable, global.utilities, global.modifiers, global.reactDropzone, global.Compressor, global.editor, global.prismReactRenderer, global.reactRouter, global.Portal));
3
+ })(this, (function(exports2, jsxRuntime, reactCompilerRuntime, React, ui, notistack, hash, formex, reactRouterDom, Fuse, equal, dateFns, locales, useMeasure, yup, reactWindow, core, sortable, utilities, modifiers, reactDropzone, Compressor, editor, prismReactRenderer, reactRouter, Portal) {
4
4
  "use strict";
5
5
  function _interopNamespaceDefault(e) {
6
6
  const n = Object.create(null, { [Symbol.toStringTag]: { value: "Module" } });
@@ -3542,26 +3542,6 @@
3542
3542
  });
3543
3543
  return properties;
3544
3544
  }
3545
- function makePropertiesNonEditable(properties) {
3546
- return Object.entries(properties).reduce((acc, [key, property]) => {
3547
- if (!isPropertyBuilder(property) && property.dataType === "map" && property.properties) {
3548
- const updated = {
3549
- ...property,
3550
- properties: makePropertiesNonEditable(property.properties)
3551
- };
3552
- acc[key] = updated;
3553
- }
3554
- if (isPropertyBuilder(property)) {
3555
- acc[key] = property;
3556
- } else {
3557
- acc[key] = {
3558
- ...property,
3559
- editable: false
3560
- };
3561
- }
3562
- return acc;
3563
- }, {});
3564
- }
3565
3545
  function applyModifyFunction(modifyCollection, collection, parentPaths) {
3566
3546
  if (modifyCollection) {
3567
3547
  const modified = modifyCollection({
@@ -3643,8 +3623,8 @@
3643
3623
  return target;
3644
3624
  } else {
3645
3625
  const mergedProperty = mergeDeep(target, source);
3646
- const targetEditable = Boolean(target.editable);
3647
- const sourceEditable = Boolean(source.editable);
3626
+ const targetEditable = target.editable === void 0 ? true : Boolean(target.editable);
3627
+ const sourceEditable = source.editable === void 0 ? true : Boolean(source.editable);
3648
3628
  if (source.dataType === "map" && source.properties) {
3649
3629
  const targetProperties = "properties" in target ? target.properties : {};
3650
3630
  const sourceProperties = "properties" in source ? source.properties : {};
@@ -7497,7 +7477,7 @@
7497
7477
  const isArrayOfMaps = ofProp?.dataType === "map";
7498
7478
  const isArrayOfPrimitives = property?.dataType === "array" && ofProp && ofProp.dataType !== "map";
7499
7479
  if (baseKey && property && isArrayOfPrimitives) {
7500
- const t52 = `grid grid-cols-12 gap-x-4 ${isTopLevel ? "py-4" : "py-2"} items-start ${isTopLevel ? `border-b ${ui.defaultBorderMixin}` : ""}`;
7480
+ const t52 = `grid grid-cols-12 gap-x-4 ${isTopLevel ? "py-4" : "py-2"} items-start ${isTopLevel ? `border-b ${ui.defaultBorderMixin} last:border-b-0` : ""}`;
7501
7481
  let t62;
7502
7482
  if ($[3] !== arrayLabel) {
7503
7483
  t62 = /* @__PURE__ */ jsxRuntime.jsx("div", { className: "col-span-4 pr-2", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Typography, { variant: "caption", color: "secondary", component: "span", className: "break-words", children: arrayLabel }) });
@@ -7532,7 +7512,7 @@
7532
7512
  }
7533
7513
  return t82;
7534
7514
  }
7535
- const t5 = `${isTopLevel ? "py-4" : "py-1"} ${isTopLevel ? `border-b ${ui.defaultBorderMixin}` : ""}`;
7515
+ const t5 = `${isTopLevel ? "py-4" : "py-1"} ${isTopLevel ? `border-b ${ui.defaultBorderMixin} last:border-b-0` : ""}`;
7536
7516
  let t6;
7537
7517
  if ($[14] !== arrayLabel || $[15] !== baseKey || $[16] !== suppressHeader) {
7538
7518
  t6 = baseKey && arrayLabel && !suppressHeader && /* @__PURE__ */ jsxRuntime.jsx(ui.Typography, { variant: "caption", color: "secondary", component: "span", children: arrayLabel });
@@ -7624,7 +7604,7 @@
7624
7604
  if (!property_0) {
7625
7605
  return null;
7626
7606
  }
7627
- const t52 = `grid grid-cols-12 gap-x-4 ${isTopLevel ? "py-4" : "py-2"} items-start ${isTopLevel ? `border-b ${ui.defaultBorderMixin}` : ""}`;
7607
+ const t52 = `grid grid-cols-12 gap-x-4 ${isTopLevel ? "py-4" : "py-2"} items-start ${isTopLevel ? `border-b ${ui.defaultBorderMixin} last:border-b-0` : ""}`;
7628
7608
  let t62;
7629
7609
  if ($[41] !== label) {
7630
7610
  t62 = /* @__PURE__ */ jsxRuntime.jsx("div", { className: "col-span-4 pr-2", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Typography, { variant: "caption", color: "secondary", component: "span", className: "break-words", children: label }) });
@@ -7671,7 +7651,7 @@
7671
7651
  }
7672
7652
  const showMapHeader = t5;
7673
7653
  const headerText = property_0?.name || label;
7674
- const t6 = `${isTopLevel ? "py-4" : "py-1"} ${isTopLevel ? `border-b ${ui.defaultBorderMixin}` : ""}`;
7654
+ const t6 = `${isTopLevel ? "py-4" : "py-1"} ${isTopLevel ? `border-b ${ui.defaultBorderMixin} last:border-b-0` : ""}`;
7675
7655
  let t7;
7676
7656
  if ($[56] !== headerText || $[57] !== showMapHeader) {
7677
7657
  t7 = showMapHeader && /* @__PURE__ */ jsxRuntime.jsx(ui.Typography, { variant: "caption", color: "secondary", component: "span", children: headerText });
@@ -7751,7 +7731,7 @@
7751
7731
  if (!property_1) {
7752
7732
  return null;
7753
7733
  }
7754
- const t5 = `grid grid-cols-12 gap-x-4 ${isTopLevel ? "py-4" : "py-2"} items-start ${isTopLevel ? `border-b ${ui.defaultBorderMixin}` : ""}`;
7734
+ const t5 = `grid grid-cols-12 gap-x-4 ${isTopLevel ? "py-4" : "py-2"} items-start ${isTopLevel ? `border-b ${ui.defaultBorderMixin} last:border-b-0` : ""}`;
7755
7735
  let t6;
7756
7736
  if ($[78] !== label_0) {
7757
7737
  t6 = /* @__PURE__ */ jsxRuntime.jsx("div", { className: "col-span-4 pr-2", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Typography, { variant: "caption", color: "secondary", component: "span", className: "break-words", children: label_0 }) });
@@ -8318,7 +8298,8 @@
8318
8298
  const processFile = storage?.processFile;
8319
8299
  const metadata = storage?.metadata;
8320
8300
  const size = multipleFilesSupported ? "medium" : "large";
8321
- const compression = storage?.imageCompression;
8301
+ const imageResize = storage?.imageResize;
8302
+ const legacyCompression = storage?.imageCompression;
8322
8303
  const internalInitialValue = getInternalInitialValue(multipleFilesSupported, value, metadata, size);
8323
8304
  const [initialValue, setInitialValue] = React.useState(value);
8324
8305
  const [internalValue, setInternalValue] = React.useState(internalInitialValue);
@@ -8390,6 +8371,11 @@
8390
8371
  onChange(fieldValue ? fieldValue[0] : null);
8391
8372
  }
8392
8373
  }, [internalValue, multipleFilesSupported, onChange, storage, storageSource]);
8374
+ const onFileUploadError = React.useCallback((entry_0) => {
8375
+ console.debug("onFileUploadError", entry_0);
8376
+ const newValue_0 = internalValue.filter((item) => item.id !== entry_0.id);
8377
+ setInternalValue(newValue_0);
8378
+ }, [internalValue]);
8393
8379
  const onFilesAdded = React.useCallback(async (acceptedFiles) => {
8394
8380
  if (!acceptedFiles.length || disabled) return;
8395
8381
  if (processFile) {
@@ -8408,8 +8394,8 @@
8408
8394
  let newInternalValue;
8409
8395
  if (multipleFilesSupported) {
8410
8396
  newInternalValue = [...internalValue, ...await Promise.all(acceptedFiles.map(async (file_2) => {
8411
- if (compression && compressionFormat(file_2)) {
8412
- file_2 = await resizeAndCompressImage(file_2, compression);
8397
+ if ((imageResize || legacyCompression) && isImageFile(file_2)) {
8398
+ file_2 = await resizeImage(file_2, imageResize, legacyCompression);
8413
8399
  }
8414
8400
  return {
8415
8401
  id: getRandomId$2(),
@@ -8421,8 +8407,8 @@
8421
8407
  }))];
8422
8408
  } else {
8423
8409
  let file_3 = acceptedFiles[0];
8424
- if (compression && compressionFormat(file_3)) {
8425
- file_3 = await resizeAndCompressImage(file_3, compression);
8410
+ if ((imageResize || legacyCompression) && isImageFile(file_3)) {
8411
+ file_3 = await resizeImage(file_3, imageResize, legacyCompression);
8426
8412
  }
8427
8413
  newInternalValue = [{
8428
8414
  id: getRandomId$2(),
@@ -8434,7 +8420,7 @@
8434
8420
  }
8435
8421
  newInternalValue = removeDuplicates(newInternalValue);
8436
8422
  setInternalValue(newInternalValue);
8437
- }, [disabled, fileNameBuilder, internalValue, metadata, multipleFilesSupported, size]);
8423
+ }, [disabled, fileNameBuilder, internalValue, metadata, multipleFilesSupported, size, imageResize, legacyCompression]);
8438
8424
  return {
8439
8425
  internalValue,
8440
8426
  setInternalValue,
@@ -8442,6 +8428,7 @@
8442
8428
  fileNameBuilder,
8443
8429
  storagePathBuilder,
8444
8430
  onFileUploadComplete,
8431
+ onFileUploadError,
8445
8432
  onFilesAdded,
8446
8433
  multipleFilesSupported
8447
8434
  };
@@ -8472,22 +8459,42 @@
8472
8459
  function getRandomId$2() {
8473
8460
  return Math.floor(Math.random() * Math.floor(Number.MAX_SAFE_INTEGER));
8474
8461
  }
8475
- const supportedTypes = {
8476
- "image/jpeg": "JPEG",
8477
- "image/png": "PNG",
8478
- "image/webp": "WEBP"
8479
- };
8480
- const compressionFormat = (file) => supportedTypes[file.type] ? supportedTypes[file.type] : null;
8481
- const defaultQuality = 100;
8482
- const resizeAndCompressImage = (file, compression) => new Promise((resolve) => {
8483
- const inputQuality = compression.quality === void 0 ? defaultQuality : compression.quality;
8484
- const quality = inputQuality >= 0 ? inputQuality <= 100 ? inputQuality : 100 : 100;
8485
- const format = compressionFormat(file);
8486
- if (!format) {
8487
- throw Error("resizeAndCompressImage: Unsupported image format");
8488
- }
8489
- Resizer.imageFileResizer(file, compression.maxWidth || Number.MAX_VALUE, compression.maxHeight || Number.MAX_VALUE, format, quality, 0, (file2) => resolve(file2), "file");
8490
- });
8462
+ function isImageFile(file) {
8463
+ return file.type === "image/jpeg" || file.type === "image/png" || file.type === "image/webp";
8464
+ }
8465
+ async function resizeImage(file, imageResize, legacyCompression) {
8466
+ const maxWidth = imageResize?.maxWidth ?? legacyCompression?.maxWidth;
8467
+ const maxHeight = imageResize?.maxHeight ?? legacyCompression?.maxHeight;
8468
+ const quality = (imageResize?.quality ?? legacyCompression?.quality ?? 80) / 100;
8469
+ const mode = imageResize?.mode ?? "contain";
8470
+ let mimeType = file.type;
8471
+ if (imageResize?.format && imageResize.format !== "original") {
8472
+ mimeType = `image/${imageResize.format}`;
8473
+ }
8474
+ return new Promise((resolve, reject) => {
8475
+ new Compressor(file, {
8476
+ quality,
8477
+ maxWidth,
8478
+ maxHeight,
8479
+ mimeType,
8480
+ // Use cover mode if specified (crops to fit)
8481
+ // Otherwise use contain mode (scales to fit)
8482
+ ...mode === "cover" || mode === void 0 ? {
8483
+ width: maxWidth,
8484
+ height: maxHeight,
8485
+ resize: "cover"
8486
+ } : {},
8487
+ success: (result) => {
8488
+ const compressedFile = new File([result], file.name, {
8489
+ type: result.type,
8490
+ lastModified: Date.now()
8491
+ });
8492
+ resolve(compressedFile);
8493
+ },
8494
+ error: reject
8495
+ });
8496
+ });
8497
+ }
8491
8498
  function StorageUploadProgress({
8492
8499
  storagePath,
8493
8500
  entry,
@@ -11832,7 +11839,7 @@
11832
11839
  if (value_1 !== "") {
11833
11840
  updateFilter(operation, dataType === "number" ? parseInt(value_1) : value_1);
11834
11841
  }
11835
- }, endAdornment: internalValue && /* @__PURE__ */ jsxRuntime.jsx(ui.IconButton, { className: "absolute right-2 top-3", onClick: (e_0) => updateFilter(operation, void 0), children: /* @__PURE__ */ jsxRuntime.jsx(ui.CloseIcon, {}) }), renderValue: (enumKey) => {
11842
+ }, endAdornment: internalValue && /* @__PURE__ */ jsxRuntime.jsx(ui.IconButton, { onClick: (e_0) => updateFilter(operation, void 0), children: /* @__PURE__ */ jsxRuntime.jsx(ui.CloseIcon, {}) }), renderValue: (enumKey) => {
11836
11843
  if (enumKey === null) {
11837
11844
  return "Filter for null values";
11838
11845
  }
@@ -11989,7 +11996,7 @@
11989
11996
  };
11990
11997
  const multipleSelectOperations = ["array-contains-any", "in"];
11991
11998
  function DateTimeFilterField(t0) {
11992
- const $ = reactCompilerRuntime.c(38);
11999
+ const $ = reactCompilerRuntime.c(39);
11993
12000
  const {
11994
12001
  isArray,
11995
12002
  mode,
@@ -12030,7 +12037,7 @@
12030
12037
  newValue = newOpIsArray ? val ? [val] : [] : "";
12031
12038
  }
12032
12039
  setOperation(op);
12033
- setInternalValue(newValue === null ? void 0 : newValue);
12040
+ setInternalValue(newValue);
12034
12041
  const hasNewValue = newValue !== null && Array.isArray(newValue) ? newValue.length > 0 : newValue !== void 0;
12035
12042
  if (op && hasNewValue) {
12036
12043
  setValue([op, newValue]);
@@ -12074,83 +12081,85 @@
12074
12081
  } else {
12075
12082
  t6 = $[16];
12076
12083
  }
12077
- const t7 = internalValue ?? void 0;
12078
- let t8;
12084
+ const t7 = internalValue === null;
12085
+ const t8 = internalValue ?? void 0;
12086
+ let t9;
12079
12087
  if ($[17] !== operation || $[18] !== updateFilter) {
12080
- t8 = (dateValue) => {
12088
+ t9 = (dateValue) => {
12081
12089
  updateFilter(operation, dateValue === null ? void 0 : dateValue);
12082
12090
  };
12083
12091
  $[17] = operation;
12084
12092
  $[18] = updateFilter;
12085
- $[19] = t8;
12093
+ $[19] = t9;
12086
12094
  } else {
12087
- t8 = $[19];
12095
+ t9 = $[19];
12088
12096
  }
12089
- let t9;
12090
- if ($[20] !== locale || $[21] !== mode || $[22] !== t7 || $[23] !== t8) {
12091
- t9 = /* @__PURE__ */ jsxRuntime.jsx(ui.DateTimeField, { mode, size: "large", locale, value: t7, onChange: t8, clearable: true });
12097
+ let t10;
12098
+ if ($[20] !== locale || $[21] !== mode || $[22] !== t7 || $[23] !== t8 || $[24] !== t9) {
12099
+ t10 = /* @__PURE__ */ jsxRuntime.jsx(ui.DateTimeField, { mode, size: "large", locale, disabled: t7, value: t8, onChange: t9, clearable: true });
12092
12100
  $[20] = locale;
12093
12101
  $[21] = mode;
12094
12102
  $[22] = t7;
12095
12103
  $[23] = t8;
12096
12104
  $[24] = t9;
12105
+ $[25] = t10;
12097
12106
  } else {
12098
- t9 = $[24];
12107
+ t10 = $[25];
12099
12108
  }
12100
- const t10 = internalValue === null;
12101
- let t11;
12102
- if ($[25] !== internalValue || $[26] !== operation || $[27] !== updateFilter) {
12103
- t11 = (checked) => {
12109
+ const t11 = internalValue === null;
12110
+ let t12;
12111
+ if ($[26] !== internalValue || $[27] !== operation || $[28] !== updateFilter) {
12112
+ t12 = (checked) => {
12104
12113
  if (internalValue !== null) {
12105
12114
  updateFilter(operation, null);
12106
12115
  } else {
12107
12116
  updateFilter(operation, void 0);
12108
12117
  }
12109
12118
  };
12110
- $[25] = internalValue;
12111
- $[26] = operation;
12112
- $[27] = updateFilter;
12113
- $[28] = t11;
12119
+ $[26] = internalValue;
12120
+ $[27] = operation;
12121
+ $[28] = updateFilter;
12122
+ $[29] = t12;
12114
12123
  } else {
12115
- t11 = $[28];
12124
+ t12 = $[29];
12116
12125
  }
12117
- let t12;
12118
- if ($[29] !== t10 || $[30] !== t11) {
12119
- t12 = /* @__PURE__ */ jsxRuntime.jsxs(ui.Label, { className: "border cursor-pointer rounded-md p-2 flex items-center gap-2 [&:has(:checked)]:bg-surface-100 dark:[&:has(:checked)]:bg-surface-800", htmlFor: "null-filter", children: [
12120
- /* @__PURE__ */ jsxRuntime.jsx(ui.Checkbox, { id: "null-filter", checked: t10, size: "small", onCheckedChange: t11 }),
12126
+ let t13;
12127
+ if ($[30] !== t11 || $[31] !== t12) {
12128
+ t13 = /* @__PURE__ */ jsxRuntime.jsxs(ui.Label, { className: "border cursor-pointer rounded-md p-2 flex items-center gap-2 [&:has(:checked)]:bg-surface-100 dark:[&:has(:checked)]:bg-surface-800", htmlFor: "null-filter", children: [
12129
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Checkbox, { id: "null-filter", checked: t11, size: "small", onCheckedChange: t12 }),
12121
12130
  "Filter for null values"
12122
12131
  ] });
12123
- $[29] = t10;
12124
12132
  $[30] = t11;
12125
12133
  $[31] = t12;
12134
+ $[32] = t13;
12126
12135
  } else {
12127
- t12 = $[31];
12136
+ t13 = $[32];
12128
12137
  }
12129
- let t13;
12130
- if ($[32] !== t12 || $[33] !== t9) {
12131
- t13 = /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-grow ml-2 flex flex-col gap-2", children: [
12132
- t9,
12133
- t12
12138
+ let t14;
12139
+ if ($[33] !== t10 || $[34] !== t13) {
12140
+ t14 = /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-grow ml-2 flex flex-col gap-2", children: [
12141
+ t10,
12142
+ t13
12134
12143
  ] });
12135
- $[32] = t12;
12136
- $[33] = t9;
12144
+ $[33] = t10;
12137
12145
  $[34] = t13;
12146
+ $[35] = t14;
12138
12147
  } else {
12139
- t13 = $[34];
12148
+ t14 = $[35];
12140
12149
  }
12141
- let t14;
12142
- if ($[35] !== t13 || $[36] !== t6) {
12143
- t14 = /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex w-[440px]", children: [
12150
+ let t15;
12151
+ if ($[36] !== t14 || $[37] !== t6) {
12152
+ t15 = /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex w-[440px]", children: [
12144
12153
  t6,
12145
- t13
12154
+ t14
12146
12155
  ] });
12147
- $[35] = t13;
12148
- $[36] = t6;
12149
- $[37] = t14;
12156
+ $[36] = t14;
12157
+ $[37] = t6;
12158
+ $[38] = t15;
12150
12159
  } else {
12151
- t14 = $[37];
12160
+ t15 = $[38];
12152
12161
  }
12153
- return t14;
12162
+ return t15;
12154
12163
  }
12155
12164
  function _temp2$5(op_1) {
12156
12165
  return /* @__PURE__ */ jsxRuntime.jsx(ui.SelectItem, { value: op_1, children: operationLabels[op_1] }, op_1);
@@ -14295,14 +14304,16 @@
14295
14304
  return t5;
14296
14305
  }
14297
14306
  function useHomePageDnd({
14298
- items: dndItems,
14299
- setItems: setDndItems,
14307
+ items,
14308
+ setItems,
14300
14309
  disabled,
14301
14310
  onCardMovedBetweenGroups,
14302
14311
  onGroupMoved,
14303
14312
  onNewGroupDrop,
14304
14313
  onPersist
14305
14314
  }) {
14315
+ const dndItems = items;
14316
+ const setDndItems = setItems;
14306
14317
  const [activeId, setActiveId] = React.useState(null);
14307
14318
  const [activeIsGroup, setActiveIsGroup] = React.useState(false);
14308
14319
  const [currentDraggingGroupId, setCurrentDraggingGroupId] = React.useState(null);
@@ -14310,6 +14321,9 @@
14310
14321
  const [isDraggingCardOnly, setIsDraggingCardOnly] = React.useState(false);
14311
14322
  const [dialogOpenForGroup, setDialogOpenForGroup] = React.useState(null);
14312
14323
  const [isHoveringNewGroupDropZone, setIsHoveringNewGroupDropZone] = React.useState(false);
14324
+ const [pendingNewGroupName, setPendingNewGroupName] = React.useState(null);
14325
+ const [stateBeforeNewGroup, setStateBeforeNewGroup] = React.useState(null);
14326
+ const preDragItemsRef = React.useRef(null);
14313
14327
  const interimItemsRef = React.useRef(null);
14314
14328
  React.useEffect(() => {
14315
14329
  interimItemsRef.current = dndItems;
@@ -14401,6 +14415,7 @@
14401
14415
  }) => {
14402
14416
  setDndKitActiveNode(active);
14403
14417
  if (disabled) return;
14418
+ preDragItemsRef.current = cloneItemsForDnd(dndItems);
14404
14419
  const isGroup = dndItems.some((g_7) => g_7.name === active.id);
14405
14420
  if (!active.data.current) active.data.current = {};
14406
14421
  active.data.current.type = isGroup ? "group" : "item";
@@ -14424,18 +14439,30 @@
14424
14439
  if (!activeCont) return;
14425
14440
  if (overCont && activeCont !== overCont) {
14426
14441
  recentlyMovedToNewContainer.current = true;
14427
- const newState = cloneItemsForDnd(dndItems);
14428
- const srcIdx = newState.findIndex((g_8) => g_8.name === activeCont);
14429
- const tgtIdx = newState.findIndex((g_9) => g_9.name === overCont);
14430
- if (srcIdx === -1 || tgtIdx === -1) return;
14431
- const src = newState[srcIdx];
14432
- const tgt = newState[tgtIdx];
14433
- const idxInSrc = src.entries.findIndex((e_2) => e_2.url === activeIdNow);
14434
- if (idxInSrc === -1) return;
14435
- const [moved] = src.entries.splice(idxInSrc, 1);
14436
- tgt.entries.push(moved);
14437
- interimItemsRef.current = newState;
14438
- setDndItems(newState);
14442
+ lastOverId.current = overIdNow;
14443
+ setDndItems((current) => {
14444
+ const newState = cloneItemsForDnd(current);
14445
+ const srcIdx = newState.findIndex((g_8) => g_8.name === activeCont);
14446
+ const tgtIdx = newState.findIndex((g_9) => g_9.name === overCont);
14447
+ if (srcIdx === -1 || tgtIdx === -1) return current;
14448
+ const src = newState[srcIdx];
14449
+ const tgt = newState[tgtIdx];
14450
+ const idxInSrc = src.entries.findIndex((e_2) => e_2.url === activeIdNow);
14451
+ if (idxInSrc === -1) return current;
14452
+ const [moved] = src.entries.splice(idxInSrc, 1);
14453
+ const overIsContainer_0 = overIdNow === overCont;
14454
+ if (overIsContainer_0) {
14455
+ tgt.entries.push(moved);
14456
+ } else {
14457
+ const overIdx = tgt.entries.findIndex((e_3) => e_3.url === overIdNow);
14458
+ if (overIdx !== -1) {
14459
+ tgt.entries.splice(overIdx, 0, moved);
14460
+ } else {
14461
+ tgt.entries.push(moved);
14462
+ }
14463
+ }
14464
+ return newState;
14465
+ });
14439
14466
  } else if (activeCont === overCont) {
14440
14467
  recentlyMovedToNewContainer.current = false;
14441
14468
  }
@@ -14462,55 +14489,101 @@
14462
14489
  }
14463
14490
  }
14464
14491
  } else {
14465
- const activeCont_0 = findDndContainer(activeIdNow_0);
14492
+ const findContainerInState = (id_0, state) => {
14493
+ const group_0 = state.find((g_13) => g_13.name === id_0);
14494
+ if (group_0) return group_0.name;
14495
+ for (const g_14 of state) {
14496
+ if (g_14.entries.some((e_4) => e_4.url === id_0)) return g_14.name;
14497
+ }
14498
+ return void 0;
14499
+ };
14500
+ const sourceState = preDragItemsRef.current || dndItems;
14501
+ const activeCont_0 = findContainerInState(activeIdNow_0, sourceState);
14502
+ findDndContainer(overIdNow_0);
14466
14503
  if (overIdNow_0 === "new-group-drop-zone") {
14467
14504
  if (activeCont_0) {
14505
+ setStateBeforeNewGroup(cloneItemsForDnd(dndItems));
14468
14506
  const newState_1 = cloneItemsForDnd(dndItems);
14469
- const srcIdx_0 = newState_1.findIndex((g_13) => g_13.name === activeCont_0);
14507
+ const srcIdx_0 = newState_1.findIndex((g_15) => g_15.name === activeCont_0);
14470
14508
  if (srcIdx_0 !== -1) {
14471
14509
  const src_0 = newState_1[srcIdx_0];
14472
- const idxInSrc_0 = src_0.entries.findIndex((e_3) => e_3.url === activeIdNow_0);
14510
+ const idxInSrc_0 = src_0.entries.findIndex((e_5) => e_5.url === activeIdNow_0);
14473
14511
  if (idxInSrc_0 !== -1) {
14474
14512
  const [dragged] = src_0.entries.splice(idxInSrc_0, 1);
14475
14513
  if (src_0.entries.length === 0) newState_1.splice(srcIdx_0, 1);
14476
14514
  let tentative = "New Group";
14477
14515
  let counter = 1;
14478
- while (newState_1.some((g_14) => g_14.name === tentative)) tentative = `New Group ${counter++}`;
14516
+ while (newState_1.some((g_16) => g_16.name === tentative)) tentative = `New Group ${counter++}`;
14479
14517
  newState_1.push({
14480
14518
  name: tentative,
14481
14519
  entries: [dragged]
14482
14520
  });
14483
14521
  setDndItems(newState_1);
14484
- onPersist?.(newState_1);
14522
+ setPendingNewGroupName(tentative);
14485
14523
  setDialogOpenForGroup(tentative);
14486
14524
  onNewGroupDrop?.();
14487
14525
  }
14488
14526
  }
14489
14527
  }
14490
14528
  } else {
14491
- const overCont_0 = findDndContainer(overIdNow_0);
14492
- if (activeCont_0 === overCont_0) {
14493
- const grpIdx = dndItems.findIndex((g_15) => g_15.name === activeCont_0);
14529
+ const overCont_1 = findDndContainer(overIdNow_0);
14530
+ if (activeCont_0 === overCont_1) {
14531
+ const grpIdx = dndItems.findIndex((g_17) => g_17.name === activeCont_0);
14494
14532
  if (grpIdx !== -1) {
14495
- const group_0 = dndItems[grpIdx];
14496
- const oldIdx = group_0.entries.findIndex((e_4) => e_4.url === activeIdNow_0);
14497
- let newIdx = group_0.entries.findIndex((e_5) => e_5.url === overIdNow_0);
14498
- if (newIdx === -1 && overIdNow_0 === activeCont_0) newIdx = group_0.entries.length - 1;
14533
+ const group_1 = dndItems[grpIdx];
14534
+ const oldIdx = group_1.entries.findIndex((e_6) => e_6.url === activeIdNow_0);
14535
+ let newIdx = group_1.entries.findIndex((e_7) => e_7.url === overIdNow_0);
14536
+ if (newIdx === -1 && overIdNow_0 === activeCont_0) newIdx = group_1.entries.length - 1;
14499
14537
  if (oldIdx !== -1 && newIdx !== -1 && oldIdx !== newIdx) {
14500
- const reordered = sortable.arrayMove(group_0.entries, oldIdx, newIdx);
14538
+ const reordered = sortable.arrayMove(group_1.entries, oldIdx, newIdx);
14501
14539
  const newState_2 = [...dndItems];
14502
14540
  newState_2[grpIdx] = {
14503
- ...group_0,
14541
+ ...group_1,
14504
14542
  entries: reordered
14505
14543
  };
14506
14544
  setDndItems(newState_2);
14507
14545
  onPersist?.(newState_2);
14508
14546
  }
14509
14547
  }
14510
- } else if (recentlyMovedToNewContainer.current && interimItemsRef.current) {
14511
- onPersist?.(interimItemsRef.current);
14548
+ } else if (overCont_1 && activeCont_0 !== overCont_1) {
14549
+ const finalState = cloneItemsForDnd(sourceState);
14550
+ const finalOverId = lastOverId.current || overIdNow_0;
14551
+ const cleanOverCont = findContainerInState(finalOverId, sourceState) || overCont_1;
14552
+ const srcIdx_1 = finalState.findIndex((g_18) => g_18.name === activeCont_0);
14553
+ const tgtIdx_0 = finalState.findIndex((g_19) => g_19.name === cleanOverCont);
14554
+ if (srcIdx_1 !== -1 && tgtIdx_0 !== -1) {
14555
+ const src_1 = finalState[srcIdx_1];
14556
+ const tgt_0 = finalState[tgtIdx_0];
14557
+ const idxInSrc_1 = src_1.entries.findIndex((e_8) => e_8.url === activeIdNow_0);
14558
+ if (idxInSrc_1 !== -1) {
14559
+ const [moved_0] = src_1.entries.splice(idxInSrc_1, 1);
14560
+ const overIsContainer_1 = finalOverId === cleanOverCont;
14561
+ if (overIsContainer_1) {
14562
+ tgt_0.entries.push(moved_0);
14563
+ } else {
14564
+ const overIdx_0 = tgt_0.entries.findIndex((e_9) => e_9.url === finalOverId);
14565
+ if (overIdx_0 !== -1) {
14566
+ tgt_0.entries.splice(overIdx_0, 0, moved_0);
14567
+ } else {
14568
+ tgt_0.entries.push(moved_0);
14569
+ }
14570
+ }
14571
+ if (src_1.entries.length === 0) {
14572
+ finalState.splice(srcIdx_1, 1);
14573
+ }
14574
+ setDndItems(finalState);
14575
+ onPersist?.(finalState);
14576
+ onCardMovedBetweenGroups?.(moved_0);
14577
+ }
14578
+ }
14579
+ } else if (recentlyMovedToNewContainer.current) {
14580
+ console.error("Move between containers detected but conditions not met", {
14581
+ activeCont: activeCont_0,
14582
+ overCont: overCont_1,
14583
+ activeIdNow: activeIdNow_0,
14584
+ overIdNow: overIdNow_0
14585
+ });
14512
14586
  }
14513
- onCardMovedBetweenGroups?.(dndItems.flatMap((g_16) => g_16.entries).find((e_6) => e_6.url === activeIdNow_0));
14514
14587
  }
14515
14588
  }
14516
14589
  resetDragState();
@@ -14525,11 +14598,11 @@
14525
14598
  };
14526
14599
  const handleDragCancel = () => resetDragState();
14527
14600
  const handleRenameGroup = (oldName, newName) => {
14528
- setDndItems((current) => {
14529
- const idx = current.findIndex((g_17) => g_17.name === oldName);
14530
- if (idx === -1) return current;
14531
- if (current.some((g_18) => g_18.name === newName && g_18.name !== oldName)) return current;
14532
- const updated = [...current];
14601
+ setDndItems((current_0) => {
14602
+ const idx = current_0.findIndex((g_20) => g_20.name === oldName);
14603
+ if (idx === -1) return current_0;
14604
+ if (current_0.some((g_21) => g_21.name === newName && g_21.name !== oldName)) return current_0;
14605
+ const updated = [...current_0];
14533
14606
  updated[idx] = {
14534
14607
  ...updated[idx],
14535
14608
  name: newName
@@ -14537,10 +14610,20 @@
14537
14610
  onPersist?.(updated);
14538
14611
  return updated;
14539
14612
  });
14613
+ setPendingNewGroupName(null);
14614
+ setStateBeforeNewGroup(null);
14540
14615
  setDialogOpenForGroup(null);
14541
14616
  };
14542
- const activeItemForOverlay = disabled || !activeId || activeIsGroup ? null : dndItems.flatMap((g_19) => g_19.entries).find((e_7) => e_7.url === activeId) || null;
14543
- const activeGroupData = disabled || !activeId || !activeIsGroup ? null : dndItems.find((g_20) => g_20.name === activeId) || null;
14617
+ const handleDialogClose = () => {
14618
+ if (pendingNewGroupName && dialogOpenForGroup === pendingNewGroupName && stateBeforeNewGroup) {
14619
+ setDndItems(stateBeforeNewGroup);
14620
+ }
14621
+ setPendingNewGroupName(null);
14622
+ setStateBeforeNewGroup(null);
14623
+ setDialogOpenForGroup(null);
14624
+ };
14625
+ const activeItemForOverlay = disabled || !activeId || activeIsGroup ? null : dndItems.flatMap((g_22) => g_22.entries).find((e_10) => e_10.url === activeId) || null;
14626
+ const activeGroupData = disabled || !activeId || !activeIsGroup ? null : dndItems.find((g_23) => g_23.name === activeId) || null;
14544
14627
  return {
14545
14628
  sensors,
14546
14629
  collisionDetection,
@@ -14558,6 +14641,7 @@
14558
14641
  dialogOpenForGroup,
14559
14642
  setDialogOpenForGroup,
14560
14643
  handleRenameGroup,
14644
+ handleDialogClose,
14561
14645
  isHoveringNewGroupDropZone,
14562
14646
  setIsHoveringNewGroupDropZone
14563
14647
  };
@@ -14935,7 +15019,7 @@
14935
15019
  entries: []
14936
15020
  });
14937
15021
  }
14938
- allProcessed = allProcessed.filter((g_4) => g_4.entries.length || groupOrderFromNavController.includes(g_4.name) || g_4.name === DEFAULT_GROUP_NAME && hasPluginAdditionalCards);
15022
+ allProcessed = allProcessed.filter((g_4) => g_4.entries.length || g_4.name === DEFAULT_GROUP_NAME && hasPluginAdditionalCards);
14939
15023
  }
14940
15024
  const admin = allProcessed.find((g_5) => g_5.name === ADMIN_GROUP_NAME);
14941
15025
  return {
@@ -14983,6 +15067,7 @@
14983
15067
  dialogOpenForGroup,
14984
15068
  setDialogOpenForGroup,
14985
15069
  handleRenameGroup,
15070
+ handleDialogClose,
14986
15071
  isHoveringNewGroupDropZone,
14987
15072
  setIsHoveringNewGroupDropZone
14988
15073
  } = useHomePageDnd({
@@ -14990,7 +15075,6 @@
14990
15075
  setItems: updateItems,
14991
15076
  disabled: !allowDragAndDrop || performingSearch,
14992
15077
  onPersist: persistNavigationGroups,
14993
- // ——► persistence here
14994
15078
  onGroupMoved: (g_8) => context.analyticsController?.onAnalyticsEvent?.("home_move_group", {
14995
15079
  name: g_8
14996
15080
  }),
@@ -15036,7 +15120,7 @@
15036
15120
  frequency: 500
15037
15121
  }
15038
15122
  }, onDragStart, onDragOver, onDragEnd, onDragCancel, modifiers: dndModifiers, children: [
15039
- /* @__PURE__ */ jsxRuntime.jsx(sortable.SortableContext, { items: containers, strategy: sortable.verticalListSortingStrategy, children: items.map((groupData) => {
15123
+ /* @__PURE__ */ jsxRuntime.jsx(sortable.SortableContext, { items: containers, strategy: sortable.verticalListSortingStrategy, children: items.map((groupData, groupIndex) => {
15040
15124
  const groupKey = groupData.name;
15041
15125
  const entriesInGroup = groupData.entries;
15042
15126
  const AdditionalCards = [];
@@ -15047,7 +15131,7 @@
15047
15131
  group: groupKey === DEFAULT_GROUP_NAME ? void 0 : groupKey,
15048
15132
  context
15049
15133
  };
15050
- if (entriesInGroup.length === 0 && (AdditionalCards.length === 0 || performingSearch) && !groupOrderFromNavController.includes(groupKey)) return null;
15134
+ if (entriesInGroup.length === 0 && (AdditionalCards.length === 0 || performingSearch)) return null;
15051
15135
  return /* @__PURE__ */ jsxRuntime.jsx(SortableNavigationGroup, { groupName: groupKey, disabled: dndDisabled, children: /* @__PURE__ */ jsxRuntime.jsx(NavigationGroup, { group: groupKey === DEFAULT_GROUP_NAME ? void 0 : groupKey, minimised: draggingGroupId === groupKey && !isDraggingCardOnly, isPotentialCardDropTarget: isDraggingCardOnly, dndDisabled, onEditGroup: () => {
15052
15136
  if (dndDisabled) return;
15053
15137
  setDialogOpenForGroup(groupKey);
@@ -15062,7 +15146,7 @@
15062
15146
  });
15063
15147
  } }, entry.url)),
15064
15148
  !performingSearch && groupKey.toLowerCase() !== ADMIN_GROUP_NAME.toLowerCase() && AdditionalCards.map((C, i_1) => /* @__PURE__ */ jsxRuntime.jsx(C, { ...actionProps }, `extra_${groupKey}_${i_1}`))
15065
- ] }) }) }) }, groupKey);
15149
+ ] }) }) }) }, `group-${groupIndex}`);
15066
15150
  }) }, JSON.stringify(containers)),
15067
15151
  /* @__PURE__ */ jsxRuntime.jsx(NewGroupDropZone, { disabled: dndDisabled, setIsHovering: setIsHoveringNewGroupDropZone }),
15068
15152
  /* @__PURE__ */ jsxRuntime.jsx(core.DragOverlay, { adjustScale: false, dropAnimation, children: activeGroupData && draggingGroupId === activeGroupData.name ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-lg bg-transparent", style: {
@@ -15083,7 +15167,7 @@
15083
15167
  additionalPluginChildrenEnd,
15084
15168
  additionalChildrenEnd
15085
15169
  ] }),
15086
- dialogOpenForGroup && /* @__PURE__ */ jsxRuntime.jsx(RenameGroupDialog, { open: true, initialName: dialogOpenForGroup, existingGroupNames: items.map((g_9) => g_9.name).filter((n) => n !== dialogOpenForGroup), onClose: () => setDialogOpenForGroup(null), onRename: (newName) => {
15170
+ dialogOpenForGroup && /* @__PURE__ */ jsxRuntime.jsx(RenameGroupDialog, { open: true, initialName: dialogOpenForGroup, existingGroupNames: items.map((g_9) => g_9.name).filter((n) => n !== dialogOpenForGroup), onClose: handleDialogClose, onRename: (newName) => {
15087
15171
  handleRenameGroup(dialogOpenForGroup, newName);
15088
15172
  } })
15089
15173
  ] });
@@ -15777,14 +15861,17 @@
15777
15861
  t14 = $[25];
15778
15862
  }
15779
15863
  let t15;
15780
- let t16;
15781
15864
  if ($[26] === Symbol.for("react.memo_cache_sentinel")) {
15782
- t15 = /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-2xl mb-4", children: "Preview Local Changes" });
15783
- t16 = /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mb-4", children: "These are the local changes that will be applied to the form." });
15865
+ t15 = /* @__PURE__ */ jsxRuntime.jsx(ui.DialogTitle, { variant: "h6", children: "Preview Local Changes" });
15784
15866
  $[26] = t15;
15785
- $[27] = t16;
15786
15867
  } else {
15787
15868
  t15 = $[26];
15869
+ }
15870
+ let t16;
15871
+ if ($[27] === Symbol.for("react.memo_cache_sentinel")) {
15872
+ t16 = /* @__PURE__ */ jsxRuntime.jsx(ui.Typography, { variant: "body2", className: "mb-4", children: "These are the local changes that will be applied to the form." });
15873
+ $[27] = t16;
15874
+ } else {
15788
15875
  t16 = $[27];
15789
15876
  }
15790
15877
  let t17;
@@ -15800,8 +15887,7 @@
15800
15887
  const t18 = properties;
15801
15888
  let t19;
15802
15889
  if ($[29] !== localChangesData || $[30] !== t18) {
15803
- t19 = /* @__PURE__ */ jsxRuntime.jsxs(ui.DialogContent, { children: [
15804
- t15,
15890
+ t19 = /* @__PURE__ */ jsxRuntime.jsxs(ui.DialogContent, { className: "my-4", children: [
15805
15891
  t16,
15806
15892
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: `border rounded-lg ${ui.defaultBorderMixin}`, style: t17, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-4", children: /* @__PURE__ */ jsxRuntime.jsx(PropertyCollectionView, { data: localChangesData, properties: t18 }) }) })
15807
15893
  ] });
@@ -15835,6 +15921,7 @@
15835
15921
  let t22;
15836
15922
  if ($[35] !== previewDialogOpen || $[36] !== t19 || $[37] !== t21) {
15837
15923
  t22 = /* @__PURE__ */ jsxRuntime.jsxs(ui.Dialog, { open: previewDialogOpen, onOpenChange: setPreviewDialogOpen, maxWidth: "4xl", children: [
15924
+ t15,
15838
15925
  t19,
15839
15926
  t21
15840
15927
  ] });
@@ -16382,7 +16469,7 @@
16382
16469
  /* @__PURE__ */ jsxRuntime.jsx("div", { id: `form_${path}`, className: ui.cls("relative flex flex-row max-w-4xl lg:max-w-3xl xl:max-w-4xl 2xl:max-w-6xl w-full h-fit"), children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: ui.cls("flex flex-col w-full pt-12 pb-16 px-4 sm:px-8 md:px-10"), children: [
16383
16470
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-row gap-4 self-end sticky top-4 z-10", children: [
16384
16471
  manualApplyLocalChanges && hasLocalChanges && /* @__PURE__ */ jsxRuntime.jsx(LocalChangesMenu, { cacheKey: status === "new" || status === "copy" ? path + "#new" : path + "/" + entityId, properties: resolvedCollection.properties, localChangesData, formex: formex$1, onClearLocalChanges: () => setLocalChangesCleared(true) }),
16385
- formex$1.dirty ? /* @__PURE__ */ jsxRuntime.jsx(ui.Tooltip, { title: "There are local unsaved changes", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Chip, { size: "small", colorScheme: "orangeDarker", children: /* @__PURE__ */ jsxRuntime.jsx(ui.EditIcon, { size: "smallest" }) }) }) : /* @__PURE__ */ jsxRuntime.jsx(ui.Tooltip, { title: "The current form is in sync with the database", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Chip, { size: "small", children: /* @__PURE__ */ jsxRuntime.jsx(ui.CheckIcon, { size: "smallest" }) }) })
16472
+ formex$1.dirty ? /* @__PURE__ */ jsxRuntime.jsx(ui.Tooltip, { title: "This form has been modified", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Chip, { size: "small", className: "py-1", colorScheme: "orangeDarker", children: /* @__PURE__ */ jsxRuntime.jsx(ui.EditIcon, { size: "smallest" }) }) }) : /* @__PURE__ */ jsxRuntime.jsx(ui.Tooltip, { title: "The current form is in sync with the database", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Chip, { size: "small", className: "py-1", children: /* @__PURE__ */ jsxRuntime.jsx(ui.CheckIcon, { size: "smallest" }) }) })
16386
16473
  ] }),
16387
16474
  formView
16388
16475
  ] }) }),
@@ -18547,7 +18634,7 @@
18547
18634
  return false;
18548
18635
  });
18549
18636
  function PropertyFieldBindingInternal(t0) {
18550
- const $ = reactCompilerRuntime.c(18);
18637
+ const $ = reactCompilerRuntime.c(19);
18551
18638
  const {
18552
18639
  propertyKey,
18553
18640
  property,
@@ -18556,6 +18643,7 @@
18556
18643
  underlyingValueHasChanged,
18557
18644
  disabled: disabledProp,
18558
18645
  partOfArray,
18646
+ partOfBlock,
18559
18647
  minimalistView,
18560
18648
  autoFocus,
18561
18649
  index,
@@ -18564,15 +18652,8 @@
18564
18652
  } = t0;
18565
18653
  const authController = useAuthController();
18566
18654
  const customizationController = useCustomizationController();
18567
- if (propertyKey === "created_by") {
18568
- console.log("Rendering field for created_by", {
18569
- propertyKey,
18570
- property,
18571
- context
18572
- });
18573
- }
18574
18655
  let t1;
18575
- if ($[0] !== authController || $[1] !== autoFocus || $[2] !== context || $[3] !== customizationController.propertyConfigs || $[4] !== disabledProp || $[5] !== includeDescription || $[6] !== index || $[7] !== minimalistView || $[8] !== onPropertyChange || $[9] !== partOfArray || $[10] !== property || $[11] !== propertyKey || $[12] !== size || $[13] !== underlyingValueHasChanged) {
18656
+ if ($[0] !== authController || $[1] !== autoFocus || $[2] !== context || $[3] !== customizationController.propertyConfigs || $[4] !== disabledProp || $[5] !== includeDescription || $[6] !== index || $[7] !== minimalistView || $[8] !== onPropertyChange || $[9] !== partOfArray || $[10] !== partOfBlock || $[11] !== property || $[12] !== propertyKey || $[13] !== size || $[14] !== underlyingValueHasChanged) {
18576
18657
  t1 = (fieldProps) => {
18577
18658
  let Component;
18578
18659
  const resolvedProperty = resolveProperty({
@@ -18635,6 +18716,7 @@
18635
18716
  context,
18636
18717
  disabled,
18637
18718
  partOfArray,
18719
+ partOfBlock,
18638
18720
  minimalistView,
18639
18721
  autoFocus,
18640
18722
  size,
@@ -18652,22 +18734,23 @@
18652
18734
  $[7] = minimalistView;
18653
18735
  $[8] = onPropertyChange;
18654
18736
  $[9] = partOfArray;
18655
- $[10] = property;
18656
- $[11] = propertyKey;
18657
- $[12] = size;
18658
- $[13] = underlyingValueHasChanged;
18659
- $[14] = t1;
18737
+ $[10] = partOfBlock;
18738
+ $[11] = property;
18739
+ $[12] = propertyKey;
18740
+ $[13] = size;
18741
+ $[14] = underlyingValueHasChanged;
18742
+ $[15] = t1;
18660
18743
  } else {
18661
- t1 = $[14];
18744
+ t1 = $[15];
18662
18745
  }
18663
18746
  let t2;
18664
- if ($[15] !== propertyKey || $[16] !== t1) {
18747
+ if ($[16] !== propertyKey || $[17] !== t1) {
18665
18748
  t2 = /* @__PURE__ */ jsxRuntime.jsx(formex.Field, { name: propertyKey, children: t1 }, propertyKey);
18666
- $[15] = propertyKey;
18667
- $[16] = t1;
18668
- $[17] = t2;
18749
+ $[16] = propertyKey;
18750
+ $[17] = t1;
18751
+ $[18] = t2;
18669
18752
  } else {
18670
- t2 = $[17];
18753
+ t2 = $[18];
18671
18754
  }
18672
18755
  return t2;
18673
18756
  }
@@ -18679,6 +18762,7 @@
18679
18762
  includeDescription,
18680
18763
  underlyingValueHasChanged,
18681
18764
  partOfArray,
18765
+ partOfBlock,
18682
18766
  minimalistView,
18683
18767
  autoFocus,
18684
18768
  context,
@@ -18728,6 +18812,7 @@
18728
18812
  disabled: disabled ?? false,
18729
18813
  underlyingValueHasChanged: underlyingValueHasChanged ?? false,
18730
18814
  partOfArray: partOfArray ?? false,
18815
+ partOfBlock: partOfBlock ?? false,
18731
18816
  minimalistView: minimalistView ?? false,
18732
18817
  autoFocus: autoFocus ?? false,
18733
18818
  customProps: customFieldProps,
@@ -20039,6 +20124,7 @@
20039
20124
  context,
20040
20125
  autoFocus,
20041
20126
  partOfArray: false,
20127
+ partOfBlock: true,
20042
20128
  minimalistView: true,
20043
20129
  onPropertyChange: storeProps
20044
20130
  } : void 0;
@@ -21050,6 +21136,11 @@
21050
21136
  console.error("Save failure");
21051
21137
  console.error(e_0);
21052
21138
  setError(e_0);
21139
+ },
21140
+ onPreSaveHookError: (e_1) => {
21141
+ console.error("Pre-save hook error");
21142
+ console.error(e_1);
21143
+ setError(e_1);
21053
21144
  }
21054
21145
  });
21055
21146
  };
@@ -21147,7 +21238,7 @@
21147
21238
  width: width_0,
21148
21239
  frozen
21149
21240
  }) => {
21150
- const isSelected = Boolean(usedSelectionController.selectedEntities.find((e_1) => e_1.id == entity_6.id && e_1.path == entity_6.path));
21241
+ const isSelected = Boolean(usedSelectionController.selectedEntities.find((e_2) => e_2.id == entity_6.id && e_2.path == entity_6.path));
21151
21242
  const customEntityActions_0 = (collection.entityActions ?? []).map((action) => resolveEntityAction(action, customizationController.entityActions)).filter(Boolean);
21152
21243
  const actions_0 = getActionsForEntity({
21153
21244
  entity: entity_6,
@@ -21156,9 +21247,9 @@
21156
21247
  return /* @__PURE__ */ jsxRuntime.jsx(EntityCollectionRowActions, { entity: entity_6, width: width_0, frozen, isSelected, selectionEnabled, size: size_0, highlightEntity: setHighlightedEntity, unhighlightEntity: unselectNavigatedEntity, collection, fullPath, fullIdPath, actions: actions_0, hideId: collection?.hideIdFromCollection, onCollectionChange: updateLastDeleteTimestamp, selectionController: usedSelectionController, openEntityMode });
21157
21248
  }, [updateLastDeleteTimestamp, usedSelectionController]);
21158
21249
  const title = /* @__PURE__ */ jsxRuntime.jsx(ui.Popover, { open: popOverOpen, onOpenChange: setPopOverOpen, enabled: Boolean(collection.description), trigger: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-start", children: [
21159
- /* @__PURE__ */ jsxRuntime.jsx(ui.Typography, { variant: "subtitle1", className: `leading-none truncate max-w-[160px] lg:max-w-[240px] ${collection.description ? "cursor-pointer" : "cursor-auto"}`, onClick: collection.description ? (e_2) => {
21250
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Typography, { variant: "subtitle1", className: `leading-none truncate max-w-[160px] lg:max-w-[240px] ${collection.description ? "cursor-pointer" : "cursor-auto"}`, onClick: collection.description ? (e_3) => {
21160
21251
  setPopOverOpen(true);
21161
- e_2.stopPropagation();
21252
+ e_3.stopPropagation();
21162
21253
  } : void 0, children: `${collection.name}` }),
21163
21254
  /* @__PURE__ */ jsxRuntime.jsx(EntitiesCount, { fullPath, collection, filter: tableController.filterValues, sortBy: tableController.sortBy, onCountChange: setDocsCount })
21164
21255
  ] }), children: collection.description && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "m-4 text-surface-900 dark:text-white", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Markdown, { source: collection.description }) }) });
@@ -22572,22 +22663,9 @@
22572
22663
  const buildUrlCollectionPath = React.useCallback((path_0) => `${removeInitialAndTrailingSlashes(baseCollectionPath)}/${encodePath(path_0)}`, [baseCollectionPath]);
22573
22664
  const allPluginGroups = plugins?.flatMap((plugin) => plugin.homePage?.navigationEntries ? plugin.homePage.navigationEntries.map((e) => e.name) : []) ?? [];
22574
22665
  const pluginGroups = [...new Set(allPluginGroups)];
22575
- const onNavigationEntriesOrderUpdate = React.useCallback((entries) => {
22576
- if (!plugins) {
22577
- return;
22578
- }
22579
- const filteredEntries = entries.filter((entry) => entry.entries.length > 0);
22580
- if (plugins.some((plugin_1) => plugin_1.homePage?.onNavigationEntriesUpdate)) {
22581
- plugins.forEach((plugin_0) => {
22582
- if (plugin_0.homePage?.onNavigationEntriesUpdate) {
22583
- plugin_0.homePage.onNavigationEntriesUpdate(filteredEntries);
22584
- }
22585
- });
22586
- }
22587
- }, [plugins]);
22588
- const computeTopNavigation = React.useCallback((collections, views, adminViews, viewsOrder_0) => {
22666
+ const computeTopNavigation = React.useCallback((collections, views, adminViews, viewsOrder_0, navigationGroupMappingsOverride, onNavigationEntriesUpdateCallback) => {
22589
22667
  const finalNavigationGroupMappings = computeNavigationGroups({
22590
- navigationGroupMappings,
22668
+ navigationGroupMappings: navigationGroupMappingsOverride ?? navigationGroupMappings,
22591
22669
  collections,
22592
22670
  views,
22593
22671
  plugins
@@ -22619,7 +22697,7 @@
22619
22697
  return acc;
22620
22698
  }, []), ...(views ?? []).reduce((acc_0, view) => {
22621
22699
  if (view.hideFromNavigation) return acc_0;
22622
- const pathKey_0 = Array.isArray(view.path) ? view.path[0] : view.path;
22700
+ const pathKey_0 = view.path;
22623
22701
  let groupName_0 = getGroup(view);
22624
22702
  if (finalNavigationGroupMappings) {
22625
22703
  for (const pluginGroupDef_0 of finalNavigationGroupMappings) {
@@ -22642,7 +22720,7 @@
22642
22720
  return acc_0;
22643
22721
  }, []), ...(adminViews ?? []).reduce((acc_1, view_0) => {
22644
22722
  if (view_0.hideFromNavigation) return acc_1;
22645
- const pathKey_1 = Array.isArray(view_0.path) ? view_0.path[0] : view_0.path;
22723
+ const pathKey_1 = view_0.path;
22646
22724
  const groupName_1 = NAVIGATION_ADMIN_GROUP_NAME;
22647
22725
  acc_1.push({
22648
22726
  id: `admin:${pathKey_1}`,
@@ -22676,21 +22754,43 @@
22676
22754
  });
22677
22755
  }
22678
22756
  const collectedGroupsFromEntries = navigationEntries.map((e_0) => e_0.group).filter(Boolean);
22679
- const allDefinedGroups = [...pluginGroups ?? [], ...collectedGroupsFromEntries];
22680
- const uniqueGroups = [...new Set(allDefinedGroups)].sort((a_1, b_1) => groupOrderValue(a_1) - groupOrderValue(b_1));
22757
+ const groupsFromMappings = finalNavigationGroupMappings.map((g_0) => g_0.name);
22758
+ const additionalGroups = collectedGroupsFromEntries.filter((g_1) => !groupsFromMappings.includes(g_1));
22759
+ const allDefinedGroups = [...pluginGroups ?? [], ...groupsFromMappings, ...additionalGroups];
22760
+ const uniqueGroupsArray = [...new Set(allDefinedGroups)];
22761
+ const adminGroups = uniqueGroupsArray.filter((g_2) => g_2 === NAVIGATION_ADMIN_GROUP_NAME);
22762
+ const nonAdminGroups = uniqueGroupsArray.filter((g_3) => g_3 !== NAVIGATION_ADMIN_GROUP_NAME);
22763
+ const uniqueGroups = [...nonAdminGroups, ...adminGroups];
22681
22764
  return {
22682
- allowDragAndDrop: plugins?.some((plugin_2) => plugin_2.homePage?.allowDragAndDrop) ?? false,
22765
+ allowDragAndDrop: plugins?.some((plugin_0) => plugin_0.homePage?.allowDragAndDrop) ?? false,
22683
22766
  navigationEntries,
22684
22767
  groups: uniqueGroups,
22685
- onNavigationEntriesUpdate: onNavigationEntriesOrderUpdate
22768
+ onNavigationEntriesUpdate: onNavigationEntriesUpdateCallback
22686
22769
  };
22687
- }, [navigationGroupMappings, buildCMSUrlPath, buildUrlCollectionPath, pluginGroups, onNavigationEntriesOrderUpdate]);
22770
+ }, [navigationGroupMappings, buildCMSUrlPath, buildUrlCollectionPath, pluginGroups]);
22771
+ const onNavigationEntriesOrderUpdate = React.useCallback((entries) => {
22772
+ if (!plugins) {
22773
+ return;
22774
+ }
22775
+ const filteredEntries = entries.filter((entry) => entry.entries.length > 0);
22776
+ if (collectionsRef.current && viewsRef.current) {
22777
+ const updatedNav = computeTopNavigation(collectionsRef.current, viewsRef.current, adminViewsRef.current ?? [], viewsOrder, filteredEntries, onNavigationEntriesOrderUpdate);
22778
+ setTopLevelNavigation(updatedNav);
22779
+ }
22780
+ if (plugins.some((plugin_2) => plugin_2.homePage?.onNavigationEntriesUpdate)) {
22781
+ plugins.forEach((plugin_1) => {
22782
+ if (plugin_1.homePage?.onNavigationEntriesUpdate) {
22783
+ plugin_1.homePage.onNavigationEntriesUpdate(filteredEntries);
22784
+ }
22785
+ });
22786
+ }
22787
+ }, [plugins, computeTopNavigation, viewsOrder]);
22688
22788
  const refreshNavigation = React.useCallback(async () => {
22689
22789
  if (disabled || authController.initialLoading) return;
22690
22790
  console.debug("Refreshing navigation");
22691
22791
  try {
22692
22792
  const [resolvedCollections = [], resolvedViews, resolvedAdminViews = []] = await Promise.all([resolveCollections(collectionsProp, collectionPermissions, authController, dataSourceDelegate, plugins), resolveCMSViews(viewsProp, authController, dataSourceDelegate), resolveCMSViews(adminViewsProp, authController, dataSourceDelegate)]);
22693
- const computedTopLevelNav = computeTopNavigation(resolvedCollections, resolvedViews, resolvedAdminViews, viewsOrder);
22793
+ const computedTopLevelNav = computeTopNavigation(resolvedCollections, resolvedViews, resolvedAdminViews, viewsOrder, void 0, onNavigationEntriesOrderUpdate);
22694
22794
  let shouldUpdateTopLevelNav = false;
22695
22795
  if (!areCollectionListsEqual(collectionsRef.current ?? [], resolvedCollections)) {
22696
22796
  collectionsRef.current = resolvedCollections;
@@ -22975,6 +23075,42 @@
22975
23075
  }
22976
23076
  return acc;
22977
23077
  }, [...result ?? []]) : result;
23078
+ const assignedEntries = /* @__PURE__ */ new Set();
23079
+ if (result) {
23080
+ result.forEach((group) => {
23081
+ group.entries.forEach((entry) => assignedEntries.add(entry));
23082
+ });
23083
+ }
23084
+ const unassignedGroupMap = {};
23085
+ (collections ?? []).forEach((collection) => {
23086
+ const entry = collection.id ?? collection.path;
23087
+ if (!assignedEntries.has(entry)) {
23088
+ const groupName = getGroup(collection);
23089
+ if (!unassignedGroupMap[groupName]) unassignedGroupMap[groupName] = [];
23090
+ unassignedGroupMap[groupName].push(entry);
23091
+ }
23092
+ });
23093
+ (views ?? []).forEach((view) => {
23094
+ const entry = view.path;
23095
+ if (!assignedEntries.has(entry)) {
23096
+ const groupName = getGroup(view);
23097
+ if (!unassignedGroupMap[groupName]) unassignedGroupMap[groupName] = [];
23098
+ unassignedGroupMap[groupName].push(entry);
23099
+ }
23100
+ });
23101
+ Object.entries(unassignedGroupMap).forEach(([groupName, entries]) => {
23102
+ if (result) {
23103
+ const existingGroup = result.find((g) => g.name === groupName);
23104
+ if (existingGroup) {
23105
+ existingGroup.entries.push(...entries);
23106
+ } else {
23107
+ result.push({
23108
+ name: groupName,
23109
+ entries
23110
+ });
23111
+ }
23112
+ }
23113
+ });
22978
23114
  if (!result) {
22979
23115
  result = [];
22980
23116
  const groupMap = {};
@@ -22986,7 +23122,7 @@
22986
23122
  });
22987
23123
  (views ?? []).forEach((view) => {
22988
23124
  const name = getGroup(view);
22989
- const entry = Array.isArray(view.path) ? view.path[0] : view.path;
23125
+ const entry = view.path;
22990
23126
  if (!groupMap[name]) groupMap[name] = [];
22991
23127
  groupMap[name].push(entry);
22992
23128
  });
@@ -27028,7 +27164,6 @@
27028
27164
  exports2.isValidRegExp = isValidRegExp;
27029
27165
  exports2.joinCollectionLists = joinCollectionLists;
27030
27166
  exports2.makePropertiesEditable = makePropertiesEditable;
27031
- exports2.makePropertiesNonEditable = makePropertiesNonEditable;
27032
27167
  exports2.mergeCallbacks = mergeCallbacks;
27033
27168
  exports2.mergeCollection = mergeCollection;
27034
27169
  exports2.mergeDeep = mergeDeep;