feat 723 : Multiple views for each board#727
Conversation
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
…to create a new board or scan for boards
…y and apply it during plugin loading
… workspace.json configs
…orrectly find out the viewType after layout is ready
….2) into the feat-723 branch
Review Summary by QodoMultiple Views Per Board with Enhanced Architecture and Date Handling Modernization
WalkthroughsDescription• **Major architectural refactor**: Transformed board structure from single board to multiple views per board, enabling users to have different Kanban and Map views within the same board • **View management system**: Added comprehensive view utilities for creating, duplicating, deleting, and reordering views with persistent state management • **Auto-scroll drag support**: Implemented configurable auto-scroll functionality during drag operations with edge detection and adjustable scroll speed • **Board persistence improvements**: Added debounced save functionality and migration system for v2.0.0 with automatic data migration on load • **Enhanced date handling**: Modernized date parsing from moment.js to date-fns, centralized date extraction functions, and improved date formatting utilities • **Improved task validation**: Added validation to prevent marking tasks complete if child/sub-tasks are incomplete, with sanitized reminder handling • **Filter system refactoring**: Refactored scanning filters to return explicit mention status and improved filter validation with comprehensive error handling • **UI enhancements**: Added new modals for view management (AddViewModal, DateTimePickerModal), boards explorer with scan functionality, and resizable views panel drawer • **Settings reorganization**: Reordered UI settings, added support for new swimlane UI types, and improved date format validation • **Translation updates**: Added comprehensive translations for multiple views, view management, swimlane configurations, and enhanced features • **Bug fixes**: Fixed diff comparison logic, checkbox validation, filter state corruption, and improved error handling throughout Diagramflowchart LR
A["Single Board<br/>Structure"] -- "Refactor to<br/>Multiple Views" --> B["Board with<br/>Views Array"]
B -- "View Management<br/>Utilities" --> C["Add/Delete/<br/>Duplicate Views"]
D["Moment.js<br/>Date Parsing"] -- "Modernize to<br/>date-fns" --> E["Improved Date<br/>Handling"]
F["Drag Operations"] -- "Add Auto-scroll<br/>Support" --> G["Enhanced UX<br/>with Scroll"]
H["Board File<br/>Manager"] -- "Add Debouncing<br/>& Migration" --> I["Persistent<br/>State v2.0.0"]
C --> J["New Modals:<br/>AddViewModal"]
E --> J
G --> J
I --> J
File Changes1. src/managers/DragDropTasksManager.ts
|
Code Review by Qodo
1. Array.contains crashes drawer
|
| item.setChecked(boardData.viewsPanel.propertiesToShow.contains(viewsPanelPropertiesToShow.Description)) | ||
| item.onClick(async () => { | ||
| if (boardData.viewsPanel.propertiesToShow.contains(viewsPanelPropertiesToShow.Description)) { | ||
| boardData.viewsPanel.propertiesToShow = boardData.viewsPanel.propertiesToShow.filter(prop => prop !== viewsPanelPropertiesToShow.Description); |
There was a problem hiding this comment.
1. Array.contains crashes drawer 🐞 Bug ≡ Correctness
TaskBoardViewContainer calls propertiesToShow.contains(...) even though propertiesToShow is a string[], so opening/rendering the views drawer will throw contains is not a function. This breaks the views drawer and can prevent the board UI from rendering correctly after the drawer is opened.
Agent Prompt
## Issue description
`boardData.viewsPanel.propertiesToShow` is a `string[]`, but the code calls `.contains(...)`, which is not a valid Array method in JS/TS. This throws at runtime when the views drawer renders.
## Issue Context
This occurs in the views drawer options menu and in the conditional rendering of view description/progress.
## Fix Focus Areas
- src/components/TaskBoardViewContainer.tsx[979-1063]
- src/interfaces/BoardConfigs.ts[188-201]
## Suggested fix
- Replace all `propertiesToShow.contains(x)` with `propertiesToShow.includes(x)`.
- (Optional) Consider normalizing `propertiesToShow` to a `Set<string>` at runtime if membership checks become frequent.
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
| const refreshView = (viewId: string) => { | ||
| setCurrentView(getViewById(boardData, viewId)!); | ||
| currentBoardData!.lastViewId = viewId; |
There was a problem hiding this comment.
2. Switch_view payload mismatch 🐞 Bug ≡ Correctness
The SWITCH_VIEW handler now treats the event payload as a viewId and calls `getViewById(boardData, viewId), but multiple emitters still send view type strings like 'map'/'kanban'`. This can set currentView to undefined and break later code paths that assume currentView is non-null.
Agent Prompt
## Issue description
`SWITCH_VIEW` is handled as though the payload is a `viewId`, but several emitters pass a view *type* (e.g., `'map'`, `'kanban'`). This can set `currentView` to `undefined` and cause runtime failures.
## Issue Context
- Listener: `setCurrentView(getViewById(boardData, viewId)!)`
- Emitters: `eventEmitter.emit('SWITCH_VIEW', viewTypeNames.map)` and similar
## Fix Focus Areas
- src/components/TaskBoardViewContainer.tsx[242-251]
- src/components/TaskBoardViewContainer.tsx[802-820]
- src/components/AddOrEditTaskRC.tsx[638-653]
- src/utils/ViewUtils.ts[25-46]
## Suggested fix
Choose one of these and apply consistently:
1) **ID-based switching**: emit `view.viewId` everywhere, and update menus/actions to look up the correct viewId to emit.
2) **Type-based switching**: rename the event to `SWITCH_VIEW_TYPE` and update the handler to resolve a view by type (e.g., via `getViewByType`) and then set both `currentViewIndex` and `currentView`.
Also add a guard in the handler:
- If the view cannot be resolved, do not update state; optionally log/report via bugReporter.
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
| const firstItemFromRegistry = Object.values(taskBoardFilesRegistry)[0]; | ||
|
|
||
| if (!firstItemFromRegistry?.filePath) { | ||
| if (!firstItemFromRegistry.filePath) { | ||
| console.error( |
There was a problem hiding this comment.
3. Empty registry dereference 🐞 Bug ☼ Reliability
TaskBoardFileManager.getLastOpenedBoard assumes there is at least one registry entry and dereferences firstItemFromRegistry.filePath without checking firstItemFromRegistry exists. If the registry is empty (fresh install or after registry cleanup), this will throw and prevent TaskBoardView from loading.
Agent Prompt
## Issue description
`getLastOpenedBoard()` can throw when `taskBoardFilesRegistry` is empty because it dereferences `firstItemFromRegistry.filePath` without checking `firstItemFromRegistry`.
## Issue Context
This path is hit from `TaskBoardView.setState()` when there is no `filePath` in the view state.
## Fix Focus Areas
- src/managers/TaskBoardFileManager.ts[671-713]
- src/obsidian_views/TaskBoardView.tsx[157-203]
## Suggested fix
- Add an early return:
- If `Object.keys(taskBoardFilesRegistry).length === 0`, return `undefined`.
- Or check `if (!firstItemFromRegistry || !firstItemFromRegistry.filePath)` before accessing `filePath`.
- Keep the error log, but avoid throwing and let `TaskBoardView` fall back to `renderNoBoard()`.
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
This is a part of the feature #698 . Both this and the PR 698 will be combined together and will be released in the next major version
2.0.0.Will mostly going to release this branch with the PR 698 if everything goes well. Otherwise, as a fallback plan, PR 698 is the only feature which will be available in the major release.
This PR will going to successfully implement all the features and functionalities discussed in the following tickets :
.taskboardfile #723