@firecms/core 3.3.0-canary.040c21c → 3.3.0-canary.1e1cce9

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 (37) hide show
  1. package/dist/components/EntityCollectionTable/column_utils.d.ts +4 -3
  2. package/dist/components/EntityCollectionView/FiltersDialog.d.ts +2 -1
  3. package/dist/components/EntityPreview.d.ts +3 -1
  4. package/dist/index.es.js +408 -297
  5. package/dist/index.es.js.map +1 -1
  6. package/dist/index.umd.js +408 -297
  7. package/dist/index.umd.js.map +1 -1
  8. package/dist/types/collections.d.ts +17 -0
  9. package/dist/types/translations.d.ts +11 -3
  10. package/dist/util/entities.d.ts +1 -0
  11. package/package.json +5 -5
  12. package/src/app/Scaffold.tsx +13 -1
  13. package/src/components/EntityCollectionTable/EntityCollectionTable.tsx +2 -1
  14. package/src/components/EntityCollectionTable/column_utils.tsx +11 -19
  15. package/src/components/EntityCollectionTable/fields/TableReferenceField.tsx +1 -1
  16. package/src/components/EntityCollectionView/EntityCollectionView.tsx +5 -2
  17. package/src/components/EntityCollectionView/EntityCollectionViewStartActions.tsx +4 -1
  18. package/src/components/EntityCollectionView/FiltersDialog.tsx +39 -28
  19. package/src/components/EntityPreview.tsx +41 -40
  20. package/src/components/HomePage/NavigationCardBinding.tsx +6 -3
  21. package/src/components/ReferenceWidget.tsx +1 -1
  22. package/src/components/SelectableTable/filters/ReferenceFilterField.tsx +2 -2
  23. package/src/components/common/useDataSourceTableController.tsx +41 -4
  24. package/src/core/DefaultDrawer.tsx +1 -1
  25. package/src/form/field_bindings/ArrayOfReferencesFieldBinding.tsx +1 -1
  26. package/src/hooks/useBuildNavigationController.tsx +5 -1
  27. package/src/locales/de.ts +13 -5
  28. package/src/locales/en.ts +13 -5
  29. package/src/locales/es.ts +13 -5
  30. package/src/locales/fr.ts +13 -5
  31. package/src/locales/hi.ts +13 -5
  32. package/src/locales/it.ts +13 -5
  33. package/src/locales/pt.ts +13 -5
  34. package/src/types/collections.ts +18 -0
  35. package/src/types/translations.ts +11 -3
  36. package/src/util/entities.ts +11 -0
  37. package/src/util/resolutions.ts +3 -0
package/dist/index.umd.js CHANGED
@@ -691,6 +691,9 @@
691
691
  return result;
692
692
  }
693
693
  function getReferenceFrom(entity) {
694
+ if (!entity) {
695
+ throw new Error("getReferenceFrom: entity is null or undefined");
696
+ }
694
697
  return new EntityReference(entity.id, entity.path, entity.databaseId);
695
698
  }
696
699
  function traverseValuesProperties(inputValues, properties, operation) {
@@ -740,6 +743,12 @@
740
743
  }
741
744
  return value;
742
745
  }
746
+ function isDataTypeFilterable(dataType, isPartOfArray = false) {
747
+ if (isPartOfArray) {
748
+ return ["string", "number", "date", "reference"].includes(dataType);
749
+ }
750
+ return ["string", "number", "boolean", "date", "reference", "array"].includes(dataType);
751
+ }
743
752
  function enumToObjectEntries(enumValues) {
744
753
  if (Array.isArray(enumValues)) {
745
754
  return enumValues;
@@ -826,8 +835,13 @@
826
835
  ...a,
827
836
  ...b
828
837
  }), {});
838
+ const {
839
+ properties: overrideProps,
840
+ ...restOverrides
841
+ } = collectionOverride ?? {};
829
842
  return {
830
843
  ...collection,
844
+ ...restOverrides,
831
845
  properties: cleanedProperties,
832
846
  originalCollection: collection
833
847
  };
@@ -4513,7 +4527,7 @@
4513
4527
  }
4514
4528
  setDataLoading(false);
4515
4529
  setDataLoadingError(void 0);
4516
- setData(entities.map(_temp$C));
4530
+ setData(entities.map(_temp$D));
4517
4531
  setNoMoreToLoad(!itemCount || entities.length < itemCount);
4518
4532
  };
4519
4533
  const onError = (error) => {
@@ -4596,7 +4610,7 @@
4596
4610
  }
4597
4611
  function _temp2$f() {
4598
4612
  }
4599
- function _temp$C(e_0) {
4613
+ function _temp$D(e_0) {
4600
4614
  return {
4601
4615
  ...e_0
4602
4616
  };
@@ -4661,7 +4675,7 @@
4661
4675
  setEntity(CACHE[`${path}/${entityId}`]);
4662
4676
  setDataLoading(false);
4663
4677
  setDataLoadingError(void 0);
4664
- return _temp$B;
4678
+ return _temp$C;
4665
4679
  } else {
4666
4680
  if (entityId && path && collection) {
4667
4681
  if (dataSource.listenEntity) {
@@ -4729,7 +4743,7 @@
4729
4743
  }
4730
4744
  function _temp2$e() {
4731
4745
  }
4732
- function _temp$B() {
4746
+ function _temp$C() {
4733
4747
  }
4734
4748
  async function saveEntityWithCallbacks({
4735
4749
  collection,
@@ -5373,7 +5387,7 @@
5373
5387
  }
5374
5388
  let t9;
5375
5389
  if ($[19] !== url) {
5376
- t9 = /* @__PURE__ */ jsxRuntime.jsx(ui.Tooltip, { title: "Open image in new tab", side: "bottom", children: /* @__PURE__ */ jsxRuntime.jsx(ui.IconButton, { className: "invisible group-hover:visible", variant: "filled", component: "a", href: url, rel: "noopener noreferrer", target: "_blank", size: "smallest", onClick: _temp$A, children: t8 }) });
5390
+ t9 = /* @__PURE__ */ jsxRuntime.jsx(ui.Tooltip, { title: "Open image in new tab", side: "bottom", children: /* @__PURE__ */ jsxRuntime.jsx(ui.IconButton, { className: "invisible group-hover:visible", variant: "filled", component: "a", href: url, rel: "noopener noreferrer", target: "_blank", size: "smallest", onClick: _temp$B, children: t8 }) });
5377
5391
  $[19] = url;
5378
5392
  $[20] = t9;
5379
5393
  } else {
@@ -5407,7 +5421,7 @@
5407
5421
  }
5408
5422
  return t11;
5409
5423
  }
5410
- function _temp$A(e_0) {
5424
+ function _temp$B(e_0) {
5411
5425
  return e_0.stopPropagation();
5412
5426
  }
5413
5427
  const FIRECMS_NS$1 = "firecms_core";
@@ -5474,7 +5488,7 @@
5474
5488
  }
5475
5489
  let t3;
5476
5490
  if ($[2] !== url) {
5477
- t3 = /* @__PURE__ */ jsxRuntime.jsxs("a", { className: "flex gap-4 break-words items-center font-medium text-primary visited:text-primary dark:visited:text-primary dark:text-primary", href: url, rel: "noopener noreferrer", onMouseDown: _temp$z, target: "_blank", children: [
5491
+ t3 = /* @__PURE__ */ jsxRuntime.jsxs("a", { className: "flex gap-4 break-words items-center font-medium text-primary visited:text-primary dark:visited:text-primary dark:text-primary", href: url, rel: "noopener noreferrer", onMouseDown: _temp$A, target: "_blank", children: [
5478
5492
  t2,
5479
5493
  url
5480
5494
  ] });
@@ -5604,7 +5618,7 @@
5604
5618
  function _temp2$d(e_0) {
5605
5619
  return e_0.stopPropagation();
5606
5620
  }
5607
- function _temp$z(e) {
5621
+ function _temp$A(e) {
5608
5622
  e.preventDefault();
5609
5623
  }
5610
5624
  function VideoPreview(t0) {
@@ -5738,7 +5752,7 @@
5738
5752
  if (Array.isArray(arrayProperty.of)) {
5739
5753
  let t1;
5740
5754
  if ($[6] !== arrayProperty.of) {
5741
- t1 = arrayProperty.of.map(_temp$y);
5755
+ t1 = arrayProperty.of.map(_temp$z);
5742
5756
  $[6] = arrayProperty.of;
5743
5757
  $[7] = t1;
5744
5758
  } else {
@@ -5876,7 +5890,7 @@
5876
5890
  }
5877
5891
  return content || null;
5878
5892
  }
5879
- function _temp$y(p, i) {
5893
+ function _temp$z(p, i) {
5880
5894
  return renderGenericArrayCell(p, i);
5881
5895
  }
5882
5896
  function renderMap(property, size) {
@@ -6320,104 +6334,77 @@
6320
6334
  actions
6321
6335
  ] });
6322
6336
  }
6323
- const EntityPreviewContainer = React__namespace.forwardRef((t0, ref) => {
6324
- const $ = reactCompilerRuntime.c(26);
6325
- let children;
6326
- let className;
6327
- let hover;
6328
- let onClick;
6329
- let props;
6330
- let style;
6331
- let t1;
6332
- let t2;
6333
- if ($[0] !== t0) {
6334
- ({
6335
- children,
6336
- hover,
6337
- onClick,
6338
- size: t1,
6339
- style,
6340
- className,
6341
- fullwidth: t2,
6342
- ...props
6343
- } = t0);
6344
- $[0] = t0;
6345
- $[1] = children;
6346
- $[2] = className;
6347
- $[3] = hover;
6348
- $[4] = onClick;
6349
- $[5] = props;
6350
- $[6] = style;
6351
- $[7] = t1;
6352
- $[8] = t2;
6353
- } else {
6354
- children = $[1];
6355
- className = $[2];
6356
- hover = $[3];
6357
- onClick = $[4];
6358
- props = $[5];
6359
- style = $[6];
6360
- t1 = $[7];
6361
- t2 = $[8];
6362
- }
6337
+ function EntityPreviewContainer(t0) {
6338
+ const $ = reactCompilerRuntime.c(15);
6339
+ const {
6340
+ children,
6341
+ hover,
6342
+ onClick,
6343
+ size: t1,
6344
+ style,
6345
+ className,
6346
+ fullwidth: t2,
6347
+ ref
6348
+ } = t0;
6363
6349
  const size = t1 === void 0 ? "medium" : t1;
6364
6350
  const fullwidth = t2 === void 0 ? true : t2;
6365
- let t3;
6366
- if ($[9] !== style) {
6367
- t3 = {
6368
- ...style,
6369
- tabindex: 0
6370
- };
6371
- $[9] = style;
6372
- $[10] = t3;
6351
+ const t3 = fullwidth ? "w-full" : "";
6352
+ 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" : "";
6353
+ const t5 = size === "small" ? "p-1" : "px-2 py-1";
6354
+ const t6 = onClick ? "cursor-pointer" : "";
6355
+ let t7;
6356
+ if ($[0] !== className || $[1] !== t3 || $[2] !== t4 || $[3] !== t5 || $[4] !== t6) {
6357
+ t7 = ui.cls("bg-white dark:bg-surface-900", "min-h-[44px]", t3, "items-center", t4, t5, "flex border rounded-lg", t6, ui.defaultBorderMixin, className);
6358
+ $[0] = className;
6359
+ $[1] = t3;
6360
+ $[2] = t4;
6361
+ $[3] = t5;
6362
+ $[4] = t6;
6363
+ $[5] = t7;
6373
6364
  } else {
6374
- t3 = $[10];
6365
+ t7 = $[5];
6375
6366
  }
6376
- const t4 = fullwidth ? "w-full" : "";
6377
- const t5 = hover ? "hover:bg-surface-accent-50 dark:hover:bg-surface-800 group-hover:bg-surface-accent-50 dark:group-hover:bg-surface-800" : "";
6378
- const t6 = size === "small" ? "p-1" : "px-2 py-1";
6379
- const t7 = onClick ? "cursor-pointer" : "";
6367
+ const divClassName = t7;
6380
6368
  let t8;
6381
- if ($[11] !== className || $[12] !== t4 || $[13] !== t5 || $[14] !== t6 || $[15] !== t7) {
6382
- t8 = ui.cls("bg-white dark:bg-surface-900", "min-h-[44px]", t4, "items-center", t5, t6, "flex border rounded-lg", t7, ui.defaultBorderMixin, className);
6383
- $[11] = className;
6384
- $[12] = t4;
6385
- $[13] = t5;
6386
- $[14] = t6;
6387
- $[15] = t7;
6388
- $[16] = t8;
6369
+ if ($[6] !== onClick) {
6370
+ t8 = onClick ? (event) => {
6371
+ event.preventDefault();
6372
+ onClick(event);
6373
+ } : void 0;
6374
+ $[6] = onClick;
6375
+ $[7] = t8;
6389
6376
  } else {
6390
- t8 = $[16];
6377
+ t8 = $[7];
6391
6378
  }
6379
+ const handleClick = t8;
6392
6380
  let t9;
6393
- if ($[17] !== onClick) {
6394
- t9 = (event) => {
6395
- if (onClick) {
6396
- event.preventDefault();
6397
- onClick(event);
6398
- }
6381
+ if ($[8] !== divClassName || $[9] !== handleClick || $[10] !== style) {
6382
+ t9 = {
6383
+ ref,
6384
+ tabIndex: 0,
6385
+ style,
6386
+ className: divClassName,
6387
+ onClick: handleClick
6399
6388
  };
6400
- $[17] = onClick;
6401
- $[18] = t9;
6389
+ $[8] = divClassName;
6390
+ $[9] = handleClick;
6391
+ $[10] = style;
6392
+ $[11] = t9;
6402
6393
  } else {
6403
- t9 = $[18];
6394
+ t9 = $[11];
6404
6395
  }
6396
+ const divProps = t9;
6405
6397
  let t10;
6406
- if ($[19] !== children || $[20] !== props || $[21] !== ref || $[22] !== t3 || $[23] !== t8 || $[24] !== t9) {
6407
- t10 = /* @__PURE__ */ jsxRuntime.jsx("div", { ref, style: t3, className: t8, onClick: t9, ...props, children });
6408
- $[19] = children;
6409
- $[20] = props;
6410
- $[21] = ref;
6411
- $[22] = t3;
6412
- $[23] = t8;
6413
- $[24] = t9;
6414
- $[25] = t10;
6398
+ if ($[12] !== children || $[13] !== divProps) {
6399
+ t10 = /* @__PURE__ */ jsxRuntime.jsx("div", { ...divProps, children });
6400
+ $[12] = children;
6401
+ $[13] = divProps;
6402
+ $[14] = t10;
6415
6403
  } else {
6416
- t10 = $[25];
6404
+ t10 = $[14];
6417
6405
  }
6418
6406
  return t10;
6419
- });
6420
- EntityPreviewContainer.displayName = "EntityPreviewContainer";
6407
+ }
6421
6408
  const ReferencePreview = function ReferencePreview2(props) {
6422
6409
  const $ = reactCompilerRuntime.c(10);
6423
6410
  const reference = props.reference;
@@ -7051,7 +7038,7 @@
7051
7038
  timeZoneName: "short"
7052
7039
  });
7053
7040
  const parts = tzFormatter.formatToParts(date);
7054
- t32 = parts.find(_temp$x)?.value ?? "";
7041
+ t32 = parts.find(_temp$y)?.value ?? "";
7055
7042
  $[6] = date;
7056
7043
  $[7] = timezone;
7057
7044
  $[8] = t32;
@@ -7122,7 +7109,7 @@
7122
7109
  }
7123
7110
  return t3;
7124
7111
  }
7125
- function _temp$x(p) {
7112
+ function _temp$y(p) {
7126
7113
  return p.type === "timeZoneName";
7127
7114
  }
7128
7115
  function MapPropertyPreview(t0) {
@@ -7217,7 +7204,7 @@
7217
7204
  }
7218
7205
  let t1;
7219
7206
  if ($[1] !== value) {
7220
- t1 = Object.entries(value).map(_temp$w);
7207
+ t1 = Object.entries(value).map(_temp$x);
7221
7208
  $[1] = value;
7222
7209
  $[2] = t1;
7223
7210
  } else {
@@ -7233,7 +7220,7 @@
7233
7220
  }
7234
7221
  return t2;
7235
7222
  }
7236
- function _temp$w(t0) {
7223
+ function _temp$x(t0) {
7237
7224
  const [key, childValue] = t0;
7238
7225
  const isTimestampObj = childValue && typeof childValue === "object" && (childValue instanceof Date || "_seconds" in childValue && "_nanoseconds" in childValue && typeof childValue._seconds === "number" && typeof childValue._nanoseconds === "number" || "seconds" in childValue && "nanoseconds" in childValue && typeof childValue.seconds === "number" && typeof childValue.nanoseconds === "number");
7239
7226
  const isScalar = childValue && (typeof childValue !== "object" || isTimestampObj);
@@ -8494,7 +8481,7 @@
8494
8481
  console.trace("onChange");
8495
8482
  if (valueType === "number") {
8496
8483
  if (multiple) {
8497
- const newValue = updatedValue.map(_temp$v);
8484
+ const newValue = updatedValue.map(_temp$w);
8498
8485
  updateValue(newValue);
8499
8486
  } else {
8500
8487
  updateValue(parseFloat(updatedValue));
@@ -8565,7 +8552,7 @@
8565
8552
  function _temp2$c(v_0) {
8566
8553
  return v_0.toString();
8567
8554
  }
8568
- function _temp$v(v) {
8555
+ function _temp$w(v) {
8569
8556
  return parseFloat(v);
8570
8557
  }
8571
8558
  function VirtualTableNumberInput(props) {
@@ -8761,7 +8748,7 @@
8761
8748
  const renderValue = t3;
8762
8749
  let t4;
8763
8750
  if ($[7] !== disabled || $[8] !== internalValue || $[9] !== multiple || $[10] !== onChange || $[11] !== renderValue || $[12] !== users || $[13] !== validValue) {
8764
- t4 = multiple ? /* @__PURE__ */ jsxRuntime.jsx(ui.MultiSelect, { inputRef: ref, className: "w-full h-full p-0 bg-transparent", position: "item-aligned", disabled, includeClear: false, useChips: false, value: validValue ? internalValue : [], onValueChange: onChange, children: users?.map(_temp$u) }) : /* @__PURE__ */ jsxRuntime.jsx(ui.Select, { inputRef: ref, size: "large", fullWidth: true, className: "w-full h-full p-0 bg-transparent", position: "item-aligned", disabled, padding: false, value: validValue ? internalValue : "", onValueChange: onChange, renderValue, children: users?.map(_temp2$b) });
8751
+ t4 = multiple ? /* @__PURE__ */ jsxRuntime.jsx(ui.MultiSelect, { inputRef: ref, className: "w-full h-full p-0 bg-transparent", position: "item-aligned", disabled, includeClear: false, useChips: false, value: validValue ? internalValue : [], onValueChange: onChange, children: users?.map(_temp$v) }) : /* @__PURE__ */ jsxRuntime.jsx(ui.Select, { inputRef: ref, size: "large", fullWidth: true, className: "w-full h-full p-0 bg-transparent", position: "item-aligned", disabled, padding: false, value: validValue ? internalValue : "", onValueChange: onChange, renderValue, children: users?.map(_temp2$b) });
8765
8752
  $[7] = disabled;
8766
8753
  $[8] = internalValue;
8767
8754
  $[9] = multiple;
@@ -8778,7 +8765,7 @@
8778
8765
  function _temp2$b(user_1) {
8779
8766
  return /* @__PURE__ */ jsxRuntime.jsx(ui.SelectItem, { value: user_1.uid, children: /* @__PURE__ */ jsxRuntime.jsx(UserDisplay, { user: user_1 }) }, user_1.uid);
8780
8767
  }
8781
- function _temp$u(user_0) {
8768
+ function _temp$v(user_0) {
8782
8769
  return /* @__PURE__ */ jsxRuntime.jsx(ui.MultiSelectItem, { value: user_0.uid, children: /* @__PURE__ */ jsxRuntime.jsx(UserDisplay, { user: user_0 }) }, user_0.uid);
8783
8770
  }
8784
8771
  class ErrorBoundary extends React.Component {
@@ -9023,7 +9010,7 @@
9023
9010
  newValue = [...internalValue];
9024
9011
  newValue = removeDuplicates(newValue);
9025
9012
  setInternalValue(newValue);
9026
- const fieldValue = newValue.filter(_temp$t).map(_temp2$a);
9013
+ const fieldValue = newValue.filter(_temp$u).map(_temp2$a);
9027
9014
  if (multipleFilesSupported) {
9028
9015
  onChange(fieldValue);
9029
9016
  } else {
@@ -9144,7 +9131,7 @@
9144
9131
  function _temp2$a(e_0) {
9145
9132
  return e_0.storagePathOrDownloadUrl;
9146
9133
  }
9147
- function _temp$t(e) {
9134
+ function _temp$u(e) {
9148
9135
  return !!e.storagePathOrDownloadUrl;
9149
9136
  }
9150
9137
  function getInternalInitialValue(multipleFilesSupported, value, metadata, size) {
@@ -9434,7 +9421,7 @@
9434
9421
  const snackbarContext = useSnackbarController();
9435
9422
  let t1;
9436
9423
  if ($[0] !== storage.acceptedFiles) {
9437
- t1 = storage.acceptedFiles ? storage.acceptedFiles.map(_temp$s).reduce(_temp2$9, {}) : void 0;
9424
+ t1 = storage.acceptedFiles ? storage.acceptedFiles.map(_temp$t).reduce(_temp2$9, {}) : void 0;
9438
9425
  $[0] = storage.acceptedFiles;
9439
9426
  $[1] = t1;
9440
9427
  } else {
@@ -9663,7 +9650,7 @@
9663
9650
  ...b
9664
9651
  };
9665
9652
  }
9666
- function _temp$s(e) {
9653
+ function _temp$t(e) {
9667
9654
  return {
9668
9655
  [e]: []
9669
9656
  };
@@ -9773,7 +9760,7 @@
9773
9760
  let t1;
9774
9761
  if ($[2] !== updateValue) {
9775
9762
  t1 = (entities) => {
9776
- updateValue(entities.map(_temp$r));
9763
+ updateValue(entities.filter(Boolean).map(_temp$s));
9777
9764
  };
9778
9765
  $[2] = updateValue;
9779
9766
  $[3] = t1;
@@ -9945,7 +9932,7 @@
9945
9932
  }
9946
9933
  return t10;
9947
9934
  }, equal);
9948
- function _temp$r(e) {
9935
+ function _temp$s(e) {
9949
9936
  return getReferenceFrom(e);
9950
9937
  }
9951
9938
  function _temp2$8(ref) {
@@ -11613,7 +11600,7 @@
11613
11600
  throw Error(`Couldn't find the corresponding collection for the path: ${ofProperty.path}`);
11614
11601
  }
11615
11602
  const onMultipleEntitiesSelected = React.useCallback((entities) => {
11616
- setValue(entities.map((e) => getReferenceFrom(e)));
11603
+ setValue(entities.filter(Boolean).map((e) => getReferenceFrom(e)));
11617
11604
  }, [setValue]);
11618
11605
  const referenceDialogController = useReferenceDialog({
11619
11606
  multiselect: true,
@@ -11723,7 +11710,7 @@
11723
11710
  }
11724
11711
  let t5;
11725
11712
  if ($[15] !== placeholder) {
11726
- t5 = placeholder && /* @__PURE__ */ jsxRuntime.jsx("div", { onClick: _temp$q, className: "flex flex-col items-center justify-center w-full h-full", children: /* @__PURE__ */ jsxRuntime.jsx(ui.DescriptionIcon, { className: "text-surface-700 dark:text-surface-300" }) });
11713
+ t5 = placeholder && /* @__PURE__ */ jsxRuntime.jsx("div", { onClick: _temp$r, className: "flex flex-col items-center justify-center w-full h-full", children: /* @__PURE__ */ jsxRuntime.jsx(ui.DescriptionIcon, { className: "text-surface-700 dark:text-surface-300" }) });
11727
11714
  $[15] = placeholder;
11728
11715
  $[16] = t5;
11729
11716
  } else {
@@ -11746,7 +11733,7 @@
11746
11733
  }
11747
11734
  return t6;
11748
11735
  }
11749
- function _temp$q(e) {
11736
+ function _temp$r(e) {
11750
11737
  return e.stopPropagation();
11751
11738
  }
11752
11739
  const dropZoneClasses = "box-border relative pt-[2px] items-center border border-transparent min-h-[254px] outline-none rounded-md duration-200 ease-[cubic-bezier(0.4,0,0.2,1)] focus:border-primary-solid";
@@ -11974,7 +11961,7 @@
11974
11961
  t4 = $[7];
11975
11962
  }
11976
11963
  const style = t4;
11977
- const getImageSizeNumber = _temp$p;
11964
+ const getImageSizeNumber = _temp$q;
11978
11965
  let child;
11979
11966
  if (entry.storagePathOrDownloadUrl) {
11980
11967
  const t52 = `storage_preview_${entry.storagePathOrDownloadUrl}`;
@@ -12049,7 +12036,7 @@
12049
12036
  }
12050
12037
  return t6;
12051
12038
  }
12052
- function _temp$p(previewSize) {
12039
+ function _temp$q(previewSize) {
12053
12040
  switch (previewSize) {
12054
12041
  case "small": {
12055
12042
  return 40;
@@ -12330,7 +12317,7 @@
12330
12317
  newValue.splice(fromIndex, 1);
12331
12318
  newValue.splice(toIndex, 0, item);
12332
12319
  setInternalValue(newValue);
12333
- const fieldValue = newValue.filter(_temp3$4).map(_temp4$3);
12320
+ const fieldValue = newValue.filter(_temp3$4).map(_temp4$4);
12334
12321
  onChange(fieldValue);
12335
12322
  };
12336
12323
  $[0] = multipleFilesSupported;
@@ -12524,7 +12511,7 @@
12524
12511
  function _temp5$2(v_0) {
12525
12512
  return !!v_0.storagePathOrDownloadUrl;
12526
12513
  }
12527
- function _temp4$3(e_0) {
12514
+ function _temp4$4(e_0) {
12528
12515
  return e_0.storagePathOrDownloadUrl;
12529
12516
  }
12530
12517
  function _temp3$4(e) {
@@ -13568,7 +13555,7 @@
13568
13555
  } else {
13569
13556
  t42 = $[20];
13570
13557
  }
13571
- t3 = Object.entries(mapProperties).filter(_temp$o).map(t42);
13558
+ t3 = Object.entries(mapProperties).filter(_temp$p).map(t42);
13572
13559
  $[6] = autoFocus;
13573
13560
  $[7] = context;
13574
13561
  $[8] = disabled;
@@ -13647,7 +13634,7 @@
13647
13634
  }
13648
13635
  return t10;
13649
13636
  }
13650
- function _temp$o(t0) {
13637
+ function _temp$p(t0) {
13651
13638
  const [, property_0] = t0;
13652
13639
  return !isHidden(property_0);
13653
13640
  }
@@ -15021,7 +15008,7 @@
15021
15008
  const property = t4;
15022
15009
  let t5;
15023
15010
  if ($[9] !== properties) {
15024
- t5 = Object.entries(properties).map(_temp$n);
15011
+ t5 = Object.entries(properties).map(_temp$o);
15025
15012
  $[9] = properties;
15026
15013
  $[10] = t5;
15027
15014
  } else {
@@ -15114,7 +15101,7 @@
15114
15101
  }
15115
15102
  return t11;
15116
15103
  }
15117
- function _temp$n(t0) {
15104
+ function _temp$o(t0) {
15118
15105
  const [key, property_0] = t0;
15119
15106
  return {
15120
15107
  id: key,
@@ -17235,24 +17222,27 @@
17235
17222
  function propertiesToColumns({
17236
17223
  properties,
17237
17224
  sortable: sortable2,
17238
- forceFilter,
17239
- AdditionalHeaderWidget
17225
+ forcedFilters,
17226
+ AdditionalHeaderWidget,
17227
+ allowedFilters
17240
17228
  }) {
17241
- const disabledFilter = Boolean(forceFilter);
17242
17229
  return Object.entries(properties).flatMap(([key, property]) => getColumnKeysForProperty(property, key)).map(({
17243
17230
  key,
17244
17231
  disabled
17245
17232
  }) => {
17246
17233
  const property = getResolvedPropertyInPath(properties, key);
17247
17234
  if (!property) throw Error("Internal error: no property found in path " + key);
17248
- const filterable = filterableProperty(property);
17235
+ const filterable = property.dataType === "array" ? isDataTypeFilterable(property.of?.dataType, true) : isDataTypeFilterable(property.dataType);
17236
+ const isFilterForced = forcedFilters?.includes(key) ?? false;
17237
+ const isFilterAllowed = allowedFilters ? allowedFilters.includes(key) : filterable;
17238
+ const filterEnabled = filterable && isFilterAllowed && !isFilterForced;
17249
17239
  return {
17250
17240
  key,
17251
17241
  align: getTableCellAlignment(property),
17252
17242
  icon: getIconForProperty(property, "small"),
17253
17243
  title: property.name ?? key,
17254
17244
  sortable: sortable2,
17255
- filter: !disabledFilter && filterable,
17245
+ filter: filterEnabled,
17256
17246
  width: getTablePropertyColumnWidth(property),
17257
17247
  resizable: true,
17258
17248
  custom: {
@@ -17265,16 +17255,6 @@
17265
17255
  };
17266
17256
  });
17267
17257
  }
17268
- function filterableProperty(property, partOfArray = false) {
17269
- if (partOfArray) {
17270
- return ["string", "number", "date", "reference"].includes(property.dataType);
17271
- }
17272
- if (property.dataType === "array") {
17273
- if (property.of) return filterableProperty(property.of, true);
17274
- else return false;
17275
- }
17276
- return ["string", "number", "boolean", "date", "reference", "array"].includes(property.dataType);
17277
- }
17278
17258
  const VirtualTableHeader = React.memo(function VirtualTableHeader2(t0) {
17279
17259
  const $ = reactCompilerRuntime.c(61);
17280
17260
  const {
@@ -18434,7 +18414,7 @@
18434
18414
  let t1;
18435
18415
  if ($[0] !== text) {
18436
18416
  const urlRegex = /https?:\/\/[^\s]+/g;
18437
- t1 = text.replace(urlRegex, _temp$m);
18417
+ t1 = text.replace(urlRegex, _temp$n);
18438
18418
  $[0] = text;
18439
18419
  $[1] = t1;
18440
18420
  } else {
@@ -18453,7 +18433,7 @@
18453
18433
  }
18454
18434
  return t2;
18455
18435
  };
18456
- function _temp$m(url) {
18436
+ function _temp$n(url) {
18457
18437
  return `<a href="${url}" class="underline" target="_blank">Link</a><br/>`;
18458
18438
  }
18459
18439
  const operationLabels$2 = {
@@ -18527,10 +18507,10 @@
18527
18507
  return path ? navigationController.getCollection(path) : void 0;
18528
18508
  }, [path]);
18529
18509
  const onSingleEntitySelected = (entity) => {
18530
- updateFilter(operation, getReferenceFrom(entity));
18510
+ if (entity) updateFilter(operation, getReferenceFrom(entity));
18531
18511
  };
18532
18512
  const onMultipleEntitiesSelected = (entities) => {
18533
- updateFilter(operation, entities.map((e) => getReferenceFrom(e)));
18513
+ updateFilter(operation, entities.filter(Boolean).map((e) => getReferenceFrom(e)));
18534
18514
  };
18535
18515
  const multiple = multipleSelectOperations$2.includes(operation);
18536
18516
  const referenceDialogController = useReferenceDialog({
@@ -18705,7 +18685,7 @@
18705
18685
  }
18706
18686
  let t8;
18707
18687
  if ($[20] !== operation || $[21] !== t6 || $[22] !== t7) {
18708
- t8 = /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-[100px]", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Select, { value: operation, size: "medium", fullWidth: true, position: "item-aligned", onValueChange: t6, renderValue: _temp$l, children: t7 }) });
18688
+ t8 = /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-[100px]", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Select, { value: operation, size: "medium", fullWidth: true, position: "item-aligned", onValueChange: t6, renderValue: _temp$m, children: t7 }) });
18709
18689
  $[20] = operation;
18710
18690
  $[21] = t6;
18711
18691
  $[22] = t7;
@@ -18759,7 +18739,7 @@
18759
18739
  let t11;
18760
18740
  if ($[40] !== dataType || $[41] !== enumValues || $[42] !== internalValue || $[43] !== isNullOperation || $[44] !== multiple || $[45] !== name || $[46] !== operation || $[47] !== updateFilter) {
18761
18741
  t11 = enumValues && multiple && /* @__PURE__ */ jsxRuntime.jsx(ui.MultiSelect, { size: "medium", position: "item-aligned", value: Array.isArray(internalValue) ? internalValue.map(_temp3$3) : [], disabled: isNullOperation, onValueChange: (value_2) => {
18762
- updateFilter(operation, dataType === "number" ? value_2.map(_temp4$2) : value_2);
18742
+ updateFilter(operation, dataType === "number" ? value_2.map(_temp4$3) : value_2);
18763
18743
  }, multiple, endAdornment: internalValue && /* @__PURE__ */ jsxRuntime.jsx(ui.IconButton, { className: "absolute right-2 top-3", onClick: (e_2) => updateFilter(operation, void 0), children: /* @__PURE__ */ jsxRuntime.jsx(ui.CloseIcon, {}) }), children: enumValues.map((enumConfig_0) => /* @__PURE__ */ jsxRuntime.jsx(ui.MultiSelectItem, { value: String(enumConfig_0.id), children: /* @__PURE__ */ jsxRuntime.jsx(EnumValuesChip, { enumKey: String(enumConfig_0.id), enumValues, size: "small" }) }, `select_value_${name}_${enumConfig_0.id}`)) });
18764
18744
  $[40] = dataType;
18765
18745
  $[41] = enumValues;
@@ -18801,7 +18781,7 @@
18801
18781
  }
18802
18782
  return t13;
18803
18783
  }
18804
- function _temp4$2(v) {
18784
+ function _temp4$3(v) {
18805
18785
  return parseInt(v);
18806
18786
  }
18807
18787
  function _temp3$3(e_1) {
@@ -18810,7 +18790,7 @@
18810
18790
  function _temp2$6(op_2) {
18811
18791
  return /* @__PURE__ */ jsxRuntime.jsx(ui.SelectItem, { value: op_2, children: operationLabels$1[op_2] }, op_2);
18812
18792
  }
18813
- function _temp$l(op_1) {
18793
+ function _temp$m(op_1) {
18814
18794
  return operationLabels$1[op_1];
18815
18795
  }
18816
18796
  function BooleanFilterField(t0) {
@@ -18981,7 +18961,7 @@
18981
18961
  }
18982
18962
  let t8;
18983
18963
  if ($[17] !== operation || $[18] !== t6 || $[19] !== t7) {
18984
- t8 = /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-[100px]", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Select, { value: operation, size: "medium", fullWidth: true, onValueChange: t6, renderValue: _temp$k, children: t7 }) });
18964
+ t8 = /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-[100px]", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Select, { value: operation, size: "medium", fullWidth: true, onValueChange: t6, renderValue: _temp$l, children: t7 }) });
18985
18965
  $[17] = operation;
18986
18966
  $[18] = t6;
18987
18967
  $[19] = t7;
@@ -19031,7 +19011,7 @@
19031
19011
  function _temp2$5(op_2) {
19032
19012
  return /* @__PURE__ */ jsxRuntime.jsx(ui.SelectItem, { value: op_2, children: operationLabels[op_2] }, op_2);
19033
19013
  }
19034
- function _temp$k(op_1) {
19014
+ function _temp$l(op_1) {
19035
19015
  return operationLabels[op_1];
19036
19016
  }
19037
19017
  const SelectableTable = function SelectableTable2({
@@ -19281,7 +19261,8 @@
19281
19261
  const columnsResult = propertiesToColumns({
19282
19262
  properties,
19283
19263
  sortable: sortable2,
19284
- forceFilter,
19264
+ forcedFilters: tableController.forcedFilters,
19265
+ allowedFilters: tableController.allowedFilters,
19285
19266
  AdditionalHeaderWidget
19286
19267
  });
19287
19268
  const propertyColumnKeys = new Set(columnsResult.map((col) => col.key));
@@ -19428,7 +19409,26 @@
19428
19409
  filterValues: initialFilterUrl,
19429
19410
  sortBy: initialSortUrl
19430
19411
  } = parseFilterAndSort(location.search);
19431
- const [filterValues_0, setFilterValues] = React.useState(forceFilter ?? (updateUrl ? initialFilterUrl : void 0) ?? initialFilter ?? void 0);
19412
+ const availableFilterKeys = collection.allowedFilters ?? Object.keys(collection.properties);
19413
+ const forcedFilterKeys = collection.forceFilter ? Object.keys(collection.forceFilter) : [];
19414
+ const allowedFilterKeys = React.useMemo(() => {
19415
+ const availableKeys = availableFilterKeys.filter((key) => {
19416
+ const property = collection.properties[key];
19417
+ if (!property) return false;
19418
+ if (typeof property === "function") return false;
19419
+ const dataType = property.dataType;
19420
+ const filterable = dataType === "array" ? isDataTypeFilterable(property.of?.dataType, true) : isDataTypeFilterable(dataType);
19421
+ return filterable;
19422
+ });
19423
+ const forcedKeys = forcedFilterKeys.filter((key_0) => !availableKeys.includes(key_0));
19424
+ return [...availableKeys, ...forcedKeys];
19425
+ }, [collection.properties, availableFilterKeys, forcedFilterKeys]);
19426
+ const removeUnallowedFilters = React.useCallback((filters) => {
19427
+ if (!filters) return;
19428
+ return Object.fromEntries(Object.entries(filters).filter(([key_1]) => allowedFilterKeys.includes(key_1)));
19429
+ }, [allowedFilterKeys]);
19430
+ const initFilters = forceFilter ?? (updateUrl ? initialFilterUrl : void 0) ?? initialFilter ?? void 0;
19431
+ const [filterValues_0, setFilterValues] = React.useState(removeUnallowedFilters(initFilters));
19432
19432
  const [sortBy_0, setSortBy] = React.useState((updateUrl ? initialSortUrl : void 0) ?? initialSortInternal);
19433
19433
  useUpdateUrl(filterValues_0, sortBy_0, searchString, updateUrl);
19434
19434
  const collectionScroll = scrollRestoration?.getCollectionScroll(fullPath, filterValues_0);
@@ -19451,7 +19451,7 @@
19451
19451
  const [dataLoading, setDataLoading] = React.useState(false);
19452
19452
  const [dataLoadingError, setDataLoadingError] = React.useState();
19453
19453
  const [noMoreToLoad, setNoMoreToLoad] = React.useState(false);
19454
- const clearFilter = React.useCallback(() => setFilterValues(forceFilter ?? void 0), [forceFilter]);
19454
+ const clearFilter = React.useCallback(() => setFilterValues(removeUnallowedFilters(forceFilter)), [forceFilter, removeUnallowedFilters]);
19455
19455
  const updateFilterValues = React.useCallback((updatedFilter) => {
19456
19456
  if (forceFilter) {
19457
19457
  console.warn("Filter is not compatible with the force filter. Ignoring filter");
@@ -19460,9 +19460,9 @@
19460
19460
  if (updatedFilter && Object.keys(updatedFilter).length === 0) {
19461
19461
  setFilterValues(void 0);
19462
19462
  } else {
19463
- setFilterValues(updatedFilter);
19463
+ setFilterValues(removeUnallowedFilters(updatedFilter));
19464
19464
  }
19465
- }, [forceFilter]);
19465
+ }, [forceFilter, removeUnallowedFilters]);
19466
19466
  React.useEffect(() => {
19467
19467
  setDataLoading(true);
19468
19468
  const onEntitiesUpdate = async (entities) => {
@@ -19537,6 +19537,8 @@
19537
19537
  dataLoadingError,
19538
19538
  filterValues: filterValues_0,
19539
19539
  setFilterValues: updateFilterValues,
19540
+ allowedFilters: allowedFilterKeys,
19541
+ forcedFilters: forcedFilterKeys,
19540
19542
  sortBy: sortBy_0,
19541
19543
  setSortBy,
19542
19544
  searchString,
@@ -19760,7 +19762,7 @@
19760
19762
  const searchBlocked = t12;
19761
19763
  let t2;
19762
19764
  if ($[15] !== customizationController.plugins || $[16] !== dataSource?.initTextSearch) {
19763
- t2 = Boolean(dataSource?.initTextSearch) || customizationController.plugins?.find(_temp$j);
19765
+ t2 = Boolean(dataSource?.initTextSearch) || customizationController.plugins?.find(_temp$k);
19764
19766
  $[15] = customizationController.plugins;
19765
19767
  $[16] = dataSource?.initTextSearch;
19766
19768
  $[17] = t2;
@@ -19852,7 +19854,7 @@
19852
19854
  }
19853
19855
  return t1;
19854
19856
  }
19855
- function _temp$j(p_0) {
19857
+ function _temp$k(p_0) {
19856
19858
  return Boolean(p_0.collectionView?.onTextSearchClick);
19857
19859
  }
19858
19860
  function DeleteEntityDialog({
@@ -20474,7 +20476,7 @@
20474
20476
  T0 = ui.Collapse;
20475
20477
  t4 = favouriteCollections.length > 0;
20476
20478
  t2 = "flex flex-row flex-wrap gap-2 pb-2 min-h-[32px]";
20477
- t3 = favouriteCollections.map(_temp$i);
20479
+ t3 = favouriteCollections.map(_temp$j);
20478
20480
  $[2] = navigationController;
20479
20481
  $[3] = t1;
20480
20482
  $[4] = T0;
@@ -20508,7 +20510,7 @@
20508
20510
  }
20509
20511
  return t6;
20510
20512
  }
20511
- function _temp$i(entry_0) {
20513
+ function _temp$j(entry_0) {
20512
20514
  return /* @__PURE__ */ jsxRuntime.jsx(NavigationChip, { entry: entry_0 }, entry_0.path);
20513
20515
  }
20514
20516
  const scrollsMap = {};
@@ -20745,7 +20747,7 @@
20745
20747
  }
20746
20748
  let t4;
20747
20749
  if ($[4] !== actions) {
20748
- t4 = /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-0.5", onClick: _temp$h, children: actions });
20750
+ t4 = /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-0.5", onClick: _temp$i, children: actions });
20749
20751
  $[4] = actions;
20750
20752
  $[5] = t4;
20751
20753
  } else {
@@ -20832,7 +20834,7 @@
20832
20834
  }
20833
20835
  return t12;
20834
20836
  });
20835
- function _temp$h(event) {
20837
+ function _temp$i(event) {
20836
20838
  event.preventDefault();
20837
20839
  event.stopPropagation();
20838
20840
  }
@@ -20892,7 +20894,7 @@
20892
20894
  return t5;
20893
20895
  }
20894
20896
  function NavigationCardBinding(t0) {
20895
- const $ = reactCompilerRuntime.c(35);
20897
+ const $ = reactCompilerRuntime.c(38);
20896
20898
  const {
20897
20899
  path,
20898
20900
  collection,
@@ -20905,6 +20907,9 @@
20905
20907
  shrink
20906
20908
  } = t0;
20907
20909
  const userConfigurationPersistence = useUserConfigurationPersistence();
20910
+ const {
20911
+ t
20912
+ } = useTranslation();
20908
20913
  const t1 = collection ?? view;
20909
20914
  let t2;
20910
20915
  if ($[0] !== t1) {
@@ -20977,51 +20982,61 @@
20977
20982
  t5 = $[13];
20978
20983
  }
20979
20984
  const actions = t5;
20985
+ let t6;
20986
+ if ($[18] !== name || $[19] !== t) {
20987
+ t6 = t(name);
20988
+ $[18] = name;
20989
+ $[19] = t;
20990
+ $[20] = t6;
20991
+ } else {
20992
+ t6 = $[20];
20993
+ }
20994
+ const translatedName = t6;
20980
20995
  if (type === "admin") {
20981
- let t62;
20982
- if ($[18] !== collectionIcon || $[19] !== name || $[20] !== url) {
20983
- t62 = /* @__PURE__ */ jsxRuntime.jsx(SmallNavigationCard, { icon: collectionIcon, name, url });
20984
- $[18] = collectionIcon;
20985
- $[19] = name;
20986
- $[20] = url;
20987
- $[21] = t62;
20996
+ let t72;
20997
+ if ($[21] !== collectionIcon || $[22] !== translatedName || $[23] !== url) {
20998
+ t72 = /* @__PURE__ */ jsxRuntime.jsx(SmallNavigationCard, { icon: collectionIcon, name: translatedName, url });
20999
+ $[21] = collectionIcon;
21000
+ $[22] = translatedName;
21001
+ $[23] = url;
21002
+ $[24] = t72;
20988
21003
  } else {
20989
- t62 = $[21];
21004
+ t72 = $[24];
20990
21005
  }
20991
- return t62;
21006
+ return t72;
20992
21007
  }
20993
- let t6;
20994
- if ($[22] !== navigate || $[23] !== onClick || $[24] !== path || $[25] !== url || $[26] !== userConfigurationPersistence) {
20995
- t6 = () => {
21008
+ let t7;
21009
+ if ($[25] !== navigate || $[26] !== onClick || $[27] !== path || $[28] !== url || $[29] !== userConfigurationPersistence) {
21010
+ t7 = () => {
20996
21011
  onClick?.();
20997
21012
  navigate(url);
20998
21013
  if (userConfigurationPersistence) {
20999
21014
  userConfigurationPersistence.setRecentlyVisitedPaths([path, ...(userConfigurationPersistence.recentlyVisitedPaths ?? []).filter((p_0) => p_0 !== path)]);
21000
21015
  }
21001
21016
  };
21002
- $[22] = navigate;
21003
- $[23] = onClick;
21004
- $[24] = path;
21005
- $[25] = url;
21006
- $[26] = userConfigurationPersistence;
21007
- $[27] = t6;
21017
+ $[25] = navigate;
21018
+ $[26] = onClick;
21019
+ $[27] = path;
21020
+ $[28] = url;
21021
+ $[29] = userConfigurationPersistence;
21022
+ $[30] = t7;
21008
21023
  } else {
21009
- t6 = $[27];
21024
+ t7 = $[30];
21010
21025
  }
21011
- let t7;
21012
- if ($[28] !== actions || $[29] !== collectionIcon || $[30] !== description || $[31] !== name || $[32] !== shrink || $[33] !== t6) {
21013
- t7 = /* @__PURE__ */ jsxRuntime.jsx(NavigationCard, { icon: collectionIcon, name, description, actions, onClick: t6, shrink });
21014
- $[28] = actions;
21015
- $[29] = collectionIcon;
21016
- $[30] = description;
21017
- $[31] = name;
21018
- $[32] = shrink;
21019
- $[33] = t6;
21020
- $[34] = t7;
21026
+ let t8;
21027
+ if ($[31] !== actions || $[32] !== collectionIcon || $[33] !== description || $[34] !== shrink || $[35] !== t7 || $[36] !== translatedName) {
21028
+ t8 = /* @__PURE__ */ jsxRuntime.jsx(NavigationCard, { icon: collectionIcon, name: translatedName, description, actions, onClick: t7, shrink });
21029
+ $[31] = actions;
21030
+ $[32] = collectionIcon;
21031
+ $[33] = description;
21032
+ $[34] = shrink;
21033
+ $[35] = t7;
21034
+ $[36] = translatedName;
21035
+ $[37] = t8;
21021
21036
  } else {
21022
- t7 = $[34];
21037
+ t8 = $[37];
21023
21038
  }
21024
- return t7;
21039
+ return t8;
21025
21040
  }
21026
21041
  const animateLayoutChanges = (args) => sortable.defaultAnimateLayoutChanges({
21027
21042
  ...args,
@@ -23175,7 +23190,7 @@
23175
23190
  let t19;
23176
23191
  let t20;
23177
23192
  if ($[19] !== items2) {
23178
- t20 = items2.map(_temp$g);
23193
+ t20 = items2.map(_temp$h);
23179
23194
  $[19] = items2;
23180
23195
  $[20] = t20;
23181
23196
  } else {
@@ -23281,7 +23296,7 @@
23281
23296
  }
23282
23297
  return t29;
23283
23298
  });
23284
- function _temp$g(i) {
23299
+ function _temp$h(i) {
23285
23300
  return i.id;
23286
23301
  }
23287
23302
  function Board(t0) {
@@ -25217,7 +25232,8 @@
25217
25232
  properties,
25218
25233
  filterValues,
25219
25234
  setFilterValues,
25220
- forceFilter
25235
+ forceFilter,
25236
+ allowedFilters
25221
25237
  }) {
25222
25238
  const {
25223
25239
  t
@@ -25229,15 +25245,14 @@
25229
25245
  setLocalFilters(filterValues ?? {});
25230
25246
  }
25231
25247
  }, [open, filterValues]);
25232
- const filterableProperties = React.useMemo(() => {
25233
- return Object.entries(properties).filter(([key, property]) => {
25234
- if (!property) return false;
25235
- if (forceFilter && key in forceFilter) return false;
25236
- const baseProperty = property.dataType === "array" ? property.of : property;
25237
- if (!baseProperty) return false;
25238
- return ["string", "number", "boolean", "date", "reference"].includes(baseProperty.dataType);
25248
+ const editableFilterProperties = React.useMemo(() => {
25249
+ return Object.entries(properties).filter(([key]) => {
25250
+ const isFilterAllowed = !allowedFilters || allowedFilters.includes(key);
25251
+ const isFilterForced = Boolean(forceFilter && Object.keys(forceFilter).includes(key));
25252
+ return isFilterAllowed && !isFilterForced;
25239
25253
  });
25240
- }, [properties, forceFilter]);
25254
+ }, [properties, allowedFilters, forceFilter]);
25255
+ const hasEditableFilterProperties = editableFilterProperties.length > 0;
25241
25256
  const handleFilterChange = React.useCallback((propertyKey, value) => {
25242
25257
  setLocalFilters((prev) => {
25243
25258
  const newFilters = {
@@ -25269,22 +25284,26 @@
25269
25284
  }));
25270
25285
  }, []);
25271
25286
  const isAnyFieldHidden = Object.values(hiddenFields).some((hidden_0) => hidden_0);
25272
- const activeFilterCount = Object.keys(localFilters).length;
25273
- const renderFilterField = React.useCallback((propertyKey_1, property_0) => {
25274
- const isArray = property_0.dataType === "array";
25275
- const baseProperty_0 = isArray ? property_0.of : property_0;
25276
- if (!baseProperty_0) return null;
25287
+ const getActiveFilterCount = () => {
25288
+ const editableLocalFilters = Object.keys(localFilters).filter((key_0) => !forceFilter || !(key_0 in forceFilter));
25289
+ return editableLocalFilters.length;
25290
+ };
25291
+ const activeFilterCount = getActiveFilterCount();
25292
+ const renderFilterField = React.useCallback((propertyKey_1, property) => {
25293
+ const isArray = property.dataType === "array";
25294
+ const baseProperty = isArray ? property.of : property;
25295
+ if (!baseProperty) return null;
25277
25296
  const filterValue = localFilters[propertyKey_1];
25278
25297
  const setValue = (value_0) => handleFilterChange(propertyKey_1, value_0);
25279
- if (baseProperty_0.dataType === "reference") {
25280
- return /* @__PURE__ */ jsxRuntime.jsx(ReferenceFilterField, { value: filterValue, setValue, name: propertyKey_1, isArray, path: baseProperty_0.path, title: property_0.name, includeId: baseProperty_0.includeId, previewProperties: baseProperty_0.previewProperties, hidden: hiddenFields[propertyKey_1] ?? false, setHidden: (hidden_1) => setHiddenForField(propertyKey_1, hidden_1) });
25281
- } else if (baseProperty_0.dataType === "number" || baseProperty_0.dataType === "string") {
25282
- const enumValues = baseProperty_0.enumValues ? enumToObjectEntries(baseProperty_0.enumValues) : void 0;
25283
- return /* @__PURE__ */ jsxRuntime.jsx(StringNumberFilterField, { value: filterValue, setValue, name: propertyKey_1, dataType: baseProperty_0.dataType, isArray, enumValues, title: property_0.name });
25284
- } else if (baseProperty_0.dataType === "boolean") {
25285
- return /* @__PURE__ */ jsxRuntime.jsx(BooleanFilterField, { value: filterValue, setValue, name: propertyKey_1, title: property_0.name });
25286
- } else if (baseProperty_0.dataType === "date") {
25287
- return /* @__PURE__ */ jsxRuntime.jsx(DateTimeFilterField, { value: filterValue, setValue, name: propertyKey_1, mode: baseProperty_0.mode, isArray, title: property_0.name });
25298
+ if (baseProperty.dataType === "reference") {
25299
+ return /* @__PURE__ */ jsxRuntime.jsx(ReferenceFilterField, { value: filterValue, setValue, name: propertyKey_1, isArray, path: baseProperty.path, title: property.name, includeId: baseProperty.includeId, previewProperties: baseProperty.previewProperties, hidden: hiddenFields[propertyKey_1] ?? false, setHidden: (hidden_1) => setHiddenForField(propertyKey_1, hidden_1) });
25300
+ } else if (baseProperty.dataType === "number" || baseProperty.dataType === "string") {
25301
+ const enumValues = baseProperty.enumValues ? enumToObjectEntries(baseProperty.enumValues) : void 0;
25302
+ return /* @__PURE__ */ jsxRuntime.jsx(StringNumberFilterField, { value: filterValue, setValue, name: propertyKey_1, dataType: baseProperty.dataType, isArray, enumValues, title: property.name });
25303
+ } else if (baseProperty.dataType === "boolean") {
25304
+ return /* @__PURE__ */ jsxRuntime.jsx(BooleanFilterField, { value: filterValue, setValue, name: propertyKey_1, title: property.name });
25305
+ } else if (baseProperty.dataType === "date") {
25306
+ return /* @__PURE__ */ jsxRuntime.jsx(DateTimeFilterField, { value: filterValue, setValue, name: propertyKey_1, mode: baseProperty.mode, isArray, title: property.name });
25288
25307
  }
25289
25308
  return null;
25290
25309
  }, [localFilters, handleFilterChange, hiddenFields, setHiddenForField]);
@@ -25293,23 +25312,25 @@
25293
25312
  /* @__PURE__ */ jsxRuntime.jsx(ui.Typography, { variant: "h6", children: t("filters") }),
25294
25313
  activeFilterCount > 0 && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "ml-2 px-2 py-0.5 text-xs rounded-full bg-primary text-white", children: activeFilterCount })
25295
25314
  ] }),
25296
- /* @__PURE__ */ jsxRuntime.jsx(ui.DialogContent, { children: filterableProperties.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx(ui.Typography, { color: "secondary", className: "py-8 text-center", children: t("no_filterable_properties") }) : /* @__PURE__ */ jsxRuntime.jsx("table", { className: "w-full border-collapse", children: /* @__PURE__ */ jsxRuntime.jsx("tbody", { children: filterableProperties.map(([propertyKey_2, property_1], index) => {
25315
+ /* @__PURE__ */ jsxRuntime.jsx(ui.DialogContent, { children: !hasEditableFilterProperties ? /* @__PURE__ */ jsxRuntime.jsx(ui.Typography, { color: "secondary", className: "py-8 text-center", children: t("no_filterable_properties") }) : /* @__PURE__ */ jsxRuntime.jsx("table", { className: "w-full border-collapse", children: /* @__PURE__ */ jsxRuntime.jsx("tbody", { children: editableFilterProperties.map(([propertyKey_2, property_0], index) => {
25297
25316
  const hasFilter = propertyKey_2 in localFilters;
25298
25317
  return /* @__PURE__ */ jsxRuntime.jsxs("tr", { className: ui.cls(index > 0 && "border-t", ui.defaultBorderMixin), children: [
25299
- /* @__PURE__ */ jsxRuntime.jsx("td", { className: "py-3 pr-4 align-middle w-[160px]", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Typography, { variant: "body2", className: ui.cls("font-medium", hasFilter && "text-primary"), children: property_1.name || propertyKey_2 }) }),
25300
- /* @__PURE__ */ jsxRuntime.jsx("td", { className: "py-3", children: renderFilterField(propertyKey_2, property_1) })
25318
+ /* @__PURE__ */ jsxRuntime.jsx("td", { className: "py-3 pr-4 align-middle w-[160px]", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Typography, { variant: "body2", className: ui.cls("font-medium", hasFilter && "text-primary"), children: property_0.name || propertyKey_2 }) }),
25319
+ /* @__PURE__ */ jsxRuntime.jsx("td", { className: "py-3", children: renderFilterField(propertyKey_2, property_0) })
25301
25320
  ] }, propertyKey_2);
25302
25321
  }) }) }) }),
25303
25322
  /* @__PURE__ */ jsxRuntime.jsxs(ui.DialogActions, { children: [
25304
25323
  /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "text", onClick: handleClearAll, disabled: activeFilterCount === 0, children: t("clear") }),
25305
25324
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-grow" }),
25306
- /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "text", onClick: () => onOpenChange(false), children: t("cancel") }),
25307
- /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "filled", onClick: handleApply, children: t("apply_filters") })
25325
+ hasEditableFilterProperties && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
25326
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "text", onClick: () => onOpenChange(false), children: t("cancel") }),
25327
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "filled", onClick: handleApply, children: t("apply_filters") })
25328
+ ] })
25308
25329
  ] })
25309
25330
  ] });
25310
25331
  }
25311
25332
  function EntityCollectionViewStartActions(t0) {
25312
- const $ = reactCompilerRuntime.c(36);
25333
+ const $ = reactCompilerRuntime.c(37);
25313
25334
  const {
25314
25335
  collection,
25315
25336
  relativePath,
@@ -25373,34 +25394,36 @@
25373
25394
  t3 = $[13];
25374
25395
  }
25375
25396
  const actionProps = t3;
25397
+ const hasAnyAllowedFilters = !tableController.allowedFilters || tableController.allowedFilters.length > 0;
25376
25398
  let t4;
25377
- if ($[14] !== activeFilterCount || $[15] !== largeLayout || $[16] !== resolvedProperties || $[17] !== t || $[18] !== tableController.setFilterValues) {
25378
- t4 = resolvedProperties && tableController.setFilterValues && /* @__PURE__ */ jsxRuntime.jsx(ui.Tooltip, { title: t("filters"), children: /* @__PURE__ */ jsxRuntime.jsx(ui.Badge, { color: "primary", invisible: activeFilterCount === 0, children: largeLayout ? /* @__PURE__ */ jsxRuntime.jsxs(ui.Button, { variant: "text", size: "small", onClick: () => setFiltersDialogOpen(true), startIcon: /* @__PURE__ */ jsxRuntime.jsx(ui.FilterListIcon, { size: "small" }), className: ui.cls(activeFilterCount > 0 && "text-primary"), children: [
25399
+ if ($[14] !== activeFilterCount || $[15] !== hasAnyAllowedFilters || $[16] !== largeLayout || $[17] !== resolvedProperties || $[18] !== t || $[19] !== tableController.setFilterValues) {
25400
+ t4 = resolvedProperties && tableController.setFilterValues && hasAnyAllowedFilters && /* @__PURE__ */ jsxRuntime.jsx(ui.Tooltip, { title: t("filters"), children: /* @__PURE__ */ jsxRuntime.jsx(ui.Badge, { color: "primary", invisible: activeFilterCount === 0, children: largeLayout ? /* @__PURE__ */ jsxRuntime.jsxs(ui.Button, { variant: "text", size: "small", onClick: () => setFiltersDialogOpen(true), startIcon: /* @__PURE__ */ jsxRuntime.jsx(ui.FilterListIcon, { size: "small" }), className: ui.cls(activeFilterCount > 0 && "text-primary"), children: [
25379
25401
  t("filters"),
25380
25402
  activeFilterCount > 0 ? ` (${activeFilterCount})` : ""
25381
25403
  ] }) : /* @__PURE__ */ jsxRuntime.jsx(ui.IconButton, { size: "small", onClick: () => setFiltersDialogOpen(true), className: ui.cls(activeFilterCount > 0 && "text-primary"), children: /* @__PURE__ */ jsxRuntime.jsx(ui.FilterListIcon, { size: "small" }) }) }) }, "filters_tooltip");
25382
25404
  $[14] = activeFilterCount;
25383
- $[15] = largeLayout;
25384
- $[16] = resolvedProperties;
25385
- $[17] = t;
25386
- $[18] = tableController.setFilterValues;
25387
- $[19] = t4;
25405
+ $[15] = hasAnyAllowedFilters;
25406
+ $[16] = largeLayout;
25407
+ $[17] = resolvedProperties;
25408
+ $[18] = t;
25409
+ $[19] = tableController.setFilterValues;
25410
+ $[20] = t4;
25388
25411
  } else {
25389
- t4 = $[19];
25412
+ t4 = $[20];
25390
25413
  }
25391
25414
  const filtersButton = t4;
25392
25415
  const t5 = !collection.forceFilter;
25393
25416
  let t6;
25394
- if ($[20] !== t5 || $[21] !== tableController) {
25417
+ if ($[21] !== t5 || $[22] !== tableController) {
25395
25418
  t6 = /* @__PURE__ */ jsxRuntime.jsx(ClearFilterSortButton, { tableController, enabled: t5 }, "clear_filter");
25396
- $[20] = t5;
25397
- $[21] = tableController;
25398
- $[22] = t6;
25419
+ $[21] = t5;
25420
+ $[22] = tableController;
25421
+ $[23] = t6;
25399
25422
  } else {
25400
- t6 = $[22];
25423
+ t6 = $[23];
25401
25424
  }
25402
25425
  let actions;
25403
- if ($[23] !== actionProps || $[24] !== filtersButton || $[25] !== plugins || $[26] !== t6) {
25426
+ if ($[24] !== actionProps || $[25] !== filtersButton || $[26] !== plugins || $[27] !== t6) {
25404
25427
  actions = [filtersButton, t6];
25405
25428
  if (plugins) {
25406
25429
  plugins.forEach((plugin, i) => {
@@ -25409,39 +25432,42 @@
25409
25432
  }
25410
25433
  });
25411
25434
  }
25412
- $[23] = actionProps;
25413
- $[24] = filtersButton;
25414
- $[25] = plugins;
25415
- $[26] = t6;
25416
- $[27] = actions;
25435
+ $[24] = actionProps;
25436
+ $[25] = filtersButton;
25437
+ $[26] = plugins;
25438
+ $[27] = t6;
25439
+ $[28] = actions;
25417
25440
  } else {
25418
- actions = $[27];
25441
+ actions = $[28];
25419
25442
  }
25420
25443
  let t7;
25421
- if ($[28] !== collection.forceFilter || $[29] !== filtersDialogOpen || $[30] !== resolvedProperties || $[31] !== tableController) {
25422
- t7 = resolvedProperties && tableController.setFilterValues && /* @__PURE__ */ jsxRuntime.jsx(FiltersDialog, { open: filtersDialogOpen, onOpenChange: setFiltersDialogOpen, properties: resolvedProperties, filterValues: tableController.filterValues, setFilterValues: (filterValues_0) => tableController.setFilterValues?.(filterValues_0 ?? {}), forceFilter: collection.forceFilter });
25423
- $[28] = collection.forceFilter;
25424
- $[29] = filtersDialogOpen;
25425
- $[30] = resolvedProperties;
25426
- $[31] = tableController;
25427
- $[32] = t7;
25444
+ if ($[29] !== collection.forceFilter || $[30] !== filtersDialogOpen || $[31] !== resolvedProperties || $[32] !== tableController) {
25445
+ t7 = resolvedProperties && tableController.setFilterValues && /* @__PURE__ */ jsxRuntime.jsx(FiltersDialog, { open: filtersDialogOpen, onOpenChange: setFiltersDialogOpen, properties: resolvedProperties, filterValues: tableController.filterValues, setFilterValues: (filterValues_0) => tableController.setFilterValues?.(filterValues_0 ?? {}), forceFilter: collection.forceFilter, allowedFilters: tableController.allowedFilters?.map(_temp$g) });
25446
+ $[29] = collection.forceFilter;
25447
+ $[30] = filtersDialogOpen;
25448
+ $[31] = resolvedProperties;
25449
+ $[32] = tableController;
25450
+ $[33] = t7;
25428
25451
  } else {
25429
- t7 = $[32];
25452
+ t7 = $[33];
25430
25453
  }
25431
25454
  let t8;
25432
- if ($[33] !== actions || $[34] !== t7) {
25455
+ if ($[34] !== actions || $[35] !== t7) {
25433
25456
  t8 = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
25434
25457
  actions,
25435
25458
  t7
25436
25459
  ] });
25437
- $[33] = actions;
25438
- $[34] = t7;
25439
- $[35] = t8;
25460
+ $[34] = actions;
25461
+ $[35] = t7;
25462
+ $[36] = t8;
25440
25463
  } else {
25441
- t8 = $[35];
25464
+ t8 = $[36];
25442
25465
  }
25443
25466
  return t8;
25444
25467
  }
25468
+ function _temp$g(key_0) {
25469
+ return key_0.toString();
25470
+ }
25445
25471
  const collectionScrollCache = /* @__PURE__ */ new Map();
25446
25472
  function useScrollRestoration() {
25447
25473
  const updateCollectionScroll = ({
@@ -25500,7 +25526,12 @@
25500
25526
  const scrollRestoration = useScrollRestoration();
25501
25527
  const collection = React.useMemo(() => {
25502
25528
  const userOverride = userConfigPersistence?.getCollectionConfig(fullPath);
25503
- return userOverride ? mergeDeep(collectionProp, userOverride) : collectionProp;
25529
+ if (!userOverride) return collectionProp;
25530
+ const {
25531
+ properties,
25532
+ ...rest
25533
+ } = userOverride;
25534
+ return mergeDeep(collectionProp, rest);
25504
25535
  }, [collectionProp, fullPath, userConfigPersistence?.getCollectionConfig]);
25505
25536
  const openEntityMode = collection?.openEntityMode ?? DEFAULT_ENTITY_OPEN_MODE;
25506
25537
  const collectionRef = React.useRef(collection);
@@ -25754,11 +25785,12 @@
25754
25785
  collection,
25755
25786
  path: fullPath,
25756
25787
  propertyConfigs: customizationController.propertyConfigs,
25757
- authController
25758
- }), [collection, fullPath]);
25788
+ authController,
25789
+ userConfigPersistence
25790
+ }), [collection, fullPath, userConfigPersistence]);
25759
25791
  const hasEnumProperty = React.useMemo(() => {
25760
- const properties = resolvedCollection.properties;
25761
- return Object.values(properties).some((prop) => prop && prop.dataType === "string" && prop.enumValues);
25792
+ const properties_0 = resolvedCollection.properties;
25793
+ return Object.values(properties_0).some((prop) => prop && prop.dataType === "string" && prop.enumValues);
25762
25794
  }, [resolvedCollection.properties]);
25763
25795
  const enabledViews = React.useMemo(() => {
25764
25796
  const configured = collection.enabledViews ?? ["table", "cards", "kanban"];
@@ -25769,8 +25801,8 @@
25769
25801
  }, [collection.enabledViews, hasEnumProperty]);
25770
25802
  const kanbanPropertyOptions = React.useMemo(() => {
25771
25803
  const options = [];
25772
- const properties_0 = resolvedCollection.properties;
25773
- for (const [key_0, property_0] of Object.entries(properties_0)) {
25804
+ const properties_1 = resolvedCollection.properties;
25805
+ for (const [key_0, property_0] of Object.entries(properties_1)) {
25774
25806
  const prop_0 = property_0;
25775
25807
  if (prop_0 && prop_0.dataType === "string" && prop_0.enumValues) {
25776
25808
  options.push({
@@ -27133,7 +27165,7 @@
27133
27165
  const onMultipleEntitiesSelected = React.useCallback((entities) => {
27134
27166
  if (disabled) return;
27135
27167
  if (onMultipleReferenceSelected) {
27136
- const references = entities ? entities.map((e) => getReferenceFrom(e)) : null;
27168
+ const references = entities ? entities.filter(Boolean).map((e) => getReferenceFrom(e)) : null;
27137
27169
  onMultipleReferenceSelected({
27138
27170
  references,
27139
27171
  entities
@@ -28073,7 +28105,14 @@
28073
28105
  if (!collections_0) return void 0;
28074
28106
  const baseCollection = getCollectionByPathOrId(removeInitialAndTrailingSlashes(idOrPath), collections_0);
28075
28107
  const userOverride = includeUserOverride ? userConfigPersistence?.getCollectionConfig(idOrPath) : void 0;
28076
- const overriddenCollection = baseCollection ? mergeDeep(baseCollection, userOverride ?? {}) : void 0;
28108
+ let overriddenCollection = baseCollection;
28109
+ if (baseCollection && userOverride) {
28110
+ const {
28111
+ properties,
28112
+ ...rest
28113
+ } = userOverride;
28114
+ overriddenCollection = mergeDeep(baseCollection, rest);
28115
+ }
28077
28116
  let result = overriddenCollection;
28078
28117
  if (overriddenCollection) {
28079
28118
  const subcollections = overriddenCollection.subcollections;
@@ -30014,7 +30053,7 @@
30014
30053
  replace: true,
30015
30054
  state: {
30016
30055
  base_location: baseLocation,
30017
- panels: updatedPanels.map(_temp4$1)
30056
+ panels: updatedPanels.map(_temp4$2)
30018
30057
  }
30019
30058
  });
30020
30059
  }
@@ -30112,7 +30151,7 @@
30112
30151
  function _temp5$1(p_3) {
30113
30152
  return p_3.key;
30114
30153
  }
30115
- function _temp4$1(p_2) {
30154
+ function _temp4$2(p_2) {
30116
30155
  return p_2.key;
30117
30156
  }
30118
30157
  function _temp3$2(p_1) {
@@ -32258,7 +32297,7 @@
32258
32297
  const otherChildren = t3;
32259
32298
  const includeDrawer = drawerChildren.length > 0;
32260
32299
  const largeLayout = useLargeLayout();
32261
- const [drawerOpen, setDrawerOpen] = React.useState(false);
32300
+ const [drawerOpen, setDrawerOpen] = React.useState(_temp4$1);
32262
32301
  const [onHover, setOnHover] = React.useState(false);
32263
32302
  let t4;
32264
32303
  if ($[6] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
@@ -32280,6 +32319,10 @@
32280
32319
  if ($[8] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
32281
32320
  t6 = () => {
32282
32321
  setDrawerOpen(true);
32322
+ try {
32323
+ localStorage.setItem("firecms_drawer_open", "true");
32324
+ } catch {
32325
+ }
32283
32326
  };
32284
32327
  $[8] = t6;
32285
32328
  } else {
@@ -32290,6 +32333,10 @@
32290
32333
  if ($[9] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
32291
32334
  t7 = () => {
32292
32335
  setDrawerOpen(false);
32336
+ try {
32337
+ localStorage.setItem("firecms_drawer_open", "false");
32338
+ } catch {
32339
+ }
32293
32340
  };
32294
32341
  $[9] = t7;
32295
32342
  } else {
@@ -32642,6 +32689,13 @@
32642
32689
  function _temp3$1(child_1) {
32643
32690
  return child_1.type.componentType !== "Drawer" && child_1.type.componentType !== "AppBar";
32644
32691
  }
32692
+ function _temp4$1() {
32693
+ try {
32694
+ return localStorage.getItem("firecms_drawer_open") === "true";
32695
+ } catch {
32696
+ return false;
32697
+ }
32698
+ }
32645
32699
  const en = {
32646
32700
  // ─── Form actions ────────────────────────────────────────────
32647
32701
  save: "Save",
@@ -32779,8 +32833,8 @@
32779
32833
  // ─── Error states ─────────────────────────────────────────────
32780
32834
  error: "Error",
32781
32835
  error_uploading_file: "Error uploading file",
32782
- error_deleting: "Error deleting",
32783
- error_before_delete: "Error before delete",
32836
+ error_deleting: "Error deleting: {{message}}",
32837
+ error_before_delete: "Error before delete: {{message}}",
32784
32838
  error_updating_asset: "Error updating asset",
32785
32839
  error_deleting_asset: "Error deleting asset",
32786
32840
  error_firestore_index: "A Firestore index is required for this query.",
@@ -33045,8 +33099,8 @@
33045
33099
  cms_users: "CMS Users",
33046
33100
  roles_menu: "Roles",
33047
33101
  project_settings: "Project settings",
33048
- firestore_explorer: "Firestore Explorer",
33049
- explore_your_firestore_data: "Explore your Firestore data",
33102
+ firestore_manager: "Firestore Manager",
33103
+ manage_your_firestore_data: "Manage your Firestore data",
33050
33104
  // ─── FireCMS Cloud Login ──────────────────────────────────────
33051
33105
  build_admin_panel_in_minutes: "Build Your Firebase Admin Panel in Minutes",
33052
33106
  go_live_instantly: "Go live instantly:",
@@ -33117,10 +33171,18 @@
33117
33171
  auto_setup_collections_button: "Automatically set up collections",
33118
33172
  auto_setup_collections_title: "Automatically set up collections?",
33119
33173
  auto_setup_collections_desc: "This will automatically create collection configs for collections that are <b>NOT</b> already mapped",
33120
- this_can_take_a_minute: "This can take a minute or two",
33174
+ setting_up_collections: "Setting up collections",
33175
+ setting_up_collection: "Setting up {{name}}",
33121
33176
  no_collections_found_to_setup: "No collections found to setup.",
33122
33177
  collections_have_been_setup: "Collections have been automatically setup.",
33123
33178
  error_setting_up_collections: "Error automatically setting up collections",
33179
+ setup_collections_title: "Set up collections",
33180
+ setup_collections_select_desc: "Select which collections to automatically set up:",
33181
+ select_all: "Select all",
33182
+ deselect_all: "Deselect all",
33183
+ setup_collections_confirm: "Set up ({{count}})",
33184
+ collection_setup_success: "{{name}} has been set up",
33185
+ go_to_collection: "Go to collection",
33124
33186
  // --- Home Suggestions ---
33125
33187
  add_your: "Add your",
33126
33188
  database_collections: "database collections",
@@ -33448,8 +33510,8 @@
33448
33510
  // ─── Error states ─────────────────────────────────────────────
33449
33511
  error: "Error",
33450
33512
  error_uploading_file: "Error al subir archivo",
33451
- error_deleting: "Error al eliminar",
33452
- error_before_delete: "Error antes de eliminar",
33513
+ error_deleting: "Error al eliminar: {{message}}",
33514
+ error_before_delete: "Error antes de eliminar: {{message}}",
33453
33515
  error_updating_asset: "Error al actualizar recurso",
33454
33516
  error_deleting_asset: "Error al eliminar recurso",
33455
33517
  error_firestore_index: "Se requiere un índice de Firestore para esta consulta.",
@@ -33716,8 +33778,8 @@
33716
33778
  cms_users: "Usuarios del CMS",
33717
33779
  roles_menu: "Roles",
33718
33780
  project_settings: "Ajustes del proyecto",
33719
- firestore_explorer: "Explorador de Firestore",
33720
- explore_your_firestore_data: "Explora tus datos de Firestore",
33781
+ firestore_manager: "Gestor de Firestore",
33782
+ manage_your_firestore_data: "Gestiona tus datos de Firestore",
33721
33783
  // ─── FireCMS Cloud Login ──────────────────────────────────────
33722
33784
  build_admin_panel_in_minutes: "Crea tu panel de administración de Firebase en minutos",
33723
33785
  go_live_instantly: "En vivo al instante:",
@@ -33788,10 +33850,18 @@
33788
33850
  auto_setup_collections_button: "Configurar colecciones automáticamente",
33789
33851
  auto_setup_collections_title: "¿Configurar colecciones automáticamente?",
33790
33852
  auto_setup_collections_desc: "Esto creará automáticamente la configuración de las colecciones que <b>NO</b> estén mapeadas",
33791
- this_can_take_a_minute: "Esto puede tardar un minuto o dos",
33853
+ setting_up_collections: "Configurando colecciones",
33854
+ setting_up_collection: "Configurando {{name}}",
33792
33855
  no_collections_found_to_setup: "No se encontraron colecciones para configurar",
33793
33856
  collections_have_been_setup: "¡Tus colecciones han sido configuradas!",
33794
33857
  error_setting_up_collections: "Error al configurar colecciones",
33858
+ setup_collections_title: "Set up collections",
33859
+ setup_collections_select_desc: "Select which collections to automatically set up:",
33860
+ select_all: "Select all",
33861
+ deselect_all: "Deselect all",
33862
+ setup_collections_confirm: "Set up ({{count}})",
33863
+ collection_setup_success: "{{name}} has been set up",
33864
+ go_to_collection: "Go to collection",
33795
33865
  // --- Home Suggestions ---
33796
33866
  add_your: "Añade tus",
33797
33867
  database_collections: "colecciones de base de datos",
@@ -34121,8 +34191,8 @@
34121
34191
  // ─── Error states ─────────────────────────────────────────────
34122
34192
  error: "Fehler",
34123
34193
  error_uploading_file: "Fehler beim Hochladen der Datei",
34124
- error_deleting: "Fehler beim Löschen",
34125
- error_before_delete: "Fehler vor dem Löschen",
34194
+ error_deleting: "Fehler beim Löschen: {{message}}",
34195
+ error_before_delete: "Fehler vor dem Löschen: {{message}}",
34126
34196
  error_updating_asset: "Fehler beim Aktualisieren des Assets",
34127
34197
  error_deleting_asset: "Fehler beim Löschen des Assets",
34128
34198
  error_firestore_index: "Für diese Abfrage ist ein Firestore-Index erforderlich.",
@@ -34387,8 +34457,8 @@
34387
34457
  cms_users: "CMS-Benutzer",
34388
34458
  roles_menu: "Rollen",
34389
34459
  project_settings: "Projekteinstellungen",
34390
- firestore_explorer: "Firestore-Explorer",
34391
- explore_your_firestore_data: "Deine Firestore-Daten durchsuchen",
34460
+ firestore_manager: "Firestore-Manager",
34461
+ manage_your_firestore_data: "Deine Firestore-Daten verwalten",
34392
34462
  // ─── FireCMS Cloud Login ──────────────────────────────────────
34393
34463
  build_admin_panel_in_minutes: "Erstellen Sie Ihr Firebase Admin Panel in wenigen Minuten",
34394
34464
  go_live_instantly: "Sofort live gehen:",
@@ -34459,10 +34529,18 @@
34459
34529
  auto_setup_collections_button: "Sammlungen automatisch einrichten",
34460
34530
  auto_setup_collections_title: "Sammlungen automatisch einrichten?",
34461
34531
  auto_setup_collections_desc: "Dadurch werden automatisch Sammlungskonfigurationen für Sammlungen erstellt, die noch <b>NICHT</b> zugeordnet sind.",
34462
- this_can_take_a_minute: "Dies kann ein bis zwei Minuten dauern",
34532
+ setting_up_collections: "Sammlungen werden eingerichtet",
34533
+ setting_up_collection: "{{name}} wird eingerichtet",
34463
34534
  no_collections_found_to_setup: "Keine einzurichtenden Sammlungen gefunden",
34464
34535
  collections_have_been_setup: "Sammlungen wurden automatisch eingerichtet",
34465
34536
  error_setting_up_collections: "Fehler beim automatischen Einrichten der Sammlungen",
34537
+ setup_collections_title: "Set up collections",
34538
+ setup_collections_select_desc: "Select which collections to automatically set up:",
34539
+ select_all: "Select all",
34540
+ deselect_all: "Deselect all",
34541
+ setup_collections_confirm: "Set up ({{count}})",
34542
+ collection_setup_success: "{{name}} has been set up",
34543
+ go_to_collection: "Go to collection",
34466
34544
  add_your: "Fügen Sie Ihre",
34467
34545
  database_collections: "Datenbanksammlungen",
34468
34546
  to_firecms: "zu FireCMS hinzu",
@@ -34790,8 +34868,8 @@
34790
34868
  // ─── Error states ─────────────────────────────────────────────
34791
34869
  error: "Erreur",
34792
34870
  error_uploading_file: "Erreur lors du téléchargement du fichier",
34793
- error_deleting: "Erreur lors de la suppression",
34794
- error_before_delete: "Erreur avant la suppression",
34871
+ error_deleting: "Erreur lors de la suppression: {{message}}",
34872
+ error_before_delete: "Erreur avant la suppression: {{message}}",
34795
34873
  error_updating_asset: "Erreur lors de la mise à jour de l'actif",
34796
34874
  error_deleting_asset: "Erreur lors de la suppression de l'actif",
34797
34875
  error_firestore_index: "Un index Firestore est requis pour cette requête.",
@@ -35056,8 +35134,8 @@
35056
35134
  cms_users: "Utilisateurs du CMS",
35057
35135
  roles_menu: "Rôles",
35058
35136
  project_settings: "Paramètres du projet",
35059
- firestore_explorer: "Explorateur Firestore",
35060
- explore_your_firestore_data: "Explorez vos données Firestore",
35137
+ firestore_manager: "Gestionnaire Firestore",
35138
+ manage_your_firestore_data: "Gérez vos données Firestore",
35061
35139
  // ─── FireCMS Cloud Login ──────────────────────────────────────
35062
35140
  build_admin_panel_in_minutes: "Créez votre panneau d'administration Firebase en quelques minutes",
35063
35141
  go_live_instantly: "Mise en ligne immédiate :",
@@ -35128,10 +35206,18 @@
35128
35206
  auto_setup_collections_button: "Configurer les collections automatiquement",
35129
35207
  auto_setup_collections_title: "Configurer les collections automatiquement ?",
35130
35208
  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",
35131
- this_can_take_a_minute: "Cela peut prendre une minute",
35209
+ setting_up_collections: "Configuration des collections",
35210
+ setting_up_collection: "Configuration de {{name}}",
35132
35211
  no_collections_found_to_setup: "Aucune collection à configurer trouvée",
35133
35212
  collections_have_been_setup: "Les collections ont été configurées",
35134
35213
  error_setting_up_collections: "Erreur lors de la configuration des collections",
35214
+ setup_collections_title: "Set up collections",
35215
+ setup_collections_select_desc: "Select which collections to automatically set up:",
35216
+ select_all: "Select all",
35217
+ deselect_all: "Deselect all",
35218
+ setup_collections_confirm: "Set up ({{count}})",
35219
+ collection_setup_success: "{{name}} has been set up",
35220
+ go_to_collection: "Go to collection",
35135
35221
  add_your: "Ajoutez vos",
35136
35222
  database_collections: "collections de base de données",
35137
35223
  to_firecms: "à FireCMS",
@@ -35459,8 +35545,8 @@
35459
35545
  // ─── Error states ─────────────────────────────────────────────
35460
35546
  error: "Errore",
35461
35547
  error_uploading_file: "Errore durante il caricamento del file",
35462
- error_deleting: "Errore durante l'eliminazione",
35463
- error_before_delete: "Errore prima dell'eliminazione",
35548
+ error_deleting: "Errore durante l'eliminazione: {{message}}",
35549
+ error_before_delete: "Errore prima dell'eliminazione: {{message}}",
35464
35550
  error_updating_asset: "Errore durante l'aggiornamento dell'asset",
35465
35551
  error_deleting_asset: "Errore durante l'eliminazione dell'asset",
35466
35552
  error_firestore_index: "Per questa query è richiesto un indice Firestore.",
@@ -35725,8 +35811,8 @@
35725
35811
  cms_users: "Utenti CMS",
35726
35812
  roles_menu: "Ruoli",
35727
35813
  project_settings: "Impostazioni del progetto",
35728
- firestore_explorer: "Esplora Firestore",
35729
- explore_your_firestore_data: "Esplora i tuoi dati Firestore",
35814
+ firestore_manager: "Gestore Firestore",
35815
+ manage_your_firestore_data: "Gestisci i tuoi dati Firestore",
35730
35816
  // ─── FireCMS Cloud Login ──────────────────────────────────────
35731
35817
  build_admin_panel_in_minutes: "Crea il tuo pannello di amministrazione Firebase in pochi minuti",
35732
35818
  go_live_instantly: "Online in un istante:",
@@ -35797,10 +35883,18 @@
35797
35883
  auto_setup_collections_button: "Configura le collezioni automaticamente",
35798
35884
  auto_setup_collections_title: "Configurazione automatica delle collezioni",
35799
35885
  auto_setup_collections_desc: "Configura le collezioni automaticamente in base ai dati Firestore esistenti. Lascia che FireCMS configuri il CMS perfetto per te.",
35800
- this_can_take_a_minute: "Potrebbe richiedere qualche minuto",
35886
+ setting_up_collections: "Configurazione delle collezioni",
35887
+ setting_up_collection: "Configurazione di {{name}}",
35801
35888
  no_collections_found_to_setup: "Nessuna collezione trovata da configurare",
35802
35889
  collections_have_been_setup: "Le collezioni sono state configurate",
35803
35890
  error_setting_up_collections: "Errore durante la configurazione delle collezioni",
35891
+ setup_collections_title: "Set up collections",
35892
+ setup_collections_select_desc: "Select which collections to automatically set up:",
35893
+ select_all: "Select all",
35894
+ deselect_all: "Deselect all",
35895
+ setup_collections_confirm: "Set up ({{count}})",
35896
+ collection_setup_success: "{{name}} has been set up",
35897
+ go_to_collection: "Go to collection",
35804
35898
  add_your: "Aggiungi le tue",
35805
35899
  database_collections: "collezioni del database",
35806
35900
  to_firecms: "a FireCMS",
@@ -36128,8 +36222,8 @@
36128
36222
  // ─── Error states ─────────────────────────────────────────────
36129
36223
  error: "त्रुटि",
36130
36224
  error_uploading_file: "फ़ाइल अपलोड करने में त्रुटि",
36131
- error_deleting: "हटाने में त्रुटि",
36132
- error_before_delete: "हटाने से पहले त्रुटि",
36225
+ error_deleting: "हटाने में त्रुटि: {{message}}",
36226
+ error_before_delete: "हटाने से पहले त्रुटि: {{message}}",
36133
36227
  error_updating_asset: "एसेट अपडेट करने में त्रुटि",
36134
36228
  error_deleting_asset: "एसेट हटाने में त्रुटि",
36135
36229
  error_firestore_index: "इस क्वेरी के लिए Firestore इंडेक्स आवश्यक है।",
@@ -36394,8 +36488,8 @@
36394
36488
  cms_users: "CMS उपयोगकर्ता",
36395
36489
  roles_menu: "भूमिकाएँ",
36396
36490
  project_settings: "परियोजना सेटिंग",
36397
- firestore_explorer: "Firestore एक्सप्लोरर",
36398
- explore_your_firestore_data: "अपने Firestore डेटा का अन्वेषण करें",
36491
+ firestore_manager: "Firestore मैनेजर",
36492
+ manage_your_firestore_data: "अपने Firestore डेटा का प्रबंधन करें",
36399
36493
  // ─── FireCMS Cloud Login ──────────────────────────────────────
36400
36494
  build_admin_panel_in_minutes: "मिनटों में अपना Firebase एडमिन पैनल बनाएं",
36401
36495
  go_live_instantly: "तुरंत लाइव जाएं:",
@@ -36466,10 +36560,18 @@
36466
36560
  auto_setup_collections_button: "संग्रहों को स्वचालित रूप से सेट करें",
36467
36561
  auto_setup_collections_title: "संग्रहों की स्वचालित सेटअप",
36468
36562
  auto_setup_collections_desc: "अपने मौजूदा Firestore डेटा के आधार पर संग्रहों को स्वचालित रूप से सेट करें। FireCMS को आपके लिए परफेक्ट CMS कॉन्फ़िगर करने दें।",
36469
- this_can_take_a_minute: "इसमें एक मिनट लग सकता है",
36563
+ setting_up_collections: "संग्रह सेट किए जा रहे हैं",
36564
+ setting_up_collection: "{{name}} सेट किया जा रहा है",
36470
36565
  no_collections_found_to_setup: "सेट करने के लिए कोई संग्रह नहीं मिला",
36471
36566
  collections_have_been_setup: "संग्रहों को सेट कर दिया गया है",
36472
36567
  error_setting_up_collections: "संग्रह सेट करने में त्रुटि",
36568
+ setup_collections_title: "Set up collections",
36569
+ setup_collections_select_desc: "Select which collections to automatically set up:",
36570
+ select_all: "Select all",
36571
+ deselect_all: "Deselect all",
36572
+ setup_collections_confirm: "Set up ({{count}})",
36573
+ collection_setup_success: "{{name}} has been set up",
36574
+ go_to_collection: "Go to collection",
36473
36575
  add_your: "अपने",
36474
36576
  database_collections: "डेटाबेस संग्रह",
36475
36577
  to_firecms: "को FireCMS में जोड़ें",
@@ -36797,8 +36899,8 @@
36797
36899
  // ─── Error states ─────────────────────────────────────────────
36798
36900
  error: "Erro",
36799
36901
  error_uploading_file: "Erro ao carregar ficheiro",
36800
- error_deleting: "Erro ao eliminar",
36801
- error_before_delete: "Erro antes de eliminar",
36902
+ error_deleting: "Erro ao eliminar: {{message}}",
36903
+ error_before_delete: "Erro antes de eliminar: {{message}}",
36802
36904
  error_updating_asset: "Erro ao atualizar recurso",
36803
36905
  error_deleting_asset: "Erro ao eliminar recurso",
36804
36906
  error_firestore_index: "É necessário um índice Firestore para esta consulta.",
@@ -37063,8 +37165,8 @@
37063
37165
  cms_users: "Utilizadores do CMS",
37064
37166
  roles_menu: "Funções",
37065
37167
  project_settings: "Definições do projeto",
37066
- firestore_explorer: "Explorador do Firestore",
37067
- explore_your_firestore_data: "Explore os seus dados do Firestore",
37168
+ firestore_manager: "Gerenciador do Firestore",
37169
+ manage_your_firestore_data: "Gerencie os seus dados do Firestore",
37068
37170
  // ─── FireCMS Cloud Login ──────────────────────────────────────
37069
37171
  build_admin_panel_in_minutes: "Construa o Seu Painel de Administração Firebase em Minutos",
37070
37172
  go_live_instantly: "Entre em produção instantaneamente:",
@@ -37135,10 +37237,18 @@
37135
37237
  auto_setup_collections_button: "Configurar coleções automaticamente",
37136
37238
  auto_setup_collections_title: "Configurar coleções automaticamente?",
37137
37239
  auto_setup_collections_desc: "Isto criará automaticamente configurações de coleção para coleções que <b>NÃO</b> estão já mapeadas",
37138
- this_can_take_a_minute: "Isto pode demorar um ou dois minutos",
37240
+ setting_up_collections: "Configurando coleções",
37241
+ setting_up_collection: "Configurando {{name}}",
37139
37242
  no_collections_found_to_setup: "Nenhuma coleção encontrada para configurar.",
37140
37243
  collections_have_been_setup: "As coleções foram configuradas automaticamente.",
37141
37244
  error_setting_up_collections: "Erro ao configurar coleções automaticamente",
37245
+ setup_collections_title: "Set up collections",
37246
+ setup_collections_select_desc: "Select which collections to automatically set up:",
37247
+ select_all: "Select all",
37248
+ deselect_all: "Deselect all",
37249
+ setup_collections_confirm: "Set up ({{count}})",
37250
+ collection_setup_success: "{{name}} has been set up",
37251
+ go_to_collection: "Go to collection",
37142
37252
  // --- Home Suggestions ---
37143
37253
  add_your: "Adicione as suas",
37144
37254
  database_collections: "coleções da base de dados",
@@ -42175,6 +42285,7 @@ ul[data-type="taskList"] li[data-checked="true"] > div > p {
42175
42285
  exports2.hydrateRegExp = hydrateRegExp;
42176
42286
  exports2.iconSynonyms = iconSynonyms;
42177
42287
  exports2.iconsSearch = iconsSearch;
42288
+ exports2.isDataTypeFilterable = isDataTypeFilterable;
42178
42289
  exports2.isDefaultFieldConfigId = isDefaultFieldConfigId;
42179
42290
  exports2.isEmptyObject = isEmptyObject;
42180
42291
  exports2.isEnumValueDisabled = isEnumValueDisabled;