@firecms/core 3.4.0-canary.8635253 → 3.4.0-canary.d20cc85
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.
- package/dist/components/EntityCollectionTable/internal/CollectionTableToolbar.d.ts +6 -1
- package/dist/components/EntityCollectionTable/internal/popup_field/PopupFormField.d.ts +3 -1
- package/dist/components/EntityCollectionView/EntityCollectionBoardView.d.ts +3 -1
- package/dist/components/EntityCollectionView/EntityCollectionView.d.ts +7 -0
- package/dist/components/EntityCollectionView/useBoardDataController.d.ts +3 -1
- package/dist/components/ReferenceTable/ReferenceSelectionTable.d.ts +10 -1
- package/dist/components/SelectableTable/filters/filter_text_input.d.ts +30 -0
- package/dist/components/SelectableTable/filters/filter_text_input.test.d.ts +1 -0
- package/dist/components/common/table_url_params.d.ts +24 -0
- package/dist/components/common/useDataSourceTableController.d.ts +7 -1
- package/dist/components/common/useTableSearchHelper.d.ts +7 -1
- package/dist/core/EntityEditView.d.ts +7 -1
- package/dist/form/EntityForm.d.ts +6 -1
- package/dist/hooks/data/save.d.ts +1 -1
- package/dist/hooks/data/useCollectionFetch.d.ts +7 -1
- package/dist/hooks/data/useEntityFetch.d.ts +6 -1
- package/dist/index.es.js +949 -622
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +948 -621
- package/dist/index.umd.js.map +1 -1
- package/dist/types/collections.d.ts +7 -0
- package/dist/types/datasource.d.ts +59 -4
- package/dist/types/entities.d.ts +21 -1
- package/dist/types/properties.d.ts +17 -1
- package/dist/types/side_entity_controller.d.ts +6 -0
- package/dist/types/translations.d.ts +6 -0
- package/dist/util/__tests__/collections.test.d.ts +1 -0
- package/dist/util/__tests__/urls.test.d.ts +1 -0
- package/dist/util/collections.d.ts +1 -1
- package/dist/util/index.d.ts +1 -0
- package/dist/util/navigation_from_path.d.ts +7 -0
- package/dist/util/navigation_utils.d.ts +3 -1
- package/dist/util/parent_references_from_path.d.ts +1 -0
- package/dist/util/urls.d.ts +22 -0
- package/package.json +4 -4
- package/src/components/EntityCollectionTable/EntityCollectionTable.tsx +1 -0
- package/src/components/EntityCollectionTable/internal/CollectionTableToolbar.tsx +7 -0
- package/src/components/EntityCollectionTable/internal/popup_field/PopupFormField.tsx +5 -1
- package/src/components/EntityCollectionView/EntityCollectionBoardView.tsx +4 -0
- package/src/components/EntityCollectionView/EntityCollectionView.tsx +29 -3
- package/src/components/EntityCollectionView/useBoardDataController.tsx +11 -0
- package/src/components/ReferenceTable/ReferenceSelectionTable.tsx +11 -0
- package/src/components/SelectableTable/filters/StringNumberFilterField.tsx +33 -7
- package/src/components/SelectableTable/filters/filter_text_input.test.ts +184 -0
- package/src/components/SelectableTable/filters/filter_text_input.ts +71 -0
- package/src/components/common/table_url_params.ts +172 -0
- package/src/components/common/useDataSourceTableController.tsx +64 -175
- package/src/components/common/useTableSearchHelper.ts +21 -2
- package/src/contexts/SnackbarProvider.tsx +14 -1
- package/src/core/EntityEditView.tsx +21 -0
- package/src/core/EntitySidePanel.tsx +2 -0
- package/src/form/EntityForm.tsx +9 -3
- package/src/hooks/data/delete.ts +2 -0
- package/src/hooks/data/save.ts +2 -0
- package/src/hooks/data/useCollectionFetch.tsx +13 -0
- package/src/hooks/data/useEntityFetch.tsx +18 -0
- package/src/hooks/useResolvedNavigationFrom.tsx +2 -0
- package/src/hooks/useValidateAuthenticator.tsx +4 -0
- package/src/internal/useBuildDataSource.ts +25 -4
- package/src/internal/useBuildSideEntityController.tsx +6 -0
- package/src/locales/de.ts +5 -0
- package/src/locales/en.ts +5 -0
- package/src/locales/es.ts +5 -0
- package/src/locales/fr.ts +5 -0
- package/src/locales/hi.ts +5 -0
- package/src/locales/it.ts +5 -0
- package/src/locales/pl.ts +5 -0
- package/src/locales/pt.ts +5 -0
- package/src/preview/components/StorageThumbnail.tsx +24 -2
- package/src/routes/FireCMSRoute.tsx +3 -0
- package/src/types/collections.ts +8 -0
- package/src/types/datasource.ts +59 -4
- package/src/types/entities.ts +24 -1
- package/src/types/properties.ts +17 -0
- package/src/types/side_entity_controller.tsx +6 -0
- package/src/types/translations.ts +6 -0
- package/src/util/__tests__/collections.test.ts +32 -0
- package/src/util/__tests__/urls.test.ts +131 -0
- package/src/util/collections.ts +1 -1
- package/src/util/entities.ts +3 -1
- package/src/util/index.ts +1 -0
- package/src/util/navigation_from_path.ts +19 -1
- package/src/util/navigation_utils.ts +4 -0
- package/src/util/parent_references_from_path.ts +10 -2
- package/src/util/previews.ts +8 -1
- package/src/util/resolutions.ts +8 -0
- package/src/util/urls.ts +52 -0
|
@@ -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,
|
|
@@ -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,
|
|
@@ -292,12 +303,15 @@ export function useBuildDataSource({
|
|
|
292
303
|
deleteEntity: useCallback(<M extends Record<string, any>>(
|
|
293
304
|
{
|
|
294
305
|
entity,
|
|
306
|
+
pathSegments,
|
|
295
307
|
collection
|
|
296
308
|
}: DeleteEntityProps<M>
|
|
297
309
|
): Promise<void> => {
|
|
298
310
|
const usedDelegate = collection?.overrides?.dataSourceDelegate ?? delegate;
|
|
299
311
|
return usedDelegate.deleteEntity({
|
|
300
312
|
entity,
|
|
313
|
+
// Falls back to what the entity carries from the fetch that produced it.
|
|
314
|
+
pathSegments: pathSegments ?? entity.pathSegments,
|
|
301
315
|
collection
|
|
302
316
|
});
|
|
303
317
|
}, [delegate.deleteEntity]),
|
|
@@ -317,25 +331,28 @@ export function useBuildDataSource({
|
|
|
317
331
|
name: string,
|
|
318
332
|
value: any,
|
|
319
333
|
entityId?: string,
|
|
320
|
-
collection?: EntityCollection
|
|
334
|
+
collection?: EntityCollection,
|
|
335
|
+
pathSegments?: string[]
|
|
321
336
|
): Promise<boolean> => {
|
|
322
337
|
const usedDelegate = collection?.overrides?.dataSourceDelegate ?? delegate;
|
|
323
|
-
return usedDelegate.checkUniqueField(path, name, value, entityId, collection);
|
|
338
|
+
return usedDelegate.checkUniqueField(path, name, value, entityId, collection, pathSegments);
|
|
324
339
|
}, [delegate.checkUniqueField]),
|
|
325
340
|
|
|
326
|
-
generateEntityId: useCallback((path: string, collection: EntityCollection): string => {
|
|
341
|
+
generateEntityId: useCallback((path: string, collection: EntityCollection, pathSegments?: string[]): string => {
|
|
327
342
|
const usedDelegate = collection?.overrides?.dataSourceDelegate ?? delegate;
|
|
328
|
-
return usedDelegate.generateEntityId(path, collection);
|
|
343
|
+
return usedDelegate.generateEntityId(path, collection, pathSegments);
|
|
329
344
|
}, [delegate.generateEntityId]),
|
|
330
345
|
|
|
331
346
|
countEntities: delegate.countEntities ? async ({
|
|
332
347
|
path,
|
|
348
|
+
pathSegments,
|
|
333
349
|
collection,
|
|
334
350
|
filter,
|
|
335
351
|
order,
|
|
336
352
|
orderBy
|
|
337
353
|
}: {
|
|
338
354
|
path: string,
|
|
355
|
+
pathSegments?: string[],
|
|
339
356
|
collection: EntityCollection<any>,
|
|
340
357
|
filter?: FilterValues<Extract<keyof any, string>>,
|
|
341
358
|
orderBy?: string,
|
|
@@ -344,6 +361,7 @@ export function useBuildDataSource({
|
|
|
344
361
|
const usedDelegate = collection?.overrides?.dataSourceDelegate ?? delegate;
|
|
345
362
|
return usedDelegate.countEntities!({
|
|
346
363
|
path,
|
|
364
|
+
pathSegments,
|
|
347
365
|
filter,
|
|
348
366
|
orderBy,
|
|
349
367
|
order,
|
|
@@ -353,11 +371,13 @@ export function useBuildDataSource({
|
|
|
353
371
|
|
|
354
372
|
isFilterCombinationValid: useCallback(({
|
|
355
373
|
path,
|
|
374
|
+
pathSegments,
|
|
356
375
|
databaseId,
|
|
357
376
|
filterValues,
|
|
358
377
|
sortBy
|
|
359
378
|
}: {
|
|
360
379
|
path: string,
|
|
380
|
+
pathSegments?: string[],
|
|
361
381
|
databaseId?: string,
|
|
362
382
|
filterValues: FilterValues<any>,
|
|
363
383
|
sortBy?: [string, "asc" | "desc"]
|
|
@@ -367,6 +387,7 @@ export function useBuildDataSource({
|
|
|
367
387
|
return delegate.isFilterCombinationValid(
|
|
368
388
|
{
|
|
369
389
|
path,
|
|
390
|
+
pathSegments,
|
|
370
391
|
databaseId,
|
|
371
392
|
filterValues,
|
|
372
393
|
sortBy
|
|
@@ -224,12 +224,14 @@ export function buildSidePanelsFromUrl(path: string, collections: EntityCollecti
|
|
|
224
224
|
let sidePanel: EntitySidePanelProps<any> | undefined = undefined;
|
|
225
225
|
let lastCollectionPath = "";
|
|
226
226
|
let lastCollectionId: string | undefined = undefined;
|
|
227
|
+
let lastCollectionSegments: string[] | undefined = undefined;
|
|
227
228
|
for (let i = 0; i < navigationViewsForPath.length; i++) {
|
|
228
229
|
const navigationEntry = navigationViewsForPath[i];
|
|
229
230
|
|
|
230
231
|
if (navigationEntry.type === "collection") {
|
|
231
232
|
lastCollectionPath = navigationEntry.path;
|
|
232
233
|
lastCollectionId = navigationEntry.collection.id;
|
|
234
|
+
lastCollectionSegments = navigationEntry.pathSegments;
|
|
233
235
|
}
|
|
234
236
|
|
|
235
237
|
const previousEntry = navigationViewsForPath[i - 1];
|
|
@@ -237,6 +239,7 @@ export function buildSidePanelsFromUrl(path: string, collections: EntityCollecti
|
|
|
237
239
|
sidePanel = {
|
|
238
240
|
path: navigationEntry.path,
|
|
239
241
|
fullIdPath: navigationEntry.fullIdPath,
|
|
242
|
+
pathSegments: navigationEntry.pathSegments,
|
|
240
243
|
entityId: navigationEntry.entityId,
|
|
241
244
|
copy: false,
|
|
242
245
|
width: navigationEntry.parentCollection?.sideDialogWidth
|
|
@@ -259,6 +262,9 @@ export function buildSidePanelsFromUrl(path: string, collections: EntityCollecti
|
|
|
259
262
|
sidePanel = {
|
|
260
263
|
path: lastCollectionPath,
|
|
261
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,
|
|
262
268
|
copy: false
|
|
263
269
|
}
|
|
264
270
|
}
|
package/src/locales/de.ts
CHANGED
|
@@ -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
|
@@ -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
|
@@ -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
|
@@ -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
|
@@ -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
|
@@ -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",
|
package/src/locales/pl.ts
CHANGED
|
@@ -389,6 +389,7 @@ export const pl: FireCMSTranslations = {
|
|
|
389
389
|
download: "Pobierz",
|
|
390
390
|
large_number_of_documents: "Ta kolekcja zawiera dużą liczbę dokumentów ({{count}}).",
|
|
391
391
|
include_undefined_values: "Uwzględnij niezdefiniowane wartości",
|
|
392
|
+
export_apply_filter_sort: "Eksportuj tylko wyniki zgodne z aktualnym filtrem/sortowaniem",
|
|
392
393
|
submit: "Wyślij",
|
|
393
394
|
|
|
394
395
|
no_filterable_properties: "Brak dostępnych właściwości do filtrowania",
|
|
@@ -590,6 +591,10 @@ export const pl: FireCMSTranslations = {
|
|
|
590
591
|
order_property_not_found: "Właściwość „{{property}}” nie istnieje lub nie jest właściwością liczbową. Wybierz prawidłową właściwość lub wyczyść wybór.",
|
|
591
592
|
no_number_properties: "Nie znaleziono właściwości liczbowych. Dodaj właściwość liczbową, aby włączyć sortowanie.",
|
|
592
593
|
order_property_description: "Wybierz właściwość liczbową, aby zachować kolejność elementów",
|
|
594
|
+
image_property: "Właściwość obrazu",
|
|
595
|
+
image_property_not_found: "Właściwość „{{property}}” nie istnieje lub nie jest właściwością obrazu. Wybierz prawidłową właściwość lub wyczyść wybór.",
|
|
596
|
+
no_image_properties: "Nie znaleziono właściwości obrazu. Dodaj właściwość przechowywania lub adresu URL obrazu, aby użyć jej jako miniatury.",
|
|
597
|
+
image_property_description: "Wybierz właściwość używaną jako miniatura w widokach Karty i Kanban. Jeśli nie zostanie ustawiona, automatycznie zostanie użyta pierwsza pasująca właściwość obrazu.",
|
|
593
598
|
display_settings: "Ustawienia wyświetlania",
|
|
594
599
|
default_row_size: "Domyślny rozmiar wiersza",
|
|
595
600
|
side_dialog_width: "Szerokość okna bocznego",
|
package/src/locales/pt.ts
CHANGED
|
@@ -394,6 +394,7 @@ export const pt: FireCMSTranslations = {
|
|
|
394
394
|
download: "Descarregar",
|
|
395
395
|
large_number_of_documents: "Esta coleção tem um grande número de documentos ({{count}}).",
|
|
396
396
|
include_undefined_values: "Incluir valores indefinidos",
|
|
397
|
+
export_apply_filter_sort: "Exportar apenas os resultados que correspondem ao filtro/ordenação atual",
|
|
397
398
|
submit: "Submeter",
|
|
398
399
|
|
|
399
400
|
no_filterable_properties: "Não há propriedades filtráveis disponíveis",
|
|
@@ -595,6 +596,10 @@ export const pt: FireCMSTranslations = {
|
|
|
595
596
|
order_property_not_found: "A propriedade \"{{property}}\" não existe ou não é uma propriedade numérica. Selecione uma propriedade válida ou limpe a seleção.",
|
|
596
597
|
no_number_properties: "Nenhuma propriedade numérica encontrada. Adicione uma propriedade numérica para habilitar a ordenação.",
|
|
597
598
|
order_property_description: "Selecione uma propriedade numérica para manter a ordem dos itens",
|
|
599
|
+
image_property: "Propriedade de imagem",
|
|
600
|
+
image_property_not_found: "A propriedade \"{{property}}\" não existe ou não é uma propriedade de imagem. Selecione uma propriedade válida ou limpe a seleção.",
|
|
601
|
+
no_image_properties: "Nenhuma propriedade de imagem encontrada. Adicione uma propriedade de armazenamento ou URL de imagem para usar como miniatura.",
|
|
602
|
+
image_property_description: "Selecione a propriedade usada como miniatura nas visualizações de Cartões e Kanban. Se não for definida, a primeira propriedade de imagem correspondente será usada automaticamente.",
|
|
598
603
|
display_settings: "Configurações de exibição",
|
|
599
604
|
default_row_size: "Tamanho de linha padrão",
|
|
600
605
|
side_dialog_width: "Largura do diálogo lateral",
|
|
@@ -6,6 +6,7 @@ import { useStorageSource } from "../../hooks";
|
|
|
6
6
|
import { DownloadConfig, FileType } from "../../types";
|
|
7
7
|
import { PreviewSize } from "../PropertyPreviewProps";
|
|
8
8
|
import { ErrorView } from "../../components";
|
|
9
|
+
import { getPreviewTypeFromUrl, isAbsoluteHttpUrl } from "../../util/urls";
|
|
9
10
|
|
|
10
11
|
type StorageThumbnailProps = {
|
|
11
12
|
storagePathOrDownloadUrl: string;
|
|
@@ -41,10 +42,20 @@ export function StorageThumbnailInternal({
|
|
|
41
42
|
const [error, setError] = React.useState<Error | undefined>(undefined);
|
|
42
43
|
const storage = useStorageSource();
|
|
43
44
|
|
|
45
|
+
/**
|
|
46
|
+
* The saved value may already be a resolved download URL instead of a
|
|
47
|
+
* storage path: either because the property is configured with
|
|
48
|
+
* `storeUrl: true`, or because the value was written directly in the
|
|
49
|
+
* datasource pointing to an externally hosted file. Such values can be
|
|
50
|
+
* previewed as they are, and must not be handed over to the storage source,
|
|
51
|
+
* which can only resolve paths of its own bucket.
|
|
52
|
+
*/
|
|
53
|
+
const valueIsUrl = storeUrl || isAbsoluteHttpUrl(storagePathOrDownloadUrl);
|
|
54
|
+
|
|
44
55
|
const [downloadConfig, setDownloadConfig] = React.useState<DownloadConfig>(URL_CACHE[storagePathOrDownloadUrl]);
|
|
45
56
|
|
|
46
57
|
useEffect(() => {
|
|
47
|
-
if (!storagePathOrDownloadUrl)
|
|
58
|
+
if (!storagePathOrDownloadUrl || valueIsUrl)
|
|
48
59
|
return;
|
|
49
60
|
let unmounted = false;
|
|
50
61
|
storage.getDownloadURL(storagePathOrDownloadUrl)
|
|
@@ -57,10 +68,21 @@ export function StorageThumbnailInternal({
|
|
|
57
68
|
return () => {
|
|
58
69
|
unmounted = true;
|
|
59
70
|
};
|
|
60
|
-
}, [storagePathOrDownloadUrl]);
|
|
71
|
+
}, [storagePathOrDownloadUrl, valueIsUrl]);
|
|
61
72
|
|
|
62
73
|
if (!storagePathOrDownloadUrl) return null;
|
|
63
74
|
|
|
75
|
+
if (valueIsUrl) {
|
|
76
|
+
// There is no storage metadata for a value that is already a URL, so the
|
|
77
|
+
// preview type is inferred from its file extension when possible.
|
|
78
|
+
return <UrlComponentPreview previewType={getPreviewTypeFromUrl(storagePathOrDownloadUrl) ?? "file"}
|
|
79
|
+
url={storagePathOrDownloadUrl}
|
|
80
|
+
interactive={interactive}
|
|
81
|
+
size={size}
|
|
82
|
+
fill={fill}
|
|
83
|
+
hint={storagePathOrDownloadUrl} />;
|
|
84
|
+
}
|
|
85
|
+
|
|
64
86
|
const filetype = downloadConfig?.metadata ? getFiletype(downloadConfig?.metadata.contentType) : undefined;
|
|
65
87
|
const previewType = filetype?.startsWith("image")
|
|
66
88
|
? "image"
|
|
@@ -99,6 +99,7 @@ export function FireCMSRoute() {
|
|
|
99
99
|
isSubCollection={false}
|
|
100
100
|
parentCollectionIds={[]}
|
|
101
101
|
fullPath={collection.path}
|
|
102
|
+
pathSegments={navigationEntries[0].pathSegments}
|
|
102
103
|
fullIdPath={collection.id}
|
|
103
104
|
updateUrl={true}
|
|
104
105
|
{...collection}
|
|
@@ -123,6 +124,7 @@ export function FireCMSRoute() {
|
|
|
123
124
|
isSubCollection={false}
|
|
124
125
|
parentCollectionIds={[]}
|
|
125
126
|
fullPath={collection.path}
|
|
127
|
+
pathSegments={firstEntry.pathSegments}
|
|
126
128
|
updateUrl={true}
|
|
127
129
|
{...collection}
|
|
128
130
|
Actions={toArray(collection.Actions)} />
|
|
@@ -255,6 +257,7 @@ function EntityFullScreenRoute({
|
|
|
255
257
|
key={collection.id + "_" + (isNew ? "new" : (isCopy ? entityId + "_copy" : entityId))}
|
|
256
258
|
entityId={isNew ? undefined : entityId}
|
|
257
259
|
fullIdPath={fullIdPath}
|
|
260
|
+
pathSegments={isNew ? lastCollectionEntry!.pathSegments : lastEntityEntry!.pathSegments}
|
|
258
261
|
collection={collection}
|
|
259
262
|
layout={"full_screen"}
|
|
260
263
|
path={collectionPath}
|
package/src/types/collections.ts
CHANGED
|
@@ -101,6 +101,14 @@ export interface EntityCollection<M extends Record<string, any> = any, USER exte
|
|
|
101
101
|
*/
|
|
102
102
|
titleProperty?: keyof M;
|
|
103
103
|
|
|
104
|
+
/**
|
|
105
|
+
* Property used as the image thumbnail in Cards and Kanban view modes.
|
|
106
|
+
* Must reference a storage/image property (or an array of them), or a
|
|
107
|
+
* string property with `url: "image"`.
|
|
108
|
+
* If not specified, the first matching image property will be used.
|
|
109
|
+
*/
|
|
110
|
+
imageProperty?: keyof M;
|
|
111
|
+
|
|
104
112
|
/**
|
|
105
113
|
* When editing an entity, you can choose to open the entity in a side dialog
|
|
106
114
|
* or in a full screen dialog. Defaults to `full_screen`.
|
package/src/types/datasource.ts
CHANGED
|
@@ -8,6 +8,20 @@ import { FireCMSContext } from "./firecms_context";
|
|
|
8
8
|
*/
|
|
9
9
|
export interface FetchEntityProps<M extends Record<string, any> = any> {
|
|
10
10
|
path: string;
|
|
11
|
+
/**
|
|
12
|
+
* The path split at its real segment boundaries, e.g.
|
|
13
|
+
* `["nodes", "node/42", "edges"]`.
|
|
14
|
+
*
|
|
15
|
+
* `path` is a single flattened string, so a parent entity id containing "/" cannot be
|
|
16
|
+
* recovered from it — `"nodes/node/42/edges"` is indistinguishable from a three-level
|
|
17
|
+
* nesting. This is the unambiguous form: one array element per segment, entity ids
|
|
18
|
+
* kept whole however many slashes they contain.
|
|
19
|
+
*
|
|
20
|
+
* For any backend whose ids cannot contain "/" this is exactly `path.split("/")`, so
|
|
21
|
+
* delegates that do not care can keep using `path`. Delegates that do should prefer
|
|
22
|
+
* `pathSegments ?? path.split("/")`.
|
|
23
|
+
*/
|
|
24
|
+
pathSegments?: string[];
|
|
11
25
|
entityId: string;
|
|
12
26
|
databaseId?: string;
|
|
13
27
|
collection?: EntityCollection<M, any>
|
|
@@ -28,6 +42,20 @@ export type ListenEntityProps<M extends Record<string, any> = any> =
|
|
|
28
42
|
*/
|
|
29
43
|
export interface FetchCollectionProps<M extends Record<string, any> = any> {
|
|
30
44
|
path: string;
|
|
45
|
+
/**
|
|
46
|
+
* The path split at its real segment boundaries, e.g.
|
|
47
|
+
* `["nodes", "node/42", "edges"]`.
|
|
48
|
+
*
|
|
49
|
+
* `path` is a single flattened string, so a parent entity id containing "/" cannot be
|
|
50
|
+
* recovered from it — `"nodes/node/42/edges"` is indistinguishable from a three-level
|
|
51
|
+
* nesting. This is the unambiguous form: one array element per segment, entity ids
|
|
52
|
+
* kept whole however many slashes they contain.
|
|
53
|
+
*
|
|
54
|
+
* For any backend whose ids cannot contain "/" this is exactly `path.split("/")`, so
|
|
55
|
+
* delegates that do not care can keep using `path`. Delegates that do should prefer
|
|
56
|
+
* `pathSegments ?? path.split("/")`.
|
|
57
|
+
*/
|
|
58
|
+
pathSegments?: string[];
|
|
31
59
|
collection?: EntityCollection<M> | ResolvedEntityCollection<M>;
|
|
32
60
|
filter?: FilterValues<Extract<keyof M, string>>,
|
|
33
61
|
limit?: number;
|
|
@@ -52,6 +80,20 @@ export type ListenCollectionProps<M extends Record<string, any> = any> =
|
|
|
52
80
|
*/
|
|
53
81
|
export interface SaveEntityProps<M extends Record<string, any> = any> {
|
|
54
82
|
path: string;
|
|
83
|
+
/**
|
|
84
|
+
* The path split at its real segment boundaries, e.g.
|
|
85
|
+
* `["nodes", "node/42", "edges"]`.
|
|
86
|
+
*
|
|
87
|
+
* `path` is a single flattened string, so a parent entity id containing "/" cannot be
|
|
88
|
+
* recovered from it — `"nodes/node/42/edges"` is indistinguishable from a three-level
|
|
89
|
+
* nesting. This is the unambiguous form: one array element per segment, entity ids
|
|
90
|
+
* kept whole however many slashes they contain.
|
|
91
|
+
*
|
|
92
|
+
* For any backend whose ids cannot contain "/" this is exactly `path.split("/")`, so
|
|
93
|
+
* delegates that do not care can keep using `path`. Delegates that do should prefer
|
|
94
|
+
* `pathSegments ?? path.split("/")`.
|
|
95
|
+
*/
|
|
96
|
+
pathSegments?: string[];
|
|
55
97
|
values: Partial<EntityValues<M>>;
|
|
56
98
|
entityId?: string; // can be empty for new entities
|
|
57
99
|
previousValues?: Partial<EntityValues<M>>;
|
|
@@ -64,6 +106,11 @@ export interface SaveEntityProps<M extends Record<string, any> = any> {
|
|
|
64
106
|
*/
|
|
65
107
|
export interface DeleteEntityProps<M extends Record<string, any> = any> {
|
|
66
108
|
entity: Entity<M>;
|
|
109
|
+
/**
|
|
110
|
+
* `entity.path` split at its real segment boundaries, when the caller knows them.
|
|
111
|
+
* Never derived from `entity.path` — see `pathSegments` on FetchCollectionProps.
|
|
112
|
+
*/
|
|
113
|
+
pathSegments?: string[];
|
|
67
114
|
collection?: EntityCollection<M> | ResolvedEntityCollection<M>;
|
|
68
115
|
}
|
|
69
116
|
|
|
@@ -203,13 +250,19 @@ export interface DataSource {
|
|
|
203
250
|
name: string,
|
|
204
251
|
value: any,
|
|
205
252
|
entityId?: string,
|
|
206
|
-
collection?: EntityCollection
|
|
253
|
+
collection?: EntityCollection,
|
|
254
|
+
/**
|
|
255
|
+
* Appended last, and optional, so existing implementations and callers keep
|
|
256
|
+
* working unchanged — a function declaring fewer parameters stays assignable.
|
|
257
|
+
* See `pathSegments` on FetchCollectionProps.
|
|
258
|
+
*/
|
|
259
|
+
pathSegments?: string[]
|
|
207
260
|
): Promise<boolean>;
|
|
208
261
|
|
|
209
262
|
/**
|
|
210
263
|
* Generate an id for a new entity
|
|
211
264
|
*/
|
|
212
|
-
generateEntityId(path: string, collection: EntityCollection): string;
|
|
265
|
+
generateEntityId(path: string, collection: EntityCollection, pathSegments?: string[]): string;
|
|
213
266
|
|
|
214
267
|
/**
|
|
215
268
|
* Count the number of entities in a collection
|
|
@@ -237,6 +290,8 @@ export interface DataSource {
|
|
|
237
290
|
}
|
|
238
291
|
|
|
239
292
|
export type FilterCombinationValidProps = {
|
|
293
|
+
/** `path` split at its real segment boundaries — see `pathSegments` on FetchCollectionProps. */
|
|
294
|
+
pathSegments?: string[];
|
|
240
295
|
path: string;
|
|
241
296
|
collection: EntityCollection<any>;
|
|
242
297
|
filterValues: FilterValues<any>;
|
|
@@ -366,12 +421,12 @@ export interface DataSourceDelegate {
|
|
|
366
421
|
* @param collection
|
|
367
422
|
* @return `true` if there are no other fields besides the given entity
|
|
368
423
|
*/
|
|
369
|
-
checkUniqueField(path: string, name: string, value: any, entityId?: string, collection?: EntityCollection): Promise<boolean>;
|
|
424
|
+
checkUniqueField(path: string, name: string, value: any, entityId?: string, collection?: EntityCollection, pathSegments?: string[]): Promise<boolean>;
|
|
370
425
|
|
|
371
426
|
/**
|
|
372
427
|
* Generate an id for a new entity
|
|
373
428
|
*/
|
|
374
|
-
generateEntityId(path: string, collection?: EntityCollection): string;
|
|
429
|
+
generateEntityId(path: string, collection?: EntityCollection, pathSegments?: string[]): string;
|
|
375
430
|
|
|
376
431
|
/**
|
|
377
432
|
* Count the number of entities in a collection
|
package/src/types/entities.ts
CHANGED
|
@@ -21,6 +21,17 @@ export interface Entity<M extends object = any> {
|
|
|
21
21
|
*/
|
|
22
22
|
path: string;
|
|
23
23
|
|
|
24
|
+
/**
|
|
25
|
+
* `path` split at its real segment boundaries, e.g. `["nodes", "node/42", "edges"]`.
|
|
26
|
+
*
|
|
27
|
+
* `path` is a single flattened string, so a parent entity id containing "/" cannot be
|
|
28
|
+
* recovered from it. This keeps each segment whole.
|
|
29
|
+
*
|
|
30
|
+
* Optional, and never derived by splitting `path` — a guess would be wrong in exactly
|
|
31
|
+
* the case the field exists for. Absent means "not known here", not "no slashes".
|
|
32
|
+
*/
|
|
33
|
+
pathSegments?: string[];
|
|
34
|
+
|
|
24
35
|
/**
|
|
25
36
|
* Current values
|
|
26
37
|
*/
|
|
@@ -55,10 +66,22 @@ export class EntityReference {
|
|
|
55
66
|
*/
|
|
56
67
|
readonly databaseId?: string;
|
|
57
68
|
|
|
58
|
-
|
|
69
|
+
/**
|
|
70
|
+
* `path` split at its real segment boundaries, e.g. `["nodes", "node/42", "edges"]`.
|
|
71
|
+
*
|
|
72
|
+
* `path` is a single flattened string, so a parent entity id containing "/" cannot be
|
|
73
|
+
* recovered from it. This keeps each segment whole.
|
|
74
|
+
*
|
|
75
|
+
* Optional, and never derived by splitting `path` — a guess would be wrong in exactly
|
|
76
|
+
* the case the field exists for. Absent means "not known here", not "no slashes".
|
|
77
|
+
*/
|
|
78
|
+
readonly pathSegments?: string[];
|
|
79
|
+
|
|
80
|
+
constructor(id: string, path: string, databaseId?: string, pathSegments?: string[]) {
|
|
59
81
|
this.id = id;
|
|
60
82
|
this.path = path;
|
|
61
83
|
this.databaseId = databaseId;
|
|
84
|
+
this.pathSegments = pathSegments;
|
|
62
85
|
}
|
|
63
86
|
|
|
64
87
|
get pathWithId() {
|
package/src/types/properties.ts
CHANGED
|
@@ -562,6 +562,22 @@ export type PropertyBuilderProps<M extends Record<string, any> = any> =
|
|
|
562
562
|
* Current value of this property
|
|
563
563
|
*/
|
|
564
564
|
propertyValue?: any;
|
|
565
|
+
/**
|
|
566
|
+
* Path of this property within the entity, in dot notation, e.g.
|
|
567
|
+
* `my_map.my_field` or `my_array.0.my_field`.
|
|
568
|
+
* Useful to look up sibling values in `values` with `getValueInPath`.
|
|
569
|
+
*
|
|
570
|
+
* When a property builder is used as the `of` prop of an array property,
|
|
571
|
+
* it is resolved twice: once per existing element, with an index
|
|
572
|
+
* qualified key (`my_array.0`), and once as the template for the element
|
|
573
|
+
* shape, with the array's own key (`my_array`). In the latter case
|
|
574
|
+
* `propertyValue` is the whole array, since the template is not bound to
|
|
575
|
+
* any element.
|
|
576
|
+
*
|
|
577
|
+
* It may be undefined if the property is resolved outside the context of
|
|
578
|
+
* an entity.
|
|
579
|
+
*/
|
|
580
|
+
propertyKey?: string;
|
|
565
581
|
/**
|
|
566
582
|
* Index of this property (only for arrays)
|
|
567
583
|
*/
|
|
@@ -592,6 +608,7 @@ export type PropertyBuilder<T extends CMSType = any, M extends Record<string, an
|
|
|
592
608
|
values,
|
|
593
609
|
previousValues,
|
|
594
610
|
propertyValue,
|
|
611
|
+
propertyKey,
|
|
595
612
|
index,
|
|
596
613
|
path,
|
|
597
614
|
entityId,
|