@firecms/core 3.1.0-canary.9e89e98 → 3.1.0-canary.dc8ac43

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 (216) 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/ErrorBoundary.d.ts +4 -2
  4. package/dist/components/HomePage/DefaultHomePage.d.ts +0 -1
  5. package/dist/components/LanguageToggle.d.ts +1 -0
  6. package/dist/components/UnsavedChangesDialog.d.ts +1 -0
  7. package/dist/components/VirtualTable/VirtualTableHeader.d.ts +1 -1
  8. package/dist/components/index.d.ts +1 -0
  9. package/dist/core/DrawerNavigationGroup.d.ts +2 -2
  10. package/dist/editor/components/SlashCommandMenu.d.ts +6 -0
  11. package/dist/editor/components/editor-bubble-item.d.ts +8 -0
  12. package/dist/editor/components/editor-bubble.d.ts +8 -0
  13. package/dist/editor/components/image-bubble.d.ts +5 -0
  14. package/dist/editor/components/index.d.ts +16 -0
  15. package/dist/editor/components/table-bubble.d.ts +5 -0
  16. package/dist/editor/editor.d.ts +30 -0
  17. package/dist/editor/extensions/HighlightDecorationExtension.d.ts +24 -0
  18. package/dist/editor/extensions/Image/index.d.ts +6 -0
  19. package/dist/editor/extensions/Image.d.ts +6 -0
  20. package/dist/editor/extensions/TextLoadingDecorationExtension.d.ts +16 -0
  21. package/dist/editor/extensions/clipboard.d.ts +7 -0
  22. package/dist/editor/extensions/custom-keymap.d.ts +1 -0
  23. package/dist/editor/extensions/drag-and-drop.d.ts +9 -0
  24. package/dist/editor/hooks/useProseMirror.d.ts +13 -0
  25. package/dist/editor/hooks/useProseMirrorContext.d.ts +9 -0
  26. package/dist/editor/index.d.ts +2 -0
  27. package/dist/editor/markdown.d.ts +5 -0
  28. package/dist/editor/nodeViews/ImageComponent.d.ts +3 -0
  29. package/dist/editor/nodeViews/ReactNodeView.d.ts +29 -0
  30. package/dist/editor/nodeViews/TaskItemComponent.d.ts +3 -0
  31. package/dist/editor/nodeViews/index.d.ts +6 -0
  32. package/dist/editor/plugins/index.d.ts +2 -0
  33. package/dist/editor/plugins/inputrules.d.ts +6 -0
  34. package/dist/editor/plugins/placeholderPlugin.d.ts +3 -0
  35. package/dist/editor/plugins/slashCommandPlugin.d.ts +12 -0
  36. package/dist/editor/schema.d.ts +2 -0
  37. package/dist/editor/selectors/ai-selector.d.ts +0 -0
  38. package/dist/editor/selectors/color-selector.d.ts +10 -0
  39. package/dist/editor/selectors/link-selector.d.ts +8 -0
  40. package/dist/editor/selectors/node-selector.d.ts +15 -0
  41. package/dist/editor/selectors/text-buttons.d.ts +1 -0
  42. package/dist/editor/types.d.ts +5 -0
  43. package/dist/editor/useProseMirror.d.ts +16 -0
  44. package/dist/editor/utils/prosemirror-utils.d.ts +6 -0
  45. package/dist/editor/utils/remove_classes.d.ts +1 -0
  46. package/dist/editor/utils/useDebouncedCallback.d.ts +1 -0
  47. package/dist/form/components/ErrorFocus.d.ts +1 -1
  48. package/dist/form/field_bindings/MarkdownEditorFieldBinding.d.ts +1 -1
  49. package/dist/hooks/index.d.ts +1 -0
  50. package/dist/hooks/useBuildNavigationController.d.ts +0 -1
  51. package/dist/hooks/useCollapsedGroups.d.ts +3 -3
  52. package/dist/hooks/useTranslation.d.ts +17 -0
  53. package/dist/i18n/FireCMSi18nProvider.d.ts +33 -0
  54. package/dist/index.d.ts +4 -0
  55. package/dist/index.es.js +13009 -2312
  56. package/dist/index.es.js.map +1 -1
  57. package/dist/index.umd.js +12997 -2320
  58. package/dist/index.umd.js.map +1 -1
  59. package/dist/internal/useRestoreScroll.d.ts +1 -1
  60. package/dist/locales/de.d.ts +2 -0
  61. package/dist/locales/en.d.ts +10 -0
  62. package/dist/locales/es.d.ts +10 -0
  63. package/dist/locales/fr.d.ts +2 -0
  64. package/dist/locales/hi.d.ts +2 -0
  65. package/dist/locales/it.d.ts +2 -0
  66. package/dist/locales/pt.d.ts +7 -0
  67. package/dist/types/analytics.d.ts +1 -1
  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/storage.d.ts +1 -0
  74. package/dist/types/translations.d.ts +646 -0
  75. package/dist/util/entities.d.ts +1 -1
  76. package/dist/util/resolutions.d.ts +2 -2
  77. package/dist/util/useStorageUploadController.d.ts +10 -1
  78. package/package.json +49 -13
  79. package/src/app/Scaffold.tsx +7 -5
  80. package/src/components/AIIcon.tsx +3 -1
  81. package/src/components/ArrayContainer.tsx +6 -4
  82. package/src/components/ClearFilterSortButton.tsx +6 -3
  83. package/src/components/ConfirmationDialog.tsx +4 -2
  84. package/src/components/DeleteEntityDialog.tsx +10 -7
  85. package/src/components/EntityCollectionTable/fields/TableReferenceField.tsx +6 -3
  86. package/src/components/EntityCollectionTable/internal/CollectionTableToolbar.tsx +3 -1
  87. package/src/components/EntityCollectionTable/internal/EntityTableCellActions.tsx +1 -1
  88. package/src/components/EntityCollectionTable/internal/popup_field/PopupFormField.tsx +3 -2
  89. package/src/components/EntityCollectionTable/internal/popup_field/useDraggable.tsx +11 -11
  90. package/src/components/EntityCollectionView/BoardSortableList.tsx +3 -1
  91. package/src/components/EntityCollectionView/CollectionDataErrorBanner.tsx +43 -0
  92. package/src/components/EntityCollectionView/EntityBoardCard.tsx +1 -1
  93. package/src/components/EntityCollectionView/EntityCard.tsx +4 -0
  94. package/src/components/EntityCollectionView/EntityCollectionBoardView.tsx +39 -46
  95. package/src/components/EntityCollectionView/EntityCollectionCardView.tsx +17 -25
  96. package/src/components/EntityCollectionView/EntityCollectionView.tsx +54 -17
  97. package/src/components/EntityCollectionView/EntityCollectionViewActions.tsx +4 -3
  98. package/src/components/EntityCollectionView/EntityCollectionViewStartActions.tsx +4 -2
  99. package/src/components/EntityCollectionView/FiltersDialog.tsx +8 -5
  100. package/src/components/EntityCollectionView/ViewModeToggle.tsx +11 -8
  101. package/src/components/EntityView.tsx +3 -2
  102. package/src/components/ErrorBoundary.tsx +27 -15
  103. package/src/components/HomePage/DefaultHomePage.tsx +19 -13
  104. package/src/components/HomePage/HomePageDnD.tsx +3 -1
  105. package/src/components/HomePage/NavigationGroup.tsx +3 -1
  106. package/src/components/HomePage/RenameGroupDialog.tsx +15 -13
  107. package/src/components/LanguageToggle.tsx +66 -0
  108. package/src/components/NotFoundPage.tsx +5 -3
  109. package/src/components/ReferenceTable/ReferenceSelectionTable.tsx +9 -7
  110. package/src/components/ReferenceWidget.tsx +3 -2
  111. package/src/components/SearchIconsView.tsx +3 -1
  112. package/src/components/SelectableTable/filters/DateTimeFilterField.tsx +11 -0
  113. package/src/components/SelectableTable/filters/ReferenceFilterField.tsx +15 -2
  114. package/src/components/SelectableTable/filters/StringNumberFilterField.tsx +11 -0
  115. package/src/components/UnsavedChangesDialog.tsx +6 -4
  116. package/src/components/VirtualTable/VirtualTable.performance.test.tsx +1 -0
  117. package/src/components/VirtualTable/VirtualTable.tsx +116 -113
  118. package/src/components/VirtualTable/VirtualTableHeader.tsx +54 -52
  119. package/src/components/VirtualTable/VirtualTableHeaderRow.tsx +1 -1
  120. package/src/components/VirtualTable/fields/VirtualTableSelect.tsx +3 -3
  121. package/src/components/common/default_entity_actions.tsx +4 -0
  122. package/src/components/common/useDataSourceTableController.tsx +12 -4
  123. package/src/components/index.tsx +1 -0
  124. package/src/core/DefaultAppBar.tsx +15 -11
  125. package/src/core/DefaultDrawer.tsx +8 -2
  126. package/src/core/DrawerNavigationGroup.tsx +5 -3
  127. package/src/core/EntityEditView.tsx +4 -3
  128. package/src/core/EntityEditViewFormActions.tsx +24 -17
  129. package/src/core/EntitySidePanel.tsx +32 -29
  130. package/src/core/FireCMS.tsx +33 -6
  131. package/src/core/field_configs.tsx +14 -9
  132. package/src/editor/components/SlashCommandMenu.tsx +516 -0
  133. package/src/editor/components/editor-bubble-item.tsx +32 -0
  134. package/src/editor/components/editor-bubble.tsx +118 -0
  135. package/src/editor/components/image-bubble.tsx +156 -0
  136. package/src/editor/components/index.ts +14 -0
  137. package/src/editor/components/table-bubble.tsx +165 -0
  138. package/src/editor/editor.tsx +455 -0
  139. package/src/editor/extensions/HighlightDecorationExtension.ts +114 -0
  140. package/src/editor/extensions/Image/index.ts +133 -0
  141. package/src/editor/extensions/Image.ts +159 -0
  142. package/src/editor/extensions/TextLoadingDecorationExtension.tsx +107 -0
  143. package/src/editor/extensions/clipboard.ts +72 -0
  144. package/src/editor/extensions/custom-keymap.ts +24 -0
  145. package/src/editor/extensions/drag-and-drop.tsx +480 -0
  146. package/src/editor/hooks/useProseMirror.ts +124 -0
  147. package/src/editor/hooks/useProseMirrorContext.ts +15 -0
  148. package/src/editor/index.ts +2 -0
  149. package/src/editor/markdown.ts +172 -0
  150. package/src/editor/nodeViews/ImageComponent.tsx +20 -0
  151. package/src/editor/nodeViews/ReactNodeView.tsx +89 -0
  152. package/src/editor/nodeViews/TaskItemComponent.tsx +29 -0
  153. package/src/editor/nodeViews/index.ts +35 -0
  154. package/src/editor/plugins/index.ts +58 -0
  155. package/src/editor/plugins/inputrules.ts +82 -0
  156. package/src/editor/plugins/placeholderPlugin.ts +55 -0
  157. package/src/editor/plugins/slashCommandPlugin.ts +61 -0
  158. package/src/editor/schema.ts +240 -0
  159. package/src/editor/selectors/ai-selector.tsx +111 -0
  160. package/src/editor/selectors/color-selector.tsx +200 -0
  161. package/src/editor/selectors/link-selector.tsx +118 -0
  162. package/src/editor/selectors/node-selector.tsx +157 -0
  163. package/src/editor/selectors/text-buttons.tsx +86 -0
  164. package/src/editor/types.ts +6 -0
  165. package/src/editor/useProseMirror.ts +126 -0
  166. package/src/editor/utils/prosemirror-utils.ts +108 -0
  167. package/src/editor/utils/remove_classes.ts +17 -0
  168. package/src/editor/utils/useDebouncedCallback.ts +25 -0
  169. package/src/form/EntityForm.tsx +85 -63
  170. package/src/form/EntityFormActions.tsx +19 -12
  171. package/src/form/PropertyFieldBinding.tsx +6 -5
  172. package/src/form/components/ErrorFocus.tsx +3 -3
  173. package/src/form/components/LocalChangesMenu.tsx +13 -13
  174. package/src/form/components/StorageItemPreview.tsx +3 -2
  175. package/src/form/components/StorageUploadProgress.tsx +18 -3
  176. package/src/form/field_bindings/ArrayOfReferencesFieldBinding.tsx +4 -4
  177. package/src/form/field_bindings/BlockFieldBinding.tsx +5 -2
  178. package/src/form/field_bindings/KeyValueFieldBinding.tsx +23 -18
  179. package/src/form/field_bindings/MapFieldBinding.tsx +4 -3
  180. package/src/form/field_bindings/MarkdownEditorFieldBinding.tsx +34 -20
  181. package/src/form/field_bindings/RepeatFieldBinding.tsx +3 -1
  182. package/src/form/field_bindings/StorageUploadFieldBinding.tsx +87 -86
  183. package/src/hooks/index.tsx +1 -0
  184. package/src/hooks/useBuildNavigationController.tsx +49 -22
  185. package/src/hooks/useCollapsedGroups.ts +7 -6
  186. package/src/hooks/useTranslation.ts +31 -0
  187. package/src/hooks/useValidateAuthenticator.tsx +1 -1
  188. package/src/i18n/FireCMSi18nProvider.tsx +160 -0
  189. package/src/index.ts +4 -0
  190. package/src/internal/useBuildDataSource.ts +1 -2
  191. package/src/internal/useBuildSideEntityController.tsx +22 -20
  192. package/src/locales/de.ts +691 -0
  193. package/src/locales/en.ts +703 -0
  194. package/src/locales/es.ts +703 -0
  195. package/src/locales/fr.ts +691 -0
  196. package/src/locales/hi.ts +691 -0
  197. package/src/locales/it.ts +691 -0
  198. package/src/locales/pt.ts +700 -0
  199. package/src/preview/PropertyPreview.tsx +1 -0
  200. package/src/preview/components/UrlComponentPreview.tsx +4 -2
  201. package/src/preview/components/UserPreview.tsx +3 -1
  202. package/src/types/analytics.ts +10 -0
  203. package/src/types/customization_controller.tsx +2 -1
  204. package/src/types/firecms.tsx +2 -1
  205. package/src/types/index.ts +1 -0
  206. package/src/types/navigation.ts +2 -2
  207. package/src/types/plugins.tsx +26 -0
  208. package/src/types/properties.ts +1 -0
  209. package/src/types/storage.ts +2 -1
  210. package/src/types/translations.ts +725 -0
  211. package/src/util/entities.ts +1 -1
  212. package/src/util/join_collections.ts +10 -8
  213. package/src/util/previews.ts +2 -2
  214. package/src/util/property_utils.tsx +1 -1
  215. package/src/util/resolutions.ts +5 -3
  216. package/src/util/useStorageUploadController.tsx +23 -29
@@ -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
  };
@@ -2,6 +2,7 @@ import React, { RefObject, useCallback, useEffect, useState } from "react";
2
2
  import equal from "react-fast-compare";
3
3
 
4
4
  import { VirtualTableColumn, VirtualTableSort, VirtualTableWhereFilterOp } from "./VirtualTableProps";
5
+ import { useTranslation } from "../../hooks";
5
6
  import { ErrorBoundary } from "../ErrorBoundary";
6
7
  import {
7
8
  ArrowUpwardIcon,
@@ -34,7 +35,7 @@ export type FilterFormFieldProps<CustomProps> = {
34
35
  };
35
36
 
36
37
  type VirtualTableHeaderProps<M extends Record<string, any>> = {
37
- resizeHandleRef: RefObject<HTMLDivElement>;
38
+ resizeHandleRef: RefObject<HTMLDivElement | null>;
38
39
  columnIndex: number;
39
40
  isResizingIndex: number;
40
41
  column: VirtualTableColumn<any>;
@@ -51,20 +52,20 @@ type VirtualTableHeaderProps<M extends Record<string, any>> = {
51
52
 
52
53
  export const VirtualTableHeader = React.memo<VirtualTableHeaderProps<any>>(
53
54
  function VirtualTableHeader<M extends Record<string, any>>({
54
- resizeHandleRef,
55
- columnIndex,
56
- isResizingIndex,
57
- sort,
58
- onColumnSort,
59
- onFilterUpdate,
60
- filter,
61
- column,
62
- onClickResizeColumn,
63
- createFilterField,
64
- AdditionalHeaderWidget,
65
- isDragging,
66
- isDraggable
67
- }: VirtualTableHeaderProps<M>) {
55
+ resizeHandleRef,
56
+ columnIndex,
57
+ isResizingIndex,
58
+ sort,
59
+ onColumnSort,
60
+ onFilterUpdate,
61
+ filter,
62
+ column,
63
+ onClickResizeColumn,
64
+ createFilterField,
65
+ AdditionalHeaderWidget,
66
+ isDragging,
67
+ isDraggable
68
+ }: VirtualTableHeaderProps<M>) {
68
69
 
69
70
  const [onHover, setOnHover] = useState(false);
70
71
 
@@ -129,11 +130,11 @@ export const VirtualTableHeader = React.memo<VirtualTableHeaderProps<any>>(
129
130
  <>
130
131
 
131
132
  {AdditionalHeaderWidget &&
132
- <AdditionalHeaderWidget onHover={onHover || openFilter}/>}
133
+ <AdditionalHeaderWidget onHover={onHover || openFilter} />}
133
134
 
134
135
  {column.sortable && (sort || hovered || openFilter) &&
135
136
  <Badge color="secondary"
136
- invisible={!sort}>
137
+ invisible={!sort}>
137
138
  <IconButton
138
139
  size={"small"}
139
140
  className={onHover || openFilter ? "bg-white dark:bg-surface-950" : undefined}
@@ -142,11 +143,11 @@ export const VirtualTableHeader = React.memo<VirtualTableHeaderProps<any>>(
142
143
  }}
143
144
  >
144
145
  {!sort &&
145
- <ArrowUpwardIcon/>}
146
+ <ArrowUpwardIcon />}
146
147
  {sort === "asc" &&
147
- <ArrowUpwardIcon/>}
148
+ <ArrowUpwardIcon />}
148
149
  {sort === "desc" &&
149
- <ArrowUpwardIcon className={"rotate-180"}/>}
150
+ <ArrowUpwardIcon className={"rotate-180"} />}
150
151
  </IconButton>
151
152
  </Badge>
152
153
  }
@@ -154,7 +155,7 @@ export const VirtualTableHeader = React.memo<VirtualTableHeaderProps<any>>(
154
155
 
155
156
  {column.filter && createFilterField && <div>
156
157
  <Badge color="secondary"
157
- invisible={!filter}>
158
+ invisible={!filter}>
158
159
 
159
160
  <Popover
160
161
  open={openFilter}
@@ -166,16 +167,16 @@ export const VirtualTableHeader = React.memo<VirtualTableHeaderProps<any>>(
166
167
  className={onHover || openFilter ? "bg-white dark:bg-surface-950" : undefined}
167
168
  size={"small"}
168
169
  onClick={handleSettingsClick}>
169
- <FilterListIcon size={"small"}/>
170
+ <FilterListIcon size={"small"} />
170
171
  </IconButton>}
171
172
  >
172
173
  <FilterForm column={column}
173
- filter={filter}
174
- onHover={onHover}
175
- onFilterUpdate={update}
176
- createFilterField={createFilterField}
177
- hidden={hidden}
178
- setHidden={setHidden}/>
174
+ filter={filter}
175
+ onHover={onHover}
176
+ onFilterUpdate={update}
177
+ createFilterField={createFilterField}
178
+ hidden={hidden}
179
+ setHidden={setHidden} />
179
180
 
180
181
  </Popover>
181
182
 
@@ -204,14 +205,16 @@ export const VirtualTableHeader = React.memo<VirtualTableHeaderProps<any>>(
204
205
  }, equal) as React.FunctionComponent<VirtualTableHeaderProps<any>>;
205
206
 
206
207
  function FilterForm<M>({
207
- column,
208
- onFilterUpdate,
209
- filter,
210
- onHover,
211
- createFilterField,
212
- hidden,
213
- setHidden
214
- }: FilterFormProps<M>) {
208
+ column,
209
+ onFilterUpdate,
210
+ filter,
211
+ onHover,
212
+ createFilterField,
213
+ hidden,
214
+ setHidden
215
+ }: FilterFormProps<M>) {
216
+
217
+ const { t } = useTranslation();
215
218
 
216
219
  const id = column.key;
217
220
 
@@ -245,12 +248,12 @@ function FilterForm<M>({
245
248
  if (!filterField) return null;
246
249
  return (
247
250
  <form noValidate={true}
248
- onSubmit={(e) => {
249
- e.stopPropagation();
250
- e.preventDefault();
251
- submit();
252
- }}
253
- className={"text-surface-900 dark:text-white"}>
251
+ onSubmit={(e) => {
252
+ e.stopPropagation();
253
+ e.preventDefault();
254
+ submit();
255
+ }}
256
+ className={"text-surface-900 dark:text-white"}>
254
257
  <div
255
258
  className={cls(defaultBorderMixin, "py-4 px-6 typography-label border-b")}>
256
259
  {column.title ?? id}
@@ -258,16 +261,15 @@ function FilterForm<M>({
258
261
  {filterField && <div className="m-4 w-[400px]">
259
262
  {filterField}
260
263
  </div>}
261
- <div className="flex justify-end m-4">
262
- <Button
263
- className="mr-4"
264
- disabled={!filterIsSet}
265
- variant={"text"}
266
- type="reset"
267
- aria-label="filter clear"
268
- onClick={reset}>Clear</Button>
269
- <Button
270
- type="submit">Filter</Button>
264
+ <div className="flex justify-end p-4 pt-0 gap-2">
265
+ <Button variant={"text"}
266
+ size={"small"}
267
+ aria-label="filter clear"
268
+ onClick={reset}>{t("clear")}</Button>
269
+
270
+ <Button variant={"outlined"}
271
+ size={"small"}
272
+ type="submit">{t("filter")}</Button>
271
273
  </div>
272
274
  </form>
273
275
  );
@@ -26,7 +26,7 @@ const SortableColumnHeader = ({
26
26
  }: {
27
27
  column: VirtualTableColumn;
28
28
  columnIndex: number;
29
- columnRefs: React.RefObject<HTMLDivElement>[];
29
+ columnRefs: React.RefObject<HTMLDivElement | null>[];
30
30
  isResizing: number;
31
31
  onFilterUpdate: any;
32
32
  filter: [VirtualTableWhereFilterOp, any] | undefined;
@@ -79,7 +79,7 @@ export function VirtualTableSelect(props: {
79
79
  multiple
80
80
  ? <MultiSelect
81
81
  inputRef={ref}
82
- className="w-full h-full p-0 bg-transparent"
82
+ className="w-full h-full p-0 bg-transparent outline-none"
83
83
  position={"item-aligned"}
84
84
  disabled={disabled}
85
85
  includeClear={false}
@@ -104,8 +104,8 @@ export function VirtualTableSelect(props: {
104
104
  inputRef={ref}
105
105
  size={"large"}
106
106
  fullWidth={true}
107
- className="w-full h-full p-0 bg-transparent"
108
- inputClassName="focus:ring-0 focus-visible:ring-0 outline-none focus:outline-none focus-visible:outline-none"
107
+ className="w-full h-full p-0 bg-transparent outline-none [&_button]:ring-0 [&_button]:ring-offset-0"
108
+ inputClassName="ring-0 ring-offset-0 focus:ring-0 focus-visible:ring-0 outline-none focus:outline-none focus-visible:outline-none focus-visible:ring-offset-0"
109
109
  position={"item-aligned"}
110
110
  disabled={disabled}
111
111
  padding={false}