@firecms/core 3.0.0-beta.14 → 3.0.0-beta.15

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.
Files changed (85) hide show
  1. package/dist/components/EntityCollectionTable/EntityCollectionRowActions.d.ts +2 -1
  2. package/dist/components/HomePage/DefaultHomePage.d.ts +2 -15
  3. package/dist/components/HomePage/HomePageDnD.d.ts +76 -0
  4. package/dist/components/HomePage/NavigationCard.d.ts +3 -1
  5. package/dist/components/HomePage/NavigationCardBinding.d.ts +3 -2
  6. package/dist/components/HomePage/NavigationGroup.d.ts +7 -1
  7. package/dist/components/HomePage/RenameGroupDialog.d.ts +9 -0
  8. package/dist/core/EntityEditView.d.ts +3 -0
  9. package/dist/core/EntityEditViewFormActions.d.ts +1 -1
  10. package/dist/core/field_configs.d.ts +1 -1
  11. package/dist/form/EntityForm.d.ts +2 -1
  12. package/dist/form/EntityFormActions.d.ts +6 -2
  13. package/dist/form/field_bindings/ReferenceAsStringFieldBinding.d.ts +9 -0
  14. package/dist/form/index.d.ts +1 -0
  15. package/dist/hooks/useBuildNavigationController.d.ts +51 -2
  16. package/dist/index.es.js +2184 -1052
  17. package/dist/index.es.js.map +1 -1
  18. package/dist/index.umd.js +2181 -1049
  19. package/dist/index.umd.js.map +1 -1
  20. package/dist/types/analytics.d.ts +1 -1
  21. package/dist/types/collections.d.ts +8 -2
  22. package/dist/types/customization_controller.d.ts +8 -0
  23. package/dist/types/entity_actions.d.ts +46 -6
  24. package/dist/types/firecms.d.ts +8 -0
  25. package/dist/types/navigation.d.ts +21 -5
  26. package/dist/types/plugins.d.ts +20 -1
  27. package/dist/types/properties.d.ts +7 -0
  28. package/dist/types/property_config.d.ts +1 -1
  29. package/dist/types/side_entity_controller.d.ts +4 -0
  30. package/dist/util/icons.d.ts +2 -2
  31. package/dist/util/navigation_from_path.d.ts +4 -0
  32. package/dist/util/resolutions.d.ts +2 -1
  33. package/package.json +5 -5
  34. package/src/components/ConfirmationDialog.tsx +1 -0
  35. package/src/components/EntityCollectionTable/EntityCollectionRowActions.tsx +6 -0
  36. package/src/components/EntityCollectionTable/PropertyTableCell.tsx +25 -3
  37. package/src/components/EntityCollectionTable/internal/CollectionTableToolbar.tsx +2 -2
  38. package/src/components/EntityCollectionView/EntityCollectionView.tsx +7 -4
  39. package/src/components/EntityCollectionView/EntityCollectionViewActions.tsx +3 -2
  40. package/src/components/FireCMSLogo.tsx +7 -51
  41. package/src/components/HomePage/DefaultHomePage.tsx +491 -157
  42. package/src/components/HomePage/FavouritesView.tsx +3 -3
  43. package/src/components/HomePage/HomePageDnD.tsx +599 -0
  44. package/src/components/HomePage/NavigationCard.tsx +47 -38
  45. package/src/components/HomePage/NavigationCardBinding.tsx +10 -6
  46. package/src/components/HomePage/NavigationGroup.tsx +63 -29
  47. package/src/components/HomePage/RenameGroupDialog.tsx +117 -0
  48. package/src/components/UnsavedChangesDialog.tsx +6 -2
  49. package/src/components/common/default_entity_actions.tsx +25 -9
  50. package/src/components/common/useDataSourceTableController.tsx +2 -2
  51. package/src/core/DefaultDrawer.tsx +8 -8
  52. package/src/core/DrawerNavigationItem.tsx +1 -1
  53. package/src/core/EntityEditView.tsx +41 -6
  54. package/src/core/EntityEditViewFormActions.tsx +154 -29
  55. package/src/core/EntitySidePanel.tsx +5 -2
  56. package/src/core/FireCMS.tsx +2 -0
  57. package/src/core/field_configs.tsx +15 -1
  58. package/src/form/EntityForm.tsx +36 -4
  59. package/src/form/EntityFormActions.tsx +51 -9
  60. package/src/form/components/StorageItemPreview.tsx +1 -1
  61. package/src/form/components/StorageUploadProgress.tsx +3 -3
  62. package/src/form/field_bindings/MarkdownEditorFieldBinding.tsx +4 -2
  63. package/src/form/field_bindings/ReferenceAsStringFieldBinding.tsx +135 -0
  64. package/src/form/field_bindings/RepeatFieldBinding.tsx +0 -1
  65. package/src/form/field_bindings/StorageUploadFieldBinding.tsx +12 -17
  66. package/src/form/index.tsx +1 -0
  67. package/src/hooks/useBuildNavigationController.tsx +273 -84
  68. package/src/internal/useBuildSideEntityController.tsx +7 -4
  69. package/src/preview/PropertyPreview.tsx +14 -0
  70. package/src/routes/FireCMSRoute.tsx +3 -3
  71. package/src/types/analytics.ts +3 -0
  72. package/src/types/collections.ts +8 -2
  73. package/src/types/customization_controller.tsx +9 -0
  74. package/src/types/entity_actions.tsx +57 -6
  75. package/src/types/firecms.tsx +9 -0
  76. package/src/types/navigation.ts +28 -6
  77. package/src/types/plugins.tsx +24 -1
  78. package/src/types/properties.ts +8 -0
  79. package/src/types/property_config.tsx +1 -0
  80. package/src/types/side_entity_controller.tsx +5 -0
  81. package/src/util/icons.tsx +22 -7
  82. package/src/util/join_collections.ts +3 -1
  83. package/src/util/navigation_from_path.ts +15 -5
  84. package/src/util/navigation_utils.ts +2 -2
  85. package/src/util/resolutions.ts +13 -1
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/modifiers"), require("@dnd-kit/sortable"), require("@dnd-kit/utilities"), 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/modifiers", "@dnd-kit/sortable", "@dnd-kit/utilities", "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.modifiers, global.sortable, global.utilities, 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, modifiers, sortable, utilities, 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("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) {
4
4
  "use strict";
5
5
  function _interopNamespaceDefault(e) {
6
6
  const n = Object.create(null, { [Symbol.toStringTag]: { value: "Module" } });
@@ -176,8 +176,8 @@
176
176
  if (openEntityMode === "side_panel") {
177
177
  sideEntityController.open({
178
178
  entityId,
179
- path: fullIdPath ?? path,
180
- // fullIdPath,
179
+ path,
180
+ fullIdPath,
181
181
  copy,
182
182
  selectedTab,
183
183
  collection,
@@ -906,6 +906,13 @@
906
906
  return entityView;
907
907
  }
908
908
  }
909
+ function resolveEntityAction(entityAction, contextEntityActions) {
910
+ if (typeof entityAction === "string") {
911
+ return contextEntityActions?.find((entry) => entry.key === entityAction);
912
+ } else {
913
+ return entityAction;
914
+ }
915
+ }
909
916
  function resolvedSelectedEntityView(customViews, customizationController, selectedTab, canEdit) {
910
917
  const resolvedEntityViews = customViews ? customViews.map((e) => resolveEntityView(e, customizationController.entityViews)).filter((e) => Boolean(e)) : [];
911
918
  const selectedEntityView = resolvedEntityViews.find((e) => e.key === selectedTab);
@@ -920,7 +927,8 @@
920
927
  const {
921
928
  path,
922
929
  collections = [],
923
- currentFullPath
930
+ currentFullPath,
931
+ currentFullIdPath
924
932
  } = props;
925
933
  const subpaths = removeInitialAndTrailingSlashes(path).split("/");
926
934
  const subpathCombinations = getCollectionPathsCombinations(subpaths);
@@ -933,13 +941,14 @@
933
941
  collection = collections && collections.find((entry) => entry.path === subpathCombination);
934
942
  }
935
943
  if (collection) {
936
- const pathOrAlias = collection.id ?? collection.path;
937
- const collectionPath = currentFullPath && currentFullPath.length > 0 ? currentFullPath + "/" + pathOrAlias : pathOrAlias;
944
+ const collectionPath = currentFullPath && currentFullPath.length > 0 ? currentFullPath + "/" + collection.path : collection.path;
945
+ const fullIdPath = currentFullIdPath && currentFullIdPath.length > 0 ? currentFullIdPath + "/" + collection.id : collection.id;
938
946
  result.push({
939
947
  type: "collection",
940
948
  id: collection.id,
941
949
  path: collectionPath,
942
950
  fullPath: collectionPath,
951
+ fullIdPath,
943
952
  collection
944
953
  });
945
954
  const restOfThePath = removeInitialAndTrailingSlashes(removeInitialAndTrailingSlashes(path).replace(subpathCombination, ""));
@@ -951,6 +960,7 @@
951
960
  type: "entity",
952
961
  entityId,
953
962
  path: collectionPath,
963
+ fullIdPath,
954
964
  fullPath,
955
965
  parentCollection: collection
956
966
  });
@@ -966,6 +976,7 @@
966
976
  type: "custom_view",
967
977
  path: collectionPath,
968
978
  entityId,
979
+ fullIdPath,
969
980
  fullPath: fullPath + "/" + customView.key,
970
981
  view: customView
971
982
  });
@@ -974,6 +985,7 @@
974
985
  path: newPath,
975
986
  collections: collection.subcollections,
976
987
  currentFullPath: fullPath,
988
+ currentFullIdPath: fullIdPath,
977
989
  contextEntityViews: props.contextEntityViews
978
990
  }));
979
991
  }
@@ -3183,16 +3195,23 @@
3183
3195
  }
3184
3196
  return Math.abs(hash2);
3185
3197
  }
3186
- function getIcon(iconKey, className, color) {
3198
+ function getIcon(iconKey, className, color, size) {
3199
+ if (React.isValidElement(iconKey)) {
3200
+ return iconKey;
3201
+ }
3187
3202
  if (!iconKey) return void 0;
3188
- iconKey = slugify(iconKey);
3189
- if (!(iconKey in iconKeysMap)) {
3190
- return void 0;
3203
+ if (typeof iconKey === "string") {
3204
+ const usedIconKey = slugify(iconKey);
3205
+ if (!(usedIconKey in iconKeysMap)) {
3206
+ return void 0;
3207
+ }
3208
+ return usedIconKey in iconKeysMap ? /* @__PURE__ */ jsxRuntime.jsx(ui.Icon, { iconKey: usedIconKey, size, className, color }) : void 0;
3191
3209
  }
3192
- return iconKey in iconKeysMap ? /* @__PURE__ */ jsxRuntime.jsx(ui.Icon, { iconKey, size: "medium", className, color }) : void 0;
3210
+ console.warn("Invalid icon key provided:", iconKey);
3211
+ return void 0;
3193
3212
  }
3194
3213
  const IconForView = React.memo(function IconForView2(t0) {
3195
- const $ = reactCompilerRuntime.c(14);
3214
+ const $ = reactCompilerRuntime.c(15);
3196
3215
  const {
3197
3216
  collectionOrView,
3198
3217
  className,
@@ -3211,14 +3230,15 @@
3211
3230
  return t22;
3212
3231
  }
3213
3232
  let t2;
3214
- if ($[1] !== className || $[2] !== collectionOrView.icon || $[3] !== color) {
3215
- t2 = getIcon(collectionOrView.icon, className, color);
3233
+ if ($[1] !== className || $[2] !== collectionOrView.icon || $[3] !== color || $[4] !== size) {
3234
+ t2 = getIcon(collectionOrView.icon, className, color, size);
3216
3235
  $[1] = className;
3217
3236
  $[2] = collectionOrView.icon;
3218
3237
  $[3] = color;
3219
- $[4] = t2;
3238
+ $[4] = size;
3239
+ $[5] = t2;
3220
3240
  } else {
3221
- t2 = $[4];
3241
+ t2 = $[5];
3222
3242
  }
3223
3243
  const icon = t2;
3224
3244
  if (collectionOrView?.icon && icon) {
@@ -3226,12 +3246,12 @@
3226
3246
  }
3227
3247
  const t3 = ("singularName" in collectionOrView ? collectionOrView.singularName : void 0) ?? collectionOrView.name;
3228
3248
  let t4;
3229
- if ($[5] !== t3) {
3249
+ if ($[6] !== t3) {
3230
3250
  t4 = slugify(t3);
3231
- $[5] = t3;
3232
- $[6] = t4;
3251
+ $[6] = t3;
3252
+ $[7] = t4;
3233
3253
  } else {
3234
- t4 = $[6];
3254
+ t4 = $[7];
3235
3255
  }
3236
3256
  let slugName = t4;
3237
3257
  let key;
@@ -3240,12 +3260,12 @@
3240
3260
  }
3241
3261
  if (!key) {
3242
3262
  let t52;
3243
- if ($[7] !== collectionOrView.path) {
3263
+ if ($[8] !== collectionOrView.path) {
3244
3264
  t52 = slugify(collectionOrView.path);
3245
- $[7] = collectionOrView.path;
3246
- $[8] = t52;
3265
+ $[8] = collectionOrView.path;
3266
+ $[9] = t52;
3247
3267
  } else {
3248
- t52 = $[8];
3268
+ t52 = $[9];
3249
3269
  }
3250
3270
  slugName = t52;
3251
3271
  if (slugName in iconKeysMap) {
@@ -3257,15 +3277,15 @@
3257
3277
  key = ui.coolIconKeys[hashString(collectionOrView.path) % iconsCount];
3258
3278
  }
3259
3279
  let t5;
3260
- if ($[9] !== className || $[10] !== color || $[11] !== key || $[12] !== size) {
3280
+ if ($[10] !== className || $[11] !== color || $[12] !== key || $[13] !== size) {
3261
3281
  t5 = /* @__PURE__ */ jsxRuntime.jsx(ui.Icon, { iconKey: key, size, className, color });
3262
- $[9] = className;
3263
- $[10] = color;
3264
- $[11] = key;
3265
- $[12] = size;
3266
- $[13] = t5;
3282
+ $[10] = className;
3283
+ $[11] = color;
3284
+ $[12] = key;
3285
+ $[13] = size;
3286
+ $[14] = t5;
3267
3287
  } else {
3268
- t5 = $[13];
3288
+ t5 = $[14];
3269
3289
  }
3270
3290
  return t5;
3271
3291
  }, (prevProps, nextProps) => {
@@ -3558,12 +3578,14 @@
3558
3578
  const sourcePropertiesOrder = getCollectionKeys(source);
3559
3579
  const mergedPropertiesOrder = [.../* @__PURE__ */ new Set([...sourcePropertiesOrder, ...targetPropertiesOrder])];
3560
3580
  const mergedEntityViews = [.../* @__PURE__ */ new Set([...target.entityViews ?? [], ...source.entityViews ?? []])];
3581
+ const mergedEntityActions = [.../* @__PURE__ */ new Set([...target.entityActions ?? [], ...source.entityActions ?? []])];
3561
3582
  let resultCollection = {
3562
3583
  ...mergedCollection,
3563
3584
  subcollections: subcollectionsMerged,
3564
3585
  properties: sortProperties(propertiesMerged, mergedPropertiesOrder),
3565
3586
  propertiesOrder: mergedPropertiesOrder,
3566
- entityViews: mergedEntityViews
3587
+ entityViews: mergedEntityViews,
3588
+ entityActions: mergedEntityActions
3567
3589
  };
3568
3590
  if (modifyCollection) {
3569
3591
  const modifiedCollection = modifyCollection({
@@ -4142,7 +4164,7 @@
4142
4164
  }
4143
4165
  setDataLoading(false);
4144
4166
  setDataLoadingError(void 0);
4145
- setData(entities.map(_temp$s));
4167
+ setData(entities.map(_temp$r));
4146
4168
  setNoMoreToLoad(!itemCount || entities.length < itemCount);
4147
4169
  };
4148
4170
  const onError = (error) => {
@@ -4175,7 +4197,7 @@
4175
4197
  orderBy: sortByProperty,
4176
4198
  order: currentSort
4177
4199
  }).then(onEntitiesUpdate).catch(onError);
4178
- return _temp2$e;
4200
+ return _temp2$d;
4179
4201
  }
4180
4202
  };
4181
4203
  $[4] = collection;
@@ -4223,9 +4245,9 @@
4223
4245
  }
4224
4246
  return t5;
4225
4247
  }
4226
- function _temp2$e() {
4248
+ function _temp2$d() {
4227
4249
  }
4228
- function _temp$s(e_0) {
4250
+ function _temp$r(e_0) {
4229
4251
  return {
4230
4252
  ...e_0
4231
4253
  };
@@ -4290,7 +4312,7 @@
4290
4312
  setEntity(CACHE[`${path}/${entityId}`]);
4291
4313
  setDataLoading(false);
4292
4314
  setDataLoadingError(void 0);
4293
- return _temp$r;
4315
+ return _temp$q;
4294
4316
  } else {
4295
4317
  if (entityId && path && collection) {
4296
4318
  if (dataSource.listenEntity) {
@@ -4309,11 +4331,11 @@
4309
4331
  databaseId,
4310
4332
  collection
4311
4333
  }).then(onEntityUpdate).catch(onError);
4312
- return _temp2$d;
4334
+ return _temp2$c;
4313
4335
  }
4314
4336
  } else {
4315
4337
  onEntityUpdate(void 0);
4316
- return _temp3$5;
4338
+ return _temp3$4;
4317
4339
  }
4318
4340
  }
4319
4341
  };
@@ -4354,11 +4376,11 @@
4354
4376
  }
4355
4377
  return t5;
4356
4378
  }
4357
- function _temp3$5() {
4379
+ function _temp3$4() {
4358
4380
  }
4359
- function _temp2$d() {
4381
+ function _temp2$c() {
4360
4382
  }
4361
- function _temp$r() {
4383
+ function _temp$q() {
4362
4384
  }
4363
4385
  async function saveEntityWithCallbacks({
4364
4386
  collection,
@@ -4942,7 +4964,7 @@
4942
4964
  }
4943
4965
  let t9;
4944
4966
  if ($[16] !== url) {
4945
- t9 = /* @__PURE__ */ jsxRuntime.jsx(ui.Tooltip, { title: "Open image in new tab", side: "bottom", children: /* @__PURE__ */ jsxRuntime.jsx(ui.IconButton, { className: "invisible group-hover:visible", variant: "filled", component: "a", href: url, rel: "noopener noreferrer", target: "_blank", size: "smallest", onClick: _temp$q, children: t8 }) });
4967
+ t9 = /* @__PURE__ */ jsxRuntime.jsx(ui.Tooltip, { title: "Open image in new tab", side: "bottom", children: /* @__PURE__ */ jsxRuntime.jsx(ui.IconButton, { className: "invisible group-hover:visible", variant: "filled", component: "a", href: url, rel: "noopener noreferrer", target: "_blank", size: "smallest", onClick: _temp$p, children: t8 }) });
4946
4968
  $[16] = url;
4947
4969
  $[17] = t9;
4948
4970
  } else {
@@ -4976,7 +4998,7 @@
4976
4998
  }
4977
4999
  return t11;
4978
5000
  }
4979
- function _temp$q(e_0) {
5001
+ function _temp$p(e_0) {
4980
5002
  return e_0.stopPropagation();
4981
5003
  }
4982
5004
  function UrlComponentPreview(t0) {
@@ -5009,7 +5031,7 @@
5009
5031
  }
5010
5032
  let t3;
5011
5033
  if ($[2] !== url) {
5012
- t3 = /* @__PURE__ */ jsxRuntime.jsxs("a", { className: "flex gap-4 break-words items-center font-medium text-primary visited:text-primary dark:visited:text-primary dark:text-primary", href: url, rel: "noopener noreferrer", onMouseDown: _temp$p, target: "_blank", children: [
5034
+ t3 = /* @__PURE__ */ jsxRuntime.jsxs("a", { className: "flex gap-4 break-words items-center font-medium text-primary visited:text-primary dark:visited:text-primary dark:text-primary", href: url, rel: "noopener noreferrer", onMouseDown: _temp$o, target: "_blank", children: [
5013
5035
  t2,
5014
5036
  url
5015
5037
  ] });
@@ -5112,7 +5134,7 @@
5112
5134
  }
5113
5135
  let t7;
5114
5136
  if ($[24] !== t4 || $[25] !== t6 || $[26] !== url) {
5115
- t7 = /* @__PURE__ */ jsxRuntime.jsxs("a", { href: url, rel: "noopener noreferrer", target: "_blank", onClick: _temp2$c, className: "flex flex-col items-center justify-center", style: t4, children: [
5137
+ t7 = /* @__PURE__ */ jsxRuntime.jsxs("a", { href: url, rel: "noopener noreferrer", target: "_blank", onClick: _temp2$b, className: "flex flex-col items-center justify-center", style: t4, children: [
5116
5138
  t5,
5117
5139
  t6
5118
5140
  ] });
@@ -5137,10 +5159,10 @@
5137
5159
  }
5138
5160
  }
5139
5161
  }
5140
- function _temp2$c(e_0) {
5162
+ function _temp2$b(e_0) {
5141
5163
  return e_0.stopPropagation();
5142
5164
  }
5143
- function _temp$p(e) {
5165
+ function _temp$o(e) {
5144
5166
  e.preventDefault();
5145
5167
  }
5146
5168
  function VideoPreview(t0) {
@@ -5274,7 +5296,7 @@
5274
5296
  if (Array.isArray(arrayProperty.of)) {
5275
5297
  let t1;
5276
5298
  if ($[6] !== arrayProperty.of) {
5277
- t1 = arrayProperty.of.map(_temp$o);
5299
+ t1 = arrayProperty.of.map(_temp$n);
5278
5300
  $[6] = arrayProperty.of;
5279
5301
  $[7] = t1;
5280
5302
  } else {
@@ -5412,7 +5434,7 @@
5412
5434
  }
5413
5435
  return content || null;
5414
5436
  }
5415
- function _temp$o(p, i) {
5437
+ function _temp$n(p, i) {
5416
5438
  return renderGenericArrayCell(p, i);
5417
5439
  }
5418
5440
  function renderMap(property, size) {
@@ -6594,7 +6616,7 @@
6594
6616
  }
6595
6617
  let t1;
6596
6618
  if ($[1] !== value) {
6597
- t1 = Object.entries(value).map(_temp$n);
6619
+ t1 = Object.entries(value).map(_temp$m);
6598
6620
  $[1] = value;
6599
6621
  $[2] = t1;
6600
6622
  } else {
@@ -6610,7 +6632,7 @@
6610
6632
  }
6611
6633
  return t2;
6612
6634
  }
6613
- function _temp$n(t0) {
6635
+ function _temp$m(t0) {
6614
6636
  const [key, childValue] = t0;
6615
6637
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: ui.cls(ui.defaultBorderMixin, "last:border-b-0 border-b"), children: [
6616
6638
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-row pt-0.5 pb-0.5 gap-2", children: [
@@ -6744,7 +6766,7 @@
6744
6766
  }
6745
6767
  }
6746
6768
  const PropertyPreview = React.memo(function PropertyPreview2(props) {
6747
- const $ = reactCompilerRuntime.c(30);
6769
+ const $ = reactCompilerRuntime.c(31);
6748
6770
  const authController = useAuthController();
6749
6771
  const customizationController = useCustomizationController();
6750
6772
  let content;
@@ -6843,7 +6865,22 @@
6843
6865
  }
6844
6866
  content = t02;
6845
6867
  } else {
6846
- content = /* @__PURE__ */ jsxRuntime.jsx(StringPropertyPreview, { ...props, property: stringProperty, value });
6868
+ if (stringProperty.reference) {
6869
+ if (typeof stringProperty.reference.path === "string") {
6870
+ content = /* @__PURE__ */ jsxRuntime.jsx(ReferencePreview, { disabled: !stringProperty.reference.path, previewProperties: stringProperty.reference.previewProperties, includeId: stringProperty.reference.includeId, includeEntityLink: stringProperty.reference.includeEntityLink, size: props.size, reference: new EntityReference(value, stringProperty.reference.path) });
6871
+ } else {
6872
+ let t02;
6873
+ if ($[23] === Symbol.for("react.memo_cache_sentinel")) {
6874
+ t02 = /* @__PURE__ */ jsxRuntime.jsx(EmptyValue, {});
6875
+ $[23] = t02;
6876
+ } else {
6877
+ t02 = $[23];
6878
+ }
6879
+ content = t02;
6880
+ }
6881
+ } else {
6882
+ content = /* @__PURE__ */ jsxRuntime.jsx(StringPropertyPreview, { ...props, property: stringProperty, value });
6883
+ }
6847
6884
  }
6848
6885
  }
6849
6886
  }
@@ -6902,12 +6939,12 @@
6902
6939
  if (property.dataType === "date") {
6903
6940
  if (value instanceof Date) {
6904
6941
  let t02;
6905
- if ($[23] !== value) {
6942
+ if ($[24] !== value) {
6906
6943
  t02 = /* @__PURE__ */ jsxRuntime.jsx(DatePreview, { date: value });
6907
- $[23] = value;
6908
- $[24] = t02;
6944
+ $[24] = value;
6945
+ $[25] = t02;
6909
6946
  } else {
6910
- t02 = $[24];
6947
+ t02 = $[25];
6911
6948
  }
6912
6949
  content = t02;
6913
6950
  } else {
@@ -6923,11 +6960,11 @@
6923
6960
  }
6924
6961
  } else {
6925
6962
  let t02;
6926
- if ($[25] === Symbol.for("react.memo_cache_sentinel")) {
6963
+ if ($[26] === Symbol.for("react.memo_cache_sentinel")) {
6927
6964
  t02 = /* @__PURE__ */ jsxRuntime.jsx(EmptyValue, {});
6928
- $[25] = t02;
6965
+ $[26] = t02;
6929
6966
  } else {
6930
- t02 = $[25];
6967
+ t02 = $[26];
6931
6968
  }
6932
6969
  content = t02;
6933
6970
  }
@@ -6947,12 +6984,12 @@
6947
6984
  }
6948
6985
  } else {
6949
6986
  let t02;
6950
- if ($[26] !== value) {
6987
+ if ($[27] !== value) {
6951
6988
  t02 = JSON.stringify(value);
6952
- $[26] = value;
6953
- $[27] = t02;
6989
+ $[27] = value;
6990
+ $[28] = t02;
6954
6991
  } else {
6955
- t02 = $[27];
6992
+ t02 = $[28];
6956
6993
  }
6957
6994
  content = t02;
6958
6995
  }
@@ -6980,12 +7017,12 @@
6980
7017
  content = $[10];
6981
7018
  }
6982
7019
  let t0;
6983
- if ($[28] !== content) {
7020
+ if ($[29] !== content) {
6984
7021
  t0 = content === void 0 || content === null || Array.isArray(content) && content.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx(EmptyValue, {}) : content;
6985
- $[28] = content;
6986
- $[29] = t0;
7022
+ $[29] = content;
7023
+ $[30] = t0;
6987
7024
  } else {
6988
- t0 = $[29];
7025
+ t0 = $[30];
6989
7026
  }
6990
7027
  return t0;
6991
7028
  }, equal);
@@ -7363,7 +7400,7 @@
7363
7400
  console.trace("onChange");
7364
7401
  if (valueType === "number") {
7365
7402
  if (multiple) {
7366
- const newValue = updatedValue.map(_temp$m);
7403
+ const newValue = updatedValue.map(_temp$l);
7367
7404
  updateValue(newValue);
7368
7405
  } else {
7369
7406
  updateValue(parseFloat(updatedValue));
@@ -7400,7 +7437,7 @@
7400
7437
  const renderValue = t3;
7401
7438
  let t4;
7402
7439
  if ($[10] !== disabled || $[11] !== enumValues || $[12] !== internalValue || $[13] !== multiple || $[14] !== onChange || $[15] !== renderValue || $[16] !== small || $[17] !== validValue) {
7403
- t4 = multiple ? /* @__PURE__ */ jsxRuntime.jsx(ui.MultiSelect, { inputRef: ref, className: "w-full h-full p-0 bg-transparent", position: "item-aligned", disabled, includeClear: false, useChips: false, value: validValue ? internalValue.map(_temp2$b) : [], onValueChange: onChange, children: enumValues?.map((enumConfig) => /* @__PURE__ */ jsxRuntime.jsx(ui.MultiSelectItem, { value: String(enumConfig.id), children: /* @__PURE__ */ jsxRuntime.jsx(EnumValuesChip, { enumKey: enumConfig.id, enumValues, size: small ? "small" : "medium" }) }, enumConfig.id)) }) : /* @__PURE__ */ jsxRuntime.jsx(ui.Select, { inputRef: ref, size: "large", fullWidth: true, className: "w-full h-full p-0 bg-transparent", position: "item-aligned", disabled, padding: false, value: validValue ? internalValue?.toString() : "", onValueChange: onChange, renderValue, children: enumValues?.map((enumConfig_0) => /* @__PURE__ */ jsxRuntime.jsx(ui.SelectItem, { value: String(enumConfig_0.id), children: /* @__PURE__ */ jsxRuntime.jsx(EnumValuesChip, { enumKey: enumConfig_0.id, enumValues, size: small ? "small" : "medium" }) }, enumConfig_0.id)) });
7440
+ t4 = multiple ? /* @__PURE__ */ jsxRuntime.jsx(ui.MultiSelect, { inputRef: ref, className: "w-full h-full p-0 bg-transparent", position: "item-aligned", disabled, includeClear: false, useChips: false, value: validValue ? internalValue.map(_temp2$a) : [], onValueChange: onChange, children: enumValues?.map((enumConfig) => /* @__PURE__ */ jsxRuntime.jsx(ui.MultiSelectItem, { value: String(enumConfig.id), children: /* @__PURE__ */ jsxRuntime.jsx(EnumValuesChip, { enumKey: enumConfig.id, enumValues, size: small ? "small" : "medium" }) }, enumConfig.id)) }) : /* @__PURE__ */ jsxRuntime.jsx(ui.Select, { inputRef: ref, size: "large", fullWidth: true, className: "w-full h-full p-0 bg-transparent", position: "item-aligned", disabled, padding: false, value: validValue ? internalValue?.toString() : "", onValueChange: onChange, renderValue, children: enumValues?.map((enumConfig_0) => /* @__PURE__ */ jsxRuntime.jsx(ui.SelectItem, { value: String(enumConfig_0.id), children: /* @__PURE__ */ jsxRuntime.jsx(EnumValuesChip, { enumKey: enumConfig_0.id, enumValues, size: small ? "small" : "medium" }) }, enumConfig_0.id)) });
7404
7441
  $[10] = disabled;
7405
7442
  $[11] = enumValues;
7406
7443
  $[12] = internalValue;
@@ -7415,10 +7452,10 @@
7415
7452
  }
7416
7453
  return t4;
7417
7454
  }
7418
- function _temp2$b(v_0) {
7455
+ function _temp2$a(v_0) {
7419
7456
  return v_0.toString();
7420
7457
  }
7421
- function _temp$m(v) {
7458
+ function _temp$l(v) {
7422
7459
  return parseFloat(v);
7423
7460
  }
7424
7461
  function VirtualTableNumberInput(props) {
@@ -7818,10 +7855,10 @@
7818
7855
  };
7819
7856
  }, [entry.file, entry.fileName, upload]);
7820
7857
  if (simple) {
7821
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: `m-4 w-${imageSize} h-${imageSize}`, children: loading && /* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: `w-${imageSize} h-${imageSize}` }) });
7858
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: `w-${imageSize} h-${imageSize}`, children: loading && /* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: `w-${imageSize} h-${imageSize}` }) });
7822
7859
  }
7823
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: ui.cls(ui.paperMixin, "relative m-4 border-box flex items-center justify-center", `min-w-[${imageSize}px] min-h-[${imageSize}px]`), children: [
7824
- loading && /* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "m-4 w-full h-full" }),
7860
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: ui.cls(ui.paperMixin, "p-4 relative border-box flex items-center justify-center", `min-w-[${imageSize}px] min-h-[${imageSize}px]`), children: [
7861
+ loading && /* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "w-full h-full" }),
7825
7862
  error && /* @__PURE__ */ jsxRuntime.jsx(ErrorView, { title: "Error uploading file", error })
7826
7863
  ] });
7827
7864
  }
@@ -7977,7 +8014,7 @@
7977
8014
  const snackbarContext = useSnackbarController();
7978
8015
  let t1;
7979
8016
  if ($[0] !== storage.acceptedFiles) {
7980
- t1 = storage.acceptedFiles ? storage.acceptedFiles.map(_temp$l).reduce(_temp2$a, {}) : void 0;
8017
+ t1 = storage.acceptedFiles ? storage.acceptedFiles.map(_temp$k).reduce(_temp2$9, {}) : void 0;
7981
8018
  $[0] = storage.acceptedFiles;
7982
8019
  $[1] = t1;
7983
8020
  } else {
@@ -8200,13 +8237,13 @@
8200
8237
  }
8201
8238
  return t20;
8202
8239
  }
8203
- function _temp2$a(a, b) {
8240
+ function _temp2$9(a, b) {
8204
8241
  return {
8205
8242
  ...a,
8206
8243
  ...b
8207
8244
  };
8208
8245
  }
8209
- function _temp$l(e) {
8246
+ function _temp$k(e) {
8210
8247
  return {
8211
8248
  [e]: []
8212
8249
  };
@@ -8313,7 +8350,7 @@
8313
8350
  let t1;
8314
8351
  if ($[2] !== updateValue) {
8315
8352
  t1 = (entities) => {
8316
- updateValue(entities.map(_temp$k));
8353
+ updateValue(entities.map(_temp$j));
8317
8354
  };
8318
8355
  $[2] = updateValue;
8319
8356
  $[3] = t1;
@@ -8323,7 +8360,7 @@
8323
8360
  const onMultipleEntitiesSelected = t1;
8324
8361
  let t2;
8325
8362
  if ($[4] !== internalValue) {
8326
- t2 = internalValue ? Array.isArray(internalValue) ? internalValue.map(_temp2$9) : internalValue.id ? [internalValue.id] : [] : [];
8363
+ t2 = internalValue ? Array.isArray(internalValue) ? internalValue.map(_temp2$8) : internalValue.id ? [internalValue.id] : [] : [];
8327
8364
  $[4] = internalValue;
8328
8365
  $[5] = t2;
8329
8366
  } else {
@@ -8474,10 +8511,10 @@
8474
8511
  }
8475
8512
  return t10;
8476
8513
  }, equal);
8477
- function _temp$k(e) {
8514
+ function _temp$j(e) {
8478
8515
  return getReferenceFrom(e);
8479
8516
  }
8480
- function _temp2$9(ref) {
8517
+ function _temp2$8(ref) {
8481
8518
  return ref.id;
8482
8519
  }
8483
8520
  yup__namespace.addMethod(yup__namespace.array, "uniqueInArray", function(mapper = (a) => a, message) {
@@ -9309,7 +9346,14 @@
9309
9346
  }
9310
9347
  if (!customField && (!customPreview || selected)) {
9311
9348
  const isAStorageProperty = isStorageProperty(property);
9312
- if (isAStorageProperty) {
9349
+ if (property.dataType === "string" && property.reference?.path) {
9350
+ const stringProperty = property;
9351
+ const path_0 = stringProperty.reference?.path;
9352
+ const referenceProperty = stringProperty.reference;
9353
+ const referenceValue = internalValue ? new EntityReference(internalValue, path_0) : void 0;
9354
+ innerComponent = /* @__PURE__ */ jsxRuntime.jsx(TableReferenceField, { name: propertyKey, internalValue: referenceValue, updateValue: (v) => updateValue(v ? v.id : null), disabled, size, path: path_0, multiselect: false, previewProperties: referenceProperty.previewProperties, includeId: referenceProperty.includeId, includeEntityLink: referenceProperty.includeEntityLink, title: stringProperty.name, forceFilter: referenceProperty.forceFilter });
9355
+ allowScroll = false;
9356
+ } else if (isAStorageProperty) {
9313
9357
  innerComponent = /* @__PURE__ */ jsxRuntime.jsx(TableStorageUpload, { error: validationError ?? error, disabled, focused: selected, selected, openPopup: setPopupCell ? openPopup : void 0, property, entity, path, value: internalValue, previewSize: getPreviewSizeFrom(size), updateValue, propertyKey });
9314
9358
  includeActions = false;
9315
9359
  showExpandIcon = true;
@@ -9325,12 +9369,12 @@
9325
9369
  allowScroll = true;
9326
9370
  }
9327
9371
  } else if (selected && property.dataType === "string") {
9328
- const stringProperty = property;
9329
- if (stringProperty.enumValues) {
9330
- innerComponent = /* @__PURE__ */ jsxRuntime.jsx(VirtualTableSelect, { name: propertyKey, multiple: false, focused: selected, disabled, valueType: "string", small: getPreviewSizeFrom(size) !== "medium", enumValues: stringProperty.enumValues, error: validationError ?? error, internalValue, updateValue });
9372
+ const stringProperty_0 = property;
9373
+ if (stringProperty_0.enumValues) {
9374
+ innerComponent = /* @__PURE__ */ jsxRuntime.jsx(VirtualTableSelect, { name: propertyKey, multiple: false, focused: selected, disabled, valueType: "string", small: getPreviewSizeFrom(size) !== "medium", enumValues: stringProperty_0.enumValues, error: validationError ?? error, internalValue, updateValue });
9331
9375
  fullHeight = true;
9332
- } else if (stringProperty.markdown || !stringProperty.storage) {
9333
- const multiline = Boolean(stringProperty.multiline) || Boolean(stringProperty.markdown);
9376
+ } else if (stringProperty_0.markdown || !stringProperty_0.storage || !stringProperty_0.reference) {
9377
+ const multiline = Boolean(stringProperty_0.multiline) || Boolean(stringProperty_0.markdown);
9334
9378
  innerComponent = /* @__PURE__ */ jsxRuntime.jsx(VirtualTableInput, { error: validationError ?? error, disabled, multiline, focused: selected, value: internalValue, updateValue });
9335
9379
  allowScroll = true;
9336
9380
  }
@@ -9499,6 +9543,7 @@
9499
9543
  entity,
9500
9544
  collection,
9501
9545
  fullPath,
9546
+ fullIdPath,
9502
9547
  width,
9503
9548
  frozen,
9504
9549
  isSelected,
@@ -9534,8 +9579,10 @@
9534
9579
  uncollapsedActions.map((action, index) => /* @__PURE__ */ jsxRuntime.jsx(ui.Tooltip, { title: action.name, asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(ui.IconButton, { onClick: (event_0) => {
9535
9580
  event_0.stopPropagation();
9536
9581
  action.onClick({
9582
+ view: "collection",
9537
9583
  entity,
9538
9584
  fullPath,
9585
+ fullIdPath,
9539
9586
  collection,
9540
9587
  context,
9541
9588
  selectionController,
@@ -9548,8 +9595,10 @@
9548
9595
  hasCollapsedActions && /* @__PURE__ */ jsxRuntime.jsx(ui.Menu, { trigger: /* @__PURE__ */ jsxRuntime.jsx(ui.IconButton, { size: largeLayout ? "medium" : "small", children: /* @__PURE__ */ jsxRuntime.jsx(ui.MoreVertIcon, {}) }), children: collapsedActions.map((action_0, index_0) => /* @__PURE__ */ jsxRuntime.jsxs(ui.MenuItem, { onClick: (e) => {
9549
9596
  e.stopPropagation();
9550
9597
  action_0.onClick({
9598
+ view: "collection",
9551
9599
  entity,
9552
9600
  fullPath,
9601
+ fullIdPath,
9553
9602
  collection,
9554
9603
  context,
9555
9604
  selectionController,
@@ -9617,14 +9666,14 @@
9617
9666
  }
9618
9667
  let t5;
9619
9668
  if ($[5] === Symbol.for("react.memo_cache_sentinel")) {
9620
- t5 = ["xs", "s", "m", "l", "xl"].map(_temp2$8);
9669
+ t5 = ["xs", "s", "m", "l", "xl"].map(_temp2$7);
9621
9670
  $[5] = t5;
9622
9671
  } else {
9623
9672
  t5 = $[5];
9624
9673
  }
9625
9674
  let t6;
9626
9675
  if ($[6] !== t3 || $[7] !== t4) {
9627
- t6 = /* @__PURE__ */ jsxRuntime.jsx(ui.Tooltip, { title: "Table row size", side: "right", sideOffset: 4, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Select, { value: t3, className: "w-16 ml-2", size: "small", onValueChange: t4, renderValue: _temp$j, children: t5 }) });
9676
+ t6 = /* @__PURE__ */ jsxRuntime.jsx(ui.Tooltip, { title: "Table row size", side: "right", sideOffset: 4, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Select, { value: t3, className: "w-16 ml-2", size: "small", onValueChange: t4, renderValue: _temp$i, children: t5 }) });
9628
9677
  $[6] = t3;
9629
9678
  $[7] = t4;
9630
9679
  $[8] = t6;
@@ -9649,7 +9698,7 @@
9649
9698
  }
9650
9699
  let t9;
9651
9700
  if ($[12] !== actionsStart || $[13] !== sizeSelect || $[14] !== t8) {
9652
- t9 = /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 md:mr-4 mr-2", children: [
9701
+ t9 = /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1 md:mr-4 mr-2", children: [
9653
9702
  t8,
9654
9703
  sizeSelect,
9655
9704
  actionsStart
@@ -9682,7 +9731,7 @@
9682
9731
  }
9683
9732
  let t12;
9684
9733
  if ($[23] !== actions || $[24] !== t10 || $[25] !== t11) {
9685
- t12 = /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
9734
+ t12 = /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1", children: [
9686
9735
  t10,
9687
9736
  t11,
9688
9737
  actions
@@ -9708,10 +9757,10 @@
9708
9757
  }
9709
9758
  return t13;
9710
9759
  }
9711
- function _temp2$8(size_0) {
9760
+ function _temp2$7(size_0) {
9712
9761
  return /* @__PURE__ */ jsxRuntime.jsx(ui.SelectItem, { value: size_0, className: "w-12 font-medium text-center", children: size_0.toUpperCase() }, size_0);
9713
9762
  }
9714
- function _temp$j(v_0) {
9763
+ function _temp$i(v_0) {
9715
9764
  return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "font-medium", children: v_0.toUpperCase() });
9716
9765
  }
9717
9766
  function getTableCellAlignment(property) {
@@ -10831,7 +10880,7 @@
10831
10880
  let t1;
10832
10881
  if ($[0] !== text) {
10833
10882
  const urlRegex = /https?:\/\/[^\s]+/g;
10834
- t1 = text.replace(urlRegex, _temp$i);
10883
+ t1 = text.replace(urlRegex, _temp$h);
10835
10884
  $[0] = text;
10836
10885
  $[1] = t1;
10837
10886
  } else {
@@ -10850,7 +10899,7 @@
10850
10899
  }
10851
10900
  return t2;
10852
10901
  };
10853
- function _temp$i(url) {
10902
+ function _temp$h(url) {
10854
10903
  return `<a href="${url}" class="underline" target="_blank">Link</a><br/>`;
10855
10904
  }
10856
10905
  const operationLabels$2 = {
@@ -11050,7 +11099,7 @@
11050
11099
  }
11051
11100
  let t5;
11052
11101
  if ($[14] !== possibleOperations) {
11053
- t5 = possibleOperations.map(_temp2$7);
11102
+ t5 = possibleOperations.map(_temp2$6);
11054
11103
  $[14] = possibleOperations;
11055
11104
  $[15] = t5;
11056
11105
  } else {
@@ -11058,7 +11107,7 @@
11058
11107
  }
11059
11108
  let t6;
11060
11109
  if ($[16] !== operation || $[17] !== t4 || $[18] !== t5) {
11061
- t6 = /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-[80px]", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Select, { value: operation, fullWidth: true, position: "item-aligned", onValueChange: t4, renderValue: _temp$h, children: t5 }) });
11110
+ t6 = /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-[80px]", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Select, { value: operation, fullWidth: true, position: "item-aligned", onValueChange: t4, renderValue: _temp$g, children: t5 }) });
11062
11111
  $[16] = operation;
11063
11112
  $[17] = t4;
11064
11113
  $[18] = t5;
@@ -11109,8 +11158,8 @@
11109
11158
  }
11110
11159
  let t9;
11111
11160
  if ($[34] !== dataType || $[35] !== enumValues || $[36] !== internalValue || $[37] !== multiple || $[38] !== name || $[39] !== operation || $[40] !== updateFilter) {
11112
- t9 = enumValues && multiple && /* @__PURE__ */ jsxRuntime.jsx(ui.MultiSelect, { position: "item-aligned", value: Array.isArray(internalValue) ? internalValue.map(_temp3$4) : [], onValueChange: (value_2) => {
11113
- updateFilter(operation, dataType === "number" ? value_2.map(_temp4$3) : value_2);
11161
+ t9 = enumValues && multiple && /* @__PURE__ */ jsxRuntime.jsx(ui.MultiSelect, { position: "item-aligned", value: Array.isArray(internalValue) ? internalValue.map(_temp3$3) : [], onValueChange: (value_2) => {
11162
+ updateFilter(operation, dataType === "number" ? value_2.map(_temp4$2) : value_2);
11114
11163
  }, multiple, endAdornment: internalValue && /* @__PURE__ */ jsxRuntime.jsx(ui.IconButton, { className: "absolute right-2 top-3", onClick: (e_2) => updateFilter(operation, void 0), children: /* @__PURE__ */ jsxRuntime.jsx(ui.CloseIcon, {}) }), children: enumValues.map((enumConfig_0) => /* @__PURE__ */ jsxRuntime.jsx(ui.MultiSelectItem, { value: String(enumConfig_0.id), children: /* @__PURE__ */ jsxRuntime.jsx(EnumValuesChip, { enumKey: String(enumConfig_0.id), enumValues, size: "small" }) }, `select_value_${name}_${enumConfig_0.id}`)) });
11115
11164
  $[34] = dataType;
11116
11165
  $[35] = enumValues;
@@ -11173,16 +11222,16 @@
11173
11222
  }
11174
11223
  return t12;
11175
11224
  }
11176
- function _temp4$3(v) {
11225
+ function _temp4$2(v) {
11177
11226
  return parseInt(v);
11178
11227
  }
11179
- function _temp3$4(e_1) {
11228
+ function _temp3$3(e_1) {
11180
11229
  return String(e_1);
11181
11230
  }
11182
- function _temp2$7(op_1) {
11231
+ function _temp2$6(op_1) {
11183
11232
  return /* @__PURE__ */ jsxRuntime.jsx(ui.SelectItem, { value: op_1, children: operationLabels$1[op_1] }, op_1);
11184
11233
  }
11185
- function _temp$h(op_0) {
11234
+ function _temp$g(op_0) {
11186
11235
  return operationLabels$1[op_0];
11187
11236
  }
11188
11237
  function BooleanFilterField(t0) {
@@ -11313,7 +11362,7 @@
11313
11362
  }
11314
11363
  let t5;
11315
11364
  if ($[11] !== possibleOperations) {
11316
- t5 = possibleOperations.map(_temp2$6);
11365
+ t5 = possibleOperations.map(_temp2$5);
11317
11366
  $[11] = possibleOperations;
11318
11367
  $[12] = t5;
11319
11368
  } else {
@@ -11321,7 +11370,7 @@
11321
11370
  }
11322
11371
  let t6;
11323
11372
  if ($[13] !== operation || $[14] !== t4 || $[15] !== t5) {
11324
- t6 = /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-[80px]", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Select, { value: operation, size: "large", fullWidth: true, onValueChange: t4, renderValue: _temp$g, children: t5 }) });
11373
+ t6 = /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-[80px]", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Select, { value: operation, size: "large", fullWidth: true, onValueChange: t4, renderValue: _temp$f, children: t5 }) });
11325
11374
  $[13] = operation;
11326
11375
  $[14] = t4;
11327
11376
  $[15] = t5;
@@ -11407,10 +11456,10 @@
11407
11456
  }
11408
11457
  return t14;
11409
11458
  }
11410
- function _temp2$6(op_1) {
11459
+ function _temp2$5(op_1) {
11411
11460
  return /* @__PURE__ */ jsxRuntime.jsx(ui.SelectItem, { value: op_1, children: operationLabels[op_1] }, op_1);
11412
11461
  }
11413
- function _temp$g(op_0) {
11462
+ function _temp$f(op_0) {
11414
11463
  return operationLabels[op_0];
11415
11464
  }
11416
11465
  const SelectableTable = function SelectableTable2({
@@ -11785,7 +11834,7 @@
11785
11834
  sortBy: initialSortUrl
11786
11835
  } = parseFilterAndSort(window.location.search);
11787
11836
  const [filterValues_0, setFilterValues] = React.useState(forceFilter ?? (updateUrl ? initialFilterUrl : void 0) ?? initialFilter ?? void 0);
11788
- const [sortBy_0, setSortBy] = React.useState(initialSortUrl ?? initialSortInternal);
11837
+ const [sortBy_0, setSortBy] = React.useState((updateUrl ? initialSortUrl : void 0) ?? initialSortInternal);
11789
11838
  useUpdateUrl(filterValues_0, sortBy_0, searchString, updateUrl);
11790
11839
  const collectionScroll = scrollRestoration?.getCollectionScroll(fullPath, filterValues_0);
11791
11840
  const initialItemCount = collectionScroll?.data.length ?? pageSize;
@@ -11971,7 +12020,7 @@
11971
12020
  }
11972
12021
  if (encodedValue !== void 0) {
11973
12022
  entries[encodeURIComponent(`${key}_op`)] = encodeURIComponent(op);
11974
- entries[encodeURIComponent(`${key}_value`)] = encodeURIComponent(encodedValue.toString());
12023
+ entries[encodeURIComponent(`${key}_value`)] = encodedValue ? encodeURIComponent(encodedValue.toString()) : "null";
11975
12024
  }
11976
12025
  }
11977
12026
  });
@@ -12114,7 +12163,7 @@
12114
12163
  const searchBlocked = t12;
12115
12164
  let t2;
12116
12165
  if ($[15] !== customizationController.plugins || $[16] !== dataSource?.initTextSearch) {
12117
- t2 = Boolean(dataSource?.initTextSearch) || customizationController.plugins?.find(_temp$f);
12166
+ t2 = Boolean(dataSource?.initTextSearch) || customizationController.plugins?.find(_temp$e);
12118
12167
  $[15] = customizationController.plugins;
12119
12168
  $[16] = dataSource?.initTextSearch;
12120
12169
  $[17] = t2;
@@ -12206,7 +12255,7 @@
12206
12255
  }
12207
12256
  return t1;
12208
12257
  }
12209
- function _temp$f(p_0) {
12258
+ function _temp$e(p_0) {
12210
12259
  return Boolean(p_0.collectionView?.onTextSearchClick);
12211
12260
  }
12212
12261
  function DeleteEntityDialog({
@@ -12351,19 +12400,26 @@
12351
12400
  return JSON.parse(stored);
12352
12401
  }
12353
12402
  const editEntityAction = {
12354
- icon: /* @__PURE__ */ jsxRuntime.jsx(ui.EditIcon, {}),
12403
+ icon: /* @__PURE__ */ jsxRuntime.jsx(ui.EditIcon, { size: "small" }),
12355
12404
  key: "edit",
12356
12405
  name: "Edit",
12357
12406
  collapsed: false,
12407
+ isEnabled: ({
12408
+ entity
12409
+ }) => Boolean(entity),
12358
12410
  onClick({
12359
12411
  entity,
12360
12412
  collection,
12361
12413
  fullPath,
12414
+ fullIdPath,
12362
12415
  context,
12363
12416
  highlightEntity,
12364
12417
  unhighlightEntity,
12365
12418
  openEntityMode
12366
12419
  }) {
12420
+ if (!entity) {
12421
+ throw new Error("INTERNAL: editEntityAction: Entity is undefined");
12422
+ }
12367
12423
  highlightEntity?.(entity);
12368
12424
  context.analyticsController?.onAnalyticsEvent?.("entity_click", {
12369
12425
  path: entity.path,
@@ -12372,7 +12428,8 @@
12372
12428
  if (collection) {
12373
12429
  addRecentId(collection.id, entity.id);
12374
12430
  }
12375
- const path = collection?.collectionGroup ? collection.id : fullPath ?? collection?.id ?? entity.path;
12431
+ const path = collection?.collectionGroup ? entity.path : fullPath ?? collection?.path ?? entity.path;
12432
+ const newFullIdPath = collection?.collectionGroup ? collection.id : fullIdPath ?? collection?.id ?? entity.path;
12376
12433
  const defaultSelectedView = resolveDefaultSelectedView(collection ? collection.defaultSelectedView : void 0, {
12377
12434
  status: "existing",
12378
12435
  entityId: entity.id
@@ -12382,7 +12439,7 @@
12382
12439
  collection,
12383
12440
  entityId: entity.id,
12384
12441
  path,
12385
- fullIdPath: path,
12442
+ fullIdPath: newFullIdPath,
12386
12443
  sideEntityController: context.sideEntityController,
12387
12444
  onClose: () => unhighlightEntity?.(entity),
12388
12445
  navigation: context.navigation,
@@ -12392,9 +12449,12 @@
12392
12449
  }
12393
12450
  };
12394
12451
  const copyEntityAction = {
12395
- icon: /* @__PURE__ */ jsxRuntime.jsx(ui.FileCopyIcon, {}),
12452
+ icon: /* @__PURE__ */ jsxRuntime.jsx(ui.FileCopyIcon, { size: "small" }),
12396
12453
  name: "Copy",
12397
12454
  key: "copy",
12455
+ isEnabled: ({
12456
+ entity
12457
+ }) => Boolean(entity),
12398
12458
  onClick({
12399
12459
  entity,
12400
12460
  collection,
@@ -12404,18 +12464,22 @@
12404
12464
  unhighlightEntity,
12405
12465
  openEntityMode
12406
12466
  }) {
12467
+ if (!entity) {
12468
+ throw new Error("INTERNAL: copyEntityAction: Entity is undefined");
12469
+ }
12407
12470
  highlightEntity?.(entity);
12408
12471
  context.analyticsController?.onAnalyticsEvent?.("copy_entity_click", {
12409
12472
  path: entity.path,
12410
12473
  entityId: entity.id
12411
12474
  });
12412
- const path = collection?.collectionGroup ? collection.id : fullPath ?? collection?.id ?? entity.path;
12475
+ const path = collection?.collectionGroup ? collection.path : fullPath ?? collection?.path ?? entity.path;
12476
+ const fullIdPath = collection?.collectionGroup ? collection.id : fullPath ?? collection?.id ?? entity.path;
12413
12477
  navigateToEntity({
12414
12478
  openEntityMode,
12415
12479
  collection,
12416
12480
  entityId: entity.id,
12417
12481
  path,
12418
- fullIdPath: path,
12482
+ fullIdPath,
12419
12483
  copy: true,
12420
12484
  sideEntityController: context.sideEntityController,
12421
12485
  onClose: () => unhighlightEntity?.(entity),
@@ -12425,9 +12489,12 @@
12425
12489
  }
12426
12490
  };
12427
12491
  const deleteEntityAction = {
12428
- icon: /* @__PURE__ */ jsxRuntime.jsx(ui.DeleteIcon, {}),
12492
+ icon: /* @__PURE__ */ jsxRuntime.jsx(ui.DeleteIcon, { size: "small" }),
12429
12493
  name: "Delete",
12430
12494
  key: "delete",
12495
+ isEnabled: ({
12496
+ entity
12497
+ }) => Boolean(entity),
12431
12498
  onClick({
12432
12499
  entity,
12433
12500
  fullPath,
@@ -12435,8 +12502,11 @@
12435
12502
  context,
12436
12503
  selectionController,
12437
12504
  onCollectionChange,
12438
- sideEntityController
12505
+ navigateBack
12439
12506
  }) {
12507
+ if (!entity) {
12508
+ throw new Error("INTERNAL: deleteEntityAction: Entity is undefined");
12509
+ }
12440
12510
  const {
12441
12511
  closeDialog
12442
12512
  } = context.dialogsController.open({
@@ -12451,7 +12521,7 @@
12451
12521
  });
12452
12522
  selectionController?.setSelectedEntities(selectionController.selectedEntities.filter((e) => e.id !== entity.id));
12453
12523
  onCollectionChange?.();
12454
- sideEntityController?.close();
12524
+ navigateBack?.();
12455
12525
  }, onClose: closeDialog });
12456
12526
  }
12457
12527
  });
@@ -12676,184 +12746,401 @@
12676
12746
  function toArray(input) {
12677
12747
  return Array.isArray(input) ? input : input ? [input] : [];
12678
12748
  }
12679
- function NavigationGroup(t0) {
12680
- const $ = reactCompilerRuntime.c(14);
12749
+ function NavigationChip(t0) {
12750
+ const $ = reactCompilerRuntime.c(18);
12681
12751
  const {
12682
- children,
12683
- group
12752
+ entry
12684
12753
  } = t0;
12754
+ const navigate = reactRouterDom.useNavigate();
12685
12755
  const userConfigurationPersistence = useUserConfigurationPersistence();
12686
- const t1 = !(userConfigurationPersistence?.collapsedGroups ?? []).includes(group ?? "ungrouped");
12756
+ if (!userConfigurationPersistence) {
12757
+ return null;
12758
+ }
12759
+ let t1;
12760
+ if ($[0] !== entry.path || $[1] !== userConfigurationPersistence.favouritePaths) {
12761
+ t1 = userConfigurationPersistence.favouritePaths.includes(entry.path);
12762
+ $[0] = entry.path;
12763
+ $[1] = userConfigurationPersistence.favouritePaths;
12764
+ $[2] = t1;
12765
+ } else {
12766
+ t1 = $[2];
12767
+ }
12768
+ const favourite = t1;
12687
12769
  let t2;
12688
- if ($[0] !== group || $[1] !== userConfigurationPersistence) {
12689
- t2 = (expanded) => {
12690
- if (userConfigurationPersistence) {
12691
- if (!expanded) {
12692
- const paths = (userConfigurationPersistence.collapsedGroups ?? []).concat(group ?? "ungrouped");
12693
- userConfigurationPersistence.setCollapsedGroups(paths);
12694
- } else {
12695
- userConfigurationPersistence.setCollapsedGroups((userConfigurationPersistence.collapsedGroups ?? []).filter((g) => g !== (group ?? "ungrouped")));
12696
- }
12770
+ if ($[3] !== entry.path || $[4] !== favourite || $[5] !== userConfigurationPersistence) {
12771
+ t2 = (e) => {
12772
+ e.preventDefault();
12773
+ e.stopPropagation();
12774
+ if (favourite) {
12775
+ userConfigurationPersistence.setFavouritePaths(userConfigurationPersistence.favouritePaths.filter((p) => p !== entry.path));
12776
+ } else {
12777
+ userConfigurationPersistence.setFavouritePaths([...userConfigurationPersistence.favouritePaths, entry.path]);
12697
12778
  }
12698
12779
  };
12699
- $[0] = group;
12700
- $[1] = userConfigurationPersistence;
12701
- $[2] = t2;
12780
+ $[3] = entry.path;
12781
+ $[4] = favourite;
12782
+ $[5] = userConfigurationPersistence;
12783
+ $[6] = t2;
12702
12784
  } else {
12703
- t2 = $[2];
12785
+ t2 = $[6];
12704
12786
  }
12787
+ const onIconClick = t2;
12705
12788
  let t3;
12706
- if ($[3] !== group) {
12707
- t3 = group?.toUpperCase() ?? "Views".toUpperCase();
12708
- $[3] = group;
12709
- $[4] = t3;
12710
- } else {
12711
- t3 = $[4];
12712
- }
12713
- let t4;
12714
- if ($[5] !== t3) {
12715
- t4 = /* @__PURE__ */ jsxRuntime.jsx(ui.Typography, { color: "secondary", className: "font-medium ml-1", children: t3 });
12716
- $[5] = t3;
12717
- $[6] = t4;
12789
+ if ($[7] !== entry.url || $[8] !== navigate) {
12790
+ t3 = () => navigate(entry.url);
12791
+ $[7] = entry.url;
12792
+ $[8] = navigate;
12793
+ $[9] = t3;
12718
12794
  } else {
12719
- t4 = $[6];
12795
+ t3 = $[9];
12720
12796
  }
12797
+ const t4 = favourite ? "text-secondary" : "text-surface-400 dark:text-surface-500";
12721
12798
  let t5;
12722
- if ($[7] !== children) {
12723
- t5 = /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mb-8", children });
12724
- $[7] = children;
12725
- $[8] = t5;
12799
+ if ($[10] !== onIconClick || $[11] !== t4) {
12800
+ t5 = /* @__PURE__ */ jsxRuntime.jsx(ui.StarIcon, { onClick: onIconClick, size: 18, className: t4 });
12801
+ $[10] = onIconClick;
12802
+ $[11] = t4;
12803
+ $[12] = t5;
12726
12804
  } else {
12727
- t5 = $[8];
12805
+ t5 = $[12];
12728
12806
  }
12729
12807
  let t6;
12730
- if ($[9] !== t1 || $[10] !== t2 || $[11] !== t4 || $[12] !== t5) {
12731
- t6 = /* @__PURE__ */ jsxRuntime.jsx(ui.ExpandablePanel, { invisible: true, titleClassName: "font-medium text-sm text-surface-600 dark:text-surface-400", innerClassName: "py-4", initiallyExpanded: t1, onExpandedChange: t2, title: t4, children: t5 });
12732
- $[9] = t1;
12733
- $[10] = t2;
12734
- $[11] = t4;
12735
- $[12] = t5;
12736
- $[13] = t6;
12808
+ if ($[13] !== entry.name || $[14] !== entry.path || $[15] !== t3 || $[16] !== t5) {
12809
+ t6 = /* @__PURE__ */ jsxRuntime.jsx(ui.Chip, { onClick: t3, icon: t5, children: entry.name }, entry.path);
12810
+ $[13] = entry.name;
12811
+ $[14] = entry.path;
12812
+ $[15] = t3;
12813
+ $[16] = t5;
12814
+ $[17] = t6;
12737
12815
  } else {
12738
- t6 = $[13];
12816
+ t6 = $[17];
12739
12817
  }
12740
12818
  return t6;
12741
12819
  }
12742
- function NavigationCard(t0) {
12743
- const $ = reactCompilerRuntime.c(23);
12744
- const {
12745
- name,
12746
- description,
12747
- icon,
12748
- actions,
12749
- onClick
12750
- } = t0;
12820
+ function FavouritesView(t0) {
12821
+ const $ = reactCompilerRuntime.c(17);
12822
+ const navigationController = useNavigationController();
12823
+ const userConfigurationPersistence = useUserConfigurationPersistence();
12824
+ if (!userConfigurationPersistence) {
12825
+ return null;
12826
+ }
12751
12827
  let t1;
12752
- if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
12753
- t1 = ui.cls("h-full p-4 cursor-pointer min-h-[230px]");
12754
- $[0] = t1;
12828
+ if ($[0] !== userConfigurationPersistence?.favouritePaths) {
12829
+ t1 = userConfigurationPersistence?.favouritePaths ?? [];
12830
+ $[0] = userConfigurationPersistence?.favouritePaths;
12831
+ $[1] = t1;
12755
12832
  } else {
12756
- t1 = $[0];
12833
+ t1 = $[1];
12757
12834
  }
12835
+ let T0;
12758
12836
  let t2;
12759
- if ($[1] !== onClick) {
12760
- t2 = () => {
12761
- onClick?.();
12762
- };
12763
- $[1] = onClick;
12764
- $[2] = t2;
12765
- } else {
12766
- t2 = $[2];
12767
- }
12768
12837
  let t3;
12769
- if ($[3] !== actions) {
12770
- t3 = /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-1", onClick: _temp$e, children: actions });
12771
- $[3] = actions;
12772
- $[4] = t3;
12773
- } else {
12774
- t3 = $[4];
12775
- }
12776
12838
  let t4;
12777
- if ($[5] !== icon || $[6] !== t3) {
12778
- t4 = /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "h-10 flex items-center w-full justify-between text-surface-300 dark:text-surface-600", children: [
12779
- icon,
12780
- t3
12781
- ] });
12782
- $[5] = icon;
12839
+ if ($[2] !== navigationController.topLevelNavigation?.navigationEntries || $[3] !== t1) {
12840
+ let t52;
12841
+ if ($[8] !== navigationController.topLevelNavigation?.navigationEntries) {
12842
+ t52 = (path) => navigationController.topLevelNavigation?.navigationEntries.find((entry) => entry.path === path);
12843
+ $[8] = navigationController.topLevelNavigation?.navigationEntries;
12844
+ $[9] = t52;
12845
+ } else {
12846
+ t52 = $[9];
12847
+ }
12848
+ const favouriteCollections = t1.map(t52).filter(Boolean);
12849
+ T0 = ui.Collapse;
12850
+ t4 = favouriteCollections.length > 0;
12851
+ t2 = "flex flex-row flex-wrap gap-2 pb-2 min-h-[32px]";
12852
+ t3 = favouriteCollections.map(_temp$d);
12853
+ $[2] = navigationController.topLevelNavigation?.navigationEntries;
12854
+ $[3] = t1;
12855
+ $[4] = T0;
12856
+ $[5] = t2;
12783
12857
  $[6] = t3;
12784
12858
  $[7] = t4;
12785
12859
  } else {
12860
+ T0 = $[4];
12861
+ t2 = $[5];
12862
+ t3 = $[6];
12786
12863
  t4 = $[7];
12787
12864
  }
12788
12865
  let t5;
12789
- if ($[8] !== name) {
12790
- t5 = /* @__PURE__ */ jsxRuntime.jsx(ui.Typography, { gutterBottom: true, variant: "h5", component: "h2", children: name });
12791
- $[8] = name;
12792
- $[9] = t5;
12866
+ if ($[10] !== t2 || $[11] !== t3) {
12867
+ t5 = /* @__PURE__ */ jsxRuntime.jsx("div", { className: t2, children: t3 });
12868
+ $[10] = t2;
12869
+ $[11] = t3;
12870
+ $[12] = t5;
12793
12871
  } else {
12794
- t5 = $[9];
12872
+ t5 = $[12];
12795
12873
  }
12796
12874
  let t6;
12797
- if ($[10] !== description) {
12798
- t6 = description && /* @__PURE__ */ jsxRuntime.jsx(ui.Typography, { variant: "body2", color: "secondary", component: "div", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Markdown, { source: description, size: "small" }) });
12799
- $[10] = description;
12800
- $[11] = t6;
12801
- } else {
12802
- t6 = $[11];
12803
- }
12804
- let t7;
12805
- if ($[12] !== t4 || $[13] !== t5 || $[14] !== t6) {
12806
- t7 = /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-grow w-full", children: [
12807
- t4,
12808
- t5,
12809
- t6
12810
- ] });
12811
- $[12] = t4;
12812
- $[13] = t5;
12813
- $[14] = t6;
12814
- $[15] = t7;
12875
+ if ($[13] !== T0 || $[14] !== t4 || $[15] !== t5) {
12876
+ t6 = /* @__PURE__ */ jsxRuntime.jsx(T0, { in: t4, children: t5 });
12877
+ $[13] = T0;
12878
+ $[14] = t4;
12879
+ $[15] = t5;
12880
+ $[16] = t6;
12815
12881
  } else {
12816
- t7 = $[15];
12882
+ t6 = $[16];
12817
12883
  }
12818
- let t8;
12819
- if ($[16] === Symbol.for("react.memo_cache_sentinel")) {
12820
- t8 = {
12821
- alignSelf: "flex-end"
12884
+ return t6;
12885
+ }
12886
+ function _temp$d(entry_0) {
12887
+ return /* @__PURE__ */ jsxRuntime.jsx(NavigationChip, { entry: entry_0 }, entry_0.path);
12888
+ }
12889
+ const scrollsMap = {};
12890
+ function useRestoreScroll() {
12891
+ const location = reactRouterDom.useLocation();
12892
+ const containerRef = React.useRef(null);
12893
+ const [scroll, setScroll] = React.useState(0);
12894
+ const [direction, setDirection] = React.useState("down");
12895
+ const handleScroll = React.useCallback(() => {
12896
+ if (!containerRef.current || !location.key) return;
12897
+ scrollsMap[location.key] = containerRef.current.scrollTop;
12898
+ setScroll(containerRef.current.scrollTop);
12899
+ setDirection(containerRef.current.scrollTop > scroll ? "down" : "up");
12900
+ }, [containerRef, location.key, scroll]);
12901
+ React.useEffect(() => {
12902
+ const container = containerRef.current;
12903
+ if (!container) return;
12904
+ container.addEventListener("scroll", handleScroll, {
12905
+ passive: true
12906
+ });
12907
+ return () => {
12908
+ if (container) container.removeEventListener("scroll", handleScroll);
12822
12909
  };
12823
- $[16] = t8;
12910
+ }, [containerRef, handleScroll, location]);
12911
+ React.useEffect(() => {
12912
+ if (!containerRef.current || !scrollsMap[location.key]) return;
12913
+ containerRef.current.scrollTo({
12914
+ top: scrollsMap[location.key],
12915
+ behavior: "auto"
12916
+ });
12917
+ }, [location]);
12918
+ return {
12919
+ containerRef,
12920
+ scroll,
12921
+ direction
12922
+ };
12923
+ }
12924
+ function NavigationGroup(t0) {
12925
+ const $ = reactCompilerRuntime.c(26);
12926
+ const {
12927
+ children,
12928
+ group,
12929
+ minimised,
12930
+ isPreview,
12931
+ isPotentialCardDropTarget,
12932
+ onEditGroup,
12933
+ dndDisabled
12934
+ } = t0;
12935
+ const [isHovered, setIsHovered] = React.useState(false);
12936
+ const currentGroupName = group ?? "Views";
12937
+ const t1 = !isPotentialCardDropTarget ? "my-10" : "my-6";
12938
+ let t2;
12939
+ if ($[0] !== t1) {
12940
+ t2 = ui.cls(t1, "transition-all duration-200 ease-in-out");
12941
+ $[0] = t1;
12942
+ $[1] = t2;
12943
+ } else {
12944
+ t2 = $[1];
12945
+ }
12946
+ const t3 = `flex items-center ${isPreview ? "px-1 py-0.5 m-0" : "ml-3.5 mt-6"} `;
12947
+ let t4;
12948
+ let t5;
12949
+ if ($[2] === Symbol.for("react.memo_cache_sentinel")) {
12950
+ t4 = () => setIsHovered(true);
12951
+ t5 = () => setIsHovered(false);
12952
+ $[2] = t4;
12953
+ $[3] = t5;
12954
+ } else {
12955
+ t4 = $[2];
12956
+ t5 = $[3];
12957
+ }
12958
+ const t6 = isPreview ? "body2" : "caption";
12959
+ const t7 = `${isPreview ? "px-1 py-0.5" : "ml-3.5"} font-medium uppercase text-sm text-surface-600 dark:text-surface-400`;
12960
+ let t8;
12961
+ if ($[4] !== currentGroupName || $[5] !== t6 || $[6] !== t7) {
12962
+ t8 = /* @__PURE__ */ jsxRuntime.jsx(ui.Typography, { variant: t6, component: "h2", color: "secondary", className: t7, children: currentGroupName });
12963
+ $[4] = currentGroupName;
12964
+ $[5] = t6;
12965
+ $[6] = t7;
12966
+ $[7] = t8;
12967
+ } else {
12968
+ t8 = $[7];
12969
+ }
12970
+ let t9;
12971
+ if ($[8] !== currentGroupName || $[9] !== dndDisabled || $[10] !== isHovered || $[11] !== isPreview || $[12] !== onEditGroup) {
12972
+ t9 = !isPreview && onEditGroup && !dndDisabled && /* @__PURE__ */ jsxRuntime.jsx(ui.IconButton, { size: "smallest", onClick: (e) => {
12973
+ e.stopPropagation();
12974
+ onEditGroup(currentGroupName);
12975
+ }, className: ui.cls("ml-2 ", isHovered ? "opacity-100" : "opacity-0", "transition-opacity duration-100"), children: /* @__PURE__ */ jsxRuntime.jsx(ui.EditIcon, { size: "smallest" }) });
12976
+ $[8] = currentGroupName;
12977
+ $[9] = dndDisabled;
12978
+ $[10] = isHovered;
12979
+ $[11] = isPreview;
12980
+ $[12] = onEditGroup;
12981
+ $[13] = t9;
12982
+ } else {
12983
+ t9 = $[13];
12984
+ }
12985
+ let t10;
12986
+ if ($[14] !== t3 || $[15] !== t8 || $[16] !== t9) {
12987
+ t10 = /* @__PURE__ */ jsxRuntime.jsxs("div", { className: t3, onMouseEnter: t4, onMouseLeave: t5, children: [
12988
+ t8,
12989
+ t9
12990
+ ] });
12991
+ $[14] = t3;
12992
+ $[15] = t8;
12993
+ $[16] = t9;
12994
+ $[17] = t10;
12995
+ } else {
12996
+ t10 = $[17];
12997
+ }
12998
+ let t11;
12999
+ if ($[18] !== children || $[19] !== isPreview || $[20] !== minimised) {
13000
+ t11 = isPreview ? children : minimised ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: ui.cls("mt-4 p-8 bg-surface-accent-200 dark:bg-surface-accent-800 rounded-lg"), style: {
13001
+ minHeight: "50px"
13002
+ } }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: ui.cls("mt-4", !minimised ? "pt-0" : ""), children });
13003
+ $[18] = children;
13004
+ $[19] = isPreview;
13005
+ $[20] = minimised;
13006
+ $[21] = t11;
13007
+ } else {
13008
+ t11 = $[21];
13009
+ }
13010
+ let t12;
13011
+ if ($[22] !== t10 || $[23] !== t11 || $[24] !== t2) {
13012
+ t12 = /* @__PURE__ */ jsxRuntime.jsxs("div", { className: t2, children: [
13013
+ t10,
13014
+ t11
13015
+ ] });
13016
+ $[22] = t10;
13017
+ $[23] = t11;
13018
+ $[24] = t2;
13019
+ $[25] = t12;
13020
+ } else {
13021
+ t12 = $[25];
13022
+ }
13023
+ return t12;
13024
+ }
13025
+ const NavigationCard = React.memo(function NavigationCard2(t0) {
13026
+ const $ = reactCompilerRuntime.c(25);
13027
+ const {
13028
+ name,
13029
+ description,
13030
+ icon,
13031
+ actions,
13032
+ onClick,
13033
+ shrink
13034
+ } = t0;
13035
+ const t1 = shrink && "w-full max-w-full min-h-0 scale-75";
13036
+ let t2;
13037
+ if ($[0] !== t1) {
13038
+ t2 = ui.cls("h-full p-4 cursor-pointer min-h-[230px] transition-all duration-200 ease-in-out", t1);
13039
+ $[0] = t1;
13040
+ $[1] = t2;
13041
+ } else {
13042
+ t2 = $[1];
13043
+ }
13044
+ let t3;
13045
+ if ($[2] !== onClick) {
13046
+ t3 = () => {
13047
+ onClick?.();
13048
+ };
13049
+ $[2] = onClick;
13050
+ $[3] = t3;
13051
+ } else {
13052
+ t3 = $[3];
13053
+ }
13054
+ let t4;
13055
+ if ($[4] !== actions) {
13056
+ t4 = /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-1", onClick: _temp$c, children: actions });
13057
+ $[4] = actions;
13058
+ $[5] = t4;
13059
+ } else {
13060
+ t4 = $[5];
13061
+ }
13062
+ let t5;
13063
+ if ($[6] !== icon || $[7] !== t4) {
13064
+ t5 = /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "h-10 flex items-center w-full justify-between text-surface-300 dark:text-surface-600", children: [
13065
+ icon,
13066
+ t4
13067
+ ] });
13068
+ $[6] = icon;
13069
+ $[7] = t4;
13070
+ $[8] = t5;
13071
+ } else {
13072
+ t5 = $[8];
13073
+ }
13074
+ let t6;
13075
+ if ($[9] !== name) {
13076
+ t6 = /* @__PURE__ */ jsxRuntime.jsx(ui.Typography, { gutterBottom: true, variant: "h5", component: "h2", children: name });
13077
+ $[9] = name;
13078
+ $[10] = t6;
13079
+ } else {
13080
+ t6 = $[10];
13081
+ }
13082
+ let t7;
13083
+ if ($[11] !== description) {
13084
+ t7 = description && /* @__PURE__ */ jsxRuntime.jsx(ui.Typography, { variant: "body2", color: "secondary", component: "div", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Markdown, { source: description, size: "small" }) });
13085
+ $[11] = description;
13086
+ $[12] = t7;
13087
+ } else {
13088
+ t7 = $[12];
13089
+ }
13090
+ let t8;
13091
+ if ($[13] !== t5 || $[14] !== t6 || $[15] !== t7) {
13092
+ t8 = /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-grow w-full", children: [
13093
+ t5,
13094
+ t6,
13095
+ t7
13096
+ ] });
13097
+ $[13] = t5;
13098
+ $[14] = t6;
13099
+ $[15] = t7;
13100
+ $[16] = t8;
12824
13101
  } else {
12825
13102
  t8 = $[16];
12826
13103
  }
12827
13104
  let t9;
12828
13105
  if ($[17] === Symbol.for("react.memo_cache_sentinel")) {
12829
- t9 = /* @__PURE__ */ jsxRuntime.jsx("div", { style: t8, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-4", children: /* @__PURE__ */ jsxRuntime.jsx(ui.ArrowForwardIcon, { className: "text-primary" }) }) });
13106
+ t9 = {
13107
+ alignSelf: "flex-end"
13108
+ };
12830
13109
  $[17] = t9;
12831
13110
  } else {
12832
13111
  t9 = $[17];
12833
13112
  }
12834
13113
  let t10;
12835
- if ($[18] !== t7) {
12836
- t10 = /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-start h-full", children: [
12837
- t7,
12838
- t9
12839
- ] });
12840
- $[18] = t7;
12841
- $[19] = t10;
13114
+ if ($[18] === Symbol.for("react.memo_cache_sentinel")) {
13115
+ t10 = /* @__PURE__ */ jsxRuntime.jsx("div", { style: t9, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-4", children: /* @__PURE__ */ jsxRuntime.jsx(ui.ArrowForwardIcon, { className: "text-primary" }) }) });
13116
+ $[18] = t10;
12842
13117
  } else {
12843
- t10 = $[19];
13118
+ t10 = $[18];
12844
13119
  }
12845
13120
  let t11;
12846
- if ($[20] !== t10 || $[21] !== t2) {
12847
- t11 = /* @__PURE__ */ jsxRuntime.jsx(ui.Card, { className: t1, onClick: t2, children: t10 });
12848
- $[20] = t10;
12849
- $[21] = t2;
12850
- $[22] = t11;
13121
+ if ($[19] !== t8) {
13122
+ t11 = /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-start h-full", children: [
13123
+ t8,
13124
+ t10
13125
+ ] });
13126
+ $[19] = t8;
13127
+ $[20] = t11;
12851
13128
  } else {
12852
- t11 = $[22];
13129
+ t11 = $[20];
12853
13130
  }
12854
- return t11;
12855
- }
12856
- function _temp$e(event) {
13131
+ let t12;
13132
+ if ($[21] !== t11 || $[22] !== t2 || $[23] !== t3) {
13133
+ t12 = /* @__PURE__ */ jsxRuntime.jsx(ui.Card, { className: t2, onClick: t3, children: t11 });
13134
+ $[21] = t11;
13135
+ $[22] = t2;
13136
+ $[23] = t3;
13137
+ $[24] = t12;
13138
+ } else {
13139
+ t12 = $[24];
13140
+ }
13141
+ return t12;
13142
+ });
13143
+ function _temp$c(event) {
12857
13144
  event.preventDefault();
12858
13145
  event.stopPropagation();
12859
13146
  }
@@ -12913,7 +13200,7 @@
12913
13200
  return t5;
12914
13201
  }
12915
13202
  function NavigationCardBinding(t0) {
12916
- const $ = reactCompilerRuntime.c(34);
13203
+ const $ = reactCompilerRuntime.c(35);
12917
13204
  const {
12918
13205
  path,
12919
13206
  collection,
@@ -12922,7 +13209,8 @@
12922
13209
  name,
12923
13210
  description,
12924
13211
  onClick,
12925
- type
13212
+ type,
13213
+ shrink
12926
13214
  } = t0;
12927
13215
  const userConfigurationPersistence = useUserConfigurationPersistence();
12928
13216
  const t1 = collection ?? view;
@@ -13029,533 +13317,1030 @@
13029
13317
  t6 = $[27];
13030
13318
  }
13031
13319
  let t7;
13032
- if ($[28] !== actions || $[29] !== collectionIcon || $[30] !== description || $[31] !== name || $[32] !== t6) {
13033
- t7 = /* @__PURE__ */ jsxRuntime.jsx(NavigationCard, { icon: collectionIcon, name, description, actions, onClick: t6 });
13320
+ if ($[28] !== actions || $[29] !== collectionIcon || $[30] !== description || $[31] !== name || $[32] !== shrink || $[33] !== t6) {
13321
+ t7 = /* @__PURE__ */ jsxRuntime.jsx(NavigationCard, { icon: collectionIcon, name, description, actions, onClick: t6, shrink });
13034
13322
  $[28] = actions;
13035
13323
  $[29] = collectionIcon;
13036
13324
  $[30] = description;
13037
13325
  $[31] = name;
13038
- $[32] = t6;
13039
- $[33] = t7;
13326
+ $[32] = shrink;
13327
+ $[33] = t6;
13328
+ $[34] = t7;
13040
13329
  } else {
13041
- t7 = $[33];
13330
+ t7 = $[34];
13042
13331
  }
13043
13332
  return t7;
13044
13333
  }
13045
- function NavigationChip(t0) {
13046
- const $ = reactCompilerRuntime.c(18);
13334
+ const animateLayoutChanges = (args) => sortable.defaultAnimateLayoutChanges({
13335
+ ...args,
13336
+ wasDragging: true
13337
+ });
13338
+ const dropAnimationConfig = {};
13339
+ const cloneSerializableNavigationEntry = (entry) => {
13340
+ const clonedEntry = {
13341
+ id: entry.id,
13342
+ path: entry.path,
13343
+ url: entry.url,
13344
+ name: entry.name,
13345
+ type: entry.type,
13346
+ collection: entry.collection ? {
13347
+ ...entry.collection
13348
+ } : void 0,
13349
+ view: entry.view ? {
13350
+ ...entry.view
13351
+ } : void 0,
13352
+ ...entry.group && {
13353
+ group: entry.group
13354
+ },
13355
+ ...entry.description && {
13356
+ description: entry.description
13357
+ }
13358
+ };
13359
+ return clonedEntry;
13360
+ };
13361
+ const cloneItemsForDnd = (items) => items.map((g) => ({
13362
+ name: g.name,
13363
+ entries: g.entries.map(cloneSerializableNavigationEntry)
13364
+ }));
13365
+ function SortableNavigationCard(t0) {
13366
+ const $ = reactCompilerRuntime.c(17);
13047
13367
  const {
13048
- entry
13368
+ entry,
13369
+ onClick
13049
13370
  } = t0;
13050
- const navigate = reactRouterDom.useNavigate();
13051
- const userConfigurationPersistence = useUserConfigurationPersistence();
13052
- if (!userConfigurationPersistence) {
13053
- return null;
13054
- }
13055
13371
  let t1;
13056
- if ($[0] !== entry.path || $[1] !== userConfigurationPersistence.favouritePaths) {
13057
- t1 = userConfigurationPersistence.favouritePaths.includes(entry.path);
13058
- $[0] = entry.path;
13059
- $[1] = userConfigurationPersistence.favouritePaths;
13060
- $[2] = t1;
13372
+ if ($[0] !== entry.url) {
13373
+ t1 = {
13374
+ id: entry.url,
13375
+ animateLayoutChanges
13376
+ };
13377
+ $[0] = entry.url;
13378
+ $[1] = t1;
13061
13379
  } else {
13062
- t1 = $[2];
13380
+ t1 = $[1];
13063
13381
  }
13064
- const favourite = t1;
13382
+ const {
13383
+ setNodeRef,
13384
+ listeners: listeners2,
13385
+ attributes,
13386
+ transform,
13387
+ transition,
13388
+ isDragging
13389
+ } = sortable.useSortable(t1);
13065
13390
  let t2;
13066
- if ($[3] !== entry.path || $[4] !== favourite || $[5] !== userConfigurationPersistence) {
13067
- t2 = (e) => {
13068
- e.preventDefault();
13069
- e.stopPropagation();
13070
- if (favourite) {
13071
- userConfigurationPersistence.setFavouritePaths(userConfigurationPersistence.favouritePaths.filter((p) => p !== entry.path));
13072
- } else {
13073
- userConfigurationPersistence.setFavouritePaths([...userConfigurationPersistence.favouritePaths, entry.path]);
13074
- }
13075
- };
13076
- $[3] = entry.path;
13077
- $[4] = favourite;
13078
- $[5] = userConfigurationPersistence;
13079
- $[6] = t2;
13391
+ if ($[2] !== transform) {
13392
+ t2 = transform ? utilities.CSS.Transform.toString(transform) : void 0;
13393
+ $[2] = transform;
13394
+ $[3] = t2;
13080
13395
  } else {
13081
- t2 = $[6];
13396
+ t2 = $[3];
13082
13397
  }
13083
- const onIconClick = t2;
13084
- let t3;
13085
- if ($[7] !== entry.url || $[8] !== navigate) {
13086
- t3 = () => navigate(entry.url);
13087
- $[7] = entry.url;
13088
- $[8] = navigate;
13089
- $[9] = t3;
13398
+ const t3 = isDragging ? 0 : 1;
13399
+ let t4;
13400
+ if ($[4] !== t2 || $[5] !== t3 || $[6] !== transition) {
13401
+ t4 = {
13402
+ transform: t2,
13403
+ transition,
13404
+ opacity: t3
13405
+ };
13406
+ $[4] = t2;
13407
+ $[5] = t3;
13408
+ $[6] = transition;
13409
+ $[7] = t4;
13090
13410
  } else {
13091
- t3 = $[9];
13411
+ t4 = $[7];
13092
13412
  }
13093
- const t4 = favourite ? "text-secondary" : "text-surface-400 dark:text-surface-500";
13413
+ const style = t4;
13094
13414
  let t5;
13095
- if ($[10] !== onIconClick || $[11] !== t4) {
13096
- t5 = /* @__PURE__ */ jsxRuntime.jsx(ui.StarIcon, { onClick: onIconClick, size: 18, className: t4 });
13097
- $[10] = onIconClick;
13098
- $[11] = t4;
13099
- $[12] = t5;
13415
+ if ($[8] !== entry || $[9] !== onClick) {
13416
+ t5 = /* @__PURE__ */ jsxRuntime.jsx(NavigationCardBinding, { ...entry, onClick });
13417
+ $[8] = entry;
13418
+ $[9] = onClick;
13419
+ $[10] = t5;
13100
13420
  } else {
13101
- t5 = $[12];
13421
+ t5 = $[10];
13102
13422
  }
13103
13423
  let t6;
13104
- if ($[13] !== entry.name || $[14] !== entry.path || $[15] !== t3 || $[16] !== t5) {
13105
- t6 = /* @__PURE__ */ jsxRuntime.jsx(ui.Chip, { onClick: t3, icon: t5, children: entry.name }, entry.path);
13106
- $[13] = entry.name;
13107
- $[14] = entry.path;
13108
- $[15] = t3;
13109
- $[16] = t5;
13110
- $[17] = t6;
13424
+ if ($[11] !== attributes || $[12] !== listeners2 || $[13] !== setNodeRef || $[14] !== style || $[15] !== t5) {
13425
+ t6 = /* @__PURE__ */ jsxRuntime.jsx("div", { ref: setNodeRef, style, ...attributes, ...listeners2, children: t5 });
13426
+ $[11] = attributes;
13427
+ $[12] = listeners2;
13428
+ $[13] = setNodeRef;
13429
+ $[14] = style;
13430
+ $[15] = t5;
13431
+ $[16] = t6;
13111
13432
  } else {
13112
- t6 = $[17];
13433
+ t6 = $[16];
13113
13434
  }
13114
13435
  return t6;
13115
13436
  }
13116
- function FavouritesView(t0) {
13117
- const $ = reactCompilerRuntime.c(17);
13118
- const navigationController = useNavigationController();
13119
- const userConfigurationPersistence = useUserConfigurationPersistence();
13120
- if (!userConfigurationPersistence) {
13121
- return null;
13437
+ function NavigationGroupDroppable(t0) {
13438
+ const $ = reactCompilerRuntime.c(11);
13439
+ const {
13440
+ id,
13441
+ itemIds,
13442
+ children,
13443
+ isPotentialCardDropTarget: t1
13444
+ } = t0;
13445
+ const isPotentialCardDropTarget = t1 === void 0 ? false : t1;
13446
+ let t2;
13447
+ if ($[0] !== id) {
13448
+ t2 = {
13449
+ id
13450
+ };
13451
+ $[0] = id;
13452
+ $[1] = t2;
13453
+ } else {
13454
+ t2 = $[1];
13122
13455
  }
13456
+ const {
13457
+ setNodeRef
13458
+ } = core.useDroppable(t2);
13459
+ const t3 = isPotentialCardDropTarget ? "p-2 bg-surface-accent-200 dark:bg-surface-accent-800 rounded-lg" : void 0;
13460
+ let t4;
13461
+ if ($[2] !== t3) {
13462
+ t4 = ui.cls(t3, "transition-all duration-200 ease-in-out");
13463
+ $[2] = t3;
13464
+ $[3] = t4;
13465
+ } else {
13466
+ t4 = $[3];
13467
+ }
13468
+ let t5;
13469
+ if ($[4] !== children || $[5] !== itemIds) {
13470
+ t5 = /* @__PURE__ */ jsxRuntime.jsx(sortable.SortableContext, { items: itemIds, strategy: sortable.rectSortingStrategy, children });
13471
+ $[4] = children;
13472
+ $[5] = itemIds;
13473
+ $[6] = t5;
13474
+ } else {
13475
+ t5 = $[6];
13476
+ }
13477
+ let t6;
13478
+ if ($[7] !== setNodeRef || $[8] !== t4 || $[9] !== t5) {
13479
+ t6 = /* @__PURE__ */ jsxRuntime.jsx("div", { ref: setNodeRef, className: t4, children: t5 });
13480
+ $[7] = setNodeRef;
13481
+ $[8] = t4;
13482
+ $[9] = t5;
13483
+ $[10] = t6;
13484
+ } else {
13485
+ t6 = $[10];
13486
+ }
13487
+ return t6;
13488
+ }
13489
+ function SortableNavigationGroup(t0) {
13490
+ const $ = reactCompilerRuntime.c(15);
13491
+ const {
13492
+ groupName,
13493
+ children,
13494
+ disabled
13495
+ } = t0;
13123
13496
  let t1;
13124
- if ($[0] !== userConfigurationPersistence?.favouritePaths) {
13125
- t1 = userConfigurationPersistence?.favouritePaths ?? [];
13126
- $[0] = userConfigurationPersistence?.favouritePaths;
13127
- $[1] = t1;
13497
+ if ($[0] !== disabled || $[1] !== groupName) {
13498
+ t1 = {
13499
+ id: groupName,
13500
+ animateLayoutChanges,
13501
+ disabled
13502
+ };
13503
+ $[0] = disabled;
13504
+ $[1] = groupName;
13505
+ $[2] = t1;
13128
13506
  } else {
13129
- t1 = $[1];
13507
+ t1 = $[2];
13130
13508
  }
13131
- let T0;
13509
+ const {
13510
+ attributes,
13511
+ listeners: listeners2,
13512
+ setNodeRef,
13513
+ transform,
13514
+ transition,
13515
+ isDragging
13516
+ } = sortable.useSortable(t1);
13132
13517
  let t2;
13133
- let t3;
13518
+ if ($[3] !== transform) {
13519
+ t2 = transform ? utilities.CSS.Transform.toString(transform) : void 0;
13520
+ $[3] = transform;
13521
+ $[4] = t2;
13522
+ } else {
13523
+ t2 = $[4];
13524
+ }
13525
+ const t3 = isDragging ? 0 : 1;
13134
13526
  let t4;
13135
- if ($[2] !== navigationController.topLevelNavigation?.navigationEntries || $[3] !== t1) {
13136
- let t52;
13137
- if ($[8] !== navigationController.topLevelNavigation?.navigationEntries) {
13138
- t52 = (path) => navigationController.topLevelNavigation?.navigationEntries.find((entry) => entry.path === path);
13139
- $[8] = navigationController.topLevelNavigation?.navigationEntries;
13140
- $[9] = t52;
13141
- } else {
13142
- t52 = $[9];
13143
- }
13144
- const favouriteCollections = t1.map(t52).filter(Boolean);
13145
- T0 = ui.Collapse;
13146
- t4 = favouriteCollections.length > 0;
13147
- t2 = "flex flex-row flex-wrap gap-2 pb-2 min-h-[32px]";
13148
- t3 = favouriteCollections.map(_temp$d);
13149
- $[2] = navigationController.topLevelNavigation?.navigationEntries;
13150
- $[3] = t1;
13151
- $[4] = T0;
13527
+ if ($[5] !== t2 || $[6] !== t3 || $[7] !== transition) {
13528
+ t4 = {
13529
+ transform: t2,
13530
+ transition,
13531
+ opacity: t3
13532
+ };
13152
13533
  $[5] = t2;
13153
13534
  $[6] = t3;
13154
- $[7] = t4;
13535
+ $[7] = transition;
13536
+ $[8] = t4;
13155
13537
  } else {
13156
- T0 = $[4];
13157
- t2 = $[5];
13158
- t3 = $[6];
13159
- t4 = $[7];
13538
+ t4 = $[8];
13160
13539
  }
13540
+ const style = t4;
13161
13541
  let t5;
13162
- if ($[10] !== t2 || $[11] !== t3) {
13163
- t5 = /* @__PURE__ */ jsxRuntime.jsx("div", { className: t2, children: t3 });
13164
- $[10] = t2;
13165
- $[11] = t3;
13166
- $[12] = t5;
13542
+ if ($[9] !== attributes || $[10] !== children || $[11] !== listeners2 || $[12] !== setNodeRef || $[13] !== style) {
13543
+ t5 = /* @__PURE__ */ jsxRuntime.jsx("div", { ref: setNodeRef, style, ...attributes, ...listeners2, children });
13544
+ $[9] = attributes;
13545
+ $[10] = children;
13546
+ $[11] = listeners2;
13547
+ $[12] = setNodeRef;
13548
+ $[13] = style;
13549
+ $[14] = t5;
13167
13550
  } else {
13168
- t5 = $[12];
13551
+ t5 = $[14];
13552
+ }
13553
+ return t5;
13554
+ }
13555
+ function useHomePageDnd({
13556
+ items: dndItems,
13557
+ setItems: setDndItems,
13558
+ disabled,
13559
+ onCardMovedBetweenGroups,
13560
+ onGroupMoved,
13561
+ onNewGroupDrop,
13562
+ onPersist
13563
+ }) {
13564
+ const [activeId, setActiveId] = React.useState(null);
13565
+ const [activeIsGroup, setActiveIsGroup] = React.useState(false);
13566
+ const [currentDraggingGroupId, setCurrentDraggingGroupId] = React.useState(null);
13567
+ const [dndKitActiveNode, setDndKitActiveNode] = React.useState(null);
13568
+ const [isDraggingCardOnly, setIsDraggingCardOnly] = React.useState(false);
13569
+ const [dialogOpenForGroup, setDialogOpenForGroup] = React.useState(null);
13570
+ const [isHoveringNewGroupDropZone, setIsHoveringNewGroupDropZone] = React.useState(false);
13571
+ const interimItemsRef = React.useRef(null);
13572
+ React.useEffect(() => {
13573
+ interimItemsRef.current = dndItems;
13574
+ }, [dndItems]);
13575
+ const mouseSensor = core.useSensor(core.MouseSensor, {
13576
+ activationConstraint: {
13577
+ distance: 10
13578
+ }
13579
+ });
13580
+ const touchSensor = core.useSensor(core.TouchSensor, {
13581
+ activationConstraint: {
13582
+ delay: 150,
13583
+ tolerance: 5
13584
+ }
13585
+ });
13586
+ const keyboardSensor = core.useSensor(core.KeyboardSensor);
13587
+ const sensors = core.useSensors(mouseSensor, touchSensor, keyboardSensor);
13588
+ const dndContainers = dndItems.map((g) => g.name);
13589
+ const findDndContainer = React.useCallback((id) => {
13590
+ if (!id) return void 0;
13591
+ const group = dndItems.find((g_0) => g_0.name === id);
13592
+ if (group) return group.name;
13593
+ for (const g_1 of dndItems) {
13594
+ if (g_1.entries.some((e) => e.url === id)) return g_1.name;
13595
+ }
13596
+ return void 0;
13597
+ }, [dndItems]);
13598
+ const lastOverId = React.useRef(null);
13599
+ const recentlyMovedToNewContainer = React.useRef(false);
13600
+ const collisionDetection = React.useCallback((args) => {
13601
+ if (disabled || !activeId) return [];
13602
+ if (activeIsGroup) {
13603
+ const groups = args.droppableContainers.filter((c) => dndItems.some((g_2) => g_2.name === c.id));
13604
+ if (!groups.length) return [];
13605
+ return core.closestCenter({
13606
+ ...args,
13607
+ droppableContainers: groups
13608
+ });
13609
+ }
13610
+ const pointer = core.pointerWithin(args);
13611
+ if (pointer.length) {
13612
+ const zone = pointer.find((c_0) => c_0.id === "new-group-drop-zone");
13613
+ if (zone) return [zone];
13614
+ const container = pointer.find((c_1) => dndItems.some((g_3) => g_3.name === c_1.id));
13615
+ if (container) {
13616
+ const itemsIn = dndItems.find((g_4) => g_4.name === container.id)?.entries;
13617
+ if (itemsIn?.length) {
13618
+ const closest = core.closestCorners({
13619
+ ...args,
13620
+ droppableContainers: args.droppableContainers.filter((c_2) => itemsIn.some((e_0) => e_0.url === c_2.id))
13621
+ });
13622
+ if (closest.length) return closest;
13623
+ }
13624
+ return [container];
13625
+ }
13626
+ const first = core.getFirstCollision(pointer, "id");
13627
+ if (first) return [{
13628
+ id: first
13629
+ }];
13630
+ }
13631
+ const rects = core.rectIntersection(args);
13632
+ const zoneRect = rects.find((c_3) => c_3.id === "new-group-drop-zone");
13633
+ if (zoneRect) return [zoneRect];
13634
+ let overId = core.getFirstCollision(rects, "id");
13635
+ if (overId != null) {
13636
+ const overIsContainer = dndItems.some((g_5) => g_5.name === overId);
13637
+ if (overIsContainer) {
13638
+ const itemsIn_0 = dndItems.find((g_6) => g_6.name === overId)?.entries;
13639
+ if (itemsIn_0?.length) {
13640
+ const closestItem = core.closestCorners({
13641
+ ...args,
13642
+ droppableContainers: args.droppableContainers.filter((c_4) => itemsIn_0.some((e_1) => e_1.url === c_4.id))
13643
+ })[0]?.id;
13644
+ if (closestItem) overId = closestItem;
13645
+ }
13646
+ }
13647
+ lastOverId.current = overId;
13648
+ return [{
13649
+ id: overId
13650
+ }];
13651
+ }
13652
+ if (recentlyMovedToNewContainer.current && lastOverId.current && !activeIsGroup) return [{
13653
+ id: lastOverId.current
13654
+ }];
13655
+ return [];
13656
+ }, [activeId, dndItems, disabled, activeIsGroup]);
13657
+ const handleDragStart = ({
13658
+ active
13659
+ }) => {
13660
+ setDndKitActiveNode(active);
13661
+ if (disabled) return;
13662
+ const isGroup = dndItems.some((g_7) => g_7.name === active.id);
13663
+ if (!active.data.current) active.data.current = {};
13664
+ active.data.current.type = isGroup ? "group" : "item";
13665
+ setActiveId(active.id);
13666
+ setActiveIsGroup(isGroup);
13667
+ setIsDraggingCardOnly(!isGroup);
13668
+ if (isGroup) setCurrentDraggingGroupId(active.id);
13669
+ recentlyMovedToNewContainer.current = false;
13670
+ };
13671
+ const handleDragOver = ({
13672
+ active: active_0,
13673
+ over
13674
+ }) => {
13675
+ if (disabled || !over) return;
13676
+ const activeIdNow = active_0.id;
13677
+ const overIdNow = over.id;
13678
+ if (activeIdNow === overIdNow) return;
13679
+ if (activeIsGroup) return;
13680
+ const activeCont = findDndContainer(activeIdNow);
13681
+ const overCont = findDndContainer(overIdNow);
13682
+ if (!activeCont) return;
13683
+ if (overCont && activeCont !== overCont) {
13684
+ recentlyMovedToNewContainer.current = true;
13685
+ const newState = cloneItemsForDnd(dndItems);
13686
+ const srcIdx = newState.findIndex((g_8) => g_8.name === activeCont);
13687
+ const tgtIdx = newState.findIndex((g_9) => g_9.name === overCont);
13688
+ if (srcIdx === -1 || tgtIdx === -1) return;
13689
+ const src = newState[srcIdx];
13690
+ const tgt = newState[tgtIdx];
13691
+ const idxInSrc = src.entries.findIndex((e_2) => e_2.url === activeIdNow);
13692
+ if (idxInSrc === -1) return;
13693
+ const [moved] = src.entries.splice(idxInSrc, 1);
13694
+ tgt.entries.push(moved);
13695
+ interimItemsRef.current = newState;
13696
+ setDndItems(newState);
13697
+ } else if (activeCont === overCont) {
13698
+ recentlyMovedToNewContainer.current = false;
13699
+ }
13700
+ };
13701
+ const handleDragEnd = ({
13702
+ active: active_1,
13703
+ over: over_0
13704
+ }) => {
13705
+ if (disabled || !over_0) {
13706
+ resetDragState();
13707
+ return;
13708
+ }
13709
+ const activeIdNow_0 = active_1.id;
13710
+ const overIdNow_0 = over_0.id;
13711
+ if (activeIsGroup) {
13712
+ if (activeIdNow_0 !== overIdNow_0 && dndItems.some((g_12) => g_12.name === overIdNow_0)) {
13713
+ const from = dndItems.findIndex((g_10) => g_10.name === activeIdNow_0);
13714
+ const to = dndItems.findIndex((g_11) => g_11.name === overIdNow_0);
13715
+ if (from !== -1 && to !== -1) {
13716
+ const newState_0 = sortable.arrayMove(dndItems, from, to);
13717
+ setDndItems(newState_0);
13718
+ onPersist?.(newState_0);
13719
+ onGroupMoved?.(activeIdNow_0, from, to);
13720
+ }
13721
+ }
13722
+ } else {
13723
+ const activeCont_0 = findDndContainer(activeIdNow_0);
13724
+ if (overIdNow_0 === "new-group-drop-zone") {
13725
+ if (activeCont_0) {
13726
+ const newState_1 = cloneItemsForDnd(dndItems);
13727
+ const srcIdx_0 = newState_1.findIndex((g_13) => g_13.name === activeCont_0);
13728
+ if (srcIdx_0 !== -1) {
13729
+ const src_0 = newState_1[srcIdx_0];
13730
+ const idxInSrc_0 = src_0.entries.findIndex((e_3) => e_3.url === activeIdNow_0);
13731
+ if (idxInSrc_0 !== -1) {
13732
+ const [dragged] = src_0.entries.splice(idxInSrc_0, 1);
13733
+ if (src_0.entries.length === 0) newState_1.splice(srcIdx_0, 1);
13734
+ let tentative = "New Group";
13735
+ let counter = 1;
13736
+ while (newState_1.some((g_14) => g_14.name === tentative)) tentative = `New Group ${counter++}`;
13737
+ newState_1.push({
13738
+ name: tentative,
13739
+ entries: [dragged]
13740
+ });
13741
+ setDndItems(newState_1);
13742
+ onPersist?.(newState_1);
13743
+ setDialogOpenForGroup(tentative);
13744
+ onNewGroupDrop?.();
13745
+ }
13746
+ }
13747
+ }
13748
+ } else {
13749
+ const overCont_0 = findDndContainer(overIdNow_0);
13750
+ if (activeCont_0 === overCont_0) {
13751
+ const grpIdx = dndItems.findIndex((g_15) => g_15.name === activeCont_0);
13752
+ if (grpIdx !== -1) {
13753
+ const group_0 = dndItems[grpIdx];
13754
+ const oldIdx = group_0.entries.findIndex((e_4) => e_4.url === activeIdNow_0);
13755
+ let newIdx = group_0.entries.findIndex((e_5) => e_5.url === overIdNow_0);
13756
+ if (newIdx === -1 && overIdNow_0 === activeCont_0) newIdx = group_0.entries.length - 1;
13757
+ if (oldIdx !== -1 && newIdx !== -1 && oldIdx !== newIdx) {
13758
+ const reordered = sortable.arrayMove(group_0.entries, oldIdx, newIdx);
13759
+ const newState_2 = [...dndItems];
13760
+ newState_2[grpIdx] = {
13761
+ ...group_0,
13762
+ entries: reordered
13763
+ };
13764
+ setDndItems(newState_2);
13765
+ onPersist?.(newState_2);
13766
+ }
13767
+ }
13768
+ } else if (recentlyMovedToNewContainer.current && interimItemsRef.current) {
13769
+ onPersist?.(interimItemsRef.current);
13770
+ }
13771
+ onCardMovedBetweenGroups?.(dndItems.flatMap((g_16) => g_16.entries).find((e_6) => e_6.url === activeIdNow_0));
13772
+ }
13773
+ }
13774
+ resetDragState();
13775
+ };
13776
+ const resetDragState = () => {
13777
+ setDndKitActiveNode(null);
13778
+ setActiveId(null);
13779
+ setActiveIsGroup(false);
13780
+ setCurrentDraggingGroupId(null);
13781
+ setIsDraggingCardOnly(false);
13782
+ recentlyMovedToNewContainer.current = false;
13783
+ };
13784
+ const handleDragCancel = () => resetDragState();
13785
+ const handleRenameGroup = (oldName, newName) => {
13786
+ setDndItems((current) => {
13787
+ const idx = current.findIndex((g_17) => g_17.name === oldName);
13788
+ if (idx === -1) return current;
13789
+ if (current.some((g_18) => g_18.name === newName && g_18.name !== oldName)) return current;
13790
+ const updated = [...current];
13791
+ updated[idx] = {
13792
+ ...updated[idx],
13793
+ name: newName
13794
+ };
13795
+ onPersist?.(updated);
13796
+ return updated;
13797
+ });
13798
+ };
13799
+ const activeItemForOverlay = disabled || !activeId || activeIsGroup ? null : dndItems.flatMap((g_19) => g_19.entries).find((e_7) => e_7.url === activeId) || null;
13800
+ const activeGroupData = disabled || !activeId || !activeIsGroup ? null : dndItems.find((g_20) => g_20.name === activeId) || null;
13801
+ return {
13802
+ sensors,
13803
+ collisionDetection,
13804
+ onDragStart: handleDragStart,
13805
+ onDragOver: handleDragOver,
13806
+ onDragEnd: handleDragEnd,
13807
+ onDragCancel: handleDragCancel,
13808
+ dropAnimation: dropAnimationConfig,
13809
+ activeItemForOverlay,
13810
+ activeGroupData,
13811
+ draggingGroupId: currentDraggingGroupId,
13812
+ containers: dndContainers,
13813
+ dndKitActiveNode,
13814
+ isDraggingCardOnly,
13815
+ dialogOpenForGroup,
13816
+ setDialogOpenForGroup,
13817
+ handleRenameGroup,
13818
+ isHoveringNewGroupDropZone,
13819
+ setIsHoveringNewGroupDropZone
13820
+ };
13821
+ }
13822
+ function NewGroupDropZone(t0) {
13823
+ const $ = reactCompilerRuntime.c(15);
13824
+ const {
13825
+ disabled,
13826
+ setIsHovering
13827
+ } = t0;
13828
+ let t1;
13829
+ if ($[0] !== disabled) {
13830
+ t1 = {
13831
+ id: "new-group-drop-zone",
13832
+ disabled
13833
+ };
13834
+ $[0] = disabled;
13835
+ $[1] = t1;
13836
+ } else {
13837
+ t1 = $[1];
13169
13838
  }
13839
+ const {
13840
+ setNodeRef,
13841
+ isOver
13842
+ } = core.useDroppable(t1);
13843
+ const [isVisible, setIsVisible] = React.useState(false);
13844
+ let t2;
13845
+ if ($[2] !== disabled) {
13846
+ t2 = {
13847
+ onDragStart(t32) {
13848
+ const {
13849
+ active
13850
+ } = t32;
13851
+ if (disabled) {
13852
+ return;
13853
+ }
13854
+ const tp = active.data.current?.type;
13855
+ setIsVisible(tp === "item");
13856
+ },
13857
+ onDragEnd() {
13858
+ setIsVisible(false);
13859
+ },
13860
+ onDragCancel() {
13861
+ setIsVisible(false);
13862
+ }
13863
+ };
13864
+ $[2] = disabled;
13865
+ $[3] = t2;
13866
+ } else {
13867
+ t2 = $[3];
13868
+ }
13869
+ core.useDndMonitor(t2);
13870
+ let t3;
13871
+ let t4;
13872
+ if ($[4] !== isOver || $[5] !== isVisible || $[6] !== setIsHovering) {
13873
+ t3 = () => {
13874
+ setIsHovering(isOver && isVisible);
13875
+ };
13876
+ t4 = [isOver, isVisible, setIsHovering];
13877
+ $[4] = isOver;
13878
+ $[5] = isVisible;
13879
+ $[6] = setIsHovering;
13880
+ $[7] = t3;
13881
+ $[8] = t4;
13882
+ } else {
13883
+ t3 = $[7];
13884
+ t4 = $[8];
13885
+ }
13886
+ React.useEffect(t3, t4);
13887
+ if (!isVisible || disabled) {
13888
+ return null;
13889
+ }
13890
+ const t5 = isOver ? "bg-surface-accent-100 dark:bg-surface-accent-800 border-surface-300 dark:border-surface-600" : "bg-surface-50 dark:bg-surface-900 border-surface-200 dark:border-surface-700";
13170
13891
  let t6;
13171
- if ($[13] !== T0 || $[14] !== t4 || $[15] !== t5) {
13172
- t6 = /* @__PURE__ */ jsxRuntime.jsx(T0, { in: t4, children: t5 });
13173
- $[13] = T0;
13174
- $[14] = t4;
13892
+ if ($[9] !== t5) {
13893
+ t6 = ui.cls("fixed right-8 top-1/2 -translate-y-1/2 w-[200px] h-[120px] border border-dashed rounded-lg flex items-center justify-center transition-all", t5);
13894
+ $[9] = t5;
13895
+ $[10] = t6;
13896
+ } else {
13897
+ t6 = $[10];
13898
+ }
13899
+ let t7;
13900
+ if ($[11] === Symbol.for("react.memo_cache_sentinel")) {
13901
+ t7 = /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-center p-4", children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "block font-medium text-sm", children: "Drop here to create a new group" }) });
13902
+ $[11] = t7;
13903
+ } else {
13904
+ t7 = $[11];
13905
+ }
13906
+ let t8;
13907
+ if ($[12] !== setNodeRef || $[13] !== t6) {
13908
+ t8 = /* @__PURE__ */ jsxRuntime.jsx("div", { ref: setNodeRef, className: t6, children: t7 });
13909
+ $[12] = setNodeRef;
13910
+ $[13] = t6;
13911
+ $[14] = t8;
13912
+ } else {
13913
+ t8 = $[14];
13914
+ }
13915
+ return t8;
13916
+ }
13917
+ function RenameGroupDialog(t0) {
13918
+ const $ = reactCompilerRuntime.c(41);
13919
+ const {
13920
+ open,
13921
+ initialName,
13922
+ existingGroupNames,
13923
+ onClose,
13924
+ onRename
13925
+ } = t0;
13926
+ const [name, setName] = React.useState(initialName);
13927
+ const [error, setError] = React.useState(null);
13928
+ const inputRef = React.useRef(null);
13929
+ let t1;
13930
+ let t2;
13931
+ if ($[0] !== initialName || $[1] !== open) {
13932
+ t1 = () => {
13933
+ if (open) {
13934
+ setName(initialName);
13935
+ setError(null);
13936
+ setTimeout(() => {
13937
+ if (inputRef.current) {
13938
+ inputRef.current.focus();
13939
+ inputRef.current.select();
13940
+ }
13941
+ }, 100);
13942
+ }
13943
+ };
13944
+ t2 = [initialName, open];
13945
+ $[0] = initialName;
13946
+ $[1] = open;
13947
+ $[2] = t1;
13948
+ $[3] = t2;
13949
+ } else {
13950
+ t1 = $[2];
13951
+ t2 = $[3];
13952
+ }
13953
+ React.useEffect(t1, t2);
13954
+ let t3;
13955
+ if ($[4] !== existingGroupNames) {
13956
+ t3 = (event) => {
13957
+ const newName = event.target.value;
13958
+ setName(newName);
13959
+ if (!newName.trim()) {
13960
+ setError("Group name cannot be empty.");
13961
+ } else {
13962
+ if (existingGroupNames.includes(newName.trim())) {
13963
+ setError("This group name already exists.");
13964
+ } else {
13965
+ setError(null);
13966
+ }
13967
+ }
13968
+ };
13969
+ $[4] = existingGroupNames;
13970
+ $[5] = t3;
13971
+ } else {
13972
+ t3 = $[5];
13973
+ }
13974
+ const handleNameChange = t3;
13975
+ let t4;
13976
+ if ($[6] !== error || $[7] !== existingGroupNames || $[8] !== name || $[9] !== onClose || $[10] !== onRename) {
13977
+ t4 = () => {
13978
+ const trimmedName = name.trim();
13979
+ if (!trimmedName) {
13980
+ setError("Group name cannot be empty.");
13981
+ return;
13982
+ }
13983
+ if (existingGroupNames.includes(trimmedName)) {
13984
+ setError("This group name already exists.");
13985
+ return;
13986
+ }
13987
+ if (!error) {
13988
+ onRename(trimmedName);
13989
+ onClose();
13990
+ }
13991
+ };
13992
+ $[6] = error;
13993
+ $[7] = existingGroupNames;
13994
+ $[8] = name;
13995
+ $[9] = onClose;
13996
+ $[10] = onRename;
13997
+ $[11] = t4;
13998
+ } else {
13999
+ t4 = $[11];
14000
+ }
14001
+ const handleSave = t4;
14002
+ let t5;
14003
+ if ($[12] !== existingGroupNames || $[13] !== handleSave || $[14] !== name) {
14004
+ t5 = (event_0) => {
14005
+ if (event_0.key === "Enter") {
14006
+ event_0.preventDefault();
14007
+ const trimmedName_0 = name.trim();
14008
+ let currentError = null;
14009
+ if (!trimmedName_0) {
14010
+ currentError = "Group name cannot be empty.";
14011
+ } else {
14012
+ if (existingGroupNames.includes(trimmedName_0)) {
14013
+ currentError = "This group name already exists.";
14014
+ }
14015
+ }
14016
+ if (!currentError && trimmedName_0) {
14017
+ handleSave();
14018
+ } else {
14019
+ if (currentError) {
14020
+ setError(currentError);
14021
+ }
14022
+ }
14023
+ }
14024
+ };
14025
+ $[12] = existingGroupNames;
14026
+ $[13] = handleSave;
14027
+ $[14] = name;
13175
14028
  $[15] = t5;
14029
+ } else {
14030
+ t5 = $[15];
14031
+ }
14032
+ const handleKeyDown = t5;
14033
+ if (!open) {
14034
+ return null;
14035
+ }
14036
+ let t6;
14037
+ if ($[16] === Symbol.for("react.memo_cache_sentinel")) {
14038
+ t6 = /* @__PURE__ */ jsxRuntime.jsx(ui.DialogTitle, { children: "Rename Group" });
13176
14039
  $[16] = t6;
13177
14040
  } else {
13178
14041
  t6 = $[16];
13179
14042
  }
13180
- return t6;
13181
- }
13182
- function _temp$d(entry_0) {
13183
- return /* @__PURE__ */ jsxRuntime.jsx(NavigationChip, { entry: entry_0 }, entry_0.path);
13184
- }
13185
- const scrollsMap = {};
13186
- function useRestoreScroll() {
13187
- const location = reactRouterDom.useLocation();
13188
- const containerRef = React.useRef(null);
13189
- const [scroll, setScroll] = React.useState(0);
13190
- const [direction, setDirection] = React.useState("down");
13191
- const handleScroll = React.useCallback(() => {
13192
- if (!containerRef.current || !location.key) return;
13193
- scrollsMap[location.key] = containerRef.current.scrollTop;
13194
- setScroll(containerRef.current.scrollTop);
13195
- setDirection(containerRef.current.scrollTop > scroll ? "down" : "up");
13196
- }, [containerRef, location.key, scroll]);
13197
- React.useEffect(() => {
13198
- const container = containerRef.current;
13199
- if (!container) return;
13200
- container.addEventListener("scroll", handleScroll, {
13201
- passive: true
13202
- });
13203
- return () => {
13204
- if (container) container.removeEventListener("scroll", handleScroll);
13205
- };
13206
- }, [containerRef, handleScroll, location]);
13207
- React.useEffect(() => {
13208
- if (!containerRef.current || !scrollsMap[location.key]) return;
13209
- containerRef.current.scrollTo({
13210
- top: scrollsMap[location.key],
13211
- behavior: "auto"
13212
- });
13213
- }, [location]);
13214
- return {
13215
- containerRef,
13216
- scroll,
13217
- direction
13218
- };
14043
+ const t7 = !!error;
14044
+ const t8 = error ? "group-name-error" : void 0;
14045
+ let t9;
14046
+ if ($[17] !== handleKeyDown || $[18] !== handleNameChange || $[19] !== name || $[20] !== t7 || $[21] !== t8) {
14047
+ t9 = /* @__PURE__ */ jsxRuntime.jsx(ui.TextField, { inputRef, label: "Group Name", value: name, onChange: handleNameChange, onKeyDown: handleKeyDown, error: t7, "aria-describedby": t8 });
14048
+ $[17] = handleKeyDown;
14049
+ $[18] = handleNameChange;
14050
+ $[19] = name;
14051
+ $[20] = t7;
14052
+ $[21] = t8;
14053
+ $[22] = t9;
14054
+ } else {
14055
+ t9 = $[22];
14056
+ }
14057
+ let t10;
14058
+ if ($[23] !== error) {
14059
+ t10 = error && /* @__PURE__ */ jsxRuntime.jsx("p", { id: "group-name-error", style: {
14060
+ display: "none"
14061
+ }, children: error });
14062
+ $[23] = error;
14063
+ $[24] = t10;
14064
+ } else {
14065
+ t10 = $[24];
14066
+ }
14067
+ let t11;
14068
+ if ($[25] !== t10 || $[26] !== t9) {
14069
+ t11 = /* @__PURE__ */ jsxRuntime.jsxs(ui.DialogContent, { children: [
14070
+ t9,
14071
+ t10
14072
+ ] });
14073
+ $[25] = t10;
14074
+ $[26] = t9;
14075
+ $[27] = t11;
14076
+ } else {
14077
+ t11 = $[27];
14078
+ }
14079
+ let t12;
14080
+ if ($[28] !== onClose) {
14081
+ t12 = /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { onClick: onClose, color: "primary", variant: "text", children: "Cancel" });
14082
+ $[28] = onClose;
14083
+ $[29] = t12;
14084
+ } else {
14085
+ t12 = $[29];
14086
+ }
14087
+ const t13 = !!error || !name.trim();
14088
+ let t14;
14089
+ if ($[30] !== handleSave || $[31] !== t13) {
14090
+ t14 = /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { onClick: handleSave, color: "primary", disabled: t13, children: "Save" });
14091
+ $[30] = handleSave;
14092
+ $[31] = t13;
14093
+ $[32] = t14;
14094
+ } else {
14095
+ t14 = $[32];
14096
+ }
14097
+ let t15;
14098
+ if ($[33] !== t12 || $[34] !== t14) {
14099
+ t15 = /* @__PURE__ */ jsxRuntime.jsxs(ui.DialogActions, { children: [
14100
+ t12,
14101
+ t14
14102
+ ] });
14103
+ $[33] = t12;
14104
+ $[34] = t14;
14105
+ $[35] = t15;
14106
+ } else {
14107
+ t15 = $[35];
14108
+ }
14109
+ let t16;
14110
+ if ($[36] !== onClose || $[37] !== open || $[38] !== t11 || $[39] !== t15) {
14111
+ t16 = /* @__PURE__ */ jsxRuntime.jsxs(ui.Dialog, { open, onOpenChange: onClose, children: [
14112
+ t6,
14113
+ t11,
14114
+ t15
14115
+ ] });
14116
+ $[36] = onClose;
14117
+ $[37] = open;
14118
+ $[38] = t11;
14119
+ $[39] = t15;
14120
+ $[40] = t16;
14121
+ } else {
14122
+ t16 = $[40];
14123
+ }
14124
+ return t16;
13219
14125
  }
13220
- function DefaultHomePage(t0) {
13221
- const $ = reactCompilerRuntime.c(71);
13222
- const {
13223
- additionalActions,
13224
- additionalChildrenStart,
13225
- additionalChildrenEnd
13226
- } = t0;
14126
+ const DEFAULT_GROUP_NAME = "Views";
14127
+ const ADMIN_GROUP_NAME = "Admin";
14128
+ function DefaultHomePage({
14129
+ additionalActions,
14130
+ additionalChildrenStart,
14131
+ additionalChildrenEnd
14132
+ }) {
13227
14133
  const context = useFireCMSContext();
13228
14134
  const customizationController = useCustomizationController();
13229
14135
  const navigationController = useNavigationController();
13230
- const fuse = React.useRef(null);
13231
- if (!navigationController.topLevelNavigation) {
13232
- throw Error("Navigation not ready in FireCMSHomePage");
13233
- }
13234
- const {
13235
- containerRef,
13236
- direction
13237
- } = useRestoreScroll();
14136
+ if (!navigationController.topLevelNavigation) throw Error("Navigation not ready");
13238
14137
  const {
13239
- navigationEntries,
13240
- groups
14138
+ allowDragAndDrop,
14139
+ navigationEntries: rawNavigationEntries,
14140
+ groups: groupOrderFromNavController,
14141
+ onNavigationEntriesUpdate
13241
14142
  } = navigationController.topLevelNavigation;
14143
+ const fuse = React.useRef(null);
13242
14144
  const [filteredUrls, setFilteredUrls] = React.useState(null);
13243
14145
  const performingSearch = Boolean(filteredUrls);
13244
- let t1;
13245
- if ($[0] !== filteredUrls || $[1] !== navigationEntries) {
13246
- t1 = filteredUrls ? filteredUrls.map((url) => navigationEntries.find((e) => e.url === url)).filter(Boolean) : navigationEntries;
13247
- $[0] = filteredUrls;
13248
- $[1] = navigationEntries;
13249
- $[2] = t1;
13250
- } else {
13251
- t1 = $[2];
13252
- }
13253
- const filteredNavigationEntries = t1;
13254
- let t2;
13255
- let t3;
13256
- if ($[3] !== navigationEntries) {
13257
- t2 = () => {
13258
- fuse.current = new Fuse(navigationEntries, {
13259
- keys: ["name", "description", "group", "path"]
14146
+ const filteredNavigationEntries = React.useMemo(() => {
14147
+ return filteredUrls ? rawNavigationEntries.filter((e) => filteredUrls.includes(e.url)) : rawNavigationEntries;
14148
+ }, [filteredUrls, rawNavigationEntries]);
14149
+ React.useEffect(() => {
14150
+ fuse.current = new Fuse(rawNavigationEntries, {
14151
+ keys: ["name", "description", "group", "path"]
14152
+ });
14153
+ }, [rawNavigationEntries]);
14154
+ const updateSearch = React.useCallback((v) => {
14155
+ if (!v?.trim()) {
14156
+ setFilteredUrls(null);
14157
+ return;
14158
+ }
14159
+ const results = fuse.current?.search(v.trim());
14160
+ setFilteredUrls(results ? results.map((x) => x.item.url) : []);
14161
+ }, []);
14162
+ const [items, setItems] = React.useState([]);
14163
+ const [adminGroupData, setAdminGroupData] = React.useState(null);
14164
+ const processedGroups = React.useMemo(() => {
14165
+ const src = filteredNavigationEntries;
14166
+ const entriesByGroup = {};
14167
+ src.forEach((e_0) => {
14168
+ const g = e_0.type === "admin" ? ADMIN_GROUP_NAME : e_0.group ?? DEFAULT_GROUP_NAME;
14169
+ (entriesByGroup[g] ??= []).push(e_0);
14170
+ });
14171
+ const hasPluginAdditionalCards = customizationController.plugins?.some((p) => p.homePage?.AdditionalCards);
14172
+ let allProcessed;
14173
+ if (performingSearch) {
14174
+ const ordered = [...new Set(src.map((e_1) => e_1.group ?? DEFAULT_GROUP_NAME))];
14175
+ allProcessed = ordered.map((name) => ({
14176
+ name,
14177
+ entries: entriesByGroup[name] || []
14178
+ })).filter((g_0) => g_0.entries.length);
14179
+ } else {
14180
+ allProcessed = groupOrderFromNavController.map((g_1) => ({
14181
+ name: g_1,
14182
+ entries: entriesByGroup[g_1] || []
14183
+ }));
14184
+ Object.keys(entriesByGroup).forEach((g_2) => {
14185
+ if (!groupOrderFromNavController.includes(g_2)) allProcessed.push({
14186
+ name: g_2,
14187
+ entries: entriesByGroup[g_2]
14188
+ });
13260
14189
  });
13261
- };
13262
- t3 = [navigationEntries];
13263
- $[3] = navigationEntries;
13264
- $[4] = t2;
13265
- $[5] = t3;
13266
- } else {
13267
- t2 = $[4];
13268
- t3 = $[5];
13269
- }
13270
- React.useEffect(t2, t3);
13271
- let t4;
13272
- if ($[6] === Symbol.for("react.memo_cache_sentinel")) {
13273
- t4 = (value) => {
13274
- if (!value || value === "") {
13275
- setFilteredUrls(null);
13276
- } else {
13277
- const searchResult = fuse.current?.search(value);
13278
- if (searchResult) {
13279
- setFilteredUrls(searchResult.map(_temp$c));
13280
- }
14190
+ if (hasPluginAdditionalCards && !allProcessed.some((g_3) => g_3.name === DEFAULT_GROUP_NAME)) {
14191
+ allProcessed.push({
14192
+ name: DEFAULT_GROUP_NAME,
14193
+ entries: []
14194
+ });
13281
14195
  }
14196
+ allProcessed = allProcessed.filter((g_4) => g_4.entries.length || groupOrderFromNavController.includes(g_4.name) || g_4.name === DEFAULT_GROUP_NAME && hasPluginAdditionalCards);
14197
+ }
14198
+ const admin = allProcessed.find((g_5) => g_5.name === ADMIN_GROUP_NAME);
14199
+ return {
14200
+ adminGroupData: admin || null,
14201
+ items: allProcessed.filter((g_6) => g_6.name !== ADMIN_GROUP_NAME)
13282
14202
  };
13283
- $[6] = t4;
13284
- } else {
13285
- t4 = $[6];
13286
- }
13287
- const updateSearchResults = t4;
13288
- let T0;
14203
+ }, [filteredNavigationEntries, performingSearch, groupOrderFromNavController, customizationController.plugins]);
14204
+ React.useEffect(() => {
14205
+ setAdminGroupData(processedGroups.adminGroupData);
14206
+ setItems(processedGroups.items);
14207
+ }, [processedGroups]);
14208
+ const updateItems = (updater) => {
14209
+ setItems(updater);
14210
+ };
14211
+ const persistNavigationGroups = (latest) => {
14212
+ const draggable = latest.map((g_7) => ({
14213
+ name: g_7.name,
14214
+ entries: g_7.entries.map((e_2) => e_2.path)
14215
+ }));
14216
+ const all = adminGroupData ? [...draggable, {
14217
+ name: adminGroupData.name,
14218
+ entries: adminGroupData.entries.map((e_3) => e_3.path)
14219
+ }] : draggable;
14220
+ onNavigationEntriesUpdate(all);
14221
+ };
14222
+ const {
14223
+ sensors,
14224
+ collisionDetection,
14225
+ onDragStart,
14226
+ onDragOver,
14227
+ onDragEnd,
14228
+ dropAnimation,
14229
+ activeItemForOverlay,
14230
+ activeGroupData,
14231
+ draggingGroupId,
14232
+ containers,
14233
+ dndKitActiveNode,
14234
+ onDragCancel,
14235
+ isDraggingCardOnly,
14236
+ dialogOpenForGroup,
14237
+ setDialogOpenForGroup,
14238
+ handleRenameGroup,
14239
+ isHoveringNewGroupDropZone,
14240
+ setIsHoveringNewGroupDropZone
14241
+ } = useHomePageDnd({
14242
+ items,
14243
+ setItems: updateItems,
14244
+ disabled: !allowDragAndDrop || performingSearch,
14245
+ onPersist: persistNavigationGroups,
14246
+ // ——► persistence here
14247
+ onGroupMoved: (g_8) => context.analyticsController?.onAnalyticsEvent?.("home_move_group", {
14248
+ name: g_8
14249
+ }),
14250
+ onCardMovedBetweenGroups: (card) => context.analyticsController?.onAnalyticsEvent?.("home_move_card", {
14251
+ id: card.id
14252
+ }),
14253
+ onNewGroupDrop: () => context.analyticsController?.onAnalyticsEvent?.("home_drop_new_group")
14254
+ });
14255
+ const {
14256
+ containerRef,
14257
+ direction
14258
+ } = useRestoreScroll();
14259
+ const dndDisabled = !allowDragAndDrop || performingSearch;
14260
+ const dndModifiers = dndKitActiveNode?.data.current?.type === "group" ? [modifiers.restrictToVerticalAxis, modifiers.restrictToWindowEdges] : [modifiers.restrictToWindowEdges];
14261
+ let additionalPluginChildrenStart;
13289
14262
  let additionalPluginChildrenEnd;
13290
14263
  let additionalPluginSections;
13291
- let t10;
13292
- let t11;
13293
- let t12;
13294
- let t13;
13295
- let t5;
13296
- let t6;
13297
- let t7;
13298
- let t8;
13299
- let t9;
13300
- if ($[7] !== additionalActions || $[8] !== additionalChildrenStart || $[9] !== containerRef || $[10] !== context || $[11] !== customizationController.plugins || $[12] !== direction || $[13] !== filteredNavigationEntries || $[14] !== filteredUrls || $[15] !== groups || $[16] !== performingSearch) {
13301
- const filteredGroups = filteredUrls ? filteredNavigationEntries.map(_temp2$5) : [];
13302
- const allGroups = filteredUrls ? filteredGroups.filter((group, index) => filteredGroups.indexOf(group) === index) : [...groups];
13303
- if (filteredNavigationEntries.filter(_temp3$3).length > 0 || filteredNavigationEntries.length === 0) {
13304
- allGroups.push(void 0);
13305
- }
13306
- let additionalPluginChildrenStart;
13307
- if (customizationController.plugins) {
13308
- let t143;
13309
- if ($[29] !== context || $[30] !== customizationController.plugins) {
13310
- const sectionProps = {
13311
- context
13312
- };
13313
- t143 = customizationController.plugins.filter(_temp4$2).map((plugin_0, i) => {
13314
- const section = plugin_0.homePage.includeSection(sectionProps);
13315
- return /* @__PURE__ */ jsxRuntime.jsx(NavigationGroup, { group: section.title, children: section.children }, `plugin_section_${plugin_0.key}`);
13316
- });
13317
- $[29] = context;
13318
- $[30] = customizationController.plugins;
13319
- $[31] = t143;
13320
- } else {
13321
- t143 = $[31];
13322
- }
13323
- let t153;
13324
- if ($[32] !== t143) {
13325
- t153 = /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: t143 });
13326
- $[32] = t143;
13327
- $[33] = t153;
13328
- } else {
13329
- t153 = $[33];
13330
- }
13331
- additionalPluginSections = t153;
13332
- let t162;
13333
- if ($[34] !== customizationController.plugins) {
13334
- t162 = customizationController.plugins.filter(_temp5$2).map(_temp6$2);
13335
- $[34] = customizationController.plugins;
13336
- $[35] = t162;
13337
- } else {
13338
- t162 = $[35];
13339
- }
13340
- let t172;
13341
- if ($[36] !== t162) {
13342
- t172 = /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-2", children: t162 });
13343
- $[36] = t162;
13344
- $[37] = t172;
13345
- } else {
13346
- t172 = $[37];
13347
- }
13348
- additionalPluginChildrenStart = t172;
13349
- let t18;
13350
- if ($[38] !== customizationController.plugins) {
13351
- t18 = customizationController.plugins.filter(_temp7$1).map(_temp8);
13352
- $[38] = customizationController.plugins;
13353
- $[39] = t18;
13354
- } else {
13355
- t18 = $[39];
13356
- }
13357
- let t19;
13358
- if ($[40] !== t18) {
13359
- t19 = /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-2", children: t18 });
13360
- $[40] = t18;
13361
- $[41] = t19;
13362
- } else {
13363
- t19 = $[41];
13364
- }
13365
- additionalPluginChildrenEnd = t19;
13366
- }
13367
- t11 = "home_page";
13368
- t12 = containerRef;
13369
- t13 = "py-2 overflow-auto h-full w-full";
13370
- T0 = ui.Container;
13371
- t5 = "6xl";
13372
- const t142 = direction === "down" ? -84 : 0;
13373
- let t152;
13374
- if ($[42] !== t142) {
13375
- t152 = {
13376
- top: t142
13377
- };
13378
- $[42] = t142;
13379
- $[43] = t152;
13380
- } else {
13381
- t152 = $[43];
13382
- }
13383
- let t16;
13384
- if ($[44] === Symbol.for("react.memo_cache_sentinel")) {
13385
- t16 = /* @__PURE__ */ jsxRuntime.jsx(ui.SearchBar, { onTextSearch: updateSearchResults, placeholder: "Search collections", large: false, autoFocus: true, innerClassName: "w-full", className: "w-full flex-grow" });
13386
- $[44] = t16;
13387
- } else {
13388
- t16 = $[44];
13389
- }
13390
- if ($[45] !== additionalActions || $[46] !== t152) {
13391
- t6 = /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "w-full sticky py-4 transition-all duration-400 ease-in-out top-0 z-10 flex flex-row gap-4", style: t152, children: [
13392
- t16,
14264
+ if (customizationController.plugins) {
14265
+ const sectionProps = {
14266
+ context
14267
+ };
14268
+ additionalPluginSections = /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: customizationController.plugins.filter((p_0) => p_0.homePage?.includeSection).map((plugin) => {
14269
+ const section = plugin.homePage.includeSection(sectionProps);
14270
+ return /* @__PURE__ */ jsxRuntime.jsx(NavigationGroup, { group: section.title, children: section.children }, `plugin_section_${plugin.key}`);
14271
+ }) });
14272
+ additionalPluginChildrenStart = /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-2", children: customizationController.plugins.filter((p_1) => p_1.homePage?.additionalChildrenStart).map((plugin_0, i) => /* @__PURE__ */ jsxRuntime.jsx("div", { children: plugin_0.homePage.additionalChildrenStart }, `plugin_children_start_${i}`)) });
14273
+ additionalPluginChildrenEnd = /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-2", children: customizationController.plugins.filter((p_2) => p_2.homePage?.additionalChildrenEnd).map((plugin_1, i_0) => /* @__PURE__ */ jsxRuntime.jsx("div", { children: plugin_1.homePage.additionalChildrenEnd }, `plugin_children_end_${i_0}`)) });
14274
+ }
14275
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { ref: containerRef, className: "py-2 overflow-auto h-full w-full", children: [
14276
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.Container, { maxWidth: "6xl", children: [
14277
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "w-full sticky py-4 transition-all duration-400 ease-in-out top-0 z-10 flex flex-row gap-4", style: {
14278
+ top: direction === "down" ? -84 : 0
14279
+ }, children: [
14280
+ /* @__PURE__ */ jsxRuntime.jsx(ui.SearchBar, { onTextSearch: updateSearch, placeholder: "Search collections", autoFocus: true, innerClassName: "w-full", className: "w-full flex-grow" }),
13393
14281
  additionalActions
13394
- ] });
13395
- $[45] = additionalActions;
13396
- $[46] = t152;
13397
- $[47] = t6;
13398
- } else {
13399
- t6 = $[47];
13400
- }
13401
- if ($[48] !== performingSearch) {
13402
- t7 = /* @__PURE__ */ jsxRuntime.jsx(FavouritesView, { hidden: performingSearch });
13403
- $[48] = performingSearch;
13404
- $[49] = t7;
13405
- } else {
13406
- t7 = $[49];
13407
- }
13408
- t8 = additionalChildrenStart;
13409
- t9 = additionalPluginChildrenStart;
13410
- let t17;
13411
- if ($[50] !== context || $[51] !== customizationController.plugins || $[52] !== filteredNavigationEntries || $[53] !== performingSearch) {
13412
- t17 = (group_0, index_0) => {
13413
- const AdditionalCards = [];
13414
- const actionProps = {
13415
- group: group_0,
13416
- context
13417
- };
13418
- if (customizationController.plugins) {
13419
- customizationController.plugins.forEach((plugin_5) => {
13420
- if (plugin_5.homePage?.AdditionalCards) {
13421
- AdditionalCards.push(...toArray(plugin_5.homePage?.AdditionalCards));
13422
- }
13423
- });
13424
- }
13425
- const thisGroupCollections = filteredNavigationEntries.filter((entry_0) => entry_0.group === group_0 || !entry_0.group && group_0 === void 0);
13426
- if (thisGroupCollections.length === 0 && (AdditionalCards.length === 0 || performingSearch)) {
13427
- return null;
14282
+ ] }),
14283
+ /* @__PURE__ */ jsxRuntime.jsx(FavouritesView, { hidden: performingSearch }),
14284
+ additionalChildrenStart,
14285
+ additionalPluginChildrenStart,
14286
+ /* @__PURE__ */ jsxRuntime.jsxs(core.DndContext, { sensors, collisionDetection, measuring: {
14287
+ droppable: {
14288
+ strategy: core.MeasuringStrategy.Always,
14289
+ frequency: 500
13428
14290
  }
13429
- return /* @__PURE__ */ jsxRuntime.jsx(NavigationGroup, { group: group_0, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4", children: [
13430
- thisGroupCollections.map((entry_1) => /* @__PURE__ */ jsxRuntime.jsx("div", { className: "col-span-1", children: /* @__PURE__ */ jsxRuntime.jsx(NavigationCardBinding, { ...entry_1, onClick: () => {
13431
- let event;
13432
- if (entry_1.type === "collection") {
13433
- event = "home_navigate_to_collection";
13434
- } else {
13435
- if (entry_1.type === "view") {
13436
- event = "home_navigate_to_view";
13437
- } else {
13438
- if (entry_1.type === "admin") {
13439
- event = "home_navigate_to_admin_view";
13440
- } else {
13441
- event = "unmapped_event";
13442
- }
13443
- }
13444
- }
13445
- context.analyticsController?.onAnalyticsEvent?.(event, {
13446
- path: entry_1.path
13447
- });
13448
- } }) }, `nav_${entry_1.group}_${entry_1.path}_${entry_1.name}`)),
13449
- group_0?.toLowerCase() !== "admin" && AdditionalCards && AdditionalCards.map((AdditionalCard, i_2) => /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx(AdditionalCard, { ...actionProps }) }, `nav_${group_0}_add_${i_2}`))
13450
- ] }) }, `plugin_section_${group_0}`);
13451
- };
13452
- $[50] = context;
13453
- $[51] = customizationController.plugins;
13454
- $[52] = filteredNavigationEntries;
13455
- $[53] = performingSearch;
13456
- $[54] = t17;
13457
- } else {
13458
- t17 = $[54];
13459
- }
13460
- t10 = allGroups.map(t17);
13461
- $[7] = additionalActions;
13462
- $[8] = additionalChildrenStart;
13463
- $[9] = containerRef;
13464
- $[10] = context;
13465
- $[11] = customizationController.plugins;
13466
- $[12] = direction;
13467
- $[13] = filteredNavigationEntries;
13468
- $[14] = filteredUrls;
13469
- $[15] = groups;
13470
- $[16] = performingSearch;
13471
- $[17] = T0;
13472
- $[18] = additionalPluginChildrenEnd;
13473
- $[19] = additionalPluginSections;
13474
- $[20] = t10;
13475
- $[21] = t11;
13476
- $[22] = t12;
13477
- $[23] = t13;
13478
- $[24] = t5;
13479
- $[25] = t6;
13480
- $[26] = t7;
13481
- $[27] = t8;
13482
- $[28] = t9;
13483
- } else {
13484
- T0 = $[17];
13485
- additionalPluginChildrenEnd = $[18];
13486
- additionalPluginSections = $[19];
13487
- t10 = $[20];
13488
- t11 = $[21];
13489
- t12 = $[22];
13490
- t13 = $[23];
13491
- t5 = $[24];
13492
- t6 = $[25];
13493
- t7 = $[26];
13494
- t8 = $[27];
13495
- t9 = $[28];
13496
- }
13497
- let t14;
13498
- if ($[55] !== T0 || $[56] !== additionalChildrenEnd || $[57] !== additionalPluginChildrenEnd || $[58] !== additionalPluginSections || $[59] !== t10 || $[60] !== t5 || $[61] !== t6 || $[62] !== t7 || $[63] !== t8 || $[64] !== t9) {
13499
- t14 = /* @__PURE__ */ jsxRuntime.jsxs(T0, { maxWidth: t5, children: [
13500
- t6,
13501
- t7,
13502
- t8,
13503
- t9,
13504
- t10,
14291
+ }, onDragStart, onDragOver, onDragEnd, onDragCancel, modifiers: dndModifiers, children: [
14292
+ /* @__PURE__ */ jsxRuntime.jsx(sortable.SortableContext, { items: containers, strategy: sortable.verticalListSortingStrategy, children: items.map((groupData) => {
14293
+ const groupKey = groupData.name;
14294
+ const entriesInGroup = groupData.entries;
14295
+ const AdditionalCards = [];
14296
+ customizationController.plugins?.forEach((p_3) => {
14297
+ if (p_3.homePage?.AdditionalCards) AdditionalCards.push(...toArray(p_3.homePage.AdditionalCards));
14298
+ });
14299
+ const actionProps = {
14300
+ group: groupKey === DEFAULT_GROUP_NAME ? void 0 : groupKey,
14301
+ context
14302
+ };
14303
+ if (entriesInGroup.length === 0 && (AdditionalCards.length === 0 || performingSearch) && !groupOrderFromNavController.includes(groupKey)) return null;
14304
+ 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: () => {
14305
+ if (dndDisabled) return;
14306
+ setDialogOpenForGroup(groupKey);
14307
+ }, children: /* @__PURE__ */ jsxRuntime.jsx(NavigationGroupDroppable, { id: groupKey, itemIds: entriesInGroup.map((e_4) => e_4.url), isPotentialCardDropTarget: isDraggingCardOnly, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4 ", children: [
14308
+ entriesInGroup.map((entry) => /* @__PURE__ */ jsxRuntime.jsx(SortableNavigationCard, { entry, onClick: () => {
14309
+ let event = "unmapped_event";
14310
+ if (entry.type === "collection") event = "home_navigate_to_collection";
14311
+ else if (entry.type === "view") event = "home_navigate_to_view";
14312
+ else if (entry.type === "admin") event = "home_navigate_to_admin_view";
14313
+ context.analyticsController?.onAnalyticsEvent?.(event, {
14314
+ path: entry.path
14315
+ });
14316
+ } }, entry.url)),
14317
+ !performingSearch && groupKey.toLowerCase() !== ADMIN_GROUP_NAME.toLowerCase() && AdditionalCards.map((C, i_1) => /* @__PURE__ */ jsxRuntime.jsx(C, { ...actionProps }, `extra_${groupKey}_${i_1}`))
14318
+ ] }) }) }) }, groupKey);
14319
+ }) }, JSON.stringify(containers)),
14320
+ /* @__PURE__ */ jsxRuntime.jsx(NewGroupDropZone, { disabled: dndDisabled, setIsHovering: setIsHoveringNewGroupDropZone }),
14321
+ /* @__PURE__ */ jsxRuntime.jsx(core.DragOverlay, { adjustScale: false, dropAnimation, children: activeGroupData && draggingGroupId === activeGroupData.name ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-lg bg-transparent", style: {
14322
+ padding: 0,
14323
+ margin: 0
14324
+ }, children: /* @__PURE__ */ jsxRuntime.jsx(NavigationGroup, { group: activeGroupData.name === DEFAULT_GROUP_NAME ? void 0 : activeGroupData.name, isPreview: false, minimised: true }) }) : activeItemForOverlay ? /* @__PURE__ */ jsxRuntime.jsx(NavigationCardBinding, { ...activeItemForOverlay, shrink: isHoveringNewGroupDropZone }) : null })
14325
+ ] }),
14326
+ !performingSearch && adminGroupData && /* @__PURE__ */ jsxRuntime.jsx(NavigationGroup, { group: adminGroupData.name, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4 ", children: adminGroupData.entries.map((entry_0) => /* @__PURE__ */ jsxRuntime.jsx(NavigationCardBinding, { ...entry_0, onClick: () => {
14327
+ let event_0 = "unmapped_event";
14328
+ if (entry_0.type === "collection") event_0 = "home_navigate_to_collection";
14329
+ else if (entry_0.type === "view") event_0 = "home_navigate_to_view";
14330
+ else if (entry_0.type === "admin") event_0 = "home_navigate_to_admin_view";
14331
+ context.analyticsController?.onAnalyticsEvent?.(event_0, {
14332
+ path: entry_0.path
14333
+ });
14334
+ } }, entry_0.url)) }) }),
13505
14335
  additionalPluginSections,
13506
14336
  additionalPluginChildrenEnd,
13507
14337
  additionalChildrenEnd
13508
- ] });
13509
- $[55] = T0;
13510
- $[56] = additionalChildrenEnd;
13511
- $[57] = additionalPluginChildrenEnd;
13512
- $[58] = additionalPluginSections;
13513
- $[59] = t10;
13514
- $[60] = t5;
13515
- $[61] = t6;
13516
- $[62] = t7;
13517
- $[63] = t8;
13518
- $[64] = t9;
13519
- $[65] = t14;
13520
- } else {
13521
- t14 = $[65];
13522
- }
13523
- let t15;
13524
- if ($[66] !== t11 || $[67] !== t12 || $[68] !== t13 || $[69] !== t14) {
13525
- t15 = /* @__PURE__ */ jsxRuntime.jsx("div", { id: t11, ref: t12, className: t13, children: t14 });
13526
- $[66] = t11;
13527
- $[67] = t12;
13528
- $[68] = t13;
13529
- $[69] = t14;
13530
- $[70] = t15;
13531
- } else {
13532
- t15 = $[70];
13533
- }
13534
- return t15;
13535
- }
13536
- function _temp8(plugin_4, i_1) {
13537
- return /* @__PURE__ */ jsxRuntime.jsx("div", { children: plugin_4.homePage.additionalChildrenEnd }, `plugin_children_start_${i_1}`);
13538
- }
13539
- function _temp7$1(plugin_3) {
13540
- return plugin_3.homePage?.additionalChildrenEnd;
13541
- }
13542
- function _temp6$2(plugin_2, i_0) {
13543
- return /* @__PURE__ */ jsxRuntime.jsx("div", { children: plugin_2.homePage.additionalChildrenStart }, `plugin_children_start_${i_0}`);
13544
- }
13545
- function _temp5$2(plugin_1) {
13546
- return plugin_1.homePage?.additionalChildrenStart;
13547
- }
13548
- function _temp4$2(plugin) {
13549
- return plugin.homePage?.includeSection;
13550
- }
13551
- function _temp3$3(e_1) {
13552
- return !e_1.group;
13553
- }
13554
- function _temp2$5(entry) {
13555
- return entry.group;
13556
- }
13557
- function _temp$c(e_0) {
13558
- return e_0.item.url;
14338
+ ] }),
14339
+ 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) => {
14340
+ handleRenameGroup(dialogOpenForGroup, newName);
14341
+ setDialogOpenForGroup(null);
14342
+ } })
14343
+ ] });
13559
14344
  }
13560
14345
  function EntityCollectionViewActions(t0) {
13561
14346
  const $ = reactCompilerRuntime.c(41);
@@ -13616,11 +14401,11 @@
13616
14401
  if (selectionEnabled) {
13617
14402
  let t42;
13618
14403
  if ($[12] !== largeLayout || $[13] !== multipleDeleteEnabled || $[14] !== onMultipleDeleteClick || $[15] !== selectedEntities?.length) {
13619
- t42 = largeLayout ? /* @__PURE__ */ jsxRuntime.jsxs(ui.Button, { variant: "text", disabled: !selectedEntities?.length || !multipleDeleteEnabled, startIcon: /* @__PURE__ */ jsxRuntime.jsx(ui.DeleteIcon, {}), onClick: onMultipleDeleteClick, color: "primary", className: "lg:w-20", children: [
14404
+ t42 = largeLayout ? /* @__PURE__ */ jsxRuntime.jsxs(ui.Button, { variant: "text", disabled: !selectedEntities?.length || !multipleDeleteEnabled, startIcon: /* @__PURE__ */ jsxRuntime.jsx(ui.DeleteIcon, { size: "small" }), onClick: onMultipleDeleteClick, color: "primary", className: "lg:w-20", children: [
13620
14405
  "(",
13621
14406
  selectedEntities?.length,
13622
14407
  ")"
13623
- ] }) : /* @__PURE__ */ jsxRuntime.jsx(ui.IconButton, { color: "primary", disabled: !selectedEntities?.length || !multipleDeleteEnabled, onClick: onMultipleDeleteClick, children: /* @__PURE__ */ jsxRuntime.jsx(ui.DeleteIcon, {}) });
14408
+ ] }) : /* @__PURE__ */ jsxRuntime.jsx(ui.IconButton, { size: "small", color: "primary", disabled: !selectedEntities?.length || !multipleDeleteEnabled, onClick: onMultipleDeleteClick, children: /* @__PURE__ */ jsxRuntime.jsx(ui.DeleteIcon, { size: "small" }) });
13624
14409
  $[12] = largeLayout;
13625
14410
  $[13] = multipleDeleteEnabled;
13626
14411
  $[14] = onMultipleDeleteClick;
@@ -13932,8 +14717,10 @@
13932
14717
  return !ele || ele === document.body ? document.body : isScrollable(ele) ? ele : getScrollableParent(ele.parentNode);
13933
14718
  };
13934
14719
  function EntityFormActions(t0) {
13935
- const $ = reactCompilerRuntime.c(12);
14720
+ const $ = reactCompilerRuntime.c(16);
13936
14721
  const {
14722
+ fullPath,
14723
+ fullIdPath,
13937
14724
  collection,
13938
14725
  entity,
13939
14726
  layout,
@@ -13942,13 +14729,17 @@
13942
14729
  disabled,
13943
14730
  status,
13944
14731
  pluginActions,
13945
- openEntityMode
14732
+ openEntityMode,
14733
+ navigateBack,
14734
+ formContext
13946
14735
  } = t0;
13947
14736
  const context = useFireCMSContext();
13948
14737
  const sideEntityController = useSideEntityController();
13949
14738
  let t1;
13950
- if ($[0] !== collection || $[1] !== context || $[2] !== disabled || $[3] !== entity || $[4] !== formex2.isSubmitting || $[5] !== layout || $[6] !== openEntityMode || $[7] !== pluginActions || $[8] !== savingError || $[9] !== sideEntityController || $[10] !== status) {
14739
+ if ($[0] !== collection || $[1] !== context || $[2] !== disabled || $[3] !== entity || $[4] !== formContext || $[5] !== formex2.isSubmitting || $[6] !== fullIdPath || $[7] !== fullPath || $[8] !== layout || $[9] !== navigateBack || $[10] !== openEntityMode || $[11] !== pluginActions || $[12] !== savingError || $[13] !== sideEntityController || $[14] !== status) {
13951
14740
  t1 = layout === "bottom" ? buildBottomActions$1({
14741
+ fullPath,
14742
+ fullIdPath,
13952
14743
  savingError,
13953
14744
  entity,
13954
14745
  collection,
@@ -13958,8 +14749,12 @@
13958
14749
  disabled,
13959
14750
  status,
13960
14751
  pluginActions,
13961
- openEntityMode
14752
+ openEntityMode,
14753
+ navigateBack,
14754
+ formContext
13962
14755
  }) : buildSideActions$1({
14756
+ fullPath,
14757
+ fullIdPath,
13963
14758
  savingError,
13964
14759
  entity,
13965
14760
  collection,
@@ -13969,28 +14764,36 @@
13969
14764
  disabled,
13970
14765
  status,
13971
14766
  pluginActions,
13972
- openEntityMode
14767
+ openEntityMode,
14768
+ navigateBack,
14769
+ formContext
13973
14770
  });
13974
14771
  $[0] = collection;
13975
14772
  $[1] = context;
13976
14773
  $[2] = disabled;
13977
14774
  $[3] = entity;
13978
- $[4] = formex2.isSubmitting;
13979
- $[5] = layout;
13980
- $[6] = openEntityMode;
13981
- $[7] = pluginActions;
13982
- $[8] = savingError;
13983
- $[9] = sideEntityController;
13984
- $[10] = status;
13985
- $[11] = t1;
14775
+ $[4] = formContext;
14776
+ $[5] = formex2.isSubmitting;
14777
+ $[6] = fullIdPath;
14778
+ $[7] = fullPath;
14779
+ $[8] = layout;
14780
+ $[9] = navigateBack;
14781
+ $[10] = openEntityMode;
14782
+ $[11] = pluginActions;
14783
+ $[12] = savingError;
14784
+ $[13] = sideEntityController;
14785
+ $[14] = status;
14786
+ $[15] = t1;
13986
14787
  } else {
13987
- t1 = $[11];
14788
+ t1 = $[15];
13988
14789
  }
13989
14790
  return t1;
13990
14791
  }
13991
14792
  function buildBottomActions$1({
13992
14793
  savingError,
13993
14794
  entity,
14795
+ fullPath,
14796
+ fullIdPath,
13994
14797
  formActions,
13995
14798
  collection,
13996
14799
  context,
@@ -13999,23 +14802,29 @@
13999
14802
  disabled,
14000
14803
  status,
14001
14804
  pluginActions,
14002
- openEntityMode
14805
+ openEntityMode,
14806
+ navigateBack,
14807
+ formContext
14003
14808
  }) {
14004
14809
  return /* @__PURE__ */ jsxRuntime.jsxs(ui.DialogActions, { position: "absolute", children: [
14005
14810
  savingError && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-right", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Typography, { color: "error", children: savingError.message }) }),
14006
14811
  entity && (formActions ?? []).length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-grow flex overflow-auto no-scrollbar", children: (formActions ?? []).map((action) => /* @__PURE__ */ jsxRuntime.jsx(ui.IconButton, { color: "primary", onClick: (event) => {
14007
14812
  event.stopPropagation();
14008
14813
  if (entity) action.onClick({
14814
+ view: "form",
14009
14815
  entity,
14010
- fullPath: collection.path,
14816
+ fullPath: fullPath ?? collection.path,
14817
+ fullIdPath: fullIdPath ?? collection.id,
14011
14818
  collection,
14012
14819
  context,
14013
14820
  sideEntityController,
14014
- openEntityMode
14821
+ openEntityMode,
14822
+ navigateBack,
14823
+ formContext
14015
14824
  });
14016
14825
  }, children: action.icon }, action.name)) }),
14017
14826
  pluginActions,
14018
- /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "text", disabled: disabled || isSubmitting, type: "reset", children: status === "existing" ? "Discard" : "Clear" }),
14827
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "text", disabled: disabled || isSubmitting, color: "primary", type: "reset", children: status === "existing" ? "Discard" : "Clear" }),
14019
14828
  /* @__PURE__ */ jsxRuntime.jsxs(ui.Button, { variant: "filled", color: "primary", type: "submit", disabled: disabled || isSubmitting, children: [
14020
14829
  status === "existing" && "Save",
14021
14830
  status === "copy" && "Create copy",
@@ -14027,6 +14836,9 @@
14027
14836
  savingError,
14028
14837
  entity,
14029
14838
  formActions,
14839
+ fullPath,
14840
+ fullIdPath,
14841
+ openEntityMode,
14030
14842
  collection,
14031
14843
  context,
14032
14844
  sideEntityController,
@@ -14048,6 +14860,7 @@
14048
14860
  }
14049
14861
  function EntityForm({
14050
14862
  path,
14863
+ fullIdPath,
14051
14864
  entityId: entityIdProp,
14052
14865
  collection,
14053
14866
  onValuesModified,
@@ -14073,6 +14886,15 @@
14073
14886
  if (collection.customId && collection.formAutoSave) {
14074
14887
  console.warn(`The collection ${collection.path} has customId and formAutoSave enabled. This is not supported and formAutoSave will be ignored`);
14075
14888
  }
14889
+ const sideEntityController = useSideEntityController();
14890
+ const navigationController = useNavigationController();
14891
+ const navigateBack = React.useCallback(() => {
14892
+ if (openEntityMode === "side_panel") {
14893
+ sideEntityController.close();
14894
+ } else {
14895
+ window.history.back();
14896
+ }
14897
+ }, []);
14076
14898
  const authController = useAuthController();
14077
14899
  const [status, setStatus] = React.useState(initialStatus);
14078
14900
  const updateStatus = (status_0) => {
@@ -14323,14 +15145,15 @@
14323
15145
  const pluginActions = [];
14324
15146
  const plugins = customizationController.plugins;
14325
15147
  const actionsDisabled = disabled || formex$1.isSubmitting || status === "existing" && !formex$1.dirty || Boolean(disabledProp);
15148
+ const parentCollectionIds = navigationController.getParentCollectionIds(path);
14326
15149
  if (plugins && collection) {
14327
15150
  const actionProps = {
14328
15151
  entityId,
15152
+ parentCollectionIds,
14329
15153
  path,
14330
15154
  status,
14331
15155
  collection,
14332
15156
  context,
14333
- currentEntityId: entityId,
14334
15157
  formContext,
14335
15158
  openEntityMode,
14336
15159
  disabled: actionsDisabled
@@ -14442,13 +15265,15 @@
14442
15265
  const formView = /* @__PURE__ */ jsxRuntime.jsx(ErrorBoundary, { children: /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
14443
15266
  !Builder && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "w-full py-2 flex flex-col items-start my-4 lg:my-6", children: [
14444
15267
  /* @__PURE__ */ jsxRuntime.jsx(ui.Typography, { className: "my-4 flex-grow line-clamp-1 " + (collection.hideIdFromForm ? "mb-6" : ""), variant: "h4", children: title ?? collection.singularName ?? collection.name }),
14445
- showEntityPath && /* @__PURE__ */ jsxRuntime.jsx(ui.Alert, { color: "base", className: "w-full", size: "small", children: /* @__PURE__ */ jsxRuntime.jsxs("code", { className: "text-xs select-all text-text-secondary dark:text-text-secondary-dark", children: [
15268
+ !entity?.values && initialStatus === "existing" && /* @__PURE__ */ jsxRuntime.jsx(ui.Alert, { color: "warning", size: "small", outerClassName: "w-full mb-4 text-xs", children: "This entity does not exist in the database" }),
15269
+ showEntityPath && /* @__PURE__ */ jsxRuntime.jsx(ui.Alert, { color: "base", outerClassName: "w-full", size: "small", children: /* @__PURE__ */ jsxRuntime.jsxs("code", { className: "text-xs select-all text-text-secondary dark:text-text-secondary-dark", children: [
14446
15270
  entity?.path ?? path,
14447
15271
  "/",
14448
15272
  entityId
14449
15273
  ] }) })
14450
15274
  ] }),
14451
15275
  children,
15276
+ initialEntityId && !entity && initialStatus !== "new" && /* @__PURE__ */ jsxRuntime.jsx(ui.Alert, { color: "info", size: "small", children: "This entity does not exist in the database" }),
14452
15277
  !Builder && !collection.hideIdFromForm && /* @__PURE__ */ jsxRuntime.jsx(CustomIdField, { customId: collection.customId, entityId, status, onChange: setEntityId, error: entityIdError, loading: customIdLoading, entity }),
14453
15278
  entityId && formContext && /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-12 flex flex-col gap-8", ref: formRef, children: [
14454
15279
  formFields(),
@@ -14462,7 +15287,7 @@
14462
15287
  if (!resolvedCollection || !path) {
14463
15288
  throw Error("INTERNAL: Collection and path must be defined in form context");
14464
15289
  }
14465
- const dialogActions = /* @__PURE__ */ jsxRuntime.jsx(EntityFormActionsComponent, { collection: resolvedCollection, path, entity, layout: forceActionsAtTheBottom ? "bottom" : "side", savingError, formex: formex$1, disabled: actionsDisabled, status, pluginActions, openEntityMode, showDefaultActions });
15290
+ const dialogActions = /* @__PURE__ */ jsxRuntime.jsx(EntityFormActionsComponent, { collection: resolvedCollection, path, fullPath: path, fullIdPath, entity, layout: forceActionsAtTheBottom ? "bottom" : "side", savingError, formex: formex$1, disabled: actionsDisabled, status, pluginActions, openEntityMode, showDefaultActions, navigateBack, formContext });
14466
15291
  return /* @__PURE__ */ jsxRuntime.jsx(formex.Formex, { value: formex$1, children: /* @__PURE__ */ jsxRuntime.jsxs("form", { onSubmit: formex$1.handleSubmit, onReset: () => formex$1.resetForm({
14467
15292
  values: getInitialEntityValues(authController, collection, path, status, entity, customizationController.propertyConfigs)
14468
15293
  }), noValidate: true, className: ui.cls("flex-1 flex flex-row w-full overflow-y-auto justify-center", className), children: [
@@ -15152,7 +15977,7 @@
15152
15977
  const t1 = size === "large" ? "min-w-[220px] min-h-[220px] max-w-[220px]" : "min-w-[118px] min-h-[118px] max-w-[118px]";
15153
15978
  let t2;
15154
15979
  if ($[0] !== className || $[1] !== t1) {
15155
- t2 = ui.cls(ui.paperMixin, "relative m-4 border-box flex items-center justify-center", t1, className);
15980
+ t2 = ui.cls(ui.paperMixin, "relative border-box flex items-center justify-center", t1, className);
15156
15981
  $[0] = className;
15157
15982
  $[1] = t1;
15158
15983
  $[2] = t2;
@@ -15317,7 +16142,7 @@
15317
16142
  const resolvedProperty = t6;
15318
16143
  let t7;
15319
16144
  if ($[21] !== minimalistView || $[22] !== property || $[23] !== propertyKey) {
15320
- t7 = !minimalistView && /* @__PURE__ */ jsxRuntime.jsx(LabelWithIconAndTooltip, { propertyKey, icon: getIconForProperty(property, "small"), required: property.validation?.required, title: property.name, className: "h-8text-text-secondary dark:text-text-secondary-dark ml-3.5" });
16145
+ t7 = !minimalistView && /* @__PURE__ */ jsxRuntime.jsx(LabelWithIconAndTooltip, { propertyKey, icon: getIconForProperty(property, "small"), required: property.validation?.required, title: property.name, className: "h-8 text-text-secondary dark:text-text-secondary-dark ml-3.5" });
15321
16146
  $[21] = minimalistView;
15322
16147
  $[22] = property;
15323
16148
  $[23] = propertyKey;
@@ -15375,7 +16200,7 @@
15375
16200
  return t12;
15376
16201
  }
15377
16202
  function SortableStorageItem(t0) {
15378
- const $ = reactCompilerRuntime.c(35);
16203
+ const $ = reactCompilerRuntime.c(34);
15379
16204
  const {
15380
16205
  id,
15381
16206
  entry,
@@ -15413,98 +16238,95 @@
15413
16238
  t2 = $[3];
15414
16239
  }
15415
16240
  const t3 = isDragging ? 100 : void 0;
15416
- const t4 = isDragging ? 0.8 : 1;
15417
- let t5;
15418
- if ($[4] !== t2 || $[5] !== t3 || $[6] !== t4 || $[7] !== transition) {
15419
- t5 = {
16241
+ let t4;
16242
+ if ($[4] !== t2 || $[5] !== t3 || $[6] !== transition) {
16243
+ t4 = {
15420
16244
  transform: t2,
15421
16245
  transition,
15422
- zIndex: t3,
15423
- opacity: t4
16246
+ zIndex: t3
15424
16247
  };
15425
16248
  $[4] = t2;
15426
16249
  $[5] = t3;
15427
- $[6] = t4;
15428
- $[7] = transition;
15429
- $[8] = t5;
16250
+ $[6] = transition;
16251
+ $[7] = t4;
15430
16252
  } else {
15431
- t5 = $[8];
16253
+ t4 = $[7];
15432
16254
  }
15433
- const style = t5;
16255
+ const style = t4;
15434
16256
  const getImageSizeNumber = _temp$a;
15435
16257
  let child;
15436
16258
  if (entry.storagePathOrDownloadUrl) {
15437
- const t62 = `storage_preview_${entry.storagePathOrDownloadUrl}`;
15438
- let t72;
15439
- if ($[9] !== entry.storagePathOrDownloadUrl || $[10] !== onClear) {
15440
- t72 = () => onClear(entry.storagePathOrDownloadUrl);
15441
- $[9] = entry.storagePathOrDownloadUrl;
15442
- $[10] = onClear;
15443
- $[11] = t72;
16259
+ const t52 = `storage_preview_${entry.storagePathOrDownloadUrl}`;
16260
+ let t62;
16261
+ if ($[8] !== entry.storagePathOrDownloadUrl || $[9] !== onClear) {
16262
+ t62 = () => onClear(entry.storagePathOrDownloadUrl);
16263
+ $[8] = entry.storagePathOrDownloadUrl;
16264
+ $[9] = onClear;
16265
+ $[10] = t62;
15444
16266
  } else {
15445
- t72 = $[11];
16267
+ t62 = $[10];
15446
16268
  }
15447
- let t8;
15448
- if ($[12] !== disabled || $[13] !== entry.size || $[14] !== entry.storagePathOrDownloadUrl || $[15] !== property || $[16] !== t62 || $[17] !== t72) {
15449
- t8 = /* @__PURE__ */ jsxRuntime.jsx(StorageItemPreview, { name: t62, property, disabled, value: entry.storagePathOrDownloadUrl, onRemove: t72, size: entry.size });
15450
- $[12] = disabled;
15451
- $[13] = entry.size;
15452
- $[14] = entry.storagePathOrDownloadUrl;
15453
- $[15] = property;
16269
+ let t7;
16270
+ if ($[11] !== disabled || $[12] !== entry.size || $[13] !== entry.storagePathOrDownloadUrl || $[14] !== property || $[15] !== t52 || $[16] !== t62) {
16271
+ t7 = /* @__PURE__ */ jsxRuntime.jsx(StorageItemPreview, { name: t52, property, disabled, value: entry.storagePathOrDownloadUrl, onRemove: t62, size: entry.size });
16272
+ $[11] = disabled;
16273
+ $[12] = entry.size;
16274
+ $[13] = entry.storagePathOrDownloadUrl;
16275
+ $[14] = property;
16276
+ $[15] = t52;
15454
16277
  $[16] = t62;
15455
- $[17] = t72;
15456
- $[18] = t8;
16278
+ $[17] = t7;
15457
16279
  } else {
15458
- t8 = $[18];
16280
+ t7 = $[17];
15459
16281
  }
15460
- child = t8;
16282
+ child = t7;
15461
16283
  } else {
15462
16284
  if (entry.file) {
15463
- let t62;
15464
- if ($[19] !== entry.file || $[20] !== storagePathBuilder) {
15465
- t62 = storagePathBuilder(entry.file);
15466
- $[19] = entry.file;
15467
- $[20] = storagePathBuilder;
15468
- $[21] = t62;
16285
+ let t52;
16286
+ if ($[18] !== entry.file || $[19] !== storagePathBuilder) {
16287
+ t52 = storagePathBuilder(entry.file);
16288
+ $[18] = entry.file;
16289
+ $[19] = storagePathBuilder;
16290
+ $[20] = t52;
15469
16291
  } else {
15470
- t62 = $[21];
16292
+ t52 = $[20];
15471
16293
  }
15472
- const t72 = getImageSizeNumber(entry.size);
15473
- let t8;
15474
- if ($[22] !== entry || $[23] !== metadata || $[24] !== onFileUploadComplete || $[25] !== t62 || $[26] !== t72) {
15475
- t8 = /* @__PURE__ */ jsxRuntime.jsx(StorageUploadProgress, { entry, metadata, storagePath: t62, onFileUploadComplete, imageSize: t72, simple: false });
15476
- $[22] = entry;
15477
- $[23] = metadata;
15478
- $[24] = onFileUploadComplete;
16294
+ const t62 = getImageSizeNumber(entry.size);
16295
+ let t7;
16296
+ if ($[21] !== entry || $[22] !== metadata || $[23] !== onFileUploadComplete || $[24] !== t52 || $[25] !== t62) {
16297
+ t7 = /* @__PURE__ */ jsxRuntime.jsx(StorageUploadProgress, { entry, metadata, storagePath: t52, onFileUploadComplete, imageSize: t62, simple: false });
16298
+ $[21] = entry;
16299
+ $[22] = metadata;
16300
+ $[23] = onFileUploadComplete;
16301
+ $[24] = t52;
15479
16302
  $[25] = t62;
15480
- $[26] = t72;
15481
- $[27] = t8;
16303
+ $[26] = t7;
15482
16304
  } else {
15483
- t8 = $[27];
16305
+ t7 = $[26];
15484
16306
  }
15485
- child = t8;
16307
+ child = t7;
15486
16308
  }
15487
16309
  }
15488
- let t6;
15489
- if ($[28] === Symbol.for("react.memo_cache_sentinel")) {
15490
- t6 = ui.cls("rounded-md m-1");
15491
- $[28] = t6;
16310
+ let t5;
16311
+ if ($[27] === Symbol.for("react.memo_cache_sentinel")) {
16312
+ t5 = ui.cls("rounded-md m-1");
16313
+ $[27] = t5;
15492
16314
  } else {
15493
- t6 = $[28];
16315
+ t5 = $[27];
15494
16316
  }
15495
- let t7;
15496
- if ($[29] !== attributes || $[30] !== child || $[31] !== listeners2 || $[32] !== setNodeRef || $[33] !== style) {
15497
- t7 = /* @__PURE__ */ jsxRuntime.jsx("div", { ref: setNodeRef, style, ...attributes, ...listeners2, className: t6, tabIndex: -1, children: child });
15498
- $[29] = attributes;
15499
- $[30] = child;
15500
- $[31] = listeners2;
15501
- $[32] = setNodeRef;
15502
- $[33] = style;
15503
- $[34] = t7;
16317
+ let t6;
16318
+ if ($[28] !== attributes || $[29] !== child || $[30] !== listeners2 || $[31] !== setNodeRef || $[32] !== style) {
16319
+ t6 = /* @__PURE__ */ jsxRuntime.jsx("div", { ref: setNodeRef, style, ...attributes, ...listeners2, className: t5, tabIndex: -1, children: child });
16320
+ $[28] = attributes;
16321
+ $[29] = child;
16322
+ $[30] = listeners2;
16323
+ $[31] = setNodeRef;
16324
+ $[32] = style;
16325
+ $[33] = t6;
15504
16326
  } else {
15505
- t7 = $[34];
16327
+ t6 = $[33];
15506
16328
  }
15507
- return t7;
16329
+ return t6;
15508
16330
  }
15509
16331
  function _temp$a(previewSize) {
15510
16332
  switch (previewSize) {
@@ -15523,7 +16345,7 @@
15523
16345
  }
15524
16346
  }
15525
16347
  function FileDropComponent(t0) {
15526
- const $ = reactCompilerRuntime.c(63);
16348
+ const $ = reactCompilerRuntime.c(61);
15527
16349
  const {
15528
16350
  storage,
15529
16351
  disabled,
@@ -15614,7 +16436,7 @@
15614
16436
  }
15615
16437
  const t6 = disabled ? ui.fieldBackgroundDisabledMixin : ui.fieldBackgroundHoverMixin;
15616
16438
  const t7 = disabled ? "text-surface-accent-600 dark:text-surface-accent-500" : "";
15617
- const t8 = multipleFilesSupported && internalValue.length === 0 && "flex";
16439
+ const t8 = multipleFilesSupported && internalValue.length ? "" : "flex";
15618
16440
  const t9 = !isDragActive;
15619
16441
  const t10 = disabled || isDndItemDragging;
15620
16442
  let t11;
@@ -15638,107 +16460,103 @@
15638
16460
  } else {
15639
16461
  t11 = $[21];
15640
16462
  }
15641
- const t12 = multipleFilesSupported && internalValue.length ? "flex-row overflow-x-auto" : "flex-col";
15642
- const t13 = internalValue.length === 0 && "min-h-[250px] justify-center";
15643
- const t14 = multipleFilesSupported && internalValue.length > 0 && "min-h-[180px]";
15644
- const t15 = !multipleFilesSupported && internalValue.length > 0 && "min-h-[250px]";
15645
- let t16;
15646
- if ($[22] !== t12 || $[23] !== t13 || $[24] !== t14 || $[25] !== t15) {
15647
- t16 = ui.cls("flex items-center p-1 no-scrollbar", t12, t13, t14, t15);
16463
+ const t12 = multipleFilesSupported && internalValue.length ? "overflow-auto" : "";
16464
+ const t13 = multipleFilesSupported && internalValue.length ? "min-h-[180px]" : "min-h-[250px]";
16465
+ let t14;
16466
+ if ($[22] !== t12 || $[23] !== t13) {
16467
+ t14 = ui.cls("flex items-center p-1 px-4 no-scrollbar", t12, t13);
15648
16468
  $[22] = t12;
15649
16469
  $[23] = t13;
15650
16470
  $[24] = t14;
15651
- $[25] = t15;
15652
- $[26] = t16;
15653
16471
  } else {
15654
- t16 = $[26];
16472
+ t14 = $[24];
15655
16473
  }
15656
- let t17;
15657
- if ($[27] !== getInputProps) {
15658
- t17 = getInputProps();
15659
- $[27] = getInputProps;
15660
- $[28] = t17;
16474
+ let t15;
16475
+ if ($[25] !== getInputProps) {
16476
+ t15 = getInputProps();
16477
+ $[25] = getInputProps;
16478
+ $[26] = t15;
15661
16479
  } else {
15662
- t17 = $[28];
16480
+ t15 = $[26];
15663
16481
  }
15664
- let t18;
15665
- if ($[29] !== autoFocus || $[30] !== t17) {
15666
- t18 = /* @__PURE__ */ jsxRuntime.jsx("input", { autoFocus, ...t17 });
15667
- $[29] = autoFocus;
15668
- $[30] = t17;
15669
- $[31] = t18;
16482
+ let t16;
16483
+ if ($[27] !== autoFocus || $[28] !== t15) {
16484
+ t16 = /* @__PURE__ */ jsxRuntime.jsx("input", { autoFocus, ...t15 });
16485
+ $[27] = autoFocus;
16486
+ $[28] = t15;
16487
+ $[29] = t16;
15670
16488
  } else {
15671
- t18 = $[31];
16489
+ t16 = $[29];
15672
16490
  }
15673
- let t19;
15674
- if ($[32] !== disabled || $[33] !== internalValue || $[34] !== metadata || $[35] !== multipleFilesSupported || $[36] !== name || $[37] !== onClear || $[38] !== onFileUploadComplete || $[39] !== property || $[40] !== storagePathBuilder) {
15675
- let t202;
15676
- if ($[42] !== disabled || $[43] !== metadata || $[44] !== multipleFilesSupported || $[45] !== name || $[46] !== onClear || $[47] !== onFileUploadComplete || $[48] !== property || $[49] !== storagePathBuilder) {
15677
- t202 = (entry) => /* @__PURE__ */ jsxRuntime.jsx(SortableStorageItem, { id: entry.id, entry, property, name, metadata, storagePathBuilder, onFileUploadComplete, onClear, disabled, isSortable: multipleFilesSupported }, entry.id);
15678
- $[42] = disabled;
15679
- $[43] = metadata;
15680
- $[44] = multipleFilesSupported;
15681
- $[45] = name;
15682
- $[46] = onClear;
15683
- $[47] = onFileUploadComplete;
15684
- $[48] = property;
15685
- $[49] = storagePathBuilder;
15686
- $[50] = t202;
16491
+ let t17;
16492
+ if ($[30] !== disabled || $[31] !== internalValue || $[32] !== metadata || $[33] !== multipleFilesSupported || $[34] !== name || $[35] !== onClear || $[36] !== onFileUploadComplete || $[37] !== property || $[38] !== storagePathBuilder) {
16493
+ let t182;
16494
+ if ($[40] !== disabled || $[41] !== metadata || $[42] !== multipleFilesSupported || $[43] !== name || $[44] !== onClear || $[45] !== onFileUploadComplete || $[46] !== property || $[47] !== storagePathBuilder) {
16495
+ t182 = (entry) => /* @__PURE__ */ jsxRuntime.jsx(SortableStorageItem, { id: entry.id, entry, property, name, metadata, storagePathBuilder, onFileUploadComplete, onClear, disabled, isSortable: multipleFilesSupported }, entry.id);
16496
+ $[40] = disabled;
16497
+ $[41] = metadata;
16498
+ $[42] = multipleFilesSupported;
16499
+ $[43] = name;
16500
+ $[44] = onClear;
16501
+ $[45] = onFileUploadComplete;
16502
+ $[46] = property;
16503
+ $[47] = storagePathBuilder;
16504
+ $[48] = t182;
15687
16505
  } else {
15688
- t202 = $[50];
15689
- }
15690
- t19 = internalValue.map(t202);
15691
- $[32] = disabled;
15692
- $[33] = internalValue;
15693
- $[34] = metadata;
15694
- $[35] = multipleFilesSupported;
15695
- $[36] = name;
15696
- $[37] = onClear;
15697
- $[38] = onFileUploadComplete;
15698
- $[39] = property;
15699
- $[40] = storagePathBuilder;
15700
- $[41] = t19;
15701
- } else {
15702
- t19 = $[41];
16506
+ t182 = $[48];
16507
+ }
16508
+ t17 = internalValue.map(t182);
16509
+ $[30] = disabled;
16510
+ $[31] = internalValue;
16511
+ $[32] = metadata;
16512
+ $[33] = multipleFilesSupported;
16513
+ $[34] = name;
16514
+ $[35] = onClear;
16515
+ $[36] = onFileUploadComplete;
16516
+ $[37] = property;
16517
+ $[38] = storagePathBuilder;
16518
+ $[39] = t17;
16519
+ } else {
16520
+ t17 = $[39];
15703
16521
  }
15704
- let t20;
15705
- if ($[51] !== t16 || $[52] !== t18 || $[53] !== t19) {
15706
- t20 = /* @__PURE__ */ jsxRuntime.jsxs("div", { className: t16, children: [
15707
- t18,
15708
- t19
16522
+ let t18;
16523
+ if ($[49] !== t14 || $[50] !== t16 || $[51] !== t17) {
16524
+ t18 = /* @__PURE__ */ jsxRuntime.jsxs("div", { className: t14, children: [
16525
+ t16,
16526
+ t17
15709
16527
  ] });
15710
- $[51] = t16;
16528
+ $[49] = t14;
16529
+ $[50] = t16;
16530
+ $[51] = t17;
15711
16531
  $[52] = t18;
15712
- $[53] = t19;
15713
- $[54] = t20;
15714
16532
  } else {
15715
- t20 = $[54];
16533
+ t18 = $[52];
15716
16534
  }
15717
- const t21 = disabled ? "text-surface-accent-600 dark:text-surface-accent-500" : "";
15718
- let t22;
15719
- if ($[55] !== helpText || $[56] !== t21) {
15720
- t22 = /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-grow min-h-[38px] box-border m-2 text-center", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Typography, { align: "center", variant: "label", className: t21, children: helpText }) });
15721
- $[55] = helpText;
15722
- $[56] = t21;
15723
- $[57] = t22;
16535
+ const t19 = disabled ? "text-surface-accent-600 dark:text-surface-accent-500" : "";
16536
+ let t20;
16537
+ if ($[53] !== helpText || $[54] !== t19) {
16538
+ t20 = /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-grow min-h-[38px] box-border m-2 text-center", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Typography, { align: "center", variant: "label", className: t19, children: helpText }) });
16539
+ $[53] = helpText;
16540
+ $[54] = t19;
16541
+ $[55] = t20;
15724
16542
  } else {
15725
- t22 = $[57];
16543
+ t20 = $[55];
15726
16544
  }
15727
- let t23;
15728
- if ($[58] !== t11 || $[59] !== t20 || $[60] !== t22 || $[61] !== t5) {
15729
- t23 = /* @__PURE__ */ jsxRuntime.jsxs("div", { ...t5, className: t11, children: [
15730
- t20,
15731
- t22
16545
+ let t21;
16546
+ if ($[56] !== t11 || $[57] !== t18 || $[58] !== t20 || $[59] !== t5) {
16547
+ t21 = /* @__PURE__ */ jsxRuntime.jsxs("div", { ...t5, className: t11, children: [
16548
+ t18,
16549
+ t20
15732
16550
  ] });
15733
- $[58] = t11;
15734
- $[59] = t20;
15735
- $[60] = t22;
15736
- $[61] = t5;
15737
- $[62] = t23;
16551
+ $[56] = t11;
16552
+ $[57] = t18;
16553
+ $[58] = t20;
16554
+ $[59] = t5;
16555
+ $[60] = t21;
15738
16556
  } else {
15739
- t23 = $[62];
16557
+ t21 = $[60];
15740
16558
  }
15741
- return t23;
16559
+ return t21;
15742
16560
  }
15743
16561
  function _temp2$4(acc, ext) {
15744
16562
  return {
@@ -16530,6 +17348,92 @@
16530
17348
  /* @__PURE__ */ jsxRuntime.jsx(FieldHelperText, { includeDescription, showError, error, disabled, property })
16531
17349
  ] });
16532
17350
  }
17351
+ function ReferenceAsStringFieldBinding(props) {
17352
+ const $ = reactCompilerRuntime.c(4);
17353
+ if (typeof props.property.reference?.path !== "string") {
17354
+ let t02;
17355
+ if ($[0] !== props) {
17356
+ t02 = /* @__PURE__ */ jsxRuntime.jsx(ReadOnlyFieldBinding, { ...props });
17357
+ $[0] = props;
17358
+ $[1] = t02;
17359
+ } else {
17360
+ t02 = $[1];
17361
+ }
17362
+ return t02;
17363
+ }
17364
+ let t0;
17365
+ if ($[2] !== props) {
17366
+ t0 = /* @__PURE__ */ jsxRuntime.jsx(ReferenceAsStringFieldBindingInternal, { ...props });
17367
+ $[2] = props;
17368
+ $[3] = t0;
17369
+ } else {
17370
+ t0 = $[3];
17371
+ }
17372
+ return t0;
17373
+ }
17374
+ function ReferenceAsStringFieldBindingInternal({
17375
+ propertyKey,
17376
+ value,
17377
+ setValue,
17378
+ error,
17379
+ showError,
17380
+ isSubmitting,
17381
+ disabled,
17382
+ minimalistView,
17383
+ property,
17384
+ includeDescription,
17385
+ size = "medium"
17386
+ }) {
17387
+ if (!property.reference?.path) {
17388
+ throw new Error("Property path is required for ReferenceAsStringFieldBinding");
17389
+ }
17390
+ useClearRestoreValue({
17391
+ property,
17392
+ value,
17393
+ setValue
17394
+ });
17395
+ const navigationController = useNavigationController();
17396
+ const path = property.reference.path;
17397
+ const collection = React.useMemo(() => {
17398
+ return path ? navigationController.getCollection(path) : void 0;
17399
+ }, [path]);
17400
+ const referenceValue = React.useMemo(() => {
17401
+ if (value && path) {
17402
+ return new EntityReference(value, path);
17403
+ }
17404
+ return void 0;
17405
+ }, [value, path]);
17406
+ if (!collection) {
17407
+ throw Error(`Couldn't find the corresponding collection for the path: ${path}`);
17408
+ }
17409
+ const onSingleEntitySelected = React.useCallback((e) => {
17410
+ setValue(e ? e.id : null);
17411
+ }, [setValue]);
17412
+ const referenceDialogController = useReferenceDialog({
17413
+ multiselect: false,
17414
+ path,
17415
+ collection,
17416
+ onSingleEntitySelected,
17417
+ selectedEntityIds: value ? [value] : void 0,
17418
+ forceFilter: property.reference.forceFilter
17419
+ });
17420
+ const onEntryClick = (e_0) => {
17421
+ e_0.preventDefault();
17422
+ referenceDialogController.open();
17423
+ };
17424
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
17425
+ !minimalistView && /* @__PURE__ */ jsxRuntime.jsx(LabelWithIconAndTooltip, { propertyKey, icon: getIconForProperty(property, "small"), required: property.validation?.required, title: property.name, className: "h-8 text-text-secondary dark:text-text-secondary-dark ml-3.5" }),
17426
+ !collection && /* @__PURE__ */ jsxRuntime.jsx(ErrorView, { error: "The specified collection does not exist. Check console" }),
17427
+ collection && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
17428
+ referenceValue && /* @__PURE__ */ jsxRuntime.jsx(ReferencePreview, { disabled: !path, previewProperties: property.reference?.previewProperties, hover: !disabled, size, onClick: disabled || isSubmitting ? void 0 : onEntryClick, reference: referenceValue, includeEntityLink: property.reference?.includeEntityLink, includeId: property.reference?.includeId }),
17429
+ !value && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "justify-center text-left", children: /* @__PURE__ */ jsxRuntime.jsxs(EntityPreviewContainer, { className: ui.cls("px-6 h-16 text-sm font-medium flex items-center gap-6", disabled || isSubmitting ? "text-surface-accent-500" : "cursor-pointer text-surface-accent-700 dark:text-surface-accent-300 hover:bg-surface-accent-50 dark:hover:bg-surface-800 group-hover:bg-surface-accent-50 dark:group-hover:bg-surface-800"), onClick: onEntryClick, size: "medium", children: [
17430
+ /* @__PURE__ */ jsxRuntime.jsx(IconForView, { collectionOrView: collection, className: "text-surface-300 dark:text-surface-600" }),
17431
+ `Edit ${property.name}`.toUpperCase()
17432
+ ] }) })
17433
+ ] }),
17434
+ /* @__PURE__ */ jsxRuntime.jsx(FieldHelperText, { includeDescription, showError, error, disabled, property })
17435
+ ] });
17436
+ }
16533
17437
  const PropertyFieldBinding = React.memo(PropertyFieldBindingInternal, (a, b) => {
16534
17438
  if (a.propertyKey !== b.propertyKey) {
16535
17439
  return false;
@@ -17772,7 +18676,6 @@
17772
18676
  minimalistView: false,
17773
18677
  autoFocus: internalId === lastAddedId
17774
18678
  };
17775
- console.debug("Building entry for", index, fieldProps);
17776
18679
  return /* @__PURE__ */ jsxRuntime.jsx(ErrorBoundary, { children: /* @__PURE__ */ jsxRuntime.jsx(PropertyFieldBinding, { ...fieldProps, index }) });
17777
18680
  };
17778
18681
  $[4] = context;
@@ -18145,6 +19048,9 @@
18145
19048
  const [fieldVersion, setFieldVersion] = React.useState(0);
18146
19049
  const internalValue = React.useRef(value);
18147
19050
  const onContentChange = React.useCallback((content) => {
19051
+ if (content === value || value === null && content === "") {
19052
+ return;
19053
+ }
18148
19054
  internalValue.current = content;
18149
19055
  setValue(content);
18150
19056
  }, [setValue]);
@@ -19144,11 +20050,12 @@
19144
20050
  frozen
19145
20051
  }) => {
19146
20052
  const isSelected = Boolean(usedSelectionController.selectedEntities.find((e_1) => e_1.id == entity_6.id && e_1.path == entity_6.path));
20053
+ const customEntityActions_0 = (collection.entityActions ?? []).map((action) => resolveEntityAction(action, customizationController.entityActions)).filter(Boolean);
19147
20054
  const actions_0 = getActionsForEntity({
19148
20055
  entity: entity_6,
19149
- customEntityActions: collection.entityActions
20056
+ customEntityActions: customEntityActions_0
19150
20057
  });
19151
- return /* @__PURE__ */ jsxRuntime.jsx(EntityCollectionRowActions, { entity: entity_6, width: width_0, frozen, isSelected, selectionEnabled, size: size_0, highlightEntity: setHighlightedEntity, unhighlightEntity: unselectNavigatedEntity, collection, fullPath: fullIdPath ?? fullPath, actions: actions_0, hideId: collection?.hideIdFromCollection, onCollectionChange: updateLastDeleteTimestamp, selectionController: usedSelectionController, openEntityMode });
20058
+ 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 });
19152
20059
  }, [updateLastDeleteTimestamp, usedSelectionController]);
19153
20060
  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: [
19154
20061
  /* @__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) => {
@@ -19506,7 +20413,7 @@
19506
20413
  }
19507
20414
  let t4;
19508
20415
  if ($[6] !== onCancel) {
19509
- t4 = /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "text", onClick: onCancel, autoFocus: true, children: "Cancel" });
20416
+ t4 = /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { color: "primary", variant: "text", onClick: onCancel, autoFocus: true, children: "Cancel" });
19510
20417
  $[6] = onCancel;
19511
20418
  $[7] = t4;
19512
20419
  } else {
@@ -19552,7 +20459,7 @@
19552
20459
  return t7;
19553
20460
  }
19554
20461
  function FireCMSLogo(t0) {
19555
- const $ = reactCompilerRuntime.c(9);
20462
+ const $ = reactCompilerRuntime.c(8);
19556
20463
  const {
19557
20464
  width,
19558
20465
  height,
@@ -19562,70 +20469,36 @@
19562
20469
  const t1 = width ?? "100%";
19563
20470
  const t2 = height ?? "100%";
19564
20471
  let t3;
20472
+ let t4;
20473
+ let t5;
19565
20474
  if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
19566
- t3 = /* @__PURE__ */ jsxRuntime.jsxs("radialGradient", { cx: "28.6213569%", cy: "43.1133328%", fx: "28.6213569%", fy: "43.1133328%", r: "71.5003456%", gradientTransform: "translate(0.286214,0.431133),rotate(3.343450),scale(1.000000,0.996175),translate(-0.286214,-0.431133)", id: "radialGradient-1", children: [
19567
- /* @__PURE__ */ jsxRuntime.jsx("stop", { stopColor: "#FF5B79", offset: "0%" }),
19568
- /* @__PURE__ */ jsxRuntime.jsx("stop", { stopColor: "#FA5574", offset: "28.0930803%" }),
19569
- /* @__PURE__ */ jsxRuntime.jsx("stop", { stopColor: "#EC4C51", offset: "44.7242531%" }),
19570
- /* @__PURE__ */ jsxRuntime.jsx("stop", { stopColor: "#9543C1", offset: "71.4578165%" }),
19571
- /* @__PURE__ */ jsxRuntime.jsx("stop", { stopColor: "#3857B3", offset: "100%" })
19572
- ] });
20475
+ t3 = /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "291.5", cy: "291.5", r: "291.5", fill: "#0070F4" });
20476
+ t4 = /* @__PURE__ */ jsxRuntime.jsx("ellipse", { cx: "292", cy: "291.5", rx: "173", ry: "173.5", fill: "#FF3773" });
20477
+ t5 = /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M465 291.5C465 268.847 460.525 246.416 451.831 225.487C443.137 204.558 430.394 185.542 414.329 169.524C398.265 153.506 379.194 140.8 358.204 132.131C337.215 123.462 314.719 119 292 119C269.281 119 246.785 123.462 225.796 132.131C204.806 140.8 185.735 153.506 169.671 169.524C153.606 185.542 140.863 204.558 132.169 225.487C123.475 246.416 119 268.847 119 291.5L292 291.5H465Z", fill: "#FFA400" });
19573
20478
  $[0] = t3;
19574
- } else {
19575
- t3 = $[0];
19576
- }
19577
- let t4;
19578
- if ($[1] === Symbol.for("react.memo_cache_sentinel")) {
19579
- t4 = /* @__PURE__ */ jsxRuntime.jsxs("radialGradient", { cx: "53.6205516%", cy: "47.2473036%", fx: "53.6205516%", fy: "47.2473036%", r: "50.8229649%", gradientTransform: "translate(0.536206,0.472473),rotate(90.000000),scale(1.000000,1.206631),translate(-0.536206,-0.472473)", id: "radialGradient-2", children: [
19580
- /* @__PURE__ */ jsxRuntime.jsx("stop", { stopColor: "#68294F", stopOpacity: "0", offset: "0%" }),
19581
- /* @__PURE__ */ jsxRuntime.jsx("stop", { stopColor: "#5E2548", stopOpacity: "0.04641108", offset: "75.3503173%" }),
19582
- /* @__PURE__ */ jsxRuntime.jsx("stop", { stopColor: "#0D060B", stopOpacity: "0.437431709", offset: "100%" })
19583
- ] });
19584
20479
  $[1] = t4;
19585
- } else {
19586
- t4 = $[1];
19587
- }
19588
- let t5;
19589
- if ($[2] === Symbol.for("react.memo_cache_sentinel")) {
19590
- t5 = /* @__PURE__ */ jsxRuntime.jsxs("defs", { children: [
19591
- t3,
19592
- t4,
19593
- /* @__PURE__ */ jsxRuntime.jsxs("radialGradient", { cx: "53.8605015%", cy: "48.1990423%", fx: "53.8605015%", fy: "48.1990423%", r: "59.9151549%", gradientTransform: "translate(0.538605,0.481990),rotate(180.000000),scale(1.000000,0.925027),translate(-0.538605,-0.481990)", id: "radialGradient-3", children: [
19594
- /* @__PURE__ */ jsxRuntime.jsx("stop", { stopColor: "#68294F", stopOpacity: "0", offset: "0%" }),
19595
- /* @__PURE__ */ jsxRuntime.jsx("stop", { stopColor: "#5E2548", stopOpacity: "0.04641108", offset: "84.0867343%" }),
19596
- /* @__PURE__ */ jsxRuntime.jsx("stop", { stopColor: "#FF0000", stopOpacity: "0.567324765", offset: "100%" })
19597
- ] })
19598
- ] });
19599
20480
  $[2] = t5;
19600
20481
  } else {
20482
+ t3 = $[0];
20483
+ t4 = $[1];
19601
20484
  t5 = $[2];
19602
20485
  }
19603
20486
  let t6;
19604
- if ($[3] === Symbol.for("react.memo_cache_sentinel")) {
19605
- t6 = /* @__PURE__ */ jsxRuntime.jsx("g", { id: "Page-1", stroke: "none", strokeWidth: "1", fill: "none", fillRule: "evenodd", children: /* @__PURE__ */ jsxRuntime.jsxs("g", { id: "firecms_logo", children: [
19606
- /* @__PURE__ */ jsxRuntime.jsx("circle", { fill: "url(#radialGradient-1)", cx: "299.5", cy: "299.5", r: "299.5" }),
19607
- /* @__PURE__ */ jsxRuntime.jsx("circle", { fill: "url(#radialGradient-2)", cx: "299.5", cy: "299.5", r: "299.5" }),
19608
- /* @__PURE__ */ jsxRuntime.jsx("circle", { fill: "url(#radialGradient-3)", cx: "299.5", cy: "299.5", r: "299.5" })
19609
- ] }) });
19610
- $[3] = t6;
19611
- } else {
19612
- t6 = $[3];
19613
- }
19614
- let t7;
19615
- if ($[4] !== className || $[5] !== style || $[6] !== t1 || $[7] !== t2) {
19616
- t7 = /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: t1, height: t2, viewBox: "0 0 599 599", version: "1.1", style, className, xmlns: "http://www.w3.org/2000/svg", children: [
19617
- t5,
19618
- t6
20487
+ if ($[3] !== className || $[4] !== style || $[5] !== t1 || $[6] !== t2) {
20488
+ t6 = /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: t1, height: t2, version: "1.1", style, className, viewBox: "0 0 583 583", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: [
20489
+ t3,
20490
+ t4,
20491
+ t5
19619
20492
  ] });
19620
- $[4] = className;
19621
- $[5] = style;
19622
- $[6] = t1;
19623
- $[7] = t2;
19624
- $[8] = t7;
20493
+ $[3] = className;
20494
+ $[4] = style;
20495
+ $[5] = t1;
20496
+ $[6] = t2;
20497
+ $[7] = t6;
19625
20498
  } else {
19626
- t7 = $[8];
20499
+ t6 = $[7];
19627
20500
  }
19628
- return t7;
20501
+ return t6;
19629
20502
  }
19630
20503
  const AppContext = React.createContext({
19631
20504
  hasDrawer: false,
@@ -20566,6 +21439,8 @@
20566
21439
  }
20567
21440
  const DEFAULT_BASE_PATH = "/";
20568
21441
  const DEFAULT_COLLECTION_PATH = "/c";
21442
+ const NAVIGATION_DEFAULT_GROUP_NAME = "Views";
21443
+ const NAVIGATION_ADMIN_GROUP_NAME = "Admin";
20569
21444
  function useBuildNavigationController(props) {
20570
21445
  const {
20571
21446
  basePath = DEFAULT_BASE_PATH,
@@ -20579,12 +21454,14 @@
20579
21454
  plugins,
20580
21455
  userConfigPersistence,
20581
21456
  dataSourceDelegate,
20582
- disabled
21457
+ disabled,
21458
+ navigationGroupMappings
20583
21459
  } = props;
20584
21460
  const navigate = reactRouterDom.useNavigate();
20585
21461
  const collectionsRef = React.useRef();
20586
21462
  const viewsRef = React.useRef();
20587
21463
  const adminViewsRef = React.useRef();
21464
+ const navigationEntriesOrderRef = React.useRef();
20588
21465
  const [initialised, setInitialised] = React.useState(false);
20589
21466
  const [topLevelNavigation, setTopLevelNavigation] = React.useState(void 0);
20590
21467
  const [navigationLoading, setNavigationLoading] = React.useState(true);
@@ -20595,80 +21472,127 @@
20595
21472
  const fullCollectionPath = cleanBasePath ? `/${cleanBasePath}/${cleanBaseCollectionPath}` : `/${cleanBaseCollectionPath}`;
20596
21473
  const buildCMSUrlPath = React.useCallback((path) => cleanBasePath ? `/${cleanBasePath}/${encodePath(path)}` : `/${encodePath(path)}`, [cleanBasePath]);
20597
21474
  const buildUrlCollectionPath = React.useCallback((path_0) => `${removeInitialAndTrailingSlashes(baseCollectionPath)}/${encodePath(path_0)}`, [baseCollectionPath]);
21475
+ const allPluginGroups = plugins?.flatMap((plugin) => plugin.homePage?.navigationEntries ? plugin.homePage.navigationEntries.map((e) => e.name) : []) ?? [];
21476
+ const pluginGroups = [...new Set(allPluginGroups)];
21477
+ const onNavigationEntriesOrderUpdate = React.useCallback((entries) => {
21478
+ if (!plugins) {
21479
+ return;
21480
+ }
21481
+ const filteredEntries = entries.filter((entry) => entry.entries.length > 0);
21482
+ if (plugins.some((plugin_1) => plugin_1.homePage?.onNavigationEntriesUpdate)) {
21483
+ plugins.forEach((plugin_0) => {
21484
+ if (plugin_0.homePage?.onNavigationEntriesUpdate) {
21485
+ plugin_0.homePage.onNavigationEntriesUpdate(filteredEntries);
21486
+ }
21487
+ });
21488
+ }
21489
+ }, [plugins]);
20598
21490
  const computeTopNavigation = React.useCallback((collections, views, adminViews, viewsOrder_0) => {
20599
- let navigationEntries = [...(collections ?? []).map((collection) => !collection.hideFromNavigation ? {
20600
- url: buildUrlCollectionPath(collection.id ?? collection.path),
20601
- type: "collection",
20602
- name: collection.name.trim(),
20603
- path: collection.id ?? collection.path,
20604
- collection,
20605
- description: collection.description?.trim(),
20606
- group: getGroup(collection)
20607
- } : void 0).filter(Boolean), ...(views ?? []).map((view) => !view.hideFromNavigation ? {
20608
- url: buildCMSUrlPath(Array.isArray(view.path) ? view.path[0] : view.path),
20609
- name: view.name.trim(),
20610
- type: "view",
20611
- path: view.path,
20612
- view,
20613
- description: view.description?.trim(),
20614
- group: getGroup(view)
20615
- } : void 0).filter(Boolean), ...(adminViews ?? []).map((view_0) => !view_0.hideFromNavigation ? {
20616
- url: buildCMSUrlPath(Array.isArray(view_0.path) ? view_0.path[0] : view_0.path),
20617
- name: view_0.name.trim(),
20618
- type: "admin",
20619
- path: view_0.path,
20620
- view: view_0,
20621
- description: view_0.description?.trim(),
20622
- group: "Admin"
20623
- } : void 0).filter(Boolean)];
20624
- navigationEntries = navigationEntries.sort((a, b) => {
20625
- if (a.group !== "Views" && a.group !== "Admin" && (b.group === "Views" || b.group === "Admin")) {
20626
- return -1;
20627
- }
20628
- if (b.group !== "Views" && b.group !== "Admin" && (a.group === "Views" || a.group === "Admin")) {
20629
- return 1;
20630
- }
20631
- if (a.group === "Admin" && b.group !== "Admin") {
20632
- return 1;
20633
- }
20634
- if (a.group !== "Admin" && b.group === "Admin") {
20635
- return -1;
20636
- }
20637
- if (a.group === "Views" && b.group !== "Views") {
20638
- return -1;
21491
+ const finalNavigationGroupMappings = computeNavigationGroups({
21492
+ navigationGroupMappings,
21493
+ collections,
21494
+ views,
21495
+ plugins
21496
+ });
21497
+ const allPluginNavigationEntries = finalNavigationGroupMappings.map((g) => g.entries).flat() ?? [];
21498
+ const navigationEntriesOrder = [...new Set(allPluginNavigationEntries)];
21499
+ let navigationEntries = [...(collections ?? []).reduce((acc, collection) => {
21500
+ if (collection.hideFromNavigation) return acc;
21501
+ const pathKey = collection.id ?? collection.path;
21502
+ let groupName = getGroup(collection);
21503
+ if (finalNavigationGroupMappings) {
21504
+ for (const pluginGroupDef of finalNavigationGroupMappings) {
21505
+ if (pluginGroupDef.entries.includes(pathKey)) {
21506
+ groupName = pluginGroupDef.name;
21507
+ break;
21508
+ }
21509
+ }
20639
21510
  }
20640
- if (a.group !== "Views" && b.group === "Views") {
20641
- return 1;
21511
+ acc.push({
21512
+ id: `collection:${pathKey}`,
21513
+ url: buildUrlCollectionPath(pathKey),
21514
+ type: "collection",
21515
+ name: collection.name.trim(),
21516
+ path: pathKey,
21517
+ collection,
21518
+ description: collection.description?.trim(),
21519
+ group: groupName ?? NAVIGATION_DEFAULT_GROUP_NAME
21520
+ });
21521
+ return acc;
21522
+ }, []), ...(views ?? []).reduce((acc_0, view) => {
21523
+ if (view.hideFromNavigation) return acc_0;
21524
+ const pathKey_0 = Array.isArray(view.path) ? view.path[0] : view.path;
21525
+ let groupName_0 = getGroup(view);
21526
+ if (finalNavigationGroupMappings) {
21527
+ for (const pluginGroupDef_0 of finalNavigationGroupMappings) {
21528
+ if (pluginGroupDef_0.entries.includes(pathKey_0)) {
21529
+ groupName_0 = pluginGroupDef_0.name;
21530
+ break;
21531
+ }
21532
+ }
20642
21533
  }
21534
+ acc_0.push({
21535
+ id: `view:${pathKey_0}`,
21536
+ url: buildCMSUrlPath(pathKey_0),
21537
+ name: view.name.trim(),
21538
+ type: "view",
21539
+ path: view.path,
21540
+ view,
21541
+ description: view.description?.trim(),
21542
+ group: groupName_0 ?? NAVIGATION_DEFAULT_GROUP_NAME
21543
+ });
21544
+ return acc_0;
21545
+ }, []), ...(adminViews ?? []).reduce((acc_1, view_0) => {
21546
+ if (view_0.hideFromNavigation) return acc_1;
21547
+ const pathKey_1 = Array.isArray(view_0.path) ? view_0.path[0] : view_0.path;
21548
+ const groupName_1 = NAVIGATION_ADMIN_GROUP_NAME;
21549
+ acc_1.push({
21550
+ id: `admin:${pathKey_1}`,
21551
+ url: buildCMSUrlPath(pathKey_1),
21552
+ name: view_0.name.trim(),
21553
+ type: "admin",
21554
+ path: view_0.path,
21555
+ view: view_0,
21556
+ description: view_0.description?.trim(),
21557
+ group: groupName_1
21558
+ });
21559
+ return acc_1;
21560
+ }, [])];
21561
+ const groupOrderValue = (groupName_2) => {
21562
+ if (groupName_2 === NAVIGATION_ADMIN_GROUP_NAME) return 1;
20643
21563
  return 0;
21564
+ };
21565
+ navigationEntries = navigationEntries.sort((a, b) => {
21566
+ return groupOrderValue(a.group) - groupOrderValue(b.group);
20644
21567
  });
20645
- if (viewsOrder_0) {
21568
+ const usedViewsOrder = viewsOrder_0 ?? navigationEntriesOrder;
21569
+ if (usedViewsOrder) {
20646
21570
  navigationEntries = navigationEntries.sort((a_0, b_0) => {
20647
- const aIndex = viewsOrder_0.indexOf(a_0.path);
20648
- const bIndex = viewsOrder_0.indexOf(b_0.path);
20649
- if (aIndex === -1 && bIndex === -1) {
20650
- return 0;
20651
- }
20652
- if (aIndex === -1) {
20653
- return 1;
20654
- }
20655
- if (bIndex === -1) {
20656
- return -1;
20657
- }
21571
+ const getSortPath = (navEntry) => typeof navEntry.path === "string" ? navEntry.path : navEntry.path[0];
21572
+ const aIndex = usedViewsOrder.indexOf(getSortPath(a_0));
21573
+ const bIndex = usedViewsOrder.indexOf(getSortPath(b_0));
21574
+ if (aIndex === -1 && bIndex === -1) return 0;
21575
+ if (aIndex === -1) return 1;
21576
+ if (bIndex === -1) return -1;
20658
21577
  return aIndex - bIndex;
20659
21578
  });
20660
21579
  }
20661
- const groups = Object.values(navigationEntries).map((e) => e.group).filter(Boolean).filter((value, index, array) => array.indexOf(value) === index);
21580
+ const collectedGroupsFromEntries = navigationEntries.map((e_0) => e_0.group).filter(Boolean);
21581
+ const allDefinedGroups = [...pluginGroups, ...collectedGroupsFromEntries];
21582
+ const uniqueGroups = [...new Set(allDefinedGroups)].sort((a_1, b_1) => groupOrderValue(a_1) - groupOrderValue(b_1));
20662
21583
  return {
21584
+ allowDragAndDrop: plugins?.some((plugin_2) => plugin_2.homePage?.allowDragAndDrop) ?? false,
20663
21585
  navigationEntries,
20664
- groups
21586
+ groups: uniqueGroups,
21587
+ onNavigationEntriesUpdate: onNavigationEntriesOrderUpdate
20665
21588
  };
20666
- }, [buildCMSUrlPath, buildUrlCollectionPath]);
21589
+ }, [navigationGroupMappings, buildCMSUrlPath, buildUrlCollectionPath, pluginGroups, onNavigationEntriesOrderUpdate]);
20667
21590
  const refreshNavigation = React.useCallback(async () => {
20668
21591
  if (disabled || authController.initialLoading) return;
20669
21592
  console.debug("Refreshing navigation");
20670
21593
  try {
20671
21594
  const [resolvedCollections = [], resolvedViews, resolvedAdminViews = []] = await Promise.all([resolveCollections(collectionsProp, collectionPermissions, authController, dataSourceDelegate, plugins), resolveCMSViews(viewsProp, authController, dataSourceDelegate), resolveCMSViews(adminViewsProp, authController, dataSourceDelegate)]);
21595
+ const computedTopLevelNav = computeTopNavigation(resolvedCollections, resolvedViews, resolvedAdminViews, viewsOrder);
20672
21596
  let shouldUpdateTopLevelNav = false;
20673
21597
  if (!areCollectionListsEqual(collectionsRef.current ?? [], resolvedCollections)) {
20674
21598
  collectionsRef.current = resolvedCollections;
@@ -20687,13 +21611,17 @@
20687
21611
  adminViewsRef.current = resolvedAdminViews;
20688
21612
  shouldUpdateTopLevelNav = true;
20689
21613
  }
20690
- const computedTopLevelNav = computeTopNavigation(resolvedCollections, resolvedViews, resolvedAdminViews, viewsOrder);
21614
+ const navigationEntriesOrder_0 = computedTopLevelNav.navigationEntries.map((e_2) => e_2.id);
21615
+ if (!equal(navigationEntriesOrderRef.current, navigationEntriesOrder_0)) {
21616
+ navigationEntriesOrderRef.current = navigationEntriesOrder_0;
21617
+ shouldUpdateTopLevelNav = true;
21618
+ }
20691
21619
  if (shouldUpdateTopLevelNav && !equal(topLevelNavigation, computedTopLevelNav)) {
20692
21620
  setTopLevelNavigation(computedTopLevelNav);
20693
21621
  }
20694
- } catch (e_0) {
20695
- console.error(e_0);
20696
- setNavigationLoadingError(e_0);
21622
+ } catch (e_1) {
21623
+ console.error(e_1);
21624
+ setNavigationLoadingError(e_1);
20697
21625
  }
20698
21626
  if (navigationLoading) setNavigationLoading(false);
20699
21627
  if (!initialised) setInitialised(true);
@@ -20893,9 +21821,9 @@
20893
21821
  function getGroup(collectionOrView) {
20894
21822
  const trimmed = collectionOrView.group?.trim();
20895
21823
  if (!trimmed || trimmed === "") {
20896
- return "Views";
21824
+ return NAVIGATION_DEFAULT_GROUP_NAME;
20897
21825
  }
20898
- return trimmed ?? "Views";
21826
+ return trimmed ?? NAVIGATION_DEFAULT_GROUP_NAME;
20899
21827
  }
20900
21828
  function areCollectionListsEqual(a, b) {
20901
21829
  if (a.length !== b.length) {
@@ -20921,6 +21849,58 @@
20921
21849
  }
20922
21850
  return equal(removeFunctions(restA), removeFunctions(restB));
20923
21851
  }
21852
+ function computeNavigationGroups({
21853
+ navigationGroupMappings,
21854
+ collections,
21855
+ views,
21856
+ plugins
21857
+ }) {
21858
+ let result = navigationGroupMappings;
21859
+ result = plugins ? plugins?.reduce((acc, plugin) => {
21860
+ if (plugin.homePage?.navigationEntries) {
21861
+ plugin.homePage.navigationEntries.forEach((entry) => {
21862
+ const {
21863
+ name,
21864
+ entries
21865
+ } = entry;
21866
+ const existingGroup = acc.find((entry2) => entry2.name === name);
21867
+ if (existingGroup) {
21868
+ existingGroup.entries.push(...entries);
21869
+ } else {
21870
+ acc.push({
21871
+ name,
21872
+ entries: [...entries]
21873
+ });
21874
+ }
21875
+ });
21876
+ }
21877
+ return acc;
21878
+ }, [...result ?? []]) : result;
21879
+ if (!result) {
21880
+ result = [];
21881
+ const groupMap = {};
21882
+ (collections ?? []).forEach((collection) => {
21883
+ const name = getGroup(collection);
21884
+ const entry = collection.id ?? collection.path;
21885
+ if (!groupMap[name]) groupMap[name] = [];
21886
+ groupMap[name].push(entry);
21887
+ });
21888
+ (views ?? []).forEach((view) => {
21889
+ const name = getGroup(view);
21890
+ const entry = Array.isArray(view.path) ? view.path[0] : view.path;
21891
+ if (!groupMap[name]) groupMap[name] = [];
21892
+ groupMap[name].push(entry);
21893
+ });
21894
+ result = Object.entries(groupMap).map(([name, entries]) => ({
21895
+ name,
21896
+ entries
21897
+ }));
21898
+ }
21899
+ result.forEach((group) => {
21900
+ group.entries = [...new Set(group.entries)];
21901
+ });
21902
+ return result;
21903
+ }
20924
21904
  function useBuildLocalConfigurationPersistence() {
20925
21905
  const $ = reactCompilerRuntime.c(15);
20926
21906
  let t0;
@@ -21336,7 +22316,7 @@
21336
22316
  }
21337
22317
  let t5;
21338
22318
  if ($[7] !== handleCancel) {
21339
- t5 = /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "text", onClick: handleCancel, autoFocus: true, children: " Cancel " });
22319
+ t5 = /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "text", color: "primary", onClick: handleCancel, autoFocus: true, children: " Cancel " });
21340
22320
  $[7] = handleCancel;
21341
22321
  $[8] = t5;
21342
22322
  } else {
@@ -21344,7 +22324,7 @@
21344
22324
  }
21345
22325
  let t6;
21346
22326
  if ($[9] !== handleOk) {
21347
- t6 = /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { onClick: handleOk, children: " Ok " });
22327
+ t6 = /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { color: "primary", onClick: handleOk, children: " Ok " });
21348
22328
  $[9] = handleOk;
21349
22329
  $[10] = t6;
21350
22330
  } else {
@@ -21488,14 +22468,17 @@
21488
22468
  status,
21489
22469
  pluginActions,
21490
22470
  openEntityMode,
21491
- showDefaultActions = true
22471
+ showDefaultActions = true,
22472
+ navigateBack,
22473
+ formContext
21492
22474
  }) {
21493
22475
  const authController = useAuthController();
21494
22476
  const context = useFireCMSContext();
21495
22477
  const sideEntityController = useSideEntityController();
21496
22478
  const sideDialogContext = useSideDialogContext();
22479
+ const customizationController = useCustomizationController();
21497
22480
  const entityActions = React.useMemo(() => {
21498
- const customEntityActions = collection.entityActions;
22481
+ const customEntityActions = (collection.entityActions ?? []).map((action) => resolveEntityAction(action, customizationController.entityActions)).filter(Boolean);
21499
22482
  const createEnabled = canCreateEntity(collection, authController, path, null);
21500
22483
  const deleteEnabled = entity ? canDeleteEntity(collection, authController, path, entity) : false;
21501
22484
  const actions = [];
@@ -21503,7 +22486,7 @@
21503
22486
  if (deleteEnabled) actions.push(deleteEntityAction);
21504
22487
  if (customEntityActions) return mergeEntityActions(actions, customEntityActions);
21505
22488
  return actions;
21506
- }, [authController, collection, path]);
22489
+ }, [authController, collection, path, customizationController.entityActions?.length]);
21507
22490
  const formActions = showDefaultActions ? entityActions.filter((a) => a.includeInForm === void 0 || a.includeInForm) : [];
21508
22491
  return layout === "bottom" ? buildBottomActions({
21509
22492
  savingError,
@@ -21517,7 +22500,9 @@
21517
22500
  status,
21518
22501
  sideDialogContext,
21519
22502
  pluginActions,
21520
- openEntityMode
22503
+ openEntityMode,
22504
+ navigateBack,
22505
+ formContext
21521
22506
  }) : buildSideActions({
21522
22507
  savingError,
21523
22508
  entity,
@@ -21530,7 +22515,9 @@
21530
22515
  disabled,
21531
22516
  status,
21532
22517
  pluginActions,
21533
- openEntityMode
22518
+ openEntityMode,
22519
+ navigateBack,
22520
+ formContext
21534
22521
  });
21535
22522
  }
21536
22523
  function buildBottomActions({
@@ -21545,22 +22532,28 @@
21545
22532
  status,
21546
22533
  sideDialogContext,
21547
22534
  pluginActions,
21548
- openEntityMode
22535
+ openEntityMode,
22536
+ navigateBack,
22537
+ formContext
21549
22538
  }) {
21550
22539
  const canClose = openEntityMode === "side_panel";
21551
22540
  return /* @__PURE__ */ jsxRuntime.jsxs(ui.DialogActions, { position: "absolute", children: [
21552
22541
  savingError && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-right", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Typography, { color: "error", children: savingError.message }) }),
21553
- entity && formActions.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-grow flex overflow-auto no-scrollbar", children: formActions.map((action) => /* @__PURE__ */ jsxRuntime.jsx(ui.IconButton, { color: "primary", onClick: (event) => {
21554
- event.stopPropagation();
21555
- if (entity) action.onClick({
22542
+ formActions.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-grow flex overflow-auto no-scrollbar", children: formActions.map((action) => {
22543
+ const props = {
22544
+ view: "form",
21556
22545
  entity,
21557
22546
  fullPath: collection.path,
21558
22547
  collection,
21559
22548
  context,
21560
22549
  sideEntityController,
21561
- openEntityMode
21562
- });
21563
- }, children: action.icon }, action.name)) }),
22550
+ openEntityMode,
22551
+ navigateBack,
22552
+ formContext
22553
+ };
22554
+ const isEnabled = !action.isEnabled || action.isEnabled(props);
22555
+ return /* @__PURE__ */ jsxRuntime.jsx(EntityActionButton, { action, enabled: isEnabled, props }, action.key);
22556
+ }) }),
21564
22557
  pluginActions,
21565
22558
  /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "text", disabled: disabled || isSubmitting, type: "reset", children: status === "existing" ? "Discard" : "Clear" }),
21566
22559
  /* @__PURE__ */ jsxRuntime.jsxs(ui.Button, { variant: canClose ? "text" : "filled", color: "primary", type: "submit", disabled: disabled || isSubmitting, onClick: () => {
@@ -21590,7 +22583,10 @@
21590
22583
  disabled,
21591
22584
  status,
21592
22585
  sideDialogContext,
21593
- pluginActions
22586
+ pluginActions,
22587
+ openEntityMode,
22588
+ navigateBack,
22589
+ formContext
21594
22590
  }) {
21595
22591
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: ui.cls("overflow-auto h-full flex flex-col gap-2 w-80 2xl:w-96 px-4 py-16 sticky top-0 border-l", ui.defaultBorderMixin), children: [
21596
22592
  /* @__PURE__ */ jsxRuntime.jsxs(ui.LoadingButton, { fullWidth: true, variant: "filled", color: "primary", type: "submit", size: "large", disabled: disabled || isSubmitting, onClick: () => {
@@ -21602,9 +22598,104 @@
21602
22598
  ] }),
21603
22599
  /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { fullWidth: true, variant: "text", disabled: disabled || isSubmitting, type: "reset", children: status === "existing" ? "Discard" : "Clear" }),
21604
22600
  pluginActions,
22601
+ formActions.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-row flex-wrap mt-2", children: formActions.map((action) => {
22602
+ const props = {
22603
+ view: "form",
22604
+ entity,
22605
+ fullPath: collection.path,
22606
+ collection,
22607
+ context,
22608
+ sideEntityController,
22609
+ openEntityMode,
22610
+ navigateBack,
22611
+ formContext
22612
+ };
22613
+ const isEnabled = !action.isEnabled || action.isEnabled(props);
22614
+ return /* @__PURE__ */ jsxRuntime.jsx(EntityActionButton, { action, enabled: isEnabled, props }, action.key);
22615
+ }) }),
21605
22616
  savingError && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-right", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Typography, { color: "error", children: savingError.message }) })
21606
22617
  ] });
21607
22618
  }
22619
+ function EntityActionButton(t0) {
22620
+ const $ = reactCompilerRuntime.c(14);
22621
+ const {
22622
+ action,
22623
+ enabled,
22624
+ props
22625
+ } = t0;
22626
+ const snackbarController = useSnackbarController();
22627
+ const [loading, setLoading] = React.useState(false);
22628
+ const t1 = !enabled;
22629
+ let t2;
22630
+ if ($[0] !== action || $[1] !== props || $[2] !== snackbarController) {
22631
+ t2 = (event) => {
22632
+ console.debug("Executing action", action.key, props);
22633
+ try {
22634
+ event.stopPropagation();
22635
+ if (props.entity) {
22636
+ const onClick = action.onClick(props);
22637
+ if (onClick instanceof Promise) {
22638
+ setLoading(true);
22639
+ onClick.catch((error) => {
22640
+ console.error("Error executing action", action.key, error);
22641
+ snackbarController.open({
22642
+ message: `Error executing action: ${error.message}`,
22643
+ type: "error"
22644
+ });
22645
+ }).finally(() => setLoading(false));
22646
+ } else {
22647
+ snackbarController.open({
22648
+ message: `Action ${action.name} executed successfully`,
22649
+ type: "success"
22650
+ });
22651
+ }
22652
+ }
22653
+ } catch (t32) {
22654
+ const e = t32;
22655
+ console.error("Error executing action", action.key, e);
22656
+ snackbarController.open({
22657
+ message: `Error executing action: ${e.message}`,
22658
+ type: "error"
22659
+ });
22660
+ }
22661
+ };
22662
+ $[0] = action;
22663
+ $[1] = props;
22664
+ $[2] = snackbarController;
22665
+ $[3] = t2;
22666
+ } else {
22667
+ t2 = $[3];
22668
+ }
22669
+ let t3;
22670
+ if ($[4] !== action.icon || $[5] !== loading) {
22671
+ t3 = loading ? /* @__PURE__ */ jsxRuntime.jsx(ui.CircularProgress, { size: "smallest" }) : action.icon;
22672
+ $[4] = action.icon;
22673
+ $[5] = loading;
22674
+ $[6] = t3;
22675
+ } else {
22676
+ t3 = $[6];
22677
+ }
22678
+ let t4;
22679
+ if ($[7] !== t1 || $[8] !== t2 || $[9] !== t3) {
22680
+ t4 = /* @__PURE__ */ jsxRuntime.jsx(ui.IconButton, { color: "primary", disabled: t1, onClick: t2, children: t3 });
22681
+ $[7] = t1;
22682
+ $[8] = t2;
22683
+ $[9] = t3;
22684
+ $[10] = t4;
22685
+ } else {
22686
+ t4 = $[10];
22687
+ }
22688
+ let t5;
22689
+ if ($[11] !== action.name || $[12] !== t4) {
22690
+ t5 = /* @__PURE__ */ jsxRuntime.jsx(ui.Tooltip, { title: action.name, children: t4 });
22691
+ $[11] = action.name;
22692
+ $[12] = t4;
22693
+ $[13] = t5;
22694
+ } else {
22695
+ t5 = $[13];
22696
+ }
22697
+ return t5;
22698
+ }
21608
22699
  function EntityJsonPreview(t0) {
21609
22700
  const $ = reactCompilerRuntime.c(6);
21610
22701
  const {
@@ -21780,6 +22871,22 @@
21780
22871
  const [formContext, setFormContext] = React.useState(void 0);
21781
22872
  const largeLayout = useLargeLayout();
21782
22873
  const customizationController = useCustomizationController();
22874
+ const plugins = customizationController.plugins;
22875
+ const pluginActionsTop = [];
22876
+ if (plugins && collection) {
22877
+ const actionProps = {
22878
+ entityId,
22879
+ parentCollectionIds,
22880
+ path,
22881
+ status,
22882
+ collection,
22883
+ context,
22884
+ formContext,
22885
+ openEntityMode: layout,
22886
+ disabled: false
22887
+ };
22888
+ pluginActionsTop.push(...plugins.map((plugin) => plugin.form?.ActionsTop ? /* @__PURE__ */ jsxRuntime.jsx(plugin.form.ActionsTop, { ...actionProps }, `actions_${plugin.key}`) : null).filter(Boolean));
22889
+ }
21783
22890
  const defaultSelectedView = React.useMemo(() => resolveDefaultSelectedView(collection ? collection.defaultSelectedView : void 0, {
21784
22891
  status,
21785
22892
  entityId
@@ -21796,7 +22903,6 @@
21796
22903
  const customViewsCount = customViews?.length ?? 0;
21797
22904
  const includeJsonView = collection.includeJsonView === void 0 ? true : collection.includeJsonView;
21798
22905
  const hasAdditionalViews = customViewsCount > 0 || subcollectionsCount > 0 || includeJsonView;
21799
- const plugins = customizationController.plugins;
21800
22906
  const {
21801
22907
  resolvedEntityViews,
21802
22908
  selectedEntityView,
@@ -21852,7 +22958,7 @@
21852
22958
  }), role: "tabpanel", children: /* @__PURE__ */ jsxRuntime.jsx(ErrorBoundary, { children: /* @__PURE__ */ jsxRuntime.jsx(EntityJsonPreview, { values: formContext?.values ?? entity?.values ?? {} }) }) }, "json_view");
21853
22959
  const subCollectionsViews = subcollections && subcollections.map((subcollection) => {
21854
22960
  const subcollectionId = subcollection.id ?? subcollection.path;
21855
- const newFullPath = usedEntity ? `${path}/${usedEntity?.id}/${removeInitialAndTrailingSlashes(subcollectionId)}` : void 0;
22961
+ const newFullPath = usedEntity ? `${path}/${usedEntity?.id}/${removeInitialAndTrailingSlashes(subcollection.path)}` : void 0;
21856
22962
  const newFullIdPath = fullIdPath ? `${fullIdPath}/${usedEntity?.id}/${removeInitialAndTrailingSlashes(subcollectionId)}` : void 0;
21857
22963
  if (selectedTab !== subcollectionId) return null;
21858
22964
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative flex-1 h-full overflow-auto w-full", role: "tabpanel", children: [
@@ -21876,7 +22982,7 @@
21876
22982
  /* @__PURE__ */ jsxRuntime.jsx(EntityView, { className: "px-8 h-full overflow-auto", entity, path, collection }),
21877
22983
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-16" })
21878
22984
  ] }) }) : null;
21879
- const entityView = /* @__PURE__ */ jsxRuntime.jsx(EntityForm, { collection, path, entityId: entityId ?? usedEntity?.id, onValuesModified, entity, initialDirtyValues: cachedDirtyValues, openEntityMode: layout, forceActionsAtTheBottom: actionsAtTheBottom, initialStatus: status, className: ui.cls((!mainViewVisible || !canEdit) && !selectedSecondaryForm ? "hidden" : "", formProps?.className), EntityFormActionsComponent: EntityEditViewFormActions, disabled: !canEdit, ...formProps, onEntityChange: (entity_0) => {
22985
+ const entityView = /* @__PURE__ */ jsxRuntime.jsx(EntityForm, { fullIdPath, collection, path, entityId: entityId ?? usedEntity?.id, onValuesModified, entity, initialDirtyValues: cachedDirtyValues, openEntityMode: layout, forceActionsAtTheBottom: actionsAtTheBottom, initialStatus: status, className: ui.cls((!mainViewVisible || !canEdit) && !selectedSecondaryForm ? "hidden" : "", formProps?.className), EntityFormActionsComponent: EntityEditViewFormActions, disabled: !canEdit, ...formProps, onEntityChange: (entity_0) => {
21880
22986
  setUsedEntity(entity_0);
21881
22987
  formProps?.onEntityChange?.(entity_0);
21882
22988
  }, onStatusChange: (status_0) => {
@@ -21898,11 +23004,12 @@
21898
23004
  const customViewTabsEnd = resolvedEntityViews.filter((view_1) => !view_1.position || view_1.position === "end").map((view_2) => /* @__PURE__ */ jsxRuntime.jsx(ui.Tab, { className: !view_2.tabComponent ? "text-sm min-w-[120px]" : void 0, value: view_2.key, children: view_2.tabComponent ?? view_2.name }, `entity_detail_collection_tab_${view_2.name}`));
21899
23005
  const shouldShowTopBar = Boolean(barActions) || hasAdditionalViews;
21900
23006
  let result = /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative flex flex-col h-full w-full bg-white dark:bg-surface-900", children: [
21901
- shouldShowTopBar && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: ui.cls("h-14 flex overflow-visible overflow-x-scroll w-full no-scrollbar h-14 border-b pl-2 pr-2 pt-1 flex items-end bg-surface-50 dark:bg-surface-900", ui.defaultBorderMixin), children: [
23007
+ shouldShowTopBar && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: ui.cls("h-14 items-center flex overflow-visible overflow-x-scroll w-full no-scrollbar h-14 border-b pl-2 pr-2 pt-1 flex bg-surface-50 dark:bg-surface-900", ui.defaultBorderMixin), children: [
21902
23008
  barActions,
21903
23009
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-grow" }),
23010
+ pluginActionsTop,
21904
23011
  globalLoading && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "self-center", children: /* @__PURE__ */ jsxRuntime.jsx(ui.CircularProgress, { size: "small" }) }),
21905
- hasAdditionalViews && /* @__PURE__ */ jsxRuntime.jsxs(ui.Tabs, { value: selectedTab, onValueChange: (value_1) => {
23012
+ hasAdditionalViews && /* @__PURE__ */ jsxRuntime.jsxs(ui.Tabs, { className: "self-end", value: selectedTab, onValueChange: (value_1) => {
21906
23013
  onSideTabClick(value_1);
21907
23014
  }, children: [
21908
23015
  includeJsonView && /* @__PURE__ */ jsxRuntime.jsx(ui.Tab, { disabled: !hasAdditionalViews, value: JSON_TAB_VALUE, className: "text-sm", children: /* @__PURE__ */ jsxRuntime.jsx(ui.CodeIcon, { size: "small" }) }),
@@ -21921,9 +23028,9 @@
21921
23028
  subCollectionsViews
21922
23029
  ] });
21923
23030
  if (plugins) {
21924
- plugins.forEach((plugin) => {
21925
- if (plugin.form?.provider) {
21926
- result = /* @__PURE__ */ jsxRuntime.jsx(plugin.form.provider.Component, { status, path, collection, entity: usedEntity, context, formContext, ...plugin.form.provider.props, children: result });
23031
+ plugins.forEach((plugin_0) => {
23032
+ if (plugin_0.form?.provider) {
23033
+ result = /* @__PURE__ */ jsxRuntime.jsx(plugin_0.form.provider.Component, { status, path, collection, entity: usedEntity, context, formContext, ...plugin_0.form.provider.props, children: result });
21927
23034
  }
21928
23035
  });
21929
23036
  }
@@ -21934,6 +23041,7 @@
21934
23041
  allowFullScreen = true,
21935
23042
  path,
21936
23043
  entityId,
23044
+ fullIdPath,
21937
23045
  formProps
21938
23046
  } = props;
21939
23047
  const {
@@ -21962,6 +23070,7 @@
21962
23070
  sideEntityController.replace({
21963
23071
  path: params.path,
21964
23072
  entityId: params.entityId,
23073
+ fullIdPath: props.fullIdPath,
21965
23074
  selectedTab: params.selectedTab,
21966
23075
  updateUrl: true,
21967
23076
  collection: params.collection
@@ -21975,7 +23084,7 @@
21975
23084
  const parentCollectionIds = React.useMemo(() => {
21976
23085
  return navigationController.getParentCollectionIds(path);
21977
23086
  }, [navigationController, path]);
21978
- const collection = props.collection ?? navigationController.getCollection(path);
23087
+ const collection = navigationController.getCollection(fullIdPath ?? path) ?? props.collection;
21979
23088
  React.useEffect(() => {
21980
23089
  function beforeunload(e) {
21981
23090
  if (blocked && collection) {
@@ -21999,21 +23108,21 @@
21999
23108
  if (!props || !collection) {
22000
23109
  return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full" });
22001
23110
  }
22002
- return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: /* @__PURE__ */ jsxRuntime.jsx(ErrorBoundary, { children: /* @__PURE__ */ jsxRuntime.jsx(EntityEditView, { ...props, layout: "side_panel", collection, parentCollectionIds, onValuesModified, onSaved: onUpdate, barActions: /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
23111
+ return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: /* @__PURE__ */ jsxRuntime.jsx(ErrorBoundary, { children: /* @__PURE__ */ jsxRuntime.jsx(EntityEditView, { ...props, fullIdPath, layout: "side_panel", collection, parentCollectionIds, onValuesModified, onSaved: onUpdate, barActions: /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
22003
23112
  /* @__PURE__ */ jsxRuntime.jsx(ui.IconButton, { className: "self-center", onClick: onClose, children: /* @__PURE__ */ jsxRuntime.jsx(ui.CloseIcon, { size: "small" }) }),
22004
23113
  allowFullScreen && /* @__PURE__ */ jsxRuntime.jsx(ui.IconButton, { className: "self-center", onClick: () => {
22005
23114
  if (entityId) navigate(location.pathname);
22006
23115
  else navigate(location.pathname + "#new");
22007
23116
  }, children: /* @__PURE__ */ jsxRuntime.jsx(ui.OpenInFullIcon, { size: "small" }) })
22008
23117
  ] }), onTabChange: ({
22009
- path: path_0,
22010
23118
  entityId: entityId_0,
22011
23119
  selectedTab,
22012
23120
  collection: collection_0
22013
23121
  }) => {
22014
23122
  sideEntityController.replace({
22015
- path: path_0,
23123
+ path,
22016
23124
  entityId: entityId_0,
23125
+ fullIdPath: props.fullIdPath,
22017
23126
  selectedTab,
22018
23127
  updateUrl: true,
22019
23128
  collection: collection_0
@@ -22170,16 +23279,18 @@
22170
23279
  });
22171
23280
  let sidePanel = void 0;
22172
23281
  let lastCollectionPath = "";
23282
+ let lastCollectionId = void 0;
22173
23283
  for (let i = 0; i < navigationViewsForPath.length; i++) {
22174
23284
  const navigationEntry = navigationViewsForPath[i];
22175
23285
  if (navigationEntry.type === "collection") {
22176
23286
  lastCollectionPath = navigationEntry.path;
23287
+ lastCollectionId = navigationEntry.collection.id;
22177
23288
  }
22178
23289
  const previousEntry = navigationViewsForPath[i - 1];
22179
23290
  if (navigationEntry.type === "entity") {
22180
23291
  sidePanel = {
22181
23292
  path: navigationEntry.path,
22182
- // fullIdPath: navigationEntry.path,
23293
+ fullIdPath: navigationEntry.fullIdPath,
22183
23294
  entityId: navigationEntry.entityId,
22184
23295
  copy: false,
22185
23296
  width: navigationEntry.parentCollection?.sideDialogWidth
@@ -22197,7 +23308,7 @@
22197
23308
  if (newFlag) {
22198
23309
  sidePanel = {
22199
23310
  path: lastCollectionPath,
22200
- // fullIdPath: lastCollectionPath,
23311
+ fullIdPath: lastCollectionId,
22201
23312
  copy: false
22202
23313
  };
22203
23314
  }
@@ -22205,7 +23316,7 @@
22205
23316
  }
22206
23317
  const propsToSidePanel = (props, buildUrlCollectionPath, resolveIdsFrom, smallLayout, customizationController, authController) => {
22207
23318
  const collectionPath = removeInitialAndTrailingSlashes(props.path);
22208
- const newPath = props.entityId ? buildUrlCollectionPath(`${collectionPath}/${props.entityId}${props.selectedTab ? "/" + props.selectedTab : ""}#${SIDE_URL_HASH}`) : buildUrlCollectionPath(`${collectionPath}#${NEW_URL_HASH}`);
23319
+ const urlPath = props.entityId ? buildUrlCollectionPath(`${collectionPath}/${props.entityId}${props.selectedTab ? "/" + props.selectedTab : ""}#${SIDE_URL_HASH}`) : buildUrlCollectionPath(`${collectionPath}#${NEW_URL_HASH}`);
22209
23320
  const resolvedPanelProps = {
22210
23321
  ...props,
22211
23322
  formProps: props.formProps
@@ -22214,7 +23325,7 @@
22214
23325
  return {
22215
23326
  key: `${props.path}/${props.entityId}`,
22216
23327
  component: /* @__PURE__ */ jsxRuntime.jsx(EntitySidePanel, { ...resolvedPanelProps }),
22217
- urlPath: newPath,
23328
+ urlPath,
22218
23329
  parentUrlPath: buildUrlCollectionPath(collectionPath),
22219
23330
  width: entityViewWidth,
22220
23331
  onClose: props.onClose,
@@ -22755,6 +23866,7 @@
22755
23866
  onAnalyticsEvent,
22756
23867
  propertyConfigs,
22757
23868
  entityViews,
23869
+ entityActions,
22758
23870
  components,
22759
23871
  navigationController,
22760
23872
  apiKey
@@ -22773,6 +23885,7 @@
22773
23885
  entityLinkBuilder,
22774
23886
  plugins,
22775
23887
  entityViews: entityViews ?? [],
23888
+ entityActions: entityActions ?? [],
22776
23889
  propertyConfigs: propertyConfigs ?? {},
22777
23890
  components
22778
23891
  };
@@ -22891,7 +24004,7 @@
22891
24004
  const {
22892
24005
  isActive
22893
24006
  } = t52;
22894
- return ui.cls("rounded-lg truncate", "hover:bg-surface-accent-300 hover:bg-opacity-75 dark:hover:bg-surface-accent-800 dark:hover:bg-opacity-75 text-text-primary dark:text-surface-200 hover:text-surface-900 hover:dark:text-white", "flex flex-row items-center mr-8", drawerOpen ? "pl-4 h-12" : "pl-4 h-11", "font-semibold text-xs", isActive ? "bg-surface-accent-200 bg-opacity-60 dark:bg-surface-800 dark:bg-opacity-50" : "");
24007
+ return ui.cls("rounded-lg truncate", "hover:bg-surface-accent-300 hover:bg-opacity-75 dark:hover:bg-surface-accent-800 dark:hover:bg-opacity-75 text-text-primary dark:text-surface-200 hover:text-surface-900 hover:dark:text-white", "flex flex-row items-center mr-8", drawerOpen ? "pl-4 h-10" : "pl-4 h-9", "font-semibold text-xs", isActive ? "bg-surface-accent-200 bg-opacity-60 dark:bg-surface-800 dark:bg-opacity-50" : "");
22895
24008
  };
22896
24009
  $[4] = drawerOpen;
22897
24010
  $[5] = t4;
@@ -23051,7 +24164,7 @@
23051
24164
  if ($[41] !== adminMenuOpen || $[42] !== buildGroupHeader || $[43] !== drawerOpen || $[44] !== navigationEntries || $[45] !== onClick || $[46] !== tooltipsOpen) {
23052
24165
  t10 = (group_0) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-surface-50 dark:bg-surface-800 dark:bg-opacity-30 my-4 rounded-lg ml-3 mr-1", children: [
23053
24166
  buildGroupHeader(group_0),
23054
- Object.values(navigationEntries).filter((e_0) => e_0.group === group_0).map((view_0, index) => /* @__PURE__ */ jsxRuntime.jsx(DrawerNavigationItem, { icon: /* @__PURE__ */ jsxRuntime.jsx(IconForView, { collectionOrView: view_0.collection ?? view_0.view, size: "small" }), tooltipsOpen, adminMenuOpen, drawerOpen, onClick: () => onClick(view_0), url: view_0.url, name: view_0.name }, `navigation_${index}`))
24167
+ Object.values(navigationEntries).filter((e_0) => e_0.group === group_0).map((view_0) => /* @__PURE__ */ jsxRuntime.jsx(DrawerNavigationItem, { icon: /* @__PURE__ */ jsxRuntime.jsx(IconForView, { collectionOrView: view_0.collection ?? view_0.view, size: "small" }), tooltipsOpen, adminMenuOpen, drawerOpen, onClick: () => onClick(view_0), url: view_0.url, name: view_0.name }, view_0.id))
23055
24168
  ] }, `drawer_group_${group_0}`);
23056
24169
  $[41] = adminMenuOpen;
23057
24170
  $[42] = buildGroupHeader;
@@ -23105,13 +24218,13 @@
23105
24218
  adminViews.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(ui.Menu, { side: "right", open: adminMenuOpen, onOpenChange: setAdminMenuOpen, trigger: /* @__PURE__ */ jsxRuntime.jsxs(ui.IconButton, { shape: "square", className: "m-4 text-surface-900 dark:text-white w-fit", children: [
23106
24219
  /* @__PURE__ */ jsxRuntime.jsx(ui.Tooltip, { title: "Admin", open: tooltipsOpen, side: "right", sideOffset: 28, children: /* @__PURE__ */ jsxRuntime.jsx(ui.MoreVertIcon, {}) }),
23107
24220
  drawerOpen && /* @__PURE__ */ jsxRuntime.jsx("div", { className: ui.cls(drawerOpen ? "opacity-100" : "opacity-0 hidden", "mx-4 font-inherit text-inherit"), children: "ADMIN" })
23108
- ] }), children: adminViews.map((entry, index_0) => /* @__PURE__ */ jsxRuntime.jsxs(ui.MenuItem, { onClick: (event) => {
24221
+ ] }), children: adminViews.map((entry) => /* @__PURE__ */ jsxRuntime.jsxs(ui.MenuItem, { onClick: (event) => {
23109
24222
  event.preventDefault();
23110
- navigate(entry.path);
24223
+ navigate(entry.url);
23111
24224
  }, children: [
23112
24225
  /* @__PURE__ */ jsxRuntime.jsx(IconForView, { collectionOrView: entry.view }),
23113
24226
  entry.name
23114
- ] }, `navigation_${index_0}`)) })
24227
+ ] }, entry.id)) })
23115
24228
  ] }) });
23116
24229
  $[0] = adminMenuOpen;
23117
24230
  $[1] = analyticsController;
@@ -23364,10 +24477,21 @@
23364
24477
  Field: StorageUploadFieldBinding
23365
24478
  }
23366
24479
  },
24480
+ reference_as_string: {
24481
+ key: "reference_as_string",
24482
+ name: "Reference (as string)",
24483
+ description: "The value refers to a different collection (it is saved as a string)",
24484
+ Icon: ui.LinkIcon,
24485
+ color: "#154fb3",
24486
+ property: {
24487
+ dataType: "string",
24488
+ Field: ReferenceAsStringFieldBinding
24489
+ }
24490
+ },
23367
24491
  reference: {
23368
24492
  key: "reference",
23369
24493
  name: "Reference",
23370
- description: "The value refers to a different collection",
24494
+ description: "The value refers to a different collection (it is saved as a reference)",
23371
24495
  Icon: ui.LinkIcon,
23372
24496
  color: "#ff0042",
23373
24497
  property: {
@@ -23498,6 +24622,8 @@
23498
24622
  return "email";
23499
24623
  } else if (property.enumValues) {
23500
24624
  return "select";
24625
+ } else if (property.reference) {
24626
+ return "reference_as_string";
23501
24627
  } else {
23502
24628
  return "text_field";
23503
24629
  }
@@ -23673,7 +24799,7 @@
23673
24799
  } else {
23674
24800
  t8 = $[22];
23675
24801
  }
23676
- t62 = /* @__PURE__ */ jsxRuntime.jsx(EntityCollectionView, { isSubCollection: false, parentCollectionIds: t8, fullPath: collection.id, updateUrl: true, ...collection, Actions: toArray(collection.Actions) }, `collection_view_${collection.id ?? collection.path}`);
24802
+ t62 = /* @__PURE__ */ jsxRuntime.jsx(EntityCollectionView, { isSubCollection: false, parentCollectionIds: t8, fullPath: collection.path, fullIdPath: collection.id, updateUrl: true, ...collection, Actions: toArray(collection.Actions) }, `collection_view_${collection.id ?? collection.path}`);
23677
24803
  }
23678
24804
  $[18] = navigation;
23679
24805
  $[19] = navigationEntries;
@@ -23713,7 +24839,7 @@
23713
24839
  } else {
23714
24840
  t8 = $[27];
23715
24841
  }
23716
- t62 = /* @__PURE__ */ jsxRuntime.jsx(EntityCollectionView, { fullIdPath: collection_0.id, isSubCollection: false, parentCollectionIds: t8, fullPath: collection_0.id, updateUrl: true, ...collection_0, Actions: toArray(collection_0.Actions) }, `collection_view_${collection_0.id ?? collection_0.path}`);
24842
+ t62 = /* @__PURE__ */ jsxRuntime.jsx(EntityCollectionView, { fullIdPath: collection_0.id, isSubCollection: false, parentCollectionIds: t8, fullPath: collection_0.path, updateUrl: true, ...collection_0, Actions: toArray(collection_0.Actions) }, `collection_view_${collection_0.id ?? collection_0.path}`);
23717
24843
  }
23718
24844
  $[23] = navigation;
23719
24845
  $[24] = navigationEntries;
@@ -24428,6 +25554,7 @@
24428
25554
  function _temp3(child_1) {
24429
25555
  return child_1.type.componentType !== "Drawer" && child_1.type.componentType !== "AppBar";
24430
25556
  }
25557
+ exports2.ADMIN_GROUP_NAME = ADMIN_GROUP_NAME;
24431
25558
  exports2.AppBar = AppBar;
24432
25559
  exports2.AppContext = AppContext;
24433
25560
  exports2.ArrayContainer = ArrayContainer;
@@ -24452,6 +25579,7 @@
24452
25579
  exports2.CircularProgressCenter = CircularProgressCenter;
24453
25580
  exports2.ConfirmationDialog = ConfirmationDialog;
24454
25581
  exports2.DEFAULT_FIELD_CONFIGS = DEFAULT_FIELD_CONFIGS;
25582
+ exports2.DEFAULT_GROUP_NAME = DEFAULT_GROUP_NAME;
24455
25583
  exports2.DRAWER_WIDTH = DRAWER_WIDTH;
24456
25584
  exports2.DatePreview = DatePreview;
24457
25585
  exports2.DateTimeFieldBinding = DateTimeFieldBinding;
@@ -24494,6 +25622,8 @@
24494
25622
  exports2.ModeControllerContext = ModeControllerContext;
24495
25623
  exports2.ModeControllerProvider = ModeControllerProvider;
24496
25624
  exports2.MultiSelectFieldBinding = MultiSelectFieldBinding;
25625
+ exports2.NAVIGATION_ADMIN_GROUP_NAME = NAVIGATION_ADMIN_GROUP_NAME;
25626
+ exports2.NAVIGATION_DEFAULT_GROUP_NAME = NAVIGATION_DEFAULT_GROUP_NAME;
24497
25627
  exports2.NavigationCard = NavigationCard;
24498
25628
  exports2.NavigationCardBinding = NavigationCardBinding;
24499
25629
  exports2.NavigationGroup = NavigationGroup;
@@ -24507,6 +25637,7 @@
24507
25637
  exports2.PropertyPreview = PropertyPreview;
24508
25638
  exports2.PropertyTableCell = PropertyTableCell;
24509
25639
  exports2.ReadOnlyFieldBinding = ReadOnlyFieldBinding;
25640
+ exports2.ReferenceAsStringFieldBinding = ReferenceAsStringFieldBinding;
24510
25641
  exports2.ReferenceFieldBinding = ReferenceFieldBinding;
24511
25642
  exports2.ReferencePreview = ReferencePreview;
24512
25643
  exports2.ReferenceSelectionTable = ReferenceSelectionTable;
@@ -24629,6 +25760,7 @@
24629
25760
  exports2.resolveCollection = resolveCollection;
24630
25761
  exports2.resolveCollectionPathIds = resolveCollectionPathIds;
24631
25762
  exports2.resolveDefaultSelectedView = resolveDefaultSelectedView;
25763
+ exports2.resolveEntityAction = resolveEntityAction;
24632
25764
  exports2.resolveEntityView = resolveEntityView;
24633
25765
  exports2.resolveEnumValues = resolveEnumValues;
24634
25766
  exports2.resolveNavigationFrom = resolveNavigationFrom;