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

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