@firecms/core 3.0.0-canary.248 → 3.0.0-canary.249

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 (45) hide show
  1. package/dist/components/HomePage/DefaultHomePage.d.ts +2 -15
  2. package/dist/components/HomePage/HomePageDnD.d.ts +76 -0
  3. package/dist/components/HomePage/NavigationCard.d.ts +3 -1
  4. package/dist/components/HomePage/NavigationCardBinding.d.ts +3 -2
  5. package/dist/components/HomePage/NavigationGroup.d.ts +7 -1
  6. package/dist/components/HomePage/RenameGroupDialog.d.ts +9 -0
  7. package/dist/core/field_configs.d.ts +1 -1
  8. package/dist/form/field_bindings/ReferenceAsStringFieldBinding.d.ts +9 -0
  9. package/dist/form/index.d.ts +1 -0
  10. package/dist/hooks/useBuildNavigationController.d.ts +51 -2
  11. package/dist/index.es.js +1726 -778
  12. package/dist/index.es.js.map +1 -1
  13. package/dist/index.umd.js +1723 -775
  14. package/dist/index.umd.js.map +1 -1
  15. package/dist/types/analytics.d.ts +1 -1
  16. package/dist/types/collections.d.ts +3 -0
  17. package/dist/types/navigation.d.ts +20 -4
  18. package/dist/types/plugins.d.ts +12 -0
  19. package/dist/types/properties.d.ts +7 -0
  20. package/dist/types/property_config.d.ts +1 -1
  21. package/dist/util/icons.d.ts +1 -1
  22. package/package.json +5 -5
  23. package/src/components/EntityCollectionTable/PropertyTableCell.tsx +25 -3
  24. package/src/components/HomePage/DefaultHomePage.tsx +476 -157
  25. package/src/components/HomePage/FavouritesView.tsx +3 -3
  26. package/src/components/HomePage/HomePageDnD.tsx +613 -0
  27. package/src/components/HomePage/NavigationCard.tsx +47 -38
  28. package/src/components/HomePage/NavigationCardBinding.tsx +10 -6
  29. package/src/components/HomePage/NavigationGroup.tsx +63 -29
  30. package/src/components/HomePage/RenameGroupDialog.tsx +113 -0
  31. package/src/core/DefaultDrawer.tsx +8 -8
  32. package/src/core/DrawerNavigationItem.tsx +1 -1
  33. package/src/core/field_configs.tsx +15 -1
  34. package/src/form/field_bindings/ReferenceAsStringFieldBinding.tsx +135 -0
  35. package/src/form/field_bindings/RepeatFieldBinding.tsx +0 -1
  36. package/src/form/index.tsx +1 -0
  37. package/src/hooks/useBuildNavigationController.tsx +273 -84
  38. package/src/preview/PropertyPreview.tsx +14 -0
  39. package/src/types/analytics.ts +3 -0
  40. package/src/types/collections.ts +3 -0
  41. package/src/types/navigation.ts +27 -5
  42. package/src/types/plugins.tsx +15 -0
  43. package/src/types/properties.ts +8 -0
  44. package/src/types/property_config.tsx +1 -0
  45. package/src/util/icons.tsx +7 -3
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" } });
@@ -3183,16 +3183,16 @@
3183
3183
  }
3184
3184
  return Math.abs(hash2);
3185
3185
  }
3186
- function getIcon(iconKey, className, color) {
3186
+ function getIcon(iconKey, className, color, size) {
3187
3187
  if (!iconKey) return void 0;
3188
3188
  iconKey = slugify(iconKey);
3189
3189
  if (!(iconKey in iconKeysMap)) {
3190
3190
  return void 0;
3191
3191
  }
3192
- return iconKey in iconKeysMap ? /* @__PURE__ */ jsxRuntime.jsx(ui.Icon, { iconKey, size: "medium", className, color }) : void 0;
3192
+ return iconKey in iconKeysMap ? /* @__PURE__ */ jsxRuntime.jsx(ui.Icon, { iconKey, size, className, color }) : void 0;
3193
3193
  }
3194
3194
  const IconForView = React.memo(function IconForView2(t0) {
3195
- const $ = reactCompilerRuntime.c(14);
3195
+ const $ = reactCompilerRuntime.c(15);
3196
3196
  const {
3197
3197
  collectionOrView,
3198
3198
  className,
@@ -3211,14 +3211,15 @@
3211
3211
  return t22;
3212
3212
  }
3213
3213
  let t2;
3214
- if ($[1] !== className || $[2] !== collectionOrView.icon || $[3] !== color) {
3215
- t2 = getIcon(collectionOrView.icon, className, color);
3214
+ if ($[1] !== className || $[2] !== collectionOrView.icon || $[3] !== color || $[4] !== size) {
3215
+ t2 = getIcon(collectionOrView.icon, className, color, size);
3216
3216
  $[1] = className;
3217
3217
  $[2] = collectionOrView.icon;
3218
3218
  $[3] = color;
3219
- $[4] = t2;
3219
+ $[4] = size;
3220
+ $[5] = t2;
3220
3221
  } else {
3221
- t2 = $[4];
3222
+ t2 = $[5];
3222
3223
  }
3223
3224
  const icon = t2;
3224
3225
  if (collectionOrView?.icon && icon) {
@@ -3226,12 +3227,12 @@
3226
3227
  }
3227
3228
  const t3 = ("singularName" in collectionOrView ? collectionOrView.singularName : void 0) ?? collectionOrView.name;
3228
3229
  let t4;
3229
- if ($[5] !== t3) {
3230
+ if ($[6] !== t3) {
3230
3231
  t4 = slugify(t3);
3231
- $[5] = t3;
3232
- $[6] = t4;
3232
+ $[6] = t3;
3233
+ $[7] = t4;
3233
3234
  } else {
3234
- t4 = $[6];
3235
+ t4 = $[7];
3235
3236
  }
3236
3237
  let slugName = t4;
3237
3238
  let key;
@@ -3240,12 +3241,12 @@
3240
3241
  }
3241
3242
  if (!key) {
3242
3243
  let t52;
3243
- if ($[7] !== collectionOrView.path) {
3244
+ if ($[8] !== collectionOrView.path) {
3244
3245
  t52 = slugify(collectionOrView.path);
3245
- $[7] = collectionOrView.path;
3246
- $[8] = t52;
3246
+ $[8] = collectionOrView.path;
3247
+ $[9] = t52;
3247
3248
  } else {
3248
- t52 = $[8];
3249
+ t52 = $[9];
3249
3250
  }
3250
3251
  slugName = t52;
3251
3252
  if (slugName in iconKeysMap) {
@@ -3257,15 +3258,15 @@
3257
3258
  key = ui.coolIconKeys[hashString(collectionOrView.path) % iconsCount];
3258
3259
  }
3259
3260
  let t5;
3260
- if ($[9] !== className || $[10] !== color || $[11] !== key || $[12] !== size) {
3261
+ if ($[10] !== className || $[11] !== color || $[12] !== key || $[13] !== size) {
3261
3262
  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;
3263
+ $[10] = className;
3264
+ $[11] = color;
3265
+ $[12] = key;
3266
+ $[13] = size;
3267
+ $[14] = t5;
3267
3268
  } else {
3268
- t5 = $[13];
3269
+ t5 = $[14];
3269
3270
  }
3270
3271
  return t5;
3271
3272
  }, (prevProps, nextProps) => {
@@ -4142,7 +4143,7 @@
4142
4143
  }
4143
4144
  setDataLoading(false);
4144
4145
  setDataLoadingError(void 0);
4145
- setData(entities.map(_temp$s));
4146
+ setData(entities.map(_temp$r));
4146
4147
  setNoMoreToLoad(!itemCount || entities.length < itemCount);
4147
4148
  };
4148
4149
  const onError = (error) => {
@@ -4175,7 +4176,7 @@
4175
4176
  orderBy: sortByProperty,
4176
4177
  order: currentSort
4177
4178
  }).then(onEntitiesUpdate).catch(onError);
4178
- return _temp2$e;
4179
+ return _temp2$d;
4179
4180
  }
4180
4181
  };
4181
4182
  $[4] = collection;
@@ -4223,9 +4224,9 @@
4223
4224
  }
4224
4225
  return t5;
4225
4226
  }
4226
- function _temp2$e() {
4227
+ function _temp2$d() {
4227
4228
  }
4228
- function _temp$s(e_0) {
4229
+ function _temp$r(e_0) {
4229
4230
  return {
4230
4231
  ...e_0
4231
4232
  };
@@ -4290,7 +4291,7 @@
4290
4291
  setEntity(CACHE[`${path}/${entityId}`]);
4291
4292
  setDataLoading(false);
4292
4293
  setDataLoadingError(void 0);
4293
- return _temp$r;
4294
+ return _temp$q;
4294
4295
  } else {
4295
4296
  if (entityId && path && collection) {
4296
4297
  if (dataSource.listenEntity) {
@@ -4309,11 +4310,11 @@
4309
4310
  databaseId,
4310
4311
  collection
4311
4312
  }).then(onEntityUpdate).catch(onError);
4312
- return _temp2$d;
4313
+ return _temp2$c;
4313
4314
  }
4314
4315
  } else {
4315
4316
  onEntityUpdate(void 0);
4316
- return _temp3$5;
4317
+ return _temp3$4;
4317
4318
  }
4318
4319
  }
4319
4320
  };
@@ -4354,11 +4355,11 @@
4354
4355
  }
4355
4356
  return t5;
4356
4357
  }
4357
- function _temp3$5() {
4358
+ function _temp3$4() {
4358
4359
  }
4359
- function _temp2$d() {
4360
+ function _temp2$c() {
4360
4361
  }
4361
- function _temp$r() {
4362
+ function _temp$q() {
4362
4363
  }
4363
4364
  async function saveEntityWithCallbacks({
4364
4365
  collection,
@@ -4942,7 +4943,7 @@
4942
4943
  }
4943
4944
  let t9;
4944
4945
  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 }) });
4946
+ 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
4947
  $[16] = url;
4947
4948
  $[17] = t9;
4948
4949
  } else {
@@ -4976,7 +4977,7 @@
4976
4977
  }
4977
4978
  return t11;
4978
4979
  }
4979
- function _temp$q(e_0) {
4980
+ function _temp$p(e_0) {
4980
4981
  return e_0.stopPropagation();
4981
4982
  }
4982
4983
  function UrlComponentPreview(t0) {
@@ -5009,7 +5010,7 @@
5009
5010
  }
5010
5011
  let t3;
5011
5012
  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: [
5013
+ 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
5014
  t2,
5014
5015
  url
5015
5016
  ] });
@@ -5112,7 +5113,7 @@
5112
5113
  }
5113
5114
  let t7;
5114
5115
  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: [
5116
+ 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
5117
  t5,
5117
5118
  t6
5118
5119
  ] });
@@ -5137,10 +5138,10 @@
5137
5138
  }
5138
5139
  }
5139
5140
  }
5140
- function _temp2$c(e_0) {
5141
+ function _temp2$b(e_0) {
5141
5142
  return e_0.stopPropagation();
5142
5143
  }
5143
- function _temp$p(e) {
5144
+ function _temp$o(e) {
5144
5145
  e.preventDefault();
5145
5146
  }
5146
5147
  function VideoPreview(t0) {
@@ -5274,7 +5275,7 @@
5274
5275
  if (Array.isArray(arrayProperty.of)) {
5275
5276
  let t1;
5276
5277
  if ($[6] !== arrayProperty.of) {
5277
- t1 = arrayProperty.of.map(_temp$o);
5278
+ t1 = arrayProperty.of.map(_temp$n);
5278
5279
  $[6] = arrayProperty.of;
5279
5280
  $[7] = t1;
5280
5281
  } else {
@@ -5412,7 +5413,7 @@
5412
5413
  }
5413
5414
  return content || null;
5414
5415
  }
5415
- function _temp$o(p, i) {
5416
+ function _temp$n(p, i) {
5416
5417
  return renderGenericArrayCell(p, i);
5417
5418
  }
5418
5419
  function renderMap(property, size) {
@@ -6594,7 +6595,7 @@
6594
6595
  }
6595
6596
  let t1;
6596
6597
  if ($[1] !== value) {
6597
- t1 = Object.entries(value).map(_temp$n);
6598
+ t1 = Object.entries(value).map(_temp$m);
6598
6599
  $[1] = value;
6599
6600
  $[2] = t1;
6600
6601
  } else {
@@ -6610,7 +6611,7 @@
6610
6611
  }
6611
6612
  return t2;
6612
6613
  }
6613
- function _temp$n(t0) {
6614
+ function _temp$m(t0) {
6614
6615
  const [key, childValue] = t0;
6615
6616
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: ui.cls(ui.defaultBorderMixin, "last:border-b-0 border-b"), children: [
6616
6617
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-row pt-0.5 pb-0.5 gap-2", children: [
@@ -6744,7 +6745,7 @@
6744
6745
  }
6745
6746
  }
6746
6747
  const PropertyPreview = React.memo(function PropertyPreview2(props) {
6747
- const $ = reactCompilerRuntime.c(30);
6748
+ const $ = reactCompilerRuntime.c(31);
6748
6749
  const authController = useAuthController();
6749
6750
  const customizationController = useCustomizationController();
6750
6751
  let content;
@@ -6843,7 +6844,22 @@
6843
6844
  }
6844
6845
  content = t02;
6845
6846
  } else {
6846
- content = /* @__PURE__ */ jsxRuntime.jsx(StringPropertyPreview, { ...props, property: stringProperty, value });
6847
+ if (stringProperty.reference) {
6848
+ if (typeof stringProperty.reference.path === "string") {
6849
+ 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) });
6850
+ } else {
6851
+ let t02;
6852
+ if ($[23] === Symbol.for("react.memo_cache_sentinel")) {
6853
+ t02 = /* @__PURE__ */ jsxRuntime.jsx(EmptyValue, {});
6854
+ $[23] = t02;
6855
+ } else {
6856
+ t02 = $[23];
6857
+ }
6858
+ content = t02;
6859
+ }
6860
+ } else {
6861
+ content = /* @__PURE__ */ jsxRuntime.jsx(StringPropertyPreview, { ...props, property: stringProperty, value });
6862
+ }
6847
6863
  }
6848
6864
  }
6849
6865
  }
@@ -6902,12 +6918,12 @@
6902
6918
  if (property.dataType === "date") {
6903
6919
  if (value instanceof Date) {
6904
6920
  let t02;
6905
- if ($[23] !== value) {
6921
+ if ($[24] !== value) {
6906
6922
  t02 = /* @__PURE__ */ jsxRuntime.jsx(DatePreview, { date: value });
6907
- $[23] = value;
6908
- $[24] = t02;
6923
+ $[24] = value;
6924
+ $[25] = t02;
6909
6925
  } else {
6910
- t02 = $[24];
6926
+ t02 = $[25];
6911
6927
  }
6912
6928
  content = t02;
6913
6929
  } else {
@@ -6923,11 +6939,11 @@
6923
6939
  }
6924
6940
  } else {
6925
6941
  let t02;
6926
- if ($[25] === Symbol.for("react.memo_cache_sentinel")) {
6942
+ if ($[26] === Symbol.for("react.memo_cache_sentinel")) {
6927
6943
  t02 = /* @__PURE__ */ jsxRuntime.jsx(EmptyValue, {});
6928
- $[25] = t02;
6944
+ $[26] = t02;
6929
6945
  } else {
6930
- t02 = $[25];
6946
+ t02 = $[26];
6931
6947
  }
6932
6948
  content = t02;
6933
6949
  }
@@ -6947,12 +6963,12 @@
6947
6963
  }
6948
6964
  } else {
6949
6965
  let t02;
6950
- if ($[26] !== value) {
6966
+ if ($[27] !== value) {
6951
6967
  t02 = JSON.stringify(value);
6952
- $[26] = value;
6953
- $[27] = t02;
6968
+ $[27] = value;
6969
+ $[28] = t02;
6954
6970
  } else {
6955
- t02 = $[27];
6971
+ t02 = $[28];
6956
6972
  }
6957
6973
  content = t02;
6958
6974
  }
@@ -6980,12 +6996,12 @@
6980
6996
  content = $[10];
6981
6997
  }
6982
6998
  let t0;
6983
- if ($[28] !== content) {
6999
+ if ($[29] !== content) {
6984
7000
  t0 = content === void 0 || content === null || Array.isArray(content) && content.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx(EmptyValue, {}) : content;
6985
- $[28] = content;
6986
- $[29] = t0;
7001
+ $[29] = content;
7002
+ $[30] = t0;
6987
7003
  } else {
6988
- t0 = $[29];
7004
+ t0 = $[30];
6989
7005
  }
6990
7006
  return t0;
6991
7007
  }, equal);
@@ -7363,7 +7379,7 @@
7363
7379
  console.trace("onChange");
7364
7380
  if (valueType === "number") {
7365
7381
  if (multiple) {
7366
- const newValue = updatedValue.map(_temp$m);
7382
+ const newValue = updatedValue.map(_temp$l);
7367
7383
  updateValue(newValue);
7368
7384
  } else {
7369
7385
  updateValue(parseFloat(updatedValue));
@@ -7400,7 +7416,7 @@
7400
7416
  const renderValue = t3;
7401
7417
  let t4;
7402
7418
  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)) });
7419
+ 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
7420
  $[10] = disabled;
7405
7421
  $[11] = enumValues;
7406
7422
  $[12] = internalValue;
@@ -7415,10 +7431,10 @@
7415
7431
  }
7416
7432
  return t4;
7417
7433
  }
7418
- function _temp2$b(v_0) {
7434
+ function _temp2$a(v_0) {
7419
7435
  return v_0.toString();
7420
7436
  }
7421
- function _temp$m(v) {
7437
+ function _temp$l(v) {
7422
7438
  return parseFloat(v);
7423
7439
  }
7424
7440
  function VirtualTableNumberInput(props) {
@@ -7977,7 +7993,7 @@
7977
7993
  const snackbarContext = useSnackbarController();
7978
7994
  let t1;
7979
7995
  if ($[0] !== storage.acceptedFiles) {
7980
- t1 = storage.acceptedFiles ? storage.acceptedFiles.map(_temp$l).reduce(_temp2$a, {}) : void 0;
7996
+ t1 = storage.acceptedFiles ? storage.acceptedFiles.map(_temp$k).reduce(_temp2$9, {}) : void 0;
7981
7997
  $[0] = storage.acceptedFiles;
7982
7998
  $[1] = t1;
7983
7999
  } else {
@@ -8200,13 +8216,13 @@
8200
8216
  }
8201
8217
  return t20;
8202
8218
  }
8203
- function _temp2$a(a, b) {
8219
+ function _temp2$9(a, b) {
8204
8220
  return {
8205
8221
  ...a,
8206
8222
  ...b
8207
8223
  };
8208
8224
  }
8209
- function _temp$l(e) {
8225
+ function _temp$k(e) {
8210
8226
  return {
8211
8227
  [e]: []
8212
8228
  };
@@ -8313,7 +8329,7 @@
8313
8329
  let t1;
8314
8330
  if ($[2] !== updateValue) {
8315
8331
  t1 = (entities) => {
8316
- updateValue(entities.map(_temp$k));
8332
+ updateValue(entities.map(_temp$j));
8317
8333
  };
8318
8334
  $[2] = updateValue;
8319
8335
  $[3] = t1;
@@ -8323,7 +8339,7 @@
8323
8339
  const onMultipleEntitiesSelected = t1;
8324
8340
  let t2;
8325
8341
  if ($[4] !== internalValue) {
8326
- t2 = internalValue ? Array.isArray(internalValue) ? internalValue.map(_temp2$9) : internalValue.id ? [internalValue.id] : [] : [];
8342
+ t2 = internalValue ? Array.isArray(internalValue) ? internalValue.map(_temp2$8) : internalValue.id ? [internalValue.id] : [] : [];
8327
8343
  $[4] = internalValue;
8328
8344
  $[5] = t2;
8329
8345
  } else {
@@ -8474,10 +8490,10 @@
8474
8490
  }
8475
8491
  return t10;
8476
8492
  }, equal);
8477
- function _temp$k(e) {
8493
+ function _temp$j(e) {
8478
8494
  return getReferenceFrom(e);
8479
8495
  }
8480
- function _temp2$9(ref) {
8496
+ function _temp2$8(ref) {
8481
8497
  return ref.id;
8482
8498
  }
8483
8499
  yup__namespace.addMethod(yup__namespace.array, "uniqueInArray", function(mapper = (a) => a, message) {
@@ -9309,7 +9325,14 @@
9309
9325
  }
9310
9326
  if (!customField && (!customPreview || selected)) {
9311
9327
  const isAStorageProperty = isStorageProperty(property);
9312
- if (isAStorageProperty) {
9328
+ if (property.dataType === "string" && property.reference?.path) {
9329
+ const stringProperty = property;
9330
+ const path_0 = stringProperty.reference?.path;
9331
+ const referenceProperty = stringProperty.reference;
9332
+ const referenceValue = internalValue ? new EntityReference(internalValue, path_0) : void 0;
9333
+ 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 });
9334
+ allowScroll = false;
9335
+ } else if (isAStorageProperty) {
9313
9336
  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
9337
  includeActions = false;
9315
9338
  showExpandIcon = true;
@@ -9325,12 +9348,12 @@
9325
9348
  allowScroll = true;
9326
9349
  }
9327
9350
  } 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 });
9351
+ const stringProperty_0 = property;
9352
+ if (stringProperty_0.enumValues) {
9353
+ 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
9354
  fullHeight = true;
9332
- } else if (stringProperty.markdown || !stringProperty.storage) {
9333
- const multiline = Boolean(stringProperty.multiline) || Boolean(stringProperty.markdown);
9355
+ } else if (stringProperty_0.markdown || !stringProperty_0.storage || !stringProperty_0.reference) {
9356
+ const multiline = Boolean(stringProperty_0.multiline) || Boolean(stringProperty_0.markdown);
9334
9357
  innerComponent = /* @__PURE__ */ jsxRuntime.jsx(VirtualTableInput, { error: validationError ?? error, disabled, multiline, focused: selected, value: internalValue, updateValue });
9335
9358
  allowScroll = true;
9336
9359
  }
@@ -9617,14 +9640,14 @@
9617
9640
  }
9618
9641
  let t5;
9619
9642
  if ($[5] === Symbol.for("react.memo_cache_sentinel")) {
9620
- t5 = ["xs", "s", "m", "l", "xl"].map(_temp2$8);
9643
+ t5 = ["xs", "s", "m", "l", "xl"].map(_temp2$7);
9621
9644
  $[5] = t5;
9622
9645
  } else {
9623
9646
  t5 = $[5];
9624
9647
  }
9625
9648
  let t6;
9626
9649
  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 }) });
9650
+ 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
9651
  $[6] = t3;
9629
9652
  $[7] = t4;
9630
9653
  $[8] = t6;
@@ -9708,10 +9731,10 @@
9708
9731
  }
9709
9732
  return t13;
9710
9733
  }
9711
- function _temp2$8(size_0) {
9734
+ function _temp2$7(size_0) {
9712
9735
  return /* @__PURE__ */ jsxRuntime.jsx(ui.SelectItem, { value: size_0, className: "w-12 font-medium text-center", children: size_0.toUpperCase() }, size_0);
9713
9736
  }
9714
- function _temp$j(v_0) {
9737
+ function _temp$i(v_0) {
9715
9738
  return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "font-medium", children: v_0.toUpperCase() });
9716
9739
  }
9717
9740
  function getTableCellAlignment(property) {
@@ -10831,7 +10854,7 @@
10831
10854
  let t1;
10832
10855
  if ($[0] !== text) {
10833
10856
  const urlRegex = /https?:\/\/[^\s]+/g;
10834
- t1 = text.replace(urlRegex, _temp$i);
10857
+ t1 = text.replace(urlRegex, _temp$h);
10835
10858
  $[0] = text;
10836
10859
  $[1] = t1;
10837
10860
  } else {
@@ -10850,7 +10873,7 @@
10850
10873
  }
10851
10874
  return t2;
10852
10875
  };
10853
- function _temp$i(url) {
10876
+ function _temp$h(url) {
10854
10877
  return `<a href="${url}" class="underline" target="_blank">Link</a><br/>`;
10855
10878
  }
10856
10879
  const operationLabels$2 = {
@@ -11050,7 +11073,7 @@
11050
11073
  }
11051
11074
  let t5;
11052
11075
  if ($[14] !== possibleOperations) {
11053
- t5 = possibleOperations.map(_temp2$7);
11076
+ t5 = possibleOperations.map(_temp2$6);
11054
11077
  $[14] = possibleOperations;
11055
11078
  $[15] = t5;
11056
11079
  } else {
@@ -11058,7 +11081,7 @@
11058
11081
  }
11059
11082
  let t6;
11060
11083
  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 }) });
11084
+ 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
11085
  $[16] = operation;
11063
11086
  $[17] = t4;
11064
11087
  $[18] = t5;
@@ -11109,8 +11132,8 @@
11109
11132
  }
11110
11133
  let t9;
11111
11134
  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);
11135
+ t9 = enumValues && multiple && /* @__PURE__ */ jsxRuntime.jsx(ui.MultiSelect, { position: "item-aligned", value: Array.isArray(internalValue) ? internalValue.map(_temp3$3) : [], onValueChange: (value_2) => {
11136
+ updateFilter(operation, dataType === "number" ? value_2.map(_temp4$2) : value_2);
11114
11137
  }, 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
11138
  $[34] = dataType;
11116
11139
  $[35] = enumValues;
@@ -11173,16 +11196,16 @@
11173
11196
  }
11174
11197
  return t12;
11175
11198
  }
11176
- function _temp4$3(v) {
11199
+ function _temp4$2(v) {
11177
11200
  return parseInt(v);
11178
11201
  }
11179
- function _temp3$4(e_1) {
11202
+ function _temp3$3(e_1) {
11180
11203
  return String(e_1);
11181
11204
  }
11182
- function _temp2$7(op_1) {
11205
+ function _temp2$6(op_1) {
11183
11206
  return /* @__PURE__ */ jsxRuntime.jsx(ui.SelectItem, { value: op_1, children: operationLabels$1[op_1] }, op_1);
11184
11207
  }
11185
- function _temp$h(op_0) {
11208
+ function _temp$g(op_0) {
11186
11209
  return operationLabels$1[op_0];
11187
11210
  }
11188
11211
  function BooleanFilterField(t0) {
@@ -11313,7 +11336,7 @@
11313
11336
  }
11314
11337
  let t5;
11315
11338
  if ($[11] !== possibleOperations) {
11316
- t5 = possibleOperations.map(_temp2$6);
11339
+ t5 = possibleOperations.map(_temp2$5);
11317
11340
  $[11] = possibleOperations;
11318
11341
  $[12] = t5;
11319
11342
  } else {
@@ -11321,7 +11344,7 @@
11321
11344
  }
11322
11345
  let t6;
11323
11346
  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 }) });
11347
+ 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
11348
  $[13] = operation;
11326
11349
  $[14] = t4;
11327
11350
  $[15] = t5;
@@ -11407,10 +11430,10 @@
11407
11430
  }
11408
11431
  return t14;
11409
11432
  }
11410
- function _temp2$6(op_1) {
11433
+ function _temp2$5(op_1) {
11411
11434
  return /* @__PURE__ */ jsxRuntime.jsx(ui.SelectItem, { value: op_1, children: operationLabels[op_1] }, op_1);
11412
11435
  }
11413
- function _temp$g(op_0) {
11436
+ function _temp$f(op_0) {
11414
11437
  return operationLabels[op_0];
11415
11438
  }
11416
11439
  const SelectableTable = function SelectableTable2({
@@ -12114,7 +12137,7 @@
12114
12137
  const searchBlocked = t12;
12115
12138
  let t2;
12116
12139
  if ($[15] !== customizationController.plugins || $[16] !== dataSource?.initTextSearch) {
12117
- t2 = Boolean(dataSource?.initTextSearch) || customizationController.plugins?.find(_temp$f);
12140
+ t2 = Boolean(dataSource?.initTextSearch) || customizationController.plugins?.find(_temp$e);
12118
12141
  $[15] = customizationController.plugins;
12119
12142
  $[16] = dataSource?.initTextSearch;
12120
12143
  $[17] = t2;
@@ -12206,7 +12229,7 @@
12206
12229
  }
12207
12230
  return t1;
12208
12231
  }
12209
- function _temp$f(p_0) {
12232
+ function _temp$e(p_0) {
12210
12233
  return Boolean(p_0.collectionView?.onTextSearchClick);
12211
12234
  }
12212
12235
  function DeleteEntityDialog({
@@ -12676,198 +12699,415 @@
12676
12699
  function toArray(input) {
12677
12700
  return Array.isArray(input) ? input : input ? [input] : [];
12678
12701
  }
12679
- function NavigationGroup(t0) {
12680
- const $ = reactCompilerRuntime.c(14);
12702
+ function NavigationChip(t0) {
12703
+ const $ = reactCompilerRuntime.c(18);
12681
12704
  const {
12682
- children,
12683
- group
12705
+ entry
12684
12706
  } = t0;
12707
+ const navigate = reactRouterDom.useNavigate();
12685
12708
  const userConfigurationPersistence = useUserConfigurationPersistence();
12686
- const t1 = !(userConfigurationPersistence?.collapsedGroups ?? []).includes(group ?? "ungrouped");
12709
+ if (!userConfigurationPersistence) {
12710
+ return null;
12711
+ }
12712
+ let t1;
12713
+ if ($[0] !== entry.path || $[1] !== userConfigurationPersistence.favouritePaths) {
12714
+ t1 = userConfigurationPersistence.favouritePaths.includes(entry.path);
12715
+ $[0] = entry.path;
12716
+ $[1] = userConfigurationPersistence.favouritePaths;
12717
+ $[2] = t1;
12718
+ } else {
12719
+ t1 = $[2];
12720
+ }
12721
+ const favourite = t1;
12687
12722
  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
- }
12723
+ if ($[3] !== entry.path || $[4] !== favourite || $[5] !== userConfigurationPersistence) {
12724
+ t2 = (e) => {
12725
+ e.preventDefault();
12726
+ e.stopPropagation();
12727
+ if (favourite) {
12728
+ userConfigurationPersistence.setFavouritePaths(userConfigurationPersistence.favouritePaths.filter((p) => p !== entry.path));
12729
+ } else {
12730
+ userConfigurationPersistence.setFavouritePaths([...userConfigurationPersistence.favouritePaths, entry.path]);
12697
12731
  }
12698
12732
  };
12699
- $[0] = group;
12700
- $[1] = userConfigurationPersistence;
12701
- $[2] = t2;
12733
+ $[3] = entry.path;
12734
+ $[4] = favourite;
12735
+ $[5] = userConfigurationPersistence;
12736
+ $[6] = t2;
12702
12737
  } else {
12703
- t2 = $[2];
12738
+ t2 = $[6];
12704
12739
  }
12740
+ const onIconClick = t2;
12705
12741
  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;
12742
+ if ($[7] !== entry.url || $[8] !== navigate) {
12743
+ t3 = () => navigate(entry.url);
12744
+ $[7] = entry.url;
12745
+ $[8] = navigate;
12746
+ $[9] = t3;
12718
12747
  } else {
12719
- t4 = $[6];
12748
+ t3 = $[9];
12720
12749
  }
12750
+ const t4 = favourite ? "text-secondary" : "text-surface-400 dark:text-surface-500";
12721
12751
  let t5;
12722
- if ($[7] !== children) {
12723
- t5 = /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mb-8", children });
12724
- $[7] = children;
12725
- $[8] = t5;
12752
+ if ($[10] !== onIconClick || $[11] !== t4) {
12753
+ t5 = /* @__PURE__ */ jsxRuntime.jsx(ui.StarIcon, { onClick: onIconClick, size: 18, className: t4 });
12754
+ $[10] = onIconClick;
12755
+ $[11] = t4;
12756
+ $[12] = t5;
12726
12757
  } else {
12727
- t5 = $[8];
12758
+ t5 = $[12];
12728
12759
  }
12729
12760
  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;
12761
+ if ($[13] !== entry.name || $[14] !== entry.path || $[15] !== t3 || $[16] !== t5) {
12762
+ t6 = /* @__PURE__ */ jsxRuntime.jsx(ui.Chip, { onClick: t3, icon: t5, children: entry.name }, entry.path);
12763
+ $[13] = entry.name;
12764
+ $[14] = entry.path;
12765
+ $[15] = t3;
12766
+ $[16] = t5;
12767
+ $[17] = t6;
12737
12768
  } else {
12738
- t6 = $[13];
12769
+ t6 = $[17];
12739
12770
  }
12740
12771
  return t6;
12741
12772
  }
12742
- function NavigationCard(t0) {
12743
- const $ = reactCompilerRuntime.c(23);
12744
- const {
12745
- name,
12746
- description,
12747
- icon,
12748
- actions,
12749
- onClick
12750
- } = t0;
12773
+ function FavouritesView(t0) {
12774
+ const $ = reactCompilerRuntime.c(17);
12775
+ const navigationController = useNavigationController();
12776
+ const userConfigurationPersistence = useUserConfigurationPersistence();
12777
+ if (!userConfigurationPersistence) {
12778
+ return null;
12779
+ }
12751
12780
  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;
12781
+ if ($[0] !== userConfigurationPersistence?.favouritePaths) {
12782
+ t1 = userConfigurationPersistence?.favouritePaths ?? [];
12783
+ $[0] = userConfigurationPersistence?.favouritePaths;
12784
+ $[1] = t1;
12755
12785
  } else {
12756
- t1 = $[0];
12786
+ t1 = $[1];
12757
12787
  }
12788
+ let T0;
12758
12789
  let t2;
12759
- if ($[1] !== onClick) {
12760
- t2 = () => {
12761
- onClick?.();
12762
- };
12763
- $[1] = onClick;
12764
- $[2] = t2;
12765
- } else {
12766
- t2 = $[2];
12767
- }
12768
12790
  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
12791
  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;
12792
+ if ($[2] !== navigationController.topLevelNavigation?.navigationEntries || $[3] !== t1) {
12793
+ let t52;
12794
+ if ($[8] !== navigationController.topLevelNavigation?.navigationEntries) {
12795
+ t52 = (path) => navigationController.topLevelNavigation?.navigationEntries.find((entry) => entry.path === path);
12796
+ $[8] = navigationController.topLevelNavigation?.navigationEntries;
12797
+ $[9] = t52;
12798
+ } else {
12799
+ t52 = $[9];
12800
+ }
12801
+ const favouriteCollections = t1.map(t52).filter(Boolean);
12802
+ T0 = ui.Collapse;
12803
+ t4 = favouriteCollections.length > 0;
12804
+ t2 = "flex flex-row flex-wrap gap-2 pb-2 min-h-[32px]";
12805
+ t3 = favouriteCollections.map(_temp$d);
12806
+ $[2] = navigationController.topLevelNavigation?.navigationEntries;
12807
+ $[3] = t1;
12808
+ $[4] = T0;
12809
+ $[5] = t2;
12783
12810
  $[6] = t3;
12784
12811
  $[7] = t4;
12785
12812
  } else {
12813
+ T0 = $[4];
12814
+ t2 = $[5];
12815
+ t3 = $[6];
12786
12816
  t4 = $[7];
12787
12817
  }
12788
12818
  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;
12819
+ if ($[10] !== t2 || $[11] !== t3) {
12820
+ t5 = /* @__PURE__ */ jsxRuntime.jsx("div", { className: t2, children: t3 });
12821
+ $[10] = t2;
12822
+ $[11] = t3;
12823
+ $[12] = t5;
12793
12824
  } else {
12794
- t5 = $[9];
12825
+ t5 = $[12];
12795
12826
  }
12796
12827
  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;
12815
- } else {
12816
- t7 = $[15];
12817
- }
12818
- let t8;
12819
- if ($[16] === Symbol.for("react.memo_cache_sentinel")) {
12820
- t8 = {
12821
- alignSelf: "flex-end"
12822
- };
12823
- $[16] = t8;
12824
- } else {
12825
- t8 = $[16];
12826
- }
12827
- let t9;
12828
- 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" }) }) });
12830
- $[17] = t9;
12831
- } else {
12832
- t9 = $[17];
12833
- }
12834
- 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;
12842
- } else {
12843
- t10 = $[19];
12844
- }
12845
- 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;
12828
+ if ($[13] !== T0 || $[14] !== t4 || $[15] !== t5) {
12829
+ t6 = /* @__PURE__ */ jsxRuntime.jsx(T0, { in: t4, children: t5 });
12830
+ $[13] = T0;
12831
+ $[14] = t4;
12832
+ $[15] = t5;
12833
+ $[16] = t6;
12851
12834
  } else {
12852
- t11 = $[22];
12835
+ t6 = $[16];
12853
12836
  }
12854
- return t11;
12837
+ return t6;
12855
12838
  }
12856
- function _temp$e(event) {
12857
- event.preventDefault();
12858
- event.stopPropagation();
12839
+ function _temp$d(entry_0) {
12840
+ return /* @__PURE__ */ jsxRuntime.jsx(NavigationChip, { entry: entry_0 }, entry_0.path);
12859
12841
  }
12860
- function SmallNavigationCard(t0) {
12861
- const $ = reactCompilerRuntime.c(10);
12862
- const {
12863
- name,
12864
- url,
12865
- icon
12866
- } = t0;
12867
- let t1;
12868
- if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
12869
- t1 = ui.cls(ui.cardMixin, ui.cardClickableMixin, "cursor-pointer flex flex-row items-center px-4 py-2 text-inherit dark:text-inherit visited:text-inherit visited:dark:text-inherit hover:text-inherit hover:dark:text-inherit ");
12870
- $[0] = t1;
12842
+ const scrollsMap = {};
12843
+ function useRestoreScroll() {
12844
+ const location = reactRouterDom.useLocation();
12845
+ const containerRef = React.useRef(null);
12846
+ const [scroll, setScroll] = React.useState(0);
12847
+ const [direction, setDirection] = React.useState("down");
12848
+ const handleScroll = React.useCallback(() => {
12849
+ if (!containerRef.current || !location.key) return;
12850
+ scrollsMap[location.key] = containerRef.current.scrollTop;
12851
+ setScroll(containerRef.current.scrollTop);
12852
+ setDirection(containerRef.current.scrollTop > scroll ? "down" : "up");
12853
+ }, [containerRef, location.key, scroll]);
12854
+ React.useEffect(() => {
12855
+ const container = containerRef.current;
12856
+ if (!container) return;
12857
+ container.addEventListener("scroll", handleScroll, {
12858
+ passive: true
12859
+ });
12860
+ return () => {
12861
+ if (container) container.removeEventListener("scroll", handleScroll);
12862
+ };
12863
+ }, [containerRef, handleScroll, location]);
12864
+ React.useEffect(() => {
12865
+ if (!containerRef.current || !scrollsMap[location.key]) return;
12866
+ containerRef.current.scrollTo({
12867
+ top: scrollsMap[location.key],
12868
+ behavior: "auto"
12869
+ });
12870
+ }, [location]);
12871
+ return {
12872
+ containerRef,
12873
+ scroll,
12874
+ direction
12875
+ };
12876
+ }
12877
+ function NavigationGroup(t0) {
12878
+ const $ = reactCompilerRuntime.c(26);
12879
+ const {
12880
+ children,
12881
+ group,
12882
+ minimised,
12883
+ isPreview,
12884
+ isPotentialCardDropTarget,
12885
+ onEditGroup,
12886
+ dndDisabled
12887
+ } = t0;
12888
+ const [isHovered, setIsHovered] = React.useState(false);
12889
+ const currentGroupName = group ?? "Views";
12890
+ const t1 = !isPotentialCardDropTarget ? "my-10" : "my-6";
12891
+ let t2;
12892
+ if ($[0] !== t1) {
12893
+ t2 = ui.cls(t1, "transition-all duration-200 ease-in-out");
12894
+ $[0] = t1;
12895
+ $[1] = t2;
12896
+ } else {
12897
+ t2 = $[1];
12898
+ }
12899
+ const t3 = `flex items-center ${isPreview ? "px-1 py-0.5 m-0" : "ml-3.5 mt-6"} `;
12900
+ let t4;
12901
+ let t5;
12902
+ if ($[2] === Symbol.for("react.memo_cache_sentinel")) {
12903
+ t4 = () => setIsHovered(true);
12904
+ t5 = () => setIsHovered(false);
12905
+ $[2] = t4;
12906
+ $[3] = t5;
12907
+ } else {
12908
+ t4 = $[2];
12909
+ t5 = $[3];
12910
+ }
12911
+ const t6 = isPreview ? "body2" : "caption";
12912
+ const t7 = `${isPreview ? "px-1 py-0.5" : "ml-3.5"} font-medium uppercase text-sm text-surface-600 dark:text-surface-400`;
12913
+ let t8;
12914
+ if ($[4] !== currentGroupName || $[5] !== t6 || $[6] !== t7) {
12915
+ t8 = /* @__PURE__ */ jsxRuntime.jsx(ui.Typography, { variant: t6, component: "h2", color: "secondary", className: t7, children: currentGroupName });
12916
+ $[4] = currentGroupName;
12917
+ $[5] = t6;
12918
+ $[6] = t7;
12919
+ $[7] = t8;
12920
+ } else {
12921
+ t8 = $[7];
12922
+ }
12923
+ let t9;
12924
+ if ($[8] !== currentGroupName || $[9] !== dndDisabled || $[10] !== isHovered || $[11] !== isPreview || $[12] !== onEditGroup) {
12925
+ t9 = !isPreview && onEditGroup && !dndDisabled && /* @__PURE__ */ jsxRuntime.jsx(ui.IconButton, { size: "smallest", onClick: (e) => {
12926
+ e.stopPropagation();
12927
+ onEditGroup(currentGroupName);
12928
+ }, className: ui.cls("ml-2 ", isHovered ? "opacity-100" : "opacity-0", "transition-opacity duration-100"), children: /* @__PURE__ */ jsxRuntime.jsx(ui.EditIcon, { size: "smallest" }) });
12929
+ $[8] = currentGroupName;
12930
+ $[9] = dndDisabled;
12931
+ $[10] = isHovered;
12932
+ $[11] = isPreview;
12933
+ $[12] = onEditGroup;
12934
+ $[13] = t9;
12935
+ } else {
12936
+ t9 = $[13];
12937
+ }
12938
+ let t10;
12939
+ if ($[14] !== t3 || $[15] !== t8 || $[16] !== t9) {
12940
+ t10 = /* @__PURE__ */ jsxRuntime.jsxs("div", { className: t3, onMouseEnter: t4, onMouseLeave: t5, children: [
12941
+ t8,
12942
+ t9
12943
+ ] });
12944
+ $[14] = t3;
12945
+ $[15] = t8;
12946
+ $[16] = t9;
12947
+ $[17] = t10;
12948
+ } else {
12949
+ t10 = $[17];
12950
+ }
12951
+ let t11;
12952
+ if ($[18] !== children || $[19] !== isPreview || $[20] !== minimised) {
12953
+ 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: {
12954
+ minHeight: "50px"
12955
+ } }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: ui.cls("mt-4", !minimised ? "pt-0" : ""), children });
12956
+ $[18] = children;
12957
+ $[19] = isPreview;
12958
+ $[20] = minimised;
12959
+ $[21] = t11;
12960
+ } else {
12961
+ t11 = $[21];
12962
+ }
12963
+ let t12;
12964
+ if ($[22] !== t10 || $[23] !== t11 || $[24] !== t2) {
12965
+ t12 = /* @__PURE__ */ jsxRuntime.jsxs("div", { className: t2, children: [
12966
+ t10,
12967
+ t11
12968
+ ] });
12969
+ $[22] = t10;
12970
+ $[23] = t11;
12971
+ $[24] = t2;
12972
+ $[25] = t12;
12973
+ } else {
12974
+ t12 = $[25];
12975
+ }
12976
+ return t12;
12977
+ }
12978
+ const NavigationCard = React.memo(function NavigationCard2(t0) {
12979
+ const $ = reactCompilerRuntime.c(25);
12980
+ const {
12981
+ name,
12982
+ description,
12983
+ icon,
12984
+ actions,
12985
+ onClick,
12986
+ shrink
12987
+ } = t0;
12988
+ const t1 = shrink && "w-full max-w-full min-h-0 scale-75";
12989
+ let t2;
12990
+ if ($[0] !== t1) {
12991
+ t2 = ui.cls("h-full p-4 cursor-pointer min-h-[230px] transition-all duration-200 ease-in-out", t1);
12992
+ $[0] = t1;
12993
+ $[1] = t2;
12994
+ } else {
12995
+ t2 = $[1];
12996
+ }
12997
+ let t3;
12998
+ if ($[2] !== onClick) {
12999
+ t3 = () => {
13000
+ onClick?.();
13001
+ };
13002
+ $[2] = onClick;
13003
+ $[3] = t3;
13004
+ } else {
13005
+ t3 = $[3];
13006
+ }
13007
+ let t4;
13008
+ if ($[4] !== actions) {
13009
+ t4 = /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-1", onClick: _temp$c, children: actions });
13010
+ $[4] = actions;
13011
+ $[5] = t4;
13012
+ } else {
13013
+ t4 = $[5];
13014
+ }
13015
+ let t5;
13016
+ if ($[6] !== icon || $[7] !== t4) {
13017
+ t5 = /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "h-10 flex items-center w-full justify-between text-surface-300 dark:text-surface-600", children: [
13018
+ icon,
13019
+ t4
13020
+ ] });
13021
+ $[6] = icon;
13022
+ $[7] = t4;
13023
+ $[8] = t5;
13024
+ } else {
13025
+ t5 = $[8];
13026
+ }
13027
+ let t6;
13028
+ if ($[9] !== name) {
13029
+ t6 = /* @__PURE__ */ jsxRuntime.jsx(ui.Typography, { gutterBottom: true, variant: "h5", component: "h2", children: name });
13030
+ $[9] = name;
13031
+ $[10] = t6;
13032
+ } else {
13033
+ t6 = $[10];
13034
+ }
13035
+ let t7;
13036
+ if ($[11] !== description) {
13037
+ t7 = description && /* @__PURE__ */ jsxRuntime.jsx(ui.Typography, { variant: "body2", color: "secondary", component: "div", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Markdown, { source: description, size: "small" }) });
13038
+ $[11] = description;
13039
+ $[12] = t7;
13040
+ } else {
13041
+ t7 = $[12];
13042
+ }
13043
+ let t8;
13044
+ if ($[13] !== t5 || $[14] !== t6 || $[15] !== t7) {
13045
+ t8 = /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-grow w-full", children: [
13046
+ t5,
13047
+ t6,
13048
+ t7
13049
+ ] });
13050
+ $[13] = t5;
13051
+ $[14] = t6;
13052
+ $[15] = t7;
13053
+ $[16] = t8;
13054
+ } else {
13055
+ t8 = $[16];
13056
+ }
13057
+ let t9;
13058
+ if ($[17] === Symbol.for("react.memo_cache_sentinel")) {
13059
+ t9 = {
13060
+ alignSelf: "flex-end"
13061
+ };
13062
+ $[17] = t9;
13063
+ } else {
13064
+ t9 = $[17];
13065
+ }
13066
+ let t10;
13067
+ if ($[18] === Symbol.for("react.memo_cache_sentinel")) {
13068
+ t10 = /* @__PURE__ */ jsxRuntime.jsx("div", { style: t9, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-4", children: /* @__PURE__ */ jsxRuntime.jsx(ui.ArrowForwardIcon, { className: "text-primary" }) }) });
13069
+ $[18] = t10;
13070
+ } else {
13071
+ t10 = $[18];
13072
+ }
13073
+ let t11;
13074
+ if ($[19] !== t8) {
13075
+ t11 = /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-start h-full", children: [
13076
+ t8,
13077
+ t10
13078
+ ] });
13079
+ $[19] = t8;
13080
+ $[20] = t11;
13081
+ } else {
13082
+ t11 = $[20];
13083
+ }
13084
+ let t12;
13085
+ if ($[21] !== t11 || $[22] !== t2 || $[23] !== t3) {
13086
+ t12 = /* @__PURE__ */ jsxRuntime.jsx(ui.Card, { className: t2, onClick: t3, children: t11 });
13087
+ $[21] = t11;
13088
+ $[22] = t2;
13089
+ $[23] = t3;
13090
+ $[24] = t12;
13091
+ } else {
13092
+ t12 = $[24];
13093
+ }
13094
+ return t12;
13095
+ });
13096
+ function _temp$c(event) {
13097
+ event.preventDefault();
13098
+ event.stopPropagation();
13099
+ }
13100
+ function SmallNavigationCard(t0) {
13101
+ const $ = reactCompilerRuntime.c(10);
13102
+ const {
13103
+ name,
13104
+ url,
13105
+ icon
13106
+ } = t0;
13107
+ let t1;
13108
+ if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
13109
+ t1 = ui.cls(ui.cardMixin, ui.cardClickableMixin, "cursor-pointer flex flex-row items-center px-4 py-2 text-inherit dark:text-inherit visited:text-inherit visited:dark:text-inherit hover:text-inherit hover:dark:text-inherit ");
13110
+ $[0] = t1;
12871
13111
  } else {
12872
13112
  t1 = $[0];
12873
13113
  }
@@ -12913,7 +13153,7 @@
12913
13153
  return t5;
12914
13154
  }
12915
13155
  function NavigationCardBinding(t0) {
12916
- const $ = reactCompilerRuntime.c(34);
13156
+ const $ = reactCompilerRuntime.c(35);
12917
13157
  const {
12918
13158
  path,
12919
13159
  collection,
@@ -12922,7 +13162,8 @@
12922
13162
  name,
12923
13163
  description,
12924
13164
  onClick,
12925
- type
13165
+ type,
13166
+ shrink
12926
13167
  } = t0;
12927
13168
  const userConfigurationPersistence = useUserConfigurationPersistence();
12928
13169
  const t1 = collection ?? view;
@@ -13029,533 +13270,1030 @@
13029
13270
  t6 = $[27];
13030
13271
  }
13031
13272
  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 });
13273
+ if ($[28] !== actions || $[29] !== collectionIcon || $[30] !== description || $[31] !== name || $[32] !== shrink || $[33] !== t6) {
13274
+ t7 = /* @__PURE__ */ jsxRuntime.jsx(NavigationCard, { icon: collectionIcon, name, description, actions, onClick: t6, shrink });
13034
13275
  $[28] = actions;
13035
13276
  $[29] = collectionIcon;
13036
13277
  $[30] = description;
13037
13278
  $[31] = name;
13038
- $[32] = t6;
13039
- $[33] = t7;
13279
+ $[32] = shrink;
13280
+ $[33] = t6;
13281
+ $[34] = t7;
13040
13282
  } else {
13041
- t7 = $[33];
13283
+ t7 = $[34];
13042
13284
  }
13043
13285
  return t7;
13044
13286
  }
13045
- function NavigationChip(t0) {
13046
- const $ = reactCompilerRuntime.c(18);
13287
+ const animateLayoutChanges = (args) => sortable.defaultAnimateLayoutChanges({
13288
+ ...args,
13289
+ wasDragging: true
13290
+ });
13291
+ const dropAnimationConfig = {};
13292
+ const cloneSerializableNavigationEntry = (entry) => {
13293
+ const clonedEntry = {
13294
+ id: entry.id,
13295
+ path: entry.path,
13296
+ url: entry.url,
13297
+ name: entry.name,
13298
+ type: entry.type,
13299
+ collection: entry.collection ? {
13300
+ ...entry.collection
13301
+ } : void 0,
13302
+ view: entry.view ? {
13303
+ ...entry.view
13304
+ } : void 0,
13305
+ ...entry.group && {
13306
+ group: entry.group
13307
+ },
13308
+ ...entry.description && {
13309
+ description: entry.description
13310
+ }
13311
+ };
13312
+ return clonedEntry;
13313
+ };
13314
+ const cloneItemsForDnd = (items) => items.map((g) => ({
13315
+ name: g.name,
13316
+ entries: g.entries.map(cloneSerializableNavigationEntry)
13317
+ }));
13318
+ function SortableNavigationCard(t0) {
13319
+ const $ = reactCompilerRuntime.c(17);
13047
13320
  const {
13048
- entry
13321
+ entry,
13322
+ onClick
13049
13323
  } = t0;
13050
- const navigate = reactRouterDom.useNavigate();
13051
- const userConfigurationPersistence = useUserConfigurationPersistence();
13052
- if (!userConfigurationPersistence) {
13053
- return null;
13054
- }
13055
13324
  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;
13325
+ if ($[0] !== entry.url) {
13326
+ t1 = {
13327
+ id: entry.url,
13328
+ animateLayoutChanges
13329
+ };
13330
+ $[0] = entry.url;
13331
+ $[1] = t1;
13061
13332
  } else {
13062
- t1 = $[2];
13333
+ t1 = $[1];
13063
13334
  }
13064
- const favourite = t1;
13335
+ const {
13336
+ setNodeRef,
13337
+ listeners: listeners2,
13338
+ attributes,
13339
+ transform,
13340
+ transition,
13341
+ isDragging
13342
+ } = sortable.useSortable(t1);
13065
13343
  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;
13344
+ let t3;
13345
+ if ($[2] !== transform) {
13346
+ t3 = transform ? utilities.CSS.Transform.toString(transform) : void 0;
13347
+ $[2] = transform;
13348
+ $[3] = t3;
13080
13349
  } else {
13081
- t2 = $[6];
13350
+ t3 = $[3];
13082
13351
  }
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;
13352
+ const t4 = isDragging ? 0 : 1;
13353
+ let t5;
13354
+ if ($[4] !== t3 || $[5] !== t4 || $[6] !== transition) {
13355
+ t5 = {
13356
+ transform: t3,
13357
+ transition,
13358
+ opacity: t4
13359
+ };
13360
+ $[4] = t3;
13361
+ $[5] = t4;
13362
+ $[6] = transition;
13363
+ $[7] = t5;
13090
13364
  } else {
13091
- t3 = $[9];
13365
+ t5 = $[7];
13366
+ }
13367
+ t2 = t5;
13368
+ const style = t2;
13369
+ let t6;
13370
+ if ($[8] !== entry || $[9] !== onClick) {
13371
+ t6 = /* @__PURE__ */ jsxRuntime.jsx(NavigationCardBinding, { ...entry, onClick });
13372
+ $[8] = entry;
13373
+ $[9] = onClick;
13374
+ $[10] = t6;
13375
+ } else {
13376
+ t6 = $[10];
13377
+ }
13378
+ let t7;
13379
+ if ($[11] !== attributes || $[12] !== listeners2 || $[13] !== setNodeRef || $[14] !== style || $[15] !== t6) {
13380
+ t7 = /* @__PURE__ */ jsxRuntime.jsx("div", { ref: setNodeRef, style, ...attributes, ...listeners2, children: t6 });
13381
+ $[11] = attributes;
13382
+ $[12] = listeners2;
13383
+ $[13] = setNodeRef;
13384
+ $[14] = style;
13385
+ $[15] = t6;
13386
+ $[16] = t7;
13387
+ } else {
13388
+ t7 = $[16];
13389
+ }
13390
+ return t7;
13391
+ }
13392
+ function NavigationGroupDroppable(t0) {
13393
+ const $ = reactCompilerRuntime.c(11);
13394
+ const {
13395
+ id,
13396
+ itemIds,
13397
+ children,
13398
+ isPotentialCardDropTarget: t1
13399
+ } = t0;
13400
+ const isPotentialCardDropTarget = t1 === void 0 ? false : t1;
13401
+ let t2;
13402
+ if ($[0] !== id) {
13403
+ t2 = {
13404
+ id
13405
+ };
13406
+ $[0] = id;
13407
+ $[1] = t2;
13408
+ } else {
13409
+ t2 = $[1];
13410
+ }
13411
+ const {
13412
+ setNodeRef
13413
+ } = core.useDroppable(t2);
13414
+ const t3 = isPotentialCardDropTarget ? "p-2 bg-surface-accent-200 dark:bg-surface-accent-800 rounded-lg" : void 0;
13415
+ let t4;
13416
+ if ($[2] !== t3) {
13417
+ t4 = ui.cls(t3, "transition-all duration-200 ease-in-out");
13418
+ $[2] = t3;
13419
+ $[3] = t4;
13420
+ } else {
13421
+ t4 = $[3];
13092
13422
  }
13093
- const t4 = favourite ? "text-secondary" : "text-surface-400 dark:text-surface-500";
13094
13423
  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;
13424
+ if ($[4] !== children || $[5] !== itemIds) {
13425
+ t5 = /* @__PURE__ */ jsxRuntime.jsx(sortable.SortableContext, { items: itemIds, strategy: sortable.rectSortingStrategy, children });
13426
+ $[4] = children;
13427
+ $[5] = itemIds;
13428
+ $[6] = t5;
13100
13429
  } else {
13101
- t5 = $[12];
13430
+ t5 = $[6];
13102
13431
  }
13103
13432
  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;
13433
+ if ($[7] !== setNodeRef || $[8] !== t4 || $[9] !== t5) {
13434
+ t6 = /* @__PURE__ */ jsxRuntime.jsx("div", { ref: setNodeRef, className: t4, children: t5 });
13435
+ $[7] = setNodeRef;
13436
+ $[8] = t4;
13437
+ $[9] = t5;
13438
+ $[10] = t6;
13111
13439
  } else {
13112
- t6 = $[17];
13440
+ t6 = $[10];
13113
13441
  }
13114
13442
  return t6;
13115
13443
  }
13116
- function FavouritesView(t0) {
13117
- const $ = reactCompilerRuntime.c(17);
13118
- const navigationController = useNavigationController();
13119
- const userConfigurationPersistence = useUserConfigurationPersistence();
13120
- if (!userConfigurationPersistence) {
13121
- return null;
13122
- }
13444
+ function SortableNavigationGroup(t0) {
13445
+ const $ = reactCompilerRuntime.c(15);
13446
+ const {
13447
+ groupName,
13448
+ children,
13449
+ disabled
13450
+ } = t0;
13123
13451
  let t1;
13124
- if ($[0] !== userConfigurationPersistence?.favouritePaths) {
13125
- t1 = userConfigurationPersistence?.favouritePaths ?? [];
13126
- $[0] = userConfigurationPersistence?.favouritePaths;
13127
- $[1] = t1;
13452
+ if ($[0] !== disabled || $[1] !== groupName) {
13453
+ t1 = {
13454
+ id: groupName,
13455
+ animateLayoutChanges,
13456
+ disabled
13457
+ };
13458
+ $[0] = disabled;
13459
+ $[1] = groupName;
13460
+ $[2] = t1;
13128
13461
  } else {
13129
- t1 = $[1];
13462
+ t1 = $[2];
13130
13463
  }
13131
- let T0;
13464
+ const {
13465
+ attributes,
13466
+ listeners: listeners2,
13467
+ setNodeRef,
13468
+ transform,
13469
+ transition,
13470
+ isDragging
13471
+ } = sortable.useSortable(t1);
13132
13472
  let t2;
13133
13473
  let t3;
13134
- 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;
13152
- $[5] = t2;
13153
- $[6] = t3;
13154
- $[7] = t4;
13474
+ if ($[3] !== transform) {
13475
+ t3 = transform ? utilities.CSS.Transform.toString(transform) : void 0;
13476
+ $[3] = transform;
13477
+ $[4] = t3;
13155
13478
  } else {
13156
- T0 = $[4];
13157
- t2 = $[5];
13158
- t3 = $[6];
13159
- t4 = $[7];
13479
+ t3 = $[4];
13160
13480
  }
13481
+ const t4 = isDragging ? 0 : 1;
13161
13482
  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;
13483
+ if ($[5] !== t3 || $[6] !== t4 || $[7] !== transition) {
13484
+ t5 = {
13485
+ transform: t3,
13486
+ transition,
13487
+ opacity: t4
13488
+ };
13489
+ $[5] = t3;
13490
+ $[6] = t4;
13491
+ $[7] = transition;
13492
+ $[8] = t5;
13167
13493
  } else {
13168
- t5 = $[12];
13494
+ t5 = $[8];
13169
13495
  }
13496
+ t2 = t5;
13497
+ const style = t2;
13170
13498
  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;
13175
- $[15] = t5;
13176
- $[16] = t6;
13499
+ if ($[9] !== attributes || $[10] !== children || $[11] !== listeners2 || $[12] !== setNodeRef || $[13] !== style) {
13500
+ t6 = /* @__PURE__ */ jsxRuntime.jsx("div", { ref: setNodeRef, style, ...attributes, ...listeners2, children });
13501
+ $[9] = attributes;
13502
+ $[10] = children;
13503
+ $[11] = listeners2;
13504
+ $[12] = setNodeRef;
13505
+ $[13] = style;
13506
+ $[14] = t6;
13177
13507
  } else {
13178
- t6 = $[16];
13508
+ t6 = $[14];
13179
13509
  }
13180
13510
  return t6;
13181
13511
  }
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]);
13512
+ function useHomePageDnd({
13513
+ items: dndItems,
13514
+ setItems: setDndItems,
13515
+ disabled,
13516
+ onCardMovedBetweenGroups,
13517
+ onGroupMoved,
13518
+ onNewGroupDrop,
13519
+ onPersist
13520
+ }) {
13521
+ const [activeId, setActiveId] = React.useState(null);
13522
+ const [activeIsGroup, setActiveIsGroup] = React.useState(false);
13523
+ const [currentDraggingGroupId, setCurrentDraggingGroupId] = React.useState(null);
13524
+ const [dndKitActiveNode, setDndKitActiveNode] = React.useState(null);
13525
+ const [isDraggingCardOnly, setIsDraggingCardOnly] = React.useState(false);
13526
+ const [dialogOpenForGroup, setDialogOpenForGroup] = React.useState(null);
13527
+ const [isHoveringNewGroupDropZone, setIsHoveringNewGroupDropZone] = React.useState(false);
13528
+ const interimItemsRef = React.useRef(null);
13207
13529
  React.useEffect(() => {
13208
- if (!containerRef.current || !scrollsMap[location.key]) return;
13209
- containerRef.current.scrollTo({
13210
- top: scrollsMap[location.key],
13211
- behavior: "auto"
13530
+ interimItemsRef.current = dndItems;
13531
+ }, [dndItems]);
13532
+ const mouseSensor = core.useSensor(core.MouseSensor, {
13533
+ activationConstraint: {
13534
+ distance: 10
13535
+ }
13536
+ });
13537
+ const touchSensor = core.useSensor(core.TouchSensor, {
13538
+ activationConstraint: {
13539
+ delay: 150,
13540
+ tolerance: 5
13541
+ }
13542
+ });
13543
+ const keyboardSensor = core.useSensor(core.KeyboardSensor);
13544
+ const sensors = core.useSensors(...disabled ? [] : [mouseSensor, touchSensor, keyboardSensor]);
13545
+ const dndContainers = React.useMemo(() => dndItems.map((g) => g.name), [dndItems]);
13546
+ const findDndContainer = React.useCallback((id) => {
13547
+ if (!id) return void 0;
13548
+ const group = dndItems.find((g_0) => g_0.name === id);
13549
+ if (group) return group.name;
13550
+ for (const g_1 of dndItems) {
13551
+ if (g_1.entries.some((e) => e.url === id)) return g_1.name;
13552
+ }
13553
+ return void 0;
13554
+ }, [dndItems]);
13555
+ const lastOverId = React.useRef(null);
13556
+ const recentlyMovedToNewContainer = React.useRef(false);
13557
+ const collisionDetection = React.useCallback((args) => {
13558
+ if (disabled || !activeId) return [];
13559
+ if (activeIsGroup) {
13560
+ const groups = args.droppableContainers.filter((c) => dndItems.some((g_2) => g_2.name === c.id));
13561
+ if (!groups.length) return [];
13562
+ return core.closestCenter({
13563
+ ...args,
13564
+ droppableContainers: groups
13565
+ });
13566
+ }
13567
+ const pointer = core.pointerWithin(args);
13568
+ if (pointer.length) {
13569
+ const zone = pointer.find((c_0) => c_0.id === "new-group-drop-zone");
13570
+ if (zone) return [zone];
13571
+ const container = pointer.find((c_1) => dndItems.some((g_3) => g_3.name === c_1.id));
13572
+ if (container) {
13573
+ const itemsIn = dndItems.find((g_4) => g_4.name === container.id)?.entries;
13574
+ if (itemsIn?.length) {
13575
+ const closest = core.closestCorners({
13576
+ ...args,
13577
+ droppableContainers: args.droppableContainers.filter((c_2) => itemsIn.some((e_0) => e_0.url === c_2.id))
13578
+ });
13579
+ if (closest.length) return closest;
13580
+ }
13581
+ return [container];
13582
+ }
13583
+ const first = core.getFirstCollision(pointer, "id");
13584
+ if (first) return [{
13585
+ id: first
13586
+ }];
13587
+ }
13588
+ const rects = core.rectIntersection(args);
13589
+ const zoneRect = rects.find((c_3) => c_3.id === "new-group-drop-zone");
13590
+ if (zoneRect) return [zoneRect];
13591
+ let overId = core.getFirstCollision(rects, "id");
13592
+ if (overId != null) {
13593
+ const overIsContainer = dndItems.some((g_5) => g_5.name === overId);
13594
+ if (overIsContainer) {
13595
+ const itemsIn_0 = dndItems.find((g_6) => g_6.name === overId)?.entries;
13596
+ if (itemsIn_0?.length) {
13597
+ const closestItem = core.closestCorners({
13598
+ ...args,
13599
+ droppableContainers: args.droppableContainers.filter((c_4) => itemsIn_0.some((e_1) => e_1.url === c_4.id))
13600
+ })[0]?.id;
13601
+ if (closestItem) overId = closestItem;
13602
+ }
13603
+ }
13604
+ lastOverId.current = overId;
13605
+ return [{
13606
+ id: overId
13607
+ }];
13608
+ }
13609
+ if (recentlyMovedToNewContainer.current && lastOverId.current && !activeIsGroup) return [{
13610
+ id: lastOverId.current
13611
+ }];
13612
+ return [];
13613
+ }, [activeId, dndItems, disabled, activeIsGroup]);
13614
+ const handleDragStart = ({
13615
+ active
13616
+ }) => {
13617
+ setDndKitActiveNode(active);
13618
+ if (disabled) return;
13619
+ const isGroup = dndItems.some((g_7) => g_7.name === active.id);
13620
+ if (!active.data.current) active.data.current = {};
13621
+ active.data.current.type = isGroup ? "group" : "item";
13622
+ setActiveId(active.id);
13623
+ setActiveIsGroup(isGroup);
13624
+ setIsDraggingCardOnly(!isGroup);
13625
+ if (isGroup) setCurrentDraggingGroupId(active.id);
13626
+ recentlyMovedToNewContainer.current = false;
13627
+ };
13628
+ const handleDragOver = ({
13629
+ active: active_0,
13630
+ over
13631
+ }) => {
13632
+ if (disabled || !over) return;
13633
+ const activeIdNow = active_0.id;
13634
+ const overIdNow = over.id;
13635
+ if (activeIdNow === overIdNow) return;
13636
+ if (activeIsGroup) return;
13637
+ const activeCont = findDndContainer(activeIdNow);
13638
+ const overCont = findDndContainer(overIdNow);
13639
+ if (!activeCont) return;
13640
+ if (overCont && activeCont !== overCont) {
13641
+ recentlyMovedToNewContainer.current = true;
13642
+ const newState = cloneItemsForDnd(dndItems);
13643
+ const srcIdx = newState.findIndex((g_8) => g_8.name === activeCont);
13644
+ const tgtIdx = newState.findIndex((g_9) => g_9.name === overCont);
13645
+ if (srcIdx === -1 || tgtIdx === -1) return;
13646
+ const src = newState[srcIdx];
13647
+ const tgt = newState[tgtIdx];
13648
+ const idxInSrc = src.entries.findIndex((e_2) => e_2.url === activeIdNow);
13649
+ if (idxInSrc === -1) return;
13650
+ const [moved] = src.entries.splice(idxInSrc, 1);
13651
+ tgt.entries.push(moved);
13652
+ interimItemsRef.current = newState;
13653
+ setDndItems(newState);
13654
+ } else if (activeCont === overCont) {
13655
+ recentlyMovedToNewContainer.current = false;
13656
+ }
13657
+ };
13658
+ const handleDragEnd = ({
13659
+ active: active_1,
13660
+ over: over_0
13661
+ }) => {
13662
+ if (disabled || !over_0) {
13663
+ resetDragState();
13664
+ return;
13665
+ }
13666
+ const activeIdNow_0 = active_1.id;
13667
+ const overIdNow_0 = over_0.id;
13668
+ if (activeIsGroup) {
13669
+ if (activeIdNow_0 !== overIdNow_0 && dndItems.some((g_12) => g_12.name === overIdNow_0)) {
13670
+ const from = dndItems.findIndex((g_10) => g_10.name === activeIdNow_0);
13671
+ const to = dndItems.findIndex((g_11) => g_11.name === overIdNow_0);
13672
+ if (from !== -1 && to !== -1) {
13673
+ const newState_0 = sortable.arrayMove(dndItems, from, to);
13674
+ setDndItems(newState_0);
13675
+ onPersist?.(newState_0);
13676
+ onGroupMoved?.(activeIdNow_0, from, to);
13677
+ }
13678
+ }
13679
+ } else {
13680
+ const activeCont_0 = findDndContainer(activeIdNow_0);
13681
+ if (overIdNow_0 === "new-group-drop-zone") {
13682
+ if (activeCont_0) {
13683
+ const newState_1 = cloneItemsForDnd(dndItems);
13684
+ const srcIdx_0 = newState_1.findIndex((g_13) => g_13.name === activeCont_0);
13685
+ if (srcIdx_0 !== -1) {
13686
+ const src_0 = newState_1[srcIdx_0];
13687
+ const idxInSrc_0 = src_0.entries.findIndex((e_3) => e_3.url === activeIdNow_0);
13688
+ if (idxInSrc_0 !== -1) {
13689
+ const [dragged] = src_0.entries.splice(idxInSrc_0, 1);
13690
+ if (src_0.entries.length === 0) newState_1.splice(srcIdx_0, 1);
13691
+ let tentative = "New Group";
13692
+ let counter = 1;
13693
+ while (newState_1.some((g_14) => g_14.name === tentative)) tentative = `New Group ${counter++}`;
13694
+ newState_1.push({
13695
+ name: tentative,
13696
+ entries: [dragged]
13697
+ });
13698
+ setDndItems(newState_1);
13699
+ onPersist?.(newState_1);
13700
+ setDialogOpenForGroup(tentative);
13701
+ onNewGroupDrop?.();
13702
+ }
13703
+ }
13704
+ }
13705
+ } else {
13706
+ const overCont_0 = findDndContainer(overIdNow_0);
13707
+ if (activeCont_0 === overCont_0) {
13708
+ const grpIdx = dndItems.findIndex((g_15) => g_15.name === activeCont_0);
13709
+ if (grpIdx !== -1) {
13710
+ const group_0 = dndItems[grpIdx];
13711
+ const oldIdx = group_0.entries.findIndex((e_4) => e_4.url === activeIdNow_0);
13712
+ let newIdx = group_0.entries.findIndex((e_5) => e_5.url === overIdNow_0);
13713
+ if (newIdx === -1 && overIdNow_0 === activeCont_0) newIdx = group_0.entries.length - 1;
13714
+ if (oldIdx !== -1 && newIdx !== -1 && oldIdx !== newIdx) {
13715
+ const reordered = sortable.arrayMove(group_0.entries, oldIdx, newIdx);
13716
+ const newState_2 = [...dndItems];
13717
+ newState_2[grpIdx] = {
13718
+ ...group_0,
13719
+ entries: reordered
13720
+ };
13721
+ setDndItems(newState_2);
13722
+ onPersist?.(newState_2);
13723
+ }
13724
+ }
13725
+ } else if (recentlyMovedToNewContainer.current && interimItemsRef.current) {
13726
+ onPersist?.(interimItemsRef.current);
13727
+ }
13728
+ onCardMovedBetweenGroups?.(dndItems.flatMap((g_16) => g_16.entries).find((e_6) => e_6.url === activeIdNow_0));
13729
+ }
13730
+ }
13731
+ resetDragState();
13732
+ };
13733
+ const resetDragState = () => {
13734
+ setDndKitActiveNode(null);
13735
+ setActiveId(null);
13736
+ setActiveIsGroup(false);
13737
+ setCurrentDraggingGroupId(null);
13738
+ setIsDraggingCardOnly(false);
13739
+ recentlyMovedToNewContainer.current = false;
13740
+ };
13741
+ const handleDragCancel = () => resetDragState();
13742
+ const handleRenameGroup = (oldName, newName) => {
13743
+ setDndItems((current) => {
13744
+ const idx = current.findIndex((g_17) => g_17.name === oldName);
13745
+ if (idx === -1) return current;
13746
+ if (current.some((g_18) => g_18.name === newName && g_18.name !== oldName)) return current;
13747
+ const updated = [...current];
13748
+ updated[idx] = {
13749
+ ...updated[idx],
13750
+ name: newName
13751
+ };
13752
+ onPersist?.(updated);
13753
+ return updated;
13212
13754
  });
13213
- }, [location]);
13755
+ };
13756
+ const activeItemForOverlay = React.useMemo(() => {
13757
+ if (disabled || !activeId || activeIsGroup) return null;
13758
+ return dndItems.flatMap((g_19) => g_19.entries).find((e_7) => e_7.url === activeId) || null;
13759
+ }, [activeId, dndItems, disabled, activeIsGroup]);
13760
+ const activeGroupData = React.useMemo(() => {
13761
+ if (disabled || !activeId || !activeIsGroup) return null;
13762
+ return dndItems.find((g_20) => g_20.name === activeId) || null;
13763
+ }, [activeId, dndItems, disabled, activeIsGroup]);
13214
13764
  return {
13215
- containerRef,
13216
- scroll,
13217
- direction
13765
+ sensors,
13766
+ collisionDetection,
13767
+ onDragStart: handleDragStart,
13768
+ onDragOver: handleDragOver,
13769
+ onDragEnd: handleDragEnd,
13770
+ onDragCancel: handleDragCancel,
13771
+ dropAnimation: dropAnimationConfig,
13772
+ activeItemForOverlay,
13773
+ activeGroupData,
13774
+ draggingGroupId: currentDraggingGroupId,
13775
+ containers: dndContainers,
13776
+ dndKitActiveNode,
13777
+ isDraggingCardOnly,
13778
+ dialogOpenForGroup,
13779
+ setDialogOpenForGroup,
13780
+ handleRenameGroup,
13781
+ isHoveringNewGroupDropZone,
13782
+ setIsHoveringNewGroupDropZone
13218
13783
  };
13219
13784
  }
13220
- function DefaultHomePage(t0) {
13221
- const $ = reactCompilerRuntime.c(71);
13785
+ function NewGroupDropZone(t0) {
13786
+ const $ = reactCompilerRuntime.c(15);
13222
13787
  const {
13223
- additionalActions,
13224
- additionalChildrenStart,
13225
- additionalChildrenEnd
13788
+ disabled,
13789
+ setIsHovering
13226
13790
  } = t0;
13227
- const context = useFireCMSContext();
13228
- const customizationController = useCustomizationController();
13229
- const navigationController = useNavigationController();
13230
- const fuse = React.useRef(null);
13231
- if (!navigationController.topLevelNavigation) {
13232
- throw Error("Navigation not ready in FireCMSHomePage");
13791
+ let t1;
13792
+ if ($[0] !== disabled) {
13793
+ t1 = {
13794
+ id: "new-group-drop-zone",
13795
+ disabled
13796
+ };
13797
+ $[0] = disabled;
13798
+ $[1] = t1;
13799
+ } else {
13800
+ t1 = $[1];
13233
13801
  }
13234
13802
  const {
13235
- containerRef,
13236
- direction
13237
- } = useRestoreScroll();
13803
+ setNodeRef,
13804
+ isOver
13805
+ } = core.useDroppable(t1);
13806
+ const [isVisible, setIsVisible] = React.useState(false);
13807
+ let t2;
13808
+ if ($[2] !== disabled) {
13809
+ t2 = {
13810
+ onDragStart(t32) {
13811
+ const {
13812
+ active
13813
+ } = t32;
13814
+ if (disabled) {
13815
+ return;
13816
+ }
13817
+ const tp = active.data.current?.type;
13818
+ setIsVisible(tp === "item");
13819
+ },
13820
+ onDragEnd() {
13821
+ setIsVisible(false);
13822
+ },
13823
+ onDragCancel() {
13824
+ setIsVisible(false);
13825
+ }
13826
+ };
13827
+ $[2] = disabled;
13828
+ $[3] = t2;
13829
+ } else {
13830
+ t2 = $[3];
13831
+ }
13832
+ core.useDndMonitor(t2);
13833
+ let t3;
13834
+ let t4;
13835
+ if ($[4] !== isOver || $[5] !== isVisible || $[6] !== setIsHovering) {
13836
+ t3 = () => {
13837
+ setIsHovering(isOver && isVisible);
13838
+ };
13839
+ t4 = [isOver, isVisible, setIsHovering];
13840
+ $[4] = isOver;
13841
+ $[5] = isVisible;
13842
+ $[6] = setIsHovering;
13843
+ $[7] = t3;
13844
+ $[8] = t4;
13845
+ } else {
13846
+ t3 = $[7];
13847
+ t4 = $[8];
13848
+ }
13849
+ React.useEffect(t3, t4);
13850
+ if (!isVisible || disabled) {
13851
+ return null;
13852
+ }
13853
+ 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";
13854
+ let t6;
13855
+ if ($[9] !== t5) {
13856
+ 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);
13857
+ $[9] = t5;
13858
+ $[10] = t6;
13859
+ } else {
13860
+ t6 = $[10];
13861
+ }
13862
+ let t7;
13863
+ if ($[11] === Symbol.for("react.memo_cache_sentinel")) {
13864
+ 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" }) });
13865
+ $[11] = t7;
13866
+ } else {
13867
+ t7 = $[11];
13868
+ }
13869
+ let t8;
13870
+ if ($[12] !== setNodeRef || $[13] !== t6) {
13871
+ t8 = /* @__PURE__ */ jsxRuntime.jsx("div", { ref: setNodeRef, className: t6, children: t7 });
13872
+ $[12] = setNodeRef;
13873
+ $[13] = t6;
13874
+ $[14] = t8;
13875
+ } else {
13876
+ t8 = $[14];
13877
+ }
13878
+ return t8;
13879
+ }
13880
+ function RenameGroupDialog(t0) {
13881
+ const $ = reactCompilerRuntime.c(41);
13238
13882
  const {
13239
- navigationEntries,
13240
- groups
13241
- } = navigationController.topLevelNavigation;
13242
- const [filteredUrls, setFilteredUrls] = React.useState(null);
13243
- const performingSearch = Boolean(filteredUrls);
13883
+ open,
13884
+ initialName,
13885
+ existingGroupNames,
13886
+ onClose,
13887
+ onRename
13888
+ } = t0;
13889
+ const [name, setName] = React.useState(initialName);
13890
+ const [error, setError] = React.useState(null);
13891
+ const inputRef = React.useRef(null);
13244
13892
  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;
13893
+ let t2;
13894
+ if ($[0] !== initialName || $[1] !== open) {
13895
+ t1 = () => {
13896
+ if (open) {
13897
+ setName(initialName);
13898
+ setError(null);
13899
+ setTimeout(() => {
13900
+ if (inputRef.current) {
13901
+ inputRef.current.focus();
13902
+ inputRef.current.select();
13903
+ }
13904
+ }, 100);
13905
+ }
13906
+ };
13907
+ t2 = [initialName, open];
13908
+ $[0] = initialName;
13909
+ $[1] = open;
13249
13910
  $[2] = t1;
13911
+ $[3] = t2;
13250
13912
  } else {
13251
13913
  t1 = $[2];
13914
+ t2 = $[3];
13252
13915
  }
13253
- const filteredNavigationEntries = t1;
13254
- let t2;
13916
+ React.useEffect(t1, t2);
13255
13917
  let t3;
13256
- if ($[3] !== navigationEntries) {
13257
- t2 = () => {
13258
- fuse.current = new Fuse(navigationEntries, {
13259
- keys: ["name", "description", "group", "path"]
13260
- });
13918
+ if ($[4] !== existingGroupNames) {
13919
+ t3 = (event) => {
13920
+ const newName = event.target.value;
13921
+ setName(newName);
13922
+ if (!newName.trim()) {
13923
+ setError("Group name cannot be empty.");
13924
+ } else {
13925
+ if (existingGroupNames.includes(newName.trim())) {
13926
+ setError("This group name already exists.");
13927
+ } else {
13928
+ setError(null);
13929
+ }
13930
+ }
13261
13931
  };
13262
- t3 = [navigationEntries];
13263
- $[3] = navigationEntries;
13264
- $[4] = t2;
13932
+ $[4] = existingGroupNames;
13265
13933
  $[5] = t3;
13266
13934
  } else {
13267
- t2 = $[4];
13268
13935
  t3 = $[5];
13269
13936
  }
13270
- React.useEffect(t2, t3);
13937
+ const handleNameChange = t3;
13271
13938
  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));
13939
+ if ($[6] !== error || $[7] !== existingGroupNames || $[8] !== name || $[9] !== onClose || $[10] !== onRename) {
13940
+ t4 = () => {
13941
+ const trimmedName = name.trim();
13942
+ if (!trimmedName) {
13943
+ setError("Group name cannot be empty.");
13944
+ return;
13945
+ }
13946
+ if (existingGroupNames.includes(trimmedName)) {
13947
+ setError("This group name already exists.");
13948
+ return;
13949
+ }
13950
+ if (!error) {
13951
+ onRename(trimmedName);
13952
+ onClose();
13953
+ }
13954
+ };
13955
+ $[6] = error;
13956
+ $[7] = existingGroupNames;
13957
+ $[8] = name;
13958
+ $[9] = onClose;
13959
+ $[10] = onRename;
13960
+ $[11] = t4;
13961
+ } else {
13962
+ t4 = $[11];
13963
+ }
13964
+ const handleSave = t4;
13965
+ let t5;
13966
+ if ($[12] !== existingGroupNames || $[13] !== handleSave || $[14] !== name) {
13967
+ t5 = (event_0) => {
13968
+ if (event_0.key === "Enter") {
13969
+ event_0.preventDefault();
13970
+ const trimmedName_0 = name.trim();
13971
+ let currentError = null;
13972
+ if (!trimmedName_0) {
13973
+ currentError = "Group name cannot be empty.";
13974
+ } else {
13975
+ if (existingGroupNames.includes(trimmedName_0)) {
13976
+ currentError = "This group name already exists.";
13977
+ }
13978
+ }
13979
+ if (!currentError && trimmedName_0) {
13980
+ handleSave();
13981
+ } else {
13982
+ if (currentError) {
13983
+ setError(currentError);
13984
+ }
13280
13985
  }
13281
13986
  }
13282
13987
  };
13283
- $[6] = t4;
13988
+ $[12] = existingGroupNames;
13989
+ $[13] = handleSave;
13990
+ $[14] = name;
13991
+ $[15] = t5;
13992
+ } else {
13993
+ t5 = $[15];
13994
+ }
13995
+ const handleKeyDown = t5;
13996
+ if (!open) {
13997
+ return null;
13998
+ }
13999
+ let t6;
14000
+ if ($[16] === Symbol.for("react.memo_cache_sentinel")) {
14001
+ t6 = /* @__PURE__ */ jsxRuntime.jsx(ui.DialogTitle, { children: "Rename Group" });
14002
+ $[16] = t6;
14003
+ } else {
14004
+ t6 = $[16];
14005
+ }
14006
+ const t7 = !!error;
14007
+ const t8 = error ? "group-name-error" : void 0;
14008
+ let t9;
14009
+ if ($[17] !== handleKeyDown || $[18] !== handleNameChange || $[19] !== name || $[20] !== t7 || $[21] !== t8) {
14010
+ t9 = /* @__PURE__ */ jsxRuntime.jsx(ui.TextField, { inputRef, label: "Group Name", value: name, onChange: handleNameChange, onKeyDown: handleKeyDown, error: t7, "aria-describedby": t8 });
14011
+ $[17] = handleKeyDown;
14012
+ $[18] = handleNameChange;
14013
+ $[19] = name;
14014
+ $[20] = t7;
14015
+ $[21] = t8;
14016
+ $[22] = t9;
14017
+ } else {
14018
+ t9 = $[22];
14019
+ }
14020
+ let t10;
14021
+ if ($[23] !== error) {
14022
+ t10 = error && /* @__PURE__ */ jsxRuntime.jsx("p", { id: "group-name-error", style: {
14023
+ display: "none"
14024
+ }, children: error });
14025
+ $[23] = error;
14026
+ $[24] = t10;
14027
+ } else {
14028
+ t10 = $[24];
14029
+ }
14030
+ let t11;
14031
+ if ($[25] !== t10 || $[26] !== t9) {
14032
+ t11 = /* @__PURE__ */ jsxRuntime.jsxs(ui.DialogContent, { children: [
14033
+ t9,
14034
+ t10
14035
+ ] });
14036
+ $[25] = t10;
14037
+ $[26] = t9;
14038
+ $[27] = t11;
14039
+ } else {
14040
+ t11 = $[27];
14041
+ }
14042
+ let t12;
14043
+ if ($[28] !== onClose) {
14044
+ t12 = /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { onClick: onClose, variant: "text", children: "Cancel" });
14045
+ $[28] = onClose;
14046
+ $[29] = t12;
14047
+ } else {
14048
+ t12 = $[29];
14049
+ }
14050
+ const t13 = !!error || !name.trim();
14051
+ let t14;
14052
+ if ($[30] !== handleSave || $[31] !== t13) {
14053
+ t14 = /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { onClick: handleSave, disabled: t13, children: "Save" });
14054
+ $[30] = handleSave;
14055
+ $[31] = t13;
14056
+ $[32] = t14;
14057
+ } else {
14058
+ t14 = $[32];
14059
+ }
14060
+ let t15;
14061
+ if ($[33] !== t12 || $[34] !== t14) {
14062
+ t15 = /* @__PURE__ */ jsxRuntime.jsxs(ui.DialogActions, { children: [
14063
+ t12,
14064
+ t14
14065
+ ] });
14066
+ $[33] = t12;
14067
+ $[34] = t14;
14068
+ $[35] = t15;
14069
+ } else {
14070
+ t15 = $[35];
14071
+ }
14072
+ let t16;
14073
+ if ($[36] !== onClose || $[37] !== open || $[38] !== t11 || $[39] !== t15) {
14074
+ t16 = /* @__PURE__ */ jsxRuntime.jsxs(ui.Dialog, { open, onOpenChange: onClose, children: [
14075
+ t6,
14076
+ t11,
14077
+ t15
14078
+ ] });
14079
+ $[36] = onClose;
14080
+ $[37] = open;
14081
+ $[38] = t11;
14082
+ $[39] = t15;
14083
+ $[40] = t16;
13284
14084
  } else {
13285
- t4 = $[6];
14085
+ t16 = $[40];
13286
14086
  }
13287
- const updateSearchResults = t4;
13288
- let T0;
13289
- let additionalPluginChildrenEnd;
13290
- 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;
14087
+ return t16;
14088
+ }
14089
+ const DEFAULT_GROUP_NAME = "Views";
14090
+ const ADMIN_GROUP_NAME = "Admin";
14091
+ function DefaultHomePage({
14092
+ additionalActions,
14093
+ additionalChildrenStart,
14094
+ additionalChildrenEnd
14095
+ }) {
14096
+ const context = useFireCMSContext();
14097
+ const customizationController = useCustomizationController();
14098
+ const navigationController = useNavigationController();
14099
+ if (!navigationController.topLevelNavigation) throw Error("Navigation not ready");
14100
+ const {
14101
+ allowDragAndDrop,
14102
+ navigationEntries: rawNavigationEntries,
14103
+ groups: groupOrderFromNavController,
14104
+ onNavigationEntriesUpdate
14105
+ } = navigationController.topLevelNavigation;
14106
+ const fuse = React.useRef(null);
14107
+ const [filteredUrls, setFilteredUrls] = React.useState(null);
14108
+ const performingSearch = Boolean(filteredUrls);
14109
+ const filteredNavigationEntries = filteredUrls ? rawNavigationEntries.filter((e) => filteredUrls.includes(e.url)) : rawNavigationEntries;
14110
+ React.useEffect(() => {
14111
+ fuse.current = new Fuse(rawNavigationEntries, {
14112
+ keys: ["name", "description", "group", "path"]
14113
+ });
14114
+ }, [rawNavigationEntries]);
14115
+ const updateSearch = React.useCallback((v) => {
14116
+ if (!v?.trim()) return setFilteredUrls(null);
14117
+ const r = fuse.current?.search(v.trim());
14118
+ setFilteredUrls(r ? r.map((x) => x.item.url) : []);
14119
+ }, []);
14120
+ const [items, setItems] = React.useState([]);
14121
+ const [adminGroupData, setAdminGroupData] = React.useState(null);
14122
+ React.useEffect(() => {
14123
+ const src = performingSearch ? filteredNavigationEntries : rawNavigationEntries;
14124
+ const entriesByGroup = {};
14125
+ src.forEach((e_0) => {
14126
+ const g = e_0.type === "admin" ? ADMIN_GROUP_NAME : e_0.group ?? DEFAULT_GROUP_NAME;
14127
+ (entriesByGroup[g] ??= []).push(e_0);
14128
+ });
14129
+ let allProcessed;
14130
+ if (performingSearch) {
14131
+ const ordered = [...new Set(src.map((e_1) => e_1.group ?? DEFAULT_GROUP_NAME))];
14132
+ allProcessed = ordered.map((name) => ({
14133
+ name,
14134
+ entries: entriesByGroup[name] || []
14135
+ })).filter((g_0) => g_0.entries.length);
13380
14136
  } else {
13381
- t152 = $[43];
14137
+ allProcessed = groupOrderFromNavController.map((g_1) => ({
14138
+ name: g_1,
14139
+ entries: entriesByGroup[g_1] || []
14140
+ }));
14141
+ Object.keys(entriesByGroup).forEach((g_2) => {
14142
+ if (!groupOrderFromNavController.includes(g_2)) allProcessed.push({
14143
+ name: g_2,
14144
+ entries: entriesByGroup[g_2]
14145
+ });
14146
+ });
14147
+ allProcessed = allProcessed.filter((g_3) => g_3.entries.length || groupOrderFromNavController.includes(g_3.name));
13382
14148
  }
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;
14149
+ const admin = allProcessed.find((g_4) => g_4.name === ADMIN_GROUP_NAME);
14150
+ if (admin) {
14151
+ setAdminGroupData(admin);
14152
+ setItems(allProcessed.filter((g_5) => g_5.name !== ADMIN_GROUP_NAME));
13387
14153
  } else {
13388
- t16 = $[44];
14154
+ setAdminGroupData(null);
14155
+ setItems(allProcessed);
13389
14156
  }
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,
14157
+ }, [performingSearch, filteredNavigationEntries, rawNavigationEntries, groupOrderFromNavController]);
14158
+ const updateItems = (updater) => {
14159
+ setItems(updater);
14160
+ };
14161
+ const persistNavigationGroups = (latest) => {
14162
+ const draggable = latest.map((g_6) => ({
14163
+ name: g_6.name,
14164
+ entries: g_6.entries.map((e_2) => e_2.path)
14165
+ }));
14166
+ const all = adminGroupData ? [...draggable, {
14167
+ name: adminGroupData.name,
14168
+ entries: adminGroupData.entries.map((e_3) => e_3.path)
14169
+ }] : draggable;
14170
+ onNavigationEntriesUpdate(all);
14171
+ };
14172
+ const {
14173
+ sensors,
14174
+ collisionDetection,
14175
+ onDragStart,
14176
+ onDragOver,
14177
+ onDragEnd,
14178
+ dropAnimation,
14179
+ activeItemForOverlay,
14180
+ activeGroupData,
14181
+ draggingGroupId,
14182
+ containers,
14183
+ dndKitActiveNode,
14184
+ onDragCancel,
14185
+ isDraggingCardOnly,
14186
+ dialogOpenForGroup,
14187
+ setDialogOpenForGroup,
14188
+ handleRenameGroup,
14189
+ isHoveringNewGroupDropZone,
14190
+ setIsHoveringNewGroupDropZone
14191
+ } = useHomePageDnd({
14192
+ items,
14193
+ setItems: updateItems,
14194
+ disabled: !allowDragAndDrop || performingSearch,
14195
+ onPersist: persistNavigationGroups,
14196
+ // ——► persistence here
14197
+ onGroupMoved: (g_7) => context.analyticsController?.onAnalyticsEvent?.("home_move_group", {
14198
+ name: g_7
14199
+ }),
14200
+ onCardMovedBetweenGroups: (card) => context.analyticsController?.onAnalyticsEvent?.("home_move_card", {
14201
+ id: card.id
14202
+ }),
14203
+ onNewGroupDrop: () => context.analyticsController?.onAnalyticsEvent?.("home_drop_new_group")
14204
+ });
14205
+ const {
14206
+ containerRef,
14207
+ direction
14208
+ } = useRestoreScroll();
14209
+ const dndDisabled = !allowDragAndDrop || performingSearch;
14210
+ const dndModifiers = React.useMemo(() => {
14211
+ if (dndKitActiveNode?.data.current?.type === "group") return [modifiers.restrictToVerticalAxis, modifiers.restrictToWindowEdges];
14212
+ return [modifiers.restrictToWindowEdges];
14213
+ }, [dndKitActiveNode]);
14214
+ let additionalPluginChildrenStart;
14215
+ let additionalPluginChildrenEnd;
14216
+ let additionalPluginSections;
14217
+ if (customizationController.plugins) {
14218
+ const sectionProps = {
14219
+ context
14220
+ };
14221
+ additionalPluginSections = /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: customizationController.plugins.filter((p) => p.homePage?.includeSection).map((plugin) => {
14222
+ const section = plugin.homePage.includeSection(sectionProps);
14223
+ return /* @__PURE__ */ jsxRuntime.jsx(NavigationGroup, { group: section.title, children: section.children }, `plugin_section_${plugin.key}`);
14224
+ }) });
14225
+ additionalPluginChildrenStart = /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-2", children: customizationController.plugins.filter((p_0) => p_0.homePage?.additionalChildrenStart).map((plugin_0, i) => /* @__PURE__ */ jsxRuntime.jsx("div", { children: plugin_0.homePage.additionalChildrenStart }, `plugin_children_start_${i}`)) });
14226
+ additionalPluginChildrenEnd = /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-2", children: customizationController.plugins.filter((p_1) => p_1.homePage?.additionalChildrenEnd).map((plugin_1, i_0) => /* @__PURE__ */ jsxRuntime.jsx("div", { children: plugin_1.homePage.additionalChildrenEnd }, `plugin_children_end_${i_0}`)) });
14227
+ }
14228
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { ref: containerRef, className: "py-2 overflow-auto h-full w-full", children: [
14229
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.Container, { maxWidth: "6xl", children: [
14230
+ /* @__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: {
14231
+ top: direction === "down" ? -84 : 0
14232
+ }, children: [
14233
+ /* @__PURE__ */ jsxRuntime.jsx(ui.SearchBar, { onTextSearch: updateSearch, placeholder: "Search collections", autoFocus: true, innerClassName: "w-full", className: "w-full flex-grow" }),
13393
14234
  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;
14235
+ ] }),
14236
+ /* @__PURE__ */ jsxRuntime.jsx(FavouritesView, { hidden: performingSearch }),
14237
+ additionalChildrenStart,
14238
+ additionalPluginChildrenStart,
14239
+ /* @__PURE__ */ jsxRuntime.jsxs(core.DndContext, { sensors, collisionDetection, measuring: {
14240
+ droppable: {
14241
+ strategy: core.MeasuringStrategy.Always,
14242
+ frequency: 500
13428
14243
  }
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,
14244
+ }, onDragStart, onDragOver, onDragEnd, onDragCancel, modifiers: dndModifiers, children: [
14245
+ /* @__PURE__ */ jsxRuntime.jsx(sortable.SortableContext, { items: containers, strategy: sortable.verticalListSortingStrategy, children: items.map((groupData) => {
14246
+ const groupKey = groupData.name;
14247
+ const entriesInGroup = groupData.entries;
14248
+ const AdditionalCards = [];
14249
+ customizationController.plugins?.forEach((p_2) => {
14250
+ if (p_2.homePage?.AdditionalCards) AdditionalCards.push(...toArray(p_2.homePage.AdditionalCards));
14251
+ });
14252
+ const actionProps = {
14253
+ group: groupKey === DEFAULT_GROUP_NAME ? void 0 : groupKey,
14254
+ context
14255
+ };
14256
+ if (entriesInGroup.length === 0 && (AdditionalCards.length === 0 || performingSearch) && !groupOrderFromNavController.includes(groupKey)) return null;
14257
+ 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: () => {
14258
+ if (dndDisabled) return;
14259
+ setDialogOpenForGroup(groupKey);
14260
+ }, 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: [
14261
+ entriesInGroup.map((entry) => /* @__PURE__ */ jsxRuntime.jsx(SortableNavigationCard, { entry, onClick: () => {
14262
+ let event = "unmapped_event";
14263
+ if (entry.type === "collection") event = "home_navigate_to_collection";
14264
+ else if (entry.type === "view") event = "home_navigate_to_view";
14265
+ else if (entry.type === "admin") event = "home_navigate_to_admin_view";
14266
+ context.analyticsController?.onAnalyticsEvent?.(event, {
14267
+ path: entry.path
14268
+ });
14269
+ } }, entry.url)),
14270
+ !performingSearch && groupKey.toLowerCase() !== ADMIN_GROUP_NAME.toLowerCase() && AdditionalCards.map((C, i_1) => /* @__PURE__ */ jsxRuntime.jsx(C, { ...actionProps }, `extra_${groupKey}_${i_1}`))
14271
+ ] }) }) }) }, groupKey);
14272
+ }) }, JSON.stringify(containers)),
14273
+ /* @__PURE__ */ jsxRuntime.jsx(NewGroupDropZone, { disabled: dndDisabled, setIsHovering: setIsHoveringNewGroupDropZone }),
14274
+ /* @__PURE__ */ jsxRuntime.jsx(core.DragOverlay, { adjustScale: false, dropAnimation, children: activeGroupData && draggingGroupId === activeGroupData.name ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-lg bg-transparent", style: {
14275
+ padding: 0,
14276
+ margin: 0
14277
+ }, 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 })
14278
+ ] }),
14279
+ !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: () => {
14280
+ let event_0 = "unmapped_event";
14281
+ if (entry_0.type === "collection") event_0 = "home_navigate_to_collection";
14282
+ else if (entry_0.type === "view") event_0 = "home_navigate_to_view";
14283
+ else if (entry_0.type === "admin") event_0 = "home_navigate_to_admin_view";
14284
+ context.analyticsController?.onAnalyticsEvent?.(event_0, {
14285
+ path: entry_0.path
14286
+ });
14287
+ } }, entry_0.url)) }) }),
13505
14288
  additionalPluginSections,
13506
14289
  additionalPluginChildrenEnd,
13507
14290
  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;
14291
+ ] }),
14292
+ dialogOpenForGroup && /* @__PURE__ */ jsxRuntime.jsx(RenameGroupDialog, { open: true, initialName: dialogOpenForGroup, existingGroupNames: items.map((g_8) => g_8.name).filter((n) => n !== dialogOpenForGroup), onClose: () => setDialogOpenForGroup(null), onRename: (newName) => {
14293
+ handleRenameGroup(dialogOpenForGroup, newName);
14294
+ setDialogOpenForGroup(null);
14295
+ } })
14296
+ ] });
13559
14297
  }
13560
14298
  function EntityCollectionViewActions(t0) {
13561
14299
  const $ = reactCompilerRuntime.c(41);
@@ -16530,6 +17268,92 @@
16530
17268
  /* @__PURE__ */ jsxRuntime.jsx(FieldHelperText, { includeDescription, showError, error, disabled, property })
16531
17269
  ] });
16532
17270
  }
17271
+ function ReferenceAsStringFieldBinding(props) {
17272
+ const $ = reactCompilerRuntime.c(4);
17273
+ if (typeof props.property.reference?.path !== "string") {
17274
+ let t02;
17275
+ if ($[0] !== props) {
17276
+ t02 = /* @__PURE__ */ jsxRuntime.jsx(ReadOnlyFieldBinding, { ...props });
17277
+ $[0] = props;
17278
+ $[1] = t02;
17279
+ } else {
17280
+ t02 = $[1];
17281
+ }
17282
+ return t02;
17283
+ }
17284
+ let t0;
17285
+ if ($[2] !== props) {
17286
+ t0 = /* @__PURE__ */ jsxRuntime.jsx(ReferenceAsStringFieldBindingInternal, { ...props });
17287
+ $[2] = props;
17288
+ $[3] = t0;
17289
+ } else {
17290
+ t0 = $[3];
17291
+ }
17292
+ return t0;
17293
+ }
17294
+ function ReferenceAsStringFieldBindingInternal({
17295
+ propertyKey,
17296
+ value,
17297
+ setValue,
17298
+ error,
17299
+ showError,
17300
+ isSubmitting,
17301
+ disabled,
17302
+ minimalistView,
17303
+ property,
17304
+ includeDescription,
17305
+ size = "medium"
17306
+ }) {
17307
+ if (!property.reference?.path) {
17308
+ throw new Error("Property path is required for ReferenceAsStringFieldBinding");
17309
+ }
17310
+ useClearRestoreValue({
17311
+ property,
17312
+ value,
17313
+ setValue
17314
+ });
17315
+ const navigationController = useNavigationController();
17316
+ const path = property.reference.path;
17317
+ const collection = React.useMemo(() => {
17318
+ return path ? navigationController.getCollection(path) : void 0;
17319
+ }, [path]);
17320
+ const referenceValue = React.useMemo(() => {
17321
+ if (value && path) {
17322
+ return new EntityReference(value, path);
17323
+ }
17324
+ return void 0;
17325
+ }, [value, path]);
17326
+ if (!collection) {
17327
+ throw Error(`Couldn't find the corresponding collection for the path: ${path}`);
17328
+ }
17329
+ const onSingleEntitySelected = React.useCallback((e) => {
17330
+ setValue(e ? e.id : null);
17331
+ }, [setValue]);
17332
+ const referenceDialogController = useReferenceDialog({
17333
+ multiselect: false,
17334
+ path,
17335
+ collection,
17336
+ onSingleEntitySelected,
17337
+ selectedEntityIds: value ? [value] : void 0,
17338
+ forceFilter: property.reference.forceFilter
17339
+ });
17340
+ const onEntryClick = (e_0) => {
17341
+ e_0.preventDefault();
17342
+ referenceDialogController.open();
17343
+ };
17344
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
17345
+ !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" }),
17346
+ !collection && /* @__PURE__ */ jsxRuntime.jsx(ErrorView, { error: "The specified collection does not exist. Check console" }),
17347
+ collection && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
17348
+ 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 }),
17349
+ !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: [
17350
+ /* @__PURE__ */ jsxRuntime.jsx(IconForView, { collectionOrView: collection, className: "text-surface-300 dark:text-surface-600" }),
17351
+ `Edit ${property.name}`.toUpperCase()
17352
+ ] }) })
17353
+ ] }),
17354
+ /* @__PURE__ */ jsxRuntime.jsx(FieldHelperText, { includeDescription, showError, error, disabled, property })
17355
+ ] });
17356
+ }
16533
17357
  const PropertyFieldBinding = React.memo(PropertyFieldBindingInternal, (a, b) => {
16534
17358
  if (a.propertyKey !== b.propertyKey) {
16535
17359
  return false;
@@ -17772,7 +18596,6 @@
17772
18596
  minimalistView: false,
17773
18597
  autoFocus: internalId === lastAddedId
17774
18598
  };
17775
- console.debug("Building entry for", index, fieldProps);
17776
18599
  return /* @__PURE__ */ jsxRuntime.jsx(ErrorBoundary, { children: /* @__PURE__ */ jsxRuntime.jsx(PropertyFieldBinding, { ...fieldProps, index }) });
17777
18600
  };
17778
18601
  $[4] = context;
@@ -20566,6 +21389,8 @@
20566
21389
  }
20567
21390
  const DEFAULT_BASE_PATH = "/";
20568
21391
  const DEFAULT_COLLECTION_PATH = "/c";
21392
+ const NAVIGATION_DEFAULT_GROUP_NAME = "Views";
21393
+ const NAVIGATION_ADMIN_GROUP_NAME = "Admin";
20569
21394
  function useBuildNavigationController(props) {
20570
21395
  const {
20571
21396
  basePath = DEFAULT_BASE_PATH,
@@ -20579,12 +21404,14 @@
20579
21404
  plugins,
20580
21405
  userConfigPersistence,
20581
21406
  dataSourceDelegate,
20582
- disabled
21407
+ disabled,
21408
+ navigationGroupMappings
20583
21409
  } = props;
20584
21410
  const navigate = reactRouterDom.useNavigate();
20585
21411
  const collectionsRef = React.useRef();
20586
21412
  const viewsRef = React.useRef();
20587
21413
  const adminViewsRef = React.useRef();
21414
+ const navigationEntriesOrderRef = React.useRef();
20588
21415
  const [initialised, setInitialised] = React.useState(false);
20589
21416
  const [topLevelNavigation, setTopLevelNavigation] = React.useState(void 0);
20590
21417
  const [navigationLoading, setNavigationLoading] = React.useState(true);
@@ -20595,80 +21422,127 @@
20595
21422
  const fullCollectionPath = cleanBasePath ? `/${cleanBasePath}/${cleanBaseCollectionPath}` : `/${cleanBaseCollectionPath}`;
20596
21423
  const buildCMSUrlPath = React.useCallback((path) => cleanBasePath ? `/${cleanBasePath}/${encodePath(path)}` : `/${encodePath(path)}`, [cleanBasePath]);
20597
21424
  const buildUrlCollectionPath = React.useCallback((path_0) => `${removeInitialAndTrailingSlashes(baseCollectionPath)}/${encodePath(path_0)}`, [baseCollectionPath]);
21425
+ const allPluginGroups = plugins?.flatMap((plugin) => plugin.homePage?.navigationEntries ? plugin.homePage.navigationEntries.map((e) => e.name) : []) ?? [];
21426
+ const pluginGroups = [...new Set(allPluginGroups)];
21427
+ const onNavigationEntriesOrderUpdate = React.useCallback((entries) => {
21428
+ if (!plugins) {
21429
+ return;
21430
+ }
21431
+ const filteredEntries = entries.filter((entry) => entry.entries.length > 0);
21432
+ if (plugins.some((plugin_1) => plugin_1.homePage?.onNavigationEntriesUpdate)) {
21433
+ plugins.forEach((plugin_0) => {
21434
+ if (plugin_0.homePage?.onNavigationEntriesUpdate) {
21435
+ plugin_0.homePage.onNavigationEntriesUpdate(filteredEntries);
21436
+ }
21437
+ });
21438
+ }
21439
+ }, [plugins]);
20598
21440
  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;
21441
+ const finalNavigationGroupMappings = computeNavigationGroups({
21442
+ navigationGroupMappings,
21443
+ collections,
21444
+ views,
21445
+ plugins
21446
+ });
21447
+ const allPluginNavigationEntries = finalNavigationGroupMappings.map((g) => g.entries).flat() ?? [];
21448
+ const navigationEntriesOrder = [...new Set(allPluginNavigationEntries)];
21449
+ let navigationEntries = [...(collections ?? []).reduce((acc, collection) => {
21450
+ if (collection.hideFromNavigation) return acc;
21451
+ const pathKey = collection.id ?? collection.path;
21452
+ let groupName = getGroup(collection);
21453
+ if (finalNavigationGroupMappings) {
21454
+ for (const pluginGroupDef of finalNavigationGroupMappings) {
21455
+ if (pluginGroupDef.entries.includes(pathKey)) {
21456
+ groupName = pluginGroupDef.name;
21457
+ break;
21458
+ }
21459
+ }
20639
21460
  }
20640
- if (a.group !== "Views" && b.group === "Views") {
20641
- return 1;
21461
+ acc.push({
21462
+ id: `collection:${pathKey}`,
21463
+ url: buildUrlCollectionPath(pathKey),
21464
+ type: "collection",
21465
+ name: collection.name.trim(),
21466
+ path: pathKey,
21467
+ collection,
21468
+ description: collection.description?.trim(),
21469
+ group: groupName ?? NAVIGATION_DEFAULT_GROUP_NAME
21470
+ });
21471
+ return acc;
21472
+ }, []), ...(views ?? []).reduce((acc_0, view) => {
21473
+ if (view.hideFromNavigation) return acc_0;
21474
+ const pathKey_0 = Array.isArray(view.path) ? view.path[0] : view.path;
21475
+ let groupName_0 = getGroup(view);
21476
+ if (finalNavigationGroupMappings) {
21477
+ for (const pluginGroupDef_0 of finalNavigationGroupMappings) {
21478
+ if (pluginGroupDef_0.entries.includes(pathKey_0)) {
21479
+ groupName_0 = pluginGroupDef_0.name;
21480
+ break;
21481
+ }
21482
+ }
20642
21483
  }
21484
+ acc_0.push({
21485
+ id: `view:${pathKey_0}`,
21486
+ url: buildCMSUrlPath(pathKey_0),
21487
+ name: view.name.trim(),
21488
+ type: "view",
21489
+ path: view.path,
21490
+ view,
21491
+ description: view.description?.trim(),
21492
+ group: groupName_0 ?? NAVIGATION_DEFAULT_GROUP_NAME
21493
+ });
21494
+ return acc_0;
21495
+ }, []), ...(adminViews ?? []).reduce((acc_1, view_0) => {
21496
+ if (view_0.hideFromNavigation) return acc_1;
21497
+ const pathKey_1 = Array.isArray(view_0.path) ? view_0.path[0] : view_0.path;
21498
+ const groupName_1 = NAVIGATION_ADMIN_GROUP_NAME;
21499
+ acc_1.push({
21500
+ id: `admin:${pathKey_1}`,
21501
+ url: buildCMSUrlPath(pathKey_1),
21502
+ name: view_0.name.trim(),
21503
+ type: "admin",
21504
+ path: view_0.path,
21505
+ view: view_0,
21506
+ description: view_0.description?.trim(),
21507
+ group: groupName_1
21508
+ });
21509
+ return acc_1;
21510
+ }, [])];
21511
+ const groupOrderValue = (groupName_2) => {
21512
+ if (groupName_2 === NAVIGATION_ADMIN_GROUP_NAME) return 1;
20643
21513
  return 0;
21514
+ };
21515
+ navigationEntries = navigationEntries.sort((a, b) => {
21516
+ return groupOrderValue(a.group) - groupOrderValue(b.group);
20644
21517
  });
20645
- if (viewsOrder_0) {
21518
+ const usedViewsOrder = viewsOrder_0 ?? navigationEntriesOrder;
21519
+ if (usedViewsOrder) {
20646
21520
  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
- }
21521
+ const getSortPath = (navEntry) => typeof navEntry.path === "string" ? navEntry.path : navEntry.path[0];
21522
+ const aIndex = usedViewsOrder.indexOf(getSortPath(a_0));
21523
+ const bIndex = usedViewsOrder.indexOf(getSortPath(b_0));
21524
+ if (aIndex === -1 && bIndex === -1) return 0;
21525
+ if (aIndex === -1) return 1;
21526
+ if (bIndex === -1) return -1;
20658
21527
  return aIndex - bIndex;
20659
21528
  });
20660
21529
  }
20661
- const groups = Object.values(navigationEntries).map((e) => e.group).filter(Boolean).filter((value, index, array) => array.indexOf(value) === index);
21530
+ const collectedGroupsFromEntries = navigationEntries.map((e_0) => e_0.group).filter(Boolean);
21531
+ const allDefinedGroups = [...pluginGroups, ...collectedGroupsFromEntries];
21532
+ const uniqueGroups = [...new Set(allDefinedGroups)].sort((a_1, b_1) => groupOrderValue(a_1) - groupOrderValue(b_1));
20662
21533
  return {
21534
+ allowDragAndDrop: plugins?.some((plugin_2) => plugin_2.homePage?.allowDragAndDrop) ?? false,
20663
21535
  navigationEntries,
20664
- groups
21536
+ groups: uniqueGroups,
21537
+ onNavigationEntriesUpdate: onNavigationEntriesOrderUpdate
20665
21538
  };
20666
- }, [buildCMSUrlPath, buildUrlCollectionPath]);
21539
+ }, [navigationGroupMappings, buildCMSUrlPath, buildUrlCollectionPath, pluginGroups, onNavigationEntriesOrderUpdate]);
20667
21540
  const refreshNavigation = React.useCallback(async () => {
20668
21541
  if (disabled || authController.initialLoading) return;
20669
21542
  console.debug("Refreshing navigation");
20670
21543
  try {
20671
21544
  const [resolvedCollections = [], resolvedViews, resolvedAdminViews = []] = await Promise.all([resolveCollections(collectionsProp, collectionPermissions, authController, dataSourceDelegate, plugins), resolveCMSViews(viewsProp, authController, dataSourceDelegate), resolveCMSViews(adminViewsProp, authController, dataSourceDelegate)]);
21545
+ const computedTopLevelNav = computeTopNavigation(resolvedCollections, resolvedViews, resolvedAdminViews, viewsOrder);
20672
21546
  let shouldUpdateTopLevelNav = false;
20673
21547
  if (!areCollectionListsEqual(collectionsRef.current ?? [], resolvedCollections)) {
20674
21548
  collectionsRef.current = resolvedCollections;
@@ -20687,13 +21561,17 @@
20687
21561
  adminViewsRef.current = resolvedAdminViews;
20688
21562
  shouldUpdateTopLevelNav = true;
20689
21563
  }
20690
- const computedTopLevelNav = computeTopNavigation(resolvedCollections, resolvedViews, resolvedAdminViews, viewsOrder);
21564
+ const navigationEntriesOrder_0 = computedTopLevelNav.navigationEntries.map((e_2) => e_2.id);
21565
+ if (!equal(navigationEntriesOrderRef.current, navigationEntriesOrder_0)) {
21566
+ navigationEntriesOrderRef.current = navigationEntriesOrder_0;
21567
+ shouldUpdateTopLevelNav = true;
21568
+ }
20691
21569
  if (shouldUpdateTopLevelNav && !equal(topLevelNavigation, computedTopLevelNav)) {
20692
21570
  setTopLevelNavigation(computedTopLevelNav);
20693
21571
  }
20694
- } catch (e_0) {
20695
- console.error(e_0);
20696
- setNavigationLoadingError(e_0);
21572
+ } catch (e_1) {
21573
+ console.error(e_1);
21574
+ setNavigationLoadingError(e_1);
20697
21575
  }
20698
21576
  if (navigationLoading) setNavigationLoading(false);
20699
21577
  if (!initialised) setInitialised(true);
@@ -20893,9 +21771,9 @@
20893
21771
  function getGroup(collectionOrView) {
20894
21772
  const trimmed = collectionOrView.group?.trim();
20895
21773
  if (!trimmed || trimmed === "") {
20896
- return "Views";
21774
+ return NAVIGATION_DEFAULT_GROUP_NAME;
20897
21775
  }
20898
- return trimmed ?? "Views";
21776
+ return trimmed ?? NAVIGATION_DEFAULT_GROUP_NAME;
20899
21777
  }
20900
21778
  function areCollectionListsEqual(a, b) {
20901
21779
  if (a.length !== b.length) {
@@ -20921,6 +21799,58 @@
20921
21799
  }
20922
21800
  return equal(removeFunctions(restA), removeFunctions(restB));
20923
21801
  }
21802
+ function computeNavigationGroups({
21803
+ navigationGroupMappings,
21804
+ collections,
21805
+ views,
21806
+ plugins
21807
+ }) {
21808
+ let result = navigationGroupMappings;
21809
+ result = plugins ? plugins?.reduce((acc, plugin) => {
21810
+ if (plugin.homePage?.navigationEntries) {
21811
+ plugin.homePage.navigationEntries.forEach((entry) => {
21812
+ const {
21813
+ name,
21814
+ entries
21815
+ } = entry;
21816
+ const existingGroup = acc.find((entry2) => entry2.name === name);
21817
+ if (existingGroup) {
21818
+ existingGroup.entries.push(...entries);
21819
+ } else {
21820
+ acc.push({
21821
+ name,
21822
+ entries: [...entries]
21823
+ });
21824
+ }
21825
+ });
21826
+ }
21827
+ return acc;
21828
+ }, [...result ?? []]) : result;
21829
+ if (!result) {
21830
+ result = [];
21831
+ const groupMap = {};
21832
+ (collections ?? []).forEach((collection) => {
21833
+ const name = getGroup(collection);
21834
+ const entry = collection.id ?? collection.path;
21835
+ if (!groupMap[name]) groupMap[name] = [];
21836
+ groupMap[name].push(entry);
21837
+ });
21838
+ (views ?? []).forEach((view) => {
21839
+ const name = getGroup(view);
21840
+ const entry = Array.isArray(view.path) ? view.path[0] : view.path;
21841
+ if (!groupMap[name]) groupMap[name] = [];
21842
+ groupMap[name].push(entry);
21843
+ });
21844
+ result = Object.entries(groupMap).map(([name, entries]) => ({
21845
+ name,
21846
+ entries
21847
+ }));
21848
+ }
21849
+ result.forEach((group) => {
21850
+ group.entries = [...new Set(group.entries)];
21851
+ });
21852
+ return result;
21853
+ }
20924
21854
  function useBuildLocalConfigurationPersistence() {
20925
21855
  const $ = reactCompilerRuntime.c(15);
20926
21856
  let t0;
@@ -22891,7 +23821,7 @@
22891
23821
  const {
22892
23822
  isActive
22893
23823
  } = 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" : "");
23824
+ 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
23825
  };
22896
23826
  $[4] = drawerOpen;
22897
23827
  $[5] = t4;
@@ -23051,7 +23981,7 @@
23051
23981
  if ($[41] !== adminMenuOpen || $[42] !== buildGroupHeader || $[43] !== drawerOpen || $[44] !== navigationEntries || $[45] !== onClick || $[46] !== tooltipsOpen) {
23052
23982
  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
23983
  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}`))
23984
+ 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
23985
  ] }, `drawer_group_${group_0}`);
23056
23986
  $[41] = adminMenuOpen;
23057
23987
  $[42] = buildGroupHeader;
@@ -23105,13 +24035,13 @@
23105
24035
  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
24036
  /* @__PURE__ */ jsxRuntime.jsx(ui.Tooltip, { title: "Admin", open: tooltipsOpen, side: "right", sideOffset: 28, children: /* @__PURE__ */ jsxRuntime.jsx(ui.MoreVertIcon, {}) }),
23107
24037
  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) => {
24038
+ ] }), children: adminViews.map((entry) => /* @__PURE__ */ jsxRuntime.jsxs(ui.MenuItem, { onClick: (event) => {
23109
24039
  event.preventDefault();
23110
- navigate(entry.path);
24040
+ navigate(entry.url);
23111
24041
  }, children: [
23112
24042
  /* @__PURE__ */ jsxRuntime.jsx(IconForView, { collectionOrView: entry.view }),
23113
24043
  entry.name
23114
- ] }, `navigation_${index_0}`)) })
24044
+ ] }, entry.id)) })
23115
24045
  ] }) });
23116
24046
  $[0] = adminMenuOpen;
23117
24047
  $[1] = analyticsController;
@@ -23364,10 +24294,21 @@
23364
24294
  Field: StorageUploadFieldBinding
23365
24295
  }
23366
24296
  },
24297
+ reference_as_string: {
24298
+ key: "reference_as_string",
24299
+ name: "Reference (as string)",
24300
+ description: "The value refers to a different collection (it is saved as a string)",
24301
+ Icon: ui.LinkIcon,
24302
+ color: "#154fb3",
24303
+ property: {
24304
+ dataType: "string",
24305
+ Field: ReferenceAsStringFieldBinding
24306
+ }
24307
+ },
23367
24308
  reference: {
23368
24309
  key: "reference",
23369
24310
  name: "Reference",
23370
- description: "The value refers to a different collection",
24311
+ description: "The value refers to a different collection (it is saved as a reference)",
23371
24312
  Icon: ui.LinkIcon,
23372
24313
  color: "#ff0042",
23373
24314
  property: {
@@ -23498,6 +24439,8 @@
23498
24439
  return "email";
23499
24440
  } else if (property.enumValues) {
23500
24441
  return "select";
24442
+ } else if (property.reference) {
24443
+ return "reference_as_string";
23501
24444
  } else {
23502
24445
  return "text_field";
23503
24446
  }
@@ -24428,6 +25371,7 @@
24428
25371
  function _temp3(child_1) {
24429
25372
  return child_1.type.componentType !== "Drawer" && child_1.type.componentType !== "AppBar";
24430
25373
  }
25374
+ exports2.ADMIN_GROUP_NAME = ADMIN_GROUP_NAME;
24431
25375
  exports2.AppBar = AppBar;
24432
25376
  exports2.AppContext = AppContext;
24433
25377
  exports2.ArrayContainer = ArrayContainer;
@@ -24452,6 +25396,7 @@
24452
25396
  exports2.CircularProgressCenter = CircularProgressCenter;
24453
25397
  exports2.ConfirmationDialog = ConfirmationDialog;
24454
25398
  exports2.DEFAULT_FIELD_CONFIGS = DEFAULT_FIELD_CONFIGS;
25399
+ exports2.DEFAULT_GROUP_NAME = DEFAULT_GROUP_NAME;
24455
25400
  exports2.DRAWER_WIDTH = DRAWER_WIDTH;
24456
25401
  exports2.DatePreview = DatePreview;
24457
25402
  exports2.DateTimeFieldBinding = DateTimeFieldBinding;
@@ -24494,6 +25439,8 @@
24494
25439
  exports2.ModeControllerContext = ModeControllerContext;
24495
25440
  exports2.ModeControllerProvider = ModeControllerProvider;
24496
25441
  exports2.MultiSelectFieldBinding = MultiSelectFieldBinding;
25442
+ exports2.NAVIGATION_ADMIN_GROUP_NAME = NAVIGATION_ADMIN_GROUP_NAME;
25443
+ exports2.NAVIGATION_DEFAULT_GROUP_NAME = NAVIGATION_DEFAULT_GROUP_NAME;
24497
25444
  exports2.NavigationCard = NavigationCard;
24498
25445
  exports2.NavigationCardBinding = NavigationCardBinding;
24499
25446
  exports2.NavigationGroup = NavigationGroup;
@@ -24507,6 +25454,7 @@
24507
25454
  exports2.PropertyPreview = PropertyPreview;
24508
25455
  exports2.PropertyTableCell = PropertyTableCell;
24509
25456
  exports2.ReadOnlyFieldBinding = ReadOnlyFieldBinding;
25457
+ exports2.ReferenceAsStringFieldBinding = ReferenceAsStringFieldBinding;
24510
25458
  exports2.ReferenceFieldBinding = ReferenceFieldBinding;
24511
25459
  exports2.ReferencePreview = ReferencePreview;
24512
25460
  exports2.ReferenceSelectionTable = ReferenceSelectionTable;