@firecms/core 3.0.0-canary.6 → 3.0.0-canary.61
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/README.md +2 -2
- package/dist/components/ClearFilterSortButton.d.ts +5 -0
- package/dist/components/EntityCollectionTable/EntityCollectionRowActions.d.ts +11 -11
- package/dist/components/EntityCollectionTable/EntityCollectionTable.d.ts +2 -2
- package/dist/components/EntityCollectionTable/EntityCollectionTableProps.d.ts +5 -3
- package/dist/components/EntityCollectionTable/PropertyTableCell.d.ts +3 -2
- package/dist/components/EntityCollectionTable/column_utils.d.ts +1 -2
- package/dist/components/EntityCollectionTable/fields/TableReferenceField.d.ts +2 -0
- package/dist/components/EntityCollectionTable/internal/CollectionTableToolbar.d.ts +1 -4
- package/dist/components/EntityCollectionTable/internal/EntityTableCell.d.ts +2 -2
- package/dist/components/EntityCollectionTable/internal/popup_field/PopupFormField.d.ts +1 -1
- package/dist/components/EntityCollectionView/EntityCollectionView.d.ts +12 -3
- package/dist/components/EntityCollectionView/EntityCollectionViewStartActions.d.ts +11 -0
- package/dist/components/EntityCollectionView/useSelectionController.d.ts +2 -0
- package/dist/components/EntityPreview.d.ts +26 -7
- package/dist/components/EntityView.d.ts +11 -0
- package/dist/components/FieldCaption.d.ts +5 -0
- package/dist/components/FireCMSAppBar.d.ts +4 -2
- package/dist/components/HomePage/NavigationCard.d.ts +8 -0
- package/dist/components/HomePage/{NavigationCollectionCard.d.ts → NavigationCardBinding.d.ts} +2 -2
- package/dist/components/HomePage/SmallNavigationCard.d.ts +6 -0
- package/dist/components/HomePage/index.d.ts +3 -1
- package/dist/components/ReferenceWidget.d.ts +3 -1
- package/dist/components/SelectableTable/SelectableTable.d.ts +1 -1
- package/dist/components/SelectableTable/filters/ReferenceFilterField.d.ts +2 -1
- package/dist/components/VirtualTable/VirtualTableProps.d.ts +6 -7
- package/dist/components/VirtualTable/types.d.ts +3 -3
- package/dist/components/{EntityCollectionTable/internal → common}/default_entity_actions.d.ts +1 -1
- package/dist/components/common/index.d.ts +1 -0
- package/dist/components/common/table_height.d.ts +5 -0
- package/dist/components/common/types.d.ts +4 -6
- package/dist/components/common/useDataSourceEntityCollectionTableController.d.ts +3 -0
- package/dist/components/index.d.ts +5 -2
- package/dist/contexts/AuthControllerContext.d.ts +1 -1
- package/dist/core/Drawer.d.ts +5 -12
- package/dist/core/DrawerNavigationItem.d.ts +9 -0
- package/dist/core/{EntityView.d.ts → EntityEditView.d.ts} +2 -2
- package/dist/core/NavigationRoutes.d.ts +1 -1
- package/dist/core/Scaffold.d.ts +8 -12
- package/dist/core/index.d.ts +3 -4
- package/dist/form/EntityForm.d.ts +1 -1
- package/dist/form/components/ErrorFocus.d.ts +1 -1
- package/dist/form/components/StorageItemPreview.d.ts +3 -2
- package/dist/form/components/StorageUploadProgress.d.ts +1 -1
- package/dist/form/field_bindings/KeyValueFieldBinding.d.ts +1 -1
- package/dist/form/field_bindings/MapFieldBinding.d.ts +1 -1
- package/dist/form/field_bindings/StorageUploadFieldBinding.d.ts +4 -3
- package/dist/form/field_bindings/TextFieldBinding.d.ts +2 -2
- package/dist/form/validation.d.ts +1 -1
- package/dist/hooks/data/delete.d.ts +2 -2
- package/dist/hooks/data/save.d.ts +2 -3
- package/dist/hooks/data/useDataSource.d.ts +2 -2
- package/dist/hooks/data/useEntityFetch.d.ts +3 -3
- package/dist/hooks/index.d.ts +2 -0
- package/dist/hooks/useBuildNavigationController.d.ts +6 -4
- package/dist/hooks/useProjectLog.d.ts +6 -2
- package/dist/hooks/useStorageSource.d.ts +2 -2
- package/dist/hooks/useValidateAuthenticator.d.ts +21 -0
- package/dist/index.es.js +10498 -9944
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +5 -5
- package/dist/index.umd.js.map +1 -1
- package/dist/internal/useBuildDataSource.d.ts +1 -16
- package/dist/preview/PropertyPreview.d.ts +1 -1
- package/dist/preview/PropertyPreviewProps.d.ts +1 -4
- package/dist/preview/components/BooleanPreview.d.ts +5 -1
- package/dist/preview/components/EnumValuesChip.d.ts +1 -1
- package/dist/preview/components/ReferencePreview.d.ts +3 -8
- package/dist/types/analytics.d.ts +1 -1
- package/dist/types/auth.d.ts +37 -1
- package/dist/types/collections.d.ts +30 -6
- package/dist/types/datasource.d.ts +21 -14
- package/dist/types/entities.d.ts +5 -1
- package/dist/types/entity_actions.d.ts +14 -0
- package/dist/types/entity_callbacks.d.ts +2 -2
- package/dist/types/entity_overrides.d.ts +6 -0
- package/dist/types/index.d.ts +2 -1
- package/dist/types/navigation.d.ts +15 -14
- package/dist/types/permissions.d.ts +5 -1
- package/dist/types/plugins.d.ts +20 -20
- package/dist/types/properties.d.ts +12 -4
- package/dist/types/property_config.d.ts +2 -2
- package/dist/types/roles.d.ts +31 -0
- package/dist/types/storage.d.ts +11 -3
- package/dist/types/user.d.ts +5 -0
- package/dist/util/collections.d.ts +9 -1
- package/dist/util/entities.d.ts +1 -1
- package/dist/util/icon_synonyms.d.ts +1 -97
- package/dist/util/icons.d.ts +8 -2
- package/dist/util/navigation_utils.d.ts +2 -2
- package/dist/util/objects.d.ts +1 -1
- package/dist/util/permissions.d.ts +4 -4
- package/dist/util/references.d.ts +4 -2
- package/dist/util/resolutions.d.ts +14 -14
- package/dist/util/useTraceUpdate.d.ts +1 -0
- package/package.json +139 -119
- package/src/components/ClearFilterSortButton.tsx +41 -0
- package/src/components/DeleteEntityDialog.tsx +4 -4
- package/src/components/EntityCollectionTable/EntityCollectionRowActions.tsx +4 -4
- package/src/components/EntityCollectionTable/EntityCollectionTable.tsx +276 -279
- package/src/components/EntityCollectionTable/EntityCollectionTableProps.tsx +9 -5
- package/src/components/EntityCollectionTable/PropertyTableCell.tsx +48 -45
- package/src/components/EntityCollectionTable/column_utils.tsx +3 -3
- package/src/components/EntityCollectionTable/fields/TableReferenceField.tsx +18 -17
- package/src/components/EntityCollectionTable/fields/TableStorageUpload.tsx +5 -5
- package/src/components/EntityCollectionTable/internal/CollectionTableToolbar.tsx +29 -34
- package/src/components/EntityCollectionTable/internal/EntityTableCell.tsx +16 -12
- package/src/components/EntityCollectionTable/internal/popup_field/PopupFormField.tsx +2 -4
- package/src/components/EntityCollectionView/EntityCollectionView.tsx +73 -72
- package/src/components/EntityCollectionView/EntityCollectionViewActions.tsx +5 -6
- package/src/components/EntityCollectionView/EntityCollectionViewStartActions.tsx +68 -0
- package/src/components/EntityCollectionView/useSelectionController.tsx +30 -0
- package/src/components/EntityPreview.tsx +209 -70
- package/src/components/EntityView.tsx +84 -0
- package/src/components/FieldCaption.tsx +14 -0
- package/src/components/FireCMSAppBar.tsx +40 -15
- package/src/components/HomePage/DefaultHomePage.tsx +15 -11
- package/src/components/HomePage/NavigationCard.tsx +69 -0
- package/src/components/HomePage/NavigationCardBinding.tsx +116 -0
- package/src/components/HomePage/SmallNavigationCard.tsx +45 -0
- package/src/components/HomePage/index.tsx +3 -1
- package/src/components/PropertyIdCopyTooltipContent.tsx +2 -3
- package/src/components/ReferenceTable/ReferenceSelectionTable.tsx +4 -4
- package/src/components/ReferenceWidget.tsx +22 -12
- package/src/components/SearchIconsView.tsx +5 -5
- package/src/components/SelectableTable/SelectableTable.tsx +5 -3
- package/src/components/SelectableTable/filters/BooleanFilterField.tsx +2 -3
- package/src/components/SelectableTable/filters/DateTimeFilterField.tsx +23 -8
- package/src/components/SelectableTable/filters/ReferenceFilterField.tsx +38 -24
- package/src/components/SelectableTable/filters/StringNumberFilterField.tsx +35 -15
- package/src/components/VirtualTable/VirtualTable.tsx +38 -29
- package/src/components/VirtualTable/VirtualTableHeader.tsx +4 -4
- package/src/components/VirtualTable/VirtualTableHeaderRow.tsx +2 -2
- package/src/components/VirtualTable/VirtualTableProps.tsx +7 -7
- package/src/components/VirtualTable/VirtualTableRow.tsx +4 -5
- package/src/components/VirtualTable/fields/VirtualTableDateField.tsx +1 -1
- package/src/components/VirtualTable/types.tsx +2 -3
- package/src/components/{EntityCollectionTable/internal → common}/default_entity_actions.tsx +11 -7
- package/src/components/common/index.ts +1 -0
- package/src/components/{VirtualTable/common.tsx → common/table_height.tsx} +5 -2
- package/src/components/common/types.tsx +4 -6
- package/src/components/common/useColumnsIds.tsx +10 -2
- package/src/components/common/useDataSourceEntityCollectionTableController.tsx +12 -1
- package/src/components/common/useTableSearchHelper.ts +39 -9
- package/src/components/index.tsx +5 -2
- package/src/contexts/AuthControllerContext.tsx +1 -1
- package/src/core/Drawer.tsx +78 -103
- package/src/core/DrawerNavigationItem.tsx +62 -0
- package/src/core/{EntityView.tsx → EntityEditView.tsx} +27 -45
- package/src/core/EntitySidePanel.tsx +3 -3
- package/src/core/FireCMS.tsx +54 -43
- package/src/core/NavigationRoutes.tsx +11 -4
- package/src/core/Scaffold.tsx +80 -66
- package/src/core/field_configs.tsx +2 -3
- package/src/core/index.tsx +3 -4
- package/src/form/EntityForm.tsx +42 -27
- package/src/form/PropertyFieldBinding.tsx +0 -2
- package/src/form/components/StorageItemPreview.tsx +7 -5
- package/src/form/components/StorageUploadProgress.tsx +9 -8
- package/src/form/field_bindings/ArrayOfReferencesFieldBinding.tsx +10 -12
- package/src/form/field_bindings/BlockFieldBinding.tsx +2 -2
- package/src/form/field_bindings/DateTimeFieldBinding.tsx +1 -1
- package/src/form/field_bindings/KeyValueFieldBinding.tsx +19 -19
- package/src/form/field_bindings/MapFieldBinding.tsx +15 -15
- package/src/form/field_bindings/MarkdownFieldBinding.tsx +2 -2
- package/src/form/field_bindings/ReadOnlyFieldBinding.tsx +3 -3
- package/src/form/field_bindings/ReferenceFieldBinding.tsx +16 -13
- package/src/form/field_bindings/SelectFieldBinding.tsx +3 -3
- package/src/form/field_bindings/StorageUploadFieldBinding.tsx +18 -9
- package/src/form/field_bindings/TextFieldBinding.tsx +7 -5
- package/src/form/validation.ts +3 -4
- package/src/hooks/data/delete.ts +3 -3
- package/src/hooks/data/save.ts +4 -2
- package/src/hooks/data/useCollectionFetch.tsx +1 -1
- package/src/hooks/data/useDataSource.tsx +8 -3
- package/src/hooks/data/useEntityFetch.tsx +4 -4
- package/src/hooks/index.tsx +3 -0
- package/src/hooks/useBuildLocalConfigurationPersistence.tsx +8 -10
- package/src/hooks/useBuildModeController.tsx +11 -5
- package/src/hooks/useBuildNavigationController.tsx +200 -83
- package/src/hooks/useProjectLog.tsx +17 -7
- package/src/hooks/useReferenceDialog.tsx +2 -2
- package/src/hooks/useResolvedNavigationFrom.tsx +1 -1
- package/src/hooks/useStorageSource.tsx +7 -2
- package/src/hooks/useValidateAuthenticator.tsx +115 -0
- package/src/internal/useBuildDataSource.ts +54 -47
- package/src/internal/useBuildSideEntityController.tsx +88 -21
- package/src/preview/PropertyPreview.tsx +5 -15
- package/src/preview/PropertyPreviewProps.tsx +1 -11
- package/src/preview/components/BooleanPreview.tsx +19 -4
- package/src/preview/components/EnumValuesChip.tsx +2 -2
- package/src/preview/components/ReferencePreview.tsx +72 -165
- package/src/preview/property_previews/ArrayOfMapsPreview.tsx +0 -1
- package/src/preview/property_previews/ArrayOfReferencesPreview.tsx +2 -1
- package/src/preview/property_previews/ArrayOfStorageComponentsPreview.tsx +0 -1
- package/src/preview/property_previews/ArrayOfStringsPreview.tsx +0 -1
- package/src/preview/property_previews/ArrayOneOfPreview.tsx +2 -3
- package/src/preview/property_previews/ArrayPropertyPreview.tsx +2 -3
- package/src/preview/property_previews/MapPropertyPreview.tsx +5 -5
- package/src/preview/property_previews/StringPropertyPreview.tsx +8 -7
- package/src/types/analytics.ts +1 -0
- package/src/types/auth.tsx +50 -1
- package/src/types/collections.ts +37 -6
- package/src/types/datasource.ts +24 -17
- package/src/types/entities.ts +9 -1
- package/src/types/entity_actions.tsx +17 -0
- package/src/types/entity_callbacks.ts +2 -2
- package/src/types/entity_overrides.tsx +7 -0
- package/src/types/firecms.tsx +0 -1
- package/src/types/index.ts +2 -1
- package/src/types/navigation.ts +17 -17
- package/src/types/permissions.ts +6 -1
- package/src/types/plugins.tsx +26 -28
- package/src/types/properties.ts +18 -6
- package/src/types/property_config.tsx +2 -2
- package/src/types/roles.ts +41 -0
- package/src/types/side_entity_controller.tsx +1 -0
- package/src/types/storage.ts +12 -3
- package/src/types/user.ts +7 -0
- package/src/util/collections.ts +22 -0
- package/src/util/entities.ts +1 -1
- package/src/util/enums.ts +1 -1
- package/src/util/icon_list.ts +2 -2
- package/src/util/icon_synonyms.ts +3 -99
- package/src/util/icons.tsx +11 -3
- package/src/util/navigation_utils.ts +6 -6
- package/src/util/objects.ts +8 -21
- package/src/util/permissions.ts +11 -8
- package/src/util/references.ts +36 -5
- package/src/util/resolutions.ts +32 -31
- package/src/util/strings.ts +2 -2
- package/src/util/useTraceUpdate.tsx +2 -1
- package/dist/components/VirtualTable/common.d.ts +0 -2
- package/dist/core/SideEntityView.d.ts +0 -7
- package/dist/internal/useBuildCustomizationController.d.ts +0 -2
- package/dist/internal/useLocaleConfig.d.ts +0 -1
- package/dist/types/appcheck.d.ts +0 -26
- package/src/components/HomePage/NavigationCollectionCard.tsx +0 -146
- package/src/core/SideEntityView.tsx +0 -38
- package/src/internal/useBuildCustomizationController.tsx +0 -5
- package/src/internal/useLocaleConfig.tsx +0 -18
- package/src/types/appcheck.ts +0 -29
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React, { useState } from "react";
|
|
2
2
|
import { EnumValuesChip } from "../../../preview";
|
|
3
3
|
import { VirtualTableWhereFilterOp } from "../../VirtualTable";
|
|
4
|
-
import { ClearIcon, IconButton, Select, SelectItem, TextField } from "@firecms/ui";
|
|
4
|
+
import { Checkbox, ClearIcon, IconButton, Label, Select, SelectItem, TextField } from "@firecms/ui";
|
|
5
5
|
import { EnumValueConfig } from "../../../types";
|
|
6
6
|
|
|
7
7
|
interface StringNumberFilterFieldProps {
|
|
@@ -50,15 +50,15 @@ export function StringNumberFilterField({
|
|
|
50
50
|
|
|
51
51
|
const [fieldOperation, fieldValue] = value || [possibleOperations[0], undefined];
|
|
52
52
|
const [operation, setOperation] = useState<VirtualTableWhereFilterOp>(fieldOperation);
|
|
53
|
-
const [internalValue, setInternalValue] = useState<string | number | string[] | number[] | undefined>(fieldValue);
|
|
53
|
+
const [internalValue, setInternalValue] = useState<string | number | string[] | number[] | null | undefined>(fieldValue);
|
|
54
54
|
|
|
55
|
-
function updateFilter(op: VirtualTableWhereFilterOp, val: string | number | string[] | number[] | undefined) {
|
|
55
|
+
function updateFilter(op: VirtualTableWhereFilterOp, val: string | number | string[] | number[] | null | undefined) {
|
|
56
56
|
let newValue = val;
|
|
57
57
|
const prevOpIsArray = multipleSelectOperations.includes(operation);
|
|
58
58
|
const newOpIsArray = multipleSelectOperations.includes(op);
|
|
59
59
|
if (prevOpIsArray !== newOpIsArray) {
|
|
60
60
|
// @ts-ignore
|
|
61
|
-
newValue = newOpIsArray ? (typeof val === "string" || typeof val === "number" ? [val] : []) :
|
|
61
|
+
newValue = newOpIsArray ? (typeof val === "string" || typeof val === "number" ? [val] : []) : undefined;
|
|
62
62
|
}
|
|
63
63
|
|
|
64
64
|
if (typeof newValue === "number" && isNaN(newValue))
|
|
@@ -84,7 +84,7 @@ export function StringNumberFilterField({
|
|
|
84
84
|
const multiple = multipleSelectOperations.includes(operation);
|
|
85
85
|
return (
|
|
86
86
|
|
|
87
|
-
<div className="flex w-[440px]
|
|
87
|
+
<div className="flex w-[440px]">
|
|
88
88
|
<div className={"w-[80px]"}>
|
|
89
89
|
<Select value={operation}
|
|
90
90
|
position={"item-aligned"}
|
|
@@ -100,11 +100,11 @@ export function StringNumberFilterField({
|
|
|
100
100
|
</Select>
|
|
101
101
|
</div>
|
|
102
102
|
|
|
103
|
-
<div className="flex-grow ml-2">
|
|
103
|
+
<div className="flex-grow ml-2 flex flex-col gap-2">
|
|
104
104
|
|
|
105
105
|
{!enumValues && <TextField
|
|
106
106
|
type={dataType === "number" ? "number" : undefined}
|
|
107
|
-
value={internalValue !== undefined ? String(internalValue) : ""}
|
|
107
|
+
value={internalValue !== undefined && internalValue != null ? String(internalValue) : ""}
|
|
108
108
|
onChange={(evt) => {
|
|
109
109
|
const val = dataType === "number"
|
|
110
110
|
? parseFloat(evt.target.value)
|
|
@@ -118,26 +118,31 @@ export function StringNumberFilterField({
|
|
|
118
118
|
/>}
|
|
119
119
|
|
|
120
120
|
{enumValues &&
|
|
121
|
-
|
|
122
121
|
<Select
|
|
123
122
|
position={"item-aligned"}
|
|
124
123
|
value={internalValue !== undefined
|
|
125
124
|
? (Array.isArray(internalValue) ? internalValue.map(e => String(e)) : String(internalValue))
|
|
126
125
|
: isArray ? [] : ""}
|
|
127
126
|
onValueChange={(value) => {
|
|
128
|
-
|
|
127
|
+
if (value !== "")
|
|
128
|
+
updateFilter(operation, dataType === "number" ? parseInt(value as string) : value as string)
|
|
129
129
|
}}
|
|
130
130
|
multiple={multiple}
|
|
131
131
|
endAdornment={internalValue && <IconButton
|
|
132
|
-
className="absolute right-
|
|
132
|
+
className="absolute right-2 top-3"
|
|
133
133
|
onClick={(e) => updateFilter(operation, undefined)}>
|
|
134
134
|
<ClearIcon/>
|
|
135
135
|
</IconButton>}
|
|
136
|
-
renderValue={(enumKey) =>
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
136
|
+
renderValue={(enumKey) => {
|
|
137
|
+
if (enumKey === null)
|
|
138
|
+
return "Filter for null values";
|
|
139
|
+
|
|
140
|
+
return <EnumValuesChip
|
|
141
|
+
key={`select_value_${name}_${enumKey}`}
|
|
142
|
+
enumKey={enumKey}
|
|
143
|
+
enumValues={enumValues}
|
|
144
|
+
size={"small"}/>;
|
|
145
|
+
}}>
|
|
141
146
|
{enumValues.map((enumConfig) => (
|
|
142
147
|
<SelectItem key={`select_value_${name}_${enumConfig.id}`}
|
|
143
148
|
value={String(enumConfig.id)}>
|
|
@@ -150,6 +155,21 @@ export function StringNumberFilterField({
|
|
|
150
155
|
</Select>
|
|
151
156
|
}
|
|
152
157
|
|
|
158
|
+
{!isArray && <Label
|
|
159
|
+
className="border cursor-pointer rounded-md p-2 flex items-center gap-2 [&:has(:checked)]:bg-gray-100 dark:[&:has(:checked)]:bg-gray-800"
|
|
160
|
+
htmlFor="null-filter"
|
|
161
|
+
>
|
|
162
|
+
<Checkbox id="null-filter"
|
|
163
|
+
checked={internalValue === null}
|
|
164
|
+
size={"small"}
|
|
165
|
+
onCheckedChange={(checked) => {
|
|
166
|
+
if (internalValue !== null)
|
|
167
|
+
updateFilter(operation, null);
|
|
168
|
+
else updateFilter(operation, undefined);
|
|
169
|
+
}}/>
|
|
170
|
+
Filter for null values
|
|
171
|
+
</Label>}
|
|
172
|
+
|
|
153
173
|
</div>
|
|
154
174
|
|
|
155
175
|
</div>
|
|
@@ -15,12 +15,11 @@ import {
|
|
|
15
15
|
VirtualTableWhereFilterOp
|
|
16
16
|
} from "./VirtualTableProps";
|
|
17
17
|
|
|
18
|
-
import { getRowHeight } from "./common";
|
|
19
18
|
import { VirtualTableContextProps } from "./types";
|
|
20
19
|
import { VirtualTableHeaderRow } from "./VirtualTableHeaderRow";
|
|
21
20
|
import { VirtualTableRow } from "./VirtualTableRow";
|
|
22
21
|
import { VirtualTableCell } from "./VirtualTableCell";
|
|
23
|
-
import { AssignmentIcon,
|
|
22
|
+
import { AssignmentIcon, CenteredView, cls, Typography } from "@firecms/ui";
|
|
24
23
|
|
|
25
24
|
const VirtualListContext = createContext<VirtualTableContextProps<any>>({} as any);
|
|
26
25
|
VirtualListContext.displayName = "VirtualListContext";
|
|
@@ -92,7 +91,7 @@ export const VirtualTable = React.memo<VirtualTableProps<any>>(
|
|
|
92
91
|
data,
|
|
93
92
|
onResetPagination,
|
|
94
93
|
onEndReached,
|
|
95
|
-
|
|
94
|
+
rowHeight = 54,
|
|
96
95
|
columns: columnsProp,
|
|
97
96
|
onRowClick,
|
|
98
97
|
onColumnResize,
|
|
@@ -108,6 +107,7 @@ export const VirtualTable = React.memo<VirtualTableProps<any>>(
|
|
|
108
107
|
hoverRow,
|
|
109
108
|
createFilterField,
|
|
110
109
|
rowClassName,
|
|
110
|
+
style,
|
|
111
111
|
className,
|
|
112
112
|
endAdornment,
|
|
113
113
|
AddColumnComponent
|
|
@@ -187,7 +187,7 @@ export const VirtualTable = React.memo<VirtualTableProps<any>>(
|
|
|
187
187
|
onSortByUpdate(undefined);
|
|
188
188
|
}, [onSortByUpdate]);
|
|
189
189
|
|
|
190
|
-
const maxScroll = Math.max((data?.length ?? 0) *
|
|
190
|
+
const maxScroll = Math.max((data?.length ?? 0) * rowHeight - bounds.height, 0);
|
|
191
191
|
const onEndReachedInternal = useCallback((scrollOffset: number) => {
|
|
192
192
|
if (onEndReached && (data?.length ?? 0) > 0 && scrollOffset > endReachCallbackThreshold.current + 600) {
|
|
193
193
|
endReachCallbackThreshold.current = scrollOffset;
|
|
@@ -225,24 +225,7 @@ export const VirtualTable = React.memo<VirtualTableProps<any>>(
|
|
|
225
225
|
}
|
|
226
226
|
|
|
227
227
|
if (onFilterUpdate) onFilterUpdate(newFilterValue);
|
|
228
|
-
|
|
229
|
-
if (column.key !== sortByProperty) {
|
|
230
|
-
resetSort();
|
|
231
|
-
}
|
|
232
|
-
}, [checkFilterCombination, currentSort, onFilterUpdate, resetSort, sortByProperty]);
|
|
233
|
-
|
|
234
|
-
const buildErrorView = useCallback(() => (
|
|
235
|
-
<div
|
|
236
|
-
className="h-full flex flex-col items-center justify-center sticky left-0">
|
|
237
|
-
|
|
238
|
-
<Typography variant={"h6"}>
|
|
239
|
-
{"Error fetching data from the data source"}
|
|
240
|
-
</Typography>
|
|
241
|
-
|
|
242
|
-
{error?.message && <Markdown className={"px-4 break-all"} source={error.message}/>}
|
|
243
|
-
|
|
244
|
-
</div>
|
|
245
|
-
), [error?.message]);
|
|
228
|
+
}, [checkFilterCombination, currentSort, onFilterUpdate, sortByProperty]);
|
|
246
229
|
|
|
247
230
|
const buildEmptyView = useCallback(() => {
|
|
248
231
|
if (loading)
|
|
@@ -255,11 +238,22 @@ export const VirtualTable = React.memo<VirtualTableProps<any>>(
|
|
|
255
238
|
}, [emptyComponent, loading]);
|
|
256
239
|
|
|
257
240
|
const empty = !loading && (data?.length ?? 0) === 0;
|
|
258
|
-
const customView = error
|
|
241
|
+
const customView = error
|
|
242
|
+
? <CenteredView maxWidth={"2xl"}
|
|
243
|
+
className="flex flex-col gap-2">
|
|
244
|
+
|
|
245
|
+
<Typography variant={"h6"}>
|
|
246
|
+
{"Error fetching data from the data source"}
|
|
247
|
+
</Typography>
|
|
248
|
+
|
|
249
|
+
{error?.message && <SafeLinkRenderer text={error.message}/>}
|
|
250
|
+
|
|
251
|
+
</CenteredView>
|
|
252
|
+
: (empty ? buildEmptyView() : undefined);
|
|
259
253
|
|
|
260
254
|
const virtualListController = {
|
|
261
255
|
data,
|
|
262
|
-
|
|
256
|
+
rowHeight: rowHeight,
|
|
263
257
|
cellRenderer,
|
|
264
258
|
columns,
|
|
265
259
|
currentSort,
|
|
@@ -282,19 +276,20 @@ export const VirtualTable = React.memo<VirtualTableProps<any>>(
|
|
|
282
276
|
return (
|
|
283
277
|
<div
|
|
284
278
|
ref={measureRef}
|
|
285
|
-
|
|
279
|
+
style={style}
|
|
280
|
+
className={cls("h-full w-full", className)}>
|
|
286
281
|
<VirtualListContext.Provider
|
|
287
282
|
value={virtualListController}>
|
|
288
283
|
|
|
289
284
|
<MemoizedList
|
|
290
285
|
outerRef={tableRef}
|
|
291
|
-
key={
|
|
286
|
+
key={rowHeight}
|
|
292
287
|
width={bounds.width}
|
|
293
288
|
height={bounds.height}
|
|
294
289
|
itemCount={(data?.length ?? 0) + (endAdornment ? 1 : 0)}
|
|
295
290
|
onScroll={onScroll}
|
|
296
291
|
includeAddColumn={Boolean(AddColumnComponent)}
|
|
297
|
-
itemSize={
|
|
292
|
+
itemSize={rowHeight}/>
|
|
298
293
|
|
|
299
294
|
</VirtualListContext.Provider>
|
|
300
295
|
</div>
|
|
@@ -334,7 +329,7 @@ function MemoizedList({
|
|
|
334
329
|
onRowClick,
|
|
335
330
|
data,
|
|
336
331
|
columns,
|
|
337
|
-
|
|
332
|
+
rowHeight = 54,
|
|
338
333
|
cellRenderer,
|
|
339
334
|
hoverRow,
|
|
340
335
|
rowClassName,
|
|
@@ -367,7 +362,7 @@ function MemoizedList({
|
|
|
367
362
|
...style,
|
|
368
363
|
top: `calc(${style.top}px + 48px)`
|
|
369
364
|
}}
|
|
370
|
-
|
|
365
|
+
rowHeight={rowHeight}>
|
|
371
366
|
|
|
372
367
|
{columns.map((column: VirtualTableColumn, columnIndex: number) => {
|
|
373
368
|
const cellData = rowData && rowData[column.key];
|
|
@@ -403,3 +398,17 @@ function MemoizedList({
|
|
|
403
398
|
{Row}
|
|
404
399
|
</List>;
|
|
405
400
|
}
|
|
401
|
+
|
|
402
|
+
const SafeLinkRenderer: React.FC<{
|
|
403
|
+
text: string;
|
|
404
|
+
}> = ({ text }) => {
|
|
405
|
+
const urlRegex = /https?:\/\/[^\s]+/g;
|
|
406
|
+
const htmlContent = text.replace(urlRegex, (url) => {
|
|
407
|
+
// For each URL found, replace it with an HTML <a> tag
|
|
408
|
+
return `<a href="${url}" class="underline" target="_blank">Link</a><br/>`;
|
|
409
|
+
});
|
|
410
|
+
|
|
411
|
+
return (
|
|
412
|
+
<div className={"break-all"} dangerouslySetInnerHTML={{ __html: htmlContent }}/>
|
|
413
|
+
);
|
|
414
|
+
};
|
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
ArrowUpwardIcon,
|
|
8
8
|
Badge,
|
|
9
9
|
Button,
|
|
10
|
-
|
|
10
|
+
cls,
|
|
11
11
|
defaultBorderMixin,
|
|
12
12
|
FilterListIcon,
|
|
13
13
|
IconButton,
|
|
@@ -85,7 +85,7 @@ export const VirtualTableHeader = React.memo<VirtualTableHeaderProps<any>>(
|
|
|
85
85
|
return (
|
|
86
86
|
<ErrorBoundary>
|
|
87
87
|
<div
|
|
88
|
-
className={
|
|
88
|
+
className={cls("flex py-0 px-3 h-full text-xs uppercase font-semibold relative select-none items-center bg-gray-50 dark:bg-gray-900",
|
|
89
89
|
"text-gray-600 hover:text-gray-800 dark:text-gray-400 dark:hover:text-gray-200 ",
|
|
90
90
|
"hover:bg-gray-100 dark:hover:bg-gray-800 hover:bg-opacity-50 dark:hover:bg-opacity-50",
|
|
91
91
|
column.frozen ? "sticky left-0 z-10" : "relative z-0"
|
|
@@ -179,7 +179,7 @@ export const VirtualTableHeader = React.memo<VirtualTableHeaderProps<any>>(
|
|
|
179
179
|
|
|
180
180
|
{column.resizable && <div
|
|
181
181
|
ref={resizeHandleRef}
|
|
182
|
-
className={
|
|
182
|
+
className={cls(
|
|
183
183
|
"absolute h-full w-[6px] top-0 right-0 cursor-col-resize",
|
|
184
184
|
hovered && "bg-gray-300 dark:bg-gray-700"
|
|
185
185
|
)}
|
|
@@ -240,7 +240,7 @@ function FilterForm<M>({
|
|
|
240
240
|
}}
|
|
241
241
|
className={"text-gray-900 dark:text-white"}>
|
|
242
242
|
<div
|
|
243
|
-
className={
|
|
243
|
+
className={cls(defaultBorderMixin, "py-4 px-6 text-xs font-semibold uppercase border-b")}>
|
|
244
244
|
{column.title ?? id}
|
|
245
245
|
</div>
|
|
246
246
|
{filterField && <div className="m-4">
|
|
@@ -4,7 +4,7 @@ import { VirtualTableColumn, VirtualTableWhereFilterOp } from "./VirtualTablePro
|
|
|
4
4
|
import { ErrorBoundary } from "../ErrorBoundary";
|
|
5
5
|
import { VirtualTableHeader } from "./VirtualTableHeader";
|
|
6
6
|
import { VirtualTableContextProps } from "./types";
|
|
7
|
-
import {
|
|
7
|
+
import { cls, defaultBorderMixin } from "@firecms/ui";
|
|
8
8
|
|
|
9
9
|
export const VirtualTableHeaderRow = ({
|
|
10
10
|
columns,
|
|
@@ -100,7 +100,7 @@ export const VirtualTableHeaderRow = ({
|
|
|
100
100
|
|
|
101
101
|
return (
|
|
102
102
|
<div
|
|
103
|
-
className={
|
|
103
|
+
className={cls(defaultBorderMixin, "z-20 sticky min-w-full flex w-fit flex-row top-0 left-0 h-12 border-b bg-gray-50 dark:bg-gray-900")}>
|
|
104
104
|
{columns.map((c, columnIndex) => {
|
|
105
105
|
const column = columns[columnIndex];
|
|
106
106
|
|
|
@@ -69,7 +69,7 @@ export interface VirtualTableProps<T extends Record<string, any>> {
|
|
|
69
69
|
/**
|
|
70
70
|
* Size of the table
|
|
71
71
|
*/
|
|
72
|
-
|
|
72
|
+
rowHeight?: number,
|
|
73
73
|
|
|
74
74
|
/**
|
|
75
75
|
* In case this table should have some filters set by default
|
|
@@ -131,6 +131,11 @@ export interface VirtualTableProps<T extends Record<string, any>> {
|
|
|
131
131
|
*/
|
|
132
132
|
className?: string;
|
|
133
133
|
|
|
134
|
+
/**
|
|
135
|
+
* Style applied to the table
|
|
136
|
+
*/
|
|
137
|
+
style?: React.CSSProperties;
|
|
138
|
+
|
|
134
139
|
/**
|
|
135
140
|
* Component rendered at the end of the table, after scroll
|
|
136
141
|
*/
|
|
@@ -232,11 +237,6 @@ export type OnVirtualTableColumnResizeParams = {
|
|
|
232
237
|
column: VirtualTableColumn
|
|
233
238
|
};
|
|
234
239
|
|
|
235
|
-
/**
|
|
236
|
-
* @see Table
|
|
237
|
-
* @group Components
|
|
238
|
-
*/
|
|
239
|
-
export type VirtualTableSize = "xs" | "s" | "m" | "l" | "xl";
|
|
240
240
|
|
|
241
241
|
/**
|
|
242
242
|
* @see Table
|
|
@@ -252,7 +252,7 @@ export type VirtualTableFilterValues<Key extends string> = Partial<Record<Key, [
|
|
|
252
252
|
|
|
253
253
|
/**
|
|
254
254
|
* Filter conditions in a `Query.where()` clause are specified using the
|
|
255
|
-
* strings
|
|
255
|
+
* strings `<`, `<=`, `==`, `>=`, `>`, `array-contains`, `in`, and `array-contains-any`.
|
|
256
256
|
* @see Table
|
|
257
257
|
* @group Models
|
|
258
258
|
*/
|
|
@@ -2,9 +2,8 @@ import React, { useCallback } from "react";
|
|
|
2
2
|
|
|
3
3
|
import equal from "react-fast-compare"
|
|
4
4
|
|
|
5
|
-
import { getRowHeight } from "./common";
|
|
6
5
|
import { VirtualTableRowProps } from "./types";
|
|
7
|
-
import {
|
|
6
|
+
import { cls } from "@firecms/ui";
|
|
8
7
|
|
|
9
8
|
export const VirtualTableRow = React.memo<VirtualTableRowProps<any>>(
|
|
10
9
|
function VirtualTableRow<T>({
|
|
@@ -12,7 +11,7 @@ export const VirtualTableRow = React.memo<VirtualTableRowProps<any>>(
|
|
|
12
11
|
rowIndex,
|
|
13
12
|
children,
|
|
14
13
|
onRowClick,
|
|
15
|
-
|
|
14
|
+
rowHeight,
|
|
16
15
|
style,
|
|
17
16
|
hoverRow,
|
|
18
17
|
rowClassName
|
|
@@ -29,7 +28,7 @@ export const VirtualTableRow = React.memo<VirtualTableRowProps<any>>(
|
|
|
29
28
|
|
|
30
29
|
return (
|
|
31
30
|
<div
|
|
32
|
-
className={
|
|
31
|
+
className={cls(
|
|
33
32
|
"flex min-w-full text-sm border-b border-gray-200 dark:border-gray-800 border-opacity-40 dark:border-opacity-40",
|
|
34
33
|
rowClassName ? rowClassName(rowData) : "",
|
|
35
34
|
{
|
|
@@ -40,7 +39,7 @@ export const VirtualTableRow = React.memo<VirtualTableRowProps<any>>(
|
|
|
40
39
|
onClick={onClick}
|
|
41
40
|
style={{
|
|
42
41
|
...(style),
|
|
43
|
-
height:
|
|
42
|
+
height: rowHeight,
|
|
44
43
|
width: "fit-content"
|
|
45
44
|
}}
|
|
46
45
|
>
|
|
@@ -25,7 +25,7 @@ export function VirtualTableDateField(props: {
|
|
|
25
25
|
return (
|
|
26
26
|
<DateTimeField
|
|
27
27
|
value={internalValue ?? undefined}
|
|
28
|
-
onChange={(dateValue) => updateValue(dateValue)}
|
|
28
|
+
onChange={(dateValue) => updateValue(dateValue ?? null)}
|
|
29
29
|
size={"medium"}
|
|
30
30
|
invisible={true}
|
|
31
31
|
className={"w-full h-full"}
|
|
@@ -5,14 +5,13 @@ import {
|
|
|
5
5
|
OnVirtualTableColumnResizeParams,
|
|
6
6
|
VirtualTableColumn,
|
|
7
7
|
VirtualTableFilterValues,
|
|
8
|
-
VirtualTableSize,
|
|
9
8
|
VirtualTableWhereFilterOp
|
|
10
9
|
} from "./VirtualTableProps";
|
|
11
10
|
import { FilterFormFieldProps } from "./VirtualTableHeader";
|
|
12
11
|
|
|
13
12
|
export type VirtualTableRowProps<T> = {
|
|
14
13
|
style: any,
|
|
15
|
-
|
|
14
|
+
rowHeight: number,
|
|
16
15
|
rowData: T;
|
|
17
16
|
rowIndex: number;
|
|
18
17
|
onRowClick?: (props: OnRowClickParams<any>) => void;
|
|
@@ -24,7 +23,7 @@ export type VirtualTableRowProps<T> = {
|
|
|
24
23
|
|
|
25
24
|
export type VirtualTableContextProps<T extends any> = {
|
|
26
25
|
data?: T[];
|
|
27
|
-
|
|
26
|
+
rowHeight?: number,
|
|
28
27
|
columns: VirtualTableColumn[];
|
|
29
28
|
cellRenderer: React.ComponentType<CellRendererParams<T>>;
|
|
30
29
|
currentSort: "asc" | "desc" | undefined;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { EntityAction } from "../../../types";
|
|
2
1
|
import { ArchiveIcon, DeleteIcon, FileCopyIcon, KeyboardTabIcon, OpenInNewIcon } from "@firecms/ui";
|
|
3
|
-
import {
|
|
2
|
+
import { EntityAction } from "../../types";
|
|
3
|
+
import { DeleteEntityDialog } from "../DeleteEntityDialog";
|
|
4
4
|
|
|
5
5
|
export const editEntityAction: EntityAction = {
|
|
6
6
|
icon: <KeyboardTabIcon/>,
|
|
@@ -9,21 +9,23 @@ export const editEntityAction: EntityAction = {
|
|
|
9
9
|
onClick({
|
|
10
10
|
entity,
|
|
11
11
|
collection,
|
|
12
|
+
fullPath,
|
|
12
13
|
context,
|
|
13
14
|
highlightEntity,
|
|
14
|
-
unhighlightEntity
|
|
15
|
+
unhighlightEntity,
|
|
15
16
|
}): Promise<void> {
|
|
16
17
|
highlightEntity?.(entity);
|
|
17
18
|
context.analyticsController?.onAnalyticsEvent?.("entity_click", {
|
|
18
19
|
path: entity.path,
|
|
19
20
|
entityId: entity.id
|
|
20
21
|
});
|
|
22
|
+
const path = collection?.collectionGroup ? entity.path : (fullPath ?? entity.path);
|
|
21
23
|
context.sideEntityController.open({
|
|
22
24
|
entityId: entity.id,
|
|
23
|
-
path
|
|
25
|
+
path,
|
|
24
26
|
collection,
|
|
25
27
|
updateUrl: true,
|
|
26
|
-
onClose: () => unhighlightEntity?.(entity)
|
|
28
|
+
onClose: () => unhighlightEntity?.(entity),
|
|
27
29
|
});
|
|
28
30
|
return Promise.resolve(undefined);
|
|
29
31
|
}
|
|
@@ -37,7 +39,7 @@ export const copyEntityAction: EntityAction = {
|
|
|
37
39
|
collection,
|
|
38
40
|
context,
|
|
39
41
|
highlightEntity,
|
|
40
|
-
unhighlightEntity
|
|
42
|
+
unhighlightEntity,
|
|
41
43
|
}): Promise<void> {
|
|
42
44
|
highlightEntity?.(entity);
|
|
43
45
|
context.analyticsController?.onAnalyticsEvent?.("copy_entity_click", {
|
|
@@ -50,11 +52,12 @@ export const copyEntityAction: EntityAction = {
|
|
|
50
52
|
copy: true,
|
|
51
53
|
collection,
|
|
52
54
|
updateUrl: true,
|
|
53
|
-
onClose: () => unhighlightEntity?.(entity)
|
|
55
|
+
onClose: () => unhighlightEntity?.(entity),
|
|
54
56
|
});
|
|
55
57
|
return Promise.resolve(undefined);
|
|
56
58
|
}
|
|
57
59
|
}
|
|
60
|
+
|
|
58
61
|
export const archiveEntityAction: EntityAction = {
|
|
59
62
|
icon: <ArchiveIcon/>,
|
|
60
63
|
name: "Archive",
|
|
@@ -69,6 +72,7 @@ export const archiveEntityAction: EntityAction = {
|
|
|
69
72
|
return Promise.resolve(undefined);
|
|
70
73
|
}
|
|
71
74
|
}
|
|
75
|
+
|
|
72
76
|
export const openWebsiteAction: EntityAction = {
|
|
73
77
|
icon: <OpenInNewIcon/>,
|
|
74
78
|
name: "See in website",
|
|
@@ -1,6 +1,9 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* @group Components
|
|
3
|
+
*/
|
|
4
|
+
export type TableSize = "xs" | "s" | "m" | "l" | "xl";
|
|
2
5
|
|
|
3
|
-
export function getRowHeight(size:
|
|
6
|
+
export function getRowHeight(size: TableSize): number {
|
|
4
7
|
switch (size) {
|
|
5
8
|
case "xl":
|
|
6
9
|
return 400;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CollectionSize,
|
|
1
|
+
import { CollectionSize, ResolvedProperty, SelectedCellProps } from "../../types";
|
|
2
2
|
|
|
3
3
|
export type EntityCollectionTableController<M extends Record<string, any>> = {
|
|
4
4
|
|
|
@@ -31,14 +31,12 @@ export type EntityCollectionTableController<M extends Record<string, any>> = {
|
|
|
31
31
|
* Props passed in a callback when the content of a cell in a table has been edited
|
|
32
32
|
* @group Collection components
|
|
33
33
|
*/
|
|
34
|
-
export interface OnCellValueChangeParams<T = any,
|
|
34
|
+
export interface OnCellValueChangeParams<T = any, D = any> {
|
|
35
35
|
value: T,
|
|
36
36
|
propertyKey: string,
|
|
37
|
-
|
|
37
|
+
data?: D,
|
|
38
38
|
onValueUpdated: () => void
|
|
39
|
-
setError: (e: Error) => void
|
|
40
|
-
fullPath: string
|
|
41
|
-
context: FireCMSContext
|
|
39
|
+
setError: (e: Error | undefined) => void
|
|
42
40
|
}
|
|
43
41
|
|
|
44
42
|
/**
|
|
@@ -7,8 +7,16 @@ const COLLECTION_GROUP_PARENT_ID = "collectionGroupParent";
|
|
|
7
7
|
|
|
8
8
|
export function useColumnIds<M extends Record<string, any>>(collection: ResolvedEntityCollection<M>, includeSubcollections: boolean): PropertyColumnConfig[] {
|
|
9
9
|
return useMemo(() => {
|
|
10
|
-
if (collection.propertiesOrder)
|
|
11
|
-
|
|
10
|
+
if (collection.propertiesOrder) {
|
|
11
|
+
const propertyColumnConfigs = hideAndExpandKeys(collection, collection.propertiesOrder);
|
|
12
|
+
if (collection.collectionGroup) {
|
|
13
|
+
propertyColumnConfigs.push({
|
|
14
|
+
key: COLLECTION_GROUP_PARENT_ID,
|
|
15
|
+
disabled: true
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
return propertyColumnConfigs;
|
|
19
|
+
}
|
|
12
20
|
return getDefaultColumnKeys(collection, includeSubcollections);
|
|
13
21
|
}, [collection, includeSubcollections]);
|
|
14
22
|
}
|
|
@@ -12,6 +12,7 @@ import {
|
|
|
12
12
|
User
|
|
13
13
|
} from "../../types";
|
|
14
14
|
import { useDebouncedData } from "./useDebouncedData";
|
|
15
|
+
import equal from "react-fast-compare"
|
|
15
16
|
|
|
16
17
|
const DEFAULT_PAGE_SIZE = 50;
|
|
17
18
|
|
|
@@ -31,6 +32,10 @@ export type DataSourceEntityCollectionTableControllerProps<M extends Record<stri
|
|
|
31
32
|
entitiesDisplayedFirst?: Entity<M>[];
|
|
32
33
|
|
|
33
34
|
lastDeleteTimestamp?: number;
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Force filter to be applied to the table.
|
|
38
|
+
*/
|
|
34
39
|
forceFilter?: FilterValues<string>;
|
|
35
40
|
}
|
|
36
41
|
|
|
@@ -65,7 +70,7 @@ export function useDataSourceEntityCollectionTableController<M extends Record<st
|
|
|
65
70
|
|
|
66
71
|
const [popupCell, setPopupCell] = React.useState<SelectedCellProps<M> | undefined>(undefined);
|
|
67
72
|
const navigation = useNavigationController();
|
|
68
|
-
const dataSource = useDataSource();
|
|
73
|
+
const dataSource = useDataSource(collection);
|
|
69
74
|
const resolvedPath = useMemo(() => navigation.resolveAliasesFrom(fullPath), [fullPath, navigation.resolveAliasesFrom]);
|
|
70
75
|
|
|
71
76
|
const forceFilter = forceFilterFromProps ?? forceFilterFromCollection;
|
|
@@ -83,6 +88,12 @@ export function useDataSourceEntityCollectionTableController<M extends Record<st
|
|
|
83
88
|
return initialSort;
|
|
84
89
|
}, [initialSort, forceFilter]);
|
|
85
90
|
|
|
91
|
+
useEffect(() => {
|
|
92
|
+
if (!equal(forceFilter, filterValues)) {
|
|
93
|
+
setFilterValues(forceFilter)
|
|
94
|
+
}
|
|
95
|
+
}, [forceFilter]);
|
|
96
|
+
|
|
86
97
|
const [filterValues, setFilterValues] = React.useState<FilterValues<Extract<keyof M, string>> | undefined>(forceFilter ?? initialFilter ?? undefined);
|
|
87
98
|
const [sortBy, setSortBy] = React.useState<[Extract<keyof M, string>, "asc" | "desc"] | undefined>(initialSortInternal);
|
|
88
99
|
|