-
Couldn't load subscription status.
- Fork 54
Fix/953 subtasks incorrectly identified as task notes #955
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Fix/953 subtasks incorrectly identified as task notes #955
Conversation
…alpass#953) Add missing isTaskFile() validation to getTaskInfo() method to ensure only files meeting task identification criteria return TaskInfo objects. Root Cause: - getTaskInfo() was returning TaskInfo for ANY file with frontmatter - Missing validation check that was present in getCachedTaskInfoSync() - Bug existed since MinimalNativeCache creation (commit 96a3f15) Changes: - Add isTaskFile() check to MinimalNativeCache.getTaskInfo() - Create comprehensive test suite for task identification validation - Ensure consistency between async and sync task info methods Impact: - Notes with Parent/project properties but no task tag/property no longer appear as subtasks - Fixes incorrect subtask display reported in issue callumalpass#953 - No breaking changes - only corrects invalid behavior Testing: - Added 13 test cases covering tag-based, property-based, and edge cases - Issue callumalpass#953 specific scenarios verified passing
…ass#953) Fix project index not updating when task tags are removed from notes. Root Cause: - MinimalNativeCache early-exited for non-task files, preventing "file-updated" event from firing when a file stopped being a task - ProjectSubtasksService had no event listeners to invalidate index on metadata changes, relying only on 30-second TTL Changes: - Add initialize() method to ProjectSubtasksService with event listeners for file-updated, file-deleted, and file-renamed events - Track files that were previously tasks in handleFileChangedDebounced() to ensure events fire when files transition from task to non-task - Clean up cached data (lastKnownTaskInfo, lastKnownFrontmatter) when files stop being tasks - Call projectSubtasksService.initialize() in main.ts during startup Impact: - Chevron state now updates instantly when task tags are added/removed - No need to wait 30 seconds or restart Obsidian for changes to reflect - Project index invalidates immediately on any metadata change Files Modified: - src/services/ProjectSubtasksService.ts (initialize, invalidateIndex) - src/utils/MinimalNativeCache.ts (handleFileChangedDebounced, handleFileChanged) - src/main.ts (initialization call)
Fix test failures in GitHub Actions by properly mocking TFile and dependencies. Root Cause: - mockFile wasn't passing instanceof TFile check (plain object) - mockFieldMapper missing storeTitleInFilename parameter - mockApp.metadataCache missing getFirstLinkpathDest method Changes: - Create mockFile using Object.create(TFile.prototype) with Object.defineProperty - Add storeTitleInFilename parameter to mockFieldMapper.mapFromFrontmatter - Add getFirstLinkpathDest method to mockApp.metadataCache Test Results: - All 13 tests passing locally - No changes to production code - only test fixes
…allumalpass#953) Fix issue where views didn't update immediately when property-based task identification changed. Required two fixes to complete the event flow: 1. Cache Event Bridge (main.ts): - Added setupCacheEventBridge() method to propagate cache events to plugin emitter - Bridges file-updated, file-deleted, and file-renamed events to EVENT_DATA_CHANGED - Ensures views listening to EVENT_DATA_CHANGED refresh when cache changes - Uses requestAnimationFrame for efficient UI updates 2. Task Validation (MinimalNativeCache.ts): - Added isTaskFile() validation to extractTaskInfoFromNative() - Ensures method returns null when file stops being a task - Prevents early exit in handleFileChangedDebounced when task becomes non-task - Fixes asymmetric behavior (task→note vs note→task transitions) Root Cause: - MinimalNativeCache triggered file-updated events but plugin's EVENT_DATA_CHANGED was never fired - extractTaskInfoFromNative() extracted TaskInfo without validating task status - When isTask changed from true to false, taskInfoEquals() returned true (same TaskInfo) - This caused early exit, preventing event propagation to views Impact: - Views now refresh immediately when task identification properties change - Works for both tag-based and property-based identification - Fixes both directions: note→task and task→note transitions - No breaking changes, only completes missing event flow Test Results: - All MinimalNativeCache tests passing (33/33) - New cache event bridge tests passing (5/5) - Fixes tests that failed in GitHub Actions CI - No new test failures introduced Files Modified: - src/main.ts: Added setupCacheEventBridge() method (38 lines) - src/utils/MinimalNativeCache.ts: Added task validation (4 lines) - tests/unit/main.cacheEventBridge.test.ts: New test file (5 tests)
|
Thanks for this fix for #953, @renatomen ! However, I'm worried the event-driven index invalidation will cause performance issues. Every file edit triggers a full subtask index rebuild (scanning all files), which can take 1-2 seconds in large vaults. The subtask index rebuilding can be very slow, which is why it is only allowed every 30 seconds. I think I might look into a different fix for #953 in v4. Basically, I think I'll add a view option that allows users to select whether filter conditions flow down into subtasks. This should allow the appropriate filtering of non-task notes from the subtasks. |
Description
Fixes #953 - Prevents non-task notes from being incorrectly identified as subtasks and ensures views update instantly when task identification changes.
Root Causes
MinimalNativeCache.getTaskInfo()returnedTaskInfofor any file with frontmatter, without validating task identification criteriaProjectSubtasksService.buildProjectIndex()marked tasks as projects based on links from non-task filesProjectSubtasksServicehad no event listeners for metadata changes, relying only on 30-second TTLMinimalNativeCachetriggeredfile-updatedevents butEVENT_DATA_CHANGEDwas never fired, so views didn't refreshextractTaskInfoFromNative()extracted TaskInfo without validating task status, causing asymmetric behavior (task→note vs note→task transitions)Solution
Task Identification Validation
isTaskFile()validation togetTaskInfo()methodisTaskFile()public for use byProjectSubtasksServiceisTaskFile()validation tobuildProjectIndex()methodEvent-Driven Cache Invalidation
initialize()method toProjectSubtasksServicewith event listenersTest Mock Fixes for CI
Object.create(TFile.prototype)to pass instanceof checksCache Event Bridge & Task Validation
main.ts): AddedsetupCacheEventBridge()method to propagate cache events (file-updated,file-deleted,file-renamed) to plugin emitter'sEVENT_DATA_CHANGED, ensuring views refresh when cache changesMinimalNativeCache.ts): AddedisTaskFile()validation toextractTaskInfoFromNative()to ensure it returnsnullwhen file stops being a task, preventing early exit in comparison logicrequestAnimationFramefor efficient UI updatesImpact
Testing
Files Modified
src/utils/MinimalNativeCache.ts- Task validation in getTaskInfo() and extractTaskInfoFromNative()src/services/ProjectSubtasksService.ts- Event listeners and cache invalidationsrc/main.ts- Cache event bridge setuptests/unit/utils/MinimalNativeCache.getTaskInfo.test.ts- Test suite (13 tests)tests/unit/main.cacheEventBridge.test.ts- New test file (5 tests)