feat: meta-type presets and TodoList system database#10
Conversation
Add new meta type presets for 'Bookmark', 'Project', 'Issue', 'Repo', 'Team', 'Events', and 'People' to enhance workspace initialization. Update the `ensurePageMetaTypes` function to seed these schemas when missing, ensuring a more comprehensive setup for new workspaces. Enhance related tests to verify the creation of these presets during workspace setup.
…itialization Introduce a new built-in system meta type 'TodoList' with fields for task management, including 'Status', 'Priority', 'Due Date', 'Assignee', 'Estimate', and 'Labels'. Update the `ensurePageMetaTypes` function to seed this schema during workspace initialization. Enhance related tests to verify the creation and properties of the 'TodoList' meta type, ensuring a comprehensive setup for new workspaces.
…ate initialization logic Eliminate the 'TodoList' system meta type from the initialization process, ensuring it is no longer created as part of the default meta types. Update the `ensurePageMetaTypes` function to reflect this change and adjust related tests accordingly. This refactor streamlines the workspace setup by focusing on essential meta types and their configurations.
Introduce a new link for the TodoList in the sidebar settings, allowing users to navigate to the TodoList settings page. Update the routing configuration to include the TodoList route and its corresponding mask, ensuring proper navigation and context handling for user workspaces. This enhancement improves the user experience by providing direct access to task management features.
…paceTodoListContainer Refactor the todo list settings route by removing the database query logic for fetching the TodoList ID and replacing it with the WorkspaceTodoListContainer component. This change simplifies the routing logic and enhances the user interface by directly integrating the container for better task management experience.
…atabase management Add new features to the todo list system, including the ability to build and manage missing views, upgrade the todo list database, and ensure proper field configurations. Refactor the todo list database creation logic to improve integration with workspace collections. Update tests to validate the new functionality and ensure comprehensive coverage of the todo list features.
Refactor the todo list system by renaming fields for clarity, introducing a new size field, and updating the sidebar menu to include a direct link to the todo list settings. Enhance the routing logic to support navigation to the new todo list modal, improving user experience and accessibility of task management features. Update tests to reflect these changes and ensure comprehensive coverage.
…sidebar improvements Add 'Created' and 'Updated' fields to the todo list system, improving task management capabilities. Refactor sidebar components to support navigation to the todo list settings and enhance user experience. Update related tests to ensure comprehensive coverage of the new features and functionality.
…ement, and sidebar improvements Introduce new functionalities to the todo list system, including the addition of 'Tags' and 'Assignees' fields, and improvements to view management with default settings for list views. Refactor sidebar components for better navigation to the todo list settings. Update tests to ensure comprehensive coverage of the new features and maintain functionality.
…list management Add functionality to ensure a reminders relation field in the todo list system, improving task management capabilities. Refactor the todo list database creation and upgrade processes to include this new field. Update tests to validate the integration of reminders and ensure comprehensive coverage of the new features.
… due reminder components Modify the layout of the RecordAttributes component to improve visual consistency by reducing the width of the field label. In the TodoListDueReminder component, enhance the logic to check for target dates before displaying due reminders, ensuring a clearer user experience. Update the workspace detail panel to include a button for clearing task selections, improving task management functionality.
…nd improved styling Add functionality to open record modals in ListViewCollectionRow and ListViewRecordRow components, enhancing user interaction with task details. Refactor button elements for better accessibility and visual consistency, including hover effects and layout adjustments. Update ListViewQuickCreate to focus on input when triggered, improving user experience. Adjust styling across components for a more cohesive design.
Refactor the ListViewCollectionRow and ListViewRecordRow components to simplify the modal navigation logic. Consolidate the conditions for opening records and improve the clarity of the code by removing redundant navigation calls. This change enhances the user experience by ensuring a more intuitive interaction with task details.
Drop the todo-list modal child route now that list view uses the right-side detail panel exclusively. Add due reminder edit/delete, keyboard task navigation, and clearer Detail affordances. Co-authored-by: Cursor <cursoragent@cursor.com>
There was a problem hiding this comment.
Code Review
This pull request introduces a built-in TodoList system database along with several starter meta-type presets (such as Bookmark, Project, and Issue) to enhance workspace initialization. It also integrates the TodoList into the UI sidebar, settings, and navigation, and adds a due date reminder feature. The review feedback highlights opportunities to improve performance by avoiding sequential awaits in a loop, prevent potential runtime errors by adding defensive checks for undefined fields, support both string and date types for target dates, and avoid unnecessary re-renders by defining a stable fallback object outside of the component.
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.
| .where('parent_id', '=', databaseId) | ||
| .execute(); | ||
|
|
||
| for (const row of records) { |
There was a problem hiding this comment.
| await workspace.nodes.updateNode(row.id, (draft) => { | ||
| if (draft.type !== 'record') { | ||
| return draft; | ||
| } | ||
|
|
||
| delete draft.fields[TODO_LIST_FIELD_IDS.assignee]; | ||
| return draft; | ||
| }); |
There was a problem hiding this comment.
To prevent potential runtime errors, add a defensive check to ensure draft.fields is defined before attempting to delete properties from it.
await workspace.nodes.updateNode(row.id, (draft) => {
if (draft.type !== 'record') {
return draft;
}
if (draft.fields) {
delete draft.fields[TODO_LIST_FIELD_IDS.assignee];
}
return draft;
});| await workspace.nodes.updateNode(row.id, (draft) => { | ||
| if (draft.type !== 'record') { | ||
| return draft; | ||
| } | ||
|
|
||
| if (matchedUserId) { | ||
| draft.fields[TODO_LIST_FIELD_IDS.assignee] = { | ||
| type: 'string_array', | ||
| value: [matchedUserId], | ||
| }; | ||
| } else { | ||
| delete draft.fields[TODO_LIST_FIELD_IDS.assignee]; | ||
| } | ||
|
|
||
| return draft; | ||
| }); |
There was a problem hiding this comment.
Add a defensive check to ensure draft.fields is initialized before setting or deleting properties on it.
await workspace.nodes.updateNode(row.id, (draft) => {
if (draft.type !== 'record') {
return draft;
}
if (!draft.fields) {
draft.fields = {};
}
if (matchedUserId) {
draft.fields[TODO_LIST_FIELD_IDS.assignee] = {
type: 'string_array',
value: [matchedUserId],
};
} else {
delete draft.fields[TODO_LIST_FIELD_IDS.assignee];
}
return draft;
});| const hasTargetDate = (record: LocalRecordNode): boolean => { | ||
| const value = record.fields[TODO_LIST_FIELD_IDS.targetDate]; | ||
| return Boolean( | ||
| value && | ||
| value.type === 'string' && | ||
| typeof value.value === 'string' && | ||
| value.value.length > 0 | ||
| ); | ||
| }; |
There was a problem hiding this comment.
The hasTargetDate check strictly requires value.type === 'string'. However, for a date field, the value type might be 'date' or 'string'. Relaxing this check to support both 'string' and 'date' types ensures the due date reminder can be enabled correctly.
| const hasTargetDate = (record: LocalRecordNode): boolean => { | |
| const value = record.fields[TODO_LIST_FIELD_IDS.targetDate]; | |
| return Boolean( | |
| value && | |
| value.type === 'string' && | |
| typeof value.value === 'string' && | |
| value.value.length > 0 | |
| ); | |
| }; | |
| const hasTargetDate = (record: LocalRecordNode): boolean => { | |
| const value = record.fields[TODO_LIST_FIELD_IDS.targetDate]; | |
| return Boolean( | |
| value && | |
| (value.type === 'string' || value.type === 'date') && | |
| typeof value.value === 'string' && | |
| value.value.length > 0 | |
| ); | |
| }; |
| const { value, setValue } = useRecordField({ | ||
| field: | ||
| remindersField?.type === 'relation' | ||
| ? remindersField | ||
| : { | ||
| id: REMINDERS_RELATION_FIELD_ID, | ||
| type: 'relation', | ||
| name: 'Reminders', | ||
| index: 'z', | ||
| databaseId: '', | ||
| }, | ||
| }); |
There was a problem hiding this comment.
Passing an inline fallback object to useRecordField causes a new object reference to be created on every render. If useRecordField has field in its dependency array, this will trigger unnecessary effect re-runs and re-renders. Define the fallback object as a stable constant outside the component instead (e.g., const FALLBACK_REMINDERS_FIELD = { id: REMINDERS_RELATION_FIELD_ID, type: 'relation' as const, name: 'Reminders', index: 'z', databaseId: '' };).
const { value, setValue } = useRecordField({
field:
remindersField?.type === 'relation'
? remindersField
: FALLBACK_REMINDERS_FIELD,
});
Pass typed LocalRecordNode and LocalDatabaseNode into due reminder props instead of context types, and align edit permission checks with record ownership. Co-authored-by: Cursor <cursoragent@cursor.com>
Summary
systemKind: todo_list).Esc,↑/↓), and editable due reminders.Test plan
↑/↓switches tasks;Esccloses panelnpm run testinpackages/client(todo-list-system tests)LOCAL_ONLY=true npm run packageand smoke-testMade with Cursor