@firecms/core 3.3.0-canary.3ea2cd2 → 3.3.0-canary.42ba35b

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.es.js CHANGED
@@ -2,7 +2,7 @@ import { jsx, jsxs, Fragment } from "react/jsx-runtime";
2
2
  import { c } from "react-compiler-runtime";
3
3
  import * as React from "react";
4
4
  import React__default, { useState, useRef, useEffect, useContext, useCallback, useMemo, createElement, forwardRef, createRef, createContext, memo, useLayoutEffect } from "react";
5
- import { getColorSchemeForSeed, CHIP_COLORS, FunctionsIcon, CircleIcon, iconKeys, coolIconKeys, Icon, Tooltip, ErrorIcon, Typography, IconButton, ContentCopyIcon, OpenInNewIcon, DescriptionIcon, cls, Skeleton, Chip, defaultBorderMixin, KeyboardTabIcon, Checkbox, AccountCircleIcon, Markdown, TextareaAutosize, focusedDisabled, MultiSelect, MultiSelectItem, Select, SelectItem, BooleanSwitch, DateTimeField, paperMixin, EditIcon, DoNotDisturbOnIcon, InfoIcon, CloseIcon, Button, ExpandablePanel, fieldBackgroundMixin, RemoveIcon, fieldBackgroundDisabledMixin, fieldBackgroundHoverMixin, TextField, Collapse, BooleanSwitchWithLabel, AddIcon, ArrowDropDownIcon, MenuItem, Menu, CircularProgress, DialogActions, LoadingButton, WarningIcon, KeyboardArrowDownIcon, VisibilityIcon, CheckIcon, CancelIcon, DialogTitle, DialogContent, Dialog, Alert, NotesIcon, MoreVertIcon, Badge, SearchBar, ArrowUpwardIcon, Popover, FilterListIcon, CenteredView, AssignmentIcon, Label, useOutsideAlerter, FileCopyIcon, DeleteIcon, StarIcon, ArrowForwardIcon, Card, cardMixin, cardClickableMixin, Container, getColorSchemeForKey, RefreshIcon, ListIcon, AppsIcon, ViewKanbanIcon, ToggleButtonGroup, ViewColumnIcon, FilterListOffIcon, SearchIcon, DarkModeIcon, LightModeIcon, BrightnessMediumIcon, LogoutIcon, Avatar, HandleIcon, KeyboardArrowUpIcon, debounce, AutoAwesomeIcon, TranslateIcon, OpenInFullIcon, Sheet, Tab, ExpandMoreIcon, Tabs, CodeIcon, ViewStreamIcon, RepeatIcon, BallotIcon, ScheduleIcon, AddLinkIcon, LinkIcon, DriveFolderUploadIcon, UploadFileIcon, FormatListNumberedIcon, NumbersIcon, PersonIcon, ListAltIcon, FlagIcon, MailIcon, HttpIcon, FormatQuoteIcon, SubjectIcon, ShortTextIcon, MenuIcon, ChevronLeftIcon, TextFieldsIcon, CheckBoxIcon, LooksOneIcon, LooksTwoIcon, Looks3Icon, FormatListBulletedIcon, ImageIcon, TableChartIcon, AutoFixHighIcon, FormatBoldIcon, FormatItalicIcon, FormatUnderlinedIcon, FormatStrikethroughIcon, useInjectStyles, Separator } from "@firecms/ui";
5
+ import { getColorSchemeForSeed, CHIP_COLORS, FunctionsIcon, CircleIcon, iconKeys, coolIconKeys, Icon, Tooltip, ErrorIcon, Typography, IconButton, ContentCopyIcon, OpenInNewIcon, DescriptionIcon, cls, Skeleton, Chip, defaultBorderMixin, KeyboardTabIcon, Checkbox, AccountCircleIcon, Markdown, TextareaAutosize, focusedDisabled, MultiSelect, MultiSelectItem, Select, SelectItem, BooleanSwitch, DateTimeField, paperMixin, EditIcon, DoNotDisturbOnIcon, InfoIcon, CloseIcon, Button, ExpandablePanel, fieldBackgroundMixin, RemoveIcon, fieldBackgroundDisabledMixin, fieldBackgroundHoverMixin, TextField, Collapse, BooleanSwitchWithLabel, AddIcon, ArrowDropDownIcon, MenuItem, Menu, CircularProgress, DialogActions, LoadingButton, WarningIcon, KeyboardArrowDownIcon, VisibilityIcon, CheckIcon, CancelIcon, DialogTitle, DialogContent, Dialog, Alert, NotesIcon, MoreVertIcon, Badge, SearchBar, ArrowUpwardIcon, Popover, FilterListIcon, CenteredView, AssignmentIcon, Label, useOutsideAlerter, FileCopyIcon, DeleteIcon, StarIcon, ArrowForwardIcon, Card, cardMixin, cardClickableMixin, Container, getColorSchemeForKey, RefreshIcon, ListIcon, AppsIcon, ViewKanbanIcon, ToggleButtonGroup, ViewColumnIcon, FilterListOffIcon, SearchIcon, DarkModeIcon, LightModeIcon, BrightnessMediumIcon, LogoutIcon, Avatar, HandleIcon, KeyboardArrowUpIcon, debounce, AutoAwesomeIcon, TranslateIcon, OpenInFullIcon, Sheet, Tab, ExpandMoreIcon, Tabs, CodeIcon, KeyboardDoubleArrowLeftIcon, KeyboardDoubleArrowRightIcon, ViewStreamIcon, RepeatIcon, BallotIcon, LocationOnIcon, ScheduleIcon, AddLinkIcon, LinkIcon, DriveFolderUploadIcon, UploadFileIcon, FormatListNumberedIcon, NumbersIcon, PersonIcon, ListAltIcon, FlagIcon, MailIcon, HttpIcon, FormatQuoteIcon, SubjectIcon, ShortTextIcon, MenuIcon, TextFieldsIcon, CheckBoxIcon, LooksOneIcon, LooksTwoIcon, Looks3Icon, FormatListBulletedIcon, ImageIcon, TableChartIcon, AutoFixHighIcon, FormatBoldIcon, FormatItalicIcon, FormatUnderlinedIcon, FormatStrikethroughIcon, useInjectStyles, Separator } from "@firecms/ui";
6
6
  import { SnackbarProvider as SnackbarProvider$1, useSnackbar } from "notistack";
7
7
  import hash from "object-hash";
8
8
  import { getIn, Field, useFormex, setIn, useCreateFormex, Formex } from "@firecms/formex";
@@ -193,6 +193,12 @@ function addInitialSlash(s) {
193
193
  if (s.startsWith("/")) return s;
194
194
  else return `/${s}`;
195
195
  }
196
+ function encodeEntityId(entityId) {
197
+ return entityId.replaceAll("%", "%25").replaceAll("/", "%2F").replaceAll("#", "%23").replaceAll("?", "%3F");
198
+ }
199
+ function decodeEntityId(encodedEntityId) {
200
+ return encodedEntityId.replaceAll("%2F", "/").replaceAll("%23", "#").replaceAll("%3F", "?").replaceAll("%25", "%");
201
+ }
196
202
  function getLastSegment(path) {
197
203
  const cleanPath = removeInitialAndTrailingSlashes(path);
198
204
  if (cleanPath.includes("/")) {
@@ -286,7 +292,7 @@ function getCollectionByPathOrId(pathOrId, collections) {
286
292
  return result;
287
293
  }
288
294
  function getCollectionPathsCombinations(subpaths) {
289
- const entries = subpaths.length > 0 && subpaths.length % 2 === 0 ? subpaths.splice(0, subpaths.length - 1) : subpaths;
295
+ const entries = subpaths.length > 0 && subpaths.length % 2 === 0 ? subpaths.slice(0, subpaths.length - 1) : subpaths;
290
296
  const length = entries.length;
291
297
  const result = [];
292
298
  for (let i = length; i > 0; i = i - 2) {
@@ -318,7 +324,7 @@ function navigateToEntity({
318
324
  onClose
319
325
  });
320
326
  } else {
321
- let to = navigation.buildUrlCollectionPath(entityId ? `${fullIdPath ?? path}/${entityId}` : fullIdPath ?? path);
327
+ let to = navigation.buildUrlCollectionPath(entityId ? `${fullIdPath ?? path}/${encodeEntityId(entityId)}` : fullIdPath ?? path);
322
328
  if (entityId && selectedTab) {
323
329
  to += `/${selectedTab}`;
324
330
  }
@@ -681,6 +687,8 @@ function getDefaultValueForDataType(dataType) {
681
687
  return [];
682
688
  } else if (dataType === "map") {
683
689
  return {};
690
+ } else if (dataType === "geopoint") {
691
+ return null;
684
692
  } else {
685
693
  return null;
686
694
  }
@@ -714,6 +722,9 @@ function sanitizeData(values, properties) {
714
722
  return result;
715
723
  }
716
724
  function getReferenceFrom(entity) {
725
+ if (!entity) {
726
+ throw new Error("getReferenceFrom: entity is null or undefined");
727
+ }
717
728
  return new EntityReference(entity.id, entity.path, entity.databaseId);
718
729
  }
719
730
  function traverseValuesProperties(inputValues, properties, operation) {
@@ -763,6 +774,12 @@ function traverseValueProperty(inputValue, property, operation) {
763
774
  }
764
775
  return value;
765
776
  }
777
+ function isDataTypeFilterable(dataType, isPartOfArray = false) {
778
+ if (isPartOfArray) {
779
+ return ["string", "number", "date", "reference"].includes(dataType);
780
+ }
781
+ return ["string", "number", "boolean", "date", "reference", "array"].includes(dataType);
782
+ }
766
783
  function enumToObjectEntries(enumValues) {
767
784
  if (Array.isArray(enumValues)) {
768
785
  return enumValues;
@@ -849,8 +866,13 @@ const resolveCollection = ({
849
866
  ...a,
850
867
  ...b
851
868
  }), {});
869
+ const {
870
+ properties: overrideProps,
871
+ ...restOverrides
872
+ } = collectionOverride ?? {};
852
873
  return {
853
874
  ...collection,
875
+ ...restOverrides,
854
876
  properties: cleanedProperties,
855
877
  originalCollection: collection
856
878
  };
@@ -1126,7 +1148,8 @@ function getNavigationEntriesFromPath(props) {
1126
1148
  path,
1127
1149
  collections = [],
1128
1150
  currentFullPath,
1129
- currentFullIdPath
1151
+ currentFullIdPath,
1152
+ currentFullUrlPath
1130
1153
  } = props;
1131
1154
  const subpaths = removeInitialAndTrailingSlashes(path).split("/");
1132
1155
  const subpathCombinations = getCollectionPathsCombinations(subpaths);
@@ -1140,26 +1163,29 @@ function getNavigationEntriesFromPath(props) {
1140
1163
  }
1141
1164
  if (collection) {
1142
1165
  const collectionPath = currentFullPath && currentFullPath.length > 0 ? currentFullPath + "/" + collection.path : collection.path;
1166
+ const collectionUrlPath = currentFullUrlPath && currentFullUrlPath.length > 0 ? currentFullUrlPath + "/" + collection.path : collection.path;
1143
1167
  const fullIdPath = currentFullIdPath && currentFullIdPath.length > 0 ? currentFullIdPath + "/" + collection.id : collection.id;
1144
1168
  result.push({
1145
1169
  type: "collection",
1146
1170
  id: collection.id,
1147
1171
  path: collectionPath,
1148
- fullPath: collectionPath,
1172
+ fullPath: collectionUrlPath,
1149
1173
  fullIdPath,
1150
1174
  collection
1151
1175
  });
1152
1176
  const restOfThePath = removeInitialAndTrailingSlashes(removeInitialAndTrailingSlashes(path).replace(subpathCombination, ""));
1153
1177
  const nextSegments = restOfThePath.length > 0 ? restOfThePath.split("/") : [];
1154
1178
  if (nextSegments.length > 0) {
1155
- const entityId = nextSegments[0];
1179
+ const encodedEntityId = nextSegments[0];
1180
+ const entityId = decodeEntityId(encodedEntityId);
1156
1181
  const fullPath = collectionPath + "/" + entityId;
1182
+ const fullUrlPath = collectionUrlPath + "/" + encodedEntityId;
1157
1183
  result.push({
1158
1184
  type: "entity",
1159
1185
  entityId,
1160
1186
  path: collectionPath,
1161
1187
  fullIdPath,
1162
- fullPath,
1188
+ fullPath: fullUrlPath,
1163
1189
  parentCollection: collection
1164
1190
  });
1165
1191
  if (nextSegments.length > 1) {
@@ -1175,7 +1201,7 @@ function getNavigationEntriesFromPath(props) {
1175
1201
  path: collectionPath,
1176
1202
  entityId,
1177
1203
  fullIdPath,
1178
- fullPath: fullPath + "/" + customView.key,
1204
+ fullPath: fullUrlPath + "/" + customView.key,
1179
1205
  view: customView
1180
1206
  });
1181
1207
  } else if (collection.subcollections) {
@@ -1184,6 +1210,7 @@ function getNavigationEntriesFromPath(props) {
1184
1210
  collections: collection.subcollections,
1185
1211
  currentFullPath: fullPath,
1186
1212
  currentFullIdPath: fullIdPath,
1213
+ currentFullUrlPath: fullUrlPath,
1187
1214
  contextEntityViews: props.contextEntityViews
1188
1215
  }));
1189
1216
  }
@@ -1588,6 +1615,77 @@ function canCreateEntity(collection, authController, path, entity) {
1588
1615
  function canDeleteEntity(collection, authController, path, entity) {
1589
1616
  return resolvePermissions(collection, authController, path, entity)?.delete ?? DEFAULT_PERMISSIONS.delete;
1590
1617
  }
1618
+ function toNumber(value) {
1619
+ return typeof value === "number" && Number.isFinite(value) ? value : void 0;
1620
+ }
1621
+ function getGeoPointCoordinates(value) {
1622
+ if (!value) return void 0;
1623
+ if (value instanceof GeoPoint) {
1624
+ return {
1625
+ latitude: value.latitude,
1626
+ longitude: value.longitude
1627
+ };
1628
+ }
1629
+ if (typeof value !== "object") return void 0;
1630
+ const latitude = toNumber(value.latitude ?? value.lat ?? value._lat);
1631
+ const longitude = toNumber(value.longitude ?? value.lng ?? value._long);
1632
+ if (latitude === void 0 || longitude === void 0) return void 0;
1633
+ return {
1634
+ latitude,
1635
+ longitude
1636
+ };
1637
+ }
1638
+ function normalizeGeoPoint(value) {
1639
+ const coordinates = getGeoPointCoordinates(value);
1640
+ if (!coordinates) return void 0;
1641
+ if (value instanceof GeoPoint) return value;
1642
+ return new GeoPoint(coordinates.latitude, coordinates.longitude);
1643
+ }
1644
+ function formatGeoPoint(value, options) {
1645
+ const coordinates = getGeoPointCoordinates(value);
1646
+ if (!coordinates) return "";
1647
+ const maximumFractionDigits = options?.maximumFractionDigits ?? 6;
1648
+ const formatter = new Intl.NumberFormat("en-US", {
1649
+ maximumFractionDigits,
1650
+ minimumFractionDigits: Math.min(2, maximumFractionDigits),
1651
+ useGrouping: false
1652
+ });
1653
+ return `${formatter.format(coordinates.latitude)}, ${formatter.format(coordinates.longitude)}`;
1654
+ }
1655
+ function parseGeoPoint(input) {
1656
+ const trimmed = input.trim();
1657
+ if (!trimmed) return {
1658
+ point: null
1659
+ };
1660
+ const parts = trimmed.split(",").map((part) => part.trim()).filter((part) => part !== "");
1661
+ if (parts.length !== 2) return {
1662
+ point: null,
1663
+ error: 'Use "lat, lng" format'
1664
+ };
1665
+ const latitude = parseFloat(parts[0]);
1666
+ const longitude = parseFloat(parts[1]);
1667
+ if (!Number.isFinite(latitude) || !Number.isFinite(longitude)) {
1668
+ return {
1669
+ point: null,
1670
+ error: "Latitude and longitude must be numbers"
1671
+ };
1672
+ }
1673
+ if (latitude < -90 || latitude > 90) {
1674
+ return {
1675
+ point: null,
1676
+ error: "Latitude must be between -90 and 90"
1677
+ };
1678
+ }
1679
+ if (longitude < -180 || longitude > 180) {
1680
+ return {
1681
+ point: null,
1682
+ error: "Longitude must be between -180 and 180"
1683
+ };
1684
+ }
1685
+ return {
1686
+ point: new GeoPoint(latitude, longitude)
1687
+ };
1688
+ }
1591
1689
  const iconSynonyms = {
1592
1690
  abc: "alphabet character font letter symbol text type",
1593
1691
  access_alarm: "clock time",
@@ -4536,7 +4634,7 @@ function useCollectionFetch(t0) {
4536
4634
  }
4537
4635
  setDataLoading(false);
4538
4636
  setDataLoadingError(void 0);
4539
- setData(entities.map(_temp$C));
4637
+ setData(entities.map(_temp$D));
4540
4638
  setNoMoreToLoad(!itemCount || entities.length < itemCount);
4541
4639
  };
4542
4640
  const onError = (error) => {
@@ -4619,7 +4717,7 @@ function useCollectionFetch(t0) {
4619
4717
  }
4620
4718
  function _temp2$f() {
4621
4719
  }
4622
- function _temp$C(e_0) {
4720
+ function _temp$D(e_0) {
4623
4721
  return {
4624
4722
  ...e_0
4625
4723
  };
@@ -4684,7 +4782,7 @@ function useEntityFetch(t0) {
4684
4782
  setEntity(CACHE[`${path}/${entityId}`]);
4685
4783
  setDataLoading(false);
4686
4784
  setDataLoadingError(void 0);
4687
- return _temp$B;
4785
+ return _temp$C;
4688
4786
  } else {
4689
4787
  if (entityId && path && collection) {
4690
4788
  if (dataSource.listenEntity) {
@@ -4752,7 +4850,7 @@ function _temp3$5() {
4752
4850
  }
4753
4851
  function _temp2$e() {
4754
4852
  }
4755
- function _temp$B() {
4853
+ function _temp$C() {
4756
4854
  }
4757
4855
  async function saveEntityWithCallbacks({
4758
4856
  collection,
@@ -5396,7 +5494,7 @@ function ImagePreview(t0) {
5396
5494
  }
5397
5495
  let t9;
5398
5496
  if ($[19] !== url) {
5399
- t9 = /* @__PURE__ */ jsx(Tooltip, { title: "Open image in new tab", side: "bottom", children: /* @__PURE__ */ jsx(IconButton, { className: "invisible group-hover:visible", variant: "filled", component: "a", href: url, rel: "noopener noreferrer", target: "_blank", size: "smallest", onClick: _temp$A, children: t8 }) });
5497
+ t9 = /* @__PURE__ */ jsx(Tooltip, { title: "Open image in new tab", side: "bottom", children: /* @__PURE__ */ jsx(IconButton, { className: "invisible group-hover:visible", variant: "filled", component: "a", href: url, rel: "noopener noreferrer", target: "_blank", size: "smallest", onClick: _temp$B, children: t8 }) });
5400
5498
  $[19] = url;
5401
5499
  $[20] = t9;
5402
5500
  } else {
@@ -5430,7 +5528,7 @@ function ImagePreview(t0) {
5430
5528
  }
5431
5529
  return t11;
5432
5530
  }
5433
- function _temp$A(e_0) {
5531
+ function _temp$B(e_0) {
5434
5532
  return e_0.stopPropagation();
5435
5533
  }
5436
5534
  const FIRECMS_NS$1 = "firecms_core";
@@ -5497,7 +5595,7 @@ function UrlComponentPreview(t0) {
5497
5595
  }
5498
5596
  let t3;
5499
5597
  if ($[2] !== url) {
5500
- t3 = /* @__PURE__ */ jsxs("a", { className: "flex gap-4 break-words items-center font-medium text-primary visited:text-primary dark:visited:text-primary dark:text-primary", href: url, rel: "noopener noreferrer", onMouseDown: _temp$z, target: "_blank", children: [
5598
+ t3 = /* @__PURE__ */ jsxs("a", { className: "flex gap-4 break-words items-center font-medium text-primary visited:text-primary dark:visited:text-primary dark:text-primary", href: url, rel: "noopener noreferrer", onMouseDown: _temp$A, target: "_blank", children: [
5501
5599
  t2,
5502
5600
  url
5503
5601
  ] });
@@ -5627,7 +5725,7 @@ function UrlComponentPreview(t0) {
5627
5725
  function _temp2$d(e_0) {
5628
5726
  return e_0.stopPropagation();
5629
5727
  }
5630
- function _temp$z(e) {
5728
+ function _temp$A(e) {
5631
5729
  e.preventDefault();
5632
5730
  }
5633
5731
  function VideoPreview(t0) {
@@ -5761,7 +5859,7 @@ function SkeletonPropertyComponent(t0) {
5761
5859
  if (Array.isArray(arrayProperty.of)) {
5762
5860
  let t1;
5763
5861
  if ($[6] !== arrayProperty.of) {
5764
- t1 = arrayProperty.of.map(_temp$y);
5862
+ t1 = arrayProperty.of.map(_temp$z);
5765
5863
  $[6] = arrayProperty.of;
5766
5864
  $[7] = t1;
5767
5865
  } else {
@@ -5899,7 +5997,7 @@ function SkeletonPropertyComponent(t0) {
5899
5997
  }
5900
5998
  return content || null;
5901
5999
  }
5902
- function _temp$y(p, i) {
6000
+ function _temp$z(p, i) {
5903
6001
  return renderGenericArrayCell(p, i);
5904
6002
  }
5905
6003
  function renderMap(property, size) {
@@ -6343,104 +6441,77 @@ function EntityPreview({
6343
6441
  actions
6344
6442
  ] });
6345
6443
  }
6346
- const EntityPreviewContainer = React.forwardRef((t0, ref) => {
6347
- const $ = c(26);
6348
- let children;
6349
- let className;
6350
- let hover;
6351
- let onClick;
6352
- let props;
6353
- let style;
6354
- let t1;
6355
- let t2;
6356
- if ($[0] !== t0) {
6357
- ({
6358
- children,
6359
- hover,
6360
- onClick,
6361
- size: t1,
6362
- style,
6363
- className,
6364
- fullwidth: t2,
6365
- ...props
6366
- } = t0);
6367
- $[0] = t0;
6368
- $[1] = children;
6369
- $[2] = className;
6370
- $[3] = hover;
6371
- $[4] = onClick;
6372
- $[5] = props;
6373
- $[6] = style;
6374
- $[7] = t1;
6375
- $[8] = t2;
6376
- } else {
6377
- children = $[1];
6378
- className = $[2];
6379
- hover = $[3];
6380
- onClick = $[4];
6381
- props = $[5];
6382
- style = $[6];
6383
- t1 = $[7];
6384
- t2 = $[8];
6385
- }
6444
+ function EntityPreviewContainer(t0) {
6445
+ const $ = c(15);
6446
+ const {
6447
+ children,
6448
+ hover,
6449
+ onClick,
6450
+ size: t1,
6451
+ style,
6452
+ className,
6453
+ fullwidth: t2,
6454
+ ref
6455
+ } = t0;
6386
6456
  const size = t1 === void 0 ? "medium" : t1;
6387
6457
  const fullwidth = t2 === void 0 ? true : t2;
6388
- let t3;
6389
- if ($[9] !== style) {
6390
- t3 = {
6391
- ...style,
6392
- tabindex: 0
6393
- };
6394
- $[9] = style;
6395
- $[10] = t3;
6458
+ const t3 = fullwidth ? "w-full" : "";
6459
+ 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" : "";
6460
+ const t5 = size === "small" ? "p-1" : "px-2 py-1";
6461
+ const t6 = onClick ? "cursor-pointer" : "";
6462
+ let t7;
6463
+ if ($[0] !== className || $[1] !== t3 || $[2] !== t4 || $[3] !== t5 || $[4] !== t6) {
6464
+ t7 = cls("bg-white dark:bg-surface-900", "min-h-[44px]", t3, "items-center", t4, t5, "flex border rounded-lg", t6, defaultBorderMixin, className);
6465
+ $[0] = className;
6466
+ $[1] = t3;
6467
+ $[2] = t4;
6468
+ $[3] = t5;
6469
+ $[4] = t6;
6470
+ $[5] = t7;
6396
6471
  } else {
6397
- t3 = $[10];
6472
+ t7 = $[5];
6398
6473
  }
6399
- const t4 = fullwidth ? "w-full" : "";
6400
- 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" : "";
6401
- const t6 = size === "small" ? "p-1" : "px-2 py-1";
6402
- const t7 = onClick ? "cursor-pointer" : "";
6474
+ const divClassName = t7;
6403
6475
  let t8;
6404
- if ($[11] !== className || $[12] !== t4 || $[13] !== t5 || $[14] !== t6 || $[15] !== t7) {
6405
- t8 = cls("bg-white dark:bg-surface-900", "min-h-[44px]", t4, "items-center", t5, t6, "flex border rounded-lg", t7, defaultBorderMixin, className);
6406
- $[11] = className;
6407
- $[12] = t4;
6408
- $[13] = t5;
6409
- $[14] = t6;
6410
- $[15] = t7;
6411
- $[16] = t8;
6476
+ if ($[6] !== onClick) {
6477
+ t8 = onClick ? (event) => {
6478
+ event.preventDefault();
6479
+ onClick(event);
6480
+ } : void 0;
6481
+ $[6] = onClick;
6482
+ $[7] = t8;
6412
6483
  } else {
6413
- t8 = $[16];
6484
+ t8 = $[7];
6414
6485
  }
6486
+ const handleClick = t8;
6415
6487
  let t9;
6416
- if ($[17] !== onClick) {
6417
- t9 = (event) => {
6418
- if (onClick) {
6419
- event.preventDefault();
6420
- onClick(event);
6421
- }
6488
+ if ($[8] !== divClassName || $[9] !== handleClick || $[10] !== style) {
6489
+ t9 = {
6490
+ ref,
6491
+ tabIndex: 0,
6492
+ style,
6493
+ className: divClassName,
6494
+ onClick: handleClick
6422
6495
  };
6423
- $[17] = onClick;
6424
- $[18] = t9;
6496
+ $[8] = divClassName;
6497
+ $[9] = handleClick;
6498
+ $[10] = style;
6499
+ $[11] = t9;
6425
6500
  } else {
6426
- t9 = $[18];
6501
+ t9 = $[11];
6427
6502
  }
6503
+ const divProps = t9;
6428
6504
  let t10;
6429
- if ($[19] !== children || $[20] !== props || $[21] !== ref || $[22] !== t3 || $[23] !== t8 || $[24] !== t9) {
6430
- t10 = /* @__PURE__ */ jsx("div", { ref, style: t3, className: t8, onClick: t9, ...props, children });
6431
- $[19] = children;
6432
- $[20] = props;
6433
- $[21] = ref;
6434
- $[22] = t3;
6435
- $[23] = t8;
6436
- $[24] = t9;
6437
- $[25] = t10;
6505
+ if ($[12] !== children || $[13] !== divProps) {
6506
+ t10 = /* @__PURE__ */ jsx("div", { ...divProps, children });
6507
+ $[12] = children;
6508
+ $[13] = divProps;
6509
+ $[14] = t10;
6438
6510
  } else {
6439
- t10 = $[25];
6511
+ t10 = $[14];
6440
6512
  }
6441
6513
  return t10;
6442
- });
6443
- EntityPreviewContainer.displayName = "EntityPreviewContainer";
6514
+ }
6444
6515
  const ReferencePreview = function ReferencePreview2(props) {
6445
6516
  const $ = c(10);
6446
6517
  const reference = props.reference;
@@ -7074,7 +7145,7 @@ function DatePreview(t0) {
7074
7145
  timeZoneName: "short"
7075
7146
  });
7076
7147
  const parts = tzFormatter.formatToParts(date);
7077
- t32 = parts.find(_temp$x)?.value ?? "";
7148
+ t32 = parts.find(_temp$y)?.value ?? "";
7078
7149
  $[6] = date;
7079
7150
  $[7] = timezone;
7080
7151
  $[8] = t32;
@@ -7145,7 +7216,7 @@ function DatePreview(t0) {
7145
7216
  }
7146
7217
  return t3;
7147
7218
  }
7148
- function _temp$x(p) {
7219
+ function _temp$y(p) {
7149
7220
  return p.type === "timeZoneName";
7150
7221
  }
7151
7222
  function MapPropertyPreview(t0) {
@@ -7240,7 +7311,7 @@ function KeyValuePreview(t0) {
7240
7311
  }
7241
7312
  let t1;
7242
7313
  if ($[1] !== value) {
7243
- t1 = Object.entries(value).map(_temp$w);
7314
+ t1 = Object.entries(value).map(_temp$x);
7244
7315
  $[1] = value;
7245
7316
  $[2] = t1;
7246
7317
  } else {
@@ -7256,7 +7327,7 @@ function KeyValuePreview(t0) {
7256
7327
  }
7257
7328
  return t2;
7258
7329
  }
7259
- function _temp$w(t0) {
7330
+ function _temp$x(t0) {
7260
7331
  const [key, childValue] = t0;
7261
7332
  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");
7262
7333
  const isScalar = childValue && (typeof childValue !== "object" || isTimestampObj);
@@ -7268,6 +7339,59 @@ function _temp$w(t0) {
7268
7339
  typeof childValue === "object" && !isTimestampObj && /* @__PURE__ */ jsx("div", { className: cls(defaultBorderMixin, "border-l pl-4"), children: /* @__PURE__ */ jsx(KeyValuePreview, { value: childValue }) })
7269
7340
  ] }, `map_preview_table_${key}}`);
7270
7341
  }
7342
+ function GeopointPropertyPreview(t0) {
7343
+ const $ = c(10);
7344
+ const {
7345
+ value,
7346
+ size
7347
+ } = t0;
7348
+ let t1;
7349
+ let t2;
7350
+ let t3;
7351
+ if ($[0] !== size || $[1] !== value) {
7352
+ t3 = /* @__PURE__ */ Symbol.for("react.early_return_sentinel");
7353
+ bb0: {
7354
+ const coordinates = getGeoPointCoordinates(value);
7355
+ if (!coordinates) {
7356
+ const t42 = size === "small" ? "text-sm text-text-secondary dark:text-text-secondary-dark" : "text-text-secondary dark:text-text-secondary-dark";
7357
+ let t5;
7358
+ if ($[5] !== t42) {
7359
+ t5 = /* @__PURE__ */ jsx("span", { className: t42, children: "—" });
7360
+ $[5] = t42;
7361
+ $[6] = t5;
7362
+ } else {
7363
+ t5 = $[6];
7364
+ }
7365
+ t3 = t5;
7366
+ break bb0;
7367
+ }
7368
+ t1 = size === "small" ? "text-sm font-mono" : "font-mono";
7369
+ t2 = formatGeoPoint(coordinates);
7370
+ }
7371
+ $[0] = size;
7372
+ $[1] = value;
7373
+ $[2] = t1;
7374
+ $[3] = t2;
7375
+ $[4] = t3;
7376
+ } else {
7377
+ t1 = $[2];
7378
+ t2 = $[3];
7379
+ t3 = $[4];
7380
+ }
7381
+ if (t3 !== /* @__PURE__ */ Symbol.for("react.early_return_sentinel")) {
7382
+ return t3;
7383
+ }
7384
+ let t4;
7385
+ if ($[7] !== t1 || $[8] !== t2) {
7386
+ t4 = /* @__PURE__ */ jsx("span", { className: t1, children: t2 });
7387
+ $[7] = t1;
7388
+ $[8] = t2;
7389
+ $[9] = t4;
7390
+ } else {
7391
+ t4 = $[9];
7392
+ }
7393
+ return t4;
7394
+ }
7271
7395
  function BooleanPreview(t0) {
7272
7396
  const $ = c(9);
7273
7397
  const {
@@ -7695,47 +7819,56 @@ const PropertyPreview = React__default.memo(function PropertyPreview2(props) {
7695
7819
  content = buildWrongValueType(propertyKey, property.dataType, value);
7696
7820
  }
7697
7821
  } else {
7698
- if (property.dataType === "reference") {
7699
- if (typeof property.path === "string") {
7700
- if (typeof value === "object" && "isEntityReference" in value && value.isEntityReference()) {
7701
- content = /* @__PURE__ */ jsx(ReferencePreview, { disabled: !property.path, previewProperties: property.previewProperties, includeId: property.includeId, includeEntityLink: property.includeEntityLink, size: props.size, reference: value });
7702
- } else {
7703
- content = buildWrongValueType(propertyKey, property.dataType, value);
7704
- }
7822
+ if (property.dataType === "geopoint") {
7823
+ const coordinates = getGeoPointCoordinates(value);
7824
+ if (coordinates) {
7825
+ content = /* @__PURE__ */ jsx(GeopointPropertyPreview, { ...props, property, value });
7705
7826
  } else {
7706
- let t02;
7707
- if ($[27] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
7708
- t02 = /* @__PURE__ */ jsx(EmptyValue, {});
7709
- $[27] = t02;
7710
- } else {
7711
- t02 = $[27];
7712
- }
7713
- content = t02;
7827
+ content = buildWrongValueType(propertyKey, property.dataType, value);
7714
7828
  }
7715
7829
  } else {
7716
- if (property.dataType === "boolean") {
7717
- if (typeof value === "boolean") {
7718
- content = /* @__PURE__ */ jsx(BooleanPreview, { value, size, property });
7830
+ if (property.dataType === "reference") {
7831
+ if (typeof property.path === "string") {
7832
+ if (typeof value === "object" && "isEntityReference" in value && value.isEntityReference()) {
7833
+ content = /* @__PURE__ */ jsx(ReferencePreview, { disabled: !property.path, previewProperties: property.previewProperties, includeId: property.includeId, includeEntityLink: property.includeEntityLink, size: props.size, reference: value });
7834
+ } else {
7835
+ content = buildWrongValueType(propertyKey, property.dataType, value);
7836
+ }
7719
7837
  } else {
7720
- content = buildWrongValueType(propertyKey, property.dataType, value);
7838
+ let t02;
7839
+ if ($[27] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
7840
+ t02 = /* @__PURE__ */ jsx(EmptyValue, {});
7841
+ $[27] = t02;
7842
+ } else {
7843
+ t02 = $[27];
7844
+ }
7845
+ content = t02;
7721
7846
  }
7722
7847
  } else {
7723
- if (property.dataType === "number") {
7724
- if (typeof value === "number") {
7725
- content = /* @__PURE__ */ jsx(NumberPropertyPreview, { ...props, value, property });
7848
+ if (property.dataType === "boolean") {
7849
+ if (typeof value === "boolean") {
7850
+ content = /* @__PURE__ */ jsx(BooleanPreview, { value, size, property });
7726
7851
  } else {
7727
7852
  content = buildWrongValueType(propertyKey, property.dataType, value);
7728
7853
  }
7729
7854
  } else {
7730
- let t02;
7731
- if ($[28] !== value) {
7732
- t02 = JSON.stringify(value, jsonStringifyReplacer);
7733
- $[28] = value;
7734
- $[29] = t02;
7855
+ if (property.dataType === "number") {
7856
+ if (typeof value === "number") {
7857
+ content = /* @__PURE__ */ jsx(NumberPropertyPreview, { ...props, value, property });
7858
+ } else {
7859
+ content = buildWrongValueType(propertyKey, property.dataType, value);
7860
+ }
7735
7861
  } else {
7736
- t02 = $[29];
7862
+ let t02;
7863
+ if ($[28] !== value) {
7864
+ t02 = JSON.stringify(value, jsonStringifyReplacer);
7865
+ $[28] = value;
7866
+ $[29] = t02;
7867
+ } else {
7868
+ t02 = $[29];
7869
+ }
7870
+ content = t02;
7737
7871
  }
7738
- content = t02;
7739
7872
  }
7740
7873
  }
7741
7874
  }
@@ -8517,7 +8650,7 @@ function VirtualTableSelect(props) {
8517
8650
  console.trace("onChange");
8518
8651
  if (valueType === "number") {
8519
8652
  if (multiple) {
8520
- const newValue = updatedValue.map(_temp$v);
8653
+ const newValue = updatedValue.map(_temp$w);
8521
8654
  updateValue(newValue);
8522
8655
  } else {
8523
8656
  updateValue(parseFloat(updatedValue));
@@ -8588,7 +8721,7 @@ function VirtualTableSelect(props) {
8588
8721
  function _temp2$c(v_0) {
8589
8722
  return v_0.toString();
8590
8723
  }
8591
- function _temp$v(v) {
8724
+ function _temp$w(v) {
8592
8725
  return parseFloat(v);
8593
8726
  }
8594
8727
  function VirtualTableNumberInput(props) {
@@ -8784,7 +8917,7 @@ function VirtualTableUserSelect(props) {
8784
8917
  const renderValue = t3;
8785
8918
  let t4;
8786
8919
  if ($[7] !== disabled || $[8] !== internalValue || $[9] !== multiple || $[10] !== onChange || $[11] !== renderValue || $[12] !== users || $[13] !== validValue) {
8787
- t4 = multiple ? /* @__PURE__ */ jsx(MultiSelect, { inputRef: ref, className: "w-full h-full p-0 bg-transparent", position: "item-aligned", disabled, includeClear: false, useChips: false, value: validValue ? internalValue : [], onValueChange: onChange, children: users?.map(_temp$u) }) : /* @__PURE__ */ jsx(Select, { inputRef: ref, size: "large", fullWidth: true, className: "w-full h-full p-0 bg-transparent", position: "item-aligned", disabled, padding: false, value: validValue ? internalValue : "", onValueChange: onChange, renderValue, children: users?.map(_temp2$b) });
8920
+ t4 = multiple ? /* @__PURE__ */ jsx(MultiSelect, { inputRef: ref, className: "w-full h-full p-0 bg-transparent", position: "item-aligned", disabled, includeClear: false, useChips: false, value: validValue ? internalValue : [], onValueChange: onChange, children: users?.map(_temp$v) }) : /* @__PURE__ */ jsx(Select, { inputRef: ref, size: "large", fullWidth: true, className: "w-full h-full p-0 bg-transparent", position: "item-aligned", disabled, padding: false, value: validValue ? internalValue : "", onValueChange: onChange, renderValue, children: users?.map(_temp2$b) });
8788
8921
  $[7] = disabled;
8789
8922
  $[8] = internalValue;
8790
8923
  $[9] = multiple;
@@ -8801,7 +8934,7 @@ function VirtualTableUserSelect(props) {
8801
8934
  function _temp2$b(user_1) {
8802
8935
  return /* @__PURE__ */ jsx(SelectItem, { value: user_1.uid, children: /* @__PURE__ */ jsx(UserDisplay, { user: user_1 }) }, user_1.uid);
8803
8936
  }
8804
- function _temp$u(user_0) {
8937
+ function _temp$v(user_0) {
8805
8938
  return /* @__PURE__ */ jsx(MultiSelectItem, { value: user_0.uid, children: /* @__PURE__ */ jsx(UserDisplay, { user: user_0 }) }, user_0.uid);
8806
8939
  }
8807
8940
  class ErrorBoundary extends React__default.Component {
@@ -9046,7 +9179,7 @@ function useStorageUploadController(t0) {
9046
9179
  newValue = [...internalValue];
9047
9180
  newValue = removeDuplicates(newValue);
9048
9181
  setInternalValue(newValue);
9049
- const fieldValue = newValue.filter(_temp$t).map(_temp2$a);
9182
+ const fieldValue = newValue.filter(_temp$u).map(_temp2$a);
9050
9183
  if (multipleFilesSupported) {
9051
9184
  onChange(fieldValue);
9052
9185
  } else {
@@ -9167,7 +9300,7 @@ function useStorageUploadController(t0) {
9167
9300
  function _temp2$a(e_0) {
9168
9301
  return e_0.storagePathOrDownloadUrl;
9169
9302
  }
9170
- function _temp$t(e) {
9303
+ function _temp$u(e) {
9171
9304
  return !!e.storagePathOrDownloadUrl;
9172
9305
  }
9173
9306
  function getInternalInitialValue(multipleFilesSupported, value, metadata, size) {
@@ -9457,7 +9590,7 @@ function StorageUpload$1(t0) {
9457
9590
  const snackbarContext = useSnackbarController();
9458
9591
  let t1;
9459
9592
  if ($[0] !== storage.acceptedFiles) {
9460
- t1 = storage.acceptedFiles ? storage.acceptedFiles.map(_temp$s).reduce(_temp2$9, {}) : void 0;
9593
+ t1 = storage.acceptedFiles ? storage.acceptedFiles.map(_temp$t).reduce(_temp2$9, {}) : void 0;
9461
9594
  $[0] = storage.acceptedFiles;
9462
9595
  $[1] = t1;
9463
9596
  } else {
@@ -9686,7 +9819,7 @@ function _temp2$9(a, b) {
9686
9819
  ...b
9687
9820
  };
9688
9821
  }
9689
- function _temp$s(e) {
9822
+ function _temp$t(e) {
9690
9823
  return {
9691
9824
  [e]: []
9692
9825
  };
@@ -9796,7 +9929,7 @@ const TableReferenceFieldInternal = React__default.memo(function TableReferenceF
9796
9929
  let t1;
9797
9930
  if ($[2] !== updateValue) {
9798
9931
  t1 = (entities) => {
9799
- updateValue(entities.map(_temp$r));
9932
+ updateValue(entities.filter(Boolean).map(_temp$s));
9800
9933
  };
9801
9934
  $[2] = updateValue;
9802
9935
  $[3] = t1;
@@ -9968,7 +10101,7 @@ const TableReferenceFieldInternal = React__default.memo(function TableReferenceF
9968
10101
  }
9969
10102
  return t10;
9970
10103
  }, equal);
9971
- function _temp$r(e) {
10104
+ function _temp$s(e) {
9972
10105
  return getReferenceFrom(e);
9973
10106
  }
9974
10107
  function _temp2$8(ref) {
@@ -11636,7 +11769,7 @@ function ArrayOfReferencesFieldBinding({
11636
11769
  throw Error(`Couldn't find the corresponding collection for the path: ${ofProperty.path}`);
11637
11770
  }
11638
11771
  const onMultipleEntitiesSelected = useCallback((entities) => {
11639
- setValue(entities.map((e) => getReferenceFrom(e)));
11772
+ setValue(entities.filter(Boolean).map((e) => getReferenceFrom(e)));
11640
11773
  }, [setValue]);
11641
11774
  const referenceDialogController = useReferenceDialog({
11642
11775
  multiselect: true,
@@ -11746,7 +11879,7 @@ function StorageItemPreview(t0) {
11746
11879
  }
11747
11880
  let t5;
11748
11881
  if ($[15] !== placeholder) {
11749
- t5 = placeholder && /* @__PURE__ */ jsx("div", { onClick: _temp$q, className: "flex flex-col items-center justify-center w-full h-full", children: /* @__PURE__ */ jsx(DescriptionIcon, { className: "text-surface-700 dark:text-surface-300" }) });
11882
+ t5 = placeholder && /* @__PURE__ */ jsx("div", { onClick: _temp$r, className: "flex flex-col items-center justify-center w-full h-full", children: /* @__PURE__ */ jsx(DescriptionIcon, { className: "text-surface-700 dark:text-surface-300" }) });
11750
11883
  $[15] = placeholder;
11751
11884
  $[16] = t5;
11752
11885
  } else {
@@ -11769,7 +11902,7 @@ function StorageItemPreview(t0) {
11769
11902
  }
11770
11903
  return t6;
11771
11904
  }
11772
- function _temp$q(e) {
11905
+ function _temp$r(e) {
11773
11906
  return e.stopPropagation();
11774
11907
  }
11775
11908
  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";
@@ -11997,7 +12130,7 @@ function SortableStorageItem(t0) {
11997
12130
  t4 = $[7];
11998
12131
  }
11999
12132
  const style = t4;
12000
- const getImageSizeNumber = _temp$p;
12133
+ const getImageSizeNumber = _temp$q;
12001
12134
  let child;
12002
12135
  if (entry.storagePathOrDownloadUrl) {
12003
12136
  const t52 = `storage_preview_${entry.storagePathOrDownloadUrl}`;
@@ -12072,7 +12205,7 @@ function SortableStorageItem(t0) {
12072
12205
  }
12073
12206
  return t6;
12074
12207
  }
12075
- function _temp$p(previewSize) {
12208
+ function _temp$q(previewSize) {
12076
12209
  switch (previewSize) {
12077
12210
  case "small": {
12078
12211
  return 40;
@@ -12353,7 +12486,7 @@ function StorageUpload(t0) {
12353
12486
  newValue.splice(fromIndex, 1);
12354
12487
  newValue.splice(toIndex, 0, item);
12355
12488
  setInternalValue(newValue);
12356
- const fieldValue = newValue.filter(_temp3$4).map(_temp4$3);
12489
+ const fieldValue = newValue.filter(_temp3$4).map(_temp4$4);
12357
12490
  onChange(fieldValue);
12358
12491
  };
12359
12492
  $[0] = multipleFilesSupported;
@@ -12547,7 +12680,7 @@ function _temp6$2(v_1) {
12547
12680
  function _temp5$2(v_0) {
12548
12681
  return !!v_0.storagePathOrDownloadUrl;
12549
12682
  }
12550
- function _temp4$3(e_0) {
12683
+ function _temp4$4(e_0) {
12551
12684
  return e_0.storagePathOrDownloadUrl;
12552
12685
  }
12553
12686
  function _temp3$4(e) {
@@ -12972,6 +13105,260 @@ function DateTimeFieldBinding(t0) {
12972
13105
  }
12973
13106
  return t13;
12974
13107
  }
13108
+ function GeopointFieldBinding(t0) {
13109
+ const $ = c(66);
13110
+ const {
13111
+ propertyKey,
13112
+ value,
13113
+ setValue,
13114
+ error,
13115
+ showError,
13116
+ disabled,
13117
+ autoFocus,
13118
+ property,
13119
+ includeDescription,
13120
+ size: t1
13121
+ } = t0;
13122
+ const size = t1 === void 0 ? "large" : t1;
13123
+ const coordinates = getGeoPointCoordinates(value);
13124
+ const canClear = Boolean(property.clearable);
13125
+ const [latitude, setLatitude] = useState(coordinates ? coordinates.latitude.toString() : "");
13126
+ const [longitude, setLongitude] = useState(coordinates ? coordinates.longitude.toString() : "");
13127
+ const [localError, setLocalError] = useState();
13128
+ const skipSyncRef = useRef(false);
13129
+ let t2;
13130
+ if ($[0] !== property || $[1] !== setValue || $[2] !== value) {
13131
+ t2 = {
13132
+ property,
13133
+ value,
13134
+ setValue
13135
+ };
13136
+ $[0] = property;
13137
+ $[1] = setValue;
13138
+ $[2] = value;
13139
+ $[3] = t2;
13140
+ } else {
13141
+ t2 = $[3];
13142
+ }
13143
+ useClearRestoreValue(t2);
13144
+ let t3;
13145
+ if ($[4] !== setLatitude || $[5] !== value) {
13146
+ t3 = () => {
13147
+ if (skipSyncRef.current) {
13148
+ skipSyncRef.current = false;
13149
+ return;
13150
+ }
13151
+ const nextCoordinates = getGeoPointCoordinates(value);
13152
+ setLatitude(nextCoordinates ? nextCoordinates.latitude.toString() : "");
13153
+ setLongitude(nextCoordinates ? nextCoordinates.longitude.toString() : "");
13154
+ };
13155
+ $[4] = setLatitude;
13156
+ $[5] = value;
13157
+ $[6] = t3;
13158
+ } else {
13159
+ t3 = $[6];
13160
+ }
13161
+ let t4;
13162
+ if ($[7] !== value) {
13163
+ t4 = [value];
13164
+ $[7] = value;
13165
+ $[8] = t4;
13166
+ } else {
13167
+ t4 = $[8];
13168
+ }
13169
+ useEffect(t3, t4);
13170
+ let t5;
13171
+ if ($[9] !== setLatitude || $[10] !== setValue) {
13172
+ t5 = (nextLatitude, nextLongitude) => {
13173
+ skipSyncRef.current = true;
13174
+ setLatitude(nextLatitude);
13175
+ setLongitude(nextLongitude);
13176
+ const trimmedLatitude = nextLatitude.trim();
13177
+ const trimmedLongitude = nextLongitude.trim();
13178
+ if (!trimmedLatitude && !trimmedLongitude) {
13179
+ setLocalError(void 0);
13180
+ setValue(null);
13181
+ return;
13182
+ }
13183
+ const parsed = parseGeoPoint(`${trimmedLatitude}, ${trimmedLongitude}`);
13184
+ if (parsed.error) {
13185
+ setLocalError(parsed.error);
13186
+ setValue(null);
13187
+ return;
13188
+ }
13189
+ setLocalError(void 0);
13190
+ setValue(parsed.point);
13191
+ };
13192
+ $[9] = setLatitude;
13193
+ $[10] = setValue;
13194
+ $[11] = t5;
13195
+ } else {
13196
+ t5 = $[11];
13197
+ }
13198
+ const updateGeoPoint = t5;
13199
+ let t6;
13200
+ if ($[12] !== updateGeoPoint) {
13201
+ t6 = (event) => {
13202
+ if (event) {
13203
+ event.preventDefault();
13204
+ event.stopPropagation();
13205
+ }
13206
+ updateGeoPoint("", "");
13207
+ };
13208
+ $[12] = updateGeoPoint;
13209
+ $[13] = t6;
13210
+ } else {
13211
+ t6 = $[13];
13212
+ }
13213
+ const handleClear = t6;
13214
+ const resolvedError = localError ?? error;
13215
+ const shouldShowError = Boolean(resolvedError) || Boolean(showError && error);
13216
+ let t7;
13217
+ if ($[14] !== property) {
13218
+ t7 = getIconForProperty(property, "small");
13219
+ $[14] = property;
13220
+ $[15] = t7;
13221
+ } else {
13222
+ t7 = $[15];
13223
+ }
13224
+ const t8 = property.validation?.required;
13225
+ const t9 = shouldShowError ? "text-red-500 dark:text-red-500" : "text-text-secondary dark:text-text-secondary-dark";
13226
+ let t10;
13227
+ if ($[16] !== property.name || $[17] !== t7 || $[18] !== t8 || $[19] !== t9) {
13228
+ t10 = /* @__PURE__ */ jsx("div", { className: "mt-1", children: /* @__PURE__ */ jsx(LabelWithIcon, { icon: t7, required: t8, title: property.name, className: t9 }) });
13229
+ $[16] = property.name;
13230
+ $[17] = t7;
13231
+ $[18] = t8;
13232
+ $[19] = t9;
13233
+ $[20] = t10;
13234
+ } else {
13235
+ t10 = $[20];
13236
+ }
13237
+ let t11;
13238
+ if ($[21] !== longitude || $[22] !== updateGeoPoint) {
13239
+ t11 = (event_0) => updateGeoPoint(event_0.target.value, longitude);
13240
+ $[21] = longitude;
13241
+ $[22] = updateGeoPoint;
13242
+ $[23] = t11;
13243
+ } else {
13244
+ t11 = $[23];
13245
+ }
13246
+ let t12;
13247
+ if ($[24] !== canClear || $[25] !== handleClear) {
13248
+ t12 = canClear ? /* @__PURE__ */ jsx(IconButton, { onClick: handleClear, children: /* @__PURE__ */ jsx(CloseIcon, {}) }) : void 0;
13249
+ $[24] = canClear;
13250
+ $[25] = handleClear;
13251
+ $[26] = t12;
13252
+ } else {
13253
+ t12 = $[26];
13254
+ }
13255
+ const t13 = shouldShowError && Boolean(resolvedError);
13256
+ let t14;
13257
+ if ($[27] !== autoFocus || $[28] !== disabled || $[29] !== latitude || $[30] !== size || $[31] !== t11 || $[32] !== t12 || $[33] !== t13) {
13258
+ t14 = /* @__PURE__ */ jsx(TextField, { size, value: latitude, onChange: t11, autoFocus, label: "Latitude", type: "number", disabled, endAdornment: t12, error: t13 });
13259
+ $[27] = autoFocus;
13260
+ $[28] = disabled;
13261
+ $[29] = latitude;
13262
+ $[30] = size;
13263
+ $[31] = t11;
13264
+ $[32] = t12;
13265
+ $[33] = t13;
13266
+ $[34] = t14;
13267
+ } else {
13268
+ t14 = $[34];
13269
+ }
13270
+ let t15;
13271
+ if ($[35] !== latitude || $[36] !== updateGeoPoint) {
13272
+ t15 = (event_1) => updateGeoPoint(latitude, event_1.target.value);
13273
+ $[35] = latitude;
13274
+ $[36] = updateGeoPoint;
13275
+ $[37] = t15;
13276
+ } else {
13277
+ t15 = $[37];
13278
+ }
13279
+ const t16 = shouldShowError && Boolean(resolvedError);
13280
+ let t17;
13281
+ if ($[38] !== disabled || $[39] !== longitude || $[40] !== size || $[41] !== t15 || $[42] !== t16) {
13282
+ t17 = /* @__PURE__ */ jsx(TextField, { size, value: longitude, onChange: t15, label: "Longitude", type: "number", disabled, error: t16 });
13283
+ $[38] = disabled;
13284
+ $[39] = longitude;
13285
+ $[40] = size;
13286
+ $[41] = t15;
13287
+ $[42] = t16;
13288
+ $[43] = t17;
13289
+ } else {
13290
+ t17 = $[43];
13291
+ }
13292
+ let t18;
13293
+ if ($[44] !== t14 || $[45] !== t17) {
13294
+ t18 = /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-1 gap-2 md:grid-cols-2", children: [
13295
+ t14,
13296
+ t17
13297
+ ] });
13298
+ $[44] = t14;
13299
+ $[45] = t17;
13300
+ $[46] = t18;
13301
+ } else {
13302
+ t18 = $[46];
13303
+ }
13304
+ let t19;
13305
+ if ($[47] !== resolvedError || $[48] !== value) {
13306
+ t19 = value && !resolvedError && /* @__PURE__ */ jsx("div", { className: "text-xs text-text-secondary dark:text-text-secondary-dark font-mono", children: formatGeoPoint(value) });
13307
+ $[47] = resolvedError;
13308
+ $[48] = value;
13309
+ $[49] = t19;
13310
+ } else {
13311
+ t19 = $[49];
13312
+ }
13313
+ let t20;
13314
+ if ($[50] !== t10 || $[51] !== t18 || $[52] !== t19) {
13315
+ t20 = /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2", children: [
13316
+ t10,
13317
+ t18,
13318
+ t19
13319
+ ] });
13320
+ $[50] = t10;
13321
+ $[51] = t18;
13322
+ $[52] = t19;
13323
+ $[53] = t20;
13324
+ } else {
13325
+ t20 = $[53];
13326
+ }
13327
+ let t21;
13328
+ if ($[54] !== propertyKey || $[55] !== t20) {
13329
+ t21 = /* @__PURE__ */ jsx(PropertyIdCopyTooltip, { propertyKey, children: t20 });
13330
+ $[54] = propertyKey;
13331
+ $[55] = t20;
13332
+ $[56] = t21;
13333
+ } else {
13334
+ t21 = $[56];
13335
+ }
13336
+ let t22;
13337
+ if ($[57] !== disabled || $[58] !== includeDescription || $[59] !== property || $[60] !== resolvedError || $[61] !== shouldShowError) {
13338
+ t22 = /* @__PURE__ */ jsx(FieldHelperText, { includeDescription, showError: shouldShowError, error: resolvedError, disabled, property });
13339
+ $[57] = disabled;
13340
+ $[58] = includeDescription;
13341
+ $[59] = property;
13342
+ $[60] = resolvedError;
13343
+ $[61] = shouldShowError;
13344
+ $[62] = t22;
13345
+ } else {
13346
+ t22 = $[62];
13347
+ }
13348
+ let t23;
13349
+ if ($[63] !== t21 || $[64] !== t22) {
13350
+ t23 = /* @__PURE__ */ jsxs(Fragment, { children: [
13351
+ t21,
13352
+ t22
13353
+ ] });
13354
+ $[63] = t21;
13355
+ $[64] = t22;
13356
+ $[65] = t23;
13357
+ } else {
13358
+ t23 = $[65];
13359
+ }
13360
+ return t23;
13361
+ }
12975
13362
  function ReadOnlyFieldBinding(t0) {
12976
13363
  const $ = c(18);
12977
13364
  const {
@@ -13591,7 +13978,7 @@ function MapFieldBinding(t0) {
13591
13978
  } else {
13592
13979
  t42 = $[20];
13593
13980
  }
13594
- t3 = Object.entries(mapProperties).filter(_temp$o).map(t42);
13981
+ t3 = Object.entries(mapProperties).filter(_temp$p).map(t42);
13595
13982
  $[6] = autoFocus;
13596
13983
  $[7] = context;
13597
13984
  $[8] = disabled;
@@ -13670,7 +14057,7 @@ function MapFieldBinding(t0) {
13670
14057
  }
13671
14058
  return t10;
13672
14059
  }
13673
- function _temp$o(t0) {
14060
+ function _temp$p(t0) {
13674
14061
  const [, property_0] = t0;
13675
14062
  return !isHidden(property_0);
13676
14063
  }
@@ -15044,7 +15431,7 @@ function BlockEntry(t0) {
15044
15431
  const property = t4;
15045
15432
  let t5;
15046
15433
  if ($[9] !== properties) {
15047
- t5 = Object.entries(properties).map(_temp$n);
15434
+ t5 = Object.entries(properties).map(_temp$o);
15048
15435
  $[9] = properties;
15049
15436
  $[10] = t5;
15050
15437
  } else {
@@ -15137,7 +15524,7 @@ function BlockEntry(t0) {
15137
15524
  }
15138
15525
  return t11;
15139
15526
  }
15140
- function _temp$n(t0) {
15527
+ function _temp$o(t0) {
15141
15528
  const [key, property_0] = t0;
15142
15529
  return {
15143
15530
  id: key,
@@ -17258,24 +17645,27 @@ function buildIdColumn(largeLayout) {
17258
17645
  function propertiesToColumns({
17259
17646
  properties,
17260
17647
  sortable,
17261
- forceFilter,
17262
- AdditionalHeaderWidget
17648
+ forcedFilters,
17649
+ AdditionalHeaderWidget,
17650
+ allowedFilters
17263
17651
  }) {
17264
- const disabledFilter = Boolean(forceFilter);
17265
17652
  return Object.entries(properties).flatMap(([key, property]) => getColumnKeysForProperty(property, key)).map(({
17266
17653
  key,
17267
17654
  disabled
17268
17655
  }) => {
17269
17656
  const property = getResolvedPropertyInPath(properties, key);
17270
17657
  if (!property) throw Error("Internal error: no property found in path " + key);
17271
- const filterable = filterableProperty(property);
17658
+ const filterable = property.dataType === "array" ? isDataTypeFilterable(property.of?.dataType, true) : isDataTypeFilterable(property.dataType);
17659
+ const isFilterForced = forcedFilters?.includes(key) ?? false;
17660
+ const isFilterAllowed = allowedFilters ? allowedFilters.includes(key) : filterable;
17661
+ const filterEnabled = filterable && isFilterAllowed && !isFilterForced;
17272
17662
  return {
17273
17663
  key,
17274
17664
  align: getTableCellAlignment(property),
17275
17665
  icon: getIconForProperty(property, "small"),
17276
17666
  title: property.name ?? key,
17277
17667
  sortable,
17278
- filter: !disabledFilter && filterable,
17668
+ filter: filterEnabled,
17279
17669
  width: getTablePropertyColumnWidth(property),
17280
17670
  resizable: true,
17281
17671
  custom: {
@@ -17288,16 +17678,6 @@ function propertiesToColumns({
17288
17678
  };
17289
17679
  });
17290
17680
  }
17291
- function filterableProperty(property, partOfArray = false) {
17292
- if (partOfArray) {
17293
- return ["string", "number", "date", "reference"].includes(property.dataType);
17294
- }
17295
- if (property.dataType === "array") {
17296
- if (property.of) return filterableProperty(property.of, true);
17297
- else return false;
17298
- }
17299
- return ["string", "number", "boolean", "date", "reference", "array"].includes(property.dataType);
17300
- }
17301
17681
  const VirtualTableHeader = React__default.memo(function VirtualTableHeader2(t0) {
17302
17682
  const $ = c(61);
17303
17683
  const {
@@ -18129,7 +18509,7 @@ const VirtualTable = React__default.memo(function VirtualTable2({
18129
18509
  const currentSort = sortBy ? sortBy[1] : void 0;
18130
18510
  const [columns, setColumns] = useState(columnsProp);
18131
18511
  const tableRef = useRef(null);
18132
- const endReachCallbackThreshold = useRef(0);
18512
+ const lastEndReachedDataLength = useRef(void 0);
18133
18513
  const debouncedScroll = useDebounceCallback(onScrollProp, 200);
18134
18514
  const [draggingColumnId, setDraggingColumnId] = useState(null);
18135
18515
  const sensors = useSensors(useSensor(PointerSensor, {
@@ -18208,7 +18588,7 @@ const VirtualTable = React__default.memo(function VirtualTable2({
18208
18588
  filterRef.current = filterInput;
18209
18589
  }, [filterInput]);
18210
18590
  const scrollToTop = useCallback(() => {
18211
- endReachCallbackThreshold.current = 0;
18591
+ lastEndReachedDataLength.current = void 0;
18212
18592
  if (tableRef.current) {
18213
18593
  tableRef.current.scrollTo(tableRef.current?.scrollLeft, 0);
18214
18594
  }
@@ -18234,28 +18614,37 @@ const VirtualTable = React__default.memo(function VirtualTable2({
18234
18614
  scrollToTop();
18235
18615
  }, [checkFilterCombination, currentSort, onFilterUpdate, onResetPagination, onSortByUpdate, scrollToTop, sortByProperty]);
18236
18616
  const maxScroll = Math.max((data?.length ?? 0) * rowHeight - bounds.height, 0);
18237
- const onEndReachedInternal = useCallback((scrollOffset) => {
18238
- if (onEndReached && (data?.length ?? 0) > 0 && scrollOffset > endReachCallbackThreshold.current + endOffset) {
18239
- endReachCallbackThreshold.current = scrollOffset;
18617
+ const onEndReachedInternal = useCallback(() => {
18618
+ const dataLength = data?.length ?? 0;
18619
+ if (onEndReached && dataLength > 0 && lastEndReachedDataLength.current !== dataLength) {
18620
+ lastEndReachedDataLength.current = dataLength;
18240
18621
  onEndReached();
18241
18622
  }
18242
18623
  }, [data?.length, onEndReached]);
18624
+ useEffect(() => {
18625
+ if (!onEndReached || loading || !data?.length || !bounds.height || !tableRef.current) {
18626
+ return;
18627
+ }
18628
+ if (tableRef.current.scrollHeight <= tableRef.current.clientHeight) {
18629
+ onEndReachedInternal();
18630
+ }
18631
+ }, [bounds.height, data?.length, loading, onEndReached, onEndReachedInternal]);
18243
18632
  const onScroll = useCallback(({
18244
18633
  scrollDirection,
18245
- scrollOffset: scrollOffset_0,
18634
+ scrollOffset,
18246
18635
  scrollUpdateWasRequested
18247
18636
  }) => {
18248
18637
  if (onScrollProp) {
18249
18638
  debouncedScroll({
18250
18639
  scrollDirection,
18251
- scrollOffset: scrollOffset_0,
18640
+ scrollOffset,
18252
18641
  scrollUpdateWasRequested
18253
18642
  });
18254
18643
  }
18255
- if (!scrollUpdateWasRequested && scrollOffset_0 >= maxScroll - endOffset) onEndReachedInternal(scrollOffset_0);
18256
- }, [maxScroll, onEndReachedInternal]);
18644
+ if (!scrollUpdateWasRequested && scrollOffset >= maxScroll - endOffset) onEndReachedInternal();
18645
+ }, [endOffset, maxScroll, onEndReachedInternal]);
18257
18646
  const onFilterUpdateInternal = useCallback((column_1, filterForProperty) => {
18258
- endReachCallbackThreshold.current = 0;
18647
+ lastEndReachedDataLength.current = void 0;
18259
18648
  const filter_0 = filterRef.current;
18260
18649
  let newFilterValue = filter_0 ? {
18261
18650
  ...filter_0
@@ -18457,7 +18846,7 @@ const SafeLinkRenderer = (t0) => {
18457
18846
  let t1;
18458
18847
  if ($[0] !== text) {
18459
18848
  const urlRegex = /https?:\/\/[^\s]+/g;
18460
- t1 = text.replace(urlRegex, _temp$m);
18849
+ t1 = text.replace(urlRegex, _temp$n);
18461
18850
  $[0] = text;
18462
18851
  $[1] = t1;
18463
18852
  } else {
@@ -18476,7 +18865,7 @@ const SafeLinkRenderer = (t0) => {
18476
18865
  }
18477
18866
  return t2;
18478
18867
  };
18479
- function _temp$m(url) {
18868
+ function _temp$n(url) {
18480
18869
  return `<a href="${url}" class="underline" target="_blank">Link</a><br/>`;
18481
18870
  }
18482
18871
  const operationLabels$2 = {
@@ -18550,10 +18939,10 @@ function ReferenceFilterField({
18550
18939
  return path ? navigationController.getCollection(path) : void 0;
18551
18940
  }, [path]);
18552
18941
  const onSingleEntitySelected = (entity) => {
18553
- updateFilter(operation, getReferenceFrom(entity));
18942
+ if (entity) updateFilter(operation, getReferenceFrom(entity));
18554
18943
  };
18555
18944
  const onMultipleEntitiesSelected = (entities) => {
18556
- updateFilter(operation, entities.map((e) => getReferenceFrom(e)));
18945
+ updateFilter(operation, entities.filter(Boolean).map((e) => getReferenceFrom(e)));
18557
18946
  };
18558
18947
  const multiple = multipleSelectOperations$2.includes(operation);
18559
18948
  const referenceDialogController = useReferenceDialog({
@@ -18728,7 +19117,7 @@ function StringNumberFilterField(t0) {
18728
19117
  }
18729
19118
  let t8;
18730
19119
  if ($[20] !== operation || $[21] !== t6 || $[22] !== t7) {
18731
- t8 = /* @__PURE__ */ jsx("div", { className: "w-[100px]", children: /* @__PURE__ */ jsx(Select, { value: operation, size: "medium", fullWidth: true, position: "item-aligned", onValueChange: t6, renderValue: _temp$l, children: t7 }) });
19120
+ t8 = /* @__PURE__ */ jsx("div", { className: "w-[100px]", children: /* @__PURE__ */ jsx(Select, { value: operation, size: "medium", fullWidth: true, position: "item-aligned", onValueChange: t6, renderValue: _temp$m, children: t7 }) });
18732
19121
  $[20] = operation;
18733
19122
  $[21] = t6;
18734
19123
  $[22] = t7;
@@ -18782,7 +19171,7 @@ function StringNumberFilterField(t0) {
18782
19171
  let t11;
18783
19172
  if ($[40] !== dataType || $[41] !== enumValues || $[42] !== internalValue || $[43] !== isNullOperation || $[44] !== multiple || $[45] !== name || $[46] !== operation || $[47] !== updateFilter) {
18784
19173
  t11 = enumValues && multiple && /* @__PURE__ */ jsx(MultiSelect, { size: "medium", position: "item-aligned", value: Array.isArray(internalValue) ? internalValue.map(_temp3$3) : [], disabled: isNullOperation, onValueChange: (value_2) => {
18785
- updateFilter(operation, dataType === "number" ? value_2.map(_temp4$2) : value_2);
19174
+ updateFilter(operation, dataType === "number" ? value_2.map(_temp4$3) : value_2);
18786
19175
  }, multiple, endAdornment: internalValue && /* @__PURE__ */ jsx(IconButton, { className: "absolute right-2 top-3", onClick: (e_2) => updateFilter(operation, void 0), children: /* @__PURE__ */ jsx(CloseIcon, {}) }), children: enumValues.map((enumConfig_0) => /* @__PURE__ */ jsx(MultiSelectItem, { value: String(enumConfig_0.id), children: /* @__PURE__ */ jsx(EnumValuesChip, { enumKey: String(enumConfig_0.id), enumValues, size: "small" }) }, `select_value_${name}_${enumConfig_0.id}`)) });
18787
19176
  $[40] = dataType;
18788
19177
  $[41] = enumValues;
@@ -18824,7 +19213,7 @@ function StringNumberFilterField(t0) {
18824
19213
  }
18825
19214
  return t13;
18826
19215
  }
18827
- function _temp4$2(v) {
19216
+ function _temp4$3(v) {
18828
19217
  return parseInt(v);
18829
19218
  }
18830
19219
  function _temp3$3(e_1) {
@@ -18833,7 +19222,7 @@ function _temp3$3(e_1) {
18833
19222
  function _temp2$6(op_2) {
18834
19223
  return /* @__PURE__ */ jsx(SelectItem, { value: op_2, children: operationLabels$1[op_2] }, op_2);
18835
19224
  }
18836
- function _temp$l(op_1) {
19225
+ function _temp$m(op_1) {
18837
19226
  return operationLabels$1[op_1];
18838
19227
  }
18839
19228
  function BooleanFilterField(t0) {
@@ -19004,7 +19393,7 @@ function DateTimeFilterField(t0) {
19004
19393
  }
19005
19394
  let t8;
19006
19395
  if ($[17] !== operation || $[18] !== t6 || $[19] !== t7) {
19007
- t8 = /* @__PURE__ */ jsx("div", { className: "w-[100px]", children: /* @__PURE__ */ jsx(Select, { value: operation, size: "medium", fullWidth: true, onValueChange: t6, renderValue: _temp$k, children: t7 }) });
19396
+ t8 = /* @__PURE__ */ jsx("div", { className: "w-[100px]", children: /* @__PURE__ */ jsx(Select, { value: operation, size: "medium", fullWidth: true, onValueChange: t6, renderValue: _temp$l, children: t7 }) });
19008
19397
  $[17] = operation;
19009
19398
  $[18] = t6;
19010
19399
  $[19] = t7;
@@ -19054,7 +19443,7 @@ function DateTimeFilterField(t0) {
19054
19443
  function _temp2$5(op_2) {
19055
19444
  return /* @__PURE__ */ jsx(SelectItem, { value: op_2, children: operationLabels[op_2] }, op_2);
19056
19445
  }
19057
- function _temp$k(op_1) {
19446
+ function _temp$l(op_1) {
19058
19447
  return operationLabels[op_1];
19059
19448
  }
19060
19449
  const SelectableTable = function SelectableTable2({
@@ -19304,7 +19693,8 @@ const EntityCollectionTable = function EntityCollectionTable2({
19304
19693
  const columnsResult = propertiesToColumns({
19305
19694
  properties,
19306
19695
  sortable,
19307
- forceFilter,
19696
+ forcedFilters: tableController.forcedFilters,
19697
+ allowedFilters: tableController.allowedFilters,
19308
19698
  AdditionalHeaderWidget
19309
19699
  });
19310
19700
  const propertyColumnKeys = new Set(columnsResult.map((col) => col.key));
@@ -19451,7 +19841,26 @@ function useDataSourceTableController({
19451
19841
  filterValues: initialFilterUrl,
19452
19842
  sortBy: initialSortUrl
19453
19843
  } = parseFilterAndSort(location.search);
19454
- const [filterValues_0, setFilterValues] = React__default.useState(forceFilter ?? (updateUrl ? initialFilterUrl : void 0) ?? initialFilter ?? void 0);
19844
+ const availableFilterKeys = collection.allowedFilters ?? Object.keys(collection.properties);
19845
+ const forcedFilterKeys = collection.forceFilter ? Object.keys(collection.forceFilter) : [];
19846
+ const allowedFilterKeys = useMemo(() => {
19847
+ const availableKeys = availableFilterKeys.filter((key) => {
19848
+ const property = collection.properties[key];
19849
+ if (!property) return false;
19850
+ if (typeof property === "function") return false;
19851
+ const dataType = property.dataType;
19852
+ const filterable = dataType === "array" ? isDataTypeFilterable(property.of?.dataType, true) : isDataTypeFilterable(dataType);
19853
+ return filterable;
19854
+ });
19855
+ const forcedKeys = forcedFilterKeys.filter((key_0) => !availableKeys.includes(key_0));
19856
+ return [...availableKeys, ...forcedKeys];
19857
+ }, [collection.properties, availableFilterKeys, forcedFilterKeys]);
19858
+ const removeUnallowedFilters = useCallback((filters) => {
19859
+ if (!filters) return;
19860
+ return Object.fromEntries(Object.entries(filters).filter(([key_1]) => allowedFilterKeys.includes(key_1)));
19861
+ }, [allowedFilterKeys]);
19862
+ const initFilters = forceFilter ?? (updateUrl ? initialFilterUrl : void 0) ?? initialFilter ?? void 0;
19863
+ const [filterValues_0, setFilterValues] = React__default.useState(removeUnallowedFilters(initFilters));
19455
19864
  const [sortBy_0, setSortBy] = React__default.useState((updateUrl ? initialSortUrl : void 0) ?? initialSortInternal);
19456
19865
  useUpdateUrl(filterValues_0, sortBy_0, searchString, updateUrl);
19457
19866
  const collectionScroll = scrollRestoration?.getCollectionScroll(fullPath, filterValues_0);
@@ -19474,7 +19883,7 @@ function useDataSourceTableController({
19474
19883
  const [dataLoading, setDataLoading] = useState(false);
19475
19884
  const [dataLoadingError, setDataLoadingError] = useState();
19476
19885
  const [noMoreToLoad, setNoMoreToLoad] = useState(false);
19477
- const clearFilter = useCallback(() => setFilterValues(forceFilter ?? void 0), [forceFilter]);
19886
+ const clearFilter = useCallback(() => setFilterValues(removeUnallowedFilters(forceFilter)), [forceFilter, removeUnallowedFilters]);
19478
19887
  const updateFilterValues = useCallback((updatedFilter) => {
19479
19888
  if (forceFilter) {
19480
19889
  console.warn("Filter is not compatible with the force filter. Ignoring filter");
@@ -19483,9 +19892,9 @@ function useDataSourceTableController({
19483
19892
  if (updatedFilter && Object.keys(updatedFilter).length === 0) {
19484
19893
  setFilterValues(void 0);
19485
19894
  } else {
19486
- setFilterValues(updatedFilter);
19895
+ setFilterValues(removeUnallowedFilters(updatedFilter));
19487
19896
  }
19488
- }, [forceFilter]);
19897
+ }, [forceFilter, removeUnallowedFilters]);
19489
19898
  useEffect(() => {
19490
19899
  setDataLoading(true);
19491
19900
  const onEntitiesUpdate = async (entities) => {
@@ -19560,6 +19969,8 @@ function useDataSourceTableController({
19560
19969
  dataLoadingError,
19561
19970
  filterValues: filterValues_0,
19562
19971
  setFilterValues: updateFilterValues,
19972
+ allowedFilters: allowedFilterKeys,
19973
+ forcedFilters: forcedFilterKeys,
19563
19974
  sortBy: sortBy_0,
19564
19975
  setSortBy,
19565
19976
  searchString,
@@ -19640,7 +20051,7 @@ function encodeFilterAndSort(filterValues, sortBy) {
19640
20051
  }
19641
20052
  if (encodedValue !== void 0) {
19642
20053
  entries[encodeURIComponent(`${key}_op`)] = encodeURIComponent(op);
19643
- entries[encodeURIComponent(`${key}_value`)] = encodedValue ? encodeURIComponent(encodedValue.toString()) : "null";
20054
+ entries[encodeURIComponent(`${key}_value`)] = encodedValue !== null && encodedValue !== void 0 ? encodeURIComponent(encodedValue.toString()) : "null";
19644
20055
  }
19645
20056
  }
19646
20057
  });
@@ -19680,7 +20091,12 @@ function isDate(dateString) {
19680
20091
  return date.toISOString() === dateString;
19681
20092
  }
19682
20093
  function encodeRef(val) {
19683
- return `ref::${val.path}/${val.id}`;
20094
+ return `ref::${val.path}/${encodeEntityId(val.id)}`;
20095
+ }
20096
+ function decodeRef(encoded) {
20097
+ const separatorIndex = encoded.lastIndexOf("/");
20098
+ if (separatorIndex < 0) return new EntityReference(encoded, "");
20099
+ return new EntityReference(decodeEntityId(encoded.substring(separatorIndex + 1)), encoded.substring(0, separatorIndex));
19684
20100
  }
19685
20101
  function decodeString(val) {
19686
20102
  let parsedFilterVal = val;
@@ -19694,8 +20110,7 @@ function decodeString(val) {
19694
20110
  try {
19695
20111
  parsedFilterVal = JSON.parse(parsedFilterVal, (key, value) => {
19696
20112
  if (typeof value === "string" && value.startsWith("ref::")) {
19697
- const [path, id] = value.substring(5).split("/");
19698
- return new EntityReference(id, path);
20113
+ return decodeRef(value.substring(5));
19699
20114
  }
19700
20115
  return value;
19701
20116
  });
@@ -19703,8 +20118,7 @@ function decodeString(val) {
19703
20118
  }
19704
20119
  }
19705
20120
  if (typeof parsedFilterVal === "string" && parsedFilterVal.startsWith("ref::")) {
19706
- const [path, id] = parsedFilterVal.substring(5).split("/");
19707
- return new EntityReference(id, path);
20121
+ return decodeRef(parsedFilterVal.substring(5));
19708
20122
  }
19709
20123
  return parsedFilterVal;
19710
20124
  }
@@ -19783,7 +20197,7 @@ function useTableSearchHelper(t0) {
19783
20197
  const searchBlocked = t12;
19784
20198
  let t2;
19785
20199
  if ($[15] !== customizationController.plugins || $[16] !== dataSource?.initTextSearch) {
19786
- t2 = Boolean(dataSource?.initTextSearch) || customizationController.plugins?.find(_temp$j);
20200
+ t2 = Boolean(dataSource?.initTextSearch) || customizationController.plugins?.find(_temp$k);
19787
20201
  $[15] = customizationController.plugins;
19788
20202
  $[16] = dataSource?.initTextSearch;
19789
20203
  $[17] = t2;
@@ -19875,7 +20289,7 @@ function useTableSearchHelper(t0) {
19875
20289
  }
19876
20290
  return t1;
19877
20291
  }
19878
- function _temp$j(p_0) {
20292
+ function _temp$k(p_0) {
19879
20293
  return Boolean(p_0.collectionView?.onTextSearchClick);
19880
20294
  }
19881
20295
  function DeleteEntityDialog({
@@ -20497,7 +20911,7 @@ function FavouritesView(t0) {
20497
20911
  T0 = Collapse;
20498
20912
  t4 = favouriteCollections.length > 0;
20499
20913
  t2 = "flex flex-row flex-wrap gap-2 pb-2 min-h-[32px]";
20500
- t3 = favouriteCollections.map(_temp$i);
20914
+ t3 = favouriteCollections.map(_temp$j);
20501
20915
  $[2] = navigationController;
20502
20916
  $[3] = t1;
20503
20917
  $[4] = T0;
@@ -20531,7 +20945,7 @@ function FavouritesView(t0) {
20531
20945
  }
20532
20946
  return t6;
20533
20947
  }
20534
- function _temp$i(entry_0) {
20948
+ function _temp$j(entry_0) {
20535
20949
  return /* @__PURE__ */ jsx(NavigationChip, { entry: entry_0 }, entry_0.path);
20536
20950
  }
20537
20951
  const scrollsMap = {};
@@ -20768,7 +21182,7 @@ const NavigationCard = React__default.memo(function NavigationCard2(t0) {
20768
21182
  }
20769
21183
  let t4;
20770
21184
  if ($[4] !== actions) {
20771
- t4 = /* @__PURE__ */ jsx("div", { className: "flex items-center gap-0.5", onClick: _temp$h, children: actions });
21185
+ t4 = /* @__PURE__ */ jsx("div", { className: "flex items-center gap-0.5", onClick: _temp$i, children: actions });
20772
21186
  $[4] = actions;
20773
21187
  $[5] = t4;
20774
21188
  } else {
@@ -20855,7 +21269,7 @@ const NavigationCard = React__default.memo(function NavigationCard2(t0) {
20855
21269
  }
20856
21270
  return t12;
20857
21271
  });
20858
- function _temp$h(event) {
21272
+ function _temp$i(event) {
20859
21273
  event.preventDefault();
20860
21274
  event.stopPropagation();
20861
21275
  }
@@ -23211,7 +23625,7 @@ const BoardColumn = memo(function BoardColumn2(t0) {
23211
23625
  let t19;
23212
23626
  let t20;
23213
23627
  if ($[19] !== items2) {
23214
- t20 = items2.map(_temp$g);
23628
+ t20 = items2.map(_temp$h);
23215
23629
  $[19] = items2;
23216
23630
  $[20] = t20;
23217
23631
  } else {
@@ -23317,7 +23731,7 @@ const BoardColumn = memo(function BoardColumn2(t0) {
23317
23731
  }
23318
23732
  return t29;
23319
23733
  });
23320
- function _temp$g(i) {
23734
+ function _temp$h(i) {
23321
23735
  return i.id;
23322
23736
  }
23323
23737
  function Board(t0) {
@@ -25253,7 +25667,8 @@ function FiltersDialog({
25253
25667
  properties,
25254
25668
  filterValues,
25255
25669
  setFilterValues,
25256
- forceFilter
25670
+ forceFilter,
25671
+ allowedFilters
25257
25672
  }) {
25258
25673
  const {
25259
25674
  t
@@ -25265,15 +25680,14 @@ function FiltersDialog({
25265
25680
  setLocalFilters(filterValues ?? {});
25266
25681
  }
25267
25682
  }, [open, filterValues]);
25268
- const filterableProperties = useMemo(() => {
25269
- return Object.entries(properties).filter(([key, property]) => {
25270
- if (!property) return false;
25271
- if (forceFilter && key in forceFilter) return false;
25272
- const baseProperty = property.dataType === "array" ? property.of : property;
25273
- if (!baseProperty) return false;
25274
- return ["string", "number", "boolean", "date", "reference"].includes(baseProperty.dataType);
25683
+ const editableFilterProperties = useMemo(() => {
25684
+ return Object.entries(properties).filter(([key]) => {
25685
+ const isFilterAllowed = !allowedFilters || allowedFilters.includes(key);
25686
+ const isFilterForced = Boolean(forceFilter && Object.keys(forceFilter).includes(key));
25687
+ return isFilterAllowed && !isFilterForced;
25275
25688
  });
25276
- }, [properties, forceFilter]);
25689
+ }, [properties, allowedFilters, forceFilter]);
25690
+ const hasEditableFilterProperties = editableFilterProperties.length > 0;
25277
25691
  const handleFilterChange = useCallback((propertyKey, value) => {
25278
25692
  setLocalFilters((prev) => {
25279
25693
  const newFilters = {
@@ -25305,22 +25719,26 @@ function FiltersDialog({
25305
25719
  }));
25306
25720
  }, []);
25307
25721
  const isAnyFieldHidden = Object.values(hiddenFields).some((hidden_0) => hidden_0);
25308
- const activeFilterCount = Object.keys(localFilters).length;
25309
- const renderFilterField = useCallback((propertyKey_1, property_0) => {
25310
- const isArray = property_0.dataType === "array";
25311
- const baseProperty_0 = isArray ? property_0.of : property_0;
25312
- if (!baseProperty_0) return null;
25722
+ const getActiveFilterCount = () => {
25723
+ const editableLocalFilters = Object.keys(localFilters).filter((key_0) => !forceFilter || !(key_0 in forceFilter));
25724
+ return editableLocalFilters.length;
25725
+ };
25726
+ const activeFilterCount = getActiveFilterCount();
25727
+ const renderFilterField = useCallback((propertyKey_1, property) => {
25728
+ const isArray = property.dataType === "array";
25729
+ const baseProperty = isArray ? property.of : property;
25730
+ if (!baseProperty) return null;
25313
25731
  const filterValue = localFilters[propertyKey_1];
25314
25732
  const setValue = (value_0) => handleFilterChange(propertyKey_1, value_0);
25315
- if (baseProperty_0.dataType === "reference") {
25316
- return /* @__PURE__ */ 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) });
25317
- } else if (baseProperty_0.dataType === "number" || baseProperty_0.dataType === "string") {
25318
- const enumValues = baseProperty_0.enumValues ? enumToObjectEntries(baseProperty_0.enumValues) : void 0;
25319
- return /* @__PURE__ */ jsx(StringNumberFilterField, { value: filterValue, setValue, name: propertyKey_1, dataType: baseProperty_0.dataType, isArray, enumValues, title: property_0.name });
25320
- } else if (baseProperty_0.dataType === "boolean") {
25321
- return /* @__PURE__ */ jsx(BooleanFilterField, { value: filterValue, setValue, name: propertyKey_1, title: property_0.name });
25322
- } else if (baseProperty_0.dataType === "date") {
25323
- return /* @__PURE__ */ jsx(DateTimeFilterField, { value: filterValue, setValue, name: propertyKey_1, mode: baseProperty_0.mode, isArray, title: property_0.name });
25733
+ if (baseProperty.dataType === "reference") {
25734
+ return /* @__PURE__ */ 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) });
25735
+ } else if (baseProperty.dataType === "number" || baseProperty.dataType === "string") {
25736
+ const enumValues = baseProperty.enumValues ? enumToObjectEntries(baseProperty.enumValues) : void 0;
25737
+ return /* @__PURE__ */ jsx(StringNumberFilterField, { value: filterValue, setValue, name: propertyKey_1, dataType: baseProperty.dataType, isArray, enumValues, title: property.name });
25738
+ } else if (baseProperty.dataType === "boolean") {
25739
+ return /* @__PURE__ */ jsx(BooleanFilterField, { value: filterValue, setValue, name: propertyKey_1, title: property.name });
25740
+ } else if (baseProperty.dataType === "date") {
25741
+ return /* @__PURE__ */ jsx(DateTimeFilterField, { value: filterValue, setValue, name: propertyKey_1, mode: baseProperty.mode, isArray, title: property.name });
25324
25742
  }
25325
25743
  return null;
25326
25744
  }, [localFilters, handleFilterChange, hiddenFields, setHiddenForField]);
@@ -25329,23 +25747,25 @@ function FiltersDialog({
25329
25747
  /* @__PURE__ */ jsx(Typography, { variant: "h6", children: t("filters") }),
25330
25748
  activeFilterCount > 0 && /* @__PURE__ */ jsx("span", { className: "ml-2 px-2 py-0.5 text-xs rounded-full bg-primary text-white", children: activeFilterCount })
25331
25749
  ] }),
25332
- /* @__PURE__ */ jsx(DialogContent, { children: filterableProperties.length === 0 ? /* @__PURE__ */ jsx(Typography, { color: "secondary", className: "py-8 text-center", children: t("no_filterable_properties") }) : /* @__PURE__ */ jsx("table", { className: "w-full border-collapse", children: /* @__PURE__ */ jsx("tbody", { children: filterableProperties.map(([propertyKey_2, property_1], index) => {
25750
+ /* @__PURE__ */ jsx(DialogContent, { children: !hasEditableFilterProperties ? /* @__PURE__ */ jsx(Typography, { color: "secondary", className: "py-8 text-center", children: t("no_filterable_properties") }) : /* @__PURE__ */ jsx("table", { className: "w-full border-collapse", children: /* @__PURE__ */ jsx("tbody", { children: editableFilterProperties.map(([propertyKey_2, property_0], index) => {
25333
25751
  const hasFilter = propertyKey_2 in localFilters;
25334
25752
  return /* @__PURE__ */ jsxs("tr", { className: cls(index > 0 && "border-t", defaultBorderMixin), children: [
25335
- /* @__PURE__ */ jsx("td", { className: "py-3 pr-4 align-middle w-[160px]", children: /* @__PURE__ */ jsx(Typography, { variant: "body2", className: cls("font-medium", hasFilter && "text-primary"), children: property_1.name || propertyKey_2 }) }),
25336
- /* @__PURE__ */ jsx("td", { className: "py-3", children: renderFilterField(propertyKey_2, property_1) })
25753
+ /* @__PURE__ */ jsx("td", { className: "py-3 pr-4 align-middle w-[160px]", children: /* @__PURE__ */ jsx(Typography, { variant: "body2", className: cls("font-medium", hasFilter && "text-primary"), children: property_0.name || propertyKey_2 }) }),
25754
+ /* @__PURE__ */ jsx("td", { className: "py-3", children: renderFilterField(propertyKey_2, property_0) })
25337
25755
  ] }, propertyKey_2);
25338
25756
  }) }) }) }),
25339
25757
  /* @__PURE__ */ jsxs(DialogActions, { children: [
25340
25758
  /* @__PURE__ */ jsx(Button, { variant: "text", onClick: handleClearAll, disabled: activeFilterCount === 0, children: t("clear") }),
25341
25759
  /* @__PURE__ */ jsx("div", { className: "flex-grow" }),
25342
- /* @__PURE__ */ jsx(Button, { variant: "text", onClick: () => onOpenChange(false), children: t("cancel") }),
25343
- /* @__PURE__ */ jsx(Button, { variant: "filled", onClick: handleApply, children: t("apply_filters") })
25760
+ hasEditableFilterProperties && /* @__PURE__ */ jsxs(Fragment, { children: [
25761
+ /* @__PURE__ */ jsx(Button, { variant: "text", onClick: () => onOpenChange(false), children: t("cancel") }),
25762
+ /* @__PURE__ */ jsx(Button, { variant: "filled", onClick: handleApply, children: t("apply_filters") })
25763
+ ] })
25344
25764
  ] })
25345
25765
  ] });
25346
25766
  }
25347
25767
  function EntityCollectionViewStartActions(t0) {
25348
- const $ = c(36);
25768
+ const $ = c(37);
25349
25769
  const {
25350
25770
  collection,
25351
25771
  relativePath,
@@ -25409,34 +25829,36 @@ function EntityCollectionViewStartActions(t0) {
25409
25829
  t3 = $[13];
25410
25830
  }
25411
25831
  const actionProps = t3;
25832
+ const hasAnyAllowedFilters = !tableController.allowedFilters || tableController.allowedFilters.length > 0;
25412
25833
  let t4;
25413
- if ($[14] !== activeFilterCount || $[15] !== largeLayout || $[16] !== resolvedProperties || $[17] !== t || $[18] !== tableController.setFilterValues) {
25414
- t4 = resolvedProperties && tableController.setFilterValues && /* @__PURE__ */ jsx(Tooltip, { title: t("filters"), children: /* @__PURE__ */ jsx(Badge, { color: "primary", invisible: activeFilterCount === 0, children: largeLayout ? /* @__PURE__ */ jsxs(Button, { variant: "text", size: "small", onClick: () => setFiltersDialogOpen(true), startIcon: /* @__PURE__ */ jsx(FilterListIcon, { size: "small" }), className: cls(activeFilterCount > 0 && "text-primary"), children: [
25834
+ if ($[14] !== activeFilterCount || $[15] !== hasAnyAllowedFilters || $[16] !== largeLayout || $[17] !== resolvedProperties || $[18] !== t || $[19] !== tableController.setFilterValues) {
25835
+ t4 = resolvedProperties && tableController.setFilterValues && hasAnyAllowedFilters && /* @__PURE__ */ jsx(Tooltip, { title: t("filters"), children: /* @__PURE__ */ jsx(Badge, { color: "primary", invisible: activeFilterCount === 0, children: largeLayout ? /* @__PURE__ */ jsxs(Button, { variant: "text", size: "small", onClick: () => setFiltersDialogOpen(true), startIcon: /* @__PURE__ */ jsx(FilterListIcon, { size: "small" }), className: cls(activeFilterCount > 0 && "text-primary"), children: [
25415
25836
  t("filters"),
25416
25837
  activeFilterCount > 0 ? ` (${activeFilterCount})` : ""
25417
25838
  ] }) : /* @__PURE__ */ jsx(IconButton, { size: "small", onClick: () => setFiltersDialogOpen(true), className: cls(activeFilterCount > 0 && "text-primary"), children: /* @__PURE__ */ jsx(FilterListIcon, { size: "small" }) }) }) }, "filters_tooltip");
25418
25839
  $[14] = activeFilterCount;
25419
- $[15] = largeLayout;
25420
- $[16] = resolvedProperties;
25421
- $[17] = t;
25422
- $[18] = tableController.setFilterValues;
25423
- $[19] = t4;
25840
+ $[15] = hasAnyAllowedFilters;
25841
+ $[16] = largeLayout;
25842
+ $[17] = resolvedProperties;
25843
+ $[18] = t;
25844
+ $[19] = tableController.setFilterValues;
25845
+ $[20] = t4;
25424
25846
  } else {
25425
- t4 = $[19];
25847
+ t4 = $[20];
25426
25848
  }
25427
25849
  const filtersButton = t4;
25428
25850
  const t5 = !collection.forceFilter;
25429
25851
  let t6;
25430
- if ($[20] !== t5 || $[21] !== tableController) {
25852
+ if ($[21] !== t5 || $[22] !== tableController) {
25431
25853
  t6 = /* @__PURE__ */ jsx(ClearFilterSortButton, { tableController, enabled: t5 }, "clear_filter");
25432
- $[20] = t5;
25433
- $[21] = tableController;
25434
- $[22] = t6;
25854
+ $[21] = t5;
25855
+ $[22] = tableController;
25856
+ $[23] = t6;
25435
25857
  } else {
25436
- t6 = $[22];
25858
+ t6 = $[23];
25437
25859
  }
25438
25860
  let actions;
25439
- if ($[23] !== actionProps || $[24] !== filtersButton || $[25] !== plugins || $[26] !== t6) {
25861
+ if ($[24] !== actionProps || $[25] !== filtersButton || $[26] !== plugins || $[27] !== t6) {
25440
25862
  actions = [filtersButton, t6];
25441
25863
  if (plugins) {
25442
25864
  plugins.forEach((plugin, i) => {
@@ -25445,39 +25867,42 @@ function EntityCollectionViewStartActions(t0) {
25445
25867
  }
25446
25868
  });
25447
25869
  }
25448
- $[23] = actionProps;
25449
- $[24] = filtersButton;
25450
- $[25] = plugins;
25451
- $[26] = t6;
25452
- $[27] = actions;
25870
+ $[24] = actionProps;
25871
+ $[25] = filtersButton;
25872
+ $[26] = plugins;
25873
+ $[27] = t6;
25874
+ $[28] = actions;
25453
25875
  } else {
25454
- actions = $[27];
25876
+ actions = $[28];
25455
25877
  }
25456
25878
  let t7;
25457
- if ($[28] !== collection.forceFilter || $[29] !== filtersDialogOpen || $[30] !== resolvedProperties || $[31] !== tableController) {
25458
- t7 = resolvedProperties && tableController.setFilterValues && /* @__PURE__ */ jsx(FiltersDialog, { open: filtersDialogOpen, onOpenChange: setFiltersDialogOpen, properties: resolvedProperties, filterValues: tableController.filterValues, setFilterValues: (filterValues_0) => tableController.setFilterValues?.(filterValues_0 ?? {}), forceFilter: collection.forceFilter });
25459
- $[28] = collection.forceFilter;
25460
- $[29] = filtersDialogOpen;
25461
- $[30] = resolvedProperties;
25462
- $[31] = tableController;
25463
- $[32] = t7;
25879
+ if ($[29] !== collection.forceFilter || $[30] !== filtersDialogOpen || $[31] !== resolvedProperties || $[32] !== tableController) {
25880
+ t7 = resolvedProperties && tableController.setFilterValues && /* @__PURE__ */ jsx(FiltersDialog, { open: filtersDialogOpen, onOpenChange: setFiltersDialogOpen, properties: resolvedProperties, filterValues: tableController.filterValues, setFilterValues: (filterValues_0) => tableController.setFilterValues?.(filterValues_0 ?? {}), forceFilter: collection.forceFilter, allowedFilters: tableController.allowedFilters?.map(_temp$g) });
25881
+ $[29] = collection.forceFilter;
25882
+ $[30] = filtersDialogOpen;
25883
+ $[31] = resolvedProperties;
25884
+ $[32] = tableController;
25885
+ $[33] = t7;
25464
25886
  } else {
25465
- t7 = $[32];
25887
+ t7 = $[33];
25466
25888
  }
25467
25889
  let t8;
25468
- if ($[33] !== actions || $[34] !== t7) {
25890
+ if ($[34] !== actions || $[35] !== t7) {
25469
25891
  t8 = /* @__PURE__ */ jsxs(Fragment, { children: [
25470
25892
  actions,
25471
25893
  t7
25472
25894
  ] });
25473
- $[33] = actions;
25474
- $[34] = t7;
25475
- $[35] = t8;
25895
+ $[34] = actions;
25896
+ $[35] = t7;
25897
+ $[36] = t8;
25476
25898
  } else {
25477
- t8 = $[35];
25899
+ t8 = $[36];
25478
25900
  }
25479
25901
  return t8;
25480
25902
  }
25903
+ function _temp$g(key_0) {
25904
+ return key_0.toString();
25905
+ }
25481
25906
  const collectionScrollCache = /* @__PURE__ */ new Map();
25482
25907
  function useScrollRestoration() {
25483
25908
  const updateCollectionScroll = ({
@@ -25536,7 +25961,12 @@ const EntityCollectionView$1 = React__default.memo(function EntityCollectionView
25536
25961
  const scrollRestoration = useScrollRestoration();
25537
25962
  const collection = useMemo(() => {
25538
25963
  const userOverride = userConfigPersistence?.getCollectionConfig(fullPath);
25539
- return userOverride ? mergeDeep(collectionProp, userOverride) : collectionProp;
25964
+ if (!userOverride) return collectionProp;
25965
+ const {
25966
+ properties,
25967
+ ...rest
25968
+ } = userOverride;
25969
+ return mergeDeep(collectionProp, rest);
25540
25970
  }, [collectionProp, fullPath, userConfigPersistence?.getCollectionConfig]);
25541
25971
  const openEntityMode = collection?.openEntityMode ?? DEFAULT_ENTITY_OPEN_MODE;
25542
25972
  const collectionRef = React__default.useRef(collection);
@@ -25790,11 +26220,12 @@ const EntityCollectionView$1 = React__default.memo(function EntityCollectionView
25790
26220
  collection,
25791
26221
  path: fullPath,
25792
26222
  propertyConfigs: customizationController.propertyConfigs,
25793
- authController
25794
- }), [collection, fullPath]);
26223
+ authController,
26224
+ userConfigPersistence
26225
+ }), [collection, fullPath, userConfigPersistence]);
25795
26226
  const hasEnumProperty = useMemo(() => {
25796
- const properties = resolvedCollection.properties;
25797
- return Object.values(properties).some((prop) => prop && prop.dataType === "string" && prop.enumValues);
26227
+ const properties_0 = resolvedCollection.properties;
26228
+ return Object.values(properties_0).some((prop) => prop && prop.dataType === "string" && prop.enumValues);
25798
26229
  }, [resolvedCollection.properties]);
25799
26230
  const enabledViews = useMemo(() => {
25800
26231
  const configured = collection.enabledViews ?? ["table", "cards", "kanban"];
@@ -25805,8 +26236,8 @@ const EntityCollectionView$1 = React__default.memo(function EntityCollectionView
25805
26236
  }, [collection.enabledViews, hasEnumProperty]);
25806
26237
  const kanbanPropertyOptions = useMemo(() => {
25807
26238
  const options = [];
25808
- const properties_0 = resolvedCollection.properties;
25809
- for (const [key_0, property_0] of Object.entries(properties_0)) {
26239
+ const properties_1 = resolvedCollection.properties;
26240
+ for (const [key_0, property_0] of Object.entries(properties_1)) {
25810
26241
  const prop_0 = property_0;
25811
26242
  if (prop_0 && prop_0.dataType === "string" && prop_0.enumValues) {
25812
26243
  options.push({
@@ -27169,7 +27600,7 @@ function ReferenceWidget({
27169
27600
  const onMultipleEntitiesSelected = useCallback((entities) => {
27170
27601
  if (disabled) return;
27171
27602
  if (onMultipleReferenceSelected) {
27172
- const references = entities ? entities.map((e) => getReferenceFrom(e)) : null;
27603
+ const references = entities ? entities.filter(Boolean).map((e) => getReferenceFrom(e)) : null;
27173
27604
  onMultipleReferenceSelected({
27174
27605
  references,
27175
27606
  entities
@@ -27878,7 +28309,7 @@ function getParentReferencesFromPath(props) {
27878
28309
  const restOfThePath = removeInitialAndTrailingSlashes(removeInitialAndTrailingSlashes(path).replace(subpathCombination, ""));
27879
28310
  const nextSegments = restOfThePath.length > 0 ? restOfThePath.split("/") : [];
27880
28311
  if (nextSegments.length > 0) {
27881
- const entityId = nextSegments[0];
28312
+ const entityId = decodeEntityId(nextSegments[0]);
27882
28313
  const fullPath = collectionPath + "/" + entityId;
27883
28314
  result.push(new EntityReference(entityId, collectionPath));
27884
28315
  if (nextSegments.length > 1) {
@@ -28109,7 +28540,14 @@ function useBuildNavigationController(props) {
28109
28540
  if (!collections_0) return void 0;
28110
28541
  const baseCollection = getCollectionByPathOrId(removeInitialAndTrailingSlashes(idOrPath), collections_0);
28111
28542
  const userOverride = includeUserOverride ? userConfigPersistence?.getCollectionConfig(idOrPath) : void 0;
28112
- const overriddenCollection = baseCollection ? mergeDeep(baseCollection, userOverride ?? {}) : void 0;
28543
+ let overriddenCollection = baseCollection;
28544
+ if (baseCollection && userOverride) {
28545
+ const {
28546
+ properties,
28547
+ ...rest
28548
+ } = userOverride;
28549
+ overriddenCollection = mergeDeep(baseCollection, rest);
28550
+ }
28113
28551
  let result = overriddenCollection;
28114
28552
  if (overriddenCollection) {
28115
28553
  const subcollections = overriddenCollection.subcollections;
@@ -29617,18 +30055,15 @@ function EntityEditViewInner({
29617
30055
  const actionsAtTheBottom = !largeLayout || layout === "side_panel" || selectedEntityView?.includeActions === "bottom";
29618
30056
  const mainViewVisible = selectedTab === MAIN_TAB_VALUE || Boolean(selectedSecondaryForm);
29619
30057
  const authController = useAuthController();
29620
- const customViewsView = customViews && resolvedEntityViews.filter((e) => !e.includeActions).map((customView) => {
29621
- if (!customView) return null;
29622
- const Builder = customView.Builder;
29623
- if (!Builder) {
29624
- console.error("INTERNAL: customView.Builder is not defined");
29625
- return null;
29626
- }
29627
- if (!entityId) {
29628
- return null;
29629
- }
30058
+ const mountedTabsRef = useRef(/* @__PURE__ */ new Set());
30059
+ if (selectedTab) {
30060
+ mountedTabsRef.current.add(selectedTab);
30061
+ }
30062
+ const readOnlyFormContext = useMemo(() => {
30063
+ if (formContext) return void 0;
30064
+ if (!entityId) return void 0;
29630
30065
  const formexStub = createFormexStub(usedEntity?.values ?? {});
29631
- const usedFormContext = formContext ?? {
30066
+ return {
29632
30067
  entityId,
29633
30068
  disabled: false,
29634
30069
  openEntityMode: layout,
@@ -29654,18 +30089,34 @@ function EntityEditViewInner({
29654
30089
  savingError: void 0,
29655
30090
  formex: formexStub
29656
30091
  };
30092
+ }, [formContext, entityId, layout, status, usedEntity, collection, path, customizationController.propertyConfigs, authController]);
30093
+ const customViewsView = customViews && resolvedEntityViews.filter((e) => !e.includeActions).map((customView) => {
30094
+ if (!customView) return null;
30095
+ const Builder = customView.Builder;
30096
+ if (!Builder) {
30097
+ console.error("INTERNAL: customView.Builder is not defined");
30098
+ return null;
30099
+ }
30100
+ if (!entityId) {
30101
+ return null;
30102
+ }
30103
+ const isActive = selectedTab === customView.key;
30104
+ if (!isActive && !mountedTabsRef.current.has(customView.key)) {
30105
+ return null;
30106
+ }
30107
+ const usedFormContext = formContext ?? readOnlyFormContext;
29657
30108
  return /* @__PURE__ */ jsx("div", { className: cls(defaultBorderMixin, "relative flex-1 w-full h-full overflow-auto", {
29658
- "hidden": selectedTab !== customView.key
30109
+ "hidden": !isActive
29659
30110
  }), role: "tabpanel", children: /* @__PURE__ */ jsx(ErrorBoundary, { children: usedFormContext && /* @__PURE__ */ jsx(Builder, { collection, parentCollectionIds, entity: usedEntity, modifiedValues: usedFormContext?.formex?.values ?? usedEntity?.values, formContext: usedFormContext }) }) }, `custom_view_${customView.key}`);
29660
30111
  }).filter(Boolean);
29661
30112
  const globalLoading = dataLoading && !usedEntity;
29662
- const jsonView = /* @__PURE__ */ jsx("div", { className: cls("relative flex-1 h-full overflow-auto w-full", {
30113
+ const jsonView = selectedTab === JSON_TAB_VALUE || mountedTabsRef.current.has(JSON_TAB_VALUE) ? /* @__PURE__ */ jsx("div", { className: cls("relative flex-1 h-full overflow-auto w-full", {
29663
30114
  "hidden": selectedTab !== JSON_TAB_VALUE
29664
- }), role: "tabpanel", children: /* @__PURE__ */ jsx(ErrorBoundary, { children: /* @__PURE__ */ jsx(EntityJsonPreview, { values: formContext?.values ?? entity?.values ?? {} }) }) }, "json_view");
30115
+ }), role: "tabpanel", children: /* @__PURE__ */ jsx(ErrorBoundary, { children: /* @__PURE__ */ jsx(EntityJsonPreview, { values: formContext?.values ?? entity?.values ?? {} }) }) }, "json_view") : null;
29665
30116
  const subCollectionsViews = subcollections && subcollections.map((subcollection) => {
29666
30117
  const subcollectionId = subcollection.id ?? subcollection.path;
29667
30118
  const newFullPath = usedEntity ? `${path}/${usedEntity?.id}/${removeInitialAndTrailingSlashes(subcollection.path)}` : void 0;
29668
- const newFullIdPath = fullIdPath ? `${fullIdPath}/${usedEntity?.id}/${removeInitialAndTrailingSlashes(subcollectionId)}` : void 0;
30119
+ const newFullIdPath = fullIdPath && usedEntity ? `${fullIdPath}/${encodeEntityId(usedEntity.id)}/${removeInitialAndTrailingSlashes(subcollectionId)}` : void 0;
29669
30120
  if (selectedTab !== subcollectionId) return null;
29670
30121
  return /* @__PURE__ */ jsxs("div", { className: "relative flex-1 h-full overflow-auto w-full", role: "tabpanel", children: [
29671
30122
  globalLoading && /* @__PURE__ */ jsx(CircularProgressCenter, {}),
@@ -29709,8 +30160,8 @@ function EntityEditViewInner({
29709
30160
  const customViewTabsStart = resolvedEntityViews.filter((view) => view.position === "start" && !groupedViews.includes(view.key)).map((view_0) => /* @__PURE__ */ jsx(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}`));
29710
30161
  const customViewTabsEnd = resolvedEntityViews.filter((view_1) => (!view_1.position || view_1.position === "end") && !groupedViews.includes(view_1.key)).map((view_2) => /* @__PURE__ */ jsx(Tab, { className: !view_2.tabComponent ? "text-sm min-w-[120px]" : void 0, value: view_2.key, children: view_2.tabComponent ?? view_2.name }, `entity_detail_collection_tab_${view_2.name}`));
29711
30162
  const viewGroupMenus = collection.viewGroups?.map((group) => {
29712
- const isActive = group.views.includes(selectedTab);
29713
- return /* @__PURE__ */ jsx(Menu, { trigger: /* @__PURE__ */ jsxs("button", { type: "button", className: 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: [
30163
+ const isActive_0 = group.views.includes(selectedTab);
30164
+ return /* @__PURE__ */ jsx(Menu, { trigger: /* @__PURE__ */ jsxs("button", { type: "button", className: 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: [
29714
30165
  group.name,
29715
30166
  /* @__PURE__ */ jsx(ExpandMoreIcon, { className: "ml-1 -mr-1", size: "small" })
29716
30167
  ] }), children: group.views.map((viewId) => {
@@ -29954,7 +30405,7 @@ function buildSidePanelsFromUrl(path, collections, newFlag) {
29954
30405
  }
29955
30406
  const propsToSidePanel = (props, buildUrlCollectionPath, resolveIdsFrom, smallLayout, customizationController, authController, locationSearch) => {
29956
30407
  const collectionPath = removeInitialAndTrailingSlashes(props.path);
29957
- const urlPath = props.entityId ? buildUrlCollectionPath(`${collectionPath}/${props.entityId}${props.selectedTab ? "/" + props.selectedTab : ""}${locationSearch}#${SIDE_URL_HASH}`) : buildUrlCollectionPath(`${collectionPath}${locationSearch}#${NEW_URL_HASH}`);
30408
+ const urlPath = props.entityId ? buildUrlCollectionPath(`${collectionPath}/${encodeEntityId(props.entityId)}${props.selectedTab ? "/" + props.selectedTab : ""}${locationSearch}#${SIDE_URL_HASH}`) : buildUrlCollectionPath(`${collectionPath}${locationSearch}#${NEW_URL_HASH}`);
29958
30409
  const resolvedPanelProps = {
29959
30410
  ...props,
29960
30411
  formProps: props.formProps
@@ -30050,7 +30501,7 @@ function useBuildSideDialogsController() {
30050
30501
  replace: true,
30051
30502
  state: {
30052
30503
  base_location: baseLocation,
30053
- panels: updatedPanels.map(_temp4$1)
30504
+ panels: updatedPanels.map(_temp4$2)
30054
30505
  }
30055
30506
  });
30056
30507
  }
@@ -30148,7 +30599,7 @@ function _temp6$1(p_4) {
30148
30599
  function _temp5$1(p_3) {
30149
30600
  return p_3.key;
30150
30601
  }
30151
- function _temp4$1(p_2) {
30602
+ function _temp4$2(p_2) {
30152
30603
  return p_2.key;
30153
30604
  }
30154
30605
  function _temp3$2(p_1) {
@@ -30668,7 +31119,7 @@ function FireCMSInternal(t0) {
30668
31119
  return t1;
30669
31120
  }
30670
31121
  function DrawerNavigationItem(t0) {
30671
- const $ = c(24);
31122
+ const $ = c(22);
30672
31123
  const {
30673
31124
  name,
30674
31125
  icon,
@@ -30680,7 +31131,7 @@ function DrawerNavigationItem(t0) {
30680
31131
  } = t0;
30681
31132
  let t1;
30682
31133
  if ($[0] !== icon) {
30683
- t1 = /* @__PURE__ */ jsx("div", { className: "text-text-secondary dark:text-text-secondary-dark", children: icon });
31134
+ t1 = /* @__PURE__ */ 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 });
30684
31135
  $[0] = icon;
30685
31136
  $[1] = t1;
30686
31137
  } else {
@@ -30705,7 +31156,7 @@ function DrawerNavigationItem(t0) {
30705
31156
  const {
30706
31157
  isActive
30707
31158
  } = t52;
30708
- return 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" : "");
31159
+ return 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" : "");
30709
31160
  };
30710
31161
  $[4] = drawerOpen;
30711
31162
  $[5] = t4;
@@ -30715,61 +31166,53 @@ function DrawerNavigationItem(t0) {
30715
31166
  const t5 = drawerOpen ? "opacity-100" : "opacity-0 hidden";
30716
31167
  let t6;
30717
31168
  if ($[6] !== t5) {
30718
- t6 = cls("text-text-primary dark:text-surface-200", t5, "ml-4 font-inherit");
31169
+ t6 = cls("text-surface-700 dark:text-surface-300", t5, "font-inherit truncate space-x-2");
30719
31170
  $[6] = t5;
30720
31171
  $[7] = t6;
30721
31172
  } else {
30722
31173
  t6 = $[7];
30723
31174
  }
30724
31175
  let t7;
30725
- if ($[8] !== name) {
30726
- t7 = name.toUpperCase();
31176
+ if ($[8] !== name || $[9] !== t6) {
31177
+ t7 = /* @__PURE__ */ jsx("div", { className: t6, children: name });
30727
31178
  $[8] = name;
30728
- $[9] = t7;
31179
+ $[9] = t6;
31180
+ $[10] = t7;
30729
31181
  } else {
30730
- t7 = $[9];
31182
+ t7 = $[10];
30731
31183
  }
30732
31184
  let t8;
30733
- if ($[10] !== t6 || $[11] !== t7) {
30734
- t8 = /* @__PURE__ */ jsx("div", { className: t6, children: t7 });
30735
- $[10] = t6;
30736
- $[11] = t7;
30737
- $[12] = t8;
30738
- } else {
30739
- t8 = $[12];
30740
- }
30741
- let t9;
30742
- if ($[13] !== iconWrap || $[14] !== onClick || $[15] !== t3 || $[16] !== t4 || $[17] !== t8 || $[18] !== url) {
30743
- t9 = /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsxs(NavLink, { onClick, style: t3, className: t4, to: url, children: [
31185
+ if ($[11] !== iconWrap || $[12] !== onClick || $[13] !== t3 || $[14] !== t4 || $[15] !== t7 || $[16] !== url) {
31186
+ t8 = /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsxs(NavLink, { onClick, style: t3, className: t4, to: url, children: [
30744
31187
  iconWrap,
30745
- t8
31188
+ t7
30746
31189
  ] }) });
30747
- $[13] = iconWrap;
30748
- $[14] = onClick;
30749
- $[15] = t3;
30750
- $[16] = t4;
31190
+ $[11] = iconWrap;
31191
+ $[12] = onClick;
31192
+ $[13] = t3;
31193
+ $[14] = t4;
31194
+ $[15] = t7;
31195
+ $[16] = url;
30751
31196
  $[17] = t8;
30752
- $[18] = url;
30753
- $[19] = t9;
30754
31197
  } else {
30755
- t9 = $[19];
31198
+ t8 = $[17];
30756
31199
  }
30757
- const listItem = t9;
30758
- const t10 = drawerOpen || adminMenuOpen ? false : tooltipsOpen;
30759
- let t11;
30760
- if ($[20] !== listItem || $[21] !== name || $[22] !== t10) {
30761
- t11 = /* @__PURE__ */ jsx(Tooltip, { open: t10, side: "right", title: name, children: listItem });
30762
- $[20] = listItem;
30763
- $[21] = name;
30764
- $[22] = t10;
30765
- $[23] = t11;
31200
+ const listItem = t8;
31201
+ const t9 = drawerOpen || adminMenuOpen ? false : tooltipsOpen;
31202
+ let t10;
31203
+ if ($[18] !== listItem || $[19] !== name || $[20] !== t9) {
31204
+ t10 = /* @__PURE__ */ jsx(Tooltip, { open: t9, side: "right", title: name, children: listItem });
31205
+ $[18] = listItem;
31206
+ $[19] = name;
31207
+ $[20] = t9;
31208
+ $[21] = t10;
30766
31209
  } else {
30767
- t11 = $[23];
31210
+ t10 = $[21];
30768
31211
  }
30769
- return t11;
31212
+ return t10;
30770
31213
  }
30771
31214
  function DrawerNavigationGroup(t0) {
30772
- const $ = c(29);
31215
+ const $ = c(41);
30773
31216
  const {
30774
31217
  group,
30775
31218
  entries,
@@ -30785,86 +31228,137 @@ function DrawerNavigationGroup(t0) {
30785
31228
  t
30786
31229
  } = useTranslation();
30787
31230
  const t1 = `drawer_group_${group}`;
30788
- let t2;
30789
- if ($[0] !== collapsed || $[1] !== drawerOpen || $[2] !== group || $[3] !== headerActions || $[4] !== onToggleCollapsed || $[5] !== t) {
30790
- t2 = drawerOpen ? /* @__PURE__ */ 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: [
30791
- /* @__PURE__ */ jsx(ExpandMoreIcon, { size: "smallest", className: cls("text-surface-500 dark:text-surface-400 transition-transform duration-200 mr-1", collapsed ? "-rotate-90" : "rotate-0") }),
30792
- /* @__PURE__ */ jsx(Typography, { variant: "caption", color: "secondary", className: "font-medium flex-grow line-clamp-1", children: (group && group !== "__default__" ? group : t("views_group")).toUpperCase() }),
30793
- headerActions && /* @__PURE__ */ jsx("div", { onClick: _temp$a, children: headerActions })
30794
- ] }) : /* @__PURE__ */ jsx("div", { className: "w-full" });
30795
- $[0] = collapsed;
30796
- $[1] = drawerOpen;
30797
- $[2] = group;
30798
- $[3] = headerActions;
30799
- $[4] = onToggleCollapsed;
30800
- $[5] = t;
30801
- $[6] = t2;
31231
+ const t2 = drawerOpen ? "cursor-pointer hover:bg-surface-100 dark:hover:bg-surface-800/40 rounded-lg" : "opacity-0 invisible pointer-events-none";
31232
+ let t3;
31233
+ if ($[0] !== t2) {
31234
+ t3 = cls("pl-3 pr-2 py-0.5 flex flex-row items-center transition-colors", t2);
31235
+ $[0] = t2;
31236
+ $[1] = t3;
30802
31237
  } else {
30803
- t2 = $[6];
31238
+ t3 = $[1];
30804
31239
  }
30805
- const t3 = collapsed ? "max-h-0 opacity-0" : "max-h-[2000px] opacity-100";
30806
- let t4;
30807
- if ($[7] !== t3) {
30808
- t4 = cls("overflow-hidden transition-all duration-200 ease-in-out", t3);
30809
- $[7] = t3;
30810
- $[8] = t4;
31240
+ const t4 = drawerOpen ? onToggleCollapsed : void 0;
31241
+ const t5 = collapsed ? "-rotate-90" : "rotate-0";
31242
+ let t6;
31243
+ if ($[2] !== t5) {
31244
+ t6 = cls("text-surface-400 dark:text-surface-400 transition-transform duration-200 mr-1", t5);
31245
+ $[2] = t5;
31246
+ $[3] = t6;
30811
31247
  } else {
30812
- t4 = $[8];
31248
+ t6 = $[3];
30813
31249
  }
30814
- let t5;
30815
- if ($[9] !== adminMenuOpen || $[10] !== collapsed || $[11] !== drawerOpen || $[12] !== entries || $[13] !== onItemClick || $[14] !== tooltipsOpen) {
30816
- let t62;
30817
- if ($[16] !== adminMenuOpen || $[17] !== collapsed || $[18] !== drawerOpen || $[19] !== onItemClick || $[20] !== tooltipsOpen) {
30818
- t62 = (entry) => /* @__PURE__ */ jsx(DrawerNavigationItem, { icon: /* @__PURE__ */ 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);
30819
- $[16] = adminMenuOpen;
30820
- $[17] = collapsed;
30821
- $[18] = drawerOpen;
30822
- $[19] = onItemClick;
30823
- $[20] = tooltipsOpen;
30824
- $[21] = t62;
31250
+ let t7;
31251
+ if ($[4] !== t6) {
31252
+ t7 = /* @__PURE__ */ jsx(ExpandMoreIcon, { size: "smallest", className: t6 });
31253
+ $[4] = t6;
31254
+ $[5] = t7;
31255
+ } else {
31256
+ t7 = $[5];
31257
+ }
31258
+ let t8;
31259
+ if ($[6] !== group || $[7] !== t) {
31260
+ t8 = group && group !== "__default__" ? group : t("views_group");
31261
+ $[6] = group;
31262
+ $[7] = t;
31263
+ $[8] = t8;
31264
+ } else {
31265
+ t8 = $[8];
31266
+ }
31267
+ let t9;
31268
+ if ($[9] !== t8) {
31269
+ t9 = /* @__PURE__ */ jsx(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 });
31270
+ $[9] = t8;
31271
+ $[10] = t9;
31272
+ } else {
31273
+ t9 = $[10];
31274
+ }
31275
+ let t10;
31276
+ if ($[11] !== headerActions) {
31277
+ t10 = headerActions && /* @__PURE__ */ jsx("div", { onClick: _temp$a, children: headerActions });
31278
+ $[11] = headerActions;
31279
+ $[12] = t10;
31280
+ } else {
31281
+ t10 = $[12];
31282
+ }
31283
+ let t11;
31284
+ if ($[13] !== t10 || $[14] !== t3 || $[15] !== t4 || $[16] !== t7 || $[17] !== t9) {
31285
+ t11 = /* @__PURE__ */ jsxs("div", { className: t3, onClick: t4, children: [
31286
+ t7,
31287
+ t9,
31288
+ t10
31289
+ ] });
31290
+ $[13] = t10;
31291
+ $[14] = t3;
31292
+ $[15] = t4;
31293
+ $[16] = t7;
31294
+ $[17] = t9;
31295
+ $[18] = t11;
31296
+ } else {
31297
+ t11 = $[18];
31298
+ }
31299
+ const t12 = collapsed ? "max-h-0 opacity-0" : "max-h-[2000px] opacity-100";
31300
+ let t13;
31301
+ if ($[19] !== t12) {
31302
+ t13 = cls("transition-all duration-200 ease-in-out overflow-hidden rounded-lg", t12);
31303
+ $[19] = t12;
31304
+ $[20] = t13;
31305
+ } else {
31306
+ t13 = $[20];
31307
+ }
31308
+ let t14;
31309
+ if ($[21] !== adminMenuOpen || $[22] !== collapsed || $[23] !== drawerOpen || $[24] !== entries || $[25] !== onItemClick || $[26] !== tooltipsOpen) {
31310
+ let t152;
31311
+ if ($[28] !== adminMenuOpen || $[29] !== collapsed || $[30] !== drawerOpen || $[31] !== onItemClick || $[32] !== tooltipsOpen) {
31312
+ t152 = (entry) => /* @__PURE__ */ jsx(DrawerNavigationItem, { icon: /* @__PURE__ */ 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);
31313
+ $[28] = adminMenuOpen;
31314
+ $[29] = collapsed;
31315
+ $[30] = drawerOpen;
31316
+ $[31] = onItemClick;
31317
+ $[32] = tooltipsOpen;
31318
+ $[33] = t152;
30825
31319
  } else {
30826
- t62 = $[21];
30827
- }
30828
- t5 = entries.map(t62);
30829
- $[9] = adminMenuOpen;
30830
- $[10] = collapsed;
30831
- $[11] = drawerOpen;
30832
- $[12] = entries;
30833
- $[13] = onItemClick;
30834
- $[14] = tooltipsOpen;
30835
- $[15] = t5;
31320
+ t152 = $[33];
31321
+ }
31322
+ t14 = entries.map(t152);
31323
+ $[21] = adminMenuOpen;
31324
+ $[22] = collapsed;
31325
+ $[23] = drawerOpen;
31326
+ $[24] = entries;
31327
+ $[25] = onItemClick;
31328
+ $[26] = tooltipsOpen;
31329
+ $[27] = t14;
30836
31330
  } else {
30837
- t5 = $[15];
31331
+ t14 = $[27];
30838
31332
  }
30839
- let t6;
30840
- if ($[22] !== t4 || $[23] !== t5) {
30841
- t6 = /* @__PURE__ */ jsx("div", { className: t4, children: t5 });
30842
- $[22] = t4;
30843
- $[23] = t5;
30844
- $[24] = t6;
31333
+ let t15;
31334
+ if ($[34] !== t13 || $[35] !== t14) {
31335
+ t15 = /* @__PURE__ */ jsx("div", { className: t13, children: t14 });
31336
+ $[34] = t13;
31337
+ $[35] = t14;
31338
+ $[36] = t15;
30845
31339
  } else {
30846
- t6 = $[24];
31340
+ t15 = $[36];
30847
31341
  }
30848
- let t7;
30849
- if ($[25] !== t1 || $[26] !== t2 || $[27] !== t6) {
30850
- t7 = /* @__PURE__ */ jsxs("div", { className: "bg-surface-50 dark:bg-surface-800/30 my-4 rounded-lg ml-3 mr-1", children: [
30851
- t2,
30852
- t6
31342
+ let t16;
31343
+ if ($[37] !== t1 || $[38] !== t11 || $[39] !== t15) {
31344
+ t16 = /* @__PURE__ */ jsxs("div", { className: "my-2 mx-2 flex flex-col", children: [
31345
+ t11,
31346
+ t15
30853
31347
  ] }, t1);
30854
- $[25] = t1;
30855
- $[26] = t2;
30856
- $[27] = t6;
30857
- $[28] = t7;
31348
+ $[37] = t1;
31349
+ $[38] = t11;
31350
+ $[39] = t15;
31351
+ $[40] = t16;
30858
31352
  } else {
30859
- t7 = $[28];
31353
+ t16 = $[40];
30860
31354
  }
30861
- return t7;
31355
+ return t16;
30862
31356
  }
30863
31357
  function _temp$a(e) {
30864
31358
  return e.stopPropagation();
30865
31359
  }
30866
31360
  function DefaultDrawer(t0) {
30867
- const $ = c(36);
31361
+ const $ = c(40);
30868
31362
  const {
30869
31363
  className,
30870
31364
  style
@@ -30876,6 +31370,20 @@ function DefaultDrawer(t0) {
30876
31370
  logo
30877
31371
  } = useApp();
30878
31372
  const [adminMenuOpen, setAdminMenuOpen] = React__default.useState(false);
31373
+ const scrollRef = React__default.useRef(null);
31374
+ const [scrolled, setScrolled] = React__default.useState(false);
31375
+ let t1;
31376
+ if ($[0] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
31377
+ t1 = () => {
31378
+ if (scrollRef.current) {
31379
+ setScrolled(scrollRef.current.scrollTop > 0);
31380
+ }
31381
+ };
31382
+ $[0] = t1;
31383
+ } else {
31384
+ t1 = $[0];
31385
+ }
31386
+ const handleScroll = t1;
30879
31387
  const analyticsController = useAnalyticsController();
30880
31388
  const navigation = useNavigationController();
30881
31389
  const {
@@ -30892,22 +31400,23 @@ function DefaultDrawer(t0) {
30892
31400
  groups
30893
31401
  } = navigation.topLevelNavigation;
30894
31402
  const adminViews = navigationEntries.filter(_temp$9) ?? [];
30895
- let t1;
30896
- if ($[0] !== groups) {
30897
- t1 = groups.filter(_temp2$3);
30898
- $[0] = groups;
30899
- $[1] = t1;
31403
+ let t2;
31404
+ if ($[1] !== groups) {
31405
+ t2 = groups.filter(_temp2$3);
31406
+ $[1] = groups;
31407
+ $[2] = t2;
30900
31408
  } else {
30901
- t1 = $[1];
31409
+ t2 = $[2];
30902
31410
  }
30903
- const groupsWithoutAdmin = t1;
31411
+ const groupsWithoutAdmin = t2;
30904
31412
  const {
30905
31413
  isGroupCollapsed,
30906
31414
  toggleGroupCollapsed
30907
31415
  } = useCollapsedGroups(groupsWithoutAdmin, "drawer");
30908
- let t2;
30909
- if ($[2] !== analyticsController || $[3] !== closeDrawer || $[4] !== largeLayout) {
30910
- t2 = (view) => {
31416
+ const drawerVisuallyOpen = drawerOpen || drawerHovered;
31417
+ let t3;
31418
+ if ($[3] !== analyticsController || $[4] !== closeDrawer || $[5] !== largeLayout) {
31419
+ t3 = (view) => {
30911
31420
  const eventName = view.type === "collection" ? "drawer_navigate_to_collection" : view.type === "view" ? "drawer_navigate_to_view" : "unmapped_event";
30912
31421
  analyticsController.onAnalyticsEvent?.(eventName, {
30913
31422
  url: view.url
@@ -30916,106 +31425,119 @@ function DefaultDrawer(t0) {
30916
31425
  closeDrawer();
30917
31426
  }
30918
31427
  };
30919
- $[2] = analyticsController;
30920
- $[3] = closeDrawer;
30921
- $[4] = largeLayout;
30922
- $[5] = t2;
31428
+ $[3] = analyticsController;
31429
+ $[4] = closeDrawer;
31430
+ $[5] = largeLayout;
31431
+ $[6] = t3;
30923
31432
  } else {
30924
- t2 = $[5];
31433
+ t3 = $[6];
30925
31434
  }
30926
- const onItemClick = t2;
30927
- let t3;
30928
- if ($[6] !== className) {
30929
- t3 = cls("flex flex-col h-full relative flex-grow w-full", className);
30930
- $[6] = className;
30931
- $[7] = t3;
31435
+ const onItemClick = t3;
31436
+ const t4 = "navigation";
31437
+ const t5 = "Main navigation";
31438
+ let t6;
31439
+ if ($[7] !== className) {
31440
+ t6 = cls("flex flex-col h-full relative grow w-full", className);
31441
+ $[7] = className;
31442
+ $[8] = t6;
30932
31443
  } else {
30933
- t3 = $[7];
31444
+ t6 = $[8];
30934
31445
  }
30935
- let t4;
30936
- if ($[8] !== logo) {
30937
- t4 = /* @__PURE__ */ jsx(DrawerLogo, { logo });
30938
- $[8] = logo;
30939
- $[9] = t4;
31446
+ let t7;
31447
+ if ($[9] !== logo) {
31448
+ t7 = /* @__PURE__ */ jsx(DrawerLogo, { logo });
31449
+ $[9] = logo;
31450
+ $[10] = t7;
30940
31451
  } else {
30941
- t4 = $[9];
31452
+ t7 = $[10];
30942
31453
  }
30943
- let t5;
30944
- if ($[10] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
30945
- t5 = {
30946
- maskImage: "linear-gradient(to bottom, transparent 0, black 20px, black calc(100% - 20px), transparent 100%)"
31454
+ 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%)";
31455
+ let t9;
31456
+ if ($[11] !== t8) {
31457
+ t9 = {
31458
+ maskImage: t8
30947
31459
  };
30948
- $[10] = t5;
31460
+ $[11] = t8;
31461
+ $[12] = t9;
30949
31462
  } else {
30950
- t5 = $[10];
31463
+ t9 = $[12];
30951
31464
  }
30952
- let t6;
30953
- if ($[11] !== adminMenuOpen || $[12] !== drawerOpen || $[13] !== groupsWithoutAdmin || $[14] !== isGroupCollapsed || $[15] !== navigationEntries || $[16] !== onItemClick || $[17] !== toggleGroupCollapsed || $[18] !== tooltipsOpen) {
30954
- let t72;
30955
- if ($[20] !== adminMenuOpen || $[21] !== drawerOpen || $[22] !== isGroupCollapsed || $[23] !== navigationEntries || $[24] !== onItemClick || $[25] !== toggleGroupCollapsed || $[26] !== tooltipsOpen) {
30956
- t72 = (group) => {
31465
+ let t10;
31466
+ if ($[13] !== adminMenuOpen || $[14] !== drawerVisuallyOpen || $[15] !== groupsWithoutAdmin || $[16] !== isGroupCollapsed || $[17] !== navigationEntries || $[18] !== onItemClick || $[19] !== toggleGroupCollapsed || $[20] !== tooltipsOpen) {
31467
+ let t112;
31468
+ if ($[22] !== adminMenuOpen || $[23] !== drawerVisuallyOpen || $[24] !== isGroupCollapsed || $[25] !== navigationEntries || $[26] !== onItemClick || $[27] !== toggleGroupCollapsed || $[28] !== tooltipsOpen) {
31469
+ t112 = (group) => {
30957
31470
  const entriesInGroup = Object.values(navigationEntries).filter((e_0) => e_0.group === group);
30958
- return /* @__PURE__ */ jsx(DrawerNavigationGroup, { group, entries: entriesInGroup, collapsed: isGroupCollapsed(group), onToggleCollapsed: () => toggleGroupCollapsed(group), drawerOpen, tooltipsOpen, adminMenuOpen, onItemClick }, `drawer_group_${group}`);
31471
+ return /* @__PURE__ */ jsx(DrawerNavigationGroup, { group, entries: entriesInGroup, collapsed: isGroupCollapsed(group), onToggleCollapsed: () => toggleGroupCollapsed(group), drawerOpen: drawerVisuallyOpen, tooltipsOpen, adminMenuOpen, onItemClick }, `drawer_group_${group}`);
30959
31472
  };
30960
- $[20] = adminMenuOpen;
30961
- $[21] = drawerOpen;
30962
- $[22] = isGroupCollapsed;
30963
- $[23] = navigationEntries;
30964
- $[24] = onItemClick;
30965
- $[25] = toggleGroupCollapsed;
30966
- $[26] = tooltipsOpen;
30967
- $[27] = t72;
31473
+ $[22] = adminMenuOpen;
31474
+ $[23] = drawerVisuallyOpen;
31475
+ $[24] = isGroupCollapsed;
31476
+ $[25] = navigationEntries;
31477
+ $[26] = onItemClick;
31478
+ $[27] = toggleGroupCollapsed;
31479
+ $[28] = tooltipsOpen;
31480
+ $[29] = t112;
30968
31481
  } else {
30969
- t72 = $[27];
30970
- }
30971
- t6 = groupsWithoutAdmin.map(t72);
30972
- $[11] = adminMenuOpen;
30973
- $[12] = drawerOpen;
30974
- $[13] = groupsWithoutAdmin;
30975
- $[14] = isGroupCollapsed;
30976
- $[15] = navigationEntries;
30977
- $[16] = onItemClick;
30978
- $[17] = toggleGroupCollapsed;
30979
- $[18] = tooltipsOpen;
30980
- $[19] = t6;
31482
+ t112 = $[29];
31483
+ }
31484
+ t10 = groupsWithoutAdmin.map(t112);
31485
+ $[13] = adminMenuOpen;
31486
+ $[14] = drawerVisuallyOpen;
31487
+ $[15] = groupsWithoutAdmin;
31488
+ $[16] = isGroupCollapsed;
31489
+ $[17] = navigationEntries;
31490
+ $[18] = onItemClick;
31491
+ $[19] = toggleGroupCollapsed;
31492
+ $[20] = tooltipsOpen;
31493
+ $[21] = t10;
30981
31494
  } else {
30982
- t6 = $[19];
31495
+ t10 = $[21];
30983
31496
  }
30984
- let t7;
30985
- if ($[28] !== t6) {
30986
- t7 = /* @__PURE__ */ jsx("div", { className: "mt-4 flex-grow overflow-scroll no-scrollbar", style: t5, children: t6 });
30987
- $[28] = t6;
30988
- $[29] = t7;
31497
+ let t11;
31498
+ if ($[30] !== t10 || $[31] !== t9) {
31499
+ t11 = /* @__PURE__ */ 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 });
31500
+ $[30] = t10;
31501
+ $[31] = t9;
31502
+ $[32] = t11;
30989
31503
  } else {
30990
- t7 = $[29];
31504
+ t11 = $[32];
30991
31505
  }
30992
- const t8 = adminViews.length > 0 && /* @__PURE__ */ jsx(Menu, { side: "right", open: adminMenuOpen, onOpenChange: setAdminMenuOpen, trigger: /* @__PURE__ */ jsxs(IconButton, { shape: "square", className: "m-4 text-surface-900 dark:text-white w-fit", children: [
30993
- /* @__PURE__ */ jsx(Tooltip, { title: "Admin", open: tooltipsOpen, side: "right", sideOffset: 28, children: /* @__PURE__ */ jsx(MoreVertIcon, {}) }),
30994
- drawerOpen && /* @__PURE__ */ jsx("div", { className: cls(drawerOpen ? "opacity-100" : "opacity-0 hidden", "mx-4 font-inherit text-inherit"), children: "ADMIN" })
31506
+ const t12 = adminViews.length > 0 && /* @__PURE__ */ jsx("div", { className: "shrink-0 px-4", children: /* @__PURE__ */ jsx(Menu, { side: "right", open: adminMenuOpen, onOpenChange: setAdminMenuOpen, trigger: /* @__PURE__ */ jsxs("div", { className: 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: [
31507
+ /* @__PURE__ */ jsx("div", { className: "shrink-0 flex items-center justify-center w-[44px] h-[30px] text-surface-500 dark:text-surface-400", children: /* @__PURE__ */ jsx(Tooltip, { title: "Admin", open: drawerVisuallyOpen || adminMenuOpen ? false : tooltipsOpen, side: "right", sideOffset: 28, children: /* @__PURE__ */ jsx(MoreVertIcon, { size: "small" }) }) }),
31508
+ drawerVisuallyOpen && /* @__PURE__ */ jsx("div", { className: cls("font-semibold text-[11px] uppercase tracking-wider text-surface-400"), children: t("admin") })
30995
31509
  ] }), children: adminViews.map((entry) => /* @__PURE__ */ jsxs(MenuItem, { onClick: (event) => {
30996
31510
  event.preventDefault();
30997
31511
  navigate(entry.url);
30998
31512
  }, children: [
30999
31513
  /* @__PURE__ */ jsx(IconForView, { collectionOrView: entry.view }),
31000
31514
  t(entry.name)
31001
- ] }, entry.id)) });
31002
- let t9;
31003
- if ($[30] !== style || $[31] !== t3 || $[32] !== t4 || $[33] !== t7 || $[34] !== t8) {
31004
- t9 = /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsxs("div", { className: t3, style, children: [
31005
- t4,
31515
+ ] }, entry.id)) }) });
31516
+ let t13;
31517
+ if ($[33] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
31518
+ t13 = /* @__PURE__ */ jsx(DrawerToggle, {});
31519
+ $[33] = t13;
31520
+ } else {
31521
+ t13 = $[33];
31522
+ }
31523
+ let t14;
31524
+ if ($[34] !== style || $[35] !== t11 || $[36] !== t12 || $[37] !== t6 || $[38] !== t7) {
31525
+ t14 = /* @__PURE__ */ jsxs("div", { role: t4, "aria-label": t5, className: t6, style, children: [
31006
31526
  t7,
31007
- t8
31008
- ] }) });
31009
- $[30] = style;
31010
- $[31] = t3;
31011
- $[32] = t4;
31012
- $[33] = t7;
31013
- $[34] = t8;
31014
- $[35] = t9;
31527
+ t11,
31528
+ t12,
31529
+ t13
31530
+ ] });
31531
+ $[34] = style;
31532
+ $[35] = t11;
31533
+ $[36] = t12;
31534
+ $[37] = t6;
31535
+ $[38] = t7;
31536
+ $[39] = t14;
31015
31537
  } else {
31016
- t9 = $[35];
31538
+ t14 = $[39];
31017
31539
  }
31018
- return t9;
31540
+ return t14;
31019
31541
  }
31020
31542
  function _temp2$3(g) {
31021
31543
  return g !== "Admin";
@@ -31023,62 +31545,133 @@ function _temp2$3(g) {
31023
31545
  function _temp$9(e) {
31024
31546
  return e.type === "admin";
31025
31547
  }
31026
- function DrawerLogo(t0) {
31027
- const $ = c(12);
31028
- const {
31029
- logo
31030
- } = t0;
31031
- const navigation = useNavigationController();
31548
+ function DrawerToggle() {
31549
+ const $ = c(26);
31032
31550
  const {
31033
- drawerOpen
31551
+ drawerOpen,
31552
+ drawerHovered,
31553
+ openDrawer,
31554
+ closeDrawer
31034
31555
  } = useApp();
31035
- const t1 = drawerOpen ? "32px 144px 0px 24px" : "72px 12px 0px 12px";
31556
+ const isExpanded = drawerOpen;
31557
+ const isHovered = drawerHovered && !drawerOpen;
31558
+ const showFullContent = isExpanded || isHovered;
31559
+ const t0 = isExpanded ? "Collapse" : "Expand";
31560
+ const t1 = isHovered ? false : void 0;
31036
31561
  let t2;
31037
- if ($[0] !== t1) {
31038
- t2 = {
31039
- transition: "padding 100ms cubic-bezier(0.4, 0, 0.6, 1) 0ms",
31040
- padding: t1
31562
+ if ($[0] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
31563
+ t2 = 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]");
31564
+ $[0] = t2;
31565
+ } else {
31566
+ t2 = $[0];
31567
+ }
31568
+ const t3 = isExpanded ? "Collapse" : "Expand";
31569
+ let t4;
31570
+ let t5;
31571
+ if ($[1] !== closeDrawer || $[2] !== isExpanded || $[3] !== openDrawer) {
31572
+ t4 = () => isExpanded ? closeDrawer() : openDrawer();
31573
+ t5 = (e) => {
31574
+ if (e.key === "Enter" || e.key === " ") {
31575
+ e.preventDefault();
31576
+ isExpanded ? closeDrawer() : openDrawer();
31577
+ }
31041
31578
  };
31042
- $[0] = t1;
31043
- $[1] = t2;
31579
+ $[1] = closeDrawer;
31580
+ $[2] = isExpanded;
31581
+ $[3] = openDrawer;
31582
+ $[4] = t4;
31583
+ $[5] = t5;
31044
31584
  } else {
31045
- t2 = $[1];
31585
+ t4 = $[4];
31586
+ t5 = $[5];
31046
31587
  }
31047
- let t3;
31048
- if ($[2] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
31049
- t3 = cls("cursor-pointer rounded ml-3 mr-1");
31050
- $[2] = t3;
31588
+ let t6;
31589
+ if ($[6] !== isExpanded) {
31590
+ t6 = /* @__PURE__ */ jsx("div", { className: "shrink-0 flex items-center justify-center w-[44px] h-[30px] text-surface-500 dark:text-surface-400", children: isExpanded ? /* @__PURE__ */ jsx(KeyboardDoubleArrowLeftIcon, { size: "small" }) : /* @__PURE__ */ jsx(KeyboardDoubleArrowRightIcon, { size: "small" }) });
31591
+ $[6] = isExpanded;
31592
+ $[7] = t6;
31051
31593
  } else {
31052
- t3 = $[2];
31594
+ t6 = $[7];
31053
31595
  }
31054
- let t4;
31055
- if ($[3] !== drawerOpen || $[4] !== logo) {
31056
- t4 = logo ? /* @__PURE__ */ jsx("img", { src: logo, alt: "Logo", className: cls("max-w-full max-h-full transition-all object-contain", drawerOpen ? "w-[96px] h-[96px]" : "w-[32px] h-[32px]") }) : /* @__PURE__ */ jsx(FireCMSLogo, {});
31057
- $[3] = drawerOpen;
31058
- $[4] = logo;
31059
- $[5] = t4;
31596
+ const t7 = showFullContent ? "opacity-100 w-auto" : "opacity-0 w-0";
31597
+ let t8;
31598
+ if ($[8] !== t7) {
31599
+ t8 = cls("overflow-hidden transition-all duration-200 ease-in-out", t7);
31600
+ $[8] = t7;
31601
+ $[9] = t8;
31060
31602
  } else {
31061
- t4 = $[5];
31603
+ t8 = $[9];
31062
31604
  }
31063
- let t5;
31064
- if ($[6] !== navigation.basePath || $[7] !== t4) {
31065
- t5 = /* @__PURE__ */ jsx(Tooltip, { title: "Home", sideOffset: 20, side: "right", children: /* @__PURE__ */ jsx(Link, { className: "block", to: navigation.basePath, children: t4 }) });
31066
- $[6] = navigation.basePath;
31067
- $[7] = t4;
31068
- $[8] = t5;
31605
+ const t9 = isExpanded ? "Collapse" : "Expand";
31606
+ let t10;
31607
+ if ($[10] !== t9) {
31608
+ t10 = /* @__PURE__ */ jsx(Typography, { variant: "body2", className: "text-surface-500 dark:text-surface-400 select-none whitespace-nowrap", children: t9 });
31609
+ $[10] = t9;
31610
+ $[11] = t10;
31069
31611
  } else {
31070
- t5 = $[8];
31612
+ t10 = $[11];
31071
31613
  }
31072
- let t6;
31073
- if ($[9] !== t2 || $[10] !== t5) {
31074
- t6 = /* @__PURE__ */ jsx("div", { style: t2, className: t3, children: t5 });
31075
- $[9] = t2;
31076
- $[10] = t5;
31077
- $[11] = t6;
31614
+ let t11;
31615
+ if ($[12] !== t10 || $[13] !== t8) {
31616
+ t11 = /* @__PURE__ */ jsx("div", { className: t8, children: t10 });
31617
+ $[12] = t10;
31618
+ $[13] = t8;
31619
+ $[14] = t11;
31078
31620
  } else {
31079
- t6 = $[11];
31621
+ t11 = $[14];
31080
31622
  }
31081
- return t6;
31623
+ let t12;
31624
+ if ($[15] !== isExpanded || $[16] !== t11 || $[17] !== t3 || $[18] !== t4 || $[19] !== t5 || $[20] !== t6) {
31625
+ t12 = /* @__PURE__ */ jsxs("div", { className: t2, role: "button", tabIndex: 0, "aria-expanded": isExpanded, "aria-label": t3, onClick: t4, onKeyDown: t5, children: [
31626
+ t6,
31627
+ t11
31628
+ ] });
31629
+ $[15] = isExpanded;
31630
+ $[16] = t11;
31631
+ $[17] = t3;
31632
+ $[18] = t4;
31633
+ $[19] = t5;
31634
+ $[20] = t6;
31635
+ $[21] = t12;
31636
+ } else {
31637
+ t12 = $[21];
31638
+ }
31639
+ let t13;
31640
+ if ($[22] !== t0 || $[23] !== t1 || $[24] !== t12) {
31641
+ t13 = /* @__PURE__ */ jsx("div", { className: "shrink-0 mt-auto px-4 pt-0.5 pb-2", children: /* @__PURE__ */ jsx(Tooltip, { title: t0, side: "right", sideOffset: 12, open: t1, children: t12 }) });
31642
+ $[22] = t0;
31643
+ $[23] = t1;
31644
+ $[24] = t12;
31645
+ $[25] = t13;
31646
+ } else {
31647
+ t13 = $[25];
31648
+ }
31649
+ return t13;
31650
+ }
31651
+ function DrawerLogo(t0) {
31652
+ const $ = c(5);
31653
+ const {
31654
+ logo
31655
+ } = t0;
31656
+ const navigation = useNavigationController();
31657
+ let t1;
31658
+ if ($[0] !== logo) {
31659
+ t1 = logo ? /* @__PURE__ */ jsx("img", { src: logo, alt: "Logo", className: "w-[28px] h-[28px] object-contain" }) : /* @__PURE__ */ jsx(FireCMSLogo, { width: "28px", height: "28px" });
31660
+ $[0] = logo;
31661
+ $[1] = t1;
31662
+ } else {
31663
+ t1 = $[1];
31664
+ }
31665
+ let t2;
31666
+ if ($[2] !== navigation.basePath || $[3] !== t1) {
31667
+ t2 = /* @__PURE__ */ jsx("div", { className: "flex flex-row items-center shrink-0 pt-4 pb-0 px-2", children: /* @__PURE__ */ jsx(Tooltip, { title: "Home", sideOffset: 20, side: "right", children: /* @__PURE__ */ jsx(Link, { className: "shrink-0 flex items-center justify-center w-[56px] h-[40px]", to: navigation.basePath, children: t1 }) }) });
31668
+ $[2] = navigation.basePath;
31669
+ $[3] = t1;
31670
+ $[4] = t2;
31671
+ } else {
31672
+ t2 = $[4];
31673
+ }
31674
+ return t2;
31082
31675
  }
31083
31676
  function UserSelectFieldBinding(t0) {
31084
31677
  const $ = c(44);
@@ -31469,6 +32062,17 @@ const DEFAULT_FIELD_CONFIGS = {
31469
32062
  Field: DateTimeFieldBinding
31470
32063
  }
31471
32064
  },
32065
+ geopoint: {
32066
+ key: "geopoint",
32067
+ name: "Geopoint",
32068
+ description: "Latitude and longitude pair",
32069
+ Icon: LocationOnIcon,
32070
+ color: "#0ea5e9",
32071
+ property: {
32072
+ dataType: "geopoint",
32073
+ Field: GeopointFieldBinding
32074
+ }
32075
+ },
31472
32076
  group: {
31473
32077
  key: "group",
31474
32078
  name: "Group",
@@ -31611,6 +32215,8 @@ function getDefaultFieldId(property) {
31611
32215
  return "switch";
31612
32216
  } else if (property.dataType === "date") {
31613
32217
  return "date_time";
32218
+ } else if (property.dataType === "geopoint") {
32219
+ return "geopoint";
31614
32220
  } else if (property.dataType === "reference") {
31615
32221
  return "reference";
31616
32222
  }
@@ -31621,6 +32227,20 @@ function getFieldId(property) {
31621
32227
  if (property.propertyConfig) return property.propertyConfig;
31622
32228
  return getDefaultFieldId(property);
31623
32229
  }
32230
+ const SIDE_PANEL_HASHES = ["#side", "#new_side"];
32231
+ function shouldBlockEntityNavigation(params) {
32232
+ const {
32233
+ currentLocation,
32234
+ nextLocation,
32235
+ entityPath,
32236
+ basePath,
32237
+ blocked
32238
+ } = params;
32239
+ if (nextLocation.pathname.startsWith(entityPath)) return false;
32240
+ if (SIDE_PANEL_HASHES.includes(nextLocation.hash)) return false;
32241
+ if (SIDE_PANEL_HASHES.includes(currentLocation.hash) && nextLocation.pathname === basePath) return false;
32242
+ return blocked;
32243
+ }
31624
32244
  const EntityEditView = lazyEager(() => Promise.resolve().then(() => EntityEditView$2), "EntityEditView");
31625
32245
  const EntityCollectionView = lazyEager(() => Promise.resolve().then(() => EntityCollectionView$2), "EntityCollectionView");
31626
32246
  function FireCMSRoute() {
@@ -31999,19 +32619,31 @@ function EntityFullScreenRoute({
31999
32619
  setSelectedTab(urlTab);
32000
32620
  }
32001
32621
  }, [urlTab]);
32002
- const basePath = !entityId || isNew ? pathname : pathname.substring(0, pathname.lastIndexOf(`/${entityId}`));
32003
- const entityPath = basePath + `/${entityId}`;
32622
+ const lastCollectionEntry = navigationEntries.findLast((entry_1) => entry_1.type === "collection");
32623
+ const entityEntryIndex = lastEntityEntry ? navigationEntries.indexOf(lastEntityEntry) : -1;
32624
+ const parentCollectionEntry = entityEntryIndex > 0 ? navigationEntries[entityEntryIndex - 1] : void 0;
32625
+ const buildUrl = (escapedPath) => addInitialSlash(navigation.buildUrlCollectionPath(escapedPath));
32626
+ const basePath = !entityId || isNew || !parentCollectionEntry ? pathname : buildUrl(parentCollectionEntry.fullPath);
32627
+ const entityPath = lastEntityEntry ? buildUrl(lastEntityEntry.fullPath) : basePath;
32628
+ const buildEntityUrl = (id, tab) => {
32629
+ const parentPath = parentCollectionEntry?.fullPath ?? lastCollectionEntry?.fullPath;
32630
+ if (!parentPath) return pathname;
32631
+ return buildUrl(`${parentPath}/${encodeEntityId(id)}${tab ? "/" + tab : ""}`);
32632
+ };
32004
32633
  let blocker = void 0;
32005
32634
  try {
32006
32635
  blocker = useBlocker(({
32636
+ currentLocation,
32007
32637
  nextLocation
32008
- }) => {
32009
- if (nextLocation.pathname.startsWith(entityPath)) return false;
32010
- return blocked.current;
32011
- });
32638
+ }) => shouldBlockEntityNavigation({
32639
+ currentLocation,
32640
+ nextLocation,
32641
+ entityPath,
32642
+ basePath,
32643
+ blocked: blocked.current
32644
+ }));
32012
32645
  } catch (e) {
32013
32646
  }
32014
- const lastCollectionEntry = navigationEntries.findLast((entry_1) => entry_1.type === "collection");
32015
32647
  if (isNew && !lastCollectionEntry) {
32016
32648
  throw new Error("INTERNAL: No collection found in the navigation");
32017
32649
  }
@@ -32019,36 +32651,23 @@ function EntityFullScreenRoute({
32019
32651
  return /* @__PURE__ */ jsx(NotFoundPage, {});
32020
32652
  }
32021
32653
  const collection = isNew ? lastCollectionEntry.collection : lastEntityEntry.parentCollection;
32022
- const fullIdPath = isNew ? lastCollectionEntry.path : lastEntityEntry.path;
32023
- const collectionPath = navigation.resolveIdsFrom(fullIdPath);
32654
+ const fullIdPath = isNew ? lastCollectionEntry.fullPath : parentCollectionEntry?.fullPath ?? lastEntityEntry.fullPath;
32655
+ const collectionPath = navigation.resolveIdsFrom(isNew ? lastCollectionEntry.path : lastEntityEntry.path);
32024
32656
  return /* @__PURE__ */ jsxs(Fragment, { children: [
32025
32657
  /* @__PURE__ */ jsx(React__default.Suspense, { fallback: null, children: /* @__PURE__ */ 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) => {
32026
- const newSelectedTab = params.selectedTab;
32027
32658
  const newEntityId = params.entityId;
32028
- if (newSelectedTab) {
32029
- navigate(`${basePath}/${newEntityId}/${newSelectedTab}`, {
32030
- replace: true
32031
- });
32032
- } else {
32033
- navigate(`${basePath}/${newEntityId}`, {
32034
- replace: true
32035
- });
32036
- }
32659
+ if (!newEntityId) return;
32660
+ navigate(buildEntityUrl(newEntityId, params.selectedTab), {
32661
+ replace: true
32662
+ });
32037
32663
  }, onTabChange: (params_0) => {
32038
32664
  setSelectedTab(params_0.selectedTab);
32039
- if (isNew) {
32665
+ if (isNew || !entityId) {
32040
32666
  return;
32041
32667
  }
32042
- const newSelectedTab_0 = params_0.selectedTab;
32043
- if (newSelectedTab_0) {
32044
- navigate(`${basePath}/${entityId}/${newSelectedTab_0}`, {
32045
- replace: true
32046
- });
32047
- } else {
32048
- navigate(`${basePath}/${entityId}`, {
32049
- replace: true
32050
- });
32051
- }
32668
+ navigate(buildEntityUrl(entityId, params_0.selectedTab), {
32669
+ replace: true
32670
+ });
32052
32671
  }, parentCollectionIds }, collection.id + "_" + (isNew ? "new" : isCopy ? entityId + "_copy" : entityId)) }),
32053
32672
  /* @__PURE__ */ jsx(UnsavedChangesDialog, { open: blocker?.state === "blocked", handleOk: () => blocker?.proceed?.(), handleCancel: () => blocker?.reset?.(), body: "You have unsaved changes in this entity." })
32054
32673
  ] });
@@ -32294,7 +32913,7 @@ const Scaffold = React__default.memo(function Scaffold2(props) {
32294
32913
  const otherChildren = t3;
32295
32914
  const includeDrawer = drawerChildren.length > 0;
32296
32915
  const largeLayout = useLargeLayout();
32297
- const [drawerOpen, setDrawerOpen] = React__default.useState(false);
32916
+ const [drawerOpen, setDrawerOpen] = React__default.useState(_temp4$1);
32298
32917
  const [onHover, setOnHover] = React__default.useState(false);
32299
32918
  let t4;
32300
32919
  if ($[6] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
@@ -32306,7 +32925,12 @@ const Scaffold = React__default.memo(function Scaffold2(props) {
32306
32925
  const setOnHoverTrue = t4;
32307
32926
  let t5;
32308
32927
  if ($[7] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
32309
- t5 = () => setOnHover(false);
32928
+ t5 = () => {
32929
+ if (typeof document !== "undefined" && document.querySelector("[data-radix-popper-content-wrapper]")) {
32930
+ return;
32931
+ }
32932
+ setOnHover(false);
32933
+ };
32310
32934
  $[7] = t5;
32311
32935
  } else {
32312
32936
  t5 = $[7];
@@ -32316,6 +32940,10 @@ const Scaffold = React__default.memo(function Scaffold2(props) {
32316
32940
  if ($[8] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
32317
32941
  t6 = () => {
32318
32942
  setDrawerOpen(true);
32943
+ try {
32944
+ localStorage.setItem("firecms_drawer_open", "true");
32945
+ } catch {
32946
+ }
32319
32947
  };
32320
32948
  $[8] = t6;
32321
32949
  } else {
@@ -32326,30 +32954,36 @@ const Scaffold = React__default.memo(function Scaffold2(props) {
32326
32954
  if ($[9] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
32327
32955
  t7 = () => {
32328
32956
  setDrawerOpen(false);
32957
+ try {
32958
+ localStorage.setItem("firecms_drawer_open", "false");
32959
+ } catch {
32960
+ }
32329
32961
  };
32330
32962
  $[9] = t7;
32331
32963
  } else {
32332
32964
  t7 = $[9];
32333
32965
  }
32334
32966
  const handleDrawerClose = t7;
32335
- const computedDrawerOpen = drawerOpen || Boolean(largeLayout && autoOpenDrawer && onHover);
32967
+ const computedDrawerOpen = drawerOpen;
32968
+ const computedDrawerHovered = Boolean(largeLayout && onHover);
32336
32969
  const hasAppBar = Boolean(appBarChildren.length > 0);
32337
32970
  let t8;
32338
- if ($[10] !== autoOpenDrawer || $[11] !== computedDrawerOpen || $[12] !== includeDrawer || $[13] !== logo || $[14] !== onHover) {
32971
+ if ($[10] !== autoOpenDrawer || $[11] !== computedDrawerHovered || $[12] !== computedDrawerOpen || $[13] !== includeDrawer || $[14] !== logo) {
32339
32972
  t8 = {
32340
32973
  logo,
32341
32974
  hasDrawer: includeDrawer,
32342
- drawerHovered: onHover,
32975
+ drawerHovered: computedDrawerHovered,
32343
32976
  drawerOpen: computedDrawerOpen,
32344
32977
  closeDrawer: handleDrawerClose,
32345
32978
  openDrawer: handleDrawerOpen,
32979
+ closeHover: setOnHoverFalse,
32346
32980
  autoOpenDrawer
32347
32981
  };
32348
32982
  $[10] = autoOpenDrawer;
32349
- $[11] = computedDrawerOpen;
32350
- $[12] = includeDrawer;
32351
- $[13] = logo;
32352
- $[14] = onHover;
32983
+ $[11] = computedDrawerHovered;
32984
+ $[12] = computedDrawerOpen;
32985
+ $[13] = includeDrawer;
32986
+ $[14] = logo;
32353
32987
  $[15] = t8;
32354
32988
  } else {
32355
32989
  t8 = $[15];
@@ -32379,11 +33013,11 @@ const Scaffold = React__default.memo(function Scaffold2(props) {
32379
33013
  }
32380
33014
  const t11 = includeDrawer && drawerChildren;
32381
33015
  let t12;
32382
- if ($[20] !== computedDrawerOpen || $[21] !== includeDrawer || $[22] !== onHover || $[23] !== t11) {
32383
- t12 = /* @__PURE__ */ jsx(DrawerWrapper, { displayed: includeDrawer, onMouseEnter: setOnHoverTrue, onMouseMove: setOnHoverTrue, onMouseLeave: setOnHoverFalse, open: computedDrawerOpen, hovered: onHover, setDrawerOpen, children: t11 });
32384
- $[20] = computedDrawerOpen;
32385
- $[21] = includeDrawer;
32386
- $[22] = onHover;
33016
+ if ($[20] !== computedDrawerHovered || $[21] !== computedDrawerOpen || $[22] !== includeDrawer || $[23] !== t11) {
33017
+ t12 = /* @__PURE__ */ jsx(DrawerWrapper, { displayed: includeDrawer, onMouseEnter: setOnHoverTrue, onMouseMove: setOnHoverTrue, onMouseLeave: setOnHoverFalse, open: computedDrawerOpen, hovered: computedDrawerHovered, setDrawerOpen, children: t11 });
33018
+ $[20] = computedDrawerHovered;
33019
+ $[21] = computedDrawerOpen;
33020
+ $[22] = includeDrawer;
32387
33021
  $[23] = t11;
32388
33022
  $[24] = t12;
32389
33023
  } else {
@@ -32481,193 +33115,149 @@ const DrawerHeader = () => {
32481
33115
  return t0;
32482
33116
  };
32483
33117
  function DrawerWrapper(props) {
32484
- const $ = c(49);
33118
+ const $ = c(36);
32485
33119
  const {
32486
33120
  t
32487
33121
  } = useTranslation();
32488
- const width = !props.displayed ? 0 : props.open ? DRAWER_WIDTH : 72;
32489
- let t0;
32490
- if ($[0] !== width) {
32491
- t0 = {
32492
- width,
32493
- 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"
32494
- };
32495
- $[0] = width;
32496
- $[1] = t0;
33122
+ const layoutWidth = !props.displayed ? 0 : props.open ? DRAWER_WIDTH : 72;
33123
+ const visualWidth = !props.displayed ? 0 : props.open || props.hovered ? DRAWER_WIDTH : 72;
33124
+ const isFloating = props.hovered && !props.open;
33125
+ 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";
33126
+ let t1;
33127
+ if ($[0] !== t0) {
33128
+ t1 = cls("h-full overflow-hidden", defaultBorderMixin, t0);
33129
+ $[0] = t0;
33130
+ $[1] = t1;
32497
33131
  } else {
32498
- t0 = $[1];
33132
+ t1 = $[1];
32499
33133
  }
32500
- let t1;
32501
- if ($[2] !== props || $[3] !== t) {
32502
- t1 = !props.open && props.displayed && /* @__PURE__ */ jsx(Tooltip, { title: t("open_menu"), side: "right", sideOffset: 12, asChild: true, children: /* @__PURE__ */ 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__ */ jsx(IconButton, { color: "inherit", "aria-label": t("open_menu"), onClick: () => props.setDrawerOpen(true), size: "large", children: /* @__PURE__ */ jsx(MenuIcon, { size: "small" }) }) }) });
32503
- $[2] = props;
32504
- $[3] = t;
32505
- $[4] = t1;
33134
+ let t2;
33135
+ if ($[2] !== visualWidth) {
33136
+ t2 = {
33137
+ width: visualWidth,
33138
+ 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"
33139
+ };
33140
+ $[2] = visualWidth;
33141
+ $[3] = t2;
32506
33142
  } else {
32507
- t1 = $[4];
33143
+ t2 = $[3];
32508
33144
  }
32509
- const t2 = `z-20 absolute right-0 top-4 ${props.open ? "opacity-100" : "opacity-0 invisible"} transition-opacity duration-200 ease-in-out`;
32510
33145
  let t3;
32511
- if ($[5] !== t) {
32512
- t3 = t("close_drawer");
32513
- $[5] = t;
32514
- $[6] = t3;
33146
+ if ($[4] !== props.children) {
33147
+ t3 = /* @__PURE__ */ jsx("div", { className: "flex flex-col h-full", children: props.children });
33148
+ $[4] = props.children;
33149
+ $[5] = t3;
32515
33150
  } else {
32516
- t3 = $[6];
33151
+ t3 = $[5];
32517
33152
  }
32518
33153
  let t4;
32519
- if ($[7] !== props) {
32520
- t4 = () => props.setDrawerOpen(false);
32521
- $[7] = props;
32522
- $[8] = t4;
32523
- } else {
32524
- t4 = $[8];
32525
- }
32526
- let t5;
32527
- if ($[9] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
32528
- t5 = /* @__PURE__ */ jsx(ChevronLeftIcon, {});
32529
- $[9] = t5;
32530
- } else {
32531
- t5 = $[9];
32532
- }
32533
- let t6;
32534
- if ($[10] !== t3 || $[11] !== t4) {
32535
- t6 = /* @__PURE__ */ jsx(IconButton, { "aria-label": t3, onClick: t4, children: t5 });
32536
- $[10] = t3;
32537
- $[11] = t4;
32538
- $[12] = t6;
32539
- } else {
32540
- t6 = $[12];
32541
- }
32542
- let t7;
32543
- if ($[13] !== t2 || $[14] !== t6) {
32544
- t7 = /* @__PURE__ */ jsx("div", { className: t2, children: t6 });
32545
- $[13] = t2;
32546
- $[14] = t6;
32547
- $[15] = t7;
32548
- } else {
32549
- t7 = $[15];
32550
- }
32551
- let t8;
32552
- if ($[16] !== props.children) {
32553
- t8 = /* @__PURE__ */ jsx("div", { className: "flex flex-col h-full", children: props.children });
32554
- $[16] = props.children;
32555
- $[17] = t8;
32556
- } else {
32557
- t8 = $[17];
32558
- }
32559
- let t9;
32560
- if ($[18] !== t0 || $[19] !== t1 || $[20] !== t7 || $[21] !== t8) {
32561
- t9 = /* @__PURE__ */ jsxs("div", { className: "relative h-full no-scrollbar overflow-y-auto overflow-x-hidden", style: t0, children: [
32562
- t1,
32563
- t7,
32564
- t8
32565
- ] });
32566
- $[18] = t0;
32567
- $[19] = t1;
32568
- $[20] = t7;
32569
- $[21] = t8;
32570
- $[22] = t9;
33154
+ if ($[6] !== t1 || $[7] !== t2 || $[8] !== t3) {
33155
+ t4 = /* @__PURE__ */ jsx("div", { className: t1, style: t2, children: t3 });
33156
+ $[6] = t1;
33157
+ $[7] = t2;
33158
+ $[8] = t3;
33159
+ $[9] = t4;
32571
33160
  } else {
32572
- t9 = $[22];
33161
+ t4 = $[9];
32573
33162
  }
32574
- const innerDrawer = t9;
33163
+ const innerDrawer = t4;
32575
33164
  const largeLayout = useLargeLayout();
32576
33165
  if (!largeLayout) {
32577
33166
  if (!props.displayed) {
32578
33167
  return null;
32579
33168
  }
32580
- let t102;
32581
- if ($[23] !== t) {
32582
- t102 = t("open_menu");
32583
- $[23] = t;
32584
- $[24] = t102;
33169
+ let t52;
33170
+ if ($[10] !== t) {
33171
+ t52 = t("open_menu");
33172
+ $[10] = t;
33173
+ $[11] = t52;
32585
33174
  } else {
32586
- t102 = $[24];
33175
+ t52 = $[11];
32587
33176
  }
32588
- let t112;
32589
- if ($[25] !== props) {
32590
- t112 = () => props.setDrawerOpen(true);
32591
- $[25] = props;
32592
- $[26] = t112;
33177
+ let t62;
33178
+ if ($[12] !== props) {
33179
+ t62 = () => props.setDrawerOpen(true);
33180
+ $[12] = props;
33181
+ $[13] = t62;
32593
33182
  } else {
32594
- t112 = $[26];
33183
+ t62 = $[13];
32595
33184
  }
32596
- let t12;
32597
- if ($[27] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
32598
- t12 = /* @__PURE__ */ jsx(MenuIcon, {});
32599
- $[27] = t12;
33185
+ let t7;
33186
+ if ($[14] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
33187
+ t7 = /* @__PURE__ */ jsx(MenuIcon, {});
33188
+ $[14] = t7;
32600
33189
  } else {
32601
- t12 = $[27];
33190
+ t7 = $[14];
32602
33191
  }
32603
- let t13;
32604
- if ($[28] !== t102 || $[29] !== t112) {
32605
- t13 = /* @__PURE__ */ jsx(IconButton, { color: "inherit", "aria-label": t102, onClick: t112, size: "large", className: "absolute sm:top-2 sm:left-4 top-1 left-2", children: t12 });
32606
- $[28] = t102;
32607
- $[29] = t112;
32608
- $[30] = t13;
33192
+ let t8;
33193
+ if ($[15] !== t52 || $[16] !== t62) {
33194
+ t8 = /* @__PURE__ */ jsx(IconButton, { color: "inherit", "aria-label": t52, onClick: t62, size: "large", className: "absolute sm:top-2 sm:left-4 top-1 left-2", children: t7 });
33195
+ $[15] = t52;
33196
+ $[16] = t62;
33197
+ $[17] = t8;
32609
33198
  } else {
32610
- t13 = $[30];
33199
+ t8 = $[17];
32611
33200
  }
32612
- const t14 = props.open;
32613
- const t15 = props.setDrawerOpen;
32614
- let t16;
32615
- if ($[31] !== t) {
32616
- t16 = t("navigation_drawer");
32617
- $[31] = t;
32618
- $[32] = t16;
33201
+ const t9 = props.open;
33202
+ const t10 = props.setDrawerOpen;
33203
+ let t11;
33204
+ if ($[18] !== t) {
33205
+ t11 = t("navigation_drawer");
33206
+ $[18] = t;
33207
+ $[19] = t11;
32619
33208
  } else {
32620
- t16 = $[32];
33209
+ t11 = $[19];
32621
33210
  }
32622
- let t17;
32623
- if ($[33] !== innerDrawer || $[34] !== props.open || $[35] !== props.setDrawerOpen || $[36] !== t16) {
32624
- t17 = /* @__PURE__ */ jsx(Sheet, { side: "left", transparent: true, open: t14, onOpenChange: t15, title: t16, overlayClassName: "bg-white bg-opacity-80 bg-white/80", children: innerDrawer });
32625
- $[33] = innerDrawer;
32626
- $[34] = props.open;
32627
- $[35] = props.setDrawerOpen;
32628
- $[36] = t16;
32629
- $[37] = t17;
33211
+ let t12;
33212
+ if ($[20] !== innerDrawer || $[21] !== props.open || $[22] !== props.setDrawerOpen || $[23] !== t11) {
33213
+ t12 = /* @__PURE__ */ jsx(Sheet, { side: "left", transparent: true, open: t9, onOpenChange: t10, title: t11, overlayClassName: "bg-white bg-opacity-80 bg-white/80", children: innerDrawer });
33214
+ $[20] = innerDrawer;
33215
+ $[21] = props.open;
33216
+ $[22] = props.setDrawerOpen;
33217
+ $[23] = t11;
33218
+ $[24] = t12;
32630
33219
  } else {
32631
- t17 = $[37];
33220
+ t12 = $[24];
32632
33221
  }
32633
- let t18;
32634
- if ($[38] !== t13 || $[39] !== t17) {
32635
- t18 = /* @__PURE__ */ jsxs(Fragment, { children: [
32636
- t13,
32637
- t17
33222
+ let t13;
33223
+ if ($[25] !== t12 || $[26] !== t8) {
33224
+ t13 = /* @__PURE__ */ jsxs(Fragment, { children: [
33225
+ t8,
33226
+ t12
32638
33227
  ] });
32639
- $[38] = t13;
32640
- $[39] = t17;
32641
- $[40] = t18;
33228
+ $[25] = t12;
33229
+ $[26] = t8;
33230
+ $[27] = t13;
32642
33231
  } else {
32643
- t18 = $[40];
33232
+ t13 = $[27];
32644
33233
  }
32645
- return t18;
33234
+ return t13;
32646
33235
  }
32647
- let t10;
32648
- if ($[41] !== width) {
32649
- t10 = {
32650
- width,
32651
- 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"
33236
+ let t5;
33237
+ if ($[28] !== layoutWidth) {
33238
+ t5 = {
33239
+ width: layoutWidth,
33240
+ minWidth: layoutWidth,
33241
+ 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"
32652
33242
  };
32653
- $[41] = width;
32654
- $[42] = t10;
33243
+ $[28] = layoutWidth;
33244
+ $[29] = t5;
32655
33245
  } else {
32656
- t10 = $[42];
33246
+ t5 = $[29];
32657
33247
  }
32658
- let t11;
32659
- if ($[43] !== innerDrawer || $[44] !== props.onMouseEnter || $[45] !== props.onMouseLeave || $[46] !== props.onMouseMove || $[47] !== t10) {
32660
- t11 = /* @__PURE__ */ jsx("div", { className: "z-20 relative", onMouseEnter: props.onMouseEnter, onMouseMove: props.onMouseMove, onMouseLeave: props.onMouseLeave, style: t10, children: innerDrawer });
32661
- $[43] = innerDrawer;
32662
- $[44] = props.onMouseEnter;
32663
- $[45] = props.onMouseLeave;
32664
- $[46] = props.onMouseMove;
32665
- $[47] = t10;
32666
- $[48] = t11;
33248
+ let t6;
33249
+ if ($[30] !== innerDrawer || $[31] !== props.onMouseEnter || $[32] !== props.onMouseLeave || $[33] !== props.onMouseMove || $[34] !== t5) {
33250
+ t6 = /* @__PURE__ */ jsx("div", { className: "z-20 relative flex-shrink-0 overflow-visible", onMouseEnter: props.onMouseEnter, onMouseMove: props.onMouseMove, onMouseLeave: props.onMouseLeave, style: t5, children: innerDrawer });
33251
+ $[30] = innerDrawer;
33252
+ $[31] = props.onMouseEnter;
33253
+ $[32] = props.onMouseLeave;
33254
+ $[33] = props.onMouseMove;
33255
+ $[34] = t5;
33256
+ $[35] = t6;
32667
33257
  } else {
32668
- t11 = $[48];
33258
+ t6 = $[35];
32669
33259
  }
32670
- return t11;
33260
+ return t6;
32671
33261
  }
32672
33262
  function _temp$6(child) {
32673
33263
  return child.type.componentType === "Drawer";
@@ -32678,6 +33268,13 @@ function _temp2$1(child_0) {
32678
33268
  function _temp3$1(child_1) {
32679
33269
  return child_1.type.componentType !== "Drawer" && child_1.type.componentType !== "AppBar";
32680
33270
  }
33271
+ function _temp4$1() {
33272
+ try {
33273
+ return localStorage.getItem("firecms_drawer_open") === "true";
33274
+ } catch {
33275
+ return false;
33276
+ }
33277
+ }
32681
33278
  const en = {
32682
33279
  // ─── Form actions ────────────────────────────────────────────
32683
33280
  save: "Save",
@@ -32815,8 +33412,8 @@ const en = {
32815
33412
  // ─── Error states ─────────────────────────────────────────────
32816
33413
  error: "Error",
32817
33414
  error_uploading_file: "Error uploading file",
32818
- error_deleting: "Error deleting",
32819
- error_before_delete: "Error before delete",
33415
+ error_deleting: "Error deleting: {{message}}",
33416
+ error_before_delete: "Error before delete: {{message}}",
32820
33417
  error_updating_asset: "Error updating asset",
32821
33418
  error_deleting_asset: "Error deleting asset",
32822
33419
  error_firestore_index: "A Firestore index is required for this query.",
@@ -33153,10 +33750,18 @@ const en = {
33153
33750
  auto_setup_collections_button: "Automatically set up collections",
33154
33751
  auto_setup_collections_title: "Automatically set up collections?",
33155
33752
  auto_setup_collections_desc: "This will automatically create collection configs for collections that are <b>NOT</b> already mapped",
33156
- this_can_take_a_minute: "This can take a minute or two",
33753
+ setting_up_collections: "Setting up collections",
33754
+ setting_up_collection: "Setting up {{name}}",
33157
33755
  no_collections_found_to_setup: "No collections found to setup.",
33158
33756
  collections_have_been_setup: "Collections have been automatically setup.",
33159
33757
  error_setting_up_collections: "Error automatically setting up collections",
33758
+ setup_collections_title: "Set up collections",
33759
+ setup_collections_select_desc: "Select which collections to automatically set up:",
33760
+ select_all: "Select all",
33761
+ deselect_all: "Deselect all",
33762
+ setup_collections_confirm: "Set up ({{count}})",
33763
+ collection_setup_success: "{{name}} has been set up",
33764
+ go_to_collection: "Go to collection",
33160
33765
  // --- Home Suggestions ---
33161
33766
  add_your: "Add your",
33162
33767
  database_collections: "database collections",
@@ -33484,8 +34089,8 @@ const es = {
33484
34089
  // ─── Error states ─────────────────────────────────────────────
33485
34090
  error: "Error",
33486
34091
  error_uploading_file: "Error al subir archivo",
33487
- error_deleting: "Error al eliminar",
33488
- error_before_delete: "Error antes de eliminar",
34092
+ error_deleting: "Error al eliminar: {{message}}",
34093
+ error_before_delete: "Error antes de eliminar: {{message}}",
33489
34094
  error_updating_asset: "Error al actualizar recurso",
33490
34095
  error_deleting_asset: "Error al eliminar recurso",
33491
34096
  error_firestore_index: "Se requiere un índice de Firestore para esta consulta.",
@@ -33824,10 +34429,18 @@ const es = {
33824
34429
  auto_setup_collections_button: "Configurar colecciones automáticamente",
33825
34430
  auto_setup_collections_title: "¿Configurar colecciones automáticamente?",
33826
34431
  auto_setup_collections_desc: "Esto creará automáticamente la configuración de las colecciones que <b>NO</b> estén mapeadas",
33827
- this_can_take_a_minute: "Esto puede tardar un minuto o dos",
34432
+ setting_up_collections: "Configurando colecciones",
34433
+ setting_up_collection: "Configurando {{name}}",
33828
34434
  no_collections_found_to_setup: "No se encontraron colecciones para configurar",
33829
34435
  collections_have_been_setup: "¡Tus colecciones han sido configuradas!",
33830
34436
  error_setting_up_collections: "Error al configurar colecciones",
34437
+ setup_collections_title: "Set up collections",
34438
+ setup_collections_select_desc: "Select which collections to automatically set up:",
34439
+ select_all: "Select all",
34440
+ deselect_all: "Deselect all",
34441
+ setup_collections_confirm: "Set up ({{count}})",
34442
+ collection_setup_success: "{{name}} has been set up",
34443
+ go_to_collection: "Go to collection",
33831
34444
  // --- Home Suggestions ---
33832
34445
  add_your: "Añade tus",
33833
34446
  database_collections: "colecciones de base de datos",
@@ -34157,8 +34770,8 @@ const de = {
34157
34770
  // ─── Error states ─────────────────────────────────────────────
34158
34771
  error: "Fehler",
34159
34772
  error_uploading_file: "Fehler beim Hochladen der Datei",
34160
- error_deleting: "Fehler beim Löschen",
34161
- error_before_delete: "Fehler vor dem Löschen",
34773
+ error_deleting: "Fehler beim Löschen: {{message}}",
34774
+ error_before_delete: "Fehler vor dem Löschen: {{message}}",
34162
34775
  error_updating_asset: "Fehler beim Aktualisieren des Assets",
34163
34776
  error_deleting_asset: "Fehler beim Löschen des Assets",
34164
34777
  error_firestore_index: "Für diese Abfrage ist ein Firestore-Index erforderlich.",
@@ -34495,10 +35108,18 @@ const de = {
34495
35108
  auto_setup_collections_button: "Sammlungen automatisch einrichten",
34496
35109
  auto_setup_collections_title: "Sammlungen automatisch einrichten?",
34497
35110
  auto_setup_collections_desc: "Dadurch werden automatisch Sammlungskonfigurationen für Sammlungen erstellt, die noch <b>NICHT</b> zugeordnet sind.",
34498
- this_can_take_a_minute: "Dies kann ein bis zwei Minuten dauern",
35111
+ setting_up_collections: "Sammlungen werden eingerichtet",
35112
+ setting_up_collection: "{{name}} wird eingerichtet",
34499
35113
  no_collections_found_to_setup: "Keine einzurichtenden Sammlungen gefunden",
34500
35114
  collections_have_been_setup: "Sammlungen wurden automatisch eingerichtet",
34501
35115
  error_setting_up_collections: "Fehler beim automatischen Einrichten der Sammlungen",
35116
+ setup_collections_title: "Set up collections",
35117
+ setup_collections_select_desc: "Select which collections to automatically set up:",
35118
+ select_all: "Select all",
35119
+ deselect_all: "Deselect all",
35120
+ setup_collections_confirm: "Set up ({{count}})",
35121
+ collection_setup_success: "{{name}} has been set up",
35122
+ go_to_collection: "Go to collection",
34502
35123
  add_your: "Fügen Sie Ihre",
34503
35124
  database_collections: "Datenbanksammlungen",
34504
35125
  to_firecms: "zu FireCMS hinzu",
@@ -34826,8 +35447,8 @@ const fr = {
34826
35447
  // ─── Error states ─────────────────────────────────────────────
34827
35448
  error: "Erreur",
34828
35449
  error_uploading_file: "Erreur lors du téléchargement du fichier",
34829
- error_deleting: "Erreur lors de la suppression",
34830
- error_before_delete: "Erreur avant la suppression",
35450
+ error_deleting: "Erreur lors de la suppression: {{message}}",
35451
+ error_before_delete: "Erreur avant la suppression: {{message}}",
34831
35452
  error_updating_asset: "Erreur lors de la mise à jour de l'actif",
34832
35453
  error_deleting_asset: "Erreur lors de la suppression de l'actif",
34833
35454
  error_firestore_index: "Un index Firestore est requis pour cette requête.",
@@ -35164,10 +35785,18 @@ const fr = {
35164
35785
  auto_setup_collections_button: "Configurer les collections automatiquement",
35165
35786
  auto_setup_collections_title: "Configurer les collections automatiquement ?",
35166
35787
  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",
35167
- this_can_take_a_minute: "Cela peut prendre une minute",
35788
+ setting_up_collections: "Configuration des collections",
35789
+ setting_up_collection: "Configuration de {{name}}",
35168
35790
  no_collections_found_to_setup: "Aucune collection à configurer trouvée",
35169
35791
  collections_have_been_setup: "Les collections ont été configurées",
35170
35792
  error_setting_up_collections: "Erreur lors de la configuration des collections",
35793
+ setup_collections_title: "Set up collections",
35794
+ setup_collections_select_desc: "Select which collections to automatically set up:",
35795
+ select_all: "Select all",
35796
+ deselect_all: "Deselect all",
35797
+ setup_collections_confirm: "Set up ({{count}})",
35798
+ collection_setup_success: "{{name}} has been set up",
35799
+ go_to_collection: "Go to collection",
35171
35800
  add_your: "Ajoutez vos",
35172
35801
  database_collections: "collections de base de données",
35173
35802
  to_firecms: "à FireCMS",
@@ -35495,8 +36124,8 @@ const it = {
35495
36124
  // ─── Error states ─────────────────────────────────────────────
35496
36125
  error: "Errore",
35497
36126
  error_uploading_file: "Errore durante il caricamento del file",
35498
- error_deleting: "Errore durante l'eliminazione",
35499
- error_before_delete: "Errore prima dell'eliminazione",
36127
+ error_deleting: "Errore durante l'eliminazione: {{message}}",
36128
+ error_before_delete: "Errore prima dell'eliminazione: {{message}}",
35500
36129
  error_updating_asset: "Errore durante l'aggiornamento dell'asset",
35501
36130
  error_deleting_asset: "Errore durante l'eliminazione dell'asset",
35502
36131
  error_firestore_index: "Per questa query è richiesto un indice Firestore.",
@@ -35833,10 +36462,18 @@ const it = {
35833
36462
  auto_setup_collections_button: "Configura le collezioni automaticamente",
35834
36463
  auto_setup_collections_title: "Configurazione automatica delle collezioni",
35835
36464
  auto_setup_collections_desc: "Configura le collezioni automaticamente in base ai dati Firestore esistenti. Lascia che FireCMS configuri il CMS perfetto per te.",
35836
- this_can_take_a_minute: "Potrebbe richiedere qualche minuto",
36465
+ setting_up_collections: "Configurazione delle collezioni",
36466
+ setting_up_collection: "Configurazione di {{name}}",
35837
36467
  no_collections_found_to_setup: "Nessuna collezione trovata da configurare",
35838
36468
  collections_have_been_setup: "Le collezioni sono state configurate",
35839
36469
  error_setting_up_collections: "Errore durante la configurazione delle collezioni",
36470
+ setup_collections_title: "Set up collections",
36471
+ setup_collections_select_desc: "Select which collections to automatically set up:",
36472
+ select_all: "Select all",
36473
+ deselect_all: "Deselect all",
36474
+ setup_collections_confirm: "Set up ({{count}})",
36475
+ collection_setup_success: "{{name}} has been set up",
36476
+ go_to_collection: "Go to collection",
35840
36477
  add_your: "Aggiungi le tue",
35841
36478
  database_collections: "collezioni del database",
35842
36479
  to_firecms: "a FireCMS",
@@ -36164,8 +36801,8 @@ const hi = {
36164
36801
  // ─── Error states ─────────────────────────────────────────────
36165
36802
  error: "त्रुटि",
36166
36803
  error_uploading_file: "फ़ाइल अपलोड करने में त्रुटि",
36167
- error_deleting: "हटाने में त्रुटि",
36168
- error_before_delete: "हटाने से पहले त्रुटि",
36804
+ error_deleting: "हटाने में त्रुटि: {{message}}",
36805
+ error_before_delete: "हटाने से पहले त्रुटि: {{message}}",
36169
36806
  error_updating_asset: "एसेट अपडेट करने में त्रुटि",
36170
36807
  error_deleting_asset: "एसेट हटाने में त्रुटि",
36171
36808
  error_firestore_index: "इस क्वेरी के लिए Firestore इंडेक्स आवश्यक है।",
@@ -36502,10 +37139,18 @@ const hi = {
36502
37139
  auto_setup_collections_button: "संग्रहों को स्वचालित रूप से सेट करें",
36503
37140
  auto_setup_collections_title: "संग्रहों की स्वचालित सेटअप",
36504
37141
  auto_setup_collections_desc: "अपने मौजूदा Firestore डेटा के आधार पर संग्रहों को स्वचालित रूप से सेट करें। FireCMS को आपके लिए परफेक्ट CMS कॉन्फ़िगर करने दें।",
36505
- this_can_take_a_minute: "इसमें एक मिनट लग सकता है",
37142
+ setting_up_collections: "संग्रह सेट किए जा रहे हैं",
37143
+ setting_up_collection: "{{name}} सेट किया जा रहा है",
36506
37144
  no_collections_found_to_setup: "सेट करने के लिए कोई संग्रह नहीं मिला",
36507
37145
  collections_have_been_setup: "संग्रहों को सेट कर दिया गया है",
36508
37146
  error_setting_up_collections: "संग्रह सेट करने में त्रुटि",
37147
+ setup_collections_title: "Set up collections",
37148
+ setup_collections_select_desc: "Select which collections to automatically set up:",
37149
+ select_all: "Select all",
37150
+ deselect_all: "Deselect all",
37151
+ setup_collections_confirm: "Set up ({{count}})",
37152
+ collection_setup_success: "{{name}} has been set up",
37153
+ go_to_collection: "Go to collection",
36509
37154
  add_your: "अपने",
36510
37155
  database_collections: "डेटाबेस संग्रह",
36511
37156
  to_firecms: "को FireCMS में जोड़ें",
@@ -36833,8 +37478,8 @@ const pt = {
36833
37478
  // ─── Error states ─────────────────────────────────────────────
36834
37479
  error: "Erro",
36835
37480
  error_uploading_file: "Erro ao carregar ficheiro",
36836
- error_deleting: "Erro ao eliminar",
36837
- error_before_delete: "Erro antes de eliminar",
37481
+ error_deleting: "Erro ao eliminar: {{message}}",
37482
+ error_before_delete: "Erro antes de eliminar: {{message}}",
36838
37483
  error_updating_asset: "Erro ao atualizar recurso",
36839
37484
  error_deleting_asset: "Erro ao eliminar recurso",
36840
37485
  error_firestore_index: "É necessário um índice Firestore para esta consulta.",
@@ -37171,10 +37816,18 @@ const pt = {
37171
37816
  auto_setup_collections_button: "Configurar coleções automaticamente",
37172
37817
  auto_setup_collections_title: "Configurar coleções automaticamente?",
37173
37818
  auto_setup_collections_desc: "Isto criará automaticamente configurações de coleção para coleções que <b>NÃO</b> estão já mapeadas",
37174
- this_can_take_a_minute: "Isto pode demorar um ou dois minutos",
37819
+ setting_up_collections: "Configurando coleções",
37820
+ setting_up_collection: "Configurando {{name}}",
37175
37821
  no_collections_found_to_setup: "Nenhuma coleção encontrada para configurar.",
37176
37822
  collections_have_been_setup: "As coleções foram configuradas automaticamente.",
37177
37823
  error_setting_up_collections: "Erro ao configurar coleções automaticamente",
37824
+ setup_collections_title: "Set up collections",
37825
+ setup_collections_select_desc: "Select which collections to automatically set up:",
37826
+ select_all: "Select all",
37827
+ deselect_all: "Deselect all",
37828
+ setup_collections_confirm: "Set up ({{count}})",
37829
+ collection_setup_success: "{{name}} has been set up",
37830
+ go_to_collection: "Go to collection",
37178
37831
  // --- Home Suggestions ---
37179
37832
  add_your: "Adicione as suas",
37180
37833
  database_collections: "coleções da base de dados",
@@ -37367,6 +38020,685 @@ const pt = {
37367
38020
  marketplace_link_error: "Erro ao vincular o projeto. Por favor, tente novamente.",
37368
38021
  marketplace_no_account_id: "Nenhum ID de conta do GCP Marketplace encontrado. Por favor, comece pelo GCP Marketplace."
37369
38022
  };
38023
+ const pl = {
38024
+ // ─── Form actions ────────────────────────────────────────────
38025
+ save: "Zapisz",
38026
+ create: "Utwórz",
38027
+ create_copy: "Utwórz kopię",
38028
+ save_and_close: "Zapisz i zamknij",
38029
+ create_copy_and_close: "Utwórz kopię i zamknij",
38030
+ create_and_close: "Utwórz i zamknij",
38031
+ discard: "Odrzuć",
38032
+ clear: "Wyczyść",
38033
+ cancel: "Anuluj",
38034
+ // ─── Entity actions ──────────────────────────────────────────
38035
+ edit: "Edytuj",
38036
+ copy: "Kopiuj",
38037
+ delete: "Usuń",
38038
+ // ─── Delete dialog ───────────────────────────────────────────
38039
+ delete_confirmation_title: "Usunąć?",
38040
+ delete_confirmation_body: "Spowoduje to usunięcie encji. Czy na pewno chcesz kontynuować?",
38041
+ delete_multiple_confirmation_body: "Spowoduje to usunięcie zaznaczonych encji. Czy na pewno chcesz kontynuować?",
38042
+ // ─── Unsaved-changes dialog ───────────────────────────────────
38043
+ unsaved_changes_title: "Niezapisane zmiany",
38044
+ unsaved_changes_body: "Masz niezapisane zmiany. Czy chcesz je odrzucić?",
38045
+ discard_changes: "Odrzuć zmiany",
38046
+ keep_editing: "Kontynuuj edycję",
38047
+ // ─── Collection table / toolbar ──────────────────────────────
38048
+ search: "Szukaj",
38049
+ find_by_id: "Znajdź po ID",
38050
+ find_entity_by_id: "Znajdź encję po ID",
38051
+ filter: "Filtr",
38052
+ filters: "Filtry",
38053
+ clear_filter: "Wyczyść filtr",
38054
+ clear_filter_sort: "Wyczyść filtr/sortowanie",
38055
+ clear_sort: "Wyczyść sortowanie",
38056
+ no_items: "Brak elementów",
38057
+ no_entries_found: "Nie znaleziono wpisów",
38058
+ all_entries_loaded: "Wczytano wszystkie wpisy ({{count}})",
38059
+ create_your_first_entry: "Utwórz swój pierwszy wpis",
38060
+ no_results_filter_sort: "Brak wyników dla zastosowanego filtra/sortowania",
38061
+ add: "Dodaj",
38062
+ remove: "Usuń",
38063
+ multiple_entities: "Wiele encji",
38064
+ unsaved_changes: "Masz niezapisane zmiany w kolekcji {{collectionName}}.",
38065
+ so_empty: "Tak pusto...",
38066
+ no_results: "Brak wyników dla zastosowanego filtra/sortowania",
38067
+ refresh_data: "Odśwież dane",
38068
+ dark_mode: "Ciemny",
38069
+ light_mode: "Jasny",
38070
+ system_mode: "Systemowy",
38071
+ ok: "Ok",
38072
+ save_collection_config: "Zapisz strukturę kolekcji",
38073
+ search_for_more_icons: "Szukaj więcej ikon…",
38074
+ ai_modified: "Zmodyfikowane przez AI",
38075
+ size_label: "Rozmiar",
38076
+ group_by: "Grupuj według",
38077
+ initialize_kanban_order: "Zainicjuj kolejność Kanban",
38078
+ copy_id: "Kopiuj ID",
38079
+ add_specific: "Dodaj {{name}}",
38080
+ select_specific: "Wybierz {{name}}",
38081
+ select_from: "Wybierz z {{name}}",
38082
+ done: "Gotowe",
38083
+ log_out: "Wyloguj się",
38084
+ license_needed: "Wymagana licencja",
38085
+ license_description: "Aby korzystać z FireCMS PRO, potrzebujesz ważnej licencji. Skontaktuj się z nami pod adresem {{email}}, aby uzyskać więcej informacji.",
38086
+ column_cannot_be_edited: "Ta kolumna nie może być edytowana bezpośrednio",
38087
+ close: "Zamknij",
38088
+ unsaved_local_changes: "Niezapisane zmiany lokalne",
38089
+ unsaved_local_changes_description: "Ten dokument został zmodyfikowany lokalnie i zawiera niezapisane zmiany. Zmiany te zostaną utracone, jeśli ich nie zastosujesz.",
38090
+ preview_changes: "Podgląd zmian",
38091
+ apply_changes: "Zastosuj zmiany",
38092
+ discard_local_changes: "Odrzuć zmiany lokalne",
38093
+ preview_local_changes: "Podgląd zmian lokalnych",
38094
+ preview_local_changes_description: "To są zmiany lokalne, które zostaną zastosowane do formularza.",
38095
+ type: "Typ",
38096
+ string: "tekst",
38097
+ number: "liczba",
38098
+ boolean: "wartość logiczna",
38099
+ date: "data",
38100
+ map: "mapa",
38101
+ array: "tablica",
38102
+ arrays_of_arrays_not_supported: "Tablice tablic nie są obsługiwane.",
38103
+ data_type_not_supported: "Typ danych {{dataType}} nie jest jeszcze obsługiwany",
38104
+ passkey_error_unsupported: "Twoje urządzenie lub przeglądarka nie obsługuje kluczy dostępu (passkeys).",
38105
+ admin: "Administrator",
38106
+ home: "Strona główna",
38107
+ this_form_has_errors: "Ten formularz zawiera błędy",
38108
+ error_loading_navigation: "Błąd wczytywania nawigacji",
38109
+ error_loading_auth: "Błąd wczytywania uwierzytelniania",
38110
+ this_form_has_been_modified: "Ten formularz został zmodyfikowany",
38111
+ current_form_in_sync: "Bieżący formularz jest zsynchronizowany z bazą danych",
38112
+ open_in_console: "Otwórz w konsoli",
38113
+ collection_does_not_exist: "Podana kolekcja nie istnieje. Sprawdź konsolę",
38114
+ unexpected_value: "Nieoczekiwana wartość",
38115
+ unexpected_value_click_to_edit: "Nieoczekiwana wartość. Kliknij, aby edytować",
38116
+ unexpected_reference_value: "Nieoczekiwana wartość referencji. Kliknij, aby edytować",
38117
+ copy_url_to_clipboard: "Kopiuj adres URL do schowka",
38118
+ open_image_in_new_tab: "Otwórz obraz w nowej karcie",
38119
+ reference_not_set: "Referencja nie ustawiona",
38120
+ reference_does_not_exist: "Referencja nie istnieje",
38121
+ entity_not_found: "Nie znaleziono encji",
38122
+ file_not_found: "Nie znaleziono pliku",
38123
+ unsaved_changes_in_entity: "Masz niezapisane zmiany w tej encji.",
38124
+ delete_this_role: "Usuń tę rolę",
38125
+ no_roles_yet: "Nie masz jeszcze żadnych ról.",
38126
+ create_default_roles: "Utwórz domyślne role",
38127
+ delete_role_confirmation: "Czy na pewno chcesz usunąć tę rolę?",
38128
+ delete_this_user: "Usuń tego użytkownika",
38129
+ no_users_yet: "Nie ma jeszcze żadnych użytkowników",
38130
+ add_logged_user_as_admin: "Dodaj zalogowanego użytkownika jako administratora",
38131
+ add_current_user_as_admin: "Dodaj bieżącego użytkownika jako administratora",
38132
+ create_default_roles_and_add_admin: "Utwórz domyślne role i dodaj bieżącego użytkownika jako administratora",
38133
+ delete_user_confirmation: "Czy na pewno chcesz usunąć tego użytkownika?",
38134
+ create_your_users_and_roles: "Utwórz użytkowników i role",
38135
+ 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.",
38136
+ save_before_changing_schema: "Musisz zapisać dokument przed zmianą schematu",
38137
+ edit_schema_for_this_form: "Edytuj schemat tego formularza",
38138
+ no_permissions_to_edit_collection: "Nie masz uprawnień do edycji tej kolekcji",
38139
+ browser_does_not_support_audio: "Twoja przeglądarka nie obsługuje elementu audio.",
38140
+ user_not_found: "Nie znaleziono użytkownika: {{value}}",
38141
+ // ─── Collection view actions ──────────────────────────────────
38142
+ delete_selected: "Usuń",
38143
+ cannot_delete_selected: "Zaznaczono co najmniej jedną encję, której nie można usunąć",
38144
+ // ─── Array / field containers ─────────────────────────────────
38145
+ add_entry: "Dodaj",
38146
+ add_on_top: "Dodaj na górze",
38147
+ add_below: "Dodaj poniżej",
38148
+ add_to_field: "Dodaj do {{fieldName}}",
38149
+ value: "Wartość",
38150
+ key: "Klucz",
38151
+ drag_drop_multiple: "Przeciągnij i upuść pliki tutaj lub kliknij, aby je wybrać. Przeciągnij, aby zmienić kolejność.",
38152
+ drag_drop_single: "Przeciągnij i upuść plik tutaj lub kliknij, aby go wybrać",
38153
+ // ─── Navigation / scaffold ────────────────────────────────────
38154
+ open_menu: "Otwórz menu",
38155
+ close_drawer: "Zamknij panel boczny",
38156
+ navigation_drawer: "Panel nawigacyjny",
38157
+ // ─── Error states ─────────────────────────────────────────────
38158
+ error: "Błąd",
38159
+ error_uploading_file: "Błąd przesyłania pliku",
38160
+ error_deleting: "Błąd podczas usuwania: {{message}}",
38161
+ error_before_delete: "Błąd przed usunięciem: {{message}}",
38162
+ error_updating_asset: "Błąd aktualizacji zasobu",
38163
+ error_deleting_asset: "Błąd usuwania zasobu",
38164
+ error_firestore_index: "Dla tego zapytania wymagany jest indeks Firestore.",
38165
+ create_index: "Utwórz indeks",
38166
+ value_is_not_reference: "Wartość nie jest referencją.",
38167
+ click_to_edit: "Kliknij, aby edytować",
38168
+ data_is_not_array_of_references: "Dane nie są tablicą referencji",
38169
+ // ─── Misc ─────────────────────────────────────────────────────
38170
+ loading: "Wczytywanie",
38171
+ local_changes_applied: "Zmiany lokalne zastosowane w formularzu",
38172
+ local_changes_discarded: "Zmiany lokalne odrzucone",
38173
+ are_you_sure_leave: "Czy na pewno chcesz opuścić tę stronę?",
38174
+ see_console_details: "Więcej informacji w konsoli.",
38175
+ drop_here_create_group: "Upuść tutaj, aby utworzyć nową grupę",
38176
+ filter_for_null_values: "Filtruj puste wartości",
38177
+ value_updated_elsewhere: "Ta wartość została zaktualizowana gdzie indziej",
38178
+ add_property: "Dodaj właściwość",
38179
+ edit_name: "Edytuj {{name}}",
38180
+ this_entity_not_exist: "Ta encja nie istnieje w bazie danych",
38181
+ internal_error: "BŁĄD wewnętrzny",
38182
+ // ─── Rename group dialog ──────────────────────────────────────
38183
+ rename_group: "Zmień nazwę grupy",
38184
+ group_name_label: "Nazwa grupy",
38185
+ group_name_empty_error: "Nazwa grupy nie może być pusta.",
38186
+ group_name_exists_error: "Taka nazwa grupy już istnieje.",
38187
+ // ─── Search ───────────────────────────────────────────────────
38188
+ search_collections: "Szukaj kolekcji",
38189
+ // ─── Navigation groups ────────────────────────────────────────
38190
+ views_group: "Widoki",
38191
+ // ─── Entity Edit View ─────────────────────────────────────────
38192
+ youd_need_to_save_before_additional_collections: "Musisz zapisać encję przed dodaniem kolejnych kolekcji",
38193
+ // ─── Not Found Page ───────────────────────────────────────────
38194
+ page_not_found: "Nie znaleziono strony",
38195
+ page_not_found_body: "Ta strona nie istnieje lub nie masz do niej dostępu",
38196
+ back_to_home: "Wróć do strony głównej",
38197
+ // ─── Collection Editor ─────────────────────────────────────────
38198
+ default_collection_view: "Domyślny widok kolekcji",
38199
+ table_view: "Tabela",
38200
+ cards_view: "Karty",
38201
+ kanban_view: "Kanban",
38202
+ choose_how_entities_displayed_default: "Wybierz, jak encje mają być domyślnie wyświetlane",
38203
+ document_view: "Widok dokumentu",
38204
+ side_panel: "Panel boczny",
38205
+ full_screen: "Pełny ekran",
38206
+ should_documents_opened_full_screen: "Czy dokumenty mają być otwierane na pełnym ekranie, czy w bocznym oknie dialogowym",
38207
+ select_custom_view: "Wybierz widok niestandardowy",
38208
+ no_custom_views_defined: "Nie zdefiniowano żadnych widoków niestandardowych. Zdefiniuj je w ustawieniach dostosowywania przed użyciem tego okna dialogowego.",
38209
+ select_custom_action: "Wybierz akcję niestandardową",
38210
+ no_custom_actions_defined: "Nie zdefiniowano żadnych akcji niestandardowych. Zdefiniuj je w ustawieniach dostosowywania przed użyciem tego okna dialogowego.",
38211
+ no_collections_found: "Nie znaleziono kolekcji",
38212
+ 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.",
38213
+ create_first_collection: "Utwórz swoją pierwszą kolekcję",
38214
+ define_collections_programmatically: "Kolekcje możesz też definiować programistycznie.",
38215
+ edit_collection: "Edytuj kolekcję",
38216
+ no_permissions_edit_collection: "Nie masz uprawnień do edycji tej kolekcji",
38217
+ no_permissions_create_collection: "Nie masz uprawnień do tworzenia kolekcji",
38218
+ create_collection: "Utwórz kolekcję",
38219
+ update_collection: "Zaktualizuj kolekcję",
38220
+ new_collection: "Nowa kolekcja",
38221
+ add_new_collection: "Dodaj nową kolekcję",
38222
+ collection_with_name: "Kolekcja {{name}}",
38223
+ change_icon: "Zmień ikonę",
38224
+ is_subcollection_of: "To jest podkolekcja",
38225
+ name: "Nazwa",
38226
+ collection_name_description: "Nazwa tej kolekcji, zwykle w liczbie mnogiej (np. Produkty)",
38227
+ path: "Ścieżka",
38228
+ relative_path_to_parent: "Ścieżka względna do elementu nadrzędnego (nie trzeba podawać ścieżki nadrzędnej)",
38229
+ path_in_database: "Ścieżka, pod którą ta kolekcja jest przechowywana w bazie danych",
38230
+ singular_name: "Nazwa w liczbie pojedynczej",
38231
+ singular_name_description: "Opcjonalnie zdefiniuj nazwę pojedynczą dla encji tej kolekcji",
38232
+ description: "Opis",
38233
+ description_of_collection: "Opis kolekcji, możesz użyć formatowania markdown",
38234
+ collection_id: "ID kolekcji",
38235
+ collection_id_description: "To ID identyfikuje tę kolekcję. Zazwyczaj jest takie samo jak ścieżka.",
38236
+ collection_group: "Grupa kolekcji",
38237
+ collection_group_description: "Grupa kolekcji obejmuje wszystkie kolekcje o tej samej ścieżce. Pozwala to na wykonywanie zapytań w wielu kolekcjach jednocześnie.",
38238
+ advanced_settings: "Ustawienia zaawansowane",
38239
+ doc_history_global: "Historia zmian dokumentu włączona, jeśli jest włączona globalnie",
38240
+ doc_history_enabled: "Historia zmian dokumentu WŁĄCZONA",
38241
+ doc_history_not_enabled: "Historia zmian dokumentu NIE jest włączona",
38242
+ 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.",
38243
+ document_id_generation: "Generowanie ID dokumentów",
38244
+ code_defined: "Zdefiniowane w kodzie",
38245
+ users_must_define_id: "Użytkownicy muszą podać ID",
38246
+ users_can_define_id: "Użytkownicy mogą podać ID, ale nie jest to wymagane",
38247
+ doc_id_auto_generated: "ID dokumentu generowane jest automatycznie",
38248
+ config_doc_id_generation: "Skonfiguruj sposób generowania ID dokumentów podczas tworzenia nowych encji.",
38249
+ enable_text_search: "Włącz wyszukiwanie tekstowe dla tej kolekcji",
38250
+ 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.",
38251
+ database_id: "ID bazy danych",
38252
+ default_text: "(domyślnie)",
38253
+ custom_actions: "Akcje niestandardowe",
38254
+ more_info: "Więcej informacji",
38255
+ define_custom_actions_cli: "Zdefiniuj własne akcje niestandardowe, przesyłając je za pomocą CLI.",
38256
+ action_defined_in_code: "Ta akcja jest zdefiniowana w kodzie pod kluczem",
38257
+ add_custom_entity_action: "Dodaj niestandardową akcję encji",
38258
+ remove_this_action: "Usunąć tę akcję?",
38259
+ remove_action_warning: "To nie usunie żadnych danych, tylko akcję w CMS",
38260
+ subcollections_of: "Podkolekcje kolekcji",
38261
+ add_subcollection: "Dodaj podkolekcję",
38262
+ custom_views: "Widoki niestandardowe",
38263
+ define_custom_views_cli: "Zdefiniuj własne widoki niestandardowe, przesyłając je za pomocą CLI.",
38264
+ view_defined_in_code: "Ten widok jest zdefiniowany w kodzie pod kluczem",
38265
+ add_custom_entity_view: "Dodaj niestandardowy widok encji",
38266
+ delete_this_subcollection: "Usunąć tę podkolekcję?",
38267
+ remove_collection_warning: "To nie usunie żadnych danych, tylko kolekcję w CMS",
38268
+ remove_this_view: "Usunąć ten widok?",
38269
+ remove_view_warning: "To nie usunie żadnych danych, tylko widok w CMS",
38270
+ no_collection_selected: "Nie wybrano kolekcji",
38271
+ code_for_collection: "Kod dla",
38272
+ use_config_define_json: "Użyj tej konfiguracji, aby zdefiniować kolekcję w formacie JSON.",
38273
+ customise_collection_code: "Jeśli chcesz dostosować kolekcję w kodzie, możesz dodać ten kod kolekcji do konfiguracji swojej aplikacji CMS.",
38274
+ copied: "Skopiowano",
38275
+ property_cant_be_edited: "Tej właściwości nie można edytować",
38276
+ property_not_editable_description: "Możesz nie mieć uprawnień do jej edycji lub jest ona zdefiniowana w kodzie z flagą editable ustawioną na false.",
38277
+ delete_this_property: "Usunąć tę właściwość?",
38278
+ delete_property_warning: "To nie usunie żadnych danych, tylko zmodyfikuje kolekcję.",
38279
+ error_must_specify_id: "Musisz podać ID dla tego pola",
38280
+ error_id_format: "ID może zawierać tylko litery, cyfry i podkreślenia (_) i nie może zaczynać się od cyfry",
38281
+ error_id_already_exists: "Istnieje już inne pole z tym ID",
38282
+ error_must_specify_title: "Musisz podać tytuł dla tego pola",
38283
+ custom_or_other: "Niestandardowe/Inne",
38284
+ select_property_widget: "Wybierz widżet właściwości",
38285
+ 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.",
38286
+ required: "Wymagane",
38287
+ enum_form_dialog: "Okno dialogowe formularza wyliczeniowego",
38288
+ imported_data_preview: "Podgląd zaimportowanych danych",
38289
+ entities_with_same_id_overwritten: "Encje o tym samym ID zostaną nadpisane",
38290
+ collection_editor: "Edytor kolekcji",
38291
+ properties_in_this_group: "Właściwości w tej grupie",
38292
+ data_property_mapping: "Mapowanie danych na właściwości",
38293
+ property_edit_view: "Widok edycji właściwości",
38294
+ all_of_these: "Wszystkie z nich",
38295
+ any_of_these: "Dowolna z nich",
38296
+ only_admins_edit_roles: "Tylko administratorzy mogą edytować role",
38297
+ error_user_not_found: "Nie znaleziono użytkownika",
38298
+ role: "Rola",
38299
+ name_of_this_role: "Nazwa tej roli",
38300
+ id_of_this_role: "ID tej roli",
38301
+ create_entities: "Tworzenie encji",
38302
+ read_entities: "Odczyt encji",
38303
+ update_entities: "Aktualizacja encji",
38304
+ delete_entities: "Usuwanie encji",
38305
+ all_collections: "Wszystkie kolekcje",
38306
+ create_entities_in_collections: "Tworzenie encji w kolekcjach",
38307
+ access_all_data_in_every_collection: "Dostęp do wszystkich danych w każdej kolekcji",
38308
+ update_data_in_any_collection: "Aktualizacja danych w dowolnej kolekcji",
38309
+ delete_data_in_any_collection: "Usuwanie danych w dowolnej kolekcji",
38310
+ allow_all_permissions_in_this_collections: "Zezwól na wszystkie uprawnienia w tych kolekcjach",
38311
+ all: "Wszystkie",
38312
+ customise_permissions_description: "Możesz dostosować uprawnienia, jakie użytkownicy z tą rolą mają w encjach każdej kolekcji",
38313
+ create_collections: "Tworzenie kolekcji",
38314
+ yes: "Tak",
38315
+ no: "Nie",
38316
+ can_user_create_collections: "Czy użytkownik może tworzyć kolekcje",
38317
+ edit_collections: "Edycja kolekcji",
38318
+ only_own_collections: "Tylko swoje",
38319
+ own: "Własne",
38320
+ can_user_edit_collections: "Czy użytkownik może edytować kolekcje",
38321
+ delete_collections: "Usuwanie kolekcji",
38322
+ can_user_delete_collections: "Czy użytkownik może usuwać kolekcje",
38323
+ error_saving_role: "Wystąpił błąd podczas zapisywania tej roli",
38324
+ create_role: "Utwórz rolę",
38325
+ update: "Aktualizuj",
38326
+ only_admins_change_roles: "Tylko administratorzy mogą zmieniać role",
38327
+ must_be_at_least_one_admin: "Musi istnieć co najmniej jeden administrator",
38328
+ logged_user_not_found: "Nie znaleziono zalogowanego użytkownika",
38329
+ user: "Użytkownik",
38330
+ user_id: "ID użytkownika",
38331
+ name_of_this_user: "Nazwa tego użytkownika",
38332
+ email_of_this_user: "Adres e-mail tego użytkownika",
38333
+ roles: "Role",
38334
+ create_user: "Utwórz użytkownika",
38335
+ users: "Użytkownicy",
38336
+ add_user: "Dodaj użytkownika",
38337
+ add_role: "Dodaj rolę",
38338
+ is_admin: "Jest administratorem",
38339
+ default_permissions: "Domyślne uprawnienia",
38340
+ created_on: "Utworzono",
38341
+ email: "E-mail",
38342
+ id: "ID",
38343
+ read: "Odczyt",
38344
+ column_in_file: "Kolumna w pliku",
38345
+ map_to_property: "Zmapuj na właściwość",
38346
+ default_values: "Wartości domyślne",
38347
+ default_values_description: "Możesz wybrać wartość domyślną dla niezmapowanych kolumn i pustych wartości:",
38348
+ property: "Właściwość",
38349
+ default_value: "Wartość domyślna",
38350
+ autogenerate_id: "Generuj ID automatycznie",
38351
+ id_column_description: "Kolumna, która będzie używana jako ID dla każdego dokumentu",
38352
+ do_not_set_value: "Nie ustawiaj wartości",
38353
+ set_value_to_true: "Ustaw wartość na true",
38354
+ set_value_to_false: "Ustaw wartość na false",
38355
+ drag_and_drop_file: "Przeciągnij i upuść plik tutaj lub kliknij, aby go przesłać",
38356
+ error_saving_data: "Błąd zapisywania danych",
38357
+ retry: "Spróbuj ponownie",
38358
+ saving_data: "Zapisywanie danych",
38359
+ entities_saved: "zapisanych encji",
38360
+ do_not_close_tab: "Nie zamykaj tej karty, w przeciwnym razie import zostanie przerwany",
38361
+ import: "Importuj",
38362
+ import_data: "Importuj dane",
38363
+ upload_file_description: "Prześlij plik CSV, Excel lub JSON i zmapuj go do istniejącego schematu",
38364
+ back: "Wstecz",
38365
+ next: "Dalej",
38366
+ save_data: "Zapisz dane",
38367
+ use_column_as_id: "Użyj tej kolumny jako ID",
38368
+ do_not_import_property: "Nie importuj tej właściwości",
38369
+ entities_will_be_overwritten: "Encje o tym samym ID zostaną nadpisane",
38370
+ data_imported_successfully: "Dane zostały pomyślnie zaimportowane",
38371
+ export: "Eksportuj",
38372
+ export_data: "Eksportuj dane",
38373
+ download_table_csv: "Pobierz zawartość tej tabeli jako plik CSV",
38374
+ csv: "CSV",
38375
+ json: "JSON",
38376
+ dates_as_timestamps: "Daty jako znaczniki czasu",
38377
+ dates_as_strings: "Daty jako ciągi znaków",
38378
+ flatten_arrays: "Spłaszcz tablice",
38379
+ download: "Pobierz",
38380
+ large_number_of_documents: "Ta kolekcja zawiera dużą liczbę dokumentów ({{count}}).",
38381
+ include_undefined_values: "Uwzględnij niezdefiniowane wartości",
38382
+ submit: "Wyślij",
38383
+ no_filterable_properties: "Brak dostępnych właściwości do filtrowania",
38384
+ apply_filters: "Zastosuj filtry",
38385
+ list: "Lista",
38386
+ cards: "Karty",
38387
+ board: "Tablica",
38388
+ 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.",
38389
+ kanban_view_not_available: "Widok Kanban jest niedostępny",
38390
+ 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.",
38391
+ no_enum_values_configured: "Nie skonfigurowano wartości wyliczeniowych dla właściwości „{{property}}”",
38392
+ 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ść.",
38393
+ initialize: "Zainicjuj",
38394
+ confirm_multiple_delete: "Potwierdzić wielokrotne usunięcie?",
38395
+ delete_entity_confirm_title: "Czy chcesz usunąć ten element: {{entityName}}?",
38396
+ /** AI Collection Generator Popover */
38397
+ generate_collection_with_ai: "Wygeneruj kolekcję za pomocą AI",
38398
+ modify_collection_with_ai: "Zmodyfikuj kolekcję za pomocą AI",
38399
+ describe_collection_to_create: "Opisz kolekcję, którą chcesz utworzyć.",
38400
+ describe_changes_to_make: "Opisz zmiany, które chcesz wprowadzić w tej kolekcji.",
38401
+ ai_placeholder_create: "np. Utwórz kolekcję produktów z nazwą, ceną, opisem i kategorią...",
38402
+ ai_placeholder_modify: "np. Dodaj pole obrazu miniatury z przechowywaniem, ustaw cenę jako wymaganą...",
38403
+ ai_assist: "Asystent AI",
38404
+ generating: "Generowanie...",
38405
+ /** Recently extracted strings for collection editor */
38406
+ this_is_subcollection_of: "To jest podkolekcja",
38407
+ use_existing_paths_database: "Użyj jednej z istniejących ścieżek w swojej bazie danych:",
38408
+ describe_collection_ai: "Opisz swoją kolekcję dla AI:",
38409
+ generate_with_ai: "Generuj za pomocą AI",
38410
+ create_from_json_config: "Utwórz z konfiguracji JSON:",
38411
+ paste_json_config: "Wklej konfigurację JSON",
38412
+ create_collection_from_file_formats: "Utwórz kolekcję z pliku (csv, json, xls, xlsx...)",
38413
+ select_template: "Wybierz szablon:",
38414
+ products: "Produkty",
38415
+ collection_products_subtitle: "Kolekcja produktów ze zdjęciami, cenami i stanem magazynowym",
38416
+ collection_users_subtitle: "Kolekcja użytkowników z adresami e-mail, imionami i rolami",
38417
+ blog_posts: "Wpisy na blogu",
38418
+ collection_blog_posts_subtitle: "Kolekcja wpisów na blogu ze zdjęciami, autorami i rozbudowaną treścią",
38419
+ pages: "Strony",
38420
+ collection_pages_subtitle: "Kolekcja stron ze zdjęciami, autorami i rozbudowaną treścią",
38421
+ continue_from_scratch: "Kontynuuj od zera",
38422
+ /** Admin views config */
38423
+ cms_users: "Użytkownicy CMS",
38424
+ roles_menu: "Role",
38425
+ project_settings: "Ustawienia projektu",
38426
+ firestore_manager: "Menedżer Firestore",
38427
+ manage_your_firestore_data: "Zarządzaj danymi w Firestore",
38428
+ // ─── FireCMS Cloud Login ──────────────────────────────────────
38429
+ build_admin_panel_in_minutes: "Zbuduj panel administracyjny Firebase w kilka minut",
38430
+ go_live_instantly: "Uruchom natychmiast:",
38431
+ create_production_ready_back_offices: "Twórz gotowe do wdrożenia panele administracyjne",
38432
+ without_the_frontend_hassle: "bez kłopotów z frontendem.",
38433
+ automatic_setup: "Automatyczna konfiguracja",
38434
+ from_your_existing_firestore_data: "na podstawie Twoich istniejących danych w Firestore.",
38435
+ seamless_real_time_firebase_integration: "Płynna integracja z Firebase w czasie rzeczywistym.",
38436
+ intuitive_spreadsheet_like_ui: "Intuicyjny interfejs przypominający arkusz kalkulacyjny,",
38437
+ your_whole_team_can_use: "z którego może korzystać cały Twój zespół.",
38438
+ focus_on_your_app: "Skup się na swojej aplikacji,",
38439
+ not_the_admin_panel: "a nie na panelu administracyjnym.",
38440
+ join_our_newsletter: "Dołącz do naszego newslettera. Bez spamu, tylko ważne aktualizacje!",
38441
+ by_signing_in_you_agree_to_our: "Logując się, akceptujesz nasz",
38442
+ terms_and_conditions: "Regulamin",
38443
+ and_our: "oraz naszą",
38444
+ privacy_policy: "Politykę prywatności",
38445
+ firecms_cloud_google_disclosure: "Korzystanie i przekazywanie przez FireCMS Cloud informacji uzyskanych z API Google do jakiejkolwiek innej aplikacji będzie zgodne z",
38446
+ google_api_services_user_data_policy: "Polityką dotyczącą danych użytkowników usług API Google",
38447
+ including_the_limited_use_requirements: "w tym z wymaganiami dotyczącymi ograniczonego użytkowania.",
38448
+ email_password: "E-mail/hasło",
38449
+ sign_in_with_google: "Zaloguj się przez Google",
38450
+ // --- Auth error messages ---
38451
+ auth_user_not_found: "Nie znaleziono użytkownika",
38452
+ auth_wrong_password: "Nieprawidłowe hasło. Spróbuj ponownie.",
38453
+ auth_user_disabled: "Użytkownik jest zablokowany. Skontaktuj się z pomocą techniczną.",
38454
+ auth_account_exists_with_different_credential: "Konto istnieje z inną metodą logowania",
38455
+ auth_email_already_in_use: "Ten adres e-mail jest już używany",
38456
+ auth_google_permissions_required: "Musisz przyznać dodatkowe uprawnienia, aby zarządzać swoimi projektami Google Cloud",
38457
+ auth_invalid_email_password: "Podaj zarówno adres e-mail, jak i hasło",
38458
+ auth_enter_email_first: "Najpierw podaj swój adres e-mail",
38459
+ auth_password_reset_sent: "Wysłano e-mail resetujący hasło",
38460
+ auth_sign_in_account: "Zaloguj się do swojego konta",
38461
+ auth_create_new_account: "Utwórz nowe konto",
38462
+ auth_password: "Hasło",
38463
+ auth_reset_password: "Zresetuj hasło",
38464
+ auth_new_user: "Nowy użytkownik?",
38465
+ auth_have_account: "Masz już konto?",
38466
+ auth_sign_in: "Zaloguj się",
38467
+ auth_sign_up: "Zarejestruj się",
38468
+ // --- SaaS Subscriptions ---
38469
+ subscriptions: "Subskrypcje",
38470
+ manage_your_subscriptions_in_stripe: "Zarządzaj swoimi subskrypcjami w Stripe",
38471
+ 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.",
38472
+ your_pro_licenses: "Twoje licencje PRO",
38473
+ create_new_license: "Utwórz nową licencję",
38474
+ 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.",
38475
+ if_you_are_an_agency: "Jeśli jesteś agencją, możesz swobodnie odsprzedawać swoją licencję swoim klientom.",
38476
+ if_you_have_any_questions: "Jeśli masz pytania lub potrzebujesz pomocy, skontaktuj się z nami pod adresem",
38477
+ you_have_not_created_any_pro_licenses: "Nie masz jeszcze żadnych licencji FireCMS PRO",
38478
+ archive: "Archiwizuj",
38479
+ licensed_projects_lowercase: "licencjonowanych projektów",
38480
+ manage: "Zarządzaj",
38481
+ update_payment_method: "Zaktualizuj metodę płatności",
38482
+ your_firecms_cloud_projects: "Twoje projekty FireCMS Cloud",
38483
+ status_active: "Aktywna",
38484
+ status_trialing: "Okres próbny",
38485
+ status_past_due: "Zaległa płatność",
38486
+ status_canceled: "Anulowana",
38487
+ status_unpaid: "Nieopłacona",
38488
+ status_incomplete: "Niekompletna",
38489
+ status_incomplete_expired: "Niekompletna, wygasła",
38490
+ status_unknown: "Nieznany",
38491
+ plan_free: "Brak subskrypcji",
38492
+ plan_cloud_plus: "Subskrybowany",
38493
+ plan_pro: "Pro",
38494
+ plan_unknown: "Nieznany plan",
38495
+ auto_setup_collections_button: "Automatycznie skonfiguruj kolekcje",
38496
+ auto_setup_collections_title: "Automatycznie skonfigurować kolekcje?",
38497
+ auto_setup_collections_desc: "Spowoduje to automatyczne utworzenie konfiguracji kolekcji dla kolekcji, które <b>NIE</b> są jeszcze zmapowane",
38498
+ setting_up_collections: "Konfigurowanie kolekcji",
38499
+ setting_up_collection: "Konfigurowanie {{name}}",
38500
+ no_collections_found_to_setup: "Nie znaleziono kolekcji do skonfigurowania.",
38501
+ collections_have_been_setup: "Kolekcje zostały automatycznie skonfigurowane.",
38502
+ error_setting_up_collections: "Błąd podczas automatycznej konfiguracji kolekcji",
38503
+ setup_collections_title: "Skonfiguruj kolekcje",
38504
+ setup_collections_select_desc: "Wybierz kolekcje do automatycznej konfiguracji:",
38505
+ select_all: "Zaznacz wszystkie",
38506
+ deselect_all: "Odznacz wszystkie",
38507
+ setup_collections_confirm: "Skonfiguruj ({{count}})",
38508
+ collection_setup_success: "{{name}} została skonfigurowana",
38509
+ go_to_collection: "Przejdź do kolekcji",
38510
+ // --- Home Suggestions ---
38511
+ add_your: "Dodaj swoje",
38512
+ database_collections: "kolekcje bazy danych",
38513
+ to_firecms: "do FireCMS",
38514
+ no_unmapped_collections: "Brak niezmapowanych kolekcji w bazie danych",
38515
+ query_and_update_with_datatalk: "Odpytuj i aktualizuj swoje dane w języku naturalnym za pomocą",
38516
+ // --- SaaS Welcome ---
38517
+ welcome_to_firecms: "Witamy w FireCMS Cloud",
38518
+ admin_panel_ready_bring_data: "Twój panel administracyjny jest gotowy. Wprowadźmy Twoje dane.",
38519
+ admin_panel_ready_get_started: "Twój panel administracyjny jest gotowy. Oto jak zacząć.",
38520
+ auto_detect_collections: "Automatyczne wykrywanie kolekcji",
38521
+ auto_detect_collections_desc: "Pozwól AI przeskanować Twoją bazę danych i automatycznie wygenerować schematy kolekcji.",
38522
+ create_a_collection: "Utwórz kolekcję",
38523
+ create_collection_desc: "Ręcznie zdefiniuj swoją pierwszą kolekcję od podstaw za pomocą edytora wizualnego.",
38524
+ read_the_docs: "Przeczytaj dokumentację",
38525
+ read_the_docs_desc: "Dowiedz się, jak dostosowywać pola, widoki, akcje i więcej.",
38526
+ explore_docs: "Poznaj dokumentację",
38527
+ want_to_customize_with_code: "Chcesz dostosować za pomocą kodu? Uruchom",
38528
+ to_scaffold_a_local_project: "aby wygenerować lokalny projekt.",
38529
+ // ─── Collection Editor — Validation ──────────────────────────
38530
+ validation: "Walidacja",
38531
+ unique: "Unikalne",
38532
+ required_message: "Treść komunikatu o wymaganym polu",
38533
+ required_tooltip: "Nie będzie można zapisać tej encji, jeśli ta wartość nie jest ustawiona",
38534
+ unique_tooltip: "Nie może istnieć wiele encji z tą samą wartością",
38535
+ lowercase: "Małe litery",
38536
+ uppercase: "Wielkie litery",
38537
+ trim: "Przytnij",
38538
+ exact_length: "Dokładna długość",
38539
+ min_length: "Minimalna długość",
38540
+ max_length: "Maksymalna długość",
38541
+ matches_regex: "Pasuje do wyrażenia regularnego",
38542
+ not_valid_regexp: "Nieprawidłowe wyrażenie regularne",
38543
+ regex_helper: "np. /^\\d+$/ tylko dla cyfr",
38544
+ min_value: "Wartość minimalna",
38545
+ max_value: "Wartość maksymalna",
38546
+ less_than: "Mniejsza niż",
38547
+ more_than: "Większa niż",
38548
+ positive_value: "Wartość dodatnia",
38549
+ negative_value: "Wartość ujemna",
38550
+ integer_value: "Wartość całkowita",
38551
+ // ─── Collection Editor — Property Edit ───────────────────────
38552
+ invalid_regular_expression: "Nieprawidłowe wyrażenie regularne",
38553
+ must_specify_target_collection: "Musisz określić docelową kolekcję dla tego pola",
38554
+ need_specify_repeat_field: "Musisz określić pole powtarzalne",
38555
+ need_specify_block_properties: "Musisz określić właściwości tego bloku",
38556
+ incomplete_condition: "Niekompletny warunek – wybierz pole",
38557
+ field_name: "Nazwa pola",
38558
+ // ─── Collection Editor — Display & Config ────────────────────
38559
+ kanban_column_property: "Właściwość kolumny Kanban",
38560
+ select_a_property: "Wybierz właściwość",
38561
+ 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.",
38562
+ no_enum_string_properties: "Nie znaleziono tekstowych właściwości wyliczeniowych. Dodaj właściwość tekstową z enumValues, aby użyć widoku Kanban.",
38563
+ kanban_column_description: "Wybierz właściwość tekstową z wartościami wyliczeniowymi, aby grupować encje w kolumny",
38564
+ create_property: "+ Utwórz właściwość „{{property}}”",
38565
+ order_property: "Właściwość kolejności",
38566
+ 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.",
38567
+ no_number_properties: "Nie znaleziono właściwości liczbowych. Dodaj właściwość liczbową, aby włączyć sortowanie.",
38568
+ order_property_description: "Wybierz właściwość liczbową, aby zachować kolejność elementów",
38569
+ display_settings: "Ustawienia wyświetlania",
38570
+ default_row_size: "Domyślny rozmiar wiersza",
38571
+ side_dialog_width: "Szerokość okna bocznego",
38572
+ side_dialog_width_description: "Opcjonalnie zdefiniuj szerokość (w pikselach) bocznego okna encji. Wartość domyślna to 768px",
38573
+ inline_editing_enabled: "Dane można edytować bezpośrednio w widoku tabeli",
38574
+ inline_editing_disabled: "Dane można edytować tylko w widoku formularza",
38575
+ inline_editing_description: "Zezwól na edycję danych bezpośrednio w widoku tabeli, bez otwierania widoku formularza.",
38576
+ include_json_view: "Uwzględnij widok JSON",
38577
+ no_json_view: "Nie uwzględniaj widoku JSON",
38578
+ json_view_description: "Uwzględnij reprezentację JSON dokumentu.",
38579
+ not_found_suffix: "nie znaleziono",
38580
+ // ─── Editor ─────────────────────────────────────────────────
38581
+ editor_text: "Tekst",
38582
+ editor_text_description: "Po prostu zacznij pisać zwykły tekst.",
38583
+ editor_heading_1: "Nagłówek 1",
38584
+ editor_heading_1_description: "Duży nagłówek sekcji.",
38585
+ editor_heading_2: "Nagłówek 2",
38586
+ editor_heading_2_description: "Średni nagłówek sekcji.",
38587
+ editor_heading_3: "Nagłówek 3",
38588
+ editor_heading_3_description: "Mały nagłówek sekcji.",
38589
+ editor_todo_list: "Lista zadań",
38590
+ editor_todo_list_description: "Śledź zadania za pomocą listy do zrobienia.",
38591
+ editor_bullet_list: "Lista punktowana",
38592
+ editor_bullet_list_description: "Utwórz prostą listę punktowaną.",
38593
+ editor_numbered_list: "Lista numerowana",
38594
+ editor_numbered_list_description: "Utwórz listę z numeracją.",
38595
+ editor_quote: "Cytat",
38596
+ editor_quote_description: "Uchwyć cytat.",
38597
+ editor_code: "Kod",
38598
+ editor_code_description: "Wstaw fragment kodu.",
38599
+ editor_image: "Obraz",
38600
+ editor_image_description: "Prześlij obraz ze swojego komputera.",
38601
+ editor_multiple: "Wielokrotne",
38602
+ editor_link: "Link",
38603
+ editor_save: "Zapisz",
38604
+ editor_cancel: "Anuluj",
38605
+ editor_remove_link: "Usuń link",
38606
+ editor_paste_or_type_link: "Wklej lub wpisz link",
38607
+ editor_open_in_new_window: "Otwórz w nowym oknie",
38608
+ editor_bold: "Pogrubienie",
38609
+ editor_italic: "Kursywa",
38610
+ editor_underline: "Podkreślenie",
38611
+ editor_strikethrough: "Przekreślenie",
38612
+ editor_autocomplete: "Autouzupełnianie",
38613
+ editor_autocomplete_description: "Dodaj tekst na podstawie kontekstu.",
38614
+ // ─── Text Search Dialog ─────────────────────────────────────
38615
+ text_search_dialog_title: "Włącz wyszukiwanie tekstowe",
38616
+ text_search_local_not_recommended: "Lokalne wyszukiwanie tekstowe nie jest zalecane dla dużych kolekcji.",
38617
+ 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.",
38618
+ 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.",
38619
+ 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.",
38620
+ text_search_own_implementation: "Zaimplementowano własny kontroler wyszukiwania tekstowego. Możesz włączyć wyszukiwanie tekstowe dla swojej kolekcji.",
38621
+ text_search_enable_for_collection: "Włącz dla tej kolekcji",
38622
+ text_search_enable_for_project: "Włącz dla projektu",
38623
+ text_search_enabled_snackbar: "Lokalne wyszukiwanie tekstowe włączone",
38624
+ // ─── Cloud Project Settings ──────────────────────────────────
38625
+ settings_subscription_plan: "Plan subskrypcji",
38626
+ settings_subscribed_to: "Obecnie subskrybujesz",
38627
+ settings_no_active_subscription: "Obecnie ten projekt nie ma aktywnej subskrypcji.",
38628
+ settings_trial_valid_until: "Twój okres próbny jest ważny do {{date}}.",
38629
+ settings_features_intro: "Oto niektóre z funkcji, z których już korzystasz, używając FireCMS Cloud",
38630
+ settings_feature_managed_service: "Zarządzana, zawsze aktualna usługa",
38631
+ settings_feature_local_text_search: "Lokalne wyszukiwanie tekstowe",
38632
+ settings_feature_unlimited_users_roles: "Nieograniczona liczba użytkowników i ról",
38633
+ settings_feature_theme_logo: "Dostosowywanie motywu i logo",
38634
+ settings_feature_custom_fields_views: "Niestandardowe pola formularzy i widoki",
38635
+ settings_feature_secondary_databases: "Dodatkowe bazy danych",
38636
+ settings_feature_ai_content: "Generowanie treści AI za pomocą OpenAI i Google",
38637
+ settings_feature_unlimited_export: "Nieograniczony eksport danych",
38638
+ settings_feature_appcheck: "AppCheck",
38639
+ settings_heading: "Ustawienia",
38640
+ settings_project_name: "Nazwa projektu",
38641
+ settings_default_language: "Język domyślny",
38642
+ settings_default_language_caption: "Wybierz język bazowy dla tego projektu. Użytkownicy mogą zmienić tę preferencję w swoich ustawieniach osobistych.",
38643
+ settings_enable_local_text_search: "Włącz lokalne wyszukiwanie tekstowe",
38644
+ 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.",
38645
+ settings_doc_history_all_collections: "Historia dokumentów włączona dla wszystkich kolekcji",
38646
+ 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.",
38647
+ settings_theme: "Motyw",
38648
+ settings_primary_color: "Kolor podstawowy",
38649
+ settings_secondary_color: "Kolor dodatkowy",
38650
+ settings_sample_theme_components: "Przykładowe komponenty motywu",
38651
+ settings_drag_drop_logo: "Przeciągnij i upuść tutaj swoje logo",
38652
+ settings_create_subscription: "Utwórz subskrypcję",
38653
+ 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.",
38654
+ settings_subscription_is: "Subskrypcja jest",
38655
+ settings_next_payment_on: "Następna płatność nastąpi {{date}}.",
38656
+ settings_seats_count: "Masz",
38657
+ settings_seat: "miejsce",
38658
+ settings_seats: "miejsc",
38659
+ settings_per_seat: "po {{price}}/miejsce/{{interval}}",
38660
+ settings_current_price: "Aktualna cena to",
38661
+ settings_per_user_usage: "na użytkownika (zależnie od zużycia).",
38662
+ settings_cancelled_active_until: "Ta subskrypcja została anulowana i będzie aktywna do {{date}}.",
38663
+ settings_no_additional_charges: "Po anulowaniu nie zostaną naliczone żadne dodatkowe opłaty.",
38664
+ settings_manage_subscription: "Zarządzaj subskrypcją",
38665
+ settings_security_rules: "Reguły bezpieczeństwa",
38666
+ 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.",
38667
+ settings_security_rules_add_domain: "Pamiętaj, aby dodać domenę {{domain}} do listy dozwolonych domen u swojego dostawcy",
38668
+ 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.",
38669
+ settings_appcheck: "AppCheck",
38670
+ 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.",
38671
+ settings_appcheck_add_domain: "Pamiętaj, aby dodać domenę {{domain}} do listy dozwolonych domen u swojego dostawcy",
38672
+ settings_appcheck_enable: "Włącz AppCheck",
38673
+ settings_appcheck_site_key: "Klucz witryny",
38674
+ settings_appcheck_update: "Zaktualizuj AppCheck",
38675
+ settings_appcheck_refresh_note: "Po zapisaniu może być konieczne odświeżenie strony, aby zobaczyć zmiany.",
38676
+ settings_appcheck_updated: "AppCheck zaktualizowany",
38677
+ settings_appcheck_error: "Błąd podczas aktualizacji AppCheck",
38678
+ // --- Permission Error View ---
38679
+ missing_firestore_security_rules: "Brak reguł bezpieczeństwa Firestore",
38680
+ 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",
38681
+ cannot_be_accessed_without_it: "nie może być dostępna bez tej reguły.",
38682
+ required_security_rule: "Wymagana reguła bezpieczeństwa",
38683
+ fix_automatically: "Napraw automatycznie",
38684
+ open_firebase_rules: "Otwórz reguły Firebase",
38685
+ security_rules_updated_successfully: "Reguły bezpieczeństwa zostały pomyślnie zaktualizowane! Odśwież stronę, aby wczytać dane.",
38686
+ sec_rules_fixing: "Naprawianie...",
38687
+ sec_rules_fixed: "Naprawiono!",
38688
+ // ─── GCP Marketplace ─────────────────────────────────────────
38689
+ marketplace_managed_by_gcp: "Zarządzane przez GCP Marketplace",
38690
+ marketplace_billing_note: "Twoja subskrypcja jest zarządzana przez Google Cloud Marketplace. Zmiany planu, rozliczenia i anulowanie są obsługiwane w konsoli GCP.",
38691
+ marketplace_manage_in_gcp_console: "Zarządzaj w konsoli GCP",
38692
+ marketplace_plan_changes_note: "Aby zmienić plan lub anulować subskrypcję, odwiedź swoje zamówienia w GCP Marketplace.",
38693
+ marketplace_welcome_title: "Witamy z GCP Marketplace!",
38694
+ marketplace_welcome_subtitle: "Twoja subskrypcja Google Cloud Marketplace jest aktywna. Wybierz istniejący projekt lub utwórz nowy, aby go połączyć.",
38695
+ marketplace_select_or_create_project: "Wybierz lub utwórz projekt",
38696
+ marketplace_link_project: "Połącz projekt",
38697
+ marketplace_linking: "Łączenie projektu…",
38698
+ marketplace_link_success: "Projekt został pomyślnie połączony! Przekierowywanie…",
38699
+ marketplace_link_error: "Błąd podczas łączenia projektu. Spróbuj ponownie.",
38700
+ marketplace_no_account_id: "Nie znaleziono ID konta GCP Marketplace. Rozpocznij od GCP Marketplace."
38701
+ };
37370
38702
  const FIRECMS_NS = "firecms_core";
37371
38703
  const FIRECMS_LOCALE_STORAGE_KEY = "firecms_locale";
37372
38704
  function FireCMSi18nProvider({
@@ -37466,6 +38798,11 @@ function buildResources(translations) {
37466
38798
  [FIRECMS_NS]: {
37467
38799
  ...pt
37468
38800
  }
38801
+ },
38802
+ pl: {
38803
+ [FIRECMS_NS]: {
38804
+ ...pl
38805
+ }
37469
38806
  }
37470
38807
  };
37471
38808
  if (!translations) return resources;
@@ -42062,6 +43399,7 @@ export {
42062
43399
  DrawerLogo,
42063
43400
  DrawerNavigationGroup,
42064
43401
  DrawerNavigationItem,
43402
+ DrawerToggle,
42065
43403
  EmptyValue,
42066
43404
  EntityCard,
42067
43405
  EntityCollectionCardView,
@@ -42088,6 +43426,8 @@ export {
42088
43426
  FormEntry,
42089
43427
  FormLayout,
42090
43428
  GeoPoint,
43429
+ GeopointFieldBinding,
43430
+ GeopointPropertyPreview,
42091
43431
  IconForView,
42092
43432
  ImagePreview,
42093
43433
  InternalUserManagementContext,
@@ -42165,15 +43505,18 @@ export {
42165
43505
  canDeleteEntity,
42166
43506
  canEditEntity,
42167
43507
  copyEntityAction,
43508
+ decodeEntityId,
42168
43509
  defaultDateFormat,
42169
43510
  deleteEntityAction,
42170
43511
  deleteEntityWithCallbacks,
42171
43512
  editEntityAction,
42172
43513
  en,
43514
+ encodeEntityId,
42173
43515
  enumToObjectEntries,
42174
43516
  es,
42175
43517
  evaluateCondition,
42176
43518
  flattenObject,
43519
+ formatGeoPoint,
42177
43520
  fullPathToCollectionSegments,
42178
43521
  getArrayResolvedProperties,
42179
43522
  getArrayValuesCount,
@@ -42195,6 +43538,7 @@ export {
42195
43538
  getFieldConfig,
42196
43539
  getFieldId,
42197
43540
  getFormFieldKeys,
43541
+ getGeoPointCoordinates,
42198
43542
  getHashValue,
42199
43543
  getIcon,
42200
43544
  getIconForProperty,
@@ -42212,6 +43556,7 @@ export {
42212
43556
  hydrateRegExp,
42213
43557
  iconSynonyms,
42214
43558
  iconsSearch,
43559
+ isDataTypeFilterable,
42215
43560
  isDefaultFieldConfigId,
42216
43561
  isEmptyObject,
42217
43562
  isEnumValueDisabled,
@@ -42231,6 +43576,8 @@ export {
42231
43576
  mergeDeep,
42232
43577
  mergeEntityActions,
42233
43578
  navigateToEntity,
43579
+ normalizeGeoPoint,
43580
+ parseGeoPoint,
42234
43581
  pick,
42235
43582
  plural,
42236
43583
  prettifyIdentifier,