@firecms/core 3.3.0-canary.3ea2cd2 → 3.3.0-canary.5906216

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 (70) hide show
  1. package/dist/app/useApp.d.ts +1 -0
  2. package/dist/components/EntityCollectionTable/column_utils.d.ts +4 -3
  3. package/dist/components/EntityCollectionView/FiltersDialog.d.ts +2 -1
  4. package/dist/components/EntityPreview.d.ts +3 -1
  5. package/dist/core/DefaultDrawer.d.ts +10 -3
  6. package/dist/core/field_configs.d.ts +1 -1
  7. package/dist/form/field_bindings/GeopointFieldBinding.d.ts +5 -0
  8. package/dist/form/index.d.ts +1 -0
  9. package/dist/index.es.js +2090 -743
  10. package/dist/index.es.js.map +1 -1
  11. package/dist/index.umd.js +2089 -742
  12. package/dist/index.umd.js.map +1 -1
  13. package/dist/locales/pl.d.ts +2 -0
  14. package/dist/preview/index.d.ts +1 -0
  15. package/dist/preview/property_previews/GeopointPropertyPreview.d.ts +4 -0
  16. package/dist/types/collections.d.ts +17 -0
  17. package/dist/types/translations.d.ts +9 -1
  18. package/dist/util/entities.d.ts +1 -0
  19. package/dist/util/geopoint.d.ts +22 -0
  20. package/dist/util/index.d.ts +1 -0
  21. package/dist/util/navigation_blocking.d.ts +22 -0
  22. package/dist/util/navigation_from_path.d.ts +10 -0
  23. package/dist/util/navigation_utils.d.ts +20 -0
  24. package/package.json +16 -9
  25. package/src/app/Scaffold.tsx +47 -45
  26. package/src/app/useApp.tsx +1 -0
  27. package/src/components/EntityCollectionTable/EntityCollectionTable.tsx +2 -1
  28. package/src/components/EntityCollectionTable/column_utils.tsx +11 -19
  29. package/src/components/EntityCollectionTable/fields/TableReferenceField.tsx +1 -1
  30. package/src/components/EntityCollectionView/EntityCollectionView.tsx +5 -2
  31. package/src/components/EntityCollectionView/EntityCollectionViewStartActions.tsx +4 -1
  32. package/src/components/EntityCollectionView/FiltersDialog.tsx +39 -28
  33. package/src/components/EntityPreview.tsx +41 -40
  34. package/src/components/ReferenceWidget.tsx +1 -1
  35. package/src/components/SelectableTable/filters/ReferenceFilterField.tsx +2 -2
  36. package/src/components/VirtualTable/VirtualTable.tsx +19 -8
  37. package/src/components/common/useDataSourceTableController.tsx +66 -10
  38. package/src/core/DefaultDrawer.tsx +150 -64
  39. package/src/core/DrawerNavigationGroup.tsx +27 -29
  40. package/src/core/DrawerNavigationItem.tsx +10 -12
  41. package/src/core/EntityEditView.tsx +57 -32
  42. package/src/core/field_configs.tsx +15 -0
  43. package/src/form/field_bindings/ArrayOfReferencesFieldBinding.tsx +1 -1
  44. package/src/form/field_bindings/GeopointFieldBinding.tsx +139 -0
  45. package/src/form/index.tsx +1 -0
  46. package/src/hooks/useBuildNavigationController.tsx +5 -1
  47. package/src/i18n/FireCMSi18nProvider.tsx +2 -0
  48. package/src/internal/useBuildSideEntityController.tsx +2 -1
  49. package/src/locales/de.ts +11 -3
  50. package/src/locales/en.ts +11 -3
  51. package/src/locales/es.ts +11 -3
  52. package/src/locales/fr.ts +11 -3
  53. package/src/locales/hi.ts +11 -3
  54. package/src/locales/it.ts +11 -3
  55. package/src/locales/pl.ts +730 -0
  56. package/src/locales/pt.ts +11 -3
  57. package/src/preview/PropertyPreview.tsx +12 -0
  58. package/src/preview/index.ts +1 -0
  59. package/src/preview/property_previews/GeopointPropertyPreview.tsx +23 -0
  60. package/src/routes/FireCMSRoute.tsx +44 -25
  61. package/src/types/collections.ts +18 -0
  62. package/src/types/translations.ts +9 -1
  63. package/src/util/entities.ts +13 -0
  64. package/src/util/geopoint.ts +81 -0
  65. package/src/util/index.ts +1 -0
  66. package/src/util/navigation_blocking.ts +45 -0
  67. package/src/util/navigation_from_path.ts +23 -6
  68. package/src/util/navigation_utils.ts +36 -2
  69. package/src/util/parent_references_from_path.ts +4 -2
  70. package/src/util/resolutions.ts +3 -0
package/dist/index.umd.js CHANGED
@@ -170,6 +170,12 @@
170
170
  if (s.startsWith("/")) return s;
171
171
  else return `/${s}`;
172
172
  }
173
+ function encodeEntityId(entityId) {
174
+ return entityId.replaceAll("%", "%25").replaceAll("/", "%2F").replaceAll("#", "%23").replaceAll("?", "%3F");
175
+ }
176
+ function decodeEntityId(encodedEntityId) {
177
+ return encodedEntityId.replaceAll("%2F", "/").replaceAll("%23", "#").replaceAll("%3F", "?").replaceAll("%25", "%");
178
+ }
173
179
  function getLastSegment(path) {
174
180
  const cleanPath = removeInitialAndTrailingSlashes(path);
175
181
  if (cleanPath.includes("/")) {
@@ -263,7 +269,7 @@
263
269
  return result;
264
270
  }
265
271
  function getCollectionPathsCombinations(subpaths) {
266
- const entries = subpaths.length > 0 && subpaths.length % 2 === 0 ? subpaths.splice(0, subpaths.length - 1) : subpaths;
272
+ const entries = subpaths.length > 0 && subpaths.length % 2 === 0 ? subpaths.slice(0, subpaths.length - 1) : subpaths;
267
273
  const length = entries.length;
268
274
  const result = [];
269
275
  for (let i = length; i > 0; i = i - 2) {
@@ -295,7 +301,7 @@
295
301
  onClose
296
302
  });
297
303
  } else {
298
- let to = navigation.buildUrlCollectionPath(entityId ? `${fullIdPath ?? path}/${entityId}` : fullIdPath ?? path);
304
+ let to = navigation.buildUrlCollectionPath(entityId ? `${fullIdPath ?? path}/${encodeEntityId(entityId)}` : fullIdPath ?? path);
299
305
  if (entityId && selectedTab) {
300
306
  to += `/${selectedTab}`;
301
307
  }
@@ -658,6 +664,8 @@
658
664
  return [];
659
665
  } else if (dataType === "map") {
660
666
  return {};
667
+ } else if (dataType === "geopoint") {
668
+ return null;
661
669
  } else {
662
670
  return null;
663
671
  }
@@ -691,6 +699,9 @@
691
699
  return result;
692
700
  }
693
701
  function getReferenceFrom(entity) {
702
+ if (!entity) {
703
+ throw new Error("getReferenceFrom: entity is null or undefined");
704
+ }
694
705
  return new EntityReference(entity.id, entity.path, entity.databaseId);
695
706
  }
696
707
  function traverseValuesProperties(inputValues, properties, operation) {
@@ -740,6 +751,12 @@
740
751
  }
741
752
  return value;
742
753
  }
754
+ function isDataTypeFilterable(dataType, isPartOfArray = false) {
755
+ if (isPartOfArray) {
756
+ return ["string", "number", "date", "reference"].includes(dataType);
757
+ }
758
+ return ["string", "number", "boolean", "date", "reference", "array"].includes(dataType);
759
+ }
743
760
  function enumToObjectEntries(enumValues) {
744
761
  if (Array.isArray(enumValues)) {
745
762
  return enumValues;
@@ -826,8 +843,13 @@
826
843
  ...a,
827
844
  ...b
828
845
  }), {});
846
+ const {
847
+ properties: overrideProps,
848
+ ...restOverrides
849
+ } = collectionOverride ?? {};
829
850
  return {
830
851
  ...collection,
852
+ ...restOverrides,
831
853
  properties: cleanedProperties,
832
854
  originalCollection: collection
833
855
  };
@@ -1103,7 +1125,8 @@
1103
1125
  path,
1104
1126
  collections = [],
1105
1127
  currentFullPath,
1106
- currentFullIdPath
1128
+ currentFullIdPath,
1129
+ currentFullUrlPath
1107
1130
  } = props;
1108
1131
  const subpaths = removeInitialAndTrailingSlashes(path).split("/");
1109
1132
  const subpathCombinations = getCollectionPathsCombinations(subpaths);
@@ -1117,26 +1140,29 @@
1117
1140
  }
1118
1141
  if (collection) {
1119
1142
  const collectionPath = currentFullPath && currentFullPath.length > 0 ? currentFullPath + "/" + collection.path : collection.path;
1143
+ const collectionUrlPath = currentFullUrlPath && currentFullUrlPath.length > 0 ? currentFullUrlPath + "/" + collection.path : collection.path;
1120
1144
  const fullIdPath = currentFullIdPath && currentFullIdPath.length > 0 ? currentFullIdPath + "/" + collection.id : collection.id;
1121
1145
  result.push({
1122
1146
  type: "collection",
1123
1147
  id: collection.id,
1124
1148
  path: collectionPath,
1125
- fullPath: collectionPath,
1149
+ fullPath: collectionUrlPath,
1126
1150
  fullIdPath,
1127
1151
  collection
1128
1152
  });
1129
1153
  const restOfThePath = removeInitialAndTrailingSlashes(removeInitialAndTrailingSlashes(path).replace(subpathCombination, ""));
1130
1154
  const nextSegments = restOfThePath.length > 0 ? restOfThePath.split("/") : [];
1131
1155
  if (nextSegments.length > 0) {
1132
- const entityId = nextSegments[0];
1156
+ const encodedEntityId = nextSegments[0];
1157
+ const entityId = decodeEntityId(encodedEntityId);
1133
1158
  const fullPath = collectionPath + "/" + entityId;
1159
+ const fullUrlPath = collectionUrlPath + "/" + encodedEntityId;
1134
1160
  result.push({
1135
1161
  type: "entity",
1136
1162
  entityId,
1137
1163
  path: collectionPath,
1138
1164
  fullIdPath,
1139
- fullPath,
1165
+ fullPath: fullUrlPath,
1140
1166
  parentCollection: collection
1141
1167
  });
1142
1168
  if (nextSegments.length > 1) {
@@ -1152,7 +1178,7 @@
1152
1178
  path: collectionPath,
1153
1179
  entityId,
1154
1180
  fullIdPath,
1155
- fullPath: fullPath + "/" + customView.key,
1181
+ fullPath: fullUrlPath + "/" + customView.key,
1156
1182
  view: customView
1157
1183
  });
1158
1184
  } else if (collection.subcollections) {
@@ -1161,6 +1187,7 @@
1161
1187
  collections: collection.subcollections,
1162
1188
  currentFullPath: fullPath,
1163
1189
  currentFullIdPath: fullIdPath,
1190
+ currentFullUrlPath: fullUrlPath,
1164
1191
  contextEntityViews: props.contextEntityViews
1165
1192
  }));
1166
1193
  }
@@ -1565,6 +1592,77 @@
1565
1592
  function canDeleteEntity(collection, authController, path, entity) {
1566
1593
  return resolvePermissions(collection, authController, path, entity)?.delete ?? DEFAULT_PERMISSIONS.delete;
1567
1594
  }
1595
+ function toNumber(value) {
1596
+ return typeof value === "number" && Number.isFinite(value) ? value : void 0;
1597
+ }
1598
+ function getGeoPointCoordinates(value) {
1599
+ if (!value) return void 0;
1600
+ if (value instanceof GeoPoint) {
1601
+ return {
1602
+ latitude: value.latitude,
1603
+ longitude: value.longitude
1604
+ };
1605
+ }
1606
+ if (typeof value !== "object") return void 0;
1607
+ const latitude = toNumber(value.latitude ?? value.lat ?? value._lat);
1608
+ const longitude = toNumber(value.longitude ?? value.lng ?? value._long);
1609
+ if (latitude === void 0 || longitude === void 0) return void 0;
1610
+ return {
1611
+ latitude,
1612
+ longitude
1613
+ };
1614
+ }
1615
+ function normalizeGeoPoint(value) {
1616
+ const coordinates = getGeoPointCoordinates(value);
1617
+ if (!coordinates) return void 0;
1618
+ if (value instanceof GeoPoint) return value;
1619
+ return new GeoPoint(coordinates.latitude, coordinates.longitude);
1620
+ }
1621
+ function formatGeoPoint(value, options) {
1622
+ const coordinates = getGeoPointCoordinates(value);
1623
+ if (!coordinates) return "";
1624
+ const maximumFractionDigits = options?.maximumFractionDigits ?? 6;
1625
+ const formatter = new Intl.NumberFormat("en-US", {
1626
+ maximumFractionDigits,
1627
+ minimumFractionDigits: Math.min(2, maximumFractionDigits),
1628
+ useGrouping: false
1629
+ });
1630
+ return `${formatter.format(coordinates.latitude)}, ${formatter.format(coordinates.longitude)}`;
1631
+ }
1632
+ function parseGeoPoint(input) {
1633
+ const trimmed = input.trim();
1634
+ if (!trimmed) return {
1635
+ point: null
1636
+ };
1637
+ const parts = trimmed.split(",").map((part) => part.trim()).filter((part) => part !== "");
1638
+ if (parts.length !== 2) return {
1639
+ point: null,
1640
+ error: 'Use "lat, lng" format'
1641
+ };
1642
+ const latitude = parseFloat(parts[0]);
1643
+ const longitude = parseFloat(parts[1]);
1644
+ if (!Number.isFinite(latitude) || !Number.isFinite(longitude)) {
1645
+ return {
1646
+ point: null,
1647
+ error: "Latitude and longitude must be numbers"
1648
+ };
1649
+ }
1650
+ if (latitude < -90 || latitude > 90) {
1651
+ return {
1652
+ point: null,
1653
+ error: "Latitude must be between -90 and 90"
1654
+ };
1655
+ }
1656
+ if (longitude < -180 || longitude > 180) {
1657
+ return {
1658
+ point: null,
1659
+ error: "Longitude must be between -180 and 180"
1660
+ };
1661
+ }
1662
+ return {
1663
+ point: new GeoPoint(latitude, longitude)
1664
+ };
1665
+ }
1568
1666
  const iconSynonyms = {
1569
1667
  abc: "alphabet character font letter symbol text type",
1570
1668
  access_alarm: "clock time",
@@ -4513,7 +4611,7 @@
4513
4611
  }
4514
4612
  setDataLoading(false);
4515
4613
  setDataLoadingError(void 0);
4516
- setData(entities.map(_temp$C));
4614
+ setData(entities.map(_temp$D));
4517
4615
  setNoMoreToLoad(!itemCount || entities.length < itemCount);
4518
4616
  };
4519
4617
  const onError = (error) => {
@@ -4596,7 +4694,7 @@
4596
4694
  }
4597
4695
  function _temp2$f() {
4598
4696
  }
4599
- function _temp$C(e_0) {
4697
+ function _temp$D(e_0) {
4600
4698
  return {
4601
4699
  ...e_0
4602
4700
  };
@@ -4661,7 +4759,7 @@
4661
4759
  setEntity(CACHE[`${path}/${entityId}`]);
4662
4760
  setDataLoading(false);
4663
4761
  setDataLoadingError(void 0);
4664
- return _temp$B;
4762
+ return _temp$C;
4665
4763
  } else {
4666
4764
  if (entityId && path && collection) {
4667
4765
  if (dataSource.listenEntity) {
@@ -4729,7 +4827,7 @@
4729
4827
  }
4730
4828
  function _temp2$e() {
4731
4829
  }
4732
- function _temp$B() {
4830
+ function _temp$C() {
4733
4831
  }
4734
4832
  async function saveEntityWithCallbacks({
4735
4833
  collection,
@@ -5373,7 +5471,7 @@
5373
5471
  }
5374
5472
  let t9;
5375
5473
  if ($[19] !== url) {
5376
- t9 = /* @__PURE__ */ jsxRuntime.jsx(ui.Tooltip, { title: "Open image in new tab", side: "bottom", children: /* @__PURE__ */ jsxRuntime.jsx(ui.IconButton, { className: "invisible group-hover:visible", variant: "filled", component: "a", href: url, rel: "noopener noreferrer", target: "_blank", size: "smallest", onClick: _temp$A, children: t8 }) });
5474
+ t9 = /* @__PURE__ */ jsxRuntime.jsx(ui.Tooltip, { title: "Open image in new tab", side: "bottom", children: /* @__PURE__ */ jsxRuntime.jsx(ui.IconButton, { className: "invisible group-hover:visible", variant: "filled", component: "a", href: url, rel: "noopener noreferrer", target: "_blank", size: "smallest", onClick: _temp$B, children: t8 }) });
5377
5475
  $[19] = url;
5378
5476
  $[20] = t9;
5379
5477
  } else {
@@ -5407,7 +5505,7 @@
5407
5505
  }
5408
5506
  return t11;
5409
5507
  }
5410
- function _temp$A(e_0) {
5508
+ function _temp$B(e_0) {
5411
5509
  return e_0.stopPropagation();
5412
5510
  }
5413
5511
  const FIRECMS_NS$1 = "firecms_core";
@@ -5474,7 +5572,7 @@
5474
5572
  }
5475
5573
  let t3;
5476
5574
  if ($[2] !== url) {
5477
- t3 = /* @__PURE__ */ jsxRuntime.jsxs("a", { className: "flex gap-4 break-words items-center font-medium text-primary visited:text-primary dark:visited:text-primary dark:text-primary", href: url, rel: "noopener noreferrer", onMouseDown: _temp$z, target: "_blank", children: [
5575
+ t3 = /* @__PURE__ */ jsxRuntime.jsxs("a", { className: "flex gap-4 break-words items-center font-medium text-primary visited:text-primary dark:visited:text-primary dark:text-primary", href: url, rel: "noopener noreferrer", onMouseDown: _temp$A, target: "_blank", children: [
5478
5576
  t2,
5479
5577
  url
5480
5578
  ] });
@@ -5604,7 +5702,7 @@
5604
5702
  function _temp2$d(e_0) {
5605
5703
  return e_0.stopPropagation();
5606
5704
  }
5607
- function _temp$z(e) {
5705
+ function _temp$A(e) {
5608
5706
  e.preventDefault();
5609
5707
  }
5610
5708
  function VideoPreview(t0) {
@@ -5738,7 +5836,7 @@
5738
5836
  if (Array.isArray(arrayProperty.of)) {
5739
5837
  let t1;
5740
5838
  if ($[6] !== arrayProperty.of) {
5741
- t1 = arrayProperty.of.map(_temp$y);
5839
+ t1 = arrayProperty.of.map(_temp$z);
5742
5840
  $[6] = arrayProperty.of;
5743
5841
  $[7] = t1;
5744
5842
  } else {
@@ -5876,7 +5974,7 @@
5876
5974
  }
5877
5975
  return content || null;
5878
5976
  }
5879
- function _temp$y(p, i) {
5977
+ function _temp$z(p, i) {
5880
5978
  return renderGenericArrayCell(p, i);
5881
5979
  }
5882
5980
  function renderMap(property, size) {
@@ -6320,104 +6418,77 @@
6320
6418
  actions
6321
6419
  ] });
6322
6420
  }
6323
- const EntityPreviewContainer = React__namespace.forwardRef((t0, ref) => {
6324
- const $ = reactCompilerRuntime.c(26);
6325
- let children;
6326
- let className;
6327
- let hover;
6328
- let onClick;
6329
- let props;
6330
- let style;
6331
- let t1;
6332
- let t2;
6333
- if ($[0] !== t0) {
6334
- ({
6335
- children,
6336
- hover,
6337
- onClick,
6338
- size: t1,
6339
- style,
6340
- className,
6341
- fullwidth: t2,
6342
- ...props
6343
- } = t0);
6344
- $[0] = t0;
6345
- $[1] = children;
6346
- $[2] = className;
6347
- $[3] = hover;
6348
- $[4] = onClick;
6349
- $[5] = props;
6350
- $[6] = style;
6351
- $[7] = t1;
6352
- $[8] = t2;
6353
- } else {
6354
- children = $[1];
6355
- className = $[2];
6356
- hover = $[3];
6357
- onClick = $[4];
6358
- props = $[5];
6359
- style = $[6];
6360
- t1 = $[7];
6361
- t2 = $[8];
6362
- }
6421
+ function EntityPreviewContainer(t0) {
6422
+ const $ = reactCompilerRuntime.c(15);
6423
+ const {
6424
+ children,
6425
+ hover,
6426
+ onClick,
6427
+ size: t1,
6428
+ style,
6429
+ className,
6430
+ fullwidth: t2,
6431
+ ref
6432
+ } = t0;
6363
6433
  const size = t1 === void 0 ? "medium" : t1;
6364
6434
  const fullwidth = t2 === void 0 ? true : t2;
6365
- let t3;
6366
- if ($[9] !== style) {
6367
- t3 = {
6368
- ...style,
6369
- tabindex: 0
6370
- };
6371
- $[9] = style;
6372
- $[10] = t3;
6435
+ const t3 = fullwidth ? "w-full" : "";
6436
+ const t4 = hover ? "hover:bg-surface-accent-50 dark:hover:bg-surface-800 group-hover:bg-surface-accent-50 dark:group-hover:bg-surface-800" : "";
6437
+ const t5 = size === "small" ? "p-1" : "px-2 py-1";
6438
+ const t6 = onClick ? "cursor-pointer" : "";
6439
+ let t7;
6440
+ if ($[0] !== className || $[1] !== t3 || $[2] !== t4 || $[3] !== t5 || $[4] !== t6) {
6441
+ t7 = ui.cls("bg-white dark:bg-surface-900", "min-h-[44px]", t3, "items-center", t4, t5, "flex border rounded-lg", t6, ui.defaultBorderMixin, className);
6442
+ $[0] = className;
6443
+ $[1] = t3;
6444
+ $[2] = t4;
6445
+ $[3] = t5;
6446
+ $[4] = t6;
6447
+ $[5] = t7;
6373
6448
  } else {
6374
- t3 = $[10];
6449
+ t7 = $[5];
6375
6450
  }
6376
- const t4 = fullwidth ? "w-full" : "";
6377
- const t5 = hover ? "hover:bg-surface-accent-50 dark:hover:bg-surface-800 group-hover:bg-surface-accent-50 dark:group-hover:bg-surface-800" : "";
6378
- const t6 = size === "small" ? "p-1" : "px-2 py-1";
6379
- const t7 = onClick ? "cursor-pointer" : "";
6451
+ const divClassName = t7;
6380
6452
  let t8;
6381
- if ($[11] !== className || $[12] !== t4 || $[13] !== t5 || $[14] !== t6 || $[15] !== t7) {
6382
- t8 = ui.cls("bg-white dark:bg-surface-900", "min-h-[44px]", t4, "items-center", t5, t6, "flex border rounded-lg", t7, ui.defaultBorderMixin, className);
6383
- $[11] = className;
6384
- $[12] = t4;
6385
- $[13] = t5;
6386
- $[14] = t6;
6387
- $[15] = t7;
6388
- $[16] = t8;
6453
+ if ($[6] !== onClick) {
6454
+ t8 = onClick ? (event) => {
6455
+ event.preventDefault();
6456
+ onClick(event);
6457
+ } : void 0;
6458
+ $[6] = onClick;
6459
+ $[7] = t8;
6389
6460
  } else {
6390
- t8 = $[16];
6461
+ t8 = $[7];
6391
6462
  }
6463
+ const handleClick = t8;
6392
6464
  let t9;
6393
- if ($[17] !== onClick) {
6394
- t9 = (event) => {
6395
- if (onClick) {
6396
- event.preventDefault();
6397
- onClick(event);
6398
- }
6465
+ if ($[8] !== divClassName || $[9] !== handleClick || $[10] !== style) {
6466
+ t9 = {
6467
+ ref,
6468
+ tabIndex: 0,
6469
+ style,
6470
+ className: divClassName,
6471
+ onClick: handleClick
6399
6472
  };
6400
- $[17] = onClick;
6401
- $[18] = t9;
6473
+ $[8] = divClassName;
6474
+ $[9] = handleClick;
6475
+ $[10] = style;
6476
+ $[11] = t9;
6402
6477
  } else {
6403
- t9 = $[18];
6478
+ t9 = $[11];
6404
6479
  }
6480
+ const divProps = t9;
6405
6481
  let t10;
6406
- if ($[19] !== children || $[20] !== props || $[21] !== ref || $[22] !== t3 || $[23] !== t8 || $[24] !== t9) {
6407
- t10 = /* @__PURE__ */ jsxRuntime.jsx("div", { ref, style: t3, className: t8, onClick: t9, ...props, children });
6408
- $[19] = children;
6409
- $[20] = props;
6410
- $[21] = ref;
6411
- $[22] = t3;
6412
- $[23] = t8;
6413
- $[24] = t9;
6414
- $[25] = t10;
6482
+ if ($[12] !== children || $[13] !== divProps) {
6483
+ t10 = /* @__PURE__ */ jsxRuntime.jsx("div", { ...divProps, children });
6484
+ $[12] = children;
6485
+ $[13] = divProps;
6486
+ $[14] = t10;
6415
6487
  } else {
6416
- t10 = $[25];
6488
+ t10 = $[14];
6417
6489
  }
6418
6490
  return t10;
6419
- });
6420
- EntityPreviewContainer.displayName = "EntityPreviewContainer";
6491
+ }
6421
6492
  const ReferencePreview = function ReferencePreview2(props) {
6422
6493
  const $ = reactCompilerRuntime.c(10);
6423
6494
  const reference = props.reference;
@@ -7051,7 +7122,7 @@
7051
7122
  timeZoneName: "short"
7052
7123
  });
7053
7124
  const parts = tzFormatter.formatToParts(date);
7054
- t32 = parts.find(_temp$x)?.value ?? "";
7125
+ t32 = parts.find(_temp$y)?.value ?? "";
7055
7126
  $[6] = date;
7056
7127
  $[7] = timezone;
7057
7128
  $[8] = t32;
@@ -7122,7 +7193,7 @@
7122
7193
  }
7123
7194
  return t3;
7124
7195
  }
7125
- function _temp$x(p) {
7196
+ function _temp$y(p) {
7126
7197
  return p.type === "timeZoneName";
7127
7198
  }
7128
7199
  function MapPropertyPreview(t0) {
@@ -7217,7 +7288,7 @@
7217
7288
  }
7218
7289
  let t1;
7219
7290
  if ($[1] !== value) {
7220
- t1 = Object.entries(value).map(_temp$w);
7291
+ t1 = Object.entries(value).map(_temp$x);
7221
7292
  $[1] = value;
7222
7293
  $[2] = t1;
7223
7294
  } else {
@@ -7233,7 +7304,7 @@
7233
7304
  }
7234
7305
  return t2;
7235
7306
  }
7236
- function _temp$w(t0) {
7307
+ function _temp$x(t0) {
7237
7308
  const [key, childValue] = t0;
7238
7309
  const isTimestampObj = childValue && typeof childValue === "object" && (childValue instanceof Date || "_seconds" in childValue && "_nanoseconds" in childValue && typeof childValue._seconds === "number" && typeof childValue._nanoseconds === "number" || "seconds" in childValue && "nanoseconds" in childValue && typeof childValue.seconds === "number" && typeof childValue.nanoseconds === "number");
7239
7310
  const isScalar = childValue && (typeof childValue !== "object" || isTimestampObj);
@@ -7245,6 +7316,59 @@
7245
7316
  typeof childValue === "object" && !isTimestampObj && /* @__PURE__ */ jsxRuntime.jsx("div", { className: ui.cls(ui.defaultBorderMixin, "border-l pl-4"), children: /* @__PURE__ */ jsxRuntime.jsx(KeyValuePreview, { value: childValue }) })
7246
7317
  ] }, `map_preview_table_${key}}`);
7247
7318
  }
7319
+ function GeopointPropertyPreview(t0) {
7320
+ const $ = reactCompilerRuntime.c(10);
7321
+ const {
7322
+ value,
7323
+ size
7324
+ } = t0;
7325
+ let t1;
7326
+ let t2;
7327
+ let t3;
7328
+ if ($[0] !== size || $[1] !== value) {
7329
+ t3 = /* @__PURE__ */ Symbol.for("react.early_return_sentinel");
7330
+ bb0: {
7331
+ const coordinates = getGeoPointCoordinates(value);
7332
+ if (!coordinates) {
7333
+ const t42 = size === "small" ? "text-sm text-text-secondary dark:text-text-secondary-dark" : "text-text-secondary dark:text-text-secondary-dark";
7334
+ let t5;
7335
+ if ($[5] !== t42) {
7336
+ t5 = /* @__PURE__ */ jsxRuntime.jsx("span", { className: t42, children: "—" });
7337
+ $[5] = t42;
7338
+ $[6] = t5;
7339
+ } else {
7340
+ t5 = $[6];
7341
+ }
7342
+ t3 = t5;
7343
+ break bb0;
7344
+ }
7345
+ t1 = size === "small" ? "text-sm font-mono" : "font-mono";
7346
+ t2 = formatGeoPoint(coordinates);
7347
+ }
7348
+ $[0] = size;
7349
+ $[1] = value;
7350
+ $[2] = t1;
7351
+ $[3] = t2;
7352
+ $[4] = t3;
7353
+ } else {
7354
+ t1 = $[2];
7355
+ t2 = $[3];
7356
+ t3 = $[4];
7357
+ }
7358
+ if (t3 !== /* @__PURE__ */ Symbol.for("react.early_return_sentinel")) {
7359
+ return t3;
7360
+ }
7361
+ let t4;
7362
+ if ($[7] !== t1 || $[8] !== t2) {
7363
+ t4 = /* @__PURE__ */ jsxRuntime.jsx("span", { className: t1, children: t2 });
7364
+ $[7] = t1;
7365
+ $[8] = t2;
7366
+ $[9] = t4;
7367
+ } else {
7368
+ t4 = $[9];
7369
+ }
7370
+ return t4;
7371
+ }
7248
7372
  function BooleanPreview(t0) {
7249
7373
  const $ = reactCompilerRuntime.c(9);
7250
7374
  const {
@@ -7672,47 +7796,56 @@
7672
7796
  content = buildWrongValueType(propertyKey, property.dataType, value);
7673
7797
  }
7674
7798
  } else {
7675
- if (property.dataType === "reference") {
7676
- if (typeof property.path === "string") {
7677
- if (typeof value === "object" && "isEntityReference" in value && value.isEntityReference()) {
7678
- content = /* @__PURE__ */ jsxRuntime.jsx(ReferencePreview, { disabled: !property.path, previewProperties: property.previewProperties, includeId: property.includeId, includeEntityLink: property.includeEntityLink, size: props.size, reference: value });
7679
- } else {
7680
- content = buildWrongValueType(propertyKey, property.dataType, value);
7681
- }
7799
+ if (property.dataType === "geopoint") {
7800
+ const coordinates = getGeoPointCoordinates(value);
7801
+ if (coordinates) {
7802
+ content = /* @__PURE__ */ jsxRuntime.jsx(GeopointPropertyPreview, { ...props, property, value });
7682
7803
  } else {
7683
- let t02;
7684
- if ($[27] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
7685
- t02 = /* @__PURE__ */ jsxRuntime.jsx(EmptyValue, {});
7686
- $[27] = t02;
7687
- } else {
7688
- t02 = $[27];
7689
- }
7690
- content = t02;
7804
+ content = buildWrongValueType(propertyKey, property.dataType, value);
7691
7805
  }
7692
7806
  } else {
7693
- if (property.dataType === "boolean") {
7694
- if (typeof value === "boolean") {
7695
- content = /* @__PURE__ */ jsxRuntime.jsx(BooleanPreview, { value, size, property });
7807
+ if (property.dataType === "reference") {
7808
+ if (typeof property.path === "string") {
7809
+ if (typeof value === "object" && "isEntityReference" in value && value.isEntityReference()) {
7810
+ content = /* @__PURE__ */ jsxRuntime.jsx(ReferencePreview, { disabled: !property.path, previewProperties: property.previewProperties, includeId: property.includeId, includeEntityLink: property.includeEntityLink, size: props.size, reference: value });
7811
+ } else {
7812
+ content = buildWrongValueType(propertyKey, property.dataType, value);
7813
+ }
7696
7814
  } else {
7697
- content = buildWrongValueType(propertyKey, property.dataType, value);
7815
+ let t02;
7816
+ if ($[27] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
7817
+ t02 = /* @__PURE__ */ jsxRuntime.jsx(EmptyValue, {});
7818
+ $[27] = t02;
7819
+ } else {
7820
+ t02 = $[27];
7821
+ }
7822
+ content = t02;
7698
7823
  }
7699
7824
  } else {
7700
- if (property.dataType === "number") {
7701
- if (typeof value === "number") {
7702
- content = /* @__PURE__ */ jsxRuntime.jsx(NumberPropertyPreview, { ...props, value, property });
7825
+ if (property.dataType === "boolean") {
7826
+ if (typeof value === "boolean") {
7827
+ content = /* @__PURE__ */ jsxRuntime.jsx(BooleanPreview, { value, size, property });
7703
7828
  } else {
7704
7829
  content = buildWrongValueType(propertyKey, property.dataType, value);
7705
7830
  }
7706
7831
  } else {
7707
- let t02;
7708
- if ($[28] !== value) {
7709
- t02 = JSON.stringify(value, jsonStringifyReplacer);
7710
- $[28] = value;
7711
- $[29] = t02;
7832
+ if (property.dataType === "number") {
7833
+ if (typeof value === "number") {
7834
+ content = /* @__PURE__ */ jsxRuntime.jsx(NumberPropertyPreview, { ...props, value, property });
7835
+ } else {
7836
+ content = buildWrongValueType(propertyKey, property.dataType, value);
7837
+ }
7712
7838
  } else {
7713
- t02 = $[29];
7839
+ let t02;
7840
+ if ($[28] !== value) {
7841
+ t02 = JSON.stringify(value, jsonStringifyReplacer);
7842
+ $[28] = value;
7843
+ $[29] = t02;
7844
+ } else {
7845
+ t02 = $[29];
7846
+ }
7847
+ content = t02;
7714
7848
  }
7715
- content = t02;
7716
7849
  }
7717
7850
  }
7718
7851
  }
@@ -8494,7 +8627,7 @@
8494
8627
  console.trace("onChange");
8495
8628
  if (valueType === "number") {
8496
8629
  if (multiple) {
8497
- const newValue = updatedValue.map(_temp$v);
8630
+ const newValue = updatedValue.map(_temp$w);
8498
8631
  updateValue(newValue);
8499
8632
  } else {
8500
8633
  updateValue(parseFloat(updatedValue));
@@ -8565,7 +8698,7 @@
8565
8698
  function _temp2$c(v_0) {
8566
8699
  return v_0.toString();
8567
8700
  }
8568
- function _temp$v(v) {
8701
+ function _temp$w(v) {
8569
8702
  return parseFloat(v);
8570
8703
  }
8571
8704
  function VirtualTableNumberInput(props) {
@@ -8761,7 +8894,7 @@
8761
8894
  const renderValue = t3;
8762
8895
  let t4;
8763
8896
  if ($[7] !== disabled || $[8] !== internalValue || $[9] !== multiple || $[10] !== onChange || $[11] !== renderValue || $[12] !== users || $[13] !== validValue) {
8764
- t4 = multiple ? /* @__PURE__ */ jsxRuntime.jsx(ui.MultiSelect, { inputRef: ref, className: "w-full h-full p-0 bg-transparent", position: "item-aligned", disabled, includeClear: false, useChips: false, value: validValue ? internalValue : [], onValueChange: onChange, children: users?.map(_temp$u) }) : /* @__PURE__ */ jsxRuntime.jsx(ui.Select, { inputRef: ref, size: "large", fullWidth: true, className: "w-full h-full p-0 bg-transparent", position: "item-aligned", disabled, padding: false, value: validValue ? internalValue : "", onValueChange: onChange, renderValue, children: users?.map(_temp2$b) });
8897
+ t4 = multiple ? /* @__PURE__ */ jsxRuntime.jsx(ui.MultiSelect, { inputRef: ref, className: "w-full h-full p-0 bg-transparent", position: "item-aligned", disabled, includeClear: false, useChips: false, value: validValue ? internalValue : [], onValueChange: onChange, children: users?.map(_temp$v) }) : /* @__PURE__ */ jsxRuntime.jsx(ui.Select, { inputRef: ref, size: "large", fullWidth: true, className: "w-full h-full p-0 bg-transparent", position: "item-aligned", disabled, padding: false, value: validValue ? internalValue : "", onValueChange: onChange, renderValue, children: users?.map(_temp2$b) });
8765
8898
  $[7] = disabled;
8766
8899
  $[8] = internalValue;
8767
8900
  $[9] = multiple;
@@ -8778,7 +8911,7 @@
8778
8911
  function _temp2$b(user_1) {
8779
8912
  return /* @__PURE__ */ jsxRuntime.jsx(ui.SelectItem, { value: user_1.uid, children: /* @__PURE__ */ jsxRuntime.jsx(UserDisplay, { user: user_1 }) }, user_1.uid);
8780
8913
  }
8781
- function _temp$u(user_0) {
8914
+ function _temp$v(user_0) {
8782
8915
  return /* @__PURE__ */ jsxRuntime.jsx(ui.MultiSelectItem, { value: user_0.uid, children: /* @__PURE__ */ jsxRuntime.jsx(UserDisplay, { user: user_0 }) }, user_0.uid);
8783
8916
  }
8784
8917
  class ErrorBoundary extends React.Component {
@@ -9023,7 +9156,7 @@
9023
9156
  newValue = [...internalValue];
9024
9157
  newValue = removeDuplicates(newValue);
9025
9158
  setInternalValue(newValue);
9026
- const fieldValue = newValue.filter(_temp$t).map(_temp2$a);
9159
+ const fieldValue = newValue.filter(_temp$u).map(_temp2$a);
9027
9160
  if (multipleFilesSupported) {
9028
9161
  onChange(fieldValue);
9029
9162
  } else {
@@ -9144,7 +9277,7 @@
9144
9277
  function _temp2$a(e_0) {
9145
9278
  return e_0.storagePathOrDownloadUrl;
9146
9279
  }
9147
- function _temp$t(e) {
9280
+ function _temp$u(e) {
9148
9281
  return !!e.storagePathOrDownloadUrl;
9149
9282
  }
9150
9283
  function getInternalInitialValue(multipleFilesSupported, value, metadata, size) {
@@ -9434,7 +9567,7 @@
9434
9567
  const snackbarContext = useSnackbarController();
9435
9568
  let t1;
9436
9569
  if ($[0] !== storage.acceptedFiles) {
9437
- t1 = storage.acceptedFiles ? storage.acceptedFiles.map(_temp$s).reduce(_temp2$9, {}) : void 0;
9570
+ t1 = storage.acceptedFiles ? storage.acceptedFiles.map(_temp$t).reduce(_temp2$9, {}) : void 0;
9438
9571
  $[0] = storage.acceptedFiles;
9439
9572
  $[1] = t1;
9440
9573
  } else {
@@ -9663,7 +9796,7 @@
9663
9796
  ...b
9664
9797
  };
9665
9798
  }
9666
- function _temp$s(e) {
9799
+ function _temp$t(e) {
9667
9800
  return {
9668
9801
  [e]: []
9669
9802
  };
@@ -9773,7 +9906,7 @@
9773
9906
  let t1;
9774
9907
  if ($[2] !== updateValue) {
9775
9908
  t1 = (entities) => {
9776
- updateValue(entities.map(_temp$r));
9909
+ updateValue(entities.filter(Boolean).map(_temp$s));
9777
9910
  };
9778
9911
  $[2] = updateValue;
9779
9912
  $[3] = t1;
@@ -9945,7 +10078,7 @@
9945
10078
  }
9946
10079
  return t10;
9947
10080
  }, equal);
9948
- function _temp$r(e) {
10081
+ function _temp$s(e) {
9949
10082
  return getReferenceFrom(e);
9950
10083
  }
9951
10084
  function _temp2$8(ref) {
@@ -11613,7 +11746,7 @@
11613
11746
  throw Error(`Couldn't find the corresponding collection for the path: ${ofProperty.path}`);
11614
11747
  }
11615
11748
  const onMultipleEntitiesSelected = React.useCallback((entities) => {
11616
- setValue(entities.map((e) => getReferenceFrom(e)));
11749
+ setValue(entities.filter(Boolean).map((e) => getReferenceFrom(e)));
11617
11750
  }, [setValue]);
11618
11751
  const referenceDialogController = useReferenceDialog({
11619
11752
  multiselect: true,
@@ -11723,7 +11856,7 @@
11723
11856
  }
11724
11857
  let t5;
11725
11858
  if ($[15] !== placeholder) {
11726
- t5 = placeholder && /* @__PURE__ */ jsxRuntime.jsx("div", { onClick: _temp$q, className: "flex flex-col items-center justify-center w-full h-full", children: /* @__PURE__ */ jsxRuntime.jsx(ui.DescriptionIcon, { className: "text-surface-700 dark:text-surface-300" }) });
11859
+ t5 = placeholder && /* @__PURE__ */ jsxRuntime.jsx("div", { onClick: _temp$r, className: "flex flex-col items-center justify-center w-full h-full", children: /* @__PURE__ */ jsxRuntime.jsx(ui.DescriptionIcon, { className: "text-surface-700 dark:text-surface-300" }) });
11727
11860
  $[15] = placeholder;
11728
11861
  $[16] = t5;
11729
11862
  } else {
@@ -11746,7 +11879,7 @@
11746
11879
  }
11747
11880
  return t6;
11748
11881
  }
11749
- function _temp$q(e) {
11882
+ function _temp$r(e) {
11750
11883
  return e.stopPropagation();
11751
11884
  }
11752
11885
  const dropZoneClasses = "box-border relative pt-[2px] items-center border border-transparent min-h-[254px] outline-none rounded-md duration-200 ease-[cubic-bezier(0.4,0,0.2,1)] focus:border-primary-solid";
@@ -11974,7 +12107,7 @@
11974
12107
  t4 = $[7];
11975
12108
  }
11976
12109
  const style = t4;
11977
- const getImageSizeNumber = _temp$p;
12110
+ const getImageSizeNumber = _temp$q;
11978
12111
  let child;
11979
12112
  if (entry.storagePathOrDownloadUrl) {
11980
12113
  const t52 = `storage_preview_${entry.storagePathOrDownloadUrl}`;
@@ -12049,7 +12182,7 @@
12049
12182
  }
12050
12183
  return t6;
12051
12184
  }
12052
- function _temp$p(previewSize) {
12185
+ function _temp$q(previewSize) {
12053
12186
  switch (previewSize) {
12054
12187
  case "small": {
12055
12188
  return 40;
@@ -12330,7 +12463,7 @@
12330
12463
  newValue.splice(fromIndex, 1);
12331
12464
  newValue.splice(toIndex, 0, item);
12332
12465
  setInternalValue(newValue);
12333
- const fieldValue = newValue.filter(_temp3$4).map(_temp4$3);
12466
+ const fieldValue = newValue.filter(_temp3$4).map(_temp4$4);
12334
12467
  onChange(fieldValue);
12335
12468
  };
12336
12469
  $[0] = multipleFilesSupported;
@@ -12524,7 +12657,7 @@
12524
12657
  function _temp5$2(v_0) {
12525
12658
  return !!v_0.storagePathOrDownloadUrl;
12526
12659
  }
12527
- function _temp4$3(e_0) {
12660
+ function _temp4$4(e_0) {
12528
12661
  return e_0.storagePathOrDownloadUrl;
12529
12662
  }
12530
12663
  function _temp3$4(e) {
@@ -12949,6 +13082,260 @@
12949
13082
  }
12950
13083
  return t13;
12951
13084
  }
13085
+ function GeopointFieldBinding(t0) {
13086
+ const $ = reactCompilerRuntime.c(66);
13087
+ const {
13088
+ propertyKey,
13089
+ value,
13090
+ setValue,
13091
+ error,
13092
+ showError,
13093
+ disabled,
13094
+ autoFocus,
13095
+ property,
13096
+ includeDescription,
13097
+ size: t1
13098
+ } = t0;
13099
+ const size = t1 === void 0 ? "large" : t1;
13100
+ const coordinates = getGeoPointCoordinates(value);
13101
+ const canClear = Boolean(property.clearable);
13102
+ const [latitude, setLatitude] = React.useState(coordinates ? coordinates.latitude.toString() : "");
13103
+ const [longitude, setLongitude] = React.useState(coordinates ? coordinates.longitude.toString() : "");
13104
+ const [localError, setLocalError] = React.useState();
13105
+ const skipSyncRef = React.useRef(false);
13106
+ let t2;
13107
+ if ($[0] !== property || $[1] !== setValue || $[2] !== value) {
13108
+ t2 = {
13109
+ property,
13110
+ value,
13111
+ setValue
13112
+ };
13113
+ $[0] = property;
13114
+ $[1] = setValue;
13115
+ $[2] = value;
13116
+ $[3] = t2;
13117
+ } else {
13118
+ t2 = $[3];
13119
+ }
13120
+ useClearRestoreValue(t2);
13121
+ let t3;
13122
+ if ($[4] !== setLatitude || $[5] !== value) {
13123
+ t3 = () => {
13124
+ if (skipSyncRef.current) {
13125
+ skipSyncRef.current = false;
13126
+ return;
13127
+ }
13128
+ const nextCoordinates = getGeoPointCoordinates(value);
13129
+ setLatitude(nextCoordinates ? nextCoordinates.latitude.toString() : "");
13130
+ setLongitude(nextCoordinates ? nextCoordinates.longitude.toString() : "");
13131
+ };
13132
+ $[4] = setLatitude;
13133
+ $[5] = value;
13134
+ $[6] = t3;
13135
+ } else {
13136
+ t3 = $[6];
13137
+ }
13138
+ let t4;
13139
+ if ($[7] !== value) {
13140
+ t4 = [value];
13141
+ $[7] = value;
13142
+ $[8] = t4;
13143
+ } else {
13144
+ t4 = $[8];
13145
+ }
13146
+ React.useEffect(t3, t4);
13147
+ let t5;
13148
+ if ($[9] !== setLatitude || $[10] !== setValue) {
13149
+ t5 = (nextLatitude, nextLongitude) => {
13150
+ skipSyncRef.current = true;
13151
+ setLatitude(nextLatitude);
13152
+ setLongitude(nextLongitude);
13153
+ const trimmedLatitude = nextLatitude.trim();
13154
+ const trimmedLongitude = nextLongitude.trim();
13155
+ if (!trimmedLatitude && !trimmedLongitude) {
13156
+ setLocalError(void 0);
13157
+ setValue(null);
13158
+ return;
13159
+ }
13160
+ const parsed = parseGeoPoint(`${trimmedLatitude}, ${trimmedLongitude}`);
13161
+ if (parsed.error) {
13162
+ setLocalError(parsed.error);
13163
+ setValue(null);
13164
+ return;
13165
+ }
13166
+ setLocalError(void 0);
13167
+ setValue(parsed.point);
13168
+ };
13169
+ $[9] = setLatitude;
13170
+ $[10] = setValue;
13171
+ $[11] = t5;
13172
+ } else {
13173
+ t5 = $[11];
13174
+ }
13175
+ const updateGeoPoint = t5;
13176
+ let t6;
13177
+ if ($[12] !== updateGeoPoint) {
13178
+ t6 = (event) => {
13179
+ if (event) {
13180
+ event.preventDefault();
13181
+ event.stopPropagation();
13182
+ }
13183
+ updateGeoPoint("", "");
13184
+ };
13185
+ $[12] = updateGeoPoint;
13186
+ $[13] = t6;
13187
+ } else {
13188
+ t6 = $[13];
13189
+ }
13190
+ const handleClear = t6;
13191
+ const resolvedError = localError ?? error;
13192
+ const shouldShowError = Boolean(resolvedError) || Boolean(showError && error);
13193
+ let t7;
13194
+ if ($[14] !== property) {
13195
+ t7 = getIconForProperty(property, "small");
13196
+ $[14] = property;
13197
+ $[15] = t7;
13198
+ } else {
13199
+ t7 = $[15];
13200
+ }
13201
+ const t8 = property.validation?.required;
13202
+ const t9 = shouldShowError ? "text-red-500 dark:text-red-500" : "text-text-secondary dark:text-text-secondary-dark";
13203
+ let t10;
13204
+ if ($[16] !== property.name || $[17] !== t7 || $[18] !== t8 || $[19] !== t9) {
13205
+ t10 = /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-1", children: /* @__PURE__ */ jsxRuntime.jsx(LabelWithIcon, { icon: t7, required: t8, title: property.name, className: t9 }) });
13206
+ $[16] = property.name;
13207
+ $[17] = t7;
13208
+ $[18] = t8;
13209
+ $[19] = t9;
13210
+ $[20] = t10;
13211
+ } else {
13212
+ t10 = $[20];
13213
+ }
13214
+ let t11;
13215
+ if ($[21] !== longitude || $[22] !== updateGeoPoint) {
13216
+ t11 = (event_0) => updateGeoPoint(event_0.target.value, longitude);
13217
+ $[21] = longitude;
13218
+ $[22] = updateGeoPoint;
13219
+ $[23] = t11;
13220
+ } else {
13221
+ t11 = $[23];
13222
+ }
13223
+ let t12;
13224
+ if ($[24] !== canClear || $[25] !== handleClear) {
13225
+ t12 = canClear ? /* @__PURE__ */ jsxRuntime.jsx(ui.IconButton, { onClick: handleClear, children: /* @__PURE__ */ jsxRuntime.jsx(ui.CloseIcon, {}) }) : void 0;
13226
+ $[24] = canClear;
13227
+ $[25] = handleClear;
13228
+ $[26] = t12;
13229
+ } else {
13230
+ t12 = $[26];
13231
+ }
13232
+ const t13 = shouldShowError && Boolean(resolvedError);
13233
+ let t14;
13234
+ if ($[27] !== autoFocus || $[28] !== disabled || $[29] !== latitude || $[30] !== size || $[31] !== t11 || $[32] !== t12 || $[33] !== t13) {
13235
+ t14 = /* @__PURE__ */ jsxRuntime.jsx(ui.TextField, { size, value: latitude, onChange: t11, autoFocus, label: "Latitude", type: "number", disabled, endAdornment: t12, error: t13 });
13236
+ $[27] = autoFocus;
13237
+ $[28] = disabled;
13238
+ $[29] = latitude;
13239
+ $[30] = size;
13240
+ $[31] = t11;
13241
+ $[32] = t12;
13242
+ $[33] = t13;
13243
+ $[34] = t14;
13244
+ } else {
13245
+ t14 = $[34];
13246
+ }
13247
+ let t15;
13248
+ if ($[35] !== latitude || $[36] !== updateGeoPoint) {
13249
+ t15 = (event_1) => updateGeoPoint(latitude, event_1.target.value);
13250
+ $[35] = latitude;
13251
+ $[36] = updateGeoPoint;
13252
+ $[37] = t15;
13253
+ } else {
13254
+ t15 = $[37];
13255
+ }
13256
+ const t16 = shouldShowError && Boolean(resolvedError);
13257
+ let t17;
13258
+ if ($[38] !== disabled || $[39] !== longitude || $[40] !== size || $[41] !== t15 || $[42] !== t16) {
13259
+ t17 = /* @__PURE__ */ jsxRuntime.jsx(ui.TextField, { size, value: longitude, onChange: t15, label: "Longitude", type: "number", disabled, error: t16 });
13260
+ $[38] = disabled;
13261
+ $[39] = longitude;
13262
+ $[40] = size;
13263
+ $[41] = t15;
13264
+ $[42] = t16;
13265
+ $[43] = t17;
13266
+ } else {
13267
+ t17 = $[43];
13268
+ }
13269
+ let t18;
13270
+ if ($[44] !== t14 || $[45] !== t17) {
13271
+ t18 = /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 gap-2 md:grid-cols-2", children: [
13272
+ t14,
13273
+ t17
13274
+ ] });
13275
+ $[44] = t14;
13276
+ $[45] = t17;
13277
+ $[46] = t18;
13278
+ } else {
13279
+ t18 = $[46];
13280
+ }
13281
+ let t19;
13282
+ if ($[47] !== resolvedError || $[48] !== value) {
13283
+ t19 = value && !resolvedError && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-xs text-text-secondary dark:text-text-secondary-dark font-mono", children: formatGeoPoint(value) });
13284
+ $[47] = resolvedError;
13285
+ $[48] = value;
13286
+ $[49] = t19;
13287
+ } else {
13288
+ t19 = $[49];
13289
+ }
13290
+ let t20;
13291
+ if ($[50] !== t10 || $[51] !== t18 || $[52] !== t19) {
13292
+ t20 = /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-2", children: [
13293
+ t10,
13294
+ t18,
13295
+ t19
13296
+ ] });
13297
+ $[50] = t10;
13298
+ $[51] = t18;
13299
+ $[52] = t19;
13300
+ $[53] = t20;
13301
+ } else {
13302
+ t20 = $[53];
13303
+ }
13304
+ let t21;
13305
+ if ($[54] !== propertyKey || $[55] !== t20) {
13306
+ t21 = /* @__PURE__ */ jsxRuntime.jsx(PropertyIdCopyTooltip, { propertyKey, children: t20 });
13307
+ $[54] = propertyKey;
13308
+ $[55] = t20;
13309
+ $[56] = t21;
13310
+ } else {
13311
+ t21 = $[56];
13312
+ }
13313
+ let t22;
13314
+ if ($[57] !== disabled || $[58] !== includeDescription || $[59] !== property || $[60] !== resolvedError || $[61] !== shouldShowError) {
13315
+ t22 = /* @__PURE__ */ jsxRuntime.jsx(FieldHelperText, { includeDescription, showError: shouldShowError, error: resolvedError, disabled, property });
13316
+ $[57] = disabled;
13317
+ $[58] = includeDescription;
13318
+ $[59] = property;
13319
+ $[60] = resolvedError;
13320
+ $[61] = shouldShowError;
13321
+ $[62] = t22;
13322
+ } else {
13323
+ t22 = $[62];
13324
+ }
13325
+ let t23;
13326
+ if ($[63] !== t21 || $[64] !== t22) {
13327
+ t23 = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
13328
+ t21,
13329
+ t22
13330
+ ] });
13331
+ $[63] = t21;
13332
+ $[64] = t22;
13333
+ $[65] = t23;
13334
+ } else {
13335
+ t23 = $[65];
13336
+ }
13337
+ return t23;
13338
+ }
12952
13339
  function ReadOnlyFieldBinding(t0) {
12953
13340
  const $ = reactCompilerRuntime.c(18);
12954
13341
  const {
@@ -13568,7 +13955,7 @@
13568
13955
  } else {
13569
13956
  t42 = $[20];
13570
13957
  }
13571
- t3 = Object.entries(mapProperties).filter(_temp$o).map(t42);
13958
+ t3 = Object.entries(mapProperties).filter(_temp$p).map(t42);
13572
13959
  $[6] = autoFocus;
13573
13960
  $[7] = context;
13574
13961
  $[8] = disabled;
@@ -13647,7 +14034,7 @@
13647
14034
  }
13648
14035
  return t10;
13649
14036
  }
13650
- function _temp$o(t0) {
14037
+ function _temp$p(t0) {
13651
14038
  const [, property_0] = t0;
13652
14039
  return !isHidden(property_0);
13653
14040
  }
@@ -15021,7 +15408,7 @@
15021
15408
  const property = t4;
15022
15409
  let t5;
15023
15410
  if ($[9] !== properties) {
15024
- t5 = Object.entries(properties).map(_temp$n);
15411
+ t5 = Object.entries(properties).map(_temp$o);
15025
15412
  $[9] = properties;
15026
15413
  $[10] = t5;
15027
15414
  } else {
@@ -15114,7 +15501,7 @@
15114
15501
  }
15115
15502
  return t11;
15116
15503
  }
15117
- function _temp$n(t0) {
15504
+ function _temp$o(t0) {
15118
15505
  const [key, property_0] = t0;
15119
15506
  return {
15120
15507
  id: key,
@@ -17235,24 +17622,27 @@
17235
17622
  function propertiesToColumns({
17236
17623
  properties,
17237
17624
  sortable: sortable2,
17238
- forceFilter,
17239
- AdditionalHeaderWidget
17625
+ forcedFilters,
17626
+ AdditionalHeaderWidget,
17627
+ allowedFilters
17240
17628
  }) {
17241
- const disabledFilter = Boolean(forceFilter);
17242
17629
  return Object.entries(properties).flatMap(([key, property]) => getColumnKeysForProperty(property, key)).map(({
17243
17630
  key,
17244
17631
  disabled
17245
17632
  }) => {
17246
17633
  const property = getResolvedPropertyInPath(properties, key);
17247
17634
  if (!property) throw Error("Internal error: no property found in path " + key);
17248
- const filterable = filterableProperty(property);
17635
+ const filterable = property.dataType === "array" ? isDataTypeFilterable(property.of?.dataType, true) : isDataTypeFilterable(property.dataType);
17636
+ const isFilterForced = forcedFilters?.includes(key) ?? false;
17637
+ const isFilterAllowed = allowedFilters ? allowedFilters.includes(key) : filterable;
17638
+ const filterEnabled = filterable && isFilterAllowed && !isFilterForced;
17249
17639
  return {
17250
17640
  key,
17251
17641
  align: getTableCellAlignment(property),
17252
17642
  icon: getIconForProperty(property, "small"),
17253
17643
  title: property.name ?? key,
17254
17644
  sortable: sortable2,
17255
- filter: !disabledFilter && filterable,
17645
+ filter: filterEnabled,
17256
17646
  width: getTablePropertyColumnWidth(property),
17257
17647
  resizable: true,
17258
17648
  custom: {
@@ -17265,16 +17655,6 @@
17265
17655
  };
17266
17656
  });
17267
17657
  }
17268
- function filterableProperty(property, partOfArray = false) {
17269
- if (partOfArray) {
17270
- return ["string", "number", "date", "reference"].includes(property.dataType);
17271
- }
17272
- if (property.dataType === "array") {
17273
- if (property.of) return filterableProperty(property.of, true);
17274
- else return false;
17275
- }
17276
- return ["string", "number", "boolean", "date", "reference", "array"].includes(property.dataType);
17277
- }
17278
17658
  const VirtualTableHeader = React.memo(function VirtualTableHeader2(t0) {
17279
17659
  const $ = reactCompilerRuntime.c(61);
17280
17660
  const {
@@ -18106,7 +18486,7 @@
18106
18486
  const currentSort = sortBy ? sortBy[1] : void 0;
18107
18487
  const [columns, setColumns] = React.useState(columnsProp);
18108
18488
  const tableRef = React.useRef(null);
18109
- const endReachCallbackThreshold = React.useRef(0);
18489
+ const lastEndReachedDataLength = React.useRef(void 0);
18110
18490
  const debouncedScroll = useDebounceCallback(onScrollProp, 200);
18111
18491
  const [draggingColumnId, setDraggingColumnId] = React.useState(null);
18112
18492
  const sensors = core.useSensors(core.useSensor(core.PointerSensor, {
@@ -18185,7 +18565,7 @@
18185
18565
  filterRef.current = filterInput;
18186
18566
  }, [filterInput]);
18187
18567
  const scrollToTop = React.useCallback(() => {
18188
- endReachCallbackThreshold.current = 0;
18568
+ lastEndReachedDataLength.current = void 0;
18189
18569
  if (tableRef.current) {
18190
18570
  tableRef.current.scrollTo(tableRef.current?.scrollLeft, 0);
18191
18571
  }
@@ -18211,28 +18591,37 @@
18211
18591
  scrollToTop();
18212
18592
  }, [checkFilterCombination, currentSort, onFilterUpdate, onResetPagination, onSortByUpdate, scrollToTop, sortByProperty]);
18213
18593
  const maxScroll = Math.max((data?.length ?? 0) * rowHeight - bounds.height, 0);
18214
- const onEndReachedInternal = React.useCallback((scrollOffset) => {
18215
- if (onEndReached && (data?.length ?? 0) > 0 && scrollOffset > endReachCallbackThreshold.current + endOffset) {
18216
- endReachCallbackThreshold.current = scrollOffset;
18594
+ const onEndReachedInternal = React.useCallback(() => {
18595
+ const dataLength = data?.length ?? 0;
18596
+ if (onEndReached && dataLength > 0 && lastEndReachedDataLength.current !== dataLength) {
18597
+ lastEndReachedDataLength.current = dataLength;
18217
18598
  onEndReached();
18218
18599
  }
18219
18600
  }, [data?.length, onEndReached]);
18601
+ React.useEffect(() => {
18602
+ if (!onEndReached || loading || !data?.length || !bounds.height || !tableRef.current) {
18603
+ return;
18604
+ }
18605
+ if (tableRef.current.scrollHeight <= tableRef.current.clientHeight) {
18606
+ onEndReachedInternal();
18607
+ }
18608
+ }, [bounds.height, data?.length, loading, onEndReached, onEndReachedInternal]);
18220
18609
  const onScroll = React.useCallback(({
18221
18610
  scrollDirection,
18222
- scrollOffset: scrollOffset_0,
18611
+ scrollOffset,
18223
18612
  scrollUpdateWasRequested
18224
18613
  }) => {
18225
18614
  if (onScrollProp) {
18226
18615
  debouncedScroll({
18227
18616
  scrollDirection,
18228
- scrollOffset: scrollOffset_0,
18617
+ scrollOffset,
18229
18618
  scrollUpdateWasRequested
18230
18619
  });
18231
18620
  }
18232
- if (!scrollUpdateWasRequested && scrollOffset_0 >= maxScroll - endOffset) onEndReachedInternal(scrollOffset_0);
18233
- }, [maxScroll, onEndReachedInternal]);
18621
+ if (!scrollUpdateWasRequested && scrollOffset >= maxScroll - endOffset) onEndReachedInternal();
18622
+ }, [endOffset, maxScroll, onEndReachedInternal]);
18234
18623
  const onFilterUpdateInternal = React.useCallback((column_1, filterForProperty) => {
18235
- endReachCallbackThreshold.current = 0;
18624
+ lastEndReachedDataLength.current = void 0;
18236
18625
  const filter_0 = filterRef.current;
18237
18626
  let newFilterValue = filter_0 ? {
18238
18627
  ...filter_0
@@ -18434,7 +18823,7 @@
18434
18823
  let t1;
18435
18824
  if ($[0] !== text) {
18436
18825
  const urlRegex = /https?:\/\/[^\s]+/g;
18437
- t1 = text.replace(urlRegex, _temp$m);
18826
+ t1 = text.replace(urlRegex, _temp$n);
18438
18827
  $[0] = text;
18439
18828
  $[1] = t1;
18440
18829
  } else {
@@ -18453,7 +18842,7 @@
18453
18842
  }
18454
18843
  return t2;
18455
18844
  };
18456
- function _temp$m(url) {
18845
+ function _temp$n(url) {
18457
18846
  return `<a href="${url}" class="underline" target="_blank">Link</a><br/>`;
18458
18847
  }
18459
18848
  const operationLabels$2 = {
@@ -18527,10 +18916,10 @@
18527
18916
  return path ? navigationController.getCollection(path) : void 0;
18528
18917
  }, [path]);
18529
18918
  const onSingleEntitySelected = (entity) => {
18530
- updateFilter(operation, getReferenceFrom(entity));
18919
+ if (entity) updateFilter(operation, getReferenceFrom(entity));
18531
18920
  };
18532
18921
  const onMultipleEntitiesSelected = (entities) => {
18533
- updateFilter(operation, entities.map((e) => getReferenceFrom(e)));
18922
+ updateFilter(operation, entities.filter(Boolean).map((e) => getReferenceFrom(e)));
18534
18923
  };
18535
18924
  const multiple = multipleSelectOperations$2.includes(operation);
18536
18925
  const referenceDialogController = useReferenceDialog({
@@ -18705,7 +19094,7 @@
18705
19094
  }
18706
19095
  let t8;
18707
19096
  if ($[20] !== operation || $[21] !== t6 || $[22] !== t7) {
18708
- t8 = /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-[100px]", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Select, { value: operation, size: "medium", fullWidth: true, position: "item-aligned", onValueChange: t6, renderValue: _temp$l, children: t7 }) });
19097
+ t8 = /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-[100px]", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Select, { value: operation, size: "medium", fullWidth: true, position: "item-aligned", onValueChange: t6, renderValue: _temp$m, children: t7 }) });
18709
19098
  $[20] = operation;
18710
19099
  $[21] = t6;
18711
19100
  $[22] = t7;
@@ -18759,7 +19148,7 @@
18759
19148
  let t11;
18760
19149
  if ($[40] !== dataType || $[41] !== enumValues || $[42] !== internalValue || $[43] !== isNullOperation || $[44] !== multiple || $[45] !== name || $[46] !== operation || $[47] !== updateFilter) {
18761
19150
  t11 = enumValues && multiple && /* @__PURE__ */ jsxRuntime.jsx(ui.MultiSelect, { size: "medium", position: "item-aligned", value: Array.isArray(internalValue) ? internalValue.map(_temp3$3) : [], disabled: isNullOperation, onValueChange: (value_2) => {
18762
- updateFilter(operation, dataType === "number" ? value_2.map(_temp4$2) : value_2);
19151
+ updateFilter(operation, dataType === "number" ? value_2.map(_temp4$3) : value_2);
18763
19152
  }, multiple, endAdornment: internalValue && /* @__PURE__ */ jsxRuntime.jsx(ui.IconButton, { className: "absolute right-2 top-3", onClick: (e_2) => updateFilter(operation, void 0), children: /* @__PURE__ */ jsxRuntime.jsx(ui.CloseIcon, {}) }), children: enumValues.map((enumConfig_0) => /* @__PURE__ */ jsxRuntime.jsx(ui.MultiSelectItem, { value: String(enumConfig_0.id), children: /* @__PURE__ */ jsxRuntime.jsx(EnumValuesChip, { enumKey: String(enumConfig_0.id), enumValues, size: "small" }) }, `select_value_${name}_${enumConfig_0.id}`)) });
18764
19153
  $[40] = dataType;
18765
19154
  $[41] = enumValues;
@@ -18801,7 +19190,7 @@
18801
19190
  }
18802
19191
  return t13;
18803
19192
  }
18804
- function _temp4$2(v) {
19193
+ function _temp4$3(v) {
18805
19194
  return parseInt(v);
18806
19195
  }
18807
19196
  function _temp3$3(e_1) {
@@ -18810,7 +19199,7 @@
18810
19199
  function _temp2$6(op_2) {
18811
19200
  return /* @__PURE__ */ jsxRuntime.jsx(ui.SelectItem, { value: op_2, children: operationLabels$1[op_2] }, op_2);
18812
19201
  }
18813
- function _temp$l(op_1) {
19202
+ function _temp$m(op_1) {
18814
19203
  return operationLabels$1[op_1];
18815
19204
  }
18816
19205
  function BooleanFilterField(t0) {
@@ -18981,7 +19370,7 @@
18981
19370
  }
18982
19371
  let t8;
18983
19372
  if ($[17] !== operation || $[18] !== t6 || $[19] !== t7) {
18984
- t8 = /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-[100px]", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Select, { value: operation, size: "medium", fullWidth: true, onValueChange: t6, renderValue: _temp$k, children: t7 }) });
19373
+ t8 = /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-[100px]", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Select, { value: operation, size: "medium", fullWidth: true, onValueChange: t6, renderValue: _temp$l, children: t7 }) });
18985
19374
  $[17] = operation;
18986
19375
  $[18] = t6;
18987
19376
  $[19] = t7;
@@ -19031,7 +19420,7 @@
19031
19420
  function _temp2$5(op_2) {
19032
19421
  return /* @__PURE__ */ jsxRuntime.jsx(ui.SelectItem, { value: op_2, children: operationLabels[op_2] }, op_2);
19033
19422
  }
19034
- function _temp$k(op_1) {
19423
+ function _temp$l(op_1) {
19035
19424
  return operationLabels[op_1];
19036
19425
  }
19037
19426
  const SelectableTable = function SelectableTable2({
@@ -19281,7 +19670,8 @@
19281
19670
  const columnsResult = propertiesToColumns({
19282
19671
  properties,
19283
19672
  sortable: sortable2,
19284
- forceFilter,
19673
+ forcedFilters: tableController.forcedFilters,
19674
+ allowedFilters: tableController.allowedFilters,
19285
19675
  AdditionalHeaderWidget
19286
19676
  });
19287
19677
  const propertyColumnKeys = new Set(columnsResult.map((col) => col.key));
@@ -19428,7 +19818,26 @@
19428
19818
  filterValues: initialFilterUrl,
19429
19819
  sortBy: initialSortUrl
19430
19820
  } = parseFilterAndSort(location.search);
19431
- const [filterValues_0, setFilterValues] = React.useState(forceFilter ?? (updateUrl ? initialFilterUrl : void 0) ?? initialFilter ?? void 0);
19821
+ const availableFilterKeys = collection.allowedFilters ?? Object.keys(collection.properties);
19822
+ const forcedFilterKeys = collection.forceFilter ? Object.keys(collection.forceFilter) : [];
19823
+ const allowedFilterKeys = React.useMemo(() => {
19824
+ const availableKeys = availableFilterKeys.filter((key) => {
19825
+ const property = collection.properties[key];
19826
+ if (!property) return false;
19827
+ if (typeof property === "function") return false;
19828
+ const dataType = property.dataType;
19829
+ const filterable = dataType === "array" ? isDataTypeFilterable(property.of?.dataType, true) : isDataTypeFilterable(dataType);
19830
+ return filterable;
19831
+ });
19832
+ const forcedKeys = forcedFilterKeys.filter((key_0) => !availableKeys.includes(key_0));
19833
+ return [...availableKeys, ...forcedKeys];
19834
+ }, [collection.properties, availableFilterKeys, forcedFilterKeys]);
19835
+ const removeUnallowedFilters = React.useCallback((filters) => {
19836
+ if (!filters) return;
19837
+ return Object.fromEntries(Object.entries(filters).filter(([key_1]) => allowedFilterKeys.includes(key_1)));
19838
+ }, [allowedFilterKeys]);
19839
+ const initFilters = forceFilter ?? (updateUrl ? initialFilterUrl : void 0) ?? initialFilter ?? void 0;
19840
+ const [filterValues_0, setFilterValues] = React.useState(removeUnallowedFilters(initFilters));
19432
19841
  const [sortBy_0, setSortBy] = React.useState((updateUrl ? initialSortUrl : void 0) ?? initialSortInternal);
19433
19842
  useUpdateUrl(filterValues_0, sortBy_0, searchString, updateUrl);
19434
19843
  const collectionScroll = scrollRestoration?.getCollectionScroll(fullPath, filterValues_0);
@@ -19451,7 +19860,7 @@
19451
19860
  const [dataLoading, setDataLoading] = React.useState(false);
19452
19861
  const [dataLoadingError, setDataLoadingError] = React.useState();
19453
19862
  const [noMoreToLoad, setNoMoreToLoad] = React.useState(false);
19454
- const clearFilter = React.useCallback(() => setFilterValues(forceFilter ?? void 0), [forceFilter]);
19863
+ const clearFilter = React.useCallback(() => setFilterValues(removeUnallowedFilters(forceFilter)), [forceFilter, removeUnallowedFilters]);
19455
19864
  const updateFilterValues = React.useCallback((updatedFilter) => {
19456
19865
  if (forceFilter) {
19457
19866
  console.warn("Filter is not compatible with the force filter. Ignoring filter");
@@ -19460,9 +19869,9 @@
19460
19869
  if (updatedFilter && Object.keys(updatedFilter).length === 0) {
19461
19870
  setFilterValues(void 0);
19462
19871
  } else {
19463
- setFilterValues(updatedFilter);
19872
+ setFilterValues(removeUnallowedFilters(updatedFilter));
19464
19873
  }
19465
- }, [forceFilter]);
19874
+ }, [forceFilter, removeUnallowedFilters]);
19466
19875
  React.useEffect(() => {
19467
19876
  setDataLoading(true);
19468
19877
  const onEntitiesUpdate = async (entities) => {
@@ -19537,6 +19946,8 @@
19537
19946
  dataLoadingError,
19538
19947
  filterValues: filterValues_0,
19539
19948
  setFilterValues: updateFilterValues,
19949
+ allowedFilters: allowedFilterKeys,
19950
+ forcedFilters: forcedFilterKeys,
19540
19951
  sortBy: sortBy_0,
19541
19952
  setSortBy,
19542
19953
  searchString,
@@ -19617,7 +20028,7 @@
19617
20028
  }
19618
20029
  if (encodedValue !== void 0) {
19619
20030
  entries[encodeURIComponent(`${key}_op`)] = encodeURIComponent(op);
19620
- entries[encodeURIComponent(`${key}_value`)] = encodedValue ? encodeURIComponent(encodedValue.toString()) : "null";
20031
+ entries[encodeURIComponent(`${key}_value`)] = encodedValue !== null && encodedValue !== void 0 ? encodeURIComponent(encodedValue.toString()) : "null";
19621
20032
  }
19622
20033
  }
19623
20034
  });
@@ -19657,7 +20068,12 @@
19657
20068
  return date.toISOString() === dateString;
19658
20069
  }
19659
20070
  function encodeRef(val) {
19660
- return `ref::${val.path}/${val.id}`;
20071
+ return `ref::${val.path}/${encodeEntityId(val.id)}`;
20072
+ }
20073
+ function decodeRef(encoded) {
20074
+ const separatorIndex = encoded.lastIndexOf("/");
20075
+ if (separatorIndex < 0) return new EntityReference(encoded, "");
20076
+ return new EntityReference(decodeEntityId(encoded.substring(separatorIndex + 1)), encoded.substring(0, separatorIndex));
19661
20077
  }
19662
20078
  function decodeString(val) {
19663
20079
  let parsedFilterVal = val;
@@ -19671,8 +20087,7 @@
19671
20087
  try {
19672
20088
  parsedFilterVal = JSON.parse(parsedFilterVal, (key, value) => {
19673
20089
  if (typeof value === "string" && value.startsWith("ref::")) {
19674
- const [path, id] = value.substring(5).split("/");
19675
- return new EntityReference(id, path);
20090
+ return decodeRef(value.substring(5));
19676
20091
  }
19677
20092
  return value;
19678
20093
  });
@@ -19680,8 +20095,7 @@
19680
20095
  }
19681
20096
  }
19682
20097
  if (typeof parsedFilterVal === "string" && parsedFilterVal.startsWith("ref::")) {
19683
- const [path, id] = parsedFilterVal.substring(5).split("/");
19684
- return new EntityReference(id, path);
20098
+ return decodeRef(parsedFilterVal.substring(5));
19685
20099
  }
19686
20100
  return parsedFilterVal;
19687
20101
  }
@@ -19760,7 +20174,7 @@
19760
20174
  const searchBlocked = t12;
19761
20175
  let t2;
19762
20176
  if ($[15] !== customizationController.plugins || $[16] !== dataSource?.initTextSearch) {
19763
- t2 = Boolean(dataSource?.initTextSearch) || customizationController.plugins?.find(_temp$j);
20177
+ t2 = Boolean(dataSource?.initTextSearch) || customizationController.plugins?.find(_temp$k);
19764
20178
  $[15] = customizationController.plugins;
19765
20179
  $[16] = dataSource?.initTextSearch;
19766
20180
  $[17] = t2;
@@ -19852,7 +20266,7 @@
19852
20266
  }
19853
20267
  return t1;
19854
20268
  }
19855
- function _temp$j(p_0) {
20269
+ function _temp$k(p_0) {
19856
20270
  return Boolean(p_0.collectionView?.onTextSearchClick);
19857
20271
  }
19858
20272
  function DeleteEntityDialog({
@@ -20474,7 +20888,7 @@
20474
20888
  T0 = ui.Collapse;
20475
20889
  t4 = favouriteCollections.length > 0;
20476
20890
  t2 = "flex flex-row flex-wrap gap-2 pb-2 min-h-[32px]";
20477
- t3 = favouriteCollections.map(_temp$i);
20891
+ t3 = favouriteCollections.map(_temp$j);
20478
20892
  $[2] = navigationController;
20479
20893
  $[3] = t1;
20480
20894
  $[4] = T0;
@@ -20508,7 +20922,7 @@
20508
20922
  }
20509
20923
  return t6;
20510
20924
  }
20511
- function _temp$i(entry_0) {
20925
+ function _temp$j(entry_0) {
20512
20926
  return /* @__PURE__ */ jsxRuntime.jsx(NavigationChip, { entry: entry_0 }, entry_0.path);
20513
20927
  }
20514
20928
  const scrollsMap = {};
@@ -20745,7 +21159,7 @@
20745
21159
  }
20746
21160
  let t4;
20747
21161
  if ($[4] !== actions) {
20748
- t4 = /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-0.5", onClick: _temp$h, children: actions });
21162
+ t4 = /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-0.5", onClick: _temp$i, children: actions });
20749
21163
  $[4] = actions;
20750
21164
  $[5] = t4;
20751
21165
  } else {
@@ -20832,7 +21246,7 @@
20832
21246
  }
20833
21247
  return t12;
20834
21248
  });
20835
- function _temp$h(event) {
21249
+ function _temp$i(event) {
20836
21250
  event.preventDefault();
20837
21251
  event.stopPropagation();
20838
21252
  }
@@ -23188,7 +23602,7 @@
23188
23602
  let t19;
23189
23603
  let t20;
23190
23604
  if ($[19] !== items2) {
23191
- t20 = items2.map(_temp$g);
23605
+ t20 = items2.map(_temp$h);
23192
23606
  $[19] = items2;
23193
23607
  $[20] = t20;
23194
23608
  } else {
@@ -23294,7 +23708,7 @@
23294
23708
  }
23295
23709
  return t29;
23296
23710
  });
23297
- function _temp$g(i) {
23711
+ function _temp$h(i) {
23298
23712
  return i.id;
23299
23713
  }
23300
23714
  function Board(t0) {
@@ -25230,7 +25644,8 @@
25230
25644
  properties,
25231
25645
  filterValues,
25232
25646
  setFilterValues,
25233
- forceFilter
25647
+ forceFilter,
25648
+ allowedFilters
25234
25649
  }) {
25235
25650
  const {
25236
25651
  t
@@ -25242,15 +25657,14 @@
25242
25657
  setLocalFilters(filterValues ?? {});
25243
25658
  }
25244
25659
  }, [open, filterValues]);
25245
- const filterableProperties = React.useMemo(() => {
25246
- return Object.entries(properties).filter(([key, property]) => {
25247
- if (!property) return false;
25248
- if (forceFilter && key in forceFilter) return false;
25249
- const baseProperty = property.dataType === "array" ? property.of : property;
25250
- if (!baseProperty) return false;
25251
- return ["string", "number", "boolean", "date", "reference"].includes(baseProperty.dataType);
25660
+ const editableFilterProperties = React.useMemo(() => {
25661
+ return Object.entries(properties).filter(([key]) => {
25662
+ const isFilterAllowed = !allowedFilters || allowedFilters.includes(key);
25663
+ const isFilterForced = Boolean(forceFilter && Object.keys(forceFilter).includes(key));
25664
+ return isFilterAllowed && !isFilterForced;
25252
25665
  });
25253
- }, [properties, forceFilter]);
25666
+ }, [properties, allowedFilters, forceFilter]);
25667
+ const hasEditableFilterProperties = editableFilterProperties.length > 0;
25254
25668
  const handleFilterChange = React.useCallback((propertyKey, value) => {
25255
25669
  setLocalFilters((prev) => {
25256
25670
  const newFilters = {
@@ -25282,22 +25696,26 @@
25282
25696
  }));
25283
25697
  }, []);
25284
25698
  const isAnyFieldHidden = Object.values(hiddenFields).some((hidden_0) => hidden_0);
25285
- const activeFilterCount = Object.keys(localFilters).length;
25286
- const renderFilterField = React.useCallback((propertyKey_1, property_0) => {
25287
- const isArray = property_0.dataType === "array";
25288
- const baseProperty_0 = isArray ? property_0.of : property_0;
25289
- if (!baseProperty_0) return null;
25699
+ const getActiveFilterCount = () => {
25700
+ const editableLocalFilters = Object.keys(localFilters).filter((key_0) => !forceFilter || !(key_0 in forceFilter));
25701
+ return editableLocalFilters.length;
25702
+ };
25703
+ const activeFilterCount = getActiveFilterCount();
25704
+ const renderFilterField = React.useCallback((propertyKey_1, property) => {
25705
+ const isArray = property.dataType === "array";
25706
+ const baseProperty = isArray ? property.of : property;
25707
+ if (!baseProperty) return null;
25290
25708
  const filterValue = localFilters[propertyKey_1];
25291
25709
  const setValue = (value_0) => handleFilterChange(propertyKey_1, value_0);
25292
- if (baseProperty_0.dataType === "reference") {
25293
- return /* @__PURE__ */ jsxRuntime.jsx(ReferenceFilterField, { value: filterValue, setValue, name: propertyKey_1, isArray, path: baseProperty_0.path, title: property_0.name, includeId: baseProperty_0.includeId, previewProperties: baseProperty_0.previewProperties, hidden: hiddenFields[propertyKey_1] ?? false, setHidden: (hidden_1) => setHiddenForField(propertyKey_1, hidden_1) });
25294
- } else if (baseProperty_0.dataType === "number" || baseProperty_0.dataType === "string") {
25295
- const enumValues = baseProperty_0.enumValues ? enumToObjectEntries(baseProperty_0.enumValues) : void 0;
25296
- return /* @__PURE__ */ jsxRuntime.jsx(StringNumberFilterField, { value: filterValue, setValue, name: propertyKey_1, dataType: baseProperty_0.dataType, isArray, enumValues, title: property_0.name });
25297
- } else if (baseProperty_0.dataType === "boolean") {
25298
- return /* @__PURE__ */ jsxRuntime.jsx(BooleanFilterField, { value: filterValue, setValue, name: propertyKey_1, title: property_0.name });
25299
- } else if (baseProperty_0.dataType === "date") {
25300
- return /* @__PURE__ */ jsxRuntime.jsx(DateTimeFilterField, { value: filterValue, setValue, name: propertyKey_1, mode: baseProperty_0.mode, isArray, title: property_0.name });
25710
+ if (baseProperty.dataType === "reference") {
25711
+ return /* @__PURE__ */ jsxRuntime.jsx(ReferenceFilterField, { value: filterValue, setValue, name: propertyKey_1, isArray, path: baseProperty.path, title: property.name, includeId: baseProperty.includeId, previewProperties: baseProperty.previewProperties, hidden: hiddenFields[propertyKey_1] ?? false, setHidden: (hidden_1) => setHiddenForField(propertyKey_1, hidden_1) });
25712
+ } else if (baseProperty.dataType === "number" || baseProperty.dataType === "string") {
25713
+ const enumValues = baseProperty.enumValues ? enumToObjectEntries(baseProperty.enumValues) : void 0;
25714
+ return /* @__PURE__ */ jsxRuntime.jsx(StringNumberFilterField, { value: filterValue, setValue, name: propertyKey_1, dataType: baseProperty.dataType, isArray, enumValues, title: property.name });
25715
+ } else if (baseProperty.dataType === "boolean") {
25716
+ return /* @__PURE__ */ jsxRuntime.jsx(BooleanFilterField, { value: filterValue, setValue, name: propertyKey_1, title: property.name });
25717
+ } else if (baseProperty.dataType === "date") {
25718
+ return /* @__PURE__ */ jsxRuntime.jsx(DateTimeFilterField, { value: filterValue, setValue, name: propertyKey_1, mode: baseProperty.mode, isArray, title: property.name });
25301
25719
  }
25302
25720
  return null;
25303
25721
  }, [localFilters, handleFilterChange, hiddenFields, setHiddenForField]);
@@ -25306,23 +25724,25 @@
25306
25724
  /* @__PURE__ */ jsxRuntime.jsx(ui.Typography, { variant: "h6", children: t("filters") }),
25307
25725
  activeFilterCount > 0 && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "ml-2 px-2 py-0.5 text-xs rounded-full bg-primary text-white", children: activeFilterCount })
25308
25726
  ] }),
25309
- /* @__PURE__ */ jsxRuntime.jsx(ui.DialogContent, { children: filterableProperties.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx(ui.Typography, { color: "secondary", className: "py-8 text-center", children: t("no_filterable_properties") }) : /* @__PURE__ */ jsxRuntime.jsx("table", { className: "w-full border-collapse", children: /* @__PURE__ */ jsxRuntime.jsx("tbody", { children: filterableProperties.map(([propertyKey_2, property_1], index) => {
25727
+ /* @__PURE__ */ jsxRuntime.jsx(ui.DialogContent, { children: !hasEditableFilterProperties ? /* @__PURE__ */ jsxRuntime.jsx(ui.Typography, { color: "secondary", className: "py-8 text-center", children: t("no_filterable_properties") }) : /* @__PURE__ */ jsxRuntime.jsx("table", { className: "w-full border-collapse", children: /* @__PURE__ */ jsxRuntime.jsx("tbody", { children: editableFilterProperties.map(([propertyKey_2, property_0], index) => {
25310
25728
  const hasFilter = propertyKey_2 in localFilters;
25311
25729
  return /* @__PURE__ */ jsxRuntime.jsxs("tr", { className: ui.cls(index > 0 && "border-t", ui.defaultBorderMixin), children: [
25312
- /* @__PURE__ */ jsxRuntime.jsx("td", { className: "py-3 pr-4 align-middle w-[160px]", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Typography, { variant: "body2", className: ui.cls("font-medium", hasFilter && "text-primary"), children: property_1.name || propertyKey_2 }) }),
25313
- /* @__PURE__ */ jsxRuntime.jsx("td", { className: "py-3", children: renderFilterField(propertyKey_2, property_1) })
25730
+ /* @__PURE__ */ jsxRuntime.jsx("td", { className: "py-3 pr-4 align-middle w-[160px]", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Typography, { variant: "body2", className: ui.cls("font-medium", hasFilter && "text-primary"), children: property_0.name || propertyKey_2 }) }),
25731
+ /* @__PURE__ */ jsxRuntime.jsx("td", { className: "py-3", children: renderFilterField(propertyKey_2, property_0) })
25314
25732
  ] }, propertyKey_2);
25315
25733
  }) }) }) }),
25316
25734
  /* @__PURE__ */ jsxRuntime.jsxs(ui.DialogActions, { children: [
25317
25735
  /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "text", onClick: handleClearAll, disabled: activeFilterCount === 0, children: t("clear") }),
25318
25736
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-grow" }),
25319
- /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "text", onClick: () => onOpenChange(false), children: t("cancel") }),
25320
- /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "filled", onClick: handleApply, children: t("apply_filters") })
25737
+ hasEditableFilterProperties && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
25738
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "text", onClick: () => onOpenChange(false), children: t("cancel") }),
25739
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "filled", onClick: handleApply, children: t("apply_filters") })
25740
+ ] })
25321
25741
  ] })
25322
25742
  ] });
25323
25743
  }
25324
25744
  function EntityCollectionViewStartActions(t0) {
25325
- const $ = reactCompilerRuntime.c(36);
25745
+ const $ = reactCompilerRuntime.c(37);
25326
25746
  const {
25327
25747
  collection,
25328
25748
  relativePath,
@@ -25386,34 +25806,36 @@
25386
25806
  t3 = $[13];
25387
25807
  }
25388
25808
  const actionProps = t3;
25809
+ const hasAnyAllowedFilters = !tableController.allowedFilters || tableController.allowedFilters.length > 0;
25389
25810
  let t4;
25390
- if ($[14] !== activeFilterCount || $[15] !== largeLayout || $[16] !== resolvedProperties || $[17] !== t || $[18] !== tableController.setFilterValues) {
25391
- t4 = resolvedProperties && tableController.setFilterValues && /* @__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: [
25811
+ if ($[14] !== activeFilterCount || $[15] !== hasAnyAllowedFilters || $[16] !== largeLayout || $[17] !== resolvedProperties || $[18] !== t || $[19] !== tableController.setFilterValues) {
25812
+ 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: [
25392
25813
  t("filters"),
25393
25814
  activeFilterCount > 0 ? ` (${activeFilterCount})` : ""
25394
25815
  ] }) : /* @__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");
25395
25816
  $[14] = activeFilterCount;
25396
- $[15] = largeLayout;
25397
- $[16] = resolvedProperties;
25398
- $[17] = t;
25399
- $[18] = tableController.setFilterValues;
25400
- $[19] = t4;
25817
+ $[15] = hasAnyAllowedFilters;
25818
+ $[16] = largeLayout;
25819
+ $[17] = resolvedProperties;
25820
+ $[18] = t;
25821
+ $[19] = tableController.setFilterValues;
25822
+ $[20] = t4;
25401
25823
  } else {
25402
- t4 = $[19];
25824
+ t4 = $[20];
25403
25825
  }
25404
25826
  const filtersButton = t4;
25405
25827
  const t5 = !collection.forceFilter;
25406
25828
  let t6;
25407
- if ($[20] !== t5 || $[21] !== tableController) {
25829
+ if ($[21] !== t5 || $[22] !== tableController) {
25408
25830
  t6 = /* @__PURE__ */ jsxRuntime.jsx(ClearFilterSortButton, { tableController, enabled: t5 }, "clear_filter");
25409
- $[20] = t5;
25410
- $[21] = tableController;
25411
- $[22] = t6;
25831
+ $[21] = t5;
25832
+ $[22] = tableController;
25833
+ $[23] = t6;
25412
25834
  } else {
25413
- t6 = $[22];
25835
+ t6 = $[23];
25414
25836
  }
25415
25837
  let actions;
25416
- if ($[23] !== actionProps || $[24] !== filtersButton || $[25] !== plugins || $[26] !== t6) {
25838
+ if ($[24] !== actionProps || $[25] !== filtersButton || $[26] !== plugins || $[27] !== t6) {
25417
25839
  actions = [filtersButton, t6];
25418
25840
  if (plugins) {
25419
25841
  plugins.forEach((plugin, i) => {
@@ -25422,39 +25844,42 @@
25422
25844
  }
25423
25845
  });
25424
25846
  }
25425
- $[23] = actionProps;
25426
- $[24] = filtersButton;
25427
- $[25] = plugins;
25428
- $[26] = t6;
25429
- $[27] = actions;
25847
+ $[24] = actionProps;
25848
+ $[25] = filtersButton;
25849
+ $[26] = plugins;
25850
+ $[27] = t6;
25851
+ $[28] = actions;
25430
25852
  } else {
25431
- actions = $[27];
25853
+ actions = $[28];
25432
25854
  }
25433
25855
  let t7;
25434
- if ($[28] !== collection.forceFilter || $[29] !== filtersDialogOpen || $[30] !== resolvedProperties || $[31] !== tableController) {
25435
- 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 });
25436
- $[28] = collection.forceFilter;
25437
- $[29] = filtersDialogOpen;
25438
- $[30] = resolvedProperties;
25439
- $[31] = tableController;
25440
- $[32] = t7;
25856
+ if ($[29] !== collection.forceFilter || $[30] !== filtersDialogOpen || $[31] !== resolvedProperties || $[32] !== tableController) {
25857
+ 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) });
25858
+ $[29] = collection.forceFilter;
25859
+ $[30] = filtersDialogOpen;
25860
+ $[31] = resolvedProperties;
25861
+ $[32] = tableController;
25862
+ $[33] = t7;
25441
25863
  } else {
25442
- t7 = $[32];
25864
+ t7 = $[33];
25443
25865
  }
25444
25866
  let t8;
25445
- if ($[33] !== actions || $[34] !== t7) {
25867
+ if ($[34] !== actions || $[35] !== t7) {
25446
25868
  t8 = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
25447
25869
  actions,
25448
25870
  t7
25449
25871
  ] });
25450
- $[33] = actions;
25451
- $[34] = t7;
25452
- $[35] = t8;
25872
+ $[34] = actions;
25873
+ $[35] = t7;
25874
+ $[36] = t8;
25453
25875
  } else {
25454
- t8 = $[35];
25876
+ t8 = $[36];
25455
25877
  }
25456
25878
  return t8;
25457
25879
  }
25880
+ function _temp$g(key_0) {
25881
+ return key_0.toString();
25882
+ }
25458
25883
  const collectionScrollCache = /* @__PURE__ */ new Map();
25459
25884
  function useScrollRestoration() {
25460
25885
  const updateCollectionScroll = ({
@@ -25513,7 +25938,12 @@
25513
25938
  const scrollRestoration = useScrollRestoration();
25514
25939
  const collection = React.useMemo(() => {
25515
25940
  const userOverride = userConfigPersistence?.getCollectionConfig(fullPath);
25516
- return userOverride ? mergeDeep(collectionProp, userOverride) : collectionProp;
25941
+ if (!userOverride) return collectionProp;
25942
+ const {
25943
+ properties,
25944
+ ...rest
25945
+ } = userOverride;
25946
+ return mergeDeep(collectionProp, rest);
25517
25947
  }, [collectionProp, fullPath, userConfigPersistence?.getCollectionConfig]);
25518
25948
  const openEntityMode = collection?.openEntityMode ?? DEFAULT_ENTITY_OPEN_MODE;
25519
25949
  const collectionRef = React.useRef(collection);
@@ -25767,11 +26197,12 @@
25767
26197
  collection,
25768
26198
  path: fullPath,
25769
26199
  propertyConfigs: customizationController.propertyConfigs,
25770
- authController
25771
- }), [collection, fullPath]);
26200
+ authController,
26201
+ userConfigPersistence
26202
+ }), [collection, fullPath, userConfigPersistence]);
25772
26203
  const hasEnumProperty = React.useMemo(() => {
25773
- const properties = resolvedCollection.properties;
25774
- return Object.values(properties).some((prop) => prop && prop.dataType === "string" && prop.enumValues);
26204
+ const properties_0 = resolvedCollection.properties;
26205
+ return Object.values(properties_0).some((prop) => prop && prop.dataType === "string" && prop.enumValues);
25775
26206
  }, [resolvedCollection.properties]);
25776
26207
  const enabledViews = React.useMemo(() => {
25777
26208
  const configured = collection.enabledViews ?? ["table", "cards", "kanban"];
@@ -25782,8 +26213,8 @@
25782
26213
  }, [collection.enabledViews, hasEnumProperty]);
25783
26214
  const kanbanPropertyOptions = React.useMemo(() => {
25784
26215
  const options = [];
25785
- const properties_0 = resolvedCollection.properties;
25786
- for (const [key_0, property_0] of Object.entries(properties_0)) {
26216
+ const properties_1 = resolvedCollection.properties;
26217
+ for (const [key_0, property_0] of Object.entries(properties_1)) {
25787
26218
  const prop_0 = property_0;
25788
26219
  if (prop_0 && prop_0.dataType === "string" && prop_0.enumValues) {
25789
26220
  options.push({
@@ -27146,7 +27577,7 @@
27146
27577
  const onMultipleEntitiesSelected = React.useCallback((entities) => {
27147
27578
  if (disabled) return;
27148
27579
  if (onMultipleReferenceSelected) {
27149
- const references = entities ? entities.map((e) => getReferenceFrom(e)) : null;
27580
+ const references = entities ? entities.filter(Boolean).map((e) => getReferenceFrom(e)) : null;
27150
27581
  onMultipleReferenceSelected({
27151
27582
  references,
27152
27583
  entities
@@ -27855,7 +28286,7 @@
27855
28286
  const restOfThePath = removeInitialAndTrailingSlashes(removeInitialAndTrailingSlashes(path).replace(subpathCombination, ""));
27856
28287
  const nextSegments = restOfThePath.length > 0 ? restOfThePath.split("/") : [];
27857
28288
  if (nextSegments.length > 0) {
27858
- const entityId = nextSegments[0];
28289
+ const entityId = decodeEntityId(nextSegments[0]);
27859
28290
  const fullPath = collectionPath + "/" + entityId;
27860
28291
  result.push(new EntityReference(entityId, collectionPath));
27861
28292
  if (nextSegments.length > 1) {
@@ -28086,7 +28517,14 @@
28086
28517
  if (!collections_0) return void 0;
28087
28518
  const baseCollection = getCollectionByPathOrId(removeInitialAndTrailingSlashes(idOrPath), collections_0);
28088
28519
  const userOverride = includeUserOverride ? userConfigPersistence?.getCollectionConfig(idOrPath) : void 0;
28089
- const overriddenCollection = baseCollection ? mergeDeep(baseCollection, userOverride ?? {}) : void 0;
28520
+ let overriddenCollection = baseCollection;
28521
+ if (baseCollection && userOverride) {
28522
+ const {
28523
+ properties,
28524
+ ...rest
28525
+ } = userOverride;
28526
+ overriddenCollection = mergeDeep(baseCollection, rest);
28527
+ }
28090
28528
  let result = overriddenCollection;
28091
28529
  if (overriddenCollection) {
28092
28530
  const subcollections = overriddenCollection.subcollections;
@@ -29594,18 +30032,15 @@
29594
30032
  const actionsAtTheBottom = !largeLayout || layout === "side_panel" || selectedEntityView?.includeActions === "bottom";
29595
30033
  const mainViewVisible = selectedTab === MAIN_TAB_VALUE || Boolean(selectedSecondaryForm);
29596
30034
  const authController = useAuthController();
29597
- const customViewsView = customViews && resolvedEntityViews.filter((e) => !e.includeActions).map((customView) => {
29598
- if (!customView) return null;
29599
- const Builder = customView.Builder;
29600
- if (!Builder) {
29601
- console.error("INTERNAL: customView.Builder is not defined");
29602
- return null;
29603
- }
29604
- if (!entityId) {
29605
- return null;
29606
- }
30035
+ const mountedTabsRef = React.useRef(/* @__PURE__ */ new Set());
30036
+ if (selectedTab) {
30037
+ mountedTabsRef.current.add(selectedTab);
30038
+ }
30039
+ const readOnlyFormContext = React.useMemo(() => {
30040
+ if (formContext) return void 0;
30041
+ if (!entityId) return void 0;
29607
30042
  const formexStub = createFormexStub(usedEntity?.values ?? {});
29608
- const usedFormContext = formContext ?? {
30043
+ return {
29609
30044
  entityId,
29610
30045
  disabled: false,
29611
30046
  openEntityMode: layout,
@@ -29631,18 +30066,34 @@
29631
30066
  savingError: void 0,
29632
30067
  formex: formexStub
29633
30068
  };
30069
+ }, [formContext, entityId, layout, status, usedEntity, collection, path, customizationController.propertyConfigs, authController]);
30070
+ const customViewsView = customViews && resolvedEntityViews.filter((e) => !e.includeActions).map((customView) => {
30071
+ if (!customView) return null;
30072
+ const Builder = customView.Builder;
30073
+ if (!Builder) {
30074
+ console.error("INTERNAL: customView.Builder is not defined");
30075
+ return null;
30076
+ }
30077
+ if (!entityId) {
30078
+ return null;
30079
+ }
30080
+ const isActive = selectedTab === customView.key;
30081
+ if (!isActive && !mountedTabsRef.current.has(customView.key)) {
30082
+ return null;
30083
+ }
30084
+ const usedFormContext = formContext ?? readOnlyFormContext;
29634
30085
  return /* @__PURE__ */ jsxRuntime.jsx("div", { className: ui.cls(ui.defaultBorderMixin, "relative flex-1 w-full h-full overflow-auto", {
29635
- "hidden": selectedTab !== customView.key
30086
+ "hidden": !isActive
29636
30087
  }), role: "tabpanel", children: /* @__PURE__ */ jsxRuntime.jsx(ErrorBoundary, { children: usedFormContext && /* @__PURE__ */ jsxRuntime.jsx(Builder, { collection, parentCollectionIds, entity: usedEntity, modifiedValues: usedFormContext?.formex?.values ?? usedEntity?.values, formContext: usedFormContext }) }) }, `custom_view_${customView.key}`);
29637
30088
  }).filter(Boolean);
29638
30089
  const globalLoading = dataLoading && !usedEntity;
29639
- const jsonView = /* @__PURE__ */ jsxRuntime.jsx("div", { className: ui.cls("relative flex-1 h-full overflow-auto w-full", {
30090
+ const jsonView = selectedTab === JSON_TAB_VALUE || mountedTabsRef.current.has(JSON_TAB_VALUE) ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: ui.cls("relative flex-1 h-full overflow-auto w-full", {
29640
30091
  "hidden": selectedTab !== JSON_TAB_VALUE
29641
- }), role: "tabpanel", children: /* @__PURE__ */ jsxRuntime.jsx(ErrorBoundary, { children: /* @__PURE__ */ jsxRuntime.jsx(EntityJsonPreview, { values: formContext?.values ?? entity?.values ?? {} }) }) }, "json_view");
30092
+ }), role: "tabpanel", children: /* @__PURE__ */ jsxRuntime.jsx(ErrorBoundary, { children: /* @__PURE__ */ jsxRuntime.jsx(EntityJsonPreview, { values: formContext?.values ?? entity?.values ?? {} }) }) }, "json_view") : null;
29642
30093
  const subCollectionsViews = subcollections && subcollections.map((subcollection) => {
29643
30094
  const subcollectionId = subcollection.id ?? subcollection.path;
29644
30095
  const newFullPath = usedEntity ? `${path}/${usedEntity?.id}/${removeInitialAndTrailingSlashes(subcollection.path)}` : void 0;
29645
- const newFullIdPath = fullIdPath ? `${fullIdPath}/${usedEntity?.id}/${removeInitialAndTrailingSlashes(subcollectionId)}` : void 0;
30096
+ const newFullIdPath = fullIdPath && usedEntity ? `${fullIdPath}/${encodeEntityId(usedEntity.id)}/${removeInitialAndTrailingSlashes(subcollectionId)}` : void 0;
29646
30097
  if (selectedTab !== subcollectionId) return null;
29647
30098
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative flex-1 h-full overflow-auto w-full", role: "tabpanel", children: [
29648
30099
  globalLoading && /* @__PURE__ */ jsxRuntime.jsx(CircularProgressCenter, {}),
@@ -29686,8 +30137,8 @@
29686
30137
  const customViewTabsStart = resolvedEntityViews.filter((view) => view.position === "start" && !groupedViews.includes(view.key)).map((view_0) => /* @__PURE__ */ jsxRuntime.jsx(ui.Tab, { className: !view_0.tabComponent ? "text-sm min-w-[120px]" : void 0, value: view_0.key, children: view_0.tabComponent ?? view_0.name }, `entity_detail_collection_tab_${view_0.name}`));
29687
30138
  const customViewTabsEnd = resolvedEntityViews.filter((view_1) => (!view_1.position || view_1.position === "end") && !groupedViews.includes(view_1.key)).map((view_2) => /* @__PURE__ */ jsxRuntime.jsx(ui.Tab, { className: !view_2.tabComponent ? "text-sm min-w-[120px]" : void 0, value: view_2.key, children: view_2.tabComponent ?? view_2.name }, `entity_detail_collection_tab_${view_2.name}`));
29688
30139
  const viewGroupMenus = collection.viewGroups?.map((group) => {
29689
- const isActive = group.views.includes(selectedTab);
29690
- return /* @__PURE__ */ jsxRuntime.jsx(ui.Menu, { trigger: /* @__PURE__ */ jsxRuntime.jsxs("button", { type: "button", className: ui.cls("inline-flex items-center justify-center whitespace-nowrap rounded-sm px-3 py-1.5 text-sm font-medium ring-offset-white transition-all", "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-surface-400 focus-visible:ring-offset-2", "disabled:pointer-events-none disabled:opacity-50", isActive ? "bg-white text-surface-900 dark:bg-surface-950 dark:text-surface-50" : "text-surface-600 dark:text-surface-400 hover:bg-surface-200 dark:hover:bg-surface-800"), children: [
30140
+ const isActive_0 = group.views.includes(selectedTab);
30141
+ return /* @__PURE__ */ jsxRuntime.jsx(ui.Menu, { trigger: /* @__PURE__ */ jsxRuntime.jsxs("button", { type: "button", className: ui.cls("inline-flex items-center justify-center whitespace-nowrap rounded-sm px-3 py-1.5 text-sm font-medium ring-offset-white transition-all", "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-surface-400 focus-visible:ring-offset-2", "disabled:pointer-events-none disabled:opacity-50", isActive_0 ? "bg-white text-surface-900 dark:bg-surface-950 dark:text-surface-50" : "text-surface-600 dark:text-surface-400 hover:bg-surface-200 dark:hover:bg-surface-800"), children: [
29691
30142
  group.name,
29692
30143
  /* @__PURE__ */ jsxRuntime.jsx(ui.ExpandMoreIcon, { className: "ml-1 -mr-1", size: "small" })
29693
30144
  ] }), children: group.views.map((viewId) => {
@@ -29931,7 +30382,7 @@
29931
30382
  }
29932
30383
  const propsToSidePanel = (props, buildUrlCollectionPath, resolveIdsFrom, smallLayout, customizationController, authController, locationSearch) => {
29933
30384
  const collectionPath = removeInitialAndTrailingSlashes(props.path);
29934
- const urlPath = props.entityId ? buildUrlCollectionPath(`${collectionPath}/${props.entityId}${props.selectedTab ? "/" + props.selectedTab : ""}${locationSearch}#${SIDE_URL_HASH}`) : buildUrlCollectionPath(`${collectionPath}${locationSearch}#${NEW_URL_HASH}`);
30385
+ const urlPath = props.entityId ? buildUrlCollectionPath(`${collectionPath}/${encodeEntityId(props.entityId)}${props.selectedTab ? "/" + props.selectedTab : ""}${locationSearch}#${SIDE_URL_HASH}`) : buildUrlCollectionPath(`${collectionPath}${locationSearch}#${NEW_URL_HASH}`);
29935
30386
  const resolvedPanelProps = {
29936
30387
  ...props,
29937
30388
  formProps: props.formProps
@@ -30027,7 +30478,7 @@
30027
30478
  replace: true,
30028
30479
  state: {
30029
30480
  base_location: baseLocation,
30030
- panels: updatedPanels.map(_temp4$1)
30481
+ panels: updatedPanels.map(_temp4$2)
30031
30482
  }
30032
30483
  });
30033
30484
  }
@@ -30125,7 +30576,7 @@
30125
30576
  function _temp5$1(p_3) {
30126
30577
  return p_3.key;
30127
30578
  }
30128
- function _temp4$1(p_2) {
30579
+ function _temp4$2(p_2) {
30129
30580
  return p_2.key;
30130
30581
  }
30131
30582
  function _temp3$2(p_1) {
@@ -30645,7 +31096,7 @@
30645
31096
  return t1;
30646
31097
  }
30647
31098
  function DrawerNavigationItem(t0) {
30648
- const $ = reactCompilerRuntime.c(24);
31099
+ const $ = reactCompilerRuntime.c(22);
30649
31100
  const {
30650
31101
  name,
30651
31102
  icon,
@@ -30657,7 +31108,7 @@
30657
31108
  } = t0;
30658
31109
  let t1;
30659
31110
  if ($[0] !== icon) {
30660
- t1 = /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-text-secondary dark:text-text-secondary-dark", children: icon });
31111
+ t1 = /* @__PURE__ */ jsxRuntime.jsx("div", { className: "shrink-0 flex items-center justify-center w-[44px] h-[30px] text-surface-500 dark:text-text-secondary-dark group-hover/nav:text-primary transition-colors duration-150", children: icon });
30661
31112
  $[0] = icon;
30662
31113
  $[1] = t1;
30663
31114
  } else {
@@ -30682,7 +31133,7 @@
30682
31133
  const {
30683
31134
  isActive
30684
31135
  } = t52;
30685
- return ui.cls("rounded-lg truncate", "hover:bg-surface-accent-300 hover:bg-opacity-75 hover:bg-surface-accent-300/75 dark:hover:bg-surface-accent-800 dark:hover:bg-opacity-75 dark:hover:bg-surface-accent-800/75 text-text-primary dark:text-surface-200 hover:text-surface-900 hover:dark:text-white hover:bg-surface-accent-300/75 dark:hover:bg-surface-accent-800/75", "flex flex-row items-center mr-8", drawerOpen ? "pl-4 h-10" : "pl-4 h-9", "font-semibold text-xs", isActive ? "bg-surface-accent-200 bg-opacity-60 dark:bg-surface-800 dark:bg-opacity-50 bg-surface-accent-200/60 dark:bg-surface-800/50" : "");
31136
+ return ui.cls("rounded-lg truncate group/nav", "hover:bg-primary/5 dark:hover:bg-primary/5 text-surface-700 dark:text-surface-300 hover:text-surface-900 dark:hover:text-white", "flex flex-row items-center", drawerOpen ? "pr-4 h-[30px]" : "h-[30px]", "font-medium text-[13px]", isActive ? "bg-primary/8 dark:bg-primary/10 text-primary dark:text-primary [&_div]:text-primary" : "");
30686
31137
  };
30687
31138
  $[4] = drawerOpen;
30688
31139
  $[5] = t4;
@@ -30692,61 +31143,53 @@
30692
31143
  const t5 = drawerOpen ? "opacity-100" : "opacity-0 hidden";
30693
31144
  let t6;
30694
31145
  if ($[6] !== t5) {
30695
- t6 = ui.cls("text-text-primary dark:text-surface-200", t5, "ml-4 font-inherit");
31146
+ t6 = ui.cls("text-surface-700 dark:text-surface-300", t5, "font-inherit truncate space-x-2");
30696
31147
  $[6] = t5;
30697
31148
  $[7] = t6;
30698
31149
  } else {
30699
31150
  t6 = $[7];
30700
31151
  }
30701
31152
  let t7;
30702
- if ($[8] !== name) {
30703
- t7 = name.toUpperCase();
31153
+ if ($[8] !== name || $[9] !== t6) {
31154
+ t7 = /* @__PURE__ */ jsxRuntime.jsx("div", { className: t6, children: name });
30704
31155
  $[8] = name;
30705
- $[9] = t7;
31156
+ $[9] = t6;
31157
+ $[10] = t7;
30706
31158
  } else {
30707
- t7 = $[9];
31159
+ t7 = $[10];
30708
31160
  }
30709
31161
  let t8;
30710
- if ($[10] !== t6 || $[11] !== t7) {
30711
- t8 = /* @__PURE__ */ jsxRuntime.jsx("div", { className: t6, children: t7 });
30712
- $[10] = t6;
30713
- $[11] = t7;
30714
- $[12] = t8;
30715
- } else {
30716
- t8 = $[12];
30717
- }
30718
- let t9;
30719
- if ($[13] !== iconWrap || $[14] !== onClick || $[15] !== t3 || $[16] !== t4 || $[17] !== t8 || $[18] !== url) {
30720
- t9 = /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsxs(reactRouterDom.NavLink, { onClick, style: t3, className: t4, to: url, children: [
31162
+ if ($[11] !== iconWrap || $[12] !== onClick || $[13] !== t3 || $[14] !== t4 || $[15] !== t7 || $[16] !== url) {
31163
+ t8 = /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsxs(reactRouterDom.NavLink, { onClick, style: t3, className: t4, to: url, children: [
30721
31164
  iconWrap,
30722
- t8
31165
+ t7
30723
31166
  ] }) });
30724
- $[13] = iconWrap;
30725
- $[14] = onClick;
30726
- $[15] = t3;
30727
- $[16] = t4;
31167
+ $[11] = iconWrap;
31168
+ $[12] = onClick;
31169
+ $[13] = t3;
31170
+ $[14] = t4;
31171
+ $[15] = t7;
31172
+ $[16] = url;
30728
31173
  $[17] = t8;
30729
- $[18] = url;
30730
- $[19] = t9;
30731
31174
  } else {
30732
- t9 = $[19];
31175
+ t8 = $[17];
30733
31176
  }
30734
- const listItem = t9;
30735
- const t10 = drawerOpen || adminMenuOpen ? false : tooltipsOpen;
30736
- let t11;
30737
- if ($[20] !== listItem || $[21] !== name || $[22] !== t10) {
30738
- t11 = /* @__PURE__ */ jsxRuntime.jsx(ui.Tooltip, { open: t10, side: "right", title: name, children: listItem });
30739
- $[20] = listItem;
30740
- $[21] = name;
30741
- $[22] = t10;
30742
- $[23] = t11;
31177
+ const listItem = t8;
31178
+ const t9 = drawerOpen || adminMenuOpen ? false : tooltipsOpen;
31179
+ let t10;
31180
+ if ($[18] !== listItem || $[19] !== name || $[20] !== t9) {
31181
+ t10 = /* @__PURE__ */ jsxRuntime.jsx(ui.Tooltip, { open: t9, side: "right", title: name, children: listItem });
31182
+ $[18] = listItem;
31183
+ $[19] = name;
31184
+ $[20] = t9;
31185
+ $[21] = t10;
30743
31186
  } else {
30744
- t11 = $[23];
31187
+ t10 = $[21];
30745
31188
  }
30746
- return t11;
31189
+ return t10;
30747
31190
  }
30748
31191
  function DrawerNavigationGroup(t0) {
30749
- const $ = reactCompilerRuntime.c(29);
31192
+ const $ = reactCompilerRuntime.c(41);
30750
31193
  const {
30751
31194
  group,
30752
31195
  entries,
@@ -30762,86 +31205,137 @@
30762
31205
  t
30763
31206
  } = useTranslation();
30764
31207
  const t1 = `drawer_group_${group}`;
30765
- let t2;
30766
- if ($[0] !== collapsed || $[1] !== drawerOpen || $[2] !== group || $[3] !== headerActions || $[4] !== onToggleCollapsed || $[5] !== t) {
30767
- t2 = drawerOpen ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pl-4 pr-2 py-2 flex flex-row items-center cursor-pointer hover:bg-surface-100 dark:hover:bg-surface-700/50 rounded-t-lg transition-colors", onClick: onToggleCollapsed, children: [
30768
- /* @__PURE__ */ jsxRuntime.jsx(ui.ExpandMoreIcon, { size: "smallest", className: ui.cls("text-surface-500 dark:text-surface-400 transition-transform duration-200 mr-1", collapsed ? "-rotate-90" : "rotate-0") }),
30769
- /* @__PURE__ */ jsxRuntime.jsx(ui.Typography, { variant: "caption", color: "secondary", className: "font-medium flex-grow line-clamp-1", children: (group && group !== "__default__" ? group : t("views_group")).toUpperCase() }),
30770
- headerActions && /* @__PURE__ */ jsxRuntime.jsx("div", { onClick: _temp$a, children: headerActions })
30771
- ] }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full" });
30772
- $[0] = collapsed;
30773
- $[1] = drawerOpen;
30774
- $[2] = group;
30775
- $[3] = headerActions;
30776
- $[4] = onToggleCollapsed;
30777
- $[5] = t;
30778
- $[6] = t2;
31208
+ const t2 = drawerOpen ? "cursor-pointer hover:bg-surface-100 dark:hover:bg-surface-800/40 rounded-lg" : "opacity-0 invisible pointer-events-none";
31209
+ let t3;
31210
+ if ($[0] !== t2) {
31211
+ t3 = ui.cls("pl-3 pr-2 py-0.5 flex flex-row items-center transition-colors", t2);
31212
+ $[0] = t2;
31213
+ $[1] = t3;
30779
31214
  } else {
30780
- t2 = $[6];
31215
+ t3 = $[1];
30781
31216
  }
30782
- const t3 = collapsed ? "max-h-0 opacity-0" : "max-h-[2000px] opacity-100";
30783
- let t4;
30784
- if ($[7] !== t3) {
30785
- t4 = ui.cls("overflow-hidden transition-all duration-200 ease-in-out", t3);
30786
- $[7] = t3;
30787
- $[8] = t4;
31217
+ const t4 = drawerOpen ? onToggleCollapsed : void 0;
31218
+ const t5 = collapsed ? "-rotate-90" : "rotate-0";
31219
+ let t6;
31220
+ if ($[2] !== t5) {
31221
+ t6 = ui.cls("text-surface-400 dark:text-surface-400 transition-transform duration-200 mr-1", t5);
31222
+ $[2] = t5;
31223
+ $[3] = t6;
30788
31224
  } else {
30789
- t4 = $[8];
31225
+ t6 = $[3];
30790
31226
  }
30791
- let t5;
30792
- if ($[9] !== adminMenuOpen || $[10] !== collapsed || $[11] !== drawerOpen || $[12] !== entries || $[13] !== onItemClick || $[14] !== tooltipsOpen) {
30793
- let t62;
30794
- if ($[16] !== adminMenuOpen || $[17] !== collapsed || $[18] !== drawerOpen || $[19] !== onItemClick || $[20] !== tooltipsOpen) {
30795
- t62 = (entry) => /* @__PURE__ */ jsxRuntime.jsx(DrawerNavigationItem, { icon: /* @__PURE__ */ jsxRuntime.jsx(IconForView, { collectionOrView: entry.collection ?? entry.view, size: 18 }), tooltipsOpen: !collapsed && tooltipsOpen, adminMenuOpen, drawerOpen, onClick: () => onItemClick?.(entry), url: entry.url, name: entry.name }, entry.id);
30796
- $[16] = adminMenuOpen;
30797
- $[17] = collapsed;
30798
- $[18] = drawerOpen;
30799
- $[19] = onItemClick;
30800
- $[20] = tooltipsOpen;
30801
- $[21] = t62;
31227
+ let t7;
31228
+ if ($[4] !== t6) {
31229
+ t7 = /* @__PURE__ */ jsxRuntime.jsx(ui.ExpandMoreIcon, { size: "smallest", className: t6 });
31230
+ $[4] = t6;
31231
+ $[5] = t7;
31232
+ } else {
31233
+ t7 = $[5];
31234
+ }
31235
+ let t8;
31236
+ if ($[6] !== group || $[7] !== t) {
31237
+ t8 = group && group !== "__default__" ? group : t("views_group");
31238
+ $[6] = group;
31239
+ $[7] = t;
31240
+ $[8] = t8;
31241
+ } else {
31242
+ t8 = $[8];
31243
+ }
31244
+ let t9;
31245
+ if ($[9] !== t8) {
31246
+ t9 = /* @__PURE__ */ jsxRuntime.jsx(ui.Typography, { variant: "caption", color: "secondary", className: "font-semibold text-[11px] uppercase tracking-wider flex-grow line-clamp-1 text-surface-400 dark:text-surface-400", children: t8 });
31247
+ $[9] = t8;
31248
+ $[10] = t9;
31249
+ } else {
31250
+ t9 = $[10];
31251
+ }
31252
+ let t10;
31253
+ if ($[11] !== headerActions) {
31254
+ t10 = headerActions && /* @__PURE__ */ jsxRuntime.jsx("div", { onClick: _temp$a, children: headerActions });
31255
+ $[11] = headerActions;
31256
+ $[12] = t10;
31257
+ } else {
31258
+ t10 = $[12];
31259
+ }
31260
+ let t11;
31261
+ if ($[13] !== t10 || $[14] !== t3 || $[15] !== t4 || $[16] !== t7 || $[17] !== t9) {
31262
+ t11 = /* @__PURE__ */ jsxRuntime.jsxs("div", { className: t3, onClick: t4, children: [
31263
+ t7,
31264
+ t9,
31265
+ t10
31266
+ ] });
31267
+ $[13] = t10;
31268
+ $[14] = t3;
31269
+ $[15] = t4;
31270
+ $[16] = t7;
31271
+ $[17] = t9;
31272
+ $[18] = t11;
31273
+ } else {
31274
+ t11 = $[18];
31275
+ }
31276
+ const t12 = collapsed ? "max-h-0 opacity-0" : "max-h-[2000px] opacity-100";
31277
+ let t13;
31278
+ if ($[19] !== t12) {
31279
+ t13 = ui.cls("transition-all duration-200 ease-in-out overflow-hidden rounded-lg", t12);
31280
+ $[19] = t12;
31281
+ $[20] = t13;
31282
+ } else {
31283
+ t13 = $[20];
31284
+ }
31285
+ let t14;
31286
+ if ($[21] !== adminMenuOpen || $[22] !== collapsed || $[23] !== drawerOpen || $[24] !== entries || $[25] !== onItemClick || $[26] !== tooltipsOpen) {
31287
+ let t152;
31288
+ if ($[28] !== adminMenuOpen || $[29] !== collapsed || $[30] !== drawerOpen || $[31] !== onItemClick || $[32] !== tooltipsOpen) {
31289
+ t152 = (entry) => /* @__PURE__ */ jsxRuntime.jsx(DrawerNavigationItem, { icon: /* @__PURE__ */ jsxRuntime.jsx(IconForView, { collectionOrView: entry.collection ?? entry.view, size: 18 }), tooltipsOpen: !collapsed && tooltipsOpen, adminMenuOpen, drawerOpen, onClick: () => onItemClick?.(entry), url: entry.url, name: entry.name }, entry.id);
31290
+ $[28] = adminMenuOpen;
31291
+ $[29] = collapsed;
31292
+ $[30] = drawerOpen;
31293
+ $[31] = onItemClick;
31294
+ $[32] = tooltipsOpen;
31295
+ $[33] = t152;
30802
31296
  } else {
30803
- t62 = $[21];
30804
- }
30805
- t5 = entries.map(t62);
30806
- $[9] = adminMenuOpen;
30807
- $[10] = collapsed;
30808
- $[11] = drawerOpen;
30809
- $[12] = entries;
30810
- $[13] = onItemClick;
30811
- $[14] = tooltipsOpen;
30812
- $[15] = t5;
31297
+ t152 = $[33];
31298
+ }
31299
+ t14 = entries.map(t152);
31300
+ $[21] = adminMenuOpen;
31301
+ $[22] = collapsed;
31302
+ $[23] = drawerOpen;
31303
+ $[24] = entries;
31304
+ $[25] = onItemClick;
31305
+ $[26] = tooltipsOpen;
31306
+ $[27] = t14;
30813
31307
  } else {
30814
- t5 = $[15];
31308
+ t14 = $[27];
30815
31309
  }
30816
- let t6;
30817
- if ($[22] !== t4 || $[23] !== t5) {
30818
- t6 = /* @__PURE__ */ jsxRuntime.jsx("div", { className: t4, children: t5 });
30819
- $[22] = t4;
30820
- $[23] = t5;
30821
- $[24] = t6;
31310
+ let t15;
31311
+ if ($[34] !== t13 || $[35] !== t14) {
31312
+ t15 = /* @__PURE__ */ jsxRuntime.jsx("div", { className: t13, children: t14 });
31313
+ $[34] = t13;
31314
+ $[35] = t14;
31315
+ $[36] = t15;
30822
31316
  } else {
30823
- t6 = $[24];
31317
+ t15 = $[36];
30824
31318
  }
30825
- let t7;
30826
- if ($[25] !== t1 || $[26] !== t2 || $[27] !== t6) {
30827
- t7 = /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-surface-50 dark:bg-surface-800/30 my-4 rounded-lg ml-3 mr-1", children: [
30828
- t2,
30829
- t6
31319
+ let t16;
31320
+ if ($[37] !== t1 || $[38] !== t11 || $[39] !== t15) {
31321
+ t16 = /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "my-2 mx-2 flex flex-col", children: [
31322
+ t11,
31323
+ t15
30830
31324
  ] }, t1);
30831
- $[25] = t1;
30832
- $[26] = t2;
30833
- $[27] = t6;
30834
- $[28] = t7;
31325
+ $[37] = t1;
31326
+ $[38] = t11;
31327
+ $[39] = t15;
31328
+ $[40] = t16;
30835
31329
  } else {
30836
- t7 = $[28];
31330
+ t16 = $[40];
30837
31331
  }
30838
- return t7;
31332
+ return t16;
30839
31333
  }
30840
31334
  function _temp$a(e) {
30841
31335
  return e.stopPropagation();
30842
31336
  }
30843
31337
  function DefaultDrawer(t0) {
30844
- const $ = reactCompilerRuntime.c(36);
31338
+ const $ = reactCompilerRuntime.c(40);
30845
31339
  const {
30846
31340
  className,
30847
31341
  style
@@ -30853,6 +31347,20 @@
30853
31347
  logo
30854
31348
  } = useApp();
30855
31349
  const [adminMenuOpen, setAdminMenuOpen] = React.useState(false);
31350
+ const scrollRef = React.useRef(null);
31351
+ const [scrolled, setScrolled] = React.useState(false);
31352
+ let t1;
31353
+ if ($[0] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
31354
+ t1 = () => {
31355
+ if (scrollRef.current) {
31356
+ setScrolled(scrollRef.current.scrollTop > 0);
31357
+ }
31358
+ };
31359
+ $[0] = t1;
31360
+ } else {
31361
+ t1 = $[0];
31362
+ }
31363
+ const handleScroll = t1;
30856
31364
  const analyticsController = useAnalyticsController();
30857
31365
  const navigation = useNavigationController();
30858
31366
  const {
@@ -30869,22 +31377,23 @@
30869
31377
  groups
30870
31378
  } = navigation.topLevelNavigation;
30871
31379
  const adminViews = navigationEntries.filter(_temp$9) ?? [];
30872
- let t1;
30873
- if ($[0] !== groups) {
30874
- t1 = groups.filter(_temp2$3);
30875
- $[0] = groups;
30876
- $[1] = t1;
31380
+ let t2;
31381
+ if ($[1] !== groups) {
31382
+ t2 = groups.filter(_temp2$3);
31383
+ $[1] = groups;
31384
+ $[2] = t2;
30877
31385
  } else {
30878
- t1 = $[1];
31386
+ t2 = $[2];
30879
31387
  }
30880
- const groupsWithoutAdmin = t1;
31388
+ const groupsWithoutAdmin = t2;
30881
31389
  const {
30882
31390
  isGroupCollapsed,
30883
31391
  toggleGroupCollapsed
30884
31392
  } = useCollapsedGroups(groupsWithoutAdmin, "drawer");
30885
- let t2;
30886
- if ($[2] !== analyticsController || $[3] !== closeDrawer || $[4] !== largeLayout) {
30887
- t2 = (view) => {
31393
+ const drawerVisuallyOpen = drawerOpen || drawerHovered;
31394
+ let t3;
31395
+ if ($[3] !== analyticsController || $[4] !== closeDrawer || $[5] !== largeLayout) {
31396
+ t3 = (view) => {
30888
31397
  const eventName = view.type === "collection" ? "drawer_navigate_to_collection" : view.type === "view" ? "drawer_navigate_to_view" : "unmapped_event";
30889
31398
  analyticsController.onAnalyticsEvent?.(eventName, {
30890
31399
  url: view.url
@@ -30893,106 +31402,119 @@
30893
31402
  closeDrawer();
30894
31403
  }
30895
31404
  };
30896
- $[2] = analyticsController;
30897
- $[3] = closeDrawer;
30898
- $[4] = largeLayout;
30899
- $[5] = t2;
31405
+ $[3] = analyticsController;
31406
+ $[4] = closeDrawer;
31407
+ $[5] = largeLayout;
31408
+ $[6] = t3;
30900
31409
  } else {
30901
- t2 = $[5];
31410
+ t3 = $[6];
30902
31411
  }
30903
- const onItemClick = t2;
30904
- let t3;
30905
- if ($[6] !== className) {
30906
- t3 = ui.cls("flex flex-col h-full relative flex-grow w-full", className);
30907
- $[6] = className;
30908
- $[7] = t3;
31412
+ const onItemClick = t3;
31413
+ const t4 = "navigation";
31414
+ const t5 = "Main navigation";
31415
+ let t6;
31416
+ if ($[7] !== className) {
31417
+ t6 = ui.cls("flex flex-col h-full relative grow w-full", className);
31418
+ $[7] = className;
31419
+ $[8] = t6;
30909
31420
  } else {
30910
- t3 = $[7];
31421
+ t6 = $[8];
30911
31422
  }
30912
- let t4;
30913
- if ($[8] !== logo) {
30914
- t4 = /* @__PURE__ */ jsxRuntime.jsx(DrawerLogo, { logo });
30915
- $[8] = logo;
30916
- $[9] = t4;
31423
+ let t7;
31424
+ if ($[9] !== logo) {
31425
+ t7 = /* @__PURE__ */ jsxRuntime.jsx(DrawerLogo, { logo });
31426
+ $[9] = logo;
31427
+ $[10] = t7;
30917
31428
  } else {
30918
- t4 = $[9];
31429
+ t7 = $[10];
30919
31430
  }
30920
- let t5;
30921
- if ($[10] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
30922
- t5 = {
30923
- maskImage: "linear-gradient(to bottom, transparent 0, black 20px, black calc(100% - 20px), transparent 100%)"
31431
+ const t8 = scrolled ? "linear-gradient(to bottom, transparent 0, black 20px, black calc(100% - 20px), transparent 100%)" : "linear-gradient(to bottom, black 0, black calc(100% - 20px), transparent 100%)";
31432
+ let t9;
31433
+ if ($[11] !== t8) {
31434
+ t9 = {
31435
+ maskImage: t8
30924
31436
  };
30925
- $[10] = t5;
31437
+ $[11] = t8;
31438
+ $[12] = t9;
30926
31439
  } else {
30927
- t5 = $[10];
31440
+ t9 = $[12];
30928
31441
  }
30929
- let t6;
30930
- if ($[11] !== adminMenuOpen || $[12] !== drawerOpen || $[13] !== groupsWithoutAdmin || $[14] !== isGroupCollapsed || $[15] !== navigationEntries || $[16] !== onItemClick || $[17] !== toggleGroupCollapsed || $[18] !== tooltipsOpen) {
30931
- let t72;
30932
- if ($[20] !== adminMenuOpen || $[21] !== drawerOpen || $[22] !== isGroupCollapsed || $[23] !== navigationEntries || $[24] !== onItemClick || $[25] !== toggleGroupCollapsed || $[26] !== tooltipsOpen) {
30933
- t72 = (group) => {
31442
+ let t10;
31443
+ if ($[13] !== adminMenuOpen || $[14] !== drawerVisuallyOpen || $[15] !== groupsWithoutAdmin || $[16] !== isGroupCollapsed || $[17] !== navigationEntries || $[18] !== onItemClick || $[19] !== toggleGroupCollapsed || $[20] !== tooltipsOpen) {
31444
+ let t112;
31445
+ if ($[22] !== adminMenuOpen || $[23] !== drawerVisuallyOpen || $[24] !== isGroupCollapsed || $[25] !== navigationEntries || $[26] !== onItemClick || $[27] !== toggleGroupCollapsed || $[28] !== tooltipsOpen) {
31446
+ t112 = (group) => {
30934
31447
  const entriesInGroup = Object.values(navigationEntries).filter((e_0) => e_0.group === group);
30935
- return /* @__PURE__ */ jsxRuntime.jsx(DrawerNavigationGroup, { group, entries: entriesInGroup, collapsed: isGroupCollapsed(group), onToggleCollapsed: () => toggleGroupCollapsed(group), drawerOpen, tooltipsOpen, adminMenuOpen, onItemClick }, `drawer_group_${group}`);
31448
+ return /* @__PURE__ */ jsxRuntime.jsx(DrawerNavigationGroup, { group, entries: entriesInGroup, collapsed: isGroupCollapsed(group), onToggleCollapsed: () => toggleGroupCollapsed(group), drawerOpen: drawerVisuallyOpen, tooltipsOpen, adminMenuOpen, onItemClick }, `drawer_group_${group}`);
30936
31449
  };
30937
- $[20] = adminMenuOpen;
30938
- $[21] = drawerOpen;
30939
- $[22] = isGroupCollapsed;
30940
- $[23] = navigationEntries;
30941
- $[24] = onItemClick;
30942
- $[25] = toggleGroupCollapsed;
30943
- $[26] = tooltipsOpen;
30944
- $[27] = t72;
31450
+ $[22] = adminMenuOpen;
31451
+ $[23] = drawerVisuallyOpen;
31452
+ $[24] = isGroupCollapsed;
31453
+ $[25] = navigationEntries;
31454
+ $[26] = onItemClick;
31455
+ $[27] = toggleGroupCollapsed;
31456
+ $[28] = tooltipsOpen;
31457
+ $[29] = t112;
30945
31458
  } else {
30946
- t72 = $[27];
30947
- }
30948
- t6 = groupsWithoutAdmin.map(t72);
30949
- $[11] = adminMenuOpen;
30950
- $[12] = drawerOpen;
30951
- $[13] = groupsWithoutAdmin;
30952
- $[14] = isGroupCollapsed;
30953
- $[15] = navigationEntries;
30954
- $[16] = onItemClick;
30955
- $[17] = toggleGroupCollapsed;
30956
- $[18] = tooltipsOpen;
30957
- $[19] = t6;
31459
+ t112 = $[29];
31460
+ }
31461
+ t10 = groupsWithoutAdmin.map(t112);
31462
+ $[13] = adminMenuOpen;
31463
+ $[14] = drawerVisuallyOpen;
31464
+ $[15] = groupsWithoutAdmin;
31465
+ $[16] = isGroupCollapsed;
31466
+ $[17] = navigationEntries;
31467
+ $[18] = onItemClick;
31468
+ $[19] = toggleGroupCollapsed;
31469
+ $[20] = tooltipsOpen;
31470
+ $[21] = t10;
30958
31471
  } else {
30959
- t6 = $[19];
31472
+ t10 = $[21];
30960
31473
  }
30961
- let t7;
30962
- if ($[28] !== t6) {
30963
- t7 = /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-4 flex-grow overflow-scroll no-scrollbar", style: t5, children: t6 });
30964
- $[28] = t6;
30965
- $[29] = t7;
31474
+ let t11;
31475
+ if ($[30] !== t10 || $[31] !== t9) {
31476
+ t11 = /* @__PURE__ */ jsxRuntime.jsx("div", { ref: scrollRef, onScroll: handleScroll, className: "flex-grow min-h-0 overflow-y-auto overflow-x-hidden no-scrollbar px-2", style: t9, children: t10 });
31477
+ $[30] = t10;
31478
+ $[31] = t9;
31479
+ $[32] = t11;
30966
31480
  } else {
30967
- t7 = $[29];
31481
+ t11 = $[32];
30968
31482
  }
30969
- const t8 = adminViews.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(ui.Menu, { side: "right", open: adminMenuOpen, onOpenChange: setAdminMenuOpen, trigger: /* @__PURE__ */ jsxRuntime.jsxs(ui.IconButton, { shape: "square", className: "m-4 text-surface-900 dark:text-white w-fit", children: [
30970
- /* @__PURE__ */ jsxRuntime.jsx(ui.Tooltip, { title: "Admin", open: tooltipsOpen, side: "right", sideOffset: 28, children: /* @__PURE__ */ jsxRuntime.jsx(ui.MoreVertIcon, {}) }),
30971
- drawerOpen && /* @__PURE__ */ jsxRuntime.jsx("div", { className: ui.cls(drawerOpen ? "opacity-100" : "opacity-0 hidden", "mx-4 font-inherit text-inherit"), children: "ADMIN" })
31483
+ const t12 = adminViews.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "shrink-0 px-4", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Menu, { side: "right", open: adminMenuOpen, onOpenChange: setAdminMenuOpen, trigger: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: ui.cls("flex flex-row items-center rounded-lg cursor-pointer w-full", "hover:bg-surface-accent-100 dark:hover:bg-surface-800 transition-colors duration-150 h-[30px]"), children: [
31484
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "shrink-0 flex items-center justify-center w-[44px] h-[30px] text-surface-500 dark:text-surface-400", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Tooltip, { title: "Admin", open: drawerVisuallyOpen || adminMenuOpen ? false : tooltipsOpen, side: "right", sideOffset: 28, children: /* @__PURE__ */ jsxRuntime.jsx(ui.MoreVertIcon, { size: "small" }) }) }),
31485
+ drawerVisuallyOpen && /* @__PURE__ */ jsxRuntime.jsx("div", { className: ui.cls("font-semibold text-[11px] uppercase tracking-wider text-surface-400"), children: t("admin") })
30972
31486
  ] }), children: adminViews.map((entry) => /* @__PURE__ */ jsxRuntime.jsxs(ui.MenuItem, { onClick: (event) => {
30973
31487
  event.preventDefault();
30974
31488
  navigate(entry.url);
30975
31489
  }, children: [
30976
31490
  /* @__PURE__ */ jsxRuntime.jsx(IconForView, { collectionOrView: entry.view }),
30977
31491
  t(entry.name)
30978
- ] }, entry.id)) });
30979
- let t9;
30980
- if ($[30] !== style || $[31] !== t3 || $[32] !== t4 || $[33] !== t7 || $[34] !== t8) {
30981
- t9 = /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: t3, style, children: [
30982
- t4,
31492
+ ] }, entry.id)) }) });
31493
+ let t13;
31494
+ if ($[33] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
31495
+ t13 = /* @__PURE__ */ jsxRuntime.jsx(DrawerToggle, {});
31496
+ $[33] = t13;
31497
+ } else {
31498
+ t13 = $[33];
31499
+ }
31500
+ let t14;
31501
+ if ($[34] !== style || $[35] !== t11 || $[36] !== t12 || $[37] !== t6 || $[38] !== t7) {
31502
+ t14 = /* @__PURE__ */ jsxRuntime.jsxs("div", { role: t4, "aria-label": t5, className: t6, style, children: [
30983
31503
  t7,
30984
- t8
30985
- ] }) });
30986
- $[30] = style;
30987
- $[31] = t3;
30988
- $[32] = t4;
30989
- $[33] = t7;
30990
- $[34] = t8;
30991
- $[35] = t9;
31504
+ t11,
31505
+ t12,
31506
+ t13
31507
+ ] });
31508
+ $[34] = style;
31509
+ $[35] = t11;
31510
+ $[36] = t12;
31511
+ $[37] = t6;
31512
+ $[38] = t7;
31513
+ $[39] = t14;
30992
31514
  } else {
30993
- t9 = $[35];
31515
+ t14 = $[39];
30994
31516
  }
30995
- return t9;
31517
+ return t14;
30996
31518
  }
30997
31519
  function _temp2$3(g) {
30998
31520
  return g !== "Admin";
@@ -31000,62 +31522,133 @@
31000
31522
  function _temp$9(e) {
31001
31523
  return e.type === "admin";
31002
31524
  }
31003
- function DrawerLogo(t0) {
31004
- const $ = reactCompilerRuntime.c(12);
31005
- const {
31006
- logo
31007
- } = t0;
31008
- const navigation = useNavigationController();
31525
+ function DrawerToggle() {
31526
+ const $ = reactCompilerRuntime.c(26);
31009
31527
  const {
31010
- drawerOpen
31528
+ drawerOpen,
31529
+ drawerHovered,
31530
+ openDrawer,
31531
+ closeDrawer
31011
31532
  } = useApp();
31012
- const t1 = drawerOpen ? "32px 144px 0px 24px" : "72px 12px 0px 12px";
31533
+ const isExpanded = drawerOpen;
31534
+ const isHovered = drawerHovered && !drawerOpen;
31535
+ const showFullContent = isExpanded || isHovered;
31536
+ const t0 = isExpanded ? "Collapse" : "Expand";
31537
+ const t1 = isHovered ? false : void 0;
31013
31538
  let t2;
31014
- if ($[0] !== t1) {
31015
- t2 = {
31016
- transition: "padding 100ms cubic-bezier(0.4, 0, 0.6, 1) 0ms",
31017
- padding: t1
31539
+ if ($[0] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
31540
+ t2 = ui.cls("flex flex-row items-center rounded-lg cursor-pointer", "hover:bg-surface-accent-100 dark:hover:bg-surface-800", "transition-colors duration-150 h-[30px]");
31541
+ $[0] = t2;
31542
+ } else {
31543
+ t2 = $[0];
31544
+ }
31545
+ const t3 = isExpanded ? "Collapse" : "Expand";
31546
+ let t4;
31547
+ let t5;
31548
+ if ($[1] !== closeDrawer || $[2] !== isExpanded || $[3] !== openDrawer) {
31549
+ t4 = () => isExpanded ? closeDrawer() : openDrawer();
31550
+ t5 = (e) => {
31551
+ if (e.key === "Enter" || e.key === " ") {
31552
+ e.preventDefault();
31553
+ isExpanded ? closeDrawer() : openDrawer();
31554
+ }
31018
31555
  };
31019
- $[0] = t1;
31020
- $[1] = t2;
31556
+ $[1] = closeDrawer;
31557
+ $[2] = isExpanded;
31558
+ $[3] = openDrawer;
31559
+ $[4] = t4;
31560
+ $[5] = t5;
31021
31561
  } else {
31022
- t2 = $[1];
31562
+ t4 = $[4];
31563
+ t5 = $[5];
31023
31564
  }
31024
- let t3;
31025
- if ($[2] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
31026
- t3 = ui.cls("cursor-pointer rounded ml-3 mr-1");
31027
- $[2] = t3;
31565
+ let t6;
31566
+ if ($[6] !== isExpanded) {
31567
+ t6 = /* @__PURE__ */ jsxRuntime.jsx("div", { className: "shrink-0 flex items-center justify-center w-[44px] h-[30px] text-surface-500 dark:text-surface-400", children: isExpanded ? /* @__PURE__ */ jsxRuntime.jsx(ui.KeyboardDoubleArrowLeftIcon, { size: "small" }) : /* @__PURE__ */ jsxRuntime.jsx(ui.KeyboardDoubleArrowRightIcon, { size: "small" }) });
31568
+ $[6] = isExpanded;
31569
+ $[7] = t6;
31028
31570
  } else {
31029
- t3 = $[2];
31571
+ t6 = $[7];
31030
31572
  }
31031
- let t4;
31032
- if ($[3] !== drawerOpen || $[4] !== logo) {
31033
- t4 = logo ? /* @__PURE__ */ jsxRuntime.jsx("img", { src: logo, alt: "Logo", className: ui.cls("max-w-full max-h-full transition-all object-contain", drawerOpen ? "w-[96px] h-[96px]" : "w-[32px] h-[32px]") }) : /* @__PURE__ */ jsxRuntime.jsx(FireCMSLogo, {});
31034
- $[3] = drawerOpen;
31035
- $[4] = logo;
31036
- $[5] = t4;
31573
+ const t7 = showFullContent ? "opacity-100 w-auto" : "opacity-0 w-0";
31574
+ let t8;
31575
+ if ($[8] !== t7) {
31576
+ t8 = ui.cls("overflow-hidden transition-all duration-200 ease-in-out", t7);
31577
+ $[8] = t7;
31578
+ $[9] = t8;
31037
31579
  } else {
31038
- t4 = $[5];
31580
+ t8 = $[9];
31039
31581
  }
31040
- let t5;
31041
- if ($[6] !== navigation.basePath || $[7] !== t4) {
31042
- t5 = /* @__PURE__ */ jsxRuntime.jsx(ui.Tooltip, { title: "Home", sideOffset: 20, side: "right", children: /* @__PURE__ */ jsxRuntime.jsx(reactRouterDom.Link, { className: "block", to: navigation.basePath, children: t4 }) });
31043
- $[6] = navigation.basePath;
31044
- $[7] = t4;
31045
- $[8] = t5;
31582
+ const t9 = isExpanded ? "Collapse" : "Expand";
31583
+ let t10;
31584
+ if ($[10] !== t9) {
31585
+ t10 = /* @__PURE__ */ jsxRuntime.jsx(ui.Typography, { variant: "body2", className: "text-surface-500 dark:text-surface-400 select-none whitespace-nowrap", children: t9 });
31586
+ $[10] = t9;
31587
+ $[11] = t10;
31046
31588
  } else {
31047
- t5 = $[8];
31589
+ t10 = $[11];
31048
31590
  }
31049
- let t6;
31050
- if ($[9] !== t2 || $[10] !== t5) {
31051
- t6 = /* @__PURE__ */ jsxRuntime.jsx("div", { style: t2, className: t3, children: t5 });
31052
- $[9] = t2;
31053
- $[10] = t5;
31054
- $[11] = t6;
31591
+ let t11;
31592
+ if ($[12] !== t10 || $[13] !== t8) {
31593
+ t11 = /* @__PURE__ */ jsxRuntime.jsx("div", { className: t8, children: t10 });
31594
+ $[12] = t10;
31595
+ $[13] = t8;
31596
+ $[14] = t11;
31055
31597
  } else {
31056
- t6 = $[11];
31598
+ t11 = $[14];
31057
31599
  }
31058
- return t6;
31600
+ let t12;
31601
+ if ($[15] !== isExpanded || $[16] !== t11 || $[17] !== t3 || $[18] !== t4 || $[19] !== t5 || $[20] !== t6) {
31602
+ t12 = /* @__PURE__ */ jsxRuntime.jsxs("div", { className: t2, role: "button", tabIndex: 0, "aria-expanded": isExpanded, "aria-label": t3, onClick: t4, onKeyDown: t5, children: [
31603
+ t6,
31604
+ t11
31605
+ ] });
31606
+ $[15] = isExpanded;
31607
+ $[16] = t11;
31608
+ $[17] = t3;
31609
+ $[18] = t4;
31610
+ $[19] = t5;
31611
+ $[20] = t6;
31612
+ $[21] = t12;
31613
+ } else {
31614
+ t12 = $[21];
31615
+ }
31616
+ let t13;
31617
+ if ($[22] !== t0 || $[23] !== t1 || $[24] !== t12) {
31618
+ t13 = /* @__PURE__ */ jsxRuntime.jsx("div", { className: "shrink-0 mt-auto px-4 pt-0.5 pb-2", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Tooltip, { title: t0, side: "right", sideOffset: 12, open: t1, children: t12 }) });
31619
+ $[22] = t0;
31620
+ $[23] = t1;
31621
+ $[24] = t12;
31622
+ $[25] = t13;
31623
+ } else {
31624
+ t13 = $[25];
31625
+ }
31626
+ return t13;
31627
+ }
31628
+ function DrawerLogo(t0) {
31629
+ const $ = reactCompilerRuntime.c(5);
31630
+ const {
31631
+ logo
31632
+ } = t0;
31633
+ const navigation = useNavigationController();
31634
+ let t1;
31635
+ if ($[0] !== logo) {
31636
+ t1 = logo ? /* @__PURE__ */ jsxRuntime.jsx("img", { src: logo, alt: "Logo", className: "w-[28px] h-[28px] object-contain" }) : /* @__PURE__ */ jsxRuntime.jsx(FireCMSLogo, { width: "28px", height: "28px" });
31637
+ $[0] = logo;
31638
+ $[1] = t1;
31639
+ } else {
31640
+ t1 = $[1];
31641
+ }
31642
+ let t2;
31643
+ if ($[2] !== navigation.basePath || $[3] !== t1) {
31644
+ t2 = /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-row items-center shrink-0 pt-4 pb-0 px-2", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Tooltip, { title: "Home", sideOffset: 20, side: "right", children: /* @__PURE__ */ jsxRuntime.jsx(reactRouterDom.Link, { className: "shrink-0 flex items-center justify-center w-[56px] h-[40px]", to: navigation.basePath, children: t1 }) }) });
31645
+ $[2] = navigation.basePath;
31646
+ $[3] = t1;
31647
+ $[4] = t2;
31648
+ } else {
31649
+ t2 = $[4];
31650
+ }
31651
+ return t2;
31059
31652
  }
31060
31653
  function UserSelectFieldBinding(t0) {
31061
31654
  const $ = reactCompilerRuntime.c(44);
@@ -31446,6 +32039,17 @@
31446
32039
  Field: DateTimeFieldBinding
31447
32040
  }
31448
32041
  },
32042
+ geopoint: {
32043
+ key: "geopoint",
32044
+ name: "Geopoint",
32045
+ description: "Latitude and longitude pair",
32046
+ Icon: ui.LocationOnIcon,
32047
+ color: "#0ea5e9",
32048
+ property: {
32049
+ dataType: "geopoint",
32050
+ Field: GeopointFieldBinding
32051
+ }
32052
+ },
31449
32053
  group: {
31450
32054
  key: "group",
31451
32055
  name: "Group",
@@ -31588,6 +32192,8 @@
31588
32192
  return "switch";
31589
32193
  } else if (property.dataType === "date") {
31590
32194
  return "date_time";
32195
+ } else if (property.dataType === "geopoint") {
32196
+ return "geopoint";
31591
32197
  } else if (property.dataType === "reference") {
31592
32198
  return "reference";
31593
32199
  }
@@ -31598,6 +32204,20 @@
31598
32204
  if (property.propertyConfig) return property.propertyConfig;
31599
32205
  return getDefaultFieldId(property);
31600
32206
  }
32207
+ const SIDE_PANEL_HASHES = ["#side", "#new_side"];
32208
+ function shouldBlockEntityNavigation(params) {
32209
+ const {
32210
+ currentLocation,
32211
+ nextLocation,
32212
+ entityPath,
32213
+ basePath,
32214
+ blocked
32215
+ } = params;
32216
+ if (nextLocation.pathname.startsWith(entityPath)) return false;
32217
+ if (SIDE_PANEL_HASHES.includes(nextLocation.hash)) return false;
32218
+ if (SIDE_PANEL_HASHES.includes(currentLocation.hash) && nextLocation.pathname === basePath) return false;
32219
+ return blocked;
32220
+ }
31601
32221
  const EntityEditView = lazyEager(() => Promise.resolve().then(() => EntityEditView$2), "EntityEditView");
31602
32222
  const EntityCollectionView = lazyEager(() => Promise.resolve().then(() => EntityCollectionView$2), "EntityCollectionView");
31603
32223
  function FireCMSRoute() {
@@ -31976,19 +32596,31 @@
31976
32596
  setSelectedTab(urlTab);
31977
32597
  }
31978
32598
  }, [urlTab]);
31979
- const basePath = !entityId || isNew ? pathname : pathname.substring(0, pathname.lastIndexOf(`/${entityId}`));
31980
- const entityPath = basePath + `/${entityId}`;
32599
+ const lastCollectionEntry = navigationEntries.findLast((entry_1) => entry_1.type === "collection");
32600
+ const entityEntryIndex = lastEntityEntry ? navigationEntries.indexOf(lastEntityEntry) : -1;
32601
+ const parentCollectionEntry = entityEntryIndex > 0 ? navigationEntries[entityEntryIndex - 1] : void 0;
32602
+ const buildUrl = (escapedPath) => addInitialSlash(navigation.buildUrlCollectionPath(escapedPath));
32603
+ const basePath = !entityId || isNew || !parentCollectionEntry ? pathname : buildUrl(parentCollectionEntry.fullPath);
32604
+ const entityPath = lastEntityEntry ? buildUrl(lastEntityEntry.fullPath) : basePath;
32605
+ const buildEntityUrl = (id, tab) => {
32606
+ const parentPath = parentCollectionEntry?.fullPath ?? lastCollectionEntry?.fullPath;
32607
+ if (!parentPath) return pathname;
32608
+ return buildUrl(`${parentPath}/${encodeEntityId(id)}${tab ? "/" + tab : ""}`);
32609
+ };
31981
32610
  let blocker = void 0;
31982
32611
  try {
31983
32612
  blocker = reactRouter.useBlocker(({
32613
+ currentLocation,
31984
32614
  nextLocation
31985
- }) => {
31986
- if (nextLocation.pathname.startsWith(entityPath)) return false;
31987
- return blocked.current;
31988
- });
32615
+ }) => shouldBlockEntityNavigation({
32616
+ currentLocation,
32617
+ nextLocation,
32618
+ entityPath,
32619
+ basePath,
32620
+ blocked: blocked.current
32621
+ }));
31989
32622
  } catch (e) {
31990
32623
  }
31991
- const lastCollectionEntry = navigationEntries.findLast((entry_1) => entry_1.type === "collection");
31992
32624
  if (isNew && !lastCollectionEntry) {
31993
32625
  throw new Error("INTERNAL: No collection found in the navigation");
31994
32626
  }
@@ -31996,36 +32628,23 @@
31996
32628
  return /* @__PURE__ */ jsxRuntime.jsx(NotFoundPage, {});
31997
32629
  }
31998
32630
  const collection = isNew ? lastCollectionEntry.collection : lastEntityEntry.parentCollection;
31999
- const fullIdPath = isNew ? lastCollectionEntry.path : lastEntityEntry.path;
32000
- const collectionPath = navigation.resolveIdsFrom(fullIdPath);
32631
+ const fullIdPath = isNew ? lastCollectionEntry.fullPath : parentCollectionEntry?.fullPath ?? lastEntityEntry.fullPath;
32632
+ const collectionPath = navigation.resolveIdsFrom(isNew ? lastCollectionEntry.path : lastEntityEntry.path);
32001
32633
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
32002
32634
  /* @__PURE__ */ jsxRuntime.jsx(React.Suspense, { fallback: null, children: /* @__PURE__ */ jsxRuntime.jsx(EntityEditView, { entityId: isNew ? void 0 : entityId, fullIdPath, collection, layout: "full_screen", path: collectionPath, copy: isCopy, selectedTab: selectedTab ?? void 0, onValuesModified: (modified) => blocked.current = modified, onSaved: (params) => {
32003
- const newSelectedTab = params.selectedTab;
32004
32635
  const newEntityId = params.entityId;
32005
- if (newSelectedTab) {
32006
- navigate(`${basePath}/${newEntityId}/${newSelectedTab}`, {
32007
- replace: true
32008
- });
32009
- } else {
32010
- navigate(`${basePath}/${newEntityId}`, {
32011
- replace: true
32012
- });
32013
- }
32636
+ if (!newEntityId) return;
32637
+ navigate(buildEntityUrl(newEntityId, params.selectedTab), {
32638
+ replace: true
32639
+ });
32014
32640
  }, onTabChange: (params_0) => {
32015
32641
  setSelectedTab(params_0.selectedTab);
32016
- if (isNew) {
32642
+ if (isNew || !entityId) {
32017
32643
  return;
32018
32644
  }
32019
- const newSelectedTab_0 = params_0.selectedTab;
32020
- if (newSelectedTab_0) {
32021
- navigate(`${basePath}/${entityId}/${newSelectedTab_0}`, {
32022
- replace: true
32023
- });
32024
- } else {
32025
- navigate(`${basePath}/${entityId}`, {
32026
- replace: true
32027
- });
32028
- }
32645
+ navigate(buildEntityUrl(entityId, params_0.selectedTab), {
32646
+ replace: true
32647
+ });
32029
32648
  }, parentCollectionIds }, collection.id + "_" + (isNew ? "new" : isCopy ? entityId + "_copy" : entityId)) }),
32030
32649
  /* @__PURE__ */ jsxRuntime.jsx(UnsavedChangesDialog, { open: blocker?.state === "blocked", handleOk: () => blocker?.proceed?.(), handleCancel: () => blocker?.reset?.(), body: "You have unsaved changes in this entity." })
32031
32650
  ] });
@@ -32271,7 +32890,7 @@
32271
32890
  const otherChildren = t3;
32272
32891
  const includeDrawer = drawerChildren.length > 0;
32273
32892
  const largeLayout = useLargeLayout();
32274
- const [drawerOpen, setDrawerOpen] = React.useState(false);
32893
+ const [drawerOpen, setDrawerOpen] = React.useState(_temp4$1);
32275
32894
  const [onHover, setOnHover] = React.useState(false);
32276
32895
  let t4;
32277
32896
  if ($[6] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
@@ -32283,7 +32902,12 @@
32283
32902
  const setOnHoverTrue = t4;
32284
32903
  let t5;
32285
32904
  if ($[7] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
32286
- t5 = () => setOnHover(false);
32905
+ t5 = () => {
32906
+ if (typeof document !== "undefined" && document.querySelector("[data-radix-popper-content-wrapper]")) {
32907
+ return;
32908
+ }
32909
+ setOnHover(false);
32910
+ };
32287
32911
  $[7] = t5;
32288
32912
  } else {
32289
32913
  t5 = $[7];
@@ -32293,6 +32917,10 @@
32293
32917
  if ($[8] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
32294
32918
  t6 = () => {
32295
32919
  setDrawerOpen(true);
32920
+ try {
32921
+ localStorage.setItem("firecms_drawer_open", "true");
32922
+ } catch {
32923
+ }
32296
32924
  };
32297
32925
  $[8] = t6;
32298
32926
  } else {
@@ -32303,30 +32931,36 @@
32303
32931
  if ($[9] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
32304
32932
  t7 = () => {
32305
32933
  setDrawerOpen(false);
32934
+ try {
32935
+ localStorage.setItem("firecms_drawer_open", "false");
32936
+ } catch {
32937
+ }
32306
32938
  };
32307
32939
  $[9] = t7;
32308
32940
  } else {
32309
32941
  t7 = $[9];
32310
32942
  }
32311
32943
  const handleDrawerClose = t7;
32312
- const computedDrawerOpen = drawerOpen || Boolean(largeLayout && autoOpenDrawer && onHover);
32944
+ const computedDrawerOpen = drawerOpen;
32945
+ const computedDrawerHovered = Boolean(largeLayout && onHover);
32313
32946
  const hasAppBar = Boolean(appBarChildren.length > 0);
32314
32947
  let t8;
32315
- if ($[10] !== autoOpenDrawer || $[11] !== computedDrawerOpen || $[12] !== includeDrawer || $[13] !== logo || $[14] !== onHover) {
32948
+ if ($[10] !== autoOpenDrawer || $[11] !== computedDrawerHovered || $[12] !== computedDrawerOpen || $[13] !== includeDrawer || $[14] !== logo) {
32316
32949
  t8 = {
32317
32950
  logo,
32318
32951
  hasDrawer: includeDrawer,
32319
- drawerHovered: onHover,
32952
+ drawerHovered: computedDrawerHovered,
32320
32953
  drawerOpen: computedDrawerOpen,
32321
32954
  closeDrawer: handleDrawerClose,
32322
32955
  openDrawer: handleDrawerOpen,
32956
+ closeHover: setOnHoverFalse,
32323
32957
  autoOpenDrawer
32324
32958
  };
32325
32959
  $[10] = autoOpenDrawer;
32326
- $[11] = computedDrawerOpen;
32327
- $[12] = includeDrawer;
32328
- $[13] = logo;
32329
- $[14] = onHover;
32960
+ $[11] = computedDrawerHovered;
32961
+ $[12] = computedDrawerOpen;
32962
+ $[13] = includeDrawer;
32963
+ $[14] = logo;
32330
32964
  $[15] = t8;
32331
32965
  } else {
32332
32966
  t8 = $[15];
@@ -32356,11 +32990,11 @@
32356
32990
  }
32357
32991
  const t11 = includeDrawer && drawerChildren;
32358
32992
  let t12;
32359
- if ($[20] !== computedDrawerOpen || $[21] !== includeDrawer || $[22] !== onHover || $[23] !== t11) {
32360
- t12 = /* @__PURE__ */ jsxRuntime.jsx(DrawerWrapper, { displayed: includeDrawer, onMouseEnter: setOnHoverTrue, onMouseMove: setOnHoverTrue, onMouseLeave: setOnHoverFalse, open: computedDrawerOpen, hovered: onHover, setDrawerOpen, children: t11 });
32361
- $[20] = computedDrawerOpen;
32362
- $[21] = includeDrawer;
32363
- $[22] = onHover;
32993
+ if ($[20] !== computedDrawerHovered || $[21] !== computedDrawerOpen || $[22] !== includeDrawer || $[23] !== t11) {
32994
+ t12 = /* @__PURE__ */ jsxRuntime.jsx(DrawerWrapper, { displayed: includeDrawer, onMouseEnter: setOnHoverTrue, onMouseMove: setOnHoverTrue, onMouseLeave: setOnHoverFalse, open: computedDrawerOpen, hovered: computedDrawerHovered, setDrawerOpen, children: t11 });
32995
+ $[20] = computedDrawerHovered;
32996
+ $[21] = computedDrawerOpen;
32997
+ $[22] = includeDrawer;
32364
32998
  $[23] = t11;
32365
32999
  $[24] = t12;
32366
33000
  } else {
@@ -32458,193 +33092,149 @@
32458
33092
  return t0;
32459
33093
  };
32460
33094
  function DrawerWrapper(props) {
32461
- const $ = reactCompilerRuntime.c(49);
33095
+ const $ = reactCompilerRuntime.c(36);
32462
33096
  const {
32463
33097
  t
32464
33098
  } = useTranslation();
32465
- const width = !props.displayed ? 0 : props.open ? DRAWER_WIDTH : 72;
32466
- let t0;
32467
- if ($[0] !== width) {
32468
- t0 = {
32469
- width,
32470
- transition: "left 100ms cubic-bezier(0.4, 0, 0.6, 1) 0ms, opacity 100ms cubic-bezier(0.4, 0, 0.6, 1) 0ms, width 100ms cubic-bezier(0.4, 0, 0.6, 1) 0ms"
32471
- };
32472
- $[0] = width;
32473
- $[1] = t0;
33099
+ const layoutWidth = !props.displayed ? 0 : props.open ? DRAWER_WIDTH : 72;
33100
+ const visualWidth = !props.displayed ? 0 : props.open || props.hovered ? DRAWER_WIDTH : 72;
33101
+ const isFloating = props.hovered && !props.open;
33102
+ const t0 = isFloating ? "absolute top-0 left-0 bottom-0 z-30 bg-surface-50 dark:bg-surface-900 shadow-lg border-r" : "relative bg-surface-50 dark:bg-surface-900";
33103
+ let t1;
33104
+ if ($[0] !== t0) {
33105
+ t1 = ui.cls("h-full overflow-hidden", ui.defaultBorderMixin, t0);
33106
+ $[0] = t0;
33107
+ $[1] = t1;
32474
33108
  } else {
32475
- t0 = $[1];
33109
+ t1 = $[1];
32476
33110
  }
32477
- let t1;
32478
- if ($[2] !== props || $[3] !== t) {
32479
- t1 = !props.open && props.displayed && /* @__PURE__ */ jsxRuntime.jsx(ui.Tooltip, { title: t("open_menu"), side: "right", sideOffset: 12, asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "ml-2 fixed top-1 left-2 sm:top-2 sm:left-2 !bg-surface-50 dark:!bg-surface-900 rounded-full w-fit z-20", children: /* @__PURE__ */ jsxRuntime.jsx(ui.IconButton, { color: "inherit", "aria-label": t("open_menu"), onClick: () => props.setDrawerOpen(true), size: "large", children: /* @__PURE__ */ jsxRuntime.jsx(ui.MenuIcon, { size: "small" }) }) }) });
32480
- $[2] = props;
32481
- $[3] = t;
32482
- $[4] = t1;
33111
+ let t2;
33112
+ if ($[2] !== visualWidth) {
33113
+ t2 = {
33114
+ width: visualWidth,
33115
+ transition: "left 75ms cubic-bezier(0.4, 0, 0.6, 1) 0ms, opacity 75ms cubic-bezier(0.4, 0, 0.6, 1) 0ms, width 75ms cubic-bezier(0.4, 0, 0.6, 1) 0ms"
33116
+ };
33117
+ $[2] = visualWidth;
33118
+ $[3] = t2;
32483
33119
  } else {
32484
- t1 = $[4];
33120
+ t2 = $[3];
32485
33121
  }
32486
- const t2 = `z-20 absolute right-0 top-4 ${props.open ? "opacity-100" : "opacity-0 invisible"} transition-opacity duration-200 ease-in-out`;
32487
33122
  let t3;
32488
- if ($[5] !== t) {
32489
- t3 = t("close_drawer");
32490
- $[5] = t;
32491
- $[6] = t3;
33123
+ if ($[4] !== props.children) {
33124
+ t3 = /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col h-full", children: props.children });
33125
+ $[4] = props.children;
33126
+ $[5] = t3;
32492
33127
  } else {
32493
- t3 = $[6];
33128
+ t3 = $[5];
32494
33129
  }
32495
33130
  let t4;
32496
- if ($[7] !== props) {
32497
- t4 = () => props.setDrawerOpen(false);
32498
- $[7] = props;
32499
- $[8] = t4;
32500
- } else {
32501
- t4 = $[8];
32502
- }
32503
- let t5;
32504
- if ($[9] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
32505
- t5 = /* @__PURE__ */ jsxRuntime.jsx(ui.ChevronLeftIcon, {});
32506
- $[9] = t5;
32507
- } else {
32508
- t5 = $[9];
32509
- }
32510
- let t6;
32511
- if ($[10] !== t3 || $[11] !== t4) {
32512
- t6 = /* @__PURE__ */ jsxRuntime.jsx(ui.IconButton, { "aria-label": t3, onClick: t4, children: t5 });
32513
- $[10] = t3;
32514
- $[11] = t4;
32515
- $[12] = t6;
32516
- } else {
32517
- t6 = $[12];
32518
- }
32519
- let t7;
32520
- if ($[13] !== t2 || $[14] !== t6) {
32521
- t7 = /* @__PURE__ */ jsxRuntime.jsx("div", { className: t2, children: t6 });
32522
- $[13] = t2;
32523
- $[14] = t6;
32524
- $[15] = t7;
32525
- } else {
32526
- t7 = $[15];
32527
- }
32528
- let t8;
32529
- if ($[16] !== props.children) {
32530
- t8 = /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col h-full", children: props.children });
32531
- $[16] = props.children;
32532
- $[17] = t8;
32533
- } else {
32534
- t8 = $[17];
32535
- }
32536
- let t9;
32537
- if ($[18] !== t0 || $[19] !== t1 || $[20] !== t7 || $[21] !== t8) {
32538
- t9 = /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative h-full no-scrollbar overflow-y-auto overflow-x-hidden", style: t0, children: [
32539
- t1,
32540
- t7,
32541
- t8
32542
- ] });
32543
- $[18] = t0;
32544
- $[19] = t1;
32545
- $[20] = t7;
32546
- $[21] = t8;
32547
- $[22] = t9;
33131
+ if ($[6] !== t1 || $[7] !== t2 || $[8] !== t3) {
33132
+ t4 = /* @__PURE__ */ jsxRuntime.jsx("div", { className: t1, style: t2, children: t3 });
33133
+ $[6] = t1;
33134
+ $[7] = t2;
33135
+ $[8] = t3;
33136
+ $[9] = t4;
32548
33137
  } else {
32549
- t9 = $[22];
33138
+ t4 = $[9];
32550
33139
  }
32551
- const innerDrawer = t9;
33140
+ const innerDrawer = t4;
32552
33141
  const largeLayout = useLargeLayout();
32553
33142
  if (!largeLayout) {
32554
33143
  if (!props.displayed) {
32555
33144
  return null;
32556
33145
  }
32557
- let t102;
32558
- if ($[23] !== t) {
32559
- t102 = t("open_menu");
32560
- $[23] = t;
32561
- $[24] = t102;
33146
+ let t52;
33147
+ if ($[10] !== t) {
33148
+ t52 = t("open_menu");
33149
+ $[10] = t;
33150
+ $[11] = t52;
32562
33151
  } else {
32563
- t102 = $[24];
33152
+ t52 = $[11];
32564
33153
  }
32565
- let t112;
32566
- if ($[25] !== props) {
32567
- t112 = () => props.setDrawerOpen(true);
32568
- $[25] = props;
32569
- $[26] = t112;
33154
+ let t62;
33155
+ if ($[12] !== props) {
33156
+ t62 = () => props.setDrawerOpen(true);
33157
+ $[12] = props;
33158
+ $[13] = t62;
32570
33159
  } else {
32571
- t112 = $[26];
33160
+ t62 = $[13];
32572
33161
  }
32573
- let t12;
32574
- if ($[27] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
32575
- t12 = /* @__PURE__ */ jsxRuntime.jsx(ui.MenuIcon, {});
32576
- $[27] = t12;
33162
+ let t7;
33163
+ if ($[14] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
33164
+ t7 = /* @__PURE__ */ jsxRuntime.jsx(ui.MenuIcon, {});
33165
+ $[14] = t7;
32577
33166
  } else {
32578
- t12 = $[27];
33167
+ t7 = $[14];
32579
33168
  }
32580
- let t13;
32581
- if ($[28] !== t102 || $[29] !== t112) {
32582
- t13 = /* @__PURE__ */ jsxRuntime.jsx(ui.IconButton, { color: "inherit", "aria-label": t102, onClick: t112, size: "large", className: "absolute sm:top-2 sm:left-4 top-1 left-2", children: t12 });
32583
- $[28] = t102;
32584
- $[29] = t112;
32585
- $[30] = t13;
33169
+ let t8;
33170
+ if ($[15] !== t52 || $[16] !== t62) {
33171
+ t8 = /* @__PURE__ */ jsxRuntime.jsx(ui.IconButton, { color: "inherit", "aria-label": t52, onClick: t62, size: "large", className: "absolute sm:top-2 sm:left-4 top-1 left-2", children: t7 });
33172
+ $[15] = t52;
33173
+ $[16] = t62;
33174
+ $[17] = t8;
32586
33175
  } else {
32587
- t13 = $[30];
33176
+ t8 = $[17];
32588
33177
  }
32589
- const t14 = props.open;
32590
- const t15 = props.setDrawerOpen;
32591
- let t16;
32592
- if ($[31] !== t) {
32593
- t16 = t("navigation_drawer");
32594
- $[31] = t;
32595
- $[32] = t16;
33178
+ const t9 = props.open;
33179
+ const t10 = props.setDrawerOpen;
33180
+ let t11;
33181
+ if ($[18] !== t) {
33182
+ t11 = t("navigation_drawer");
33183
+ $[18] = t;
33184
+ $[19] = t11;
32596
33185
  } else {
32597
- t16 = $[32];
33186
+ t11 = $[19];
32598
33187
  }
32599
- let t17;
32600
- if ($[33] !== innerDrawer || $[34] !== props.open || $[35] !== props.setDrawerOpen || $[36] !== t16) {
32601
- t17 = /* @__PURE__ */ jsxRuntime.jsx(ui.Sheet, { side: "left", transparent: true, open: t14, onOpenChange: t15, title: t16, overlayClassName: "bg-white bg-opacity-80 bg-white/80", children: innerDrawer });
32602
- $[33] = innerDrawer;
32603
- $[34] = props.open;
32604
- $[35] = props.setDrawerOpen;
32605
- $[36] = t16;
32606
- $[37] = t17;
33188
+ let t12;
33189
+ if ($[20] !== innerDrawer || $[21] !== props.open || $[22] !== props.setDrawerOpen || $[23] !== t11) {
33190
+ t12 = /* @__PURE__ */ jsxRuntime.jsx(ui.Sheet, { side: "left", transparent: true, open: t9, onOpenChange: t10, title: t11, overlayClassName: "bg-white bg-opacity-80 bg-white/80", children: innerDrawer });
33191
+ $[20] = innerDrawer;
33192
+ $[21] = props.open;
33193
+ $[22] = props.setDrawerOpen;
33194
+ $[23] = t11;
33195
+ $[24] = t12;
32607
33196
  } else {
32608
- t17 = $[37];
33197
+ t12 = $[24];
32609
33198
  }
32610
- let t18;
32611
- if ($[38] !== t13 || $[39] !== t17) {
32612
- t18 = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
32613
- t13,
32614
- t17
33199
+ let t13;
33200
+ if ($[25] !== t12 || $[26] !== t8) {
33201
+ t13 = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
33202
+ t8,
33203
+ t12
32615
33204
  ] });
32616
- $[38] = t13;
32617
- $[39] = t17;
32618
- $[40] = t18;
33205
+ $[25] = t12;
33206
+ $[26] = t8;
33207
+ $[27] = t13;
32619
33208
  } else {
32620
- t18 = $[40];
33209
+ t13 = $[27];
32621
33210
  }
32622
- return t18;
33211
+ return t13;
32623
33212
  }
32624
- let t10;
32625
- if ($[41] !== width) {
32626
- t10 = {
32627
- width,
32628
- transition: "left 100ms cubic-bezier(0.4, 0, 0.6, 1) 0ms, opacity 100ms cubic-bezier(0.4, 0, 0.6, 1) 0ms, width 100ms cubic-bezier(0.4, 0, 0.6, 1) 0ms"
33213
+ let t5;
33214
+ if ($[28] !== layoutWidth) {
33215
+ t5 = {
33216
+ width: layoutWidth,
33217
+ minWidth: layoutWidth,
33218
+ transition: "left 75ms cubic-bezier(0.4, 0, 0.6, 1) 0ms, opacity 75ms cubic-bezier(0.4, 0, 0.6, 1) 0ms, width 75ms cubic-bezier(0.4, 0, 0.6, 1) 0ms"
32629
33219
  };
32630
- $[41] = width;
32631
- $[42] = t10;
33220
+ $[28] = layoutWidth;
33221
+ $[29] = t5;
32632
33222
  } else {
32633
- t10 = $[42];
33223
+ t5 = $[29];
32634
33224
  }
32635
- let t11;
32636
- if ($[43] !== innerDrawer || $[44] !== props.onMouseEnter || $[45] !== props.onMouseLeave || $[46] !== props.onMouseMove || $[47] !== t10) {
32637
- t11 = /* @__PURE__ */ jsxRuntime.jsx("div", { className: "z-20 relative", onMouseEnter: props.onMouseEnter, onMouseMove: props.onMouseMove, onMouseLeave: props.onMouseLeave, style: t10, children: innerDrawer });
32638
- $[43] = innerDrawer;
32639
- $[44] = props.onMouseEnter;
32640
- $[45] = props.onMouseLeave;
32641
- $[46] = props.onMouseMove;
32642
- $[47] = t10;
32643
- $[48] = t11;
33225
+ let t6;
33226
+ if ($[30] !== innerDrawer || $[31] !== props.onMouseEnter || $[32] !== props.onMouseLeave || $[33] !== props.onMouseMove || $[34] !== t5) {
33227
+ t6 = /* @__PURE__ */ jsxRuntime.jsx("div", { className: "z-20 relative flex-shrink-0 overflow-visible", onMouseEnter: props.onMouseEnter, onMouseMove: props.onMouseMove, onMouseLeave: props.onMouseLeave, style: t5, children: innerDrawer });
33228
+ $[30] = innerDrawer;
33229
+ $[31] = props.onMouseEnter;
33230
+ $[32] = props.onMouseLeave;
33231
+ $[33] = props.onMouseMove;
33232
+ $[34] = t5;
33233
+ $[35] = t6;
32644
33234
  } else {
32645
- t11 = $[48];
33235
+ t6 = $[35];
32646
33236
  }
32647
- return t11;
33237
+ return t6;
32648
33238
  }
32649
33239
  function _temp$6(child) {
32650
33240
  return child.type.componentType === "Drawer";
@@ -32655,6 +33245,13 @@
32655
33245
  function _temp3$1(child_1) {
32656
33246
  return child_1.type.componentType !== "Drawer" && child_1.type.componentType !== "AppBar";
32657
33247
  }
33248
+ function _temp4$1() {
33249
+ try {
33250
+ return localStorage.getItem("firecms_drawer_open") === "true";
33251
+ } catch {
33252
+ return false;
33253
+ }
33254
+ }
32658
33255
  const en = {
32659
33256
  // ─── Form actions ────────────────────────────────────────────
32660
33257
  save: "Save",
@@ -32792,8 +33389,8 @@
32792
33389
  // ─── Error states ─────────────────────────────────────────────
32793
33390
  error: "Error",
32794
33391
  error_uploading_file: "Error uploading file",
32795
- error_deleting: "Error deleting",
32796
- error_before_delete: "Error before delete",
33392
+ error_deleting: "Error deleting: {{message}}",
33393
+ error_before_delete: "Error before delete: {{message}}",
32797
33394
  error_updating_asset: "Error updating asset",
32798
33395
  error_deleting_asset: "Error deleting asset",
32799
33396
  error_firestore_index: "A Firestore index is required for this query.",
@@ -33130,10 +33727,18 @@
33130
33727
  auto_setup_collections_button: "Automatically set up collections",
33131
33728
  auto_setup_collections_title: "Automatically set up collections?",
33132
33729
  auto_setup_collections_desc: "This will automatically create collection configs for collections that are <b>NOT</b> already mapped",
33133
- this_can_take_a_minute: "This can take a minute or two",
33730
+ setting_up_collections: "Setting up collections",
33731
+ setting_up_collection: "Setting up {{name}}",
33134
33732
  no_collections_found_to_setup: "No collections found to setup.",
33135
33733
  collections_have_been_setup: "Collections have been automatically setup.",
33136
33734
  error_setting_up_collections: "Error automatically setting up collections",
33735
+ setup_collections_title: "Set up collections",
33736
+ setup_collections_select_desc: "Select which collections to automatically set up:",
33737
+ select_all: "Select all",
33738
+ deselect_all: "Deselect all",
33739
+ setup_collections_confirm: "Set up ({{count}})",
33740
+ collection_setup_success: "{{name}} has been set up",
33741
+ go_to_collection: "Go to collection",
33137
33742
  // --- Home Suggestions ---
33138
33743
  add_your: "Add your",
33139
33744
  database_collections: "database collections",
@@ -33461,8 +34066,8 @@
33461
34066
  // ─── Error states ─────────────────────────────────────────────
33462
34067
  error: "Error",
33463
34068
  error_uploading_file: "Error al subir archivo",
33464
- error_deleting: "Error al eliminar",
33465
- error_before_delete: "Error antes de eliminar",
34069
+ error_deleting: "Error al eliminar: {{message}}",
34070
+ error_before_delete: "Error antes de eliminar: {{message}}",
33466
34071
  error_updating_asset: "Error al actualizar recurso",
33467
34072
  error_deleting_asset: "Error al eliminar recurso",
33468
34073
  error_firestore_index: "Se requiere un índice de Firestore para esta consulta.",
@@ -33801,10 +34406,18 @@
33801
34406
  auto_setup_collections_button: "Configurar colecciones automáticamente",
33802
34407
  auto_setup_collections_title: "¿Configurar colecciones automáticamente?",
33803
34408
  auto_setup_collections_desc: "Esto creará automáticamente la configuración de las colecciones que <b>NO</b> estén mapeadas",
33804
- this_can_take_a_minute: "Esto puede tardar un minuto o dos",
34409
+ setting_up_collections: "Configurando colecciones",
34410
+ setting_up_collection: "Configurando {{name}}",
33805
34411
  no_collections_found_to_setup: "No se encontraron colecciones para configurar",
33806
34412
  collections_have_been_setup: "¡Tus colecciones han sido configuradas!",
33807
34413
  error_setting_up_collections: "Error al configurar colecciones",
34414
+ setup_collections_title: "Set up collections",
34415
+ setup_collections_select_desc: "Select which collections to automatically set up:",
34416
+ select_all: "Select all",
34417
+ deselect_all: "Deselect all",
34418
+ setup_collections_confirm: "Set up ({{count}})",
34419
+ collection_setup_success: "{{name}} has been set up",
34420
+ go_to_collection: "Go to collection",
33808
34421
  // --- Home Suggestions ---
33809
34422
  add_your: "Añade tus",
33810
34423
  database_collections: "colecciones de base de datos",
@@ -34134,8 +34747,8 @@
34134
34747
  // ─── Error states ─────────────────────────────────────────────
34135
34748
  error: "Fehler",
34136
34749
  error_uploading_file: "Fehler beim Hochladen der Datei",
34137
- error_deleting: "Fehler beim Löschen",
34138
- error_before_delete: "Fehler vor dem Löschen",
34750
+ error_deleting: "Fehler beim Löschen: {{message}}",
34751
+ error_before_delete: "Fehler vor dem Löschen: {{message}}",
34139
34752
  error_updating_asset: "Fehler beim Aktualisieren des Assets",
34140
34753
  error_deleting_asset: "Fehler beim Löschen des Assets",
34141
34754
  error_firestore_index: "Für diese Abfrage ist ein Firestore-Index erforderlich.",
@@ -34472,10 +35085,18 @@
34472
35085
  auto_setup_collections_button: "Sammlungen automatisch einrichten",
34473
35086
  auto_setup_collections_title: "Sammlungen automatisch einrichten?",
34474
35087
  auto_setup_collections_desc: "Dadurch werden automatisch Sammlungskonfigurationen für Sammlungen erstellt, die noch <b>NICHT</b> zugeordnet sind.",
34475
- this_can_take_a_minute: "Dies kann ein bis zwei Minuten dauern",
35088
+ setting_up_collections: "Sammlungen werden eingerichtet",
35089
+ setting_up_collection: "{{name}} wird eingerichtet",
34476
35090
  no_collections_found_to_setup: "Keine einzurichtenden Sammlungen gefunden",
34477
35091
  collections_have_been_setup: "Sammlungen wurden automatisch eingerichtet",
34478
35092
  error_setting_up_collections: "Fehler beim automatischen Einrichten der Sammlungen",
35093
+ setup_collections_title: "Set up collections",
35094
+ setup_collections_select_desc: "Select which collections to automatically set up:",
35095
+ select_all: "Select all",
35096
+ deselect_all: "Deselect all",
35097
+ setup_collections_confirm: "Set up ({{count}})",
35098
+ collection_setup_success: "{{name}} has been set up",
35099
+ go_to_collection: "Go to collection",
34479
35100
  add_your: "Fügen Sie Ihre",
34480
35101
  database_collections: "Datenbanksammlungen",
34481
35102
  to_firecms: "zu FireCMS hinzu",
@@ -34803,8 +35424,8 @@
34803
35424
  // ─── Error states ─────────────────────────────────────────────
34804
35425
  error: "Erreur",
34805
35426
  error_uploading_file: "Erreur lors du téléchargement du fichier",
34806
- error_deleting: "Erreur lors de la suppression",
34807
- error_before_delete: "Erreur avant la suppression",
35427
+ error_deleting: "Erreur lors de la suppression: {{message}}",
35428
+ error_before_delete: "Erreur avant la suppression: {{message}}",
34808
35429
  error_updating_asset: "Erreur lors de la mise à jour de l'actif",
34809
35430
  error_deleting_asset: "Erreur lors de la suppression de l'actif",
34810
35431
  error_firestore_index: "Un index Firestore est requis pour cette requête.",
@@ -35141,10 +35762,18 @@
35141
35762
  auto_setup_collections_button: "Configurer les collections automatiquement",
35142
35763
  auto_setup_collections_title: "Configurer les collections automatiquement ?",
35143
35764
  auto_setup_collections_desc: "Cela créera automatiquement des configurations de collection pour les collections qui ne sont <b>PAS</b> déjà mappées",
35144
- this_can_take_a_minute: "Cela peut prendre une minute",
35765
+ setting_up_collections: "Configuration des collections",
35766
+ setting_up_collection: "Configuration de {{name}}",
35145
35767
  no_collections_found_to_setup: "Aucune collection à configurer trouvée",
35146
35768
  collections_have_been_setup: "Les collections ont été configurées",
35147
35769
  error_setting_up_collections: "Erreur lors de la configuration des collections",
35770
+ setup_collections_title: "Set up collections",
35771
+ setup_collections_select_desc: "Select which collections to automatically set up:",
35772
+ select_all: "Select all",
35773
+ deselect_all: "Deselect all",
35774
+ setup_collections_confirm: "Set up ({{count}})",
35775
+ collection_setup_success: "{{name}} has been set up",
35776
+ go_to_collection: "Go to collection",
35148
35777
  add_your: "Ajoutez vos",
35149
35778
  database_collections: "collections de base de données",
35150
35779
  to_firecms: "à FireCMS",
@@ -35472,8 +36101,8 @@
35472
36101
  // ─── Error states ─────────────────────────────────────────────
35473
36102
  error: "Errore",
35474
36103
  error_uploading_file: "Errore durante il caricamento del file",
35475
- error_deleting: "Errore durante l'eliminazione",
35476
- error_before_delete: "Errore prima dell'eliminazione",
36104
+ error_deleting: "Errore durante l'eliminazione: {{message}}",
36105
+ error_before_delete: "Errore prima dell'eliminazione: {{message}}",
35477
36106
  error_updating_asset: "Errore durante l'aggiornamento dell'asset",
35478
36107
  error_deleting_asset: "Errore durante l'eliminazione dell'asset",
35479
36108
  error_firestore_index: "Per questa query è richiesto un indice Firestore.",
@@ -35810,10 +36439,18 @@
35810
36439
  auto_setup_collections_button: "Configura le collezioni automaticamente",
35811
36440
  auto_setup_collections_title: "Configurazione automatica delle collezioni",
35812
36441
  auto_setup_collections_desc: "Configura le collezioni automaticamente in base ai dati Firestore esistenti. Lascia che FireCMS configuri il CMS perfetto per te.",
35813
- this_can_take_a_minute: "Potrebbe richiedere qualche minuto",
36442
+ setting_up_collections: "Configurazione delle collezioni",
36443
+ setting_up_collection: "Configurazione di {{name}}",
35814
36444
  no_collections_found_to_setup: "Nessuna collezione trovata da configurare",
35815
36445
  collections_have_been_setup: "Le collezioni sono state configurate",
35816
36446
  error_setting_up_collections: "Errore durante la configurazione delle collezioni",
36447
+ setup_collections_title: "Set up collections",
36448
+ setup_collections_select_desc: "Select which collections to automatically set up:",
36449
+ select_all: "Select all",
36450
+ deselect_all: "Deselect all",
36451
+ setup_collections_confirm: "Set up ({{count}})",
36452
+ collection_setup_success: "{{name}} has been set up",
36453
+ go_to_collection: "Go to collection",
35817
36454
  add_your: "Aggiungi le tue",
35818
36455
  database_collections: "collezioni del database",
35819
36456
  to_firecms: "a FireCMS",
@@ -36141,8 +36778,8 @@
36141
36778
  // ─── Error states ─────────────────────────────────────────────
36142
36779
  error: "त्रुटि",
36143
36780
  error_uploading_file: "फ़ाइल अपलोड करने में त्रुटि",
36144
- error_deleting: "हटाने में त्रुटि",
36145
- error_before_delete: "हटाने से पहले त्रुटि",
36781
+ error_deleting: "हटाने में त्रुटि: {{message}}",
36782
+ error_before_delete: "हटाने से पहले त्रुटि: {{message}}",
36146
36783
  error_updating_asset: "एसेट अपडेट करने में त्रुटि",
36147
36784
  error_deleting_asset: "एसेट हटाने में त्रुटि",
36148
36785
  error_firestore_index: "इस क्वेरी के लिए Firestore इंडेक्स आवश्यक है।",
@@ -36479,10 +37116,18 @@
36479
37116
  auto_setup_collections_button: "संग्रहों को स्वचालित रूप से सेट करें",
36480
37117
  auto_setup_collections_title: "संग्रहों की स्वचालित सेटअप",
36481
37118
  auto_setup_collections_desc: "अपने मौजूदा Firestore डेटा के आधार पर संग्रहों को स्वचालित रूप से सेट करें। FireCMS को आपके लिए परफेक्ट CMS कॉन्फ़िगर करने दें।",
36482
- this_can_take_a_minute: "इसमें एक मिनट लग सकता है",
37119
+ setting_up_collections: "संग्रह सेट किए जा रहे हैं",
37120
+ setting_up_collection: "{{name}} सेट किया जा रहा है",
36483
37121
  no_collections_found_to_setup: "सेट करने के लिए कोई संग्रह नहीं मिला",
36484
37122
  collections_have_been_setup: "संग्रहों को सेट कर दिया गया है",
36485
37123
  error_setting_up_collections: "संग्रह सेट करने में त्रुटि",
37124
+ setup_collections_title: "Set up collections",
37125
+ setup_collections_select_desc: "Select which collections to automatically set up:",
37126
+ select_all: "Select all",
37127
+ deselect_all: "Deselect all",
37128
+ setup_collections_confirm: "Set up ({{count}})",
37129
+ collection_setup_success: "{{name}} has been set up",
37130
+ go_to_collection: "Go to collection",
36486
37131
  add_your: "अपने",
36487
37132
  database_collections: "डेटाबेस संग्रह",
36488
37133
  to_firecms: "को FireCMS में जोड़ें",
@@ -36810,8 +37455,8 @@
36810
37455
  // ─── Error states ─────────────────────────────────────────────
36811
37456
  error: "Erro",
36812
37457
  error_uploading_file: "Erro ao carregar ficheiro",
36813
- error_deleting: "Erro ao eliminar",
36814
- error_before_delete: "Erro antes de eliminar",
37458
+ error_deleting: "Erro ao eliminar: {{message}}",
37459
+ error_before_delete: "Erro antes de eliminar: {{message}}",
36815
37460
  error_updating_asset: "Erro ao atualizar recurso",
36816
37461
  error_deleting_asset: "Erro ao eliminar recurso",
36817
37462
  error_firestore_index: "É necessário um índice Firestore para esta consulta.",
@@ -37148,10 +37793,18 @@
37148
37793
  auto_setup_collections_button: "Configurar coleções automaticamente",
37149
37794
  auto_setup_collections_title: "Configurar coleções automaticamente?",
37150
37795
  auto_setup_collections_desc: "Isto criará automaticamente configurações de coleção para coleções que <b>NÃO</b> estão já mapeadas",
37151
- this_can_take_a_minute: "Isto pode demorar um ou dois minutos",
37796
+ setting_up_collections: "Configurando coleções",
37797
+ setting_up_collection: "Configurando {{name}}",
37152
37798
  no_collections_found_to_setup: "Nenhuma coleção encontrada para configurar.",
37153
37799
  collections_have_been_setup: "As coleções foram configuradas automaticamente.",
37154
37800
  error_setting_up_collections: "Erro ao configurar coleções automaticamente",
37801
+ setup_collections_title: "Set up collections",
37802
+ setup_collections_select_desc: "Select which collections to automatically set up:",
37803
+ select_all: "Select all",
37804
+ deselect_all: "Deselect all",
37805
+ setup_collections_confirm: "Set up ({{count}})",
37806
+ collection_setup_success: "{{name}} has been set up",
37807
+ go_to_collection: "Go to collection",
37155
37808
  // --- Home Suggestions ---
37156
37809
  add_your: "Adicione as suas",
37157
37810
  database_collections: "coleções da base de dados",
@@ -37344,6 +37997,685 @@
37344
37997
  marketplace_link_error: "Erro ao vincular o projeto. Por favor, tente novamente.",
37345
37998
  marketplace_no_account_id: "Nenhum ID de conta do GCP Marketplace encontrado. Por favor, comece pelo GCP Marketplace."
37346
37999
  };
38000
+ const pl = {
38001
+ // ─── Form actions ────────────────────────────────────────────
38002
+ save: "Zapisz",
38003
+ create: "Utwórz",
38004
+ create_copy: "Utwórz kopię",
38005
+ save_and_close: "Zapisz i zamknij",
38006
+ create_copy_and_close: "Utwórz kopię i zamknij",
38007
+ create_and_close: "Utwórz i zamknij",
38008
+ discard: "Odrzuć",
38009
+ clear: "Wyczyść",
38010
+ cancel: "Anuluj",
38011
+ // ─── Entity actions ──────────────────────────────────────────
38012
+ edit: "Edytuj",
38013
+ copy: "Kopiuj",
38014
+ delete: "Usuń",
38015
+ // ─── Delete dialog ───────────────────────────────────────────
38016
+ delete_confirmation_title: "Usunąć?",
38017
+ delete_confirmation_body: "Spowoduje to usunięcie encji. Czy na pewno chcesz kontynuować?",
38018
+ delete_multiple_confirmation_body: "Spowoduje to usunięcie zaznaczonych encji. Czy na pewno chcesz kontynuować?",
38019
+ // ─── Unsaved-changes dialog ───────────────────────────────────
38020
+ unsaved_changes_title: "Niezapisane zmiany",
38021
+ unsaved_changes_body: "Masz niezapisane zmiany. Czy chcesz je odrzucić?",
38022
+ discard_changes: "Odrzuć zmiany",
38023
+ keep_editing: "Kontynuuj edycję",
38024
+ // ─── Collection table / toolbar ──────────────────────────────
38025
+ search: "Szukaj",
38026
+ find_by_id: "Znajdź po ID",
38027
+ find_entity_by_id: "Znajdź encję po ID",
38028
+ filter: "Filtr",
38029
+ filters: "Filtry",
38030
+ clear_filter: "Wyczyść filtr",
38031
+ clear_filter_sort: "Wyczyść filtr/sortowanie",
38032
+ clear_sort: "Wyczyść sortowanie",
38033
+ no_items: "Brak elementów",
38034
+ no_entries_found: "Nie znaleziono wpisów",
38035
+ all_entries_loaded: "Wczytano wszystkie wpisy ({{count}})",
38036
+ create_your_first_entry: "Utwórz swój pierwszy wpis",
38037
+ no_results_filter_sort: "Brak wyników dla zastosowanego filtra/sortowania",
38038
+ add: "Dodaj",
38039
+ remove: "Usuń",
38040
+ multiple_entities: "Wiele encji",
38041
+ unsaved_changes: "Masz niezapisane zmiany w kolekcji {{collectionName}}.",
38042
+ so_empty: "Tak pusto...",
38043
+ no_results: "Brak wyników dla zastosowanego filtra/sortowania",
38044
+ refresh_data: "Odśwież dane",
38045
+ dark_mode: "Ciemny",
38046
+ light_mode: "Jasny",
38047
+ system_mode: "Systemowy",
38048
+ ok: "Ok",
38049
+ save_collection_config: "Zapisz strukturę kolekcji",
38050
+ search_for_more_icons: "Szukaj więcej ikon…",
38051
+ ai_modified: "Zmodyfikowane przez AI",
38052
+ size_label: "Rozmiar",
38053
+ group_by: "Grupuj według",
38054
+ initialize_kanban_order: "Zainicjuj kolejność Kanban",
38055
+ copy_id: "Kopiuj ID",
38056
+ add_specific: "Dodaj {{name}}",
38057
+ select_specific: "Wybierz {{name}}",
38058
+ select_from: "Wybierz z {{name}}",
38059
+ done: "Gotowe",
38060
+ log_out: "Wyloguj się",
38061
+ license_needed: "Wymagana licencja",
38062
+ license_description: "Aby korzystać z FireCMS PRO, potrzebujesz ważnej licencji. Skontaktuj się z nami pod adresem {{email}}, aby uzyskać więcej informacji.",
38063
+ column_cannot_be_edited: "Ta kolumna nie może być edytowana bezpośrednio",
38064
+ close: "Zamknij",
38065
+ unsaved_local_changes: "Niezapisane zmiany lokalne",
38066
+ unsaved_local_changes_description: "Ten dokument został zmodyfikowany lokalnie i zawiera niezapisane zmiany. Zmiany te zostaną utracone, jeśli ich nie zastosujesz.",
38067
+ preview_changes: "Podgląd zmian",
38068
+ apply_changes: "Zastosuj zmiany",
38069
+ discard_local_changes: "Odrzuć zmiany lokalne",
38070
+ preview_local_changes: "Podgląd zmian lokalnych",
38071
+ preview_local_changes_description: "To są zmiany lokalne, które zostaną zastosowane do formularza.",
38072
+ type: "Typ",
38073
+ string: "tekst",
38074
+ number: "liczba",
38075
+ boolean: "wartość logiczna",
38076
+ date: "data",
38077
+ map: "mapa",
38078
+ array: "tablica",
38079
+ arrays_of_arrays_not_supported: "Tablice tablic nie są obsługiwane.",
38080
+ data_type_not_supported: "Typ danych {{dataType}} nie jest jeszcze obsługiwany",
38081
+ passkey_error_unsupported: "Twoje urządzenie lub przeglądarka nie obsługuje kluczy dostępu (passkeys).",
38082
+ admin: "Administrator",
38083
+ home: "Strona główna",
38084
+ this_form_has_errors: "Ten formularz zawiera błędy",
38085
+ error_loading_navigation: "Błąd wczytywania nawigacji",
38086
+ error_loading_auth: "Błąd wczytywania uwierzytelniania",
38087
+ this_form_has_been_modified: "Ten formularz został zmodyfikowany",
38088
+ current_form_in_sync: "Bieżący formularz jest zsynchronizowany z bazą danych",
38089
+ open_in_console: "Otwórz w konsoli",
38090
+ collection_does_not_exist: "Podana kolekcja nie istnieje. Sprawdź konsolę",
38091
+ unexpected_value: "Nieoczekiwana wartość",
38092
+ unexpected_value_click_to_edit: "Nieoczekiwana wartość. Kliknij, aby edytować",
38093
+ unexpected_reference_value: "Nieoczekiwana wartość referencji. Kliknij, aby edytować",
38094
+ copy_url_to_clipboard: "Kopiuj adres URL do schowka",
38095
+ open_image_in_new_tab: "Otwórz obraz w nowej karcie",
38096
+ reference_not_set: "Referencja nie ustawiona",
38097
+ reference_does_not_exist: "Referencja nie istnieje",
38098
+ entity_not_found: "Nie znaleziono encji",
38099
+ file_not_found: "Nie znaleziono pliku",
38100
+ unsaved_changes_in_entity: "Masz niezapisane zmiany w tej encji.",
38101
+ delete_this_role: "Usuń tę rolę",
38102
+ no_roles_yet: "Nie masz jeszcze żadnych ról.",
38103
+ create_default_roles: "Utwórz domyślne role",
38104
+ delete_role_confirmation: "Czy na pewno chcesz usunąć tę rolę?",
38105
+ delete_this_user: "Usuń tego użytkownika",
38106
+ no_users_yet: "Nie ma jeszcze żadnych użytkowników",
38107
+ add_logged_user_as_admin: "Dodaj zalogowanego użytkownika jako administratora",
38108
+ add_current_user_as_admin: "Dodaj bieżącego użytkownika jako administratora",
38109
+ create_default_roles_and_add_admin: "Utwórz domyślne role i dodaj bieżącego użytkownika jako administratora",
38110
+ delete_user_confirmation: "Czy na pewno chcesz usunąć tego użytkownika?",
38111
+ create_your_users_and_roles: "Utwórz użytkowników i role",
38112
+ no_users_or_roles_defined: "Nie masz zdefiniowanych użytkowników ani ról. Możesz utworzyć domyślne role i dodać bieżącego użytkownika jako administratora.",
38113
+ save_before_changing_schema: "Musisz zapisać dokument przed zmianą schematu",
38114
+ edit_schema_for_this_form: "Edytuj schemat tego formularza",
38115
+ no_permissions_to_edit_collection: "Nie masz uprawnień do edycji tej kolekcji",
38116
+ browser_does_not_support_audio: "Twoja przeglądarka nie obsługuje elementu audio.",
38117
+ user_not_found: "Nie znaleziono użytkownika: {{value}}",
38118
+ // ─── Collection view actions ──────────────────────────────────
38119
+ delete_selected: "Usuń",
38120
+ cannot_delete_selected: "Zaznaczono co najmniej jedną encję, której nie można usunąć",
38121
+ // ─── Array / field containers ─────────────────────────────────
38122
+ add_entry: "Dodaj",
38123
+ add_on_top: "Dodaj na górze",
38124
+ add_below: "Dodaj poniżej",
38125
+ add_to_field: "Dodaj do {{fieldName}}",
38126
+ value: "Wartość",
38127
+ key: "Klucz",
38128
+ drag_drop_multiple: "Przeciągnij i upuść pliki tutaj lub kliknij, aby je wybrać. Przeciągnij, aby zmienić kolejność.",
38129
+ drag_drop_single: "Przeciągnij i upuść plik tutaj lub kliknij, aby go wybrać",
38130
+ // ─── Navigation / scaffold ────────────────────────────────────
38131
+ open_menu: "Otwórz menu",
38132
+ close_drawer: "Zamknij panel boczny",
38133
+ navigation_drawer: "Panel nawigacyjny",
38134
+ // ─── Error states ─────────────────────────────────────────────
38135
+ error: "Błąd",
38136
+ error_uploading_file: "Błąd przesyłania pliku",
38137
+ error_deleting: "Błąd podczas usuwania: {{message}}",
38138
+ error_before_delete: "Błąd przed usunięciem: {{message}}",
38139
+ error_updating_asset: "Błąd aktualizacji zasobu",
38140
+ error_deleting_asset: "Błąd usuwania zasobu",
38141
+ error_firestore_index: "Dla tego zapytania wymagany jest indeks Firestore.",
38142
+ create_index: "Utwórz indeks",
38143
+ value_is_not_reference: "Wartość nie jest referencją.",
38144
+ click_to_edit: "Kliknij, aby edytować",
38145
+ data_is_not_array_of_references: "Dane nie są tablicą referencji",
38146
+ // ─── Misc ─────────────────────────────────────────────────────
38147
+ loading: "Wczytywanie",
38148
+ local_changes_applied: "Zmiany lokalne zastosowane w formularzu",
38149
+ local_changes_discarded: "Zmiany lokalne odrzucone",
38150
+ are_you_sure_leave: "Czy na pewno chcesz opuścić tę stronę?",
38151
+ see_console_details: "Więcej informacji w konsoli.",
38152
+ drop_here_create_group: "Upuść tutaj, aby utworzyć nową grupę",
38153
+ filter_for_null_values: "Filtruj puste wartości",
38154
+ value_updated_elsewhere: "Ta wartość została zaktualizowana gdzie indziej",
38155
+ add_property: "Dodaj właściwość",
38156
+ edit_name: "Edytuj {{name}}",
38157
+ this_entity_not_exist: "Ta encja nie istnieje w bazie danych",
38158
+ internal_error: "BŁĄD wewnętrzny",
38159
+ // ─── Rename group dialog ──────────────────────────────────────
38160
+ rename_group: "Zmień nazwę grupy",
38161
+ group_name_label: "Nazwa grupy",
38162
+ group_name_empty_error: "Nazwa grupy nie może być pusta.",
38163
+ group_name_exists_error: "Taka nazwa grupy już istnieje.",
38164
+ // ─── Search ───────────────────────────────────────────────────
38165
+ search_collections: "Szukaj kolekcji",
38166
+ // ─── Navigation groups ────────────────────────────────────────
38167
+ views_group: "Widoki",
38168
+ // ─── Entity Edit View ─────────────────────────────────────────
38169
+ youd_need_to_save_before_additional_collections: "Musisz zapisać encję przed dodaniem kolejnych kolekcji",
38170
+ // ─── Not Found Page ───────────────────────────────────────────
38171
+ page_not_found: "Nie znaleziono strony",
38172
+ page_not_found_body: "Ta strona nie istnieje lub nie masz do niej dostępu",
38173
+ back_to_home: "Wróć do strony głównej",
38174
+ // ─── Collection Editor ─────────────────────────────────────────
38175
+ default_collection_view: "Domyślny widok kolekcji",
38176
+ table_view: "Tabela",
38177
+ cards_view: "Karty",
38178
+ kanban_view: "Kanban",
38179
+ choose_how_entities_displayed_default: "Wybierz, jak encje mają być domyślnie wyświetlane",
38180
+ document_view: "Widok dokumentu",
38181
+ side_panel: "Panel boczny",
38182
+ full_screen: "Pełny ekran",
38183
+ should_documents_opened_full_screen: "Czy dokumenty mają być otwierane na pełnym ekranie, czy w bocznym oknie dialogowym",
38184
+ select_custom_view: "Wybierz widok niestandardowy",
38185
+ no_custom_views_defined: "Nie zdefiniowano żadnych widoków niestandardowych. Zdefiniuj je w ustawieniach dostosowywania przed użyciem tego okna dialogowego.",
38186
+ select_custom_action: "Wybierz akcję niestandardową",
38187
+ no_custom_actions_defined: "Nie zdefiniowano żadnych akcji niestandardowych. Zdefiniuj je w ustawieniach dostosowywania przed użyciem tego okna dialogowego.",
38188
+ no_collections_found: "Nie znaleziono kolekcji",
38189
+ start_building_collections: "Twórz kolekcje w FireCMS bez trudu. Zmapuj je z istniejącymi danymi w bazie, zaimportuj z plików lub skorzystaj z naszych szablonów.",
38190
+ create_first_collection: "Utwórz swoją pierwszą kolekcję",
38191
+ define_collections_programmatically: "Kolekcje możesz też definiować programistycznie.",
38192
+ edit_collection: "Edytuj kolekcję",
38193
+ no_permissions_edit_collection: "Nie masz uprawnień do edycji tej kolekcji",
38194
+ no_permissions_create_collection: "Nie masz uprawnień do tworzenia kolekcji",
38195
+ create_collection: "Utwórz kolekcję",
38196
+ update_collection: "Zaktualizuj kolekcję",
38197
+ new_collection: "Nowa kolekcja",
38198
+ add_new_collection: "Dodaj nową kolekcję",
38199
+ collection_with_name: "Kolekcja {{name}}",
38200
+ change_icon: "Zmień ikonę",
38201
+ is_subcollection_of: "To jest podkolekcja",
38202
+ name: "Nazwa",
38203
+ collection_name_description: "Nazwa tej kolekcji, zwykle w liczbie mnogiej (np. Produkty)",
38204
+ path: "Ścieżka",
38205
+ relative_path_to_parent: "Ścieżka względna do elementu nadrzędnego (nie trzeba podawać ścieżki nadrzędnej)",
38206
+ path_in_database: "Ścieżka, pod którą ta kolekcja jest przechowywana w bazie danych",
38207
+ singular_name: "Nazwa w liczbie pojedynczej",
38208
+ singular_name_description: "Opcjonalnie zdefiniuj nazwę pojedynczą dla encji tej kolekcji",
38209
+ description: "Opis",
38210
+ description_of_collection: "Opis kolekcji, możesz użyć formatowania markdown",
38211
+ collection_id: "ID kolekcji",
38212
+ collection_id_description: "To ID identyfikuje tę kolekcję. Zazwyczaj jest takie samo jak ścieżka.",
38213
+ collection_group: "Grupa kolekcji",
38214
+ collection_group_description: "Grupa kolekcji obejmuje wszystkie kolekcje o tej samej ścieżce. Pozwala to na wykonywanie zapytań w wielu kolekcjach jednocześnie.",
38215
+ advanced_settings: "Ustawienia zaawansowane",
38216
+ doc_history_global: "Historia zmian dokumentu włączona, jeśli jest włączona globalnie",
38217
+ doc_history_enabled: "Historia zmian dokumentu WŁĄCZONA",
38218
+ doc_history_not_enabled: "Historia zmian dokumentu NIE jest włączona",
38219
+ doc_history_description: "Po włączeniu każdy dokument w tej kolekcji będzie miał historię zmian. Jest to przydatne do celów audytowych. Dane są przechowywane w podkolekcji dokumentu w bazie danych o nazwie __history.",
38220
+ document_id_generation: "Generowanie ID dokumentów",
38221
+ code_defined: "Zdefiniowane w kodzie",
38222
+ users_must_define_id: "Użytkownicy muszą podać ID",
38223
+ users_can_define_id: "Użytkownicy mogą podać ID, ale nie jest to wymagane",
38224
+ doc_id_auto_generated: "ID dokumentu generowane jest automatycznie",
38225
+ config_doc_id_generation: "Skonfiguruj sposób generowania ID dokumentów podczas tworzenia nowych encji.",
38226
+ enable_text_search: "Włącz wyszukiwanie tekstowe dla tej kolekcji",
38227
+ text_search_description: "Zezwól na wyszukiwanie tekstowe w tej kolekcji. Jeśli nie określono delegata wyszukiwania tekstowego, użyte zostanie wbudowane lokalne wyszukiwanie tekstowe. Nie jest to zalecane w przypadku dużych kolekcji, ponieważ może powodować problemy z wydajnością i kosztami.",
38228
+ database_id: "ID bazy danych",
38229
+ default_text: "(domyślnie)",
38230
+ custom_actions: "Akcje niestandardowe",
38231
+ more_info: "Więcej informacji",
38232
+ define_custom_actions_cli: "Zdefiniuj własne akcje niestandardowe, przesyłając je za pomocą CLI.",
38233
+ action_defined_in_code: "Ta akcja jest zdefiniowana w kodzie pod kluczem",
38234
+ add_custom_entity_action: "Dodaj niestandardową akcję encji",
38235
+ remove_this_action: "Usunąć tę akcję?",
38236
+ remove_action_warning: "To nie usunie żadnych danych, tylko akcję w CMS",
38237
+ subcollections_of: "Podkolekcje kolekcji",
38238
+ add_subcollection: "Dodaj podkolekcję",
38239
+ custom_views: "Widoki niestandardowe",
38240
+ define_custom_views_cli: "Zdefiniuj własne widoki niestandardowe, przesyłając je za pomocą CLI.",
38241
+ view_defined_in_code: "Ten widok jest zdefiniowany w kodzie pod kluczem",
38242
+ add_custom_entity_view: "Dodaj niestandardowy widok encji",
38243
+ delete_this_subcollection: "Usunąć tę podkolekcję?",
38244
+ remove_collection_warning: "To nie usunie żadnych danych, tylko kolekcję w CMS",
38245
+ remove_this_view: "Usunąć ten widok?",
38246
+ remove_view_warning: "To nie usunie żadnych danych, tylko widok w CMS",
38247
+ no_collection_selected: "Nie wybrano kolekcji",
38248
+ code_for_collection: "Kod dla",
38249
+ use_config_define_json: "Użyj tej konfiguracji, aby zdefiniować kolekcję w formacie JSON.",
38250
+ customise_collection_code: "Jeśli chcesz dostosować kolekcję w kodzie, możesz dodać ten kod kolekcji do konfiguracji swojej aplikacji CMS.",
38251
+ copied: "Skopiowano",
38252
+ property_cant_be_edited: "Tej właściwości nie można edytować",
38253
+ property_not_editable_description: "Możesz nie mieć uprawnień do jej edycji lub jest ona zdefiniowana w kodzie z flagą editable ustawioną na false.",
38254
+ delete_this_property: "Usunąć tę właściwość?",
38255
+ delete_property_warning: "To nie usunie żadnych danych, tylko zmodyfikuje kolekcję.",
38256
+ error_must_specify_id: "Musisz podać ID dla tego pola",
38257
+ error_id_format: "ID może zawierać tylko litery, cyfry i podkreślenia (_) i nie może zaczynać się od cyfry",
38258
+ error_id_already_exists: "Istnieje już inne pole z tym ID",
38259
+ error_must_specify_title: "Musisz podać tytuł dla tego pola",
38260
+ custom_or_other: "Niestandardowe/Inne",
38261
+ select_property_widget: "Wybierz widżet właściwości",
38262
+ error_changing_data_type: "Ten widżet używa innego typu danych niż pierwotnie wybrany widżet. Może to powodować błędy z istniejącymi danymi.",
38263
+ required: "Wymagane",
38264
+ enum_form_dialog: "Okno dialogowe formularza wyliczeniowego",
38265
+ imported_data_preview: "Podgląd zaimportowanych danych",
38266
+ entities_with_same_id_overwritten: "Encje o tym samym ID zostaną nadpisane",
38267
+ collection_editor: "Edytor kolekcji",
38268
+ properties_in_this_group: "Właściwości w tej grupie",
38269
+ data_property_mapping: "Mapowanie danych na właściwości",
38270
+ property_edit_view: "Widok edycji właściwości",
38271
+ all_of_these: "Wszystkie z nich",
38272
+ any_of_these: "Dowolna z nich",
38273
+ only_admins_edit_roles: "Tylko administratorzy mogą edytować role",
38274
+ error_user_not_found: "Nie znaleziono użytkownika",
38275
+ role: "Rola",
38276
+ name_of_this_role: "Nazwa tej roli",
38277
+ id_of_this_role: "ID tej roli",
38278
+ create_entities: "Tworzenie encji",
38279
+ read_entities: "Odczyt encji",
38280
+ update_entities: "Aktualizacja encji",
38281
+ delete_entities: "Usuwanie encji",
38282
+ all_collections: "Wszystkie kolekcje",
38283
+ create_entities_in_collections: "Tworzenie encji w kolekcjach",
38284
+ access_all_data_in_every_collection: "Dostęp do wszystkich danych w każdej kolekcji",
38285
+ update_data_in_any_collection: "Aktualizacja danych w dowolnej kolekcji",
38286
+ delete_data_in_any_collection: "Usuwanie danych w dowolnej kolekcji",
38287
+ allow_all_permissions_in_this_collections: "Zezwól na wszystkie uprawnienia w tych kolekcjach",
38288
+ all: "Wszystkie",
38289
+ customise_permissions_description: "Możesz dostosować uprawnienia, jakie użytkownicy z tą rolą mają w encjach każdej kolekcji",
38290
+ create_collections: "Tworzenie kolekcji",
38291
+ yes: "Tak",
38292
+ no: "Nie",
38293
+ can_user_create_collections: "Czy użytkownik może tworzyć kolekcje",
38294
+ edit_collections: "Edycja kolekcji",
38295
+ only_own_collections: "Tylko swoje",
38296
+ own: "Własne",
38297
+ can_user_edit_collections: "Czy użytkownik może edytować kolekcje",
38298
+ delete_collections: "Usuwanie kolekcji",
38299
+ can_user_delete_collections: "Czy użytkownik może usuwać kolekcje",
38300
+ error_saving_role: "Wystąpił błąd podczas zapisywania tej roli",
38301
+ create_role: "Utwórz rolę",
38302
+ update: "Aktualizuj",
38303
+ only_admins_change_roles: "Tylko administratorzy mogą zmieniać role",
38304
+ must_be_at_least_one_admin: "Musi istnieć co najmniej jeden administrator",
38305
+ logged_user_not_found: "Nie znaleziono zalogowanego użytkownika",
38306
+ user: "Użytkownik",
38307
+ user_id: "ID użytkownika",
38308
+ name_of_this_user: "Nazwa tego użytkownika",
38309
+ email_of_this_user: "Adres e-mail tego użytkownika",
38310
+ roles: "Role",
38311
+ create_user: "Utwórz użytkownika",
38312
+ users: "Użytkownicy",
38313
+ add_user: "Dodaj użytkownika",
38314
+ add_role: "Dodaj rolę",
38315
+ is_admin: "Jest administratorem",
38316
+ default_permissions: "Domyślne uprawnienia",
38317
+ created_on: "Utworzono",
38318
+ email: "E-mail",
38319
+ id: "ID",
38320
+ read: "Odczyt",
38321
+ column_in_file: "Kolumna w pliku",
38322
+ map_to_property: "Zmapuj na właściwość",
38323
+ default_values: "Wartości domyślne",
38324
+ default_values_description: "Możesz wybrać wartość domyślną dla niezmapowanych kolumn i pustych wartości:",
38325
+ property: "Właściwość",
38326
+ default_value: "Wartość domyślna",
38327
+ autogenerate_id: "Generuj ID automatycznie",
38328
+ id_column_description: "Kolumna, która będzie używana jako ID dla każdego dokumentu",
38329
+ do_not_set_value: "Nie ustawiaj wartości",
38330
+ set_value_to_true: "Ustaw wartość na true",
38331
+ set_value_to_false: "Ustaw wartość na false",
38332
+ drag_and_drop_file: "Przeciągnij i upuść plik tutaj lub kliknij, aby go przesłać",
38333
+ error_saving_data: "Błąd zapisywania danych",
38334
+ retry: "Spróbuj ponownie",
38335
+ saving_data: "Zapisywanie danych",
38336
+ entities_saved: "zapisanych encji",
38337
+ do_not_close_tab: "Nie zamykaj tej karty, w przeciwnym razie import zostanie przerwany",
38338
+ import: "Importuj",
38339
+ import_data: "Importuj dane",
38340
+ upload_file_description: "Prześlij plik CSV, Excel lub JSON i zmapuj go do istniejącego schematu",
38341
+ back: "Wstecz",
38342
+ next: "Dalej",
38343
+ save_data: "Zapisz dane",
38344
+ use_column_as_id: "Użyj tej kolumny jako ID",
38345
+ do_not_import_property: "Nie importuj tej właściwości",
38346
+ entities_will_be_overwritten: "Encje o tym samym ID zostaną nadpisane",
38347
+ data_imported_successfully: "Dane zostały pomyślnie zaimportowane",
38348
+ export: "Eksportuj",
38349
+ export_data: "Eksportuj dane",
38350
+ download_table_csv: "Pobierz zawartość tej tabeli jako plik CSV",
38351
+ csv: "CSV",
38352
+ json: "JSON",
38353
+ dates_as_timestamps: "Daty jako znaczniki czasu",
38354
+ dates_as_strings: "Daty jako ciągi znaków",
38355
+ flatten_arrays: "Spłaszcz tablice",
38356
+ download: "Pobierz",
38357
+ large_number_of_documents: "Ta kolekcja zawiera dużą liczbę dokumentów ({{count}}).",
38358
+ include_undefined_values: "Uwzględnij niezdefiniowane wartości",
38359
+ submit: "Wyślij",
38360
+ no_filterable_properties: "Brak dostępnych właściwości do filtrowania",
38361
+ apply_filters: "Zastosuj filtry",
38362
+ list: "Lista",
38363
+ cards: "Karty",
38364
+ board: "Tablica",
38365
+ initialize_kanban_order_desc: "Spowoduje to przypisanie sekwencyjnych wartości kolejności wszystkim elementom, które ich nie mają. Elementy zachowają swoją bieżącą kolejność w ramach każdej kolumny.",
38366
+ kanban_view_not_available: "Widok Kanban jest niedostępny",
38367
+ kanban_view_requires_enum: "Widok Kanban wymaga właściwości tekstowej z wartościami wyliczeniowymi, aby grupować encje w kolumny. Dodaj właściwość wyliczeniową do schematu swojej kolekcji, aby użyć tego widoku.",
38368
+ no_enum_values_configured: "Nie skonfigurowano wartości wyliczeniowych dla właściwości „{{property}}”",
38369
+ items_need_backfill: "Niektóre elementy nie mają ustawionych wartości kolejności. Zainicjuj je, aby włączyć zmianę kolejności metodą przeciągnij i upuść.",
38370
+ initialize: "Zainicjuj",
38371
+ confirm_multiple_delete: "Potwierdzić wielokrotne usunięcie?",
38372
+ delete_entity_confirm_title: "Czy chcesz usunąć ten element: {{entityName}}?",
38373
+ /** AI Collection Generator Popover */
38374
+ generate_collection_with_ai: "Wygeneruj kolekcję za pomocą AI",
38375
+ modify_collection_with_ai: "Zmodyfikuj kolekcję za pomocą AI",
38376
+ describe_collection_to_create: "Opisz kolekcję, którą chcesz utworzyć.",
38377
+ describe_changes_to_make: "Opisz zmiany, które chcesz wprowadzić w tej kolekcji.",
38378
+ ai_placeholder_create: "np. Utwórz kolekcję produktów z nazwą, ceną, opisem i kategorią...",
38379
+ ai_placeholder_modify: "np. Dodaj pole obrazu miniatury z przechowywaniem, ustaw cenę jako wymaganą...",
38380
+ ai_assist: "Asystent AI",
38381
+ generating: "Generowanie...",
38382
+ /** Recently extracted strings for collection editor */
38383
+ this_is_subcollection_of: "To jest podkolekcja",
38384
+ use_existing_paths_database: "Użyj jednej z istniejących ścieżek w swojej bazie danych:",
38385
+ describe_collection_ai: "Opisz swoją kolekcję dla AI:",
38386
+ generate_with_ai: "Generuj za pomocą AI",
38387
+ create_from_json_config: "Utwórz z konfiguracji JSON:",
38388
+ paste_json_config: "Wklej konfigurację JSON",
38389
+ create_collection_from_file_formats: "Utwórz kolekcję z pliku (csv, json, xls, xlsx...)",
38390
+ select_template: "Wybierz szablon:",
38391
+ products: "Produkty",
38392
+ collection_products_subtitle: "Kolekcja produktów ze zdjęciami, cenami i stanem magazynowym",
38393
+ collection_users_subtitle: "Kolekcja użytkowników z adresami e-mail, imionami i rolami",
38394
+ blog_posts: "Wpisy na blogu",
38395
+ collection_blog_posts_subtitle: "Kolekcja wpisów na blogu ze zdjęciami, autorami i rozbudowaną treścią",
38396
+ pages: "Strony",
38397
+ collection_pages_subtitle: "Kolekcja stron ze zdjęciami, autorami i rozbudowaną treścią",
38398
+ continue_from_scratch: "Kontynuuj od zera",
38399
+ /** Admin views config */
38400
+ cms_users: "Użytkownicy CMS",
38401
+ roles_menu: "Role",
38402
+ project_settings: "Ustawienia projektu",
38403
+ firestore_manager: "Menedżer Firestore",
38404
+ manage_your_firestore_data: "Zarządzaj danymi w Firestore",
38405
+ // ─── FireCMS Cloud Login ──────────────────────────────────────
38406
+ build_admin_panel_in_minutes: "Zbuduj panel administracyjny Firebase w kilka minut",
38407
+ go_live_instantly: "Uruchom natychmiast:",
38408
+ create_production_ready_back_offices: "Twórz gotowe do wdrożenia panele administracyjne",
38409
+ without_the_frontend_hassle: "bez kłopotów z frontendem.",
38410
+ automatic_setup: "Automatyczna konfiguracja",
38411
+ from_your_existing_firestore_data: "na podstawie Twoich istniejących danych w Firestore.",
38412
+ seamless_real_time_firebase_integration: "Płynna integracja z Firebase w czasie rzeczywistym.",
38413
+ intuitive_spreadsheet_like_ui: "Intuicyjny interfejs przypominający arkusz kalkulacyjny,",
38414
+ your_whole_team_can_use: "z którego może korzystać cały Twój zespół.",
38415
+ focus_on_your_app: "Skup się na swojej aplikacji,",
38416
+ not_the_admin_panel: "a nie na panelu administracyjnym.",
38417
+ join_our_newsletter: "Dołącz do naszego newslettera. Bez spamu, tylko ważne aktualizacje!",
38418
+ by_signing_in_you_agree_to_our: "Logując się, akceptujesz nasz",
38419
+ terms_and_conditions: "Regulamin",
38420
+ and_our: "oraz naszą",
38421
+ privacy_policy: "Politykę prywatności",
38422
+ firecms_cloud_google_disclosure: "Korzystanie i przekazywanie przez FireCMS Cloud informacji uzyskanych z API Google do jakiejkolwiek innej aplikacji będzie zgodne z",
38423
+ google_api_services_user_data_policy: "Polityką dotyczącą danych użytkowników usług API Google",
38424
+ including_the_limited_use_requirements: "w tym z wymaganiami dotyczącymi ograniczonego użytkowania.",
38425
+ email_password: "E-mail/hasło",
38426
+ sign_in_with_google: "Zaloguj się przez Google",
38427
+ // --- Auth error messages ---
38428
+ auth_user_not_found: "Nie znaleziono użytkownika",
38429
+ auth_wrong_password: "Nieprawidłowe hasło. Spróbuj ponownie.",
38430
+ auth_user_disabled: "Użytkownik jest zablokowany. Skontaktuj się z pomocą techniczną.",
38431
+ auth_account_exists_with_different_credential: "Konto istnieje z inną metodą logowania",
38432
+ auth_email_already_in_use: "Ten adres e-mail jest już używany",
38433
+ auth_google_permissions_required: "Musisz przyznać dodatkowe uprawnienia, aby zarządzać swoimi projektami Google Cloud",
38434
+ auth_invalid_email_password: "Podaj zarówno adres e-mail, jak i hasło",
38435
+ auth_enter_email_first: "Najpierw podaj swój adres e-mail",
38436
+ auth_password_reset_sent: "Wysłano e-mail resetujący hasło",
38437
+ auth_sign_in_account: "Zaloguj się do swojego konta",
38438
+ auth_create_new_account: "Utwórz nowe konto",
38439
+ auth_password: "Hasło",
38440
+ auth_reset_password: "Zresetuj hasło",
38441
+ auth_new_user: "Nowy użytkownik?",
38442
+ auth_have_account: "Masz już konto?",
38443
+ auth_sign_in: "Zaloguj się",
38444
+ auth_sign_up: "Zarejestruj się",
38445
+ // --- SaaS Subscriptions ---
38446
+ subscriptions: "Subskrypcje",
38447
+ manage_your_subscriptions_in_stripe: "Zarządzaj swoimi subskrypcjami w Stripe",
38448
+ go_to_your_stripe_portal: "Przejdź do swojego portalu Stripe, aby zobaczyć historię płatności. Możesz tam również zarządzać subskrypcjami powiązanymi z zalogowanym użytkownikiem.",
38449
+ your_pro_licenses: "Twoje licencje PRO",
38450
+ create_new_license: "Utwórz nową licencję",
38451
+ create_subscriptions_in_this_section: "Twórz subskrypcje w tej sekcji tylko w przypadku samodzielnie hostowanego FireCMS PRO. Jeśli korzystasz z FireCMS Cloud, możesz zaktualizować swój projekt w ustawieniach projektu.",
38452
+ if_you_are_an_agency: "Jeśli jesteś agencją, możesz swobodnie odsprzedawać swoją licencję swoim klientom.",
38453
+ if_you_have_any_questions: "Jeśli masz pytania lub potrzebujesz pomocy, skontaktuj się z nami pod adresem",
38454
+ you_have_not_created_any_pro_licenses: "Nie masz jeszcze żadnych licencji FireCMS PRO",
38455
+ archive: "Archiwizuj",
38456
+ licensed_projects_lowercase: "licencjonowanych projektów",
38457
+ manage: "Zarządzaj",
38458
+ update_payment_method: "Zaktualizuj metodę płatności",
38459
+ your_firecms_cloud_projects: "Twoje projekty FireCMS Cloud",
38460
+ status_active: "Aktywna",
38461
+ status_trialing: "Okres próbny",
38462
+ status_past_due: "Zaległa płatność",
38463
+ status_canceled: "Anulowana",
38464
+ status_unpaid: "Nieopłacona",
38465
+ status_incomplete: "Niekompletna",
38466
+ status_incomplete_expired: "Niekompletna, wygasła",
38467
+ status_unknown: "Nieznany",
38468
+ plan_free: "Brak subskrypcji",
38469
+ plan_cloud_plus: "Subskrybowany",
38470
+ plan_pro: "Pro",
38471
+ plan_unknown: "Nieznany plan",
38472
+ auto_setup_collections_button: "Automatycznie skonfiguruj kolekcje",
38473
+ auto_setup_collections_title: "Automatycznie skonfigurować kolekcje?",
38474
+ auto_setup_collections_desc: "Spowoduje to automatyczne utworzenie konfiguracji kolekcji dla kolekcji, które <b>NIE</b> są jeszcze zmapowane",
38475
+ setting_up_collections: "Konfigurowanie kolekcji",
38476
+ setting_up_collection: "Konfigurowanie {{name}}",
38477
+ no_collections_found_to_setup: "Nie znaleziono kolekcji do skonfigurowania.",
38478
+ collections_have_been_setup: "Kolekcje zostały automatycznie skonfigurowane.",
38479
+ error_setting_up_collections: "Błąd podczas automatycznej konfiguracji kolekcji",
38480
+ setup_collections_title: "Skonfiguruj kolekcje",
38481
+ setup_collections_select_desc: "Wybierz kolekcje do automatycznej konfiguracji:",
38482
+ select_all: "Zaznacz wszystkie",
38483
+ deselect_all: "Odznacz wszystkie",
38484
+ setup_collections_confirm: "Skonfiguruj ({{count}})",
38485
+ collection_setup_success: "{{name}} została skonfigurowana",
38486
+ go_to_collection: "Przejdź do kolekcji",
38487
+ // --- Home Suggestions ---
38488
+ add_your: "Dodaj swoje",
38489
+ database_collections: "kolekcje bazy danych",
38490
+ to_firecms: "do FireCMS",
38491
+ no_unmapped_collections: "Brak niezmapowanych kolekcji w bazie danych",
38492
+ query_and_update_with_datatalk: "Odpytuj i aktualizuj swoje dane w języku naturalnym za pomocą",
38493
+ // --- SaaS Welcome ---
38494
+ welcome_to_firecms: "Witamy w FireCMS Cloud",
38495
+ admin_panel_ready_bring_data: "Twój panel administracyjny jest gotowy. Wprowadźmy Twoje dane.",
38496
+ admin_panel_ready_get_started: "Twój panel administracyjny jest gotowy. Oto jak zacząć.",
38497
+ auto_detect_collections: "Automatyczne wykrywanie kolekcji",
38498
+ auto_detect_collections_desc: "Pozwól AI przeskanować Twoją bazę danych i automatycznie wygenerować schematy kolekcji.",
38499
+ create_a_collection: "Utwórz kolekcję",
38500
+ create_collection_desc: "Ręcznie zdefiniuj swoją pierwszą kolekcję od podstaw za pomocą edytora wizualnego.",
38501
+ read_the_docs: "Przeczytaj dokumentację",
38502
+ read_the_docs_desc: "Dowiedz się, jak dostosowywać pola, widoki, akcje i więcej.",
38503
+ explore_docs: "Poznaj dokumentację",
38504
+ want_to_customize_with_code: "Chcesz dostosować za pomocą kodu? Uruchom",
38505
+ to_scaffold_a_local_project: "aby wygenerować lokalny projekt.",
38506
+ // ─── Collection Editor — Validation ──────────────────────────
38507
+ validation: "Walidacja",
38508
+ unique: "Unikalne",
38509
+ required_message: "Treść komunikatu o wymaganym polu",
38510
+ required_tooltip: "Nie będzie można zapisać tej encji, jeśli ta wartość nie jest ustawiona",
38511
+ unique_tooltip: "Nie może istnieć wiele encji z tą samą wartością",
38512
+ lowercase: "Małe litery",
38513
+ uppercase: "Wielkie litery",
38514
+ trim: "Przytnij",
38515
+ exact_length: "Dokładna długość",
38516
+ min_length: "Minimalna długość",
38517
+ max_length: "Maksymalna długość",
38518
+ matches_regex: "Pasuje do wyrażenia regularnego",
38519
+ not_valid_regexp: "Nieprawidłowe wyrażenie regularne",
38520
+ regex_helper: "np. /^\\d+$/ tylko dla cyfr",
38521
+ min_value: "Wartość minimalna",
38522
+ max_value: "Wartość maksymalna",
38523
+ less_than: "Mniejsza niż",
38524
+ more_than: "Większa niż",
38525
+ positive_value: "Wartość dodatnia",
38526
+ negative_value: "Wartość ujemna",
38527
+ integer_value: "Wartość całkowita",
38528
+ // ─── Collection Editor — Property Edit ───────────────────────
38529
+ invalid_regular_expression: "Nieprawidłowe wyrażenie regularne",
38530
+ must_specify_target_collection: "Musisz określić docelową kolekcję dla tego pola",
38531
+ need_specify_repeat_field: "Musisz określić pole powtarzalne",
38532
+ need_specify_block_properties: "Musisz określić właściwości tego bloku",
38533
+ incomplete_condition: "Niekompletny warunek – wybierz pole",
38534
+ field_name: "Nazwa pola",
38535
+ // ─── Collection Editor — Display & Config ────────────────────
38536
+ kanban_column_property: "Właściwość kolumny Kanban",
38537
+ select_a_property: "Wybierz właściwość",
38538
+ kanban_property_not_found: "Właściwość „{{property}}” nie istnieje lub nie jest tekstową właściwością wyliczeniową. Wybierz prawidłową właściwość lub wyczyść wybór.",
38539
+ no_enum_string_properties: "Nie znaleziono tekstowych właściwości wyliczeniowych. Dodaj właściwość tekstową z enumValues, aby użyć widoku Kanban.",
38540
+ kanban_column_description: "Wybierz właściwość tekstową z wartościami wyliczeniowymi, aby grupować encje w kolumny",
38541
+ create_property: "+ Utwórz właściwość „{{property}}”",
38542
+ order_property: "Właściwość kolejności",
38543
+ order_property_not_found: "Właściwość „{{property}}” nie istnieje lub nie jest właściwością liczbową. Wybierz prawidłową właściwość lub wyczyść wybór.",
38544
+ no_number_properties: "Nie znaleziono właściwości liczbowych. Dodaj właściwość liczbową, aby włączyć sortowanie.",
38545
+ order_property_description: "Wybierz właściwość liczbową, aby zachować kolejność elementów",
38546
+ display_settings: "Ustawienia wyświetlania",
38547
+ default_row_size: "Domyślny rozmiar wiersza",
38548
+ side_dialog_width: "Szerokość okna bocznego",
38549
+ side_dialog_width_description: "Opcjonalnie zdefiniuj szerokość (w pikselach) bocznego okna encji. Wartość domyślna to 768px",
38550
+ inline_editing_enabled: "Dane można edytować bezpośrednio w widoku tabeli",
38551
+ inline_editing_disabled: "Dane można edytować tylko w widoku formularza",
38552
+ inline_editing_description: "Zezwól na edycję danych bezpośrednio w widoku tabeli, bez otwierania widoku formularza.",
38553
+ include_json_view: "Uwzględnij widok JSON",
38554
+ no_json_view: "Nie uwzględniaj widoku JSON",
38555
+ json_view_description: "Uwzględnij reprezentację JSON dokumentu.",
38556
+ not_found_suffix: "nie znaleziono",
38557
+ // ─── Editor ─────────────────────────────────────────────────
38558
+ editor_text: "Tekst",
38559
+ editor_text_description: "Po prostu zacznij pisać zwykły tekst.",
38560
+ editor_heading_1: "Nagłówek 1",
38561
+ editor_heading_1_description: "Duży nagłówek sekcji.",
38562
+ editor_heading_2: "Nagłówek 2",
38563
+ editor_heading_2_description: "Średni nagłówek sekcji.",
38564
+ editor_heading_3: "Nagłówek 3",
38565
+ editor_heading_3_description: "Mały nagłówek sekcji.",
38566
+ editor_todo_list: "Lista zadań",
38567
+ editor_todo_list_description: "Śledź zadania za pomocą listy do zrobienia.",
38568
+ editor_bullet_list: "Lista punktowana",
38569
+ editor_bullet_list_description: "Utwórz prostą listę punktowaną.",
38570
+ editor_numbered_list: "Lista numerowana",
38571
+ editor_numbered_list_description: "Utwórz listę z numeracją.",
38572
+ editor_quote: "Cytat",
38573
+ editor_quote_description: "Uchwyć cytat.",
38574
+ editor_code: "Kod",
38575
+ editor_code_description: "Wstaw fragment kodu.",
38576
+ editor_image: "Obraz",
38577
+ editor_image_description: "Prześlij obraz ze swojego komputera.",
38578
+ editor_multiple: "Wielokrotne",
38579
+ editor_link: "Link",
38580
+ editor_save: "Zapisz",
38581
+ editor_cancel: "Anuluj",
38582
+ editor_remove_link: "Usuń link",
38583
+ editor_paste_or_type_link: "Wklej lub wpisz link",
38584
+ editor_open_in_new_window: "Otwórz w nowym oknie",
38585
+ editor_bold: "Pogrubienie",
38586
+ editor_italic: "Kursywa",
38587
+ editor_underline: "Podkreślenie",
38588
+ editor_strikethrough: "Przekreślenie",
38589
+ editor_autocomplete: "Autouzupełnianie",
38590
+ editor_autocomplete_description: "Dodaj tekst na podstawie kontekstu.",
38591
+ // ─── Text Search Dialog ─────────────────────────────────────
38592
+ text_search_dialog_title: "Włącz wyszukiwanie tekstowe",
38593
+ text_search_local_not_recommended: "Lokalne wyszukiwanie tekstowe nie jest zalecane dla dużych kolekcji.",
38594
+ text_search_local_fetch_warning: "Pamiętaj, że włączenie lokalnego wyszukiwania tekstowego wymaga pobrania wszystkich dokumentów z kolekcji i zapisania ich w przeglądarce. Może to być nieefektywne w przypadku dużych kolekcji, a także może wiązać się z dodatkowymi kosztami.",
38595
+ text_search_external_suggestion: "W przypadku większych kolekcji zalecamy użycie zewnętrznej wyszukiwarki, takiej jak Algolia lub Elastic Search, oraz przypisanie delegata wyszukiwania do swojej konfiguracji.",
38596
+ text_search_local_description: "Lokalne wyszukiwanie tekstowe to najprostszy sposób na włączenie wyszukiwania tekstowego w kolekcji. Wczytuje wszystkie dokumenty kolekcji w przeglądarce i przeprowadza wyszukiwanie lokalnie. Jest to zalecana opcja dla małych kolekcji.",
38597
+ text_search_own_implementation: "Zaimplementowano własny kontroler wyszukiwania tekstowego. Możesz włączyć wyszukiwanie tekstowe dla swojej kolekcji.",
38598
+ text_search_enable_for_collection: "Włącz dla tej kolekcji",
38599
+ text_search_enable_for_project: "Włącz dla projektu",
38600
+ text_search_enabled_snackbar: "Lokalne wyszukiwanie tekstowe włączone",
38601
+ // ─── Cloud Project Settings ──────────────────────────────────
38602
+ settings_subscription_plan: "Plan subskrypcji",
38603
+ settings_subscribed_to: "Obecnie subskrybujesz",
38604
+ settings_no_active_subscription: "Obecnie ten projekt nie ma aktywnej subskrypcji.",
38605
+ settings_trial_valid_until: "Twój okres próbny jest ważny do {{date}}.",
38606
+ settings_features_intro: "Oto niektóre z funkcji, z których już korzystasz, używając FireCMS Cloud",
38607
+ settings_feature_managed_service: "Zarządzana, zawsze aktualna usługa",
38608
+ settings_feature_local_text_search: "Lokalne wyszukiwanie tekstowe",
38609
+ settings_feature_unlimited_users_roles: "Nieograniczona liczba użytkowników i ról",
38610
+ settings_feature_theme_logo: "Dostosowywanie motywu i logo",
38611
+ settings_feature_custom_fields_views: "Niestandardowe pola formularzy i widoki",
38612
+ settings_feature_secondary_databases: "Dodatkowe bazy danych",
38613
+ settings_feature_ai_content: "Generowanie treści AI za pomocą OpenAI i Google",
38614
+ settings_feature_unlimited_export: "Nieograniczony eksport danych",
38615
+ settings_feature_appcheck: "AppCheck",
38616
+ settings_heading: "Ustawienia",
38617
+ settings_project_name: "Nazwa projektu",
38618
+ settings_default_language: "Język domyślny",
38619
+ settings_default_language_caption: "Wybierz język bazowy dla tego projektu. Użytkownicy mogą zmienić tę preferencję w swoich ustawieniach osobistych.",
38620
+ settings_enable_local_text_search: "Włącz lokalne wyszukiwanie tekstowe",
38621
+ settings_local_text_search_caption: "Włącz lokalne wyszukiwanie tekstowe dla wszystkich kolekcji. Pozwoli to na wyszukiwanie pól tekstowych w kolekcjach za pomocą paska wyszukiwania FireCMS. Pamiętaj, że ta funkcja może wiązać się z wyższą liczbą odczytów, ponieważ indeksuje wszystkie pola tekstowe w kolekcjach.",
38622
+ settings_doc_history_all_collections: "Historia dokumentów włączona dla wszystkich kolekcji",
38623
+ settings_doc_history_caption: "Gdy ta opcja jest włączona, wszystkie kolekcje będą miały domyślnie włączoną historię. To ustawienie można zastąpić dla każdej kolekcji osobno. Historia jest zapisywana w podkolekcji __history każdego dokumentu.",
38624
+ settings_theme: "Motyw",
38625
+ settings_primary_color: "Kolor podstawowy",
38626
+ settings_secondary_color: "Kolor dodatkowy",
38627
+ settings_sample_theme_components: "Przykładowe komponenty motywu",
38628
+ settings_drag_drop_logo: "Przeciągnij i upuść tutaj swoje logo",
38629
+ settings_create_subscription: "Utwórz subskrypcję",
38630
+ settings_stripe_disclaimer: "Zostaniesz przekierowany do Stripe, aby dokończyć subskrypcję. Rozliczenie miesięczne na podstawie maksymalnej liczby użytkowników w danym miesiącu. Anuluj w dowolnym momencie – bieżący okres rozliczeniowy jest już opłacony, więc po anulowaniu nie zostaną naliczone żadne dodatkowe opłaty.",
38631
+ settings_subscription_is: "Subskrypcja jest",
38632
+ settings_next_payment_on: "Następna płatność nastąpi {{date}}.",
38633
+ settings_seats_count: "Masz",
38634
+ settings_seat: "miejsce",
38635
+ settings_seats: "miejsc",
38636
+ settings_per_seat: "po {{price}}/miejsce/{{interval}}",
38637
+ settings_current_price: "Aktualna cena to",
38638
+ settings_per_user_usage: "na użytkownika (zależnie od zużycia).",
38639
+ settings_cancelled_active_until: "Ta subskrypcja została anulowana i będzie aktywna do {{date}}.",
38640
+ settings_no_additional_charges: "Po anulowaniu nie zostaną naliczone żadne dodatkowe opłaty.",
38641
+ settings_manage_subscription: "Zarządzaj subskrypcją",
38642
+ settings_security_rules: "Reguły bezpieczeństwa",
38643
+ settings_security_rules_description: "FireCMS wykorzystuje reguły bezpieczeństwa Firebase do ograniczania dostępu do danych. Podczas tworzenia nowego użytkownika za pomocą FireCMS do użytkownika w projekcie klienckim dodawane jest niestandardowe roszczenie fireCMSUser. Dodając poniższe reguły bezpieczeństwa do swojego projektu, zapewniasz użytkownikom FireCMS dostęp do danych za pośrednictwem FireCMS.",
38644
+ settings_security_rules_add_domain: "Pamiętaj, aby dodać domenę {{domain}} do listy dozwolonych domen u swojego dostawcy",
38645
+ settings_security_rules_caption: "Te reguły ograniczają dostęp do danych wyłącznie do użytkowników FireCMS, ale nie wymuszają uprawnień na poziomie bazy danych. Uprawnienia są jednak egzekwowane po stronie frontendu, co w większości projektów sprawdzi się dobrze. Jeśli potrzebujesz wymuszać uprawnienia na poziomie bazy danych, możesz samodzielnie zmodyfikować te reguły bezpieczeństwa według swoich potrzeb. Role przypisane użytkownikowi są ustawiane jako niestandardowe roszczenie w tokenie uwierzytelniania Firebase, więc możesz ich użyć w regułach bezpieczeństwa.",
38646
+ settings_appcheck: "AppCheck",
38647
+ settings_appcheck_description: "Możesz włączyć AppCheck, aby chronić swoje usługi Firebase przed nadużyciami. Sprawdź, jak go skonfigurować, w dokumentacji Firebase. Gdy masz ustawionego dostawcę, możesz go tutaj włączyć. Będziesz musiał podać sekret w ustawieniach projektu Firebase oraz klucz witryny w konfiguracji FireCMS.",
38648
+ settings_appcheck_add_domain: "Pamiętaj, aby dodać domenę {{domain}} do listy dozwolonych domen u swojego dostawcy",
38649
+ settings_appcheck_enable: "Włącz AppCheck",
38650
+ settings_appcheck_site_key: "Klucz witryny",
38651
+ settings_appcheck_update: "Zaktualizuj AppCheck",
38652
+ settings_appcheck_refresh_note: "Po zapisaniu może być konieczne odświeżenie strony, aby zobaczyć zmiany.",
38653
+ settings_appcheck_updated: "AppCheck zaktualizowany",
38654
+ settings_appcheck_error: "Błąd podczas aktualizacji AppCheck",
38655
+ // --- Permission Error View ---
38656
+ missing_firestore_security_rules: "Brak reguł bezpieczeństwa Firestore",
38657
+ firecms_cloud_requires_security_rule: "FireCMS Cloud wymaga określonej reguły bezpieczeństwa w Twoim Firestore, aby przyznać dostęp uwierzytelnionym użytkownikom. Kolekcja",
38658
+ cannot_be_accessed_without_it: "nie może być dostępna bez tej reguły.",
38659
+ required_security_rule: "Wymagana reguła bezpieczeństwa",
38660
+ fix_automatically: "Napraw automatycznie",
38661
+ open_firebase_rules: "Otwórz reguły Firebase",
38662
+ security_rules_updated_successfully: "Reguły bezpieczeństwa zostały pomyślnie zaktualizowane! Odśwież stronę, aby wczytać dane.",
38663
+ sec_rules_fixing: "Naprawianie...",
38664
+ sec_rules_fixed: "Naprawiono!",
38665
+ // ─── GCP Marketplace ─────────────────────────────────────────
38666
+ marketplace_managed_by_gcp: "Zarządzane przez GCP Marketplace",
38667
+ marketplace_billing_note: "Twoja subskrypcja jest zarządzana przez Google Cloud Marketplace. Zmiany planu, rozliczenia i anulowanie są obsługiwane w konsoli GCP.",
38668
+ marketplace_manage_in_gcp_console: "Zarządzaj w konsoli GCP",
38669
+ marketplace_plan_changes_note: "Aby zmienić plan lub anulować subskrypcję, odwiedź swoje zamówienia w GCP Marketplace.",
38670
+ marketplace_welcome_title: "Witamy z GCP Marketplace!",
38671
+ marketplace_welcome_subtitle: "Twoja subskrypcja Google Cloud Marketplace jest aktywna. Wybierz istniejący projekt lub utwórz nowy, aby go połączyć.",
38672
+ marketplace_select_or_create_project: "Wybierz lub utwórz projekt",
38673
+ marketplace_link_project: "Połącz projekt",
38674
+ marketplace_linking: "Łączenie projektu…",
38675
+ marketplace_link_success: "Projekt został pomyślnie połączony! Przekierowywanie…",
38676
+ marketplace_link_error: "Błąd podczas łączenia projektu. Spróbuj ponownie.",
38677
+ marketplace_no_account_id: "Nie znaleziono ID konta GCP Marketplace. Rozpocznij od GCP Marketplace."
38678
+ };
37347
38679
  const FIRECMS_NS = "firecms_core";
37348
38680
  const FIRECMS_LOCALE_STORAGE_KEY = "firecms_locale";
37349
38681
  function FireCMSi18nProvider({
@@ -37443,6 +38775,11 @@
37443
38775
  [FIRECMS_NS]: {
37444
38776
  ...pt
37445
38777
  }
38778
+ },
38779
+ pl: {
38780
+ [FIRECMS_NS]: {
38781
+ ...pl
38782
+ }
37446
38783
  }
37447
38784
  };
37448
38785
  if (!translations) return resources;
@@ -42038,6 +43375,7 @@ ul[data-type="taskList"] li[data-checked="true"] > div > p {
42038
43375
  exports2.DrawerLogo = DrawerLogo;
42039
43376
  exports2.DrawerNavigationGroup = DrawerNavigationGroup;
42040
43377
  exports2.DrawerNavigationItem = DrawerNavigationItem;
43378
+ exports2.DrawerToggle = DrawerToggle;
42041
43379
  exports2.EmptyValue = EmptyValue;
42042
43380
  exports2.EntityCard = EntityCard;
42043
43381
  exports2.EntityCollectionCardView = EntityCollectionCardView;
@@ -42064,6 +43402,8 @@ ul[data-type="taskList"] li[data-checked="true"] > div > p {
42064
43402
  exports2.FormEntry = FormEntry;
42065
43403
  exports2.FormLayout = FormLayout;
42066
43404
  exports2.GeoPoint = GeoPoint;
43405
+ exports2.GeopointFieldBinding = GeopointFieldBinding;
43406
+ exports2.GeopointPropertyPreview = GeopointPropertyPreview;
42067
43407
  exports2.IconForView = IconForView;
42068
43408
  exports2.ImagePreview = ImagePreview;
42069
43409
  exports2.InternalUserManagementContext = InternalUserManagementContext;
@@ -42141,15 +43481,18 @@ ul[data-type="taskList"] li[data-checked="true"] > div > p {
42141
43481
  exports2.canDeleteEntity = canDeleteEntity;
42142
43482
  exports2.canEditEntity = canEditEntity;
42143
43483
  exports2.copyEntityAction = copyEntityAction;
43484
+ exports2.decodeEntityId = decodeEntityId;
42144
43485
  exports2.defaultDateFormat = defaultDateFormat;
42145
43486
  exports2.deleteEntityAction = deleteEntityAction;
42146
43487
  exports2.deleteEntityWithCallbacks = deleteEntityWithCallbacks;
42147
43488
  exports2.editEntityAction = editEntityAction;
42148
43489
  exports2.en = en;
43490
+ exports2.encodeEntityId = encodeEntityId;
42149
43491
  exports2.enumToObjectEntries = enumToObjectEntries;
42150
43492
  exports2.es = es;
42151
43493
  exports2.evaluateCondition = evaluateCondition;
42152
43494
  exports2.flattenObject = flattenObject;
43495
+ exports2.formatGeoPoint = formatGeoPoint;
42153
43496
  exports2.fullPathToCollectionSegments = fullPathToCollectionSegments;
42154
43497
  exports2.getArrayResolvedProperties = getArrayResolvedProperties;
42155
43498
  exports2.getArrayValuesCount = getArrayValuesCount;
@@ -42171,6 +43514,7 @@ ul[data-type="taskList"] li[data-checked="true"] > div > p {
42171
43514
  exports2.getFieldConfig = getFieldConfig;
42172
43515
  exports2.getFieldId = getFieldId;
42173
43516
  exports2.getFormFieldKeys = getFormFieldKeys;
43517
+ exports2.getGeoPointCoordinates = getGeoPointCoordinates;
42174
43518
  exports2.getHashValue = getHashValue;
42175
43519
  exports2.getIcon = getIcon;
42176
43520
  exports2.getIconForProperty = getIconForProperty;
@@ -42188,6 +43532,7 @@ ul[data-type="taskList"] li[data-checked="true"] > div > p {
42188
43532
  exports2.hydrateRegExp = hydrateRegExp;
42189
43533
  exports2.iconSynonyms = iconSynonyms;
42190
43534
  exports2.iconsSearch = iconsSearch;
43535
+ exports2.isDataTypeFilterable = isDataTypeFilterable;
42191
43536
  exports2.isDefaultFieldConfigId = isDefaultFieldConfigId;
42192
43537
  exports2.isEmptyObject = isEmptyObject;
42193
43538
  exports2.isEnumValueDisabled = isEnumValueDisabled;
@@ -42207,6 +43552,8 @@ ul[data-type="taskList"] li[data-checked="true"] > div > p {
42207
43552
  exports2.mergeDeep = mergeDeep;
42208
43553
  exports2.mergeEntityActions = mergeEntityActions;
42209
43554
  exports2.navigateToEntity = navigateToEntity;
43555
+ exports2.normalizeGeoPoint = normalizeGeoPoint;
43556
+ exports2.parseGeoPoint = parseGeoPoint;
42210
43557
  exports2.pick = pick;
42211
43558
  exports2.plural = plural;
42212
43559
  exports2.prettifyIdentifier = prettifyIdentifier;