@firecms/core 3.0.0-canary.235 → 3.0.0-canary.239
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/EntityPreview.d.ts +4 -2
- package/dist/components/SelectableTable/SelectableTable.d.ts +1 -1
- package/dist/components/index.d.ts +1 -0
- package/dist/hooks/useBuildNavigationController.d.ts +2 -9
- package/dist/index.es.js +271 -144
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +271 -144
- package/dist/index.umd.js.map +1 -1
- package/dist/types/collections.d.ts +13 -0
- package/dist/types/plugins.d.ts +12 -0
- package/dist/types/side_entity_controller.d.ts +4 -0
- package/dist/util/callbacks.d.ts +2 -0
- package/dist/util/index.d.ts +1 -0
- package/package.json +5 -5
- package/src/components/ConfirmationDialog.tsx +9 -9
- package/src/components/EntityCollectionTable/PropertyTableCell.tsx +1 -1
- package/src/components/EntityCollectionTable/internal/CollectionTableToolbar.tsx +1 -1
- package/src/components/EntityCollectionView/EntityCollectionView.tsx +2 -0
- package/src/components/EntityPreview.tsx +18 -14
- package/src/components/ErrorView.tsx +1 -1
- package/src/components/HomePage/DefaultHomePage.tsx +1 -1
- package/src/components/SelectableTable/SelectableTable.tsx +140 -143
- package/src/components/VirtualTable/VirtualTable.tsx +7 -4
- package/src/components/index.tsx +2 -0
- package/src/core/EntityEditView.tsx +24 -14
- package/src/core/EntitySidePanel.tsx +17 -10
- package/src/form/components/LabelWithIcon.tsx +1 -1
- package/src/form/field_bindings/KeyValueFieldBinding.tsx +0 -2
- package/src/form/field_bindings/MarkdownEditorFieldBinding.tsx +1 -1
- package/src/form/field_bindings/MultiSelectFieldBinding.tsx +1 -1
- package/src/form/field_bindings/ReadOnlyFieldBinding.tsx +1 -1
- package/src/form/field_bindings/ReferenceFieldBinding.tsx +1 -1
- package/src/form/field_bindings/SelectFieldBinding.tsx +1 -1
- package/src/hooks/useBuildNavigationController.tsx +29 -16
- package/src/internal/useBuildSideEntityController.tsx +1 -1
- package/src/preview/components/ReferencePreview.tsx +1 -1
- package/src/preview/property_previews/ArrayOfMapsPreview.tsx +1 -1
- package/src/preview/property_previews/SkeletonPropertyComponent.tsx +1 -1
- package/src/types/collections.ts +16 -0
- package/src/types/firecms.tsx +0 -1
- package/src/types/plugins.tsx +16 -0
- package/src/types/side_entity_controller.tsx +5 -5
- package/src/util/callbacks.ts +119 -0
- package/src/util/index.ts +1 -0
|
@@ -293,6 +293,11 @@ export interface EntityCollection<M extends Record<string, any> = any, USER exte
|
|
|
293
293
|
* If set to true, a tab including the JSON representation of the entity will be included.
|
|
294
294
|
*/
|
|
295
295
|
includeJsonView?: boolean;
|
|
296
|
+
/**
|
|
297
|
+
* If set to true, changes to the entity will be saved in a subcollection.
|
|
298
|
+
* This prop has no effect if the history plugin is not enabled
|
|
299
|
+
*/
|
|
300
|
+
history?: boolean;
|
|
296
301
|
}
|
|
297
302
|
/**
|
|
298
303
|
* Parameter passed to the `Actions` prop in the collection configuration.
|
|
@@ -437,6 +442,10 @@ export type EntityCustomView<M extends Record<string, any> = any> = {
|
|
|
437
442
|
* Name of this custom view.
|
|
438
443
|
*/
|
|
439
444
|
name: string;
|
|
445
|
+
/**
|
|
446
|
+
* Render this custom view in the tab of the entity view, instead of the name
|
|
447
|
+
*/
|
|
448
|
+
tabComponent?: React.ReactNode;
|
|
440
449
|
/**
|
|
441
450
|
* If set to true, the actions of the entity (save, discard,delete) will be
|
|
442
451
|
* included in the view. By default the actions are located in the right or bottom,
|
|
@@ -448,6 +457,10 @@ export type EntityCustomView<M extends Record<string, any> = any> = {
|
|
|
448
457
|
* Builder for rendering the custom view
|
|
449
458
|
*/
|
|
450
459
|
Builder?: React.ComponentType<EntityCustomViewParams<M>>;
|
|
460
|
+
/**
|
|
461
|
+
* Position of this tab in the entity view. Defaults to `end`.
|
|
462
|
+
*/
|
|
463
|
+
position?: "start" | "end";
|
|
451
464
|
};
|
|
452
465
|
/**
|
|
453
466
|
* Parameters passed to the builder in charge of rendering a custom panel for
|
package/dist/types/plugins.d.ts
CHANGED
|
@@ -131,6 +131,18 @@ export type FireCMSPlugin<PROPS = any, FORM_PROPS = any, EC extends EntityCollec
|
|
|
131
131
|
fieldBuilder?: <T extends CMSType = CMSType>(props: PluginFieldBuilderParams<T, any, EC>) => React.ComponentType<FieldProps<T>> | null;
|
|
132
132
|
fieldBuilderEnabled?: <T extends CMSType = CMSType>(props: PluginFieldBuilderParams<T>) => boolean;
|
|
133
133
|
};
|
|
134
|
+
collection?: {
|
|
135
|
+
/**
|
|
136
|
+
* Use this method to modify a single collection before it is rendered.
|
|
137
|
+
* @param collection
|
|
138
|
+
*/
|
|
139
|
+
modifyCollection?: (collection: EntityCollection) => EntityCollection;
|
|
140
|
+
/**
|
|
141
|
+
* Use this method to modify, add or remove collections.
|
|
142
|
+
* @param collections
|
|
143
|
+
*/
|
|
144
|
+
injectCollections?: (collections: EntityCollection[]) => EntityCollection[];
|
|
145
|
+
};
|
|
134
146
|
};
|
|
135
147
|
/**
|
|
136
148
|
* Props passed to the {@link FireCMSPlugin.homePage.CollectionActions} method.
|
|
@@ -60,6 +60,10 @@ export interface EntitySidePanelProps<M extends Record<string, any> = any> {
|
|
|
60
60
|
* Override some form properties
|
|
61
61
|
*/
|
|
62
62
|
formProps?: Partial<EntityFormProps<M>>;
|
|
63
|
+
/**
|
|
64
|
+
* Allow the user to open the entity fullscreen
|
|
65
|
+
*/
|
|
66
|
+
allowFullScreen?: boolean;
|
|
63
67
|
}
|
|
64
68
|
/**
|
|
65
69
|
* Controller to open the side dialog displaying entity forms
|
package/dist/util/index.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@firecms/core",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "3.0.0-canary.
|
|
4
|
+
"version": "3.0.0-canary.239",
|
|
5
5
|
"description": "Awesome Firebase/Firestore-based headless open-source CMS",
|
|
6
6
|
"funding": {
|
|
7
7
|
"url": "https://github.com/sponsors/firecmsco"
|
|
@@ -50,9 +50,9 @@
|
|
|
50
50
|
"./package.json": "./package.json"
|
|
51
51
|
},
|
|
52
52
|
"dependencies": {
|
|
53
|
-
"@firecms/editor": "^3.0.0-canary.
|
|
54
|
-
"@firecms/formex": "^3.0.0-canary.
|
|
55
|
-
"@firecms/ui": "^3.0.0-canary.
|
|
53
|
+
"@firecms/editor": "^3.0.0-canary.239",
|
|
54
|
+
"@firecms/formex": "^3.0.0-canary.239",
|
|
55
|
+
"@firecms/ui": "^3.0.0-canary.239",
|
|
56
56
|
"@hello-pangea/dnd": "^17.0.0",
|
|
57
57
|
"@radix-ui/react-portal": "^1.1.3",
|
|
58
58
|
"clsx": "^2.1.1",
|
|
@@ -105,7 +105,7 @@
|
|
|
105
105
|
"dist",
|
|
106
106
|
"src"
|
|
107
107
|
],
|
|
108
|
-
"gitHead": "
|
|
108
|
+
"gitHead": "28e265bdb20ddd0d2eb813e9cbc2c082e17c2c65",
|
|
109
109
|
"publishConfig": {
|
|
110
110
|
"access": "public"
|
|
111
111
|
},
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
|
|
3
|
-
import { Button, Dialog, DialogActions, DialogContent, DialogTitle, LoadingButton
|
|
3
|
+
import { Button, Dialog, DialogActions, DialogContent, DialogTitle, LoadingButton } from "@firecms/ui";
|
|
4
4
|
|
|
5
5
|
export function ConfirmationDialog({
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
6
|
+
open,
|
|
7
|
+
onAccept,
|
|
8
|
+
onCancel,
|
|
9
|
+
title,
|
|
10
|
+
loading,
|
|
11
|
+
body
|
|
12
|
+
}: {
|
|
13
13
|
open: boolean,
|
|
14
14
|
onAccept: () => void,
|
|
15
15
|
onCancel: () => void,
|
|
@@ -38,7 +38,7 @@ export function ConfirmationDialog({
|
|
|
38
38
|
type="submit"
|
|
39
39
|
loading={loading}
|
|
40
40
|
onClick={onAccept}
|
|
41
|
-
|
|
41
|
+
autoFocus>
|
|
42
42
|
Ok
|
|
43
43
|
</LoadingButton>
|
|
44
44
|
</DialogActions>
|
|
@@ -394,7 +394,7 @@ export const PropertyTableCell = React.memo<PropertyTableCellProps<any>>(
|
|
|
394
394
|
size={size}
|
|
395
395
|
multiselect={true}
|
|
396
396
|
path={arrayProperty.of.path}
|
|
397
|
-
previewProperties={arrayProperty.of.
|
|
397
|
+
previewProperties={arrayProperty.of.previewKeys}
|
|
398
398
|
title={arrayProperty.name}
|
|
399
399
|
forceFilter={arrayProperty.of.forceFilter}
|
|
400
400
|
includeId={arrayProperty.of.includeId}
|
|
@@ -55,7 +55,7 @@ export function CollectionTableToolbar({
|
|
|
55
55
|
<Tooltip title={"Table row size"} side={"right"} sideOffset={4}>
|
|
56
56
|
<Select
|
|
57
57
|
value={size as string}
|
|
58
|
-
className="w-16
|
|
58
|
+
className="w-16 ml-2"
|
|
59
59
|
size={"small"}
|
|
60
60
|
onValueChange={(v) => onSizeChanged(v as CollectionSize)}
|
|
61
61
|
renderValue={(v) => <div className={"font-medium"}>{v.toUpperCase()}</div>}
|
|
@@ -753,6 +753,8 @@ export const EntityCollectionView = React.memo(
|
|
|
753
753
|
equal(a.additionalFields, b.additionalFields) &&
|
|
754
754
|
equal(a.sideDialogWidth, b.sideDialogWidth) &&
|
|
755
755
|
equal(a.openEntityMode, b.openEntityMode) &&
|
|
756
|
+
equal(a.exportable, b.exportable) &&
|
|
757
|
+
equal(a.history, b.history) &&
|
|
756
758
|
equal(a.forceFilter, b.forceFilter);
|
|
757
759
|
}) as React.FunctionComponent<EntityCollectionViewProps<any>>
|
|
758
760
|
|
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
getEntityImagePreviewPropertyKey,
|
|
8
8
|
getEntityPreviewKeys,
|
|
9
9
|
getEntityTitlePropertyKey,
|
|
10
|
+
getPropertyInPath,
|
|
10
11
|
getValueInPath,
|
|
11
12
|
IconForView,
|
|
12
13
|
resolveCollection
|
|
@@ -26,11 +27,13 @@ export type EntityPreviewProps = {
|
|
|
26
27
|
actions?: React.ReactNode,
|
|
27
28
|
collection?: EntityCollection,
|
|
28
29
|
hover?: boolean;
|
|
29
|
-
|
|
30
|
+
previewKeys?: string[],
|
|
30
31
|
disabled?: boolean,
|
|
31
32
|
entity: Entity<any>,
|
|
32
33
|
includeId?: boolean,
|
|
34
|
+
includeTitle?: boolean,
|
|
33
35
|
includeEntityLink?: boolean,
|
|
36
|
+
includeImage?: boolean,
|
|
34
37
|
onClick?: (e: React.SyntheticEvent) => void;
|
|
35
38
|
};
|
|
36
39
|
|
|
@@ -43,12 +46,14 @@ export function EntityPreview({
|
|
|
43
46
|
disabled,
|
|
44
47
|
hover,
|
|
45
48
|
collection: collectionProp,
|
|
46
|
-
|
|
49
|
+
previewKeys,
|
|
47
50
|
onClick,
|
|
48
51
|
size,
|
|
49
52
|
includeId = true,
|
|
53
|
+
includeTitle = true,
|
|
50
54
|
includeEntityLink = true,
|
|
51
|
-
|
|
55
|
+
includeImage = true,
|
|
56
|
+
entity,
|
|
52
57
|
}: EntityPreviewProps) {
|
|
53
58
|
|
|
54
59
|
const authController = useAuthController();
|
|
@@ -72,11 +77,11 @@ export function EntityPreview({
|
|
|
72
77
|
authController
|
|
73
78
|
}), [collection]);
|
|
74
79
|
|
|
75
|
-
const listProperties = useMemo(() => getEntityPreviewKeys(authController, resolvedCollection, customizationController.propertyConfigs,
|
|
76
|
-
[
|
|
80
|
+
const listProperties = useMemo(() => previewKeys ?? getEntityPreviewKeys(authController, resolvedCollection, customizationController.propertyConfigs, previewKeys, size === "medium" || size === "large" ? 3 : 1),
|
|
81
|
+
[previewKeys, resolvedCollection, size]);
|
|
77
82
|
|
|
78
|
-
const titleProperty = getEntityTitlePropertyKey(resolvedCollection, customizationController.propertyConfigs);
|
|
79
|
-
const imagePropertyKey = getEntityImagePreviewPropertyKey(resolvedCollection);
|
|
83
|
+
const titleProperty = includeTitle ? getEntityTitlePropertyKey(resolvedCollection, customizationController.propertyConfigs) : undefined;
|
|
84
|
+
const imagePropertyKey = includeImage ? getEntityImagePreviewPropertyKey(resolvedCollection) : undefined;
|
|
80
85
|
const imageProperty = imagePropertyKey ? resolvedCollection.properties[imagePropertyKey] : undefined;
|
|
81
86
|
const usedImageProperty = imageProperty && "of" in imageProperty ? imageProperty.of : imageProperty;
|
|
82
87
|
const restProperties = listProperties.filter(p => p !== titleProperty && p !== imagePropertyKey);
|
|
@@ -103,9 +108,7 @@ export function EntityPreview({
|
|
|
103
108
|
</div>
|
|
104
109
|
|
|
105
110
|
|
|
106
|
-
<div className={"flex flex-col grow
|
|
107
|
-
"maxWidth": "calc(100% - 96px)"
|
|
108
|
-
}}>
|
|
111
|
+
<div className={"flex flex-col grow w-full m-1 shrink min-w-0"}>
|
|
109
112
|
|
|
110
113
|
{size !== "small" && includeId && (
|
|
111
114
|
entity
|
|
@@ -135,9 +138,10 @@ export function EntityPreview({
|
|
|
135
138
|
)}
|
|
136
139
|
|
|
137
140
|
{restProperties && restProperties.map((key) => {
|
|
138
|
-
const childProperty = resolvedCollection.properties
|
|
141
|
+
const childProperty = getPropertyInPath(resolvedCollection.properties, key);
|
|
139
142
|
if (!childProperty) return null;
|
|
140
143
|
|
|
144
|
+
const valueInPath = getValueInPath(entity.values, key);
|
|
141
145
|
return (
|
|
142
146
|
<div key={"ref_prev_" + key}
|
|
143
147
|
className={cls("truncate", restProperties.length > 1 ? "my-0.5" : "my-0")}>
|
|
@@ -145,7 +149,7 @@ export function EntityPreview({
|
|
|
145
149
|
entity
|
|
146
150
|
? <PropertyPreview
|
|
147
151
|
propertyKey={key as string}
|
|
148
|
-
value={
|
|
152
|
+
value={valueInPath}
|
|
149
153
|
property={childProperty as ResolvedProperty}
|
|
150
154
|
size={"small"}/>
|
|
151
155
|
: <SkeletonPropertyComponent
|
|
@@ -162,7 +166,7 @@ export function EntityPreview({
|
|
|
162
166
|
<Tooltip title={`See details for ${entity.id}`} className={"shrink-0"}>
|
|
163
167
|
<IconButton
|
|
164
168
|
color={"inherit"}
|
|
165
|
-
size={"
|
|
169
|
+
size={"small"}
|
|
166
170
|
className={size !== "small" ? "self-start" : ""}
|
|
167
171
|
onClick={(e) => {
|
|
168
172
|
e.stopPropagation();
|
|
@@ -177,7 +181,7 @@ export function EntityPreview({
|
|
|
177
181
|
updateUrl: true
|
|
178
182
|
});
|
|
179
183
|
}}>
|
|
180
|
-
<KeyboardTabIcon size={"
|
|
184
|
+
<KeyboardTabIcon size={"small"}/>
|
|
181
185
|
</IconButton>
|
|
182
186
|
</Tooltip>}
|
|
183
187
|
|
|
@@ -179,7 +179,7 @@ export function DefaultHomePage({
|
|
|
179
179
|
|
|
180
180
|
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
|
|
181
181
|
{thisGroupCollections.map((entry) => (
|
|
182
|
-
<div key={`nav_${entry.group}_${entry.name}`} className="col-span-1">
|
|
182
|
+
<div key={`nav_${entry.group}_${entry.path}_${entry.name}`} className="col-span-1">
|
|
183
183
|
<NavigationCardBinding
|
|
184
184
|
{...entry}
|
|
185
185
|
onClick={() => {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { useCallback, useEffect, useRef } from "react";
|
|
1
|
+
import React, { useCallback, useEffect, useMemo, useRef } from "react";
|
|
2
2
|
import {
|
|
3
3
|
CollectionSize,
|
|
4
4
|
Entity,
|
|
@@ -119,150 +119,147 @@ export type SelectableTableProps<M extends Record<string, any>> = {
|
|
|
119
119
|
* @see VirtualTable
|
|
120
120
|
* @group Components
|
|
121
121
|
*/
|
|
122
|
-
export const SelectableTable =
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
122
|
+
export const SelectableTable = function SelectableTable<M extends Record<string, any>>
|
|
123
|
+
({
|
|
124
|
+
onValueChange,
|
|
125
|
+
cellRenderer,
|
|
126
|
+
onEntityClick,
|
|
127
|
+
onColumnResize,
|
|
128
|
+
hoverRow = true,
|
|
129
|
+
size = "m",
|
|
130
|
+
inlineEditing = false,
|
|
131
|
+
tableController:
|
|
132
|
+
{
|
|
133
|
+
data,
|
|
134
|
+
dataLoading,
|
|
135
|
+
noMoreToLoad,
|
|
136
|
+
dataLoadingError,
|
|
137
|
+
filterValues,
|
|
138
|
+
setFilterValues,
|
|
139
|
+
sortBy,
|
|
140
|
+
setSortBy,
|
|
141
|
+
itemCount,
|
|
142
|
+
setItemCount,
|
|
143
|
+
pageSize = 50,
|
|
144
|
+
paginationEnabled,
|
|
145
|
+
checkFilterCombination,
|
|
146
|
+
setPopupCell
|
|
147
|
+
},
|
|
148
|
+
filterable = true,
|
|
149
|
+
onScroll,
|
|
150
|
+
initialScroll,
|
|
151
|
+
emptyComponent,
|
|
152
|
+
columns,
|
|
153
|
+
forceFilter,
|
|
154
|
+
highlightedRow,
|
|
155
|
+
endAdornment,
|
|
156
|
+
AddColumnComponent
|
|
157
|
+
}: SelectableTableProps<M>) {
|
|
158
|
+
|
|
159
|
+
const ref = useRef<HTMLDivElement>(null);
|
|
160
|
+
|
|
161
|
+
const [selectedCell, setSelectedCell] = React.useState<SelectedCellProps<M> | undefined>(undefined);
|
|
162
|
+
|
|
163
|
+
const loadNextPage = () => {
|
|
164
|
+
if (!paginationEnabled || dataLoading || noMoreToLoad)
|
|
165
|
+
return;
|
|
166
|
+
if (itemCount !== undefined)
|
|
167
|
+
setItemCount?.(itemCount + pageSize);
|
|
168
|
+
};
|
|
169
|
+
|
|
170
|
+
const resetPagination = useCallback(() => {
|
|
171
|
+
setItemCount?.(pageSize);
|
|
172
|
+
}, [pageSize]);
|
|
173
|
+
|
|
174
|
+
const onRowClick = useCallback(({ rowData }: {
|
|
175
|
+
rowData: Entity<M>
|
|
176
|
+
}) => {
|
|
177
|
+
if (inlineEditing)
|
|
178
|
+
return;
|
|
179
|
+
return onEntityClick && onEntityClick(rowData);
|
|
180
|
+
}, [onEntityClick, inlineEditing]);
|
|
181
|
+
|
|
182
|
+
useOutsideAlerter(ref,
|
|
183
|
+
() => {
|
|
184
|
+
if (selectedCell) {
|
|
185
|
+
unselect();
|
|
186
|
+
}
|
|
187
|
+
},
|
|
188
|
+
Boolean(selectedCell));
|
|
189
|
+
|
|
190
|
+
const select = useCallback((cell?: SelectedCellProps<M>) => {
|
|
191
|
+
setSelectedCell(cell);
|
|
192
|
+
}, []);
|
|
193
|
+
|
|
194
|
+
const unselect = useCallback(() => {
|
|
195
|
+
setSelectedCell(undefined);
|
|
196
|
+
}, []);
|
|
197
|
+
|
|
198
|
+
// on ESC key press
|
|
199
|
+
useEffect(() => {
|
|
200
|
+
const escFunction = (event: any) => {
|
|
201
|
+
if (event.keyCode === 27) {
|
|
202
|
+
unselect();
|
|
203
|
+
}
|
|
169
204
|
};
|
|
205
|
+
document.addEventListener("keydown", escFunction, false);
|
|
206
|
+
return () => {
|
|
207
|
+
document.removeEventListener("keydown", escFunction, false);
|
|
208
|
+
};
|
|
209
|
+
}, [unselect]);
|
|
210
|
+
|
|
211
|
+
const onFilterUpdate = useCallback((updatedFilterValues?: FilterValues<any>) => {
|
|
212
|
+
setFilterValues?.({ ...updatedFilterValues, ...forceFilter } as FilterValues<any>);
|
|
213
|
+
}, [forceFilter]);
|
|
214
|
+
|
|
215
|
+
const contextValue = useMemo(() => ({
|
|
216
|
+
setPopupCell: setPopupCell as ((cell?: SelectedCellProps<M>) => void),
|
|
217
|
+
select,
|
|
218
|
+
onValueChange,
|
|
219
|
+
size: size ?? "m",
|
|
220
|
+
selectedCell
|
|
221
|
+
}), [setPopupCell, select, onValueChange, size, selectedCell]);
|
|
222
|
+
|
|
223
|
+
return (
|
|
224
|
+
<SelectableTableContext.Provider
|
|
225
|
+
value={contextValue}>
|
|
226
|
+
<div className="h-full w-full flex flex-col bg-white dark:bg-surface-950"
|
|
227
|
+
ref={ref}>
|
|
228
|
+
|
|
229
|
+
<VirtualTable
|
|
230
|
+
data={data}
|
|
231
|
+
columns={columns}
|
|
232
|
+
cellRenderer={cellRenderer}
|
|
233
|
+
onRowClick={inlineEditing ? undefined : (onEntityClick ? onRowClick : undefined)}
|
|
234
|
+
onEndReached={loadNextPage}
|
|
235
|
+
onResetPagination={resetPagination}
|
|
236
|
+
error={dataLoadingError}
|
|
237
|
+
onColumnResize={onColumnResize}
|
|
238
|
+
rowHeight={getRowHeight(size)}
|
|
239
|
+
loading={dataLoading}
|
|
240
|
+
filter={filterValues}
|
|
241
|
+
onFilterUpdate={setFilterValues ? onFilterUpdate : undefined}
|
|
242
|
+
sortBy={sortBy}
|
|
243
|
+
onSortByUpdate={setSortBy as ((sortBy?: [string, "asc" | "desc"]) => void)}
|
|
244
|
+
hoverRow={hoverRow}
|
|
245
|
+
initialScroll={initialScroll}
|
|
246
|
+
onScroll={onScroll}
|
|
247
|
+
checkFilterCombination={checkFilterCombination}
|
|
248
|
+
createFilterField={filterable ? createFilterField : undefined}
|
|
249
|
+
rowClassName={useCallback((entity: Entity<M>) => {
|
|
250
|
+
return highlightedRow?.(entity) ? "bg-surface-100 bg-opacity-75 dark:bg-surface-800 dark:bg-opacity-75" : "";
|
|
251
|
+
}, [highlightedRow])}
|
|
252
|
+
className="flex-grow"
|
|
253
|
+
emptyComponent={emptyComponent}
|
|
254
|
+
endAdornment={endAdornment}
|
|
255
|
+
AddColumnComponent={AddColumnComponent}
|
|
256
|
+
/>
|
|
257
|
+
|
|
258
|
+
</div>
|
|
259
|
+
</SelectableTableContext.Provider>
|
|
260
|
+
);
|
|
170
261
|
|
|
171
|
-
|
|
172
|
-
setItemCount?.(pageSize);
|
|
173
|
-
}, [pageSize]);
|
|
174
|
-
|
|
175
|
-
const onRowClick = useCallback(({ rowData }: {
|
|
176
|
-
rowData: Entity<M>
|
|
177
|
-
}) => {
|
|
178
|
-
if (inlineEditing)
|
|
179
|
-
return;
|
|
180
|
-
return onEntityClick && onEntityClick(rowData);
|
|
181
|
-
}, [onEntityClick, inlineEditing]);
|
|
182
|
-
|
|
183
|
-
useOutsideAlerter(ref,
|
|
184
|
-
() => {
|
|
185
|
-
if (selectedCell) {
|
|
186
|
-
unselect();
|
|
187
|
-
}
|
|
188
|
-
},
|
|
189
|
-
Boolean(selectedCell));
|
|
190
|
-
|
|
191
|
-
// on ESC key press
|
|
192
|
-
useEffect(() => {
|
|
193
|
-
const escFunction = (event: any) => {
|
|
194
|
-
if (event.keyCode === 27) {
|
|
195
|
-
unselect();
|
|
196
|
-
}
|
|
197
|
-
};
|
|
198
|
-
document.addEventListener("keydown", escFunction, false);
|
|
199
|
-
return () => {
|
|
200
|
-
document.removeEventListener("keydown", escFunction, false);
|
|
201
|
-
};
|
|
202
|
-
});
|
|
203
|
-
|
|
204
|
-
const select = useCallback((cell?: SelectedCellProps<M>) => {
|
|
205
|
-
setSelectedCell(cell);
|
|
206
|
-
}, []);
|
|
207
|
-
|
|
208
|
-
const unselect = useCallback(() => {
|
|
209
|
-
setSelectedCell(undefined);
|
|
210
|
-
}, []);
|
|
211
|
-
|
|
212
|
-
const onFilterUpdate = useCallback((updatedFilterValues?: FilterValues<any>) => {
|
|
213
|
-
setFilterValues?.({ ...updatedFilterValues, ...forceFilter } as FilterValues<any>);
|
|
214
|
-
}, [forceFilter]);
|
|
215
|
-
|
|
216
|
-
return (
|
|
217
|
-
<SelectableTableContext.Provider
|
|
218
|
-
value={{
|
|
219
|
-
setPopupCell: setPopupCell as ((cell?: SelectedCellProps<M>) => void),
|
|
220
|
-
select,
|
|
221
|
-
onValueChange,
|
|
222
|
-
size: size ?? "m",
|
|
223
|
-
selectedCell,
|
|
224
|
-
}}
|
|
225
|
-
>
|
|
226
|
-
<div className="h-full w-full flex flex-col bg-white dark:bg-surface-950"
|
|
227
|
-
ref={ref}>
|
|
228
|
-
|
|
229
|
-
<VirtualTable
|
|
230
|
-
data={data}
|
|
231
|
-
columns={columns}
|
|
232
|
-
cellRenderer={cellRenderer}
|
|
233
|
-
onRowClick={inlineEditing ? undefined : (onEntityClick ? onRowClick : undefined)}
|
|
234
|
-
onEndReached={loadNextPage}
|
|
235
|
-
onResetPagination={resetPagination}
|
|
236
|
-
error={dataLoadingError}
|
|
237
|
-
onColumnResize={onColumnResize}
|
|
238
|
-
rowHeight={getRowHeight(size)}
|
|
239
|
-
loading={dataLoading}
|
|
240
|
-
filter={filterValues}
|
|
241
|
-
onFilterUpdate={setFilterValues ? onFilterUpdate : undefined}
|
|
242
|
-
sortBy={sortBy}
|
|
243
|
-
onSortByUpdate={setSortBy as ((sortBy?: [string, "asc" | "desc"]) => void)}
|
|
244
|
-
hoverRow={hoverRow}
|
|
245
|
-
initialScroll={initialScroll}
|
|
246
|
-
onScroll={onScroll}
|
|
247
|
-
checkFilterCombination={checkFilterCombination}
|
|
248
|
-
createFilterField={filterable ? createFilterField : undefined}
|
|
249
|
-
rowClassName={useCallback((entity: Entity<M>) => {
|
|
250
|
-
return highlightedRow?.(entity) ? "bg-surface-100 bg-opacity-75 dark:bg-surface-800 dark:bg-opacity-75" : "";
|
|
251
|
-
}, [highlightedRow])}
|
|
252
|
-
className="flex-grow"
|
|
253
|
-
emptyComponent={emptyComponent}
|
|
254
|
-
endAdornment={endAdornment}
|
|
255
|
-
AddColumnComponent={AddColumnComponent}
|
|
256
|
-
/>
|
|
257
|
-
|
|
258
|
-
</div>
|
|
259
|
-
</SelectableTableContext.Provider>
|
|
260
|
-
);
|
|
261
|
-
|
|
262
|
-
},
|
|
263
|
-
() => false,
|
|
264
|
-
// equal
|
|
265
|
-
);
|
|
262
|
+
};
|
|
266
263
|
|
|
267
264
|
function createFilterField({
|
|
268
265
|
id,
|
|
@@ -170,10 +170,13 @@ export const VirtualTable = React.memo<VirtualTableProps<any>>(
|
|
|
170
170
|
});
|
|
171
171
|
|
|
172
172
|
const onColumnResizeInternal = useCallback((params: OnVirtualTableColumnResizeParams) => {
|
|
173
|
-
if (debug)
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
173
|
+
if (debug) console.log("onColumnResizeInternal", params);
|
|
174
|
+
setColumns(prevColumns =>
|
|
175
|
+
prevColumns.map((column) =>
|
|
176
|
+
column.key === params.column.key ? params.column : column
|
|
177
|
+
)
|
|
178
|
+
);
|
|
179
|
+
}, []);
|
|
177
180
|
|
|
178
181
|
const onColumnResizeEndInternal = useCallback((params: OnVirtualTableColumnResizeParams) => {
|
|
179
182
|
if (debug)
|