@firecms/collection_editor 3.0.1 → 3.1.0-canary.02232f4

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 (119) hide show
  1. package/dist/ConfigControllerProvider.d.ts +6 -0
  2. package/dist/api/generateCollectionApi.d.ts +71 -0
  3. package/dist/api/index.d.ts +1 -0
  4. package/dist/index.d.ts +5 -1
  5. package/dist/index.es.js +15260 -8173
  6. package/dist/index.es.js.map +1 -1
  7. package/dist/index.umd.js +15257 -8170
  8. package/dist/index.umd.js.map +1 -1
  9. package/dist/locales/de.d.ts +120 -0
  10. package/dist/locales/en.d.ts +120 -0
  11. package/dist/locales/es.d.ts +120 -0
  12. package/dist/locales/fr.d.ts +120 -0
  13. package/dist/locales/hi.d.ts +120 -0
  14. package/dist/locales/it.d.ts +120 -0
  15. package/dist/locales/pt.d.ts +120 -0
  16. package/dist/types/collection_editor_controller.d.ts +14 -0
  17. package/dist/types/collection_inference.d.ts +8 -2
  18. package/dist/types/config_controller.d.ts +23 -2
  19. package/dist/ui/AddKanbanColumnAction.d.ts +11 -0
  20. package/dist/ui/KanbanSetupAction.d.ts +10 -0
  21. package/dist/ui/collection_editor/AICollectionGeneratorPopover.d.ts +37 -0
  22. package/dist/ui/collection_editor/AIModifiedPathsContext.d.ts +20 -0
  23. package/dist/ui/collection_editor/CollectionDetailsForm.d.ts +2 -3
  24. package/dist/ui/collection_editor/CollectionEditorDialog.d.ts +24 -0
  25. package/dist/ui/collection_editor/CollectionEditorWelcomeView.d.ts +4 -1
  26. package/dist/ui/collection_editor/CollectionJsonImportDialog.d.ts +7 -0
  27. package/dist/ui/collection_editor/CollectionYupValidation.d.ts +9 -13
  28. package/dist/ui/collection_editor/DisplaySettingsForm.d.ts +3 -0
  29. package/dist/ui/collection_editor/EntityActionsEditTab.d.ts +2 -1
  30. package/dist/ui/collection_editor/ExtendSettingsForm.d.ts +14 -0
  31. package/dist/ui/collection_editor/GeneralSettingsForm.d.ts +7 -0
  32. package/dist/ui/collection_editor/KanbanConfigSection.d.ts +4 -0
  33. package/dist/ui/collection_editor/PropertyEditView.d.ts +6 -1
  34. package/dist/ui/collection_editor/PropertyTree.d.ts +2 -1
  35. package/dist/ui/collection_editor/SubcollectionsEditTab.d.ts +2 -1
  36. package/dist/ui/collection_editor/ViewModeSwitch.d.ts +6 -0
  37. package/dist/ui/collection_editor/properties/EnumPropertyField.d.ts +2 -1
  38. package/dist/ui/collection_editor/properties/conditions/ConditionsEditor.d.ts +10 -0
  39. package/dist/ui/collection_editor/properties/conditions/ConditionsPanel.d.ts +2 -0
  40. package/dist/ui/collection_editor/properties/conditions/EnumConditionsEditor.d.ts +6 -0
  41. package/dist/ui/collection_editor/properties/conditions/index.d.ts +6 -0
  42. package/dist/ui/collection_editor/properties/conditions/property_paths.d.ts +19 -0
  43. package/dist/useCollectionEditorPlugin.d.ts +7 -1
  44. package/dist/utils/validateCollectionJson.d.ts +22 -0
  45. package/package.json +15 -15
  46. package/src/ConfigControllerProvider.tsx +82 -47
  47. package/src/api/generateCollectionApi.ts +119 -0
  48. package/src/api/index.ts +1 -0
  49. package/src/index.ts +28 -1
  50. package/src/locales/de.ts +125 -0
  51. package/src/locales/en.ts +145 -0
  52. package/src/locales/es.ts +125 -0
  53. package/src/locales/fr.ts +125 -0
  54. package/src/locales/hi.ts +125 -0
  55. package/src/locales/it.ts +125 -0
  56. package/src/locales/pt.ts +125 -0
  57. package/src/types/collection_editor_controller.tsx +16 -3
  58. package/src/types/collection_inference.ts +15 -2
  59. package/src/types/config_controller.tsx +27 -2
  60. package/src/ui/AddKanbanColumnAction.tsx +203 -0
  61. package/src/ui/EditorCollectionAction.tsx +3 -3
  62. package/src/ui/EditorCollectionActionStart.tsx +1 -2
  63. package/src/ui/EditorEntityAction.tsx +3 -2
  64. package/src/ui/HomePageEditorCollectionAction.tsx +41 -13
  65. package/src/ui/KanbanSetupAction.tsx +38 -0
  66. package/src/ui/MissingReferenceWidget.tsx +1 -1
  67. package/src/ui/NewCollectionButton.tsx +4 -2
  68. package/src/ui/NewCollectionCard.tsx +7 -4
  69. package/src/ui/PropertyAddColumnComponent.tsx +4 -3
  70. package/src/ui/collection_editor/AICollectionGeneratorPopover.tsx +243 -0
  71. package/src/ui/collection_editor/AIModifiedPathsContext.tsx +88 -0
  72. package/src/ui/collection_editor/CollectionDetailsForm.tsx +222 -267
  73. package/src/ui/collection_editor/CollectionEditorDialog.tsx +270 -198
  74. package/src/ui/collection_editor/CollectionEditorWelcomeView.tsx +138 -71
  75. package/src/ui/collection_editor/CollectionJsonImportDialog.tsx +171 -0
  76. package/src/ui/collection_editor/CollectionPropertiesEditorForm.tsx +202 -101
  77. package/src/ui/collection_editor/DisplaySettingsForm.tsx +335 -0
  78. package/src/ui/collection_editor/EntityActionsEditTab.tsx +106 -97
  79. package/src/ui/collection_editor/EntityActionsSelectDialog.tsx +8 -10
  80. package/src/ui/collection_editor/EntityCustomViewsSelectDialog.tsx +5 -7
  81. package/src/ui/collection_editor/EnumForm.tsx +153 -102
  82. package/src/ui/collection_editor/ExtendSettingsForm.tsx +94 -0
  83. package/src/ui/collection_editor/GeneralSettingsForm.tsx +335 -0
  84. package/src/ui/collection_editor/GetCodeDialog.tsx +63 -41
  85. package/src/ui/collection_editor/KanbanConfigSection.tsx +209 -0
  86. package/src/ui/collection_editor/LayoutModeSwitch.tsx +27 -43
  87. package/src/ui/collection_editor/PropertyEditView.tsx +272 -199
  88. package/src/ui/collection_editor/PropertyFieldPreview.tsx +1 -1
  89. package/src/ui/collection_editor/PropertyTree.tsx +130 -58
  90. package/src/ui/collection_editor/SubcollectionsEditTab.tsx +169 -163
  91. package/src/ui/collection_editor/UnsavedChangesDialog.tsx +0 -2
  92. package/src/ui/collection_editor/ViewModeSwitch.tsx +43 -0
  93. package/src/ui/collection_editor/import/CollectionEditorImportDataPreview.tsx +6 -3
  94. package/src/ui/collection_editor/import/CollectionEditorImportMapping.tsx +5 -2
  95. package/src/ui/collection_editor/properties/BlockPropertyField.tsx +0 -2
  96. package/src/ui/collection_editor/properties/BooleanPropertyField.tsx +4 -1
  97. package/src/ui/collection_editor/properties/CommonPropertyFields.tsx +6 -4
  98. package/src/ui/collection_editor/properties/DateTimePropertyField.tsx +126 -42
  99. package/src/ui/collection_editor/properties/EnumPropertyField.tsx +32 -24
  100. package/src/ui/collection_editor/properties/MapPropertyField.tsx +8 -9
  101. package/src/ui/collection_editor/properties/MarkdownPropertyField.tsx +128 -53
  102. package/src/ui/collection_editor/properties/NumberPropertyField.tsx +3 -1
  103. package/src/ui/collection_editor/properties/ReferencePropertyField.tsx +5 -4
  104. package/src/ui/collection_editor/properties/StoragePropertyField.tsx +47 -52
  105. package/src/ui/collection_editor/properties/StringPropertyField.tsx +3 -1
  106. package/src/ui/collection_editor/properties/UrlPropertyField.tsx +12 -10
  107. package/src/ui/collection_editor/properties/advanced/AdvancedPropertyValidation.tsx +23 -4
  108. package/src/ui/collection_editor/properties/conditions/ConditionsEditor.tsx +866 -0
  109. package/src/ui/collection_editor/properties/conditions/ConditionsPanel.tsx +28 -0
  110. package/src/ui/collection_editor/properties/conditions/EnumConditionsEditor.tsx +599 -0
  111. package/src/ui/collection_editor/properties/conditions/index.ts +6 -0
  112. package/src/ui/collection_editor/properties/conditions/property_paths.ts +92 -0
  113. package/src/ui/collection_editor/properties/validation/ArrayPropertyValidation.tsx +5 -2
  114. package/src/ui/collection_editor/properties/validation/GeneralPropertyValidation.tsx +7 -5
  115. package/src/ui/collection_editor/properties/validation/NumberPropertyValidation.tsx +10 -7
  116. package/src/ui/collection_editor/properties/validation/StringPropertyValidation.tsx +11 -9
  117. package/src/ui/collection_editor/properties/validation/ValidationPanel.tsx +5 -2
  118. package/src/useCollectionEditorPlugin.tsx +53 -22
  119. package/src/utils/validateCollectionJson.ts +380 -0
@@ -6,23 +6,25 @@ import {
6
6
  ErrorBoundary,
7
7
  isPropertyBuilder,
8
8
  makePropertiesEditable,
9
+ MapProperty,
9
10
  Properties,
10
11
  Property,
11
12
  PropertyConfig,
12
13
  PropertyOrBuilder,
13
14
  useLargeLayout,
14
15
  User,
15
- useSnackbarController
16
+ useSnackbarController,
17
+ useTranslation
16
18
  } from "@firecms/core";
17
19
  import {
18
20
  AddIcon,
19
- AutorenewIcon,
20
21
  Button,
21
22
  CircularProgress,
22
23
  cls,
23
24
  CodeIcon,
24
25
  DebouncedTextField,
25
26
  defaultBorderMixin,
27
+ FindInPageIcon,
26
28
  IconButton,
27
29
  Tooltip,
28
30
  Typography,
@@ -33,6 +35,7 @@ import { OnPropertyChangedParams, PropertyForm, PropertyFormDialog } from "./Pro
33
35
  import { PropertyTree } from "./PropertyTree";
34
36
  import { PersistedCollection } from "../../types/persisted_collection";
35
37
  import { GetCodeDialog } from "./GetCodeDialog";
38
+ import { useAIModifiedPaths } from "./AIModifiedPathsContext";
36
39
 
37
40
  type CollectionEditorFormProps = {
38
41
  showErrors: boolean;
@@ -50,19 +53,19 @@ type CollectionEditorFormProps = {
50
53
  };
51
54
 
52
55
  export function CollectionPropertiesEditorForm({
53
- showErrors,
54
- isNewCollection,
55
- propertyErrorsRef,
56
- onPropertyError,
57
- setDirty,
58
- reservedGroups,
59
- extraIcon,
60
- getUser,
61
- getData,
62
- doCollectionInference,
63
- propertyConfigs,
64
- collectionEditable
65
- }: CollectionEditorFormProps) {
56
+ showErrors,
57
+ isNewCollection,
58
+ propertyErrorsRef,
59
+ onPropertyError,
60
+ setDirty,
61
+ reservedGroups,
62
+ extraIcon,
63
+ getUser,
64
+ getData,
65
+ doCollectionInference,
66
+ propertyConfigs,
67
+ collectionEditable
68
+ }: CollectionEditorFormProps) {
66
69
 
67
70
  const {
68
71
  values,
@@ -77,6 +80,7 @@ export function CollectionPropertiesEditorForm({
77
80
 
78
81
  const largeLayout = useLargeLayout();
79
82
  const asDialog = !largeLayout
83
+ const { t } = useTranslation();
80
84
 
81
85
  // index of the selected property within the namespace
82
86
  const [selectedPropertyIndex, setSelectedPropertyIndex] = useState<number | undefined>();
@@ -108,7 +112,7 @@ export function CollectionPropertiesEditorForm({
108
112
 
109
113
  setInferringProperties(true);
110
114
 
111
- console.debug("CollectionEditor: inferring properties from data", doCollectionInference, values);
115
+ console.debug("CollectionEditor: inferring properties from data", values);
112
116
  // @ts-ignore
113
117
  doCollectionInference(values)
114
118
  .then((newCollection) => {
@@ -123,35 +127,130 @@ export function CollectionPropertiesEditorForm({
123
127
  });
124
128
  return;
125
129
  }
126
- // find properties in the new collection, not present in the current one
127
- const newPropertyKeys = (newCollection.properties ? Object.keys(newCollection.properties) : [])
130
+
131
+ // Helper function to find all new property keys including nested ones
132
+ const findNewPropertyKeys = (
133
+ existingProps: Record<string, PropertyOrBuilder> | undefined,
134
+ newProps: Record<string, PropertyOrBuilder> | undefined,
135
+ namespace?: string
136
+ ): string[] => {
137
+ if (!newProps) return [];
138
+ const keys: string[] = [];
139
+
140
+ for (const key of Object.keys(newProps)) {
141
+ const fullKey = namespace ? `${namespace}.${key}` : key;
142
+ const existingProp = existingProps?.[key];
143
+ const newProp = newProps[key];
144
+
145
+ if (!existingProp) {
146
+ // This is a completely new property
147
+ keys.push(fullKey);
148
+ } else if (
149
+ typeof newProp === "object" &&
150
+ "dataType" in newProp &&
151
+ newProp.dataType === "map" &&
152
+ newProp.properties
153
+ ) {
154
+ // This is a map property, check for new nested properties
155
+ const existingMapProps = typeof existingProp === "object" &&
156
+ "dataType" in existingProp &&
157
+ existingProp.dataType === "map"
158
+ ? (existingProp as any).properties
159
+ : undefined;
160
+ keys.push(...findNewPropertyKeys(existingMapProps, newProp.properties as Record<string, PropertyOrBuilder>, fullKey));
161
+ }
162
+ }
163
+ return keys;
164
+ };
165
+
166
+ // Helper function to add only new properties without overwriting existing ones
167
+ // This preserves existing property configurations while adding missing nested properties
168
+ const addNewPropertiesOnly = (
169
+ existingProps: Record<string, PropertyOrBuilder> | undefined,
170
+ newProps: Record<string, PropertyOrBuilder> | undefined
171
+ ): Record<string, PropertyOrBuilder> => {
172
+ if (!newProps) return existingProps ?? {};
173
+ if (!existingProps) return newProps;
174
+
175
+ const result = { ...existingProps };
176
+
177
+ for (const key of Object.keys(newProps)) {
178
+ const existingProp = existingProps[key];
179
+ const newProp = newProps[key];
180
+
181
+ if (!existingProp) {
182
+ // This property doesn't exist, add it
183
+ result[key] = newProp;
184
+ } else if (
185
+ typeof existingProp === "object" &&
186
+ "dataType" in existingProp &&
187
+ existingProp.dataType === "map" &&
188
+ typeof newProp === "object" &&
189
+ "dataType" in newProp &&
190
+ newProp.dataType === "map" &&
191
+ newProp.properties
192
+ ) {
193
+ // Both are map properties, recursively add new nested properties
194
+ // Only if the existing map has properties, merge them; otherwise keep existing as-is
195
+ const existingMapProps = (existingProp as MapProperty).properties as Record<string, PropertyOrBuilder> | undefined;
196
+ if (existingMapProps) {
197
+ result[key] = {
198
+ ...existingProp,
199
+ properties: addNewPropertiesOnly(
200
+ existingMapProps,
201
+ newProp.properties as Record<string, PropertyOrBuilder>
202
+ )
203
+ };
204
+ }
205
+ // If existingProp doesn't have properties, keep it as-is (don't overwrite with inferred)
206
+ }
207
+ // Otherwise, keep the existing property as-is (don't overwrite)
208
+ }
209
+
210
+ return result;
211
+ };
212
+
213
+ // Add only new properties from inferred collection without replacing existing ones
214
+ const updatedProperties = addNewPropertiesOnly(
215
+ values.properties ?? {},
216
+ newCollection.properties as Record<string, PropertyOrBuilder>
217
+ ) as { [key: string]: PropertyOrBuilder };
218
+
219
+ // Find all new property keys including nested ones
220
+ const allNewPropertyKeys = findNewPropertyKeys(
221
+ values.properties,
222
+ newCollection.properties as Record<string, PropertyOrBuilder>
223
+ );
224
+
225
+ // Find new top-level property keys for the properties order
226
+ const newTopLevelPropertyKeys = (newCollection.properties ? Object.keys(newCollection.properties) : [])
128
227
  .filter((propertyKey) => !values.properties[propertyKey]);
129
- if (newPropertyKeys.length === 0) {
228
+
229
+ // Check if there are any changes (new properties or modified nested properties)
230
+ if (allNewPropertyKeys.length === 0) {
130
231
  snackbarController.open({
131
232
  type: "info",
132
233
  message: "No new properties found in existing data"
133
234
  });
134
235
  return;
135
236
  }
136
- // add them to the current collection
137
- const updatedProperties = {
138
- ...newPropertyKeys.reduce((acc, propertyKey) => {
139
- acc[propertyKey] = (newCollection.properties ?? {})[propertyKey];
140
- return acc;
141
- }, {} as {
142
- [key: string]: PropertyOrBuilder
143
- }),
144
- ...values.properties
145
- };
237
+
238
+ // Update properties order: keep existing order and append new keys at the beginning
239
+ // Use Object.keys from updatedProperties to ensure all properties are included
240
+ const allExistingKeys = values.propertiesOrder ?? Object.keys(values.properties ?? {});
146
241
  const updatedPropertiesOrder = [
147
- ...newPropertyKeys,
148
- ...(values.propertiesOrder ?? [])
242
+ ...newTopLevelPropertyKeys,
243
+ ...allExistingKeys.filter(key => !newTopLevelPropertyKeys.includes(key))
149
244
  ];
150
- setFieldValue("properties", updatedProperties, false);
151
245
 
246
+ setFieldValue("properties", updatedProperties, false);
152
247
  updatePropertiesOrder(updatedPropertiesOrder);
248
+ setInferredPropertyKeys(allNewPropertyKeys);
153
249
 
154
- setInferredPropertyKeys(newPropertyKeys);
250
+ snackbarController.open({
251
+ type: "success",
252
+ message: `Added ${allNewPropertyKeys.length} new ${allNewPropertyKeys.length === 1 ? "property" : "properties"}`
253
+ });
155
254
  })
156
255
  .finally(() => {
157
256
  setInferringProperties(false);
@@ -197,9 +296,9 @@ export function CollectionPropertiesEditorForm({
197
296
  };
198
297
 
199
298
  const onPropertyCreated = ({
200
- id,
201
- property
202
- }: {
299
+ id,
300
+ property
301
+ }: {
203
302
  id?: string,
204
303
  property: Property
205
304
  }) => {
@@ -223,11 +322,11 @@ export function CollectionPropertiesEditorForm({
223
322
  };
224
323
 
225
324
  const onPropertyChanged = ({
226
- id,
227
- property,
228
- previousId,
229
- namespace
230
- }: OnPropertyChangedParams) => {
325
+ id,
326
+ property,
327
+ previousId,
328
+ namespace
329
+ }: OnPropertyChangedParams) => {
231
330
 
232
331
  const fullId = id ? getFullId(id, namespace) : undefined;
233
332
  const propertyPath = fullId ? idToPropertiesPath(fullId) : undefined;
@@ -292,6 +391,10 @@ export function CollectionPropertiesEditorForm({
292
391
 
293
392
  const owner = useMemo(() => values.ownerId && getUser ? getUser(values.ownerId) : null, [getUser, values.ownerId]);
294
393
 
394
+ // Get AI generation counter for key to force remount on AI changes
395
+ const aiModifiedPaths = useAIModifiedPaths();
396
+ const generationCounter = aiModifiedPaths?.generationCounter ?? 0;
397
+
295
398
  const onPropertyClick = (propertyKey: string, namespace?: string) => {
296
399
  console.debug("CollectionEditor: onPropertyClick", {
297
400
  propertyKey,
@@ -303,7 +406,7 @@ export function CollectionPropertiesEditorForm({
303
406
  };
304
407
 
305
408
  const body = (
306
- <div className={"grid grid-cols-12 gap-2 h-full bg-white dark:bg-surface-950"}>
409
+ <div className={"grid grid-cols-12 gap-2 h-full bg-surface dark:bg-surface-dark"}>
307
410
  <div className={cls(
308
411
  "bg-surface-50 dark:bg-surface-900",
309
412
  "p-4 md:p-8 pb-20 md:pb-20",
@@ -324,13 +427,13 @@ export function CollectionPropertiesEditorForm({
324
427
  placeholder={"Collection name"}
325
428
  size={"small"}
326
429
  required
327
- error={Boolean(errors?.name)}/>
430
+ error={Boolean(errors?.name)} />
328
431
 
329
432
  {owner &&
330
433
  <Typography variant={"body2"}
331
- className={"ml-2"}
332
- color={"secondary"}>
333
- Created by {owner.displayName}
434
+ className={"ml-2"}
435
+ color={"secondary"}>
436
+ {t("created_by", { name: owner.displayName ?? "" })}
334
437
  </Typography>}
335
438
  </div>
336
439
 
@@ -339,31 +442,29 @@ export function CollectionPropertiesEditorForm({
339
442
  </div>}
340
443
 
341
444
  <div className="ml-1 mt-2 flex flex-row gap-2">
342
- <Tooltip title={"Get the code for this collection"}
343
- asChild={true}>
445
+ <Tooltip title={t("get_code_for_collection")}
446
+ asChild={true}>
344
447
  <IconButton
345
448
  variant={"filled"}
346
449
  disabled={inferringProperties}
347
450
  onClick={() => setCodeDialogOpen(true)}>
348
- <CodeIcon/>
451
+ <CodeIcon />
349
452
  </IconButton>
350
453
  </Tooltip>
351
- {inferPropertiesFromData && <Tooltip title={"Add new properties based on data"}
352
- asChild={true}>
454
+ {inferPropertiesFromData && <Tooltip title={t("add_properties_from_data")}
455
+ asChild={true}>
353
456
  <IconButton
354
457
  variant={"filled"}
355
458
  disabled={inferringProperties}
356
459
  onClick={inferPropertiesFromData}>
357
- {inferringProperties ? <CircularProgress size={"small"}/> : <AutorenewIcon/>}
460
+ {inferringProperties ? <CircularProgress size={"small"} /> : <FindInPageIcon />}
358
461
  </IconButton>
359
462
  </Tooltip>}
360
- <Tooltip title={"Add new property"}
361
- asChild={true}>
463
+ <Tooltip title={t("add_new_property")}
464
+ asChild={true}>
362
465
  <Button
363
- variant={"outlined"}
364
- color={"primary"}
365
466
  onClick={() => setNewPropertyDialogOpen(true)}>
366
- <AddIcon/>
467
+ <AddIcon />
367
468
  </Button>
368
469
  </Tooltip>
369
470
  </div>
@@ -379,18 +480,16 @@ export function CollectionPropertiesEditorForm({
379
480
  propertiesOrder={usedPropertiesOrder}
380
481
  onPropertyClick={onPropertyClick}
381
482
  onPropertyMove={onPropertyMove}
382
- onPropertyRemove={isNewCollection ? deleteProperty : undefined}
483
+ onPropertyRemove={(isNewCollection || (inferredPropertyKeys && inferredPropertyKeys.length > 0)) ? deleteProperty : undefined}
383
484
  collectionEditable={collectionEditable}
384
- errors={errors}/>
485
+ errors={errors} />
385
486
  </ErrorBoundary>
386
487
 
387
488
  <Button className={"mt-8 w-full"}
388
- color="primary"
389
- variant={"outlined"}
390
- size={"large"}
391
- onClick={() => setNewPropertyDialogOpen(true)}
392
- startIcon={<AddIcon/>}>
393
- Add new property
489
+ size={"large"}
490
+ onClick={() => setNewPropertyDialogOpen(true)}
491
+ startIcon={<AddIcon />}>
492
+ {t("add_new_property")}
394
493
  </Button>
395
494
  </div>
396
495
 
@@ -404,7 +503,7 @@ export function CollectionPropertiesEditorForm({
404
503
  !isPropertyBuilder(selectedProperty) &&
405
504
  <PropertyForm
406
505
  inArray={false}
407
- key={`edit_view_${selectedPropertyIndex}`}
506
+ key={`edit_view_${selectedPropertyIndex}_${generationCounter}`}
408
507
  existingProperty={!isNewCollection}
409
508
  autoUpdateId={false}
410
509
  allowDataInference={!isNewCollection}
@@ -420,27 +519,27 @@ export function CollectionPropertiesEditorForm({
420
519
  getData={getData}
421
520
  propertyConfigs={propertyConfigs}
422
521
  collectionEditable={collectionEditable}
522
+ collectionProperties={values.properties as Properties}
423
523
  />}
424
524
 
425
525
  {!selectedProperty &&
426
526
  <div className={"w-full flex flex-col items-center justify-center h-full gap-4"}>
427
527
  <Typography variant={"label"} className="">
428
528
  {emptyCollection
429
- ? "Now you can add your first property"
430
- : "Select a property to edit it"}
529
+ ? t("add_first_property")
530
+ : t("select_property_to_edit")}
431
531
  </Typography>
432
- <Button variant={"outlined"}
433
- color={"primary"}
434
- onClick={() => setNewPropertyDialogOpen(true)}
532
+ <Button
533
+ onClick={() => setNewPropertyDialogOpen(true)}
435
534
  >
436
- <AddIcon/>
437
- Add new property
535
+ <AddIcon />
536
+ {t("add_new_property")}
438
537
  </Button>
439
538
  </div>}
440
539
 
441
540
  {selectedProperty && isPropertyBuilder(selectedProperty) &&
442
541
  <Typography variant={"label"} className="flex items-center justify-center">
443
- {"This property is defined as a property builder in code"}
542
+ {t("property_defined_as_builder")}
444
543
  </Typography>}
445
544
  </div>
446
545
  </div>}
@@ -448,7 +547,7 @@ export function CollectionPropertiesEditorForm({
448
547
  {asDialog && <PropertyFormDialog
449
548
  inArray={false}
450
549
  open={selectedPropertyIndex !== undefined}
451
- key={`edit_view_${selectedPropertyIndex}`}
550
+ key={`edit_view_${selectedPropertyIndex}_${generationCounter}`}
452
551
  autoUpdateId={!selectedProperty}
453
552
  allowDataInference={!isNewCollection}
454
553
  existingProperty={true}
@@ -464,40 +563,42 @@ export function CollectionPropertiesEditorForm({
464
563
  getData={getData}
465
564
  propertyConfigs={propertyConfigs}
466
565
  collectionEditable={collectionEditable}
566
+ collectionProperties={values.properties as Properties}
467
567
  onCancel={closePropertyDialog}
468
568
  onOkClicked={asDialog
469
569
  ? closePropertyDialog
470
570
  : undefined
471
- }/>}
571
+ } />}
472
572
 
473
573
  </div>);
474
574
 
475
575
  return (<>
476
576
 
477
- {body}
478
-
479
- {/* This is the dialog used for new properties*/}
480
- <PropertyFormDialog
481
- inArray={false}
482
- existingProperty={false}
483
- autoOpenTypeSelect={true}
484
- autoUpdateId={true}
485
- forceShowErrors={showErrors}
486
- open={newPropertyDialogOpen}
487
- onCancel={() => setNewPropertyDialogOpen(false)}
488
- onPropertyChanged={onPropertyCreated}
489
- getData={getData}
490
- allowDataInference={!isNewCollection}
491
- propertyConfigs={propertyConfigs}
492
- collectionEditable={collectionEditable}
493
- existingPropertyKeys={values.propertiesOrder as string[]}/>
494
-
495
- <ErrorBoundary>
496
- <GetCodeDialog
497
- collection={values}
498
- open={codeDialogOpen}
499
- onOpenChange={setCodeDialogOpen}/>
500
- </ErrorBoundary>
501
- </>
577
+ {body}
578
+
579
+ {/* This is the dialog used for new properties*/}
580
+ <PropertyFormDialog
581
+ inArray={false}
582
+ existingProperty={false}
583
+ autoOpenTypeSelect={true}
584
+ autoUpdateId={true}
585
+ forceShowErrors={showErrors}
586
+ open={newPropertyDialogOpen}
587
+ onCancel={() => setNewPropertyDialogOpen(false)}
588
+ onPropertyChanged={onPropertyCreated}
589
+ getData={getData}
590
+ allowDataInference={!isNewCollection}
591
+ propertyConfigs={propertyConfigs}
592
+ collectionEditable={collectionEditable}
593
+ collectionProperties={values.properties as Properties}
594
+ existingPropertyKeys={values.propertiesOrder as string[]} />
595
+
596
+ <ErrorBoundary>
597
+ <GetCodeDialog
598
+ collection={values}
599
+ open={codeDialogOpen}
600
+ onOpenChange={setCodeDialogOpen} />
601
+ </ErrorBoundary>
602
+ </>
502
603
  );
503
604
  }