@firecms/core 3.0.0-canary.5 → 3.0.0-canary.50
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/internal/CollectionTableToolbar.d.ts +1 -4
- 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 +25 -7
- package/dist/components/EntityView.d.ts +11 -0
- package/dist/components/FieldCaption.d.ts +5 -0
- package/dist/components/FireCMSAppBar.d.ts +3 -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/SelectableTable/SelectableTable.d.ts +1 -1
- package/dist/components/VirtualTable/VirtualTableProps.d.ts +1 -1
- package/dist/components/common/types.d.ts +4 -6
- package/dist/components/common/useDataSourceEntityCollectionTableController.d.ts +3 -0
- package/dist/components/index.d.ts +4 -2
- package/dist/contexts/AuthControllerContext.d.ts +1 -1
- 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 +1 -1
- 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 +1 -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 +10402 -9898
- 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 -12
- 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 +1 -7
- package/dist/types/analytics.d.ts +1 -1
- package/dist/types/auth.d.ts +37 -1
- package/dist/types/collections.d.ts +29 -5
- package/dist/types/datasource.d.ts +3 -6
- 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 +14 -13
- package/dist/types/permissions.d.ts +5 -1
- package/dist/types/plugins.d.ts +20 -20
- package/dist/types/properties.d.ts +4 -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 -4
- package/dist/util/icons.d.ts +8 -2
- package/dist/util/navigation_utils.d.ts +2 -2
- package/dist/util/permissions.d.ts +4 -4
- package/dist/util/references.d.ts +4 -2
- package/dist/util/resolutions.d.ts +9 -13
- 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 +2 -2
- package/src/components/EntityCollectionTable/EntityCollectionTable.tsx +275 -278
- package/src/components/EntityCollectionTable/EntityCollectionTableProps.tsx +9 -5
- package/src/components/EntityCollectionTable/PropertyTableCell.tsx +44 -44
- package/src/components/EntityCollectionTable/column_utils.tsx +3 -3
- package/src/components/EntityCollectionTable/fields/TableReferenceField.tsx +9 -16
- package/src/components/EntityCollectionTable/fields/TableStorageUpload.tsx +3 -3
- package/src/components/EntityCollectionTable/internal/CollectionTableToolbar.tsx +27 -32
- package/src/components/EntityCollectionTable/internal/EntityTableCell.tsx +11 -6
- package/src/components/EntityCollectionTable/internal/default_entity_actions.tsx +9 -5
- package/src/components/EntityCollectionTable/internal/popup_field/PopupFormField.tsx +2 -4
- package/src/components/EntityCollectionView/EntityCollectionView.tsx +69 -64
- 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 +207 -70
- package/src/components/EntityView.tsx +84 -0
- package/src/components/FieldCaption.tsx +14 -0
- package/src/components/FireCMSAppBar.tsx +33 -11
- 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/ReferenceTable/ReferenceSelectionTable.tsx +4 -4
- package/src/components/ReferenceWidget.tsx +4 -4
- package/src/components/SearchIconsView.tsx +4 -4
- package/src/components/SelectableTable/SelectableTable.tsx +1 -1
- 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 +35 -24
- package/src/components/SelectableTable/filters/StringNumberFilterField.tsx +35 -15
- package/src/components/VirtualTable/VirtualTable.tsx +28 -20
- package/src/components/VirtualTable/VirtualTableProps.tsx +1 -1
- package/src/components/VirtualTable/fields/VirtualTableDateField.tsx +1 -1
- package/src/components/common/types.tsx +4 -6
- package/src/components/common/useDataSourceEntityCollectionTableController.tsx +12 -1
- package/src/components/index.tsx +4 -2
- package/src/contexts/AuthControllerContext.tsx +1 -1
- package/src/core/Drawer.tsx +66 -39
- package/src/core/{EntityView.tsx → EntityEditView.tsx} +21 -40
- package/src/core/EntitySidePanel.tsx +2 -2
- package/src/core/FireCMS.tsx +18 -3
- package/src/core/NavigationRoutes.tsx +11 -4
- package/src/core/Scaffold.tsx +5 -4
- package/src/core/field_configs.tsx +1 -2
- package/src/form/EntityForm.tsx +40 -21
- package/src/form/PropertyFieldBinding.tsx +0 -2
- package/src/form/components/StorageItemPreview.tsx +5 -3
- package/src/form/components/StorageUploadProgress.tsx +7 -6
- package/src/form/field_bindings/ArrayOfReferencesFieldBinding.tsx +8 -12
- package/src/form/field_bindings/DateTimeFieldBinding.tsx +1 -1
- package/src/form/field_bindings/KeyValueFieldBinding.tsx +15 -15
- package/src/form/field_bindings/MapFieldBinding.tsx +15 -15
- package/src/form/field_bindings/ReadOnlyFieldBinding.tsx +1 -1
- package/src/form/field_bindings/ReferenceFieldBinding.tsx +1 -0
- package/src/form/field_bindings/StorageUploadFieldBinding.tsx +14 -5
- 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 +2 -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 +2 -0
- package/src/hooks/useBuildLocalConfigurationPersistence.tsx +9 -10
- package/src/hooks/useBuildModeController.tsx +11 -5
- package/src/hooks/useBuildNavigationController.tsx +199 -81
- package/src/hooks/useProjectLog.tsx +17 -7
- package/src/hooks/useReferenceDialog.tsx +2 -2
- package/src/hooks/useStorageSource.tsx +7 -2
- package/src/hooks/useValidateAuthenticator.tsx +115 -0
- package/src/internal/useBuildDataSource.ts +42 -44
- package/src/internal/useBuildSideEntityController.tsx +86 -20
- package/src/preview/PropertyPreview.tsx +3 -14
- package/src/preview/PropertyPreviewProps.tsx +1 -11
- package/src/preview/components/BooleanPreview.tsx +19 -4
- package/src/preview/components/EnumValuesChip.tsx +1 -1
- package/src/preview/components/ReferencePreview.tsx +55 -147
- package/src/preview/property_previews/ArrayOfMapsPreview.tsx +0 -1
- package/src/preview/property_previews/ArrayOfReferencesPreview.tsx +0 -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 +0 -1
- package/src/preview/property_previews/ArrayPropertyPreview.tsx +0 -1
- 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 +33 -5
- package/src/types/datasource.ts +8 -5
- 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 -16
- package/src/types/permissions.ts +6 -1
- package/src/types/plugins.tsx +26 -28
- package/src/types/properties.ts +8 -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/icon_list.ts +2 -2
- package/src/util/icon_synonyms.ts +1 -4
- package/src/util/icons.tsx +11 -3
- package/src/util/navigation_utils.ts +6 -6
- package/src/util/objects.ts +0 -14
- package/src/util/permissions.ts +11 -8
- package/src/util/references.ts +36 -5
- package/src/util/resolutions.ts +6 -24
- package/src/util/strings.ts +2 -2
- package/src/util/useTraceUpdate.tsx +2 -1
- package/dist/core/SideEntityView.d.ts +0 -7
- 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/useLocaleConfig.tsx +0 -18
- package/src/types/appcheck.ts +0 -29
|
@@ -24,7 +24,7 @@ import { getPreviewSizeFrom } from "../../preview/util";
|
|
|
24
24
|
import { isReadOnly } from "../../util";
|
|
25
25
|
|
|
26
26
|
import { CustomFieldValidator, mapPropertyToYup } from "../../form/validation";
|
|
27
|
-
import {
|
|
27
|
+
import { useFireCMSContext } from "../../hooks";
|
|
28
28
|
|
|
29
29
|
import { EntityTableCell } from "./internal/EntityTableCell";
|
|
30
30
|
import { EntityTableCellActions } from "./internal/EntityTableCellActions";
|
|
@@ -33,7 +33,7 @@ import { getRowHeight } from "../VirtualTable/common";
|
|
|
33
33
|
import { useSelectableTableController } from "../SelectableTable/SelectableTableContext";
|
|
34
34
|
import { useClearRestoreValue } from "../../form/useClearRestoreValue";
|
|
35
35
|
|
|
36
|
-
export interface PropertyTableCellProps<T extends CMSType
|
|
36
|
+
export interface PropertyTableCellProps<T extends CMSType> {
|
|
37
37
|
propertyKey: string;
|
|
38
38
|
columnIndex: number;
|
|
39
39
|
align: "right" | "left" | "center";
|
|
@@ -46,6 +46,7 @@ export interface PropertyTableCellProps<T extends CMSType, M extends Record<stri
|
|
|
46
46
|
entity: Entity<any>;
|
|
47
47
|
path: string;
|
|
48
48
|
disabled: boolean;
|
|
49
|
+
enablePopupIcon?: boolean;
|
|
49
50
|
}
|
|
50
51
|
|
|
51
52
|
function isStorageProperty(property: ResolvedProperty) {
|
|
@@ -62,7 +63,7 @@ function isStorageProperty(property: ResolvedProperty) {
|
|
|
62
63
|
return false;
|
|
63
64
|
}
|
|
64
65
|
|
|
65
|
-
export const PropertyTableCell = React.memo<PropertyTableCellProps<any
|
|
66
|
+
export const PropertyTableCell = React.memo<PropertyTableCellProps<any>>(
|
|
66
67
|
function PropertyTableCell<T extends CMSType, M extends Record<string, any>>({
|
|
67
68
|
propertyKey,
|
|
68
69
|
customFieldValidator,
|
|
@@ -74,10 +75,9 @@ export const PropertyTableCell = React.memo<PropertyTableCellProps<any, any>>(
|
|
|
74
75
|
path,
|
|
75
76
|
entity,
|
|
76
77
|
readonly,
|
|
77
|
-
disabled: disabledProp
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
const context = useFireCMSContext();
|
|
78
|
+
disabled: disabledProp,
|
|
79
|
+
enablePopupIcon = true
|
|
80
|
+
}: PropertyTableCellProps<T>) {
|
|
81
81
|
|
|
82
82
|
const {
|
|
83
83
|
onValueChange,
|
|
@@ -95,6 +95,7 @@ export const PropertyTableCell = React.memo<PropertyTableCellProps<any, any>>(
|
|
|
95
95
|
const internalValueRef = useRef(value);
|
|
96
96
|
|
|
97
97
|
const [error, setError] = useState<Error | undefined>();
|
|
98
|
+
const [validationError, setValidationError] = useState<Error | undefined>();
|
|
98
99
|
const [saved, setSaved] = useState<boolean>(false);
|
|
99
100
|
|
|
100
101
|
const onValueUpdated = useCallback(() => {
|
|
@@ -120,7 +121,7 @@ export const PropertyTableCell = React.memo<PropertyTableCellProps<any, any>>(
|
|
|
120
121
|
useEffect(
|
|
121
122
|
() => {
|
|
122
123
|
if (!equal(value, internalValueRef.current)) {
|
|
123
|
-
|
|
124
|
+
setValidationError(undefined);
|
|
124
125
|
setInternalValue(value);
|
|
125
126
|
internalValueRef.current = value;
|
|
126
127
|
onValueUpdated();
|
|
@@ -136,32 +137,34 @@ export const PropertyTableCell = React.memo<PropertyTableCellProps<any, any>>(
|
|
|
136
137
|
validation
|
|
137
138
|
.validate(value)
|
|
138
139
|
.then(() => {
|
|
139
|
-
|
|
140
|
+
setValidationError(undefined);
|
|
140
141
|
internalValueRef.current = value;
|
|
141
142
|
if (onValueChange) {
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
})
|
|
143
|
+
try {
|
|
144
|
+
onValueChange({
|
|
145
|
+
value,
|
|
146
|
+
propertyKey,
|
|
147
|
+
setError,
|
|
148
|
+
onValueUpdated,
|
|
149
|
+
data: entity,
|
|
150
|
+
});
|
|
151
|
+
} catch (e:any) {
|
|
152
|
+
console.error("onValueChange error", e);
|
|
153
|
+
setError(e);
|
|
154
|
+
}
|
|
155
|
+
|
|
151
156
|
}
|
|
152
157
|
})
|
|
153
158
|
.catch((e) => {
|
|
154
|
-
|
|
159
|
+
setValidationError(e);
|
|
155
160
|
});
|
|
156
161
|
};
|
|
157
162
|
|
|
158
163
|
useEffect(() => {
|
|
159
164
|
validation
|
|
160
165
|
.validate(internalValue)
|
|
161
|
-
.then(() =>
|
|
162
|
-
.catch(
|
|
163
|
-
setError(e);
|
|
164
|
-
});
|
|
166
|
+
.then(() => setValidationError(undefined))
|
|
167
|
+
.catch(setValidationError);
|
|
165
168
|
}, [internalValue, validation, propertyKey, property, entity]);
|
|
166
169
|
|
|
167
170
|
const updateValue = (newValue: any | null) => {
|
|
@@ -237,7 +240,6 @@ export const PropertyTableCell = React.memo<PropertyTableCellProps<any, any>>(
|
|
|
237
240
|
height={getRowHeight(size)}
|
|
238
241
|
propertyKey={propertyKey}
|
|
239
242
|
property={property}
|
|
240
|
-
// entity={entity}
|
|
241
243
|
value={internalValue}
|
|
242
244
|
size={getPreviewSizeFrom(size)}
|
|
243
245
|
/>
|
|
@@ -247,7 +249,7 @@ export const PropertyTableCell = React.memo<PropertyTableCellProps<any, any>>(
|
|
|
247
249
|
if (!customField && (!customPreview || selected)) {
|
|
248
250
|
const isAStorageProperty = isStorageProperty(property);
|
|
249
251
|
if (isAStorageProperty) {
|
|
250
|
-
innerComponent = <TableStorageUpload error={error}
|
|
252
|
+
innerComponent = <TableStorageUpload error={validationError ?? error}
|
|
251
253
|
disabled={disabled}
|
|
252
254
|
focused={selected}
|
|
253
255
|
selected={selected}
|
|
@@ -274,7 +276,7 @@ export const PropertyTableCell = React.memo<PropertyTableCellProps<any, any>>(
|
|
|
274
276
|
valueType={"number"}
|
|
275
277
|
small={getPreviewSizeFrom(size) !== "medium"}
|
|
276
278
|
enumValues={numberProperty.enumValues}
|
|
277
|
-
error={error}
|
|
279
|
+
error={validationError ?? error}
|
|
278
280
|
internalValue={internalValue as string | number}
|
|
279
281
|
updateValue={updateValue}
|
|
280
282
|
/>;
|
|
@@ -282,7 +284,7 @@ export const PropertyTableCell = React.memo<PropertyTableCellProps<any, any>>(
|
|
|
282
284
|
} else {
|
|
283
285
|
innerComponent = <VirtualTableNumberInput
|
|
284
286
|
align={align}
|
|
285
|
-
error={error}
|
|
287
|
+
error={validationError ?? error}
|
|
286
288
|
focused={selected}
|
|
287
289
|
disabled={disabled}
|
|
288
290
|
value={internalValue as number}
|
|
@@ -300,14 +302,14 @@ export const PropertyTableCell = React.memo<PropertyTableCellProps<any, any>>(
|
|
|
300
302
|
valueType={"string"}
|
|
301
303
|
small={getPreviewSizeFrom(size) !== "medium"}
|
|
302
304
|
enumValues={stringProperty.enumValues}
|
|
303
|
-
error={error}
|
|
305
|
+
error={validationError ?? error}
|
|
304
306
|
internalValue={internalValue as string | number}
|
|
305
307
|
updateValue={updateValue}
|
|
306
308
|
/>;
|
|
307
309
|
fullHeight = true;
|
|
308
310
|
} else if (!stringProperty.storage) {
|
|
309
311
|
const multiline = Boolean(stringProperty.multiline) || Boolean(stringProperty.markdown);
|
|
310
|
-
innerComponent = <VirtualTableInput error={error}
|
|
312
|
+
innerComponent = <VirtualTableInput error={validationError ?? error}
|
|
311
313
|
disabled={disabled}
|
|
312
314
|
multiline={multiline}
|
|
313
315
|
focused={selected}
|
|
@@ -317,7 +319,7 @@ export const PropertyTableCell = React.memo<PropertyTableCellProps<any, any>>(
|
|
|
317
319
|
allowScroll = true;
|
|
318
320
|
}
|
|
319
321
|
} else if (property.dataType === "boolean") {
|
|
320
|
-
innerComponent = <VirtualTableSwitch error={error}
|
|
322
|
+
innerComponent = <VirtualTableSwitch error={validationError ?? error}
|
|
321
323
|
disabled={disabled}
|
|
322
324
|
focused={selected}
|
|
323
325
|
internalValue={internalValue as boolean}
|
|
@@ -325,7 +327,7 @@ export const PropertyTableCell = React.memo<PropertyTableCellProps<any, any>>(
|
|
|
325
327
|
/>;
|
|
326
328
|
} else if (property.dataType === "date") {
|
|
327
329
|
innerComponent = <VirtualTableDateField name={propertyKey as string}
|
|
328
|
-
error={error}
|
|
330
|
+
error={validationError ?? error}
|
|
329
331
|
disabled={disabled}
|
|
330
332
|
mode={property.mode}
|
|
331
333
|
focused={selected}
|
|
@@ -368,7 +370,7 @@ export const PropertyTableCell = React.memo<PropertyTableCellProps<any, any>>(
|
|
|
368
370
|
small={getPreviewSizeFrom(size) !== "medium"}
|
|
369
371
|
valueType={arrayProperty.of.dataType}
|
|
370
372
|
enumValues={arrayProperty.of.enumValues}
|
|
371
|
-
error={error}
|
|
373
|
+
error={validationError ?? error}
|
|
372
374
|
internalValue={internalValue as string | number}
|
|
373
375
|
updateValue={updateValue}
|
|
374
376
|
/>;
|
|
@@ -401,16 +403,14 @@ export const PropertyTableCell = React.memo<PropertyTableCellProps<any, any>>(
|
|
|
401
403
|
|
|
402
404
|
if (!innerComponent) {
|
|
403
405
|
allowScroll = false;
|
|
404
|
-
showExpandIcon = selected && !innerComponent && !disabled && !readOnlyProperty;
|
|
406
|
+
showExpandIcon = enablePopupIcon && selected && !innerComponent && !disabled && !readOnlyProperty;
|
|
405
407
|
innerComponent = (
|
|
406
|
-
<PropertyPreview
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
property={property}
|
|
413
|
-
size={getPreviewSizeFrom(size)}
|
|
408
|
+
<PropertyPreview width={width}
|
|
409
|
+
height={height}
|
|
410
|
+
propertyKey={propertyKey as string}
|
|
411
|
+
value={internalValue}
|
|
412
|
+
property={property}
|
|
413
|
+
size={getPreviewSizeFrom(size)}
|
|
414
414
|
/>
|
|
415
415
|
);
|
|
416
416
|
}
|
|
@@ -427,7 +427,7 @@ export const PropertyTableCell = React.memo<PropertyTableCellProps<any, any>>(
|
|
|
427
427
|
removePadding={removePadding}
|
|
428
428
|
fullHeight={fullHeight}
|
|
429
429
|
saved={saved}
|
|
430
|
-
error={error}
|
|
430
|
+
error={validationError ?? error}
|
|
431
431
|
align={align}
|
|
432
432
|
allowScroll={allowScroll}
|
|
433
433
|
showExpandIcon={showExpandIcon}
|
|
@@ -447,9 +447,9 @@ export const PropertyTableCell = React.memo<PropertyTableCellProps<any, any>>(
|
|
|
447
447
|
);
|
|
448
448
|
|
|
449
449
|
},
|
|
450
|
-
areEqual) as React.FunctionComponent<PropertyTableCellProps<any
|
|
450
|
+
areEqual) as React.FunctionComponent<PropertyTableCellProps<any>>;
|
|
451
451
|
|
|
452
|
-
function areEqual(prevProps: PropertyTableCellProps<any
|
|
452
|
+
function areEqual(prevProps: PropertyTableCellProps<any>, nextProps: PropertyTableCellProps<any>) {
|
|
453
453
|
return prevProps.height === nextProps.height &&
|
|
454
454
|
prevProps.propertyKey === nextProps.propertyKey &&
|
|
455
455
|
prevProps.align === nextProps.align &&
|
|
@@ -21,7 +21,6 @@ export interface PropertiesToColumnsParams<M extends Record<string, any>> {
|
|
|
21
21
|
properties: ResolvedProperties<M>;
|
|
22
22
|
sortable?: boolean;
|
|
23
23
|
forceFilter?: FilterValues<keyof M extends string ? keyof M : never>;
|
|
24
|
-
disabledFilter?: boolean;
|
|
25
24
|
AdditionalHeaderWidget?: React.ComponentType<{
|
|
26
25
|
property: ResolvedProperty,
|
|
27
26
|
propertyKey: string,
|
|
@@ -29,7 +28,8 @@ export interface PropertiesToColumnsParams<M extends Record<string, any>> {
|
|
|
29
28
|
}>;
|
|
30
29
|
}
|
|
31
30
|
|
|
32
|
-
export function propertiesToColumns<M extends Record<string, any>>({ properties, sortable, forceFilter,
|
|
31
|
+
export function propertiesToColumns<M extends Record<string, any>>({ properties, sortable, forceFilter, AdditionalHeaderWidget }: PropertiesToColumnsParams<M>): VirtualTableColumn[] {
|
|
32
|
+
const disabledFilter = Boolean(forceFilter);
|
|
33
33
|
return Object.entries<ResolvedProperty>(properties)
|
|
34
34
|
.flatMap(([key, property]) => getColumnKeysForProperty(property, key))
|
|
35
35
|
.map(({
|
|
@@ -45,7 +45,7 @@ export function propertiesToColumns<M extends Record<string, any>>({ properties,
|
|
|
45
45
|
align: getTableCellAlignment(property),
|
|
46
46
|
icon: getIconForProperty(property, "small"),
|
|
47
47
|
title: property.name ?? key as string,
|
|
48
|
-
sortable: sortable
|
|
48
|
+
sortable: sortable,
|
|
49
49
|
filter: !disabledFilter && filterable,
|
|
50
50
|
width: getTablePropertyColumnWidth(property),
|
|
51
51
|
resizable: true,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React, { useCallback, useState } from "react";
|
|
2
2
|
import equal from "react-fast-compare"
|
|
3
3
|
|
|
4
|
-
import { ReferencePreview
|
|
4
|
+
import { ReferencePreview } from "../../../preview";
|
|
5
5
|
import { CollectionSize, Entity, EntityCollection, EntityReference, FilterValues } from "../../../types";
|
|
6
6
|
|
|
7
7
|
import { getPreviewSizeFrom } from "../../../preview/util";
|
|
@@ -9,6 +9,7 @@ import { getReferenceFrom } from "../../../util";
|
|
|
9
9
|
import { useCustomizationController, useNavigationController, useReferenceDialog } from "../../../hooks";
|
|
10
10
|
import { ErrorView } from "../../ErrorView";
|
|
11
11
|
import { Button } from "@firecms/ui";
|
|
12
|
+
import { EntityPreviewContainer } from "../../EntityPreview";
|
|
12
13
|
|
|
13
14
|
type TableReferenceFieldProps = {
|
|
14
15
|
name: string;
|
|
@@ -28,7 +29,7 @@ export function TableReferenceField(props: TableReferenceFieldProps) {
|
|
|
28
29
|
|
|
29
30
|
const navigationController = useNavigationController();
|
|
30
31
|
const { path } = props;
|
|
31
|
-
const collection = navigationController.getCollection
|
|
32
|
+
const collection = navigationController.getCollection(path);
|
|
32
33
|
if (!collection) {
|
|
33
34
|
if (customizationController.components?.missingReference) {
|
|
34
35
|
return <customizationController.components.missingReference path={path}/>;
|
|
@@ -57,11 +58,6 @@ export const TableReferenceFieldSuccess = React.memo(
|
|
|
57
58
|
collection
|
|
58
59
|
} = props;
|
|
59
60
|
|
|
60
|
-
const [onHover, setOnHover] = useState(false);
|
|
61
|
-
|
|
62
|
-
const hoverTrue = useCallback(() => setOnHover(true), []);
|
|
63
|
-
const hoverFalse = useCallback(() => setOnHover(false), []);
|
|
64
|
-
|
|
65
61
|
const onSingleEntitySelected = useCallback((entity: Entity<any>) => {
|
|
66
62
|
updateValue(entity ? getReferenceFrom(entity) : null);
|
|
67
63
|
}, [updateValue]);
|
|
@@ -101,29 +97,29 @@ export const TableReferenceFieldSuccess = React.memo(
|
|
|
101
97
|
onClick={disabled ? undefined : handleOpen}
|
|
102
98
|
size={getPreviewSizeFrom(size)}
|
|
103
99
|
reference={internalValue as EntityReference}
|
|
104
|
-
|
|
100
|
+
hover={!disabled}
|
|
105
101
|
disabled={!path}
|
|
106
102
|
previewProperties={previewProperties}
|
|
107
103
|
/>;
|
|
108
104
|
else
|
|
109
|
-
return <
|
|
105
|
+
return <EntityPreviewContainer
|
|
110
106
|
onClick={disabled ? undefined : handleOpen}
|
|
111
107
|
size={getPreviewSizeFrom(size)}>
|
|
112
108
|
<ErrorView title="Value is not a reference." error={"Click to edit"}/>
|
|
113
|
-
</
|
|
109
|
+
</EntityPreviewContainer>;
|
|
114
110
|
};
|
|
115
111
|
|
|
116
112
|
const buildMultipleReferenceField = () => {
|
|
117
113
|
if (Array.isArray(internalValue))
|
|
118
114
|
return <>
|
|
119
115
|
{internalValue.map((reference, index) =>
|
|
120
|
-
<div className="
|
|
116
|
+
<div className="w-full my-0.5"
|
|
121
117
|
key={`preview_array_ref_${name}_${index}`}>
|
|
122
118
|
<ReferencePreview
|
|
123
119
|
onClick={disabled ? undefined : handleOpen}
|
|
124
120
|
size={"tiny"}
|
|
125
121
|
reference={reference}
|
|
126
|
-
|
|
122
|
+
hover={!disabled}
|
|
127
123
|
disabled={!path}
|
|
128
124
|
previewProperties={previewProperties}
|
|
129
125
|
/>
|
|
@@ -139,10 +135,7 @@ export const TableReferenceFieldSuccess = React.memo(
|
|
|
139
135
|
return <ErrorView error={"The specified collection does not exist"}/>;
|
|
140
136
|
|
|
141
137
|
return (
|
|
142
|
-
<div className="w-full"
|
|
143
|
-
onMouseEnter={hoverTrue}
|
|
144
|
-
onMouseMove={hoverTrue}
|
|
145
|
-
onMouseLeave={hoverFalse}>
|
|
138
|
+
<div className="w-full group">
|
|
146
139
|
|
|
147
140
|
{internalValue && !multiselect && buildSingleReferenceField()}
|
|
148
141
|
|
|
@@ -51,7 +51,7 @@ export function TableStorageUpload(props: {
|
|
|
51
51
|
entity,
|
|
52
52
|
path,
|
|
53
53
|
previewSize,
|
|
54
|
-
updateValue
|
|
54
|
+
updateValue,
|
|
55
55
|
} = props;
|
|
56
56
|
|
|
57
57
|
const storageSource = useStorageSource();
|
|
@@ -137,7 +137,7 @@ function StorageUpload({
|
|
|
137
137
|
storage,
|
|
138
138
|
onFilesAdded,
|
|
139
139
|
onFileUploadComplete,
|
|
140
|
-
storagePathBuilder
|
|
140
|
+
storagePathBuilder,
|
|
141
141
|
}: StorageUploadProps) {
|
|
142
142
|
|
|
143
143
|
const [onHover, setOnHover] = useState(false);
|
|
@@ -293,7 +293,7 @@ export function TableStorageItemPreview({
|
|
|
293
293
|
|
|
294
294
|
return (
|
|
295
295
|
<div
|
|
296
|
-
className={"relative
|
|
296
|
+
className={"relative p-2 max-w-full"}
|
|
297
297
|
>
|
|
298
298
|
|
|
299
299
|
{value &&
|
|
@@ -16,20 +16,27 @@ import { useLargeLayout } from "../../../hooks";
|
|
|
16
16
|
|
|
17
17
|
interface CollectionTableToolbarProps {
|
|
18
18
|
size: CollectionSize;
|
|
19
|
-
filterIsSet: boolean;
|
|
20
19
|
loading: boolean;
|
|
21
|
-
forceFilter?: boolean;
|
|
22
20
|
actionsStart?: React.ReactNode;
|
|
23
21
|
actions?: React.ReactNode;
|
|
24
22
|
title?: React.ReactNode,
|
|
25
23
|
onTextSearchClick?: () => void;
|
|
26
24
|
onTextSearch?: (searchString?: string) => void;
|
|
27
25
|
onSizeChanged: (size: CollectionSize) => void;
|
|
28
|
-
clearFilter?: () => void;
|
|
29
26
|
textSearchLoading?: boolean;
|
|
30
27
|
}
|
|
31
28
|
|
|
32
|
-
export function CollectionTableToolbar(
|
|
29
|
+
export function CollectionTableToolbar({
|
|
30
|
+
actions,
|
|
31
|
+
actionsStart,
|
|
32
|
+
loading,
|
|
33
|
+
onSizeChanged,
|
|
34
|
+
onTextSearch,
|
|
35
|
+
onTextSearchClick,
|
|
36
|
+
size,
|
|
37
|
+
textSearchLoading,
|
|
38
|
+
title
|
|
39
|
+
}: CollectionTableToolbarProps) {
|
|
33
40
|
|
|
34
41
|
const searchInputRef = React.useRef<HTMLInputElement>(null);
|
|
35
42
|
const largeLayout = useLargeLayout();
|
|
@@ -37,30 +44,20 @@ export function CollectionTableToolbar(props: CollectionTableToolbarProps) {
|
|
|
37
44
|
const searchLoading = React.useRef<boolean>(false);
|
|
38
45
|
|
|
39
46
|
useEffect(() => {
|
|
40
|
-
if (searchInputRef.current && searchLoading.current && !
|
|
47
|
+
if (searchInputRef.current && searchLoading.current && !textSearchLoading) {
|
|
41
48
|
searchInputRef.current.focus();
|
|
42
49
|
}
|
|
43
|
-
searchLoading.current =
|
|
44
|
-
}, [
|
|
45
|
-
|
|
46
|
-
const clearFilterButton = !props.forceFilter && props.filterIsSet && props.clearFilter &&
|
|
47
|
-
<Button
|
|
48
|
-
variant={"outlined"}
|
|
49
|
-
className="h-fit-content"
|
|
50
|
-
aria-label="filter clear"
|
|
51
|
-
onClick={props.clearFilter}
|
|
52
|
-
size="small">
|
|
53
|
-
<FilterListOffIcon/>
|
|
54
|
-
Clear filter
|
|
55
|
-
</Button>;
|
|
50
|
+
searchLoading.current = textSearchLoading ?? false;
|
|
51
|
+
}, [textSearchLoading]);
|
|
52
|
+
|
|
56
53
|
|
|
57
54
|
const sizeSelect = (
|
|
58
55
|
<Tooltip title={"Table row size"} side={"right"} sideOffset={4}>
|
|
59
56
|
<Select
|
|
60
|
-
value={
|
|
57
|
+
value={size as string}
|
|
61
58
|
className="w-16 h-10"
|
|
62
59
|
size={"small"}
|
|
63
|
-
onValueChange={(v) =>
|
|
60
|
+
onValueChange={(v) => onSizeChanged(v as CollectionSize)}
|
|
64
61
|
renderValue={(v) => <div className={"font-medium"}>{v.toUpperCase()}</div>}
|
|
65
62
|
>
|
|
66
63
|
{["xs", "s", "m", "l", "xl"].map((size) => (
|
|
@@ -78,36 +75,34 @@ export function CollectionTableToolbar(props: CollectionTableToolbarProps) {
|
|
|
78
75
|
|
|
79
76
|
<div className="flex items-center gap-2 md:mr-4 mr-2">
|
|
80
77
|
|
|
81
|
-
{
|
|
82
|
-
{
|
|
78
|
+
{title && <div className={"hidden lg:block"}>
|
|
79
|
+
{title}
|
|
83
80
|
</div>}
|
|
84
81
|
|
|
85
82
|
{sizeSelect}
|
|
86
83
|
|
|
87
|
-
{
|
|
88
|
-
|
|
89
|
-
{clearFilterButton}
|
|
84
|
+
{actionsStart}
|
|
90
85
|
|
|
91
86
|
</div>
|
|
92
87
|
|
|
93
88
|
<div className="flex items-center gap-2">
|
|
94
89
|
|
|
95
90
|
{largeLayout && <div className="w-[22px]">
|
|
96
|
-
{
|
|
91
|
+
{loading &&
|
|
97
92
|
<CircularProgress size={"small"}/>}
|
|
98
93
|
</div>}
|
|
99
94
|
|
|
100
|
-
{(
|
|
95
|
+
{(onTextSearch || onTextSearchClick) &&
|
|
101
96
|
<SearchBar
|
|
102
97
|
key={"search-bar"}
|
|
103
98
|
inputRef={searchInputRef}
|
|
104
|
-
loading={
|
|
105
|
-
disabled={Boolean(
|
|
106
|
-
onClick={
|
|
107
|
-
onTextSearch={
|
|
99
|
+
loading={textSearchLoading}
|
|
100
|
+
disabled={Boolean(onTextSearchClick)}
|
|
101
|
+
onClick={onTextSearchClick}
|
|
102
|
+
onTextSearch={onTextSearchClick ? undefined : onTextSearch}
|
|
108
103
|
expandable={true}/>}
|
|
109
104
|
|
|
110
|
-
{
|
|
105
|
+
{actions}
|
|
111
106
|
|
|
112
107
|
</div>
|
|
113
108
|
|
|
@@ -96,7 +96,7 @@ export const EntityTableCell = React.memo<EntityTableCellProps>(
|
|
|
96
96
|
const [onHover, setOnHover] = useState(false);
|
|
97
97
|
const [internalSaved, setInternalSaved] = useState(saved);
|
|
98
98
|
|
|
99
|
-
const showError = !disabled && error;
|
|
99
|
+
const showError = !disabled && Boolean(error);
|
|
100
100
|
|
|
101
101
|
useEffect(() => {
|
|
102
102
|
if (saved) {
|
|
@@ -176,21 +176,26 @@ export const EntityTableCell = React.memo<EntityTableCellProps>(
|
|
|
176
176
|
const setOnHoverTrue = useCallback(() => setOnHover(true), []);
|
|
177
177
|
const setOnHoverFalse = useCallback(() => setOnHover(false), []);
|
|
178
178
|
|
|
179
|
+
const borderClass = showError
|
|
180
|
+
? "border-red-500"
|
|
181
|
+
: internalSaved
|
|
182
|
+
? "border-green-500"
|
|
183
|
+
: isSelected
|
|
184
|
+
? "border-primary"
|
|
185
|
+
: "border-transparent";
|
|
186
|
+
|
|
179
187
|
return (
|
|
180
188
|
<div
|
|
181
|
-
ref={ref}
|
|
182
189
|
className={cn(
|
|
183
190
|
"transition-colors duration-100 ease-in-out",
|
|
184
191
|
`flex relative h-full rounded-md p-${p} border border-4 border-opacity-75`,
|
|
185
192
|
onHover && !disabled ? "bg-gray-50 dark:bg-gray-900" : "",
|
|
186
193
|
saved ? "bg-gray-100 bg-opacity-75 dark:bg-gray-800 dark:bg-opacity-75" : "",
|
|
187
|
-
!isSelected && !internalSaved && !showError ? "border-transparent" : "",
|
|
188
194
|
hideOverflow ? "overflow-hidden" : "",
|
|
189
195
|
isSelected ? "bg-gray-50 dark:bg-gray-900" : "",
|
|
190
|
-
|
|
191
|
-
internalSaved ? "border-green-500 " : "",
|
|
192
|
-
showError ? "border-red-500" : ""
|
|
196
|
+
borderClass
|
|
193
197
|
)}
|
|
198
|
+
ref={ref}
|
|
194
199
|
style={{
|
|
195
200
|
justifyContent,
|
|
196
201
|
alignItems: disabled || !isOverflowing ? "center" : undefined,
|
|
@@ -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",
|
|
@@ -41,7 +41,7 @@ interface PopupFormFieldProps<M extends Record<string, any>> {
|
|
|
41
41
|
* Callback when the value of a cell has been edited
|
|
42
42
|
* @param params
|
|
43
43
|
*/
|
|
44
|
-
onCellValueChange?: (params: OnCellValueChangeParams<any,
|
|
44
|
+
onCellValueChange?: (params: OnCellValueChangeParams<any, any>) => Promise<void> | void;
|
|
45
45
|
}
|
|
46
46
|
|
|
47
47
|
export function PopupFormField<M extends Record<string, any>>(props: PopupFormFieldProps<M>) {
|
|
@@ -205,12 +205,10 @@ export function PopupFormFieldInternal<M extends Record<string, any>>({
|
|
|
205
205
|
return onCellValueChange({
|
|
206
206
|
value: values[propertyKey as string],
|
|
207
207
|
propertyKey: propertyKey as string,
|
|
208
|
-
entity,
|
|
208
|
+
data: entity,
|
|
209
209
|
setError: setSavingError,
|
|
210
210
|
onValueUpdated: () => {
|
|
211
211
|
},
|
|
212
|
-
fullPath: path,
|
|
213
|
-
context: fireCMSContext
|
|
214
212
|
});
|
|
215
213
|
}
|
|
216
214
|
return Promise.resolve();
|