@firecms/core 3.0.0-canary.252 → 3.0.0-canary.253
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/components/EntityCollectionTable/EntityCollectionRowActions.d.ts +2 -1
- package/dist/core/EntityEditView.d.ts +3 -0
- package/dist/form/EntityForm.d.ts +2 -1
- package/dist/form/EntityFormActions.d.ts +3 -1
- package/dist/index.es.js +87 -87
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +87 -87
- package/dist/index.umd.js.map +1 -1
- package/dist/types/entity_actions.d.ts +1 -0
- package/dist/types/side_entity_controller.d.ts +4 -0
- package/dist/util/navigation_from_path.d.ts +4 -0
- package/package.json +5 -5
- package/src/components/EntityCollectionTable/EntityCollectionRowActions.tsx +4 -0
- package/src/components/EntityCollectionView/EntityCollectionView.tsx +2 -2
- package/src/components/FireCMSLogo.tsx +7 -51
- package/src/components/common/default_entity_actions.tsx +7 -4
- package/src/core/EntityEditView.tsx +13 -1
- package/src/core/EntitySidePanel.tsx +4 -1
- package/src/form/EntityForm.tsx +6 -0
- package/src/form/EntityFormActions.tsx +14 -1
- package/src/internal/useBuildSideEntityController.tsx +7 -4
- package/src/routes/FireCMSRoute.tsx +3 -3
- package/src/types/entity_actions.tsx +1 -0
- package/src/types/side_entity_controller.tsx +5 -0
- package/src/util/navigation_from_path.ts +15 -5
- package/src/util/navigation_utils.ts +2 -2
|
@@ -46,6 +46,7 @@ export type EntityActionClickProps<M extends object, USER extends User = User> =
|
|
|
46
46
|
entity: Entity<M>;
|
|
47
47
|
context: FireCMSContext<USER>;
|
|
48
48
|
fullPath?: string;
|
|
49
|
+
fullIdPath?: string;
|
|
49
50
|
collection?: EntityCollection<M>;
|
|
50
51
|
selectionController?: SelectionController;
|
|
51
52
|
highlightEntity?: (entity: Entity<any>) => void;
|
|
@@ -11,6 +11,10 @@ export interface EntitySidePanelProps<M extends Record<string, any> = any> {
|
|
|
11
11
|
* Absolute path of the entity
|
|
12
12
|
*/
|
|
13
13
|
path: string;
|
|
14
|
+
/**
|
|
15
|
+
* Full CMS path of the entity, including the collection and sub-collections.
|
|
16
|
+
*/
|
|
17
|
+
fullIdPath?: string;
|
|
14
18
|
/**
|
|
15
19
|
* ID of the entity, if not set, it means we are creating a new entity
|
|
16
20
|
*/
|
|
@@ -4,6 +4,7 @@ export interface NavigationViewEntityInternal<M extends Record<string, any>> {
|
|
|
4
4
|
type: "entity";
|
|
5
5
|
entityId: string;
|
|
6
6
|
path: string;
|
|
7
|
+
fullIdPath: string;
|
|
7
8
|
fullPath: string;
|
|
8
9
|
parentCollection: EntityCollection<M>;
|
|
9
10
|
}
|
|
@@ -11,12 +12,14 @@ export interface NavigationViewCollectionInternal<M extends Record<string, any>>
|
|
|
11
12
|
type: "collection";
|
|
12
13
|
id: string;
|
|
13
14
|
path: string;
|
|
15
|
+
fullIdPath: string;
|
|
14
16
|
fullPath: string;
|
|
15
17
|
collection: EntityCollection<M>;
|
|
16
18
|
}
|
|
17
19
|
export interface NavigationViewEntityCustomInternal<M extends Record<string, any>> {
|
|
18
20
|
type: "custom_view";
|
|
19
21
|
path: string;
|
|
22
|
+
fullIdPath: string;
|
|
20
23
|
fullPath: string;
|
|
21
24
|
entityId: string;
|
|
22
25
|
view: EntityCustomView<M>;
|
|
@@ -25,5 +28,6 @@ export declare function getNavigationEntriesFromPath(props: {
|
|
|
25
28
|
path: string;
|
|
26
29
|
collections: EntityCollection[] | undefined;
|
|
27
30
|
currentFullPath?: string;
|
|
31
|
+
currentFullIdPath?: string;
|
|
28
32
|
contextEntityViews?: EntityCustomView<any>[];
|
|
29
33
|
}): NavigationViewInternal[];
|
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.253",
|
|
5
5
|
"description": "Awesome Firebase/Firestore-based headless open-source CMS",
|
|
6
6
|
"funding": {
|
|
7
7
|
"url": "https://github.com/sponsors/firecmsco"
|
|
@@ -53,9 +53,9 @@
|
|
|
53
53
|
"@dnd-kit/core": "^6.3.1",
|
|
54
54
|
"@dnd-kit/modifiers": "^9.0.0",
|
|
55
55
|
"@dnd-kit/sortable": "^10.0.0",
|
|
56
|
-
"@firecms/editor": "^3.0.0-canary.
|
|
57
|
-
"@firecms/formex": "^3.0.0-canary.
|
|
58
|
-
"@firecms/ui": "^3.0.0-canary.
|
|
56
|
+
"@firecms/editor": "^3.0.0-canary.253",
|
|
57
|
+
"@firecms/formex": "^3.0.0-canary.253",
|
|
58
|
+
"@firecms/ui": "^3.0.0-canary.253",
|
|
59
59
|
"@radix-ui/react-portal": "^1.1.3",
|
|
60
60
|
"clsx": "^2.1.1",
|
|
61
61
|
"date-fns": "^3.6.0",
|
|
@@ -107,7 +107,7 @@
|
|
|
107
107
|
"dist",
|
|
108
108
|
"src"
|
|
109
109
|
],
|
|
110
|
-
"gitHead": "
|
|
110
|
+
"gitHead": "c4dff639fcd32ba5d706f5b8cf92692af6e94893",
|
|
111
111
|
"publishConfig": {
|
|
112
112
|
"access": "public"
|
|
113
113
|
},
|
|
@@ -33,6 +33,7 @@ export const EntityCollectionRowActions = function EntityCollectionRowActions({
|
|
|
33
33
|
entity,
|
|
34
34
|
collection,
|
|
35
35
|
fullPath,
|
|
36
|
+
fullIdPath,
|
|
36
37
|
width,
|
|
37
38
|
frozen,
|
|
38
39
|
isSelected,
|
|
@@ -50,6 +51,7 @@ export const EntityCollectionRowActions = function EntityCollectionRowActions({
|
|
|
50
51
|
entity: Entity<any>,
|
|
51
52
|
collection?: EntityCollection<any>,
|
|
52
53
|
fullPath?: string,
|
|
54
|
+
fullIdPath?: string,
|
|
53
55
|
width: number,
|
|
54
56
|
frozen?: boolean,
|
|
55
57
|
size: CollectionSize,
|
|
@@ -107,6 +109,7 @@ export const EntityCollectionRowActions = function EntityCollectionRowActions({
|
|
|
107
109
|
action.onClick({
|
|
108
110
|
entity,
|
|
109
111
|
fullPath,
|
|
112
|
+
fullIdPath,
|
|
110
113
|
collection,
|
|
111
114
|
context,
|
|
112
115
|
selectionController,
|
|
@@ -136,6 +139,7 @@ export const EntityCollectionRowActions = function EntityCollectionRowActions({
|
|
|
136
139
|
action.onClick({
|
|
137
140
|
entity,
|
|
138
141
|
fullPath,
|
|
142
|
+
fullIdPath,
|
|
139
143
|
collection,
|
|
140
144
|
context,
|
|
141
145
|
selectionController,
|
|
@@ -256,7 +256,6 @@ export const EntityCollectionView = React.memo(
|
|
|
256
256
|
}, [unselectNavigatedEntity, sideEntityController]);
|
|
257
257
|
|
|
258
258
|
const onNewClick = useCallback(() => {
|
|
259
|
-
|
|
260
259
|
const collection = collectionRef.current;
|
|
261
260
|
analyticsController.onAnalyticsEvent?.("new_entity_click", {
|
|
262
261
|
path: fullPath
|
|
@@ -539,7 +538,8 @@ export const EntityCollectionView = React.memo(
|
|
|
539
538
|
highlightEntity={setHighlightedEntity}
|
|
540
539
|
unhighlightEntity={unselectNavigatedEntity}
|
|
541
540
|
collection={collection}
|
|
542
|
-
fullPath={
|
|
541
|
+
fullPath={fullPath}
|
|
542
|
+
fullIdPath={fullIdPath}
|
|
543
543
|
actions={actions}
|
|
544
544
|
hideId={collection?.hideIdFromCollection}
|
|
545
545
|
onCollectionChange={updateLastDeleteTimestamp}
|
|
@@ -14,59 +14,15 @@ export function FireCMSLogo({
|
|
|
14
14
|
return (
|
|
15
15
|
<svg
|
|
16
16
|
width={width ?? "100%"} height={height ?? "100%"}
|
|
17
|
-
|
|
17
|
+
version="1.1"
|
|
18
18
|
style={style}
|
|
19
19
|
className={className}
|
|
20
|
-
xmlns="http://www.w3.org/2000/svg">
|
|
21
|
-
<
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
id="radialGradient-1">
|
|
27
|
-
<stop stopColor="#FF5B79" offset="0%"/>
|
|
28
|
-
<stop stopColor="#FA5574" offset="28.0930803%"/>
|
|
29
|
-
<stop stopColor="#EC4C51" offset="44.7242531%"/>
|
|
30
|
-
<stop stopColor="#9543C1" offset="71.4578165%"/>
|
|
31
|
-
<stop stopColor="#3857B3" offset="100%"/>
|
|
32
|
-
</radialGradient>
|
|
33
|
-
<radialGradient cx="53.6205516%" cy="47.2473036%"
|
|
34
|
-
fx="53.6205516%"
|
|
35
|
-
fy="47.2473036%" r="50.8229649%"
|
|
36
|
-
gradientTransform="translate(0.536206,0.472473),rotate(90.000000),scale(1.000000,1.206631),translate(-0.536206,-0.472473)"
|
|
37
|
-
id="radialGradient-2">
|
|
38
|
-
<stop stopColor="#68294F" stopOpacity="0" offset="0%"/>
|
|
39
|
-
<stop stopColor="#5E2548" stopOpacity="0.04641108"
|
|
40
|
-
offset="75.3503173%"/>
|
|
41
|
-
<stop stopColor="#0D060B" stopOpacity="0.437431709"
|
|
42
|
-
offset="100%"/>
|
|
43
|
-
</radialGradient>
|
|
44
|
-
<radialGradient cx="53.8605015%" cy="48.1990423%"
|
|
45
|
-
fx="53.8605015%"
|
|
46
|
-
fy="48.1990423%" r="59.9151549%"
|
|
47
|
-
gradientTransform="translate(0.538605,0.481990),rotate(180.000000),scale(1.000000,0.925027),translate(-0.538605,-0.481990)"
|
|
48
|
-
id="radialGradient-3">
|
|
49
|
-
<stop stopColor="#68294F" stopOpacity="0" offset="0%"/>
|
|
50
|
-
<stop stopColor="#5E2548" stopOpacity="0.04641108"
|
|
51
|
-
offset="84.0867343%"/>
|
|
52
|
-
<stop stopColor="#FF0000" stopOpacity="0.567324765"
|
|
53
|
-
offset="100%"/>
|
|
54
|
-
</radialGradient>
|
|
55
|
-
</defs>
|
|
56
|
-
<g id="Page-1" stroke="none" strokeWidth="1" fill="none"
|
|
57
|
-
fillRule="evenodd">
|
|
58
|
-
<g id="firecms_logo">
|
|
59
|
-
<circle fill="url(#radialGradient-1)" cx="299.5"
|
|
60
|
-
cy="299.5"
|
|
61
|
-
r="299.5"/>
|
|
62
|
-
<circle fill="url(#radialGradient-2)" cx="299.5"
|
|
63
|
-
cy="299.5"
|
|
64
|
-
r="299.5"/>
|
|
65
|
-
<circle fill="url(#radialGradient-3)" cx="299.5"
|
|
66
|
-
cy="299.5"
|
|
67
|
-
r="299.5"/>
|
|
68
|
-
</g>
|
|
69
|
-
</g>
|
|
20
|
+
viewBox="0 0 583 583" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
21
|
+
<circle cx="291.5" cy="291.5" r="291.5" fill="#0070F4"/>
|
|
22
|
+
<ellipse cx="292" cy="291.5" rx="173" ry="173.5" fill="#FF3773"/>
|
|
23
|
+
<path
|
|
24
|
+
d="M465 291.5C465 268.847 460.525 246.416 451.831 225.487C443.137 204.558 430.394 185.542 414.329 169.524C398.265 153.506 379.194 140.8 358.204 132.131C337.215 123.462 314.719 119 292 119C269.281 119 246.785 123.462 225.796 132.131C204.806 140.8 185.735 153.506 169.671 169.524C153.606 185.542 140.863 204.558 132.169 225.487C123.475 246.416 119 268.847 119 291.5L292 291.5H465Z"
|
|
25
|
+
fill="#FFA400"/>
|
|
70
26
|
</svg>
|
|
71
27
|
);
|
|
72
28
|
|
|
@@ -13,6 +13,7 @@ export const editEntityAction: EntityAction = {
|
|
|
13
13
|
entity,
|
|
14
14
|
collection,
|
|
15
15
|
fullPath,
|
|
16
|
+
fullIdPath,
|
|
16
17
|
context,
|
|
17
18
|
highlightEntity,
|
|
18
19
|
unhighlightEntity,
|
|
@@ -30,7 +31,8 @@ export const editEntityAction: EntityAction = {
|
|
|
30
31
|
addRecentId(collection.id, entity.id);
|
|
31
32
|
}
|
|
32
33
|
|
|
33
|
-
const path = collection?.collectionGroup ? collection.
|
|
34
|
+
const path = collection?.collectionGroup ? collection.path : (fullPath ?? collection?.path ?? entity.path);
|
|
35
|
+
const newFullIdPath = collection?.collectionGroup ? collection.id : (fullIdPath ?? collection?.id ?? entity.path);
|
|
34
36
|
const defaultSelectedView = resolveDefaultSelectedView(
|
|
35
37
|
collection ? collection.defaultSelectedView : undefined,
|
|
36
38
|
{
|
|
@@ -43,7 +45,7 @@ export const editEntityAction: EntityAction = {
|
|
|
43
45
|
collection,
|
|
44
46
|
entityId: entity.id,
|
|
45
47
|
path,
|
|
46
|
-
fullIdPath:
|
|
48
|
+
fullIdPath: newFullIdPath,
|
|
47
49
|
sideEntityController: context.sideEntityController,
|
|
48
50
|
onClose: () => unhighlightEntity?.(entity),
|
|
49
51
|
navigation: context.navigation,
|
|
@@ -73,13 +75,14 @@ export const copyEntityAction: EntityAction = {
|
|
|
73
75
|
entityId: entity.id
|
|
74
76
|
});
|
|
75
77
|
|
|
76
|
-
const path = collection?.collectionGroup ? collection.
|
|
78
|
+
const path = collection?.collectionGroup ? collection.path : (fullPath ?? collection?.path ?? entity.path);
|
|
79
|
+
const fullIdPath = collection?.collectionGroup ? collection.id : (fullPath ?? collection?.id ?? entity.path);
|
|
77
80
|
navigateToEntity({
|
|
78
81
|
openEntityMode,
|
|
79
82
|
collection,
|
|
80
83
|
entityId: entity.id,
|
|
81
84
|
path,
|
|
82
|
-
fullIdPath
|
|
85
|
+
fullIdPath,
|
|
83
86
|
copy: true,
|
|
84
87
|
sideEntityController: context.sideEntityController,
|
|
85
88
|
onClose: () => unhighlightEntity?.(entity),
|
|
@@ -41,9 +41,13 @@ export type OnTabChangeParams<M extends Record<string, any>> = {
|
|
|
41
41
|
entityId?: string;
|
|
42
42
|
selectedTab?: string;
|
|
43
43
|
collection: EntityCollection<M>;
|
|
44
|
+
|
|
44
45
|
};
|
|
45
46
|
|
|
46
47
|
export interface EntityEditViewProps<M extends Record<string, any>> {
|
|
48
|
+
/**
|
|
49
|
+
* The database path of the entity, e.g. "users" or "products".
|
|
50
|
+
*/
|
|
47
51
|
path: string;
|
|
48
52
|
/**
|
|
49
53
|
* The navigation path to the entity.
|
|
@@ -279,8 +283,15 @@ export function EntityEditViewInner<M extends Record<string, any>>({
|
|
|
279
283
|
|
|
280
284
|
const subCollectionsViews = subcollections && subcollections.map((subcollection) => {
|
|
281
285
|
const subcollectionId = subcollection.id ?? subcollection.path;
|
|
282
|
-
const newFullPath = usedEntity ? `${path}/${usedEntity?.id}/${removeInitialAndTrailingSlashes(
|
|
286
|
+
const newFullPath = usedEntity ? `${path}/${usedEntity?.id}/${removeInitialAndTrailingSlashes(subcollection.path)}` : undefined;
|
|
283
287
|
const newFullIdPath = fullIdPath ? `${fullIdPath}/${usedEntity?.id}/${removeInitialAndTrailingSlashes(subcollectionId)}` : undefined;
|
|
288
|
+
console.debug("Rendering subcollection", {
|
|
289
|
+
subcollectionId,
|
|
290
|
+
fullIdPath,
|
|
291
|
+
newFullPath,
|
|
292
|
+
newFullIdPath,
|
|
293
|
+
selectedTab
|
|
294
|
+
});
|
|
284
295
|
|
|
285
296
|
if (selectedTab !== subcollectionId) return null;
|
|
286
297
|
return (
|
|
@@ -342,6 +353,7 @@ export function EntityEditViewInner<M extends Record<string, any>>({
|
|
|
342
353
|
</div> : null;
|
|
343
354
|
|
|
344
355
|
const entityView = <EntityForm<M>
|
|
356
|
+
fullIdPath={fullIdPath}
|
|
345
357
|
collection={collection}
|
|
346
358
|
path={path}
|
|
347
359
|
entityId={entityId ?? usedEntity?.id}
|
|
@@ -23,6 +23,7 @@ export function EntitySidePanel(props: EntitySidePanelProps) {
|
|
|
23
23
|
allowFullScreen = true,
|
|
24
24
|
path,
|
|
25
25
|
entityId,
|
|
26
|
+
fullIdPath,
|
|
26
27
|
formProps,
|
|
27
28
|
} = props;
|
|
28
29
|
|
|
@@ -57,6 +58,7 @@ export function EntitySidePanel(props: EntitySidePanelProps) {
|
|
|
57
58
|
sideEntityController.replace({
|
|
58
59
|
path: params.path,
|
|
59
60
|
entityId: params.entityId,
|
|
61
|
+
fullIdPath: props.fullIdPath,
|
|
60
62
|
selectedTab: params.selectedTab,
|
|
61
63
|
updateUrl: true,
|
|
62
64
|
collection: params.collection,
|
|
@@ -110,6 +112,7 @@ export function EntitySidePanel(props: EntitySidePanelProps) {
|
|
|
110
112
|
<ErrorBoundary>
|
|
111
113
|
<EntityEditView
|
|
112
114
|
{...props}
|
|
115
|
+
fullIdPath={fullIdPath}
|
|
113
116
|
layout={"side_panel"}
|
|
114
117
|
collection={collection}
|
|
115
118
|
parentCollectionIds={parentCollectionIds}
|
|
@@ -133,7 +136,6 @@ export function EntitySidePanel(props: EntitySidePanelProps) {
|
|
|
133
136
|
</IconButton>}
|
|
134
137
|
</>}
|
|
135
138
|
onTabChange={({
|
|
136
|
-
path,
|
|
137
139
|
entityId,
|
|
138
140
|
selectedTab,
|
|
139
141
|
collection,
|
|
@@ -141,6 +143,7 @@ export function EntitySidePanel(props: EntitySidePanelProps) {
|
|
|
141
143
|
sideEntityController.replace({
|
|
142
144
|
path,
|
|
143
145
|
entityId,
|
|
146
|
+
fullIdPath: props.fullIdPath,
|
|
144
147
|
selectedTab,
|
|
145
148
|
updateUrl: true,
|
|
146
149
|
collection,
|
package/src/form/EntityForm.tsx
CHANGED
|
@@ -57,6 +57,7 @@ export type OnUpdateParams = {
|
|
|
57
57
|
|
|
58
58
|
export type EntityFormProps<M extends Record<string, any>> = {
|
|
59
59
|
path: string;
|
|
60
|
+
fullIdPath?: string;
|
|
60
61
|
collection: EntityCollection<M>;
|
|
61
62
|
entityId?: string;
|
|
62
63
|
entity?: Entity<M>;
|
|
@@ -96,6 +97,7 @@ export type EntityFormProps<M extends Record<string, any>> = {
|
|
|
96
97
|
|
|
97
98
|
export function EntityForm<M extends Record<string, any>>({
|
|
98
99
|
path,
|
|
100
|
+
fullIdPath,
|
|
99
101
|
entityId: entityIdProp,
|
|
100
102
|
collection,
|
|
101
103
|
onValuesModified,
|
|
@@ -119,6 +121,7 @@ export function EntityForm<M extends Record<string, any>>({
|
|
|
119
121
|
children
|
|
120
122
|
}: EntityFormProps<M>) {
|
|
121
123
|
|
|
124
|
+
|
|
122
125
|
if (collection.customId && collection.formAutoSave) {
|
|
123
126
|
console.warn(`The collection ${collection.path} has customId and formAutoSave enabled. This is not supported and formAutoSave will be ignored`);
|
|
124
127
|
}
|
|
@@ -665,9 +668,12 @@ export function EntityForm<M extends Record<string, any>>({
|
|
|
665
668
|
throw Error("INTERNAL: Collection and path must be defined in form context");
|
|
666
669
|
}
|
|
667
670
|
|
|
671
|
+
|
|
668
672
|
const dialogActions = <EntityFormActionsComponent
|
|
669
673
|
collection={resolvedCollection}
|
|
670
674
|
path={path}
|
|
675
|
+
fullPath={path}
|
|
676
|
+
fullIdPath={fullIdPath}
|
|
671
677
|
entity={entity}
|
|
672
678
|
layout={forceActionsAtTheBottom ? "bottom" : "side"}
|
|
673
679
|
savingError={savingError}
|
|
@@ -5,6 +5,8 @@ import { FormexController } from "@firecms/formex";
|
|
|
5
5
|
import { useFireCMSContext, useSideEntityController } from "../hooks";
|
|
6
6
|
|
|
7
7
|
export interface EntityFormActionsProps {
|
|
8
|
+
fullPath: string;
|
|
9
|
+
fullIdPath?: string;
|
|
8
10
|
collection: ResolvedEntityCollection;
|
|
9
11
|
path: string;
|
|
10
12
|
entity?: Entity;
|
|
@@ -19,6 +21,8 @@ export interface EntityFormActionsProps {
|
|
|
19
21
|
}
|
|
20
22
|
|
|
21
23
|
export function EntityFormActions({
|
|
24
|
+
fullPath,
|
|
25
|
+
fullIdPath,
|
|
22
26
|
collection,
|
|
23
27
|
entity,
|
|
24
28
|
layout,
|
|
@@ -35,6 +39,8 @@ export function EntityFormActions({
|
|
|
35
39
|
|
|
36
40
|
return layout === "bottom"
|
|
37
41
|
? buildBottomActions({
|
|
42
|
+
fullPath,
|
|
43
|
+
fullIdPath,
|
|
38
44
|
savingError,
|
|
39
45
|
entity,
|
|
40
46
|
collection,
|
|
@@ -47,6 +53,8 @@ export function EntityFormActions({
|
|
|
47
53
|
openEntityMode
|
|
48
54
|
})
|
|
49
55
|
: buildSideActions({
|
|
56
|
+
fullPath,
|
|
57
|
+
fullIdPath,
|
|
50
58
|
savingError,
|
|
51
59
|
entity,
|
|
52
60
|
collection,
|
|
@@ -61,6 +69,8 @@ export function EntityFormActions({
|
|
|
61
69
|
}
|
|
62
70
|
|
|
63
71
|
type ActionsViewProps<M extends object> = {
|
|
72
|
+
fullPath: string,
|
|
73
|
+
fullIdPath?: string,
|
|
64
74
|
savingError: Error | undefined,
|
|
65
75
|
entity: Entity<M> | undefined,
|
|
66
76
|
formActions?: EntityAction[],
|
|
@@ -77,6 +87,8 @@ type ActionsViewProps<M extends object> = {
|
|
|
77
87
|
function buildBottomActions<M extends object>({
|
|
78
88
|
savingError,
|
|
79
89
|
entity,
|
|
90
|
+
fullPath,
|
|
91
|
+
fullIdPath,
|
|
80
92
|
formActions,
|
|
81
93
|
collection,
|
|
82
94
|
context,
|
|
@@ -104,7 +116,8 @@ function buildBottomActions<M extends object>({
|
|
|
104
116
|
if (entity)
|
|
105
117
|
action.onClick({
|
|
106
118
|
entity,
|
|
107
|
-
fullPath: collection.path,
|
|
119
|
+
fullPath: fullPath ?? collection.path,
|
|
120
|
+
fullIdPath: fullIdPath ?? collection.id,
|
|
108
121
|
collection: collection,
|
|
109
122
|
context,
|
|
110
123
|
sideEntityController,
|
|
@@ -215,6 +215,7 @@ export const useBuildSideEntityController = (navigation: NavigationController,
|
|
|
215
215
|
|
|
216
216
|
export function buildSidePanelsFromUrl(path: string, collections: EntityCollection[], newFlag: boolean): EntitySidePanelProps<any>[] {
|
|
217
217
|
|
|
218
|
+
|
|
218
219
|
const navigationViewsForPath: NavigationViewInternal<any>[] = getNavigationEntriesFromPath({
|
|
219
220
|
path,
|
|
220
221
|
collections
|
|
@@ -222,18 +223,20 @@ export function buildSidePanelsFromUrl(path: string, collections: EntityCollecti
|
|
|
222
223
|
|
|
223
224
|
let sidePanel: EntitySidePanelProps<any> | undefined = undefined;
|
|
224
225
|
let lastCollectionPath = "";
|
|
226
|
+
let lastCollectionId: string | undefined = undefined;
|
|
225
227
|
for (let i = 0; i < navigationViewsForPath.length; i++) {
|
|
226
228
|
const navigationEntry = navigationViewsForPath[i];
|
|
227
229
|
|
|
228
230
|
if (navigationEntry.type === "collection") {
|
|
229
231
|
lastCollectionPath = navigationEntry.path;
|
|
232
|
+
lastCollectionId = navigationEntry.collection.id;
|
|
230
233
|
}
|
|
231
234
|
|
|
232
235
|
const previousEntry = navigationViewsForPath[i - 1];
|
|
233
236
|
if (navigationEntry.type === "entity") {
|
|
234
237
|
sidePanel = {
|
|
235
238
|
path: navigationEntry.path,
|
|
236
|
-
|
|
239
|
+
fullIdPath: navigationEntry.fullIdPath,
|
|
237
240
|
entityId: navigationEntry.entityId,
|
|
238
241
|
copy: false,
|
|
239
242
|
width: navigationEntry.parentCollection?.sideDialogWidth
|
|
@@ -255,7 +258,7 @@ export function buildSidePanelsFromUrl(path: string, collections: EntityCollecti
|
|
|
255
258
|
if (newFlag) {
|
|
256
259
|
sidePanel = {
|
|
257
260
|
path: lastCollectionPath,
|
|
258
|
-
|
|
261
|
+
fullIdPath: lastCollectionId,
|
|
259
262
|
copy: false
|
|
260
263
|
}
|
|
261
264
|
}
|
|
@@ -273,7 +276,7 @@ const propsToSidePanel = (props: EntitySidePanelProps,
|
|
|
273
276
|
|
|
274
277
|
const collectionPath = removeInitialAndTrailingSlashes(props.path);
|
|
275
278
|
|
|
276
|
-
const
|
|
279
|
+
const urlPath = props.entityId
|
|
277
280
|
? buildUrlCollectionPath(`${collectionPath}/${props.entityId}${props.selectedTab ? "/" + props.selectedTab : ""}#${SIDE_URL_HASH}`)
|
|
278
281
|
: buildUrlCollectionPath(`${collectionPath}#${NEW_URL_HASH}`);
|
|
279
282
|
|
|
@@ -286,7 +289,7 @@ const propsToSidePanel = (props: EntitySidePanelProps,
|
|
|
286
289
|
return {
|
|
287
290
|
key: `${props.path}/${props.entityId}`,
|
|
288
291
|
component: <EntitySidePanel {...resolvedPanelProps}/>,
|
|
289
|
-
urlPath:
|
|
292
|
+
urlPath: urlPath,
|
|
290
293
|
parentUrlPath: buildUrlCollectionPath(collectionPath),
|
|
291
294
|
width: entityViewWidth,
|
|
292
295
|
onClose: props.onClose,
|
|
@@ -79,7 +79,8 @@ export function FireCMSRoute() {
|
|
|
79
79
|
key={`collection_view_${collection.id ?? collection.path}`}
|
|
80
80
|
isSubCollection={false}
|
|
81
81
|
parentCollectionIds={[]}
|
|
82
|
-
fullPath={collection.
|
|
82
|
+
fullPath={collection.path}
|
|
83
|
+
fullIdPath={collection.id}
|
|
83
84
|
updateUrl={true}
|
|
84
85
|
{...collection}
|
|
85
86
|
Actions={toArray(collection.Actions)}/>
|
|
@@ -100,7 +101,7 @@ export function FireCMSRoute() {
|
|
|
100
101
|
fullIdPath={collection.id}
|
|
101
102
|
isSubCollection={false}
|
|
102
103
|
parentCollectionIds={[]}
|
|
103
|
-
fullPath={collection.
|
|
104
|
+
fullPath={collection.path}
|
|
104
105
|
updateUrl={true}
|
|
105
106
|
{...collection}
|
|
106
107
|
Actions={toArray(collection.Actions)}/>;
|
|
@@ -200,7 +201,6 @@ function EntityFullScreenRoute({
|
|
|
200
201
|
const collection = isNew ? lastCollectionEntry!.collection : lastEntityEntry!.parentCollection;
|
|
201
202
|
const fullIdPath = isNew ? lastCollectionEntry!.path : lastEntityEntry!.path;
|
|
202
203
|
const collectionPath = navigation.resolveIdsFrom(fullIdPath);
|
|
203
|
-
|
|
204
204
|
return <>
|
|
205
205
|
<EntityEditView
|
|
206
206
|
key={collection.id + "_" + (isNew ? "new" : (isCopy ? entityId + "_copy" : entityId))}
|
|
@@ -54,6 +54,7 @@ export type EntityActionClickProps<M extends object, USER extends User = User> =
|
|
|
54
54
|
entity: Entity<M>;
|
|
55
55
|
context: FireCMSContext<USER>;
|
|
56
56
|
fullPath?: string;
|
|
57
|
+
fullIdPath?: string;
|
|
57
58
|
collection?: EntityCollection<M>;
|
|
58
59
|
selectionController?: SelectionController;
|
|
59
60
|
highlightEntity?: (entity: Entity<any>) => void;
|
|
@@ -15,6 +15,11 @@ export interface EntitySidePanelProps<M extends Record<string, any> = any> {
|
|
|
15
15
|
*/
|
|
16
16
|
path: string;
|
|
17
17
|
|
|
18
|
+
/**
|
|
19
|
+
* Full CMS path of the entity, including the collection and sub-collections.
|
|
20
|
+
*/
|
|
21
|
+
fullIdPath?: string;
|
|
22
|
+
|
|
18
23
|
/**
|
|
19
24
|
* ID of the entity, if not set, it means we are creating a new entity
|
|
20
25
|
*/
|
|
@@ -11,6 +11,7 @@ export interface NavigationViewEntityInternal<M extends Record<string, any>> {
|
|
|
11
11
|
type: "entity";
|
|
12
12
|
entityId: string;
|
|
13
13
|
path: string;
|
|
14
|
+
fullIdPath: string;
|
|
14
15
|
fullPath: string;
|
|
15
16
|
parentCollection: EntityCollection<M>;
|
|
16
17
|
}
|
|
@@ -19,6 +20,7 @@ export interface NavigationViewCollectionInternal<M extends Record<string, any>>
|
|
|
19
20
|
type: "collection";
|
|
20
21
|
id: string;
|
|
21
22
|
path: string;
|
|
23
|
+
fullIdPath: string;
|
|
22
24
|
fullPath: string;
|
|
23
25
|
collection: EntityCollection<M>;
|
|
24
26
|
}
|
|
@@ -26,6 +28,7 @@ export interface NavigationViewCollectionInternal<M extends Record<string, any>>
|
|
|
26
28
|
export interface NavigationViewEntityCustomInternal<M extends Record<string, any>> {
|
|
27
29
|
type: "custom_view";
|
|
28
30
|
path: string;
|
|
31
|
+
fullIdPath: string;
|
|
29
32
|
fullPath: string;
|
|
30
33
|
entityId: string;
|
|
31
34
|
view: EntityCustomView<M>;
|
|
@@ -35,13 +38,15 @@ export function getNavigationEntriesFromPath(props: {
|
|
|
35
38
|
path: string,
|
|
36
39
|
collections: EntityCollection[] | undefined,
|
|
37
40
|
currentFullPath?: string,
|
|
41
|
+
currentFullIdPath?: string,
|
|
38
42
|
contextEntityViews?: EntityCustomView<any>[]
|
|
39
43
|
}): NavigationViewInternal [] {
|
|
40
44
|
|
|
41
45
|
const {
|
|
42
46
|
path,
|
|
43
47
|
collections = [],
|
|
44
|
-
currentFullPath
|
|
48
|
+
currentFullPath,
|
|
49
|
+
currentFullIdPath
|
|
45
50
|
} = props;
|
|
46
51
|
|
|
47
52
|
const subpaths = removeInitialAndTrailingSlashes(path).split("/");
|
|
@@ -58,16 +63,18 @@ export function getNavigationEntriesFromPath(props: {
|
|
|
58
63
|
}
|
|
59
64
|
|
|
60
65
|
if (collection) {
|
|
61
|
-
const pathOrAlias = collection.id ?? collection.path;
|
|
62
66
|
const collectionPath = currentFullPath && currentFullPath.length > 0
|
|
63
|
-
? (currentFullPath + "/" +
|
|
64
|
-
:
|
|
65
|
-
|
|
67
|
+
? (currentFullPath + "/" + collection.path)
|
|
68
|
+
: collection.path;
|
|
69
|
+
const fullIdPath = currentFullIdPath && currentFullIdPath.length > 0
|
|
70
|
+
? (currentFullIdPath + "/" + collection.id)
|
|
71
|
+
: collection.id;
|
|
66
72
|
result.push({
|
|
67
73
|
type: "collection",
|
|
68
74
|
id: collection.id,
|
|
69
75
|
path: collectionPath,
|
|
70
76
|
fullPath: collectionPath,
|
|
77
|
+
fullIdPath,
|
|
71
78
|
collection
|
|
72
79
|
});
|
|
73
80
|
const restOfThePath = removeInitialAndTrailingSlashes(removeInitialAndTrailingSlashes(path).replace(subpathCombination, ""));
|
|
@@ -79,6 +86,7 @@ export function getNavigationEntriesFromPath(props: {
|
|
|
79
86
|
type: "entity",
|
|
80
87
|
entityId,
|
|
81
88
|
path: collectionPath,
|
|
89
|
+
fullIdPath,
|
|
82
90
|
fullPath: fullPath,
|
|
83
91
|
parentCollection: collection
|
|
84
92
|
});
|
|
@@ -97,6 +105,7 @@ export function getNavigationEntriesFromPath(props: {
|
|
|
97
105
|
type: "custom_view",
|
|
98
106
|
path: collectionPath,
|
|
99
107
|
entityId: entityId,
|
|
108
|
+
fullIdPath,
|
|
100
109
|
fullPath: fullPath + "/" + customView.key,
|
|
101
110
|
view: customView
|
|
102
111
|
});
|
|
@@ -105,6 +114,7 @@ export function getNavigationEntriesFromPath(props: {
|
|
|
105
114
|
path: newPath,
|
|
106
115
|
collections: collection.subcollections,
|
|
107
116
|
currentFullPath: fullPath,
|
|
117
|
+
currentFullIdPath: fullIdPath,
|
|
108
118
|
contextEntityViews: props.contextEntityViews
|
|
109
119
|
}));
|
|
110
120
|
}
|