@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
@@ -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,34 @@ 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
+ }: VirtualTableProps<T>) {
130
130
 
131
131
  const sortByProperty: string | undefined = sortBy ? sortBy[0] : undefined;
132
132
  const currentSort: "asc" | "desc" | undefined = sortBy ? sortBy[1] : undefined;
@@ -234,7 +234,7 @@ export const VirtualTable = React.memo<VirtualTableProps<any>>(
234
234
  }, [columns, onColumnResize]);
235
235
 
236
236
  // saving the current filter as a ref as a workaround for header closure
237
- const filterRef = useRef<VirtualTableFilterValues<any> | undefined>();
237
+ const filterRef = useRef<VirtualTableFilterValues<any> | undefined>(undefined);
238
238
 
239
239
  useEffect(() => {
240
240
  filterRef.current = filterInput;
@@ -285,10 +285,10 @@ export const VirtualTable = React.memo<VirtualTableProps<any>>(
285
285
  }, [data?.length, onEndReached]);
286
286
 
287
287
  const onScroll = useCallback(({
288
- scrollDirection,
289
- scrollOffset,
290
- scrollUpdateWasRequested
291
- }: {
288
+ scrollDirection,
289
+ scrollOffset,
290
+ scrollUpdateWasRequested
291
+ }: {
292
292
  scrollDirection: "forward" | "backward",
293
293
  scrollOffset: number,
294
294
  scrollUpdateWasRequested: boolean;
@@ -327,21 +327,21 @@ export const VirtualTable = React.memo<VirtualTableProps<any>>(
327
327
  const empty = !loading && (data?.length ?? 0) === 0;
328
328
  const customView = error
329
329
  ? <CenteredView maxWidth={"2xl"}
330
- className="flex flex-col gap-2">
330
+ className="flex flex-col gap-2">
331
331
 
332
332
  <Typography variant={"h6"}>
333
333
  {"Error"}
334
334
  </Typography>
335
335
 
336
- {error?.message && <SafeLinkRenderer text={error.message}/>}
336
+ {error?.message && <SafeLinkRenderer text={error.message} />}
337
337
 
338
338
  </CenteredView>
339
339
  : (empty
340
340
  ? (loading
341
- ? <CircularProgressCenter/>
341
+ ? <CircularProgressCenter />
342
342
  : <div
343
343
  className="flex flex-col overflow-auto items-center justify-center p-2 gap-2 h-full">
344
- <AssignmentIcon/>
344
+ <AssignmentIcon />
345
345
  {emptyComponent}
346
346
  </div>)
347
347
  : undefined);
@@ -397,7 +397,7 @@ export const VirtualTable = React.memo<VirtualTableProps<any>>(
397
397
  itemCount={(data?.length ?? 0) + (endAdornment ? 1 : 0)}
398
398
  onScroll={draggingColumnId ? undefined : onScroll}
399
399
  includeAddColumn={Boolean(AddColumnComponent)}
400
- itemSize={rowHeight}/>
400
+ itemSize={rowHeight} />
401
401
 
402
402
  </VirtualListContext.Provider>
403
403
  </div>
@@ -429,13 +429,13 @@ export const VirtualTable = React.memo<VirtualTableProps<any>>(
429
429
  );
430
430
  // Wrapper that applies sortable transforms to cells
431
431
  const SortableCellWrapper = ({
432
- columnKey,
433
- width,
434
- isDragging,
435
- isDraggable,
436
- frozen,
437
- children
438
- }: {
432
+ columnKey,
433
+ width,
434
+ isDragging,
435
+ isDraggable,
436
+ frozen,
437
+ children
438
+ }: {
439
439
  columnKey: string;
440
440
  width: number;
441
441
  isDragging: boolean;
@@ -454,6 +454,9 @@ const SortableCellWrapper = ({
454
454
  disabled: !isDraggable || frozen
455
455
  });
456
456
 
457
+ // Remove tabIndex from attributes to avoid capturing focus before cell content
458
+ const { tabIndex: _tabIndex, ...attrsWithoutTabIndex } = attributes;
459
+
457
460
  const style = {
458
461
  // Only use translate, ignore any scale transforms
459
462
  transform: transform ? `translateX(${transform.x}px)` : undefined,
@@ -472,7 +475,7 @@ const SortableCellWrapper = ({
472
475
  "flex-shrink-0",
473
476
  frozen && "sticky left-0 z-10 bg-white dark:bg-surface-950"
474
477
  )}
475
- {...attributes}
478
+ {...attrsWithoutTabIndex}
476
479
  >
477
480
  {children}
478
481
  </div>
@@ -480,15 +483,15 @@ const SortableCellWrapper = ({
480
483
  };
481
484
 
482
485
  function MemoizedList({
483
- outerRef,
484
- width,
485
- height,
486
- itemCount,
487
- onScroll,
488
- itemSize,
489
- includeAddColumn
490
- }: {
491
- outerRef: RefObject<HTMLDivElement>;
486
+ outerRef,
487
+ width,
488
+ height,
489
+ itemCount,
490
+ onScroll,
491
+ itemSize,
492
+ includeAddColumn
493
+ }: {
494
+ outerRef: RefObject<HTMLDivElement | null>;
492
495
  width: number;
493
496
  height: number;
494
497
  itemCount: number;
@@ -502,22 +505,22 @@ function MemoizedList({
502
505
  }) {
503
506
 
504
507
  const Row = useCallback(({
505
- index,
506
- style
507
- }: any) => {
508
+ index,
509
+ style
510
+ }: any) => {
508
511
  return <VirtualListContext.Consumer>
509
512
  {({
510
- onRowClick,
511
- data,
512
- columns,
513
- rowHeight = 54,
514
- cellRenderer,
515
- hoverRow,
516
- rowClassName,
517
- endAdornment,
518
- draggingColumnId,
519
- onColumnsOrderChange
520
- }) => {
513
+ onRowClick,
514
+ data,
515
+ columns,
516
+ rowHeight = 54,
517
+ cellRenderer,
518
+ hoverRow,
519
+ rowClassName,
520
+ endAdornment,
521
+ draggingColumnId,
522
+ onColumnsOrderChange
523
+ }) => {
521
524
 
522
525
  if (endAdornment && index === (data ?? []).length) {
523
526
  return <div style={{
@@ -569,12 +572,12 @@ function MemoizedList({
569
572
  rowData={rowData}
570
573
  cellData={cellData}
571
574
  rowIndex={index}
572
- columnIndex={columnIndex}/>
575
+ columnIndex={columnIndex} />
573
576
  </SortableCellWrapper>
574
577
  );
575
578
  })}
576
579
 
577
- {includeAddColumn && <div className={"w-20"}/>}
580
+ {includeAddColumn && <div className={"w-20"} />}
578
581
 
579
582
  </VirtualTableRow>
580
583
  );
@@ -605,6 +608,6 @@ const SafeLinkRenderer: React.FC<{
605
608
  });
606
609
 
607
610
  return (
608
- <div className={"break-all"} dangerouslySetInnerHTML={{ __html: htmlContent }}/>
611
+ <div className={"break-all"} dangerouslySetInnerHTML={{ __html: htmlContent }} />
609
612
  );
610
613
  };