@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.
- package/dist/components/EntityCollectionTable/internal/popup_field/useDraggable.d.ts +2 -2
- package/dist/components/EntityCollectionView/CollectionDataErrorBanner.d.ts +4 -0
- package/dist/components/ErrorBoundary.d.ts +4 -2
- package/dist/components/HomePage/DefaultHomePage.d.ts +0 -1
- package/dist/components/LanguageToggle.d.ts +1 -0
- package/dist/components/UnsavedChangesDialog.d.ts +1 -0
- package/dist/components/VirtualTable/VirtualTableHeader.d.ts +1 -1
- package/dist/components/index.d.ts +1 -0
- package/dist/core/DrawerNavigationGroup.d.ts +2 -2
- package/dist/editor/components/SlashCommandMenu.d.ts +6 -0
- package/dist/editor/components/editor-bubble-item.d.ts +8 -0
- package/dist/editor/components/editor-bubble.d.ts +8 -0
- package/dist/editor/components/image-bubble.d.ts +5 -0
- package/dist/editor/components/index.d.ts +16 -0
- package/dist/editor/components/table-bubble.d.ts +5 -0
- package/dist/editor/editor.d.ts +30 -0
- package/dist/editor/extensions/HighlightDecorationExtension.d.ts +24 -0
- package/dist/editor/extensions/Image/index.d.ts +6 -0
- package/dist/editor/extensions/Image.d.ts +6 -0
- package/dist/editor/extensions/TextLoadingDecorationExtension.d.ts +16 -0
- package/dist/editor/extensions/clipboard.d.ts +7 -0
- package/dist/editor/extensions/custom-keymap.d.ts +1 -0
- package/dist/editor/extensions/drag-and-drop.d.ts +9 -0
- package/dist/editor/hooks/useProseMirror.d.ts +13 -0
- package/dist/editor/hooks/useProseMirrorContext.d.ts +9 -0
- package/dist/editor/index.d.ts +2 -0
- package/dist/editor/markdown.d.ts +5 -0
- package/dist/editor/nodeViews/ImageComponent.d.ts +3 -0
- package/dist/editor/nodeViews/ReactNodeView.d.ts +29 -0
- package/dist/editor/nodeViews/TaskItemComponent.d.ts +3 -0
- package/dist/editor/nodeViews/index.d.ts +6 -0
- package/dist/editor/plugins/index.d.ts +2 -0
- package/dist/editor/plugins/inputrules.d.ts +6 -0
- package/dist/editor/plugins/placeholderPlugin.d.ts +3 -0
- package/dist/editor/plugins/slashCommandPlugin.d.ts +12 -0
- package/dist/editor/schema.d.ts +2 -0
- package/dist/editor/selectors/ai-selector.d.ts +0 -0
- package/dist/editor/selectors/color-selector.d.ts +10 -0
- package/dist/editor/selectors/link-selector.d.ts +8 -0
- package/dist/editor/selectors/node-selector.d.ts +15 -0
- package/dist/editor/selectors/text-buttons.d.ts +1 -0
- package/dist/editor/types.d.ts +5 -0
- package/dist/editor/useProseMirror.d.ts +16 -0
- package/dist/editor/utils/prosemirror-utils.d.ts +6 -0
- package/dist/editor/utils/remove_classes.d.ts +1 -0
- package/dist/editor/utils/useDebouncedCallback.d.ts +1 -0
- package/dist/form/components/ErrorFocus.d.ts +1 -1
- package/dist/form/field_bindings/MarkdownEditorFieldBinding.d.ts +1 -1
- package/dist/hooks/index.d.ts +1 -0
- package/dist/hooks/useBuildNavigationController.d.ts +0 -1
- package/dist/hooks/useCollapsedGroups.d.ts +3 -3
- package/dist/hooks/useTranslation.d.ts +17 -0
- package/dist/i18n/FireCMSi18nProvider.d.ts +33 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.es.js +13009 -2312
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +12997 -2320
- package/dist/index.umd.js.map +1 -1
- package/dist/internal/useRestoreScroll.d.ts +1 -1
- package/dist/locales/de.d.ts +2 -0
- package/dist/locales/en.d.ts +10 -0
- package/dist/locales/es.d.ts +10 -0
- package/dist/locales/fr.d.ts +2 -0
- package/dist/locales/hi.d.ts +2 -0
- package/dist/locales/it.d.ts +2 -0
- package/dist/locales/pt.d.ts +7 -0
- package/dist/types/analytics.d.ts +1 -1
- package/dist/types/customization_controller.d.ts +2 -1
- package/dist/types/firecms.d.ts +2 -1
- package/dist/types/index.d.ts +1 -0
- package/dist/types/navigation.d.ts +2 -2
- package/dist/types/plugins.d.ts +23 -0
- package/dist/types/storage.d.ts +1 -0
- package/dist/types/translations.d.ts +646 -0
- package/dist/util/entities.d.ts +1 -1
- package/dist/util/resolutions.d.ts +2 -2
- package/dist/util/useStorageUploadController.d.ts +10 -1
- package/package.json +49 -13
- package/src/app/Scaffold.tsx +7 -5
- package/src/components/AIIcon.tsx +3 -1
- package/src/components/ArrayContainer.tsx +6 -4
- package/src/components/ClearFilterSortButton.tsx +6 -3
- package/src/components/ConfirmationDialog.tsx +4 -2
- package/src/components/DeleteEntityDialog.tsx +10 -7
- package/src/components/EntityCollectionTable/fields/TableReferenceField.tsx +6 -3
- package/src/components/EntityCollectionTable/internal/CollectionTableToolbar.tsx +3 -1
- package/src/components/EntityCollectionTable/internal/EntityTableCellActions.tsx +1 -1
- package/src/components/EntityCollectionTable/internal/popup_field/PopupFormField.tsx +3 -2
- package/src/components/EntityCollectionTable/internal/popup_field/useDraggable.tsx +11 -11
- package/src/components/EntityCollectionView/BoardSortableList.tsx +3 -1
- package/src/components/EntityCollectionView/CollectionDataErrorBanner.tsx +43 -0
- package/src/components/EntityCollectionView/EntityBoardCard.tsx +1 -1
- package/src/components/EntityCollectionView/EntityCard.tsx +4 -0
- package/src/components/EntityCollectionView/EntityCollectionBoardView.tsx +39 -46
- package/src/components/EntityCollectionView/EntityCollectionCardView.tsx +17 -25
- package/src/components/EntityCollectionView/EntityCollectionView.tsx +54 -17
- package/src/components/EntityCollectionView/EntityCollectionViewActions.tsx +4 -3
- package/src/components/EntityCollectionView/EntityCollectionViewStartActions.tsx +4 -2
- package/src/components/EntityCollectionView/FiltersDialog.tsx +8 -5
- package/src/components/EntityCollectionView/ViewModeToggle.tsx +11 -8
- package/src/components/EntityView.tsx +3 -2
- package/src/components/ErrorBoundary.tsx +27 -15
- package/src/components/HomePage/DefaultHomePage.tsx +19 -13
- package/src/components/HomePage/HomePageDnD.tsx +3 -1
- package/src/components/HomePage/NavigationGroup.tsx +3 -1
- package/src/components/HomePage/RenameGroupDialog.tsx +15 -13
- package/src/components/LanguageToggle.tsx +66 -0
- package/src/components/NotFoundPage.tsx +5 -3
- package/src/components/ReferenceTable/ReferenceSelectionTable.tsx +9 -7
- package/src/components/ReferenceWidget.tsx +3 -2
- package/src/components/SearchIconsView.tsx +3 -1
- package/src/components/SelectableTable/filters/DateTimeFilterField.tsx +11 -0
- package/src/components/SelectableTable/filters/ReferenceFilterField.tsx +15 -2
- package/src/components/SelectableTable/filters/StringNumberFilterField.tsx +11 -0
- package/src/components/UnsavedChangesDialog.tsx +6 -4
- package/src/components/VirtualTable/VirtualTable.performance.test.tsx +1 -0
- package/src/components/VirtualTable/VirtualTable.tsx +116 -113
- package/src/components/VirtualTable/VirtualTableHeader.tsx +54 -52
- package/src/components/VirtualTable/VirtualTableHeaderRow.tsx +1 -1
- package/src/components/VirtualTable/fields/VirtualTableSelect.tsx +3 -3
- package/src/components/common/default_entity_actions.tsx +4 -0
- package/src/components/common/useDataSourceTableController.tsx +12 -4
- package/src/components/index.tsx +1 -0
- package/src/core/DefaultAppBar.tsx +15 -11
- package/src/core/DefaultDrawer.tsx +8 -2
- package/src/core/DrawerNavigationGroup.tsx +5 -3
- package/src/core/EntityEditView.tsx +4 -3
- package/src/core/EntityEditViewFormActions.tsx +24 -17
- package/src/core/EntitySidePanel.tsx +32 -29
- package/src/core/FireCMS.tsx +33 -6
- package/src/core/field_configs.tsx +14 -9
- package/src/editor/components/SlashCommandMenu.tsx +516 -0
- package/src/editor/components/editor-bubble-item.tsx +32 -0
- package/src/editor/components/editor-bubble.tsx +118 -0
- package/src/editor/components/image-bubble.tsx +156 -0
- package/src/editor/components/index.ts +14 -0
- package/src/editor/components/table-bubble.tsx +165 -0
- package/src/editor/editor.tsx +455 -0
- package/src/editor/extensions/HighlightDecorationExtension.ts +114 -0
- package/src/editor/extensions/Image/index.ts +133 -0
- package/src/editor/extensions/Image.ts +159 -0
- package/src/editor/extensions/TextLoadingDecorationExtension.tsx +107 -0
- package/src/editor/extensions/clipboard.ts +72 -0
- package/src/editor/extensions/custom-keymap.ts +24 -0
- package/src/editor/extensions/drag-and-drop.tsx +480 -0
- package/src/editor/hooks/useProseMirror.ts +124 -0
- package/src/editor/hooks/useProseMirrorContext.ts +15 -0
- package/src/editor/index.ts +2 -0
- package/src/editor/markdown.ts +172 -0
- package/src/editor/nodeViews/ImageComponent.tsx +20 -0
- package/src/editor/nodeViews/ReactNodeView.tsx +89 -0
- package/src/editor/nodeViews/TaskItemComponent.tsx +29 -0
- package/src/editor/nodeViews/index.ts +35 -0
- package/src/editor/plugins/index.ts +58 -0
- package/src/editor/plugins/inputrules.ts +82 -0
- package/src/editor/plugins/placeholderPlugin.ts +55 -0
- package/src/editor/plugins/slashCommandPlugin.ts +61 -0
- package/src/editor/schema.ts +240 -0
- package/src/editor/selectors/ai-selector.tsx +111 -0
- package/src/editor/selectors/color-selector.tsx +200 -0
- package/src/editor/selectors/link-selector.tsx +118 -0
- package/src/editor/selectors/node-selector.tsx +157 -0
- package/src/editor/selectors/text-buttons.tsx +86 -0
- package/src/editor/types.ts +6 -0
- package/src/editor/useProseMirror.ts +126 -0
- package/src/editor/utils/prosemirror-utils.ts +108 -0
- package/src/editor/utils/remove_classes.ts +17 -0
- package/src/editor/utils/useDebouncedCallback.ts +25 -0
- package/src/form/EntityForm.tsx +85 -63
- package/src/form/EntityFormActions.tsx +19 -12
- package/src/form/PropertyFieldBinding.tsx +6 -5
- package/src/form/components/ErrorFocus.tsx +3 -3
- package/src/form/components/LocalChangesMenu.tsx +13 -13
- package/src/form/components/StorageItemPreview.tsx +3 -2
- package/src/form/components/StorageUploadProgress.tsx +18 -3
- package/src/form/field_bindings/ArrayOfReferencesFieldBinding.tsx +4 -4
- package/src/form/field_bindings/BlockFieldBinding.tsx +5 -2
- package/src/form/field_bindings/KeyValueFieldBinding.tsx +23 -18
- package/src/form/field_bindings/MapFieldBinding.tsx +4 -3
- package/src/form/field_bindings/MarkdownEditorFieldBinding.tsx +34 -20
- package/src/form/field_bindings/RepeatFieldBinding.tsx +3 -1
- package/src/form/field_bindings/StorageUploadFieldBinding.tsx +87 -86
- package/src/hooks/index.tsx +1 -0
- package/src/hooks/useBuildNavigationController.tsx +49 -22
- package/src/hooks/useCollapsedGroups.ts +7 -6
- package/src/hooks/useTranslation.ts +31 -0
- package/src/hooks/useValidateAuthenticator.tsx +1 -1
- package/src/i18n/FireCMSi18nProvider.tsx +160 -0
- package/src/index.ts +4 -0
- package/src/internal/useBuildDataSource.ts +1 -2
- package/src/internal/useBuildSideEntityController.tsx +22 -20
- package/src/locales/de.ts +691 -0
- package/src/locales/en.ts +703 -0
- package/src/locales/es.ts +703 -0
- package/src/locales/fr.ts +691 -0
- package/src/locales/hi.ts +691 -0
- package/src/locales/it.ts +691 -0
- package/src/locales/pt.ts +700 -0
- package/src/preview/PropertyPreview.tsx +1 -0
- package/src/preview/components/UrlComponentPreview.tsx +4 -2
- package/src/preview/components/UserPreview.tsx +3 -1
- package/src/types/analytics.ts +10 -0
- package/src/types/customization_controller.tsx +2 -1
- package/src/types/firecms.tsx +2 -1
- package/src/types/index.ts +1 -0
- package/src/types/navigation.ts +2 -2
- package/src/types/plugins.tsx +26 -0
- package/src/types/properties.ts +1 -0
- package/src/types/storage.ts +2 -1
- package/src/types/translations.ts +725 -0
- package/src/util/entities.ts +1 -1
- package/src/util/join_collections.ts +10 -8
- package/src/util/previews.ts +2 -2
- package/src/util/property_utils.tsx +1 -1
- package/src/util/resolutions.ts +5 -3
- 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
|
-
|
|
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
|
-
|
|
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>
|
|
40
|
+
onClick={handleCancel} autoFocus> {t("cancel")} </Button>
|
|
39
41
|
<Button
|
|
40
|
-
onClick={handleOk}>
|
|
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
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
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
|
-
|
|
62
|
+
ref={ref}
|
|
63
|
+
{...rest}
|
|
57
64
|
style={{
|
|
58
|
-
|
|
59
|
-
|
|
65
|
+
...rest?.style,
|
|
66
|
+
minHeight: "100%",
|
|
67
|
+
position: "relative"
|
|
60
68
|
}}>
|
|
61
|
-
<
|
|
62
|
-
|
|
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
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
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
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
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
|
-
|
|
289
|
-
|
|
290
|
-
|
|
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
|
-
|
|
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
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
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
|
-
{...
|
|
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
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
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
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
+
index,
|
|
509
|
+
style
|
|
510
|
+
}: any) => {
|
|
508
511
|
return <VirtualListContext.Consumer>
|
|
509
512
|
{({
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
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
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
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
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
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
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
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
|
|
262
|
-
<Button
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
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}
|