@firecms/core 3.1.0-canary.1df3b2c → 3.1.0-canary.75005e4

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 (209) hide show
  1. package/dist/components/EntityCollectionTable/internal/popup_field/useDraggable.d.ts +2 -2
  2. package/dist/components/EntityCollectionView/CollectionDataErrorBanner.d.ts +4 -0
  3. package/dist/components/EntityCollectionView/ViewModeToggle.d.ts +5 -10
  4. package/dist/components/ErrorBoundary.d.ts +4 -2
  5. package/dist/components/HomePage/DefaultHomePage.d.ts +0 -1
  6. package/dist/components/LanguageToggle.d.ts +1 -0
  7. package/dist/components/UnsavedChangesDialog.d.ts +1 -0
  8. package/dist/components/VirtualTable/VirtualTableHeader.d.ts +1 -1
  9. package/dist/components/index.d.ts +1 -0
  10. package/dist/core/DrawerNavigationGroup.d.ts +2 -2
  11. package/dist/editor/components/SlashCommandMenu.d.ts +6 -0
  12. package/dist/editor/components/editor-bubble-item.d.ts +8 -0
  13. package/dist/editor/components/editor-bubble.d.ts +8 -0
  14. package/dist/editor/components/index.d.ts +14 -0
  15. package/dist/editor/editor.d.ts +30 -0
  16. package/dist/editor/extensions/HighlightDecorationExtension.d.ts +24 -0
  17. package/dist/editor/extensions/Image/index.d.ts +6 -0
  18. package/dist/editor/extensions/Image.d.ts +6 -0
  19. package/dist/editor/extensions/TextLoadingDecorationExtension.d.ts +16 -0
  20. package/dist/editor/extensions/clipboard.d.ts +7 -0
  21. package/dist/editor/extensions/custom-keymap.d.ts +1 -0
  22. package/dist/editor/extensions/drag-and-drop.d.ts +9 -0
  23. package/dist/editor/hooks/useProseMirror.d.ts +14 -0
  24. package/dist/editor/hooks/useProseMirrorContext.d.ts +9 -0
  25. package/dist/editor/index.d.ts +2 -0
  26. package/dist/editor/markdown.d.ts +5 -0
  27. package/dist/editor/nodeViews/ImageComponent.d.ts +3 -0
  28. package/dist/editor/nodeViews/ReactNodeView.d.ts +29 -0
  29. package/dist/editor/nodeViews/TaskItemComponent.d.ts +3 -0
  30. package/dist/editor/nodeViews/index.d.ts +6 -0
  31. package/dist/editor/plugins/index.d.ts +2 -0
  32. package/dist/editor/plugins/inputrules.d.ts +6 -0
  33. package/dist/editor/plugins/placeholderPlugin.d.ts +3 -0
  34. package/dist/editor/plugins/slashCommandPlugin.d.ts +11 -0
  35. package/dist/editor/schema.d.ts +2 -0
  36. package/dist/editor/selectors/ai-selector.d.ts +0 -0
  37. package/dist/editor/selectors/color-selector.d.ts +10 -0
  38. package/dist/editor/selectors/link-selector.d.ts +8 -0
  39. package/dist/editor/selectors/node-selector.d.ts +15 -0
  40. package/dist/editor/selectors/text-buttons.d.ts +1 -0
  41. package/dist/editor/types.d.ts +5 -0
  42. package/dist/editor/useProseMirror.d.ts +16 -0
  43. package/dist/editor/utils/prosemirror-utils.d.ts +6 -0
  44. package/dist/editor/utils/remove_classes.d.ts +1 -0
  45. package/dist/editor/utils/useDebouncedCallback.d.ts +1 -0
  46. package/dist/form/components/ErrorFocus.d.ts +1 -1
  47. package/dist/form/field_bindings/MarkdownEditorFieldBinding.d.ts +1 -1
  48. package/dist/hooks/index.d.ts +1 -0
  49. package/dist/hooks/useBuildNavigationController.d.ts +0 -1
  50. package/dist/hooks/useCollapsedGroups.d.ts +3 -3
  51. package/dist/hooks/useTranslation.d.ts +17 -0
  52. package/dist/i18n/FireCMSi18nProvider.d.ts +33 -0
  53. package/dist/index.d.ts +4 -0
  54. package/dist/index.es.js +11441 -2215
  55. package/dist/index.es.js.map +1 -1
  56. package/dist/index.umd.js +11423 -2216
  57. package/dist/index.umd.js.map +1 -1
  58. package/dist/internal/useRestoreScroll.d.ts +1 -1
  59. package/dist/locales/de.d.ts +2 -0
  60. package/dist/locales/en.d.ts +10 -0
  61. package/dist/locales/es.d.ts +10 -0
  62. package/dist/locales/fr.d.ts +2 -0
  63. package/dist/locales/hi.d.ts +2 -0
  64. package/dist/locales/it.d.ts +2 -0
  65. package/dist/locales/pt.d.ts +7 -0
  66. package/dist/types/analytics.d.ts +1 -1
  67. package/dist/types/collections.d.ts +8 -0
  68. package/dist/types/customization_controller.d.ts +2 -1
  69. package/dist/types/firecms.d.ts +2 -1
  70. package/dist/types/index.d.ts +1 -0
  71. package/dist/types/navigation.d.ts +2 -2
  72. package/dist/types/plugins.d.ts +23 -0
  73. package/dist/types/translations.d.ts +646 -0
  74. package/dist/util/entities.d.ts +1 -1
  75. package/dist/util/resolutions.d.ts +2 -2
  76. package/package.json +47 -13
  77. package/src/app/Scaffold.tsx +7 -5
  78. package/src/components/AIIcon.tsx +3 -1
  79. package/src/components/ArrayContainer.tsx +6 -4
  80. package/src/components/ClearFilterSortButton.tsx +6 -3
  81. package/src/components/ConfirmationDialog.tsx +4 -2
  82. package/src/components/DeleteEntityDialog.tsx +10 -7
  83. package/src/components/EntityCollectionTable/fields/TableReferenceField.tsx +6 -3
  84. package/src/components/EntityCollectionTable/internal/CollectionTableToolbar.tsx +3 -1
  85. package/src/components/EntityCollectionTable/internal/EntityTableCellActions.tsx +1 -1
  86. package/src/components/EntityCollectionTable/internal/popup_field/PopupFormField.tsx +3 -2
  87. package/src/components/EntityCollectionTable/internal/popup_field/useDraggable.tsx +11 -11
  88. package/src/components/EntityCollectionView/BoardSortableList.tsx +3 -1
  89. package/src/components/EntityCollectionView/CollectionDataErrorBanner.tsx +43 -0
  90. package/src/components/EntityCollectionView/EntityBoardCard.tsx +1 -1
  91. package/src/components/EntityCollectionView/EntityCard.tsx +4 -0
  92. package/src/components/EntityCollectionView/EntityCollectionBoardView.tsx +39 -46
  93. package/src/components/EntityCollectionView/EntityCollectionCardView.tsx +17 -25
  94. package/src/components/EntityCollectionView/EntityCollectionView.tsx +73 -31
  95. package/src/components/EntityCollectionView/EntityCollectionViewActions.tsx +4 -3
  96. package/src/components/EntityCollectionView/EntityCollectionViewStartActions.tsx +4 -2
  97. package/src/components/EntityCollectionView/FiltersDialog.tsx +8 -5
  98. package/src/components/EntityCollectionView/ViewModeToggle.tsx +37 -37
  99. package/src/components/EntityView.tsx +3 -2
  100. package/src/components/ErrorBoundary.tsx +27 -15
  101. package/src/components/HomePage/DefaultHomePage.tsx +19 -13
  102. package/src/components/HomePage/HomePageDnD.tsx +3 -1
  103. package/src/components/HomePage/NavigationGroup.tsx +3 -1
  104. package/src/components/HomePage/RenameGroupDialog.tsx +15 -13
  105. package/src/components/LanguageToggle.tsx +66 -0
  106. package/src/components/NotFoundPage.tsx +5 -3
  107. package/src/components/ReferenceTable/ReferenceSelectionTable.tsx +9 -7
  108. package/src/components/ReferenceWidget.tsx +3 -2
  109. package/src/components/SearchIconsView.tsx +3 -1
  110. package/src/components/SelectableTable/filters/DateTimeFilterField.tsx +11 -0
  111. package/src/components/SelectableTable/filters/ReferenceFilterField.tsx +15 -2
  112. package/src/components/SelectableTable/filters/StringNumberFilterField.tsx +11 -0
  113. package/src/components/UnsavedChangesDialog.tsx +6 -4
  114. package/src/components/VirtualTable/VirtualTable.performance.test.tsx +1 -0
  115. package/src/components/VirtualTable/VirtualTable.tsx +116 -113
  116. package/src/components/VirtualTable/VirtualTableHeader.tsx +54 -52
  117. package/src/components/VirtualTable/VirtualTableHeaderRow.tsx +1 -1
  118. package/src/components/VirtualTable/fields/VirtualTableSelect.tsx +3 -3
  119. package/src/components/common/default_entity_actions.tsx +4 -0
  120. package/src/components/common/useDataSourceTableController.tsx +12 -4
  121. package/src/components/index.tsx +1 -0
  122. package/src/core/DefaultAppBar.tsx +15 -11
  123. package/src/core/DefaultDrawer.tsx +8 -2
  124. package/src/core/DrawerNavigationGroup.tsx +5 -3
  125. package/src/core/EntityEditView.tsx +4 -3
  126. package/src/core/EntityEditViewFormActions.tsx +24 -17
  127. package/src/core/EntitySidePanel.tsx +32 -29
  128. package/src/core/FireCMS.tsx +33 -6
  129. package/src/core/field_configs.tsx +14 -9
  130. package/src/editor/components/SlashCommandMenu.tsx +348 -0
  131. package/src/editor/components/editor-bubble-item.tsx +32 -0
  132. package/src/editor/components/editor-bubble.tsx +118 -0
  133. package/src/editor/components/index.ts +12 -0
  134. package/src/editor/editor.tsx +307 -0
  135. package/src/editor/extensions/HighlightDecorationExtension.ts +114 -0
  136. package/src/editor/extensions/Image/index.ts +133 -0
  137. package/src/editor/extensions/Image.ts +144 -0
  138. package/src/editor/extensions/TextLoadingDecorationExtension.tsx +107 -0
  139. package/src/editor/extensions/clipboard.ts +72 -0
  140. package/src/editor/extensions/custom-keymap.ts +24 -0
  141. package/src/editor/extensions/drag-and-drop.tsx +472 -0
  142. package/src/editor/hooks/useProseMirror.ts +115 -0
  143. package/src/editor/hooks/useProseMirrorContext.ts +15 -0
  144. package/src/editor/index.ts +2 -0
  145. package/src/editor/markdown.ts +110 -0
  146. package/src/editor/nodeViews/ImageComponent.tsx +20 -0
  147. package/src/editor/nodeViews/ReactNodeView.tsx +89 -0
  148. package/src/editor/nodeViews/TaskItemComponent.tsx +29 -0
  149. package/src/editor/nodeViews/index.ts +35 -0
  150. package/src/editor/plugins/index.ts +55 -0
  151. package/src/editor/plugins/inputrules.ts +82 -0
  152. package/src/editor/plugins/placeholderPlugin.ts +55 -0
  153. package/src/editor/plugins/slashCommandPlugin.ts +49 -0
  154. package/src/editor/schema.ts +228 -0
  155. package/src/editor/selectors/ai-selector.tsx +111 -0
  156. package/src/editor/selectors/color-selector.tsx +200 -0
  157. package/src/editor/selectors/link-selector.tsx +118 -0
  158. package/src/editor/selectors/node-selector.tsx +157 -0
  159. package/src/editor/selectors/text-buttons.tsx +86 -0
  160. package/src/editor/types.ts +6 -0
  161. package/src/editor/useProseMirror.ts +126 -0
  162. package/src/editor/utils/prosemirror-utils.ts +78 -0
  163. package/src/editor/utils/remove_classes.ts +17 -0
  164. package/src/editor/utils/useDebouncedCallback.ts +25 -0
  165. package/src/form/EntityForm.tsx +76 -63
  166. package/src/form/EntityFormActions.tsx +19 -12
  167. package/src/form/PropertyFieldBinding.tsx +6 -5
  168. package/src/form/components/ErrorFocus.tsx +3 -3
  169. package/src/form/components/LocalChangesMenu.tsx +13 -13
  170. package/src/form/components/StorageItemPreview.tsx +3 -2
  171. package/src/form/field_bindings/ArrayOfReferencesFieldBinding.tsx +4 -4
  172. package/src/form/field_bindings/BlockFieldBinding.tsx +5 -2
  173. package/src/form/field_bindings/KeyValueFieldBinding.tsx +23 -18
  174. package/src/form/field_bindings/MapFieldBinding.tsx +4 -3
  175. package/src/form/field_bindings/MarkdownEditorFieldBinding.tsx +4 -4
  176. package/src/form/field_bindings/RepeatFieldBinding.tsx +3 -1
  177. package/src/form/field_bindings/StorageUploadFieldBinding.tsx +87 -85
  178. package/src/hooks/index.tsx +1 -0
  179. package/src/hooks/useBuildNavigationController.tsx +49 -22
  180. package/src/hooks/useCollapsedGroups.ts +7 -6
  181. package/src/hooks/useTranslation.ts +31 -0
  182. package/src/hooks/useValidateAuthenticator.tsx +1 -1
  183. package/src/i18n/FireCMSi18nProvider.tsx +160 -0
  184. package/src/index.ts +4 -0
  185. package/src/internal/useBuildDataSource.ts +1 -2
  186. package/src/internal/useBuildSideEntityController.tsx +22 -20
  187. package/src/locales/de.ts +691 -0
  188. package/src/locales/en.ts +703 -0
  189. package/src/locales/es.ts +703 -0
  190. package/src/locales/fr.ts +691 -0
  191. package/src/locales/hi.ts +691 -0
  192. package/src/locales/it.ts +691 -0
  193. package/src/locales/pt.ts +700 -0
  194. package/src/preview/PropertyPreview.tsx +1 -0
  195. package/src/preview/components/UrlComponentPreview.tsx +4 -2
  196. package/src/preview/components/UserPreview.tsx +3 -1
  197. package/src/types/analytics.ts +10 -0
  198. package/src/types/collections.ts +9 -0
  199. package/src/types/customization_controller.tsx +2 -1
  200. package/src/types/firecms.tsx +2 -1
  201. package/src/types/index.ts +1 -0
  202. package/src/types/navigation.ts +2 -2
  203. package/src/types/plugins.tsx +26 -0
  204. package/src/types/translations.ts +725 -0
  205. package/src/util/entities.ts +1 -1
  206. package/src/util/join_collections.ts +10 -8
  207. package/src/util/previews.ts +2 -2
  208. package/src/util/property_utils.tsx +1 -1
  209. package/src/util/resolutions.ts +5 -3
@@ -22,6 +22,7 @@ import {
22
22
  import { getDefaultValueForDataType, getIconForProperty } from "../../util";
23
23
  import { useCustomizationController } from "../../hooks";
24
24
  import { getIn } from "@firecms/formex";
25
+ import { useTranslation } from "../../hooks/useTranslation";
25
26
 
26
27
  type MapEditViewRowState = [number, {
27
28
  key: string,
@@ -54,6 +55,7 @@ export function KeyValueFieldBinding({
54
55
  throw Error(`Your property ${propertyKey} needs to have the 'keyValue' prop in order to use this field binding`);
55
56
  }
56
57
 
58
+ const { t } = useTranslation();
57
59
  const initialValues = getIn(context.formex.initialValues, propertyKey);
58
60
 
59
61
  const mapFormView = <MapEditView value={value}
@@ -103,6 +105,7 @@ function MapEditView<T extends Record<string, any>>({
103
105
  fieldName,
104
106
  disabled
105
107
  }: MapEditViewParams<T>) {
108
+ const { t } = useTranslation();
106
109
  const [internalState, setInternalState] = React.useState<MapEditViewRowState[]>(
107
110
  Object.keys(initialValue ?? {}).map((key) => [getRandomId(), {
108
111
  key,
@@ -230,7 +233,7 @@ function MapEditView<T extends Record<string, any>>({
230
233
  }]]);
231
234
  }
232
235
  }>
233
- {fieldName ? `Add to ${fieldName}` : "Add"}
236
+ {fieldName ? t("add_to_field", { fieldName }) : t("add_entry")}
234
237
  </Button>
235
238
 
236
239
  </div>;
@@ -261,12 +264,13 @@ function MapKeyValueRow<T extends Record<string, any>>({
261
264
  }) {
262
265
 
263
266
  const { locale } = useCustomizationController();
267
+ const { t } = useTranslation();
264
268
 
265
269
  function buildInput(entryValue: any, fieldKey: string, dataType: DataType) {
266
270
  if (dataType === "string" || dataType === "number") {
267
271
  return <TextField
268
272
  key={dataType}
269
- placeholder={"value"}
273
+ placeholder={t("value")}
270
274
  value={entryValue}
271
275
  type={dataType === "number" ? "number" : "text"}
272
276
  size={"medium"}
@@ -325,7 +329,7 @@ function MapKeyValueRow<T extends Record<string, any>>({
325
329
  <ArrayContainer value={entryValue}
326
330
  newDefaultEntry={""}
327
331
  droppableId={rowId.toString()}
328
- addLabel={fieldKey ? `Add to ${fieldKey}` : "Add"}
332
+ addLabel={fieldKey ? t("add_to_field", { fieldName: fieldKey }) : t("add_entry")}
329
333
  size={"small"}
330
334
  disabled={disabled || !fieldKey}
331
335
  canAddElements={true}
@@ -370,7 +374,7 @@ function MapKeyValueRow<T extends Record<string, any>>({
370
374
  } else {
371
375
  return <Typography
372
376
  variant={"caption"}>
373
- {`Data type ${dataType} not supported yet`}
377
+ {t("data_type_not_supported", { dataType })}
374
378
  </Typography>;
375
379
  }
376
380
  }
@@ -386,7 +390,7 @@ function MapKeyValueRow<T extends Record<string, any>>({
386
390
  <div className="w-[300px] max-w-[30%]">
387
391
  <TextField
388
392
  value={fieldKey}
389
- placeholder={"key"}
393
+ placeholder={t("key")}
390
394
  disabled={disabled || (entryValue !== undefined && entryValue !== null && entryValue !== "")}
391
395
  size={"medium"}
392
396
  onChange={(event) => {
@@ -404,17 +408,17 @@ function MapKeyValueRow<T extends Record<string, any>>({
404
408
  </IconButton>}
405
409
  >
406
410
  <MenuItem dense
407
- onClick={() => doUpdateDataType("string")}>string</MenuItem>
411
+ onClick={() => doUpdateDataType("string")}>{t("string")}</MenuItem>
408
412
  <MenuItem dense
409
- onClick={() => doUpdateDataType("number")}>number</MenuItem>
413
+ onClick={() => doUpdateDataType("number")}>{t("number")}</MenuItem>
410
414
  <MenuItem dense
411
- onClick={() => doUpdateDataType("boolean")}>boolean</MenuItem>
415
+ onClick={() => doUpdateDataType("boolean")}>{t("boolean")}</MenuItem>
412
416
  <MenuItem dense
413
- onClick={() => doUpdateDataType("date")}>date</MenuItem>
417
+ onClick={() => doUpdateDataType("date")}>{t("date")}</MenuItem>
414
418
  <MenuItem dense
415
- onClick={() => doUpdateDataType("map")}>map</MenuItem>
419
+ onClick={() => doUpdateDataType("map")}>{t("map")}</MenuItem>
416
420
  <MenuItem dense
417
- onClick={() => doUpdateDataType("array")}>array</MenuItem>
421
+ onClick={() => doUpdateDataType("array")}>{t("array")}</MenuItem>
418
422
  </Menu>
419
423
 
420
424
  <IconButton aria-label="delete"
@@ -446,6 +450,7 @@ function ArrayKeyValueRow<T>({
446
450
  }) {
447
451
 
448
452
  const { locale } = useCustomizationController();
453
+ const { t } = useTranslation();
449
454
  const [selectedDataType, setSelectedDataType] = useState<DataType>(getDataType(value) ?? "string");
450
455
 
451
456
  function doUpdateDataType(dataType: DataType) {
@@ -487,7 +492,7 @@ function ArrayKeyValueRow<T>({
487
492
  }}/>;
488
493
  } else if (dataType === "array") {
489
494
  return <Typography variant={"caption"}>
490
- Arrays of arrays are not supported.
495
+ {t("arrays_of_arrays_not_supported")}
491
496
  </Typography>;
492
497
  } else if (dataType === "map") {
493
498
  return <div className={cls(defaultBorderMixin, "ml-2 pl-2 border-l border-solid")}>
@@ -499,7 +504,7 @@ function ArrayKeyValueRow<T>({
499
504
  } else {
500
505
  return <Typography
501
506
  variant={"caption"}>
502
- {`Data type ${dataType} not supported yet`}
507
+ {t("data_type_not_supported", { dataType })}
503
508
  </Typography>;
504
509
  }
505
510
  }
@@ -519,15 +524,15 @@ function ArrayKeyValueRow<T>({
519
524
  <ArrowDropDownIcon/>
520
525
  </IconButton>}>
521
526
  <MenuItem dense
522
- onClick={() => doUpdateDataType("string")}>string</MenuItem>
527
+ onClick={() => doUpdateDataType("string")}>{t("string")}</MenuItem>
523
528
  <MenuItem dense
524
- onClick={() => doUpdateDataType("number")}>number</MenuItem>
529
+ onClick={() => doUpdateDataType("number")}>{t("number")}</MenuItem>
525
530
  <MenuItem dense
526
- onClick={() => doUpdateDataType("boolean")}>boolean</MenuItem>
531
+ onClick={() => doUpdateDataType("boolean")}>{t("boolean")}</MenuItem>
527
532
  <MenuItem dense
528
- onClick={() => doUpdateDataType("map")}>map</MenuItem>
533
+ onClick={() => doUpdateDataType("map")}>{t("map")}</MenuItem>
529
534
  <MenuItem dense
530
- onClick={() => doUpdateDataType("date")}>date</MenuItem>
535
+ onClick={() => doUpdateDataType("date")}>{t("date")}</MenuItem>
531
536
  </Menu>
532
537
 
533
538
  </Typography>
@@ -7,6 +7,7 @@ import { FieldHelperText, LabelWithIconAndTooltip } from "../components";
7
7
  import { FormEntry } from "../components/FormEntry";
8
8
  import { PropertyFieldBinding } from "../PropertyFieldBinding";
9
9
  import { cls, ExpandablePanel, InputLabel, Select, SelectItem } from "@firecms/ui";
10
+ import { useTranslation } from "../../hooks";
10
11
 
11
12
  /**
12
13
  * Field that renders the children property fields
@@ -91,7 +92,7 @@ export function MapFieldBinding({
91
92
  }
92
93
  </div>
93
94
 
94
- {/*{pickOnlySomeKeys && buildPickKeysSelect(disabled, property.properties, setValue, value)}*/}
95
+ {/*{pickOnlySomeKeys && buildPickKeysSelect(disabled, property.properties, setValue, value, t)}*/}
95
96
 
96
97
  </>
97
98
  ;
@@ -128,7 +129,7 @@ export function MapFieldBinding({
128
129
  );
129
130
  }
130
131
 
131
- const buildPickKeysSelect = (disabled: boolean, properties: Properties, setValue: (value: any) => void, value: any) => {
132
+ const buildPickKeysSelect = (disabled: boolean, properties: Properties, setValue: (value: any) => void, value: any, t: any) => {
132
133
 
133
134
  const keys = Object.keys(properties)
134
135
  .filter((key) => !value || !(key in value));
@@ -143,7 +144,7 @@ const buildPickKeysSelect = (disabled: boolean, properties: Properties, setValue
143
144
  if (!keys.length) return <></>;
144
145
 
145
146
  return <div className={"m-4"}>
146
- <InputLabel>Add property</InputLabel>
147
+ <InputLabel>{t("add_property")}</InputLabel>
147
148
  <Select
148
149
  value={""}
149
150
  size={"large"}
@@ -12,7 +12,7 @@ import {
12
12
  useStorageSource
13
13
  } from "../../index";
14
14
  import { cls, fieldBackgroundDisabledMixin, fieldBackgroundHoverMixin, fieldBackgroundMixin } from "@firecms/ui";
15
- import { FireCMSEditor, FireCMSEditorProps } from "@firecms/editor";
15
+ import { FireCMSEditor, FireCMSEditorProps } from "../../editor";
16
16
  import { resolveProperty, resolveStorageFilenameString, resolveStoragePathString } from "../../util";
17
17
 
18
18
  interface MarkdownEditorFieldProps {
@@ -55,17 +55,17 @@ export function MarkdownEditorFieldBinding({
55
55
  }
56
56
  internalValue.current = content;
57
57
  setValue(content);
58
- }, [setValue]);
58
+ }, [setValue, value]);
59
59
 
60
60
  useEffect(() => {
61
61
  if (internalValue.current !== value) {
62
62
  internalValue.current = value;
63
- setFieldVersion(fieldVersion + 1);
63
+ setFieldVersion(v => v + 1);
64
64
  }
65
65
  }, [value]);
66
66
 
67
67
  const resolvedProperty = resolveProperty({
68
- propertyOrBuilder: property as PropertyOrBuilder,
68
+ propertyOrBuilder: property as PropertyOrBuilder<string>,
69
69
  values: entityValues,
70
70
  authController
71
71
  }) as ResolvedStringProperty | ResolvedArrayProperty<string[]>;
@@ -7,6 +7,7 @@ import { PropertyFieldBinding } from "../PropertyFieldBinding";
7
7
  import { ExpandablePanel, Typography } from "@firecms/ui";
8
8
  import { useClearRestoreValue } from "../useClearRestoreValue";
9
9
  import { useAuthController } from "../../hooks";
10
+ import { useTranslation } from "../../hooks/useTranslation";
10
11
 
11
12
  /**
12
13
  * Generic array field that allows reordering and renders the child property
@@ -34,6 +35,7 @@ export function RepeatFieldBinding<T extends Array<any>>({
34
35
 
35
36
  const authController = useAuthController();
36
37
  const minimalistView = minimalistViewProp || property.minimalistView;
38
+ const { t } = useTranslation();
37
39
 
38
40
  if (!property.of)
39
41
  throw Error("RepeatFieldBinding misconfiguration. Property `of` not set");
@@ -87,7 +89,7 @@ export function RepeatFieldBinding<T extends Array<any>>({
87
89
  const canAddElements = !property.disabled && !isSubmitting && !disabled && (property.canAddElements || property.canAddElements === undefined);
88
90
  const sortable = property.sortable === undefined ? true : property.sortable;
89
91
  const arrayContainer = <ArrayContainer droppableId={propertyKey}
90
- addLabel={property.name ? "Add entry to " + property.name : "Add entry"}
92
+ addLabel={property.name ? t("add_to_field", { fieldName: property.name }) : t("add_entry")}
91
93
  value={value}
92
94
  buildEntry={buildEntry}
93
95
  onInternalIdAdded={setLastAddedId}
@@ -41,6 +41,7 @@ import {
41
41
  Typography
42
42
  } from "@firecms/ui";
43
43
  import { useClearRestoreValue } from "../useClearRestoreValue";
44
+ import { useTranslation } from "../../hooks/useTranslation";
44
45
 
45
46
  const dropZoneClasses = "box-border relative pt-[2px] items-center border border-transparent min-h-[254px] outline-none rounded-md duration-200 ease-[cubic-bezier(0.4,0,0.2,1)] focus:border-primary-solid";
46
47
  const disabledClasses = fieldBackgroundDisabledMixin;
@@ -52,18 +53,18 @@ const rejectDropClasses = "transition-colors duration-200 ease-[cubic-bezier(0,0
52
53
  type StorageUploadFieldProps = FieldProps<string | string[]>;
53
54
 
54
55
  export function StorageUploadFieldBinding({
55
- propertyKey,
56
- value,
57
- setValue,
58
- error,
59
- showError,
60
- autoFocus,
61
- minimalistView,
62
- property,
63
- includeDescription,
64
- context,
65
- isSubmitting,
66
- }: StorageUploadFieldProps) {
56
+ propertyKey,
57
+ value,
58
+ setValue,
59
+ error,
60
+ showError,
61
+ autoFocus,
62
+ minimalistView,
63
+ property,
64
+ includeDescription,
65
+ context,
66
+ isSubmitting,
67
+ }: StorageUploadFieldProps) {
67
68
 
68
69
  const authController = useAuthController();
69
70
 
@@ -100,7 +101,7 @@ export function StorageUploadFieldBinding({
100
101
  });
101
102
 
102
103
  const resolvedProperty = resolveProperty({
103
- propertyOrBuilder: property as PropertyOrBuilder,
104
+ propertyOrBuilder: property as PropertyOrBuilder<string>,
104
105
  authController
105
106
  }) as ResolvedStringProperty | ResolvedArrayProperty<string[]>;
106
107
 
@@ -114,7 +115,7 @@ export function StorageUploadFieldBinding({
114
115
  icon={getIconForProperty(property, "small")}
115
116
  required={property.validation?.required}
116
117
  title={property.name}
117
- className={"h-8 text-text-secondary dark:text-text-secondary-dark ml-3.5"}/>}
118
+ className={"h-8 text-text-secondary dark:text-text-secondary-dark ml-3.5"} />}
118
119
 
119
120
  <StorageUpload
120
121
  value={internalValue}
@@ -128,13 +129,13 @@ export function StorageUploadFieldBinding({
128
129
  onFileUploadComplete={onFileUploadComplete}
129
130
  storagePathBuilder={storagePathBuilder}
130
131
  storage={storage}
131
- multipleFilesSupported={multipleFilesSupported}/>
132
+ multipleFilesSupported={multipleFilesSupported} />
132
133
 
133
134
  <FieldHelperText includeDescription={includeDescription}
134
- showError={showError}
135
- error={error}
136
- disabled={disabled}
137
- property={property}/>
135
+ showError={showError}
136
+ error={error}
137
+ disabled={disabled}
138
+ property={property} />
138
139
 
139
140
  </>
140
141
  );
@@ -154,15 +155,15 @@ interface SortableStorageItemProps {
154
155
  }
155
156
 
156
157
  function SortableStorageItem({
157
- id,
158
- entry,
159
- property,
160
- metadata,
161
- storagePathBuilder,
162
- onFileUploadComplete,
163
- onClear,
164
- disabled,
165
- }: SortableStorageItemProps) {
158
+ id,
159
+ entry,
160
+ property,
161
+ metadata,
162
+ storagePathBuilder,
163
+ onFileUploadComplete,
164
+ onClear,
165
+ disabled,
166
+ }: SortableStorageItemProps) {
166
167
 
167
168
  const {
168
169
  attributes,
@@ -201,7 +202,7 @@ function SortableStorageItem({
201
202
  disabled={disabled}
202
203
  value={entry.storagePathOrDownloadUrl}
203
204
  onRemove={() => onClear(entry.storagePathOrDownloadUrl!)}
204
- size={entry.size}/>
205
+ size={entry.size} />
205
206
  );
206
207
  } else if (entry.file) {
207
208
  child = (
@@ -231,21 +232,21 @@ function SortableStorageItem({
231
232
  }
232
233
 
233
234
  function FileDropComponent({
234
- storage,
235
- disabled,
236
- onFilesAdded,
237
- multipleFilesSupported,
238
- autoFocus,
239
- internalValue,
240
- property,
241
- onClear,
242
- metadata,
243
- storagePathBuilder,
244
- onFileUploadComplete,
245
- name,
246
- helpText,
247
- isDndItemDragging
248
- }: {
235
+ storage,
236
+ disabled,
237
+ onFilesAdded,
238
+ multipleFilesSupported,
239
+ autoFocus,
240
+ internalValue,
241
+ property,
242
+ onClear,
243
+ metadata,
244
+ storagePathBuilder,
245
+ onFileUploadComplete,
246
+ name,
247
+ helpText,
248
+ isDndItemDragging
249
+ }: {
249
250
  storage: StorageConfig,
250
251
  disabled: boolean,
251
252
  onFilesAdded: (acceptedFiles: File[]) => Promise<void>,
@@ -271,33 +272,33 @@ function FileDropComponent({
271
272
  isDragAccept,
272
273
  isDragReject
273
274
  } = useDropzone({
274
- accept: storage.acceptedFiles ? storage.acceptedFiles.reduce((acc, ext) => ({
275
- ...acc,
276
- [ext]: []
277
- }), {}) : undefined,
278
- disabled: disabled || isDndItemDragging,
279
- noDragEventsBubbling: true,
280
- maxSize: storage.maxSize,
281
- onDrop: onFilesAdded,
282
- onDropRejected: (fileRejections) => {
283
- for (const fileRejection of fileRejections) {
284
- for (const error of fileRejection.errors) {
285
- console.error("Error uploading file: ", error);
286
- if (error.code === "file-too-large") {
287
- snackbarContext.open({
288
- type: "error",
289
- message: `Error uploading file: File is larger than ${storage.maxSize} bytes`
290
- });
291
- } else if (error.code === "file-invalid-type") {
292
- snackbarContext.open({
293
- type: "error",
294
- message: "Error uploading file: File type is not supported"
295
- });
296
- }
275
+ accept: storage.acceptedFiles ? storage.acceptedFiles.reduce((acc, ext) => ({
276
+ ...acc,
277
+ [ext]: []
278
+ }), {}) : undefined,
279
+ disabled: disabled || isDndItemDragging,
280
+ noDragEventsBubbling: true,
281
+ maxSize: storage.maxSize,
282
+ onDrop: onFilesAdded,
283
+ onDropRejected: (fileRejections) => {
284
+ for (const fileRejection of fileRejections) {
285
+ for (const error of fileRejection.errors) {
286
+ console.error("Error uploading file: ", error);
287
+ if (error.code === "file-too-large") {
288
+ snackbarContext.open({
289
+ type: "error",
290
+ message: `Error uploading file: File is larger than ${storage.maxSize} bytes`
291
+ });
292
+ } else if (error.code === "file-invalid-type") {
293
+ snackbarContext.open({
294
+ type: "error",
295
+ message: "Error uploading file: File type is not supported"
296
+ });
297
297
  }
298
298
  }
299
299
  }
300
300
  }
301
+ }
301
302
  );
302
303
 
303
304
  return (
@@ -349,8 +350,8 @@ function FileDropComponent({
349
350
  <div
350
351
  className="flex-grow min-h-[38px] box-border m-2 text-center">
351
352
  <Typography align={"center"}
352
- variant={"label"}
353
- className={disabled ? "text-surface-accent-600 dark:text-surface-accent-500" : ""}>
353
+ variant={"label"}
354
+ className={disabled ? "text-surface-accent-600 dark:text-surface-accent-500" : ""}>
354
355
  {helpText}
355
356
  </Typography>
356
357
  </div>
@@ -374,19 +375,20 @@ export interface StorageUploadProps {
374
375
  }
375
376
 
376
377
  export function StorageUpload({
377
- property,
378
- name,
379
- value, // This is internalValue from useStorageUploadController
380
- setInternalValue,
381
- onChange,
382
- multipleFilesSupported,
383
- onFileUploadComplete,
384
- disabled,
385
- onFilesAdded,
386
- autoFocus,
387
- storage,
388
- storagePathBuilder,
389
- }: StorageUploadProps) {
378
+ property,
379
+ name,
380
+ value, // This is internalValue from useStorageUploadController
381
+ setInternalValue,
382
+ onChange,
383
+ multipleFilesSupported,
384
+ onFileUploadComplete,
385
+ disabled,
386
+ onFilesAdded,
387
+ autoFocus,
388
+ storage,
389
+ storagePathBuilder,
390
+ }: StorageUploadProps) {
391
+ const { t } = useTranslation();
390
392
 
391
393
  if (multipleFilesSupported) {
392
394
  const arrayProperty = property as ResolvedArrayProperty<string[]>;
@@ -461,8 +463,8 @@ export function StorageUpload({
461
463
  }, [value, multipleFilesSupported, onChange, setInternalValue]);
462
464
 
463
465
  const helpText = multipleFilesSupported
464
- ? "Drag 'n' drop some files here, or click to select files. Drag to reorder."
465
- : "Drag 'n' drop a file here, or click to select one";
466
+ ? t("drag_drop_multiple")
467
+ : t("drag_drop_single");
466
468
 
467
469
  const renderProperty: ResolvedStringProperty = multipleFilesSupported
468
470
  ? (property as ResolvedArrayProperty<string[]>).of as ResolvedStringProperty
@@ -500,6 +502,6 @@ export function StorageUpload({
500
502
  );
501
503
  } else {
502
504
  // For single file, no D&D context is needed
503
- return <FileDropComponent {...fileDropProps} isDndItemDragging={false}/>;
505
+ return <FileDropComponent {...fileDropProps} isDndItemDragging={false} />;
504
506
  }
505
507
  }
@@ -31,3 +31,4 @@ export * from "./useBuildLocalConfigurationPersistence";
31
31
  export * from "./useBuildModeController";
32
32
 
33
33
  export * from "./useValidateAuthenticator";
34
+ export * from "./useTranslation";