Skip to content

Conversation

@phortx
Copy link

@phortx phortx commented Jan 16, 2026

Progress Bar Feature: Task Completion Tracking

Adds a progress bar that displays task completion status based on first-level checkboxes in the task body. With focus on performance, customization, and full Bases integration. This is inspired by Trello.

Bildschirmfoto 2026-01-16 um 12 39 10

(Screenshot from a task card from the TaskNotes KanBan Base View)

Features

  • Progress Calculation: Automatically counts first-level checkboxes (no indentation) in the task body
  • Flexible Display: Configurable display modes (bar-only, text-only, bar with text)
  • Full Bases Integration: Progress is available as task.progress in all Bases views (including standard Table view) and selectable in property picker
  • Sorting & Filtering: Progress can be sorted and filtered in Bases views
  • Empty State Handling: Configurable display for tasks without checkboxes (hide or show "0/0 (0%)")
  • Automatic Updates: Progress is automatically recalculated and persisted when:
    • Task details are updated via updateTask()
    • Task files are modified directly (e.g., checkbox toggled in editor)
    • New tasks are created with details
  • Documentation

Technical Details

Architecture

  • New Service: ProgressService for centralized progress calculation with caching
  • Frontmatter Persistence: Progress is stored in frontmatter as task_progress (percentage number 0-100) for Bases compatibility
  • FieldMapper Integration: Progress is integrated into the FieldMapper system, allowing user-configurable field names
  • Lazy Loading: Progress is only calculated when the property is visible (performance optimization)
  • Cache Invalidation: Automatic cache cleanup on task updates
  • File Change Listener: Debounced listener (500ms) updates progress when task files are modified directly
  • Settings Listeners: All views react to settings changes and re-render accordingly
  • Documentation: Updated Development Guidelines with section on adding computed properties that need Bases integration

Property Name Mapping

The progress property uses a three-tier naming system:

  1. Frontmatter Field: Configurable field name (default: task_progress, stored in YAML frontmatter as a number 0-100)

    • This is the actual field name in the task file's frontmatter
    • Configurable via FieldMapper (default: task_progress, but users can change it to progress or any other name)
    • The FieldMapper handles the mapping between internal name and frontmatter name
  2. Bases Property: task.progress (used in Bases views)

    • This is the property name exposed to Bases for sorting, filtering, and display
    • Always called task.progress regardless of the frontmatter field name
    • Mapped from the configured frontmatter field in BasesDataAdapter
    • Registered as a computed property in BasesViewBase.registerComputedProperties()
  3. Internal Property: progress (used in TaskInfo and TaskCard)

    • This is the internal property name in TypeScript code
    • Contains ProgressInfo object with completed, total, and percentage
    • Mapped via PropertyMappingService for display in TaskCard

Why Three Names?

  • Frontmatter: User-configurable via FieldMapper (allows customization)
  • Bases: Always task.progress (consistent Bases API, regardless of frontmatter name)
  • Internal: Always progress (standardized name for consistent code usage)

Note: The default frontmatter field name is task_progress, but users can configure it to be progress or any other name via FieldMapper settings. The Bases property name task.progress and internal name progress remain constant.

Implementation Flow

  1. Calculation: ProgressService.calculateProgress() analyzes task body for checkboxes
  2. Persistence: Value is written to frontmatter via FieldMapper.mapToFrontmatter()
  3. Bases Discovery: BasesDataAdapter maps task_progresstask.progress
  4. Display: TaskCard renders progress bar using task.progress property
  5. Auto-Update: File change listener recalculates when body content changes

Breaking Changes

None. The feature is enabled by default but can be disabled in settings.

Migration Notes

  • Existing tasks without progress will automatically get progress calculated on first update or file change
  • Progress is stored in frontmatter, so it persists across plugin restarts
  • If you manually edit task_progress in frontmatter, it will be recalculated on next file change

Known Issues and Future Improvements

  • TaskCard in Note: The TaskCard widget within notes doesn't refresh when ticking checkboxes. This is a more fundamental problem, as it doesn't refresh when changing properties or title too. This affects all properties, not just progress.
  • Progress Bar Color: Progress bar color is static. Could be enhanced with color coding (red/orange/green) depending on progress percentage.
  • Performance: For very large task bodies (>10,000 lines), progress calculation might be slow. Consider optimization if this becomes an issue.
  • For existing vaults: Existing Tasks has to be changed once in order to initially calculate the progress. Maybe this is something that can be automated?

Disclaimer

I'm not an experienced Obsidian Plugin Dev, but tried to align with all guidelines and be consistent with existent code. Feedback is very welcome! :)

@phortx phortx marked this pull request as draft January 16, 2026 12:23
@phortx
Copy link
Author

phortx commented Jan 16, 2026

I'm not super happy with the fact that we calculate and set the progress into frontmatter, but couldn't find a better way to make it compatible with standard base views. However for TaskNotes views it works with a calculated property very well.

Standard Bases views (table etc) gave me lot of headache while trying to get it running as a calculated property, but that's currently simply not possible the way obsidian bases work. If anyone has an idea, feel free to fork this branch and try it and get the same headache 😄

@phortx phortx marked this pull request as ready for review January 16, 2026 14:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant