@firecms/core 3.0.0-canary.11 → 3.0.0-canary.111
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 +1 -1
- 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/CircularProgressCenter.d.ts +1 -1
- package/dist/components/ClearFilterSortButton.d.ts +5 -0
- 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 +2 -0
- package/dist/components/EntityCollectionTable/internal/CollectionTableToolbar.d.ts +1 -4
- package/dist/components/EntityCollectionTable/internal/EntityTableCell.d.ts +2 -2
- package/dist/components/EntityCollectionTable/internal/popup_field/PopupFormField.d.ts +2 -2
- package/dist/components/EntityCollectionView/EntityCollectionView.d.ts +12 -2
- package/dist/components/EntityCollectionView/EntityCollectionViewStartActions.d.ts +11 -0
- package/dist/components/EntityPreview.d.ts +5 -4
- 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 +3 -1
- 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 +9 -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/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 +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 +2 -4
- 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 +2 -2
- package/dist/hooks/useValidateAuthenticator.d.ts +4 -8
- package/dist/index.d.ts +1 -0
- package/dist/index.es.js +15632 -12442
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +19871 -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 +2 -1
- 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 +45 -31
- package/dist/types/entities.d.ts +6 -1
- package/dist/types/entity_actions.d.ts +14 -0
- package/dist/types/fields.d.ts +45 -39
- 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 +32 -19
- package/dist/types/storage.d.ts +11 -3
- package/dist/util/entities.d.ts +1 -1
- package/dist/util/icon_list.d.ts +5 -1
- package/dist/util/icon_synonyms.d.ts +1 -97
- package/dist/util/icons.d.ts +2 -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/resolutions.d.ts +14 -13
- package/dist/util/storage.d.ts +23 -2
- package/dist/util/useStorageUploadController.d.ts +1 -1
- package/package.json +128 -119
- package/src/app/AppBar.tsx +18 -0
- package/src/app/Drawer.tsx +25 -0
- package/src/app/Scaffold.tsx +245 -0
- package/src/app/index.ts +4 -0
- package/src/app/useApp.tsx +32 -0
- package/src/components/ArrayContainer.tsx +9 -7
- package/src/components/CircularProgressCenter.tsx +1 -1
- package/src/components/ClearFilterSortButton.tsx +41 -0
- 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 +22 -12
- 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 +17 -13
- 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 +75 -51
- package/src/components/EntityCollectionView/EntityCollectionViewStartActions.tsx +68 -0
- package/src/components/EntityCollectionView/useSelectionController.tsx +19 -7
- package/src/components/EntityPreview.tsx +21 -15
- package/src/components/EntityView.tsx +5 -5
- package/src/components/ErrorView.tsx +1 -1
- package/src/components/HomePage/DefaultHomePage.tsx +24 -15
- 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 +2 -5
- package/src/components/ReferenceWidget.tsx +22 -12
- package/src/components/SearchIconsView.tsx +11 -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 +35 -15
- package/src/components/VirtualTable/VirtualTable.tsx +70 -37
- package/src/components/VirtualTable/VirtualTableCell.tsx +1 -1
- 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 +1 -1
- package/src/components/VirtualTable/types.tsx +2 -3
- package/src/components/{EntityCollectionTable/internal → common}/default_entity_actions.tsx +2 -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 +11 -0
- package/src/components/common/useTableSearchHelper.ts +53 -12
- package/src/components/index.tsx +3 -1
- package/src/contexts/DialogsProvider.tsx +2 -2
- package/src/{components/FireCMSAppBar.tsx → core/DefaultAppBar.tsx} +52 -37
- package/src/core/DefaultDrawer.tsx +177 -0
- package/src/core/DrawerNavigationItem.tsx +64 -0
- package/src/core/EntityEditView.tsx +702 -137
- package/src/core/EntitySidePanel.tsx +1 -2
- package/src/core/FireCMS.tsx +39 -44
- package/src/core/NavigationRoutes.tsx +7 -8
- package/src/core/SideDialogs.tsx +4 -0
- package/src/core/field_configs.tsx +4 -5
- 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/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 +15 -11
- package/src/form/field_bindings/ArrayOfReferencesFieldBinding.tsx +26 -21
- package/src/form/field_bindings/BlockFieldBinding.tsx +13 -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 +15 -15
- package/src/form/field_bindings/MarkdownEditorFieldBinding.tsx +138 -0
- package/src/form/field_bindings/MultiSelectBinding.tsx +9 -5
- package/src/form/field_bindings/ReadOnlyFieldBinding.tsx +11 -16
- package/src/form/field_bindings/ReferenceFieldBinding.tsx +37 -27
- package/src/form/field_bindings/RepeatFieldBinding.tsx +20 -16
- package/src/form/field_bindings/SelectFieldBinding.tsx +47 -41
- package/src/form/field_bindings/StorageUploadFieldBinding.tsx +31 -52
- package/src/form/field_bindings/SwitchFieldBinding.tsx +9 -5
- package/src/form/field_bindings/TextFieldBinding.tsx +26 -22
- package/src/form/index.tsx +6 -6
- package/src/form/validation.ts +1 -17
- package/src/hooks/data/save.ts +6 -1
- package/src/hooks/data/useDataSource.tsx +1 -1
- 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 +94 -32
- package/src/hooks/useProjectLog.tsx +19 -8
- 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 +84 -62
- package/src/internal/useBuildSideEntityController.tsx +90 -21
- 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 -23
- package/src/preview/components/StorageThumbnail.tsx +5 -1
- package/src/preview/components/UrlComponentPreview.tsx +44 -11
- package/src/preview/property_previews/ArrayOfMapsPreview.tsx +0 -1
- 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 +53 -39
- package/src/types/entities.ts +11 -1
- package/src/types/entity_actions.tsx +16 -3
- package/src/types/fields.tsx +49 -43
- 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 +37 -20
- package/src/types/storage.ts +12 -3
- package/src/util/entities.ts +5 -4
- 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/index.ts +1 -0
- 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/references.ts +3 -0
- package/src/util/resolutions.ts +44 -39
- package/src/util/storage.ts +76 -22
- package/src/util/strings.ts +2 -2
- package/src/util/useStorageUploadController.tsx +22 -4
- 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
|
@@ -19,7 +19,7 @@ import {
|
|
|
19
19
|
import {
|
|
20
20
|
applyPermissionsFunctionIfEmpty,
|
|
21
21
|
getCollectionByPathOrId,
|
|
22
|
-
mergeDeep,
|
|
22
|
+
mergeDeep, removeFunctions,
|
|
23
23
|
removeInitialAndTrailingSlashes,
|
|
24
24
|
resolveCollectionPathIds,
|
|
25
25
|
resolvePermissions
|
|
@@ -29,7 +29,7 @@ import { getParentReferencesFromPath } from "../util/parent_references_from_path
|
|
|
29
29
|
const DEFAULT_BASE_PATH = "/";
|
|
30
30
|
const DEFAULT_COLLECTION_PATH = "/c";
|
|
31
31
|
|
|
32
|
-
type BuildNavigationContextProps<EC extends EntityCollection, UserType extends User> = {
|
|
32
|
+
export type BuildNavigationContextProps<EC extends EntityCollection, UserType extends User> = {
|
|
33
33
|
basePath?: string,
|
|
34
34
|
baseCollectionPath?: string,
|
|
35
35
|
authController: AuthController<UserType>;
|
|
@@ -130,6 +130,30 @@ export function useBuildNavigationController<EC extends EntityCollection, UserTy
|
|
|
130
130
|
.filter(Boolean) as TopNavigationEntry[]
|
|
131
131
|
];
|
|
132
132
|
|
|
133
|
+
// Sort by group, entries with group "Admin" will go last, and second to last will be the group "Views"
|
|
134
|
+
navigationEntries = navigationEntries.sort((a, b) => {
|
|
135
|
+
if (a.group !== "Views" && a.group !== "Admin" && (b.group === "Views" || b.group === "Admin")) {
|
|
136
|
+
return -1;
|
|
137
|
+
}
|
|
138
|
+
if (b.group !== "Views" && b.group !== "Admin" && (a.group === "Views" || a.group === "Admin")) {
|
|
139
|
+
return 1;
|
|
140
|
+
}
|
|
141
|
+
if (a.group === "Admin" && b.group !== "Admin") {
|
|
142
|
+
return 1;
|
|
143
|
+
}
|
|
144
|
+
if (a.group !== "Admin" && b.group === "Admin") {
|
|
145
|
+
return -1;
|
|
146
|
+
}
|
|
147
|
+
if (a.group === "Views" && b.group !== "Views") {
|
|
148
|
+
return -1;
|
|
149
|
+
}
|
|
150
|
+
if (a.group !== "Views" && b.group === "Views") {
|
|
151
|
+
return 1;
|
|
152
|
+
}
|
|
153
|
+
return 0;
|
|
154
|
+
|
|
155
|
+
});
|
|
156
|
+
|
|
133
157
|
if (viewsOrder) {
|
|
134
158
|
navigationEntries = navigationEntries.sort((a, b) => {
|
|
135
159
|
const aIndex = viewsOrder.indexOf(a.path);
|
|
@@ -163,32 +187,51 @@ export function useBuildNavigationController<EC extends EntityCollection, UserTy
|
|
|
163
187
|
if (authController.initialLoading)
|
|
164
188
|
return;
|
|
165
189
|
|
|
190
|
+
console.debug("Refreshing navigation");
|
|
191
|
+
|
|
166
192
|
try {
|
|
167
|
-
|
|
193
|
+
|
|
168
194
|
const [resolvedCollections = [], resolvedViews, resolvedAdminViews = []] = await Promise.all([
|
|
169
195
|
resolveCollections(collectionsProp, collectionPermissions, authController, dataSourceDelegate, injectCollections),
|
|
170
196
|
resolveCMSViews(viewsProp, authController, dataSourceDelegate),
|
|
171
197
|
resolveCMSViews(adminViewsProp, authController, dataSourceDelegate)
|
|
172
198
|
]
|
|
173
199
|
);
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
200
|
+
|
|
201
|
+
let shouldUpdateTopLevelNav = false;
|
|
202
|
+
if (!areCollectionListsEqual(collectionsRef.current ?? [], resolvedCollections)) {
|
|
203
|
+
console.log("Collections need to be updated");
|
|
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)) {
|
|
212
|
+
console.log("Views need to be updated");
|
|
181
213
|
viewsRef.current = resolvedViews;
|
|
214
|
+
shouldUpdateTopLevelNav = true;
|
|
215
|
+
}
|
|
216
|
+
if (!equal(adminViewsRef.current, resolvedAdminViews)) {
|
|
217
|
+
console.log("Admin views need to be updated");
|
|
182
218
|
adminViewsRef.current = resolvedAdminViews;
|
|
183
|
-
|
|
219
|
+
shouldUpdateTopLevelNav = true;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
const computedTopLevelNav = computeTopNavigation(resolvedCollections, resolvedViews, resolvedAdminViews, viewsOrder);
|
|
223
|
+
if (shouldUpdateTopLevelNav && !equal(topLevelNavigation, computedTopLevelNav)) {
|
|
224
|
+
setTopLevelNavigation(computedTopLevelNav);
|
|
184
225
|
}
|
|
185
226
|
} catch (e) {
|
|
186
227
|
console.error(e);
|
|
187
228
|
setNavigationLoadingError(e as any);
|
|
188
229
|
}
|
|
189
230
|
|
|
190
|
-
|
|
191
|
-
|
|
231
|
+
if (navigationLoading)
|
|
232
|
+
setNavigationLoading(false);
|
|
233
|
+
if (!initialised)
|
|
234
|
+
setInitialised(true);
|
|
192
235
|
|
|
193
236
|
}, [
|
|
194
237
|
collectionsProp,
|
|
@@ -205,9 +248,8 @@ export function useBuildNavigationController<EC extends EntityCollection, UserTy
|
|
|
205
248
|
refreshNavigation();
|
|
206
249
|
}, [refreshNavigation]);
|
|
207
250
|
|
|
208
|
-
const getCollection = useCallback(
|
|
251
|
+
const getCollection = useCallback((
|
|
209
252
|
idOrPath: string,
|
|
210
|
-
entityId?: string,
|
|
211
253
|
includeUserOverride = false
|
|
212
254
|
): EC | undefined => {
|
|
213
255
|
const collections = collectionsRef.current;
|
|
@@ -217,8 +259,7 @@ export function useBuildNavigationController<EC extends EntityCollection, UserTy
|
|
|
217
259
|
const baseCollection = getCollectionByPathOrId(removeInitialAndTrailingSlashes(idOrPath), collections);
|
|
218
260
|
|
|
219
261
|
const userOverride = includeUserOverride ? userConfigPersistence?.getCollectionConfig(idOrPath) : undefined;
|
|
220
|
-
|
|
221
|
-
const overriddenCollection = baseCollection ? mergeDeep(baseCollection, userOverride) : undefined;
|
|
262
|
+
const overriddenCollection = baseCollection ? mergeDeep(baseCollection, userOverride ?? {}) : undefined;
|
|
222
263
|
|
|
223
264
|
let result: Partial<EntityCollection> | undefined = overriddenCollection;
|
|
224
265
|
|
|
@@ -238,17 +279,14 @@ export function useBuildNavigationController<EC extends EntityCollection, UserTy
|
|
|
238
279
|
|
|
239
280
|
return { ...overriddenCollection, ...result } as EC;
|
|
240
281
|
|
|
241
|
-
}, [
|
|
242
|
-
basePath,
|
|
243
|
-
baseCollectionPath,
|
|
244
|
-
]);
|
|
282
|
+
}, [userConfigPersistence]);
|
|
245
283
|
|
|
246
284
|
const getCollectionFromPaths = useCallback(<EC extends EntityCollection>(pathSegments: string[]): EC | undefined => {
|
|
247
285
|
|
|
248
286
|
const collections = collectionsRef.current;
|
|
287
|
+
if (collections === undefined)
|
|
288
|
+
throw Error("getCollectionFromPaths: Collections have not been initialised yet");
|
|
249
289
|
let currentCollections: EntityCollection[] | undefined = [...(collections ?? [])];
|
|
250
|
-
if (!currentCollections)
|
|
251
|
-
throw Error("Collections have not been initialised yet");
|
|
252
290
|
|
|
253
291
|
for (let i = 0; i < pathSegments.length; i++) {
|
|
254
292
|
const pathSegment = pathSegments[i];
|
|
@@ -267,9 +305,9 @@ export function useBuildNavigationController<EC extends EntityCollection, UserTy
|
|
|
267
305
|
const getCollectionFromIds = useCallback(<EC extends EntityCollection>(ids: string[]): EC | undefined => {
|
|
268
306
|
|
|
269
307
|
const collections = collectionsRef.current;
|
|
308
|
+
if (collections === undefined)
|
|
309
|
+
throw Error("getCollectionFromIds: Collections have not been initialised yet");
|
|
270
310
|
let currentCollections: EntityCollection[] | undefined = [...(collections ?? [])];
|
|
271
|
-
if (!currentCollections)
|
|
272
|
-
throw Error("Collections have not been initialised yet");
|
|
273
311
|
|
|
274
312
|
for (let i = 0; i < ids.length; i++) {
|
|
275
313
|
const id = ids[i];
|
|
@@ -305,9 +343,7 @@ export function useBuildNavigationController<EC extends EntityCollection, UserTy
|
|
|
305
343
|
[]);
|
|
306
344
|
|
|
307
345
|
const resolveAliasesFrom = useCallback((path: string): string => {
|
|
308
|
-
const collections = collectionsRef.current;
|
|
309
|
-
if (!collections)
|
|
310
|
-
throw Error("Collections have not been initialised yet");
|
|
346
|
+
const collections = collectionsRef.current ?? [];
|
|
311
347
|
return resolveCollectionPathIds(path, collections);
|
|
312
348
|
}, []);
|
|
313
349
|
|
|
@@ -410,7 +446,7 @@ async function resolveCollections(collections: undefined | EntityCollection[] |
|
|
|
410
446
|
collectionPermissions: PermissionsBuilder | undefined,
|
|
411
447
|
authController: AuthController,
|
|
412
448
|
dataSource: DataSourceDelegate,
|
|
413
|
-
injectCollections?: (collections: EntityCollection[]) => EntityCollection[]) {
|
|
449
|
+
injectCollections?: (collections: EntityCollection[]) => EntityCollection[]): Promise<EntityCollection[]> {
|
|
414
450
|
let resolvedCollections: EntityCollection[] = [];
|
|
415
451
|
if (typeof collections === "function") {
|
|
416
452
|
resolvedCollections = await collections({
|
|
@@ -422,14 +458,14 @@ async function resolveCollections(collections: undefined | EntityCollection[] |
|
|
|
422
458
|
resolvedCollections = collections;
|
|
423
459
|
}
|
|
424
460
|
|
|
425
|
-
resolvedCollections = applyPermissionsFunctionIfEmpty(resolvedCollections, collectionPermissions);
|
|
426
|
-
|
|
427
|
-
resolvedCollections = filterOutNotAllowedCollections(resolvedCollections, authController);
|
|
428
|
-
|
|
429
461
|
if (injectCollections) {
|
|
430
462
|
resolvedCollections = injectCollections(resolvedCollections ?? []);
|
|
431
463
|
}
|
|
432
464
|
|
|
465
|
+
resolvedCollections = applyPermissionsFunctionIfEmpty(resolvedCollections, collectionPermissions);
|
|
466
|
+
|
|
467
|
+
resolvedCollections = filterOutNotAllowedCollections(resolvedCollections, authController);
|
|
468
|
+
|
|
433
469
|
return resolvedCollections;
|
|
434
470
|
}
|
|
435
471
|
|
|
@@ -454,3 +490,29 @@ function getGroup(collectionOrView: EntityCollection<any, any> | CMSView) {
|
|
|
454
490
|
}
|
|
455
491
|
return trimmed ?? "Views";
|
|
456
492
|
}
|
|
493
|
+
|
|
494
|
+
function areCollectionListsEqual(a: EntityCollection[], b: EntityCollection[]) {
|
|
495
|
+
if (a.length !== b.length) {
|
|
496
|
+
return false;
|
|
497
|
+
}
|
|
498
|
+
const aCopy = [...a];
|
|
499
|
+
const bCopy = [...b];
|
|
500
|
+
const aSorted = aCopy.sort((x, y) => x.id.localeCompare(y.id));
|
|
501
|
+
const bSorted = bCopy.sort((x, y) => x.id.localeCompare(y.id));
|
|
502
|
+
return aSorted.every((value, index) => areCollectionsEqual(value, bSorted[index]));
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
function areCollectionsEqual(a: EntityCollection, b: EntityCollection) {
|
|
506
|
+
const {
|
|
507
|
+
subcollections: subcollectionsA,
|
|
508
|
+
...restA
|
|
509
|
+
} = a;
|
|
510
|
+
const {
|
|
511
|
+
subcollections: subcollectionsB,
|
|
512
|
+
...restB
|
|
513
|
+
} = b;
|
|
514
|
+
if (!areCollectionListsEqual(subcollectionsA ?? [], subcollectionsB ?? [])) {
|
|
515
|
+
return false;
|
|
516
|
+
}
|
|
517
|
+
return equal(removeFunctions(restA), removeFunctions(restB));
|
|
518
|
+
}
|
|
@@ -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,17 +9,26 @@ 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) {
|
|
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
|
+
email: authController.user?.email ?? null,
|
|
29
|
+
datasource: dataSourceKey,
|
|
30
|
+
plugins: pluginKeys
|
|
31
|
+
})
|
|
23
32
|
})
|
|
24
33
|
.then(async (res) => {
|
|
25
34
|
return res.json();
|
|
@@ -27,15 +36,17 @@ async function makeRequest(authController: AuthController, pluginKeys: string |
|
|
|
27
36
|
}
|
|
28
37
|
|
|
29
38
|
export function useProjectLog(authController: AuthController,
|
|
39
|
+
dataSourceDelegate: DataSourceDelegate,
|
|
30
40
|
plugins?: FireCMSPlugin<any, any, any>[]): AccessResponse | null {
|
|
31
41
|
const [accessResponse, setAccessResponse] = useState<AccessResponse | null>(null);
|
|
32
42
|
const accessedUserRef = useRef<string | null>(null);
|
|
33
|
-
const
|
|
43
|
+
const dataSourceKey = dataSourceDelegate.key;
|
|
44
|
+
const pluginKeys = plugins?.map(plugin => plugin.key);
|
|
34
45
|
useEffect(() => {
|
|
35
46
|
if (authController.user && authController.user.uid !== accessedUserRef.current && !authController.initialLoading) {
|
|
36
|
-
makeRequest(authController, pluginKeys).then(setAccessResponse);
|
|
47
|
+
makeRequest(authController, dataSourceKey, pluginKeys).then(setAccessResponse);
|
|
37
48
|
accessedUserRef.current = authController.user.uid;
|
|
38
49
|
}
|
|
39
|
-
}, [authController]);
|
|
50
|
+
}, [authController, dataSourceKey, pluginKeys]);
|
|
40
51
|
return accessResponse;
|
|
41
52
|
}
|
|
@@ -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
|
}
|
|
@@ -1,43 +1,38 @@
|
|
|
1
1
|
import { useCallback, useEffect, useRef, useState } from "react";
|
|
2
2
|
import equal from "react-fast-compare";
|
|
3
3
|
|
|
4
|
-
import {
|
|
4
|
+
import { AuthController, Authenticator, DataSourceDelegate, StorageSource, User } from "../index";
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* This hook is used internally for validating an authenticator.
|
|
8
8
|
*
|
|
9
9
|
* @param authController
|
|
10
10
|
* @param authentication
|
|
11
|
-
* @param getAppCheckToken
|
|
12
|
-
* @param appCheckForceRefresh
|
|
13
11
|
* @param storageSource
|
|
14
|
-
* @param
|
|
12
|
+
* @param dataSourceDelegate
|
|
15
13
|
*/
|
|
16
|
-
export function useValidateAuthenticator<UserType extends User = User, Controller extends AuthController<UserType> = AuthController<UserType>>
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
dataSourceDelegate: DataSourceDelegate;
|
|
32
|
-
storageSource: StorageSource;
|
|
33
|
-
}): {
|
|
14
|
+
export function useValidateAuthenticator<UserType extends User = User, Controller extends AuthController<UserType> = AuthController<UserType>>
|
|
15
|
+
({
|
|
16
|
+
disabled,
|
|
17
|
+
authController,
|
|
18
|
+
authenticator,
|
|
19
|
+
storageSource,
|
|
20
|
+
dataSourceDelegate
|
|
21
|
+
}:
|
|
22
|
+
{
|
|
23
|
+
disabled?: boolean,
|
|
24
|
+
authController: Controller,
|
|
25
|
+
authenticator?: boolean | Authenticator<UserType, Controller>,
|
|
26
|
+
dataSourceDelegate: DataSourceDelegate;
|
|
27
|
+
storageSource: StorageSource;
|
|
28
|
+
}): {
|
|
34
29
|
canAccessMainView: boolean,
|
|
35
30
|
authLoading: boolean,
|
|
36
31
|
notAllowedError: any,
|
|
37
32
|
authVerified: boolean,
|
|
38
33
|
} {
|
|
39
34
|
|
|
40
|
-
const authenticationEnabled = Boolean(
|
|
35
|
+
const authenticationEnabled = Boolean(authenticator);
|
|
41
36
|
|
|
42
37
|
const [authLoading, setAuthLoading] = useState<boolean>(authenticationEnabled);
|
|
43
38
|
const [notAllowedError, setNotAllowedError] = useState<any>(false);
|
|
@@ -76,26 +71,11 @@ export function useValidateAuthenticator<UserType extends User = User, Controlle
|
|
|
76
71
|
}
|
|
77
72
|
|
|
78
73
|
const delegateUser = authController.user;
|
|
79
|
-
console.debug("Checking authentication for user", delegateUser);
|
|
80
74
|
|
|
81
|
-
if (
|
|
82
|
-
try {
|
|
83
|
-
if (!await getAppCheckToken(appCheckForceRefresh)) {
|
|
84
|
-
setNotAllowedError("App Check failed.");
|
|
85
|
-
authController.signOut();
|
|
86
|
-
} else {
|
|
87
|
-
console.debug("App Check success.");
|
|
88
|
-
}
|
|
89
|
-
} catch (e: any) {
|
|
90
|
-
setNotAllowedError(e.message);
|
|
91
|
-
authController.signOut();
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
if (authentication instanceof Function && delegateUser && !equal(checkedUserRef.current?.uid, delegateUser.uid)) {
|
|
75
|
+
if (authenticator instanceof Function && delegateUser && !equal(checkedUserRef.current?.uid, delegateUser.uid)) {
|
|
96
76
|
setAuthLoading(true);
|
|
97
77
|
try {
|
|
98
|
-
const allowed = await
|
|
78
|
+
const allowed = await authenticator({
|
|
99
79
|
user: delegateUser,
|
|
100
80
|
authController,
|
|
101
81
|
dataSourceDelegate,
|
|
@@ -120,7 +100,7 @@ export function useValidateAuthenticator<UserType extends User = User, Controlle
|
|
|
120
100
|
setAuthVerified(true);
|
|
121
101
|
}
|
|
122
102
|
|
|
123
|
-
}, [disabled, authController,
|
|
103
|
+
}, [disabled, authController, authenticator, dataSourceDelegate, storageSource]);
|
|
124
104
|
|
|
125
105
|
useEffect(() => {
|
|
126
106
|
checkAuthentication();
|