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

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 (108) 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/EntityCollectionTable/internal/CollectionTableToolbar.d.ts +6 -1
  4. package/dist/components/EntityCollectionView/EntityCollectionView.d.ts +7 -0
  5. package/dist/components/EntityCollectionView/FiltersDialog.d.ts +2 -1
  6. package/dist/components/EntityPreview.d.ts +3 -1
  7. package/dist/components/SelectableTable/filters/filter_text_input.d.ts +30 -0
  8. package/dist/components/SelectableTable/filters/filter_text_input.test.d.ts +1 -0
  9. package/dist/components/common/table_url_params.d.ts +24 -0
  10. package/dist/components/common/useDataSourceTableController.d.ts +7 -1
  11. package/dist/components/common/useTableSearchHelper.d.ts +7 -1
  12. package/dist/core/DefaultDrawer.d.ts +10 -3
  13. package/dist/core/EntityEditView.d.ts +7 -1
  14. package/dist/core/field_configs.d.ts +1 -1
  15. package/dist/form/field_bindings/GeopointFieldBinding.d.ts +5 -0
  16. package/dist/form/index.d.ts +1 -0
  17. package/dist/hooks/data/save.d.ts +1 -1
  18. package/dist/hooks/data/useEntityFetch.d.ts +6 -1
  19. package/dist/index.es.js +2790 -1270
  20. package/dist/index.es.js.map +1 -1
  21. package/dist/index.umd.js +2788 -1268
  22. package/dist/index.umd.js.map +1 -1
  23. package/dist/locales/pl.d.ts +2 -0
  24. package/dist/preview/index.d.ts +1 -0
  25. package/dist/preview/property_previews/GeopointPropertyPreview.d.ts +4 -0
  26. package/dist/types/collections.d.ts +24 -0
  27. package/dist/types/datasource.d.ts +42 -0
  28. package/dist/types/properties.d.ts +17 -1
  29. package/dist/types/side_entity_controller.d.ts +6 -0
  30. package/dist/types/translations.d.ts +6 -0
  31. package/dist/util/__tests__/collections.test.d.ts +1 -0
  32. package/dist/util/__tests__/urls.test.d.ts +1 -0
  33. package/dist/util/collections.d.ts +1 -1
  34. package/dist/util/entities.d.ts +1 -0
  35. package/dist/util/geopoint.d.ts +22 -0
  36. package/dist/util/index.d.ts +2 -0
  37. package/dist/util/navigation_blocking.d.ts +22 -0
  38. package/dist/util/navigation_from_path.d.ts +17 -0
  39. package/dist/util/navigation_utils.d.ts +23 -1
  40. package/dist/util/urls.d.ts +22 -0
  41. package/package.json +16 -9
  42. package/src/app/Scaffold.tsx +34 -44
  43. package/src/app/useApp.tsx +1 -0
  44. package/src/components/EntityCollectionTable/EntityCollectionTable.tsx +3 -1
  45. package/src/components/EntityCollectionTable/column_utils.tsx +11 -19
  46. package/src/components/EntityCollectionTable/fields/TableReferenceField.tsx +1 -1
  47. package/src/components/EntityCollectionTable/internal/CollectionTableToolbar.tsx +7 -0
  48. package/src/components/EntityCollectionView/EntityCollectionView.tsx +19 -1
  49. package/src/components/EntityCollectionView/EntityCollectionViewStartActions.tsx +4 -1
  50. package/src/components/EntityCollectionView/FiltersDialog.tsx +39 -28
  51. package/src/components/EntityPreview.tsx +41 -40
  52. package/src/components/ReferenceWidget.tsx +1 -1
  53. package/src/components/SelectableTable/filters/ReferenceFilterField.tsx +2 -2
  54. package/src/components/SelectableTable/filters/StringNumberFilterField.tsx +33 -7
  55. package/src/components/SelectableTable/filters/filter_text_input.test.ts +184 -0
  56. package/src/components/SelectableTable/filters/filter_text_input.ts +71 -0
  57. package/src/components/VirtualTable/VirtualTable.tsx +19 -8
  58. package/src/components/common/table_url_params.ts +172 -0
  59. package/src/components/common/useDataSourceTableController.tsx +98 -159
  60. package/src/components/common/useTableSearchHelper.ts +21 -2
  61. package/src/contexts/SnackbarProvider.tsx +14 -1
  62. package/src/core/DefaultDrawer.tsx +150 -64
  63. package/src/core/DrawerNavigationGroup.tsx +27 -29
  64. package/src/core/DrawerNavigationItem.tsx +10 -12
  65. package/src/core/EntityEditView.tsx +75 -32
  66. package/src/core/EntitySidePanel.tsx +2 -0
  67. package/src/core/field_configs.tsx +15 -0
  68. package/src/form/EntityForm.tsx +1 -1
  69. package/src/form/field_bindings/ArrayOfReferencesFieldBinding.tsx +1 -1
  70. package/src/form/field_bindings/GeopointFieldBinding.tsx +139 -0
  71. package/src/form/index.tsx +1 -0
  72. package/src/hooks/data/save.ts +2 -0
  73. package/src/hooks/data/useEntityFetch.tsx +9 -0
  74. package/src/hooks/useValidateAuthenticator.tsx +4 -0
  75. package/src/i18n/FireCMSi18nProvider.tsx +2 -0
  76. package/src/internal/useBuildDataSource.ts +11 -0
  77. package/src/internal/useBuildSideEntityController.tsx +8 -1
  78. package/src/locales/de.ts +7 -2
  79. package/src/locales/en.ts +7 -2
  80. package/src/locales/es.ts +7 -2
  81. package/src/locales/fr.ts +7 -2
  82. package/src/locales/hi.ts +7 -2
  83. package/src/locales/it.ts +7 -2
  84. package/src/locales/pl.ts +735 -0
  85. package/src/locales/pt.ts +7 -2
  86. package/src/preview/PropertyPreview.tsx +12 -0
  87. package/src/preview/components/StorageThumbnail.tsx +24 -2
  88. package/src/preview/index.ts +1 -0
  89. package/src/preview/property_previews/GeopointPropertyPreview.tsx +23 -0
  90. package/src/routes/FireCMSRoute.tsx +47 -25
  91. package/src/types/collections.ts +26 -0
  92. package/src/types/datasource.ts +42 -0
  93. package/src/types/properties.ts +17 -0
  94. package/src/types/side_entity_controller.tsx +6 -0
  95. package/src/types/translations.ts +6 -0
  96. package/src/util/__tests__/collections.test.ts +32 -0
  97. package/src/util/__tests__/urls.test.ts +131 -0
  98. package/src/util/collections.ts +1 -1
  99. package/src/util/entities.ts +13 -0
  100. package/src/util/geopoint.ts +81 -0
  101. package/src/util/index.ts +2 -0
  102. package/src/util/navigation_blocking.ts +45 -0
  103. package/src/util/navigation_from_path.ts +41 -6
  104. package/src/util/navigation_utils.ts +40 -2
  105. package/src/util/parent_references_from_path.ts +4 -2
  106. package/src/util/previews.ts +8 -1
  107. package/src/util/resolutions.ts +8 -0
  108. package/src/util/urls.ts +52 -0
@@ -0,0 +1,139 @@
1
+ import React, { useEffect, useRef, useState } from "react";
2
+
3
+ import { CloseIcon, IconButton, TextField } from "@firecms/ui";
4
+ import { FieldProps, GeoPoint } from "../../types";
5
+ import { FieldHelperText, LabelWithIcon } from "../components";
6
+ import { PropertyIdCopyTooltip } from "../../components";
7
+ import { useClearRestoreValue } from "../useClearRestoreValue";
8
+ import { getIconForProperty } from "../../util";
9
+ import { formatGeoPoint, getGeoPointCoordinates, parseGeoPoint } from "../../util/geopoint";
10
+
11
+ type GeopointFieldBindingProps = FieldProps<GeoPoint>;
12
+
13
+ export function GeopointFieldBinding({
14
+ propertyKey,
15
+ value,
16
+ setValue,
17
+ error,
18
+ showError,
19
+ disabled,
20
+ autoFocus,
21
+ property,
22
+ includeDescription,
23
+ size = "large"
24
+ }: GeopointFieldBindingProps) {
25
+
26
+ const coordinates = getGeoPointCoordinates(value);
27
+ const canClear = Boolean((property as any).clearable);
28
+ const [latitude, setLatitude] = useState<string>(coordinates ? coordinates.latitude.toString() : "");
29
+ const [longitude, setLongitude] = useState<string>(coordinates ? coordinates.longitude.toString() : "");
30
+ const [localError, setLocalError] = useState<string | undefined>();
31
+ const skipSyncRef = useRef(false);
32
+
33
+ useClearRestoreValue({
34
+ property,
35
+ value,
36
+ setValue
37
+ });
38
+
39
+ useEffect(() => {
40
+ if (skipSyncRef.current) {
41
+ skipSyncRef.current = false;
42
+ return;
43
+ }
44
+ const nextCoordinates = getGeoPointCoordinates(value);
45
+ setLatitude(nextCoordinates ? nextCoordinates.latitude.toString() : "");
46
+ setLongitude(nextCoordinates ? nextCoordinates.longitude.toString() : "");
47
+ }, [value]);
48
+
49
+ const updateGeoPoint = (nextLatitude: string, nextLongitude: string) => {
50
+ skipSyncRef.current = true;
51
+ setLatitude(nextLatitude);
52
+ setLongitude(nextLongitude);
53
+
54
+ const trimmedLatitude = nextLatitude.trim();
55
+ const trimmedLongitude = nextLongitude.trim();
56
+
57
+ if (!trimmedLatitude && !trimmedLongitude) {
58
+ setLocalError(undefined);
59
+ setValue(null);
60
+ return;
61
+ }
62
+
63
+ const parsed = parseGeoPoint(`${trimmedLatitude}, ${trimmedLongitude}`);
64
+
65
+ if (parsed.error) {
66
+ setLocalError(parsed.error);
67
+ setValue(null);
68
+ return;
69
+ }
70
+
71
+ setLocalError(undefined);
72
+ setValue(parsed.point);
73
+ };
74
+
75
+ const handleClear = (event?: React.MouseEvent) => {
76
+ if (event) {
77
+ event.preventDefault();
78
+ event.stopPropagation();
79
+ }
80
+ updateGeoPoint("", "");
81
+ };
82
+
83
+ const resolvedError = localError ?? error;
84
+ const shouldShowError = Boolean(resolvedError) || Boolean(showError && error);
85
+
86
+ return (
87
+ <>
88
+ <PropertyIdCopyTooltip propertyKey={propertyKey}>
89
+ <div className="flex flex-col gap-2">
90
+ <div className="mt-1">
91
+ <LabelWithIcon
92
+ icon={getIconForProperty(property, "small")}
93
+ required={property.validation?.required}
94
+ title={property.name}
95
+ className={shouldShowError ? "text-red-500 dark:text-red-500" : "text-text-secondary dark:text-text-secondary-dark"}
96
+ />
97
+ </div>
98
+ <div className="grid grid-cols-1 gap-2 md:grid-cols-2">
99
+ <TextField
100
+ size={size}
101
+ value={latitude}
102
+ onChange={(event) => updateGeoPoint(event.target.value, longitude)}
103
+ autoFocus={autoFocus}
104
+ label={"Latitude"}
105
+ type="number"
106
+ disabled={disabled}
107
+ endAdornment={canClear ? (
108
+ <IconButton onClick={handleClear}>
109
+ <CloseIcon />
110
+ </IconButton>
111
+ ) : undefined}
112
+ error={shouldShowError && Boolean(resolvedError)}
113
+ />
114
+ <TextField
115
+ size={size}
116
+ value={longitude}
117
+ onChange={(event) => updateGeoPoint(latitude, event.target.value)}
118
+ label={"Longitude"}
119
+ type="number"
120
+ disabled={disabled}
121
+ error={shouldShowError && Boolean(resolvedError)}
122
+ />
123
+ </div>
124
+ {value && !resolvedError && (
125
+ <div className="text-xs text-text-secondary dark:text-text-secondary-dark font-mono">
126
+ {formatGeoPoint(value)}
127
+ </div>
128
+ )}
129
+ </div>
130
+ </PropertyIdCopyTooltip>
131
+
132
+ <FieldHelperText includeDescription={includeDescription}
133
+ showError={shouldShowError}
134
+ error={resolvedError}
135
+ disabled={disabled}
136
+ property={property}/>
137
+ </>
138
+ );
139
+ }
@@ -11,6 +11,7 @@ export { StorageUploadFieldBinding } from "./field_bindings/StorageUploadFieldBi
11
11
  export { TextFieldBinding } from "./field_bindings/TextFieldBinding";
12
12
  export { SwitchFieldBinding } from "./field_bindings/SwitchFieldBinding";
13
13
  export { DateTimeFieldBinding } from "./field_bindings/DateTimeFieldBinding";
14
+ export { GeopointFieldBinding } from "./field_bindings/GeopointFieldBinding";
14
15
  export { ReferenceFieldBinding } from "./field_bindings/ReferenceFieldBinding";
15
16
  export { ReferenceAsStringFieldBinding } from "./field_bindings/ReferenceAsStringFieldBinding";
16
17
  export { MapFieldBinding } from "./field_bindings/MapFieldBinding";
@@ -43,6 +43,7 @@ export type SaveEntityWithCallbacksProps<M extends Record<string, any>> =
43
43
  export async function saveEntityWithCallbacks<M extends Record<string, any>, USER extends User>({
44
44
  collection,
45
45
  path,
46
+ pathSegments,
46
47
  entityId,
47
48
  values,
48
49
  previousValues,
@@ -103,6 +104,7 @@ export async function saveEntityWithCallbacks<M extends Record<string, any>, USE
103
104
  return dataSource.saveEntity({
104
105
  collection,
105
106
  path: resolvedPath,
107
+ pathSegments: pathSegments ?? resolvedPath.split("/"),
106
108
  entityId,
107
109
  values: updatedValues,
108
110
  previousValues,
@@ -9,6 +9,11 @@ import { useFireCMSContext } from "../useFireCMSContext";
9
9
  */
10
10
  export interface EntityFetchProps<M extends Record<string, any>, USER extends User = User> {
11
11
  path: string;
12
+ /**
13
+ * `path` split at its real segment boundaries. Forwarded to the datasource so a parent
14
+ * entity id containing "/" stays unambiguous. Defaults to splitting the resolved path.
15
+ */
16
+ pathSegments?: string[];
12
17
  entityId?: string;
13
18
  databaseId?: string;
14
19
  collection: EntityCollection<M, USER>;
@@ -39,6 +44,7 @@ const CACHE: Record<string, Entity<any> | undefined> = {};
39
44
  export function useEntityFetch<M extends Record<string, any>, USER extends User>(
40
45
  {
41
46
  path: inputPath,
47
+ pathSegments: inputPathSegments,
42
48
  entityId,
43
49
  collection,
44
50
  databaseId,
@@ -49,6 +55,7 @@ export function useEntityFetch<M extends Record<string, any>, USER extends User>
49
55
  const navigationController = useNavigationController();
50
56
 
51
57
  const path = navigationController.resolveIdsFrom(inputPath);
58
+ const pathSegments = inputPathSegments ?? path.split("/");
52
59
 
53
60
  const context: FireCMSContext<USER> = useFireCMSContext();
54
61
 
@@ -97,6 +104,7 @@ export function useEntityFetch<M extends Record<string, any>, USER extends User>
97
104
  if (dataSource.listenEntity) {
98
105
  return dataSource.listenEntity<M>({
99
106
  path,
107
+ pathSegments,
100
108
  entityId,
101
109
  databaseId,
102
110
  collection,
@@ -106,6 +114,7 @@ export function useEntityFetch<M extends Record<string, any>, USER extends User>
106
114
  } else {
107
115
  dataSource.fetchEntity<M>({
108
116
  path,
117
+ pathSegments,
109
118
  entityId,
110
119
  databaseId,
111
120
  collection
@@ -74,6 +74,10 @@ export function useValidateAuthenticator<USER extends User = any>
74
74
 
75
75
  if (authenticator instanceof Function && delegateUser && !equal(checkedUserRef.current?.uid, delegateUser.uid)) {
76
76
  setAuthLoading(true);
77
+ // Reset the error of any previous authentication attempt. Otherwise, a
78
+ // rejected user would keep `canAccessMainView` to false for every user
79
+ // logging in afterwards, locking them out of the CMS until a page reload.
80
+ setNotAllowedError(false);
77
81
  try {
78
82
  const allowed = await authenticator({
79
83
  user: delegateUser,
@@ -8,6 +8,7 @@ import { fr } from "../locales/fr";
8
8
  import { it } from "../locales/it";
9
9
  import { hi } from "../locales/hi";
10
10
  import { pt } from "../locales/pt";
11
+ import { pl } from "../locales/pl";
11
12
  import { FireCMSTranslations } from "../types/translations";
12
13
 
13
14
  const FIRECMS_NS = "firecms_core";
@@ -139,6 +140,7 @@ function buildResources(
139
140
  it: { [FIRECMS_NS]: { ...it } },
140
141
  hi: { [FIRECMS_NS]: { ...hi } },
141
142
  pt: { [FIRECMS_NS]: { ...pt } },
143
+ pl: { [FIRECMS_NS]: { ...pl } },
142
144
  };
143
145
 
144
146
  if (!translations) return resources;
@@ -55,6 +55,7 @@ export function useBuildDataSource({
55
55
  */
56
56
  fetchCollection: useCallback(<M extends Record<string, any>>({
57
57
  path,
58
+ pathSegments,
58
59
  collection,
59
60
  filter,
60
61
  limit,
@@ -67,6 +68,7 @@ export function useBuildDataSource({
67
68
  const usedDelegate = collection?.overrides?.dataSourceDelegate ?? delegate;
68
69
  return usedDelegate.fetchCollection<M>({
69
70
  path,
71
+ pathSegments,
70
72
  filter,
71
73
  limit,
72
74
  startAfter,
@@ -97,6 +99,7 @@ export function useBuildDataSource({
97
99
  ? useCallback(<M extends Record<string, any>>(
98
100
  {
99
101
  path,
102
+ pathSegments,
100
103
  collection: collectionProp,
101
104
  filter,
102
105
  limit,
@@ -117,6 +120,7 @@ export function useBuildDataSource({
117
120
 
118
121
  return usedDelegate.listenCollection<M>({
119
122
  path,
123
+ pathSegments,
120
124
  filter,
121
125
  limit,
122
126
  startAfter,
@@ -139,6 +143,7 @@ export function useBuildDataSource({
139
143
  */
140
144
  fetchEntity: useCallback(<M extends Record<string, any>>({
141
145
  path,
146
+ pathSegments,
142
147
  entityId,
143
148
  collection
144
149
  }: FetchEntityProps<M>
@@ -146,6 +151,7 @@ export function useBuildDataSource({
146
151
  const usedDelegate = collection?.overrides?.dataSourceDelegate ?? delegate;
147
152
  return usedDelegate.fetchEntity({
148
153
  path,
154
+ pathSegments,
149
155
  entityId,
150
156
  collection
151
157
  });
@@ -165,6 +171,7 @@ export function useBuildDataSource({
165
171
  ? useCallback(<M extends Record<string, any>>(
166
172
  {
167
173
  path,
174
+ pathSegments,
168
175
  entityId,
169
176
  collection,
170
177
  onUpdate,
@@ -177,6 +184,7 @@ export function useBuildDataSource({
177
184
 
178
185
  return usedDelegate.listenEntity<M>({
179
186
  path,
187
+ pathSegments,
180
188
  entityId,
181
189
  onUpdate,
182
190
  onError,
@@ -198,6 +206,7 @@ export function useBuildDataSource({
198
206
  saveEntity: useCallback(async <M extends Record<string, any>>(
199
207
  {
200
208
  path,
209
+ pathSegments,
201
210
  entityId,
202
211
  values,
203
212
  collection: collectionProp,
@@ -244,6 +253,7 @@ export function useBuildDataSource({
244
253
  try {
245
254
  const entities = await usedDelegate.fetchCollection({
246
255
  path,
256
+ pathSegments,
247
257
  orderBy: orderProperty,
248
258
  order: "asc",
249
259
  limit: 1,
@@ -270,6 +280,7 @@ export function useBuildDataSource({
270
280
 
271
281
  return usedDelegate.saveEntity({
272
282
  path,
283
+ pathSegments,
273
284
  collection,
274
285
  entityId,
275
286
  values: finalValues,
@@ -13,6 +13,7 @@ import {
13
13
  import { getNavigationEntriesFromPath, NavigationViewInternal } from "../util/navigation_from_path";
14
14
  import { useLocation } from "react-router-dom";
15
15
  import {
16
+ encodeEntityId,
16
17
  removeInitialAndTrailingSlashes,
17
18
  resolveCollection,
18
19
  resolveDefaultSelectedView,
@@ -223,12 +224,14 @@ export function buildSidePanelsFromUrl(path: string, collections: EntityCollecti
223
224
  let sidePanel: EntitySidePanelProps<any> | undefined = undefined;
224
225
  let lastCollectionPath = "";
225
226
  let lastCollectionId: string | undefined = undefined;
227
+ let lastCollectionSegments: string[] | undefined = undefined;
226
228
  for (let i = 0; i < navigationViewsForPath.length; i++) {
227
229
  const navigationEntry = navigationViewsForPath[i];
228
230
 
229
231
  if (navigationEntry.type === "collection") {
230
232
  lastCollectionPath = navigationEntry.path;
231
233
  lastCollectionId = navigationEntry.collection.id;
234
+ lastCollectionSegments = navigationEntry.pathSegments;
232
235
  }
233
236
 
234
237
  const previousEntry = navigationViewsForPath[i - 1];
@@ -236,6 +239,7 @@ export function buildSidePanelsFromUrl(path: string, collections: EntityCollecti
236
239
  sidePanel = {
237
240
  path: navigationEntry.path,
238
241
  fullIdPath: navigationEntry.fullIdPath,
242
+ pathSegments: navigationEntry.pathSegments,
239
243
  entityId: navigationEntry.entityId,
240
244
  copy: false,
241
245
  width: navigationEntry.parentCollection?.sideDialogWidth
@@ -258,6 +262,9 @@ export function buildSidePanelsFromUrl(path: string, collections: EntityCollecti
258
262
  sidePanel = {
259
263
  path: lastCollectionPath,
260
264
  fullIdPath: lastCollectionId,
265
+ // A new entity still needs unambiguous segments: it may be created inside a
266
+ // subcollection whose parent id contains "/".
267
+ pathSegments: lastCollectionSegments,
261
268
  copy: false
262
269
  }
263
270
  }
@@ -277,7 +284,7 @@ const propsToSidePanel = (props: EntitySidePanelProps,
277
284
  const collectionPath = removeInitialAndTrailingSlashes(props.path);
278
285
 
279
286
  const urlPath = props.entityId
280
- ? buildUrlCollectionPath(`${collectionPath}/${props.entityId}${props.selectedTab ? "/" + props.selectedTab : ""}${locationSearch}#${SIDE_URL_HASH}`)
287
+ ? buildUrlCollectionPath(`${collectionPath}/${encodeEntityId(props.entityId)}${props.selectedTab ? "/" + props.selectedTab : ""}${locationSearch}#${SIDE_URL_HASH}`)
281
288
  : buildUrlCollectionPath(`${collectionPath}${locationSearch}#${NEW_URL_HASH}`);
282
289
 
283
290
  const resolvedPanelProps: EntitySidePanelProps<any> = {
package/src/locales/de.ts CHANGED
@@ -146,8 +146,8 @@ export const de: FireCMSTranslations = {
146
146
  // ─── Error states ─────────────────────────────────────────────
147
147
  error: "Fehler",
148
148
  error_uploading_file: "Fehler beim Hochladen der Datei",
149
- error_deleting: "Fehler beim Löschen",
150
- error_before_delete: "Fehler vor dem Löschen",
149
+ error_deleting: "Fehler beim Löschen: {{message}}",
150
+ error_before_delete: "Fehler vor dem Löschen: {{message}}",
151
151
  error_updating_asset: "Fehler beim Aktualisieren des Assets",
152
152
  error_deleting_asset: "Fehler beim Löschen des Assets",
153
153
  error_firestore_index: "Für diese Abfrage ist ein Firestore-Index erforderlich.",
@@ -389,6 +389,7 @@ export const de: FireCMSTranslations = {
389
389
  download: "Herunterladen",
390
390
  large_number_of_documents: "Diese Sammlung hat eine große Anzahl von Dokumenten ({{count}}).",
391
391
  include_undefined_values: "Undefinierte Werte einschließen",
392
+ export_apply_filter_sort: "Nur Ergebnisse exportieren, die dem aktuellen Filter/der aktuellen Sortierung entsprechen",
392
393
  submit: "Einreichen",
393
394
 
394
395
  no_filterable_properties: "Keine filterbaren Eigenschaften verfügbar",
@@ -586,6 +587,10 @@ export const de: FireCMSTranslations = {
586
587
  order_property_not_found: "Eigenschaft \"{{property}}\" existiert nicht oder ist keine Zahlen-Eigenschaft. Bitte wählen Sie eine gültige Eigenschaft oder löschen Sie die Auswahl.",
587
588
  no_number_properties: "Keine Zahlen-Eigenschaften gefunden. Fügen Sie eine Zahlen-Eigenschaft hinzu, um die Sortierung zu aktivieren.",
588
589
  order_property_description: "Wählen Sie eine Zahlen-Eigenschaft, um die Reihenfolge der Elemente beizubehalten",
590
+ image_property: "Bild-Eigenschaft",
591
+ image_property_not_found: "Eigenschaft \"{{property}}\" existiert nicht oder ist keine Bild-Eigenschaft. Bitte wählen Sie eine gültige Eigenschaft oder löschen Sie die Auswahl.",
592
+ no_image_properties: "Keine Bild-Eigenschaften gefunden. Fügen Sie eine Speicher- oder Bild-URL-Eigenschaft hinzu, um sie als Vorschaubild zu verwenden.",
593
+ image_property_description: "Wählen Sie die Eigenschaft, die als Vorschaubild in den Ansichten Karten und Kanban verwendet wird. Wenn nicht festgelegt, wird automatisch die erste passende Bild-Eigenschaft verwendet.",
589
594
  display_settings: "Anzeigeeinstellungen",
590
595
  default_row_size: "Standard-Zeilengröße",
591
596
  side_dialog_width: "Seitendialog-Breite",
package/src/locales/en.ts CHANGED
@@ -154,8 +154,8 @@ export const en: FireCMSTranslations = {
154
154
  // ─── Error states ─────────────────────────────────────────────
155
155
  error: "Error",
156
156
  error_uploading_file: "Error uploading file",
157
- error_deleting: "Error deleting",
158
- error_before_delete: "Error before delete",
157
+ error_deleting: "Error deleting: {{message}}",
158
+ error_before_delete: "Error before delete: {{message}}",
159
159
  error_updating_asset: "Error updating asset",
160
160
  error_deleting_asset: "Error deleting asset",
161
161
  error_firestore_index: "A Firestore index is required for this query.",
@@ -397,6 +397,7 @@ export const en: FireCMSTranslations = {
397
397
  download: "Download",
398
398
  large_number_of_documents: "This collections has a large number of documents ({{count}}).",
399
399
  include_undefined_values: "Include undefined values",
400
+ export_apply_filter_sort: "Only export results matching the current filter/sort",
400
401
  submit: "Submit",
401
402
 
402
403
  no_filterable_properties: "No filterable properties available",
@@ -598,6 +599,10 @@ export const en: FireCMSTranslations = {
598
599
  order_property_not_found: "Property \"{{property}}\" does not exist or is not a number property. Please select a valid property or clear the selection.",
599
600
  no_number_properties: "No number properties found. Add a number property to enable ordering.",
600
601
  order_property_description: "Select a number property to persist the order of items",
602
+ image_property: "Image Property",
603
+ image_property_not_found: "Property \"{{property}}\" does not exist or is not an image property. Please select a valid property or clear the selection.",
604
+ no_image_properties: "No image properties found. Add a storage or URL image property to use as a thumbnail.",
605
+ image_property_description: "Select the property used as the thumbnail image in Cards and Kanban view modes. If not set, the first matching image property will be used automatically.",
601
606
  display_settings: "Display settings",
602
607
  default_row_size: "Default row size",
603
608
  side_dialog_width: "Side dialog width",
package/src/locales/es.ts CHANGED
@@ -152,8 +152,8 @@ export const es: FireCMSTranslations = {
152
152
  // ─── Error states ─────────────────────────────────────────────
153
153
  error: "Error",
154
154
  error_uploading_file: "Error al subir archivo",
155
- error_deleting: "Error al eliminar",
156
- error_before_delete: "Error antes de eliminar",
155
+ error_deleting: "Error al eliminar: {{message}}",
156
+ error_before_delete: "Error antes de eliminar: {{message}}",
157
157
  error_updating_asset: "Error al actualizar recurso",
158
158
  error_deleting_asset: "Error al eliminar recurso",
159
159
  error_firestore_index: "Se requiere un índice de Firestore para esta consulta.",
@@ -397,6 +397,7 @@ export const es: FireCMSTranslations = {
397
397
  download: "Descargar",
398
398
  large_number_of_documents: "Esta colección posee un gran número de documentos ({{count}}).",
399
399
  include_undefined_values: "Incluir valores omitidos (undefined)",
400
+ export_apply_filter_sort: "Exportar solo los resultados que coinciden con el filtro/orden actual",
400
401
  submit: "Enviar",
401
402
 
402
403
  no_filterable_properties: "No hay propiedades filtrables disponibles",
@@ -598,6 +599,10 @@ export const es: FireCMSTranslations = {
598
599
  order_property_not_found: "La propiedad \"{{property}}\" no existe o no es una propiedad numérica. Selecciona una propiedad válida o borra la selección.",
599
600
  no_number_properties: "No se encontraron propiedades numéricas. Agrega una propiedad numérica para habilitar el ordenamiento.",
600
601
  order_property_description: "Selecciona una propiedad numérica para mantener el orden de los elementos",
602
+ image_property: "Propiedad de imagen",
603
+ image_property_not_found: "La propiedad \"{{property}}\" no existe o no es una propiedad de imagen. Selecciona una propiedad válida o borra la selección.",
604
+ no_image_properties: "No se encontraron propiedades de imagen. Agrega una propiedad de almacenamiento o URL de imagen para usarla como miniatura.",
605
+ image_property_description: "Selecciona la propiedad usada como miniatura en las vistas de Tarjetas y Kanban. Si no se establece, se usará automáticamente la primera propiedad de imagen que coincida.",
601
606
  display_settings: "Configuración de visualización",
602
607
  default_row_size: "Tamaño de fila predeterminado",
603
608
  side_dialog_width: "Ancho del diálogo lateral",
package/src/locales/fr.ts CHANGED
@@ -146,8 +146,8 @@ export const fr: FireCMSTranslations = {
146
146
  // ─── Error states ─────────────────────────────────────────────
147
147
  error: "Erreur",
148
148
  error_uploading_file: "Erreur lors du téléchargement du fichier",
149
- error_deleting: "Erreur lors de la suppression",
150
- error_before_delete: "Erreur avant la suppression",
149
+ error_deleting: "Erreur lors de la suppression: {{message}}",
150
+ error_before_delete: "Erreur avant la suppression: {{message}}",
151
151
  error_updating_asset: "Erreur lors de la mise à jour de l'actif",
152
152
  error_deleting_asset: "Erreur lors de la suppression de l'actif",
153
153
  error_firestore_index: "Un index Firestore est requis pour cette requête.",
@@ -389,6 +389,7 @@ export const fr: FireCMSTranslations = {
389
389
  download: "Télécharger",
390
390
  large_number_of_documents: "Cette collection contient un grand nombre de documents ({{count}}).",
391
391
  include_undefined_values: "Inclure les valeurs non définies",
392
+ export_apply_filter_sort: "N'exporter que les résultats correspondant au filtre/tri actuel",
392
393
  submit: "Soumettre",
393
394
 
394
395
  no_filterable_properties: "Aucune propriété filtrable disponible",
@@ -586,6 +587,10 @@ export const fr: FireCMSTranslations = {
586
587
  order_property_not_found: "La propriété \"{{property}}\" n'existe pas ou n'est pas une propriété numérique. Veuillez sélectionner une propriété valide ou effacer la sélection.",
587
588
  no_number_properties: "Aucune propriété numérique trouvée. Ajoutez une propriété numérique pour activer le tri.",
588
589
  order_property_description: "Sélectionnez une propriété numérique pour conserver l'ordre des éléments",
590
+ image_property: "Propriété d'image",
591
+ image_property_not_found: "La propriété \"{{property}}\" n'existe pas ou n'est pas une propriété d'image. Veuillez sélectionner une propriété valide ou effacer la sélection.",
592
+ no_image_properties: "Aucune propriété d'image trouvée. Ajoutez une propriété de stockage ou d'URL d'image à utiliser comme miniature.",
593
+ image_property_description: "Sélectionnez la propriété utilisée comme miniature dans les vues Cartes et Kanban. Si elle n'est pas définie, la première propriété d'image correspondante sera utilisée automatiquement.",
589
594
  display_settings: "Paramètres d'affichage",
590
595
  default_row_size: "Taille de ligne par défaut",
591
596
  side_dialog_width: "Largeur du dialogue latéral",
package/src/locales/hi.ts CHANGED
@@ -146,8 +146,8 @@ export const hi: FireCMSTranslations = {
146
146
  // ─── Error states ─────────────────────────────────────────────
147
147
  error: "त्रुटि",
148
148
  error_uploading_file: "फ़ाइल अपलोड करने में त्रुटि",
149
- error_deleting: "हटाने में त्रुटि",
150
- error_before_delete: "हटाने से पहले त्रुटि",
149
+ error_deleting: "हटाने में त्रुटि: {{message}}",
150
+ error_before_delete: "हटाने से पहले त्रुटि: {{message}}",
151
151
  error_updating_asset: "एसेट अपडेट करने में त्रुटि",
152
152
  error_deleting_asset: "एसेट हटाने में त्रुटि",
153
153
  error_firestore_index: "इस क्वेरी के लिए Firestore इंडेक्स आवश्यक है।",
@@ -389,6 +389,7 @@ export const hi: FireCMSTranslations = {
389
389
  download: "डाउनलोड",
390
390
  large_number_of_documents: "इस संग्रह में बड़ी संख्या में दस्तावेज़ हैं ({{count}})।",
391
391
  include_undefined_values: "अपरिभाषित (undefined) मान शामिल करें",
392
+ export_apply_filter_sort: "केवल वर्तमान फ़िल्टर/सॉर्ट से मेल खाने वाले परिणाम निर्यात करें",
392
393
  submit: "सबमिट करें",
393
394
 
394
395
  no_filterable_properties: "कोई फ़िल्टर करने योग्य गुण उपलब्ध नहीं हैं",
@@ -586,6 +587,10 @@ export const hi: FireCMSTranslations = {
586
587
  order_property_not_found: "प्रॉपर्टी \"{{property}}\" मौजूद नहीं है या एक संख्या प्रॉपर्टी नहीं है। कृपया एक वैध प्रॉपर्टी चुनें या चयन साफ़ करें।",
587
588
  no_number_properties: "कोई संख्या प्रॉपर्टी नहीं मिली। क्रम सक्षम करने के लिए एक संख्या प्रॉपर्टी जोड़ें।",
588
589
  order_property_description: "आइटम का क्रम बनाए रखने के लिए एक संख्या प्रॉपर्टी चुनें",
590
+ image_property: "इमेज प्रॉपर्टी",
591
+ image_property_not_found: "प्रॉपर्टी \"{{property}}\" मौजूद नहीं है या एक इमेज प्रॉपर्टी नहीं है। कृपया एक वैध प्रॉपर्टी चुनें या चयन साफ़ करें।",
592
+ no_image_properties: "कोई इमेज प्रॉपर्टी नहीं मिली। थंबनेल के रूप में उपयोग करने के लिए एक स्टोरेज या URL इमेज प्रॉपर्टी जोड़ें।",
593
+ image_property_description: "कार्ड्स और कानबन व्यू मोड में थंबनेल इमेज के रूप में उपयोग की जाने वाली प्रॉपर्टी चुनें। यदि सेट नहीं किया गया है, तो पहली मिलान वाली इमेज प्रॉपर्टी स्वचालित रूप से उपयोग की जाएगी।",
589
594
  display_settings: "प्रदर्शन सेटिंग्स",
590
595
  default_row_size: "डिफ़ॉल्ट पंक्ति आकार",
591
596
  side_dialog_width: "साइड डायलॉग चौड़ाई",
package/src/locales/it.ts CHANGED
@@ -146,8 +146,8 @@ export const it: FireCMSTranslations = {
146
146
  // ─── Error states ─────────────────────────────────────────────
147
147
  error: "Errore",
148
148
  error_uploading_file: "Errore durante il caricamento del file",
149
- error_deleting: "Errore durante l'eliminazione",
150
- error_before_delete: "Errore prima dell'eliminazione",
149
+ error_deleting: "Errore durante l'eliminazione: {{message}}",
150
+ error_before_delete: "Errore prima dell'eliminazione: {{message}}",
151
151
  error_updating_asset: "Errore durante l'aggiornamento dell'asset",
152
152
  error_deleting_asset: "Errore durante l'eliminazione dell'asset",
153
153
  error_firestore_index: "Per questa query è richiesto un indice Firestore.",
@@ -389,6 +389,7 @@ export const it: FireCMSTranslations = {
389
389
  download: "Scarica",
390
390
  large_number_of_documents: "Questa collezione contiene un numero elevato di documenti ({{count}})",
391
391
  include_undefined_values: "Includi valori non definiti",
392
+ export_apply_filter_sort: "Esporta solo i risultati che corrispondono al filtro/ordinamento attuale",
392
393
  submit: "Invia",
393
394
 
394
395
  no_filterable_properties: "Nessuna proprietà filtrabile disponibile",
@@ -586,6 +587,10 @@ export const it: FireCMSTranslations = {
586
587
  order_property_not_found: "La proprietà \"{{property}}\" non esiste o non è una proprietà numerica. Seleziona una proprietà valida o cancella la selezione.",
587
588
  no_number_properties: "Nessuna proprietà numerica trovata. Aggiungi una proprietà numerica per abilitare l'ordinamento.",
588
589
  order_property_description: "Seleziona una proprietà numerica per mantenere l'ordine degli elementi",
590
+ image_property: "Proprietà immagine",
591
+ image_property_not_found: "La proprietà \"{{property}}\" non esiste o non è una proprietà immagine. Seleziona una proprietà valida o cancella la selezione.",
592
+ no_image_properties: "Nessuna proprietà immagine trovata. Aggiungi una proprietà di archiviazione o URL immagine da usare come miniatura.",
593
+ image_property_description: "Seleziona la proprietà utilizzata come miniatura nelle viste Schede e Kanban. Se non impostata, verrà utilizzata automaticamente la prima proprietà immagine corrispondente.",
589
594
  display_settings: "Impostazioni di visualizzazione",
590
595
  default_row_size: "Dimensione riga predefinita",
591
596
  side_dialog_width: "Larghezza del dialogo laterale",