@firecms/core 3.4.0-canary.0ef7442 → 3.4.0-canary.2575a08

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 (74) hide show
  1. package/dist/components/EntityCollectionView/EntityCollectionView.d.ts +3 -2
  2. package/dist/components/EntityCollectionView/EntityCollectionViewActions.d.ts +3 -1
  3. package/dist/components/EntityCollectionView/EntityCollectionViewStartActions.d.ts +3 -1
  4. package/dist/components/common/useDataSourceTableController.d.ts +4 -2
  5. package/dist/components/common/useTableSearchHelper.d.ts +3 -1
  6. package/dist/core/EntityEditView.d.ts +2 -0
  7. package/dist/core/EntityEditViewFormActions.d.ts +1 -1
  8. package/dist/form/EntityForm.d.ts +2 -0
  9. package/dist/form/EntityFormActions.d.ts +2 -0
  10. package/dist/hooks/data/delete.d.ts +1 -1
  11. package/dist/hooks/data/useCollectionFetch.d.ts +1 -1
  12. package/dist/hooks/data/useEntityFetch.d.ts +4 -1
  13. package/dist/i18n/__tests__/FireCMSi18nProvider.test.d.ts +1 -0
  14. package/dist/i18n/__tests__/nested_provider_lifecycle.test.d.ts +1 -0
  15. package/dist/index.es.js +853 -600
  16. package/dist/index.es.js.map +1 -1
  17. package/dist/index.umd.js +852 -599
  18. package/dist/index.umd.js.map +1 -1
  19. package/dist/types/collections.d.ts +7 -0
  20. package/dist/types/datasource.d.ts +8 -0
  21. package/dist/types/entity_actions.d.ts +6 -0
  22. package/dist/types/entity_callbacks.d.ts +21 -0
  23. package/dist/types/navigation.d.ts +34 -5
  24. package/dist/types/plugins.d.ts +13 -0
  25. package/dist/types/side_entity_controller.d.ts +3 -2
  26. package/dist/util/entity_cache.d.ts +11 -0
  27. package/dist/util/navigation_utils.d.ts +84 -2
  28. package/dist/util/parent_references_from_path.d.ts +15 -0
  29. package/dist/util/paths.d.ts +28 -0
  30. package/dist/util/permissions.d.ts +10 -4
  31. package/package.json +3 -3
  32. package/src/components/DeleteEntityDialog.tsx +2 -0
  33. package/src/components/EntityCollectionTable/EntityCollectionRowActions.tsx +2 -2
  34. package/src/components/EntityCollectionView/EntityCollectionBoardView.tsx +8 -0
  35. package/src/components/EntityCollectionView/EntityCollectionView.tsx +40 -15
  36. package/src/components/EntityCollectionView/EntityCollectionViewActions.tsx +6 -2
  37. package/src/components/EntityCollectionView/EntityCollectionViewStartActions.tsx +4 -0
  38. package/src/components/EntityCollectionView/useBoardDataController.tsx +7 -2
  39. package/src/components/EntityPreview.tsx +4 -1
  40. package/src/components/ReferenceTable/ReferenceSelectionTable.tsx +8 -2
  41. package/src/components/common/default_entity_actions.tsx +22 -2
  42. package/src/components/common/useDataSourceTableController.tsx +26 -8
  43. package/src/components/common/useTableSearchHelper.ts +5 -0
  44. package/src/core/EntityEditView.tsx +8 -12
  45. package/src/core/EntityEditViewFormActions.tsx +3 -2
  46. package/src/core/EntitySidePanel.tsx +6 -4
  47. package/src/form/EntityForm.tsx +22 -7
  48. package/src/form/EntityFormActions.tsx +2 -0
  49. package/src/hooks/data/delete.ts +8 -2
  50. package/src/hooks/data/save.ts +4 -1
  51. package/src/hooks/data/useCollectionFetch.tsx +9 -2
  52. package/src/hooks/data/useEntityFetch.tsx +19 -6
  53. package/src/hooks/useBuildNavigationController.tsx +23 -8
  54. package/src/hooks/useResolvedNavigationFrom.tsx +1 -1
  55. package/src/i18n/FireCMSi18nProvider.tsx +48 -4
  56. package/src/i18n/__tests__/FireCMSi18nProvider.test.tsx +91 -0
  57. package/src/i18n/__tests__/nested_provider_lifecycle.test.tsx +67 -0
  58. package/src/internal/useBuildDataSource.ts +13 -12
  59. package/src/internal/useBuildSideEntityController.tsx +13 -5
  60. package/src/preview/components/ReferencePreview.tsx +7 -3
  61. package/src/routes/FireCMSRoute.tsx +9 -4
  62. package/src/types/collections.ts +8 -0
  63. package/src/types/datasource.ts +8 -0
  64. package/src/types/entity_actions.tsx +6 -0
  65. package/src/types/entity_callbacks.ts +24 -0
  66. package/src/types/navigation.ts +35 -5
  67. package/src/types/plugins.tsx +13 -0
  68. package/src/types/side_entity_controller.tsx +3 -2
  69. package/src/util/entity_cache.ts +18 -0
  70. package/src/util/navigation_from_path.ts +6 -1
  71. package/src/util/navigation_utils.ts +204 -2
  72. package/src/util/parent_references_from_path.ts +32 -1
  73. package/src/util/paths.ts +40 -3
  74. package/src/util/permissions.ts +22 -10
package/dist/index.umd.js CHANGED
@@ -192,6 +192,11 @@
192
192
  function decodeEntityId(encodedEntityId) {
193
193
  return encodedEntityId.replaceAll("%2F", "/").replaceAll("%23", "#").replaceAll("%3F", "?").replaceAll("%25", "%");
194
194
  }
195
+ function buildSubcollectionPathSegments(parentPathSegments, entityId, subcollectionPath) {
196
+ if (!parentPathSegments || !entityId) return void 0;
197
+ const ownSegments = removeInitialAndTrailingSlashes(subcollectionPath).split("/");
198
+ return [...parentPathSegments, entityId, ...ownSegments];
199
+ }
195
200
  function getLastSegment(path) {
196
201
  const cleanPath = removeInitialAndTrailingSlashes(path);
197
202
  if (cleanPath.includes("/")) {
@@ -200,7 +205,88 @@
200
205
  }
201
206
  return cleanPath;
202
207
  }
203
- function resolveCollectionPathIds(path, allCollections) {
208
+ function walkPathSegments(pathSegments, allCollections) {
209
+ const resolved = [];
210
+ const steps = [];
211
+ let currentCollections = allCollections;
212
+ let index = 0;
213
+ while (index < pathSegments.length) {
214
+ const remaining = pathSegments.slice(index);
215
+ if (!currentCollections || currentCollections.length === 0) {
216
+ resolved.push(...remaining);
217
+ return {
218
+ resolved,
219
+ steps,
220
+ unmatched: remaining[0]
221
+ };
222
+ }
223
+ let match;
224
+ for (const collection of currentCollections) {
225
+ for (const candidate of [collection.path, collection.id]) {
226
+ if (!candidate) continue;
227
+ const parts = removeInitialAndTrailingSlashes(candidate).split("/");
228
+ if (parts.length > remaining.length) continue;
229
+ if (parts.some((part, i) => part !== remaining[i])) continue;
230
+ if (!match || parts.length > match.length) match = {
231
+ collection,
232
+ length: parts.length
233
+ };
234
+ }
235
+ }
236
+ if (!match) {
237
+ resolved.push(...remaining);
238
+ return {
239
+ resolved,
240
+ steps,
241
+ unmatched: remaining[0]
242
+ };
243
+ }
244
+ resolved.push(...removeInitialAndTrailingSlashes(match.collection.path).split("/"));
245
+ index += match.length;
246
+ const step = {
247
+ collection: match.collection,
248
+ collectionPath: resolved.join("/"),
249
+ collectionSegments: [...resolved]
250
+ };
251
+ steps.push(step);
252
+ if (index >= pathSegments.length) {
253
+ return {
254
+ resolved,
255
+ steps,
256
+ collection: match.collection
257
+ };
258
+ }
259
+ step.entityId = pathSegments[index];
260
+ resolved.push(pathSegments[index]);
261
+ index += 1;
262
+ if (index >= pathSegments.length) {
263
+ return {
264
+ resolved,
265
+ steps,
266
+ collection: match.collection
267
+ };
268
+ }
269
+ currentCollections = match.collection.subcollections;
270
+ }
271
+ return {
272
+ resolved,
273
+ steps
274
+ };
275
+ }
276
+ function resolveCollectionPathSegments(pathSegments, allCollections) {
277
+ const walk = walkPathSegments(pathSegments, allCollections);
278
+ if (walk.unmatched !== void 0) {
279
+ console.warn(`resolveCollectionPathSegments: Collection definition not found for segment "${walk.unmatched}" in [${pathSegments.join(", ")}]. Carrying the remaining segments through unresolved.`);
280
+ }
281
+ return walk.resolved;
282
+ }
283
+ function getCollectionByPathSegments(pathSegments, collections) {
284
+ return walkPathSegments(pathSegments, collections).collection;
285
+ }
286
+ function resolveCollectionPathIds(path, allCollections, pathSegments) {
287
+ if (pathSegments) {
288
+ return resolveCollectionPathSegments(pathSegments, allCollections).join("/");
289
+ }
204
290
  let remainingPath = removeInitialAndTrailingSlashes(path);
205
291
  if (!remainingPath) {
206
292
  return "";
@@ -262,7 +348,10 @@
262
348
  }
263
349
  return resolvedPathParts.join("/");
264
350
  }
265
- function getCollectionByPathOrId(pathOrId, collections) {
351
+ function getCollectionByPathOrId(pathOrId, collections, pathSegments) {
352
+ if (pathSegments) {
353
+ return getCollectionByPathSegments(pathSegments, collections);
354
+ }
266
355
  const subpaths = removeInitialAndTrailingSlashes(pathOrId).split("/");
267
356
  if (subpaths.length % 2 === 0) {
268
357
  throw Error(`getCollectionByPathOrId: Collection paths must have an odd number of segments: ${pathOrId}`);
@@ -319,6 +408,9 @@
319
408
  onClose
320
409
  });
321
410
  } else {
411
+ if (!fullIdPath && pathSegments?.some((segment) => segment.includes("/"))) {
412
+ 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".`);
413
+ }
322
414
  let to = navigation.buildUrlCollectionPath(entityId ? `${fullIdPath ?? path}/${encodeEntityId(entityId)}` : fullIdPath ?? path);
323
415
  if (entityId && selectedTab) {
324
416
  to += `/${selectedTab}`;
@@ -1222,7 +1314,12 @@
1222
1314
  path: newPath,
1223
1315
  collections: collection.subcollections,
1224
1316
  currentFullPath: fullPath,
1225
- currentFullIdPath: fullIdPath,
1317
+ // The entity id is a hop in the id chain exactly as it is in the
1318
+ // other two. Without it a nested `fullIdPath` was
1319
+ // "products/locales" rather than "products/pid/locales", so any
1320
+ // URL built from it pointed at a collection that does not exist.
1321
+ // Escaped, because `fullIdPath` is URL-facing.
1322
+ currentFullIdPath: fullIdPath + "/" + encodedEntityId,
1226
1323
  currentFullUrlPath: fullUrlPath,
1227
1324
  currentPathSegments: entitySegments,
1228
1325
  contextEntityViews: props.contextEntityViews
@@ -1394,7 +1491,16 @@
1394
1491
  return paths.reduce((a, b) => `${a}${COLLECTION_PATH_SEPARATOR}${b}`);
1395
1492
  }
1396
1493
  function fullPathToCollectionSegments(path) {
1397
- return path.split("/").filter((e, i) => i % 2 === 0);
1494
+ return positionalCollectionSegments(path);
1495
+ }
1496
+ function collectionSegmentsFrom(pathSegments) {
1497
+ return keepCollectionPositions(pathSegments);
1498
+ }
1499
+ function positionalCollectionSegments(path) {
1500
+ return keepCollectionPositions(path.split("/"));
1501
+ }
1502
+ function keepCollectionPositions(segments) {
1503
+ return segments.filter((e, i) => i % 2 === 0);
1398
1504
  }
1399
1505
  function serializeRegExp(input) {
1400
1506
  if (!input) return "";
@@ -1624,35 +1730,35 @@
1624
1730
  create: true,
1625
1731
  delete: true
1626
1732
  };
1627
- function resolvePermissions(collection, authController, path, entity) {
1733
+ function resolvePermissions(collection, authController, path, entity, pathSegments) {
1628
1734
  const permission = collection.permissions;
1629
1735
  if (permission === void 0) {
1630
1736
  return DEFAULT_PERMISSIONS;
1631
1737
  } else if (typeof permission === "object") {
1632
1738
  return permission;
1633
1739
  } else if (typeof permission === "function") {
1634
- const pathSegments = fullPathToCollectionSegments(path);
1740
+ const collectionSegments = pathSegments ? collectionSegmentsFrom(pathSegments) : fullPathToCollectionSegments(path);
1635
1741
  return permission({
1636
1742
  entity,
1637
1743
  path,
1638
1744
  user: authController.user,
1639
1745
  authController,
1640
1746
  collection,
1641
- pathSegments
1747
+ pathSegments: collectionSegments
1642
1748
  });
1643
1749
  }
1644
1750
  console.error("Permissions:", permission);
1645
1751
  throw Error("New type of permission added and not mapped");
1646
1752
  }
1647
- function canEditEntity(collection, authController, path, entity) {
1648
- return resolvePermissions(collection, authController, path, entity)?.edit ?? DEFAULT_PERMISSIONS.edit;
1753
+ function canEditEntity(collection, authController, path, entity, pathSegments) {
1754
+ return resolvePermissions(collection, authController, path, entity, pathSegments)?.edit ?? DEFAULT_PERMISSIONS.edit;
1649
1755
  }
1650
- function canCreateEntity(collection, authController, path, entity) {
1756
+ function canCreateEntity(collection, authController, path, entity, pathSegments) {
1651
1757
  if (collection.collectionGroup) return false;
1652
- return resolvePermissions(collection, authController, path, entity)?.create ?? DEFAULT_PERMISSIONS.create;
1758
+ return resolvePermissions(collection, authController, path, entity, pathSegments)?.create ?? DEFAULT_PERMISSIONS.create;
1653
1759
  }
1654
- function canDeleteEntity(collection, authController, path, entity) {
1655
- return resolvePermissions(collection, authController, path, entity)?.delete ?? DEFAULT_PERMISSIONS.delete;
1760
+ function canDeleteEntity(collection, authController, path, entity, pathSegments) {
1761
+ return resolvePermissions(collection, authController, path, entity, pathSegments)?.delete ?? DEFAULT_PERMISSIONS.delete;
1656
1762
  }
1657
1763
  function toNumber(value) {
1658
1764
  return typeof value === "number" && Number.isFinite(value) ? value : void 0;
@@ -4624,10 +4730,10 @@
4624
4730
  return fireCMSContextRef.current;
4625
4731
  };
4626
4732
  function useCollectionFetch(t0) {
4627
- const $ = reactCompilerRuntime.c(27);
4733
+ const $ = reactCompilerRuntime.c(31);
4628
4734
  const {
4629
4735
  path: inputPath,
4630
- pathSegments,
4736
+ pathSegments: inputPathSegments,
4631
4737
  collection,
4632
4738
  filterValues,
4633
4739
  sortBy,
@@ -4637,32 +4743,43 @@
4637
4743
  const dataSource = useDataSource();
4638
4744
  const navigationController = useNavigationController();
4639
4745
  let t1;
4640
- if ($[0] !== inputPath || $[1] !== navigationController) {
4641
- t1 = navigationController.resolveIdsFrom(inputPath);
4642
- $[0] = inputPath;
4746
+ if ($[0] !== inputPathSegments || $[1] !== navigationController) {
4747
+ t1 = inputPathSegments ? navigationController.resolveSegmentsFrom?.(inputPathSegments) ?? inputPathSegments : void 0;
4748
+ $[0] = inputPathSegments;
4643
4749
  $[1] = navigationController;
4644
4750
  $[2] = t1;
4645
4751
  } else {
4646
4752
  t1 = $[2];
4647
4753
  }
4648
- const path = t1;
4754
+ const pathSegments = t1;
4755
+ let t2;
4756
+ if ($[3] !== inputPath || $[4] !== inputPathSegments || $[5] !== navigationController) {
4757
+ t2 = navigationController.resolveIdsFrom(inputPath, inputPathSegments);
4758
+ $[3] = inputPath;
4759
+ $[4] = inputPathSegments;
4760
+ $[5] = navigationController;
4761
+ $[6] = t2;
4762
+ } else {
4763
+ t2 = $[6];
4764
+ }
4765
+ const path = t2;
4649
4766
  const sortByProperty = sortBy ? sortBy[0] : void 0;
4650
4767
  const currentSort = sortBy ? sortBy[1] : void 0;
4651
4768
  const context = useFireCMSContext();
4652
- let t2;
4653
- if ($[3] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
4654
- t2 = [];
4655
- $[3] = t2;
4769
+ let t3;
4770
+ if ($[7] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
4771
+ t3 = [];
4772
+ $[7] = t3;
4656
4773
  } else {
4657
- t2 = $[3];
4774
+ t3 = $[7];
4658
4775
  }
4659
- const [data, setData] = React.useState(t2);
4776
+ const [data, setData] = React.useState(t3);
4660
4777
  const [dataLoading, setDataLoading] = React.useState(false);
4661
4778
  const [dataLoadingError, setDataLoadingError] = React.useState();
4662
4779
  const [noMoreToLoad, setNoMoreToLoad] = React.useState(false);
4663
- let t3;
4664
- if ($[4] !== collection || $[5] !== context || $[6] !== currentSort || $[7] !== dataSource || $[8] !== filterValues || $[9] !== itemCount || $[10] !== path || $[11] !== pathSegments || $[12] !== searchString || $[13] !== sortByProperty) {
4665
- t3 = () => {
4780
+ let t4;
4781
+ if ($[8] !== collection || $[9] !== context || $[10] !== currentSort || $[11] !== dataSource || $[12] !== filterValues || $[13] !== itemCount || $[14] !== path || $[15] !== pathSegments || $[16] !== searchString || $[17] !== sortByProperty) {
4782
+ t4 = () => {
4666
4783
  setDataLoading(true);
4667
4784
  const onEntitiesUpdate = async (entities) => {
4668
4785
  if (pathSegments) {
@@ -4676,11 +4793,12 @@
4676
4793
  entities = await Promise.all(entities.map((entity) => collection.callbacks.onFetch({
4677
4794
  collection,
4678
4795
  path,
4796
+ pathSegments,
4679
4797
  entity,
4680
4798
  context
4681
4799
  })));
4682
- } catch (t42) {
4683
- const e_0 = t42;
4800
+ } catch (t52) {
4801
+ const e_0 = t52;
4684
4802
  console.error(e_0);
4685
4803
  }
4686
4804
  }
@@ -4724,51 +4842,51 @@
4724
4842
  return _temp2$f;
4725
4843
  }
4726
4844
  };
4727
- $[4] = collection;
4728
- $[5] = context;
4729
- $[6] = currentSort;
4730
- $[7] = dataSource;
4731
- $[8] = filterValues;
4732
- $[9] = itemCount;
4733
- $[10] = path;
4734
- $[11] = pathSegments;
4735
- $[12] = searchString;
4736
- $[13] = sortByProperty;
4737
- $[14] = t3;
4845
+ $[8] = collection;
4846
+ $[9] = context;
4847
+ $[10] = currentSort;
4848
+ $[11] = dataSource;
4849
+ $[12] = filterValues;
4850
+ $[13] = itemCount;
4851
+ $[14] = path;
4852
+ $[15] = pathSegments;
4853
+ $[16] = searchString;
4854
+ $[17] = sortByProperty;
4855
+ $[18] = t4;
4738
4856
  } else {
4739
- t3 = $[14];
4857
+ t4 = $[18];
4740
4858
  }
4741
- let t4;
4742
- if ($[15] !== currentSort || $[16] !== filterValues || $[17] !== itemCount || $[18] !== path || $[19] !== searchString || $[20] !== sortByProperty) {
4743
- t4 = [path, itemCount, currentSort, sortByProperty, filterValues, searchString];
4744
- $[15] = currentSort;
4745
- $[16] = filterValues;
4746
- $[17] = itemCount;
4747
- $[18] = path;
4748
- $[19] = searchString;
4749
- $[20] = sortByProperty;
4750
- $[21] = t4;
4859
+ let t5;
4860
+ if ($[19] !== currentSort || $[20] !== filterValues || $[21] !== itemCount || $[22] !== path || $[23] !== searchString || $[24] !== sortByProperty) {
4861
+ t5 = [path, itemCount, currentSort, sortByProperty, filterValues, searchString];
4862
+ $[19] = currentSort;
4863
+ $[20] = filterValues;
4864
+ $[21] = itemCount;
4865
+ $[22] = path;
4866
+ $[23] = searchString;
4867
+ $[24] = sortByProperty;
4868
+ $[25] = t5;
4751
4869
  } else {
4752
- t4 = $[21];
4870
+ t5 = $[25];
4753
4871
  }
4754
- React.useEffect(t3, t4);
4755
- let t5;
4756
- if ($[22] !== data || $[23] !== dataLoading || $[24] !== dataLoadingError || $[25] !== noMoreToLoad) {
4757
- t5 = {
4872
+ React.useEffect(t4, t5);
4873
+ let t6;
4874
+ if ($[26] !== data || $[27] !== dataLoading || $[28] !== dataLoadingError || $[29] !== noMoreToLoad) {
4875
+ t6 = {
4758
4876
  data,
4759
4877
  dataLoading,
4760
4878
  dataLoadingError,
4761
4879
  noMoreToLoad
4762
4880
  };
4763
- $[22] = data;
4764
- $[23] = dataLoading;
4765
- $[24] = dataLoadingError;
4766
- $[25] = noMoreToLoad;
4767
- $[26] = t5;
4881
+ $[26] = data;
4882
+ $[27] = dataLoading;
4883
+ $[28] = dataLoadingError;
4884
+ $[29] = noMoreToLoad;
4885
+ $[30] = t6;
4768
4886
  } else {
4769
- t5 = $[26];
4887
+ t6 = $[30];
4770
4888
  }
4771
- return t5;
4889
+ return t6;
4772
4890
  }
4773
4891
  function _temp2$f() {
4774
4892
  }
@@ -4777,9 +4895,132 @@
4777
4895
  ...e_1
4778
4896
  };
4779
4897
  }
4898
+ function entityCacheKey(path, entityId) {
4899
+ return `${path}/${entityId === void 0 ? entityId : encodeEntityId(entityId)}`;
4900
+ }
4901
+ const LOCAL_STORAGE_PREFIX = "entity_cache::";
4902
+ const entityCache = /* @__PURE__ */ new Map();
4903
+ const isLocalStorageAvailable = typeof localStorage !== "undefined";
4904
+ function customReplacer(key) {
4905
+ const value = this[key];
4906
+ if (value instanceof Date) {
4907
+ return {
4908
+ __type: "Date",
4909
+ value: value.toISOString()
4910
+ };
4911
+ }
4912
+ if (value instanceof EntityReference) {
4913
+ return {
4914
+ __type: "EntityReference",
4915
+ id: value.id,
4916
+ path: value.path,
4917
+ databaseId: value.databaseId
4918
+ };
4919
+ }
4920
+ if (value instanceof GeoPoint) {
4921
+ return {
4922
+ __type: "GeoPoint",
4923
+ latitude: value.latitude,
4924
+ longitude: value.longitude
4925
+ };
4926
+ }
4927
+ if (value instanceof Vector) {
4928
+ return {
4929
+ __type: "Vector",
4930
+ value: value.value
4931
+ };
4932
+ }
4933
+ return value;
4934
+ }
4935
+ function customReviver(key, value) {
4936
+ if (value && typeof value === "object" && "__type" in value) {
4937
+ switch (value.__type) {
4938
+ case "Date":
4939
+ return new Date(value.value);
4940
+ case "EntityReference":
4941
+ return new EntityReference(value.id, value.path, value.databaseId);
4942
+ case "GeoPoint":
4943
+ return new GeoPoint(value.latitude, value.longitude);
4944
+ case "Vector":
4945
+ return new Vector(value.value);
4946
+ default:
4947
+ return value;
4948
+ }
4949
+ }
4950
+ return value;
4951
+ }
4952
+ function saveEntityToCache(path, data) {
4953
+ if (isLocalStorageAvailable) {
4954
+ try {
4955
+ const key = LOCAL_STORAGE_PREFIX + path;
4956
+ const entityString = JSON.stringify(data, customReplacer);
4957
+ console.debug("Saving entity to localStorage:", {
4958
+ key,
4959
+ entityString
4960
+ });
4961
+ localStorage.setItem(key, entityString);
4962
+ } catch (error) {
4963
+ console.error(`Failed to save entity for path "${path}" to localStorage:`, error);
4964
+ }
4965
+ }
4966
+ }
4967
+ function removeEntityFromMemoryCache(path) {
4968
+ entityCache.delete(path);
4969
+ }
4970
+ function saveEntityToMemoryCache(path, data) {
4971
+ entityCache.set(path, data);
4972
+ }
4973
+ function getEntityFromMemoryCache(path) {
4974
+ return entityCache.get(path);
4975
+ }
4976
+ function getEntityFromCache(path) {
4977
+ if (isLocalStorageAvailable) {
4978
+ try {
4979
+ const key = LOCAL_STORAGE_PREFIX + path;
4980
+ const entityString = localStorage.getItem(key);
4981
+ if (entityString) {
4982
+ const entity = JSON.parse(entityString, customReviver);
4983
+ return entity;
4984
+ }
4985
+ } catch (error) {
4986
+ console.error(`Failed to load entity for path "${path}" from localStorage:`, error);
4987
+ }
4988
+ }
4989
+ return void 0;
4990
+ }
4991
+ function removeEntityFromCache(path) {
4992
+ if (isLocalStorageAvailable) {
4993
+ try {
4994
+ const key = LOCAL_STORAGE_PREFIX + path;
4995
+ localStorage.removeItem(key);
4996
+ } catch (error) {
4997
+ console.error(`Failed to remove entity for path "${path}" from localStorage:`, error);
4998
+ }
4999
+ }
5000
+ }
5001
+ function flattenKeys(obj, prefix = "", result = []) {
5002
+ if (isObject(obj) || Array.isArray(obj)) {
5003
+ const plainObject = isPlainObject(obj);
5004
+ if (!plainObject && prefix) {
5005
+ result.push(prefix);
5006
+ } else {
5007
+ for (const key in obj) {
5008
+ if (Object.prototype.hasOwnProperty.call(obj, key)) {
5009
+ const newKey = prefix ? Array.isArray(obj) ? `${prefix}[${key}]` : `${prefix}.${key}` : key;
5010
+ if (isObject(obj[key]) || Array.isArray(obj[key])) {
5011
+ flattenKeys(obj[key], newKey, result);
5012
+ } else {
5013
+ result.push(newKey);
5014
+ }
5015
+ }
5016
+ }
5017
+ }
5018
+ }
5019
+ return result;
5020
+ }
4780
5021
  const CACHE = {};
4781
5022
  function useEntityFetch(t0) {
4782
- const $ = reactCompilerRuntime.c(19);
5023
+ const $ = reactCompilerRuntime.c(23);
4783
5024
  const {
4784
5025
  path: inputPath,
4785
5026
  pathSegments: inputPathSegments,
@@ -4792,23 +5033,33 @@
4792
5033
  const dataSource = useDataSource();
4793
5034
  const navigationController = useNavigationController();
4794
5035
  let t2;
4795
- if ($[0] !== inputPath || $[1] !== navigationController) {
4796
- t2 = navigationController.resolveIdsFrom(inputPath);
4797
- $[0] = inputPath;
5036
+ if ($[0] !== inputPathSegments || $[1] !== navigationController) {
5037
+ t2 = inputPathSegments ? navigationController.resolveSegmentsFrom?.(inputPathSegments) ?? inputPathSegments : void 0;
5038
+ $[0] = inputPathSegments;
4798
5039
  $[1] = navigationController;
4799
5040
  $[2] = t2;
4800
5041
  } else {
4801
5042
  t2 = $[2];
4802
5043
  }
4803
- const path = t2;
4804
- const pathSegments = inputPathSegments;
5044
+ const pathSegments = t2;
5045
+ let t3;
5046
+ if ($[3] !== inputPath || $[4] !== inputPathSegments || $[5] !== navigationController) {
5047
+ t3 = navigationController.resolveIdsFrom(inputPath, inputPathSegments);
5048
+ $[3] = inputPath;
5049
+ $[4] = inputPathSegments;
5050
+ $[5] = navigationController;
5051
+ $[6] = t3;
5052
+ } else {
5053
+ t3 = $[6];
5054
+ }
5055
+ const path = t3;
4805
5056
  const context = useFireCMSContext();
4806
5057
  const [entity, setEntity] = React.useState();
4807
5058
  const [dataLoading, setDataLoading] = React.useState(true);
4808
5059
  const [dataLoadingError, setDataLoadingError] = React.useState();
4809
- let t3;
4810
- if ($[3] !== collection || $[4] !== context || $[5] !== dataSource || $[6] !== databaseId || $[7] !== entityId || $[8] !== path || $[9] !== pathSegments || $[10] !== useCache) {
4811
- t3 = () => {
5060
+ let t4;
5061
+ if ($[7] !== collection || $[8] !== context || $[9] !== dataSource || $[10] !== databaseId || $[11] !== entityId || $[12] !== path || $[13] !== pathSegments || $[14] !== useCache) {
5062
+ t4 = () => {
4812
5063
  setDataLoading(true);
4813
5064
  const onEntityUpdate = async (updatedEntity) => {
4814
5065
  if (updatedEntity && pathSegments && !updatedEntity.pathSegments) {
@@ -4822,15 +5073,16 @@
4822
5073
  updatedEntity = await collection.callbacks.onFetch({
4823
5074
  collection,
4824
5075
  path,
5076
+ pathSegments,
4825
5077
  entity: updatedEntity,
4826
5078
  context
4827
5079
  });
4828
- } catch (t42) {
4829
- const e = t42;
5080
+ } catch (t52) {
5081
+ const e = t52;
4830
5082
  console.error(e);
4831
5083
  }
4832
5084
  }
4833
- CACHE[`${path}/${entityId}`] = updatedEntity;
5085
+ CACHE[entityCacheKey(path, entityId)] = updatedEntity;
4834
5086
  setEntity(updatedEntity);
4835
5087
  setDataLoading(false);
4836
5088
  setDataLoadingError(void 0);
@@ -4841,8 +5093,8 @@
4841
5093
  setEntity(void 0);
4842
5094
  setDataLoadingError(error);
4843
5095
  };
4844
- if (entityId && useCache && CACHE[`${path}/${entityId}`]) {
4845
- setEntity(CACHE[`${path}/${entityId}`]);
5096
+ if (entityId && useCache && CACHE[entityCacheKey(path, entityId)]) {
5097
+ setEntity(CACHE[entityCacheKey(path, entityId)]);
4846
5098
  setDataLoading(false);
4847
5099
  setDataLoadingError(void 0);
4848
5100
  return _temp$C;
@@ -4874,43 +5126,43 @@
4874
5126
  }
4875
5127
  }
4876
5128
  };
4877
- $[3] = collection;
4878
- $[4] = context;
4879
- $[5] = dataSource;
4880
- $[6] = databaseId;
4881
- $[7] = entityId;
4882
- $[8] = path;
4883
- $[9] = pathSegments;
4884
- $[10] = useCache;
4885
- $[11] = t3;
5129
+ $[7] = collection;
5130
+ $[8] = context;
5131
+ $[9] = dataSource;
5132
+ $[10] = databaseId;
5133
+ $[11] = entityId;
5134
+ $[12] = path;
5135
+ $[13] = pathSegments;
5136
+ $[14] = useCache;
5137
+ $[15] = t4;
4886
5138
  } else {
4887
- t3 = $[11];
5139
+ t4 = $[15];
4888
5140
  }
4889
- let t4;
4890
- if ($[12] !== entityId || $[13] !== path) {
4891
- t4 = [entityId, path];
4892
- $[12] = entityId;
4893
- $[13] = path;
4894
- $[14] = t4;
5141
+ let t5;
5142
+ if ($[16] !== entityId || $[17] !== path) {
5143
+ t5 = [entityId, path];
5144
+ $[16] = entityId;
5145
+ $[17] = path;
5146
+ $[18] = t5;
4895
5147
  } else {
4896
- t4 = $[14];
5148
+ t5 = $[18];
4897
5149
  }
4898
- React.useEffect(t3, t4);
4899
- let t5;
4900
- if ($[15] !== dataLoading || $[16] !== dataLoadingError || $[17] !== entity) {
4901
- t5 = {
5150
+ React.useEffect(t4, t5);
5151
+ let t6;
5152
+ if ($[19] !== dataLoading || $[20] !== dataLoadingError || $[21] !== entity) {
5153
+ t6 = {
4902
5154
  entity,
4903
5155
  dataLoading,
4904
5156
  dataLoadingError
4905
5157
  };
4906
- $[15] = dataLoading;
4907
- $[16] = dataLoadingError;
4908
- $[17] = entity;
4909
- $[18] = t5;
5158
+ $[19] = dataLoading;
5159
+ $[20] = dataLoadingError;
5160
+ $[21] = entity;
5161
+ $[22] = t6;
4910
5162
  } else {
4911
- t5 = $[18];
5163
+ t6 = $[22];
4912
5164
  }
4913
- return t5;
5165
+ return t6;
4914
5166
  }
4915
5167
  function _temp3$5() {
4916
5168
  }
@@ -4938,7 +5190,7 @@
4938
5190
  }
4939
5191
  let updatedValues;
4940
5192
  const customizationController = context.customizationController;
4941
- const resolvedPath = context.navigation.resolveIdsFrom(path);
5193
+ const resolvedPath = context.navigation.resolveIdsFrom(path, pathSegments);
4942
5194
  const callbacks = collection.callbacks;
4943
5195
  if (callbacks?.onPreSave) {
4944
5196
  try {
@@ -4953,6 +5205,7 @@
4953
5205
  updatedValues = await callbacks.onPreSave({
4954
5206
  collection: resolvedCollection,
4955
5207
  path,
5208
+ pathSegments,
4956
5209
  resolvedPath,
4957
5210
  entityId,
4958
5211
  values,
@@ -4990,6 +5243,7 @@
4990
5243
  callbacks.onSaveSuccess({
4991
5244
  collection: resolvedCollection,
4992
5245
  path,
5246
+ pathSegments,
4993
5247
  resolvedPath,
4994
5248
  entityId: entity.id,
4995
5249
  values: updatedValues,
@@ -5015,6 +5269,7 @@
5015
5269
  callbacks.onSaveFailure({
5016
5270
  collection: resolvedCollection,
5017
5271
  path,
5272
+ pathSegments,
5018
5273
  resolvedPath,
5019
5274
  entityId,
5020
5275
  values: updatedValues,
@@ -5029,6 +5284,7 @@
5029
5284
  async function deleteEntityWithCallbacks({
5030
5285
  dataSource,
5031
5286
  entity,
5287
+ pathSegments,
5032
5288
  collection,
5033
5289
  callbacks,
5034
5290
  onDeleteSuccess,
@@ -5038,11 +5294,13 @@
5038
5294
  context
5039
5295
  }) {
5040
5296
  console.debug("Deleting entity", entity.path, entity.id);
5297
+ const resolvedPathSegments = pathSegments ?? entity.pathSegments;
5041
5298
  const entityDeleteProps = {
5042
5299
  entity,
5043
5300
  collection,
5044
5301
  entityId: entity.id,
5045
5302
  path: entity.path,
5303
+ pathSegments: resolvedPathSegments,
5046
5304
  context
5047
5305
  };
5048
5306
  if (callbacks?.onPreDelete) {
@@ -5055,8 +5313,7 @@
5055
5313
  }
5056
5314
  }
5057
5315
  return dataSource.deleteEntity({
5058
- // Carried by the entity from the fetch that produced it; undefined if unknown.
5059
- pathSegments: entity.pathSegments,
5316
+ pathSegments: resolvedPathSegments,
5060
5317
  entity,
5061
5318
  collection
5062
5319
  }).then(() => {
@@ -5092,7 +5349,7 @@
5092
5349
  if (entry.type === "collection") {
5093
5350
  return Promise.resolve(entry);
5094
5351
  } else if (entry.type === "entity") {
5095
- const collection = navigation.getCollection(entry.path);
5352
+ const collection = navigation.getCollection(entry.path, false, entry.pathSegments);
5096
5353
  if (!collection) {
5097
5354
  throw Error(`No collection defined in the navigation for the entity with path ${entry.path}`);
5098
5355
  }
@@ -6499,7 +6756,7 @@
6499
6756
  const sideEntityController = useSideEntityController();
6500
6757
  const customizationController = useCustomizationController();
6501
6758
  const navigationController = useNavigationController();
6502
- const collection = collectionProp ?? navigationController.getCollection(entity.path);
6759
+ const collection = collectionProp ?? navigationController.getCollection(entity.path, false, entity.pathSegments);
6503
6760
  if (!collection) {
6504
6761
  throw Error(`Couldn't find the corresponding collection view for the path: ${entity.path}`);
6505
6762
  }
@@ -6542,6 +6799,9 @@
6542
6799
  sideEntityController.open({
6543
6800
  entityId: entity.id,
6544
6801
  path: entity.path,
6802
+ // Paired with `entity.path` above; undefined if the entity was
6803
+ // loaded without them.
6804
+ pathSegments: entity.pathSegments,
6545
6805
  collection,
6546
6806
  updateUrl: true
6547
6807
  });
@@ -6666,7 +6926,7 @@
6666
6926
  return t0;
6667
6927
  };
6668
6928
  function ReferencePreviewInternal(t0) {
6669
- const $ = reactCompilerRuntime.c(22);
6929
+ const $ = reactCompilerRuntime.c(23);
6670
6930
  const {
6671
6931
  disabled,
6672
6932
  reference,
@@ -6682,70 +6942,71 @@
6682
6942
  const customizationController = useCustomizationController();
6683
6943
  const navigationController = useNavigationController();
6684
6944
  let t3;
6685
- if ($[0] !== navigationController || $[1] !== reference.path) {
6686
- t3 = navigationController.getCollection(reference.path);
6945
+ if ($[0] !== navigationController || $[1] !== reference.path || $[2] !== reference.pathSegments) {
6946
+ t3 = navigationController.getCollection(reference.path, false, reference.pathSegments);
6687
6947
  $[0] = navigationController;
6688
6948
  $[1] = reference.path;
6689
- $[2] = t3;
6949
+ $[2] = reference.pathSegments;
6950
+ $[3] = t3;
6690
6951
  } else {
6691
- t3 = $[2];
6952
+ t3 = $[3];
6692
6953
  }
6693
6954
  const collection = t3;
6694
6955
  if (!collection) {
6695
6956
  if (customizationController.components?.missingReference) {
6696
6957
  let t42;
6697
- if ($[3] !== customizationController.components.missingReference || $[4] !== reference.path) {
6958
+ if ($[4] !== customizationController.components.missingReference || $[5] !== reference.path) {
6698
6959
  t42 = /* @__PURE__ */ jsxRuntime.jsx(customizationController.components.missingReference, { path: reference.path });
6699
- $[3] = customizationController.components.missingReference;
6700
- $[4] = reference.path;
6701
- $[5] = t42;
6960
+ $[4] = customizationController.components.missingReference;
6961
+ $[5] = reference.path;
6962
+ $[6] = t42;
6702
6963
  } else {
6703
- t42 = $[5];
6964
+ t42 = $[6];
6704
6965
  }
6705
6966
  return t42;
6706
6967
  } else {
6707
6968
  const t42 = size ?? "medium";
6708
6969
  let t5;
6709
- if ($[6] !== reference.pathWithId) {
6970
+ if ($[7] !== reference.pathWithId) {
6710
6971
  t5 = /* @__PURE__ */ jsxRuntime.jsx(ErrorView, { error: "Unexpected reference value. Click to edit", tooltip: reference.pathWithId });
6711
- $[6] = reference.pathWithId;
6712
- $[7] = t5;
6972
+ $[7] = reference.pathWithId;
6973
+ $[8] = t5;
6713
6974
  } else {
6714
- t5 = $[7];
6975
+ t5 = $[8];
6715
6976
  }
6716
6977
  let t6;
6717
- if ($[8] !== onClick || $[9] !== t42 || $[10] !== t5) {
6978
+ if ($[9] !== onClick || $[10] !== t42 || $[11] !== t5) {
6718
6979
  t6 = /* @__PURE__ */ jsxRuntime.jsx(EntityPreviewContainer, { onClick, size: t42, children: t5 });
6719
- $[8] = onClick;
6720
- $[9] = t42;
6721
- $[10] = t5;
6722
- $[11] = t6;
6980
+ $[9] = onClick;
6981
+ $[10] = t42;
6982
+ $[11] = t5;
6983
+ $[12] = t6;
6723
6984
  } else {
6724
- t6 = $[11];
6985
+ t6 = $[12];
6725
6986
  }
6726
6987
  return t6;
6727
6988
  }
6728
6989
  }
6729
6990
  let t4;
6730
- if ($[12] !== collection || $[13] !== disabled || $[14] !== hover || $[15] !== includeEntityLink || $[16] !== includeId || $[17] !== onClick || $[18] !== previewProperties || $[19] !== reference || $[20] !== size) {
6991
+ if ($[13] !== collection || $[14] !== disabled || $[15] !== hover || $[16] !== includeEntityLink || $[17] !== includeId || $[18] !== onClick || $[19] !== previewProperties || $[20] !== reference || $[21] !== size) {
6731
6992
  t4 = /* @__PURE__ */ jsxRuntime.jsx(ReferencePreviewExisting, { reference, collection, previewProperties, size, disabled, includeEntityLink, includeId, onClick, hover });
6732
- $[12] = collection;
6733
- $[13] = disabled;
6734
- $[14] = hover;
6735
- $[15] = includeEntityLink;
6736
- $[16] = includeId;
6737
- $[17] = onClick;
6738
- $[18] = previewProperties;
6739
- $[19] = reference;
6740
- $[20] = size;
6741
- $[21] = t4;
6993
+ $[13] = collection;
6994
+ $[14] = disabled;
6995
+ $[15] = hover;
6996
+ $[16] = includeEntityLink;
6997
+ $[17] = includeId;
6998
+ $[18] = onClick;
6999
+ $[19] = previewProperties;
7000
+ $[20] = reference;
7001
+ $[21] = size;
7002
+ $[22] = t4;
6742
7003
  } else {
6743
- t4 = $[21];
7004
+ t4 = $[22];
6744
7005
  }
6745
7006
  return t4;
6746
7007
  }
6747
7008
  function ReferencePreviewExisting(t0) {
6748
- const $ = reactCompilerRuntime.c(35);
7009
+ const $ = reactCompilerRuntime.c(37);
6749
7010
  const {
6750
7011
  reference,
6751
7012
  collection,
@@ -6758,9 +7019,10 @@
6758
7019
  hover
6759
7020
  } = t0;
6760
7021
  let t1;
6761
- if ($[0] !== collection || $[1] !== reference.id || $[2] !== reference.path) {
7022
+ if ($[0] !== collection || $[1] !== reference.id || $[2] !== reference.path || $[3] !== reference.pathSegments) {
6762
7023
  t1 = {
6763
7024
  path: reference.path,
7025
+ pathSegments: reference.pathSegments,
6764
7026
  entityId: reference.id,
6765
7027
  collection,
6766
7028
  useCache: true
@@ -6768,46 +7030,48 @@
6768
7030
  $[0] = collection;
6769
7031
  $[1] = reference.id;
6770
7032
  $[2] = reference.path;
6771
- $[3] = t1;
7033
+ $[3] = reference.pathSegments;
7034
+ $[4] = t1;
6772
7035
  } else {
6773
- t1 = $[3];
7036
+ t1 = $[4];
6774
7037
  }
6775
7038
  const {
6776
7039
  entity,
6777
7040
  dataLoading
6778
7041
  } = useEntityFetch(t1);
6779
7042
  if (entity) {
6780
- referencesCache.set(reference.pathWithId, entity);
7043
+ referencesCache.set(entityCacheKey(reference.path, reference.id), entity);
6781
7044
  }
6782
7045
  let t2;
6783
- if ($[4] !== entity || $[5] !== reference.pathWithId) {
6784
- t2 = entity ?? referencesCache.get(reference.pathWithId);
6785
- $[4] = entity;
6786
- $[5] = reference.pathWithId;
6787
- $[6] = t2;
7046
+ if ($[5] !== entity || $[6] !== reference.id || $[7] !== reference.path) {
7047
+ t2 = entity ?? referencesCache.get(entityCacheKey(reference.path, reference.id));
7048
+ $[5] = entity;
7049
+ $[6] = reference.id;
7050
+ $[7] = reference.path;
7051
+ $[8] = t2;
6788
7052
  } else {
6789
- t2 = $[6];
7053
+ t2 = $[8];
6790
7054
  }
6791
7055
  const usedEntity = t2;
6792
7056
  let body;
6793
7057
  if (!reference) {
6794
7058
  let t32;
6795
- if ($[7] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
7059
+ if ($[9] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
6796
7060
  t32 = /* @__PURE__ */ jsxRuntime.jsx(ErrorView, { error: "Reference not set" });
6797
- $[7] = t32;
7061
+ $[9] = t32;
6798
7062
  } else {
6799
- t32 = $[7];
7063
+ t32 = $[9];
6800
7064
  }
6801
7065
  body = t32;
6802
7066
  } else {
6803
7067
  if (usedEntity && !usedEntity.values) {
6804
7068
  let t32;
6805
- if ($[8] !== reference.path) {
7069
+ if ($[10] !== reference.path) {
6806
7070
  t32 = /* @__PURE__ */ jsxRuntime.jsx(ErrorView, { error: "Reference does not exist", tooltip: reference.path });
6807
- $[8] = reference.path;
6808
- $[9] = t32;
7071
+ $[10] = reference.path;
7072
+ $[11] = t32;
6809
7073
  } else {
6810
- t32 = $[9];
7074
+ t32 = $[11];
6811
7075
  }
6812
7076
  body = t32;
6813
7077
  }
@@ -6816,15 +7080,15 @@
6816
7080
  const t32 = disabled ? void 0 : onClick;
6817
7081
  const t4 = disabled ? void 0 : hover;
6818
7082
  let t5;
6819
- if ($[10] !== body || $[11] !== size || $[12] !== t32 || $[13] !== t4) {
7083
+ if ($[12] !== body || $[13] !== size || $[14] !== t32 || $[15] !== t4) {
6820
7084
  t5 = /* @__PURE__ */ jsxRuntime.jsx(EntityPreviewContainer, { onClick: t32, hover: t4, size, children: body });
6821
- $[10] = body;
6822
- $[11] = size;
6823
- $[12] = t32;
6824
- $[13] = t4;
6825
- $[14] = t5;
7085
+ $[12] = body;
7086
+ $[13] = size;
7087
+ $[14] = t32;
7088
+ $[15] = t4;
7089
+ $[16] = t5;
6826
7090
  } else {
6827
- t5 = $[14];
7091
+ t5 = $[16];
6828
7092
  }
6829
7093
  return t5;
6830
7094
  }
@@ -6832,21 +7096,21 @@
6832
7096
  const t32 = disabled ? void 0 : onClick;
6833
7097
  const t4 = disabled ? void 0 : hover;
6834
7098
  let t5;
6835
- if ($[15] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
7099
+ if ($[17] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
6836
7100
  t5 = /* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, {});
6837
- $[15] = t5;
7101
+ $[17] = t5;
6838
7102
  } else {
6839
- t5 = $[15];
7103
+ t5 = $[17];
6840
7104
  }
6841
7105
  let t6;
6842
- if ($[16] !== size || $[17] !== t32 || $[18] !== t4) {
7106
+ if ($[18] !== size || $[19] !== t32 || $[20] !== t4) {
6843
7107
  t6 = /* @__PURE__ */ jsxRuntime.jsx(EntityPreviewContainer, { onClick: t32, hover: t4, size, children: t5 });
6844
- $[16] = size;
6845
- $[17] = t32;
6846
- $[18] = t4;
6847
- $[19] = t6;
7108
+ $[18] = size;
7109
+ $[19] = t32;
7110
+ $[20] = t4;
7111
+ $[21] = t6;
6848
7112
  } else {
6849
- t6 = $[19];
7113
+ t6 = $[21];
6850
7114
  }
6851
7115
  return t6;
6852
7116
  }
@@ -6854,39 +7118,39 @@
6854
7118
  const t32 = disabled ? void 0 : onClick;
6855
7119
  const t4 = disabled ? void 0 : hover;
6856
7120
  let t5;
6857
- if ($[20] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
7121
+ if ($[22] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
6858
7122
  t5 = /* @__PURE__ */ jsxRuntime.jsx(ErrorView, { error: "Entity not found" });
6859
- $[20] = t5;
7123
+ $[22] = t5;
6860
7124
  } else {
6861
- t5 = $[20];
7125
+ t5 = $[22];
6862
7126
  }
6863
7127
  let t6;
6864
- if ($[21] !== size || $[22] !== t32 || $[23] !== t4) {
7128
+ if ($[23] !== size || $[24] !== t32 || $[25] !== t4) {
6865
7129
  t6 = /* @__PURE__ */ jsxRuntime.jsx(EntityPreviewContainer, { onClick: t32, hover: t4, size, children: t5 });
6866
- $[21] = size;
6867
- $[22] = t32;
6868
- $[23] = t4;
6869
- $[24] = t6;
7130
+ $[23] = size;
7131
+ $[24] = t32;
7132
+ $[25] = t4;
7133
+ $[26] = t6;
6870
7134
  } else {
6871
- t6 = $[24];
7135
+ t6 = $[26];
6872
7136
  }
6873
7137
  return t6;
6874
7138
  }
6875
7139
  let t3;
6876
- if ($[25] !== collection || $[26] !== disabled || $[27] !== hover || $[28] !== includeEntityLink || $[29] !== includeId || $[30] !== onClick || $[31] !== previewProperties || $[32] !== size || $[33] !== usedEntity) {
7140
+ if ($[27] !== collection || $[28] !== disabled || $[29] !== hover || $[30] !== includeEntityLink || $[31] !== includeId || $[32] !== onClick || $[33] !== previewProperties || $[34] !== size || $[35] !== usedEntity) {
6877
7141
  t3 = /* @__PURE__ */ jsxRuntime.jsx(EntityPreview, { size, previewKeys: previewProperties, disabled, entity: usedEntity, collection, onClick, includeEntityLink, includeId, hover });
6878
- $[25] = collection;
6879
- $[26] = disabled;
6880
- $[27] = hover;
6881
- $[28] = includeEntityLink;
6882
- $[29] = includeId;
6883
- $[30] = onClick;
6884
- $[31] = previewProperties;
6885
- $[32] = size;
6886
- $[33] = usedEntity;
6887
- $[34] = t3;
7142
+ $[27] = collection;
7143
+ $[28] = disabled;
7144
+ $[29] = hover;
7145
+ $[30] = includeEntityLink;
7146
+ $[31] = includeId;
7147
+ $[32] = onClick;
7148
+ $[33] = previewProperties;
7149
+ $[34] = size;
7150
+ $[35] = usedEntity;
7151
+ $[36] = t3;
6888
7152
  } else {
6889
- t3 = $[34];
7153
+ t3 = $[36];
6890
7154
  }
6891
7155
  return t3;
6892
7156
  }
@@ -11183,126 +11447,6 @@
11183
11447
  function areEqual(prevProps, nextProps) {
11184
11448
  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;
11185
11449
  }
11186
- const LOCAL_STORAGE_PREFIX = "entity_cache::";
11187
- const entityCache = /* @__PURE__ */ new Map();
11188
- const isLocalStorageAvailable = typeof localStorage !== "undefined";
11189
- function customReplacer(key) {
11190
- const value = this[key];
11191
- if (value instanceof Date) {
11192
- return {
11193
- __type: "Date",
11194
- value: value.toISOString()
11195
- };
11196
- }
11197
- if (value instanceof EntityReference) {
11198
- return {
11199
- __type: "EntityReference",
11200
- id: value.id,
11201
- path: value.path,
11202
- databaseId: value.databaseId
11203
- };
11204
- }
11205
- if (value instanceof GeoPoint) {
11206
- return {
11207
- __type: "GeoPoint",
11208
- latitude: value.latitude,
11209
- longitude: value.longitude
11210
- };
11211
- }
11212
- if (value instanceof Vector) {
11213
- return {
11214
- __type: "Vector",
11215
- value: value.value
11216
- };
11217
- }
11218
- return value;
11219
- }
11220
- function customReviver(key, value) {
11221
- if (value && typeof value === "object" && "__type" in value) {
11222
- switch (value.__type) {
11223
- case "Date":
11224
- return new Date(value.value);
11225
- case "EntityReference":
11226
- return new EntityReference(value.id, value.path, value.databaseId);
11227
- case "GeoPoint":
11228
- return new GeoPoint(value.latitude, value.longitude);
11229
- case "Vector":
11230
- return new Vector(value.value);
11231
- default:
11232
- return value;
11233
- }
11234
- }
11235
- return value;
11236
- }
11237
- function saveEntityToCache(path, data) {
11238
- if (isLocalStorageAvailable) {
11239
- try {
11240
- const key = LOCAL_STORAGE_PREFIX + path;
11241
- const entityString = JSON.stringify(data, customReplacer);
11242
- console.debug("Saving entity to localStorage:", {
11243
- key,
11244
- entityString
11245
- });
11246
- localStorage.setItem(key, entityString);
11247
- } catch (error) {
11248
- console.error(`Failed to save entity for path "${path}" to localStorage:`, error);
11249
- }
11250
- }
11251
- }
11252
- function removeEntityFromMemoryCache(path) {
11253
- entityCache.delete(path);
11254
- }
11255
- function saveEntityToMemoryCache(path, data) {
11256
- entityCache.set(path, data);
11257
- }
11258
- function getEntityFromMemoryCache(path) {
11259
- return entityCache.get(path);
11260
- }
11261
- function getEntityFromCache(path) {
11262
- if (isLocalStorageAvailable) {
11263
- try {
11264
- const key = LOCAL_STORAGE_PREFIX + path;
11265
- const entityString = localStorage.getItem(key);
11266
- if (entityString) {
11267
- const entity = JSON.parse(entityString, customReviver);
11268
- return entity;
11269
- }
11270
- } catch (error) {
11271
- console.error(`Failed to load entity for path "${path}" from localStorage:`, error);
11272
- }
11273
- }
11274
- return void 0;
11275
- }
11276
- function removeEntityFromCache(path) {
11277
- if (isLocalStorageAvailable) {
11278
- try {
11279
- const key = LOCAL_STORAGE_PREFIX + path;
11280
- localStorage.removeItem(key);
11281
- } catch (error) {
11282
- console.error(`Failed to remove entity for path "${path}" from localStorage:`, error);
11283
- }
11284
- }
11285
- }
11286
- function flattenKeys(obj, prefix = "", result = []) {
11287
- if (isObject(obj) || Array.isArray(obj)) {
11288
- const plainObject = isPlainObject(obj);
11289
- if (!plainObject && prefix) {
11290
- result.push(prefix);
11291
- } else {
11292
- for (const key in obj) {
11293
- if (Object.prototype.hasOwnProperty.call(obj, key)) {
11294
- const newKey = prefix ? Array.isArray(obj) ? `${prefix}[${key}]` : `${prefix}.${key}` : key;
11295
- if (isObject(obj[key]) || Array.isArray(obj[key])) {
11296
- flattenKeys(obj[key], newKey, result);
11297
- } else {
11298
- result.push(newKey);
11299
- }
11300
- }
11301
- }
11302
- }
11303
- }
11304
- return result;
11305
- }
11306
11450
  function FieldHelperText(t0) {
11307
11451
  const $ = reactCompilerRuntime.c(10);
11308
11452
  const {
@@ -16797,6 +16941,7 @@
16797
16941
  entityId: entityIdProp,
16798
16942
  collection,
16799
16943
  path,
16944
+ pathSegments,
16800
16945
  values: valuesToBeSaved
16801
16946
  });
16802
16947
  }, false, 2e3);
@@ -16824,7 +16969,7 @@
16824
16969
  const [savingError, setSavingError] = React.useState();
16825
16970
  const autoSave = collection.formAutoSave && !collection.customId;
16826
16971
  const baseInitialValues = React.useMemo(() => getInitialEntityValues(authController, collection, path, status, entity, customizationController.propertyConfigs), [authController, collection, path, status, entity, customizationController.propertyConfigs]);
16827
- const localChangesDataRaw = React.useMemo(() => entityId ? getEntityFromCache(path + "/" + entityId) : getEntityFromCache(path + "#new"), [entityId, path]);
16972
+ const localChangesDataRaw = React.useMemo(() => entityId ? getEntityFromCache(entityCacheKey(path, entityId)) : getEntityFromCache(path + "#new"), [entityId, path]);
16828
16973
  const [localChangesCleared, setLocalChangesCleared] = React.useState(false);
16829
16974
  const localChangesBackup = getLocalChangesBackup(collection);
16830
16975
  const autoApplyLocalChanges = localChangesBackup === "auto_apply";
@@ -16886,7 +17031,7 @@
16886
17031
  onValuesModified?.(false, initialValues_0);
16887
17032
  },
16888
17033
  onValuesChangeDeferred: (values_0, controller) => {
16889
- const key = status === "new" || status === "copy" ? path + "#new" : path + "/" + entityId;
17034
+ const key = status === "new" || status === "copy" ? path + "#new" : entityCacheKey(path, entityId);
16890
17035
  if (controller.dirty && localChangesBackup !== false) {
16891
17036
  const touchedValues = removeEmptyContainers(extractTouchedValues(values_0, controller.touched));
16892
17037
  if (touchedValues && Object.keys(touchedValues).length > 0) {
@@ -16951,8 +17096,8 @@
16951
17096
  removeEntityFromMemoryCache(path + "#new");
16952
17097
  removeEntityFromCache(path + "#new");
16953
17098
  } else {
16954
- removeEntityFromMemoryCache(path + "/" + entityId);
16955
- removeEntityFromCache(path + "/" + entityId);
17099
+ removeEntityFromMemoryCache(entityCacheKey(path, entityId));
17100
+ removeEntityFromCache(entityCacheKey(path, entityId));
16956
17101
  }
16957
17102
  }
16958
17103
  const onSaveSuccess = (updatedEntity) => {
@@ -16970,6 +17115,7 @@
16970
17115
  entity: updatedEntity,
16971
17116
  status,
16972
17117
  path,
17118
+ pathSegments,
16973
17119
  entityId: updatedEntity.id,
16974
17120
  collection
16975
17121
  });
@@ -16988,10 +17134,12 @@
16988
17134
  previousValues,
16989
17135
  entityId: entityId_0,
16990
17136
  collection: collection_0,
16991
- path: path_0
17137
+ path: path_0,
17138
+ pathSegments: pathSegments_0
16992
17139
  }) => {
16993
17140
  return saveEntityWithCallbacks({
16994
17141
  path: path_0,
17142
+ pathSegments: pathSegments_0,
16995
17143
  entityId: entityId_0,
16996
17144
  values: values_2,
16997
17145
  previousValues,
@@ -17008,6 +17156,7 @@
17008
17156
  const onSaveEntityRequest = async ({
17009
17157
  collection: collection_1,
17010
17158
  path: path_1,
17159
+ pathSegments: pathSegments_1,
17011
17160
  entityId: entityId_1,
17012
17161
  values: values_3,
17013
17162
  previousValues: previousValues_0,
@@ -17020,6 +17169,7 @@
17020
17169
  return saveEntity({
17021
17170
  collection: collection_1,
17022
17171
  path: path_1,
17172
+ pathSegments: pathSegments_1,
17023
17173
  entityId: entityId_1,
17024
17174
  values: values_3,
17025
17175
  previousValues: previousValues_0
@@ -17032,6 +17182,7 @@
17032
17182
  return onSaveEntityRequest({
17033
17183
  collection: resolvedCollection,
17034
17184
  path,
17185
+ pathSegments,
17035
17186
  entityId,
17036
17187
  values: values_4,
17037
17188
  previousValues: entity?.values,
@@ -17076,12 +17227,13 @@
17076
17227
  const pluginBeforeTitle = [];
17077
17228
  const plugins = customizationController.plugins;
17078
17229
  const actionsDisabled = disabled || formex$1.isSubmitting || status === "existing" && !formex$1.dirty || Boolean(disabledProp);
17079
- const parentCollectionIds = navigationController.getParentCollectionIds(path);
17230
+ const parentCollectionIds = navigationController.getParentCollectionIds(path, pathSegments);
17080
17231
  if (plugins && collection) {
17081
17232
  const actionProps = {
17082
17233
  entityId,
17083
17234
  parentCollectionIds,
17084
17235
  path,
17236
+ pathSegments,
17085
17237
  status,
17086
17238
  collection,
17087
17239
  context,
@@ -17230,13 +17382,13 @@
17230
17382
  if (!resolvedCollection || !path) {
17231
17383
  throw Error("INTERNAL: Collection and path must be defined in form context");
17232
17384
  }
17233
- const dialogActions = /* @__PURE__ */ jsxRuntime.jsx(EntityFormActionsComponent, { collection: resolvedCollection, path, fullPath: path, fullIdPath, entity, layout: forceActionsAtTheBottom ? "bottom" : "side", savingError, formex: formex$1, disabled: actionsDisabled, status, pluginActions: pluginActions ?? [], openEntityMode, showDefaultActions, navigateBack, formContext });
17385
+ const dialogActions = /* @__PURE__ */ jsxRuntime.jsx(EntityFormActionsComponent, { collection: resolvedCollection, path, pathSegments, fullPath: path, fullIdPath, entity, layout: forceActionsAtTheBottom ? "bottom" : "side", savingError, formex: formex$1, disabled: actionsDisabled, status, pluginActions: pluginActions ?? [], openEntityMode, showDefaultActions, navigateBack, formContext });
17234
17386
  return /* @__PURE__ */ jsxRuntime.jsx(formex.Formex, { value: formex$1, children: /* @__PURE__ */ jsxRuntime.jsxs("form", { onSubmit: formex$1.handleSubmit, onReset: () => formex$1.resetForm({
17235
17387
  values: baseInitialValues
17236
17388
  }), noValidate: true, className: ui.cls("flex-1 flex flex-row w-full overflow-y-auto justify-center", className), children: [
17237
17389
  /* @__PURE__ */ jsxRuntime.jsx("div", { id: `form_${path}`, className: ui.cls("relative flex flex-row max-w-4xl lg:max-w-3xl xl:max-w-4xl 2xl:max-w-6xl w-full h-fit"), children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: ui.cls("flex flex-col w-full pt-12 pb-16 px-4 sm:px-8 md:px-10"), children: [
17238
17390
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-row gap-4 self-end sticky top-4 z-10", children: [
17239
- manualApplyLocalChanges && hasLocalChanges && /* @__PURE__ */ jsxRuntime.jsx(LocalChangesMenu, { cacheKey: status === "new" || status === "copy" ? path + "#new" : path + "/" + entityId, properties: resolvedCollection.properties, cachedData: localChangesDataRaw, formex: formex$1, onClearLocalChanges: () => setLocalChangesCleared(true) }),
17391
+ manualApplyLocalChanges && hasLocalChanges && /* @__PURE__ */ jsxRuntime.jsx(LocalChangesMenu, { cacheKey: status === "new" || status === "copy" ? path + "#new" : entityCacheKey(path, entityId), properties: resolvedCollection.properties, cachedData: localChangesDataRaw, formex: formex$1, onClearLocalChanges: () => setLocalChangesCleared(true) }),
17240
17392
  formex$1.dirty ? /* @__PURE__ */ jsxRuntime.jsx(ui.Tooltip, { title: "This form has been modified", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Chip, { size: "small", className: "py-1", colorScheme: "orangeDarker", children: /* @__PURE__ */ jsxRuntime.jsx(ui.EditIcon, { size: "smallest" }) }) }) : /* @__PURE__ */ jsxRuntime.jsx(ui.Tooltip, { title: "The current form is in sync with the database", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Chip, { size: "small", className: "py-1", children: /* @__PURE__ */ jsxRuntime.jsx(ui.CheckIcon, { size: "smallest" }) }) })
17241
17393
  ] }),
17242
17394
  formView
@@ -17327,7 +17479,7 @@
17327
17479
  const collapsedActions = actions.filter((a_0) => a_0.collapsed || a_0.collapsed === void 0);
17328
17480
  const uncollapsedActions = actions.filter((a_1) => a_1.collapsed === false);
17329
17481
  const enableLocalChangesBackup = collection ? getLocalChangesBackup(collection) : false;
17330
- const cachedData = enableLocalChangesBackup ? getEntityFromCache(fullPath + "/" + entity.id) : void 0;
17482
+ const cachedData = enableLocalChangesBackup ? getEntityFromCache(entityCacheKey(fullPath, entity.id)) : void 0;
17331
17483
  const hasDraft = (() => {
17332
17484
  if (!cachedData || typeof cachedData !== "object" || Object.keys(cachedData).length === 0) return false;
17333
17485
  const realChanges = getChanges(cachedData, entity?.values ?? {});
@@ -20093,8 +20245,8 @@
20093
20245
  const [popupCell, setPopupCell] = React.useState(void 0);
20094
20246
  const navigation = useNavigationController();
20095
20247
  const dataSource = useDataSource();
20096
- const resolvedPath = React.useMemo(() => navigation.resolveIdsFrom(fullPath), [fullPath, navigation.resolveIdsFrom]);
20097
- const resolvedPathSegments = pathSegments;
20248
+ const resolvedPath = React.useMemo(() => navigation.resolveIdsFrom(fullPath, pathSegments), [fullPath, pathSegments, navigation.resolveIdsFrom]);
20249
+ const resolvedPathSegments = React.useMemo(() => pathSegments ? navigation.resolveSegmentsFrom?.(pathSegments) ?? pathSegments : void 0, [pathSegments, navigation.resolveSegmentsFrom]);
20098
20250
  const forceFilter = forceFilterFromProps ?? forceFilterFromCollection;
20099
20251
  const paginationEnabled = collection.pagination === void 0 || Boolean(collection.pagination);
20100
20252
  const pageSize = typeof collection.pagination === "number" ? collection.pagination : DEFAULT_PAGE_SIZE$1;
@@ -20156,10 +20308,10 @@
20156
20308
  const [sortBy_0, setSortBy] = React.useState((updateUrl ? initialSortUrl : void 0) ?? initialSortInternal);
20157
20309
  const [searchString, setSearchString] = React.useState(updateUrl ? initialSearchUrl : void 0);
20158
20310
  useUpdateUrl(filterValues_0, sortBy_0, searchString, updateUrl);
20159
- const collectionScroll = scrollRestoration?.getCollectionScroll(fullPath, filterValues_0);
20160
- const initialItemCount = collectionScroll?.data.length ?? pageSize;
20311
+ const collectionScroll = scrollRestoration?.getCollectionScroll(resolvedPath, filterValues_0);
20312
+ const initialItemCount = collectionScroll?.data.length || pageSize;
20161
20313
  React.useEffect(() => {
20162
- if (scrollRestoration) {
20314
+ if (scrollRestoration && rawData.length > 0) {
20163
20315
  scrollRestoration.updateCollectionScroll({
20164
20316
  fullPath: resolvedPath,
20165
20317
  scrollOffset: collectionScroll?.scrollOffset ?? 0,
@@ -20202,6 +20354,7 @@
20202
20354
  entities = await Promise.all(entities.map((entity) => collection.callbacks.onFetch({
20203
20355
  collection,
20204
20356
  path: resolvedPath,
20357
+ pathSegments: resolvedPathSegments,
20205
20358
  entity,
20206
20359
  context
20207
20360
  })));
@@ -20358,10 +20511,11 @@
20358
20511
  };
20359
20512
  }
20360
20513
  function useTableSearchHelper(t0) {
20361
- const $ = reactCompilerRuntime.c(18);
20514
+ const $ = reactCompilerRuntime.c(19);
20362
20515
  const {
20363
20516
  collection,
20364
20517
  fullPath,
20518
+ pathSegments,
20365
20519
  parentCollectionIds,
20366
20520
  initialSearchString
20367
20521
  } = t0;
@@ -20373,11 +20527,12 @@
20373
20527
  const autoInitialisedRef = React.useRef(false);
20374
20528
  let onTextSearchClick;
20375
20529
  let textSearchEnabled;
20376
- if ($[0] !== collection || $[1] !== context || $[2] !== customizationController.plugins || $[3] !== dataSource || $[4] !== fullPath || $[5] !== parentCollectionIds) {
20530
+ if ($[0] !== collection || $[1] !== context || $[2] !== customizationController.plugins || $[3] !== dataSource || $[4] !== fullPath || $[5] !== parentCollectionIds || $[6] !== pathSegments) {
20377
20531
  textSearchEnabled = Boolean(collection.textSearchEnabled);
20378
20532
  const props = {
20379
20533
  context,
20380
20534
  path: fullPath,
20535
+ pathSegments,
20381
20536
  databaseId: collection.databaseId,
20382
20537
  collection,
20383
20538
  parentCollectionIds
@@ -20397,6 +20552,7 @@
20397
20552
  promises.push(p_1.collectionView.onTextSearchClick({
20398
20553
  context,
20399
20554
  path: fullPath,
20555
+ pathSegments,
20400
20556
  collection,
20401
20557
  parentCollectionIds
20402
20558
  }));
@@ -20428,15 +20584,16 @@
20428
20584
  $[3] = dataSource;
20429
20585
  $[4] = fullPath;
20430
20586
  $[5] = parentCollectionIds;
20431
- $[6] = onTextSearchClick;
20432
- $[7] = textSearchEnabled;
20587
+ $[6] = pathSegments;
20588
+ $[7] = onTextSearchClick;
20589
+ $[8] = textSearchEnabled;
20433
20590
  } else {
20434
- onTextSearchClick = $[6];
20435
- textSearchEnabled = $[7];
20591
+ onTextSearchClick = $[7];
20592
+ textSearchEnabled = $[8];
20436
20593
  }
20437
20594
  const shouldAutoInitialise = Boolean(initialSearchString) && textSearchEnabled && !textSearchInitialised && Boolean(onTextSearchClick);
20438
20595
  let t1;
20439
- if ($[8] !== onTextSearchClick || $[9] !== shouldAutoInitialise) {
20596
+ if ($[9] !== onTextSearchClick || $[10] !== shouldAutoInitialise) {
20440
20597
  t1 = () => {
20441
20598
  if (autoInitialisedRef.current || !shouldAutoInitialise) {
20442
20599
  return;
@@ -20444,36 +20601,36 @@
20444
20601
  autoInitialisedRef.current = true;
20445
20602
  onTextSearchClick?.();
20446
20603
  };
20447
- $[8] = onTextSearchClick;
20448
- $[9] = shouldAutoInitialise;
20449
- $[10] = t1;
20604
+ $[9] = onTextSearchClick;
20605
+ $[10] = shouldAutoInitialise;
20606
+ $[11] = t1;
20450
20607
  } else {
20451
- t1 = $[10];
20608
+ t1 = $[11];
20452
20609
  }
20453
20610
  let t2;
20454
- if ($[11] !== shouldAutoInitialise) {
20611
+ if ($[12] !== shouldAutoInitialise) {
20455
20612
  t2 = [shouldAutoInitialise];
20456
- $[11] = shouldAutoInitialise;
20457
- $[12] = t2;
20613
+ $[12] = shouldAutoInitialise;
20614
+ $[13] = t2;
20458
20615
  } else {
20459
- t2 = $[12];
20616
+ t2 = $[13];
20460
20617
  }
20461
20618
  React.useEffect(t1, t2);
20462
20619
  let t3;
20463
- if ($[13] !== onTextSearchClick || $[14] !== textSearchEnabled || $[15] !== textSearchInitialised || $[16] !== textSearchLoading) {
20620
+ if ($[14] !== onTextSearchClick || $[15] !== textSearchEnabled || $[16] !== textSearchInitialised || $[17] !== textSearchLoading) {
20464
20621
  t3 = {
20465
20622
  textSearchLoading,
20466
20623
  textSearchInitialised,
20467
20624
  onTextSearchClick,
20468
20625
  textSearchEnabled
20469
20626
  };
20470
- $[13] = onTextSearchClick;
20471
- $[14] = textSearchEnabled;
20472
- $[15] = textSearchInitialised;
20473
- $[16] = textSearchLoading;
20474
- $[17] = t3;
20627
+ $[14] = onTextSearchClick;
20628
+ $[15] = textSearchEnabled;
20629
+ $[16] = textSearchInitialised;
20630
+ $[17] = textSearchLoading;
20631
+ $[18] = t3;
20475
20632
  } else {
20476
- t3 = $[17];
20633
+ t3 = $[18];
20477
20634
  }
20478
20635
  return t3;
20479
20636
  }
@@ -20542,6 +20699,8 @@
20542
20699
  const performDelete = React.useCallback((entity_3) => deleteEntityWithCallbacks({
20543
20700
  dataSource,
20544
20701
  entity: entity_3,
20702
+ // The entity is the authority on where it lives; stated rather than left implicit.
20703
+ pathSegments: entity_3.pathSegments,
20545
20704
  collection: resolvedCollection,
20546
20705
  callbacks,
20547
20706
  onDeleteSuccess,
@@ -20643,6 +20802,7 @@
20643
20802
  entity,
20644
20803
  collection,
20645
20804
  fullPath,
20805
+ pathSegments,
20646
20806
  fullIdPath,
20647
20807
  context,
20648
20808
  highlightEntity,
@@ -20661,6 +20821,7 @@
20661
20821
  addRecentId(collection.id, entity.id);
20662
20822
  }
20663
20823
  const path = collection?.collectionGroup ? entity.path : fullPath ?? collection?.path ?? entity.path;
20824
+ const resolvedPathSegments = collection?.collectionGroup ? entity.pathSegments : pathSegments ?? entity.pathSegments;
20664
20825
  const newFullIdPath = collection?.collectionGroup ? collection.id : fullIdPath ?? collection?.id ?? entity.path;
20665
20826
  const defaultSelectedView = resolveDefaultSelectedView(collection ? collection.defaultSelectedView : void 0, {
20666
20827
  status: "existing",
@@ -20671,6 +20832,7 @@
20671
20832
  collection,
20672
20833
  entityId: entity.id,
20673
20834
  path,
20835
+ pathSegments: resolvedPathSegments,
20674
20836
  fullIdPath: newFullIdPath,
20675
20837
  sideEntityController: context.sideEntityController,
20676
20838
  onClose: () => unhighlightEntity?.(entity),
@@ -20692,6 +20854,8 @@
20692
20854
  collection,
20693
20855
  context,
20694
20856
  fullPath,
20857
+ pathSegments,
20858
+ fullIdPath,
20695
20859
  highlightEntity,
20696
20860
  unhighlightEntity,
20697
20861
  openEntityMode
@@ -20705,13 +20869,15 @@
20705
20869
  entityId: entity.id
20706
20870
  });
20707
20871
  const path = collection?.collectionGroup ? collection.path : fullPath ?? collection?.path ?? entity.path;
20708
- const fullIdPath = collection?.collectionGroup ? collection.id : fullPath ?? collection?.id ?? entity.path;
20872
+ const resolvedPathSegments = collection?.collectionGroup ? void 0 : pathSegments ?? entity.pathSegments;
20873
+ const newFullIdPath = collection?.collectionGroup ? collection.id : fullIdPath ?? collection?.id;
20709
20874
  navigateToEntity({
20710
20875
  openEntityMode,
20711
20876
  collection,
20712
20877
  entityId: entity.id,
20713
20878
  path,
20714
- fullIdPath,
20879
+ pathSegments: resolvedPathSegments,
20880
+ fullIdPath: newFullIdPath,
20715
20881
  copy: true,
20716
20882
  sideEntityController: context.sideEntityController,
20717
20883
  onClose: () => unhighlightEntity?.(entity),
@@ -20781,7 +20947,7 @@
20781
20947
  const navigation = useNavigationController();
20782
20948
  const analyticsController = useAnalyticsController();
20783
20949
  const customizationController = useCustomizationController();
20784
- const fullPath = navigation.resolveIdsFrom(pathInput);
20950
+ const fullPath = navigation.resolveIdsFrom(pathInput, pathSegments);
20785
20951
  const dataSource = useDataSource();
20786
20952
  const [entitiesDisplayedFirst, setEntitiesDisplayedFirst] = React.useState([]);
20787
20953
  const toggleEntitySelection = (entity) => {
@@ -20856,6 +21022,7 @@
20856
21022
  });
20857
21023
  sideEntityController.open({
20858
21024
  path: fullPath,
21025
+ pathSegments,
20859
21026
  collection,
20860
21027
  updateUrl: true,
20861
21028
  onUpdate: ({
@@ -20905,6 +21072,7 @@
20905
21072
  onTextSearchClick,
20906
21073
  textSearchEnabled
20907
21074
  } = useTableSearchHelper({
21075
+ pathSegments,
20908
21076
  collection,
20909
21077
  fullPath
20910
21078
  });
@@ -20916,7 +21084,7 @@
20916
21084
  }) : t("select_from", {
20917
21085
  name: collection.name
20918
21086
  })
20919
- ] }), defaultSize: collection.defaultSize, properties: resolvedCollection.properties, forceFilter, inlineEditing: false, selectionController, actions: /* @__PURE__ */ jsxRuntime.jsx(ReferenceDialogActions, { collection, path: fullPath, onNewClick, onClear }) }) }),
21087
+ ] }), defaultSize: collection.defaultSize, properties: resolvedCollection.properties, forceFilter, inlineEditing: false, selectionController, actions: /* @__PURE__ */ jsxRuntime.jsx(ReferenceDialogActions, { collection, path: fullPath, pathSegments, onNewClick, onClear }) }) }),
20920
21088
  /* @__PURE__ */ jsxRuntime.jsxs(ui.DialogActions, { translucent: false, children: [
20921
21089
  description && /* @__PURE__ */ jsxRuntime.jsx(ui.Typography, { variant: "body2", className: "flex-grow text-left", children: description }),
20922
21090
  /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { onClick: onDone, variant: "filled", children: t("done") })
@@ -20924,10 +21092,11 @@
20924
21092
  ] });
20925
21093
  }
20926
21094
  function ReferenceDialogActions(t0) {
20927
- const $ = reactCompilerRuntime.c(17);
21095
+ const $ = reactCompilerRuntime.c(18);
20928
21096
  const {
20929
21097
  collection,
20930
21098
  path,
21099
+ pathSegments,
20931
21100
  onClear,
20932
21101
  onNewClick
20933
21102
  } = t0;
@@ -20949,8 +21118,8 @@
20949
21118
  }
20950
21119
  const onClick = t1;
20951
21120
  let t2;
20952
- if ($[2] !== authController || $[3] !== collection || $[4] !== largeLayout || $[5] !== onClick || $[6] !== path || $[7] !== t) {
20953
- t2 = canCreateEntity(collection, authController, path, null) && onClick && (largeLayout ? /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { onClick, startIcon: /* @__PURE__ */ jsxRuntime.jsx(ui.AddIcon, {}), children: t("add_specific", {
21121
+ if ($[2] !== authController || $[3] !== collection || $[4] !== largeLayout || $[5] !== onClick || $[6] !== path || $[7] !== pathSegments || $[8] !== t) {
21122
+ t2 = canCreateEntity(collection, authController, path, null, pathSegments) && onClick && (largeLayout ? /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { onClick, startIcon: /* @__PURE__ */ jsxRuntime.jsx(ui.AddIcon, {}), children: t("add_specific", {
20954
21123
  name: collection.singularName ?? collection.name
20955
21124
  }) }) : /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { onClick, children: /* @__PURE__ */ jsxRuntime.jsx(ui.AddIcon, {}) }));
20956
21125
  $[2] = authController;
@@ -20958,40 +21127,41 @@
20958
21127
  $[4] = largeLayout;
20959
21128
  $[5] = onClick;
20960
21129
  $[6] = path;
20961
- $[7] = t;
20962
- $[8] = t2;
21130
+ $[7] = pathSegments;
21131
+ $[8] = t;
21132
+ $[9] = t2;
20963
21133
  } else {
20964
- t2 = $[8];
21134
+ t2 = $[9];
20965
21135
  }
20966
21136
  const addButton = t2;
20967
21137
  let t3;
20968
- if ($[9] !== t) {
21138
+ if ($[10] !== t) {
20969
21139
  t3 = t("clear");
20970
- $[9] = t;
20971
- $[10] = t3;
21140
+ $[10] = t;
21141
+ $[11] = t3;
20972
21142
  } else {
20973
- t3 = $[10];
21143
+ t3 = $[11];
20974
21144
  }
20975
21145
  let t4;
20976
- if ($[11] !== onClear || $[12] !== t3) {
21146
+ if ($[12] !== onClear || $[13] !== t3) {
20977
21147
  t4 = /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { onClick: onClear, variant: "text", children: t3 });
20978
- $[11] = onClear;
20979
- $[12] = t3;
20980
- $[13] = t4;
21148
+ $[12] = onClear;
21149
+ $[13] = t3;
21150
+ $[14] = t4;
20981
21151
  } else {
20982
- t4 = $[13];
21152
+ t4 = $[14];
20983
21153
  }
20984
21154
  let t5;
20985
- if ($[14] !== addButton || $[15] !== t4) {
21155
+ if ($[15] !== addButton || $[16] !== t4) {
20986
21156
  t5 = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
20987
21157
  t4,
20988
21158
  addButton
20989
21159
  ] });
20990
- $[14] = addButton;
20991
- $[15] = t4;
20992
- $[16] = t5;
21160
+ $[15] = addButton;
21161
+ $[16] = t4;
21162
+ $[17] = t5;
20993
21163
  } else {
20994
- t5 = $[16];
21164
+ t5 = $[17];
20995
21165
  }
20996
21166
  return t5;
20997
21167
  }
@@ -22907,7 +23077,7 @@
22907
23077
  return React.useContext(BreadcrumbContext);
22908
23078
  };
22909
23079
  function EntityCollectionViewActions(t0) {
22910
- const $ = reactCompilerRuntime.c(45);
23080
+ const $ = reactCompilerRuntime.c(48);
22911
23081
  const {
22912
23082
  collection,
22913
23083
  relativePath,
@@ -22916,6 +23086,7 @@
22916
23086
  onMultipleDeleteClick,
22917
23087
  selectionEnabled,
22918
23088
  path,
23089
+ pathSegments,
22919
23090
  selectionController,
22920
23091
  tableController,
22921
23092
  collectionEntitiesCount
@@ -22938,8 +23109,8 @@
22938
23109
  const largeLayout = useLargeLayout();
22939
23110
  const selectedEntities = selectionController.selectedEntities;
22940
23111
  let t2;
22941
- if ($[2] !== authController || $[3] !== collection || $[4] !== largeLayout || $[5] !== onNewClick || $[6] !== path || $[7] !== t) {
22942
- t2 = canCreateEntity(collection, authController, path, null) && onNewClick && (largeLayout ? /* @__PURE__ */ jsxRuntime.jsxs(ui.Button, { id: `add_entity_${path}`, onClick: onNewClick, startIcon: /* @__PURE__ */ jsxRuntime.jsx(ui.AddIcon, { size: "small" }), variant: "filled", color: "primary", children: [
23112
+ if ($[2] !== authController || $[3] !== collection || $[4] !== largeLayout || $[5] !== onNewClick || $[6] !== path || $[7] !== pathSegments || $[8] !== t) {
23113
+ t2 = canCreateEntity(collection, authController, path, null, pathSegments) && onNewClick && (largeLayout ? /* @__PURE__ */ jsxRuntime.jsxs(ui.Button, { id: `add_entity_${path}`, onClick: onNewClick, startIcon: /* @__PURE__ */ jsxRuntime.jsx(ui.AddIcon, { size: "small" }), variant: "filled", color: "primary", children: [
22943
23114
  t("add"),
22944
23115
  " ",
22945
23116
  collection.singularName ?? collection.name
@@ -22949,65 +23120,68 @@
22949
23120
  $[4] = largeLayout;
22950
23121
  $[5] = onNewClick;
22951
23122
  $[6] = path;
22952
- $[7] = t;
22953
- $[8] = t2;
23123
+ $[7] = pathSegments;
23124
+ $[8] = t;
23125
+ $[9] = t2;
22954
23126
  } else {
22955
- t2 = $[8];
23127
+ t2 = $[9];
22956
23128
  }
22957
23129
  const addButton = t2;
22958
23130
  let t3;
22959
- if ($[9] !== authController || $[10] !== collection || $[11] !== path) {
22960
- t3 = canDeleteEntity(collection, authController, path, null);
22961
- $[9] = authController;
22962
- $[10] = collection;
22963
- $[11] = path;
22964
- $[12] = t3;
23131
+ if ($[10] !== authController || $[11] !== collection || $[12] !== path || $[13] !== pathSegments) {
23132
+ t3 = canDeleteEntity(collection, authController, path, null, pathSegments);
23133
+ $[10] = authController;
23134
+ $[11] = collection;
23135
+ $[12] = path;
23136
+ $[13] = pathSegments;
23137
+ $[14] = t3;
22965
23138
  } else {
22966
- t3 = $[12];
23139
+ t3 = $[14];
22967
23140
  }
22968
23141
  const multipleDeleteEnabled = t3;
22969
23142
  let multipleDeleteButton;
22970
23143
  if (selectionEnabled) {
22971
23144
  let t42;
22972
- if ($[13] !== largeLayout || $[14] !== multipleDeleteEnabled || $[15] !== onMultipleDeleteClick || $[16] !== selectedEntities?.length) {
23145
+ if ($[15] !== largeLayout || $[16] !== multipleDeleteEnabled || $[17] !== onMultipleDeleteClick || $[18] !== selectedEntities?.length) {
22973
23146
  t42 = largeLayout ? /* @__PURE__ */ jsxRuntime.jsxs(ui.Button, { variant: "text", disabled: !selectedEntities?.length || !multipleDeleteEnabled, startIcon: /* @__PURE__ */ jsxRuntime.jsx(ui.DeleteIcon, { size: "small" }), onClick: onMultipleDeleteClick, color: "primary", className: "lg:w-20", children: [
22974
23147
  "(",
22975
23148
  selectedEntities?.length,
22976
23149
  ")"
22977
23150
  ] }) : /* @__PURE__ */ jsxRuntime.jsx(ui.IconButton, { size: "small", color: "primary", disabled: !selectedEntities?.length || !multipleDeleteEnabled, onClick: onMultipleDeleteClick, children: /* @__PURE__ */ jsxRuntime.jsx(ui.DeleteIcon, { size: "small" }) });
22978
- $[13] = largeLayout;
22979
- $[14] = multipleDeleteEnabled;
22980
- $[15] = onMultipleDeleteClick;
22981
- $[16] = selectedEntities?.length;
22982
- $[17] = t42;
23151
+ $[15] = largeLayout;
23152
+ $[16] = multipleDeleteEnabled;
23153
+ $[17] = onMultipleDeleteClick;
23154
+ $[18] = selectedEntities?.length;
23155
+ $[19] = t42;
22983
23156
  } else {
22984
- t42 = $[17];
23157
+ t42 = $[19];
22985
23158
  }
22986
23159
  const button = t42;
22987
23160
  let t52;
22988
- if ($[18] !== multipleDeleteEnabled || $[19] !== t) {
23161
+ if ($[20] !== multipleDeleteEnabled || $[21] !== t) {
22989
23162
  t52 = multipleDeleteEnabled ? t("delete_selected") : t("cannot_delete_selected");
22990
- $[18] = multipleDeleteEnabled;
22991
- $[19] = t;
22992
- $[20] = t52;
23163
+ $[20] = multipleDeleteEnabled;
23164
+ $[21] = t;
23165
+ $[22] = t52;
22993
23166
  } else {
22994
- t52 = $[20];
23167
+ t52 = $[22];
22995
23168
  }
22996
23169
  let t62;
22997
- if ($[21] !== button || $[22] !== t52) {
23170
+ if ($[23] !== button || $[24] !== t52) {
22998
23171
  t62 = /* @__PURE__ */ jsxRuntime.jsx(ui.Tooltip, { title: t52, children: button });
22999
- $[21] = button;
23000
- $[22] = t52;
23001
- $[23] = t62;
23172
+ $[23] = button;
23173
+ $[24] = t52;
23174
+ $[25] = t62;
23002
23175
  } else {
23003
- t62 = $[23];
23176
+ t62 = $[25];
23004
23177
  }
23005
23178
  multipleDeleteButton = t62;
23006
23179
  }
23007
23180
  let t4;
23008
- if ($[24] !== collection || $[25] !== collectionEntitiesCount || $[26] !== context || $[27] !== parentCollectionIds || $[28] !== path || $[29] !== relativePath || $[30] !== selectionController || $[31] !== tableController) {
23181
+ if ($[26] !== collection || $[27] !== collectionEntitiesCount || $[28] !== context || $[29] !== parentCollectionIds || $[30] !== path || $[31] !== pathSegments || $[32] !== relativePath || $[33] !== selectionController || $[34] !== tableController) {
23009
23182
  t4 = {
23010
23183
  path,
23184
+ pathSegments,
23011
23185
  relativePath,
23012
23186
  parentCollectionIds,
23013
23187
  collection,
@@ -23016,28 +23190,29 @@
23016
23190
  tableController,
23017
23191
  collectionEntitiesCount
23018
23192
  };
23019
- $[24] = collection;
23020
- $[25] = collectionEntitiesCount;
23021
- $[26] = context;
23022
- $[27] = parentCollectionIds;
23023
- $[28] = path;
23024
- $[29] = relativePath;
23025
- $[30] = selectionController;
23026
- $[31] = tableController;
23027
- $[32] = t4;
23193
+ $[26] = collection;
23194
+ $[27] = collectionEntitiesCount;
23195
+ $[28] = context;
23196
+ $[29] = parentCollectionIds;
23197
+ $[30] = path;
23198
+ $[31] = pathSegments;
23199
+ $[32] = relativePath;
23200
+ $[33] = selectionController;
23201
+ $[34] = tableController;
23202
+ $[35] = t4;
23028
23203
  } else {
23029
- t4 = $[32];
23204
+ t4 = $[35];
23030
23205
  }
23031
23206
  const actionProps = t4;
23032
23207
  let actions;
23033
- if ($[33] !== actionProps || $[34] !== collection.Actions || $[35] !== plugins) {
23208
+ if ($[36] !== actionProps || $[37] !== collection.Actions || $[38] !== plugins) {
23034
23209
  let t52;
23035
- if ($[37] !== actionProps) {
23210
+ if ($[40] !== actionProps) {
23036
23211
  t52 = (Action, i) => /* @__PURE__ */ jsxRuntime.jsx(ErrorBoundary, { children: /* @__PURE__ */ jsxRuntime.jsx(Action, { ...actionProps }) }, `actions_${i}`);
23037
- $[37] = actionProps;
23038
- $[38] = t52;
23212
+ $[40] = actionProps;
23213
+ $[41] = t52;
23039
23214
  } else {
23040
- t52 = $[38];
23215
+ t52 = $[41];
23041
23216
  }
23042
23217
  actions = toArray(collection.Actions).map(t52);
23043
23218
  if (plugins) {
@@ -23047,34 +23222,34 @@
23047
23222
  }
23048
23223
  });
23049
23224
  }
23050
- $[33] = actionProps;
23051
- $[34] = collection.Actions;
23052
- $[35] = plugins;
23053
- $[36] = actions;
23225
+ $[36] = actionProps;
23226
+ $[37] = collection.Actions;
23227
+ $[38] = plugins;
23228
+ $[39] = actions;
23054
23229
  } else {
23055
- actions = $[36];
23230
+ actions = $[39];
23056
23231
  }
23057
23232
  let t5;
23058
- if ($[39] !== actions) {
23233
+ if ($[42] !== actions) {
23059
23234
  t5 = /* @__PURE__ */ jsxRuntime.jsx(ErrorBoundary, { children: actions });
23060
- $[39] = actions;
23061
- $[40] = t5;
23235
+ $[42] = actions;
23236
+ $[43] = t5;
23062
23237
  } else {
23063
- t5 = $[40];
23238
+ t5 = $[43];
23064
23239
  }
23065
23240
  let t6;
23066
- if ($[41] !== addButton || $[42] !== multipleDeleteButton || $[43] !== t5) {
23241
+ if ($[44] !== addButton || $[45] !== multipleDeleteButton || $[46] !== t5) {
23067
23242
  t6 = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
23068
23243
  t5,
23069
23244
  multipleDeleteButton,
23070
23245
  addButton
23071
23246
  ] });
23072
- $[41] = addButton;
23073
- $[42] = multipleDeleteButton;
23074
- $[43] = t5;
23075
- $[44] = t6;
23247
+ $[44] = addButton;
23248
+ $[45] = multipleDeleteButton;
23249
+ $[46] = t5;
23250
+ $[47] = t6;
23076
23251
  } else {
23077
- t6 = $[44];
23252
+ t6 = $[47];
23078
23253
  }
23079
23254
  return t6;
23080
23255
  }
@@ -24420,8 +24595,8 @@
24420
24595
  const context = useFireCMSContext();
24421
24596
  const dataSource = useDataSource();
24422
24597
  const navigation = useNavigationController();
24423
- const resolvedPath = React.useMemo(() => navigation.resolveIdsFrom(fullPath), [fullPath, navigation.resolveIdsFrom]);
24424
- const resolvedPathSegments = pathSegments;
24598
+ const resolvedPath = React.useMemo(() => navigation.resolveIdsFrom(fullPath, pathSegments), [fullPath, pathSegments, navigation.resolveIdsFrom]);
24599
+ const resolvedPathSegments = React.useMemo(() => pathSegments ? navigation.resolveSegmentsFrom?.(pathSegments) ?? pathSegments : void 0, [pathSegments, navigation.resolveSegmentsFrom]);
24425
24600
  const dataSourceRef = React.useRef(dataSource);
24426
24601
  const collectionRef = React.useRef(collection);
24427
24602
  const contextRef = React.useRef(context);
@@ -24507,6 +24682,7 @@
24507
24682
  processed = await Promise.all(processed.map((entity) => currentCollection.callbacks.onFetch({
24508
24683
  collection: currentCollection,
24509
24684
  path: currentResolvedPath,
24685
+ pathSegments: currentPathSegments,
24510
24686
  entity,
24511
24687
  context: currentContext
24512
24688
  })));
@@ -25015,6 +25191,7 @@
25015
25191
  let completed = 0;
25016
25192
  currentDataSource.countEntities({
25017
25193
  path: fullPath,
25194
+ pathSegments,
25018
25195
  collection: currentCollection
25019
25196
  }).then((count) => {
25020
25197
  totalCount = count;
@@ -25025,6 +25202,7 @@
25025
25202
  }).catch((e) => console.warn("Failed to get total count:", e));
25026
25203
  currentDataSource.countEntities({
25027
25204
  path: fullPath,
25205
+ pathSegments,
25028
25206
  collection: currentCollection,
25029
25207
  filter: {
25030
25208
  [orderProperty]: ["!=", null]
@@ -25132,6 +25310,8 @@
25132
25310
  }
25133
25311
  const saveProps = {
25134
25312
  path: entity_2.path,
25313
+ // Paired with `entity.path`: the segments the entity was loaded with.
25314
+ pathSegments: entity_2.pathSegments,
25135
25315
  entityId: entity_2.id,
25136
25316
  values: updatedValues,
25137
25317
  previousValues: entity_2.values,
@@ -25169,6 +25349,7 @@
25169
25349
  console.log("Fetching all documents from collection...");
25170
25350
  const allDocs = await dataSource.fetchCollection({
25171
25351
  path: fullPath,
25352
+ pathSegments,
25172
25353
  collection,
25173
25354
  limit: 1e4
25174
25355
  // Fetch all
@@ -25187,6 +25368,8 @@
25187
25368
  }, orderProperty, index);
25188
25369
  const saveProps_0 = {
25189
25370
  path: entity_4.path,
25371
+ // Paired with `entity.path`: the segments the entity was loaded with.
25372
+ pathSegments: entity_4.pathSegments,
25190
25373
  entityId: entity_4.id,
25191
25374
  values: updatedValues_0,
25192
25375
  previousValues: entity_4.values,
@@ -25272,6 +25455,7 @@
25272
25455
  });
25273
25456
  sideEntityController.open({
25274
25457
  path: fullPath,
25458
+ pathSegments,
25275
25459
  collection,
25276
25460
  entityId: void 0,
25277
25461
  updateUrl: true,
@@ -25969,12 +26153,13 @@
25969
26153
  ] });
25970
26154
  }
25971
26155
  function EntityCollectionViewStartActions(t0) {
25972
- const $ = reactCompilerRuntime.c(37);
26156
+ const $ = reactCompilerRuntime.c(38);
25973
26157
  const {
25974
26158
  collection,
25975
26159
  relativePath,
25976
26160
  parentCollectionIds,
25977
26161
  path,
26162
+ pathSegments,
25978
26163
  selectionController,
25979
26164
  tableController,
25980
26165
  collectionEntitiesCount,
@@ -26009,9 +26194,10 @@
26009
26194
  }
26010
26195
  const activeFilterCount = t2;
26011
26196
  let t3;
26012
- if ($[5] !== collection || $[6] !== collectionEntitiesCount || $[7] !== context || $[8] !== parentCollectionIds || $[9] !== path || $[10] !== relativePath || $[11] !== selectionController || $[12] !== tableController) {
26197
+ if ($[5] !== collection || $[6] !== collectionEntitiesCount || $[7] !== context || $[8] !== parentCollectionIds || $[9] !== path || $[10] !== pathSegments || $[11] !== relativePath || $[12] !== selectionController || $[13] !== tableController) {
26013
26198
  t3 = {
26014
26199
  path,
26200
+ pathSegments,
26015
26201
  relativePath,
26016
26202
  parentCollectionIds,
26017
26203
  collection,
@@ -26025,44 +26211,45 @@
26025
26211
  $[7] = context;
26026
26212
  $[8] = parentCollectionIds;
26027
26213
  $[9] = path;
26028
- $[10] = relativePath;
26029
- $[11] = selectionController;
26030
- $[12] = tableController;
26031
- $[13] = t3;
26214
+ $[10] = pathSegments;
26215
+ $[11] = relativePath;
26216
+ $[12] = selectionController;
26217
+ $[13] = tableController;
26218
+ $[14] = t3;
26032
26219
  } else {
26033
- t3 = $[13];
26220
+ t3 = $[14];
26034
26221
  }
26035
26222
  const actionProps = t3;
26036
26223
  const hasAnyAllowedFilters = !tableController.allowedFilters || tableController.allowedFilters.length > 0;
26037
26224
  let t4;
26038
- if ($[14] !== activeFilterCount || $[15] !== hasAnyAllowedFilters || $[16] !== largeLayout || $[17] !== resolvedProperties || $[18] !== t || $[19] !== tableController.setFilterValues) {
26225
+ if ($[15] !== activeFilterCount || $[16] !== hasAnyAllowedFilters || $[17] !== largeLayout || $[18] !== resolvedProperties || $[19] !== t || $[20] !== tableController.setFilterValues) {
26039
26226
  t4 = resolvedProperties && tableController.setFilterValues && hasAnyAllowedFilters && /* @__PURE__ */ jsxRuntime.jsx(ui.Tooltip, { title: t("filters"), children: /* @__PURE__ */ jsxRuntime.jsx(ui.Badge, { color: "primary", invisible: activeFilterCount === 0, children: largeLayout ? /* @__PURE__ */ jsxRuntime.jsxs(ui.Button, { variant: "text", size: "small", onClick: () => setFiltersDialogOpen(true), startIcon: /* @__PURE__ */ jsxRuntime.jsx(ui.FilterListIcon, { size: "small" }), className: ui.cls(activeFilterCount > 0 && "text-primary"), children: [
26040
26227
  t("filters"),
26041
26228
  activeFilterCount > 0 ? ` (${activeFilterCount})` : ""
26042
26229
  ] }) : /* @__PURE__ */ jsxRuntime.jsx(ui.IconButton, { size: "small", onClick: () => setFiltersDialogOpen(true), className: ui.cls(activeFilterCount > 0 && "text-primary"), children: /* @__PURE__ */ jsxRuntime.jsx(ui.FilterListIcon, { size: "small" }) }) }) }, "filters_tooltip");
26043
- $[14] = activeFilterCount;
26044
- $[15] = hasAnyAllowedFilters;
26045
- $[16] = largeLayout;
26046
- $[17] = resolvedProperties;
26047
- $[18] = t;
26048
- $[19] = tableController.setFilterValues;
26049
- $[20] = t4;
26230
+ $[15] = activeFilterCount;
26231
+ $[16] = hasAnyAllowedFilters;
26232
+ $[17] = largeLayout;
26233
+ $[18] = resolvedProperties;
26234
+ $[19] = t;
26235
+ $[20] = tableController.setFilterValues;
26236
+ $[21] = t4;
26050
26237
  } else {
26051
- t4 = $[20];
26238
+ t4 = $[21];
26052
26239
  }
26053
26240
  const filtersButton = t4;
26054
26241
  const t5 = !collection.forceFilter;
26055
26242
  let t6;
26056
- if ($[21] !== t5 || $[22] !== tableController) {
26243
+ if ($[22] !== t5 || $[23] !== tableController) {
26057
26244
  t6 = /* @__PURE__ */ jsxRuntime.jsx(ClearFilterSortButton, { tableController, enabled: t5 }, "clear_filter");
26058
- $[21] = t5;
26059
- $[22] = tableController;
26060
- $[23] = t6;
26245
+ $[22] = t5;
26246
+ $[23] = tableController;
26247
+ $[24] = t6;
26061
26248
  } else {
26062
- t6 = $[23];
26249
+ t6 = $[24];
26063
26250
  }
26064
26251
  let actions;
26065
- if ($[24] !== actionProps || $[25] !== filtersButton || $[26] !== plugins || $[27] !== t6) {
26252
+ if ($[25] !== actionProps || $[26] !== filtersButton || $[27] !== plugins || $[28] !== t6) {
26066
26253
  actions = [filtersButton, t6];
26067
26254
  if (plugins) {
26068
26255
  plugins.forEach((plugin, i) => {
@@ -26071,36 +26258,36 @@
26071
26258
  }
26072
26259
  });
26073
26260
  }
26074
- $[24] = actionProps;
26075
- $[25] = filtersButton;
26076
- $[26] = plugins;
26077
- $[27] = t6;
26078
- $[28] = actions;
26261
+ $[25] = actionProps;
26262
+ $[26] = filtersButton;
26263
+ $[27] = plugins;
26264
+ $[28] = t6;
26265
+ $[29] = actions;
26079
26266
  } else {
26080
- actions = $[28];
26267
+ actions = $[29];
26081
26268
  }
26082
26269
  let t7;
26083
- if ($[29] !== collection.forceFilter || $[30] !== filtersDialogOpen || $[31] !== resolvedProperties || $[32] !== tableController) {
26270
+ if ($[30] !== collection.forceFilter || $[31] !== filtersDialogOpen || $[32] !== resolvedProperties || $[33] !== tableController) {
26084
26271
  t7 = resolvedProperties && tableController.setFilterValues && /* @__PURE__ */ jsxRuntime.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) });
26085
- $[29] = collection.forceFilter;
26086
- $[30] = filtersDialogOpen;
26087
- $[31] = resolvedProperties;
26088
- $[32] = tableController;
26089
- $[33] = t7;
26272
+ $[30] = collection.forceFilter;
26273
+ $[31] = filtersDialogOpen;
26274
+ $[32] = resolvedProperties;
26275
+ $[33] = tableController;
26276
+ $[34] = t7;
26090
26277
  } else {
26091
- t7 = $[33];
26278
+ t7 = $[34];
26092
26279
  }
26093
26280
  let t8;
26094
- if ($[34] !== actions || $[35] !== t7) {
26281
+ if ($[35] !== actions || $[36] !== t7) {
26095
26282
  t8 = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
26096
26283
  actions,
26097
26284
  t7
26098
26285
  ] });
26099
- $[34] = actions;
26100
- $[35] = t7;
26101
- $[36] = t8;
26286
+ $[35] = actions;
26287
+ $[36] = t7;
26288
+ $[37] = t8;
26102
26289
  } else {
26103
- t8 = $[36];
26290
+ t8 = $[37];
26104
26291
  }
26105
26292
  return t8;
26106
26293
  }
@@ -26178,7 +26365,7 @@
26178
26365
  React.useEffect(() => {
26179
26366
  collectionRef.current = collection;
26180
26367
  }, [collection]);
26181
- const canCreateEntities = canCreateEntity(collection, authController, fullPath, null);
26368
+ const canCreateEntities = canCreateEntity(collection, authController, fullPath, null, pathSegments);
26182
26369
  const [highlightedEntity, setHighlightedEntity] = React.useState(void 0);
26183
26370
  const [deleteEntityClicked, setDeleteEntityClicked] = React.useState(void 0);
26184
26371
  const [lastDeleteTimestamp, setLastDeleteTimestamp] = React.useState(0);
@@ -26196,7 +26383,7 @@
26196
26383
  }, [highlightedEntity]);
26197
26384
  const checkInlineEditing = React.useCallback((entity) => {
26198
26385
  const collection_0 = collectionRef.current;
26199
- if (!canEditEntity(collection_0, authController, fullPath, entity ?? null)) {
26386
+ if (!canEditEntity(collection_0, authController, fullPath, entity ?? null, pathSegments)) {
26200
26387
  return false;
26201
26388
  }
26202
26389
  return collection_0.inlineEditing === void 0 || collection_0.inlineEditing;
@@ -26286,10 +26473,12 @@
26286
26473
  if (collection_1) {
26287
26474
  addRecentId(collection_1.id, clickedEntity.id);
26288
26475
  }
26289
- const path = collection_1?.collectionGroup ? clickedEntity.path : fullPath ?? clickedEntity.path;
26476
+ const isCollectionGroup = Boolean(collection_1?.collectionGroup);
26477
+ const path = isCollectionGroup ? clickedEntity.path : fullPath ?? clickedEntity.path;
26290
26478
  navigateToEntity({
26291
26479
  navigation,
26292
26480
  path,
26481
+ pathSegments: isCollectionGroup ? clickedEntity.pathSegments : pathSegments ?? clickedEntity.pathSegments,
26293
26482
  fullIdPath,
26294
26483
  sideEntityController,
26295
26484
  openEntityMode,
@@ -26377,13 +26566,13 @@
26377
26566
  });
26378
26567
  }
26379
26568
  }, [setViewMode, userConfigPersistence, onCollectionModifiedForUser, fullPath, analyticsController, viewMode]);
26380
- const createEnabled = canCreateEntity(collection, authController, fullPath, null);
26569
+ const createEnabled = canCreateEntity(collection, authController, fullPath, null, pathSegments);
26381
26570
  const uniqueFieldValidator = React.useCallback(({
26382
26571
  name,
26383
26572
  value,
26384
26573
  property,
26385
26574
  entityId
26386
- }) => dataSource.checkUniqueField(fullPath, name, value, entityId, collection), [fullPath]);
26575
+ }) => dataSource.checkUniqueField(fullPath, name, value, entityId, collection, pathSegments), [fullPath, pathSegments]);
26387
26576
  const onValueChange = ({
26388
26577
  value: value_0,
26389
26578
  propertyKey,
@@ -26396,6 +26585,8 @@
26396
26585
  }, propertyKey, value_0);
26397
26586
  const saveProps = {
26398
26587
  path: entity_1.path ?? fullPath,
26588
+ // Paired with the `path` above: the row's segments describe the row's path.
26589
+ pathSegments: entity_1.path ? entity_1.pathSegments : pathSegments,
26399
26590
  entityId: entity_1.id,
26400
26591
  values: updatedValues,
26401
26592
  previousValues: entity_1.values,
@@ -26423,7 +26614,7 @@
26423
26614
  }
26424
26615
  });
26425
26616
  };
26426
- const resolvedFullPath = navigation.resolveIdsFrom(fullPath);
26617
+ const resolvedFullPath = navigation.resolveIdsFrom(fullPath, pathSegments);
26427
26618
  const resolvedCollection = React.useMemo(() => resolveCollection({
26428
26619
  collection,
26429
26620
  path: fullPath,
@@ -26552,9 +26743,9 @@
26552
26743
  Builder: ({
26553
26744
  entity: entity_4
26554
26745
  }) => {
26555
- const collectionsWithPath = navigation.getParentReferencesFromPath(entity_4.path);
26746
+ const collectionsWithPath = navigation.getParentReferencesFromPath(entity_4.path, entity_4.pathSegments);
26556
26747
  return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-2 w-full", children: collectionsWithPath.map((reference) => {
26557
- return /* @__PURE__ */ jsxRuntime.jsx(ReferencePreview, { reference, size: "small" }, reference.path + "/" + reference.id);
26748
+ return /* @__PURE__ */ jsxRuntime.jsx(ReferencePreview, { reference, size: "small" }, entityCacheKey(reference.path, reference.id));
26558
26749
  }) });
26559
26750
  }
26560
26751
  }] : [];
@@ -26568,7 +26759,7 @@
26568
26759
  entity: entity_5,
26569
26760
  customEntityActions
26570
26761
  }) => {
26571
- const deleteEnabled = entity_5 ? canDeleteEntity(collection, authController, fullPath, entity_5) : true;
26762
+ const deleteEnabled = entity_5 ? canDeleteEntity(collection, authController, fullPath, entity_5, entity_5.pathSegments ?? pathSegments) : true;
26572
26763
  const actions = [{
26573
26764
  ...editEntityAction,
26574
26765
  name: t("edit")
@@ -26633,6 +26824,7 @@
26633
26824
  onTextSearchClick,
26634
26825
  textSearchEnabled
26635
26826
  } = useTableSearchHelper({
26827
+ pathSegments,
26636
26828
  collection,
26637
26829
  fullPath: resolvedFullPath,
26638
26830
  parentCollectionIds,
@@ -26656,7 +26848,7 @@
26656
26848
  }, [tableController.dataLoadingError, customizationController.plugins, fullPath, collection, parentCollectionIds]);
26657
26849
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: ui.cls("overflow-hidden h-full w-full rounded-md flex flex-col", className), ref: containerRef, children: [
26658
26850
  countFetcher,
26659
- /* @__PURE__ */ jsxRuntime.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__ */ jsxRuntime.jsx(EntityCollectionViewStartActions, { parentCollectionIds: parentCollectionIds ?? [], collection, tableController, path: fullPath, relativePath: collection.path, selectionController: usedSelectionController, collectionEntitiesCount: docsCount, resolvedProperties: resolvedCollection.properties }), actions: /* @__PURE__ */ jsxRuntime.jsx(EntityCollectionViewActions, { parentCollectionIds: parentCollectionIds ?? [], collection, tableController, onMultipleDeleteClick, onNewClick, path: fullPath, relativePath: collection.path, selectionController: usedSelectionController, selectionEnabled, collectionEntitiesCount: docsCount }) }),
26851
+ /* @__PURE__ */ jsxRuntime.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__ */ jsxRuntime.jsx(EntityCollectionViewStartActions, { parentCollectionIds: parentCollectionIds ?? [], collection, tableController, path: fullPath, pathSegments, relativePath: collection.path, selectionController: usedSelectionController, collectionEntitiesCount: docsCount, resolvedProperties: resolvedCollection.properties }), actions: /* @__PURE__ */ jsxRuntime.jsx(EntityCollectionViewActions, { parentCollectionIds: parentCollectionIds ?? [], collection, tableController, onMultipleDeleteClick, onNewClick, path: fullPath, pathSegments, relativePath: collection.path, selectionController: usedSelectionController, selectionEnabled, collectionEntitiesCount: docsCount }) }),
26660
26852
  tableController.dataLoadingError ? pluginErrorView ?? /* @__PURE__ */ jsxRuntime.jsx(CollectionDataErrorBanner, { error: tableController.dataLoadingError }) : viewMode === "kanban" && enabledViews.includes("kanban") ? /* @__PURE__ */ jsxRuntime.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__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center justify-center", children: [
26661
26853
  /* @__PURE__ */ jsxRuntime.jsx(ui.Typography, { variant: "subtitle2", children: t("so_empty") }),
26662
26854
  /* @__PURE__ */ jsxRuntime.jsxs(ui.Button, { onClick: onNewClick, className: "mt-4", children: [
@@ -26675,7 +26867,7 @@
26675
26867
  /* @__PURE__ */ jsxRuntime.jsx(ui.AddIcon, {}),
26676
26868
  t("create_your_first_entry")
26677
26869
  ] })
26678
- ] }) : /* @__PURE__ */ jsxRuntime.jsx(ui.Typography, { variant: "label", children: t("no_results_filter_sort") }), hoverRow, inlineEditing: checkInlineEditing(), AdditionalHeaderWidget: buildAdditionalHeaderWidget, AddColumnComponent: addColumnComponentInternal, getIdColumnWidth, additionalIDHeaderWidget: /* @__PURE__ */ jsxRuntime.jsx(EntityIdHeaderWidget, { path: fullPath, fullIdPath: fullIdPath ?? fullPath, collection }), openEntityMode, onColumnsOrderChange: (newColumns) => {
26870
+ ] }) : /* @__PURE__ */ jsxRuntime.jsx(ui.Typography, { variant: "label", children: t("no_results_filter_sort") }), hoverRow, inlineEditing: checkInlineEditing(), AdditionalHeaderWidget: buildAdditionalHeaderWidget, AddColumnComponent: addColumnComponentInternal, getIdColumnWidth, additionalIDHeaderWidget: /* @__PURE__ */ jsxRuntime.jsx(EntityIdHeaderWidget, { path: fullPath, pathSegments, fullIdPath: fullIdPath ?? fullPath, collection }), openEntityMode, onColumnsOrderChange: (newColumns) => {
26679
26871
  const seenKeys = /* @__PURE__ */ new Set();
26680
26872
  const newPropertiesOrder = newColumns.filter((col) => !col.frozen && getPropertyInPath(collection.properties, col.key)).map((col_0) => col_0.key).filter((key_1) => {
26681
26873
  if (seenKeys.has(key_1)) return false;
@@ -26714,8 +26906,8 @@
26714
26906
  const [error, setError] = React.useState(void 0);
26715
26907
  const sortByProperty = sortBy ? sortBy[0] : void 0;
26716
26908
  const currentSort = sortBy ? sortBy[1] : void 0;
26717
- const resolvedPath = React.useMemo(() => navigation.resolveIdsFrom(fullPath), [fullPath, navigation.resolveIdsFrom]);
26718
- const resolvedPathSegments = pathSegments;
26909
+ const resolvedPath = React.useMemo(() => navigation.resolveIdsFrom(fullPath, pathSegments), [fullPath, pathSegments, navigation.resolveIdsFrom]);
26910
+ const resolvedPathSegments = React.useMemo(() => pathSegments ? navigation.resolveSegmentsFrom?.(pathSegments) ?? pathSegments : void 0, [pathSegments, navigation.resolveSegmentsFrom]);
26719
26911
  React.useEffect(() => {
26720
26912
  if (dataSource.countEntities) dataSource.countEntities({
26721
26913
  path: resolvedPath,
@@ -26755,10 +26947,11 @@
26755
26947
  };
26756
26948
  }
26757
26949
  function EntityIdHeaderWidget(t0) {
26758
- const $ = reactCompilerRuntime.c(48);
26950
+ const $ = reactCompilerRuntime.c(50);
26759
26951
  const {
26760
26952
  collection,
26761
26953
  path,
26954
+ pathSegments,
26762
26955
  fullIdPath
26763
26956
  } = t0;
26764
26957
  const navigation = useNavigationController();
@@ -26799,7 +26992,7 @@
26799
26992
  t4 = $[6];
26800
26993
  }
26801
26994
  let t5;
26802
- if ($[7] !== collection || $[8] !== fullIdPath || $[9] !== navigation || $[10] !== openEntityMode || $[11] !== path || $[12] !== searchString || $[13] !== sideEntityController) {
26995
+ if ($[7] !== collection || $[8] !== fullIdPath || $[9] !== navigation || $[10] !== openEntityMode || $[11] !== path || $[12] !== pathSegments || $[13] !== searchString || $[14] !== sideEntityController) {
26803
26996
  t5 = (e) => {
26804
26997
  e.preventDefault();
26805
26998
  if (!searchString) {
@@ -26813,6 +27006,7 @@
26813
27006
  collection,
26814
27007
  entityId,
26815
27008
  path,
27009
+ pathSegments,
26816
27010
  fullIdPath,
26817
27011
  sideEntityController,
26818
27012
  navigation
@@ -26823,130 +27017,133 @@
26823
27017
  $[9] = navigation;
26824
27018
  $[10] = openEntityMode;
26825
27019
  $[11] = path;
26826
- $[12] = searchString;
26827
- $[13] = sideEntityController;
26828
- $[14] = t5;
27020
+ $[12] = pathSegments;
27021
+ $[13] = searchString;
27022
+ $[14] = sideEntityController;
27023
+ $[15] = t5;
26829
27024
  } else {
26830
- t5 = $[14];
27025
+ t5 = $[15];
26831
27026
  }
26832
27027
  let t6;
26833
- if ($[15] !== t) {
27028
+ if ($[16] !== t) {
26834
27029
  t6 = t("find_entity_by_id");
26835
- $[15] = t;
26836
- $[16] = t6;
27030
+ $[16] = t;
27031
+ $[17] = t6;
26837
27032
  } else {
26838
- t6 = $[16];
27033
+ t6 = $[17];
26839
27034
  }
26840
27035
  let t7;
26841
- if ($[17] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
27036
+ if ($[18] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
26842
27037
  t7 = (e_0) => {
26843
27038
  setSearchString(e_0.target.value);
26844
27039
  };
26845
- $[17] = t7;
27040
+ $[18] = t7;
26846
27041
  } else {
26847
- t7 = $[17];
27042
+ t7 = $[18];
26848
27043
  }
26849
27044
  let t8;
26850
- if ($[18] !== openPopup || $[19] !== searchString || $[20] !== t6) {
27045
+ if ($[19] !== openPopup || $[20] !== searchString || $[21] !== t6) {
26851
27046
  t8 = /* @__PURE__ */ jsxRuntime.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 " + ui.focusedDisabled });
26852
- $[18] = openPopup;
26853
- $[19] = searchString;
26854
- $[20] = t6;
26855
- $[21] = t8;
27047
+ $[19] = openPopup;
27048
+ $[20] = searchString;
27049
+ $[21] = t6;
27050
+ $[22] = t8;
26856
27051
  } else {
26857
- t8 = $[21];
27052
+ t8 = $[22];
26858
27053
  }
26859
27054
  const t9 = !searchString.trim();
26860
27055
  let t10;
26861
- if ($[22] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
27056
+ if ($[23] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
26862
27057
  t10 = /* @__PURE__ */ jsxRuntime.jsx(ui.KeyboardTabIcon, {});
26863
- $[22] = t10;
27058
+ $[23] = t10;
26864
27059
  } else {
26865
- t10 = $[22];
27060
+ t10 = $[23];
26866
27061
  }
26867
27062
  let t11;
26868
- if ($[23] !== t9) {
27063
+ if ($[24] !== t9) {
26869
27064
  t11 = /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "text", disabled: t9, type: "submit", children: t10 });
26870
- $[23] = t9;
26871
- $[24] = t11;
27065
+ $[24] = t9;
27066
+ $[25] = t11;
26872
27067
  } else {
26873
- t11 = $[24];
27068
+ t11 = $[25];
26874
27069
  }
26875
27070
  let t12;
26876
- if ($[25] !== t11 || $[26] !== t8) {
27071
+ if ($[26] !== t11 || $[27] !== t8) {
26877
27072
  t12 = /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex p-2 w-full gap-2", children: [
26878
27073
  t8,
26879
27074
  t11
26880
27075
  ] });
26881
- $[25] = t11;
26882
- $[26] = t8;
26883
- $[27] = t12;
27076
+ $[26] = t11;
27077
+ $[27] = t8;
27078
+ $[28] = t12;
26884
27079
  } else {
26885
- t12 = $[27];
27080
+ t12 = $[28];
26886
27081
  }
26887
27082
  let t13;
26888
- if ($[28] !== t12 || $[29] !== t5) {
27083
+ if ($[29] !== t12 || $[30] !== t5) {
26889
27084
  t13 = /* @__PURE__ */ jsxRuntime.jsx("form", { noValidate: true, onSubmit: t5, className: "w-96 max-w-full", children: t12 });
26890
- $[28] = t12;
26891
- $[29] = t5;
26892
- $[30] = t13;
27085
+ $[29] = t12;
27086
+ $[30] = t5;
27087
+ $[31] = t13;
26893
27088
  } else {
26894
- t13 = $[30];
27089
+ t13 = $[31];
26895
27090
  }
26896
27091
  let t14;
26897
- if ($[31] !== collection || $[32] !== fullIdPath || $[33] !== navigation || $[34] !== openEntityMode || $[35] !== path || $[36] !== recentIds || $[37] !== sideEntityController) {
26898
- t14 = recentIds && recentIds.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-2 p-2", children: recentIds.map((id) => /* @__PURE__ */ jsxRuntime.jsx(ReferencePreview, { reference: new EntityReference(id, path), hover: true, onClick: () => {
27092
+ if ($[32] !== collection || $[33] !== fullIdPath || $[34] !== navigation || $[35] !== openEntityMode || $[36] !== path || $[37] !== pathSegments || $[38] !== recentIds || $[39] !== sideEntityController) {
27093
+ t14 = recentIds && recentIds.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-2 p-2", children: recentIds.map((id) => /* @__PURE__ */ jsxRuntime.jsx(ReferencePreview, { reference: new EntityReference(id, path, void 0, pathSegments), hover: true, onClick: () => {
26899
27094
  setOpenPopup(false);
26900
27095
  navigateToEntity({
26901
27096
  openEntityMode,
26902
27097
  collection,
26903
27098
  entityId: id,
26904
27099
  path,
27100
+ pathSegments,
26905
27101
  fullIdPath,
26906
27102
  sideEntityController,
26907
27103
  navigation
26908
27104
  });
26909
27105
  }, includeEntityLink: false, size: "small" }, id)) });
26910
- $[31] = collection;
26911
- $[32] = fullIdPath;
26912
- $[33] = navigation;
26913
- $[34] = openEntityMode;
26914
- $[35] = path;
26915
- $[36] = recentIds;
26916
- $[37] = sideEntityController;
26917
- $[38] = t14;
27106
+ $[32] = collection;
27107
+ $[33] = fullIdPath;
27108
+ $[34] = navigation;
27109
+ $[35] = openEntityMode;
27110
+ $[36] = path;
27111
+ $[37] = pathSegments;
27112
+ $[38] = recentIds;
27113
+ $[39] = sideEntityController;
27114
+ $[40] = t14;
26918
27115
  } else {
26919
- t14 = $[38];
27116
+ t14 = $[40];
26920
27117
  }
26921
27118
  let t15;
26922
- if ($[39] !== t13 || $[40] !== t14) {
27119
+ if ($[41] !== t13 || $[42] !== t14) {
26923
27120
  t15 = /* @__PURE__ */ jsxRuntime.jsxs("div", { className: t4, children: [
26924
27121
  t13,
26925
27122
  t14
26926
27123
  ] });
26927
- $[39] = t13;
26928
- $[40] = t14;
26929
- $[41] = t15;
27124
+ $[41] = t13;
27125
+ $[42] = t14;
27126
+ $[43] = t15;
26930
27127
  } else {
26931
- t15 = $[41];
27128
+ t15 = $[43];
26932
27129
  }
26933
27130
  let t16;
26934
- if ($[42] !== openPopup || $[43] !== t15) {
27131
+ if ($[44] !== openPopup || $[45] !== t15) {
26935
27132
  t16 = /* @__PURE__ */ jsxRuntime.jsx(ui.Popover, { open: openPopup, onOpenChange: setOpenPopup, sideOffset: 0, align: "start", alignOffset: -117, trigger: t3, children: t15 });
26936
- $[42] = openPopup;
26937
- $[43] = t15;
26938
- $[44] = t16;
27133
+ $[44] = openPopup;
27134
+ $[45] = t15;
27135
+ $[46] = t16;
26939
27136
  } else {
26940
- t16 = $[44];
27137
+ t16 = $[46];
26941
27138
  }
26942
27139
  let t17;
26943
- if ($[45] !== t16 || $[46] !== t2) {
27140
+ if ($[47] !== t16 || $[48] !== t2) {
26944
27141
  t17 = /* @__PURE__ */ jsxRuntime.jsx(ui.Tooltip, { title: t2, asChild: false, children: t16 });
26945
- $[45] = t16;
26946
- $[46] = t2;
26947
- $[47] = t17;
27142
+ $[47] = t16;
27143
+ $[48] = t2;
27144
+ $[49] = t17;
26948
27145
  } else {
26949
- t17 = $[47];
27146
+ t17 = $[49];
26950
27147
  }
26951
27148
  return t17;
26952
27149
  }
@@ -28514,8 +28711,12 @@
28514
28711
  path,
28515
28712
  collections = [],
28516
28713
  currentFullPath,
28517
- currentPathSegments = []
28714
+ currentPathSegments = [],
28715
+ pathSegments
28518
28716
  } = props;
28717
+ if (pathSegments) {
28718
+ return getParentReferencesFromPathSegments(pathSegments, collections);
28719
+ }
28519
28720
  const subpaths = removeInitialAndTrailingSlashes(path).split("/");
28520
28721
  const subpathCombinations = getCollectionPathsCombinations(subpaths);
28521
28722
  const result = [];
@@ -28552,6 +28753,9 @@
28552
28753
  }
28553
28754
  return result;
28554
28755
  }
28756
+ function getParentReferencesFromPathSegments(pathSegments, collections) {
28757
+ return walkPathSegments(pathSegments, collections).steps.filter((step) => step.entityId !== void 0).map((step) => new EntityReference(step.entityId, step.collectionPath, void 0, step.collectionSegments));
28758
+ }
28555
28759
  const DEFAULT_BASE_PATH = "/";
28556
28760
  const DEFAULT_COLLECTION_PATH = "/c";
28557
28761
  const NAVIGATION_ADMIN_GROUP_NAME = "Admin";
@@ -28756,10 +28960,10 @@
28756
28960
  React.useEffect(() => {
28757
28961
  refreshNavigation();
28758
28962
  }, [refreshNavigation]);
28759
- const getCollection = React.useCallback((idOrPath, includeUserOverride = false) => {
28963
+ const getCollection = React.useCallback((idOrPath, includeUserOverride = false, pathSegments) => {
28760
28964
  const collections_0 = collectionsRef.current;
28761
28965
  if (!collections_0) return void 0;
28762
- const baseCollection = getCollectionByPathOrId(removeInitialAndTrailingSlashes(idOrPath), collections_0);
28966
+ const baseCollection = getCollectionByPathOrId(removeInitialAndTrailingSlashes(idOrPath), collections_0, pathSegments);
28763
28967
  const userOverride = includeUserOverride ? userConfigPersistence?.getCollectionConfig(idOrPath) : void 0;
28764
28968
  let overriddenCollection = baseCollection;
28765
28969
  if (baseCollection && userOverride) {
@@ -28794,16 +28998,16 @@
28794
28998
  if (!collection_0) return void 0;
28795
28999
  return collection_0;
28796
29000
  }, []);
28797
- const getCollectionFromPaths = React.useCallback((pathSegments) => {
29001
+ const getCollectionFromPaths = React.useCallback((pathSegments_0) => {
28798
29002
  const collections_2 = collectionsRef.current;
28799
29003
  if (collections_2 === void 0) throw Error("getCollectionFromPaths: Collections have not been initialised yet");
28800
29004
  let currentCollections = [...collections_2 ?? []];
28801
- for (let i = 0; i < pathSegments.length; i++) {
28802
- const pathSegment = pathSegments[i];
29005
+ for (let i = 0; i < pathSegments_0.length; i++) {
29006
+ const pathSegment = pathSegments_0[i];
28803
29007
  const collection_1 = currentCollections.find((c_0) => c_0.id === pathSegment || c_0.path === pathSegment);
28804
29008
  if (!collection_1) return void 0;
28805
29009
  currentCollections = collection_1.subcollections;
28806
- if (i === pathSegments.length - 1) return collection_1;
29010
+ if (i === pathSegments_0.length - 1) return collection_1;
28807
29011
  }
28808
29012
  return void 0;
28809
29013
  }, []);
@@ -28828,33 +29032,37 @@
28828
29032
  if (cleanPath_0.startsWith(fullCollectionPath)) return cleanPath_0.replace(fullCollectionPath, "");
28829
29033
  throw Error("Expected path starting with " + fullCollectionPath);
28830
29034
  }, [fullCollectionPath]);
28831
- const resolveIdsFrom = React.useCallback((path_3) => {
29035
+ const resolveIdsFrom = React.useCallback((path_3, pathSegments_1) => {
28832
29036
  const collections_4 = collectionsRef.current ?? [];
28833
- return resolveCollectionPathIds(path_3, collections_4);
29037
+ return resolveCollectionPathIds(path_3, collections_4, pathSegments_1);
28834
29038
  }, []);
28835
- const getAllParentReferencesForPath = React.useCallback((path_4) => {
29039
+ const resolveSegmentsFrom = React.useCallback((pathSegments_2) => {
28836
29040
  const collections_5 = collectionsRef.current ?? [];
29041
+ return resolveCollectionPathSegments(pathSegments_2, collections_5);
29042
+ }, []);
29043
+ const getAllParentReferencesForPath = React.useCallback((path_4, pathSegments_3) => {
29044
+ const collections_6 = collectionsRef.current ?? [];
28837
29045
  return getParentReferencesFromPath({
28838
29046
  path: path_4,
28839
- collections: collections_5
29047
+ pathSegments: pathSegments_3,
29048
+ collections: collections_6
28840
29049
  });
28841
29050
  }, []);
28842
- const getParentCollectionIds = React.useCallback((path_5) => {
28843
- const strings = path_5.split("/");
28844
- const oddPathSegments = strings.filter((_, i_1) => i_1 % 2 === 0);
29051
+ const getParentCollectionIds = React.useCallback((path_5, pathSegments_4) => {
29052
+ const oddPathSegments = pathSegments_4 ? collectionSegmentsFrom(pathSegments_4) : fullPathToCollectionSegments(path_5);
28845
29053
  oddPathSegments.pop();
28846
29054
  const result_0 = [];
28847
- for (let i_2 = 1; i_2 <= oddPathSegments.length; i_2++) {
28848
- result_0.push(oddPathSegments.slice(0, i_2));
29055
+ for (let i_1 = 1; i_1 <= oddPathSegments.length; i_1++) {
29056
+ result_0.push(oddPathSegments.slice(0, i_1));
28849
29057
  }
28850
29058
  return result_0.map((r) => getCollectionFromPaths(r)?.id).filter(Boolean);
28851
29059
  }, [getAllParentReferencesForPath]);
28852
29060
  const convertIdsToPaths = React.useCallback((ids_0) => {
28853
- const collections_6 = collectionsRef.current;
28854
- let currentCollections_1 = collections_6;
29061
+ const collections_7 = collectionsRef.current;
29062
+ let currentCollections_1 = collections_7;
28855
29063
  const paths = [];
28856
- for (let i_3 = 0; i_3 < ids_0.length; i_3++) {
28857
- const id_1 = ids_0[i_3];
29064
+ for (let i_2 = 0; i_2 < ids_0.length; i_2++) {
29065
+ const id_1 = ids_0[i_2];
28858
29066
  const collection_3 = currentCollections_1.find((c_2) => c_2.id === id_1);
28859
29067
  if (!collection_3) throw Error(`Collection with id ${id_1} not found`);
28860
29068
  paths.push(collection_3.path);
@@ -28880,6 +29088,7 @@
28880
29088
  urlPathToDataPath,
28881
29089
  buildUrlCollectionPath,
28882
29090
  resolveIdsFrom,
29091
+ resolveSegmentsFrom,
28883
29092
  topLevelNavigation,
28884
29093
  refreshNavigation,
28885
29094
  getParentReferencesFromPath: getAllParentReferencesForPath,
@@ -29637,6 +29846,7 @@
29637
29846
  if (params.status !== "existing") {
29638
29847
  sideEntityController.replace({
29639
29848
  path: params.path,
29849
+ pathSegments: params.pathSegments ?? pathSegments,
29640
29850
  entityId: params.entityId,
29641
29851
  fullIdPath: props.fullIdPath,
29642
29852
  selectedTab: params.selectedTab,
@@ -29650,9 +29860,9 @@
29650
29860
  }
29651
29861
  };
29652
29862
  const parentCollectionIds = React.useMemo(() => {
29653
- return navigationController.getParentCollectionIds(path);
29863
+ return navigationController.getParentCollectionIds(path, pathSegments);
29654
29864
  }, [navigationController, path]);
29655
- const collection = props.collection ?? navigationController.getCollection(fullIdPath ?? path);
29865
+ const collection = props.collection ?? navigationController.getCollection(fullIdPath ?? path, false, pathSegments);
29656
29866
  React.useEffect(() => {
29657
29867
  function beforeunload(e) {
29658
29868
  if (blocked && collection) {
@@ -29680,7 +29890,7 @@
29680
29890
  }) => /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
29681
29891
  /* @__PURE__ */ jsxRuntime.jsx(ui.IconButton, { className: "self-center", size: "smallest", onClick: onClose, children: /* @__PURE__ */ jsxRuntime.jsx(ui.CloseIcon, { size: "smallest" }) }),
29682
29892
  allowFullScreen && /* @__PURE__ */ jsxRuntime.jsx(ui.IconButton, { className: "self-center", size: "smallest", onClick: () => {
29683
- const key = status === "new" || status === "copy" ? path + "#new" : path + "/" + entityId;
29893
+ const key = status === "new" || status === "copy" ? path + "#new" : entityCacheKey(path, entityId);
29684
29894
  saveEntityToMemoryCache(key, values);
29685
29895
  if (entityId) navigate(location.pathname + location.search);
29686
29896
  else navigate(location.pathname + location.search + "#new");
@@ -29692,6 +29902,7 @@
29692
29902
  }) => {
29693
29903
  sideEntityController.replace({
29694
29904
  path,
29905
+ pathSegments,
29695
29906
  entityId: entityId_0,
29696
29907
  fullIdPath: props.fullIdPath,
29697
29908
  selectedTab,
@@ -29807,6 +30018,7 @@
29807
30018
  function EntityEditViewFormActions({
29808
30019
  collection,
29809
30020
  path,
30021
+ pathSegments,
29810
30022
  entity,
29811
30023
  layout,
29812
30024
  savingError,
@@ -29829,8 +30041,8 @@
29829
30041
  } = useTranslation();
29830
30042
  const entityActions = React.useMemo(() => {
29831
30043
  const customEntityActions = (collection.entityActions ?? []).map((action) => resolveEntityAction(action, customizationController.entityActions)).filter(Boolean);
29832
- const createEnabled = canCreateEntity(collection, authController, path, null);
29833
- const deleteEnabled = entity ? canDeleteEntity(collection, authController, path, entity) : false;
30044
+ const createEnabled = canCreateEntity(collection, authController, path, null, pathSegments);
30045
+ const deleteEnabled = entity ? canDeleteEntity(collection, authController, path, entity, entity.pathSegments ?? pathSegments) : false;
29834
30046
  const actions = [];
29835
30047
  if (createEnabled) actions.push(copyEntityAction);
29836
30048
  if (deleteEnabled) actions.push(deleteEntityAction);
@@ -30186,7 +30398,7 @@
30186
30398
  databaseId: props.databaseId,
30187
30399
  useCache: false
30188
30400
  });
30189
- const initialDirtyValues = entityId ? getEntityFromMemoryCache(props.path + "/" + entityId) : getEntityFromMemoryCache(props.path + "#new");
30401
+ const initialDirtyValues = entityId ? getEntityFromMemoryCache(entityCacheKey(props.path, entityId)) : getEntityFromMemoryCache(props.path + "#new");
30190
30402
  const authController = useAuthController();
30191
30403
  const initialStatus = props.copy ? "copy" : entityId ? "existing" : "new";
30192
30404
  const [status, setStatus] = React.useState(initialStatus);
@@ -30194,7 +30406,7 @@
30194
30406
  if (status === "new" || status === "copy") {
30195
30407
  return true;
30196
30408
  } else {
30197
- return entity ? canEditEntity(props.collection, authController, props.path, entity ?? null) : void 0;
30409
+ return entity ? canEditEntity(props.collection, authController, props.path, entity ?? null, props.pathSegments) : void 0;
30198
30410
  }
30199
30411
  }, [authController, entity, status]);
30200
30412
  if (dataLoading && !initialDirtyValues || (!entity || canEdit === void 0) && (status === "existing" || status === "copy")) {
@@ -30244,6 +30456,7 @@
30244
30456
  entityId,
30245
30457
  parentCollectionIds,
30246
30458
  path,
30459
+ pathSegments,
30247
30460
  status,
30248
30461
  collection,
30249
30462
  context,
@@ -30342,7 +30555,7 @@
30342
30555
  const subcollectionId = subcollection.id ?? subcollection.path;
30343
30556
  const newFullPath = usedEntity ? `${path}/${usedEntity?.id}/${removeInitialAndTrailingSlashes(subcollection.path)}` : void 0;
30344
30557
  const newFullIdPath = fullIdPath && usedEntity ? `${fullIdPath}/${encodeEntityId(usedEntity.id)}/${removeInitialAndTrailingSlashes(subcollectionId)}` : void 0;
30345
- const newPathSegments = usedEntity && pathSegments ? [...pathSegments, usedEntity.id, ...removeInitialAndTrailingSlashes(subcollection.path).split("/")] : void 0;
30558
+ const newPathSegments = buildSubcollectionPathSegments(pathSegments, usedEntity?.id, subcollection.path);
30346
30559
  if (selectedTab !== subcollectionId) return null;
30347
30560
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative flex-1 h-full overflow-auto w-full", role: "tabpanel", children: [
30348
30561
  globalLoading && /* @__PURE__ */ jsxRuntime.jsx(CircularProgressCenter, {}),
@@ -30636,19 +30849,21 @@
30636
30849
  return sidePanel ? [sidePanel] : [];
30637
30850
  }
30638
30851
  const propsToSidePanel = (props, buildUrlCollectionPath, resolveIdsFrom, smallLayout, customizationController, authController, locationSearch) => {
30639
- const collectionPath = removeInitialAndTrailingSlashes(props.path);
30640
- const urlPath = props.entityId ? buildUrlCollectionPath(`${collectionPath}/${encodeEntityId(props.entityId)}${props.selectedTab ? "/" + props.selectedTab : ""}${locationSearch}#${SIDE_URL_HASH}`) : buildUrlCollectionPath(`${collectionPath}${locationSearch}#${NEW_URL_HASH}`);
30852
+ const urlChain = removeInitialAndTrailingSlashes(props.fullIdPath ?? props.path);
30853
+ const urlPath = props.entityId ? buildUrlCollectionPath(`${urlChain}/${encodeEntityId(props.entityId)}${props.selectedTab ? "/" + props.selectedTab : ""}${locationSearch}#${SIDE_URL_HASH}`) : buildUrlCollectionPath(`${urlChain}${locationSearch}#${NEW_URL_HASH}`);
30641
30854
  const resolvedPanelProps = {
30642
30855
  ...props,
30643
30856
  formProps: props.formProps
30644
30857
  };
30645
30858
  const entityViewWidth = getEntityViewWidth(props, smallLayout, customizationController, authController);
30646
30859
  return {
30647
- key: `${props.path}/${props.entityId}`,
30860
+ // Built from the escaped chain so that two different chains which happen to flatten
30861
+ // to the same raw string are still two different panels.
30862
+ key: `${urlChain}/${props.entityId ? encodeEntityId(props.entityId) : ""}`,
30648
30863
  component: void 0,
30649
30864
  // Lazy render in SideDialogs for better performance
30650
30865
  urlPath,
30651
- parentUrlPath: buildUrlCollectionPath(collectionPath),
30866
+ parentUrlPath: buildUrlCollectionPath(urlChain),
30652
30867
  width: entityViewWidth,
30653
30868
  onClose: props.onClose,
30654
30869
  additional: resolvedPanelProps
@@ -30917,7 +31132,7 @@
30917
31132
  onUpdate,
30918
31133
  onError
30919
31134
  }) => {
30920
- const collection_0 = collectionProp ?? navigationController.getCollection(path_0);
31135
+ const collection_0 = collectionProp ?? navigationController.getCollection(path_0, false, pathSegments_0);
30921
31136
  const usedDelegate_0 = collection_0?.overrides?.dataSourceDelegate ?? delegate;
30922
31137
  if (!usedDelegate_0.listenCollection) throw Error("useBuildDataSource delegate not initialised");
30923
31138
  return usedDelegate_0.listenCollection({
@@ -31003,7 +31218,7 @@
31003
31218
  collection: collectionProp_0,
31004
31219
  status
31005
31220
  }) => {
31006
- const collection_3 = collectionProp_0 ?? navigationController.getCollection(path_3);
31221
+ const collection_3 = collectionProp_0 ?? navigationController.getCollection(path_3, false, pathSegments_3);
31007
31222
  const usedDelegate_3 = collection_3?.overrides?.dataSourceDelegate ?? delegate;
31008
31223
  const resolvedCollection = collection_3 ? resolveCollection({
31009
31224
  collection: collection_3,
@@ -31060,8 +31275,11 @@
31060
31275
  status
31061
31276
  }).then((res) => {
31062
31277
  return {
31063
- id: res.id,
31064
- path: res.path,
31278
+ ...res,
31279
+ // A delegate that predates `pathSegments` returns none; the segments we
31280
+ // just saved with describe exactly this entity's collection, so they are
31281
+ // the authoritative answer rather than a guess.
31282
+ pathSegments: res.pathSegments ?? pathSegments_3,
31065
31283
  values: usedDelegate_3.delegateToCMSModel(finalValues)
31066
31284
  };
31067
31285
  });
@@ -31103,6 +31321,8 @@
31103
31321
  const usedDelegate_6 = collection_6?.overrides?.dataSourceDelegate ?? delegate;
31104
31322
  return usedDelegate_6.generateEntityId(path_5, collection_6, pathSegments_6);
31105
31323
  }, [delegate.generateEntityId]),
31324
+ // Typed with the declared props rather than an inline duplicate: the duplicate is
31325
+ // free to drift from the interface, and a field it forgets is dropped in silence.
31106
31326
  countEntities: delegate.countEntities ? async ({
31107
31327
  path: path_6,
31108
31328
  pathSegments: pathSegments_7,
@@ -32629,7 +32849,7 @@
32629
32849
  let collection;
32630
32850
  collection = navigation.getCollectionById(navigationEntries[0].id);
32631
32851
  if (!collection) {
32632
- collection = navigation.getCollection(navigationEntries[0].path);
32852
+ collection = navigation.getCollection(navigationEntries[0].path, false, navigationEntries[0].pathSegments);
32633
32853
  }
32634
32854
  if (!collection) {
32635
32855
  t16 = null;
@@ -32740,7 +32960,7 @@
32740
32960
  const firstEntry = navigationEntries[0];
32741
32961
  collection_0 = navigation.getCollectionById(firstEntry.id);
32742
32962
  if (!collection_0) {
32743
- collection_0 = navigation.getCollection(firstEntry.path);
32963
+ collection_0 = navigation.getCollection(firstEntry.path, false, firstEntry.pathSegments);
32744
32964
  }
32745
32965
  if (!collection_0) {
32746
32966
  t16 = null;
@@ -32913,9 +33133,10 @@
32913
33133
  }
32914
33134
  const collection = isNew ? lastCollectionEntry.collection : lastEntityEntry.parentCollection;
32915
33135
  const fullIdPath = isNew ? lastCollectionEntry.fullPath : parentCollectionEntry?.fullPath ?? lastEntityEntry.fullPath;
32916
- const collectionPath = navigation.resolveIdsFrom(isNew ? lastCollectionEntry.path : lastEntityEntry.path);
33136
+ const pathSegments = isNew ? lastCollectionEntry.pathSegments : lastEntityEntry.pathSegments;
33137
+ const collectionPath = navigation.resolveIdsFrom(isNew ? lastCollectionEntry.path : lastEntityEntry.path, pathSegments);
32917
33138
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
32918
- /* @__PURE__ */ jsxRuntime.jsx(React.Suspense, { fallback: null, children: /* @__PURE__ */ jsxRuntime.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) => {
33139
+ /* @__PURE__ */ jsxRuntime.jsx(React.Suspense, { fallback: null, children: /* @__PURE__ */ jsxRuntime.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) => {
32919
33140
  const newEntityId = params.entityId;
32920
33141
  if (!newEntityId) return;
32921
33142
  navigate(buildEntityUrl(newEntityId, params.selectedTab), {
@@ -39007,12 +39228,27 @@
39007
39228
  translations,
39008
39229
  children
39009
39230
  }) {
39231
+ const parentI18n = React.useContext(reactI18next.I18nContext)?.i18n;
39232
+ const parentInstance = parentI18n?.hasResourceBundle?.("en", FIRECMS_NS) ? parentI18n : void 0;
39010
39233
  const i18nRef = React.useRef(null);
39011
39234
  const [ready, setReady] = React.useState(false);
39012
39235
  if (!i18nRef.current) {
39013
39236
  const instance = i18next.createInstance();
39014
39237
  const resources = buildResources(translations);
39015
- let initialLocale = locale;
39238
+ if (parentInstance) {
39239
+ const inherited = parentInstance.services?.resourceStore?.data ?? {};
39240
+ for (const [lang, namespaces] of Object.entries(inherited)) {
39241
+ const bundle = namespaces?.[FIRECMS_NS];
39242
+ if (!bundle) continue;
39243
+ resources[lang] = {
39244
+ [FIRECMS_NS]: {
39245
+ ...bundle,
39246
+ ...translations?.[lang] ?? {}
39247
+ }
39248
+ };
39249
+ }
39250
+ }
39251
+ let initialLocale = parentInstance?.language ?? locale;
39016
39252
  if (typeof window !== "undefined") {
39017
39253
  const stored = localStorage.getItem(FIRECMS_LOCALE_STORAGE_KEY);
39018
39254
  if (stored) initialLocale = stored;
@@ -39037,6 +39273,17 @@
39037
39273
  });
39038
39274
  i18nRef.current = instance;
39039
39275
  }
39276
+ React.useEffect(() => {
39277
+ if (!parentInstance || !i18nRef.current) return;
39278
+ const instance_0 = i18nRef.current;
39279
+ const follow = (lng_0) => {
39280
+ if (instance_0.language !== lng_0) instance_0.changeLanguage(lng_0);
39281
+ };
39282
+ parentInstance.on("languageChanged", follow);
39283
+ return () => {
39284
+ parentInstance.off("languageChanged", follow);
39285
+ };
39286
+ }, [parentInstance]);
39040
39287
  React.useEffect(() => {
39041
39288
  if (i18nRef.current && i18nRef.current.language !== locale) {
39042
39289
  const hasUserPreference = typeof window !== "undefined" && Boolean(localStorage.getItem(FIRECMS_LOCALE_STORAGE_KEY));
@@ -39048,11 +39295,11 @@
39048
39295
  React.useEffect(() => {
39049
39296
  if (!i18nRef.current) return;
39050
39297
  const resources_0 = buildResources(translations);
39051
- for (const [lang, bundle] of Object.entries(resources_0)) {
39298
+ for (const [lang_0, bundle_0] of Object.entries(resources_0)) {
39052
39299
  i18nRef.current.addResourceBundle(
39053
- lang,
39300
+ lang_0,
39054
39301
  FIRECMS_NS,
39055
- bundle[FIRECMS_NS],
39302
+ bundle_0[FIRECMS_NS],
39056
39303
  true,
39057
39304
  // deep merge
39058
39305
  true
@@ -43801,9 +44048,11 @@ ul[data-type="taskList"] li[data-checked="true"] > div > p {
43801
44048
  exports2.buildProperties = buildProperties;
43802
44049
  exports2.buildPropertiesOrBuilder = buildPropertiesOrBuilder;
43803
44050
  exports2.buildProperty = buildProperty;
44051
+ exports2.buildSubcollectionPathSegments = buildSubcollectionPathSegments;
43804
44052
  exports2.canCreateEntity = canCreateEntity;
43805
44053
  exports2.canDeleteEntity = canDeleteEntity;
43806
44054
  exports2.canEditEntity = canEditEntity;
44055
+ exports2.collectionSegmentsFrom = collectionSegmentsFrom;
43807
44056
  exports2.copyEntityAction = copyEntityAction;
43808
44057
  exports2.decodeEntityId = decodeEntityId;
43809
44058
  exports2.defaultDateFormat = defaultDateFormat;
@@ -43822,6 +44071,7 @@ ul[data-type="taskList"] li[data-checked="true"] > div > p {
43822
44071
  exports2.getArrayValuesCount = getArrayValuesCount;
43823
44072
  exports2.getBracketNotation = getBracketNotation;
43824
44073
  exports2.getCollectionByPathOrId = getCollectionByPathOrId;
44074
+ exports2.getCollectionByPathSegments = getCollectionByPathSegments;
43825
44075
  exports2.getCollectionPathsCombinations = getCollectionPathsCombinations;
43826
44076
  exports2.getColorForProperty = getColorForProperty;
43827
44077
  exports2.getColorScheme = getColorScheme;
@@ -43883,6 +44133,7 @@ ul[data-type="taskList"] li[data-checked="true"] > div > p {
43883
44133
  exports2.parseGeoPoint = parseGeoPoint;
43884
44134
  exports2.pick = pick;
43885
44135
  exports2.plural = plural;
44136
+ exports2.positionalCollectionSegments = positionalCollectionSegments;
43886
44137
  exports2.prettifyIdentifier = prettifyIdentifier;
43887
44138
  exports2.printChanged = printChanged;
43888
44139
  exports2.propertiesToColumns = propertiesToColumns;
@@ -43904,6 +44155,7 @@ ul[data-type="taskList"] li[data-checked="true"] > div > p {
43904
44155
  exports2.resolveArrayProperty = resolveArrayProperty;
43905
44156
  exports2.resolveCollection = resolveCollection;
43906
44157
  exports2.resolveCollectionPathIds = resolveCollectionPathIds;
44158
+ exports2.resolveCollectionPathSegments = resolveCollectionPathSegments;
43907
44159
  exports2.resolveDefaultSelectedView = resolveDefaultSelectedView;
43908
44160
  exports2.resolveEntityAction = resolveEntityAction;
43909
44161
  exports2.resolveEntityView = resolveEntityView;
@@ -43966,6 +44218,7 @@ ul[data-type="taskList"] li[data-checked="true"] > div > p {
43966
44218
  exports2.useTraceUpdate = useTraceUpdate;
43967
44219
  exports2.useTranslation = useTranslation;
43968
44220
  exports2.useValidateAuthenticator = useValidateAuthenticator;
44221
+ exports2.walkPathSegments = walkPathSegments;
43969
44222
  exports2.yupToFormErrors = yupToFormErrors;
43970
44223
  Object.defineProperty(exports2, Symbol.toStringTag, { value: "Module" });
43971
44224
  }));