diff --git a/docs/TIMEZONE_HANDLING_GUIDE.md b/docs/TIMEZONE_HANDLING_GUIDE.md deleted file mode 100644 index 891581bd..00000000 --- a/docs/TIMEZONE_HANDLING_GUIDE.md +++ /dev/null @@ -1,210 +0,0 @@ -# TaskNotes Timezone Handling Guide - -## Overview - -TaskNotes uses a **UTC Midnight Convention** to ensure consistent date handling across all timezones. This guide explains how to handle dates correctly to avoid timezone-related bugs. - -## Core Principle: Local Dates for Users, UTC for RRule - -1. **User-facing operations** (display, input, storage) use **local dates** -2. **RRule operations** internally use **UTC** but convert to/from local dates at boundaries -3. **Never mix** `format()` with `formatDateForStorage()` - they're the same now! - -## The Golden Rules - -### ✅ DO Use These Functions - -```typescript -// For storing/displaying dates (YYYY-MM-DD format) -import { formatDateForStorage, getTodayLocal } from '@/utils/dateUtils'; - -const today = getTodayLocal(); -const dateString = formatDateForStorage(someDate); -``` - -### ❌ DON'T Use These - -```typescript -// NEVER use format() from date-fns directly for dates -import { format } from 'date-fns'; -const dateString = format(date, 'yyyy-MM-dd'); // ❌ WRONG! - -// NEVER create dates like this for today -const today = new Date(); // ❌ WRONG! Includes time component -``` - -## Common Scenarios - -### 1. Getting Today's Date - -```typescript -// ✅ CORRECT -import { getTodayLocal } from '@/utils/dateUtils'; -const today = getTodayLocal(); // Returns Date object at 00:00:00 local time - -// ✅ CORRECT - As a string -import { getTodayString } from '@/utils/dateUtils'; -const todayStr = getTodayString(); // Returns "YYYY-MM-DD" - -// ❌ WRONG -const today = new Date(); // Has time component, can cause boundary issues -``` - -### 2. Formatting Dates for Storage - -```typescript -// ✅ CORRECT -import { formatDateForStorage } from '@/utils/dateUtils'; -const dateStr = formatDateForStorage(date); // Always returns local date - -// ❌ WRONG -import { format } from 'date-fns'; -const dateStr = format(date, 'yyyy-MM-dd'); // May use wrong timezone -``` - -### 3. Parsing Date Strings - -```typescript -// ✅ CORRECT - For date-only strings -import { parseDateAsLocal } from '@/utils/dateUtils'; -const date = parseDateAsLocal('2025-01-21'); // Interprets as local date - -// ✅ CORRECT - For dates with time -import { parseDate } from '@/utils/dateUtils'; -const dateTime = parseDate('2025-01-21T14:30:00Z'); - -// ❌ WRONG -const date = new Date('2025-01-21'); // May interpret as UTC midnight -``` - -### 4. Working with Recurring Tasks (RRule) - -```typescript -// ✅ CORRECT - RRule handles UTC conversion internally -import { isDueByRRule, generateRecurringInstances } from '@/utils/helpers'; - -// Just pass local dates - the functions handle UTC conversion -const isdue = isDueByRRule(task, localDate); -const instances = generateRecurringInstances(task, startDate, endDate); - -// ❌ WRONG - Don't manually convert to UTC -const utcDate = new Date(Date.UTC(...)); // Let the helpers handle this -``` - -### 5. Task Completion - -```typescript -// ✅ CORRECT -const completionDate = formatDateForStorage(getTodayLocal()); -task.complete_instances.push(completionDate); - -// ❌ WRONG -const completionDate = format(new Date(), 'yyyy-MM-dd'); -``` - -### 6. Calendar Operations - -```typescript -// ✅ CORRECT - Calendar should use local dates -const calendarDate = formatDateForStorage(selectedDate); -const events = getEventsForDate(parseDateAsLocal(dateString)); - -// ❌ WRONG -const calendarDate = formatDateForStorage(date); // This now returns local anyway -``` - -## Key Functions Reference - -### From `dateUtils.ts`: - -- `getTodayLocal()` - Get today as Date object at 00:00:00 local -- `getTodayString()` - Get today as "YYYY-MM-DD" string -- `formatDateForStorage(date)` - Convert any date to "YYYY-MM-DD" local -- `parseDateAsLocal(dateString)` - Parse "YYYY-MM-DD" as local date -- `parseDate(dateString)` - Parse any date string (handles timezones) -- `hasTimeComponent(dateString)` - Check if string includes time - -### What About `formatDateForStorage()`? - -This function converts Date objects to YYYY-MM-DD format using local timezone components. It ensures consistent date formatting for storage and display purposes. - -## Testing Your Code - -When writing tests involving dates: - -```typescript -// ✅ CORRECT - Use specific dates -const testDate = new Date(2025, 0, 21); // January 21, 2025 local -const testDateStr = '2025-01-21'; - -// ✅ CORRECT - Mock current date -jest.spyOn(Date, 'now').mockReturnValue(new Date(2025, 0, 21).getTime()); - -// ❌ WRONG - Don't use dynamic dates in tests -const today = new Date(); // Makes tests non-deterministic -``` - -## Common Pitfalls to Avoid - -### 1. The Midnight Boundary Problem - -```typescript -// ❌ PROBLEM: User in AEST (UTC+10) at 11 PM marks task complete -const now = new Date(); // 2025-01-21T23:00:00+10:00 -const utcString = format(now, 'yyyy-MM-dd'); // "2025-01-21" -const localString = formatDateForStorage(now); // "2025-01-21" ✅ Same! - -// But if they marked it at 1 AM... -const later = new Date(); // 2025-01-22T01:00:00+10:00 -const utcString = format(later, 'yyyy-MM-dd'); // Would be "2025-01-21" ❌ Wrong! -const localString = formatDateForStorage(later); // "2025-01-22" ✅ Correct! -``` - -### 2. String Comparison Safety - -```typescript -// ✅ SAFE - Both sides use same format -const isOverdue = task.scheduled < getTodayString(); - -// ❌ UNSAFE - Mixing formats -const isOverdue = task.scheduled < format(new Date(), 'yyyy-MM-dd'); -``` - -### 3. RRule Date Anchoring - -```typescript -// ✅ CORRECT - Let helpers handle UTC conversion -const instances = generateRecurringInstances(task, startDate, endDate); - -// ❌ WRONG - Don't pre-convert to UTC -const utcStart = new Date(Date.UTC(...)); -const instances = generateRecurringInstances(task, utcStart, utcEnd); -``` - -## Migration Checklist - -When updating old code: - -- [ ] Replace all `format(date, 'yyyy-MM-dd')` with `formatDateForStorage(date)` -- [ ] Replace `new Date()` for today with `getTodayLocal()` -- [ ] Replace manual date string parsing with `parseDateAsLocal()` -- [ ] Ensure calendar operations use local dates -- [ ] Update tests to use fixed dates instead of dynamic dates - -## Why This Approach? - -1. **Users think in local dates** - When they see "Jan 21", they mean Jan 21 in their timezone -2. **RRule needs UTC** - But we handle the conversion transparently -3. **Consistency prevents bugs** - Using the same format everywhere eliminates boundary issues -4. **Storage remains stable** - "2025-01-21" means the same thing regardless of where it's read - -## Questions? - -If you're unsure about date handling in a specific scenario: - -1. Check existing similar code in the codebase -2. Default to using the utility functions in `dateUtils.ts` -3. Write a test to verify the behavior across timezone boundaries -4. Ask in code review if still uncertain - -Remember: **When in doubt, use `formatDateForStorage()` and `getTodayLocal()`!** \ No newline at end of file diff --git a/docs/TIMEZONE_HANDLING_UTC.md b/docs/TIMEZONE_HANDLING_UTC.md deleted file mode 100644 index 2219a570..00000000 --- a/docs/TIMEZONE_HANDLING_UTC.md +++ /dev/null @@ -1,360 +0,0 @@ -# UTC-Based Timezone Handling in TaskNotes - -## Overview - -TaskNotes implements a UTC-based timezone approach to ensure consistent date handling across all timezones while maintaining intuitive user behavior. This document explains the technical implementation, design decisions, and best practices for developers working with the codebase. - -## Core Architecture - -### The UTC Midnight Convention - -TaskNotes follows a **UTC Midnight Convention** that operates on two key principles: - -1. **User-facing operations** use local dates for intuitive behavior -2. **Internal calculations** use UTC to prevent timezone-dependent bugs - -This hybrid approach ensures that: -- Users see dates in their local timezone context -- The system calculates dates consistently regardless of user timezone -- Recurring tasks and date boundaries work correctly across all timezones - -### Date Flow Architecture - -``` -User Input (Local) → Storage (YYYY-MM-DD) → Processing (UTC) → Display (Local) -``` - -## Key Functions and Behavior - -### Date Creation Functions - -#### `formatDateForStorage(date: Date): string` - -**Purpose**: Converts Date objects to YYYY-MM-DD format using UTC components to ensure consistent date representation across timezones. - -**Behavior**: -```typescript -// Uses UTC methods to prevent timezone shifts -const year = date.getUTCFullYear(); -const month = String(date.getUTCMonth() + 1).padStart(2, '0'); -const day = String(date.getUTCDate()).padStart(2, '0'); -return `${year}-${month}-${day}`; -``` - -**When to use**: Converting any Date object to storage format, replacing `format(date, 'yyyy-MM-dd')`. - -#### `getTodayLocal(): Date` - -**Purpose**: Returns today's date as a Date object set to midnight local time. - -**Behavior**: -```typescript -const now = new Date(); -return new Date(now.getFullYear(), now.getMonth(), now.getDate()); -``` - -**When to use**: Getting "today" from the user's perspective for comparisons and calculations. - -#### `parseDateAsLocal(dateString: string): Date` - -**Purpose**: Parses YYYY-MM-DD strings as local dates at midnight to ensure consistent day representation. - -**Behavior**: -```typescript -// For "2024-10-01", creates Date(2024, 9, 1) - local midnight -const [year, month, day] = dateString.split('-').map(Number); -return new Date(year, month - 1, day); -``` - -**When to use**: Converting date-only strings to Date objects for user-facing operations. - -#### `createUTCDateForRRule(dateString: string): Date` - -**Purpose**: Creates UTC dates at midnight for RRule operations to preserve correct day-of-week calculations. - -**Behavior**: -```typescript -// For "2024-10-01", creates Date.UTC(2024, 9, 1) - UTC midnight -return new Date(Date.UTC(year, month - 1, day)); -``` - -**When to use**: Converting dates for recurring task calculations with RRule library. - -### Date Comparison and Utilities - -#### `isOverdueTimeAware(dateString: string, isCompleted?: boolean, hideCompletedFromOverdue?: boolean): boolean` - -**Purpose**: Determines if a date/datetime is overdue with completion status awareness. - -**Behavior**: -- For datetime strings: Compares with current moment -- For date-only strings: Compares calendar days using local dates -- Respects completion status and user preferences - -#### `isBeforeDateTimeAware(date1: string, date2: string): boolean` - -**Purpose**: Time-aware comparison for sorting tasks with mixed date/datetime formats. - -**Behavior**: -- Both have time: Direct comparison -- Neither has time: Compare start-of-day -- Mixed: Treat date-only as end-of-day for sorting - -#### `hasTimeComponent(dateString: string): boolean` - -**Purpose**: Detects if a date string includes time information. - -**Pattern**: Checks for 'T' followed by time pattern (HH:mm or HH:mm:ss). - -## Timezone Handling Guidelines - -### For Developers - -#### 1. Date Storage and Retrieval - -```typescript -// ✅ CORRECT - Use formatDateForStorage for consistent dates -const dueDate = formatDateForStorage(selectedDate); - -// ❌ INCORRECT - Don't use date-fns format directly -const dueDate = format(selectedDate, 'yyyy-MM-dd'); -``` - -#### 2. Getting Today's Date - -```typescript -// ✅ CORRECT - Use getTodayLocal for user perspective -const today = getTodayLocal(); - -// ✅ CORRECT - Use getTodayString for string format -const todayStr = getTodayString(); - -// ❌ INCORRECT - Don't use new Date() for "today" -const today = new Date(); // Includes time, causes boundary issues -``` - -#### 3. Date Parsing - -```typescript -// ✅ CORRECT - Use parseDateAsLocal for date-only strings -const taskDate = parseDateAsLocal('2024-10-01'); - -// ✅ CORRECT - Use parseDate for datetime strings -const timestamp = parseDate('2024-10-01T14:30:00Z'); - -// ❌ INCORRECT - Don't mix parsing functions -const taskDate = parseDate('2024-10-01'); // May cause timezone shifts -``` - -#### 4. Recurring Task Calculations - -```typescript -// ✅ CORRECT - Use createUTCDateForRRule for RRule operations -const rruleDate = createUTCDateForRRule(dateString); -const isRecurring = rrule.between(rruleDate, endDate); - -// ❌ INCORRECT - Don't use local dates with RRule -const localDate = parseDateAsLocal(dateString); -const isRecurring = rrule.between(localDate, endDate); // Wrong day-of-week -``` - -### Common Pitfalls and Solutions - -#### 1. Off-by-One Day Errors - -**Problem**: Users in certain timezones see tasks on wrong days. - -**Cause**: Mixing UTC and local date interpretations. - -**Solution**: -```typescript -// ✅ CORRECT - Consistent local date handling -const dueDate = formatDateForStorage(userSelectedDate); -const taskDate = parseDateAsLocal(dueDate); -const isToday = isSameDay(taskDate, getTodayLocal()); - -// ❌ INCORRECT - Mixed timezone handling -const dueDate = format(userSelectedDate, 'yyyy-MM-dd'); // UTC -const taskDate = parseDate(dueDate); // Might shift timezone -``` - -#### 2. Recurring Task Wrong Day - -**Problem**: Recurring tasks appear on incorrect days in some timezones. - -**Cause**: RRule calculations using local dates instead of UTC. - -**Solution**: -```typescript -// ✅ CORRECT - Use UTC dates for RRule, local for boundaries -const startUTC = createUTCDateForRRule(startDateString); -const checkDateUTC = createUTCDateForRRule(formatDateForStorage(checkDate)); -const isRecurring = rrule.between(startUTC, checkDateUTC); - -// ❌ INCORRECT - Using local dates with RRule -const startLocal = parseDateAsLocal(startDateString); -const isRecurring = rrule.between(startLocal, checkDate); // Wrong calculations -``` - -#### 3. Calendar Display Issues - -**Problem**: Tasks show on wrong calendar dates. - -**Cause**: Inconsistent date formatting between storage and display. - -**Solution**: -```typescript -// ✅ CORRECT - Consistent formatting -const calendarDate = formatDateForStorage(selectedDate); -const tasksForDate = getTasksForDate(calendarDate); - -// ❌ INCORRECT - Mixed formatting approaches -const calendarDate = format(selectedDate, 'yyyy-MM-dd'); // Might be UTC -const tasksForDate = getTasksForDate(calendarDate); // Expects local -``` - -## Recent Fixes (Issues #327, #322, #314) - -### Issue #327: Recurring Task Wrong Day Completion - -**Problem**: Users completing recurring tasks on the correct day had the completion recorded for the wrong date, causing the task to still appear as due. - -**Root Cause**: `isDueByRRule` function was using `formatDateForStorage()` (returns local date) to create dates that were then passed to `createUTCDateForRRule()` (expects UTC interpretation), causing a timezone mismatch. - -**Fix Applied**: -1. Added `formatDateAsUTCString()` function for RRule-specific formatting -2. Updated `isDueByRRule` to use `formatDateAsUTCString` instead of `formatDateForStorage` -3. Ensured all RRule operations use consistent UTC dates - -**Code Change**: -```typescript -// Before (BROKEN) -const dateStr = formatDateForStorage(targetDate); // Local date string -const rruleDate = createUTCDateForRRule(dateStr); // Interpreted as UTC - MISMATCH! - -// After (FIXED) -const dateStr = formatDateAsUTCString(targetDate); // UTC date string -const rruleDate = createUTCDateForRRule(dateStr); // Interpreted as UTC - CONSISTENT! -``` - -### Issue #322: Calendar Display Timezone Bugs - -**Problem**: Tasks appeared on wrong dates in calendar views depending on user timezone. - -**Root Cause**: Inconsistent use of `format()` vs `formatDateForStorage()` for date string generation. - -**Fix Applied**: -1. Standardized all calendar date formatting to use `formatDateForStorage()` -2. Updated AdvancedCalendarView, TaskEditModal, and other calendar components -3. Ensured consistent local date interpretation throughout the calendar system - -### Issue #314: Complete Instances Timezone Inconsistency - -**Problem**: Task completion dates stored in `complete_instances` array were inconsistent across timezones. - -**Root Cause**: Mixed use of UTC and local date formatting when recording completion dates. - -**Fix Applied**: -1. Standardized completion date recording to use `formatDateForStorage()` -2. Added `validateCompleteInstances()` function to filter invalid time-only entries -3. Updated all completion workflows to use consistent local date format - -## Testing Strategy - -### Timezone-Aware Test Cases - -TaskNotes includes comprehensive tests for timezone handling: - -1. **Basic Date Functions**: Test date creation, parsing, and formatting across timezones -2. **Recurring Task Logic**: Verify RRule calculations work correctly regardless of user timezone -3. **Completion Workflows**: Test task completion recording and validation -4. **Calendar Integration**: Verify tasks appear on correct dates in all views -5. **Edge Cases**: Test boundary conditions like midnight, DST transitions, etc. - -### Test Structure Example - -```typescript -describe('Timezone handling', () => { - it('should handle recurring tasks consistently across timezones', () => { - // Test setup with specific timezone - const task = createRecurringTask('2024-10-01', 'daily'); - const checkDate = new Date('2024-10-05T12:00:00Z'); - - // Test in different timezone contexts - const isRecurring = isDueByRRule(task, checkDate); - expect(isRecurring).toBe(true); // Should work regardless of test runner timezone - }); -}); -``` - -## Migration Notes - -### For Existing Code - -When updating existing code to follow the UTC-based approach: - -1. **Replace date-fns format calls**: - ```typescript - // Old - const dateStr = format(date, 'yyyy-MM-dd'); - - // New - const dateStr = formatDateForStorage(date); - ``` - -2. **Update "today" calculations**: - ```typescript - // Old - const today = new Date(); - - // New - const today = getTodayLocal(); - ``` - -3. **Fix date parsing**: - ```typescript - // Old (for date-only strings) - const date = parseDate('2024-10-01'); - - // New (for date-only strings) - const date = parseDateAsLocal('2024-10-01'); - ``` - -### Breaking Changes - -The UTC-based approach introduces some breaking changes: - -1. **Date Storage Format**: All dates now consistently use local timezone interpretation -2. **RRule Integration**: Requires specific UTC handling for recurring task calculations -3. **API Consistency**: Date functions now have clearer, more specific purposes - -## Performance Considerations - -The UTC-based approach is designed for performance: - -1. **Reduced Calculations**: Fewer timezone conversions in hot paths -2. **Consistent Caching**: Date strings are consistent across operations -3. **Optimized Comparisons**: Time-aware comparisons reduce unnecessary parsing - -## Future Considerations - -### Potential Enhancements - -1. **Timezone-Aware Display**: Show tasks with time in user's preferred timezone -2. **Multi-Timezone Support**: Handle tasks created in different timezones -3. **DST Handling**: Enhanced support for daylight saving time transitions -4. **Performance Optimization**: Further caching of timezone calculations - -### Compatibility - -The UTC-based approach maintains backward compatibility: - -1. **Existing Data**: Works with existing YYYY-MM-DD date formats -2. **API Stability**: Core date functions maintain same signatures -3. **Plugin Integration**: Compatible with Obsidian's date handling expectations - -## Conclusion - -The UTC-based timezone approach provides TaskNotes with robust, consistent date handling that prevents timezone-related bugs while maintaining intuitive user behavior. By following the guidelines in this document, developers can ensure their code works correctly for users in all timezones. - -For quick reference, see the [Timezone Quick Reference Guide](TIMEZONE_QUICK_REFERENCE.md) for common patterns and functions. \ No newline at end of file diff --git a/docs/TIMEZONE_QUICK_REFERENCE.md b/docs/TIMEZONE_QUICK_REFERENCE.md deleted file mode 100644 index 3c445785..00000000 --- a/docs/TIMEZONE_QUICK_REFERENCE.md +++ /dev/null @@ -1,88 +0,0 @@ -# TaskNotes Timezone Quick Reference - -## 🚀 Quick Cheat Sheet - -### Today's Date -```typescript -// ✅ DO -import { getTodayLocal, getTodayString } from '@/utils/dateUtils'; -const today = getTodayLocal(); // Date object -const todayStr = getTodayString(); // "YYYY-MM-DD" - -// ❌ DON'T -const today = new Date(); // Has time component! -``` - -### Format for Storage -```typescript -// ✅ DO -import { formatDateForStorage } from '@/utils/dateUtils'; -const dateStr = formatDateForStorage(date); - -// ❌ DON'T -import { format } from 'date-fns'; -const dateStr = format(date, 'yyyy-MM-dd'); -``` - -### Parse Date Strings -```typescript -// ✅ DO -import { parseDateAsLocal } from '@/utils/dateUtils'; -const date = parseDateAsLocal('2025-01-21'); // For date-only - -// ❌ DON'T -const date = new Date('2025-01-21'); // May be UTC! -``` - -### Complete a Task -```typescript -// ✅ DO -const completionDate = formatDateForStorage(getTodayLocal()); -task.complete_instances.push(completionDate); - -// ❌ DON'T -task.complete_instances.push(format(new Date(), 'yyyy-MM-dd')); -``` - -## 📋 Copy-Paste Templates - -### Import Block -```typescript -import { - getTodayLocal, - getTodayString, - formatDateForStorage, - parseDateAsLocal -} from '@/utils/dateUtils'; -``` - -### Common Patterns -```typescript -// Check if overdue -const isOverdue = task.scheduled < getTodayString(); - -// Get date 7 days from now -const futureDate = new Date(getTodayLocal()); -futureDate.setDate(futureDate.getDate() + 7); -const futureDateStr = formatDateForStorage(futureDate); - -// Calendar date selection -const handleDateSelect = (date: Date) => { - const dateStr = formatDateForStorage(date); - // Use dateStr for storage/display -}; -``` - -## ⚠️ Red Flags in Code Review - -1. Direct use of `format(date, 'yyyy-MM-dd')` -2. `new Date()` when you just need today's date -3. Manual UTC conversion for RRule operations -4. Mixing different date formatting methods -5. `new Date(dateString)` without parseDate functions - -## 💡 Remember - -**Local dates for users, UTC handled internally for RRule** - -When in doubt: `formatDateForStorage()` + `getTodayLocal()` \ No newline at end of file diff --git a/docs/calendar-setup.md b/docs/calendar-setup.md index 1fdc74ea..cf8e2cdc 100644 --- a/docs/calendar-setup.md +++ b/docs/calendar-setup.md @@ -45,9 +45,21 @@ To connect your calendars, you'll need to create OAuth applications with Google - Navigate to "App registrations" → "New registration" - Name: Choose any name (e.g., "TaskNotes") - Supported account types: Select appropriate option for your use case - - Redirect URI: Add "http://localhost:8080" (Platform: Web) + - Redirect URI: Leave blank for now (we'll add it via manifest) -2. **Configure API Permissions** +2. **Configure Redirect URI via Manifest** + - In your app registration, go to "Manifest" + - Find the `replyUrlsWithType` array and add: + ```json + { + "url": "http://127.0.0.1", + "type": "Web" + } + ``` + - Save the manifest + - Note: Azure Portal UI may not allow `http://127.0.0.1` directly, but the manifest editor does. Azure ignores the port for loopback addresses, so any port will work. + +3. **Configure API Permissions** - In your app registration, go to "API permissions" - Add permissions: - `Calendars.Read` @@ -55,12 +67,12 @@ To connect your calendars, you'll need to create OAuth applications with Google - `offline_access` - Grant admin consent if required -3. **Get Credentials** +4. **Get Credentials** - In "Overview", copy the Application (client) ID - In "Certificates & secrets", create a new client secret - Copy the secret value immediately (shown only once) -4. **Configure TaskNotes** +5. **Configure TaskNotes** - In TaskNotes Settings → Integrations → Calendar: - Paste your Client ID in the Microsoft Calendar card - Paste your Client Secret in the Microsoft Calendar card @@ -78,9 +90,8 @@ To connect your calendars, you'll need to create OAuth applications with Google **"Failed to connect"** - Verify Client ID and Secret are correct -- Check redirect URI is configured: `http://localhost:8080` -- Check no other services are running on port 8080 - - You may need to disable the API integration and restart if it is using port 8080. You will be able to re-enable the API after calendar authorization. +- For Microsoft: Check redirect URI `http://127.0.0.1` is configured via the manifest editor (not `localhost`) +- For Google: Check redirect URI `http://localhost:8080` is configured - Ensure required API permissions are granted **"Failed to fetch events"** diff --git a/docs/core-concepts.md b/docs/core-concepts.md index 144f02c2..065665e3 100644 --- a/docs/core-concepts.md +++ b/docs/core-concepts.md @@ -6,18 +6,122 @@ TaskNotes follows the "one note per task" principle, where each task lives as a Individual Markdown notes replace centralized databases or proprietary formats. Each task file can be read, edited, and backed up with any text editor or automation tool. -The note body holds additional context like research findings, meeting notes, or links to related documents. Since tasks are proper notes, they work with Obsidian's backlinking, graph visualization, and tag management. +### Task Structure -This approach does create many small files, which may not suit every organizational preference. +A TaskNotes task is a standard Markdown file with YAML frontmatter: -## YAML Frontmatter for Structured Data +```markdown +--- +tags: + - task +title: Review quarterly report +status: in-progress +priority: high +due: 2025-01-15 +scheduled: 2025-01-14 +contexts: + - "@office" +projects: + - "[[Q1 Planning]]" +--- -Task metadata like due dates, priorities, and status live in YAML frontmatter. This standard has tool support for integrating task data with external systems and extending the data model with custom fields. +## Notes -TaskNotes queries Obsidian's metadata cache directly. Version 4 requires the Bases core plugin to be enabled for main views. Plain text files work with version control systems like Git. +Key points to review: +- Revenue projections +- Budget allocations + +## Meeting Notes + +Discussion with finance team on 2025-01-10... +``` + +The frontmatter contains structured, queryable properties. The note body holds freeform content—research findings, meeting notes, checklists, or links to related documents. + +### Obsidian Integration + +Since tasks are proper notes, they work with Obsidian's core features: + +- **Backlinks**: See which notes reference a task +- **Graph View**: Visualize task relationships and project connections +- **Tags**: Use Obsidian's tag system for additional categorization +- **Search**: Find tasks using Obsidian's search +- **Links**: Reference tasks from daily notes, meeting notes, or project documents + +This approach creates many small files. TaskNotes stores tasks in a configurable folder (default: `TaskNotes/Tasks/`) to keep them organized. + +## YAML Frontmatter + +Task properties are stored in YAML frontmatter, a standard format with broad tool support. + +### Property Types + +TaskNotes uses several property types: + +| Type | Example | Description | +|------|---------|-------------| +| Text | `title: Buy groceries` | Single text value | +| List | `tags: [work, urgent]` | Multiple values | +| Date | `due: 2025-01-15` | ISO 8601 date format | +| DateTime | `scheduled: 2025-01-15T09:00` | Date with time | +| Link | `projects: ["[[Project A]]"]` | Obsidian wikilinks | +| Number | `timeEstimate: 60` | Numeric values (minutes) | + +### Field Mapping + +Property keys are configurable. If your vault uses `deadline` instead of `due`, you can map TaskNotes to use your existing field names without modifying your files. + +### Custom Fields + +Add any frontmatter property to your tasks. User-defined fields work in filtering, sorting, and templates. Define custom fields in Settings → Task Properties to include them in task modals and views. + +## Bases Integration + +TaskNotes v4 uses Obsidian's Bases core plugin for its main views. Bases provides: + +- **Filtering**: Query tasks using AND/OR conditions +- **Sorting**: Order tasks by any property +- **Grouping**: Organize tasks by status, priority, project, or custom fields +- **Views**: Task List, Kanban, Calendar, and Agenda are all Bases views + +Views are stored as `.base` files in `TaskNotes/Views/`. These files contain YAML configuration that defines the view's query and display settings. You can duplicate, modify, or create new views by editing these files. + +### Enabling Bases + +Bases is a core plugin included with Obsidian 1.10.1+: + +1. Open Settings → Core Plugins +2. Enable "Bases" +3. TaskNotes views will now function ## Methodology-Agnostic Design -TaskNotes does not enforce a specific productivity methodology. The tools support various approaches: +TaskNotes provides tools without enforcing a specific productivity methodology. The same features support different approaches: -Getting Things Done uses contexts, status workflows, and calendar integration. Time-based planning uses calendar integration and time tracking. Project-centric workflows use the projects feature with tags, contexts, and linking. Kanban and Agile methodologies use the Kanban view and customizable status systems. \ No newline at end of file +### Getting Things Done (GTD) + +- **Contexts** (`@home`, `@office`, `@phone`) for location/tool-based grouping +- **Projects** for multi-step outcomes +- **Status workflows** for next actions, waiting, and someday/maybe +- **Calendar integration** for time-specific commitments + +### Time-Based Planning + +- **Calendar views** for scheduling and time-blocking +- **Scheduled dates** for when to work on tasks +- **Time tracking** for logging work sessions +- **Pomodoro timer** for focused work intervals + +### Project-Centric Workflows + +- **Project links** connecting tasks to project notes +- **Dependencies** for task sequencing +- **Subtasks** created from project context menus +- **Filtering by project** in all views + +### Kanban / Agile + +- **Kanban view** with customizable columns +- **Swimlanes** for two-dimensional organization +- **Drag-and-drop** status changes +- **Custom status values** for your workflow stages diff --git a/docs/features.md b/docs/features.md index 85096ae2..e1288beb 100644 --- a/docs/features.md +++ b/docs/features.md @@ -12,13 +12,9 @@ See [Task Management](features/task-management.md) for details. ## Filtering and Views -TaskNotes v4 uses the Bases core plugin for filtering, sorting, and grouping tasks. Bases is an official Obsidian plugin built directly into the application. Views are defined through YAML-based `.base` files in your vault, which specify query conditions using AND/OR logic, sort orders, and grouping criteria by task properties such as tags, status, or custom fields. +TaskNotes uses Obsidian's Bases core plugin for filtering, sorting, and grouping tasks. Views are defined through YAML-based `.base` files that specify query conditions, sort orders, and grouping criteria. Hierarchical subgrouping supports two-level organization. -Saved views are stored as `.base` files rather than in plugin settings. This allows multiple task perspectives that can be switched between. Hierarchical subgrouping supports two-level organization, where tasks are first grouped by one criterion (e.g., status) and then subdivided by another (e.g., priority). - -The Bases core plugin must be enabled for TaskNotes main views to function. - -For details on Bases syntax, filtering, and views, see the [official Obsidian Bases documentation](https://help.obsidian.md/Bases/Introduction+to+Bases). +For details on how Bases integration works, see [Core Concepts](core-concepts.md#bases-integration). For Bases syntax documentation, see the [official Obsidian Bases documentation](https://help.obsidian.md/Bases/Introduction+to+Bases). ## Inline Task Integration @@ -50,7 +46,7 @@ See [User Fields](features/user-fields.md) for details. ## Integrations -TaskNotes v4 requires the Bases core plugin to be enabled for main task views to function. Bases is an official Obsidian plugin built directly into the application, not a community plugin. This integration allows TaskNotes tasks to function as data sources within Bases databases. +TaskNotes integrates with external calendars (Google Calendar, Microsoft Outlook) via OAuth, ICS calendar subscriptions, and provides an HTTP API for automation. See [Integrations](settings/integrations.md) for details. @@ -58,18 +54,4 @@ See [Integrations](settings/integrations.md) for details. External applications can interact with TaskNotes through its REST API for automation, reporting, and integration with other tools. -See [HTTP API](../HTTP_API.md) for details. - -## View Types - -[Task List View](../views/task-list.md) handles filtering, sorting, and grouping. [Kanban View](../views/kanban-view.md) organizes tasks as cards across status columns. - -[Calendar Views](../views/calendar-views.md) provide visual scheduling with time-blocking. The [Agenda View](../views/agenda-view.md) command opens the calendar's list mode for daily and weekly planning. - -## Settings - -[General](../settings/general.md) controls task identification, file storage, and click behavior. [Task Properties](../settings/task-properties.md) configures property keys, defaults, and NLP triggers. [Features](../settings/features.md) manages inline tasks, natural language processing, and the Pomodoro timer. - -[Appearance & UI](../settings/appearance.md) controls visual elements. [Modal Fields](../settings/modal-fields.md) configures field visibility in task modals. - -[Calendar Settings](../settings/calendar-settings.md) handles calendar appearance and behavior. [Integrations](../settings/integrations.md) manages OAuth calendars, ICS subscriptions, and the HTTP API. [Advanced Settings](../settings/advanced-settings.md) covers field mapping. [Misc Settings](../settings/misc-settings.md) contains additional options. +See [HTTP API](HTTP_API.md) for details. diff --git a/docs/features/calendar-integration.md b/docs/features/calendar-integration.md index 5b9bc99c..bf0cbcf9 100644 --- a/docs/features/calendar-integration.md +++ b/docs/features/calendar-integration.md @@ -36,32 +36,9 @@ TaskNotes stores OAuth access tokens and refresh tokens locally. Tokens are refr ## Calendar Views -TaskNotes provides two calendar views implemented as Bases views. Both views require the **Bases core plugin** to be enabled in Obsidian. +TaskNotes provides Calendar and Mini Calendar views that display tasks alongside OAuth calendar events and ICS subscriptions. Both views support drag-and-drop scheduling. -### Calendar View - -The Calendar View offers multiple display modes—month, week, day, year, and custom days (2-10 days)—and supports: - -- Drag-and-drop task scheduling and rescheduling -- Click dates or time slots to create new tasks -- Display of scheduled tasks, due tasks, recurring tasks, time entries, and time blocks -- OAuth calendar events from Google and Microsoft -- Read-only ICS subscription events -- Custom day view for flexible screen space utilization - -Calendar views are configured through `.base` files in your vault, which define the data source, filters, and view-specific options. - -### Mini Calendar - -The Mini Calendar is a month-based Bases view that displays notes and tasks organized by date. Features include: - -- Heatmap styling to visualize note/task density per day -- Fuzzy selector modal when clicking on days (allows quick selection from multiple notes) -- Keyboard navigation for date selection -- Configurable date property (supports `file.ctime`, `file.mtime`, or any custom date property) -- Configurable title property for displaying note names - -The Mini Calendar operates as a Bases view and is configured through a `.base` file that specifies the date property and display options. +For detailed view documentation, see [Calendar Views](../views/calendar-views.md). ## Time Entry Editor @@ -94,40 +71,7 @@ TaskNotes can subscribe to external calendar feeds using the iCalendar (ICS) for Add and manage ICS subscriptions from **Settings → TaskNotes → Integrations → Calendar subscriptions**. -### Creating Content from Calendar Events - -TaskNotes allows you to create notes and tasks directly from calendar events through the event information modal. When you click on a calendar event, you can: - -**Create Notes from Events:** - -- Generate notes using the event title, date, location, and description -- Apply custom templates for consistent note formatting -- Automatically link notes to the original calendar event for reference - -**Create Tasks from Events:** - -- Convert calendar events into actionable tasks -- Preserve the event's start time as the task's scheduled date and time -- Include event duration as the task's time estimate -- Add event location as a task context -- Automatically tag tasks with the ICS event identifier - -**Link Existing Content:** - -- Connect existing notes to calendar events -- View all notes and tasks related to a specific event -- Maintain bidirectional references between calendar events and vault content - -### Event Information Modal - -The event information modal displays details about calendar events and provides action buttons for content creation. The modal shows: - -- Event title, date, time, location, and description -- Source calendar subscription name -- List of related notes and tasks (if any exist) -- Options to create new content or link existing notes - -Related notes and tasks are automatically identified by their ICS event ID field. Tasks are distinguished from notes based on the presence of the configured task tag in their frontmatter. +For details on creating notes and tasks from calendar events, see [ICS Integration](ics-integration.md). ## Time Blocking diff --git a/docs/features/integrations.md b/docs/features/integrations.md index b2e1f6a8..6d0f9c55 100644 --- a/docs/features/integrations.md +++ b/docs/features/integrations.md @@ -1,85 +1,29 @@ - # Integrations -TaskNotes integrates with other Obsidian plugins. +TaskNotes integrates with external services and Obsidian's core plugins. [← Back to Features](../features.md) -## Bases +## Bases Core Plugin -TaskNotes integrates with the [Bases plugin](https://github.com/obsidian-community/obsidian-bases). This allows you to use your tasks as a data source in your Bases databases. +TaskNotes v4 uses Obsidian's Bases core plugin for its main views (Task List, Kanban, Calendar, Agenda). Bases must be enabled from Settings → Core Plugins. -### Features +For details on Bases integration, see [Core Concepts](../core-concepts.md#bases-integration). -- **Task Views**: TaskNotes provides three views for Bases: "Task List", "Kanban", and "Calendar". -- **Task Properties**: Task properties are displayed on the task cards in the Bases views. -- **Formula Computation**: Use Bases formulas to perform calculations on your task data. +## External Calendars -### Getting Started +TaskNotes supports bidirectional sync with Google Calendar and Microsoft Outlook via OAuth, plus read-only access to any calendar via ICS subscriptions. -To use the Bases integration, you need to have both the TaskNotes and Bases plugins installed and enabled. Bases 1.10.0 or higher is required for Calendar view support. +For setup instructions, see [Calendar Integration](calendar-integration.md). -1. **Enable the Integration**: Open **Settings → TaskNotes → Integrations** and enable the "Bases integration" toggle (restart Obsidian after changing this setting). -2. **Create a View**: In Bases, create a new view and select either the "TaskNotes Task List", "TaskNotes Kanban", or "TaskNotes Calendar" view. +## HTTP API -Your tasks will now be available in the Bases view. +A REST API enables external applications to create, update, and query tasks. Use this for automation, browser extensions, mobile apps, or custom integrations. -### Calendar View +For API documentation, see [HTTP API](../HTTP_API.md). -The Calendar view (requires Bases 1.10.0+) provides multiple viewing modes and supports both task-based and property-based events: +## Webhooks -#### View Modes +Send task data to external services when tasks are created, updated, or completed. Supports custom payload transformations for services like Slack, Discord, and Microsoft Teams. -- Month view -- Week view -- Day view -- Year view -- List view - -#### Event Types - -The Calendar view can display multiple types of events: - -- Tasks with scheduled dates -- Tasks with due dates -- Recurring task instances -- Time tracking entries -- Timeblocks from daily notes -- Property-based events from any notes in the Bases source - -#### Property-Based Events - -Property-based events allow you to display any notes from your Bases source on the calendar by specifying which date properties to use: - -- Configure start date property, end date property, and title property in settings -- Date values can be stored as date properties or text properties containing ISO dates -- Notes with invalid date values are handled gracefully -- Drag-and-drop support updates the date properties in frontmatter - -#### Layout and Display Options - -- Time format (12-hour or 24-hour) -- Weekend visibility toggle -- All-day event slot display -- Today button and highlight -- Configurable scroll time -- Adjustable event height -- Individual visibility toggles for each event type - -#### Date Navigation - -Configure how the calendar determines its initial display date: - -- Hardcoded date option: Set a specific date (YYYY-MM-DD format) for the calendar to display on load -- Property-based navigation: Automatically navigate to dates from filtered note properties -- Three navigation strategies: First result, Earliest date, or Latest date -- Supports both static views and dynamic filtered views - -#### List View - -The list view displays events in a chronological format with custom card rendering for different event types: - -- Task cards show status, priority, and other task properties -- Timeblock cards display duration and associated tasks -- ICS event cards show event details from subscribed calendars -- Property-based event cards display the note title and date range +For configuration, see [Webhooks](../webhooks.md). diff --git a/docs/features/task-management.md b/docs/features/task-management.md index eff6c492..bcbdf366 100644 --- a/docs/features/task-management.md +++ b/docs/features/task-management.md @@ -2,7 +2,7 @@ [← Back to Features](../features.md) -TaskNotes provides a system for managing tasks based on the principle of "one note per task." This approach allows you to create, edit, and organize tasks with a set of properties while maintaining the portability and extensibility of plain text files. +This page covers task creation, properties, projects, dependencies, recurring tasks, and reminders. For the underlying architecture, see [Core Concepts](../core-concepts.md). ## Creating and Editing Tasks @@ -87,23 +87,9 @@ Additionally, you can convert any line type in your notes to TaskNotes using the ## Task Properties -Each task in TaskNotes is a Markdown file with a YAML frontmatter block that stores its properties. The core properties include: +Tasks store their data in YAML frontmatter with properties for status, priority, dates, contexts, projects, tags, time estimates, recurrence, and reminders. Custom fields can extend this structure. -- **Title**: The main description of the task. -- **Status**: The current state of the task (e.g., "Open," "In Progress," "Done"). Status can also be set to boolean values `true` or `false` for compatibility with Obsidian's checkbox properties. -- **Priority**: The importance of the task (e.g., "Low," "Normal," "High"). -- **Due Date**: The date by which the task must be completed. -- **Scheduled Date**: The date on which you plan to work on the task. -- **Contexts**: Location or tool-based groupings (e.g., "@home", "@work"). -- **Projects**: Links to project notes in your vault that the task belongs to. -- **Dependencies**: References to other tasks that must complete before this task can proceed, plus the reciprocal list of tasks blocked by the current one. -- **Tags**: Standard Obsidian tags for categorization. -- **Time Estimate**: The estimated time required to complete the task, in minutes. -- **Recurrence**: The pattern for repeating tasks, using the RRule standard. -- **Time Entries**: An array of recorded work sessions, with start and stop times. -- **Reminders**: Custom reminders to notify you before or at specific times related to the task. - -You can also add your own custom fields to the YAML frontmatter, and use the **Field Mapping** feature to map them to TaskNotes' internal properties. +For property types and examples, see [Core Concepts](../core-concepts.md#yaml-frontmatter). For configuration options, see [Task Properties Settings](../settings/task-properties.md). ## Projects @@ -240,22 +226,6 @@ DTSTART:20250801T100000Z;FREQ=MONTHLY;BYDAY=-1FR → Last Friday of each month at 10:00 AM, starting August 1, 2025 ``` -### Visual Hierarchy in Calendar Views - -The Calendar View displays recurring tasks with distinct visual styling: - -#### Next Scheduled Occurrence -- **Solid border** with full opacity -- Shows at the date/time specified in the `scheduled` field -- Can appear on any date, even outside the recurring pattern -- Dragging updates only the `scheduled` field (manual reschedule) - -#### Pattern Instances -- **Dashed border** with reduced opacity (70%) -- Shows preview of when future recurring instances will appear -- Generated from the DTSTART date/time and recurrence rule -- Dragging updates the DTSTART time (changes all future pattern instances) - ### Dynamic Scheduled Dates The `scheduled` field automatically updates to show the next uncompleted occurrence: @@ -294,19 +264,10 @@ complete_instances: ["2025-08-04"] ### Drag and Drop Behavior -#### Dragging Next Scheduled Occurrence (Solid Border) +In calendar views, recurring tasks display two types of events: -- **Updates**: Only the `scheduled` field -- **Effect**: Reschedules just that specific occurrence -- **Pattern**: Remains unchanged -- **Use case**: "I need to do today's workout at 2 PM instead of 9 AM" - -#### Dragging Pattern Instances (Dashed Border) - -- **Updates**: DTSTART time in the recurrence rule -- **Effect**: Changes when all future pattern instances appear -- **Next occurrence**: Remains independently scheduled -- **Use case**: "I want to change my daily workout from 9 AM to 2 PM going forward" +- **Next occurrence** (solid border): Dragging updates only the `scheduled` field for that specific instance +- **Pattern instances** (dashed border): Dragging updates DTSTART, changing all future pattern instances ### Completion Tracking @@ -542,51 +503,6 @@ Common default reminder configurations: - 1 day before due date (for project deadlines) - Custom absolute reminders for recurring processes -### Integration with Task Workflows +### Technical Details -#### Task Creation Integration - -Reminders integrate with all task creation workflows: - -- Default reminders apply automatically during creation -- Additional reminders can be added during the creation process - -#### Task Editing Integration - -The task editing process provides full reminder management: - -- View all existing reminders -- Add, edit, or remove individual reminders -- Quick access through context menus -- Real-time validation and preview - -#### Calendar View Integration - -Reminders work alongside calendar features: - -- Open reminder actions from calendar event context menus -- Reminder schedules remain intact when you drag and drop tasks to new dates or times - -### Field Mapping Support - -The reminder system integrates with TaskNotes' field mapping functionality: - -- **Custom Property Names**: Map reminders to custom frontmatter property names -- **Vault Compatibility**: Adapt to existing vault structures and naming conventions -- **Migration Support**: Maintain compatibility when changing field mappings - -### Technical Implementation - -#### iCalendar VALARM Compliance - -TaskNotes reminder implementation follows the iCalendar VALARM specification: -- Standard duration formats (ISO 8601) -- Proper trigger mechanisms for relative and absolute reminders -- Compatible data structures for interoperability - -#### Performance Considerations - -The reminder system is designed for efficiency: -- Lazy loading of reminder data -- Minimal impact on task loading performance -- Efficient storage in YAML frontmatter format +Reminders use the iCalendar VALARM specification with ISO 8601 duration formats. The reminder property name can be customized through field mapping in settings. diff --git a/docs/index.md b/docs/index.md index f664d59d..cca7d5ca 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,55 +1,54 @@ # TaskNotes Documentation -TaskNotes is a task and note management plugin for Obsidian that follows the "one note per task" principle. Task information is stored in YAML frontmatter, keeping your data in plain text files that work with any text editor. - -## How It Works - -The plugin treats each task as a separate note with structured metadata in the frontmatter. Tasks have structured data for organization while the note content remains flexible. - -TaskNotes uses Obsidian's metadata cache for compatibility with other plugins. Since task data lives in YAML frontmatter, you can add custom fields and modify property names to match your vault's existing structure. - -The main views (Task List, Kanban, and Calendar) are built using the Bases core plugin and stored as `.base` files in the `TaskNotes/Views/` directory. Bases is an official Obsidian core plugin that must be enabled from Settings → Core Plugins. View configuration is managed through YAML, and filtering is handled directly within each view's configuration rather than through a separate FilterBar component. - -The plugin does not enforce a specific task management methodology. +TaskNotes is a task and note management plugin for Obsidian that follows the "one note per task" principle. Each task is a Markdown file with structured metadata in YAML frontmatter. ## Requirements -- **Obsidian**: Version 1.10.1 or later (TaskNotes v4 relies on the Bases public API introduced in 1.10.1) -- **Bases Core Plugin**: Must be enabled from Settings → Core Plugins (required for Task List, Kanban, Calendar, Agenda, and MiniCalendar views) - -## Features - -Each task supports properties including title, status, priority, due dates, contexts, tags, time estimates, recurrence patterns, and reminders. Custom fields extend this structure. - -Time tracking records work sessions in each task's frontmatter. The Pomodoro timer logs timed work sessions to tasks. - -The plugin provides multiple views. The Task List view handles filtering and organizing tasks. The Kanban board includes optional swimlane layouts for grouping. The Calendar view offers month, week, day, year, and list modes. The Agenda command opens the calendar in list mode for daily or weekly reviews. The MiniCalendar provides fuzzy search and keyboard navigation. The Task List, Kanban, Calendar, Agenda, and MiniCalendar views are implemented as Bases views. The Pomodoro timer is a standalone component. - -Inline task widgets display task information in the editor. Convert existing checkbox tasks or create tasks using natural language processing that parses plain text into structured tasks. Task modal fields are configurable. - -Calendar integration supports ICS feeds and OAuth authentication for Google Calendar and Microsoft Outlook. The Calendar view supports time-blocking and drag-to-reschedule. - -## Why One Note Per Task? - -Each task can contain meeting notes, research, brainstorming, or other content alongside the task itself. - -Tasks can reference other notes, appear in graph view, and show up in backlinks. - -This approach provides structured metadata for filtering and organizing while keeping note content flexible. - -## Plain Text Advantages - -Task data lives in standard Markdown files with YAML frontmatter. You can edit tasks with any text editor, process them with scripts, or migrate them to other systems. - -YAML frontmatter is human-readable. Other Obsidian plugins can work with your task data. You can extend the structure by adding fields. - -Tasks work with version control systems like Git. The plugin uses Obsidian's metadata cache. +- **Obsidian**: Version 1.10.1 or later +- **Bases Core Plugin**: Must be enabled (Settings → Core Plugins → Bases) ## Getting Started -1. **Install and Enable**: Install the plugin from the Obsidian Community Plugins directory -2. **Create Your First Task**: Use the "Create Task" command or convert an existing checkbox -3. **Explore Views**: Try the different view types -4. **Configure Settings**: Customize task properties, views, and integrations +### 1. Install and Enable -The plugin includes default settings that can be customized. Use the navigation menu to explore features, configuration options, and capabilities. +1. Open Obsidian Settings → Community Plugins +2. Browse and search for "TaskNotes" +3. Install and enable the plugin +4. Enable the Bases core plugin: Settings → Core Plugins → Bases + +### 2. Create Your First Task + +**Option A: Command Palette** + +1. Press `Ctrl/Cmd + P` to open the command palette +2. Type "TaskNotes: Create new task" +3. Fill in the task details and click Create + +**Option B: Convert a Checkbox** + +1. In any note, type a checkbox: `- [ ] Buy groceries` +2. Position your cursor on the line +3. Click the convert button that appears, or use "TaskNotes: Create new inline task" + +### 3. Open the Task List + +1. Click the TaskNotes icon in the left ribbon, or +2. Use the command palette: "TaskNotes: Open tasks view" + +### 4. Explore + +- **[Core Concepts](core-concepts.md)**: How tasks work, YAML structure, Bases integration +- **[Features](features.md)**: Task properties, time tracking, calendar integration +- **[Views](views.md)**: Task List, Kanban, Calendar, Agenda, Pomodoro +- **[Settings](settings.md)**: Configuration options + +## Quick Links + +| Topic | Description | +|-------|-------------| +| [Task Management](features/task-management.md) | Status, priority, dates, reminders, recurring tasks | +| [Inline Tasks](features/inline-tasks.md) | Widgets, natural language parsing, checkbox conversion | +| [Calendar Integration](features/calendar-integration.md) | Google Calendar, Outlook, ICS subscriptions | +| [HTTP API](HTTP_API.md) | REST API for automation and external tools | +| [Migration Guide](migration-v3-to-v4.md) | Upgrading from TaskNotes v3 | +| [Troubleshooting](troubleshooting.md) | Common issues and solutions | diff --git a/docs/migration-v3-to-v4.md b/docs/migration-v3-to-v4.md new file mode 100644 index 00000000..96c662d4 --- /dev/null +++ b/docs/migration-v3-to-v4.md @@ -0,0 +1,134 @@ +# Migrating from v3 to v4 + +TaskNotes v4 migrates all views to the Bases system. This guide covers what changed and how to update your setup. + +## Requirements + +- **Obsidian 1.10.1 or later** (required for Bases API) +- **Bases core plugin enabled** (Settings → Core Plugins → Bases) + +## What Changed + +### Views are Now Bases Files + +All task views (Task List, Kanban, Calendar, Agenda) are now `.base` files stored in `TaskNotes/Views/`. This replaces the custom view system in v3. + +| v3 | v4 | +|----|-----| +| Views stored in plugin settings | Views stored as `.base` files | +| Custom filter UI | Bases filter syntax | +| Saved views in settings | Each view is a separate file | + +### Automatic Migration on First Launch + +When you first open TaskNotes v4: + +1. Default `.base` files are created in `TaskNotes/Views/` +2. Ribbon icons and commands now open these `.base` files +3. Your existing task files are unchanged + +### Converting Saved Filter Views + +If you had saved filter views in v3, you can convert them to `.base` files: + +1. Go to Settings → General +2. Find the "Convert Saved Views" button +3. Click to convert your saved views +4. Converted views appear in `TaskNotes/Views/` + +This is a one-way conversion. The original saved views remain in settings until you delete them. + +## Breaking Changes + +### View Configuration + +v3 saved views with custom filters need manual conversion to Bases filter syntax. Simple filters (status, priority, due date) convert automatically. Complex filters may need adjustment. + +**v3 Filter Example:** +``` +status: in-progress +priority: high +``` + +**v4 Bases Syntax:** +```yaml +filters: + and: + - status == "in-progress" + - priority == "high" +``` + +See the [Obsidian Bases documentation](https://help.obsidian.md/Bases/Introduction+to+Bases) for filter syntax details. + +### Minimum Obsidian Version + +v4 requires Obsidian 1.10.1 or later. If you can't upgrade Obsidian, stay on TaskNotes v3. + +## New Features in v4 + +### OAuth Calendar Integration + +v4 adds Google Calendar and Microsoft Outlook integration: + +- View external calendar events alongside tasks +- Drag events to reschedule (syncs back to calendar provider) +- Events sync every 15 minutes + +See [Calendar Setup](calendar-setup.md) for configuration. + +### Kanban Swimlanes + +The Kanban view now supports horizontal swimlane grouping: + +```yaml +views: + - type: tasknotesKanban + groupBy: + property: status + config: + swimLane: priority +``` + +### Time Entry Editor + +A dedicated modal for managing time entries: + +- Alt-drag on calendar to create time entries +- View total tracked time per task +- Edit and delete time entries + +## Troubleshooting + +### Views Not Loading + +1. Verify Bases core plugin is enabled (Settings → Core Plugins) +2. Check that `.base` files exist in `TaskNotes/Views/` +3. Restart Obsidian + +### Missing Saved Views After Upgrade + +Saved views from v3 are preserved in settings. Use the conversion button in Settings → General to create `.base` files from them. + +### Filter Syntax Errors + +Bases uses different filter syntax than v3. Common issues: + +| Problem | Solution | +|---------|----------| +| `status: done` | Use `status == "done"` | +| Multiple conditions | Wrap in `and:` or `or:` block | +| Date comparisons | Use `date(due) < today()` | + +### Downgrading to v3 + +Migration is one-way. If you need to downgrade: + +1. Uninstall TaskNotes v4 +2. Install TaskNotes v3 from releases +3. Reconfigure your saved views manually + +Your task files are unaffected—only view configurations change. + +## View Templates + +For complete `.base` file examples, see [Default Base Templates](views/default-base-templates.md). diff --git a/docs/releases.md b/docs/releases.md index 763087e7..add30576 100644 --- a/docs/releases.md +++ b/docs/releases.md @@ -4,7 +4,21 @@ Welcome to the TaskNotes release notes. Here you can find detailed information a ## Latest Releases -### Version 3.x (Current) +### Version 4.x (Current) + +- [4.1.1](releases/4.1.1.md) +- [4.1.0](releases/4.1.0.md) +- [4.0.5](releases/4.0.5.md) +- [4.0.4](releases/4.0.4.md) +- [4.0.3](releases/4.0.3.md) +- [4.0.2](releases/4.0.2.md) +- [4.0.1](releases/4.0.1.md) +- [4.0.0-beta.3](releases/4.0.0-beta.3.md) +- [4.0.0-beta.2](releases/4.0.0-beta.2.md) +- [4.0.0-beta.1](releases/4.0.0-beta.1.md) +- [4.0.0-beta.0](releases/4.0.0-beta.0.md) + +### Version 3.x - [3.18.2](releases/3.18.2.md) - [3.18.1](releases/3.18.1.md) diff --git a/docs/settings/integrations.md b/docs/settings/integrations.md index 1eafa632..475c0625 100644 --- a/docs/settings/integrations.md +++ b/docs/settings/integrations.md @@ -5,16 +5,9 @@ These settings control the integration with other plugins and services, such as [← Back to Settings](../settings.md) -## Bases integration +## Bases Integration -TaskNotes v4 requires the Bases core plugin for main task views (Calendar, Kanban, Tasks, Agenda) to function. Bases is an official Obsidian core plugin built directly into Obsidian, not a community plugin. - -**To enable Bases:** -1. Open Settings → Core Plugins -2. Enable "Bases" -3. Restart Obsidian - -Once enabled, TaskNotes view commands and ribbon icons will open `.base` files from your vault. Default `.base` files are automatically created in the `TaskNotes/Views/` directory on first launch. +TaskNotes v4 uses Obsidian's Bases core plugin for its main views. For setup instructions, see [Core Concepts](../core-concepts.md#bases-integration). ### View Commands Configuration diff --git a/docs/settings/task-defaults.md b/docs/settings/task-defaults.md index d3b4d8b0..952b3a77 100644 --- a/docs/settings/task-defaults.md +++ b/docs/settings/task-defaults.md @@ -235,232 +235,28 @@ When enabled, the task's title is stored in the filename instead of frontmatter. ## Default Reminders -Default reminders are configured in the **Task Properties** tab within the Reminders property card. Each reminder you configure will be automatically applied to new tasks. +Configure default reminders in **Settings → Task Properties → Reminders**. These reminders automatically apply to new tasks. -### Configuring Default Reminders +### Reminder Types -1. Open TaskNotes settings (Settings → TaskNotes) -2. Navigate to the "Task Properties" tab -3. Expand the "Reminders" property card -4. Use the "Default Reminders" section to add new reminders +**Relative reminders** trigger based on a task's due or scheduled date: +- 15 minutes before due date +- 1 hour before scheduled date +- 2 days before due date -### Default Reminder Types +**Absolute reminders** trigger at a specific date and time, regardless of task dates. -You can configure both types of reminders as defaults: +### Configuration -#### Relative Default Reminders +1. Navigate to Settings → TaskNotes → Task Properties +2. Expand the Reminders card +3. In the Default Reminders section, select type (Relative or Absolute) +4. Configure timing and optional description +5. Click "Add Default Reminder" -Relative default reminders are triggered relative to a task's due date or scheduled date: +Default reminders apply to tasks created via the modal, instant conversion, and natural language parsing. Existing reminders can be viewed, edited, or deleted from the same settings panel. -- **Anchor Date**: Choose between "due date" or "scheduled date" -- **Timing**: Specify the offset (e.g., 15 minutes, 1 hour, 2 days) -- **Direction**: Choose "before" or "after" the anchor date -- **Description**: Optional custom reminder message - -**Example Configurations:** -``` -15 minutes before due date -1 hour before scheduled date -2 days before due date -30 minutes after scheduled date -``` - -#### Absolute Default Reminders - -Absolute default reminders are triggered at specific dates and times: - -- **Date**: Set the specific date for the reminder -- **Time**: Set the specific time for the reminder -- **Description**: Optional custom reminder message - -**Example Configurations:** - -``` -Every Monday at 9:00 AM (for weekly planning) -October 26, 2025 at 2:30 PM (for project deadline) -Tomorrow at 10:00 AM (for follow-up tasks) -``` - -### Default Reminder Application - -Default reminders automatically apply to new tasks created through: - -#### Manual Task Creation - -- Tasks created using the Task Creation Modal -- Default reminders are added automatically based on available anchor dates -- Additional reminders can be added during the creation process - -#### Instant Conversion - -- Tasks created by converting existing content (checkboxes, bullet points, etc.) -- Default reminders apply based on the converted task's properties -- Respects existing due and scheduled dates from natural language parsing - -#### Natural Language Task Creation - -- Tasks created using the natural language parser -- Default reminders integrate with parsed task properties -- Applied after natural language processing is complete - -### Managing Default Reminders - -#### Adding Default Reminders - -Use the form interface in settings to add new default reminders: - -1. **Select Reminder Type**: Choose between "Relative" or "Absolute" -2. **Configure Timing**: Set the specific timing parameters -3. **Add Description**: Optionally add a custom reminder message -4. **Save Configuration**: Click "Add Default Reminder" to save - -#### Editing Default Reminders - -Default reminders can be managed through the settings interface: - -- **View All Defaults**: See a list of all configured default reminders -- **Delete Defaults**: Remove unwanted default reminders -- **Modify Settings**: Edit timing, descriptions, and other parameters - -### Default Reminder Examples - -#### Common Workflow Patterns - -**Getting Things Done (GTD) Setup:** - -``` -15 minutes before due date (quick review) -1 day before due date (preparation time) -``` - -**Time-blocking Setup:** - -``` -30 minutes before scheduled date (preparation) -5 minutes before scheduled date (start notification) -``` - -**Project Management Setup:** - -``` -1 week before due date (progress check) -2 days before due date (final review) -4 hours before due date (completion deadline) -``` - -#### Task Type Specific Defaults - -**Meeting Tasks:** - -``` -30 minutes before scheduled date (preparation) -5 minutes before scheduled date (join notification) -``` - -**Deadline Tasks:** - -``` -1 week before due date (progress milestone) -2 days before due date (completion buffer) -4 hours before due date (final submission) -``` - -**Follow-up Tasks:** - -``` -Absolute reminder: Next Monday at 9:00 AM -Relative reminder: 1 day after due date (if not completed) -``` - -### Integration with Existing Settings - -#### Field Mapping Compatibility - -Default reminders integrate with the Field Mapping system: - -- **Custom Property Names**: Map reminders to custom frontmatter property names -- **Vault Compatibility**: Adapt to existing vault structures -- **Migration Support**: Maintain compatibility when changing field mappings - -#### Template Integration - -Default reminders work alongside template systems: - -- **Applied After Templates**: Default reminders are added after template processing -- **Template Variables**: Templates can reference reminder-related variables -- **Combined Workflows**: Templates and default reminders complement each other - -### Data Storage and Format - -Default reminders are stored in your TaskNotes settings and converted to task reminders when new tasks are created. They maintain the same data structure as task reminders: - -#### Settings Storage Format - -```json -{ - "defaultReminders": [ - { - "id": "def_rem_1678886400000", - "type": "relative", - "relatedTo": "due", - "offset": 15, - "unit": "minutes", - "direction": "before", - "description": "Task review reminder" - }, - { - "id": "def_rem_1678886400001", - "type": "absolute", - "absoluteDate": "2025-10-26", - "absoluteTime": "09:00", - "description": "Weekly planning session" - } - ] -} -``` - -#### Task Application Format - -When applied to tasks, default reminders are converted to the standard reminder format: - -```yaml -reminders: - - id: "rem_1678886400000_abc123xyz" - type: "relative" - relatedTo: "due" - offset: "-PT15M" - description: "Task review reminder" - - id: "rem_1678886400001_def456uvw" - type: "absolute" - absoluteTime: "2025-10-26T09:00:00" - description: "Weekly planning session" -``` - -### Best Practices - -#### Reminder Strategy - -**Start Simple:** Begin with one or two common default reminders and add more as needed. - -**Consider Context:** Different types of tasks may benefit from different reminder patterns. - -**Avoid Overloading:** Too many default reminders can become overwhelming and reduce their effectiveness. - -#### Timing Considerations - -**Buffer Time:** Include enough lead time for preparation and action. - -**Multiple Alerts:** Use multiple reminders for important deadlines (e.g., 1 week, 2 days, 4 hours before). - -**Personal Patterns:** Align reminder timing with your personal work patterns and schedule. - -#### Maintenance - -**Regular Review:** Periodically review and adjust default reminders based on effectiveness. - -**Seasonal Adjustments:** Consider adjusting reminder patterns for different seasons or project types. - -**Feedback Integration:** Use your experience with reminders to refine default configurations. +For detailed reminder documentation, see [Task Reminders](../features/task-management.md#task-reminders). ## Template System diff --git a/docs/troubleshooting.md b/docs/troubleshooting.md index d8b618da..af874163 100644 --- a/docs/troubleshooting.md +++ b/docs/troubleshooting.md @@ -1,6 +1,29 @@ # Troubleshooting -This section covers common issues and their solutions when using TaskNotes. +Common issues and solutions for TaskNotes. + +## Bases and Views (v4) + +### Views Not Loading + +**Symptoms**: TaskNotes views show errors or don't display tasks + +**Solutions**: + +1. Enable the Bases core plugin: Settings → Core Plugins → Bases +2. Restart Obsidian after enabling Bases +3. Check that `.base` files exist in `TaskNotes/Views/` +4. Use Settings → TaskNotes → Integrations → "Create default files" to regenerate view files + +### Commands Open Wrong Files + +**Symptoms**: Ribbon icons or commands open unexpected files + +**Solutions**: + +1. Check view file paths in Settings → TaskNotes → Integrations → View Commands +2. Click "Reset" next to each command to restore default paths +3. Verify the `.base` files exist at the configured paths ## Common Issues @@ -59,35 +82,23 @@ This section covers common issues and their solutions when using TaskNotes. **Symptoms**: Calendar views are slow or unresponsive -**Possible Causes**: - -- Large number of tasks or external calendar events -- Multiple ICS subscriptions with frequent refresh -- Complex recurring task patterns - **Solutions**: -1. Disable unused event types in calendar view toggles +1. Disable unused event types (scheduled, due, recurring, time entries) in view settings 2. Increase ICS subscription refresh intervals -3. Consider disabling note indexing in Misc settings if you don't use the Notes view -4. Reduce the number of external calendar subscriptions +3. Reduce the date range displayed +4. See [Performance Troubleshooting](#performance-troubleshooting) for general tips ### Natural Language Parsing Not Working **Symptoms**: Natural language input doesn't extract expected task properties -**Possible Causes**: - -- Natural language processing is disabled -- Input format doesn't match supported patterns -- Custom status/priority words not configured - **Solutions**: -1. Enable "Natural language input" in Task Defaults settings -2. Review supported syntax in the Natural Language Processing documentation -3. Configure custom priority and status words if using non-default values -4. Try simpler input patterns to test basic functionality +1. Enable "Natural language input" in Settings → TaskNotes → Features +2. Check trigger characters match your input (default: `@` for contexts, `#` for tags, `!` for priority) +3. Configure custom status/priority words in Settings → TaskNotes → Task Properties +4. See [NLP API](nlp-api.md) for supported syntax ### Time Tracking Issues @@ -147,23 +158,47 @@ This section covers common issues and their solutions when using TaskNotes. **Solutions**: -1. Disable note indexing in Misc settings if you don't use the Notes view -2. Reduce the number of external calendar subscriptions -3. Exclude large folders from note processing -4. Consider using simpler status and priority configurations +1. Reduce the number of external calendar subscriptions +2. Increase ICS refresh intervals (Settings → Integrations → Calendar subscriptions) +3. Exclude large folders (Settings → General → Excluded folders) +4. Disable unused calendar event types in view settings ## External Calendar Issues +### OAuth Calendar Not Connecting + +**Symptoms**: Google Calendar or Microsoft Outlook won't connect + +**Solutions**: + +1. Verify Client ID and Client Secret are correct (no extra spaces) +2. Check redirect URI matches exactly: `http://localhost:42813/callback` +3. Ensure the OAuth app is published or you're listed as a test user +4. Try disconnecting and reconnecting +5. Check browser popup blockers aren't blocking the auth window +6. See [Calendar Setup](calendar-setup.md) for detailed OAuth configuration + +### OAuth Calendar Not Syncing + +**Symptoms**: Connected calendar shows old events or doesn't update + +**Solutions**: + +1. Click the manual refresh button in Settings → Integrations +2. Check "Last sync time" to see when data was last fetched +3. Disconnect and reconnect the calendar +4. Verify events exist in the source calendar + ### ICS Subscriptions Not Loading -**Symptoms**: External calendar events don't appear in calendar views +**Symptoms**: ICS calendar events don't appear in calendar views **Solutions**: 1. Verify ICS URL is correct and accessible 2. Check network connection and firewall settings 3. Try manual refresh of the subscription -4. Validate ICS feed using online ICS validators +4. Validate ICS feed using an online ICS validator 5. Check error messages in subscription status ### Calendar Sync Problems @@ -175,35 +210,28 @@ This section covers common issues and their solutions when using TaskNotes. 1. Check refresh interval settings for the subscription 2. Manually refresh the subscription 3. Verify the external calendar is actually updated at the source -4. Clear cached calendar data by removing and re-adding subscription +4. Remove and re-add the subscription to clear cached data ## Getting Help -### Diagnostic Information +### Reporting Issues -When reporting issues, include: +Report bugs on [GitHub Issues](https://github.com/callumalpass/tasknotes/issues). Include: -1. TaskNotes version number -2. Obsidian version -3. Operating system -4. Specific error messages -5. Steps to reproduce the issue -6. Screenshots if relevant - -### Community Support - -- Check the GitHub repository for existing issues -- Search community forums for similar problems -- Review documentation for configuration guidance +- TaskNotes and Obsidian versions +- Operating system +- Steps to reproduce +- Error messages (open console with `Ctrl/Cmd + Shift + I`) +- Screenshots if relevant ### Configuration Reset -If all else fails, you can reset TaskNotes configuration: +If all else fails, reset TaskNotes configuration: 1. Close Obsidian 2. Navigate to `.obsidian/plugins/tasknotes/` 3. Rename or delete `data.json` -4. Restart Obsidian (this will reset all settings to defaults) +4. Restart Obsidian -!!! warning "Important" - Resetting configuration will lose all custom settings, status configurations, and ICS subscriptions. Export or document your current settings before resetting. +!!! warning + This resets all settings, status configurations, and calendar subscriptions. Document your settings before resetting. diff --git a/docs/views.md b/docs/views.md index 4e1d0dd7..eea44583 100644 --- a/docs/views.md +++ b/docs/views.md @@ -4,21 +4,10 @@ TaskNotes provides multiple views for managing tasks and tracking productivity. [← Back to Documentation](index.md) -## Bases Plugin Requirement - -All task-focused views in TaskNotes v4 use Obsidian's **Bases core plugin**. This is an official Obsidian plugin built directly into the application, not a community plugin. - -**To enable Bases:** -1. Open Settings → Core Plugins -2. Enable "Bases" -3. TaskNotes view commands and ribbon icons will open `.base` files from `TaskNotes/Views/` - -Bases views use YAML configuration in `.base` files to define filtering, sorting, and grouping behavior. View configurations from TaskNotes v3 must be manually converted to `.base` file format. See [Default Base Templates](views/default-base-templates.md) for complete template examples. +For details on Bases integration and how to enable it, see [Core Concepts](core-concepts.md#bases-integration). For view templates and configuration examples, see [Default Base Templates](views/default-base-templates.md). ## Task-Focused Views -All task-focused views are implemented as Bases views using `.base` files. - - **[Task List View](views/task-list.md)**: Displays tasks in a list format. Supports filtering, sorting, and grouping via YAML configuration in the `.base` file. - **[Kanban View](views/kanban-view.md)**: Displays tasks as cards organized by status. Supports optional swimlane layout for additional organization. - **[Calendar Views](views/calendar-views.md)**: Calendar-based task visualization with multiple view modes (month, week, day, year, list). Supports drag-and-drop scheduling, time-blocking, and OAuth calendars. diff --git a/docs/views/kanban-view.md b/docs/views/kanban-view.md index 41c0a3c5..5530c237 100644 --- a/docs/views/kanban-view.md +++ b/docs/views/kanban-view.md @@ -2,23 +2,11 @@ [← Back to Views](../views.md) -The Kanban View displays tasks as cards organized in columns, where each column represents a distinct value of a grouped property. This view operates within Obsidian's Bases core plugin. - -## Bases Architecture - -The Kanban view functions as a Bases view type. It reads data from `.base` files located in your vault's `TaskNotes/Views/` directory. These files contain YAML frontmatter that defines the view configuration, including data source, filtering, sorting, and Kanban-specific options. - -### Requirements - -- Obsidian 1.10.1 or later -- Bases core plugin enabled -- A `groupBy` property configured in the view settings - -The `groupBy` property determines the column structure. Each unique value of this property becomes a column in the Kanban board. +The Kanban View displays tasks as cards organized in columns, where each column represents a distinct value of a grouped property. ## Configuration -Kanban views are configured through the Bases interface. Open a `.base` file and access the view settings panel to configure options. +Kanban views are stored as `.base` files in `TaskNotes/Views/`. The `groupBy` property determines the column structure—each unique value becomes a column in the board. Open a `.base` file and access the view settings panel to configure options. ### Core Settings (Bases) diff --git a/mkdocs.yml b/mkdocs.yml index afa0fc00..a08ebf49 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -73,10 +73,7 @@ nav: - NLP API: nlp-api.md - Webhooks: webhooks.md - Workflows: workflows.md - - Advanced Topics: - - Timezone Handling: TIMEZONE_HANDLING_GUIDE.md - - UTC Implementation: TIMEZONE_HANDLING_UTC.md - - Timezone Quick Reference: TIMEZONE_QUICK_REFERENCE.md + - Migration Guide: migration-v3-to-v4.md - Development: - Translation Workflow: development/translations.md - i18n-state-manager: development/i18n-state-manager.md