@firecms/core 3.0.0-alpha.44 → 3.0.0-alpha.46
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/contexts/NavigationContext.d.ts +2 -2
- package/dist/core/NavigationRoutes.d.ts +1 -1
- package/dist/core/index.d.ts +1 -1
- package/dist/hooks/data/save.d.ts +2 -1
- package/dist/hooks/index.d.ts +1 -2
- package/dist/hooks/{useNavigationContext.d.ts → useNavigationController.d.ts} +2 -2
- package/dist/index.es.js +5444 -5440
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +13 -13
- package/dist/index.umd.js.map +1 -1
- package/dist/{hooks → internal}/useBuildDataSource.d.ts +3 -2
- package/dist/internal/useBuildNavigationController.d.ts +14 -0
- package/dist/internal/useBuildSideEntityController.d.ts +2 -2
- package/dist/types/datasource.d.ts +3 -3
- package/dist/types/firecms.d.ts +4 -4
- package/dist/types/firecms_context.d.ts +2 -2
- package/dist/types/navigation.d.ts +2 -2
- package/package.json +2 -2
- package/src/components/EntityCollectionTable/fields/TableReferenceField.tsx +3 -3
- package/src/components/EntityCollectionTable/filters/ReferenceFilterField.tsx +3 -3
- package/src/components/EntityCollectionTable/useEntityCollectionTableController.tsx +2 -2
- package/src/components/EntityCollectionView/EntityCollectionView.tsx +4 -3
- package/src/components/EntityCollectionView/EntityCollectionViewActions.tsx +3 -3
- package/src/components/FireCMSAppBar.tsx +2 -2
- package/src/components/HomePage/DefaultHomePage.tsx +4 -4
- package/src/components/HomePage/FavouritesView.tsx +3 -3
- package/src/components/ReferenceSelectionInner.tsx +2 -2
- package/src/contexts/NavigationContext.tsx +2 -2
- package/src/core/Drawer.tsx +2 -2
- package/src/core/EntitySidePanel.tsx +4 -4
- package/src/core/FireCMS.tsx +29 -23
- package/src/core/NavigationRoutes.tsx +3 -3
- package/src/core/Scaffold.tsx +3 -3
- package/src/core/index.tsx +1 -1
- package/src/form/components/ReferenceWidget.tsx +4 -4
- package/src/form/field_bindings/ArrayOfReferencesFieldBinding.tsx +3 -3
- package/src/form/field_bindings/ReferenceFieldBinding.tsx +3 -3
- package/src/hooks/data/save.ts +11 -1
- package/src/hooks/data/useCollectionFetch.tsx +3 -3
- package/src/hooks/data/useEntityFetch.tsx +3 -3
- package/src/hooks/index.tsx +1 -2
- package/src/hooks/useFireCMSContext.tsx +2 -2
- package/src/hooks/{useNavigationContext.tsx → useNavigationController.tsx} +3 -3
- package/src/hooks/useReferenceDialog.tsx +2 -2
- package/src/{hooks → internal}/useBuildDataSource.ts +34 -25
- package/src/internal/{useBuildNavigationContext.tsx → useBuildNavigationController.tsx} +22 -18
- package/src/internal/useBuildSideEntityController.tsx +3 -3
- package/src/preview/components/ReferencePreview.tsx +3 -3
- package/src/types/datasource.ts +3 -3
- package/src/types/firecms.tsx +4 -4
- package/src/types/firecms_context.tsx +2 -2
- package/src/types/navigation.ts +2 -2
- package/dist/internal/useBuildNavigationContext.d.ts +0 -14
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-
import { DataSource, DataSourceDelegate, EntityReference, GeoPoint, PropertyConfig } from "../types";
|
|
1
|
+
import { DataSource, DataSourceDelegate, EntityReference, GeoPoint, NavigationController, PropertyConfig } from "../types";
|
|
2
2
|
/**
|
|
3
3
|
* Use this hook to build a {@link DataSource} based on Firestore
|
|
4
4
|
* @param firebaseApp
|
|
5
5
|
* @group Firebase
|
|
6
6
|
*/
|
|
7
|
-
export declare function useBuildDataSource({ delegate, propertyConfigs }: {
|
|
7
|
+
export declare function useBuildDataSource({ delegate, propertyConfigs, navigationController }: {
|
|
8
8
|
delegate: DataSourceDelegate;
|
|
9
9
|
propertyConfigs?: Record<string, PropertyConfig>;
|
|
10
|
+
navigationController: NavigationController;
|
|
10
11
|
}): DataSource;
|
|
11
12
|
/**
|
|
12
13
|
* Recursive function that converts Firestore data types into CMS or plain
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { AuthController, CMSView, CMSViewsBuilder, DataSourceDelegate, EntityCollection, EntityCollectionsBuilder, FireCMSPlugin, NavigationController, User, UserConfigurationPersistence } from "../types";
|
|
2
|
+
type BuildNavigationContextProps<EC extends EntityCollection, UserType extends User> = {
|
|
3
|
+
basePath?: string;
|
|
4
|
+
baseCollectionPath?: string;
|
|
5
|
+
authController: AuthController<UserType>;
|
|
6
|
+
collections?: EC[] | EntityCollectionsBuilder<EC>;
|
|
7
|
+
views?: CMSView[] | CMSViewsBuilder;
|
|
8
|
+
userConfigPersistence?: UserConfigurationPersistence;
|
|
9
|
+
plugins?: FireCMSPlugin[];
|
|
10
|
+
dataSource: DataSourceDelegate;
|
|
11
|
+
};
|
|
12
|
+
export declare function useBuildNavigationController<EC extends EntityCollection, UserType extends User>({ basePath, baseCollectionPath, authController, collections: baseCollections, views: baseViews, userConfigPersistence, plugins, dataSource }: BuildNavigationContextProps<EC, UserType>): NavigationController;
|
|
13
|
+
export declare function getSidePanelKey(path: string, entityId?: string): string;
|
|
14
|
+
export {};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { EntityCollection, EntitySidePanelProps,
|
|
1
|
+
import { EntityCollection, EntitySidePanelProps, NavigationController, SideDialogsController, SideEntityController } from "../types";
|
|
2
2
|
export declare function getEntityViewWidth(props: EntitySidePanelProps<any>, small: boolean): string;
|
|
3
|
-
export declare const useBuildSideEntityController: (navigation:
|
|
3
|
+
export declare const useBuildSideEntityController: (navigation: NavigationController, sideDialogsController: SideDialogsController) => SideEntityController;
|
|
4
4
|
export declare function buildSidePanelsFromUrl(path: string, collections: EntityCollection[], newFlag: boolean): EntitySidePanelProps<any>[];
|
|
@@ -7,7 +7,7 @@ import { ResolvedEntityCollection } from "./resolved_entities";
|
|
|
7
7
|
export interface FetchEntityProps<M extends Record<string, any> = any> {
|
|
8
8
|
path: string;
|
|
9
9
|
entityId: string;
|
|
10
|
-
collection
|
|
10
|
+
collection?: EntityCollection<M>;
|
|
11
11
|
}
|
|
12
12
|
/**
|
|
13
13
|
* @group Datasource
|
|
@@ -21,7 +21,7 @@ export type ListenEntityProps<M extends Record<string, any> = any> = FetchEntity
|
|
|
21
21
|
*/
|
|
22
22
|
export interface FetchCollectionProps<M extends Record<string, any> = any> {
|
|
23
23
|
path: string;
|
|
24
|
-
collection
|
|
24
|
+
collection?: EntityCollection<M> | ResolvedEntityCollection<M>;
|
|
25
25
|
filter?: FilterValues<Extract<keyof M, string>>;
|
|
26
26
|
limit?: number;
|
|
27
27
|
startAfter?: any[];
|
|
@@ -44,7 +44,7 @@ export interface SaveEntityProps<M extends Record<string, any> = any> {
|
|
|
44
44
|
values: Partial<EntityValues<M>>;
|
|
45
45
|
entityId?: string;
|
|
46
46
|
previousValues?: Partial<EntityValues<M>>;
|
|
47
|
-
collection
|
|
47
|
+
collection?: EntityCollection<M> | ResolvedEntityCollection<M>;
|
|
48
48
|
status: EntityStatus;
|
|
49
49
|
}
|
|
50
50
|
/**
|
package/dist/types/firecms.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import { User } from "./user";
|
|
3
3
|
import { AuthController } from "./auth";
|
|
4
|
-
import {
|
|
4
|
+
import { DataSourceDelegate } from "./datasource";
|
|
5
5
|
import { EntityCollection, EntityCustomView } from "./collections";
|
|
6
6
|
import { CMSView } from "./navigation";
|
|
7
7
|
import { FireCMSContext } from "./firecms_context";
|
|
@@ -25,7 +25,7 @@ import { CMSAnalyticsEvent } from "./analytics";
|
|
|
25
25
|
export type EntityCollectionsBuilder<EC extends EntityCollection = EntityCollection> = (params: {
|
|
26
26
|
user: User | null;
|
|
27
27
|
authController: AuthController;
|
|
28
|
-
dataSource:
|
|
28
|
+
dataSource: DataSourceDelegate;
|
|
29
29
|
}) => EC[] | Promise<EC[]>;
|
|
30
30
|
/**
|
|
31
31
|
* Use this callback to build custom views dynamically.
|
|
@@ -39,7 +39,7 @@ export type EntityCollectionsBuilder<EC extends EntityCollection = EntityCollect
|
|
|
39
39
|
export type CMSViewsBuilder = (params: {
|
|
40
40
|
user: User | null;
|
|
41
41
|
authController: AuthController;
|
|
42
|
-
dataSource:
|
|
42
|
+
dataSource: DataSourceDelegate;
|
|
43
43
|
}) => CMSView[] | Promise<CMSView[]>;
|
|
44
44
|
/**
|
|
45
45
|
* @group Models
|
|
@@ -100,7 +100,7 @@ export type FireCMSProps<UserType extends User, EC extends EntityCollection> = {
|
|
|
100
100
|
/**
|
|
101
101
|
* Connector to your database
|
|
102
102
|
*/
|
|
103
|
-
|
|
103
|
+
dataSourceDelegate: DataSourceDelegate;
|
|
104
104
|
/**
|
|
105
105
|
* Connector to your file upload/fetch implementation
|
|
106
106
|
*/
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Locale } from "./locales";
|
|
2
2
|
import { DataSource } from "./datasource";
|
|
3
3
|
import { StorageSource } from "./storage";
|
|
4
|
-
import {
|
|
4
|
+
import { NavigationController } from "./navigation";
|
|
5
5
|
import { SideEntityController } from "./side_entity_controller";
|
|
6
6
|
import { AuthController } from "./auth";
|
|
7
7
|
import { EntityLinkBuilder } from "./entity_link_builder";
|
|
@@ -44,7 +44,7 @@ export type FireCMSContext<UserType extends User = User, AuthControllerType exte
|
|
|
44
44
|
* attributes.
|
|
45
45
|
* @see useNavigation
|
|
46
46
|
*/
|
|
47
|
-
navigation:
|
|
47
|
+
navigation: NavigationController;
|
|
48
48
|
/**
|
|
49
49
|
* Controller to open the side dialog displaying entity forms
|
|
50
50
|
* @see useSideEntityController
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { EntityCollection } from "./collections";
|
|
2
2
|
import { EntityReference } from "./entities";
|
|
3
3
|
/**
|
|
4
|
-
*
|
|
4
|
+
* Controller that includes the resolved navigation and utility methods and
|
|
5
5
|
* attributes.
|
|
6
6
|
* @group Models
|
|
7
7
|
*/
|
|
8
|
-
export type
|
|
8
|
+
export type NavigationController = {
|
|
9
9
|
/**
|
|
10
10
|
* List of the mapped collections in the CMS.
|
|
11
11
|
* Each entry relates to a collection in the root database.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@firecms/core",
|
|
3
|
-
"version": "3.0.0-alpha.
|
|
3
|
+
"version": "3.0.0-alpha.46",
|
|
4
4
|
"description": "Awesome Firebase/Firestore-based headless open-source CMS",
|
|
5
5
|
"funding": {
|
|
6
6
|
"url": "https://github.com/sponsors/firecmsco"
|
|
@@ -133,7 +133,7 @@
|
|
|
133
133
|
"dist",
|
|
134
134
|
"src"
|
|
135
135
|
],
|
|
136
|
-
"gitHead": "
|
|
136
|
+
"gitHead": "53ef13adab3db13baeea2ad7953e37cf3552fd62",
|
|
137
137
|
"publishConfig": {
|
|
138
138
|
"access": "public"
|
|
139
139
|
}
|
|
@@ -4,7 +4,7 @@ import { CollectionSize, Entity, EntityCollection, EntityReference, FilterValues
|
|
|
4
4
|
|
|
5
5
|
import { getPreviewSizeFrom } from "../../../preview/util";
|
|
6
6
|
import { getReferenceFrom } from "../../../util";
|
|
7
|
-
import { useFireCMSContext,
|
|
7
|
+
import { useFireCMSContext, useNavigationController, useReferenceDialog } from "../../../hooks";
|
|
8
8
|
import { ErrorView } from "../../ErrorView";
|
|
9
9
|
import { Button } from "../../../ui/Button";
|
|
10
10
|
|
|
@@ -24,9 +24,9 @@ type TableReferenceFieldProps = {
|
|
|
24
24
|
export function TableReferenceField(props: TableReferenceFieldProps) {
|
|
25
25
|
|
|
26
26
|
const context = useFireCMSContext();
|
|
27
|
-
const
|
|
27
|
+
const navigationController = useNavigationController();
|
|
28
28
|
const { path } = props;
|
|
29
|
-
const collection =
|
|
29
|
+
const collection = navigationController.getCollection<EntityCollection>(path);
|
|
30
30
|
if (!collection) {
|
|
31
31
|
if (context.components?.missingReference) {
|
|
32
32
|
return <context.components.missingReference path={path}/>;
|
|
@@ -3,7 +3,7 @@ import { VirtualTableWhereFilterOp } from "../../VirtualTable";
|
|
|
3
3
|
import { Entity, EntityCollection, EntityReference } from "../../../types";
|
|
4
4
|
import { ReferencePreview } from "../../../preview";
|
|
5
5
|
import { getReferenceFrom } from "../../../util";
|
|
6
|
-
import {
|
|
6
|
+
import { useNavigationController, useReferenceDialog } from "../../../hooks";
|
|
7
7
|
import { Button, Select, SelectItem } from "../../../ui";
|
|
8
8
|
|
|
9
9
|
interface ReferenceFilterFieldProps {
|
|
@@ -94,9 +94,9 @@ export function ReferenceFilterField({
|
|
|
94
94
|
}
|
|
95
95
|
}
|
|
96
96
|
|
|
97
|
-
const
|
|
97
|
+
const navigationController = useNavigationController();
|
|
98
98
|
const collection: EntityCollection | undefined = useMemo(() => {
|
|
99
|
-
return path ?
|
|
99
|
+
return path ? navigationController.getCollection(path) : undefined;
|
|
100
100
|
}, [path]);
|
|
101
101
|
|
|
102
102
|
const onSingleEntitySelected = (entity: Entity<any>) => {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React, { useCallback, useMemo } from "react";
|
|
2
2
|
|
|
3
|
-
import { useCollectionFetch, useDataSource,
|
|
3
|
+
import { useCollectionFetch, useDataSource, useNavigationController } from "../../hooks";
|
|
4
4
|
import { useDataOrder } from "../../hooks/data/useDataOrder";
|
|
5
5
|
import { Entity, EntityCollection, FilterValues, SelectedCellProps, TableController, User } from "../../types";
|
|
6
6
|
import { useDebouncedData } from "./useDebouncedData";
|
|
@@ -45,7 +45,7 @@ export function useEntityCollectionTableController<M extends Record<string, any>
|
|
|
45
45
|
|
|
46
46
|
const [popupCell, setPopupCell] = React.useState<SelectedCellProps<M> | undefined>(undefined);
|
|
47
47
|
|
|
48
|
-
const navigation =
|
|
48
|
+
const navigation = useNavigationController();
|
|
49
49
|
const dataSource = useDataSource();
|
|
50
50
|
const resolvedPath = useMemo(() => navigation.resolveAliasesFrom(fullPath), [fullPath, navigation.resolveAliasesFrom]);
|
|
51
51
|
|
|
@@ -42,7 +42,7 @@ import {
|
|
|
42
42
|
useDataSource,
|
|
43
43
|
useFireCMSContext,
|
|
44
44
|
useLargeLayout,
|
|
45
|
-
|
|
45
|
+
useNavigationController,
|
|
46
46
|
useSideEntityController
|
|
47
47
|
} from "../../hooks";
|
|
48
48
|
import { useUserConfigurationPersistence } from "../../hooks/useUserConfigurationPersistence";
|
|
@@ -109,7 +109,7 @@ export const EntityCollectionView = React.memo(
|
|
|
109
109
|
) {
|
|
110
110
|
|
|
111
111
|
const dataSource = useDataSource();
|
|
112
|
-
const navigation =
|
|
112
|
+
const navigation = useNavigationController();
|
|
113
113
|
const sideEntityController = useSideEntityController();
|
|
114
114
|
const authController = useAuthController();
|
|
115
115
|
const userConfigPersistence = useUserConfigurationPersistence();
|
|
@@ -304,6 +304,7 @@ export const EntityCollectionView = React.memo(
|
|
|
304
304
|
|
|
305
305
|
return saveEntityWithCallbacks({
|
|
306
306
|
...saveProps,
|
|
307
|
+
collection,
|
|
307
308
|
callbacks: collection.callbacks,
|
|
308
309
|
dataSource,
|
|
309
310
|
context,
|
|
@@ -668,7 +669,7 @@ function EntitiesCount({
|
|
|
668
669
|
}) {
|
|
669
670
|
|
|
670
671
|
const dataSource = useDataSource();
|
|
671
|
-
const navigation =
|
|
672
|
+
const navigation = useNavigationController();
|
|
672
673
|
const [count, setCount] = useState<number | undefined>(undefined);
|
|
673
674
|
const [error, setError] = useState<Error | undefined>(undefined);
|
|
674
675
|
|
|
@@ -111,11 +111,11 @@ export function EntityCollectionViewActions<M extends Record<string, any>>({
|
|
|
111
111
|
));
|
|
112
112
|
|
|
113
113
|
if (plugins) {
|
|
114
|
-
plugins.forEach(plugin => {
|
|
114
|
+
plugins.forEach((plugin, i) => {
|
|
115
115
|
if (plugin.collections?.CollectionActions) {
|
|
116
116
|
actions.push(...toArray(plugin.collections?.CollectionActions)
|
|
117
|
-
.map((Action,
|
|
118
|
-
<ErrorBoundary key={`plugin_actions_${i}`}>
|
|
117
|
+
.map((Action, j) => (
|
|
118
|
+
<ErrorBoundary key={`plugin_actions_${i}_${j}`}>
|
|
119
119
|
<Action {...actionProps} {...plugin.collections?.collectionActionsProps}/>
|
|
120
120
|
</ErrorBoundary>
|
|
121
121
|
)));
|
|
@@ -3,7 +3,7 @@ import React from "react";
|
|
|
3
3
|
import { Link as ReactLink } from "react-router-dom";
|
|
4
4
|
import { ErrorBoundary } from "../components";
|
|
5
5
|
import { Avatar, cn, IconButton, Menu, MenuItem, Typography } from "../ui";
|
|
6
|
-
import { useAuthController, useLargeLayout, useModeController,
|
|
6
|
+
import { useAuthController, useLargeLayout, useModeController, useNavigationController } from "../hooks";
|
|
7
7
|
import { DarkModeIcon, LightModeIcon, LogoutIcon } from "../icons";
|
|
8
8
|
import { Skeleton } from "../ui/Skeleton";
|
|
9
9
|
import { User } from "../types";
|
|
@@ -50,7 +50,7 @@ export const FireCMSAppBar = function FireCMSAppBar({
|
|
|
50
50
|
style,
|
|
51
51
|
user: userProp
|
|
52
52
|
}: FireCMSAppBarProps) {
|
|
53
|
-
const navigation =
|
|
53
|
+
const navigation = useNavigationController();
|
|
54
54
|
|
|
55
55
|
const authController = useAuthController();
|
|
56
56
|
const {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React, { useCallback, useEffect, useState } from "react";
|
|
2
2
|
|
|
3
|
-
import { useFireCMSContext,
|
|
3
|
+
import { useFireCMSContext, useNavigationController } from "../../hooks";
|
|
4
4
|
import { PluginGenericProps, PluginHomePageAdditionalCardsProps } from "../../types";
|
|
5
5
|
|
|
6
6
|
import { toArray } from "../../util/arrays";
|
|
@@ -35,9 +35,9 @@ export function DefaultHomePage({
|
|
|
35
35
|
}) {
|
|
36
36
|
|
|
37
37
|
const context = useFireCMSContext();
|
|
38
|
-
const
|
|
38
|
+
const navigationController = useNavigationController();
|
|
39
39
|
|
|
40
|
-
if (!
|
|
40
|
+
if (!navigationController.topLevelNavigation)
|
|
41
41
|
throw Error("Navigation not ready in FireCMSHomePage");
|
|
42
42
|
|
|
43
43
|
const {
|
|
@@ -49,7 +49,7 @@ export function DefaultHomePage({
|
|
|
49
49
|
const {
|
|
50
50
|
navigationEntries,
|
|
51
51
|
groups
|
|
52
|
-
} =
|
|
52
|
+
} = navigationController.topLevelNavigation;
|
|
53
53
|
|
|
54
54
|
const [filteredUrls, setFilteredUrls] = useState<string[] | null>(null);
|
|
55
55
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { useNavigate } from "react-router-dom";
|
|
2
|
-
import {
|
|
2
|
+
import { useNavigationController } from "../../hooks";
|
|
3
3
|
import { useUserConfigurationPersistence } from "../../hooks/useUserConfigurationPersistence";
|
|
4
4
|
import { TopNavigationEntry } from "../../types";
|
|
5
5
|
import { Chip, Collapse } from "../../ui";
|
|
@@ -46,14 +46,14 @@ function NavigationChip({ entry }: { entry: TopNavigationEntry }) {
|
|
|
46
46
|
|
|
47
47
|
export function FavouritesView({ hidden }: { hidden: boolean }) {
|
|
48
48
|
|
|
49
|
-
const
|
|
49
|
+
const navigationController = useNavigationController();
|
|
50
50
|
const userConfigurationPersistence = useUserConfigurationPersistence();
|
|
51
51
|
|
|
52
52
|
if (!userConfigurationPersistence)
|
|
53
53
|
return null;
|
|
54
54
|
|
|
55
55
|
const favouriteCollections = (userConfigurationPersistence?.favouritePaths ?? [])
|
|
56
|
-
.map((path) =>
|
|
56
|
+
.map((path) => navigationController.topLevelNavigation?.navigationEntries.find((entry) => entry.path === path))
|
|
57
57
|
.filter(Boolean) as TopNavigationEntry[];
|
|
58
58
|
|
|
59
59
|
return <Collapse in={favouriteCollections.length > 0}>
|
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
useDataSource,
|
|
9
9
|
useFireCMSContext,
|
|
10
10
|
useLargeLayout,
|
|
11
|
-
|
|
11
|
+
useNavigationController,
|
|
12
12
|
useSideEntityController
|
|
13
13
|
} from "../hooks";
|
|
14
14
|
import { ErrorView } from "./ErrorView";
|
|
@@ -101,7 +101,7 @@ export function ReferenceSelectionInner<M extends Record<string, any>>(
|
|
|
101
101
|
|
|
102
102
|
const sideDialogContext = useSideDialogContext();
|
|
103
103
|
const sideEntityController = useSideEntityController();
|
|
104
|
-
const navigation =
|
|
104
|
+
const navigation = useNavigationController();
|
|
105
105
|
const context = useFireCMSContext();
|
|
106
106
|
|
|
107
107
|
const fullPath = navigation.resolveAliasesFrom(pathInput);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
import {
|
|
2
|
+
import { NavigationController } from "../types";
|
|
3
3
|
|
|
4
|
-
export const
|
|
4
|
+
export const NavigationContext = React.createContext<NavigationController>({} as NavigationController);
|
package/src/core/Drawer.tsx
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React, { useCallback } from "react";
|
|
2
2
|
|
|
3
|
-
import { useFireCMSContext, useLargeLayout,
|
|
3
|
+
import { useFireCMSContext, useLargeLayout, useNavigationController } from "../hooks";
|
|
4
4
|
|
|
5
5
|
import { NavLink } from "react-router-dom";
|
|
6
6
|
import { CMSAnalyticsEvent, TopNavigationEntry, TopNavigationResult } from "../types";
|
|
@@ -28,7 +28,7 @@ export function Drawer({
|
|
|
28
28
|
}: DrawerProps) {
|
|
29
29
|
|
|
30
30
|
const context = useFireCMSContext();
|
|
31
|
-
const navigation =
|
|
31
|
+
const navigation = useNavigationController();
|
|
32
32
|
|
|
33
33
|
const tooltipsOpen = hovered && !drawerOpen;
|
|
34
34
|
const largeLayout = useLargeLayout();
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React, { useCallback, useEffect, useMemo } from "react";
|
|
2
2
|
|
|
3
3
|
import { EntitySidePanelProps } from "../types";
|
|
4
|
-
import {
|
|
4
|
+
import { useNavigationController } from "../hooks";
|
|
5
5
|
|
|
6
6
|
import { ErrorBoundary } from "../components";
|
|
7
7
|
import { EntityView } from "../internal/EntityView";
|
|
@@ -23,21 +23,21 @@ export function EntitySidePanel(props: EntitySidePanelProps) {
|
|
|
23
23
|
setBlockedNavigationMessage
|
|
24
24
|
} = useSideDialogContext();
|
|
25
25
|
|
|
26
|
-
const
|
|
26
|
+
const navigationController = useNavigationController();
|
|
27
27
|
|
|
28
28
|
const collection = useMemo(() => {
|
|
29
29
|
if (!props) return undefined;
|
|
30
30
|
let usedCollection = props.collection;
|
|
31
31
|
|
|
32
32
|
if (!usedCollection) {
|
|
33
|
-
usedCollection =
|
|
33
|
+
usedCollection = navigationController.getCollection(props.path, props.entityId);
|
|
34
34
|
if (!usedCollection) {
|
|
35
35
|
console.error("ERROR: No collection found in path `", props.path, "`. Entity id: ", props.entityId);
|
|
36
36
|
throw Error("ERROR: No collection found in path `" + props.path + "`. Make sure you have defined a collection for this path in the root navigation.");
|
|
37
37
|
}
|
|
38
38
|
}
|
|
39
39
|
return usedCollection;
|
|
40
|
-
}, [
|
|
40
|
+
}, [navigationController, props]);
|
|
41
41
|
|
|
42
42
|
useEffect(() => {
|
|
43
43
|
function beforeunload(e: any) {
|
package/src/core/FireCMS.tsx
CHANGED
|
@@ -2,25 +2,22 @@ import React, { useMemo } from "react";
|
|
|
2
2
|
|
|
3
3
|
import { EntityCollection, FireCMSContext, FireCMSPlugin, FireCMSProps, User } from "../types";
|
|
4
4
|
import { BreadcrumbsProvider } from "../contexts/BreacrumbsContext";
|
|
5
|
-
import { ModeControllerContext } from "../contexts
|
|
5
|
+
import { AuthControllerContext, ModeControllerContext } from "../contexts";
|
|
6
6
|
import { useBuildSideEntityController } from "../internal/useBuildSideEntityController";
|
|
7
|
-
import { useBuildNavigationContext } from "../internal/useBuildNavigationContext";
|
|
8
|
-
import { useBuildSideDialogsController } from "../internal/useBuildSideDialogsController";
|
|
9
7
|
import { FireCMSContextInstance, useFireCMSContext, useModeController } from "../hooks";
|
|
8
|
+
import { useBuildSideDialogsController } from "../internal/useBuildSideDialogsController";
|
|
10
9
|
import { ErrorView } from "../components";
|
|
11
10
|
import { StorageSourceContext } from "../contexts/StorageSourceContext";
|
|
12
11
|
import { UserConfigurationPersistenceContext } from "../contexts/UserConfigurationPersistenceContext";
|
|
13
12
|
import { DataSourceContext } from "../contexts/DataSourceContext";
|
|
14
13
|
import { SideEntityControllerContext } from "../contexts/SideEntityControllerContext";
|
|
15
|
-
import {
|
|
16
|
-
import { AuthControllerContext } from "../contexts/AuthControllerContext";
|
|
14
|
+
import { NavigationContext } from "../contexts/NavigationContext";
|
|
17
15
|
import { SideDialogsControllerContext } from "../contexts/SideDialogsControllerContext";
|
|
18
16
|
import { useLocaleConfig } from "../internal/useLocaleConfig";
|
|
19
17
|
import { CenteredView } from "../ui";
|
|
20
18
|
import { DialogsProvider } from "../contexts/DialogsProvider";
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
const DEFAULT_COLLECTION_PATH = "/c";
|
|
19
|
+
import { useBuildNavigationController } from "../internal/useBuildNavigationController";
|
|
20
|
+
import { useBuildDataSource } from "../internal/useBuildDataSource";
|
|
24
21
|
|
|
25
22
|
/**
|
|
26
23
|
* If you are using independent components of the CMS
|
|
@@ -39,43 +36,52 @@ export function FireCMS<UserType extends User, EC extends EntityCollection>(prop
|
|
|
39
36
|
const modeController = useModeController();
|
|
40
37
|
const {
|
|
41
38
|
children,
|
|
42
|
-
collections,
|
|
43
|
-
views,
|
|
44
39
|
entityLinkBuilder,
|
|
45
40
|
userConfigPersistence,
|
|
46
41
|
dateTimeFormat,
|
|
47
42
|
locale,
|
|
48
43
|
authController,
|
|
49
44
|
storageSource,
|
|
50
|
-
|
|
51
|
-
basePath = DEFAULT_BASE_PATH,
|
|
52
|
-
baseCollectionPath = DEFAULT_COLLECTION_PATH,
|
|
45
|
+
dataSourceDelegate,
|
|
53
46
|
plugins,
|
|
54
47
|
onAnalyticsEvent,
|
|
55
48
|
propertyConfigs,
|
|
56
49
|
entityViews,
|
|
57
|
-
components
|
|
50
|
+
components,
|
|
51
|
+
baseCollectionPath,
|
|
52
|
+
basePath,
|
|
53
|
+
collections,
|
|
54
|
+
views
|
|
58
55
|
} = props;
|
|
59
56
|
|
|
60
57
|
useLocaleConfig(locale);
|
|
61
58
|
|
|
62
|
-
const
|
|
59
|
+
const navigationController = useBuildNavigationController({
|
|
63
60
|
basePath,
|
|
64
61
|
baseCollectionPath,
|
|
65
62
|
authController,
|
|
66
63
|
collections,
|
|
67
64
|
views,
|
|
68
65
|
userConfigPersistence,
|
|
69
|
-
dataSource,
|
|
66
|
+
dataSource: dataSourceDelegate,
|
|
70
67
|
plugins
|
|
71
68
|
});
|
|
72
69
|
|
|
70
|
+
/**
|
|
71
|
+
* Controller in charge of fetching and persisting data
|
|
72
|
+
*/
|
|
73
|
+
const dataSource = useBuildDataSource({
|
|
74
|
+
delegate: dataSourceDelegate,
|
|
75
|
+
propertyConfigs,
|
|
76
|
+
navigationController
|
|
77
|
+
});
|
|
78
|
+
|
|
73
79
|
const sideDialogsController = useBuildSideDialogsController();
|
|
74
|
-
const sideEntityController = useBuildSideEntityController(
|
|
80
|
+
const sideEntityController = useBuildSideEntityController(navigationController, sideDialogsController);
|
|
75
81
|
|
|
76
82
|
const pluginsLoading = plugins?.some(p => p.loading) ?? false;
|
|
77
83
|
|
|
78
|
-
const loading = authController.initialLoading ||
|
|
84
|
+
const loading = authController.initialLoading || navigationController.loading || pluginsLoading;
|
|
79
85
|
|
|
80
86
|
const context: Partial<FireCMSContext> = useMemo(() => ({
|
|
81
87
|
entityLinkBuilder,
|
|
@@ -88,12 +94,12 @@ export function FireCMS<UserType extends User, EC extends EntityCollection>(prop
|
|
|
88
94
|
components
|
|
89
95
|
}), [dateTimeFormat, locale, plugins, entityViews, propertyConfigs, components]);
|
|
90
96
|
|
|
91
|
-
if (
|
|
97
|
+
if (navigationController.navigationLoadingError) {
|
|
92
98
|
return (
|
|
93
99
|
<CenteredView maxWidth={"md"} fullScreen={true}>
|
|
94
100
|
<ErrorView
|
|
95
101
|
title={"Error loading navigation"}
|
|
96
|
-
error={
|
|
102
|
+
error={navigationController.navigationLoadingError}/>
|
|
97
103
|
</CenteredView>
|
|
98
104
|
);
|
|
99
105
|
}
|
|
@@ -123,8 +129,8 @@ export function FireCMS<UserType extends User, EC extends EntityCollection>(prop
|
|
|
123
129
|
value={sideDialogsController}>
|
|
124
130
|
<SideEntityControllerContext.Provider
|
|
125
131
|
value={sideEntityController}>
|
|
126
|
-
<
|
|
127
|
-
value={
|
|
132
|
+
<NavigationContext.Provider
|
|
133
|
+
value={navigationController}>
|
|
128
134
|
<BreadcrumbsProvider>
|
|
129
135
|
<DialogsProvider>
|
|
130
136
|
<FireCMSInternal
|
|
@@ -133,7 +139,7 @@ export function FireCMS<UserType extends User, EC extends EntityCollection>(prop
|
|
|
133
139
|
</FireCMSInternal>
|
|
134
140
|
</DialogsProvider>
|
|
135
141
|
</BreadcrumbsProvider>
|
|
136
|
-
</
|
|
142
|
+
</NavigationContext.Provider>
|
|
137
143
|
</SideEntityControllerContext.Provider>
|
|
138
144
|
</SideDialogsControllerContext.Provider>
|
|
139
145
|
</AuthControllerContext.Provider>
|
|
@@ -3,7 +3,7 @@ import React, { PropsWithChildren } from "react";
|
|
|
3
3
|
import { Route, Routes, useLocation } from "react-router-dom";
|
|
4
4
|
import { CMSView } from "../types";
|
|
5
5
|
import { DefaultHomePage, EntityCollectionView, NotFoundPage } from "../components";
|
|
6
|
-
import { useBreadcrumbsContext,
|
|
6
|
+
import { useBreadcrumbsContext, useNavigationController } from "../hooks";
|
|
7
7
|
import { toArray } from "../util/arrays";
|
|
8
8
|
import equal from "react-fast-compare"
|
|
9
9
|
|
|
@@ -23,7 +23,7 @@ export type NavigationRoutesProps = {
|
|
|
23
23
|
/**
|
|
24
24
|
* This component is in charge of rendering
|
|
25
25
|
* all the related routes (entity collection root views, custom views
|
|
26
|
-
* or the home route) related to a {@link
|
|
26
|
+
* or the home route) related to a {@link NavigationController}.
|
|
27
27
|
* This component needs a parent {@link FireCMS}
|
|
28
28
|
*
|
|
29
29
|
* @constructor
|
|
@@ -37,7 +37,7 @@ export const NavigationRoutes = React.memo<NavigationRoutesProps>(
|
|
|
37
37
|
}: NavigationRoutesProps) {
|
|
38
38
|
|
|
39
39
|
const location = useLocation();
|
|
40
|
-
const navigation =
|
|
40
|
+
const navigation = useNavigationController();
|
|
41
41
|
|
|
42
42
|
if (!navigation)
|
|
43
43
|
return <></>;
|
package/src/core/Scaffold.tsx
CHANGED
|
@@ -3,7 +3,7 @@ import equal from "react-fast-compare"
|
|
|
3
3
|
import { Link } from "react-router-dom";
|
|
4
4
|
|
|
5
5
|
import { Drawer as DefaultDrawer, DrawerProps } from "./Drawer";
|
|
6
|
-
import { useLargeLayout,
|
|
6
|
+
import { useLargeLayout, useNavigationController } from "../hooks";
|
|
7
7
|
import { CircularProgressCenter, ErrorBoundary, FireCMSAppBar, FireCMSAppBarProps, FireCMSLogo } from "../components";
|
|
8
8
|
import { cn, IconButton, Sheet, Tooltip } from "../ui";
|
|
9
9
|
import { ChevronLeftIcon, MenuIcon } from "../icons";
|
|
@@ -85,7 +85,7 @@ export const Scaffold = React.memo<PropsWithChildren<ScaffoldProps>>(
|
|
|
85
85
|
|
|
86
86
|
const largeLayout = useLargeLayout();
|
|
87
87
|
|
|
88
|
-
const navigation =
|
|
88
|
+
const navigation = useNavigationController();
|
|
89
89
|
const [drawerOpen, setDrawerOpen] = React.useState(false);
|
|
90
90
|
const [onHover, setOnHover] = React.useState(false);
|
|
91
91
|
|
|
@@ -171,7 +171,7 @@ function StyledDrawer(props: {
|
|
|
171
171
|
onMouseLeave: () => void
|
|
172
172
|
}) {
|
|
173
173
|
|
|
174
|
-
const navigation =
|
|
174
|
+
const navigation = useNavigationController();
|
|
175
175
|
|
|
176
176
|
const width = !props.displayed ? 0 : (props.open ? DRAWER_WIDTH : 72);
|
|
177
177
|
const innerDrawer = <div
|
package/src/core/index.tsx
CHANGED
|
@@ -7,7 +7,7 @@ import { LabelWithIcon } from "../components";
|
|
|
7
7
|
import {
|
|
8
8
|
useEntityFetch,
|
|
9
9
|
useFireCMSContext,
|
|
10
|
-
|
|
10
|
+
useNavigationController,
|
|
11
11
|
useReferenceDialog,
|
|
12
12
|
useSideEntityController
|
|
13
13
|
} from "../../hooks";
|
|
@@ -49,12 +49,12 @@ export function ReferenceWidget<M extends Record<string, any>>({
|
|
|
49
49
|
}) {
|
|
50
50
|
|
|
51
51
|
const fireCMSContext = useFireCMSContext();
|
|
52
|
-
const
|
|
52
|
+
const navigationController = useNavigationController();
|
|
53
53
|
const sideEntityController = useSideEntityController();
|
|
54
54
|
|
|
55
55
|
const collection: EntityCollection | undefined = useMemo(() => {
|
|
56
|
-
return
|
|
57
|
-
}, [path,
|
|
56
|
+
return navigationController.getCollection(path);
|
|
57
|
+
}, [path, navigationController]);
|
|
58
58
|
|
|
59
59
|
if (!collection) {
|
|
60
60
|
throw Error(`Couldn't find the corresponding collection for the path: ${path}`);
|