@firecms/core 3.4.0-canary.63041d0 → 3.4.0-canary.cfeed0b

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 (82) hide show
  1. package/dist/components/EntityCollectionTable/internal/popup_field/PopupFormField.d.ts +3 -1
  2. package/dist/components/EntityCollectionView/EntityCollectionBoardView.d.ts +3 -1
  3. package/dist/components/EntityCollectionView/EntityCollectionView.d.ts +3 -2
  4. package/dist/components/EntityCollectionView/EntityCollectionViewActions.d.ts +3 -1
  5. package/dist/components/EntityCollectionView/EntityCollectionViewStartActions.d.ts +3 -1
  6. package/dist/components/EntityCollectionView/useBoardDataController.d.ts +3 -1
  7. package/dist/components/ReferenceTable/ReferenceSelectionTable.d.ts +10 -1
  8. package/dist/components/common/useDataSourceTableController.d.ts +4 -2
  9. package/dist/components/common/useTableSearchHelper.d.ts +3 -1
  10. package/dist/core/EntityEditView.d.ts +2 -0
  11. package/dist/core/EntityEditViewFormActions.d.ts +1 -1
  12. package/dist/form/EntityForm.d.ts +8 -1
  13. package/dist/form/EntityFormActions.d.ts +2 -0
  14. package/dist/hooks/data/delete.d.ts +1 -1
  15. package/dist/hooks/data/useCollectionFetch.d.ts +7 -1
  16. package/dist/hooks/data/useEntityFetch.d.ts +4 -1
  17. package/dist/i18n/__tests__/FireCMSi18nProvider.test.d.ts +1 -0
  18. package/dist/i18n/__tests__/nested_provider_lifecycle.test.d.ts +1 -0
  19. package/dist/index.es.js +967 -649
  20. package/dist/index.es.js.map +1 -1
  21. package/dist/index.umd.js +966 -648
  22. package/dist/index.umd.js.map +1 -1
  23. package/dist/types/collections.d.ts +7 -0
  24. package/dist/types/datasource.d.ts +25 -4
  25. package/dist/types/entities.d.ts +21 -1
  26. package/dist/types/entity_actions.d.ts +6 -0
  27. package/dist/types/entity_callbacks.d.ts +21 -0
  28. package/dist/types/navigation.d.ts +34 -5
  29. package/dist/types/plugins.d.ts +13 -0
  30. package/dist/types/side_entity_controller.d.ts +3 -2
  31. package/dist/util/entity_cache.d.ts +11 -0
  32. package/dist/util/navigation_utils.d.ts +84 -2
  33. package/dist/util/parent_references_from_path.d.ts +16 -0
  34. package/dist/util/paths.d.ts +28 -0
  35. package/dist/util/permissions.d.ts +10 -4
  36. package/package.json +4 -4
  37. package/src/components/DeleteEntityDialog.tsx +2 -0
  38. package/src/components/EntityCollectionTable/EntityCollectionRowActions.tsx +2 -2
  39. package/src/components/EntityCollectionTable/internal/popup_field/PopupFormField.tsx +5 -1
  40. package/src/components/EntityCollectionView/EntityCollectionBoardView.tsx +12 -0
  41. package/src/components/EntityCollectionView/EntityCollectionView.tsx +49 -16
  42. package/src/components/EntityCollectionView/EntityCollectionViewActions.tsx +6 -2
  43. package/src/components/EntityCollectionView/EntityCollectionViewStartActions.tsx +4 -0
  44. package/src/components/EntityCollectionView/useBoardDataController.tsx +17 -1
  45. package/src/components/EntityPreview.tsx +4 -1
  46. package/src/components/ReferenceTable/ReferenceSelectionTable.tsx +19 -2
  47. package/src/components/common/default_entity_actions.tsx +22 -2
  48. package/src/components/common/useDataSourceTableController.tsx +17 -5
  49. package/src/components/common/useTableSearchHelper.ts +5 -0
  50. package/src/core/EntityEditView.tsx +11 -12
  51. package/src/core/EntityEditViewFormActions.tsx +3 -2
  52. package/src/core/EntitySidePanel.tsx +6 -4
  53. package/src/form/EntityForm.tsx +30 -9
  54. package/src/form/EntityFormActions.tsx +2 -0
  55. package/src/hooks/data/delete.ts +8 -0
  56. package/src/hooks/data/save.ts +5 -2
  57. package/src/hooks/data/useCollectionFetch.tsx +21 -1
  58. package/src/hooks/data/useEntityFetch.tsx +28 -6
  59. package/src/hooks/useBuildNavigationController.tsx +23 -8
  60. package/src/hooks/useResolvedNavigationFrom.tsx +3 -1
  61. package/src/i18n/FireCMSi18nProvider.tsx +48 -4
  62. package/src/i18n/__tests__/FireCMSi18nProvider.test.tsx +91 -0
  63. package/src/i18n/__tests__/nested_provider_lifecycle.test.tsx +67 -0
  64. package/src/internal/useBuildDataSource.ts +26 -15
  65. package/src/internal/useBuildSideEntityController.tsx +13 -5
  66. package/src/preview/components/ReferencePreview.tsx +7 -3
  67. package/src/routes/FireCMSRoute.tsx +9 -4
  68. package/src/types/collections.ts +8 -0
  69. package/src/types/datasource.ts +25 -4
  70. package/src/types/entities.ts +24 -1
  71. package/src/types/entity_actions.tsx +6 -0
  72. package/src/types/entity_callbacks.ts +24 -0
  73. package/src/types/navigation.ts +35 -5
  74. package/src/types/plugins.tsx +13 -0
  75. package/src/types/side_entity_controller.tsx +3 -2
  76. package/src/util/entities.ts +3 -1
  77. package/src/util/entity_cache.ts +18 -0
  78. package/src/util/navigation_from_path.ts +6 -1
  79. package/src/util/navigation_utils.ts +204 -2
  80. package/src/util/parent_references_from_path.ts +42 -3
  81. package/src/util/paths.ts +40 -3
  82. package/src/util/permissions.ts +22 -10
package/dist/index.es.js CHANGED
@@ -10,7 +10,7 @@ import { useLocation, useNavigate, Link, NavLink, Routes, Route, createBrowserRo
10
10
  import Fuse from "fuse.js";
11
11
  import equal from "react-fast-compare";
12
12
  import jsonLogic from "json-logic-js";
13
- import { useTranslation as useTranslation$1, initReactI18next, I18nextProvider } from "react-i18next";
13
+ import { useTranslation as useTranslation$1, I18nContext, initReactI18next, I18nextProvider } from "react-i18next";
14
14
  import { format } from "date-fns";
15
15
  import * as locales from "date-fns/locale";
16
16
  import { useDropzone } from "react-dropzone";
@@ -215,6 +215,11 @@ function encodeEntityId(entityId) {
215
215
  function decodeEntityId(encodedEntityId) {
216
216
  return encodedEntityId.replaceAll("%2F", "/").replaceAll("%23", "#").replaceAll("%3F", "?").replaceAll("%25", "%");
217
217
  }
218
+ function buildSubcollectionPathSegments(parentPathSegments, entityId, subcollectionPath) {
219
+ if (!parentPathSegments || !entityId) return void 0;
220
+ const ownSegments = removeInitialAndTrailingSlashes(subcollectionPath).split("/");
221
+ return [...parentPathSegments, entityId, ...ownSegments];
222
+ }
218
223
  function getLastSegment(path) {
219
224
  const cleanPath = removeInitialAndTrailingSlashes(path);
220
225
  if (cleanPath.includes("/")) {
@@ -223,7 +228,88 @@ function getLastSegment(path) {
223
228
  }
224
229
  return cleanPath;
225
230
  }
226
- function resolveCollectionPathIds(path, allCollections) {
231
+ function walkPathSegments(pathSegments, allCollections) {
232
+ const resolved = [];
233
+ const steps = [];
234
+ let currentCollections = allCollections;
235
+ let index = 0;
236
+ while (index < pathSegments.length) {
237
+ const remaining = pathSegments.slice(index);
238
+ if (!currentCollections || currentCollections.length === 0) {
239
+ resolved.push(...remaining);
240
+ return {
241
+ resolved,
242
+ steps,
243
+ unmatched: remaining[0]
244
+ };
245
+ }
246
+ let match;
247
+ for (const collection of currentCollections) {
248
+ for (const candidate of [collection.path, collection.id]) {
249
+ if (!candidate) continue;
250
+ const parts = removeInitialAndTrailingSlashes(candidate).split("/");
251
+ if (parts.length > remaining.length) continue;
252
+ if (parts.some((part, i) => part !== remaining[i])) continue;
253
+ if (!match || parts.length > match.length) match = {
254
+ collection,
255
+ length: parts.length
256
+ };
257
+ }
258
+ }
259
+ if (!match) {
260
+ resolved.push(...remaining);
261
+ return {
262
+ resolved,
263
+ steps,
264
+ unmatched: remaining[0]
265
+ };
266
+ }
267
+ resolved.push(...removeInitialAndTrailingSlashes(match.collection.path).split("/"));
268
+ index += match.length;
269
+ const step = {
270
+ collection: match.collection,
271
+ collectionPath: resolved.join("/"),
272
+ collectionSegments: [...resolved]
273
+ };
274
+ steps.push(step);
275
+ if (index >= pathSegments.length) {
276
+ return {
277
+ resolved,
278
+ steps,
279
+ collection: match.collection
280
+ };
281
+ }
282
+ step.entityId = pathSegments[index];
283
+ resolved.push(pathSegments[index]);
284
+ index += 1;
285
+ if (index >= pathSegments.length) {
286
+ return {
287
+ resolved,
288
+ steps,
289
+ collection: match.collection
290
+ };
291
+ }
292
+ currentCollections = match.collection.subcollections;
293
+ }
294
+ return {
295
+ resolved,
296
+ steps
297
+ };
298
+ }
299
+ function resolveCollectionPathSegments(pathSegments, allCollections) {
300
+ const walk = walkPathSegments(pathSegments, allCollections);
301
+ if (walk.unmatched !== void 0) {
302
+ console.warn(`resolveCollectionPathSegments: Collection definition not found for segment "${walk.unmatched}" in [${pathSegments.join(", ")}]. Carrying the remaining segments through unresolved.`);
303
+ }
304
+ return walk.resolved;
305
+ }
306
+ function getCollectionByPathSegments(pathSegments, collections) {
307
+ return walkPathSegments(pathSegments, collections).collection;
308
+ }
309
+ function resolveCollectionPathIds(path, allCollections, pathSegments) {
310
+ if (pathSegments) {
311
+ return resolveCollectionPathSegments(pathSegments, allCollections).join("/");
312
+ }
227
313
  let remainingPath = removeInitialAndTrailingSlashes(path);
228
314
  if (!remainingPath) {
229
315
  return "";
@@ -285,7 +371,10 @@ function resolveCollectionPathIds(path, allCollections) {
285
371
  }
286
372
  return resolvedPathParts.join("/");
287
373
  }
288
- function getCollectionByPathOrId(pathOrId, collections) {
374
+ function getCollectionByPathOrId(pathOrId, collections, pathSegments) {
375
+ if (pathSegments) {
376
+ return getCollectionByPathSegments(pathSegments, collections);
377
+ }
289
378
  const subpaths = removeInitialAndTrailingSlashes(pathOrId).split("/");
290
379
  if (subpaths.length % 2 === 0) {
291
380
  throw Error(`getCollectionByPathOrId: Collection paths must have an odd number of segments: ${pathOrId}`);
@@ -342,6 +431,9 @@ function navigateToEntity({
342
431
  onClose
343
432
  });
344
433
  } else {
434
+ if (!fullIdPath && pathSegments?.some((segment) => segment.includes("/"))) {
435
+ console.warn(`navigateToEntity: no "fullIdPath" was given and "${path}" contains an entity id with a "/", so no unambiguous URL can be built for it. The link will point at a different location. Pass "fullIdPath" — the escaped chain — alongside "path".`);
436
+ }
345
437
  let to = navigation.buildUrlCollectionPath(entityId ? `${fullIdPath ?? path}/${encodeEntityId(entityId)}` : fullIdPath ?? path);
346
438
  if (entityId && selectedTab) {
347
439
  to += `/${selectedTab}`;
@@ -369,10 +461,21 @@ class EntityReference {
369
461
  * Optional database ID where the entity is stored (if multiple databases are used)
370
462
  */
371
463
  databaseId;
372
- constructor(id, path, databaseId) {
464
+ /**
465
+ * `path` split at its real segment boundaries, e.g. `["nodes", "node/42", "edges"]`.
466
+ *
467
+ * `path` is a single flattened string, so a parent entity id containing "/" cannot be
468
+ * recovered from it. This keeps each segment whole.
469
+ *
470
+ * Optional, and never derived by splitting `path` — a guess would be wrong in exactly
471
+ * the case the field exists for. Absent means "not known here", not "no slashes".
472
+ */
473
+ pathSegments;
474
+ constructor(id, path, databaseId, pathSegments) {
373
475
  this.id = id;
374
476
  this.path = path;
375
477
  this.databaseId = databaseId;
478
+ this.pathSegments = pathSegments;
376
479
  }
377
480
  get pathWithId() {
378
481
  return `${this.path}/${this.id}`;
@@ -743,7 +846,7 @@ function getReferenceFrom(entity) {
743
846
  if (!entity) {
744
847
  throw new Error("getReferenceFrom: entity is null or undefined");
745
848
  }
746
- return new EntityReference(entity.id, entity.path, entity.databaseId);
849
+ return new EntityReference(entity.id, entity.path, entity.databaseId, entity.pathSegments);
747
850
  }
748
851
  function traverseValuesProperties(inputValues, properties, operation) {
749
852
  const safeInputValues = inputValues ?? {};
@@ -1234,7 +1337,12 @@ function getNavigationEntriesFromPath(props) {
1234
1337
  path: newPath,
1235
1338
  collections: collection.subcollections,
1236
1339
  currentFullPath: fullPath,
1237
- currentFullIdPath: fullIdPath,
1340
+ // The entity id is a hop in the id chain exactly as it is in the
1341
+ // other two. Without it a nested `fullIdPath` was
1342
+ // "products/locales" rather than "products/pid/locales", so any
1343
+ // URL built from it pointed at a collection that does not exist.
1344
+ // Escaped, because `fullIdPath` is URL-facing.
1345
+ currentFullIdPath: fullIdPath + "/" + encodedEntityId,
1238
1346
  currentFullUrlPath: fullUrlPath,
1239
1347
  currentPathSegments: entitySegments,
1240
1348
  contextEntityViews: props.contextEntityViews
@@ -1406,7 +1514,16 @@ function segmentsToStrippedPath(paths) {
1406
1514
  return paths.reduce((a, b) => `${a}${COLLECTION_PATH_SEPARATOR}${b}`);
1407
1515
  }
1408
1516
  function fullPathToCollectionSegments(path) {
1409
- return path.split("/").filter((e, i) => i % 2 === 0);
1517
+ return positionalCollectionSegments(path);
1518
+ }
1519
+ function collectionSegmentsFrom(pathSegments) {
1520
+ return keepCollectionPositions(pathSegments);
1521
+ }
1522
+ function positionalCollectionSegments(path) {
1523
+ return keepCollectionPositions(path.split("/"));
1524
+ }
1525
+ function keepCollectionPositions(segments) {
1526
+ return segments.filter((e, i) => i % 2 === 0);
1410
1527
  }
1411
1528
  function serializeRegExp(input) {
1412
1529
  if (!input) return "";
@@ -1636,35 +1753,35 @@ const DEFAULT_PERMISSIONS = {
1636
1753
  create: true,
1637
1754
  delete: true
1638
1755
  };
1639
- function resolvePermissions(collection, authController, path, entity) {
1756
+ function resolvePermissions(collection, authController, path, entity, pathSegments) {
1640
1757
  const permission = collection.permissions;
1641
1758
  if (permission === void 0) {
1642
1759
  return DEFAULT_PERMISSIONS;
1643
1760
  } else if (typeof permission === "object") {
1644
1761
  return permission;
1645
1762
  } else if (typeof permission === "function") {
1646
- const pathSegments = fullPathToCollectionSegments(path);
1763
+ const collectionSegments = pathSegments ? collectionSegmentsFrom(pathSegments) : fullPathToCollectionSegments(path);
1647
1764
  return permission({
1648
1765
  entity,
1649
1766
  path,
1650
1767
  user: authController.user,
1651
1768
  authController,
1652
1769
  collection,
1653
- pathSegments
1770
+ pathSegments: collectionSegments
1654
1771
  });
1655
1772
  }
1656
1773
  console.error("Permissions:", permission);
1657
1774
  throw Error("New type of permission added and not mapped");
1658
1775
  }
1659
- function canEditEntity(collection, authController, path, entity) {
1660
- return resolvePermissions(collection, authController, path, entity)?.edit ?? DEFAULT_PERMISSIONS.edit;
1776
+ function canEditEntity(collection, authController, path, entity, pathSegments) {
1777
+ return resolvePermissions(collection, authController, path, entity, pathSegments)?.edit ?? DEFAULT_PERMISSIONS.edit;
1661
1778
  }
1662
- function canCreateEntity(collection, authController, path, entity) {
1779
+ function canCreateEntity(collection, authController, path, entity, pathSegments) {
1663
1780
  if (collection.collectionGroup) return false;
1664
- return resolvePermissions(collection, authController, path, entity)?.create ?? DEFAULT_PERMISSIONS.create;
1781
+ return resolvePermissions(collection, authController, path, entity, pathSegments)?.create ?? DEFAULT_PERMISSIONS.create;
1665
1782
  }
1666
- function canDeleteEntity(collection, authController, path, entity) {
1667
- return resolvePermissions(collection, authController, path, entity)?.delete ?? DEFAULT_PERMISSIONS.delete;
1783
+ function canDeleteEntity(collection, authController, path, entity, pathSegments) {
1784
+ return resolvePermissions(collection, authController, path, entity, pathSegments)?.delete ?? DEFAULT_PERMISSIONS.delete;
1668
1785
  }
1669
1786
  function toNumber(value) {
1670
1787
  return typeof value === "number" && Number.isFinite(value) ? value : void 0;
@@ -4636,9 +4753,10 @@ const useFireCMSContext = () => {
4636
4753
  return fireCMSContextRef.current;
4637
4754
  };
4638
4755
  function useCollectionFetch(t0) {
4639
- const $ = c(26);
4756
+ const $ = c(31);
4640
4757
  const {
4641
4758
  path: inputPath,
4759
+ pathSegments: inputPathSegments,
4642
4760
  collection,
4643
4761
  filterValues,
4644
4762
  sortBy,
@@ -4648,45 +4766,63 @@ function useCollectionFetch(t0) {
4648
4766
  const dataSource = useDataSource();
4649
4767
  const navigationController = useNavigationController();
4650
4768
  let t1;
4651
- if ($[0] !== inputPath || $[1] !== navigationController) {
4652
- t1 = navigationController.resolveIdsFrom(inputPath);
4653
- $[0] = inputPath;
4769
+ if ($[0] !== inputPathSegments || $[1] !== navigationController) {
4770
+ t1 = inputPathSegments ? navigationController.resolveSegmentsFrom?.(inputPathSegments) ?? inputPathSegments : void 0;
4771
+ $[0] = inputPathSegments;
4654
4772
  $[1] = navigationController;
4655
4773
  $[2] = t1;
4656
4774
  } else {
4657
4775
  t1 = $[2];
4658
4776
  }
4659
- const path = t1;
4777
+ const pathSegments = t1;
4778
+ let t2;
4779
+ if ($[3] !== inputPath || $[4] !== inputPathSegments || $[5] !== navigationController) {
4780
+ t2 = navigationController.resolveIdsFrom(inputPath, inputPathSegments);
4781
+ $[3] = inputPath;
4782
+ $[4] = inputPathSegments;
4783
+ $[5] = navigationController;
4784
+ $[6] = t2;
4785
+ } else {
4786
+ t2 = $[6];
4787
+ }
4788
+ const path = t2;
4660
4789
  const sortByProperty = sortBy ? sortBy[0] : void 0;
4661
4790
  const currentSort = sortBy ? sortBy[1] : void 0;
4662
4791
  const context = useFireCMSContext();
4663
- let t2;
4664
- if ($[3] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
4665
- t2 = [];
4666
- $[3] = t2;
4792
+ let t3;
4793
+ if ($[7] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
4794
+ t3 = [];
4795
+ $[7] = t3;
4667
4796
  } else {
4668
- t2 = $[3];
4797
+ t3 = $[7];
4669
4798
  }
4670
- const [data, setData] = useState(t2);
4799
+ const [data, setData] = useState(t3);
4671
4800
  const [dataLoading, setDataLoading] = useState(false);
4672
4801
  const [dataLoadingError, setDataLoadingError] = useState();
4673
4802
  const [noMoreToLoad, setNoMoreToLoad] = useState(false);
4674
- let t3;
4675
- if ($[4] !== collection || $[5] !== context || $[6] !== currentSort || $[7] !== dataSource || $[8] !== filterValues || $[9] !== itemCount || $[10] !== path || $[11] !== searchString || $[12] !== sortByProperty) {
4676
- t3 = () => {
4803
+ let t4;
4804
+ if ($[8] !== collection || $[9] !== context || $[10] !== currentSort || $[11] !== dataSource || $[12] !== filterValues || $[13] !== itemCount || $[14] !== path || $[15] !== pathSegments || $[16] !== searchString || $[17] !== sortByProperty) {
4805
+ t4 = () => {
4677
4806
  setDataLoading(true);
4678
4807
  const onEntitiesUpdate = async (entities) => {
4808
+ if (pathSegments) {
4809
+ entities = entities.map((e) => e.pathSegments ? e : {
4810
+ ...e,
4811
+ pathSegments
4812
+ });
4813
+ }
4679
4814
  if (collection.callbacks?.onFetch) {
4680
4815
  try {
4681
4816
  entities = await Promise.all(entities.map((entity) => collection.callbacks.onFetch({
4682
4817
  collection,
4683
4818
  path,
4819
+ pathSegments,
4684
4820
  entity,
4685
4821
  context
4686
4822
  })));
4687
- } catch (t42) {
4688
- const e = t42;
4689
- console.error(e);
4823
+ } catch (t52) {
4824
+ const e_0 = t52;
4825
+ console.error(e_0);
4690
4826
  }
4691
4827
  }
4692
4828
  setDataLoading(false);
@@ -4703,6 +4839,7 @@ function useCollectionFetch(t0) {
4703
4839
  if (dataSource.listenCollection) {
4704
4840
  return dataSource.listenCollection({
4705
4841
  path,
4842
+ pathSegments,
4706
4843
  collection,
4707
4844
  onUpdate: onEntitiesUpdate,
4708
4845
  onError,
@@ -4716,6 +4853,7 @@ function useCollectionFetch(t0) {
4716
4853
  } else {
4717
4854
  dataSource.fetchCollection({
4718
4855
  path,
4856
+ pathSegments,
4719
4857
  collection,
4720
4858
  searchString,
4721
4859
  filter: filterValues,
@@ -4727,61 +4865,185 @@ function useCollectionFetch(t0) {
4727
4865
  return _temp2$f;
4728
4866
  }
4729
4867
  };
4730
- $[4] = collection;
4731
- $[5] = context;
4732
- $[6] = currentSort;
4733
- $[7] = dataSource;
4734
- $[8] = filterValues;
4735
- $[9] = itemCount;
4736
- $[10] = path;
4737
- $[11] = searchString;
4738
- $[12] = sortByProperty;
4739
- $[13] = t3;
4868
+ $[8] = collection;
4869
+ $[9] = context;
4870
+ $[10] = currentSort;
4871
+ $[11] = dataSource;
4872
+ $[12] = filterValues;
4873
+ $[13] = itemCount;
4874
+ $[14] = path;
4875
+ $[15] = pathSegments;
4876
+ $[16] = searchString;
4877
+ $[17] = sortByProperty;
4878
+ $[18] = t4;
4740
4879
  } else {
4741
- t3 = $[13];
4880
+ t4 = $[18];
4742
4881
  }
4743
- let t4;
4744
- if ($[14] !== currentSort || $[15] !== filterValues || $[16] !== itemCount || $[17] !== path || $[18] !== searchString || $[19] !== sortByProperty) {
4745
- t4 = [path, itemCount, currentSort, sortByProperty, filterValues, searchString];
4746
- $[14] = currentSort;
4747
- $[15] = filterValues;
4748
- $[16] = itemCount;
4749
- $[17] = path;
4750
- $[18] = searchString;
4751
- $[19] = sortByProperty;
4752
- $[20] = t4;
4882
+ let t5;
4883
+ if ($[19] !== currentSort || $[20] !== filterValues || $[21] !== itemCount || $[22] !== path || $[23] !== searchString || $[24] !== sortByProperty) {
4884
+ t5 = [path, itemCount, currentSort, sortByProperty, filterValues, searchString];
4885
+ $[19] = currentSort;
4886
+ $[20] = filterValues;
4887
+ $[21] = itemCount;
4888
+ $[22] = path;
4889
+ $[23] = searchString;
4890
+ $[24] = sortByProperty;
4891
+ $[25] = t5;
4753
4892
  } else {
4754
- t4 = $[20];
4893
+ t5 = $[25];
4755
4894
  }
4756
- useEffect(t3, t4);
4757
- let t5;
4758
- if ($[21] !== data || $[22] !== dataLoading || $[23] !== dataLoadingError || $[24] !== noMoreToLoad) {
4759
- t5 = {
4895
+ useEffect(t4, t5);
4896
+ let t6;
4897
+ if ($[26] !== data || $[27] !== dataLoading || $[28] !== dataLoadingError || $[29] !== noMoreToLoad) {
4898
+ t6 = {
4760
4899
  data,
4761
4900
  dataLoading,
4762
4901
  dataLoadingError,
4763
4902
  noMoreToLoad
4764
4903
  };
4765
- $[21] = data;
4766
- $[22] = dataLoading;
4767
- $[23] = dataLoadingError;
4768
- $[24] = noMoreToLoad;
4769
- $[25] = t5;
4904
+ $[26] = data;
4905
+ $[27] = dataLoading;
4906
+ $[28] = dataLoadingError;
4907
+ $[29] = noMoreToLoad;
4908
+ $[30] = t6;
4770
4909
  } else {
4771
- t5 = $[25];
4910
+ t6 = $[30];
4772
4911
  }
4773
- return t5;
4912
+ return t6;
4774
4913
  }
4775
4914
  function _temp2$f() {
4776
4915
  }
4777
- function _temp$D(e_0) {
4916
+ function _temp$D(e_1) {
4778
4917
  return {
4779
- ...e_0
4918
+ ...e_1
4780
4919
  };
4781
4920
  }
4921
+ function entityCacheKey(path, entityId) {
4922
+ return `${path}/${entityId === void 0 ? entityId : encodeEntityId(entityId)}`;
4923
+ }
4924
+ const LOCAL_STORAGE_PREFIX = "entity_cache::";
4925
+ const entityCache = /* @__PURE__ */ new Map();
4926
+ const isLocalStorageAvailable = typeof localStorage !== "undefined";
4927
+ function customReplacer(key) {
4928
+ const value = this[key];
4929
+ if (value instanceof Date) {
4930
+ return {
4931
+ __type: "Date",
4932
+ value: value.toISOString()
4933
+ };
4934
+ }
4935
+ if (value instanceof EntityReference) {
4936
+ return {
4937
+ __type: "EntityReference",
4938
+ id: value.id,
4939
+ path: value.path,
4940
+ databaseId: value.databaseId
4941
+ };
4942
+ }
4943
+ if (value instanceof GeoPoint) {
4944
+ return {
4945
+ __type: "GeoPoint",
4946
+ latitude: value.latitude,
4947
+ longitude: value.longitude
4948
+ };
4949
+ }
4950
+ if (value instanceof Vector) {
4951
+ return {
4952
+ __type: "Vector",
4953
+ value: value.value
4954
+ };
4955
+ }
4956
+ return value;
4957
+ }
4958
+ function customReviver(key, value) {
4959
+ if (value && typeof value === "object" && "__type" in value) {
4960
+ switch (value.__type) {
4961
+ case "Date":
4962
+ return new Date(value.value);
4963
+ case "EntityReference":
4964
+ return new EntityReference(value.id, value.path, value.databaseId);
4965
+ case "GeoPoint":
4966
+ return new GeoPoint(value.latitude, value.longitude);
4967
+ case "Vector":
4968
+ return new Vector(value.value);
4969
+ default:
4970
+ return value;
4971
+ }
4972
+ }
4973
+ return value;
4974
+ }
4975
+ function saveEntityToCache(path, data) {
4976
+ if (isLocalStorageAvailable) {
4977
+ try {
4978
+ const key = LOCAL_STORAGE_PREFIX + path;
4979
+ const entityString = JSON.stringify(data, customReplacer);
4980
+ console.debug("Saving entity to localStorage:", {
4981
+ key,
4982
+ entityString
4983
+ });
4984
+ localStorage.setItem(key, entityString);
4985
+ } catch (error) {
4986
+ console.error(`Failed to save entity for path "${path}" to localStorage:`, error);
4987
+ }
4988
+ }
4989
+ }
4990
+ function removeEntityFromMemoryCache(path) {
4991
+ entityCache.delete(path);
4992
+ }
4993
+ function saveEntityToMemoryCache(path, data) {
4994
+ entityCache.set(path, data);
4995
+ }
4996
+ function getEntityFromMemoryCache(path) {
4997
+ return entityCache.get(path);
4998
+ }
4999
+ function getEntityFromCache(path) {
5000
+ if (isLocalStorageAvailable) {
5001
+ try {
5002
+ const key = LOCAL_STORAGE_PREFIX + path;
5003
+ const entityString = localStorage.getItem(key);
5004
+ if (entityString) {
5005
+ const entity = JSON.parse(entityString, customReviver);
5006
+ return entity;
5007
+ }
5008
+ } catch (error) {
5009
+ console.error(`Failed to load entity for path "${path}" from localStorage:`, error);
5010
+ }
5011
+ }
5012
+ return void 0;
5013
+ }
5014
+ function removeEntityFromCache(path) {
5015
+ if (isLocalStorageAvailable) {
5016
+ try {
5017
+ const key = LOCAL_STORAGE_PREFIX + path;
5018
+ localStorage.removeItem(key);
5019
+ } catch (error) {
5020
+ console.error(`Failed to remove entity for path "${path}" from localStorage:`, error);
5021
+ }
5022
+ }
5023
+ }
5024
+ function flattenKeys(obj, prefix = "", result = []) {
5025
+ if (isObject(obj) || Array.isArray(obj)) {
5026
+ const plainObject = isPlainObject(obj);
5027
+ if (!plainObject && prefix) {
5028
+ result.push(prefix);
5029
+ } else {
5030
+ for (const key in obj) {
5031
+ if (Object.prototype.hasOwnProperty.call(obj, key)) {
5032
+ const newKey = prefix ? Array.isArray(obj) ? `${prefix}[${key}]` : `${prefix}.${key}` : key;
5033
+ if (isObject(obj[key]) || Array.isArray(obj[key])) {
5034
+ flattenKeys(obj[key], newKey, result);
5035
+ } else {
5036
+ result.push(newKey);
5037
+ }
5038
+ }
5039
+ }
5040
+ }
5041
+ }
5042
+ return result;
5043
+ }
4782
5044
  const CACHE = {};
4783
5045
  function useEntityFetch(t0) {
4784
- const $ = c(21);
5046
+ const $ = c(23);
4785
5047
  const {
4786
5048
  path: inputPath,
4787
5049
  pathSegments: inputPathSegments,
@@ -4793,44 +5055,57 @@ function useEntityFetch(t0) {
4793
5055
  const useCache = t1 === void 0 ? false : t1;
4794
5056
  const dataSource = useDataSource();
4795
5057
  const navigationController = useNavigationController();
4796
- let path;
4797
5058
  let t2;
4798
- if ($[0] !== inputPath || $[1] !== inputPathSegments || $[2] !== navigationController) {
4799
- path = navigationController.resolveIdsFrom(inputPath);
4800
- t2 = inputPathSegments ?? path.split("/");
4801
- $[0] = inputPath;
4802
- $[1] = inputPathSegments;
4803
- $[2] = navigationController;
4804
- $[3] = path;
4805
- $[4] = t2;
5059
+ if ($[0] !== inputPathSegments || $[1] !== navigationController) {
5060
+ t2 = inputPathSegments ? navigationController.resolveSegmentsFrom?.(inputPathSegments) ?? inputPathSegments : void 0;
5061
+ $[0] = inputPathSegments;
5062
+ $[1] = navigationController;
5063
+ $[2] = t2;
4806
5064
  } else {
4807
- path = $[3];
4808
- t2 = $[4];
5065
+ t2 = $[2];
4809
5066
  }
4810
5067
  const pathSegments = t2;
5068
+ let t3;
5069
+ if ($[3] !== inputPath || $[4] !== inputPathSegments || $[5] !== navigationController) {
5070
+ t3 = navigationController.resolveIdsFrom(inputPath, inputPathSegments);
5071
+ $[3] = inputPath;
5072
+ $[4] = inputPathSegments;
5073
+ $[5] = navigationController;
5074
+ $[6] = t3;
5075
+ } else {
5076
+ t3 = $[6];
5077
+ }
5078
+ const path = t3;
4811
5079
  const context = useFireCMSContext();
4812
5080
  const [entity, setEntity] = useState();
4813
5081
  const [dataLoading, setDataLoading] = useState(true);
4814
5082
  const [dataLoadingError, setDataLoadingError] = useState();
4815
- let t3;
4816
- if ($[5] !== collection || $[6] !== context || $[7] !== dataSource || $[8] !== databaseId || $[9] !== entityId || $[10] !== path || $[11] !== pathSegments || $[12] !== useCache) {
4817
- t3 = () => {
5083
+ let t4;
5084
+ if ($[7] !== collection || $[8] !== context || $[9] !== dataSource || $[10] !== databaseId || $[11] !== entityId || $[12] !== path || $[13] !== pathSegments || $[14] !== useCache) {
5085
+ t4 = () => {
4818
5086
  setDataLoading(true);
4819
5087
  const onEntityUpdate = async (updatedEntity) => {
5088
+ if (updatedEntity && pathSegments && !updatedEntity.pathSegments) {
5089
+ updatedEntity = {
5090
+ ...updatedEntity,
5091
+ pathSegments
5092
+ };
5093
+ }
4820
5094
  if (collection.callbacks?.onFetch && updatedEntity) {
4821
5095
  try {
4822
5096
  updatedEntity = await collection.callbacks.onFetch({
4823
5097
  collection,
4824
5098
  path,
5099
+ pathSegments,
4825
5100
  entity: updatedEntity,
4826
5101
  context
4827
5102
  });
4828
- } catch (t42) {
4829
- const e = t42;
5103
+ } catch (t52) {
5104
+ const e = t52;
4830
5105
  console.error(e);
4831
5106
  }
4832
5107
  }
4833
- CACHE[`${path}/${entityId}`] = updatedEntity;
5108
+ CACHE[entityCacheKey(path, entityId)] = updatedEntity;
4834
5109
  setEntity(updatedEntity);
4835
5110
  setDataLoading(false);
4836
5111
  setDataLoadingError(void 0);
@@ -4841,8 +5116,8 @@ function useEntityFetch(t0) {
4841
5116
  setEntity(void 0);
4842
5117
  setDataLoadingError(error);
4843
5118
  };
4844
- if (entityId && useCache && CACHE[`${path}/${entityId}`]) {
4845
- setEntity(CACHE[`${path}/${entityId}`]);
5119
+ if (entityId && useCache && CACHE[entityCacheKey(path, entityId)]) {
5120
+ setEntity(CACHE[entityCacheKey(path, entityId)]);
4846
5121
  setDataLoading(false);
4847
5122
  setDataLoadingError(void 0);
4848
5123
  return _temp$C;
@@ -4874,43 +5149,43 @@ function useEntityFetch(t0) {
4874
5149
  }
4875
5150
  }
4876
5151
  };
4877
- $[5] = collection;
4878
- $[6] = context;
4879
- $[7] = dataSource;
4880
- $[8] = databaseId;
4881
- $[9] = entityId;
4882
- $[10] = path;
4883
- $[11] = pathSegments;
4884
- $[12] = useCache;
4885
- $[13] = t3;
5152
+ $[7] = collection;
5153
+ $[8] = context;
5154
+ $[9] = dataSource;
5155
+ $[10] = databaseId;
5156
+ $[11] = entityId;
5157
+ $[12] = path;
5158
+ $[13] = pathSegments;
5159
+ $[14] = useCache;
5160
+ $[15] = t4;
4886
5161
  } else {
4887
- t3 = $[13];
5162
+ t4 = $[15];
4888
5163
  }
4889
- let t4;
4890
- if ($[14] !== entityId || $[15] !== path) {
4891
- t4 = [entityId, path];
4892
- $[14] = entityId;
4893
- $[15] = path;
4894
- $[16] = t4;
5164
+ let t5;
5165
+ if ($[16] !== entityId || $[17] !== path) {
5166
+ t5 = [entityId, path];
5167
+ $[16] = entityId;
5168
+ $[17] = path;
5169
+ $[18] = t5;
4895
5170
  } else {
4896
- t4 = $[16];
5171
+ t5 = $[18];
4897
5172
  }
4898
- useEffect(t3, t4);
4899
- let t5;
4900
- if ($[17] !== dataLoading || $[18] !== dataLoadingError || $[19] !== entity) {
4901
- t5 = {
5173
+ useEffect(t4, t5);
5174
+ let t6;
5175
+ if ($[19] !== dataLoading || $[20] !== dataLoadingError || $[21] !== entity) {
5176
+ t6 = {
4902
5177
  entity,
4903
5178
  dataLoading,
4904
5179
  dataLoadingError
4905
5180
  };
4906
- $[17] = dataLoading;
4907
- $[18] = dataLoadingError;
4908
- $[19] = entity;
4909
- $[20] = t5;
5181
+ $[19] = dataLoading;
5182
+ $[20] = dataLoadingError;
5183
+ $[21] = entity;
5184
+ $[22] = t6;
4910
5185
  } else {
4911
- t5 = $[20];
5186
+ t6 = $[22];
4912
5187
  }
4913
- return t5;
5188
+ return t6;
4914
5189
  }
4915
5190
  function _temp3$5() {
4916
5191
  }
@@ -4938,7 +5213,7 @@ async function saveEntityWithCallbacks({
4938
5213
  }
4939
5214
  let updatedValues;
4940
5215
  const customizationController = context.customizationController;
4941
- const resolvedPath = context.navigation.resolveIdsFrom(path);
5216
+ const resolvedPath = context.navigation.resolveIdsFrom(path, pathSegments);
4942
5217
  const callbacks = collection.callbacks;
4943
5218
  if (callbacks?.onPreSave) {
4944
5219
  try {
@@ -4953,6 +5228,7 @@ async function saveEntityWithCallbacks({
4953
5228
  updatedValues = await callbacks.onPreSave({
4954
5229
  collection: resolvedCollection,
4955
5230
  path,
5231
+ pathSegments,
4956
5232
  resolvedPath,
4957
5233
  entityId,
4958
5234
  values,
@@ -4971,7 +5247,7 @@ async function saveEntityWithCallbacks({
4971
5247
  return dataSource.saveEntity({
4972
5248
  collection,
4973
5249
  path: resolvedPath,
4974
- pathSegments: pathSegments ?? resolvedPath.split("/"),
5250
+ pathSegments,
4975
5251
  entityId,
4976
5252
  values: updatedValues,
4977
5253
  previousValues,
@@ -4990,6 +5266,7 @@ async function saveEntityWithCallbacks({
4990
5266
  callbacks.onSaveSuccess({
4991
5267
  collection: resolvedCollection,
4992
5268
  path,
5269
+ pathSegments,
4993
5270
  resolvedPath,
4994
5271
  entityId: entity.id,
4995
5272
  values: updatedValues,
@@ -5015,6 +5292,7 @@ async function saveEntityWithCallbacks({
5015
5292
  callbacks.onSaveFailure({
5016
5293
  collection: resolvedCollection,
5017
5294
  path,
5295
+ pathSegments,
5018
5296
  resolvedPath,
5019
5297
  entityId,
5020
5298
  values: updatedValues,
@@ -5029,6 +5307,7 @@ async function saveEntityWithCallbacks({
5029
5307
  async function deleteEntityWithCallbacks({
5030
5308
  dataSource,
5031
5309
  entity,
5310
+ pathSegments,
5032
5311
  collection,
5033
5312
  callbacks,
5034
5313
  onDeleteSuccess,
@@ -5038,11 +5317,13 @@ async function deleteEntityWithCallbacks({
5038
5317
  context
5039
5318
  }) {
5040
5319
  console.debug("Deleting entity", entity.path, entity.id);
5320
+ const resolvedPathSegments = pathSegments ?? entity.pathSegments;
5041
5321
  const entityDeleteProps = {
5042
5322
  entity,
5043
5323
  collection,
5044
5324
  entityId: entity.id,
5045
5325
  path: entity.path,
5326
+ pathSegments: resolvedPathSegments,
5046
5327
  context
5047
5328
  };
5048
5329
  if (callbacks?.onPreDelete) {
@@ -5055,6 +5336,7 @@ async function deleteEntityWithCallbacks({
5055
5336
  }
5056
5337
  }
5057
5338
  return dataSource.deleteEntity({
5339
+ pathSegments: resolvedPathSegments,
5058
5340
  entity,
5059
5341
  collection
5060
5342
  }).then(() => {
@@ -5090,12 +5372,14 @@ function resolveNavigationFrom({
5090
5372
  if (entry.type === "collection") {
5091
5373
  return Promise.resolve(entry);
5092
5374
  } else if (entry.type === "entity") {
5093
- const collection = navigation.getCollection(entry.path);
5375
+ const collection = navigation.getCollection(entry.path, false, entry.pathSegments);
5094
5376
  if (!collection) {
5095
5377
  throw Error(`No collection defined in the navigation for the entity with path ${entry.path}`);
5096
5378
  }
5097
5379
  return dataSource.fetchEntity({
5098
5380
  path: entry.path,
5381
+ // The navigation entry already knows the real segment boundaries.
5382
+ pathSegments: entry.pathSegments,
5099
5383
  entityId: entry.entityId,
5100
5384
  collection
5101
5385
  }).then((entity) => {
@@ -6495,7 +6779,7 @@ function EntityPreview({
6495
6779
  const sideEntityController = useSideEntityController();
6496
6780
  const customizationController = useCustomizationController();
6497
6781
  const navigationController = useNavigationController();
6498
- const collection = collectionProp ?? navigationController.getCollection(entity.path);
6782
+ const collection = collectionProp ?? navigationController.getCollection(entity.path, false, entity.pathSegments);
6499
6783
  if (!collection) {
6500
6784
  throw Error(`Couldn't find the corresponding collection view for the path: ${entity.path}`);
6501
6785
  }
@@ -6538,6 +6822,9 @@ function EntityPreview({
6538
6822
  sideEntityController.open({
6539
6823
  entityId: entity.id,
6540
6824
  path: entity.path,
6825
+ // Paired with `entity.path` above; undefined if the entity was
6826
+ // loaded without them.
6827
+ pathSegments: entity.pathSegments,
6541
6828
  collection,
6542
6829
  updateUrl: true
6543
6830
  });
@@ -6662,7 +6949,7 @@ const ReferencePreview = function ReferencePreview2(props) {
6662
6949
  return t0;
6663
6950
  };
6664
6951
  function ReferencePreviewInternal(t0) {
6665
- const $ = c(22);
6952
+ const $ = c(23);
6666
6953
  const {
6667
6954
  disabled,
6668
6955
  reference,
@@ -6678,70 +6965,71 @@ function ReferencePreviewInternal(t0) {
6678
6965
  const customizationController = useCustomizationController();
6679
6966
  const navigationController = useNavigationController();
6680
6967
  let t3;
6681
- if ($[0] !== navigationController || $[1] !== reference.path) {
6682
- t3 = navigationController.getCollection(reference.path);
6968
+ if ($[0] !== navigationController || $[1] !== reference.path || $[2] !== reference.pathSegments) {
6969
+ t3 = navigationController.getCollection(reference.path, false, reference.pathSegments);
6683
6970
  $[0] = navigationController;
6684
6971
  $[1] = reference.path;
6685
- $[2] = t3;
6972
+ $[2] = reference.pathSegments;
6973
+ $[3] = t3;
6686
6974
  } else {
6687
- t3 = $[2];
6975
+ t3 = $[3];
6688
6976
  }
6689
6977
  const collection = t3;
6690
6978
  if (!collection) {
6691
6979
  if (customizationController.components?.missingReference) {
6692
6980
  let t42;
6693
- if ($[3] !== customizationController.components.missingReference || $[4] !== reference.path) {
6981
+ if ($[4] !== customizationController.components.missingReference || $[5] !== reference.path) {
6694
6982
  t42 = /* @__PURE__ */ jsx(customizationController.components.missingReference, { path: reference.path });
6695
- $[3] = customizationController.components.missingReference;
6696
- $[4] = reference.path;
6697
- $[5] = t42;
6983
+ $[4] = customizationController.components.missingReference;
6984
+ $[5] = reference.path;
6985
+ $[6] = t42;
6698
6986
  } else {
6699
- t42 = $[5];
6987
+ t42 = $[6];
6700
6988
  }
6701
6989
  return t42;
6702
6990
  } else {
6703
6991
  const t42 = size ?? "medium";
6704
6992
  let t5;
6705
- if ($[6] !== reference.pathWithId) {
6993
+ if ($[7] !== reference.pathWithId) {
6706
6994
  t5 = /* @__PURE__ */ jsx(ErrorView, { error: "Unexpected reference value. Click to edit", tooltip: reference.pathWithId });
6707
- $[6] = reference.pathWithId;
6708
- $[7] = t5;
6995
+ $[7] = reference.pathWithId;
6996
+ $[8] = t5;
6709
6997
  } else {
6710
- t5 = $[7];
6998
+ t5 = $[8];
6711
6999
  }
6712
7000
  let t6;
6713
- if ($[8] !== onClick || $[9] !== t42 || $[10] !== t5) {
7001
+ if ($[9] !== onClick || $[10] !== t42 || $[11] !== t5) {
6714
7002
  t6 = /* @__PURE__ */ jsx(EntityPreviewContainer, { onClick, size: t42, children: t5 });
6715
- $[8] = onClick;
6716
- $[9] = t42;
6717
- $[10] = t5;
6718
- $[11] = t6;
7003
+ $[9] = onClick;
7004
+ $[10] = t42;
7005
+ $[11] = t5;
7006
+ $[12] = t6;
6719
7007
  } else {
6720
- t6 = $[11];
7008
+ t6 = $[12];
6721
7009
  }
6722
7010
  return t6;
6723
7011
  }
6724
7012
  }
6725
7013
  let t4;
6726
- if ($[12] !== collection || $[13] !== disabled || $[14] !== hover || $[15] !== includeEntityLink || $[16] !== includeId || $[17] !== onClick || $[18] !== previewProperties || $[19] !== reference || $[20] !== size) {
7014
+ if ($[13] !== collection || $[14] !== disabled || $[15] !== hover || $[16] !== includeEntityLink || $[17] !== includeId || $[18] !== onClick || $[19] !== previewProperties || $[20] !== reference || $[21] !== size) {
6727
7015
  t4 = /* @__PURE__ */ jsx(ReferencePreviewExisting, { reference, collection, previewProperties, size, disabled, includeEntityLink, includeId, onClick, hover });
6728
- $[12] = collection;
6729
- $[13] = disabled;
6730
- $[14] = hover;
6731
- $[15] = includeEntityLink;
6732
- $[16] = includeId;
6733
- $[17] = onClick;
6734
- $[18] = previewProperties;
6735
- $[19] = reference;
6736
- $[20] = size;
6737
- $[21] = t4;
7016
+ $[13] = collection;
7017
+ $[14] = disabled;
7018
+ $[15] = hover;
7019
+ $[16] = includeEntityLink;
7020
+ $[17] = includeId;
7021
+ $[18] = onClick;
7022
+ $[19] = previewProperties;
7023
+ $[20] = reference;
7024
+ $[21] = size;
7025
+ $[22] = t4;
6738
7026
  } else {
6739
- t4 = $[21];
7027
+ t4 = $[22];
6740
7028
  }
6741
7029
  return t4;
6742
7030
  }
6743
7031
  function ReferencePreviewExisting(t0) {
6744
- const $ = c(35);
7032
+ const $ = c(37);
6745
7033
  const {
6746
7034
  reference,
6747
7035
  collection,
@@ -6754,9 +7042,10 @@ function ReferencePreviewExisting(t0) {
6754
7042
  hover
6755
7043
  } = t0;
6756
7044
  let t1;
6757
- if ($[0] !== collection || $[1] !== reference.id || $[2] !== reference.path) {
7045
+ if ($[0] !== collection || $[1] !== reference.id || $[2] !== reference.path || $[3] !== reference.pathSegments) {
6758
7046
  t1 = {
6759
7047
  path: reference.path,
7048
+ pathSegments: reference.pathSegments,
6760
7049
  entityId: reference.id,
6761
7050
  collection,
6762
7051
  useCache: true
@@ -6764,46 +7053,48 @@ function ReferencePreviewExisting(t0) {
6764
7053
  $[0] = collection;
6765
7054
  $[1] = reference.id;
6766
7055
  $[2] = reference.path;
6767
- $[3] = t1;
7056
+ $[3] = reference.pathSegments;
7057
+ $[4] = t1;
6768
7058
  } else {
6769
- t1 = $[3];
7059
+ t1 = $[4];
6770
7060
  }
6771
7061
  const {
6772
7062
  entity,
6773
7063
  dataLoading
6774
7064
  } = useEntityFetch(t1);
6775
7065
  if (entity) {
6776
- referencesCache.set(reference.pathWithId, entity);
7066
+ referencesCache.set(entityCacheKey(reference.path, reference.id), entity);
6777
7067
  }
6778
7068
  let t2;
6779
- if ($[4] !== entity || $[5] !== reference.pathWithId) {
6780
- t2 = entity ?? referencesCache.get(reference.pathWithId);
6781
- $[4] = entity;
6782
- $[5] = reference.pathWithId;
6783
- $[6] = t2;
7069
+ if ($[5] !== entity || $[6] !== reference.id || $[7] !== reference.path) {
7070
+ t2 = entity ?? referencesCache.get(entityCacheKey(reference.path, reference.id));
7071
+ $[5] = entity;
7072
+ $[6] = reference.id;
7073
+ $[7] = reference.path;
7074
+ $[8] = t2;
6784
7075
  } else {
6785
- t2 = $[6];
7076
+ t2 = $[8];
6786
7077
  }
6787
7078
  const usedEntity = t2;
6788
7079
  let body;
6789
7080
  if (!reference) {
6790
7081
  let t32;
6791
- if ($[7] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
7082
+ if ($[9] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
6792
7083
  t32 = /* @__PURE__ */ jsx(ErrorView, { error: "Reference not set" });
6793
- $[7] = t32;
7084
+ $[9] = t32;
6794
7085
  } else {
6795
- t32 = $[7];
7086
+ t32 = $[9];
6796
7087
  }
6797
7088
  body = t32;
6798
7089
  } else {
6799
7090
  if (usedEntity && !usedEntity.values) {
6800
7091
  let t32;
6801
- if ($[8] !== reference.path) {
7092
+ if ($[10] !== reference.path) {
6802
7093
  t32 = /* @__PURE__ */ jsx(ErrorView, { error: "Reference does not exist", tooltip: reference.path });
6803
- $[8] = reference.path;
6804
- $[9] = t32;
7094
+ $[10] = reference.path;
7095
+ $[11] = t32;
6805
7096
  } else {
6806
- t32 = $[9];
7097
+ t32 = $[11];
6807
7098
  }
6808
7099
  body = t32;
6809
7100
  }
@@ -6812,15 +7103,15 @@ function ReferencePreviewExisting(t0) {
6812
7103
  const t32 = disabled ? void 0 : onClick;
6813
7104
  const t4 = disabled ? void 0 : hover;
6814
7105
  let t5;
6815
- if ($[10] !== body || $[11] !== size || $[12] !== t32 || $[13] !== t4) {
7106
+ if ($[12] !== body || $[13] !== size || $[14] !== t32 || $[15] !== t4) {
6816
7107
  t5 = /* @__PURE__ */ jsx(EntityPreviewContainer, { onClick: t32, hover: t4, size, children: body });
6817
- $[10] = body;
6818
- $[11] = size;
6819
- $[12] = t32;
6820
- $[13] = t4;
6821
- $[14] = t5;
7108
+ $[12] = body;
7109
+ $[13] = size;
7110
+ $[14] = t32;
7111
+ $[15] = t4;
7112
+ $[16] = t5;
6822
7113
  } else {
6823
- t5 = $[14];
7114
+ t5 = $[16];
6824
7115
  }
6825
7116
  return t5;
6826
7117
  }
@@ -6828,21 +7119,21 @@ function ReferencePreviewExisting(t0) {
6828
7119
  const t32 = disabled ? void 0 : onClick;
6829
7120
  const t4 = disabled ? void 0 : hover;
6830
7121
  let t5;
6831
- if ($[15] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
7122
+ if ($[17] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
6832
7123
  t5 = /* @__PURE__ */ jsx(Skeleton, {});
6833
- $[15] = t5;
7124
+ $[17] = t5;
6834
7125
  } else {
6835
- t5 = $[15];
7126
+ t5 = $[17];
6836
7127
  }
6837
7128
  let t6;
6838
- if ($[16] !== size || $[17] !== t32 || $[18] !== t4) {
7129
+ if ($[18] !== size || $[19] !== t32 || $[20] !== t4) {
6839
7130
  t6 = /* @__PURE__ */ jsx(EntityPreviewContainer, { onClick: t32, hover: t4, size, children: t5 });
6840
- $[16] = size;
6841
- $[17] = t32;
6842
- $[18] = t4;
6843
- $[19] = t6;
7131
+ $[18] = size;
7132
+ $[19] = t32;
7133
+ $[20] = t4;
7134
+ $[21] = t6;
6844
7135
  } else {
6845
- t6 = $[19];
7136
+ t6 = $[21];
6846
7137
  }
6847
7138
  return t6;
6848
7139
  }
@@ -6850,39 +7141,39 @@ function ReferencePreviewExisting(t0) {
6850
7141
  const t32 = disabled ? void 0 : onClick;
6851
7142
  const t4 = disabled ? void 0 : hover;
6852
7143
  let t5;
6853
- if ($[20] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
7144
+ if ($[22] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
6854
7145
  t5 = /* @__PURE__ */ jsx(ErrorView, { error: "Entity not found" });
6855
- $[20] = t5;
7146
+ $[22] = t5;
6856
7147
  } else {
6857
- t5 = $[20];
7148
+ t5 = $[22];
6858
7149
  }
6859
7150
  let t6;
6860
- if ($[21] !== size || $[22] !== t32 || $[23] !== t4) {
7151
+ if ($[23] !== size || $[24] !== t32 || $[25] !== t4) {
6861
7152
  t6 = /* @__PURE__ */ jsx(EntityPreviewContainer, { onClick: t32, hover: t4, size, children: t5 });
6862
- $[21] = size;
6863
- $[22] = t32;
6864
- $[23] = t4;
6865
- $[24] = t6;
7153
+ $[23] = size;
7154
+ $[24] = t32;
7155
+ $[25] = t4;
7156
+ $[26] = t6;
6866
7157
  } else {
6867
- t6 = $[24];
7158
+ t6 = $[26];
6868
7159
  }
6869
7160
  return t6;
6870
7161
  }
6871
7162
  let t3;
6872
- if ($[25] !== collection || $[26] !== disabled || $[27] !== hover || $[28] !== includeEntityLink || $[29] !== includeId || $[30] !== onClick || $[31] !== previewProperties || $[32] !== size || $[33] !== usedEntity) {
7163
+ if ($[27] !== collection || $[28] !== disabled || $[29] !== hover || $[30] !== includeEntityLink || $[31] !== includeId || $[32] !== onClick || $[33] !== previewProperties || $[34] !== size || $[35] !== usedEntity) {
6873
7164
  t3 = /* @__PURE__ */ jsx(EntityPreview, { size, previewKeys: previewProperties, disabled, entity: usedEntity, collection, onClick, includeEntityLink, includeId, hover });
6874
- $[25] = collection;
6875
- $[26] = disabled;
6876
- $[27] = hover;
6877
- $[28] = includeEntityLink;
6878
- $[29] = includeId;
6879
- $[30] = onClick;
6880
- $[31] = previewProperties;
6881
- $[32] = size;
6882
- $[33] = usedEntity;
6883
- $[34] = t3;
7165
+ $[27] = collection;
7166
+ $[28] = disabled;
7167
+ $[29] = hover;
7168
+ $[30] = includeEntityLink;
7169
+ $[31] = includeId;
7170
+ $[32] = onClick;
7171
+ $[33] = previewProperties;
7172
+ $[34] = size;
7173
+ $[35] = usedEntity;
7174
+ $[36] = t3;
6884
7175
  } else {
6885
- t3 = $[34];
7176
+ t3 = $[36];
6886
7177
  }
6887
7178
  return t3;
6888
7179
  }
@@ -11179,126 +11470,6 @@ const PropertyTableCell = React__default.memo(function PropertyTableCell2({
11179
11470
  function areEqual(prevProps, nextProps) {
11180
11471
  return prevProps.height === nextProps.height && prevProps.propertyKey === nextProps.propertyKey && prevProps.align === nextProps.align && prevProps.width === nextProps.width && equal(prevProps.property, nextProps.property) && equal(prevProps.value, nextProps.value) && equal(prevProps.entity.id, nextProps.entity.id) && equal(prevProps.entity.values, nextProps.entity.values) && prevProps.isDragging === nextProps.isDragging && prevProps.isDraggable === nextProps.isDraggable && prevProps.frozen === nextProps.frozen;
11181
11472
  }
11182
- const LOCAL_STORAGE_PREFIX = "entity_cache::";
11183
- const entityCache = /* @__PURE__ */ new Map();
11184
- const isLocalStorageAvailable = typeof localStorage !== "undefined";
11185
- function customReplacer(key) {
11186
- const value = this[key];
11187
- if (value instanceof Date) {
11188
- return {
11189
- __type: "Date",
11190
- value: value.toISOString()
11191
- };
11192
- }
11193
- if (value instanceof EntityReference) {
11194
- return {
11195
- __type: "EntityReference",
11196
- id: value.id,
11197
- path: value.path,
11198
- databaseId: value.databaseId
11199
- };
11200
- }
11201
- if (value instanceof GeoPoint) {
11202
- return {
11203
- __type: "GeoPoint",
11204
- latitude: value.latitude,
11205
- longitude: value.longitude
11206
- };
11207
- }
11208
- if (value instanceof Vector) {
11209
- return {
11210
- __type: "Vector",
11211
- value: value.value
11212
- };
11213
- }
11214
- return value;
11215
- }
11216
- function customReviver(key, value) {
11217
- if (value && typeof value === "object" && "__type" in value) {
11218
- switch (value.__type) {
11219
- case "Date":
11220
- return new Date(value.value);
11221
- case "EntityReference":
11222
- return new EntityReference(value.id, value.path, value.databaseId);
11223
- case "GeoPoint":
11224
- return new GeoPoint(value.latitude, value.longitude);
11225
- case "Vector":
11226
- return new Vector(value.value);
11227
- default:
11228
- return value;
11229
- }
11230
- }
11231
- return value;
11232
- }
11233
- function saveEntityToCache(path, data) {
11234
- if (isLocalStorageAvailable) {
11235
- try {
11236
- const key = LOCAL_STORAGE_PREFIX + path;
11237
- const entityString = JSON.stringify(data, customReplacer);
11238
- console.debug("Saving entity to localStorage:", {
11239
- key,
11240
- entityString
11241
- });
11242
- localStorage.setItem(key, entityString);
11243
- } catch (error) {
11244
- console.error(`Failed to save entity for path "${path}" to localStorage:`, error);
11245
- }
11246
- }
11247
- }
11248
- function removeEntityFromMemoryCache(path) {
11249
- entityCache.delete(path);
11250
- }
11251
- function saveEntityToMemoryCache(path, data) {
11252
- entityCache.set(path, data);
11253
- }
11254
- function getEntityFromMemoryCache(path) {
11255
- return entityCache.get(path);
11256
- }
11257
- function getEntityFromCache(path) {
11258
- if (isLocalStorageAvailable) {
11259
- try {
11260
- const key = LOCAL_STORAGE_PREFIX + path;
11261
- const entityString = localStorage.getItem(key);
11262
- if (entityString) {
11263
- const entity = JSON.parse(entityString, customReviver);
11264
- return entity;
11265
- }
11266
- } catch (error) {
11267
- console.error(`Failed to load entity for path "${path}" from localStorage:`, error);
11268
- }
11269
- }
11270
- return void 0;
11271
- }
11272
- function removeEntityFromCache(path) {
11273
- if (isLocalStorageAvailable) {
11274
- try {
11275
- const key = LOCAL_STORAGE_PREFIX + path;
11276
- localStorage.removeItem(key);
11277
- } catch (error) {
11278
- console.error(`Failed to remove entity for path "${path}" from localStorage:`, error);
11279
- }
11280
- }
11281
- }
11282
- function flattenKeys(obj, prefix = "", result = []) {
11283
- if (isObject(obj) || Array.isArray(obj)) {
11284
- const plainObject = isPlainObject(obj);
11285
- if (!plainObject && prefix) {
11286
- result.push(prefix);
11287
- } else {
11288
- for (const key in obj) {
11289
- if (Object.prototype.hasOwnProperty.call(obj, key)) {
11290
- const newKey = prefix ? Array.isArray(obj) ? `${prefix}[${key}]` : `${prefix}.${key}` : key;
11291
- if (isObject(obj[key]) || Array.isArray(obj[key])) {
11292
- flattenKeys(obj[key], newKey, result);
11293
- } else {
11294
- result.push(newKey);
11295
- }
11296
- }
11297
- }
11298
- }
11299
- }
11300
- return result;
11301
- }
11302
11473
  function FieldHelperText(t0) {
11303
11474
  const $ = c(10);
11304
11475
  const {
@@ -16742,6 +16913,7 @@ function getChanges(source, comparison) {
16742
16913
  }
16743
16914
  function EntityForm({
16744
16915
  path,
16916
+ pathSegments,
16745
16917
  fullIdPath,
16746
16918
  entityId: entityIdProp,
16747
16919
  collection,
@@ -16792,6 +16964,7 @@ function EntityForm({
16792
16964
  entityId: entityIdProp,
16793
16965
  collection,
16794
16966
  path,
16967
+ pathSegments,
16795
16968
  values: valuesToBeSaved
16796
16969
  });
16797
16970
  }, false, 2e3);
@@ -16808,7 +16981,7 @@ function EntityForm({
16808
16981
  if (mustSetCustomId) {
16809
16982
  return void 0;
16810
16983
  } else {
16811
- return dataSource.generateEntityId(path, collection);
16984
+ return dataSource.generateEntityId(path, collection, pathSegments);
16812
16985
  }
16813
16986
  } else {
16814
16987
  return entityIdProp;
@@ -16819,7 +16992,7 @@ function EntityForm({
16819
16992
  const [savingError, setSavingError] = useState();
16820
16993
  const autoSave = collection.formAutoSave && !collection.customId;
16821
16994
  const baseInitialValues = useMemo(() => getInitialEntityValues(authController, collection, path, status, entity, customizationController.propertyConfigs), [authController, collection, path, status, entity, customizationController.propertyConfigs]);
16822
- const localChangesDataRaw = useMemo(() => entityId ? getEntityFromCache(path + "/" + entityId) : getEntityFromCache(path + "#new"), [entityId, path]);
16995
+ const localChangesDataRaw = useMemo(() => entityId ? getEntityFromCache(entityCacheKey(path, entityId)) : getEntityFromCache(path + "#new"), [entityId, path]);
16823
16996
  const [localChangesCleared, setLocalChangesCleared] = useState(false);
16824
16997
  const localChangesBackup = getLocalChangesBackup(collection);
16825
16998
  const autoApplyLocalChanges = localChangesBackup === "auto_apply";
@@ -16881,7 +17054,7 @@ function EntityForm({
16881
17054
  onValuesModified?.(false, initialValues_0);
16882
17055
  },
16883
17056
  onValuesChangeDeferred: (values_0, controller) => {
16884
- const key = status === "new" || status === "copy" ? path + "#new" : path + "/" + entityId;
17057
+ const key = status === "new" || status === "copy" ? path + "#new" : entityCacheKey(path, entityId);
16885
17058
  if (controller.dirty && localChangesBackup !== false) {
16886
17059
  const touchedValues = removeEmptyContainers(extractTouchedValues(values_0, controller.touched));
16887
17060
  if (touchedValues && Object.keys(touchedValues).length > 0) {
@@ -16946,8 +17119,8 @@ function EntityForm({
16946
17119
  removeEntityFromMemoryCache(path + "#new");
16947
17120
  removeEntityFromCache(path + "#new");
16948
17121
  } else {
16949
- removeEntityFromMemoryCache(path + "/" + entityId);
16950
- removeEntityFromCache(path + "/" + entityId);
17122
+ removeEntityFromMemoryCache(entityCacheKey(path, entityId));
17123
+ removeEntityFromCache(entityCacheKey(path, entityId));
16951
17124
  }
16952
17125
  }
16953
17126
  const onSaveSuccess = (updatedEntity) => {
@@ -16965,6 +17138,7 @@ function EntityForm({
16965
17138
  entity: updatedEntity,
16966
17139
  status,
16967
17140
  path,
17141
+ pathSegments,
16968
17142
  entityId: updatedEntity.id,
16969
17143
  collection
16970
17144
  });
@@ -16983,10 +17157,12 @@ function EntityForm({
16983
17157
  previousValues,
16984
17158
  entityId: entityId_0,
16985
17159
  collection: collection_0,
16986
- path: path_0
17160
+ path: path_0,
17161
+ pathSegments: pathSegments_0
16987
17162
  }) => {
16988
17163
  return saveEntityWithCallbacks({
16989
17164
  path: path_0,
17165
+ pathSegments: pathSegments_0,
16990
17166
  entityId: entityId_0,
16991
17167
  values: values_2,
16992
17168
  previousValues,
@@ -17003,6 +17179,7 @@ function EntityForm({
17003
17179
  const onSaveEntityRequest = async ({
17004
17180
  collection: collection_1,
17005
17181
  path: path_1,
17182
+ pathSegments: pathSegments_1,
17006
17183
  entityId: entityId_1,
17007
17184
  values: values_3,
17008
17185
  previousValues: previousValues_0,
@@ -17015,6 +17192,7 @@ function EntityForm({
17015
17192
  return saveEntity({
17016
17193
  collection: collection_1,
17017
17194
  path: path_1,
17195
+ pathSegments: pathSegments_1,
17018
17196
  entityId: entityId_1,
17019
17197
  values: values_3,
17020
17198
  previousValues: previousValues_0
@@ -17027,6 +17205,7 @@ function EntityForm({
17027
17205
  return onSaveEntityRequest({
17028
17206
  collection: resolvedCollection,
17029
17207
  path,
17208
+ pathSegments,
17030
17209
  entityId,
17031
17210
  values: values_4,
17032
17211
  previousValues: entity?.values,
@@ -17071,12 +17250,13 @@ function EntityForm({
17071
17250
  const pluginBeforeTitle = [];
17072
17251
  const plugins = customizationController.plugins;
17073
17252
  const actionsDisabled = disabled || formex.isSubmitting || status === "existing" && !formex.dirty || Boolean(disabledProp);
17074
- const parentCollectionIds = navigationController.getParentCollectionIds(path);
17253
+ const parentCollectionIds = navigationController.getParentCollectionIds(path, pathSegments);
17075
17254
  if (plugins && collection) {
17076
17255
  const actionProps = {
17077
17256
  entityId,
17078
17257
  parentCollectionIds,
17079
17258
  path,
17259
+ pathSegments,
17080
17260
  status,
17081
17261
  collection,
17082
17262
  context,
@@ -17121,7 +17301,7 @@ function EntityForm({
17121
17301
  const uniqueFieldValidator = useCallback(({
17122
17302
  name,
17123
17303
  value
17124
- }) => dataSource.checkUniqueField(path, name, value, entityId, collection), [dataSource, path, entityId]);
17304
+ }) => dataSource.checkUniqueField(path, name, value, entityId, collection, pathSegments), [dataSource, path, entityId]);
17125
17305
  const validationSchema = useMemo(() => entityId ? getYupEntitySchema(entityId, resolvedCollection.properties, uniqueFieldValidator) : void 0, [entityId, resolvedCollection.properties, uniqueFieldValidator]);
17126
17306
  useOnAutoSave(autoSave, formex, lastSavedValues, save);
17127
17307
  const prevEntityValuesRef = useRef(entity?.values);
@@ -17225,13 +17405,13 @@ function EntityForm({
17225
17405
  if (!resolvedCollection || !path) {
17226
17406
  throw Error("INTERNAL: Collection and path must be defined in form context");
17227
17407
  }
17228
- const dialogActions = /* @__PURE__ */ jsx(EntityFormActionsComponent, { collection: resolvedCollection, path, fullPath: path, fullIdPath, entity, layout: forceActionsAtTheBottom ? "bottom" : "side", savingError, formex, disabled: actionsDisabled, status, pluginActions: pluginActions ?? [], openEntityMode, showDefaultActions, navigateBack, formContext });
17408
+ const dialogActions = /* @__PURE__ */ jsx(EntityFormActionsComponent, { collection: resolvedCollection, path, pathSegments, fullPath: path, fullIdPath, entity, layout: forceActionsAtTheBottom ? "bottom" : "side", savingError, formex, disabled: actionsDisabled, status, pluginActions: pluginActions ?? [], openEntityMode, showDefaultActions, navigateBack, formContext });
17229
17409
  return /* @__PURE__ */ jsx(Formex, { value: formex, children: /* @__PURE__ */ jsxs("form", { onSubmit: formex.handleSubmit, onReset: () => formex.resetForm({
17230
17410
  values: baseInitialValues
17231
17411
  }), noValidate: true, className: cls("flex-1 flex flex-row w-full overflow-y-auto justify-center", className), children: [
17232
17412
  /* @__PURE__ */ jsx("div", { id: `form_${path}`, className: cls("relative flex flex-row max-w-4xl lg:max-w-3xl xl:max-w-4xl 2xl:max-w-6xl w-full h-fit"), children: /* @__PURE__ */ jsxs("div", { className: cls("flex flex-col w-full pt-12 pb-16 px-4 sm:px-8 md:px-10"), children: [
17233
17413
  /* @__PURE__ */ jsxs("div", { className: "flex flex-row gap-4 self-end sticky top-4 z-10", children: [
17234
- manualApplyLocalChanges && hasLocalChanges && /* @__PURE__ */ jsx(LocalChangesMenu, { cacheKey: status === "new" || status === "copy" ? path + "#new" : path + "/" + entityId, properties: resolvedCollection.properties, cachedData: localChangesDataRaw, formex, onClearLocalChanges: () => setLocalChangesCleared(true) }),
17414
+ manualApplyLocalChanges && hasLocalChanges && /* @__PURE__ */ jsx(LocalChangesMenu, { cacheKey: status === "new" || status === "copy" ? path + "#new" : entityCacheKey(path, entityId), properties: resolvedCollection.properties, cachedData: localChangesDataRaw, formex, onClearLocalChanges: () => setLocalChangesCleared(true) }),
17235
17415
  formex.dirty ? /* @__PURE__ */ jsx(Tooltip, { title: "This form has been modified", children: /* @__PURE__ */ jsx(Chip, { size: "small", className: "py-1", colorScheme: "orangeDarker", children: /* @__PURE__ */ jsx(EditIcon, { size: "smallest" }) }) }) : /* @__PURE__ */ jsx(Tooltip, { title: "The current form is in sync with the database", children: /* @__PURE__ */ jsx(Chip, { size: "small", className: "py-1", children: /* @__PURE__ */ jsx(CheckIcon, { size: "smallest" }) }) })
17236
17416
  ] }),
17237
17417
  formView
@@ -17322,7 +17502,7 @@ const EntityCollectionRowActions = function EntityCollectionRowActions2({
17322
17502
  const collapsedActions = actions.filter((a_0) => a_0.collapsed || a_0.collapsed === void 0);
17323
17503
  const uncollapsedActions = actions.filter((a_1) => a_1.collapsed === false);
17324
17504
  const enableLocalChangesBackup = collection ? getLocalChangesBackup(collection) : false;
17325
- const cachedData = enableLocalChangesBackup ? getEntityFromCache(fullPath + "/" + entity.id) : void 0;
17505
+ const cachedData = enableLocalChangesBackup ? getEntityFromCache(entityCacheKey(fullPath, entity.id)) : void 0;
17326
17506
  const hasDraft = (() => {
17327
17507
  if (!cachedData || typeof cachedData !== "object" || Object.keys(cachedData).length === 0) return false;
17328
17508
  const realChanges = getChanges(cachedData, entity?.values ?? {});
@@ -20088,8 +20268,8 @@ function useDataSourceTableController({
20088
20268
  const [popupCell, setPopupCell] = React__default.useState(void 0);
20089
20269
  const navigation = useNavigationController();
20090
20270
  const dataSource = useDataSource();
20091
- const resolvedPath = useMemo(() => navigation.resolveIdsFrom(fullPath), [fullPath, navigation.resolveIdsFrom]);
20092
- const resolvedPathSegments = useMemo(() => pathSegments ?? resolvedPath.split("/"), [pathSegments, resolvedPath]);
20271
+ const resolvedPath = useMemo(() => navigation.resolveIdsFrom(fullPath, pathSegments), [fullPath, pathSegments, navigation.resolveIdsFrom]);
20272
+ const resolvedPathSegments = useMemo(() => pathSegments ? navigation.resolveSegmentsFrom?.(pathSegments) ?? pathSegments : void 0, [pathSegments, navigation.resolveSegmentsFrom]);
20093
20273
  const forceFilter = forceFilterFromProps ?? forceFilterFromCollection;
20094
20274
  const paginationEnabled = collection.pagination === void 0 || Boolean(collection.pagination);
20095
20275
  const pageSize = typeof collection.pagination === "number" ? collection.pagination : DEFAULT_PAGE_SIZE$1;
@@ -20097,6 +20277,7 @@ function useDataSourceTableController({
20097
20277
  if (!dataSource.isFilterCombinationValid) return true;
20098
20278
  return dataSource.isFilterCombinationValid({
20099
20279
  path: resolvedPath,
20280
+ pathSegments: resolvedPathSegments,
20100
20281
  collection,
20101
20282
  filterValues,
20102
20283
  sortBy
@@ -20185,22 +20366,29 @@ function useDataSourceTableController({
20185
20366
  useEffect(() => {
20186
20367
  setDataLoading(true);
20187
20368
  const onEntitiesUpdate = async (entities) => {
20369
+ if (resolvedPathSegments) {
20370
+ entities = entities.map((e) => e.pathSegments ? e : {
20371
+ ...e,
20372
+ pathSegments: resolvedPathSegments
20373
+ });
20374
+ }
20188
20375
  if (collection.callbacks?.onFetch) {
20189
20376
  try {
20190
20377
  entities = await Promise.all(entities.map((entity) => collection.callbacks.onFetch({
20191
20378
  collection,
20192
20379
  path: resolvedPath,
20380
+ pathSegments: resolvedPathSegments,
20193
20381
  entity,
20194
20382
  context
20195
20383
  })));
20196
- } catch (e) {
20197
- console.error(e);
20384
+ } catch (e_0) {
20385
+ console.error(e_0);
20198
20386
  }
20199
20387
  }
20200
20388
  setDataLoading(false);
20201
20389
  setDataLoadingError(void 0);
20202
- setRawData(entities.map((e_0) => ({
20203
- ...e_0
20390
+ setRawData(entities.map((e_1) => ({
20391
+ ...e_1
20204
20392
  // values: sanitizeData(e.values, resolvedCollection.properties)
20205
20393
  })));
20206
20394
  setNoMoreToLoad(!itemCount || entities.length < itemCount);
@@ -20241,8 +20429,8 @@ function useDataSourceTableController({
20241
20429
  return () => {
20242
20430
  };
20243
20431
  }
20244
- } catch (e_1) {
20245
- onError(e_1 instanceof Error ? e_1 : new Error(String(e_1)));
20432
+ } catch (e_2) {
20433
+ onError(e_2 instanceof Error ? e_2 : new Error(String(e_2)));
20246
20434
  return () => {
20247
20435
  };
20248
20436
  }
@@ -20346,10 +20534,11 @@ function useSelectionController(onSelectionChange) {
20346
20534
  };
20347
20535
  }
20348
20536
  function useTableSearchHelper(t0) {
20349
- const $ = c(18);
20537
+ const $ = c(19);
20350
20538
  const {
20351
20539
  collection,
20352
20540
  fullPath,
20541
+ pathSegments,
20353
20542
  parentCollectionIds,
20354
20543
  initialSearchString
20355
20544
  } = t0;
@@ -20361,11 +20550,12 @@ function useTableSearchHelper(t0) {
20361
20550
  const autoInitialisedRef = useRef(false);
20362
20551
  let onTextSearchClick;
20363
20552
  let textSearchEnabled;
20364
- if ($[0] !== collection || $[1] !== context || $[2] !== customizationController.plugins || $[3] !== dataSource || $[4] !== fullPath || $[5] !== parentCollectionIds) {
20553
+ if ($[0] !== collection || $[1] !== context || $[2] !== customizationController.plugins || $[3] !== dataSource || $[4] !== fullPath || $[5] !== parentCollectionIds || $[6] !== pathSegments) {
20365
20554
  textSearchEnabled = Boolean(collection.textSearchEnabled);
20366
20555
  const props = {
20367
20556
  context,
20368
20557
  path: fullPath,
20558
+ pathSegments,
20369
20559
  databaseId: collection.databaseId,
20370
20560
  collection,
20371
20561
  parentCollectionIds
@@ -20385,6 +20575,7 @@ function useTableSearchHelper(t0) {
20385
20575
  promises.push(p_1.collectionView.onTextSearchClick({
20386
20576
  context,
20387
20577
  path: fullPath,
20578
+ pathSegments,
20388
20579
  collection,
20389
20580
  parentCollectionIds
20390
20581
  }));
@@ -20416,15 +20607,16 @@ function useTableSearchHelper(t0) {
20416
20607
  $[3] = dataSource;
20417
20608
  $[4] = fullPath;
20418
20609
  $[5] = parentCollectionIds;
20419
- $[6] = onTextSearchClick;
20420
- $[7] = textSearchEnabled;
20610
+ $[6] = pathSegments;
20611
+ $[7] = onTextSearchClick;
20612
+ $[8] = textSearchEnabled;
20421
20613
  } else {
20422
- onTextSearchClick = $[6];
20423
- textSearchEnabled = $[7];
20614
+ onTextSearchClick = $[7];
20615
+ textSearchEnabled = $[8];
20424
20616
  }
20425
20617
  const shouldAutoInitialise = Boolean(initialSearchString) && textSearchEnabled && !textSearchInitialised && Boolean(onTextSearchClick);
20426
20618
  let t1;
20427
- if ($[8] !== onTextSearchClick || $[9] !== shouldAutoInitialise) {
20619
+ if ($[9] !== onTextSearchClick || $[10] !== shouldAutoInitialise) {
20428
20620
  t1 = () => {
20429
20621
  if (autoInitialisedRef.current || !shouldAutoInitialise) {
20430
20622
  return;
@@ -20432,36 +20624,36 @@ function useTableSearchHelper(t0) {
20432
20624
  autoInitialisedRef.current = true;
20433
20625
  onTextSearchClick?.();
20434
20626
  };
20435
- $[8] = onTextSearchClick;
20436
- $[9] = shouldAutoInitialise;
20437
- $[10] = t1;
20627
+ $[9] = onTextSearchClick;
20628
+ $[10] = shouldAutoInitialise;
20629
+ $[11] = t1;
20438
20630
  } else {
20439
- t1 = $[10];
20631
+ t1 = $[11];
20440
20632
  }
20441
20633
  let t2;
20442
- if ($[11] !== shouldAutoInitialise) {
20634
+ if ($[12] !== shouldAutoInitialise) {
20443
20635
  t2 = [shouldAutoInitialise];
20444
- $[11] = shouldAutoInitialise;
20445
- $[12] = t2;
20636
+ $[12] = shouldAutoInitialise;
20637
+ $[13] = t2;
20446
20638
  } else {
20447
- t2 = $[12];
20639
+ t2 = $[13];
20448
20640
  }
20449
20641
  useEffect(t1, t2);
20450
20642
  let t3;
20451
- if ($[13] !== onTextSearchClick || $[14] !== textSearchEnabled || $[15] !== textSearchInitialised || $[16] !== textSearchLoading) {
20643
+ if ($[14] !== onTextSearchClick || $[15] !== textSearchEnabled || $[16] !== textSearchInitialised || $[17] !== textSearchLoading) {
20452
20644
  t3 = {
20453
20645
  textSearchLoading,
20454
20646
  textSearchInitialised,
20455
20647
  onTextSearchClick,
20456
20648
  textSearchEnabled
20457
20649
  };
20458
- $[13] = onTextSearchClick;
20459
- $[14] = textSearchEnabled;
20460
- $[15] = textSearchInitialised;
20461
- $[16] = textSearchLoading;
20462
- $[17] = t3;
20650
+ $[14] = onTextSearchClick;
20651
+ $[15] = textSearchEnabled;
20652
+ $[16] = textSearchInitialised;
20653
+ $[17] = textSearchLoading;
20654
+ $[18] = t3;
20463
20655
  } else {
20464
- t3 = $[17];
20656
+ t3 = $[18];
20465
20657
  }
20466
20658
  return t3;
20467
20659
  }
@@ -20530,6 +20722,8 @@ function DeleteEntityDialog({
20530
20722
  const performDelete = useCallback((entity_3) => deleteEntityWithCallbacks({
20531
20723
  dataSource,
20532
20724
  entity: entity_3,
20725
+ // The entity is the authority on where it lives; stated rather than left implicit.
20726
+ pathSegments: entity_3.pathSegments,
20533
20727
  collection: resolvedCollection,
20534
20728
  callbacks,
20535
20729
  onDeleteSuccess,
@@ -20631,6 +20825,7 @@ const editEntityAction = {
20631
20825
  entity,
20632
20826
  collection,
20633
20827
  fullPath,
20828
+ pathSegments,
20634
20829
  fullIdPath,
20635
20830
  context,
20636
20831
  highlightEntity,
@@ -20649,6 +20844,7 @@ const editEntityAction = {
20649
20844
  addRecentId(collection.id, entity.id);
20650
20845
  }
20651
20846
  const path = collection?.collectionGroup ? entity.path : fullPath ?? collection?.path ?? entity.path;
20847
+ const resolvedPathSegments = collection?.collectionGroup ? entity.pathSegments : pathSegments ?? entity.pathSegments;
20652
20848
  const newFullIdPath = collection?.collectionGroup ? collection.id : fullIdPath ?? collection?.id ?? entity.path;
20653
20849
  const defaultSelectedView = resolveDefaultSelectedView(collection ? collection.defaultSelectedView : void 0, {
20654
20850
  status: "existing",
@@ -20659,6 +20855,7 @@ const editEntityAction = {
20659
20855
  collection,
20660
20856
  entityId: entity.id,
20661
20857
  path,
20858
+ pathSegments: resolvedPathSegments,
20662
20859
  fullIdPath: newFullIdPath,
20663
20860
  sideEntityController: context.sideEntityController,
20664
20861
  onClose: () => unhighlightEntity?.(entity),
@@ -20680,6 +20877,8 @@ const copyEntityAction = {
20680
20877
  collection,
20681
20878
  context,
20682
20879
  fullPath,
20880
+ pathSegments,
20881
+ fullIdPath,
20683
20882
  highlightEntity,
20684
20883
  unhighlightEntity,
20685
20884
  openEntityMode
@@ -20693,13 +20892,15 @@ const copyEntityAction = {
20693
20892
  entityId: entity.id
20694
20893
  });
20695
20894
  const path = collection?.collectionGroup ? collection.path : fullPath ?? collection?.path ?? entity.path;
20696
- const fullIdPath = collection?.collectionGroup ? collection.id : fullPath ?? collection?.id ?? entity.path;
20895
+ const resolvedPathSegments = collection?.collectionGroup ? void 0 : pathSegments ?? entity.pathSegments;
20896
+ const newFullIdPath = collection?.collectionGroup ? collection.id : fullIdPath ?? collection?.id;
20697
20897
  navigateToEntity({
20698
20898
  openEntityMode,
20699
20899
  collection,
20700
20900
  entityId: entity.id,
20701
20901
  path,
20702
- fullIdPath,
20902
+ pathSegments: resolvedPathSegments,
20903
+ fullIdPath: newFullIdPath,
20703
20904
  copy: true,
20704
20905
  sideEntityController: context.sideEntityController,
20705
20906
  onClose: () => unhighlightEntity?.(entity),
@@ -20754,6 +20955,7 @@ function ReferenceSelectionTable({
20754
20955
  multiselect,
20755
20956
  collection,
20756
20957
  path: pathInput,
20958
+ pathSegments,
20757
20959
  selectedEntityIds: selectedEntityIdsProp,
20758
20960
  description,
20759
20961
  forceFilter,
@@ -20768,7 +20970,7 @@ function ReferenceSelectionTable({
20768
20970
  const navigation = useNavigationController();
20769
20971
  const analyticsController = useAnalyticsController();
20770
20972
  const customizationController = useCustomizationController();
20771
- const fullPath = navigation.resolveIdsFrom(pathInput);
20973
+ const fullPath = navigation.resolveIdsFrom(pathInput, pathSegments);
20772
20974
  const dataSource = useDataSource();
20773
20975
  const [entitiesDisplayedFirst, setEntitiesDisplayedFirst] = useState([]);
20774
20976
  const toggleEntitySelection = (entity) => {
@@ -20796,6 +20998,7 @@ function ReferenceSelectionTable({
20796
20998
  if (selectedEntityIds && collection) {
20797
20999
  Promise.all(selectedEntityIds.map((entityId) => dataSource.fetchEntity({
20798
21000
  path: fullPath,
21001
+ pathSegments,
20799
21002
  entityId,
20800
21003
  collection
20801
21004
  }))).then((entities) => {
@@ -20842,6 +21045,7 @@ function ReferenceSelectionTable({
20842
21045
  });
20843
21046
  sideEntityController.open({
20844
21047
  path: fullPath,
21048
+ pathSegments,
20845
21049
  collection,
20846
21050
  updateUrl: true,
20847
21051
  onUpdate: ({
@@ -20891,6 +21095,7 @@ function ReferenceSelectionTable({
20891
21095
  onTextSearchClick,
20892
21096
  textSearchEnabled
20893
21097
  } = useTableSearchHelper({
21098
+ pathSegments,
20894
21099
  collection,
20895
21100
  fullPath
20896
21101
  });
@@ -20902,7 +21107,7 @@ function ReferenceSelectionTable({
20902
21107
  }) : t("select_from", {
20903
21108
  name: collection.name
20904
21109
  })
20905
- ] }), defaultSize: collection.defaultSize, properties: resolvedCollection.properties, forceFilter, inlineEditing: false, selectionController, actions: /* @__PURE__ */ jsx(ReferenceDialogActions, { collection, path: fullPath, onNewClick, onClear }) }) }),
21110
+ ] }), defaultSize: collection.defaultSize, properties: resolvedCollection.properties, forceFilter, inlineEditing: false, selectionController, actions: /* @__PURE__ */ jsx(ReferenceDialogActions, { collection, path: fullPath, pathSegments, onNewClick, onClear }) }) }),
20906
21111
  /* @__PURE__ */ jsxs(DialogActions, { translucent: false, children: [
20907
21112
  description && /* @__PURE__ */ jsx(Typography, { variant: "body2", className: "flex-grow text-left", children: description }),
20908
21113
  /* @__PURE__ */ jsx(Button, { onClick: onDone, variant: "filled", children: t("done") })
@@ -20910,10 +21115,11 @@ function ReferenceSelectionTable({
20910
21115
  ] });
20911
21116
  }
20912
21117
  function ReferenceDialogActions(t0) {
20913
- const $ = c(17);
21118
+ const $ = c(18);
20914
21119
  const {
20915
21120
  collection,
20916
21121
  path,
21122
+ pathSegments,
20917
21123
  onClear,
20918
21124
  onNewClick
20919
21125
  } = t0;
@@ -20935,8 +21141,8 @@ function ReferenceDialogActions(t0) {
20935
21141
  }
20936
21142
  const onClick = t1;
20937
21143
  let t2;
20938
- if ($[2] !== authController || $[3] !== collection || $[4] !== largeLayout || $[5] !== onClick || $[6] !== path || $[7] !== t) {
20939
- t2 = canCreateEntity(collection, authController, path, null) && onClick && (largeLayout ? /* @__PURE__ */ jsx(Button, { onClick, startIcon: /* @__PURE__ */ jsx(AddIcon, {}), children: t("add_specific", {
21144
+ if ($[2] !== authController || $[3] !== collection || $[4] !== largeLayout || $[5] !== onClick || $[6] !== path || $[7] !== pathSegments || $[8] !== t) {
21145
+ t2 = canCreateEntity(collection, authController, path, null, pathSegments) && onClick && (largeLayout ? /* @__PURE__ */ jsx(Button, { onClick, startIcon: /* @__PURE__ */ jsx(AddIcon, {}), children: t("add_specific", {
20940
21146
  name: collection.singularName ?? collection.name
20941
21147
  }) }) : /* @__PURE__ */ jsx(Button, { onClick, children: /* @__PURE__ */ jsx(AddIcon, {}) }));
20942
21148
  $[2] = authController;
@@ -20944,40 +21150,41 @@ function ReferenceDialogActions(t0) {
20944
21150
  $[4] = largeLayout;
20945
21151
  $[5] = onClick;
20946
21152
  $[6] = path;
20947
- $[7] = t;
20948
- $[8] = t2;
21153
+ $[7] = pathSegments;
21154
+ $[8] = t;
21155
+ $[9] = t2;
20949
21156
  } else {
20950
- t2 = $[8];
21157
+ t2 = $[9];
20951
21158
  }
20952
21159
  const addButton = t2;
20953
21160
  let t3;
20954
- if ($[9] !== t) {
21161
+ if ($[10] !== t) {
20955
21162
  t3 = t("clear");
20956
- $[9] = t;
20957
- $[10] = t3;
21163
+ $[10] = t;
21164
+ $[11] = t3;
20958
21165
  } else {
20959
- t3 = $[10];
21166
+ t3 = $[11];
20960
21167
  }
20961
21168
  let t4;
20962
- if ($[11] !== onClear || $[12] !== t3) {
21169
+ if ($[12] !== onClear || $[13] !== t3) {
20963
21170
  t4 = /* @__PURE__ */ jsx(Button, { onClick: onClear, variant: "text", children: t3 });
20964
- $[11] = onClear;
20965
- $[12] = t3;
20966
- $[13] = t4;
21171
+ $[12] = onClear;
21172
+ $[13] = t3;
21173
+ $[14] = t4;
20967
21174
  } else {
20968
- t4 = $[13];
21175
+ t4 = $[14];
20969
21176
  }
20970
21177
  let t5;
20971
- if ($[14] !== addButton || $[15] !== t4) {
21178
+ if ($[15] !== addButton || $[16] !== t4) {
20972
21179
  t5 = /* @__PURE__ */ jsxs(Fragment, { children: [
20973
21180
  t4,
20974
21181
  addButton
20975
21182
  ] });
20976
- $[14] = addButton;
20977
- $[15] = t4;
20978
- $[16] = t5;
21183
+ $[15] = addButton;
21184
+ $[16] = t4;
21185
+ $[17] = t5;
20979
21186
  } else {
20980
- t5 = $[16];
21187
+ t5 = $[17];
20981
21188
  }
20982
21189
  return t5;
20983
21190
  }
@@ -22893,7 +23100,7 @@ const useBreadcrumbsController = () => {
22893
23100
  return useContext(BreadcrumbContext);
22894
23101
  };
22895
23102
  function EntityCollectionViewActions(t0) {
22896
- const $ = c(45);
23103
+ const $ = c(48);
22897
23104
  const {
22898
23105
  collection,
22899
23106
  relativePath,
@@ -22902,6 +23109,7 @@ function EntityCollectionViewActions(t0) {
22902
23109
  onMultipleDeleteClick,
22903
23110
  selectionEnabled,
22904
23111
  path,
23112
+ pathSegments,
22905
23113
  selectionController,
22906
23114
  tableController,
22907
23115
  collectionEntitiesCount
@@ -22924,8 +23132,8 @@ function EntityCollectionViewActions(t0) {
22924
23132
  const largeLayout = useLargeLayout();
22925
23133
  const selectedEntities = selectionController.selectedEntities;
22926
23134
  let t2;
22927
- if ($[2] !== authController || $[3] !== collection || $[4] !== largeLayout || $[5] !== onNewClick || $[6] !== path || $[7] !== t) {
22928
- t2 = canCreateEntity(collection, authController, path, null) && onNewClick && (largeLayout ? /* @__PURE__ */ jsxs(Button, { id: `add_entity_${path}`, onClick: onNewClick, startIcon: /* @__PURE__ */ jsx(AddIcon, { size: "small" }), variant: "filled", color: "primary", children: [
23135
+ if ($[2] !== authController || $[3] !== collection || $[4] !== largeLayout || $[5] !== onNewClick || $[6] !== path || $[7] !== pathSegments || $[8] !== t) {
23136
+ t2 = canCreateEntity(collection, authController, path, null, pathSegments) && onNewClick && (largeLayout ? /* @__PURE__ */ jsxs(Button, { id: `add_entity_${path}`, onClick: onNewClick, startIcon: /* @__PURE__ */ jsx(AddIcon, { size: "small" }), variant: "filled", color: "primary", children: [
22929
23137
  t("add"),
22930
23138
  " ",
22931
23139
  collection.singularName ?? collection.name
@@ -22935,65 +23143,68 @@ function EntityCollectionViewActions(t0) {
22935
23143
  $[4] = largeLayout;
22936
23144
  $[5] = onNewClick;
22937
23145
  $[6] = path;
22938
- $[7] = t;
22939
- $[8] = t2;
23146
+ $[7] = pathSegments;
23147
+ $[8] = t;
23148
+ $[9] = t2;
22940
23149
  } else {
22941
- t2 = $[8];
23150
+ t2 = $[9];
22942
23151
  }
22943
23152
  const addButton = t2;
22944
23153
  let t3;
22945
- if ($[9] !== authController || $[10] !== collection || $[11] !== path) {
22946
- t3 = canDeleteEntity(collection, authController, path, null);
22947
- $[9] = authController;
22948
- $[10] = collection;
22949
- $[11] = path;
22950
- $[12] = t3;
23154
+ if ($[10] !== authController || $[11] !== collection || $[12] !== path || $[13] !== pathSegments) {
23155
+ t3 = canDeleteEntity(collection, authController, path, null, pathSegments);
23156
+ $[10] = authController;
23157
+ $[11] = collection;
23158
+ $[12] = path;
23159
+ $[13] = pathSegments;
23160
+ $[14] = t3;
22951
23161
  } else {
22952
- t3 = $[12];
23162
+ t3 = $[14];
22953
23163
  }
22954
23164
  const multipleDeleteEnabled = t3;
22955
23165
  let multipleDeleteButton;
22956
23166
  if (selectionEnabled) {
22957
23167
  let t42;
22958
- if ($[13] !== largeLayout || $[14] !== multipleDeleteEnabled || $[15] !== onMultipleDeleteClick || $[16] !== selectedEntities?.length) {
23168
+ if ($[15] !== largeLayout || $[16] !== multipleDeleteEnabled || $[17] !== onMultipleDeleteClick || $[18] !== selectedEntities?.length) {
22959
23169
  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: [
22960
23170
  "(",
22961
23171
  selectedEntities?.length,
22962
23172
  ")"
22963
23173
  ] }) : /* @__PURE__ */ jsx(IconButton, { size: "small", color: "primary", disabled: !selectedEntities?.length || !multipleDeleteEnabled, onClick: onMultipleDeleteClick, children: /* @__PURE__ */ jsx(DeleteIcon, { size: "small" }) });
22964
- $[13] = largeLayout;
22965
- $[14] = multipleDeleteEnabled;
22966
- $[15] = onMultipleDeleteClick;
22967
- $[16] = selectedEntities?.length;
22968
- $[17] = t42;
23174
+ $[15] = largeLayout;
23175
+ $[16] = multipleDeleteEnabled;
23176
+ $[17] = onMultipleDeleteClick;
23177
+ $[18] = selectedEntities?.length;
23178
+ $[19] = t42;
22969
23179
  } else {
22970
- t42 = $[17];
23180
+ t42 = $[19];
22971
23181
  }
22972
23182
  const button = t42;
22973
23183
  let t52;
22974
- if ($[18] !== multipleDeleteEnabled || $[19] !== t) {
23184
+ if ($[20] !== multipleDeleteEnabled || $[21] !== t) {
22975
23185
  t52 = multipleDeleteEnabled ? t("delete_selected") : t("cannot_delete_selected");
22976
- $[18] = multipleDeleteEnabled;
22977
- $[19] = t;
22978
- $[20] = t52;
23186
+ $[20] = multipleDeleteEnabled;
23187
+ $[21] = t;
23188
+ $[22] = t52;
22979
23189
  } else {
22980
- t52 = $[20];
23190
+ t52 = $[22];
22981
23191
  }
22982
23192
  let t62;
22983
- if ($[21] !== button || $[22] !== t52) {
23193
+ if ($[23] !== button || $[24] !== t52) {
22984
23194
  t62 = /* @__PURE__ */ jsx(Tooltip, { title: t52, children: button });
22985
- $[21] = button;
22986
- $[22] = t52;
22987
- $[23] = t62;
23195
+ $[23] = button;
23196
+ $[24] = t52;
23197
+ $[25] = t62;
22988
23198
  } else {
22989
- t62 = $[23];
23199
+ t62 = $[25];
22990
23200
  }
22991
23201
  multipleDeleteButton = t62;
22992
23202
  }
22993
23203
  let t4;
22994
- if ($[24] !== collection || $[25] !== collectionEntitiesCount || $[26] !== context || $[27] !== parentCollectionIds || $[28] !== path || $[29] !== relativePath || $[30] !== selectionController || $[31] !== tableController) {
23204
+ if ($[26] !== collection || $[27] !== collectionEntitiesCount || $[28] !== context || $[29] !== parentCollectionIds || $[30] !== path || $[31] !== pathSegments || $[32] !== relativePath || $[33] !== selectionController || $[34] !== tableController) {
22995
23205
  t4 = {
22996
23206
  path,
23207
+ pathSegments,
22997
23208
  relativePath,
22998
23209
  parentCollectionIds,
22999
23210
  collection,
@@ -23002,28 +23213,29 @@ function EntityCollectionViewActions(t0) {
23002
23213
  tableController,
23003
23214
  collectionEntitiesCount
23004
23215
  };
23005
- $[24] = collection;
23006
- $[25] = collectionEntitiesCount;
23007
- $[26] = context;
23008
- $[27] = parentCollectionIds;
23009
- $[28] = path;
23010
- $[29] = relativePath;
23011
- $[30] = selectionController;
23012
- $[31] = tableController;
23013
- $[32] = t4;
23216
+ $[26] = collection;
23217
+ $[27] = collectionEntitiesCount;
23218
+ $[28] = context;
23219
+ $[29] = parentCollectionIds;
23220
+ $[30] = path;
23221
+ $[31] = pathSegments;
23222
+ $[32] = relativePath;
23223
+ $[33] = selectionController;
23224
+ $[34] = tableController;
23225
+ $[35] = t4;
23014
23226
  } else {
23015
- t4 = $[32];
23227
+ t4 = $[35];
23016
23228
  }
23017
23229
  const actionProps = t4;
23018
23230
  let actions;
23019
- if ($[33] !== actionProps || $[34] !== collection.Actions || $[35] !== plugins) {
23231
+ if ($[36] !== actionProps || $[37] !== collection.Actions || $[38] !== plugins) {
23020
23232
  let t52;
23021
- if ($[37] !== actionProps) {
23233
+ if ($[40] !== actionProps) {
23022
23234
  t52 = (Action, i) => /* @__PURE__ */ jsx(ErrorBoundary, { children: /* @__PURE__ */ jsx(Action, { ...actionProps }) }, `actions_${i}`);
23023
- $[37] = actionProps;
23024
- $[38] = t52;
23235
+ $[40] = actionProps;
23236
+ $[41] = t52;
23025
23237
  } else {
23026
- t52 = $[38];
23238
+ t52 = $[41];
23027
23239
  }
23028
23240
  actions = toArray(collection.Actions).map(t52);
23029
23241
  if (plugins) {
@@ -23033,34 +23245,34 @@ function EntityCollectionViewActions(t0) {
23033
23245
  }
23034
23246
  });
23035
23247
  }
23036
- $[33] = actionProps;
23037
- $[34] = collection.Actions;
23038
- $[35] = plugins;
23039
- $[36] = actions;
23248
+ $[36] = actionProps;
23249
+ $[37] = collection.Actions;
23250
+ $[38] = plugins;
23251
+ $[39] = actions;
23040
23252
  } else {
23041
- actions = $[36];
23253
+ actions = $[39];
23042
23254
  }
23043
23255
  let t5;
23044
- if ($[39] !== actions) {
23256
+ if ($[42] !== actions) {
23045
23257
  t5 = /* @__PURE__ */ jsx(ErrorBoundary, { children: actions });
23046
- $[39] = actions;
23047
- $[40] = t5;
23258
+ $[42] = actions;
23259
+ $[43] = t5;
23048
23260
  } else {
23049
- t5 = $[40];
23261
+ t5 = $[43];
23050
23262
  }
23051
23263
  let t6;
23052
- if ($[41] !== addButton || $[42] !== multipleDeleteButton || $[43] !== t5) {
23264
+ if ($[44] !== addButton || $[45] !== multipleDeleteButton || $[46] !== t5) {
23053
23265
  t6 = /* @__PURE__ */ jsxs(Fragment, { children: [
23054
23266
  t5,
23055
23267
  multipleDeleteButton,
23056
23268
  addButton
23057
23269
  ] });
23058
- $[41] = addButton;
23059
- $[42] = multipleDeleteButton;
23060
- $[43] = t5;
23061
- $[44] = t6;
23270
+ $[44] = addButton;
23271
+ $[45] = multipleDeleteButton;
23272
+ $[46] = t5;
23273
+ $[47] = t6;
23062
23274
  } else {
23063
- t6 = $[44];
23275
+ t6 = $[47];
23064
23276
  }
23065
23277
  return t6;
23066
23278
  }
@@ -24394,6 +24606,7 @@ const EntityBoardCard = memo(EntityBoardCardInner);
24394
24606
  const DEFAULT_PAGE_SIZE = 20;
24395
24607
  function useBoardDataController({
24396
24608
  fullPath,
24609
+ pathSegments,
24397
24610
  collection,
24398
24611
  columnProperty,
24399
24612
  columns,
@@ -24405,7 +24618,8 @@ function useBoardDataController({
24405
24618
  const context = useFireCMSContext();
24406
24619
  const dataSource = useDataSource();
24407
24620
  const navigation = useNavigationController();
24408
- const resolvedPath = useMemo(() => navigation.resolveIdsFrom(fullPath), [fullPath, navigation.resolveIdsFrom]);
24621
+ const resolvedPath = useMemo(() => navigation.resolveIdsFrom(fullPath, pathSegments), [fullPath, pathSegments, navigation.resolveIdsFrom]);
24622
+ const resolvedPathSegments = useMemo(() => pathSegments ? navigation.resolveSegmentsFrom?.(pathSegments) ?? pathSegments : void 0, [pathSegments, navigation.resolveSegmentsFrom]);
24409
24623
  const dataSourceRef = useRef(dataSource);
24410
24624
  const collectionRef = useRef(collection);
24411
24625
  const contextRef = useRef(context);
@@ -24417,11 +24631,13 @@ function useBoardDataController({
24417
24631
  const orderPropertyRef = useRef(orderProperty);
24418
24632
  const searchStringRef = useRef(searchString);
24419
24633
  const resolvedPathRef = useRef(resolvedPath);
24634
+ const resolvedPathSegmentsRef = useRef(resolvedPathSegments);
24420
24635
  filterValuesRef.current = filterValues;
24421
24636
  columnPropertyRef.current = columnProperty;
24422
24637
  orderPropertyRef.current = orderProperty;
24423
24638
  searchStringRef.current = searchString;
24424
24639
  resolvedPathRef.current = resolvedPath;
24640
+ resolvedPathSegmentsRef.current = resolvedPathSegments;
24425
24641
  const [columnItemCounts, setColumnItemCounts] = useState(() => {
24426
24642
  const initial = {};
24427
24643
  columns.forEach((col) => {
@@ -24468,6 +24684,7 @@ function useBoardDataController({
24468
24684
  const currentOrderProperty = orderPropertyRef.current;
24469
24685
  const currentSearchString = searchStringRef.current;
24470
24686
  const currentResolvedPath = resolvedPathRef.current;
24687
+ const currentPathSegments = resolvedPathSegmentsRef.current;
24471
24688
  const columnFilter = {
24472
24689
  ...currentFilterValues,
24473
24690
  [currentColumnProperty]: ["==", column]
@@ -24488,6 +24705,7 @@ function useBoardDataController({
24488
24705
  processed = await Promise.all(processed.map((entity) => currentCollection.callbacks.onFetch({
24489
24706
  collection: currentCollection,
24490
24707
  path: currentResolvedPath,
24708
+ pathSegments: currentPathSegments,
24491
24709
  entity,
24492
24710
  context: currentContext
24493
24711
  })));
@@ -24524,6 +24742,7 @@ function useBoardDataController({
24524
24742
  if (currentDataSource.listenCollection) {
24525
24743
  const unsubscribe = currentDataSource.listenCollection({
24526
24744
  path: currentResolvedPath,
24745
+ pathSegments: currentPathSegments,
24527
24746
  collection: currentCollection,
24528
24747
  onUpdate,
24529
24748
  onError,
@@ -24538,6 +24757,7 @@ function useBoardDataController({
24538
24757
  } else {
24539
24758
  currentDataSource.fetchCollection({
24540
24759
  path: currentResolvedPath,
24760
+ pathSegments: currentPathSegments,
24541
24761
  collection: currentCollection,
24542
24762
  searchString: currentSearchString,
24543
24763
  filter: columnFilter,
@@ -24566,6 +24786,7 @@ function useBoardDataController({
24566
24786
  const currentColumnProperty = columnPropertyRef.current;
24567
24787
  const currentSearchString = searchStringRef.current;
24568
24788
  const currentResolvedPath = resolvedPathRef.current;
24789
+ const currentPathSegments = resolvedPathSegmentsRef.current;
24569
24790
  const currentColumns = columns;
24570
24791
  const currentColumnItemCounts = columnItemCounts;
24571
24792
  const timeoutId = setTimeout(() => {
@@ -24580,6 +24801,7 @@ function useBoardDataController({
24580
24801
  };
24581
24802
  currentDataSource.countEntities({
24582
24803
  path: currentResolvedPath,
24804
+ pathSegments: currentPathSegments,
24583
24805
  collection: currentCollection,
24584
24806
  filter: columnFilter,
24585
24807
  searchString: currentSearchString
@@ -24824,6 +25046,7 @@ function EntityCollectionBoardView({
24824
25046
  collection,
24825
25047
  tableController,
24826
25048
  fullPath,
25049
+ pathSegments,
24827
25050
  parentCollectionIds = [],
24828
25051
  columnProperty,
24829
25052
  onEntityClick,
@@ -24917,6 +25140,7 @@ function EntityCollectionBoardView({
24917
25140
  const columns = localColumnsOrder;
24918
25141
  const boardDataController = useBoardDataController({
24919
25142
  fullPath,
25143
+ pathSegments,
24920
25144
  collection,
24921
25145
  columnProperty,
24922
25146
  columns,
@@ -24990,6 +25214,7 @@ function EntityCollectionBoardView({
24990
25214
  let completed = 0;
24991
25215
  currentDataSource.countEntities({
24992
25216
  path: fullPath,
25217
+ pathSegments,
24993
25218
  collection: currentCollection
24994
25219
  }).then((count) => {
24995
25220
  totalCount = count;
@@ -25000,6 +25225,7 @@ function EntityCollectionBoardView({
25000
25225
  }).catch((e) => console.warn("Failed to get total count:", e));
25001
25226
  currentDataSource.countEntities({
25002
25227
  path: fullPath,
25228
+ pathSegments,
25003
25229
  collection: currentCollection,
25004
25230
  filter: {
25005
25231
  [orderProperty]: ["!=", null]
@@ -25107,6 +25333,8 @@ function EntityCollectionBoardView({
25107
25333
  }
25108
25334
  const saveProps = {
25109
25335
  path: entity_2.path,
25336
+ // Paired with `entity.path`: the segments the entity was loaded with.
25337
+ pathSegments: entity_2.pathSegments,
25110
25338
  entityId: entity_2.id,
25111
25339
  values: updatedValues,
25112
25340
  previousValues: entity_2.values,
@@ -25144,6 +25372,7 @@ function EntityCollectionBoardView({
25144
25372
  console.log("Fetching all documents from collection...");
25145
25373
  const allDocs = await dataSource.fetchCollection({
25146
25374
  path: fullPath,
25375
+ pathSegments,
25147
25376
  collection,
25148
25377
  limit: 1e4
25149
25378
  // Fetch all
@@ -25162,6 +25391,8 @@ function EntityCollectionBoardView({
25162
25391
  }, orderProperty, index);
25163
25392
  const saveProps_0 = {
25164
25393
  path: entity_4.path,
25394
+ // Paired with `entity.path`: the segments the entity was loaded with.
25395
+ pathSegments: entity_4.pathSegments,
25165
25396
  entityId: entity_4.id,
25166
25397
  values: updatedValues_0,
25167
25398
  previousValues: entity_4.values,
@@ -25247,6 +25478,7 @@ function EntityCollectionBoardView({
25247
25478
  });
25248
25479
  sideEntityController.open({
25249
25480
  path: fullPath,
25481
+ pathSegments,
25250
25482
  collection,
25251
25483
  entityId: void 0,
25252
25484
  updateUrl: true,
@@ -25462,7 +25694,7 @@ function PopupFormField(props) {
25462
25694
  return t0;
25463
25695
  }
25464
25696
  function PopupFormFieldLoading(t0) {
25465
- const $ = c(21);
25697
+ const $ = c(22);
25466
25698
  const {
25467
25699
  tableKey,
25468
25700
  entityId,
@@ -25470,6 +25702,7 @@ function PopupFormFieldLoading(t0) {
25470
25702
  propertyKey,
25471
25703
  collection: inputCollection,
25472
25704
  path,
25705
+ pathSegments,
25473
25706
  cellRect,
25474
25707
  open,
25475
25708
  onClose,
@@ -25480,33 +25713,35 @@ function PopupFormFieldLoading(t0) {
25480
25713
  const [entity, setEntity] = useState(void 0);
25481
25714
  let t1;
25482
25715
  let t2;
25483
- if ($[0] !== dataSource || $[1] !== entityId || $[2] !== inputCollection || $[3] !== path) {
25716
+ if ($[0] !== dataSource || $[1] !== entityId || $[2] !== inputCollection || $[3] !== path || $[4] !== pathSegments) {
25484
25717
  t1 = () => {
25485
25718
  if (entityId && inputCollection) {
25486
25719
  dataSource.fetchEntity({
25487
25720
  path,
25721
+ pathSegments,
25488
25722
  entityId,
25489
25723
  collection: inputCollection
25490
25724
  }).then(setEntity);
25491
25725
  }
25492
25726
  };
25493
- t2 = [entityId, inputCollection, dataSource, path];
25727
+ t2 = [entityId, inputCollection, dataSource, path, pathSegments];
25494
25728
  $[0] = dataSource;
25495
25729
  $[1] = entityId;
25496
25730
  $[2] = inputCollection;
25497
25731
  $[3] = path;
25498
- $[4] = t1;
25499
- $[5] = t2;
25732
+ $[4] = pathSegments;
25733
+ $[5] = t1;
25734
+ $[6] = t2;
25500
25735
  } else {
25501
- t1 = $[4];
25502
- t2 = $[5];
25736
+ t1 = $[5];
25737
+ t2 = $[6];
25503
25738
  }
25504
25739
  useEffect(t1, t2);
25505
25740
  if (!entity) {
25506
25741
  return null;
25507
25742
  }
25508
25743
  let t3;
25509
- if ($[6] !== cellRect || $[7] !== container || $[8] !== customFieldValidator || $[9] !== entityId || $[10] !== inputCollection || $[11] !== onCellValueChange || $[12] !== onClose || $[13] !== open || $[14] !== path || $[15] !== propertyKey || $[16] !== tableKey) {
25744
+ if ($[7] !== cellRect || $[8] !== container || $[9] !== customFieldValidator || $[10] !== entityId || $[11] !== inputCollection || $[12] !== onCellValueChange || $[13] !== onClose || $[14] !== open || $[15] !== path || $[16] !== propertyKey || $[17] !== tableKey) {
25510
25745
  t3 = {
25511
25746
  tableKey,
25512
25747
  entityId,
@@ -25520,29 +25755,29 @@ function PopupFormFieldLoading(t0) {
25520
25755
  onCellValueChange,
25521
25756
  container
25522
25757
  };
25523
- $[6] = cellRect;
25524
- $[7] = container;
25525
- $[8] = customFieldValidator;
25526
- $[9] = entityId;
25527
- $[10] = inputCollection;
25528
- $[11] = onCellValueChange;
25529
- $[12] = onClose;
25530
- $[13] = open;
25531
- $[14] = path;
25532
- $[15] = propertyKey;
25533
- $[16] = tableKey;
25534
- $[17] = t3;
25758
+ $[7] = cellRect;
25759
+ $[8] = container;
25760
+ $[9] = customFieldValidator;
25761
+ $[10] = entityId;
25762
+ $[11] = inputCollection;
25763
+ $[12] = onCellValueChange;
25764
+ $[13] = onClose;
25765
+ $[14] = open;
25766
+ $[15] = path;
25767
+ $[16] = propertyKey;
25768
+ $[17] = tableKey;
25769
+ $[18] = t3;
25535
25770
  } else {
25536
- t3 = $[17];
25771
+ t3 = $[18];
25537
25772
  }
25538
25773
  let t4;
25539
- if ($[18] !== entity || $[19] !== t3) {
25774
+ if ($[19] !== entity || $[20] !== t3) {
25540
25775
  t4 = /* @__PURE__ */ jsx(PopupFormFieldInternal, { ...t3, entity });
25541
- $[18] = entity;
25542
- $[19] = t3;
25543
- $[20] = t4;
25776
+ $[19] = entity;
25777
+ $[20] = t3;
25778
+ $[21] = t4;
25544
25779
  } else {
25545
- t4 = $[20];
25780
+ t4 = $[21];
25546
25781
  }
25547
25782
  return t4;
25548
25783
  }
@@ -25941,12 +26176,13 @@ function FiltersDialog({
25941
26176
  ] });
25942
26177
  }
25943
26178
  function EntityCollectionViewStartActions(t0) {
25944
- const $ = c(37);
26179
+ const $ = c(38);
25945
26180
  const {
25946
26181
  collection,
25947
26182
  relativePath,
25948
26183
  parentCollectionIds,
25949
26184
  path,
26185
+ pathSegments,
25950
26186
  selectionController,
25951
26187
  tableController,
25952
26188
  collectionEntitiesCount,
@@ -25981,9 +26217,10 @@ function EntityCollectionViewStartActions(t0) {
25981
26217
  }
25982
26218
  const activeFilterCount = t2;
25983
26219
  let t3;
25984
- if ($[5] !== collection || $[6] !== collectionEntitiesCount || $[7] !== context || $[8] !== parentCollectionIds || $[9] !== path || $[10] !== relativePath || $[11] !== selectionController || $[12] !== tableController) {
26220
+ if ($[5] !== collection || $[6] !== collectionEntitiesCount || $[7] !== context || $[8] !== parentCollectionIds || $[9] !== path || $[10] !== pathSegments || $[11] !== relativePath || $[12] !== selectionController || $[13] !== tableController) {
25985
26221
  t3 = {
25986
26222
  path,
26223
+ pathSegments,
25987
26224
  relativePath,
25988
26225
  parentCollectionIds,
25989
26226
  collection,
@@ -25997,44 +26234,45 @@ function EntityCollectionViewStartActions(t0) {
25997
26234
  $[7] = context;
25998
26235
  $[8] = parentCollectionIds;
25999
26236
  $[9] = path;
26000
- $[10] = relativePath;
26001
- $[11] = selectionController;
26002
- $[12] = tableController;
26003
- $[13] = t3;
26237
+ $[10] = pathSegments;
26238
+ $[11] = relativePath;
26239
+ $[12] = selectionController;
26240
+ $[13] = tableController;
26241
+ $[14] = t3;
26004
26242
  } else {
26005
- t3 = $[13];
26243
+ t3 = $[14];
26006
26244
  }
26007
26245
  const actionProps = t3;
26008
26246
  const hasAnyAllowedFilters = !tableController.allowedFilters || tableController.allowedFilters.length > 0;
26009
26247
  let t4;
26010
- if ($[14] !== activeFilterCount || $[15] !== hasAnyAllowedFilters || $[16] !== largeLayout || $[17] !== resolvedProperties || $[18] !== t || $[19] !== tableController.setFilterValues) {
26248
+ if ($[15] !== activeFilterCount || $[16] !== hasAnyAllowedFilters || $[17] !== largeLayout || $[18] !== resolvedProperties || $[19] !== t || $[20] !== tableController.setFilterValues) {
26011
26249
  t4 = resolvedProperties && tableController.setFilterValues && hasAnyAllowedFilters && /* @__PURE__ */ jsx(Tooltip, { title: t("filters"), children: /* @__PURE__ */ jsx(Badge, { color: "primary", invisible: activeFilterCount === 0, children: largeLayout ? /* @__PURE__ */ jsxs(Button, { variant: "text", size: "small", onClick: () => setFiltersDialogOpen(true), startIcon: /* @__PURE__ */ jsx(FilterListIcon, { size: "small" }), className: cls(activeFilterCount > 0 && "text-primary"), children: [
26012
26250
  t("filters"),
26013
26251
  activeFilterCount > 0 ? ` (${activeFilterCount})` : ""
26014
26252
  ] }) : /* @__PURE__ */ jsx(IconButton, { size: "small", onClick: () => setFiltersDialogOpen(true), className: cls(activeFilterCount > 0 && "text-primary"), children: /* @__PURE__ */ jsx(FilterListIcon, { size: "small" }) }) }) }, "filters_tooltip");
26015
- $[14] = activeFilterCount;
26016
- $[15] = hasAnyAllowedFilters;
26017
- $[16] = largeLayout;
26018
- $[17] = resolvedProperties;
26019
- $[18] = t;
26020
- $[19] = tableController.setFilterValues;
26021
- $[20] = t4;
26253
+ $[15] = activeFilterCount;
26254
+ $[16] = hasAnyAllowedFilters;
26255
+ $[17] = largeLayout;
26256
+ $[18] = resolvedProperties;
26257
+ $[19] = t;
26258
+ $[20] = tableController.setFilterValues;
26259
+ $[21] = t4;
26022
26260
  } else {
26023
- t4 = $[20];
26261
+ t4 = $[21];
26024
26262
  }
26025
26263
  const filtersButton = t4;
26026
26264
  const t5 = !collection.forceFilter;
26027
26265
  let t6;
26028
- if ($[21] !== t5 || $[22] !== tableController) {
26266
+ if ($[22] !== t5 || $[23] !== tableController) {
26029
26267
  t6 = /* @__PURE__ */ jsx(ClearFilterSortButton, { tableController, enabled: t5 }, "clear_filter");
26030
- $[21] = t5;
26031
- $[22] = tableController;
26032
- $[23] = t6;
26268
+ $[22] = t5;
26269
+ $[23] = tableController;
26270
+ $[24] = t6;
26033
26271
  } else {
26034
- t6 = $[23];
26272
+ t6 = $[24];
26035
26273
  }
26036
26274
  let actions;
26037
- if ($[24] !== actionProps || $[25] !== filtersButton || $[26] !== plugins || $[27] !== t6) {
26275
+ if ($[25] !== actionProps || $[26] !== filtersButton || $[27] !== plugins || $[28] !== t6) {
26038
26276
  actions = [filtersButton, t6];
26039
26277
  if (plugins) {
26040
26278
  plugins.forEach((plugin, i) => {
@@ -26043,36 +26281,36 @@ function EntityCollectionViewStartActions(t0) {
26043
26281
  }
26044
26282
  });
26045
26283
  }
26046
- $[24] = actionProps;
26047
- $[25] = filtersButton;
26048
- $[26] = plugins;
26049
- $[27] = t6;
26050
- $[28] = actions;
26284
+ $[25] = actionProps;
26285
+ $[26] = filtersButton;
26286
+ $[27] = plugins;
26287
+ $[28] = t6;
26288
+ $[29] = actions;
26051
26289
  } else {
26052
- actions = $[28];
26290
+ actions = $[29];
26053
26291
  }
26054
26292
  let t7;
26055
- if ($[29] !== collection.forceFilter || $[30] !== filtersDialogOpen || $[31] !== resolvedProperties || $[32] !== tableController) {
26293
+ if ($[30] !== collection.forceFilter || $[31] !== filtersDialogOpen || $[32] !== resolvedProperties || $[33] !== tableController) {
26056
26294
  t7 = resolvedProperties && tableController.setFilterValues && /* @__PURE__ */ jsx(FiltersDialog, { open: filtersDialogOpen, onOpenChange: setFiltersDialogOpen, properties: resolvedProperties, filterValues: tableController.filterValues, setFilterValues: (filterValues_0) => tableController.setFilterValues?.(filterValues_0 ?? {}), forceFilter: collection.forceFilter, allowedFilters: tableController.allowedFilters?.map(_temp$g) });
26057
- $[29] = collection.forceFilter;
26058
- $[30] = filtersDialogOpen;
26059
- $[31] = resolvedProperties;
26060
- $[32] = tableController;
26061
- $[33] = t7;
26295
+ $[30] = collection.forceFilter;
26296
+ $[31] = filtersDialogOpen;
26297
+ $[32] = resolvedProperties;
26298
+ $[33] = tableController;
26299
+ $[34] = t7;
26062
26300
  } else {
26063
- t7 = $[33];
26301
+ t7 = $[34];
26064
26302
  }
26065
26303
  let t8;
26066
- if ($[34] !== actions || $[35] !== t7) {
26304
+ if ($[35] !== actions || $[36] !== t7) {
26067
26305
  t8 = /* @__PURE__ */ jsxs(Fragment, { children: [
26068
26306
  actions,
26069
26307
  t7
26070
26308
  ] });
26071
- $[34] = actions;
26072
- $[35] = t7;
26073
- $[36] = t8;
26309
+ $[35] = actions;
26310
+ $[36] = t7;
26311
+ $[37] = t8;
26074
26312
  } else {
26075
- t8 = $[36];
26313
+ t8 = $[37];
26076
26314
  }
26077
26315
  return t8;
26078
26316
  }
@@ -26150,7 +26388,7 @@ const EntityCollectionView$1 = React__default.memo(function EntityCollectionView
26150
26388
  useEffect(() => {
26151
26389
  collectionRef.current = collection;
26152
26390
  }, [collection]);
26153
- const canCreateEntities = canCreateEntity(collection, authController, fullPath, null);
26391
+ const canCreateEntities = canCreateEntity(collection, authController, fullPath, null, pathSegments);
26154
26392
  const [highlightedEntity, setHighlightedEntity] = useState(void 0);
26155
26393
  const [deleteEntityClicked, setDeleteEntityClicked] = React__default.useState(void 0);
26156
26394
  const [lastDeleteTimestamp, setLastDeleteTimestamp] = React__default.useState(0);
@@ -26168,7 +26406,7 @@ const EntityCollectionView$1 = React__default.memo(function EntityCollectionView
26168
26406
  }, [highlightedEntity]);
26169
26407
  const checkInlineEditing = useCallback((entity) => {
26170
26408
  const collection_0 = collectionRef.current;
26171
- if (!canEditEntity(collection_0, authController, fullPath, entity ?? null)) {
26409
+ if (!canEditEntity(collection_0, authController, fullPath, entity ?? null, pathSegments)) {
26172
26410
  return false;
26173
26411
  }
26174
26412
  return collection_0.inlineEditing === void 0 || collection_0.inlineEditing;
@@ -26258,10 +26496,12 @@ const EntityCollectionView$1 = React__default.memo(function EntityCollectionView
26258
26496
  if (collection_1) {
26259
26497
  addRecentId(collection_1.id, clickedEntity.id);
26260
26498
  }
26261
- const path = collection_1?.collectionGroup ? clickedEntity.path : fullPath ?? clickedEntity.path;
26499
+ const isCollectionGroup = Boolean(collection_1?.collectionGroup);
26500
+ const path = isCollectionGroup ? clickedEntity.path : fullPath ?? clickedEntity.path;
26262
26501
  navigateToEntity({
26263
26502
  navigation,
26264
26503
  path,
26504
+ pathSegments: isCollectionGroup ? clickedEntity.pathSegments : pathSegments ?? clickedEntity.pathSegments,
26265
26505
  fullIdPath,
26266
26506
  sideEntityController,
26267
26507
  openEntityMode,
@@ -26349,13 +26589,13 @@ const EntityCollectionView$1 = React__default.memo(function EntityCollectionView
26349
26589
  });
26350
26590
  }
26351
26591
  }, [setViewMode, userConfigPersistence, onCollectionModifiedForUser, fullPath, analyticsController, viewMode]);
26352
- const createEnabled = canCreateEntity(collection, authController, fullPath, null);
26592
+ const createEnabled = canCreateEntity(collection, authController, fullPath, null, pathSegments);
26353
26593
  const uniqueFieldValidator = useCallback(({
26354
26594
  name,
26355
26595
  value,
26356
26596
  property,
26357
26597
  entityId
26358
- }) => dataSource.checkUniqueField(fullPath, name, value, entityId, collection), [fullPath]);
26598
+ }) => dataSource.checkUniqueField(fullPath, name, value, entityId, collection, pathSegments), [fullPath, pathSegments]);
26359
26599
  const onValueChange = ({
26360
26600
  value: value_0,
26361
26601
  propertyKey,
@@ -26368,6 +26608,8 @@ const EntityCollectionView$1 = React__default.memo(function EntityCollectionView
26368
26608
  }, propertyKey, value_0);
26369
26609
  const saveProps = {
26370
26610
  path: entity_1.path ?? fullPath,
26611
+ // Paired with the `path` above: the row's segments describe the row's path.
26612
+ pathSegments: entity_1.path ? entity_1.pathSegments : pathSegments,
26371
26613
  entityId: entity_1.id,
26372
26614
  values: updatedValues,
26373
26615
  previousValues: entity_1.values,
@@ -26395,7 +26637,7 @@ const EntityCollectionView$1 = React__default.memo(function EntityCollectionView
26395
26637
  }
26396
26638
  });
26397
26639
  };
26398
- const resolvedFullPath = navigation.resolveIdsFrom(fullPath);
26640
+ const resolvedFullPath = navigation.resolveIdsFrom(fullPath, pathSegments);
26399
26641
  const resolvedCollection = useMemo(() => resolveCollection({
26400
26642
  collection,
26401
26643
  path: fullPath,
@@ -26524,9 +26766,9 @@ const EntityCollectionView$1 = React__default.memo(function EntityCollectionView
26524
26766
  Builder: ({
26525
26767
  entity: entity_4
26526
26768
  }) => {
26527
- const collectionsWithPath = navigation.getParentReferencesFromPath(entity_4.path);
26769
+ const collectionsWithPath = navigation.getParentReferencesFromPath(entity_4.path, entity_4.pathSegments);
26528
26770
  return /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-2 w-full", children: collectionsWithPath.map((reference) => {
26529
- return /* @__PURE__ */ jsx(ReferencePreview, { reference, size: "small" }, reference.path + "/" + reference.id);
26771
+ return /* @__PURE__ */ jsx(ReferencePreview, { reference, size: "small" }, entityCacheKey(reference.path, reference.id));
26530
26772
  }) });
26531
26773
  }
26532
26774
  }] : [];
@@ -26540,7 +26782,7 @@ const EntityCollectionView$1 = React__default.memo(function EntityCollectionView
26540
26782
  entity: entity_5,
26541
26783
  customEntityActions
26542
26784
  }) => {
26543
- const deleteEnabled = entity_5 ? canDeleteEntity(collection, authController, fullPath, entity_5) : true;
26785
+ const deleteEnabled = entity_5 ? canDeleteEntity(collection, authController, fullPath, entity_5, entity_5.pathSegments ?? pathSegments) : true;
26544
26786
  const actions = [{
26545
26787
  ...editEntityAction,
26546
26788
  name: t("edit")
@@ -26582,7 +26824,7 @@ const EntityCollectionView$1 = React__default.memo(function EntityCollectionView
26582
26824
  breadcrumbs.updateCount(fullPath, docsCount);
26583
26825
  }
26584
26826
  }, [docsCount, fullPath, breadcrumbs.updateCount]);
26585
- const countFetcher = /* @__PURE__ */ jsx(EntitiesCount, { fullPath, collection, filter: tableController.filterValues, sortBy: tableController.sortBy, onCountChange: setDocsCount });
26827
+ const countFetcher = /* @__PURE__ */ jsx(EntitiesCount, { fullPath, pathSegments, collection, filter: tableController.filterValues, sortBy: tableController.sortBy, onCountChange: setDocsCount });
26586
26828
  const buildAdditionalHeaderWidget = useCallback(({
26587
26829
  property: property_2,
26588
26830
  propertyKey: propertyKey_1,
@@ -26605,6 +26847,7 @@ const EntityCollectionView$1 = React__default.memo(function EntityCollectionView
26605
26847
  onTextSearchClick,
26606
26848
  textSearchEnabled
26607
26849
  } = useTableSearchHelper({
26850
+ pathSegments,
26608
26851
  collection,
26609
26852
  fullPath: resolvedFullPath,
26610
26853
  parentCollectionIds,
@@ -26628,8 +26871,8 @@ const EntityCollectionView$1 = React__default.memo(function EntityCollectionView
26628
26871
  }, [tableController.dataLoadingError, customizationController.plugins, fullPath, collection, parentCollectionIds]);
26629
26872
  return /* @__PURE__ */ jsxs("div", { className: cls("overflow-hidden h-full w-full rounded-md flex flex-col", className), ref: containerRef, children: [
26630
26873
  countFetcher,
26631
- /* @__PURE__ */ jsx(CollectionTableToolbar, { loading: tableController.dataLoading, onTextSearch: textSearchEnabled && textSearchInitialised ? tableController.setSearchString : void 0, onTextSearchClick: textSearchEnabled && !textSearchInitialised ? onTextSearchClick : void 0, initialSearchString: tableController.searchString, textSearchLoading, viewModeToggle: viewModeToggleElement, actionsStart: /* @__PURE__ */ jsx(EntityCollectionViewStartActions, { parentCollectionIds: parentCollectionIds ?? [], collection, tableController, path: fullPath, relativePath: collection.path, selectionController: usedSelectionController, collectionEntitiesCount: docsCount, resolvedProperties: resolvedCollection.properties }), actions: /* @__PURE__ */ jsx(EntityCollectionViewActions, { parentCollectionIds: parentCollectionIds ?? [], collection, tableController, onMultipleDeleteClick, onNewClick, path: fullPath, relativePath: collection.path, selectionController: usedSelectionController, selectionEnabled, collectionEntitiesCount: docsCount }) }),
26632
- tableController.dataLoadingError ? pluginErrorView ?? /* @__PURE__ */ jsx(CollectionDataErrorBanner, { error: tableController.dataLoadingError }) : viewMode === "kanban" && enabledViews.includes("kanban") ? /* @__PURE__ */ jsx(EntityCollectionBoardView, { collection, tableController, fullPath, parentCollectionIds, columnProperty: selectedKanbanProperty, onEntityClick, selectionController: usedSelectionController, selectionEnabled, highlightedEntities: highlightedEntity ? [highlightedEntity] : [], deletedEntities, emptyComponent: canCreateEntities && tableController.filterValues === void 0 && tableController.sortBy === void 0 ? /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center justify-center", children: [
26874
+ /* @__PURE__ */ jsx(CollectionTableToolbar, { loading: tableController.dataLoading, onTextSearch: textSearchEnabled && textSearchInitialised ? tableController.setSearchString : void 0, onTextSearchClick: textSearchEnabled && !textSearchInitialised ? onTextSearchClick : void 0, initialSearchString: tableController.searchString, textSearchLoading, viewModeToggle: viewModeToggleElement, actionsStart: /* @__PURE__ */ jsx(EntityCollectionViewStartActions, { parentCollectionIds: parentCollectionIds ?? [], collection, tableController, path: fullPath, pathSegments, relativePath: collection.path, selectionController: usedSelectionController, collectionEntitiesCount: docsCount, resolvedProperties: resolvedCollection.properties }), actions: /* @__PURE__ */ jsx(EntityCollectionViewActions, { parentCollectionIds: parentCollectionIds ?? [], collection, tableController, onMultipleDeleteClick, onNewClick, path: fullPath, pathSegments, relativePath: collection.path, selectionController: usedSelectionController, selectionEnabled, collectionEntitiesCount: docsCount }) }),
26875
+ tableController.dataLoadingError ? pluginErrorView ?? /* @__PURE__ */ jsx(CollectionDataErrorBanner, { error: tableController.dataLoadingError }) : viewMode === "kanban" && enabledViews.includes("kanban") ? /* @__PURE__ */ jsx(EntityCollectionBoardView, { collection, tableController, fullPath, pathSegments, parentCollectionIds, columnProperty: selectedKanbanProperty, onEntityClick, selectionController: usedSelectionController, selectionEnabled, highlightedEntities: highlightedEntity ? [highlightedEntity] : [], deletedEntities, emptyComponent: canCreateEntities && tableController.filterValues === void 0 && tableController.sortBy === void 0 ? /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center justify-center", children: [
26633
26876
  /* @__PURE__ */ jsx(Typography, { variant: "subtitle2", children: t("so_empty") }),
26634
26877
  /* @__PURE__ */ jsxs(Button, { onClick: onNewClick, className: "mt-4", children: [
26635
26878
  /* @__PURE__ */ jsx(AddIcon, {}),
@@ -26647,7 +26890,7 @@ const EntityCollectionView$1 = React__default.memo(function EntityCollectionView
26647
26890
  /* @__PURE__ */ jsx(AddIcon, {}),
26648
26891
  t("create_your_first_entry")
26649
26892
  ] })
26650
- ] }) : /* @__PURE__ */ jsx(Typography, { variant: "label", children: t("no_results_filter_sort") }), hoverRow, inlineEditing: checkInlineEditing(), AdditionalHeaderWidget: buildAdditionalHeaderWidget, AddColumnComponent: addColumnComponentInternal, getIdColumnWidth, additionalIDHeaderWidget: /* @__PURE__ */ jsx(EntityIdHeaderWidget, { path: fullPath, fullIdPath: fullIdPath ?? fullPath, collection }), openEntityMode, onColumnsOrderChange: (newColumns) => {
26893
+ ] }) : /* @__PURE__ */ jsx(Typography, { variant: "label", children: t("no_results_filter_sort") }), hoverRow, inlineEditing: checkInlineEditing(), AdditionalHeaderWidget: buildAdditionalHeaderWidget, AddColumnComponent: addColumnComponentInternal, getIdColumnWidth, additionalIDHeaderWidget: /* @__PURE__ */ jsx(EntityIdHeaderWidget, { path: fullPath, pathSegments, fullIdPath: fullIdPath ?? fullPath, collection }), openEntityMode, onColumnsOrderChange: (newColumns) => {
26651
26894
  const seenKeys = /* @__PURE__ */ new Set();
26652
26895
  const newPropertiesOrder = newColumns.filter((col) => !col.frozen && getPropertyInPath(collection.properties, col.key)).map((col_0) => col_0.key).filter((key_1) => {
26653
26896
  if (seenKeys.has(key_1)) return false;
@@ -26666,7 +26909,7 @@ const EntityCollectionView$1 = React__default.memo(function EntityCollectionView
26666
26909
  });
26667
26910
  }
26668
26911
  } }, `collection_table_${fullPath}`),
26669
- popupCell && /* @__PURE__ */ jsx(PopupFormField, { open: Boolean(popupCell), onClose: onPopupClose, cellRect: popupCell?.cellRect, propertyKey: popupCell?.propertyKey, collection, entityId: popupCell.entityId, tableKey: tableKey.current, customFieldValidator: uniqueFieldValidator, path: resolvedFullPath, onCellValueChange: onValueChange, container: containerRef.current }, `popup_form_${popupCell?.propertyKey}_${popupCell?.entityId}`),
26912
+ popupCell && /* @__PURE__ */ jsx(PopupFormField, { pathSegments, open: Boolean(popupCell), onClose: onPopupClose, cellRect: popupCell?.cellRect, propertyKey: popupCell?.propertyKey, collection, entityId: popupCell.entityId, tableKey: tableKey.current, customFieldValidator: uniqueFieldValidator, path: resolvedFullPath, onCellValueChange: onValueChange, container: containerRef.current }, `popup_form_${popupCell?.propertyKey}_${popupCell?.entityId}`),
26670
26913
  deleteEntityClicked && /* @__PURE__ */ jsx(DeleteEntityDialog, { entityOrEntitiesToDelete: deleteEntityClicked, path: fullPath, collection, callbacks: collection.callbacks, open: Boolean(deleteEntityClicked), onEntityDelete: internalOnEntityDelete, onMultipleEntitiesDelete: internalOnMultipleEntitiesDelete, onClose: () => setDeleteEntityClicked(void 0) })
26671
26914
  ] });
26672
26915
  }, (a, b) => {
@@ -26677,7 +26920,8 @@ function EntitiesCount({
26677
26920
  collection,
26678
26921
  filter,
26679
26922
  sortBy,
26680
- onCountChange
26923
+ onCountChange,
26924
+ pathSegments
26681
26925
  }) {
26682
26926
  const dataSource = useDataSource();
26683
26927
  const navigation = useNavigationController();
@@ -26685,16 +26929,18 @@ function EntitiesCount({
26685
26929
  const [error, setError] = useState(void 0);
26686
26930
  const sortByProperty = sortBy ? sortBy[0] : void 0;
26687
26931
  const currentSort = sortBy ? sortBy[1] : void 0;
26688
- const resolvedPath = useMemo(() => navigation.resolveIdsFrom(fullPath), [fullPath, navigation.resolveIdsFrom]);
26932
+ const resolvedPath = useMemo(() => navigation.resolveIdsFrom(fullPath, pathSegments), [fullPath, pathSegments, navigation.resolveIdsFrom]);
26933
+ const resolvedPathSegments = useMemo(() => pathSegments ? navigation.resolveSegmentsFrom?.(pathSegments) ?? pathSegments : void 0, [pathSegments, navigation.resolveSegmentsFrom]);
26689
26934
  useEffect(() => {
26690
26935
  if (dataSource.countEntities) dataSource.countEntities({
26691
26936
  path: resolvedPath,
26937
+ pathSegments: resolvedPathSegments,
26692
26938
  collection,
26693
26939
  filter,
26694
26940
  orderBy: sortByProperty,
26695
26941
  order: currentSort
26696
26942
  }).then(setCount).catch(setError);
26697
- }, [fullPath, dataSource.countEntities, resolvedPath, collection, filter, sortByProperty, currentSort]);
26943
+ }, [fullPath, dataSource.countEntities, resolvedPath, resolvedPathSegments, collection, filter, sortByProperty, currentSort]);
26698
26944
  useEffect(() => {
26699
26945
  if (onCountChange && count !== void 0) {
26700
26946
  setError(void 0);
@@ -26724,10 +26970,11 @@ function buildPropertyWidthOverwrite(key, width) {
26724
26970
  };
26725
26971
  }
26726
26972
  function EntityIdHeaderWidget(t0) {
26727
- const $ = c(48);
26973
+ const $ = c(50);
26728
26974
  const {
26729
26975
  collection,
26730
26976
  path,
26977
+ pathSegments,
26731
26978
  fullIdPath
26732
26979
  } = t0;
26733
26980
  const navigation = useNavigationController();
@@ -26768,7 +27015,7 @@ function EntityIdHeaderWidget(t0) {
26768
27015
  t4 = $[6];
26769
27016
  }
26770
27017
  let t5;
26771
- if ($[7] !== collection || $[8] !== fullIdPath || $[9] !== navigation || $[10] !== openEntityMode || $[11] !== path || $[12] !== searchString || $[13] !== sideEntityController) {
27018
+ if ($[7] !== collection || $[8] !== fullIdPath || $[9] !== navigation || $[10] !== openEntityMode || $[11] !== path || $[12] !== pathSegments || $[13] !== searchString || $[14] !== sideEntityController) {
26772
27019
  t5 = (e) => {
26773
27020
  e.preventDefault();
26774
27021
  if (!searchString) {
@@ -26782,6 +27029,7 @@ function EntityIdHeaderWidget(t0) {
26782
27029
  collection,
26783
27030
  entityId,
26784
27031
  path,
27032
+ pathSegments,
26785
27033
  fullIdPath,
26786
27034
  sideEntityController,
26787
27035
  navigation
@@ -26792,130 +27040,133 @@ function EntityIdHeaderWidget(t0) {
26792
27040
  $[9] = navigation;
26793
27041
  $[10] = openEntityMode;
26794
27042
  $[11] = path;
26795
- $[12] = searchString;
26796
- $[13] = sideEntityController;
26797
- $[14] = t5;
27043
+ $[12] = pathSegments;
27044
+ $[13] = searchString;
27045
+ $[14] = sideEntityController;
27046
+ $[15] = t5;
26798
27047
  } else {
26799
- t5 = $[14];
27048
+ t5 = $[15];
26800
27049
  }
26801
27050
  let t6;
26802
- if ($[15] !== t) {
27051
+ if ($[16] !== t) {
26803
27052
  t6 = t("find_entity_by_id");
26804
- $[15] = t;
26805
- $[16] = t6;
27053
+ $[16] = t;
27054
+ $[17] = t6;
26806
27055
  } else {
26807
- t6 = $[16];
27056
+ t6 = $[17];
26808
27057
  }
26809
27058
  let t7;
26810
- if ($[17] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
27059
+ if ($[18] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
26811
27060
  t7 = (e_0) => {
26812
27061
  setSearchString(e_0.target.value);
26813
27062
  };
26814
- $[17] = t7;
27063
+ $[18] = t7;
26815
27064
  } else {
26816
- t7 = $[17];
27065
+ t7 = $[18];
26817
27066
  }
26818
27067
  let t8;
26819
- if ($[18] !== openPopup || $[19] !== searchString || $[20] !== t6) {
27068
+ if ($[19] !== openPopup || $[20] !== searchString || $[21] !== t6) {
26820
27069
  t8 = /* @__PURE__ */ jsx("input", { autoFocus: openPopup, placeholder: t6, onChange: t7, value: searchString, className: "rounded-lg bg-white dark:bg-surface-800 flex-grow bg-transparent outline-none p-2 " + focusedDisabled });
26821
- $[18] = openPopup;
26822
- $[19] = searchString;
26823
- $[20] = t6;
26824
- $[21] = t8;
27070
+ $[19] = openPopup;
27071
+ $[20] = searchString;
27072
+ $[21] = t6;
27073
+ $[22] = t8;
26825
27074
  } else {
26826
- t8 = $[21];
27075
+ t8 = $[22];
26827
27076
  }
26828
27077
  const t9 = !searchString.trim();
26829
27078
  let t10;
26830
- if ($[22] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
27079
+ if ($[23] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
26831
27080
  t10 = /* @__PURE__ */ jsx(KeyboardTabIcon, {});
26832
- $[22] = t10;
27081
+ $[23] = t10;
26833
27082
  } else {
26834
- t10 = $[22];
27083
+ t10 = $[23];
26835
27084
  }
26836
27085
  let t11;
26837
- if ($[23] !== t9) {
27086
+ if ($[24] !== t9) {
26838
27087
  t11 = /* @__PURE__ */ jsx(Button, { variant: "text", disabled: t9, type: "submit", children: t10 });
26839
- $[23] = t9;
26840
- $[24] = t11;
27088
+ $[24] = t9;
27089
+ $[25] = t11;
26841
27090
  } else {
26842
- t11 = $[24];
27091
+ t11 = $[25];
26843
27092
  }
26844
27093
  let t12;
26845
- if ($[25] !== t11 || $[26] !== t8) {
27094
+ if ($[26] !== t11 || $[27] !== t8) {
26846
27095
  t12 = /* @__PURE__ */ jsxs("div", { className: "flex p-2 w-full gap-2", children: [
26847
27096
  t8,
26848
27097
  t11
26849
27098
  ] });
26850
- $[25] = t11;
26851
- $[26] = t8;
26852
- $[27] = t12;
27099
+ $[26] = t11;
27100
+ $[27] = t8;
27101
+ $[28] = t12;
26853
27102
  } else {
26854
- t12 = $[27];
27103
+ t12 = $[28];
26855
27104
  }
26856
27105
  let t13;
26857
- if ($[28] !== t12 || $[29] !== t5) {
27106
+ if ($[29] !== t12 || $[30] !== t5) {
26858
27107
  t13 = /* @__PURE__ */ jsx("form", { noValidate: true, onSubmit: t5, className: "w-96 max-w-full", children: t12 });
26859
- $[28] = t12;
26860
- $[29] = t5;
26861
- $[30] = t13;
27108
+ $[29] = t12;
27109
+ $[30] = t5;
27110
+ $[31] = t13;
26862
27111
  } else {
26863
- t13 = $[30];
27112
+ t13 = $[31];
26864
27113
  }
26865
27114
  let t14;
26866
- if ($[31] !== collection || $[32] !== fullIdPath || $[33] !== navigation || $[34] !== openEntityMode || $[35] !== path || $[36] !== recentIds || $[37] !== sideEntityController) {
26867
- t14 = recentIds && recentIds.length > 0 && /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-2 p-2", children: recentIds.map((id) => /* @__PURE__ */ jsx(ReferencePreview, { reference: new EntityReference(id, path), hover: true, onClick: () => {
27115
+ if ($[32] !== collection || $[33] !== fullIdPath || $[34] !== navigation || $[35] !== openEntityMode || $[36] !== path || $[37] !== pathSegments || $[38] !== recentIds || $[39] !== sideEntityController) {
27116
+ t14 = recentIds && recentIds.length > 0 && /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-2 p-2", children: recentIds.map((id) => /* @__PURE__ */ jsx(ReferencePreview, { reference: new EntityReference(id, path, void 0, pathSegments), hover: true, onClick: () => {
26868
27117
  setOpenPopup(false);
26869
27118
  navigateToEntity({
26870
27119
  openEntityMode,
26871
27120
  collection,
26872
27121
  entityId: id,
26873
27122
  path,
27123
+ pathSegments,
26874
27124
  fullIdPath,
26875
27125
  sideEntityController,
26876
27126
  navigation
26877
27127
  });
26878
27128
  }, includeEntityLink: false, size: "small" }, id)) });
26879
- $[31] = collection;
26880
- $[32] = fullIdPath;
26881
- $[33] = navigation;
26882
- $[34] = openEntityMode;
26883
- $[35] = path;
26884
- $[36] = recentIds;
26885
- $[37] = sideEntityController;
26886
- $[38] = t14;
27129
+ $[32] = collection;
27130
+ $[33] = fullIdPath;
27131
+ $[34] = navigation;
27132
+ $[35] = openEntityMode;
27133
+ $[36] = path;
27134
+ $[37] = pathSegments;
27135
+ $[38] = recentIds;
27136
+ $[39] = sideEntityController;
27137
+ $[40] = t14;
26887
27138
  } else {
26888
- t14 = $[38];
27139
+ t14 = $[40];
26889
27140
  }
26890
27141
  let t15;
26891
- if ($[39] !== t13 || $[40] !== t14) {
27142
+ if ($[41] !== t13 || $[42] !== t14) {
26892
27143
  t15 = /* @__PURE__ */ jsxs("div", { className: t4, children: [
26893
27144
  t13,
26894
27145
  t14
26895
27146
  ] });
26896
- $[39] = t13;
26897
- $[40] = t14;
26898
- $[41] = t15;
27147
+ $[41] = t13;
27148
+ $[42] = t14;
27149
+ $[43] = t15;
26899
27150
  } else {
26900
- t15 = $[41];
27151
+ t15 = $[43];
26901
27152
  }
26902
27153
  let t16;
26903
- if ($[42] !== openPopup || $[43] !== t15) {
27154
+ if ($[44] !== openPopup || $[45] !== t15) {
26904
27155
  t16 = /* @__PURE__ */ jsx(Popover, { open: openPopup, onOpenChange: setOpenPopup, sideOffset: 0, align: "start", alignOffset: -117, trigger: t3, children: t15 });
26905
- $[42] = openPopup;
26906
- $[43] = t15;
26907
- $[44] = t16;
27156
+ $[44] = openPopup;
27157
+ $[45] = t15;
27158
+ $[46] = t16;
26908
27159
  } else {
26909
- t16 = $[44];
27160
+ t16 = $[46];
26910
27161
  }
26911
27162
  let t17;
26912
- if ($[45] !== t16 || $[46] !== t2) {
27163
+ if ($[47] !== t16 || $[48] !== t2) {
26913
27164
  t17 = /* @__PURE__ */ jsx(Tooltip, { title: t2, asChild: false, children: t16 });
26914
- $[45] = t16;
26915
- $[46] = t2;
26916
- $[47] = t17;
27165
+ $[47] = t16;
27166
+ $[48] = t2;
27167
+ $[49] = t17;
26917
27168
  } else {
26918
- t17 = $[47];
27169
+ t17 = $[49];
26919
27170
  }
26920
27171
  return t17;
26921
27172
  }
@@ -28482,8 +28733,13 @@ function getParentReferencesFromPath(props) {
28482
28733
  const {
28483
28734
  path,
28484
28735
  collections = [],
28485
- currentFullPath
28736
+ currentFullPath,
28737
+ currentPathSegments = [],
28738
+ pathSegments
28486
28739
  } = props;
28740
+ if (pathSegments) {
28741
+ return getParentReferencesFromPathSegments(pathSegments, collections);
28742
+ }
28487
28743
  const subpaths = removeInitialAndTrailingSlashes(path).split("/");
28488
28744
  const subpathCombinations = getCollectionPathsCombinations(subpaths);
28489
28745
  const result = [];
@@ -28492,12 +28748,14 @@ function getParentReferencesFromPath(props) {
28492
28748
  const collection = collections && collections.find((entry) => entry.id === subpathCombination || entry.path === subpathCombination);
28493
28749
  if (collection) {
28494
28750
  const collectionPath = currentFullPath && currentFullPath.length > 0 ? currentFullPath + "/" + collection.path : collection.path;
28751
+ const collectionSegments = [...currentPathSegments, ...collection.path.split("/")];
28495
28752
  const restOfThePath = removeInitialAndTrailingSlashes(removeInitialAndTrailingSlashes(path).replace(subpathCombination, ""));
28496
28753
  const nextSegments = restOfThePath.length > 0 ? restOfThePath.split("/") : [];
28497
28754
  if (nextSegments.length > 0) {
28498
28755
  const entityId = decodeEntityId(nextSegments[0]);
28499
28756
  const fullPath = collectionPath + "/" + entityId;
28500
- result.push(new EntityReference(entityId, collectionPath));
28757
+ const entitySegments = [...collectionSegments, entityId];
28758
+ result.push(new EntityReference(entityId, collectionPath, void 0, collectionSegments));
28501
28759
  if (nextSegments.length > 1) {
28502
28760
  const newPath = nextSegments.slice(1).join("/");
28503
28761
  if (!collection) {
@@ -28507,7 +28765,8 @@ function getParentReferencesFromPath(props) {
28507
28765
  result.push(...getParentReferencesFromPath({
28508
28766
  path: newPath,
28509
28767
  collections: collection.subcollections,
28510
- currentFullPath: fullPath
28768
+ currentFullPath: fullPath,
28769
+ currentPathSegments: entitySegments
28511
28770
  }));
28512
28771
  }
28513
28772
  }
@@ -28517,6 +28776,9 @@ function getParentReferencesFromPath(props) {
28517
28776
  }
28518
28777
  return result;
28519
28778
  }
28779
+ function getParentReferencesFromPathSegments(pathSegments, collections) {
28780
+ return walkPathSegments(pathSegments, collections).steps.filter((step) => step.entityId !== void 0).map((step) => new EntityReference(step.entityId, step.collectionPath, void 0, step.collectionSegments));
28781
+ }
28520
28782
  const DEFAULT_BASE_PATH = "/";
28521
28783
  const DEFAULT_COLLECTION_PATH = "/c";
28522
28784
  const NAVIGATION_ADMIN_GROUP_NAME = "Admin";
@@ -28721,10 +28983,10 @@ function useBuildNavigationController(props) {
28721
28983
  useEffect(() => {
28722
28984
  refreshNavigation();
28723
28985
  }, [refreshNavigation]);
28724
- const getCollection = useCallback((idOrPath, includeUserOverride = false) => {
28986
+ const getCollection = useCallback((idOrPath, includeUserOverride = false, pathSegments) => {
28725
28987
  const collections_0 = collectionsRef.current;
28726
28988
  if (!collections_0) return void 0;
28727
- const baseCollection = getCollectionByPathOrId(removeInitialAndTrailingSlashes(idOrPath), collections_0);
28989
+ const baseCollection = getCollectionByPathOrId(removeInitialAndTrailingSlashes(idOrPath), collections_0, pathSegments);
28728
28990
  const userOverride = includeUserOverride ? userConfigPersistence?.getCollectionConfig(idOrPath) : void 0;
28729
28991
  let overriddenCollection = baseCollection;
28730
28992
  if (baseCollection && userOverride) {
@@ -28759,16 +29021,16 @@ function useBuildNavigationController(props) {
28759
29021
  if (!collection_0) return void 0;
28760
29022
  return collection_0;
28761
29023
  }, []);
28762
- const getCollectionFromPaths = useCallback((pathSegments) => {
29024
+ const getCollectionFromPaths = useCallback((pathSegments_0) => {
28763
29025
  const collections_2 = collectionsRef.current;
28764
29026
  if (collections_2 === void 0) throw Error("getCollectionFromPaths: Collections have not been initialised yet");
28765
29027
  let currentCollections = [...collections_2 ?? []];
28766
- for (let i = 0; i < pathSegments.length; i++) {
28767
- const pathSegment = pathSegments[i];
29028
+ for (let i = 0; i < pathSegments_0.length; i++) {
29029
+ const pathSegment = pathSegments_0[i];
28768
29030
  const collection_1 = currentCollections.find((c_0) => c_0.id === pathSegment || c_0.path === pathSegment);
28769
29031
  if (!collection_1) return void 0;
28770
29032
  currentCollections = collection_1.subcollections;
28771
- if (i === pathSegments.length - 1) return collection_1;
29033
+ if (i === pathSegments_0.length - 1) return collection_1;
28772
29034
  }
28773
29035
  return void 0;
28774
29036
  }, []);
@@ -28793,33 +29055,37 @@ function useBuildNavigationController(props) {
28793
29055
  if (cleanPath_0.startsWith(fullCollectionPath)) return cleanPath_0.replace(fullCollectionPath, "");
28794
29056
  throw Error("Expected path starting with " + fullCollectionPath);
28795
29057
  }, [fullCollectionPath]);
28796
- const resolveIdsFrom = useCallback((path_3) => {
29058
+ const resolveIdsFrom = useCallback((path_3, pathSegments_1) => {
28797
29059
  const collections_4 = collectionsRef.current ?? [];
28798
- return resolveCollectionPathIds(path_3, collections_4);
29060
+ return resolveCollectionPathIds(path_3, collections_4, pathSegments_1);
28799
29061
  }, []);
28800
- const getAllParentReferencesForPath = useCallback((path_4) => {
29062
+ const resolveSegmentsFrom = useCallback((pathSegments_2) => {
28801
29063
  const collections_5 = collectionsRef.current ?? [];
29064
+ return resolveCollectionPathSegments(pathSegments_2, collections_5);
29065
+ }, []);
29066
+ const getAllParentReferencesForPath = useCallback((path_4, pathSegments_3) => {
29067
+ const collections_6 = collectionsRef.current ?? [];
28802
29068
  return getParentReferencesFromPath({
28803
29069
  path: path_4,
28804
- collections: collections_5
29070
+ pathSegments: pathSegments_3,
29071
+ collections: collections_6
28805
29072
  });
28806
29073
  }, []);
28807
- const getParentCollectionIds = useCallback((path_5) => {
28808
- const strings = path_5.split("/");
28809
- const oddPathSegments = strings.filter((_, i_1) => i_1 % 2 === 0);
29074
+ const getParentCollectionIds = useCallback((path_5, pathSegments_4) => {
29075
+ const oddPathSegments = pathSegments_4 ? collectionSegmentsFrom(pathSegments_4) : fullPathToCollectionSegments(path_5);
28810
29076
  oddPathSegments.pop();
28811
29077
  const result_0 = [];
28812
- for (let i_2 = 1; i_2 <= oddPathSegments.length; i_2++) {
28813
- result_0.push(oddPathSegments.slice(0, i_2));
29078
+ for (let i_1 = 1; i_1 <= oddPathSegments.length; i_1++) {
29079
+ result_0.push(oddPathSegments.slice(0, i_1));
28814
29080
  }
28815
29081
  return result_0.map((r) => getCollectionFromPaths(r)?.id).filter(Boolean);
28816
29082
  }, [getAllParentReferencesForPath]);
28817
29083
  const convertIdsToPaths = useCallback((ids_0) => {
28818
- const collections_6 = collectionsRef.current;
28819
- let currentCollections_1 = collections_6;
29084
+ const collections_7 = collectionsRef.current;
29085
+ let currentCollections_1 = collections_7;
28820
29086
  const paths = [];
28821
- for (let i_3 = 0; i_3 < ids_0.length; i_3++) {
28822
- const id_1 = ids_0[i_3];
29087
+ for (let i_2 = 0; i_2 < ids_0.length; i_2++) {
29088
+ const id_1 = ids_0[i_2];
28823
29089
  const collection_3 = currentCollections_1.find((c_2) => c_2.id === id_1);
28824
29090
  if (!collection_3) throw Error(`Collection with id ${id_1} not found`);
28825
29091
  paths.push(collection_3.path);
@@ -28845,6 +29111,7 @@ function useBuildNavigationController(props) {
28845
29111
  urlPathToDataPath,
28846
29112
  buildUrlCollectionPath,
28847
29113
  resolveIdsFrom,
29114
+ resolveSegmentsFrom,
28848
29115
  topLevelNavigation,
28849
29116
  refreshNavigation,
28850
29117
  getParentReferencesFromPath: getAllParentReferencesForPath,
@@ -29602,6 +29869,7 @@ function EntitySidePanel(props) {
29602
29869
  if (params.status !== "existing") {
29603
29870
  sideEntityController.replace({
29604
29871
  path: params.path,
29872
+ pathSegments: params.pathSegments ?? pathSegments,
29605
29873
  entityId: params.entityId,
29606
29874
  fullIdPath: props.fullIdPath,
29607
29875
  selectedTab: params.selectedTab,
@@ -29615,9 +29883,9 @@ function EntitySidePanel(props) {
29615
29883
  }
29616
29884
  };
29617
29885
  const parentCollectionIds = useMemo(() => {
29618
- return navigationController.getParentCollectionIds(path);
29886
+ return navigationController.getParentCollectionIds(path, pathSegments);
29619
29887
  }, [navigationController, path]);
29620
- const collection = props.collection ?? navigationController.getCollection(fullIdPath ?? path);
29888
+ const collection = props.collection ?? navigationController.getCollection(fullIdPath ?? path, false, pathSegments);
29621
29889
  useEffect(() => {
29622
29890
  function beforeunload(e) {
29623
29891
  if (blocked && collection) {
@@ -29645,7 +29913,7 @@ function EntitySidePanel(props) {
29645
29913
  }) => /* @__PURE__ */ jsxs(Fragment, { children: [
29646
29914
  /* @__PURE__ */ jsx(IconButton, { className: "self-center", size: "smallest", onClick: onClose, children: /* @__PURE__ */ jsx(CloseIcon, { size: "smallest" }) }),
29647
29915
  allowFullScreen && /* @__PURE__ */ jsx(IconButton, { className: "self-center", size: "smallest", onClick: () => {
29648
- const key = status === "new" || status === "copy" ? path + "#new" : path + "/" + entityId;
29916
+ const key = status === "new" || status === "copy" ? path + "#new" : entityCacheKey(path, entityId);
29649
29917
  saveEntityToMemoryCache(key, values);
29650
29918
  if (entityId) navigate(location.pathname + location.search);
29651
29919
  else navigate(location.pathname + location.search + "#new");
@@ -29657,6 +29925,7 @@ function EntitySidePanel(props) {
29657
29925
  }) => {
29658
29926
  sideEntityController.replace({
29659
29927
  path,
29928
+ pathSegments,
29660
29929
  entityId: entityId_0,
29661
29930
  fullIdPath: props.fullIdPath,
29662
29931
  selectedTab,
@@ -29772,6 +30041,7 @@ function SideDialogView({
29772
30041
  function EntityEditViewFormActions({
29773
30042
  collection,
29774
30043
  path,
30044
+ pathSegments,
29775
30045
  entity,
29776
30046
  layout,
29777
30047
  savingError,
@@ -29794,8 +30064,8 @@ function EntityEditViewFormActions({
29794
30064
  } = useTranslation();
29795
30065
  const entityActions = useMemo(() => {
29796
30066
  const customEntityActions = (collection.entityActions ?? []).map((action) => resolveEntityAction(action, customizationController.entityActions)).filter(Boolean);
29797
- const createEnabled = canCreateEntity(collection, authController, path, null);
29798
- const deleteEnabled = entity ? canDeleteEntity(collection, authController, path, entity) : false;
30067
+ const createEnabled = canCreateEntity(collection, authController, path, null, pathSegments);
30068
+ const deleteEnabled = entity ? canDeleteEntity(collection, authController, path, entity, entity.pathSegments ?? pathSegments) : false;
29799
30069
  const actions = [];
29800
30070
  if (createEnabled) actions.push(copyEntityAction);
29801
30071
  if (deleteEnabled) actions.push(deleteEntityAction);
@@ -30151,7 +30421,7 @@ function EntityEditView$1({
30151
30421
  databaseId: props.databaseId,
30152
30422
  useCache: false
30153
30423
  });
30154
- const initialDirtyValues = entityId ? getEntityFromMemoryCache(props.path + "/" + entityId) : getEntityFromMemoryCache(props.path + "#new");
30424
+ const initialDirtyValues = entityId ? getEntityFromMemoryCache(entityCacheKey(props.path, entityId)) : getEntityFromMemoryCache(props.path + "#new");
30155
30425
  const authController = useAuthController();
30156
30426
  const initialStatus = props.copy ? "copy" : entityId ? "existing" : "new";
30157
30427
  const [status, setStatus] = useState(initialStatus);
@@ -30159,7 +30429,7 @@ function EntityEditView$1({
30159
30429
  if (status === "new" || status === "copy") {
30160
30430
  return true;
30161
30431
  } else {
30162
- return entity ? canEditEntity(props.collection, authController, props.path, entity ?? null) : void 0;
30432
+ return entity ? canEditEntity(props.collection, authController, props.path, entity ?? null, props.pathSegments) : void 0;
30163
30433
  }
30164
30434
  }, [authController, entity, status]);
30165
30435
  if (dataLoading && !initialDirtyValues || (!entity || canEdit === void 0) && (status === "existing" || status === "copy")) {
@@ -30209,6 +30479,7 @@ function EntityEditViewInner({
30209
30479
  entityId,
30210
30480
  parentCollectionIds,
30211
30481
  path,
30482
+ pathSegments,
30212
30483
  status,
30213
30484
  collection,
30214
30485
  context,
@@ -30307,7 +30578,7 @@ function EntityEditViewInner({
30307
30578
  const subcollectionId = subcollection.id ?? subcollection.path;
30308
30579
  const newFullPath = usedEntity ? `${path}/${usedEntity?.id}/${removeInitialAndTrailingSlashes(subcollection.path)}` : void 0;
30309
30580
  const newFullIdPath = fullIdPath && usedEntity ? `${fullIdPath}/${encodeEntityId(usedEntity.id)}/${removeInitialAndTrailingSlashes(subcollectionId)}` : void 0;
30310
- const newPathSegments = usedEntity ? [...pathSegments ?? path.split("/"), usedEntity.id, ...removeInitialAndTrailingSlashes(subcollection.path).split("/")] : void 0;
30581
+ const newPathSegments = buildSubcollectionPathSegments(pathSegments, usedEntity?.id, subcollection.path);
30311
30582
  if (selectedTab !== subcollectionId) return null;
30312
30583
  return /* @__PURE__ */ jsxs("div", { className: "relative flex-1 h-full overflow-auto w-full", role: "tabpanel", children: [
30313
30584
  globalLoading && /* @__PURE__ */ jsx(CircularProgressCenter, {}),
@@ -30330,7 +30601,7 @@ function EntityEditViewInner({
30330
30601
  /* @__PURE__ */ jsx(EntityView, { className: "px-8 h-full overflow-auto", entity, path, collection }),
30331
30602
  /* @__PURE__ */ jsx("div", { className: "h-16" })
30332
30603
  ] }) }) : null;
30333
- const entityView = /* @__PURE__ */ jsx(EntityForm, { fullIdPath, collection, path, entityId: entityId ?? usedEntity?.id, onValuesModified, entity, initialDirtyValues, openEntityMode: layout, forceActionsAtTheBottom: actionsAtTheBottom, initialStatus: status, className: cls((!mainViewVisible || !canEdit) && !selectedSecondaryForm ? "hidden" : "", formProps?.className), EntityFormActionsComponent: EntityEditViewFormActions, disabled: !canEdit, ...formProps, onEntityChange: (entity_0) => {
30604
+ const entityView = /* @__PURE__ */ jsx(EntityForm, { fullIdPath, collection, path, pathSegments, entityId: entityId ?? usedEntity?.id, onValuesModified, entity, initialDirtyValues, openEntityMode: layout, forceActionsAtTheBottom: actionsAtTheBottom, initialStatus: status, className: cls((!mainViewVisible || !canEdit) && !selectedSecondaryForm ? "hidden" : "", formProps?.className), EntityFormActionsComponent: EntityEditViewFormActions, disabled: !canEdit, ...formProps, onEntityChange: (entity_0) => {
30334
30605
  setUsedEntity(entity_0);
30335
30606
  formProps?.onEntityChange?.(entity_0);
30336
30607
  }, onStatusChange: (status_0) => {
@@ -30601,19 +30872,21 @@ function buildSidePanelsFromUrl(path, collections, newFlag) {
30601
30872
  return sidePanel ? [sidePanel] : [];
30602
30873
  }
30603
30874
  const propsToSidePanel = (props, buildUrlCollectionPath, resolveIdsFrom, smallLayout, customizationController, authController, locationSearch) => {
30604
- const collectionPath = removeInitialAndTrailingSlashes(props.path);
30605
- const urlPath = props.entityId ? buildUrlCollectionPath(`${collectionPath}/${encodeEntityId(props.entityId)}${props.selectedTab ? "/" + props.selectedTab : ""}${locationSearch}#${SIDE_URL_HASH}`) : buildUrlCollectionPath(`${collectionPath}${locationSearch}#${NEW_URL_HASH}`);
30875
+ const urlChain = removeInitialAndTrailingSlashes(props.fullIdPath ?? props.path);
30876
+ const urlPath = props.entityId ? buildUrlCollectionPath(`${urlChain}/${encodeEntityId(props.entityId)}${props.selectedTab ? "/" + props.selectedTab : ""}${locationSearch}#${SIDE_URL_HASH}`) : buildUrlCollectionPath(`${urlChain}${locationSearch}#${NEW_URL_HASH}`);
30606
30877
  const resolvedPanelProps = {
30607
30878
  ...props,
30608
30879
  formProps: props.formProps
30609
30880
  };
30610
30881
  const entityViewWidth = getEntityViewWidth(props, smallLayout, customizationController, authController);
30611
30882
  return {
30612
- key: `${props.path}/${props.entityId}`,
30883
+ // Built from the escaped chain so that two different chains which happen to flatten
30884
+ // to the same raw string are still two different panels.
30885
+ key: `${urlChain}/${props.entityId ? encodeEntityId(props.entityId) : ""}`,
30613
30886
  component: void 0,
30614
30887
  // Lazy render in SideDialogs for better performance
30615
30888
  urlPath,
30616
- parentUrlPath: buildUrlCollectionPath(collectionPath),
30889
+ parentUrlPath: buildUrlCollectionPath(urlChain),
30617
30890
  width: entityViewWidth,
30618
30891
  onClose: props.onClose,
30619
30892
  additional: resolvedPanelProps
@@ -30882,7 +31155,7 @@ function useBuildDataSource({
30882
31155
  onUpdate,
30883
31156
  onError
30884
31157
  }) => {
30885
- const collection_0 = collectionProp ?? navigationController.getCollection(path_0);
31158
+ const collection_0 = collectionProp ?? navigationController.getCollection(path_0, false, pathSegments_0);
30886
31159
  const usedDelegate_0 = collection_0?.overrides?.dataSourceDelegate ?? delegate;
30887
31160
  if (!usedDelegate_0.listenCollection) throw Error("useBuildDataSource delegate not initialised");
30888
31161
  return usedDelegate_0.listenCollection({
@@ -30968,7 +31241,7 @@ function useBuildDataSource({
30968
31241
  collection: collectionProp_0,
30969
31242
  status
30970
31243
  }) => {
30971
- const collection_3 = collectionProp_0 ?? navigationController.getCollection(path_3);
31244
+ const collection_3 = collectionProp_0 ?? navigationController.getCollection(path_3, false, pathSegments_3);
30972
31245
  const usedDelegate_3 = collection_3?.overrides?.dataSourceDelegate ?? delegate;
30973
31246
  const resolvedCollection = collection_3 ? resolveCollection({
30974
31247
  collection: collection_3,
@@ -31025,8 +31298,11 @@ function useBuildDataSource({
31025
31298
  status
31026
31299
  }).then((res) => {
31027
31300
  return {
31028
- id: res.id,
31029
- path: res.path,
31301
+ ...res,
31302
+ // A delegate that predates `pathSegments` returns none; the segments we
31303
+ // just saved with describe exactly this entity's collection, so they are
31304
+ // the authoritative answer rather than a guess.
31305
+ pathSegments: res.pathSegments ?? pathSegments_3,
31030
31306
  values: usedDelegate_3.delegateToCMSModel(finalValues)
31031
31307
  };
31032
31308
  });
@@ -31039,11 +31315,14 @@ function useBuildDataSource({
31039
31315
  */
31040
31316
  deleteEntity: useCallback(({
31041
31317
  entity,
31318
+ pathSegments: pathSegments_4,
31042
31319
  collection: collection_4
31043
31320
  }) => {
31044
31321
  const usedDelegate_4 = collection_4?.overrides?.dataSourceDelegate ?? delegate;
31045
31322
  return usedDelegate_4.deleteEntity({
31046
31323
  entity,
31324
+ // Falls back to what the entity carries from the fetch that produced it.
31325
+ pathSegments: pathSegments_4 ?? entity.pathSegments,
31047
31326
  collection: collection_4
31048
31327
  });
31049
31328
  }, [delegate.deleteEntity]),
@@ -31057,16 +31336,19 @@ function useBuildDataSource({
31057
31336
  * @return `true` if there are no other fields besides the given entity
31058
31337
  * @group Firestore
31059
31338
  */
31060
- checkUniqueField: useCallback((path_4, name, value, entityId_2, collection_5) => {
31339
+ checkUniqueField: useCallback((path_4, name, value, entityId_2, collection_5, pathSegments_5) => {
31061
31340
  const usedDelegate_5 = collection_5?.overrides?.dataSourceDelegate ?? delegate;
31062
- return usedDelegate_5.checkUniqueField(path_4, name, value, entityId_2, collection_5);
31341
+ return usedDelegate_5.checkUniqueField(path_4, name, value, entityId_2, collection_5, pathSegments_5);
31063
31342
  }, [delegate.checkUniqueField]),
31064
- generateEntityId: useCallback((path_5, collection_6) => {
31343
+ generateEntityId: useCallback((path_5, collection_6, pathSegments_6) => {
31065
31344
  const usedDelegate_6 = collection_6?.overrides?.dataSourceDelegate ?? delegate;
31066
- return usedDelegate_6.generateEntityId(path_5, collection_6);
31345
+ return usedDelegate_6.generateEntityId(path_5, collection_6, pathSegments_6);
31067
31346
  }, [delegate.generateEntityId]),
31347
+ // Typed with the declared props rather than an inline duplicate: the duplicate is
31348
+ // free to drift from the interface, and a field it forgets is dropped in silence.
31068
31349
  countEntities: delegate.countEntities ? async ({
31069
31350
  path: path_6,
31351
+ pathSegments: pathSegments_7,
31070
31352
  collection: collection_7,
31071
31353
  filter: filter_1,
31072
31354
  order: order_1,
@@ -31075,6 +31357,7 @@ function useBuildDataSource({
31075
31357
  const usedDelegate_7 = collection_7?.overrides?.dataSourceDelegate ?? delegate;
31076
31358
  return usedDelegate_7.countEntities({
31077
31359
  path: path_6,
31360
+ pathSegments: pathSegments_7,
31078
31361
  filter: filter_1,
31079
31362
  orderBy: orderBy_1,
31080
31363
  order: order_1,
@@ -31083,6 +31366,7 @@ function useBuildDataSource({
31083
31366
  } : void 0,
31084
31367
  isFilterCombinationValid: useCallback(({
31085
31368
  path: path_7,
31369
+ pathSegments: pathSegments_8,
31086
31370
  databaseId,
31087
31371
  filterValues,
31088
31372
  sortBy
@@ -31090,6 +31374,7 @@ function useBuildDataSource({
31090
31374
  if (!delegate.isFilterCombinationValid) return true;
31091
31375
  return delegate.isFilterCombinationValid({
31092
31376
  path: path_7,
31377
+ pathSegments: pathSegments_8,
31093
31378
  databaseId,
31094
31379
  filterValues,
31095
31380
  sortBy
@@ -32587,7 +32872,7 @@ function FireCMSRoute() {
32587
32872
  let collection;
32588
32873
  collection = navigation.getCollectionById(navigationEntries[0].id);
32589
32874
  if (!collection) {
32590
- collection = navigation.getCollection(navigationEntries[0].path);
32875
+ collection = navigation.getCollection(navigationEntries[0].path, false, navigationEntries[0].pathSegments);
32591
32876
  }
32592
32877
  if (!collection) {
32593
32878
  t16 = null;
@@ -32698,7 +32983,7 @@ function FireCMSRoute() {
32698
32983
  const firstEntry = navigationEntries[0];
32699
32984
  collection_0 = navigation.getCollectionById(firstEntry.id);
32700
32985
  if (!collection_0) {
32701
- collection_0 = navigation.getCollection(firstEntry.path);
32986
+ collection_0 = navigation.getCollection(firstEntry.path, false, firstEntry.pathSegments);
32702
32987
  }
32703
32988
  if (!collection_0) {
32704
32989
  t16 = null;
@@ -32871,9 +33156,10 @@ function EntityFullScreenRoute({
32871
33156
  }
32872
33157
  const collection = isNew ? lastCollectionEntry.collection : lastEntityEntry.parentCollection;
32873
33158
  const fullIdPath = isNew ? lastCollectionEntry.fullPath : parentCollectionEntry?.fullPath ?? lastEntityEntry.fullPath;
32874
- const collectionPath = navigation.resolveIdsFrom(isNew ? lastCollectionEntry.path : lastEntityEntry.path);
33159
+ const pathSegments = isNew ? lastCollectionEntry.pathSegments : lastEntityEntry.pathSegments;
33160
+ const collectionPath = navigation.resolveIdsFrom(isNew ? lastCollectionEntry.path : lastEntityEntry.path, pathSegments);
32875
33161
  return /* @__PURE__ */ jsxs(Fragment, { children: [
32876
- /* @__PURE__ */ jsx(React__default.Suspense, { fallback: null, children: /* @__PURE__ */ jsx(EntityEditView, { entityId: isNew ? void 0 : entityId, fullIdPath, pathSegments: isNew ? lastCollectionEntry.pathSegments : lastEntityEntry.pathSegments, collection, layout: "full_screen", path: collectionPath, copy: isCopy, selectedTab: selectedTab ?? void 0, onValuesModified: (modified) => blocked.current = modified, onSaved: (params) => {
33162
+ /* @__PURE__ */ jsx(React__default.Suspense, { fallback: null, children: /* @__PURE__ */ jsx(EntityEditView, { entityId: isNew ? void 0 : entityId, fullIdPath, pathSegments, collection, layout: "full_screen", path: collectionPath, copy: isCopy, selectedTab: selectedTab ?? void 0, onValuesModified: (modified) => blocked.current = modified, onSaved: (params) => {
32877
33163
  const newEntityId = params.entityId;
32878
33164
  if (!newEntityId) return;
32879
33165
  navigate(buildEntityUrl(newEntityId, params.selectedTab), {
@@ -38965,12 +39251,27 @@ function FireCMSi18nProvider({
38965
39251
  translations,
38966
39252
  children
38967
39253
  }) {
39254
+ const parentI18n = useContext(I18nContext)?.i18n;
39255
+ const parentInstance = parentI18n?.hasResourceBundle?.("en", FIRECMS_NS) ? parentI18n : void 0;
38968
39256
  const i18nRef = useRef(null);
38969
39257
  const [ready, setReady] = React__default.useState(false);
38970
39258
  if (!i18nRef.current) {
38971
39259
  const instance = i18next.createInstance();
38972
39260
  const resources = buildResources(translations);
38973
- let initialLocale = locale;
39261
+ if (parentInstance) {
39262
+ const inherited = parentInstance.services?.resourceStore?.data ?? {};
39263
+ for (const [lang, namespaces] of Object.entries(inherited)) {
39264
+ const bundle = namespaces?.[FIRECMS_NS];
39265
+ if (!bundle) continue;
39266
+ resources[lang] = {
39267
+ [FIRECMS_NS]: {
39268
+ ...bundle,
39269
+ ...translations?.[lang] ?? {}
39270
+ }
39271
+ };
39272
+ }
39273
+ }
39274
+ let initialLocale = parentInstance?.language ?? locale;
38974
39275
  if (typeof window !== "undefined") {
38975
39276
  const stored = localStorage.getItem(FIRECMS_LOCALE_STORAGE_KEY);
38976
39277
  if (stored) initialLocale = stored;
@@ -38995,6 +39296,17 @@ function FireCMSi18nProvider({
38995
39296
  });
38996
39297
  i18nRef.current = instance;
38997
39298
  }
39299
+ useEffect(() => {
39300
+ if (!parentInstance || !i18nRef.current) return;
39301
+ const instance_0 = i18nRef.current;
39302
+ const follow = (lng_0) => {
39303
+ if (instance_0.language !== lng_0) instance_0.changeLanguage(lng_0);
39304
+ };
39305
+ parentInstance.on("languageChanged", follow);
39306
+ return () => {
39307
+ parentInstance.off("languageChanged", follow);
39308
+ };
39309
+ }, [parentInstance]);
38998
39310
  useEffect(() => {
38999
39311
  if (i18nRef.current && i18nRef.current.language !== locale) {
39000
39312
  const hasUserPreference = typeof window !== "undefined" && Boolean(localStorage.getItem(FIRECMS_LOCALE_STORAGE_KEY));
@@ -39006,11 +39318,11 @@ function FireCMSi18nProvider({
39006
39318
  useEffect(() => {
39007
39319
  if (!i18nRef.current) return;
39008
39320
  const resources_0 = buildResources(translations);
39009
- for (const [lang, bundle] of Object.entries(resources_0)) {
39321
+ for (const [lang_0, bundle_0] of Object.entries(resources_0)) {
39010
39322
  i18nRef.current.addResourceBundle(
39011
- lang,
39323
+ lang_0,
39012
39324
  FIRECMS_NS,
39013
- bundle[FIRECMS_NS],
39325
+ bundle_0[FIRECMS_NS],
39014
39326
  true,
39015
39327
  // deep merge
39016
39328
  true
@@ -43760,9 +44072,11 @@ export {
43760
44072
  buildProperties,
43761
44073
  buildPropertiesOrBuilder,
43762
44074
  buildProperty,
44075
+ buildSubcollectionPathSegments,
43763
44076
  canCreateEntity,
43764
44077
  canDeleteEntity,
43765
44078
  canEditEntity,
44079
+ collectionSegmentsFrom,
43766
44080
  copyEntityAction,
43767
44081
  decodeEntityId,
43768
44082
  defaultDateFormat,
@@ -43781,6 +44095,7 @@ export {
43781
44095
  getArrayValuesCount,
43782
44096
  getBracketNotation,
43783
44097
  getCollectionByPathOrId,
44098
+ getCollectionByPathSegments,
43784
44099
  getCollectionPathsCombinations,
43785
44100
  getColorForProperty,
43786
44101
  getColorScheme,
@@ -43842,6 +44157,7 @@ export {
43842
44157
  parseGeoPoint,
43843
44158
  pick,
43844
44159
  plural,
44160
+ positionalCollectionSegments,
43845
44161
  prettifyIdentifier,
43846
44162
  printChanged,
43847
44163
  propertiesToColumns,
@@ -43863,6 +44179,7 @@ export {
43863
44179
  resolveArrayProperty,
43864
44180
  resolveCollection,
43865
44181
  resolveCollectionPathIds,
44182
+ resolveCollectionPathSegments,
43866
44183
  resolveDefaultSelectedView,
43867
44184
  resolveEntityAction,
43868
44185
  resolveEntityView,
@@ -43925,6 +44242,7 @@ export {
43925
44242
  useTraceUpdate,
43926
44243
  useTranslation,
43927
44244
  useValidateAuthenticator,
44245
+ walkPathSegments,
43928
44246
  yupToFormErrors
43929
44247
  };
43930
44248
  //# sourceMappingURL=index.es.js.map