Commit graph

17665 commits

Author SHA1 Message Date
Johannes Millan
42b0d65352 fix(e2e): dismiss Welcome intro dialog before Shepherd tour
The E2E tests were failing because dismissTourIfVisible only handled
the Shepherd tour steps, not the Welcome intro mat-dialog that appears
first. This dialog blocks UI interactions causing test timeouts.

Updated tour-helpers.ts to:
- Add dismissWelcomeDialog() for the intro dialog
- Add dismissShepherdTour() for the tour steps
- Update dismissTourIfVisible() to handle both in sequence
2026-01-09 18:28:18 +01:00
Johannes Millan
cabe73177a Merge branch 'master' into feat/operation-logs
* master:
  16.9.1
  fix(e2e): handle task deletion confirmation dialog in WebDAV sync test
  fix: resolve build failures from missing translations and unused imports
  16.9.0
  Added Scoop installation instructions
2026-01-09 18:00:51 +01:00
Johannes Millan
b099ffe627 build(e2e): add fast local Docker Compose setup for E2E tests 2026-01-09 18:00:24 +01:00
Johannes Millan
79276f3fc7 16.9.1 2026-01-09 17:59:07 +01:00
Johannes Millan
9c7549af40 fix(e2e): handle task deletion confirmation dialog in WebDAV sync test
The test was failing because task deletion now shows a confirmation
dialog by default (isConfirmBeforeTaskDelete=true). Added handling
to click the confirm button before expecting the task count to change.
2026-01-09 17:59:06 +01:00
Johannes Millan
dae5caa6ff fix: resolve build failures from missing translations and unused imports
Remove unused imports (MatSlideToggle, MatFormField, MatLabel, TranslatePipe,
RouterLink) and add missing translation keys for CalDAV issue content, G.SHARE,
and WORKLOG restore task from archive.
2026-01-09 17:59:06 +01:00
Johannes Millan
cdf52cc4e5 fix(e2e): split docker-compose files for standalone webdav tests
docker-compose.e2e.yaml was failing when used standalone because the
supersync service only had a port override without a base definition.
Split into separate files so e2e:docker:webdav works without errors.
2026-01-09 17:27:30 +01:00
Johannes Millan
ca98d2c936 fix(e2e): use correct selector for confirm button in task-crud test
The confirm button has type="button" with e2e="confirmBtn" attribute,
not type="submit". Updated selector to match the actual button.
2026-01-09 17:18:36 +01:00
Johannes Millan
723896e9bc fix: resolve compilation errors after merge
- Add missing T.PS.RELOAD translation key
- Add missing T.GLOBAL section with COPY_SUFFIX key
- Fix TaskArchiveService import path in repeat-task-heatmap component
- Remove stale task-archive.service.js compiled file
2026-01-09 17:04:29 +01:00
Johannes Millan
150fd074ab Merge branch 'master' into feat/operation-logs
Integrate master branch updates into operation-logs feature branch:
- Add heatmap components and scheduled date group pipe
- Add task delete confirmation dialog and tests
- Update Android focus mode and sound configuration
- Add GitLab PAT authentication support
- Merge translation keys and i18n updates
2026-01-09 16:57:25 +01:00
Johannes Millan
b3dfd1f6a2
Merge pull request #5914 from Gitoffthelawn/patch-1
Added Scoop installation instructions
2026-01-09 16:57:12 +01:00
Johannes Millan
4919ab188b 16.9.0 2026-01-09 16:41:59 +01:00
Johannes Millan
1acef88877 Merge remote-tracking branch 'origin/master'
* origin/master:
  Update Chinese localization strings in zh.json

# Conflicts:
#	src/assets/i18n/zh.json
2026-01-09 16:39:30 +01:00
Johannes Millan
a2e1f932f4 fix: address code review issues from daily review
- Apply runtime default for isConfirmBeforeTaskDelete to ensure existing users get confirmation dialog
- Add takeUntil cleanup for dialog subscription in context menu
- Move _isTaskDeleteTriggered flag before delete call to prevent race condition
- Replace alert() with PFLog.warn() for non-blocking notification
- Change any to unknown type for better type safety
- Localize month names using DateAdapter instead of hardcoded English strings
- Remove duplicate monthNames array declaration (DRY)
2026-01-09 16:25:41 +01:00
Johannes Millan
73690c3766 feat(task-repeat): add history heatmap to repeat config dialog
Extract reusable heatmap component from activity-heatmap and add
a new repeat-task-heatmap that shows time spent history for
repeatable task instances in the configuration dialog.
2026-01-09 15:55:17 +01:00
Johannes Millan
7bf9e9393e fix(imex): auto-fix deprecated metric/improvement array fields on import
Add handlers to autoFixTypiaErrors to fix validation errors for deprecated
fields that will be removed in future:
- metric.entities[*].obstructions, improvements, improvementsTomorrow
- improvement.hiddenImprovementBannerItems

These fields are now auto-fixed to empty arrays when missing/undefined,
allowing import of older backups without validation failures.
2026-01-09 15:43:55 +01:00
Johannes Millan
d2a13d21e3 fix(imex): show validation error details on import failure
Include failed field paths in DataValidationFailedError message and
display them in the snackbar, making it easier to debug import issues.
2026-01-09 15:43:39 +01:00
Johannes Millan
10d652a382 fix(reminder): invoke cfg signal correctly to access reminder config 2026-01-09 15:36:27 +01:00
Johannes Millan
45826b8bcf
Merge pull request #5945 from dXrayb/patch-13
Update Chinese localization strings in zh.json
2026-01-09 15:33:21 +01:00
Johannes Millan
93c319830f fix(gitlab): use consistent update detection logic across methods
Apply GitHub's OR pattern to fix timing bug while preserving filterUsername.
Refactor getFreshDataForIssueTasks to call getFreshDataForIssueTask (DRY).

Fixes inconsistency from #5944 where only one method was updated.
2026-01-09 15:11:16 +01:00
Johannes Millan
dfa6a94a4b fix(android): show notification with sound when focus mode timer completes in background
When the app is backgrounded on Android, the focus mode countdown timer
now triggers a high-priority notification with alarm sound and vibration
when it completes. Previously, only the silent foreground service
notification was shown, causing users to miss timer completion.

Changes:
- Add completion notification channel with IMPORTANCE_HIGH
- Detect timer completion in FocusModeForegroundService
- Broadcast completion event to activity via LocalBroadcastManager
- Forward event to Angular via onFocusModeTimerComplete$ subject
- Handle native completion in effects to sync app state

Fixes #5923
2026-01-09 15:01:06 +01:00
Johannes Millan
ba9ceb25fd fix(reminder): cancel native Android alarm when removing reminder
Fixes #5921: When a task was rescheduled by removing the time and
changing only the date, the native Android alarm would still fire at
the original time. This was because removeTaskReminderSideEffects$
only removed the reminder from ReminderService but did not cancel
the native Android alarm.

Added explicit native Android alarm cancellation following the same
pattern used in clearRemindersOnDelete$, unscheduleDoneTask$, and
other similar effects.
2026-01-09 15:01:06 +01:00
Johannes Millan
5f724ad16e fix(reminder): prevent duplicate notifications from worker race condition
Add service-level deduplication to prevent the same reminder from
triggering multiple notifications when the worker's 10-second polling
interval races with state updates.

The fix tracks recently processed reminder IDs and filters them out
before emitting. IDs are cleared when snoozing (to allow re-trigger at
new time) and auto-cleaned after 60 seconds to prevent memory leaks.

Closes #5925
2026-01-09 15:01:06 +01:00
Johannes Millan
6d1f5a7113 feat(reminder): add option to disable window focus on reminder
Add isFocusWindow setting to reminder config, defaulting to false.
This prevents the app from stealing focus when reminders fire, which
was interrupting users working in other applications.

Closes #5922
2026-01-09 15:01:06 +01:00
Johannes Millan
dc498ef77d fix(ci): fix first-time contributor welcome action
- Change repo-token to repo_token (correct parameter name)
- Add write permissions for issues and pull-requests
2026-01-09 15:01:06 +01:00
Johannes Millan
6d96cab5ae feat(tasks): show focus session option in context menu on mobile
Remove IS_TOUCH_PRIMARY restriction so the "Start Focus Session"
context menu entry is visible on mobile/touch devices.
2026-01-09 15:01:06 +01:00
Johannes Millan
d475d88da3 feat(work-view): show day of week in scheduled date group headers
Display weekday alongside date when tasks are grouped by scheduled date
(e.g., "Wed 1/15" instead of "2025-01-15"), making it easier to identify
weekends at a glance.

Closes #5941
2026-01-09 15:01:06 +01:00
Johannes Millan
2194cb952d fix(planner): respect first day of week setting in schedule dialog
Wait for localization config to load before rendering mat-calendar
so DateAdapter.getFirstDayOfWeek() returns the user's configured value.

Fixes #5935
2026-01-09 15:01:06 +01:00
Johannes Millan
f3954131ac feat(tasks): add confirmation dialog before task deletion
Add optional setting to show confirmation dialog when deleting tasks
via keyboard shortcut (Backspace) or context menu. This prevents
accidental cascading deletions when users press Backspace expecting
browser-like "go back" behavior.

- Add isConfirmBeforeTaskDelete setting (defaults to true)
- Add confirmation dialog to TaskComponent.deleteTask()
- Add confirmation dialog to context menu deleteTask()
- Add setting checkbox in Settings > Misc
- Add unit and E2E tests for the feature

Closes #5942
2026-01-09 15:01:06 +01:00
Johannes Millan
b3ecfabc45 feat(18n): update translations 2026-01-09 15:01:06 +01:00
Johannes Millan
124ab686ed chore(i18n): remove 228 unimplemented feature translation keys
Remove translation keys for features that were planned but never
implemented, including:

- F.FOCUS_MODE.* (11) - planned focus mode extensions
- F.JIRA.STEPPER.* (5) - setup wizard never built
- F.METRIC.EVAL_FORM.* (15) - unused evaluation fields
- F.SYNC.* (36) - unused error states and dialogs
- F.TASK.* (29) - unused task bar and reminder keys
- F.PROJECT.D_CREATE.SETUP_* (7) - issue provider setup wizards
- F.ISSUE.*/JIRA.*/GITEA.*/etc (various) - unused provider keys
- MH.*/GCF.*/PLUGINS.*/G.* (various) - miscellaneous unused

Remaining 18 "unused" keys are false positives due to dynamic
object access pattern (F.TAG_FOLDER.*, F.PROJECT_FOLDER.*).

Total translation keys: 1965 → 1594 (371 removed, 19% reduction)
2026-01-09 15:00:36 +01:00
Johannes Millan
af4e622f91 chore(i18n): remove additional 86 orphan translation keys
Remove keys that are duplicates, never implemented, or obsolete:
- F.SAFETY_BACKUP.* (32) - orphan duplicate of F.SYNC.SAFETY_BACKUP
- F.PROCRASTINATION.* (32) - feature never implemented
- GCF.PAST.* (11) - orphan duplicate of GLOBAL_RELATIVE_TIME.PAST
- GCF.TIMELINE.* (10) - settings form never implemented
- WW.HELP_PROCRASTINATION (1) - related to unimplemented feature

Total unused keys reduced: 350 → 264
Remaining 264 keys need case-by-case review (planned features,
dynamic object access patterns, edge cases).

Add docs/unused-translations-analysis.md with detailed findings.
2026-01-09 14:59:05 +01:00
Johannes Millan
12d315a703 chore(i18n): add unused translation scanner and remove orphaned keys
Add tools to detect and clean up unused translation keys:
- find-unused-translations.js: scans for T.* and string literal patterns
- cleanup-unused-translations.js: removes specified orphaned sections

Remove 34 orphaned translation keys from all 25 language files:
- ANDROID.* (5 keys) - code removed in previous commits
- THEMES.* (17 keys) - never used, themes use hardcoded names
- F.CALDAV.ISSUE_CONTENT.* (12 keys) - never wired up

Convert string literal translation keys to T.* pattern in:
- dialog-user-profile-management component
- user-profile-button component
- plugin-management component
- config-sound-form component
- lazy-chart component
2026-01-09 14:59:05 +01:00
Johannes Millan
dec0d4ec33
Merge pull request #5944 from kemsar/bugfix/5518-gitlab-created-tasks-show-updated-when-not
Fixes Gitlab created tasks being marked incorrectly as updated
2026-01-09 14:57:27 +01:00
John
c1aace20fb
Update Chinese localization strings in zh.json 2026-01-09 21:52:39 +08:00
Johannes Millan
38428d6e1c
Merge pull request #5930 from ryziopl/master
Translation to Polish
2026-01-09 14:36:54 +01:00
Johannes Millan
565f1c8cc7 fix(e2e): stabilize flaky supersync tag deletion and migration tests
supersync-models.spec.ts:
- Replace fragile inline tag deletion with robust retry-wrapped implementation
- Use toPass() with increasing intervals for automatic retries
- Properly expand Tags section before finding target tag
- Wait for tag to disappear as final verification

supersync-server-migration.spec.ts:
- Remove unnecessary waitForTimeout(500) before sync
- Existing waitForTask() calls handle synchronization properly
2026-01-09 14:17:30 +01:00
Johannes Millan
eeb19a351f test(e2e): add legacy data migration E2E test
Add comprehensive E2E test that verifies legacy data (pre-operation-log
format) migrates correctly when the app starts. The test:

- Seeds legacy 'pf' IndexedDB database with test data before app loads
- Verifies backup file is downloaded during migration
- Validates all data migrates correctly including:
  - Tasks with subtasks (parent-child relationships)
  - Projects and tags
  - Sync provider settings (WebDAV/SuperSync configs)
  - Archive data (archiveYoung and archiveOld)
  - Time tracking data and notes

Includes comprehensive fixture file with realistic legacy state format.
2026-01-09 12:58:58 +01:00
Johannes Millan
bb0a8fdef2 test(util): add LOCAL_ACTIONS filtering mechanism tests
Verifies the core sync filtering mechanism that all 27 effects depend on:
- LOCAL_ACTIONS filters out actions with meta.isRemote: true
- LOCAL_ACTIONS passes through local actions (no meta or isRemote: false)
- ALL_ACTIONS receives both remote and local actions

This single test validates the filtering mechanism that prevents effects
from running during remote sync operations.
2026-01-09 11:58:22 +01:00
Johannes Millan
8aea93f900 perf(op-log): batch IndexedDB operations in conflict resolution
Replace sequential hasOp() + append() calls with batch operations:
- Use filterNewOps() to batch-check for duplicate ops
- Use appendBatch() to write multiple ops in a single transaction
- Reduces O(n) database calls to O(2) for each operation category

This optimization applies to:
- Remote-wins conflict ops
- Local-wins remote ops (stored then rejected)
- Non-conflicting piggybacked ops

Updated tests to expect appendBatch calls instead of append.
2026-01-09 11:36:34 +01:00
Johannes Millan
2c785622f5 test(e2e): add snapshot replacement detection test
Adds E2E test for the scenario where an already-syncing client detects
that another client has uploaded a snapshot replacement:

1. Client A sets up sync, uploads initial data
2. Client B connects (no local data), downloads A's data
3. Client B creates a local task (not yet synced)
4. Client C connects with local data, resolves conflict with USE_LOCAL
5. Client B syncs and should detect the gap/snapshot replacement

This tests the fix for snapshot replacement detection in
file-based-sync-adapter.service.ts, which uses clientId comparison
when available and falls back to syncVersion comparison otherwise.
2026-01-09 11:21:20 +01:00
Johannes Millan
7f0a10e704 test(op-log): add credential store and race condition tests
- credential-store.service.spec.ts: tests for OAuth token storage,
  caching, callbacks, and security considerations
- race-conditions.integration.spec.ts: tests for flush polling,
  concurrent writes, lock contention, vector clock races, and cache
  invalidation scenarios
2026-01-09 11:20:20 +01:00
Johannes Millan
ae127ff83a fix(op-log): improve type safety by replacing any with unknown
- auto-fix-typia-errors.ts: use unknown with type guards in path utilities
- data-repair.ts: add type-safe helper for entity state reset
- is-data-repair-possible.util.ts: use 'in' operator for property checks
- is-related-model-data-valid.ts: use MenuTreeTreeNode type instead of any[]
- sync.types.ts: use recursive Serializable type for SerializableObject
- sync-errors.ts: use IValidation<unknown> for validation result types
- dropbox-api.ts: use string | Record<string, unknown> for upload data
- persistent-action.interface.ts: add eslint-disable comment for justified any
2026-01-09 11:20:08 +01:00
Johannes Millan
fa7f37f8a3 fix(sync): use clientId for snapshot replacement detection
When detecting snapshot replacement during op download, use a dual-strategy:
- If excludeClient is provided: use clientId comparison (more accurate)
- If excludeClient is undefined: fall back to syncVersion comparison

This fixes gap detection when another client uploads a fresh snapshot
that replaces all ops but keeps syncVersion at 1.

The ternary handles both scenarios:
- Unit tests: pass excludeClient, use clientId check
- Download service: passes undefined, uses syncVersion check
2026-01-09 10:39:42 +01:00
Johannes Millan
2cfd52c968 feat(op-log): add unit tests and optimize remote ops batching
Add unit tests for LWWOperationFactory and StateSnapshotService to
improve test coverage. Optimize remote ops processing by replacing
sequential append calls with a single appendBatch call, reducing
N database transactions to 1.
2026-01-08 21:59:09 +01:00
Johannes Millan
18900a8dc5 test(e2e): add WebDAV sync tests for archives, delete cascade, and TODAY tag
Add comprehensive E2E tests for WebDAV sync edge cases:

- webdav-sync-archive.spec.ts: Tests for archive sync functionality
- webdav-sync-delete-cascade.spec.ts: Tests delete tag/project cascading
  to archived tasks across synced clients
- webdav-sync-today-tag.spec.ts: Tests concurrent TODAY tag operations
  (reordering, creation, removal) with LWW convergence

Also adds deleteTag() and deleteProject() methods to page objects.
2026-01-08 21:42:21 +01:00
Johannes Millan
94e4959b91 fix(e2e): handle ENOENT errors in closeClient cleanup
Playwright throws ENOENT errors when finalizing trace artifacts for
manually-created browser contexts. This is a known issue when using
trace: 'retain-on-failure' with contexts created via browser.newContext().

The fix extends error handling to catch and log these cleanup errors
instead of failing the test after assertions have already passed.
2026-01-08 20:44:24 +01:00
Johannes Millan
f899720b47 fix(sync): add snapshotReplacement detection guard and E2E test
The initial fix returned correct serverSeq after snapshot upload,
but snapshotReplacement gap detection still triggered incorrectly.
When sinceSeq equals syncVersion, we're in sync (our own upload),
not detecting another client's snapshot replacement.

Added E2E regression test for WebDAV sync to verify no repeated
conflict dialog after USE_LOCAL resolution.
2026-01-08 20:20:48 +01:00
Johannes Millan
42d197f659 fix(test): update full-state payload format in upload service tests
Update test fixtures to use correct NgRx entity format (task, project,
tag, globalConfig) instead of invalid plural keys (tasks, projects).
This aligns tests with the payload validation added in 2d26228ca.
2026-01-08 20:13:45 +01:00
Kevin Sarsen
6870483d4c
Fixes Gitlab created tasks being marked incorrectly as updated
Rather than comparing the issues last update timestamp with the last comment timestamp, it now compares the issue last update timestamp with the task `issueLastUpdated` property. This avoids the latency between an update and the update being logged in the comments.

Fixes #5518
2026-01-08 11:40:18 -07:00