@firecms/core 3.1.0-canary.1df3b2c → 3.1.0-canary.501d471

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 (246) 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 +2 -1
  9. package/dist/components/VirtualTable/VirtualTableHeaderRow.d.ts +1 -1
  10. package/dist/components/VirtualTable/VirtualTableProps.d.ts +6 -1
  11. package/dist/components/VirtualTable/types.d.ts +1 -0
  12. package/dist/components/index.d.ts +1 -0
  13. package/dist/core/DrawerNavigationGroup.d.ts +2 -2
  14. package/dist/editor/components/SlashCommandMenu.d.ts +6 -0
  15. package/dist/editor/components/editor-bubble-item.d.ts +8 -0
  16. package/dist/editor/components/editor-bubble.d.ts +8 -0
  17. package/dist/editor/components/image-bubble.d.ts +5 -0
  18. package/dist/editor/components/index.d.ts +16 -0
  19. package/dist/editor/components/table-bubble.d.ts +5 -0
  20. package/dist/editor/editor.d.ts +30 -0
  21. package/dist/editor/extensions/HighlightDecorationExtension.d.ts +24 -0
  22. package/dist/editor/extensions/Image/index.d.ts +6 -0
  23. package/dist/editor/extensions/Image.d.ts +6 -0
  24. package/dist/editor/extensions/TextLoadingDecorationExtension.d.ts +16 -0
  25. package/dist/editor/extensions/clipboard.d.ts +7 -0
  26. package/dist/editor/extensions/custom-keymap.d.ts +1 -0
  27. package/dist/editor/extensions/drag-and-drop.d.ts +9 -0
  28. package/dist/editor/hooks/useProseMirror.d.ts +13 -0
  29. package/dist/editor/hooks/useProseMirrorContext.d.ts +9 -0
  30. package/dist/editor/index.d.ts +2 -0
  31. package/dist/editor/markdown.d.ts +5 -0
  32. package/dist/editor/nodeViews/ImageComponent.d.ts +3 -0
  33. package/dist/editor/nodeViews/ReactNodeView.d.ts +29 -0
  34. package/dist/editor/nodeViews/TaskItemComponent.d.ts +3 -0
  35. package/dist/editor/nodeViews/index.d.ts +6 -0
  36. package/dist/editor/plugins/index.d.ts +2 -0
  37. package/dist/editor/plugins/inputrules.d.ts +6 -0
  38. package/dist/editor/plugins/placeholderPlugin.d.ts +3 -0
  39. package/dist/editor/plugins/slashCommandPlugin.d.ts +12 -0
  40. package/dist/editor/schema.d.ts +2 -0
  41. package/dist/editor/selectors/ai-selector.d.ts +0 -0
  42. package/dist/editor/selectors/color-selector.d.ts +10 -0
  43. package/dist/editor/selectors/link-selector.d.ts +8 -0
  44. package/dist/editor/selectors/node-selector.d.ts +15 -0
  45. package/dist/editor/selectors/text-buttons.d.ts +1 -0
  46. package/dist/editor/types.d.ts +5 -0
  47. package/dist/editor/useProseMirror.d.ts +16 -0
  48. package/dist/editor/utils/prosemirror-utils.d.ts +6 -0
  49. package/dist/editor/utils/remove_classes.d.ts +1 -0
  50. package/dist/editor/utils/useDebouncedCallback.d.ts +1 -0
  51. package/dist/form/components/ErrorFocus.d.ts +1 -1
  52. package/dist/form/field_bindings/MapFieldBinding.d.ts +1 -1
  53. package/dist/form/field_bindings/MarkdownEditorFieldBinding.d.ts +1 -1
  54. package/dist/hooks/index.d.ts +1 -0
  55. package/dist/hooks/useBuildNavigationController.d.ts +0 -1
  56. package/dist/hooks/useCollapsedGroups.d.ts +3 -3
  57. package/dist/hooks/useTranslation.d.ts +17 -0
  58. package/dist/i18n/FireCMSi18nProvider.d.ts +33 -0
  59. package/dist/index.d.ts +5 -0
  60. package/dist/index.es.js +29682 -18363
  61. package/dist/index.es.js.map +1 -1
  62. package/dist/index.umd.js +29681 -18382
  63. package/dist/index.umd.js.map +1 -1
  64. package/dist/internal/useRestoreScroll.d.ts +1 -1
  65. package/dist/locales/de.d.ts +2 -0
  66. package/dist/locales/en.d.ts +10 -0
  67. package/dist/locales/es.d.ts +10 -0
  68. package/dist/locales/fr.d.ts +2 -0
  69. package/dist/locales/hi.d.ts +2 -0
  70. package/dist/locales/it.d.ts +2 -0
  71. package/dist/locales/pt.d.ts +7 -0
  72. package/dist/types/analytics.d.ts +1 -1
  73. package/dist/types/collections.d.ts +46 -0
  74. package/dist/types/customization_controller.d.ts +2 -1
  75. package/dist/types/firecms.d.ts +2 -1
  76. package/dist/types/index.d.ts +1 -0
  77. package/dist/types/navigation.d.ts +2 -2
  78. package/dist/types/plugins.d.ts +23 -0
  79. package/dist/types/properties.d.ts +9 -8
  80. package/dist/types/storage.d.ts +1 -0
  81. package/dist/types/translations.d.ts +669 -0
  82. package/dist/util/entities.d.ts +1 -1
  83. package/dist/util/index.d.ts +1 -0
  84. package/dist/util/lazy_eager.d.ts +7 -0
  85. package/dist/util/objects.d.ts +1 -0
  86. package/dist/util/resolutions.d.ts +2 -2
  87. package/dist/util/useStorageUploadController.d.ts +10 -1
  88. package/package.json +49 -13
  89. package/src/app/Scaffold.tsx +7 -5
  90. package/src/components/AIIcon.tsx +3 -1
  91. package/src/components/ArrayContainer.tsx +6 -4
  92. package/src/components/ClearFilterSortButton.tsx +6 -3
  93. package/src/components/ConfirmationDialog.tsx +4 -2
  94. package/src/components/DeleteEntityDialog.tsx +10 -7
  95. package/src/components/EntityCollectionTable/EntityCollectionRowActions.tsx +9 -3
  96. package/src/components/EntityCollectionTable/fields/TableReferenceField.tsx +6 -3
  97. package/src/components/EntityCollectionTable/internal/CollectionTableToolbar.tsx +3 -1
  98. package/src/components/EntityCollectionTable/internal/EntityTableCellActions.tsx +1 -1
  99. package/src/components/EntityCollectionTable/internal/popup_field/PopupFormField.tsx +3 -2
  100. package/src/components/EntityCollectionTable/internal/popup_field/useDraggable.tsx +11 -11
  101. package/src/components/EntityCollectionView/BoardSortableList.tsx +3 -1
  102. package/src/components/EntityCollectionView/CollectionDataErrorBanner.tsx +43 -0
  103. package/src/components/EntityCollectionView/EntityBoardCard.tsx +1 -1
  104. package/src/components/EntityCollectionView/EntityCard.tsx +4 -0
  105. package/src/components/EntityCollectionView/EntityCollectionBoardView.tsx +39 -46
  106. package/src/components/EntityCollectionView/EntityCollectionCardView.tsx +17 -25
  107. package/src/components/EntityCollectionView/EntityCollectionView.tsx +71 -31
  108. package/src/components/EntityCollectionView/EntityCollectionViewActions.tsx +4 -3
  109. package/src/components/EntityCollectionView/EntityCollectionViewStartActions.tsx +4 -2
  110. package/src/components/EntityCollectionView/FiltersDialog.tsx +8 -5
  111. package/src/components/EntityCollectionView/ViewModeToggle.tsx +37 -37
  112. package/src/components/EntityJsonPreview.tsx +2 -1
  113. package/src/components/EntityView.tsx +3 -2
  114. package/src/components/ErrorBoundary.tsx +27 -15
  115. package/src/components/HomePage/DefaultHomePage.tsx +19 -13
  116. package/src/components/HomePage/HomePageDnD.tsx +3 -1
  117. package/src/components/HomePage/NavigationGroup.tsx +3 -1
  118. package/src/components/HomePage/RenameGroupDialog.tsx +15 -13
  119. package/src/components/LanguageToggle.tsx +66 -0
  120. package/src/components/NotFoundPage.tsx +5 -3
  121. package/src/components/ReferenceTable/ReferenceSelectionTable.tsx +9 -7
  122. package/src/components/ReferenceWidget.tsx +3 -2
  123. package/src/components/SearchIconsView.tsx +3 -1
  124. package/src/components/SelectableTable/filters/DateTimeFilterField.tsx +11 -0
  125. package/src/components/SelectableTable/filters/ReferenceFilterField.tsx +15 -2
  126. package/src/components/SelectableTable/filters/StringNumberFilterField.tsx +11 -0
  127. package/src/components/UnsavedChangesDialog.tsx +6 -4
  128. package/src/components/VirtualTable/VirtualTable.performance.test.tsx +1 -0
  129. package/src/components/VirtualTable/VirtualTable.tsx +121 -116
  130. package/src/components/VirtualTable/VirtualTableHeader.tsx +59 -56
  131. package/src/components/VirtualTable/VirtualTableHeaderRow.tsx +9 -4
  132. package/src/components/VirtualTable/VirtualTableProps.tsx +7 -1
  133. package/src/components/VirtualTable/fields/VirtualTableSelect.tsx +3 -3
  134. package/src/components/VirtualTable/types.tsx +1 -0
  135. package/src/components/common/default_entity_actions.tsx +4 -0
  136. package/src/components/common/useDataSourceTableController.tsx +12 -4
  137. package/src/components/index.tsx +1 -0
  138. package/src/core/DefaultAppBar.tsx +15 -11
  139. package/src/core/DefaultDrawer.tsx +8 -2
  140. package/src/core/DrawerNavigationGroup.tsx +5 -3
  141. package/src/core/EntityEditView.tsx +54 -8
  142. package/src/core/EntityEditViewFormActions.tsx +24 -17
  143. package/src/core/EntitySidePanel.tsx +34 -30
  144. package/src/core/FireCMS.tsx +33 -6
  145. package/src/core/field_configs.tsx +18 -11
  146. package/src/editor/components/SlashCommandMenu.tsx +516 -0
  147. package/src/editor/components/editor-bubble-item.tsx +32 -0
  148. package/src/editor/components/editor-bubble.tsx +118 -0
  149. package/src/editor/components/image-bubble.tsx +156 -0
  150. package/src/editor/components/index.ts +14 -0
  151. package/src/editor/components/table-bubble.tsx +165 -0
  152. package/src/editor/editor.tsx +455 -0
  153. package/src/editor/extensions/HighlightDecorationExtension.ts +114 -0
  154. package/src/editor/extensions/Image/index.ts +133 -0
  155. package/src/editor/extensions/Image.ts +159 -0
  156. package/src/editor/extensions/TextLoadingDecorationExtension.tsx +107 -0
  157. package/src/editor/extensions/clipboard.ts +72 -0
  158. package/src/editor/extensions/custom-keymap.ts +24 -0
  159. package/src/editor/extensions/drag-and-drop.tsx +480 -0
  160. package/src/editor/hooks/useProseMirror.ts +124 -0
  161. package/src/editor/hooks/useProseMirrorContext.ts +15 -0
  162. package/src/editor/index.ts +2 -0
  163. package/src/editor/markdown.ts +172 -0
  164. package/src/editor/nodeViews/ImageComponent.tsx +20 -0
  165. package/src/editor/nodeViews/ReactNodeView.tsx +89 -0
  166. package/src/editor/nodeViews/TaskItemComponent.tsx +29 -0
  167. package/src/editor/nodeViews/index.ts +35 -0
  168. package/src/editor/plugins/index.ts +58 -0
  169. package/src/editor/plugins/inputrules.ts +82 -0
  170. package/src/editor/plugins/placeholderPlugin.ts +55 -0
  171. package/src/editor/plugins/slashCommandPlugin.ts +61 -0
  172. package/src/editor/schema.ts +240 -0
  173. package/src/editor/selectors/ai-selector.tsx +111 -0
  174. package/src/editor/selectors/color-selector.tsx +200 -0
  175. package/src/editor/selectors/link-selector.tsx +118 -0
  176. package/src/editor/selectors/node-selector.tsx +157 -0
  177. package/src/editor/selectors/text-buttons.tsx +86 -0
  178. package/src/editor/types.ts +6 -0
  179. package/src/editor/useProseMirror.ts +126 -0
  180. package/src/editor/utils/prosemirror-utils.ts +108 -0
  181. package/src/editor/utils/remove_classes.ts +17 -0
  182. package/src/editor/utils/useDebouncedCallback.ts +25 -0
  183. package/src/form/EntityForm.tsx +149 -67
  184. package/src/form/EntityFormActions.tsx +19 -12
  185. package/src/form/PropertyFieldBinding.tsx +10 -8
  186. package/src/form/components/ErrorFocus.tsx +3 -3
  187. package/src/form/components/LocalChangesMenu.tsx +13 -13
  188. package/src/form/components/StorageItemPreview.tsx +3 -2
  189. package/src/form/components/StorageUploadProgress.tsx +18 -3
  190. package/src/form/field_bindings/ArrayCustomShapedFieldBinding.tsx +18 -5
  191. package/src/form/field_bindings/ArrayOfReferencesFieldBinding.tsx +22 -9
  192. package/src/form/field_bindings/BlockFieldBinding.tsx +26 -9
  193. package/src/form/field_bindings/DateTimeFieldBinding.tsx +1 -1
  194. package/src/form/field_bindings/KeyValueFieldBinding.tsx +46 -24
  195. package/src/form/field_bindings/MapFieldBinding.tsx +27 -11
  196. package/src/form/field_bindings/MarkdownEditorFieldBinding.tsx +74 -37
  197. package/src/form/field_bindings/MultiSelectFieldBinding.tsx +15 -1
  198. package/src/form/field_bindings/ReferenceAsStringFieldBinding.tsx +25 -11
  199. package/src/form/field_bindings/ReferenceFieldBinding.tsx +25 -11
  200. package/src/form/field_bindings/RepeatFieldBinding.tsx +21 -6
  201. package/src/form/field_bindings/SelectFieldBinding.tsx +7 -5
  202. package/src/form/field_bindings/StorageUploadFieldBinding.tsx +110 -92
  203. package/src/form/field_bindings/SwitchFieldBinding.tsx +31 -14
  204. package/src/form/field_bindings/TextFieldBinding.tsx +10 -7
  205. package/src/form/field_bindings/UserSelectFieldBinding.tsx +7 -5
  206. package/src/hooks/index.tsx +1 -0
  207. package/src/hooks/useBuildNavigationController.tsx +49 -22
  208. package/src/hooks/useCollapsedGroups.ts +7 -6
  209. package/src/hooks/useTranslation.ts +31 -0
  210. package/src/hooks/useValidateAuthenticator.tsx +1 -1
  211. package/src/i18n/FireCMSi18nProvider.tsx +160 -0
  212. package/src/index.ts +5 -0
  213. package/src/internal/useBuildDataSource.ts +1 -2
  214. package/src/internal/useBuildSideEntityController.tsx +22 -20
  215. package/src/locales/de.ts +718 -0
  216. package/src/locales/en.ts +730 -0
  217. package/src/locales/es.ts +730 -0
  218. package/src/locales/fr.ts +718 -0
  219. package/src/locales/hi.ts +718 -0
  220. package/src/locales/it.ts +718 -0
  221. package/src/locales/pt.ts +727 -0
  222. package/src/preview/PropertyPreview.tsx +4 -2
  223. package/src/preview/components/ReferencePreview.tsx +2 -1
  224. package/src/preview/components/UrlComponentPreview.tsx +4 -2
  225. package/src/preview/components/UserPreview.tsx +3 -1
  226. package/src/preview/property_previews/MapPropertyPreview.tsx +49 -27
  227. package/src/routes/FireCMSRoute.tsx +63 -54
  228. package/src/types/analytics.ts +10 -0
  229. package/src/types/collections.ts +49 -0
  230. package/src/types/customization_controller.tsx +2 -1
  231. package/src/types/firecms.tsx +2 -1
  232. package/src/types/index.ts +1 -0
  233. package/src/types/navigation.ts +2 -2
  234. package/src/types/plugins.tsx +26 -0
  235. package/src/types/properties.ts +12 -10
  236. package/src/types/storage.ts +2 -1
  237. package/src/types/translations.ts +752 -0
  238. package/src/util/entities.ts +1 -1
  239. package/src/util/index.ts +1 -0
  240. package/src/util/join_collections.ts +10 -8
  241. package/src/util/lazy_eager.tsx +33 -0
  242. package/src/util/objects.ts +15 -0
  243. package/src/util/previews.ts +2 -2
  244. package/src/util/property_utils.tsx +1 -1
  245. package/src/util/resolutions.ts +5 -3
  246. package/src/util/useStorageUploadController.tsx +23 -29
@@ -1,8 +1,10 @@
1
1
  import React from "react";
2
2
  import { Link } from "react-router-dom";
3
3
  import { Button, Typography } from "@firecms/ui";
4
+ import { useTranslation } from "../hooks/useTranslation";
4
5
 
5
6
  export function NotFoundPage() {
7
+ const { t } = useTranslation();
6
8
 
7
9
  return (
8
10
  <div className="flex w-full h-full">
@@ -10,15 +12,15 @@ export function NotFoundPage() {
10
12
  >
11
13
  <Typography variant={"h4"} align={"center"}
12
14
  gutterBottom={true}>
13
- Page not found
15
+ {t("page_not_found")}
14
16
  </Typography>
15
17
  <Typography align={"center"} gutterBottom={true}>
16
- This page does not exist or you may not have access to it
18
+ {t("page_not_found_body")}
17
19
  </Typography>
18
20
  <Button
19
21
  variant={"text"}
20
22
  component={Link}
21
- to={"/"}>Back to home</Button>
23
+ to={"/"}>{t("back_to_home")}</Button>
22
24
  </div>
23
25
  </div>
24
26
  );
@@ -12,7 +12,8 @@ import {
12
12
  useDataSource,
13
13
  useLargeLayout,
14
14
  useNavigationController,
15
- useSideEntityController
15
+ useSideEntityController,
16
+ useTranslation
16
17
  } from "../../hooks";
17
18
  import { ErrorView } from "../ErrorView";
18
19
  import { AddIcon, Button, DialogActions, Typography } from "@firecms/ui";
@@ -101,6 +102,7 @@ export function ReferenceSelectionTable<M extends Record<string, any>>(
101
102
  maxSelection,
102
103
  }: ReferenceSelectionInnerProps<M>) {
103
104
 
105
+ const { t } = useTranslation();
104
106
  const authController = useAuthController();
105
107
  const sideDialogContext = useSideDialogContext();
106
108
  const sideEntityController = useSideEntityController();
@@ -302,8 +304,8 @@ export function ReferenceSelectionTable<M extends Record<string, any>>(
302
304
  collectionOrView={collection}
303
305
  className={"text-surface-300 dark:text-surface-600"}/>
304
306
  {collection.singularName
305
- ? `Select ${collection.singularName}`
306
- : `Select from ${collection.name}`}
307
+ ? t("select_specific", { name: collection.singularName })
308
+ : t("select_from", { name: collection.name })}
307
309
  </Typography>}
308
310
  defaultSize={collection.defaultSize}
309
311
  properties={resolvedCollection.properties}
@@ -327,7 +329,7 @@ export function ReferenceSelectionTable<M extends Record<string, any>>(
327
329
  <Button
328
330
  onClick={onDone}
329
331
  variant="filled">
330
- Done
332
+ {t("done")}
331
333
  </Button>
332
334
  </DialogActions>
333
335
  </div>
@@ -347,7 +349,7 @@ function ReferenceDialogActions({
347
349
  onClear: () => void,
348
350
  onNewClick: () => void
349
351
  }) {
350
-
352
+ const { t } = useTranslation();
351
353
  const authController = useAuthController();
352
354
 
353
355
  const largeLayout = useLargeLayout();
@@ -363,7 +365,7 @@ function ReferenceDialogActions({
363
365
  ? <Button
364
366
  onClick={onClick}
365
367
  startIcon={<AddIcon/>}>
366
- Add {collection.singularName ?? collection.name}
368
+ {t("add_specific", { name: collection.singularName ?? collection.name })}
367
369
  </Button>
368
370
  : <Button
369
371
  onClick={onClick}>
@@ -374,7 +376,7 @@ function ReferenceDialogActions({
374
376
  <>
375
377
  <Button onClick={onClear}
376
378
  variant={"text"}>
377
- Clear
379
+ {t("clear")}
378
380
  </Button>
379
381
  {addButton}
380
382
  </>
@@ -3,7 +3,7 @@ import React, { useCallback, useMemo } from "react";
3
3
  import { Entity, EntityCollection, EntityReference, FilterValues } from "../types";
4
4
  import { getReferenceFrom } from "../util";
5
5
  import { PreviewSize, ReferencePreview } from "../preview";
6
- import { useNavigationController, useReferenceDialog } from "../hooks";
6
+ import { useNavigationController, useReferenceDialog, useTranslation } from "../hooks";
7
7
  import { Button, cls } from "@firecms/ui";
8
8
 
9
9
  export type ReferenceWidgetProps<M extends Record<string, any>> = {
@@ -50,6 +50,7 @@ export function ReferenceWidget<M extends Record<string, any>>({
50
50
  includeEntityLink
51
51
  }: ReferenceWidgetProps<M>) {
52
52
 
53
+ const { t } = useTranslation();
53
54
  const navigationController = useNavigationController();
54
55
 
55
56
  const collection: EntityCollection | undefined = useMemo(() => {
@@ -145,7 +146,7 @@ export function ReferenceWidget<M extends Record<string, any>>({
145
146
  {!value && <div className="justify-center text-left">
146
147
  <Button disabled={disabled}
147
148
  onClick={onEntryClick}>
148
- Edit {name}
149
+ {t("edit_name", { name: name ?? "" })}
149
150
  </Button>
150
151
  </div>}
151
152
 
@@ -2,6 +2,7 @@ import React from "react";
2
2
 
3
3
  import { coolIconKeys, debounce, Icon, IconButton, iconKeys, SearchBar, Tooltip } from "@firecms/ui";
4
4
  import { iconSynonyms, iconsSearch } from "../util";
5
+ import { useTranslation } from "../hooks/useTranslation";
5
6
 
6
7
  const UPDATE_SEARCH_INDEX_WAIT_MS = 220;
7
8
 
@@ -22,6 +23,7 @@ export function SearchIconsView({
22
23
  selectedIcon = "",
23
24
  onIconSelected
24
25
  }: SearchIconsProps) {
26
+ const { t } = useTranslation();
25
27
  const [keys, setKeys] = React.useState<string[] | null>(null);
26
28
  const [query, setQuery] = React.useState<string>("");
27
29
 
@@ -53,7 +55,7 @@ export function SearchIconsView({
53
55
  autoFocus={false}
54
56
  innerClassName={"w-full sticky top-0 z-10"}
55
57
  onTextSearch={(value?: string) => setQuery(value ?? "")}
56
- placeholder="Search for more icons…"
58
+ placeholder={t("search_for_more_icons")}
57
59
  />
58
60
 
59
61
  <div className={"flex max-w-full flex-wrap mt-4"}>
@@ -48,6 +48,17 @@ export function DateTimeFilterField({
48
48
  const [operation, setOperation] = useState<VirtualTableWhereFilterOp | "is-null">(fieldOperation === "==" && fieldValue === null ? "is-null" : fieldOperation);
49
49
  const [internalValue, setInternalValue] = useState<Date | null | undefined>(fieldValue);
50
50
 
51
+ React.useEffect(() => {
52
+ if (value) {
53
+ const [op, val] = value;
54
+ setOperation(op === "==" && val === null ? "is-null" : op);
55
+ setInternalValue(val);
56
+ } else {
57
+ setOperation(possibleOperations[0]);
58
+ setInternalValue(undefined);
59
+ }
60
+ }, [value, possibleOperations[0]]);
61
+
51
62
  const isNullOperation = operation === "is-null";
52
63
 
53
64
  function updateFilter(op: VirtualTableWhereFilterOp | "is-null", val: Date | undefined | null) {
@@ -3,7 +3,7 @@ import { VirtualTableWhereFilterOp } from "../../VirtualTable";
3
3
  import { Entity, EntityCollection, EntityReference } from "../../../types";
4
4
  import { ReferencePreview } from "../../../preview";
5
5
  import { getReferenceFrom } from "../../../util";
6
- import { useNavigationController, useReferenceDialog } from "../../../hooks";
6
+ import { useNavigationController, useReferenceDialog, useTranslation } from "../../../hooks";
7
7
  import { Button, Checkbox, Label, Select, SelectItem } from "@firecms/ui";
8
8
 
9
9
  interface ReferenceFilterFieldProps {
@@ -44,6 +44,8 @@ export function ReferenceFilterField({
44
44
  setHidden
45
45
  }: ReferenceFilterFieldProps) {
46
46
 
47
+ const { t } = useTranslation();
48
+
47
49
  const possibleOperations: (keyof typeof operationLabels)[] = isArray
48
50
  ? ["array-contains"]
49
51
  : ["==", "!=", ">", "<", ">=", "<="];
@@ -58,6 +60,17 @@ export function ReferenceFilterField({
58
60
  const [operation, setOperation] = useState<VirtualTableWhereFilterOp>(fieldOperation);
59
61
  const [internalValue, setInternalValue] = useState<EntityReference | EntityReference[] | undefined | null>(fieldValue);
60
62
 
63
+ React.useEffect(() => {
64
+ if (value) {
65
+ const [op, val] = value;
66
+ setOperation(op);
67
+ setInternalValue(val);
68
+ } else {
69
+ setOperation(possibleOperations[0] as VirtualTableWhereFilterOp);
70
+ setInternalValue(undefined);
71
+ }
72
+ }, [value, possibleOperations[0]]);
73
+
61
74
  const selectedEntityIds = internalValue
62
75
  ? (Array.isArray(internalValue) ? internalValue.map((ref) => {
63
76
  if (!(ref?.isEntityReference && ref?.isEntityReference())) {
@@ -192,7 +205,7 @@ export function ReferenceFilterField({
192
205
  updateFilter(operation, null);
193
206
  else updateFilter(operation, undefined);
194
207
  }} />
195
- Filter for null values
208
+ {t("filter_for_null_values")}
196
209
  </Label>}
197
210
 
198
211
  </div>
@@ -61,6 +61,17 @@ export function StringNumberFilterField({
61
61
  const [operation, setOperation] = useState<VirtualTableWhereFilterOp | "is-null">(fieldOperation === "==" && fieldValue === null ? "is-null" : fieldOperation);
62
62
  const [internalValue, setInternalValue] = useState<string | number | string[] | number[] | null | undefined>(fieldValue);
63
63
 
64
+ React.useEffect(() => {
65
+ if (value) {
66
+ const [op, val] = value;
67
+ setOperation(op === "==" && val === null ? "is-null" : op);
68
+ setInternalValue(val);
69
+ } else {
70
+ setOperation(possibleOperations[0]);
71
+ setInternalValue(undefined);
72
+ }
73
+ }, [value, possibleOperations[0]]);
74
+
64
75
  const isNullOperation = operation === "is-null";
65
76
 
66
77
  function updateFilter(op: VirtualTableWhereFilterOp | "is-null", val: string | number | string[] | number[] | null | undefined) {
@@ -1,4 +1,6 @@
1
+ import React from "react";
1
2
  import { Button, Dialog, DialogActions, DialogContent, DialogTitle, Typography } from "@firecms/ui";
3
+ import { useTranslation } from "../hooks/useTranslation";
2
4
 
3
5
  export interface UnsavedChangesDialogProps {
4
6
  open: boolean;
@@ -15,7 +17,7 @@ export function UnsavedChangesDialog({
15
17
  body,
16
18
  title
17
19
  }: UnsavedChangesDialogProps) {
18
-
20
+ const { t } = useTranslation();
19
21
  return (
20
22
  <Dialog
21
23
  onEscapeKeyDown={() => {
@@ -29,15 +31,15 @@ export function UnsavedChangesDialog({
29
31
  {body}
30
32
 
31
33
  <Typography>
32
- Are you sure you want to leave this page?
34
+ {t("are_you_sure_leave")}
33
35
  </Typography>
34
36
 
35
37
  </DialogContent>
36
38
  <DialogActions>
37
39
  <Button variant="text"
38
- onClick={handleCancel} autoFocus> Cancel </Button>
40
+ onClick={handleCancel} autoFocus> {t("cancel")} </Button>
39
41
  <Button
40
- onClick={handleOk}> Ok </Button>
42
+ onClick={handleOk}> {t("ok")} </Button>
41
43
  </DialogActions>
42
44
  </Dialog>
43
45
  );
@@ -3,6 +3,7 @@
3
3
  * @jest-environment jsdom
4
4
  */
5
5
  import React from 'react';
6
+ /* eslint-disable i18next/no-literal-string */
6
7
  import { render, act } from '@testing-library/react';
7
8
  import { VirtualTable } from './VirtualTable';
8
9
  import { VirtualTableProps } from './VirtualTableProps';
@@ -42,52 +42,52 @@ type InnerElementProps = {
42
42
 
43
43
  // eslint-disable-next-line react/display-name
44
44
  const innerElementType = forwardRef<HTMLDivElement, InnerElementProps>(({
45
- children,
46
- ...rest
47
- }: InnerElementProps, ref) => {
48
-
49
- return (
50
- <VirtualListContext.Consumer>
51
- {(virtualTableProps) => {
52
- const customView = virtualTableProps.customView;
53
- return (
54
- <>
45
+ children,
46
+ ...rest
47
+ }: InnerElementProps, ref) => {
48
+
49
+ return (
50
+ <VirtualListContext.Consumer>
51
+ {(virtualTableProps) => {
52
+ const customView = virtualTableProps.customView;
53
+ return (
54
+ <>
55
+ <div
56
+ id={"virtual-table"}
57
+ style={{
58
+ position: "relative",
59
+ height: "100%"
60
+ }}>
55
61
  <div
56
- id={"virtual-table"}
62
+ ref={ref}
63
+ {...rest}
57
64
  style={{
58
- position: "relative",
59
- height: "100%"
65
+ ...rest?.style,
66
+ minHeight: "100%",
67
+ position: "relative"
60
68
  }}>
61
- <div
62
- ref={ref}
63
- {...rest}
64
- style={{
65
- ...rest?.style,
66
- minHeight: "100%",
67
- position: "relative"
68
- }}>
69
- <VirtualTableHeaderRow {...virtualTableProps} />
70
- {!customView && children}
71
- </div>
72
-
69
+ <VirtualTableHeaderRow {...virtualTableProps} />
70
+ {!customView && children}
73
71
  </div>
74
72
 
75
- {customView && <div style={{
76
- position: "sticky",
77
- top: "48px",
78
- flexGrow: 1,
79
- height: "calc(100% - 48px)",
80
- marginTop: "calc(48px - 100vh)",
81
- left: 0
82
- }}>{customView}</div>}
83
-
84
- </>
85
- );
86
- }}
87
- </VirtualListContext.Consumer>
88
- );
89
- })
90
- ;
73
+ </div>
74
+
75
+ {customView && <div style={{
76
+ position: "sticky",
77
+ top: "48px",
78
+ flexGrow: 1,
79
+ height: "calc(100% - 48px)",
80
+ marginTop: "calc(48px - 100vh)",
81
+ left: 0
82
+ }}>{customView}</div>}
83
+
84
+ </>
85
+ );
86
+ }}
87
+ </VirtualListContext.Consumer>
88
+ );
89
+ })
90
+ ;
91
91
 
92
92
  /**
93
93
  * This is a Table component that allows displaying arbitrary data, not
@@ -99,34 +99,35 @@ const innerElementType = forwardRef<HTMLDivElement, InnerElementProps>(({
99
99
  */
100
100
  export const VirtualTable = React.memo<VirtualTableProps<any>>(
101
101
  function VirtualTable<T extends Record<string, any>>({
102
- data,
103
- onResetPagination,
104
- onEndReached,
105
- endOffset = 600,
106
- rowHeight = 54,
107
- columns: columnsProp,
108
- onRowClick,
109
- onColumnResize,
110
- filter: filterInput,
111
- checkFilterCombination,
112
- onFilterUpdate,
113
- sortBy,
114
- error,
115
- emptyComponent,
116
- onSortByUpdate,
117
- onScroll: onScrollProp,
118
- loading,
119
- cellRenderer,
120
- hoverRow,
121
- createFilterField,
122
- rowClassName,
123
- style,
124
- className,
125
- endAdornment,
126
- AddColumnComponent,
127
- initialScroll = 0,
128
- onColumnsOrderChange,
129
- }: VirtualTableProps<T>) {
102
+ data,
103
+ onResetPagination,
104
+ onEndReached,
105
+ endOffset = 600,
106
+ rowHeight = 54,
107
+ columns: columnsProp,
108
+ onRowClick,
109
+ onColumnResize,
110
+ filter: filterInput,
111
+ checkFilterCombination,
112
+ onFilterUpdate,
113
+ sortBy,
114
+ error,
115
+ emptyComponent,
116
+ onSortByUpdate,
117
+ onScroll: onScrollProp,
118
+ loading,
119
+ cellRenderer,
120
+ hoverRow,
121
+ createFilterField,
122
+ rowClassName,
123
+ style,
124
+ className,
125
+ endAdornment,
126
+ AddColumnComponent,
127
+ initialScroll = 0,
128
+ onColumnsOrderChange,
129
+ headerIconSize,
130
+ }: VirtualTableProps<T>) {
130
131
 
131
132
  const sortByProperty: string | undefined = sortBy ? sortBy[0] : undefined;
132
133
  const currentSort: "asc" | "desc" | undefined = sortBy ? sortBy[1] : undefined;
@@ -211,7 +212,7 @@ export const VirtualTable = React.memo<VirtualTableProps<any>>(
211
212
  }, [tableRef]);
212
213
 
213
214
  const [measureRef, bounds] = useMeasure({
214
- debounce: 50,
215
+ debounce: 0,
215
216
  polyfill: ResizeObserver,
216
217
  scroll: true,
217
218
  // This is important for handling zooming in react-flow
@@ -234,7 +235,7 @@ export const VirtualTable = React.memo<VirtualTableProps<any>>(
234
235
  }, [columns, onColumnResize]);
235
236
 
236
237
  // saving the current filter as a ref as a workaround for header closure
237
- const filterRef = useRef<VirtualTableFilterValues<any> | undefined>();
238
+ const filterRef = useRef<VirtualTableFilterValues<any> | undefined>(undefined);
238
239
 
239
240
  useEffect(() => {
240
241
  filterRef.current = filterInput;
@@ -285,10 +286,10 @@ export const VirtualTable = React.memo<VirtualTableProps<any>>(
285
286
  }, [data?.length, onEndReached]);
286
287
 
287
288
  const onScroll = useCallback(({
288
- scrollDirection,
289
- scrollOffset,
290
- scrollUpdateWasRequested
291
- }: {
289
+ scrollDirection,
290
+ scrollOffset,
291
+ scrollUpdateWasRequested
292
+ }: {
292
293
  scrollDirection: "forward" | "backward",
293
294
  scrollOffset: number,
294
295
  scrollUpdateWasRequested: boolean;
@@ -327,21 +328,21 @@ export const VirtualTable = React.memo<VirtualTableProps<any>>(
327
328
  const empty = !loading && (data?.length ?? 0) === 0;
328
329
  const customView = error
329
330
  ? <CenteredView maxWidth={"2xl"}
330
- className="flex flex-col gap-2">
331
+ className="flex flex-col gap-2">
331
332
 
332
333
  <Typography variant={"h6"}>
333
334
  {"Error"}
334
335
  </Typography>
335
336
 
336
- {error?.message && <SafeLinkRenderer text={error.message}/>}
337
+ {error?.message && <SafeLinkRenderer text={error.message} />}
337
338
 
338
339
  </CenteredView>
339
340
  : (empty
340
341
  ? (loading
341
- ? <CircularProgressCenter/>
342
+ ? <CircularProgressCenter />
342
343
  : <div
343
344
  className="flex flex-col overflow-auto items-center justify-center p-2 gap-2 h-full">
344
- <AssignmentIcon/>
345
+ <AssignmentIcon />
345
346
  {emptyComponent}
346
347
  </div>)
347
348
  : undefined);
@@ -369,8 +370,9 @@ export const VirtualTable = React.memo<VirtualTableProps<any>>(
369
370
  setColumns(newColumns);
370
371
  onColumnsOrderChange(newColumns);
371
372
  } : undefined,
372
- draggingColumnId
373
- }), [data, rowHeight, cellRenderer, columns, currentSort, onRowClick, customView, onColumnResizeInternal, onColumnResizeEndInternal, filterInput, onColumnSort, onFilterUpdateInternal, sortByProperty, hoverRow, createFilterField, rowClassName, endAdornment, AddColumnComponent, onColumnsOrderChange, draggingColumnId]);
373
+ draggingColumnId,
374
+ headerIconSize,
375
+ }), [data, rowHeight, cellRenderer, columns, currentSort, onRowClick, customView, onColumnResizeInternal, onColumnResizeEndInternal, filterInput, onColumnSort, onFilterUpdateInternal, sortByProperty, hoverRow, createFilterField, rowClassName, endAdornment, AddColumnComponent, onColumnsOrderChange, draggingColumnId, headerIconSize]);
374
376
 
375
377
  // Get sortable column keys (excluding frozen columns)
376
378
  const sortableColumnKeys = columns
@@ -397,7 +399,7 @@ export const VirtualTable = React.memo<VirtualTableProps<any>>(
397
399
  itemCount={(data?.length ?? 0) + (endAdornment ? 1 : 0)}
398
400
  onScroll={draggingColumnId ? undefined : onScroll}
399
401
  includeAddColumn={Boolean(AddColumnComponent)}
400
- itemSize={rowHeight}/>
402
+ itemSize={rowHeight} />
401
403
 
402
404
  </VirtualListContext.Provider>
403
405
  </div>
@@ -429,13 +431,13 @@ export const VirtualTable = React.memo<VirtualTableProps<any>>(
429
431
  );
430
432
  // Wrapper that applies sortable transforms to cells
431
433
  const SortableCellWrapper = ({
432
- columnKey,
433
- width,
434
- isDragging,
435
- isDraggable,
436
- frozen,
437
- children
438
- }: {
434
+ columnKey,
435
+ width,
436
+ isDragging,
437
+ isDraggable,
438
+ frozen,
439
+ children
440
+ }: {
439
441
  columnKey: string;
440
442
  width: number;
441
443
  isDragging: boolean;
@@ -454,6 +456,9 @@ const SortableCellWrapper = ({
454
456
  disabled: !isDraggable || frozen
455
457
  });
456
458
 
459
+ // Remove tabIndex from attributes to avoid capturing focus before cell content
460
+ const { tabIndex: _tabIndex, ...attrsWithoutTabIndex } = attributes;
461
+
457
462
  const style = {
458
463
  // Only use translate, ignore any scale transforms
459
464
  transform: transform ? `translateX(${transform.x}px)` : undefined,
@@ -472,7 +477,7 @@ const SortableCellWrapper = ({
472
477
  "flex-shrink-0",
473
478
  frozen && "sticky left-0 z-10 bg-white dark:bg-surface-950"
474
479
  )}
475
- {...attributes}
480
+ {...attrsWithoutTabIndex}
476
481
  >
477
482
  {children}
478
483
  </div>
@@ -480,15 +485,15 @@ const SortableCellWrapper = ({
480
485
  };
481
486
 
482
487
  function MemoizedList({
483
- outerRef,
484
- width,
485
- height,
486
- itemCount,
487
- onScroll,
488
- itemSize,
489
- includeAddColumn
490
- }: {
491
- outerRef: RefObject<HTMLDivElement>;
488
+ outerRef,
489
+ width,
490
+ height,
491
+ itemCount,
492
+ onScroll,
493
+ itemSize,
494
+ includeAddColumn
495
+ }: {
496
+ outerRef: RefObject<HTMLDivElement | null>;
492
497
  width: number;
493
498
  height: number;
494
499
  itemCount: number;
@@ -502,22 +507,22 @@ function MemoizedList({
502
507
  }) {
503
508
 
504
509
  const Row = useCallback(({
505
- index,
506
- style
507
- }: any) => {
510
+ index,
511
+ style
512
+ }: any) => {
508
513
  return <VirtualListContext.Consumer>
509
514
  {({
510
- onRowClick,
511
- data,
512
- columns,
513
- rowHeight = 54,
514
- cellRenderer,
515
- hoverRow,
516
- rowClassName,
517
- endAdornment,
518
- draggingColumnId,
519
- onColumnsOrderChange
520
- }) => {
515
+ onRowClick,
516
+ data,
517
+ columns,
518
+ rowHeight = 54,
519
+ cellRenderer,
520
+ hoverRow,
521
+ rowClassName,
522
+ endAdornment,
523
+ draggingColumnId,
524
+ onColumnsOrderChange
525
+ }) => {
521
526
 
522
527
  if (endAdornment && index === (data ?? []).length) {
523
528
  return <div style={{
@@ -569,12 +574,12 @@ function MemoizedList({
569
574
  rowData={rowData}
570
575
  cellData={cellData}
571
576
  rowIndex={index}
572
- columnIndex={columnIndex}/>
577
+ columnIndex={columnIndex} />
573
578
  </SortableCellWrapper>
574
579
  );
575
580
  })}
576
581
 
577
- {includeAddColumn && <div className={"w-20"}/>}
582
+ {includeAddColumn && <div className={"w-20"} />}
578
583
 
579
584
  </VirtualTableRow>
580
585
  );
@@ -605,6 +610,6 @@ const SafeLinkRenderer: React.FC<{
605
610
  });
606
611
 
607
612
  return (
608
- <div className={"break-all"} dangerouslySetInnerHTML={{ __html: htmlContent }}/>
613
+ <div className={"break-all"} dangerouslySetInnerHTML={{ __html: htmlContent }} />
609
614
  );
610
615
  };