Commit graph

17548 commits

Author SHA1 Message Date
Johannes Millan
a42c8a4cee Merge branch 'master' into feat/operation-logs
* master:
  refactor(dialog): remove unused OnDestroy implementation from DialogAddNoteComponent
  fix(calendar): poll all calendar tasks and prevent auto-move of existing tasks
  docs: add info about how to translate stuff #5893
  refactor(calendar): replace deprecated toPromise with firstValueFrom
  build: update links to match our new organization
  add QuestArc to community plugins list
  feat(calendar): implement polling for calendar task updates and enhance data retrieval logic
  fix(heatmap): use app theme class instead of prefers-color-scheme
  fix(focus-mode): start break from banner when manual break start enabled
  feat(i18n): connect Finnish and Swedish translation files
  refactor(focus-mode): split sessionComplete$ and breakComplete$ into single-responsibility effects
  Fixing Plugin API doc on persistence

# Conflicts:
#	src/app/features/issue/store/poll-issue-updates.effects.ts
#	src/app/t.const.ts
2026-01-05 19:12:46 +01:00
Johannes Millan
ef171790fb refactor(dialog): remove unused OnDestroy implementation from DialogAddNoteComponent 2026-01-05 18:42:48 +01:00
Johannes Millan
a7c780a444 test: add comprehensive tests for TaskService and StartupService
TaskService (45 tests):
- Task selection, lifecycle, updates, ordering
- Subtask management, archiving, project transfer
- Scheduling, time tracking, task creation

StartupService (16 tests):
- Initialization flow with BroadcastChannel mocking
- App rating logic (day tracking, dialog triggers)
- Tour detection, plugin init, storage persistence
2026-01-05 18:31:46 +01:00
Johannes Millan
c2b7627125 fix(calendar): poll all calendar tasks and prevent auto-move of existing tasks
- Poll ALL calendar tasks across all projects, not just current context
- Replace forkJoin with merge (forkJoin never emits with timer)
- Add selectAllCalendarIssueTasks selector for cross-project calendar tasks
- Prevent existing ICAL tasks from being auto-moved to current context
- Add error handling to prevent polling stream termination on errors
- Add comprehensive tests for polling effects and selector

Fixes #4474
2026-01-05 18:26:57 +01:00
Johannes Millan
08971fce47 docs: add info about how to translate stuff #5893 2026-01-05 18:05:45 +01:00
Johannes Millan
f0f536671b test(server): fix testing gaps and failing tests
1. Add DELETE /api/sync/data route tests to sync.routes.spec.ts:
   - Test successful deletion returns { success: true }
   - Test 401 without authorization
   - Test uploading new data works after reset

2. Fix passkey.spec.ts failures (4 tests):
   - Add missing passkey.findUnique mock for credential lookup
   - Update test expectations for discoverable credentials
     (no allowCredentials - implementation changed)

3. Fix password-reset-api.spec.ts failures (12 tests):
   - Exclude from vitest - tests routes that don't exist
   - Server uses passkey/magic link auth, not password auth

All 412 tests now pass.
2026-01-05 17:39:17 +01:00
Johannes Millan
24d3fb6fab Merge remote-tracking branch 'origin/master'
* origin/master:
  add QuestArc to community plugins list
  Fixing Plugin API doc on persistence
2026-01-05 17:36:12 +01:00
Johannes Millan
001d89d58e fix(test): update operation-log.effects.spec.ts mocks for new dependencies
Update test mocks to match implementation changes in OperationLogEffects:

- Add ClientIdService mock (replaces pfapiService.metaModel.loadClientId)
- Add OperationCaptureService mock (for dequeue() calls)
- Add clearVectorClockCache to OperationLogStoreService mock
- Remove obsolete Injector and mockPfapiService dependencies
- Update "cache clientId" test to use mockClientIdService

Fixes 18 failing unit tests.
2026-01-05 16:51:23 +01:00
Johannes Millan
e38b5967c2 refactor(calendar): replace deprecated toPromise with firstValueFrom
- Modernize async code in CalendarCommonInterfacesService
- Add 5 integration tests for polling feature:
  - Provider batching verification
  - Mixed provider success/failure scenarios
  - Input validation for missing IDs
  - Multi-field change detection
  - Poll interval configuration test
- Fix timezone-sensitive test for all-day event conversion
2026-01-05 16:50:55 +01:00
Johannes Millan
b3131bea1e
Merge pull request #5892 from suitably/master
add QuestArc to community plugins list
2026-01-05 16:50:06 +01:00
Johannes Millan
b893c1373f fix(sync): remove task from planner.days[today] when transferring away
When a task was transferred from today to another day, it was not being
removed from planner.days[today] due to the `prevDay === today` skip
condition. This caused AddTasksForTomorrowService to find stale tasks
in planner.days[today] and re-add them to today via planTasksForToday,
which reset task.dueDay back to today - effectively reverting the
user's planner changes after sync.

The fix removes the `prevDay === today` condition so tasks are properly
removed from planner.days[today] when transferred away. TODAY_TAG.taskIds
still handles today's task ordering, but planner.days[today] now stays
consistent with task.dueDay.

Added 3 edge case tests:
- Verify task.dueDay is updated when transferring from today
- Handle transfer when planner.days[today] doesn't exist
- Handle transfer when task isn't in planner.days[today]

Also fixes pre-existing broken tests in:
- task-reminder.effects.spec.ts (removed obsolete tests for removed effect)
- plugin-hooks.effects.spec.ts (fixed invalid action property)
2026-01-05 16:26:48 +01:00
Johannes Millan
e641b89187 test(server): add unit tests for deleteAllUserData (Reset Account)
Add comprehensive unit tests for the reset account functionality:

- Test that deleteAllUserData removes all operations for a user
- Test that new operations can be uploaded after reset
- Test that resetting one user doesn't affect other users' data

Also adds missing userSyncState.deleteMany mock to the test setup.
2026-01-05 15:47:43 +01:00
Johannes Millan
1a79592aca build: update links to match our new organization 2026-01-05 14:45:06 +01:00
suitably
573819b3fe
add QuestArc to community plugins list 2026-01-05 13:26:15 +01:00
Johannes Millan
5ee3fb2e23 feat(calendar): implement polling for calendar task updates and enhance data retrieval logic
#4474
2026-01-05 13:20:44 +01:00
Johannes Millan
f9635423d6 feat(server): add Account Settings page with reset and delete options
Add a dedicated Account Settings page to the SuperSync server web interface:

- Move Reset Account and Delete Account buttons from token display to
  separate Account Settings page for better UX
- Reset Account clears all synced data but keeps account active
- Delete Account permanently removes account and all data
- Add E2E tests for account reset functionality

Closes #5848
2026-01-05 12:54:53 +01:00
Johannes Millan
159b28948f fix(heatmap): use app theme class instead of prefers-color-scheme
Replace @media (prefers-color-scheme: dark) with :host-context(.isDarkTheme)
so heatmap labels adapt to app-level theme switching, not just OS preference.

- Use var(--text-color-muted) for label text colors (auto-adapts to theme)
- Use CSS variables for backgrounds, scrollbars, and outlines
- Remove hardcoded rgba() colors in favor of theme-aware variables

Fixes #5883
2026-01-05 12:20:18 +01:00
Johannes Millan
7838d34fb0 fix(focus-mode): start break from banner when manual break start enabled
When using Pomodoro with "Manually start breaks" and "Start focus sessions
with banner only", pressing the play button after session completion now
correctly starts a break instead of a new session.

Fixes #5889
2026-01-05 12:20:08 +01:00
Johannes Millan
2e890fc0d6 fix(e2e): skip supersync tests when server unavailable
Move health check into testRunId fixture so all supersync tests
automatically skip when the server isn't running. Previously, tests
would fail with ECONNREFUSED and count toward the 5-failure limit,
interrupting the entire test run.
2026-01-05 11:50:51 +01:00
Johannes Millan
d033b9b43b feat(i18n): connect Finnish and Swedish translation files
Add fi.json and sv.json to the language configuration so users can
select Finnish (Suomi) and Swedish (Svenska) in the settings.
2026-01-05 11:34:50 +01:00
Johannes Millan
9e1c695665
Merge pull request #5891 from baflo/persistence-doc
Fixing Plugin API doc on persistence
2026-01-05 11:30:07 +01:00
Johannes Millan
ec8c4bdb8e refactor(focus-mode): split sessionComplete$ and breakComplete$ into single-responsibility effects
Split monolithic effects into focused, testable units:

sessionComplete$ (5+ concerns) → 4 effects:
- incrementCycleOnSessionComplete$: Pomodoro cycle management
- stopTrackingOnManualEnd$: Stop tracking on manual end (bug #5875)
- autoStartBreakOnSessionComplete$: Auto-start break after session
- notifyOnSessionComplete$: User notification

breakComplete$ (3 concerns) → 3 effects:
- resumeTrackingOnBreakComplete$: Resume tracking after break
- autoStartSessionOnBreakComplete$: Auto-start next session
- notifyOnBreakComplete$: User notification

Added 16 new tests before refactoring (TDD approach).
All 3265 tests pass.
2026-01-05 11:23:46 +01:00
Florian Bachmann
3bc5bb28cd
Fixing Plugin API doc on persistence 2026-01-05 08:03:07 +01:00
Johannes Millan
e046eb9100 fix(e2e): limit supersync test workers to prevent server crash
SuperSync tests create 2-3 browser contexts per test. Running with
12 workers resulted in 24-36 simultaneous connections overwhelming
the Angular dev server, causing ERR_CONNECTION_REFUSED errors.

Changes:
- Add --workers=3 to e2e:supersync and e2e:supersync:file scripts
- Add documentation to supersync.fixture.ts explaining the issue
2026-01-04 18:47:02 +01:00
Johannes Millan
1057b8ebdb fix(e2e): improve stability of flaky sync tests
supersync.page.ts:
- Skip encryption checkbox handling when isEncryptionEnabled is undefined
  (fixes server migration test timeout)
- Add waitFor() and settle delay before checkbox interactions
- Increase checkbox toggle timeout from 10s to 15s

supersync-models.spec.ts:
- Add extra sync cycle after tag deletion for complete synchronization
- Use toPass() with 15s timeout for tag visibility checks
- Reduces wait times but adds more robust retry logic

supersync-lww-conflict.spec.ts:
- Add explicit waitFor() before task interactions
- Add 100ms settle delay after hover for reliable button clicks
- Add timeout to toHaveClass assertions
2026-01-04 18:43:10 +01:00
Johannes Millan
3f3f0685eb Merge branch 'master' into feat/operation-logs
* master: (21 commits)
  test: increase timeout for encryption
  16.8.3
  fix(e2e): use pressSequentially for time input in task-detail tests
  fix(sync): resolve 25-second initial sync timeout race condition
  feat(e2e): add Docker-based E2E test isolation
  fix(schedule): start tracking selected task when pressing Y in schedule view
  fix(tasks): clear reminder when clicking "today" button on already-today tasks
  fix(e2e): use format-agnostic time change in task-detail tests
  16.8.2
  fix(test): reset selector overrides to prevent test pollution
  build: update CLAUDE.md
  fix(calendar): add periodic refresh for planner and scheduler views
  feat(effects): consolidate task update actions in PluginHooksEffects
  fix(sync): show skip button immediately when offline
  fix(db): add missing _afterReady guard to loadAll method
  feat(android): add alarm sound and vibration to task reminders
  feat(sync): add skip button to loading screen when waiting for sync
  fix(pomodoro): allow manual session end to start break early
  fix(i18n): add missing translate pipe to play button tooltip
  fix(tasks): handle undefined tasks in reminder effect
  ...

# Conflicts:
#	CLAUDE.md
#	docker-compose.e2e.yaml
#	e2e/tests/task-detail/task-detail.spec.ts
#	package.json
#	src/app/features/tasks/store/task-reminder.effects.spec.ts
#	src/app/features/tasks/store/task-reminder.effects.ts
#	src/app/plugins/plugin-hooks.effects.ts
2026-01-04 18:20:10 +01:00
Johannes Millan
32b6e22fe8 test: increase timeout for encryption 2026-01-04 18:08:46 +01:00
Johannes Millan
f37110bbb5 fix(e2e): improve test stability for parallel execution
SuperSync page object improvements:
- Add networkidle wait before interacting with sync dialog
- Add explicit mat-dialog-container wait before form interaction
- Add toBeAttached() assertions for element stability
- Use toPass() with progressive backoff for dropdown interactions
- Dismiss existing dropdown overlays before retrying
- Add blur() calls in password change dialog for Angular validation
- Add try-catch for fresh client dialog race condition

Task detail tests:
- Add blur() after time input fill to ensure Angular registers
  the change before clicking Save

These changes fix intermittent failures when running E2E tests
with multiple workers in parallel.
2026-01-04 17:35:47 +01:00
Johannes Millan
2cc06178e5 16.8.3 2026-01-04 17:27:04 +01:00
Johannes Millan
333c3a16bc fix(e2e): use pressSequentially for time input in task-detail tests
The fill() method on time combobox wasn't triggering proper change events.
Use clear() + pressSequentially() + Tab to properly commit the time change
before clicking Save.
2026-01-04 17:20:29 +01:00
Johannes Millan
570a0b590d fix(sync): resolve 25-second initial sync timeout race condition
The debounceTime(1000) added in 871ee354c delayed ALL emissions by 1 second,
including the initial value. When sync.effects.ts used withLatestFrom(isOnline$)
and the app initialized faster than 1 second, the observable chain hung forever
because withLatestFrom requires the other observable to have already emitted.

Add startWith(navigator.onLine) after debounceTime to provide an immediate
initial value while still debouncing subsequent online/offline events.

Fixes #5868, #5877
2026-01-04 17:15:50 +01:00
Johannes Millan
40d7118e17 feat(e2e): add Docker-based E2E test isolation
Add Docker setup for running E2E tests with the Angular dev server
containerized while Playwright runs on the host. Supports multiple
instances via configurable ports.

New files:
- Dockerfile.e2e.dev: Dev server image
- docker-compose.e2e.yaml: E2E orchestration config
- scripts/wait-for-app.sh: Health check script

New npm scripts:
- e2e:docker: Run E2E with containerized app
- e2e:docker:webdav: Same but includes WebDAV for sync tests

Usage: APP_PORT=4343 npm run e2e:docker
2026-01-04 17:09:39 +01:00
Johannes Millan
acedc67f2a fix(schedule): start tracking selected task when pressing Y in schedule view
When a user clicked on a task in the Schedule view and pressed Y to start
time tracking, a different task was being tracked instead. This happened
because Schedule view only sets selectedTaskId (for the detail panel) but
not focusedTaskId (used by keyboard shortcuts).

The fix modifies TaskShortcutService to use selectedTaskId as a fallback
when focusedTaskId is null, specifically for the togglePlay (Y) shortcut.

Priority order:
1. If focusedTaskId exists → delegate to TaskComponent (existing behavior)
2. If no focusedTaskId but selectedTaskId exists → toggle tracking for selected task
3. If neither exists → use global toggle behavior

Fixes #5884
2026-01-04 17:07:29 +01:00
Johannes Millan
2af57d2b4a fix(tasks): clear reminder when clicking "today" button on already-today tasks
When a task was scheduled for today with a time-based reminder, clicking
the "today" quick access button in the context menu was creating a new
reminder instead of clearing it. This was because the _schedule method
detected dueWithTime and called scheduleTask() which creates a reminder.

Now the method first checks if the task is already scheduled for today
with time and we're planning for today - in that case, it calls
addToMyDay() which properly clears the reminder via planTasksForToday.

Fixes #5872
2026-01-04 16:59:26 +01:00
Johannes Millan
098e19f9ca fix(e2e): use format-agnostic time change in task-detail tests
The tests assumed 12-hour AM/PM format, but the app defaults to en_gb
locale which uses 24-hour format. Changed to increment hour instead
of flipping AM/PM, which works with both formats.
2026-01-04 16:20:18 +01:00
Johannes Millan
70f1e4ba73 16.8.2 2026-01-04 14:57:50 +01:00
Johannes Millan
d4b40e80d5 fix(test): reset selector overrides to prevent test pollution
Add store.resetSelectors() in afterEach to prevent MockStore selector
overrides from persisting and affecting other test files.
2026-01-04 14:56:08 +01:00
Johannes Millan
d8a6a7dc62 build: update CLAUDE.md 2026-01-04 14:52:35 +01:00
Johannes Millan
77c4c33988 fix(calendar): add periodic refresh for planner and scheduler views
The icalEvents$ observable now refreshes periodically using a timer-based
approach. This ensures calendar events update in planner and scheduler
views without requiring an app restart.

Key changes:
- Add LOCAL_FILE_CHECK_INTERVAL (5 min) for file:// URLs
- Add getEffectiveCheckInterval() to determine poll interval per provider
- Refactor icalEvents$ to use timer(0, minInterval) for periodic refresh
- Move shareReplay to outer observable to prevent memory leaks
- Add comprehensive test coverage (84 tests)

Fixes #4474
2026-01-04 14:14:25 +01:00
Johannes Millan
386c636e5f feat(effects): consolidate task update actions in PluginHooksEffects 2026-01-04 13:03:28 +01:00
Johannes Millan
ccd4846b88 fix(sync): show skip button immediately when offline
When sync is enabled and the device is offline, show the skip sync
button immediately (~1 second) instead of waiting 3 seconds. This
improves startup UX when network is unavailable.

Fixes #5877
2026-01-04 12:54:21 +01:00
Johannes Millan
270eca3600 fix(db): add missing _afterReady guard to loadAll method
Fixes race condition where loadAll() could access the database before
initialization completes, causing "database connection is closing" errors.

Fixes #5734
2026-01-04 12:45:54 +01:00
Johannes Millan
b7cbef2f79 feat(android): add alarm sound and vibration to task reminders
Use default alarm ringtone with USAGE_ALARM audio attributes so
reminders play even when phone is on silent. Add vibration pattern
and change notification category from REMINDER to ALARM.

Fixes #5603
2026-01-04 12:45:00 +01:00
Johannes Millan
12e68cdb0e feat(sync): add skip button to loading screen when waiting for sync
Adds a "Skip waiting for sync" button that appears after 3 seconds on
the loading screen. This allows users to proceed with local data while
sync continues in the background.

Fixes #5868
2026-01-04 12:36:00 +01:00
Johannes Millan
291d3e8caf fix(pomodoro): allow manual session end to start break early
Remove the `!action.isManual` check from shouldAutoStartBreak condition,
so manually ending a Pomodoro session now triggers a break (or shows
"Start Break" button if isManualBreakStart is enabled).

Fixes #5876
2026-01-04 12:12:49 +01:00
Johannes Millan
abfff278a4 fix(i18n): add missing translate pipe to play button tooltip
Fixes #5874
2026-01-04 12:07:14 +01:00
Johannes Millan
4497aed317 fix(tasks): handle undefined tasks in reminder effect
Add optional chaining to prevent TypeError when planTasksForToday
is triggered with task IDs that no longer exist in the store.

Fixes #5873
2026-01-04 12:06:33 +01:00
Johannes Millan
55fc8551cd fix(focus-mode): sync time tracking with Pomodoro breaks and manual end
- Skip break when user starts time tracking during break (syncs state)
- Stop time tracking when session is manually ended via "End Session"

Fixes #5875
2026-01-04 12:05:34 +01:00
Johannes Millan
7436c20167 refactor: cleanup 2026-01-03 18:52:10 +01:00
Johannes Millan
85fa50974b Merge branch 'master' into feat/operation-logs
* master:
  refactor(e2e): improve test infrastructure for easier expansion
  chore(e2e): remove broken/empty skipped tests
  test(e2e): fix flaky plugin and WebDAV sync tests
  refactor(e2e): replace waitForTimeout with condition-based waits
  perf(e2e): remove ineffective waits to speed up test runs
  docs(e2e): add CLAUDE.md reference and barrel export for easier test creation
  build: update dep
  refactor(e2e): simplify waits and fix flaky tests
  feat(e2e): streamline e2e test development with improved infrastructure
  perf(e2e): optimize wait utilities and addTask method for faster test execution
  16.8.1

# Conflicts:
#	e2e/pages/base.page.ts
#	e2e/pages/project.page.ts
#	e2e/tests/reminders/reminders-schedule-page.spec.ts
#	e2e/tests/sync/webdav-sync-advanced.spec.ts
#	e2e/tests/sync/webdav-sync-expansion.spec.ts
#	e2e/tests/sync/webdav-sync-full.spec.ts
#	e2e/utils/waits.ts
2026-01-03 18:51:51 +01:00