@firecms/core 3.0.0-canary.13 → 3.0.0-canary.130
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/app/AppBar.d.ts +12 -0
- package/dist/app/Drawer.d.ts +17 -0
- package/dist/app/Scaffold.d.ts +30 -0
- package/dist/app/index.d.ts +4 -0
- package/dist/app/useApp.d.ts +16 -0
- package/dist/components/ArrayContainer.d.ts +2 -1
- package/dist/components/CircularProgressCenter.d.ts +1 -1
- package/dist/components/ClearFilterSortButton.d.ts +5 -0
- package/dist/components/{DeleteConfirmationDialog.d.ts → ConfirmationDialog.d.ts} +1 -1
- package/dist/components/EntityCollectionTable/EntityCollectionRowActions.d.ts +11 -12
- package/dist/components/EntityCollectionTable/EntityCollectionTable.d.ts +1 -1
- package/dist/components/EntityCollectionTable/EntityCollectionTableProps.d.ts +5 -3
- package/dist/components/EntityCollectionTable/PropertyTableCell.d.ts +1 -0
- package/dist/components/EntityCollectionTable/column_utils.d.ts +1 -2
- package/dist/components/EntityCollectionTable/fields/TableReferenceField.d.ts +3 -1
- 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 +2 -2
- package/dist/components/EntityCollectionView/EntityCollectionView.d.ts +12 -2
- package/dist/components/EntityCollectionView/EntityCollectionViewStartActions.d.ts +11 -0
- package/dist/components/EntityCollectionView/utils.d.ts +3 -0
- package/dist/components/EntityPreview.d.ts +7 -6
- 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/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 +15 -12
- 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/useColumnsIds.d.ts +2 -1
- package/dist/components/common/useDataSourceEntityCollectionTableController.d.ts +3 -0
- package/dist/components/index.d.ts +4 -2
- package/dist/{components/FireCMSAppBar.d.ts → core/DefaultAppBar.d.ts} +6 -9
- package/dist/core/DefaultDrawer.d.ts +19 -0
- package/dist/core/DrawerNavigationItem.d.ts +10 -0
- package/dist/core/EntityEditView.d.ts +18 -4
- package/dist/core/FireCMS.d.ts +1 -1
- package/dist/core/NavigationRoutes.d.ts +3 -3
- package/dist/core/index.d.ts +3 -4
- package/dist/form/PropertyFieldBinding.d.ts +1 -1
- package/dist/form/components/ErrorFocus.d.ts +1 -1
- package/dist/form/components/FieldHelperText.d.ts +3 -3
- 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/StorageItemPreview.d.ts +4 -4
- 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 +3 -5
- package/dist/form/field_bindings/TextFieldBinding.d.ts +1 -1
- package/dist/form/index.d.ts +3 -5
- package/dist/form/useClearRestoreValue.d.ts +2 -2
- package/dist/hooks/data/save.d.ts +1 -2
- package/dist/hooks/index.d.ts +1 -0
- package/dist/hooks/useBuildNavigationController.d.ts +1 -2
- package/dist/hooks/useProjectLog.d.ts +8 -2
- package/dist/hooks/useValidateAuthenticator.d.ts +4 -8
- package/dist/index.d.ts +1 -0
- package/dist/index.es.js +15835 -12470
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +20046 -587
- package/dist/index.umd.js.map +1 -1
- package/dist/internal/useBuildDataSource.d.ts +1 -16
- package/dist/preview/PropertyPreviewProps.d.ts +6 -1
- package/dist/preview/components/EnumValuesChip.d.ts +1 -1
- package/dist/preview/components/ReferencePreview.d.ts +3 -2
- package/dist/preview/components/StorageThumbnail.d.ts +2 -1
- package/dist/preview/components/UrlComponentPreview.d.ts +2 -1
- package/dist/types/auth.d.ts +3 -3
- package/dist/types/collections.d.ts +39 -5
- package/dist/types/datasource.d.ts +55 -35
- package/dist/types/entities.d.ts +6 -1
- package/dist/types/entity_actions.d.ts +14 -0
- package/dist/types/entity_overrides.d.ts +2 -2
- package/dist/types/fields.d.ts +47 -41
- package/dist/types/firecms.d.ts +4 -0
- package/dist/types/index.d.ts +0 -1
- package/dist/types/navigation.d.ts +6 -5
- package/dist/types/plugins.d.ts +14 -4
- package/dist/types/properties.d.ts +34 -21
- package/dist/types/side_dialogs_controller.d.ts +10 -0
- package/dist/types/storage.d.ts +86 -3
- package/dist/util/entities.d.ts +2 -2
- package/dist/util/icon_list.d.ts +5 -1
- package/dist/util/icon_synonyms.d.ts +1 -97
- package/dist/util/icons.d.ts +3 -2
- package/dist/util/index.d.ts +1 -0
- package/dist/util/navigation_utils.d.ts +2 -2
- package/dist/util/objects.d.ts +1 -1
- package/dist/util/plurals.d.ts +0 -2
- package/dist/util/property_utils.d.ts +1 -1
- package/dist/util/resolutions.d.ts +27 -13
- package/dist/util/storage.d.ts +23 -2
- package/dist/util/useStorageUploadController.d.ts +3 -3
- package/package.json +128 -119
- package/src/app/AppBar.tsx +18 -0
- package/src/app/Drawer.tsx +25 -0
- package/src/app/Scaffold.tsx +244 -0
- package/src/app/index.ts +4 -0
- package/src/app/useApp.tsx +32 -0
- package/src/components/ArrayContainer.tsx +16 -11
- package/src/components/CircularProgressCenter.tsx +1 -1
- package/src/components/ClearFilterSortButton.tsx +41 -0
- package/src/components/{DeleteConfirmationDialog.tsx → ConfirmationDialog.tsx} +1 -1
- package/src/components/EntityCollectionTable/EntityCollectionRowActions.tsx +12 -19
- package/src/components/EntityCollectionTable/EntityCollectionTable.tsx +21 -20
- package/src/components/EntityCollectionTable/EntityCollectionTableProps.tsx +10 -6
- package/src/components/EntityCollectionTable/PropertyTableCell.tsx +41 -35
- package/src/components/EntityCollectionTable/column_utils.tsx +3 -3
- package/src/components/EntityCollectionTable/fields/TableReferenceField.tsx +31 -16
- package/src/components/EntityCollectionTable/fields/TableStorageUpload.tsx +14 -6
- package/src/components/EntityCollectionTable/internal/CollectionTableToolbar.tsx +29 -34
- package/src/components/EntityCollectionTable/internal/EntityTableCell.tsx +32 -30
- package/src/components/EntityCollectionTable/internal/EntityTableCellActions.tsx +19 -7
- package/src/components/EntityCollectionTable/internal/popup_field/PopupFormField.tsx +7 -10
- package/src/components/EntityCollectionView/EntityCollectionView.tsx +136 -83
- package/src/components/EntityCollectionView/EntityCollectionViewStartActions.tsx +68 -0
- package/src/components/EntityCollectionView/useSelectionController.tsx +19 -7
- package/src/components/EntityCollectionView/utils.ts +19 -0
- package/src/components/EntityPreview.tsx +42 -38
- package/src/components/EntityView.tsx +5 -5
- package/src/components/ErrorView.tsx +1 -1
- package/src/components/HomePage/DefaultHomePage.tsx +25 -19
- package/src/components/HomePage/NavigationCard.tsx +3 -3
- package/src/components/HomePage/NavigationCardBinding.tsx +1 -1
- package/src/components/HomePage/SmallNavigationCard.tsx +5 -6
- package/src/components/PropertyIdCopyTooltip.tsx +48 -0
- package/src/components/ReferenceTable/ReferenceSelectionTable.tsx +8 -6
- package/src/components/ReferenceWidget.tsx +22 -12
- package/src/components/SearchIconsView.tsx +10 -7
- package/src/components/SelectableTable/SelectableTable.tsx +7 -7
- package/src/components/SelectableTable/filters/BooleanFilterField.tsx +2 -3
- package/src/components/SelectableTable/filters/DateTimeFilterField.tsx +22 -7
- package/src/components/SelectableTable/filters/ReferenceFilterField.tsx +28 -6
- package/src/components/SelectableTable/filters/StringNumberFilterField.tsx +88 -21
- package/src/components/VirtualTable/VirtualTable.tsx +77 -46
- package/src/components/VirtualTable/VirtualTableCell.tsx +1 -9
- package/src/components/VirtualTable/VirtualTableHeader.tsx +4 -4
- package/src/components/VirtualTable/VirtualTableHeaderRow.tsx +2 -2
- package/src/components/VirtualTable/VirtualTableProps.tsx +18 -14
- package/src/components/VirtualTable/VirtualTableRow.tsx +4 -5
- package/src/components/VirtualTable/fields/VirtualTableDateField.tsx +4 -4
- 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/VirtualTable/types.tsx +2 -3
- package/src/components/{EntityCollectionTable/internal → common}/default_entity_actions.tsx +6 -2
- 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 +23 -2
- package/src/components/common/useDataSourceEntityCollectionTableController.tsx +23 -12
- package/src/components/common/useTableSearchHelper.ts +53 -12
- package/src/components/index.tsx +4 -2
- package/src/contexts/DialogsProvider.tsx +2 -2
- package/src/{components/FireCMSAppBar.tsx → core/DefaultAppBar.tsx} +52 -37
- package/src/core/DefaultDrawer.tsx +183 -0
- package/src/core/DrawerNavigationItem.tsx +66 -0
- package/src/core/EntityEditView.tsx +715 -149
- package/src/core/EntitySidePanel.tsx +1 -2
- package/src/core/FireCMS.tsx +55 -49
- package/src/core/NavigationRoutes.tsx +7 -8
- package/src/core/SideDialogs.tsx +1 -0
- package/src/core/field_configs.tsx +7 -8
- package/src/core/index.tsx +3 -4
- package/src/form/PropertyFieldBinding.tsx +53 -21
- package/src/form/components/CustomIdField.tsx +4 -2
- package/src/form/components/FieldHelperText.tsx +4 -4
- 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 +21 -11
- package/src/form/components/StorageUploadProgress.tsx +3 -4
- package/src/form/components/index.tsx +1 -0
- package/src/form/field_bindings/ArrayCustomShapedFieldBinding.tsx +26 -15
- package/src/form/field_bindings/ArrayOfReferencesFieldBinding.tsx +29 -24
- package/src/form/field_bindings/BlockFieldBinding.tsx +14 -12
- package/src/form/field_bindings/DateTimeFieldBinding.tsx +17 -14
- package/src/form/field_bindings/KeyValueFieldBinding.tsx +52 -46
- package/src/form/field_bindings/MapFieldBinding.tsx +17 -17
- 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 +11 -16
- package/src/form/field_bindings/ReferenceFieldBinding.tsx +41 -30
- package/src/form/field_bindings/RepeatFieldBinding.tsx +32 -19
- package/src/form/field_bindings/SelectFieldBinding.tsx +20 -13
- package/src/form/field_bindings/StorageUploadFieldBinding.tsx +36 -46
- 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/form/validation.ts +1 -17
- package/src/hooks/data/delete.ts +2 -1
- package/src/hooks/data/save.ts +6 -1
- package/src/hooks/data/useDataSource.tsx +11 -3
- package/src/hooks/index.tsx +1 -0
- package/src/hooks/useBuildLocalConfigurationPersistence.tsx +8 -10
- package/src/hooks/useBuildModeController.tsx +11 -5
- package/src/hooks/useBuildNavigationController.tsx +91 -31
- package/src/hooks/useProjectLog.tsx +32 -10
- package/src/hooks/useResolvedNavigationFrom.tsx +1 -1
- package/src/hooks/useValidateAuthenticator.tsx +21 -41
- package/src/index.ts +1 -0
- package/src/internal/useBuildDataSource.ts +71 -81
- package/src/internal/useBuildSideDialogsController.tsx +1 -0
- package/src/internal/useBuildSideEntityController.tsx +102 -22
- package/src/internal/useUnsavedChangesDialog.tsx +3 -1
- package/src/preview/PropertyPreview.tsx +10 -17
- package/src/preview/PropertyPreviewProps.tsx +7 -1
- package/src/preview/components/BooleanPreview.tsx +2 -2
- package/src/preview/components/EnumValuesChip.tsx +2 -2
- package/src/preview/components/ImagePreview.tsx +24 -34
- package/src/preview/components/ReferencePreview.tsx +23 -34
- package/src/preview/components/StorageThumbnail.tsx +5 -1
- package/src/preview/components/UrlComponentPreview.tsx +44 -11
- package/src/preview/property_previews/ArrayOfMapsPreview.tsx +1 -2
- package/src/preview/property_previews/ArrayOfReferencesPreview.tsx +3 -2
- package/src/preview/property_previews/ArrayOfStorageComponentsPreview.tsx +1 -2
- package/src/preview/property_previews/ArrayOfStringsPreview.tsx +0 -1
- package/src/preview/property_previews/ArrayOneOfPreview.tsx +3 -4
- package/src/preview/property_previews/ArrayPropertyPreview.tsx +3 -4
- package/src/preview/property_previews/MapPropertyPreview.tsx +6 -6
- package/src/preview/property_previews/SkeletonPropertyComponent.tsx +2 -2
- package/src/preview/property_previews/StringPropertyPreview.tsx +3 -3
- package/src/preview/util.ts +2 -2
- package/src/types/auth.tsx +3 -3
- package/src/types/collections.ts +48 -7
- package/src/types/customization_controller.tsx +0 -1
- package/src/types/datasource.ts +65 -43
- package/src/types/entities.ts +11 -1
- package/src/types/entity_actions.tsx +16 -3
- package/src/types/entity_overrides.tsx +2 -2
- package/src/types/fields.tsx +51 -45
- package/src/types/firecms.tsx +5 -0
- package/src/types/index.ts +0 -1
- package/src/types/navigation.ts +7 -7
- package/src/types/plugins.tsx +16 -6
- package/src/types/properties.ts +39 -22
- package/src/types/side_dialogs_controller.tsx +13 -0
- package/src/types/storage.ts +94 -3
- package/src/util/entities.ts +6 -5
- package/src/util/enums.ts +1 -1
- package/src/util/icon_list.ts +15 -10
- package/src/util/icon_synonyms.ts +3 -99
- package/src/util/icons.tsx +8 -2
- package/src/util/index.ts +1 -0
- package/src/util/make_properties_editable.ts +13 -5
- package/src/util/navigation_utils.ts +6 -6
- package/src/util/objects.ts +25 -28
- package/src/util/permissions.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 +74 -41
- package/src/util/storage.ts +79 -21
- package/src/util/strings.ts +2 -2
- package/src/util/useStorageUploadController.tsx +33 -7
- package/src/util/useTraceUpdate.tsx +1 -0
- package/dist/components/PropertyIdCopyTooltipContent.d.ts +0 -3
- package/dist/components/VirtualTable/common.d.ts +0 -2
- package/dist/core/Drawer.d.ts +0 -23
- package/dist/core/Scaffold.d.ts +0 -55
- package/dist/core/SideEntityView.d.ts +0 -7
- package/dist/form/EntityForm.d.ts +0 -77
- package/dist/form/field_bindings/MarkdownFieldBinding.d.ts +0 -9
- 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/PropertyIdCopyTooltipContent.tsx +0 -28
- package/src/core/Drawer.tsx +0 -191
- package/src/core/Scaffold.tsx +0 -281
- package/src/core/SideEntityView.tsx +0 -38
- package/src/form/EntityForm.tsx +0 -728
- package/src/form/field_bindings/MarkdownFieldBinding.tsx +0 -695
- package/src/internal/useBuildCustomizationController.tsx +0 -5
- package/src/internal/useLocaleConfig.tsx +0 -18
- package/src/types/appcheck.ts +0 -29
|
@@ -6,6 +6,7 @@ import { FieldHelperText, LabelWithIcon } from "../components";
|
|
|
6
6
|
import { getIconForProperty } from "../../util";
|
|
7
7
|
import { PropertyPreview } from "../../preview";
|
|
8
8
|
import { useClearRestoreValue } from "../useClearRestoreValue";
|
|
9
|
+
import { PropertyIdCopyTooltip } from "../../components/PropertyIdCopyTooltip";
|
|
9
10
|
|
|
10
11
|
interface TextFieldBindingProps<T extends string | number> extends FieldProps<T> {
|
|
11
12
|
allowInfinity?: boolean
|
|
@@ -18,7 +19,6 @@ interface TextFieldBindingProps<T extends string | number> extends FieldProps<T>
|
|
|
18
19
|
* @group Form fields
|
|
19
20
|
*/
|
|
20
21
|
export function TextFieldBinding<T extends string | number>({
|
|
21
|
-
context,
|
|
22
22
|
propertyKey,
|
|
23
23
|
value,
|
|
24
24
|
setValue,
|
|
@@ -28,6 +28,7 @@ export function TextFieldBinding<T extends string | number>({
|
|
|
28
28
|
autoFocus,
|
|
29
29
|
property,
|
|
30
30
|
includeDescription,
|
|
31
|
+
size = "medium"
|
|
31
32
|
}: TextFieldBindingProps<T>) {
|
|
32
33
|
|
|
33
34
|
let multiline: boolean | undefined;
|
|
@@ -67,27 +68,29 @@ export function TextFieldBinding<T extends string | number>({
|
|
|
67
68
|
const isMultiline = Boolean(multiline);
|
|
68
69
|
|
|
69
70
|
const inputType = property.dataType === "number" ? "number" : undefined;
|
|
70
|
-
return (
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
<
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
71
|
+
return (<>
|
|
72
|
+
<PropertyIdCopyTooltip propertyKey={propertyKey}>
|
|
73
|
+
<TextField
|
|
74
|
+
size={size}
|
|
75
|
+
value={value}
|
|
76
|
+
onChange={onChange}
|
|
77
|
+
autoFocus={autoFocus}
|
|
78
|
+
label={<LabelWithIcon
|
|
79
|
+
icon={getIconForProperty(property, "small")}
|
|
80
|
+
required={property.validation?.required}
|
|
81
|
+
title={property.name}/>}
|
|
82
|
+
type={inputType}
|
|
83
|
+
multiline={isMultiline}
|
|
84
|
+
disabled={disabled}
|
|
85
|
+
endAdornment={
|
|
86
|
+
property.clearable && <IconButton
|
|
87
|
+
onClick={handleClearClick}>
|
|
88
|
+
<ClearIcon/>
|
|
89
|
+
</IconButton>
|
|
90
|
+
}
|
|
91
|
+
error={showError ? error : undefined}
|
|
92
|
+
inputClassName={error ? "text-red-500 dark:text-red-600" : ""}/>
|
|
93
|
+
</PropertyIdCopyTooltip>
|
|
91
94
|
<FieldHelperText includeDescription={includeDescription}
|
|
92
95
|
showError={showError}
|
|
93
96
|
error={error}
|
|
@@ -100,7 +103,7 @@ export function TextFieldBinding<T extends string | number>({
|
|
|
100
103
|
<PropertyPreview
|
|
101
104
|
value={value}
|
|
102
105
|
property={property}
|
|
103
|
-
size={
|
|
106
|
+
size={size}/>
|
|
104
107
|
</Collapse>}
|
|
105
108
|
|
|
106
109
|
</>
|
package/src/form/index.tsx
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { SelectFieldBinding } from "./field_bindings/SelectFieldBinding";
|
|
2
|
-
import {
|
|
2
|
+
import { MultiSelectFieldBinding } from "./field_bindings/MultiSelectFieldBinding";
|
|
3
3
|
import { ArrayOfReferencesFieldBinding } from "./field_bindings/ArrayOfReferencesFieldBinding";
|
|
4
4
|
import { StorageUploadFieldBinding } from "./field_bindings/StorageUploadFieldBinding";
|
|
5
5
|
import { TextFieldBinding } from "./field_bindings/TextFieldBinding";
|
|
@@ -11,13 +11,13 @@ import { KeyValueFieldBinding } from "./field_bindings/KeyValueFieldBinding";
|
|
|
11
11
|
import { RepeatFieldBinding } from "./field_bindings/RepeatFieldBinding";
|
|
12
12
|
import { BlockFieldBinding } from "./field_bindings/BlockFieldBinding";
|
|
13
13
|
import { ReadOnlyFieldBinding } from "./field_bindings/ReadOnlyFieldBinding";
|
|
14
|
-
import {
|
|
14
|
+
import { MarkdownEditorFieldBinding } from "./field_bindings/MarkdownEditorFieldBinding";
|
|
15
15
|
import { ArrayCustomShapedFieldBinding } from "./field_bindings/ArrayCustomShapedFieldBinding";
|
|
16
16
|
|
|
17
17
|
export {
|
|
18
18
|
ArrayCustomShapedFieldBinding,
|
|
19
19
|
RepeatFieldBinding,
|
|
20
|
-
|
|
20
|
+
MultiSelectFieldBinding,
|
|
21
21
|
ArrayOfReferencesFieldBinding,
|
|
22
22
|
BlockFieldBinding,
|
|
23
23
|
DateTimeFieldBinding,
|
|
@@ -28,16 +28,11 @@ export {
|
|
|
28
28
|
SelectFieldBinding,
|
|
29
29
|
StorageUploadFieldBinding,
|
|
30
30
|
SwitchFieldBinding,
|
|
31
|
-
|
|
31
|
+
MarkdownEditorFieldBinding,
|
|
32
32
|
TextFieldBinding
|
|
33
33
|
};
|
|
34
34
|
|
|
35
35
|
export * from "./components";
|
|
36
36
|
|
|
37
|
-
export type { EntityFormProps } from "./EntityForm";
|
|
38
|
-
export {
|
|
39
|
-
EntityForm
|
|
40
|
-
} from "./EntityForm";
|
|
41
|
-
|
|
42
37
|
export { PropertyFieldBinding } from "./PropertyFieldBinding";
|
|
43
38
|
export * from "./useClearRestoreValue";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { useEffect, useRef } from "react";
|
|
2
|
-
import { CMSType, ResolvedProperty } from "../types";
|
|
2
|
+
import { CMSType, Property, ResolvedProperty } from "../types";
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Hook we use to restore a value after it has been cleared
|
|
@@ -14,7 +14,7 @@ export function useClearRestoreValue<T extends CMSType>({
|
|
|
14
14
|
setValue
|
|
15
15
|
}:
|
|
16
16
|
{
|
|
17
|
-
property: ResolvedProperty<T>,
|
|
17
|
+
property: Property<T> | ResolvedProperty<T>,
|
|
18
18
|
value: T,
|
|
19
19
|
setValue: (value: T | null, shouldValidate?: boolean) => void
|
|
20
20
|
}) {
|
package/src/form/validation.ts
CHANGED
|
@@ -112,23 +112,7 @@ export function getYupMapObjectSchema({
|
|
|
112
112
|
if (validation?.required) {
|
|
113
113
|
return shape.required(validation?.requiredMessage ? validation.requiredMessage : "Required").nullable(true);
|
|
114
114
|
}
|
|
115
|
-
return shape.nullable(true);
|
|
116
|
-
// const object: ObjectSchema<any> = yup.object().shape(objectSchema);
|
|
117
|
-
// return validation?.required
|
|
118
|
-
// ? object.required(validation?.requiredMessage ? validation.requiredMessage : "Required").nullable(true)
|
|
119
|
-
// : yup.object().optional().default(undefined).notRequired().nullable(true).test(
|
|
120
|
-
// "empty-check",
|
|
121
|
-
// "Optional map can be empty",
|
|
122
|
-
// (o: any, testContext: any) => {
|
|
123
|
-
// try {
|
|
124
|
-
// if (!o || Object.keys(o).length === 0) return true;
|
|
125
|
-
// return object.validateSync(o);
|
|
126
|
-
// } catch (e) {
|
|
127
|
-
// testContext.createError(e);
|
|
128
|
-
// console.error(e);
|
|
129
|
-
// return false;
|
|
130
|
-
// }
|
|
131
|
-
// });
|
|
115
|
+
return yup.object().shape(shape.fields).default(undefined).notRequired().nullable(true);
|
|
132
116
|
}
|
|
133
117
|
|
|
134
118
|
function getYupStringSchema({
|
package/src/hooks/data/delete.ts
CHANGED
package/src/hooks/data/save.ts
CHANGED
|
@@ -17,7 +17,6 @@ import { resolveCollection } from "../../util";
|
|
|
17
17
|
export type SaveEntityWithCallbacksProps<M extends Record<string, any>> =
|
|
18
18
|
SaveEntityProps<M> &
|
|
19
19
|
{
|
|
20
|
-
callbacks?: EntityCallbacks<M>;
|
|
21
20
|
onSaveSuccess?: (updatedEntity: Entity<M>) => void,
|
|
22
21
|
onSaveFailure?: (e: Error) => void,
|
|
23
22
|
onPreSaveHookError?: (e: Error) => void,
|
|
@@ -109,6 +108,11 @@ export async function saveEntityWithCallbacks<M extends Record<string, any>, Use
|
|
|
109
108
|
updatedValues = values;
|
|
110
109
|
}
|
|
111
110
|
|
|
111
|
+
console.log("Saving entity", {
|
|
112
|
+
entityId,
|
|
113
|
+
updatedValues,
|
|
114
|
+
collection
|
|
115
|
+
});
|
|
112
116
|
return dataSource.saveEntity({
|
|
113
117
|
collection,
|
|
114
118
|
path: resolvedPath,
|
|
@@ -145,6 +149,7 @@ export async function saveEntityWithCallbacks<M extends Record<string, any>, Use
|
|
|
145
149
|
onSaveSuccess(entity);
|
|
146
150
|
})
|
|
147
151
|
.catch((e) => {
|
|
152
|
+
console.error("!!!", e);
|
|
148
153
|
if (callbacks?.onSaveFailure) {
|
|
149
154
|
|
|
150
155
|
const resolvedCollection = resolveCollection<M>({
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { useContext
|
|
1
|
+
import { useContext } from "react";
|
|
2
2
|
import { DataSource, EntityCollection } from "../../types";
|
|
3
3
|
import { DataSourceContext } from "../../contexts/DataSourceContext";
|
|
4
4
|
|
|
@@ -7,8 +7,16 @@ import { DataSourceContext } from "../../contexts/DataSourceContext";
|
|
|
7
7
|
* @group Hooks and utilities
|
|
8
8
|
*/
|
|
9
9
|
export const useDataSource = (collection?: EntityCollection<any, any>): DataSource => {
|
|
10
|
+
// const customizationController = useCustomizationController();
|
|
11
|
+
// const navigationController = useNavigationController();
|
|
10
12
|
const defaultDataSource = useContext(DataSourceContext);
|
|
11
|
-
if (collection?.overrides?.
|
|
12
|
-
|
|
13
|
+
// if (collection?.overrides?.dataSourceDelegate) {
|
|
14
|
+
// console.trace("Using custom data source for collection " + collection.id);
|
|
15
|
+
// return useBuildDataSource({
|
|
16
|
+
// delegate: collection.overrides.dataSourceDelegate,
|
|
17
|
+
// propertyConfigs: customizationController?.propertyConfigs,
|
|
18
|
+
// navigationController: navigationController
|
|
19
|
+
// });
|
|
20
|
+
// }
|
|
13
21
|
return defaultDataSource;
|
|
14
22
|
};
|
package/src/hooks/index.tsx
CHANGED
|
@@ -10,6 +10,7 @@ export * from "./useResolvedNavigationFrom";
|
|
|
10
10
|
|
|
11
11
|
export * from "./useStorageSource";
|
|
12
12
|
export * from "./useAuthController";
|
|
13
|
+
export * from "./useDialogsController";
|
|
13
14
|
export * from "./useSideDialogsController";
|
|
14
15
|
export * from "./useSideEntityController";
|
|
15
16
|
export * from "./useFireCMSContext";
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { useCallback, useEffect, useState } from "react";
|
|
1
|
+
import { useCallback, useEffect, useRef, useState } from "react";
|
|
2
2
|
import { PartialEntityCollection, UserConfigurationPersistence } from "../types";
|
|
3
3
|
import { mergeDeep, stripCollectionPath } from "../util";
|
|
4
4
|
|
|
5
5
|
export function useBuildLocalConfigurationPersistence(): UserConfigurationPersistence {
|
|
6
6
|
|
|
7
|
-
const
|
|
7
|
+
const configCache = useRef<Record<string, PartialEntityCollection>>({});
|
|
8
8
|
|
|
9
9
|
const getCollectionFromStorage = useCallback((storageKey: string) => {
|
|
10
10
|
const item = localStorage.getItem(storageKey);
|
|
@@ -13,20 +13,18 @@ export function useBuildLocalConfigurationPersistence(): UserConfigurationPersis
|
|
|
13
13
|
|
|
14
14
|
const getCollectionConfig = useCallback(<M extends Record<string, any>>(path: string): PartialEntityCollection<M> => {
|
|
15
15
|
const storageKey = `collection_config::${stripCollectionPath(path)}`;
|
|
16
|
-
if (configCache[storageKey]) {
|
|
17
|
-
return configCache[storageKey] as PartialEntityCollection<M>;
|
|
16
|
+
if (configCache.current[storageKey]) {
|
|
17
|
+
return configCache.current[storageKey] as PartialEntityCollection<M>;
|
|
18
18
|
}
|
|
19
19
|
return getCollectionFromStorage(storageKey);
|
|
20
|
-
}, [
|
|
20
|
+
}, [getCollectionFromStorage]);
|
|
21
21
|
|
|
22
22
|
const onCollectionModified = useCallback(<M extends Record<string, any>>(path: string, data: PartialEntityCollection<M>) => {
|
|
23
23
|
const storageKey = `collection_config::${stripCollectionPath(path)}`;
|
|
24
24
|
localStorage.setItem(storageKey, JSON.stringify(data));
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
return (mergeDeep(currentCache, newConfig));
|
|
29
|
-
});
|
|
25
|
+
const cachedConfig = configCache.current[storageKey];
|
|
26
|
+
const newConfig = mergeDeep(cachedConfig ?? getCollectionFromStorage(path), data);
|
|
27
|
+
configCache.current[storageKey] = mergeDeep(configCache.current[storageKey], newConfig);
|
|
30
28
|
}, [getCollectionFromStorage]);
|
|
31
29
|
|
|
32
30
|
const [recentlyVisitedPaths, _setRecentlyVisitedPaths] = useState<string[]>([]);
|
|
@@ -8,8 +8,13 @@ import { ModeController } from "./index";
|
|
|
8
8
|
*/
|
|
9
9
|
export function useBuildModeController(): ModeController {
|
|
10
10
|
|
|
11
|
-
const prefersDarkModeQuery =
|
|
12
|
-
|
|
11
|
+
const prefersDarkModeQuery = useCallback((): boolean => {
|
|
12
|
+
if (typeof window === "undefined")
|
|
13
|
+
return false;
|
|
14
|
+
const mediaQueryList = window.matchMedia("(prefers-color-scheme: dark)");
|
|
15
|
+
return mediaQueryList.matches;
|
|
16
|
+
}, []);
|
|
17
|
+
|
|
13
18
|
const prefersDarkModeStorage: boolean | null = localStorage.getItem("prefers-dark-mode") != null ? localStorage.getItem("prefers-dark-mode") === "true" : null;
|
|
14
19
|
const prefersDarkMode = prefersDarkModeStorage ?? prefersDarkModeQuery;
|
|
15
20
|
const [mode, setMode] = useState<"light" | "dark">(prefersDarkMode ? "dark" : "light");
|
|
@@ -23,7 +28,7 @@ export function useBuildModeController(): ModeController {
|
|
|
23
28
|
const setDarkMode = useCallback(() => {
|
|
24
29
|
setMode("dark");
|
|
25
30
|
setDocumentMode("dark");
|
|
26
|
-
}, [
|
|
31
|
+
}, []);
|
|
27
32
|
|
|
28
33
|
const setLightMode = useCallback(() => {
|
|
29
34
|
setMode("light");
|
|
@@ -37,14 +42,15 @@ export function useBuildModeController(): ModeController {
|
|
|
37
42
|
|
|
38
43
|
const toggleMode = useCallback(() => {
|
|
39
44
|
|
|
45
|
+
const prefersDarkModeQueryResult = prefersDarkModeQuery();
|
|
40
46
|
if (mode === "light") {
|
|
41
|
-
if (!
|
|
47
|
+
if (!prefersDarkModeQueryResult)
|
|
42
48
|
localStorage.setItem("prefers-dark-mode", "true");
|
|
43
49
|
else
|
|
44
50
|
localStorage.removeItem("prefers-dark-mode");
|
|
45
51
|
setDarkMode();
|
|
46
52
|
} else {
|
|
47
|
-
if (
|
|
53
|
+
if (prefersDarkModeQueryResult)
|
|
48
54
|
localStorage.setItem("prefers-dark-mode", "false");
|
|
49
55
|
else
|
|
50
56
|
localStorage.removeItem("prefers-dark-mode");
|
|
@@ -20,6 +20,7 @@ import {
|
|
|
20
20
|
applyPermissionsFunctionIfEmpty,
|
|
21
21
|
getCollectionByPathOrId,
|
|
22
22
|
mergeDeep,
|
|
23
|
+
removeFunctions,
|
|
23
24
|
removeInitialAndTrailingSlashes,
|
|
24
25
|
resolveCollectionPathIds,
|
|
25
26
|
resolvePermissions
|
|
@@ -29,7 +30,7 @@ import { getParentReferencesFromPath } from "../util/parent_references_from_path
|
|
|
29
30
|
const DEFAULT_BASE_PATH = "/";
|
|
30
31
|
const DEFAULT_COLLECTION_PATH = "/c";
|
|
31
32
|
|
|
32
|
-
type BuildNavigationContextProps<EC extends EntityCollection, UserType extends User> = {
|
|
33
|
+
export type BuildNavigationContextProps<EC extends EntityCollection, UserType extends User> = {
|
|
33
34
|
basePath?: string,
|
|
34
35
|
baseCollectionPath?: string,
|
|
35
36
|
authController: AuthController<UserType>;
|
|
@@ -130,6 +131,30 @@ export function useBuildNavigationController<EC extends EntityCollection, UserTy
|
|
|
130
131
|
.filter(Boolean) as TopNavigationEntry[]
|
|
131
132
|
];
|
|
132
133
|
|
|
134
|
+
// Sort by group, entries with group "Admin" will go last, and second to last will be the group "Views"
|
|
135
|
+
navigationEntries = navigationEntries.sort((a, b) => {
|
|
136
|
+
if (a.group !== "Views" && a.group !== "Admin" && (b.group === "Views" || b.group === "Admin")) {
|
|
137
|
+
return -1;
|
|
138
|
+
}
|
|
139
|
+
if (b.group !== "Views" && b.group !== "Admin" && (a.group === "Views" || a.group === "Admin")) {
|
|
140
|
+
return 1;
|
|
141
|
+
}
|
|
142
|
+
if (a.group === "Admin" && b.group !== "Admin") {
|
|
143
|
+
return 1;
|
|
144
|
+
}
|
|
145
|
+
if (a.group !== "Admin" && b.group === "Admin") {
|
|
146
|
+
return -1;
|
|
147
|
+
}
|
|
148
|
+
if (a.group === "Views" && b.group !== "Views") {
|
|
149
|
+
return -1;
|
|
150
|
+
}
|
|
151
|
+
if (a.group !== "Views" && b.group === "Views") {
|
|
152
|
+
return 1;
|
|
153
|
+
}
|
|
154
|
+
return 0;
|
|
155
|
+
|
|
156
|
+
});
|
|
157
|
+
|
|
133
158
|
if (viewsOrder) {
|
|
134
159
|
navigationEntries = navigationEntries.sort((a, b) => {
|
|
135
160
|
const aIndex = viewsOrder.indexOf(a.path);
|
|
@@ -163,32 +188,48 @@ export function useBuildNavigationController<EC extends EntityCollection, UserTy
|
|
|
163
188
|
if (authController.initialLoading)
|
|
164
189
|
return;
|
|
165
190
|
|
|
191
|
+
console.debug("Refreshing navigation");
|
|
192
|
+
|
|
166
193
|
try {
|
|
167
|
-
|
|
194
|
+
|
|
168
195
|
const [resolvedCollections = [], resolvedViews, resolvedAdminViews = []] = await Promise.all([
|
|
169
196
|
resolveCollections(collectionsProp, collectionPermissions, authController, dataSourceDelegate, injectCollections),
|
|
170
197
|
resolveCMSViews(viewsProp, authController, dataSourceDelegate),
|
|
171
198
|
resolveCMSViews(adminViewsProp, authController, dataSourceDelegate)
|
|
172
199
|
]
|
|
173
200
|
);
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
201
|
+
|
|
202
|
+
let shouldUpdateTopLevelNav = false;
|
|
203
|
+
if (!areCollectionListsEqual(collectionsRef.current ?? [], resolvedCollections)) {
|
|
204
|
+
collectionsRef.current = resolvedCollections;
|
|
205
|
+
shouldUpdateTopLevelNav = true;
|
|
206
|
+
}
|
|
207
|
+
if (collectionsRef.current === undefined) {
|
|
180
208
|
collectionsRef.current = resolvedCollections;
|
|
209
|
+
shouldUpdateTopLevelNav = true;
|
|
210
|
+
}
|
|
211
|
+
if (!equal(viewsRef.current, resolvedViews)) {
|
|
181
212
|
viewsRef.current = resolvedViews;
|
|
213
|
+
shouldUpdateTopLevelNav = true;
|
|
214
|
+
}
|
|
215
|
+
if (!equal(adminViewsRef.current, resolvedAdminViews)) {
|
|
182
216
|
adminViewsRef.current = resolvedAdminViews;
|
|
183
|
-
|
|
217
|
+
shouldUpdateTopLevelNav = true;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
const computedTopLevelNav = computeTopNavigation(resolvedCollections, resolvedViews, resolvedAdminViews, viewsOrder);
|
|
221
|
+
if (shouldUpdateTopLevelNav && !equal(topLevelNavigation, computedTopLevelNav)) {
|
|
222
|
+
setTopLevelNavigation(computedTopLevelNav);
|
|
184
223
|
}
|
|
185
224
|
} catch (e) {
|
|
186
225
|
console.error(e);
|
|
187
226
|
setNavigationLoadingError(e as any);
|
|
188
227
|
}
|
|
189
228
|
|
|
190
|
-
|
|
191
|
-
|
|
229
|
+
if (navigationLoading)
|
|
230
|
+
setNavigationLoading(false);
|
|
231
|
+
if (!initialised)
|
|
232
|
+
setInitialised(true);
|
|
192
233
|
|
|
193
234
|
}, [
|
|
194
235
|
collectionsProp,
|
|
@@ -205,9 +246,8 @@ export function useBuildNavigationController<EC extends EntityCollection, UserTy
|
|
|
205
246
|
refreshNavigation();
|
|
206
247
|
}, [refreshNavigation]);
|
|
207
248
|
|
|
208
|
-
const getCollection = useCallback(
|
|
249
|
+
const getCollection = useCallback((
|
|
209
250
|
idOrPath: string,
|
|
210
|
-
entityId?: string,
|
|
211
251
|
includeUserOverride = false
|
|
212
252
|
): EC | undefined => {
|
|
213
253
|
const collections = collectionsRef.current;
|
|
@@ -217,8 +257,7 @@ export function useBuildNavigationController<EC extends EntityCollection, UserTy
|
|
|
217
257
|
const baseCollection = getCollectionByPathOrId(removeInitialAndTrailingSlashes(idOrPath), collections);
|
|
218
258
|
|
|
219
259
|
const userOverride = includeUserOverride ? userConfigPersistence?.getCollectionConfig(idOrPath) : undefined;
|
|
220
|
-
|
|
221
|
-
const overriddenCollection = baseCollection ? mergeDeep(baseCollection, userOverride) : undefined;
|
|
260
|
+
const overriddenCollection = baseCollection ? mergeDeep(baseCollection, userOverride ?? {}) : undefined;
|
|
222
261
|
|
|
223
262
|
let result: Partial<EntityCollection> | undefined = overriddenCollection;
|
|
224
263
|
|
|
@@ -238,17 +277,14 @@ export function useBuildNavigationController<EC extends EntityCollection, UserTy
|
|
|
238
277
|
|
|
239
278
|
return { ...overriddenCollection, ...result } as EC;
|
|
240
279
|
|
|
241
|
-
}, [
|
|
242
|
-
basePath,
|
|
243
|
-
baseCollectionPath,
|
|
244
|
-
]);
|
|
280
|
+
}, [userConfigPersistence]);
|
|
245
281
|
|
|
246
282
|
const getCollectionFromPaths = useCallback(<EC extends EntityCollection>(pathSegments: string[]): EC | undefined => {
|
|
247
283
|
|
|
248
284
|
const collections = collectionsRef.current;
|
|
285
|
+
if (collections === undefined)
|
|
286
|
+
throw Error("getCollectionFromPaths: Collections have not been initialised yet");
|
|
249
287
|
let currentCollections: EntityCollection[] | undefined = [...(collections ?? [])];
|
|
250
|
-
if (!currentCollections)
|
|
251
|
-
throw Error("Collections have not been initialised yet");
|
|
252
288
|
|
|
253
289
|
for (let i = 0; i < pathSegments.length; i++) {
|
|
254
290
|
const pathSegment = pathSegments[i];
|
|
@@ -267,9 +303,9 @@ export function useBuildNavigationController<EC extends EntityCollection, UserTy
|
|
|
267
303
|
const getCollectionFromIds = useCallback(<EC extends EntityCollection>(ids: string[]): EC | undefined => {
|
|
268
304
|
|
|
269
305
|
const collections = collectionsRef.current;
|
|
306
|
+
if (collections === undefined)
|
|
307
|
+
throw Error("getCollectionFromIds: Collections have not been initialised yet");
|
|
270
308
|
let currentCollections: EntityCollection[] | undefined = [...(collections ?? [])];
|
|
271
|
-
if (!currentCollections)
|
|
272
|
-
throw Error("Collections have not been initialised yet");
|
|
273
309
|
|
|
274
310
|
for (let i = 0; i < ids.length; i++) {
|
|
275
311
|
const id = ids[i];
|
|
@@ -305,9 +341,7 @@ export function useBuildNavigationController<EC extends EntityCollection, UserTy
|
|
|
305
341
|
[]);
|
|
306
342
|
|
|
307
343
|
const resolveAliasesFrom = useCallback((path: string): string => {
|
|
308
|
-
const collections = collectionsRef.current;
|
|
309
|
-
if (!collections)
|
|
310
|
-
throw Error("Collections have not been initialised yet");
|
|
344
|
+
const collections = collectionsRef.current ?? [];
|
|
311
345
|
return resolveCollectionPathIds(path, collections);
|
|
312
346
|
}, []);
|
|
313
347
|
|
|
@@ -410,7 +444,7 @@ async function resolveCollections(collections: undefined | EntityCollection[] |
|
|
|
410
444
|
collectionPermissions: PermissionsBuilder | undefined,
|
|
411
445
|
authController: AuthController,
|
|
412
446
|
dataSource: DataSourceDelegate,
|
|
413
|
-
injectCollections?: (collections: EntityCollection[]) => EntityCollection[]) {
|
|
447
|
+
injectCollections?: (collections: EntityCollection[]) => EntityCollection[]): Promise<EntityCollection[]> {
|
|
414
448
|
let resolvedCollections: EntityCollection[] = [];
|
|
415
449
|
if (typeof collections === "function") {
|
|
416
450
|
resolvedCollections = await collections({
|
|
@@ -422,14 +456,14 @@ async function resolveCollections(collections: undefined | EntityCollection[] |
|
|
|
422
456
|
resolvedCollections = collections;
|
|
423
457
|
}
|
|
424
458
|
|
|
425
|
-
resolvedCollections = applyPermissionsFunctionIfEmpty(resolvedCollections, collectionPermissions);
|
|
426
|
-
|
|
427
|
-
resolvedCollections = filterOutNotAllowedCollections(resolvedCollections, authController);
|
|
428
|
-
|
|
429
459
|
if (injectCollections) {
|
|
430
460
|
resolvedCollections = injectCollections(resolvedCollections ?? []);
|
|
431
461
|
}
|
|
432
462
|
|
|
463
|
+
resolvedCollections = applyPermissionsFunctionIfEmpty(resolvedCollections, collectionPermissions);
|
|
464
|
+
|
|
465
|
+
resolvedCollections = filterOutNotAllowedCollections(resolvedCollections, authController);
|
|
466
|
+
|
|
433
467
|
return resolvedCollections;
|
|
434
468
|
}
|
|
435
469
|
|
|
@@ -454,3 +488,29 @@ function getGroup(collectionOrView: EntityCollection<any, any> | CMSView) {
|
|
|
454
488
|
}
|
|
455
489
|
return trimmed ?? "Views";
|
|
456
490
|
}
|
|
491
|
+
|
|
492
|
+
function areCollectionListsEqual(a: EntityCollection[], b: EntityCollection[]) {
|
|
493
|
+
if (a.length !== b.length) {
|
|
494
|
+
return false;
|
|
495
|
+
}
|
|
496
|
+
const aCopy = [...a];
|
|
497
|
+
const bCopy = [...b];
|
|
498
|
+
const aSorted = aCopy.sort((x, y) => x.id.localeCompare(y.id));
|
|
499
|
+
const bSorted = bCopy.sort((x, y) => x.id.localeCompare(y.id));
|
|
500
|
+
return aSorted.every((value, index) => areCollectionsEqual(value, bSorted[index]));
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
function areCollectionsEqual(a: EntityCollection, b: EntityCollection) {
|
|
504
|
+
const {
|
|
505
|
+
subcollections: subcollectionsA,
|
|
506
|
+
...restA
|
|
507
|
+
} = a;
|
|
508
|
+
const {
|
|
509
|
+
subcollections: subcollectionsB,
|
|
510
|
+
...restB
|
|
511
|
+
} = b;
|
|
512
|
+
if (!areCollectionListsEqual(subcollectionsA ?? [], subcollectionsB ?? [])) {
|
|
513
|
+
return false;
|
|
514
|
+
}
|
|
515
|
+
return equal(removeFunctions(restA), removeFunctions(restB));
|
|
516
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { useEffect, useRef, useState } from "react";
|
|
2
|
-
import { AuthController, FireCMSPlugin } from "../types";
|
|
2
|
+
import { AuthController, DataSourceDelegate, FireCMSPlugin } from "../types";
|
|
3
3
|
|
|
4
4
|
export const DEFAULT_SERVER_DEV = "https://api-kdoe6pj3qq-ey.a.run.app";
|
|
5
5
|
export const DEFAULT_SERVER = "https://api-drplyi3b6q-ey.a.run.app";
|
|
@@ -9,33 +9,55 @@ export type AccessResponse = {
|
|
|
9
9
|
message?: string;
|
|
10
10
|
}
|
|
11
11
|
|
|
12
|
-
async function makeRequest(authController: AuthController, pluginKeys: string | undefined) {
|
|
13
|
-
|
|
12
|
+
async function makeRequest(authController: AuthController, dataSourceKey: string, pluginKeys: string[] | undefined, apiKey?: string): Promise<AccessResponse> {
|
|
13
|
+
let idToken: string | null;
|
|
14
|
+
try {
|
|
15
|
+
idToken = await authController.getAuthToken();
|
|
16
|
+
} catch (e) {
|
|
17
|
+
idToken = null;
|
|
18
|
+
}
|
|
14
19
|
return fetch(DEFAULT_SERVER + "/access_log",
|
|
15
20
|
{
|
|
16
21
|
// mode: "no-cors",
|
|
17
22
|
method: "POST",
|
|
18
23
|
headers: {
|
|
19
24
|
"Content-Type": "application/json",
|
|
20
|
-
Authorization: `Basic ${
|
|
25
|
+
Authorization: `Basic ${idToken}`
|
|
21
26
|
},
|
|
22
|
-
body: JSON.stringify({
|
|
27
|
+
body: JSON.stringify({
|
|
28
|
+
apiKey,
|
|
29
|
+
email: authController.user?.email ?? null,
|
|
30
|
+
datasource: dataSourceKey,
|
|
31
|
+
plugins: pluginKeys
|
|
32
|
+
})
|
|
23
33
|
})
|
|
24
34
|
.then(async (res) => {
|
|
25
35
|
return res.json();
|
|
26
36
|
});
|
|
27
37
|
}
|
|
28
38
|
|
|
29
|
-
export
|
|
30
|
-
|
|
39
|
+
export interface UseProjectLogParams {
|
|
40
|
+
apiKey?: string;
|
|
41
|
+
authController: AuthController;
|
|
42
|
+
dataSourceDelegate: DataSourceDelegate;
|
|
43
|
+
plugins?: FireCMSPlugin<any, any, any>[];
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export function useProjectLog({
|
|
47
|
+
authController,
|
|
48
|
+
dataSourceDelegate,
|
|
49
|
+
plugins,
|
|
50
|
+
apiKey
|
|
51
|
+
}: UseProjectLogParams): AccessResponse | null {
|
|
31
52
|
const [accessResponse, setAccessResponse] = useState<AccessResponse | null>(null);
|
|
32
53
|
const accessedUserRef = useRef<string | null>(null);
|
|
33
|
-
const
|
|
54
|
+
const dataSourceKey = dataSourceDelegate.key;
|
|
55
|
+
const pluginKeys = plugins?.map(plugin => plugin.key);
|
|
34
56
|
useEffect(() => {
|
|
35
57
|
if (authController.user && authController.user.uid !== accessedUserRef.current && !authController.initialLoading) {
|
|
36
|
-
makeRequest(authController, pluginKeys).then(setAccessResponse);
|
|
58
|
+
makeRequest(authController, dataSourceKey, pluginKeys, apiKey).then(setAccessResponse);
|
|
37
59
|
accessedUserRef.current = authController.user.uid;
|
|
38
60
|
}
|
|
39
|
-
}, [authController]);
|
|
61
|
+
}, [authController, dataSourceKey, pluginKeys]);
|
|
40
62
|
return accessResponse;
|
|
41
63
|
}
|
|
@@ -80,7 +80,7 @@ export function resolveNavigationFrom<M extends Record<string, any>, UserType ex
|
|
|
80
80
|
if (entry.type === "collection") {
|
|
81
81
|
return Promise.resolve(entry);
|
|
82
82
|
} else if (entry.type === "entity") {
|
|
83
|
-
const collection = navigation.getCollection(entry.path
|
|
83
|
+
const collection = navigation.getCollection(entry.path);
|
|
84
84
|
if (!collection) {
|
|
85
85
|
throw Error(`No collection defined in the navigation for the entity with path ${entry.path}`);
|
|
86
86
|
}
|