@firecms/core 3.0.0-beta.8 → 3.0.0-beta.9
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/app/Drawer.d.ts +1 -1
- package/dist/app/Scaffold.d.ts +1 -1
- package/dist/components/ArrayContainer.d.ts +2 -1
- package/dist/components/CircularProgressCenter.d.ts +1 -1
- package/dist/components/EntityCollectionTable/EntityCollectionRowActions.d.ts +0 -1
- package/dist/components/EntityCollectionTable/fields/TableReferenceField.d.ts +1 -1
- package/dist/components/EntityCollectionTable/internal/popup_field/PopupFormField.d.ts +1 -1
- package/dist/components/EntityCollectionView/EntityCollectionView.d.ts +1 -1
- package/dist/components/EntityPreview.d.ts +1 -1
- package/dist/components/ErrorView.d.ts +1 -1
- package/dist/components/HomePage/DefaultHomePage.d.ts +1 -1
- package/dist/components/HomePage/NavigationCardBinding.d.ts +1 -1
- package/dist/components/PropertyIdCopyTooltip.d.ts +8 -0
- package/dist/components/VirtualTable/VirtualTableProps.d.ts +10 -6
- package/dist/components/common/useColumnsIds.d.ts +2 -1
- package/dist/components/index.d.ts +1 -0
- package/dist/core/DefaultAppBar.d.ts +1 -1
- package/dist/core/DefaultDrawer.d.ts +1 -1
- package/dist/core/DrawerNavigationItem.d.ts +2 -1
- package/dist/core/EntityEditView.d.ts +3 -3
- package/dist/core/FireCMS.d.ts +1 -1
- package/dist/core/NavigationRoutes.d.ts +1 -1
- package/dist/form/PropertyFieldBinding.d.ts +1 -1
- package/dist/form/components/FormikArrayContainer.d.ts +2 -1
- package/dist/form/components/LabelWithIcon.d.ts +1 -1
- package/dist/form/components/LabelWithIconAndTooltip.d.ts +15 -0
- package/dist/form/components/index.d.ts +1 -0
- package/dist/form/field_bindings/ArrayCustomShapedFieldBinding.d.ts +1 -1
- package/dist/form/field_bindings/ArrayOfReferencesFieldBinding.d.ts +1 -1
- package/dist/form/field_bindings/BlockFieldBinding.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/MarkdownEditorFieldBinding.d.ts +11 -0
- package/dist/form/field_bindings/{MultiSelectBinding.d.ts → MultiSelectFieldBinding.d.ts} +1 -1
- package/dist/form/field_bindings/ReadOnlyFieldBinding.d.ts +1 -1
- package/dist/form/field_bindings/RepeatFieldBinding.d.ts +1 -1
- package/dist/form/field_bindings/SelectFieldBinding.d.ts +1 -1
- package/dist/form/field_bindings/StorageUploadFieldBinding.d.ts +1 -1
- package/dist/form/field_bindings/TextFieldBinding.d.ts +1 -1
- package/dist/form/index.d.ts +3 -3
- package/dist/form/useClearRestoreValue.d.ts +2 -2
- package/dist/hooks/useProjectLog.d.ts +2 -2
- package/dist/index.es.js +14127 -11014
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +19987 -587
- package/dist/index.umd.js.map +1 -1
- package/dist/preview/PropertyPreviewProps.d.ts +1 -1
- package/dist/preview/components/EnumValuesChip.d.ts +1 -1
- package/dist/preview/components/ReferencePreview.d.ts +1 -1
- package/dist/types/auth.d.ts +1 -1
- package/dist/types/collections.d.ts +12 -3
- package/dist/types/datasource.d.ts +35 -22
- package/dist/types/entities.d.ts +1 -0
- package/dist/types/entity_overrides.d.ts +2 -2
- package/dist/types/fields.d.ts +20 -15
- package/dist/types/navigation.d.ts +1 -0
- package/dist/types/properties.d.ts +18 -18
- package/dist/types/side_dialogs_controller.d.ts +10 -0
- package/dist/types/storage.d.ts +75 -0
- package/dist/util/entities.d.ts +1 -1
- package/dist/util/icon_list.d.ts +5 -1
- package/dist/util/icons.d.ts +1 -0
- package/dist/util/index.d.ts +1 -0
- package/dist/util/plurals.d.ts +0 -2
- package/dist/util/property_utils.d.ts +1 -1
- package/dist/util/resolutions.d.ts +15 -1
- package/dist/util/storage.d.ts +1 -1
- package/dist/util/useStorageUploadController.d.ts +2 -2
- package/package.json +15 -17
- package/src/app/Drawer.tsx +1 -1
- package/src/app/Scaffold.tsx +22 -27
- package/src/components/ArrayContainer.tsx +15 -10
- package/src/components/CircularProgressCenter.tsx +1 -1
- package/src/components/EntityCollectionTable/EntityCollectionRowActions.tsx +4 -9
- package/src/components/EntityCollectionTable/EntityCollectionTable.tsx +2 -2
- package/src/components/EntityCollectionTable/PropertyTableCell.tsx +4 -2
- package/src/components/EntityCollectionTable/fields/TableReferenceField.tsx +21 -14
- package/src/components/EntityCollectionTable/fields/TableStorageUpload.tsx +12 -4
- package/src/components/EntityCollectionTable/internal/EntityTableCell.tsx +17 -19
- package/src/components/EntityCollectionTable/internal/EntityTableCellActions.tsx +19 -7
- package/src/components/EntityCollectionTable/internal/popup_field/PopupFormField.tsx +3 -5
- package/src/components/EntityCollectionView/EntityCollectionView.tsx +26 -25
- package/src/components/EntityCollectionView/useSelectionController.tsx +19 -7
- package/src/components/EntityPreview.tsx +30 -31
- package/src/components/ErrorView.tsx +1 -1
- package/src/components/HomePage/DefaultHomePage.tsx +24 -18
- package/src/components/HomePage/NavigationCardBinding.tsx +1 -1
- package/src/components/HomePage/SmallNavigationCard.tsx +1 -2
- package/src/components/PropertyIdCopyTooltip.tsx +48 -0
- package/src/components/ReferenceTable/ReferenceSelectionTable.tsx +7 -6
- package/src/components/SearchIconsView.tsx +5 -2
- package/src/components/SelectableTable/SelectableTable.tsx +2 -4
- package/src/components/SelectableTable/filters/DateTimeFilterField.tsx +1 -1
- package/src/components/SelectableTable/filters/StringNumberFilterField.tsx +54 -7
- package/src/components/VirtualTable/VirtualTable.tsx +33 -9
- package/src/components/VirtualTable/VirtualTableCell.tsx +1 -9
- package/src/components/VirtualTable/VirtualTableProps.tsx +12 -8
- package/src/components/VirtualTable/fields/VirtualTableDateField.tsx +3 -3
- package/src/components/VirtualTable/fields/VirtualTableInput.tsx +2 -1
- package/src/components/VirtualTable/fields/VirtualTableNumberInput.tsx +2 -1
- package/src/components/VirtualTable/fields/VirtualTableSelect.tsx +14 -28
- package/src/components/common/useColumnsIds.tsx +13 -0
- package/src/components/common/useDataSourceEntityCollectionTableController.tsx +12 -12
- package/src/components/common/useTableSearchHelper.ts +1 -0
- package/src/components/index.tsx +1 -0
- package/src/core/DefaultAppBar.tsx +3 -3
- package/src/core/DefaultDrawer.tsx +18 -12
- package/src/core/DrawerNavigationItem.tsx +31 -27
- package/src/core/EntityEditView.tsx +136 -109
- package/src/core/FireCMS.tsx +2 -2
- package/src/core/NavigationRoutes.tsx +1 -1
- package/src/core/SideDialogs.tsx +1 -0
- package/src/core/field_configs.tsx +5 -5
- package/src/form/PropertyFieldBinding.tsx +24 -14
- package/src/form/components/CustomIdField.tsx +4 -2
- package/src/form/components/FieldHelperText.tsx +1 -1
- package/src/form/components/FormikArrayContainer.tsx +4 -1
- package/src/form/components/LabelWithIcon.tsx +27 -19
- package/src/form/components/LabelWithIconAndTooltip.tsx +28 -0
- package/src/form/components/StorageItemPreview.tsx +1 -0
- package/src/form/components/StorageUploadProgress.tsx +0 -1
- package/src/form/components/index.tsx +1 -0
- package/src/form/field_bindings/ArrayCustomShapedFieldBinding.tsx +22 -14
- package/src/form/field_bindings/ArrayOfReferencesFieldBinding.tsx +24 -22
- package/src/form/field_bindings/BlockFieldBinding.tsx +13 -11
- package/src/form/field_bindings/DateTimeFieldBinding.tsx +17 -14
- package/src/form/field_bindings/KeyValueFieldBinding.tsx +8 -7
- package/src/form/field_bindings/MapFieldBinding.tsx +16 -24
- package/src/form/field_bindings/MarkdownEditorFieldBinding.tsx +150 -0
- package/src/form/field_bindings/{MultiSelectBinding.tsx → MultiSelectFieldBinding.tsx} +25 -20
- package/src/form/field_bindings/ReadOnlyFieldBinding.tsx +9 -7
- package/src/form/field_bindings/ReferenceFieldBinding.tsx +27 -18
- package/src/form/field_bindings/RepeatFieldBinding.tsx +27 -17
- package/src/form/field_bindings/SelectFieldBinding.tsx +17 -10
- package/src/form/field_bindings/StorageUploadFieldBinding.tsx +36 -17
- package/src/form/field_bindings/SwitchFieldBinding.tsx +9 -5
- package/src/form/field_bindings/TextFieldBinding.tsx +26 -23
- package/src/form/index.tsx +4 -9
- package/src/form/useClearRestoreValue.tsx +2 -2
- package/src/hooks/data/delete.ts +2 -1
- package/src/hooks/data/save.ts +5 -2
- package/src/hooks/data/useDataSource.tsx +11 -3
- package/src/hooks/useBuildNavigationController.tsx +10 -3
- package/src/hooks/useProjectLog.tsx +18 -7
- package/src/internal/useBuildDataSource.ts +59 -76
- package/src/internal/useBuildSideDialogsController.tsx +1 -0
- package/src/internal/useBuildSideEntityController.tsx +17 -4
- package/src/internal/useUnsavedChangesDialog.tsx +3 -1
- package/src/preview/PropertyPreview.tsx +2 -2
- package/src/preview/PropertyPreviewProps.tsx +1 -1
- package/src/preview/components/BooleanPreview.tsx +1 -1
- package/src/preview/components/EnumValuesChip.tsx +1 -1
- package/src/preview/components/ImagePreview.tsx +4 -2
- package/src/preview/components/ReferencePreview.tsx +2 -13
- package/src/preview/components/UrlComponentPreview.tsx +1 -1
- package/src/preview/property_previews/ArrayOfMapsPreview.tsx +1 -1
- package/src/preview/property_previews/ArrayOfReferencesPreview.tsx +1 -1
- package/src/preview/property_previews/ArrayOfStorageComponentsPreview.tsx +1 -1
- package/src/preview/property_previews/ArrayOneOfPreview.tsx +2 -2
- package/src/preview/property_previews/ArrayPropertyPreview.tsx +1 -1
- package/src/preview/property_previews/MapPropertyPreview.tsx +1 -1
- package/src/preview/property_previews/SkeletonPropertyComponent.tsx +2 -2
- package/src/preview/property_previews/StringPropertyPreview.tsx +2 -2
- package/src/preview/util.ts +2 -2
- package/src/types/auth.tsx +1 -1
- package/src/types/collections.ts +15 -4
- package/src/types/datasource.ts +42 -27
- package/src/types/entities.ts +2 -0
- package/src/types/entity_overrides.tsx +2 -2
- package/src/types/fields.tsx +23 -17
- package/src/types/navigation.ts +1 -0
- package/src/types/properties.ts +18 -17
- package/src/types/side_dialogs_controller.tsx +13 -0
- package/src/types/storage.ts +82 -0
- package/src/util/entities.ts +1 -1
- package/src/util/icon_list.ts +14 -9
- package/src/util/icons.tsx +8 -2
- package/src/util/index.ts +1 -0
- package/src/util/plurals.ts +0 -2
- package/src/util/property_utils.tsx +1 -1
- package/src/util/references.ts +3 -0
- package/src/util/resolutions.ts +43 -11
- package/src/util/storage.ts +6 -2
- package/src/util/useStorageUploadController.tsx +15 -7
- package/dist/components/PropertyIdCopyTooltipContent.d.ts +0 -3
- package/dist/form/PropertiesForm.d.ts +0 -8
- package/dist/form/field_bindings/MarkdownFieldBinding.d.ts +0 -9
- package/src/components/PropertyIdCopyTooltipContent.tsx +0 -27
- package/src/form/PropertiesForm.tsx +0 -81
- package/src/form/field_bindings/MarkdownFieldBinding.tsx +0 -695
|
@@ -1,7 +1,17 @@
|
|
|
1
1
|
import React, { useState } from "react";
|
|
2
2
|
import { EnumValuesChip } from "../../../preview";
|
|
3
3
|
import { VirtualTableWhereFilterOp } from "../../VirtualTable";
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
Checkbox,
|
|
6
|
+
ClearIcon,
|
|
7
|
+
IconButton,
|
|
8
|
+
Label,
|
|
9
|
+
MultiSelect,
|
|
10
|
+
MultiSelectItem,
|
|
11
|
+
Select,
|
|
12
|
+
SelectItem,
|
|
13
|
+
TextField
|
|
14
|
+
} from "@firecms/ui";
|
|
5
15
|
import { EnumValueConfig } from "../../../types";
|
|
6
16
|
|
|
7
17
|
interface StringNumberFilterFieldProps {
|
|
@@ -82,6 +92,7 @@ export function StringNumberFilterField({
|
|
|
82
92
|
}
|
|
83
93
|
|
|
84
94
|
const multiple = multipleSelectOperations.includes(operation);
|
|
95
|
+
|
|
85
96
|
return (
|
|
86
97
|
|
|
87
98
|
<div className="flex w-[440px]">
|
|
@@ -117,17 +128,14 @@ export function StringNumberFilterField({
|
|
|
117
128
|
</IconButton>}
|
|
118
129
|
/>}
|
|
119
130
|
|
|
120
|
-
{enumValues &&
|
|
131
|
+
{enumValues && !multiple &&
|
|
121
132
|
<Select
|
|
122
133
|
position={"item-aligned"}
|
|
123
|
-
value={internalValue
|
|
124
|
-
? (Array.isArray(internalValue) ? internalValue.map(e => String(e)) : String(internalValue))
|
|
125
|
-
: isArray ? [] : ""}
|
|
134
|
+
value={typeof internalValue === "string" ? internalValue : ""}
|
|
126
135
|
onValueChange={(value) => {
|
|
127
136
|
if (value !== "")
|
|
128
137
|
updateFilter(operation, dataType === "number" ? parseInt(value as string) : value as string)
|
|
129
138
|
}}
|
|
130
|
-
multiple={multiple}
|
|
131
139
|
endAdornment={internalValue && <IconButton
|
|
132
140
|
className="absolute right-2 top-3"
|
|
133
141
|
onClick={(e) => updateFilter(operation, undefined)}>
|
|
@@ -136,6 +144,8 @@ export function StringNumberFilterField({
|
|
|
136
144
|
renderValue={(enumKey) => {
|
|
137
145
|
if (enumKey === null)
|
|
138
146
|
return "Filter for null values";
|
|
147
|
+
if (enumKey === undefined)
|
|
148
|
+
return null;
|
|
139
149
|
|
|
140
150
|
return <EnumValuesChip
|
|
141
151
|
key={`select_value_${name}_${enumKey}`}
|
|
@@ -144,7 +154,7 @@ export function StringNumberFilterField({
|
|
|
144
154
|
size={"small"}/>;
|
|
145
155
|
}}>
|
|
146
156
|
{enumValues.map((enumConfig) => (
|
|
147
|
-
<SelectItem key={`
|
|
157
|
+
<SelectItem key={`select_item_${name}_${enumConfig.id}`}
|
|
148
158
|
value={String(enumConfig.id)}>
|
|
149
159
|
<EnumValuesChip
|
|
150
160
|
enumKey={String(enumConfig.id)}
|
|
@@ -155,6 +165,43 @@ export function StringNumberFilterField({
|
|
|
155
165
|
</Select>
|
|
156
166
|
}
|
|
157
167
|
|
|
168
|
+
{enumValues && multiple &&
|
|
169
|
+
<MultiSelect
|
|
170
|
+
position={"item-aligned"}
|
|
171
|
+
value={Array.isArray(internalValue) ? internalValue.map(e => String(e)) : []}
|
|
172
|
+
onValueChange={(value) => {
|
|
173
|
+
updateFilter(operation, dataType === "number" ? value.map(v => parseInt(v)) : value)
|
|
174
|
+
}}
|
|
175
|
+
multiple={multiple}
|
|
176
|
+
endAdornment={internalValue && <IconButton
|
|
177
|
+
className="absolute right-2 top-3"
|
|
178
|
+
onClick={(e) => updateFilter(operation, undefined)}>
|
|
179
|
+
<ClearIcon/>
|
|
180
|
+
</IconButton>}
|
|
181
|
+
// renderValues={(enumKeys) => {
|
|
182
|
+
// console.log("renderValues", enumKeys);
|
|
183
|
+
// if (enumKeys === null)
|
|
184
|
+
// return "Filter for null values";
|
|
185
|
+
//
|
|
186
|
+
// return enumKeys.map(key => <EnumValuesChip
|
|
187
|
+
// key={`select_value_${name}_${enumKeys}`}
|
|
188
|
+
// enumKey={key}
|
|
189
|
+
// enumValues={enumValues}
|
|
190
|
+
// size={"small"}/>);
|
|
191
|
+
// }}
|
|
192
|
+
>
|
|
193
|
+
{enumValues.map((enumConfig) => (
|
|
194
|
+
<MultiSelectItem key={`select_value_${name}_${enumConfig.id}`}
|
|
195
|
+
value={String(enumConfig.id)}>
|
|
196
|
+
<EnumValuesChip
|
|
197
|
+
enumKey={String(enumConfig.id)}
|
|
198
|
+
enumValues={enumValues}
|
|
199
|
+
size={"small"}/>
|
|
200
|
+
</MultiSelectItem>
|
|
201
|
+
))}
|
|
202
|
+
</MultiSelect>
|
|
203
|
+
}
|
|
204
|
+
|
|
158
205
|
{!isArray && <Label
|
|
159
206
|
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
207
|
htmlFor="null-filter"
|
|
@@ -91,6 +91,7 @@ export const VirtualTable = React.memo<VirtualTableProps<any>>(
|
|
|
91
91
|
data,
|
|
92
92
|
onResetPagination,
|
|
93
93
|
onEndReached,
|
|
94
|
+
endOffset = 600,
|
|
94
95
|
rowHeight = 54,
|
|
95
96
|
columns: columnsProp,
|
|
96
97
|
onRowClick,
|
|
@@ -110,7 +111,8 @@ export const VirtualTable = React.memo<VirtualTableProps<any>>(
|
|
|
110
111
|
style,
|
|
111
112
|
className,
|
|
112
113
|
endAdornment,
|
|
113
|
-
AddColumnComponent
|
|
114
|
+
AddColumnComponent,
|
|
115
|
+
debug
|
|
114
116
|
}: VirtualTableProps<T>) {
|
|
115
117
|
|
|
116
118
|
const sortByProperty: string | undefined = sortBy ? sortBy[0] : undefined;
|
|
@@ -128,10 +130,14 @@ export const VirtualTable = React.memo<VirtualTableProps<any>>(
|
|
|
128
130
|
const [measureRef, bounds] = useMeasure();
|
|
129
131
|
|
|
130
132
|
const onColumnResizeInternal = useCallback((params: OnVirtualTableColumnResizeParams) => {
|
|
133
|
+
if (debug)
|
|
134
|
+
console.log("onColumnResizeInternal", params);
|
|
131
135
|
setColumns(columns.map((column) => column.key === params.column.key ? params.column : column));
|
|
132
136
|
}, [columns]);
|
|
133
137
|
|
|
134
138
|
const onColumnResizeEndInternal = useCallback((params: OnVirtualTableColumnResizeParams) => {
|
|
139
|
+
if (debug)
|
|
140
|
+
console.log("onColumnResizeEndInternal", params);
|
|
135
141
|
setColumns(columns.map((column) => column.key === params.column.key ? params.column : column));
|
|
136
142
|
if (onColumnResize) {
|
|
137
143
|
onColumnResize(params);
|
|
@@ -142,10 +148,14 @@ export const VirtualTable = React.memo<VirtualTableProps<any>>(
|
|
|
142
148
|
const filterRef = useRef<VirtualTableFilterValues<any> | undefined>();
|
|
143
149
|
|
|
144
150
|
useEffect(() => {
|
|
151
|
+
if (debug)
|
|
152
|
+
console.log("Filter updated", filterInput);
|
|
145
153
|
filterRef.current = filterInput;
|
|
146
154
|
}, [filterInput]);
|
|
147
155
|
|
|
148
156
|
const scrollToTop = useCallback(() => {
|
|
157
|
+
if (debug)
|
|
158
|
+
console.log("scrollToTop");
|
|
149
159
|
endReachCallbackThreshold.current = 0;
|
|
150
160
|
if (tableRef.current) {
|
|
151
161
|
// scrollRef.current = [scrollRef.current[0], 0];
|
|
@@ -155,6 +165,9 @@ export const VirtualTable = React.memo<VirtualTableProps<any>>(
|
|
|
155
165
|
|
|
156
166
|
const onColumnSort = useCallback((key: string) => {
|
|
157
167
|
|
|
168
|
+
if (debug)
|
|
169
|
+
console.log("onColumnSort", key);
|
|
170
|
+
|
|
158
171
|
const isDesc = sortByProperty === key && currentSort === "desc";
|
|
159
172
|
const isAsc = sortByProperty === key && currentSort === "asc";
|
|
160
173
|
const newSort = isAsc ? "desc" : (isDesc ? undefined : "asc");
|
|
@@ -181,21 +194,21 @@ export const VirtualTable = React.memo<VirtualTableProps<any>>(
|
|
|
181
194
|
scrollToTop();
|
|
182
195
|
}, [checkFilterCombination, currentSort, onFilterUpdate, onResetPagination, onSortByUpdate, scrollToTop, sortByProperty]);
|
|
183
196
|
|
|
184
|
-
const resetSort = useCallback(() => {
|
|
185
|
-
endReachCallbackThreshold.current = 0;
|
|
186
|
-
if (onSortByUpdate)
|
|
187
|
-
onSortByUpdate(undefined);
|
|
188
|
-
}, [onSortByUpdate]);
|
|
189
|
-
|
|
190
197
|
const maxScroll = Math.max((data?.length ?? 0) * rowHeight - bounds.height, 0);
|
|
198
|
+
if (debug)
|
|
199
|
+
console.log("maxScroll", maxScroll);
|
|
200
|
+
|
|
191
201
|
const onEndReachedInternal = useCallback((scrollOffset: number) => {
|
|
192
|
-
if (
|
|
202
|
+
if (debug)
|
|
203
|
+
console.log("onEndReachedInternal", scrollOffset, endReachCallbackThreshold.current + endOffset);
|
|
204
|
+
if (onEndReached && (data?.length ?? 0) > 0 && scrollOffset > endReachCallbackThreshold.current + endOffset) {
|
|
193
205
|
endReachCallbackThreshold.current = scrollOffset;
|
|
194
206
|
onEndReached();
|
|
195
207
|
}
|
|
196
208
|
}, [data?.length, onEndReached]);
|
|
197
209
|
|
|
198
210
|
const onScroll = useCallback(({
|
|
211
|
+
scrollDirection,
|
|
199
212
|
scrollOffset,
|
|
200
213
|
scrollUpdateWasRequested
|
|
201
214
|
}: {
|
|
@@ -203,11 +216,19 @@ export const VirtualTable = React.memo<VirtualTableProps<any>>(
|
|
|
203
216
|
scrollOffset: number,
|
|
204
217
|
scrollUpdateWasRequested: boolean;
|
|
205
218
|
}) => {
|
|
206
|
-
if
|
|
219
|
+
if(debug)
|
|
220
|
+
console.log("onScroll", {
|
|
221
|
+
scrollDirection,
|
|
222
|
+
scrollOffset,
|
|
223
|
+
scrollUpdateWasRequested
|
|
224
|
+
});
|
|
225
|
+
if (!scrollUpdateWasRequested && (scrollOffset >= maxScroll - endOffset))
|
|
207
226
|
onEndReachedInternal(scrollOffset);
|
|
208
227
|
}, [maxScroll, onEndReachedInternal]);
|
|
209
228
|
|
|
210
229
|
const onFilterUpdateInternal = useCallback((column: VirtualTableColumn, filterForProperty?: [VirtualTableWhereFilterOp, any]) => {
|
|
230
|
+
if(debug)
|
|
231
|
+
console.log("onFilterUpdateInternal", column, filterForProperty);
|
|
211
232
|
|
|
212
233
|
endReachCallbackThreshold.current = 0;
|
|
213
234
|
const filter = filterRef.current;
|
|
@@ -272,6 +293,9 @@ export const VirtualTable = React.memo<VirtualTableProps<any>>(
|
|
|
272
293
|
AddColumnComponent
|
|
273
294
|
};
|
|
274
295
|
|
|
296
|
+
if(debug)
|
|
297
|
+
console.log("VirtualTable render", virtualListController);
|
|
298
|
+
|
|
275
299
|
// useTraceUpdate(virtualListController);
|
|
276
300
|
return (
|
|
277
301
|
<div
|
|
@@ -16,7 +16,7 @@ type VirtualTableCellProps<T extends any> = {
|
|
|
16
16
|
};
|
|
17
17
|
|
|
18
18
|
export const VirtualTableCell = React.memo<VirtualTableCellProps<any>>(
|
|
19
|
-
function VirtualTableCell<T
|
|
19
|
+
function VirtualTableCell<T>(props: VirtualTableCellProps<T>) {
|
|
20
20
|
// @ts-ignore
|
|
21
21
|
return props.rowData && props.cellRenderer(
|
|
22
22
|
{
|
|
@@ -30,14 +30,6 @@ export const VirtualTableCell = React.memo<VirtualTableCellProps<any>>(
|
|
|
30
30
|
width: props.column.width
|
|
31
31
|
} as CellRendererParams<T>
|
|
32
32
|
);
|
|
33
|
-
// return props.rowData && <props.cellRenderer
|
|
34
|
-
// rowData={props.rowData}
|
|
35
|
-
// rowIndex={props.rowIndex}
|
|
36
|
-
// isScrolling={false}
|
|
37
|
-
// column={props.column}
|
|
38
|
-
// columns={props.columns}
|
|
39
|
-
// columnIndex={props.columnIndex}
|
|
40
|
-
// width={props.column.width}/>
|
|
41
33
|
},
|
|
42
34
|
(a, b) => {
|
|
43
35
|
return equal(a.rowData, b.rowData) &&
|
|
@@ -31,11 +31,6 @@ export interface VirtualTableProps<T extends Record<string, any>> {
|
|
|
31
31
|
*/
|
|
32
32
|
cellRenderer: React.ComponentType<CellRendererParams<T>>;
|
|
33
33
|
|
|
34
|
-
/**
|
|
35
|
-
* If enabled, content is loaded in batch
|
|
36
|
-
*/
|
|
37
|
-
paginationEnabled?: boolean;
|
|
38
|
-
|
|
39
34
|
/**
|
|
40
35
|
* Set this callback if you want to support some combinations
|
|
41
36
|
* of filter combinations only.
|
|
@@ -50,6 +45,11 @@ export interface VirtualTableProps<T extends Record<string, any>> {
|
|
|
50
45
|
*/
|
|
51
46
|
onEndReached?: () => void;
|
|
52
47
|
|
|
48
|
+
/**
|
|
49
|
+
* Offset in pixels where the onEndReached callback is triggered
|
|
50
|
+
*/
|
|
51
|
+
endOffset?: number;
|
|
52
|
+
|
|
53
53
|
/**
|
|
54
54
|
* When the pagination should be reset. E.g. the filters or sorting
|
|
55
55
|
* has been reset.
|
|
@@ -147,9 +147,14 @@ export interface VirtualTableProps<T extends Record<string, any>> {
|
|
|
147
147
|
*/
|
|
148
148
|
AddColumnComponent?: React.ComponentType;
|
|
149
149
|
|
|
150
|
+
/**
|
|
151
|
+
* Debug mode
|
|
152
|
+
*/
|
|
153
|
+
debug?: boolean;
|
|
154
|
+
|
|
150
155
|
}
|
|
151
156
|
|
|
152
|
-
export type CellRendererParams<T
|
|
157
|
+
export type CellRendererParams<T = any> = {
|
|
153
158
|
column: VirtualTableColumn;
|
|
154
159
|
columns: VirtualTableColumn[];
|
|
155
160
|
columnIndex: number;
|
|
@@ -163,7 +168,7 @@ export type CellRendererParams<T extends any = any> = {
|
|
|
163
168
|
* @see Table
|
|
164
169
|
* @group Components
|
|
165
170
|
*/
|
|
166
|
-
export interface VirtualTableColumn<CustomProps
|
|
171
|
+
export interface VirtualTableColumn<CustomProps = any> {
|
|
167
172
|
|
|
168
173
|
/**
|
|
169
174
|
* Data key for the cell value, could be "a.b.c"
|
|
@@ -237,7 +242,6 @@ export type OnVirtualTableColumnResizeParams = {
|
|
|
237
242
|
column: VirtualTableColumn
|
|
238
243
|
};
|
|
239
244
|
|
|
240
|
-
|
|
241
245
|
/**
|
|
242
246
|
* @see Table
|
|
243
247
|
* @group Components
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
import { DateTimeField } from "@firecms/ui";
|
|
2
|
+
import { cls, DateTimeField, focusedDisabled } from "@firecms/ui";
|
|
3
3
|
import { useCustomizationController } from "../../../hooks";
|
|
4
4
|
|
|
5
5
|
export function VirtualTableDateField(props: {
|
|
@@ -28,8 +28,8 @@ export function VirtualTableDateField(props: {
|
|
|
28
28
|
onChange={(dateValue) => updateValue(dateValue ?? null)}
|
|
29
29
|
size={"medium"}
|
|
30
30
|
invisible={true}
|
|
31
|
-
|
|
32
|
-
|
|
31
|
+
inputClassName={cls("w-full h-full", focusedDisabled)}
|
|
32
|
+
className={cls("w-full h-full", focusedDisabled)}
|
|
33
33
|
mode={mode}
|
|
34
34
|
locale={locale}
|
|
35
35
|
/>
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React, { useEffect, useRef, useState } from "react";
|
|
2
2
|
|
|
3
3
|
import { useDebouncedCallback } from "../../../util";
|
|
4
|
-
import { TextareaAutosize } from "@firecms/ui";
|
|
4
|
+
import { focusedDisabled, TextareaAutosize } from "@firecms/ui";
|
|
5
5
|
|
|
6
6
|
export function VirtualTableInput(props: {
|
|
7
7
|
error: Error | undefined;
|
|
@@ -58,6 +58,7 @@ export function VirtualTableInput(props: {
|
|
|
58
58
|
|
|
59
59
|
return (
|
|
60
60
|
<TextareaAutosize
|
|
61
|
+
className={focusedDisabled}
|
|
61
62
|
ref={ref}
|
|
62
63
|
style={{
|
|
63
64
|
padding: 0,
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import React, { useEffect, useRef, useState } from "react";
|
|
2
2
|
import { useDebouncedCallback } from "../../../util";
|
|
3
|
+
import { cls, focusedDisabled } from "@firecms/ui";
|
|
3
4
|
|
|
4
5
|
export function VirtualTableNumberInput(props: {
|
|
5
6
|
error: Error | undefined;
|
|
@@ -65,7 +66,7 @@ export function VirtualTableNumberInput(props: {
|
|
|
65
66
|
return (
|
|
66
67
|
<input
|
|
67
68
|
ref={ref}
|
|
68
|
-
className="w-full text-right p-0 m-0 bg-transparent border-none resize-none outline-none font-normal leading-normal text-unset"
|
|
69
|
+
className={cls("w-full text-right p-0 m-0 bg-transparent border-none resize-none outline-none font-normal leading-normal text-unset", focusedDisabled)}
|
|
69
70
|
style={{
|
|
70
71
|
textAlign: align
|
|
71
72
|
}}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { EnumValueConfig } from "../../../types";
|
|
2
|
-
import {
|
|
2
|
+
import { EnumValuesChip } from "../../../preview";
|
|
3
3
|
import React, { useCallback, useEffect } from "react";
|
|
4
4
|
import { MultiSelect, MultiSelectItem, Select, SelectItem } from "@firecms/ui";
|
|
5
5
|
|
|
@@ -18,9 +18,7 @@ export function VirtualTableSelect(props: {
|
|
|
18
18
|
}) {
|
|
19
19
|
|
|
20
20
|
const {
|
|
21
|
-
name,
|
|
22
21
|
enumValues,
|
|
23
|
-
error,
|
|
24
22
|
internalValue,
|
|
25
23
|
disabled,
|
|
26
24
|
small,
|
|
@@ -41,6 +39,7 @@ export function VirtualTableSelect(props: {
|
|
|
41
39
|
}, [focused, ref]);
|
|
42
40
|
|
|
43
41
|
const onChange = useCallback((updatedValue: string | string[]) => {
|
|
42
|
+
console.trace("onChange");
|
|
44
43
|
if (valueType === "number") {
|
|
45
44
|
if (multiple) {
|
|
46
45
|
const newValue = (updatedValue as string[]).map((v) => parseFloat(v));
|
|
@@ -58,37 +57,27 @@ export function VirtualTableSelect(props: {
|
|
|
58
57
|
}
|
|
59
58
|
}, [multiple, updateValue, valueType]);
|
|
60
59
|
|
|
61
|
-
const renderValue = (enumKey
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
enumValues={enumValues}
|
|
68
|
-
size={small ? "small" : "medium"}/>;
|
|
69
|
-
} else {
|
|
70
|
-
return <EnumValuesChip
|
|
71
|
-
key={`${enumKey}-${index}`}
|
|
72
|
-
enumKey={enumKey}
|
|
73
|
-
enumValues={enumValues}
|
|
74
|
-
size={small ? "small" : "medium"}/>;
|
|
75
|
-
}
|
|
60
|
+
const renderValue = (enumKey?: string | number) => {
|
|
61
|
+
return <EnumValuesChip
|
|
62
|
+
key={`${enumKey}`}
|
|
63
|
+
enumKey={String(enumKey)}
|
|
64
|
+
enumValues={enumValues}
|
|
65
|
+
size={small ? "small" : "medium"}/>;
|
|
76
66
|
};
|
|
67
|
+
|
|
77
68
|
return (
|
|
78
69
|
multiple
|
|
79
70
|
? <MultiSelect
|
|
80
71
|
inputRef={ref}
|
|
81
|
-
containerClassName="w-full h-full"
|
|
82
72
|
className="w-full h-full p-0 bg-transparent"
|
|
83
73
|
position={"item-aligned"}
|
|
84
74
|
disabled={disabled}
|
|
85
|
-
|
|
86
|
-
|
|
75
|
+
includeClear={false}
|
|
76
|
+
useChips={false}
|
|
87
77
|
value={validValue
|
|
88
78
|
? ((internalValue as any[]).map(v => v.toString()))
|
|
89
79
|
: ([])}
|
|
90
|
-
|
|
91
|
-
renderValue={renderValue}>
|
|
80
|
+
onValueChange={onChange}>
|
|
92
81
|
{enumValues?.map((enumConfig) => (
|
|
93
82
|
<MultiSelectItem
|
|
94
83
|
key={enumConfig.id}
|
|
@@ -105,14 +94,11 @@ export function VirtualTableSelect(props: {
|
|
|
105
94
|
className="w-full h-full p-0 bg-transparent"
|
|
106
95
|
position={"item-aligned"}
|
|
107
96
|
disabled={disabled}
|
|
108
|
-
multiple={multiple}
|
|
109
97
|
padding={false}
|
|
110
|
-
includeFocusOutline={false}
|
|
111
98
|
value={validValue
|
|
112
|
-
?
|
|
113
|
-
:
|
|
99
|
+
? internalValue?.toString()
|
|
100
|
+
: ""}
|
|
114
101
|
onValueChange={onChange}
|
|
115
|
-
onMultiValueChange={onChange}
|
|
116
102
|
renderValue={renderValue}>
|
|
117
103
|
{enumValues?.map((enumConfig) => (
|
|
118
104
|
<SelectItem
|
|
@@ -106,3 +106,16 @@ export function getColumnKeysForProperty(property: ResolvedProperty, key: string
|
|
|
106
106
|
disabled: disabled || Boolean(property.disabled) || Boolean(property.readOnly)
|
|
107
107
|
}];
|
|
108
108
|
}
|
|
109
|
+
|
|
110
|
+
export function getFormFieldKeys(collection: EntityCollection): string[] {
|
|
111
|
+
const propertyKeys = Object.keys(collection.properties);
|
|
112
|
+
const additionalFields = collection.additionalFields ?? [];
|
|
113
|
+
const allKeys = [
|
|
114
|
+
...propertyKeys,
|
|
115
|
+
...additionalFields.map((field) => field.key)
|
|
116
|
+
];
|
|
117
|
+
if (collection.propertiesOrder) {
|
|
118
|
+
return collection.propertiesOrder.filter(key => allKeys.includes(key));
|
|
119
|
+
}
|
|
120
|
+
return allKeys;
|
|
121
|
+
}
|
|
@@ -80,6 +80,18 @@ export function useDataSourceEntityCollectionTableController<M extends Record<st
|
|
|
80
80
|
const [searchString, setSearchString] = React.useState<string | undefined>();
|
|
81
81
|
const [itemCount, setItemCount] = React.useState<number | undefined>(paginationEnabled ? pageSize : undefined);
|
|
82
82
|
|
|
83
|
+
const checkFilterCombination = useCallback((filterValues: FilterValues<any>,
|
|
84
|
+
sortBy?: [string, "asc" | "desc"]) => {
|
|
85
|
+
if (!dataSource.isFilterCombinationValid)
|
|
86
|
+
return true;
|
|
87
|
+
return dataSource.isFilterCombinationValid({
|
|
88
|
+
path: resolvedPath,
|
|
89
|
+
collection,
|
|
90
|
+
filterValues,
|
|
91
|
+
sortBy
|
|
92
|
+
})
|
|
93
|
+
}, []);
|
|
94
|
+
|
|
83
95
|
const initialSortInternal = useMemo(() => {
|
|
84
96
|
if (initialSort && forceFilter && !checkFilterCombination(forceFilter, initialSort)) {
|
|
85
97
|
console.warn("Initial sort is not compatible with the force filter. Ignoring initial sort");
|
|
@@ -108,18 +120,6 @@ export function useDataSourceEntityCollectionTableController<M extends Record<st
|
|
|
108
120
|
const [dataLoadingError, setDataLoadingError] = useState<Error | undefined>();
|
|
109
121
|
const [noMoreToLoad, setNoMoreToLoad] = useState<boolean>(false);
|
|
110
122
|
|
|
111
|
-
const checkFilterCombination = useCallback((filterValues: FilterValues<any>,
|
|
112
|
-
sortBy?: [string, "asc" | "desc"]) => {
|
|
113
|
-
if (!dataSource.isFilterCombinationValid)
|
|
114
|
-
return true;
|
|
115
|
-
return dataSource.isFilterCombinationValid({
|
|
116
|
-
path: resolvedPath,
|
|
117
|
-
collection,
|
|
118
|
-
filterValues,
|
|
119
|
-
sortBy
|
|
120
|
-
})
|
|
121
|
-
}, []);
|
|
122
|
-
|
|
123
123
|
const clearFilter = useCallback(() => setFilterValues(forceFilter ?? undefined), [forceFilter]);
|
|
124
124
|
|
|
125
125
|
const updateFilterValues = useCallback((updatedFilter: FilterValues<Extract<keyof M, string>> | undefined) => {
|
package/src/components/index.tsx
CHANGED
|
@@ -19,6 +19,7 @@ export * from "./EntityCollectionView/EntityCollectionViewActions";
|
|
|
19
19
|
export * from "./EntityCollectionView/useSelectionController";
|
|
20
20
|
|
|
21
21
|
export * from "./PropertyConfigBadge";
|
|
22
|
+
export * from "./PropertyIdCopyTooltip";
|
|
22
23
|
|
|
23
24
|
export * from "./EntityCollectionTable";
|
|
24
25
|
export * from "./NotFoundPage";
|
|
@@ -45,7 +45,7 @@ export type DefaultAppBarProps<ADDITIONAL_PROPS = object> = {
|
|
|
45
45
|
* This component renders the main app bar of FireCMS.
|
|
46
46
|
* You will likely not need to use this component directly.
|
|
47
47
|
*
|
|
48
|
-
|
|
48
|
+
|
|
49
49
|
*/
|
|
50
50
|
export const DefaultAppBar = function DefaultAppBar({
|
|
51
51
|
title,
|
|
@@ -95,7 +95,7 @@ export const DefaultAppBar = function DefaultAppBar({
|
|
|
95
95
|
return (
|
|
96
96
|
<div
|
|
97
97
|
style={style}
|
|
98
|
-
className={cls("
|
|
98
|
+
className={cls("w-full h-16 transition-all ease-in duration-75 fixed",
|
|
99
99
|
{
|
|
100
100
|
"pl-[17rem]": drawerOpen && largeLayout,
|
|
101
101
|
"pl-20": hasDrawer && !(drawerOpen && largeLayout),
|
|
@@ -124,7 +124,7 @@ export const DefaultAppBar = function DefaultAppBar({
|
|
|
124
124
|
{typeof title === "string"
|
|
125
125
|
? <Typography variant="subtitle1"
|
|
126
126
|
noWrap
|
|
127
|
-
className={"ml-2
|
|
127
|
+
className={cls("transition-all", drawerOpen ? "ml-2" : "")}>
|
|
128
128
|
{title}
|
|
129
129
|
</Typography>
|
|
130
130
|
: title}
|
|
@@ -30,15 +30,15 @@ export function DefaultDrawer({
|
|
|
30
30
|
logo
|
|
31
31
|
} = useApp();
|
|
32
32
|
|
|
33
|
+
const [adminMenuOpen, setAdminMenuOpen] = React.useState(false);
|
|
34
|
+
|
|
33
35
|
const analyticsController = useAnalyticsController();
|
|
34
36
|
const navigation = useNavigationController();
|
|
35
37
|
|
|
36
|
-
const tooltipsOpen = drawerHovered && !drawerOpen;
|
|
38
|
+
const tooltipsOpen = drawerHovered && !drawerOpen && !adminMenuOpen;
|
|
37
39
|
const largeLayout = useLargeLayout();
|
|
38
40
|
const navigate = useNavigate();
|
|
39
41
|
|
|
40
|
-
const [adminMenuOpen, setAdminMenuOpen] = React.useState(false);
|
|
41
|
-
|
|
42
42
|
if (!navigation.topLevelNavigation)
|
|
43
43
|
throw Error("Navigation not ready in Drawer");
|
|
44
44
|
|
|
@@ -51,9 +51,9 @@ export function DefaultDrawer({
|
|
|
51
51
|
const groupsWithoutAdmin = groups.filter(g => g !== "Admin");
|
|
52
52
|
|
|
53
53
|
const buildGroupHeader = useCallback((group?: string) => {
|
|
54
|
-
if (!drawerOpen) return <div className="
|
|
54
|
+
if (!drawerOpen) return <div className="w-full"/>;
|
|
55
55
|
return <div
|
|
56
|
-
className="
|
|
56
|
+
className="pl-6 pr-8 py-4 flex flex-row items-center">
|
|
57
57
|
<Typography variant={"caption"}
|
|
58
58
|
color={"secondary"}
|
|
59
59
|
className="font-medium flex-grow line-clamp-1">
|
|
@@ -78,10 +78,14 @@ export function DefaultDrawer({
|
|
|
78
78
|
|
|
79
79
|
<DrawerLogo logo={logo}/>
|
|
80
80
|
|
|
81
|
-
<div className={"overflow-scroll no-scrollbar"}
|
|
81
|
+
<div className={"mt-4 flex-grow overflow-scroll no-scrollbar"}
|
|
82
|
+
style={{
|
|
83
|
+
maskImage: "linear-gradient(to bottom, transparent 0, black 20px, black calc(100% - 20px), transparent 100%)",
|
|
84
|
+
}}>
|
|
82
85
|
|
|
83
86
|
{groupsWithoutAdmin.map((group) => (
|
|
84
|
-
<
|
|
87
|
+
<div
|
|
88
|
+
className={"bg-gray-50 dark:bg-gray-800 dark:bg-opacity-30 my-4 rounded-lg ml-4"}
|
|
85
89
|
key={`drawer_group_${group}`}>
|
|
86
90
|
{buildGroupHeader(group)}
|
|
87
91
|
{Object.values(navigationEntries)
|
|
@@ -89,18 +93,20 @@ export function DefaultDrawer({
|
|
|
89
93
|
.map((view, index) =>
|
|
90
94
|
<DrawerNavigationItem
|
|
91
95
|
key={`navigation_${index}`}
|
|
92
|
-
icon={<IconForView collectionOrView={view.collection ?? view.view}/>}
|
|
96
|
+
icon={<IconForView collectionOrView={view.collection ?? view.view} size={"small"}/>}
|
|
93
97
|
tooltipsOpen={tooltipsOpen}
|
|
98
|
+
adminMenuOpen={adminMenuOpen}
|
|
94
99
|
drawerOpen={drawerOpen}
|
|
95
100
|
onClick={() => onClick(view)}
|
|
96
101
|
url={view.url}
|
|
97
102
|
name={view.name}/>)}
|
|
98
|
-
</
|
|
103
|
+
</div>
|
|
99
104
|
))}
|
|
100
105
|
|
|
101
106
|
</div>
|
|
102
107
|
|
|
103
108
|
{adminViews.length > 0 && <Menu
|
|
109
|
+
side={"right"}
|
|
104
110
|
open={adminMenuOpen}
|
|
105
111
|
onOpenChange={setAdminMenuOpen}
|
|
106
112
|
trigger={
|
|
@@ -144,7 +150,7 @@ export function DefaultDrawer({
|
|
|
144
150
|
* It expands when the drawer is open.
|
|
145
151
|
*
|
|
146
152
|
* @param logo
|
|
147
|
-
|
|
153
|
+
|
|
148
154
|
*/
|
|
149
155
|
export function DrawerLogo({ logo }: {
|
|
150
156
|
logo?: string;
|
|
@@ -155,9 +161,9 @@ export function DrawerLogo({ logo }: {
|
|
|
155
161
|
return <div
|
|
156
162
|
style={{
|
|
157
163
|
transition: "padding 100ms cubic-bezier(0.4, 0, 0.6, 1) 0ms",
|
|
158
|
-
padding: drawerOpen ? "32px 144px 0px 24px" : "72px
|
|
164
|
+
padding: drawerOpen ? "32px 144px 0px 24px" : "72px 12px 0px 12px"
|
|
159
165
|
}}
|
|
160
|
-
className={cls("cursor-pointer")}>
|
|
166
|
+
className={cls("cursor-pointer ml-4")}>
|
|
161
167
|
|
|
162
168
|
<Tooltip title={"Home"}
|
|
163
169
|
sideOffset={20}
|