Polish File Meta Types UX and defer heavy web bundles#12
Conversation
Improve file meta type views (gallery thumbnails, relations, calendar upload, folder picker), fix meta types navigation and editor mount timing, and lazy-load large UI chunks to shrink the web entry bundle. Co-authored-by: Cursor <cursoragent@cursor.com>
There was a problem hiding this comment.
Code Review
This pull request introduces File Meta Types (MVP + Phase 2), generalizing the meta-type system to support both pages and files across database views (board, calendar, gallery, list, and table). It also implements performance optimizations, such as lazy loading key layout and editor components, and optimizing syntax highlighting imports in lowlight. Additionally, a new folder picker utility (buildFolderPickerOptions) is added to resolve nested folder paths. Feedback on the changes highlights a potential infinite loop in the folder path traversal logic if cyclic folder references exist, and suggests implementing a cycle detector using a Set along with corresponding unit tests to ensure robustness.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
| const buildPath = (folder: LocalFolderNode): string => { | ||
| const parts = [folder.name]; | ||
| let current = folder; | ||
|
|
||
| while (current.parentId !== spaceId) { | ||
| const parent = byId.get(current.parentId); | ||
| if (!parent) { | ||
| break; | ||
| } | ||
|
|
||
| parts.unshift(parent.name); | ||
| current = parent; | ||
| } | ||
|
|
||
| return parts.join(' / '); | ||
| }; |
There was a problem hiding this comment.
The while loop resolves folder paths by traversing parent folders. If there is a cyclic reference in the folder structure (e.g., Folder A's parent is Folder B, and Folder B's parent is Folder A), this loop will run infinitely, freezing the browser tab. Implementing a cycle detector using a Set prevents this infinite loop and ensures robust execution.
const buildPath = (folder: LocalFolderNode): string => {
const parts = [folder.name];
let current = folder;
const visited = new Set<string>([folder.id]);
while (current.parentId !== spaceId) {
if (visited.has(current.parentId)) {
break;
}
visited.add(current.parentId);
const parent = byId.get(current.parentId);
if (!parent) {
break;
}
parts.unshift(parent.name);
current = parent;
}
return parts.join(' / ');
};| describe('buildFolderPickerOptions', () => { | ||
| it('builds nested folder paths within a space', () => { | ||
| const folders = [ | ||
| baseFolder({ id: 'folder-a', name: 'Assets', parentId: 'space-1' }), | ||
| baseFolder({ id: 'folder-b', name: 'Contracts', parentId: 'folder-a' }), | ||
| ]; | ||
|
|
||
| expect(buildFolderPickerOptions(folders, 'space-1')).toEqual([ | ||
| { id: 'folder-a', label: 'Assets' }, | ||
| { id: 'folder-b', label: 'Assets / Contracts' }, | ||
| ]); | ||
| }); | ||
| }); |
There was a problem hiding this comment.
Add a test case to verify that cyclic folder references are handled gracefully without causing infinite loops, ensuring the robustness of the cycle-safe path building logic.
describe('buildFolderPickerOptions', () => {
it('builds nested folder paths within a space', () => {
const folders = [
baseFolder({ id: 'folder-a', name: 'Assets', parentId: 'space-1' }),
baseFolder({ id: 'folder-b', name: 'Contracts', parentId: 'folder-a' }),
];
expect(buildFolderPickerOptions(folders, 'space-1')).toEqual([
{ id: 'folder-a', label: 'Assets' },
{ id: 'folder-b', label: 'Assets / Contracts' },
]);
});
it('handles cyclic folder references gracefully without infinite loops', () => {
const folders = [
baseFolder({ id: 'folder-a', name: 'Folder A', parentId: 'folder-b' }),
baseFolder({ id: 'folder-b', name: 'Folder B', parentId: 'folder-a' }),
];
expect(buildFolderPickerOptions(folders, 'space-1')).toEqual([
{ id: 'folder-a', label: 'Folder A' },
{ id: 'folder-b', label: 'Folder B' },
]);
});
});
Summary
docs/file-meta-types.mdanddocs/roadmap.md.Test plan
npm run buildpackages/uitests (49 passed)make:local)Made with Cursor