@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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@firecms/core",
3
3
  "type": "module",
4
- "version": "3.0.0-canary.225",
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.225",
54
- "@firecms/formex": "^3.0.0-canary.225",
55
- "@firecms/ui": "^3.0.0-canary.225",
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": "e16b0ebd1efe8103cdc036b7ffda2c90eb813118",
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 [measureRef, bounds] = useMeasure();
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 ? entity.path : (fullPath ?? entity.path);
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
- const path = collection?.collectionGroup ? entity.path : (fullPath ?? entity.path)
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(`resolveCollectionPathAliases: Collection paths must have an odd number of segments: ${path}`);
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
- const aliasedCollection = allCollections.find((col) => col.id === subpaths[0]);
43
- let resolvedAliased;
44
- if (aliasedCollection) {
45
- resolvedAliased = aliasedCollection.path;
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
- if (subpaths.length > 1) {
49
- const segmentCollection = getCollectionByPathOrId(resolvedAliased ?? subpaths[0], allCollections);
50
- if (!segmentCollection?.subcollections) {
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
- const restOfThePath = cleanPath.split("/").slice(2).join("/");
54
- return (resolvedAliased ?? subpaths[0]) + "/" + subpaths[1] + "/" + resolveCollectionPathIds(restOfThePath, segmentCollection.subcollections);
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.