@firecms/core 3.0.0-canary.39 → 3.0.0-canary.40
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/index.es.js +1101 -1080
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +5 -5
- package/dist/index.umd.js.map +1 -1
- package/package.json +4 -4
- package/src/hooks/useBuildModeController.tsx +11 -5
- package/src/hooks/useBuildNavigationController.tsx +40 -7
- package/src/internal/useBuildSideEntityController.tsx +15 -12
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@firecms/core",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "3.0.0-canary.
|
|
4
|
+
"version": "3.0.0-canary.40",
|
|
5
5
|
"description": "Awesome Firebase/Firestore-based headless open-source CMS",
|
|
6
6
|
"funding": {
|
|
7
7
|
"url": "https://github.com/sponsors/firecmsco"
|
|
@@ -46,8 +46,8 @@
|
|
|
46
46
|
"./package.json": "./package.json"
|
|
47
47
|
},
|
|
48
48
|
"dependencies": {
|
|
49
|
-
"@firecms/formex": "^3.0.0-canary.
|
|
50
|
-
"@firecms/ui": "^3.0.0-canary.
|
|
49
|
+
"@firecms/formex": "^3.0.0-canary.40",
|
|
50
|
+
"@firecms/ui": "^3.0.0-canary.40",
|
|
51
51
|
"@fontsource/jetbrains-mono": "^5.0.19",
|
|
52
52
|
"@fontsource/roboto": "^5.0.12",
|
|
53
53
|
"@hello-pangea/dnd": "^16.5.0",
|
|
@@ -115,7 +115,7 @@
|
|
|
115
115
|
"dist",
|
|
116
116
|
"src"
|
|
117
117
|
],
|
|
118
|
-
"gitHead": "
|
|
118
|
+
"gitHead": "40b01721ac260b6cce7f5d8a3a1d768410e7f20d",
|
|
119
119
|
"publishConfig": {
|
|
120
120
|
"access": "public"
|
|
121
121
|
}
|
|
@@ -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");
|
|
@@ -187,6 +187,8 @@ export function useBuildNavigationController<EC extends EntityCollection, UserTy
|
|
|
187
187
|
if (authController.initialLoading)
|
|
188
188
|
return;
|
|
189
189
|
|
|
190
|
+
console.debug("Refreshing navigation");
|
|
191
|
+
|
|
190
192
|
try {
|
|
191
193
|
|
|
192
194
|
const [resolvedCollections = [], resolvedViews, resolvedAdminViews = []] = await Promise.all([
|
|
@@ -196,16 +198,23 @@ export function useBuildNavigationController<EC extends EntityCollection, UserTy
|
|
|
196
198
|
]
|
|
197
199
|
);
|
|
198
200
|
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
!equal(viewsRef.current, resolvedViews) ||
|
|
202
|
-
!equal(adminViewsRef.current, resolvedAdminViews) ||
|
|
203
|
-
!equal(topLevelNavigation, computeTopNavigation(resolvedCollections, resolvedViews, resolvedAdminViews, viewsOrder))
|
|
204
|
-
) {
|
|
201
|
+
let shouldUpdateTopLevelNav = false;
|
|
202
|
+
if (!areCollectionListsEqual(collectionsRef.current ?? [], resolvedCollections)) {
|
|
205
203
|
collectionsRef.current = resolvedCollections;
|
|
204
|
+
shouldUpdateTopLevelNav = true;
|
|
205
|
+
}
|
|
206
|
+
if (!equal(viewsRef.current, resolvedViews)) {
|
|
206
207
|
viewsRef.current = resolvedViews;
|
|
208
|
+
shouldUpdateTopLevelNav = true;
|
|
209
|
+
}
|
|
210
|
+
if (!equal(adminViewsRef.current, resolvedAdminViews)) {
|
|
207
211
|
adminViewsRef.current = resolvedAdminViews;
|
|
208
|
-
|
|
212
|
+
shouldUpdateTopLevelNav = true;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
const computedTopLevelNav = computeTopNavigation(resolvedCollections, resolvedViews, resolvedAdminViews, viewsOrder);
|
|
216
|
+
if (shouldUpdateTopLevelNav && !equal(topLevelNavigation, computedTopLevelNav)) {
|
|
217
|
+
setTopLevelNavigation(computedTopLevelNav);
|
|
209
218
|
}
|
|
210
219
|
} catch (e) {
|
|
211
220
|
console.error(e);
|
|
@@ -475,3 +484,27 @@ function getGroup(collectionOrView: EntityCollection<any, any> | CMSView) {
|
|
|
475
484
|
}
|
|
476
485
|
return trimmed ?? "Views";
|
|
477
486
|
}
|
|
487
|
+
|
|
488
|
+
function areCollectionListsEqual(a: EntityCollection[], b: EntityCollection[]) {
|
|
489
|
+
if (a.length !== b.length) {
|
|
490
|
+
return false;
|
|
491
|
+
}
|
|
492
|
+
const aSorted = a.sort((a, b) => a.id.localeCompare(b.id));
|
|
493
|
+
const bSorted = b.sort((a, b) => a.id.localeCompare(b.id));
|
|
494
|
+
return aSorted.every((value, index) => areCollectionsEqual(value, bSorted[index]));
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
function areCollectionsEqual(a: EntityCollection, b: EntityCollection) {
|
|
498
|
+
const {
|
|
499
|
+
subcollections: subcollectionsA,
|
|
500
|
+
...restA
|
|
501
|
+
} = a;
|
|
502
|
+
const {
|
|
503
|
+
subcollections: subcollectionsB,
|
|
504
|
+
...restB
|
|
505
|
+
} = b;
|
|
506
|
+
if (!areCollectionListsEqual(subcollectionsA ?? [], subcollectionsB ?? [])) {
|
|
507
|
+
return false;
|
|
508
|
+
}
|
|
509
|
+
return equal(restA, restB);
|
|
510
|
+
}
|
|
@@ -43,9 +43,9 @@ export const useBuildSideEntityController = (navigation: NavigationController,
|
|
|
43
43
|
const panel = panelsFromUrl[i];
|
|
44
44
|
setTimeout(() => {
|
|
45
45
|
if (i === 0)
|
|
46
|
-
sideDialogsController.replace(propsToSidePanel(panel, navigation, smallLayout));
|
|
46
|
+
sideDialogsController.replace(propsToSidePanel(panel, navigation.buildUrlCollectionPath, navigation.resolveAliasesFrom, smallLayout));
|
|
47
47
|
else
|
|
48
|
-
sideDialogsController.open(propsToSidePanel(panel, navigation, smallLayout))
|
|
48
|
+
sideDialogsController.open(propsToSidePanel(panel, navigation.buildUrlCollectionPath, navigation.resolveAliasesFrom, smallLayout))
|
|
49
49
|
}, 1);
|
|
50
50
|
}
|
|
51
51
|
} else {
|
|
@@ -53,7 +53,7 @@ export const useBuildSideEntityController = (navigation: NavigationController,
|
|
|
53
53
|
}
|
|
54
54
|
initialised.current = true;
|
|
55
55
|
}
|
|
56
|
-
}, [location, navigation, sideDialogsController, smallLayout]);
|
|
56
|
+
}, [location, navigation.loading, navigation.isUrlCollectionPath, navigation.buildUrlCollectionPath, navigation.resolveAliasesFrom, sideDialogsController, smallLayout, navigation]);
|
|
57
57
|
|
|
58
58
|
const close = useCallback(() => {
|
|
59
59
|
sideDialogsController.close();
|
|
@@ -76,9 +76,9 @@ export const useBuildSideEntityController = (navigation: NavigationController,
|
|
|
76
76
|
sideDialogsController.open(propsToSidePanel({
|
|
77
77
|
selectedSubPath: defaultSelectedView,
|
|
78
78
|
...props,
|
|
79
|
-
}, navigation, smallLayout));
|
|
79
|
+
}, navigation.buildUrlCollectionPath, navigation.resolveAliasesFrom, smallLayout));
|
|
80
80
|
|
|
81
|
-
}, [sideDialogsController, navigation, smallLayout]);
|
|
81
|
+
}, [sideDialogsController, navigation.buildUrlCollectionPath, navigation.resolveAliasesFrom, smallLayout]);
|
|
82
82
|
|
|
83
83
|
const replace = useCallback((props: EntitySidePanelProps<any>) => {
|
|
84
84
|
|
|
@@ -86,9 +86,9 @@ export const useBuildSideEntityController = (navigation: NavigationController,
|
|
|
86
86
|
throw Error("If you want to copy an entity you need to provide an entityId");
|
|
87
87
|
}
|
|
88
88
|
|
|
89
|
-
sideDialogsController.replace(propsToSidePanel(props, navigation, smallLayout));
|
|
89
|
+
sideDialogsController.replace(propsToSidePanel(props, navigation.buildUrlCollectionPath, navigation.resolveAliasesFrom, smallLayout));
|
|
90
90
|
|
|
91
|
-
}, [navigation, sideDialogsController, smallLayout]);
|
|
91
|
+
}, [navigation.buildUrlCollectionPath, navigation.resolveAliasesFrom, sideDialogsController, smallLayout]);
|
|
92
92
|
|
|
93
93
|
return {
|
|
94
94
|
close,
|
|
@@ -149,14 +149,17 @@ export function buildSidePanelsFromUrl(path: string, collections: EntityCollecti
|
|
|
149
149
|
return sidePanels;
|
|
150
150
|
}
|
|
151
151
|
|
|
152
|
-
const propsToSidePanel = (props: EntitySidePanelProps<any>,
|
|
152
|
+
const propsToSidePanel = (props: EntitySidePanelProps<any>,
|
|
153
|
+
buildUrlCollectionPath: (path: string) => string,
|
|
154
|
+
resolveAliasesFrom: (pathWithAliases: string) => string,
|
|
155
|
+
smallLayout: boolean): SideDialogPanelProps => {
|
|
153
156
|
|
|
154
157
|
const collectionPath = removeInitialAndTrailingSlashes(props.path);
|
|
155
158
|
|
|
156
159
|
const newPath = props.entityId
|
|
157
|
-
?
|
|
158
|
-
:
|
|
159
|
-
const resolvedPath =
|
|
160
|
+
? buildUrlCollectionPath(`${collectionPath}/${props.entityId}/${props.selectedSubPath || ""}`)
|
|
161
|
+
: buildUrlCollectionPath(`${collectionPath}#${NEW_URL_HASH}`);
|
|
162
|
+
const resolvedPath = resolveAliasesFrom(props.path);
|
|
160
163
|
|
|
161
164
|
const resolvedPanelProps: EntitySidePanelProps<any> = {
|
|
162
165
|
...props,
|
|
@@ -167,7 +170,7 @@ const propsToSidePanel = (props: EntitySidePanelProps<any>, navigation: Navigati
|
|
|
167
170
|
key: `${props.path}/${props.entityId}`,
|
|
168
171
|
component: <EntitySidePanel {...resolvedPanelProps}/>,
|
|
169
172
|
urlPath: newPath,
|
|
170
|
-
parentUrlPath:
|
|
173
|
+
parentUrlPath: buildUrlCollectionPath(collectionPath),
|
|
171
174
|
width: getEntityViewWidth(props, smallLayout),
|
|
172
175
|
onClose: props.onClose
|
|
173
176
|
});
|