@firecms/core 3.0.0-canary.225 → 3.0.0-canary.227
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 +63 -17
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +63 -17
- package/dist/index.umd.js.map +1 -1
- package/package.json +5 -5
- package/src/components/EntityCollectionView/EntityCollectionView.tsx +1 -1
- package/src/components/VirtualTable/VirtualTable.tsx +29 -1
- package/src/components/common/default_entity_actions.tsx +3 -2
- package/src/util/navigation_utils.ts +59 -14
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.227",
|
|
5
5
|
"description": "Awesome Firebase/Firestore-based headless open-source CMS",
|
|
6
6
|
"funding": {
|
|
7
7
|
"url": "https://github.com/sponsors/firecmsco"
|
|
@@ -50,9 +50,9 @@
|
|
|
50
50
|
"./package.json": "./package.json"
|
|
51
51
|
},
|
|
52
52
|
"dependencies": {
|
|
53
|
-
"@firecms/editor": "^3.0.0-canary.
|
|
54
|
-
"@firecms/formex": "^3.0.0-canary.
|
|
55
|
-
"@firecms/ui": "^3.0.0-canary.
|
|
53
|
+
"@firecms/editor": "^3.0.0-canary.227",
|
|
54
|
+
"@firecms/formex": "^3.0.0-canary.227",
|
|
55
|
+
"@firecms/ui": "^3.0.0-canary.227",
|
|
56
56
|
"@hello-pangea/dnd": "^17.0.0",
|
|
57
57
|
"@radix-ui/react-portal": "^1.1.3",
|
|
58
58
|
"clsx": "^2.1.1",
|
|
@@ -105,7 +105,7 @@
|
|
|
105
105
|
"dist",
|
|
106
106
|
"src"
|
|
107
107
|
],
|
|
108
|
-
"gitHead": "
|
|
108
|
+
"gitHead": "7bd583a9a6d3edb89a5872aebd2c358bff4f1b09",
|
|
109
109
|
"publishConfig": {
|
|
110
110
|
"access": "public"
|
|
111
111
|
},
|
|
@@ -147,9 +147,9 @@ export const EntityCollectionView = React.memo(
|
|
|
147
147
|
) {
|
|
148
148
|
|
|
149
149
|
const context = useFireCMSContext();
|
|
150
|
+
const navigation = useNavigationController();
|
|
150
151
|
const fullPath = fullPathProp ?? collectionProp.path;
|
|
151
152
|
const dataSource = useDataSource(collectionProp);
|
|
152
|
-
const navigation = useNavigationController();
|
|
153
153
|
const sideEntityController = useSideEntityController();
|
|
154
154
|
const authController = useAuthController();
|
|
155
155
|
const userConfigPersistence = useUserConfigurationPersistence();
|
|
@@ -139,7 +139,35 @@ export const VirtualTable = React.memo<VirtualTableProps<any>>(
|
|
|
139
139
|
setColumns(columnsProp);
|
|
140
140
|
}, [columnsProp]);
|
|
141
141
|
|
|
142
|
-
const [
|
|
142
|
+
const [_, setForceUpdate] = useState(false);
|
|
143
|
+
useEffect(() => {
|
|
144
|
+
// Create a ResizeObserver to detect size changes more aggressively
|
|
145
|
+
if (tableRef.current) {
|
|
146
|
+
const resizeObserver = new ResizeObserver(() => {
|
|
147
|
+
// Force a re-render when size changes
|
|
148
|
+
setForceUpdate(prev => !prev);
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
resizeObserver.observe(tableRef.current);
|
|
152
|
+
|
|
153
|
+
return () => {
|
|
154
|
+
if (tableRef.current) {
|
|
155
|
+
resizeObserver.unobserve(tableRef.current);
|
|
156
|
+
}
|
|
157
|
+
resizeObserver.disconnect();
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
return () => {
|
|
161
|
+
}
|
|
162
|
+
}, [tableRef]);
|
|
163
|
+
|
|
164
|
+
const [measureRef, bounds] = useMeasure({
|
|
165
|
+
debounce: 50,
|
|
166
|
+
polyfill: ResizeObserver,
|
|
167
|
+
scroll: true,
|
|
168
|
+
// This is important for handling zooming in react-flow
|
|
169
|
+
offsetSize: true
|
|
170
|
+
});
|
|
143
171
|
|
|
144
172
|
const onColumnResizeInternal = useCallback((params: OnVirtualTableColumnResizeParams) => {
|
|
145
173
|
if (debug)
|
|
@@ -30,7 +30,7 @@ export const editEntityAction: EntityAction = {
|
|
|
30
30
|
addRecentId(collection.id, entity.id);
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
-
const path = collection?.collectionGroup ?
|
|
33
|
+
const path = collection?.collectionGroup ? collection.id : (fullPath ?? collection?.id ?? entity.path);
|
|
34
34
|
const defaultSelectedView = resolveDefaultSelectedView(
|
|
35
35
|
collection ? collection.defaultSelectedView : undefined,
|
|
36
36
|
{
|
|
@@ -71,7 +71,8 @@ export const copyEntityAction: EntityAction = {
|
|
|
71
71
|
path: entity.path,
|
|
72
72
|
entityId: entity.id
|
|
73
73
|
});
|
|
74
|
-
|
|
74
|
+
|
|
75
|
+
const path = collection?.collectionGroup ? collection.id : (fullPath ?? collection?.id ?? entity.path);
|
|
75
76
|
navigateToEntity({
|
|
76
77
|
openEntityMode,
|
|
77
78
|
collection,
|
|
@@ -32,31 +32,76 @@ export function getLastSegment(path: string) {
|
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
export function resolveCollectionPathIds(path: string, allCollections: EntityCollection[]): string {
|
|
35
|
-
|
|
36
35
|
const cleanPath = removeInitialAndTrailingSlashes(path);
|
|
37
36
|
const subpaths = cleanPath.split("/");
|
|
37
|
+
|
|
38
38
|
if (subpaths.length % 2 === 0) {
|
|
39
|
-
throw Error(`
|
|
39
|
+
throw Error(`resolveCollectionPathIds: Collection paths must have an odd number of segments: ${path}`);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Check if the path exactly matches a collection path
|
|
43
|
+
const exactMatch = allCollections.find(col => col.path === cleanPath);
|
|
44
|
+
if (exactMatch) {
|
|
45
|
+
return exactMatch.path;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
if (subpaths.length === 1) {
|
|
49
|
+
// Find collection by ID and return its path
|
|
50
|
+
const aliasedCollection = allCollections.find((col) => col.id === subpaths[0]);
|
|
51
|
+
return aliasedCollection?.path ?? subpaths[0];
|
|
40
52
|
}
|
|
41
53
|
|
|
42
|
-
|
|
43
|
-
let
|
|
44
|
-
|
|
45
|
-
|
|
54
|
+
// Try to match a multi-segment collection path
|
|
55
|
+
let matchingCollection: EntityCollection | undefined;
|
|
56
|
+
let entityIndex = 1;
|
|
57
|
+
|
|
58
|
+
// Check if the path starts with a multi-segment collection path
|
|
59
|
+
for (const collection of allCollections) {
|
|
60
|
+
const pathSegments = collection.path.split("/");
|
|
61
|
+
if (pathSegments.length > 1 &&
|
|
62
|
+
subpaths.slice(0, pathSegments.length).join("/") === collection.path) {
|
|
63
|
+
matchingCollection = collection;
|
|
64
|
+
entityIndex = pathSegments.length;
|
|
65
|
+
break;
|
|
66
|
+
}
|
|
46
67
|
}
|
|
47
68
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
69
|
+
// If no multi-segment match, fall back to single segment matching
|
|
70
|
+
if (!matchingCollection) {
|
|
71
|
+
const matchingCollections = allCollections.filter(col =>
|
|
72
|
+
col.id === subpaths[0] || col.path === subpaths[0]
|
|
73
|
+
);
|
|
74
|
+
|
|
75
|
+
if (!matchingCollections.length) {
|
|
51
76
|
return cleanPath;
|
|
52
77
|
}
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
} else {
|
|
56
|
-
return resolvedAliased ?? cleanPath;
|
|
78
|
+
|
|
79
|
+
matchingCollection = matchingCollections[0];
|
|
57
80
|
}
|
|
58
|
-
}
|
|
59
81
|
|
|
82
|
+
const entityId = subpaths[entityIndex];
|
|
83
|
+
const remainingPath = subpaths.slice(entityIndex + 1);
|
|
84
|
+
|
|
85
|
+
// If we have a subcollection ID, try to resolve it
|
|
86
|
+
if (remainingPath.length > 0) {
|
|
87
|
+
const subcollectionId = remainingPath[0];
|
|
88
|
+
const subcollection = matchingCollection.subcollections?.find(
|
|
89
|
+
subcol => subcol.id === subcollectionId
|
|
90
|
+
);
|
|
91
|
+
|
|
92
|
+
if (subcollection) {
|
|
93
|
+
return `${matchingCollection.path}/${entityId}/${subcollection.path}`;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// If there are no remaining path segments, just return the collection path with entity ID
|
|
98
|
+
if (remainingPath.length === 0) {
|
|
99
|
+
return `${matchingCollection.path}/${entityId}`;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// Default case - couldn't match subcollection
|
|
103
|
+
return `${matchingCollection.path}/${entityId}/${remainingPath.join("/")}`;
|
|
104
|
+
}
|
|
60
105
|
/**
|
|
61
106
|
* Find the corresponding view at any depth for a given path.
|
|
62
107
|
* Note that path or segments of the paths can be collection aliases.
|