Commit graph

17976 commits

Author SHA1 Message Date
Johannes Millan
dbaaab8faa fix(snap): remove duplicate plugs from configuration
The default plug already includes home, desktop, and desktop-legacy.
Explicitly listing them again caused snap store rejection due to duplicates.
2026-01-17 14:50:56 +01:00
Johannes Millan
53324bac08 17.0.0-RC.7 2026-01-17 13:33:56 +01:00
Johannes Millan
ce595ba212 17.0.0-RC.6 2026-01-17 13:32:33 +01:00
Johannes Millan
7137533407 test(e2e): fix additional tests for tabbed config page
Update plugin-lifecycle, plugin-upload, and reminders tests to
navigate to correct tabs:
- Plugin tests navigate to Plugins tab (extension icon)
- Reminder tests navigate to Time & Tracking tab (timer icon)

Fixes 5 additional E2E test failures after config page refactoring.
2026-01-17 13:26:57 +01:00
Johannes Millan
1f3098a48f test(e2e): update page objects for tabbed config page UI
Update ImportPage, SettingsPage, and plugin test helpers to navigate
to correct tabs after config page refactoring. Import/Export section
is now in Sync & Backup tab, plugins in Plugins tab.

Fixes 6 failing E2E tests:
- archive-import-persistence (3 tests)
- archive-subtasks (3 tests)
2026-01-17 13:20:35 +01:00
Johannes Millan
1c0581bca8 fix(snap): add filesystem and desktop integration plugs
Fixes #6031

- Add home and removable-media plugs for local file sync access
- Add desktop and desktop-legacy plugs for taskbar pinning in Cinnamon
- Update install hook to prompt for home interface connection
- Add documentation warnings about snap limitations and data persistence

All plugs include inline comments explaining their purpose and linking to issue.
2026-01-17 12:44:30 +01:00
Johannes Millan
a11257e70b fix(ci): grant write permissions for Claude code review to post comments
The Claude Code Review workflow needs pull-requests: write permission to post review comments on PRs. Previously it only had read access, causing "Actor does not have write permissions" errors.
2026-01-17 12:36:07 +01:00
Johannes Millan
efad5565e7 test(tags): update tests for subtask filtering in tag lists
Update unit tests to verify that:
- Subtasks are excluded when parent is in the same tag/TODAY list
- Subtasks appear as top-level items when parent is NOT in the list
2026-01-17 12:36:07 +01:00
Johannes Millan
0c5bc46e67 fix(tags): show subtasks in tag lists only when parent is not in same list
Subtasks can be added to tag lists (including TODAY), but they only appear
as top-level items when their parent is NOT in the same list. When both
parent and subtask are in the same tag/TODAY list, the subtask is shown
nested under the parent instead of separately.

This prevents duplicate display while allowing subtasks to be tagged
independently when needed.
2026-01-17 12:36:07 +01:00
Johannes Millan
7a7cb031b9 fix(ci): add memory allocation to Mac test step to prevent OOM 2026-01-17 12:36:07 +01:00
Johannes Millan
bd7944131a
Merge pull request #6034 from steindvart/pull-request-template
Add pull request template
2026-01-17 12:31:25 +01:00
Johannes Millan
8580742272
Merge pull request #6033 from steindvart/settings-tabs
Organize settings page into horizontal tabs for improved usability
2026-01-17 12:27:14 +01:00
Ivan Kalashnikov
8e811a4943 docs: add pull request template. 2026-01-17 15:47:22 +07:00
Ivan Kalashnikov
f2b5cbb958 refactor(config-page): update comments for clarity and remove unused service injection 2026-01-17 15:30:52 +07:00
Ivan Kalashnikov
bb485df58a style(config-page): center align tab content with auto margins 2026-01-17 14:46:55 +07:00
Ivan Kalashnikov
cdd99dedfe refactor(config): remove collapsible element from plugins tab. 2026-01-17 14:33:21 +07:00
Ivan Kalashnikov
34aee6a12c docs: add TODOs. 2026-01-17 14:25:43 +07:00
Ivan Kalashnikov
8afe8335fb refactor(i18n): remove 'PRODUCTIVITY_HELPER' key from translation files. 2026-01-17 14:18:38 +07:00
Ivan Kalashnikov
4c7875c8dd fix(i18n): update Russian translations and make alphabetical order for en and ru. 2026-01-17 14:16:37 +07:00
Ivan Kalashnikov
d7a1a3a1d0 refactor(config): reorder service injections for improved readability 2026-01-17 13:58:04 +07:00
Ivan Kalashnikov
c64485b888 fix(config): rename 'Plugins & Shortcuts' to 'Plugins' for consistency in UI and translations 2026-01-17 12:55:30 +07:00
Johannes Millan
3c5b441046 17.0.0-RC.5 2026-01-16 22:35:17 +01:00
Johannes Millan
0cd6dfaf43 17.0.0-RC.4 2026-01-16 22:34:50 +01:00
Johannes Millan
b0f4e99c0b test(e2e): fix flaky focus mode tests
Fixed 6 flaky E2E tests in focus mode by addressing race conditions
with countdown animation and session state transitions.

Changes:
- Added pointer-events: none to countdown component to prevent blocking
  clicks during fade-out animation (195ms)
- Replaced arbitrary timeouts with explicit waits for session-in-progress
  indicator (complete session button) in all focus mode tests
- Tests now wait for countdown animation to fully complete before
  interacting with UI elements

Root causes:
1. Countdown overlay intercepted pointer events during fade animation,
   causing clicks to fail intermittently
2. 900ms delay between countdown completion and session start caused
   race conditions when using fixed timeouts

Affected tests:
- focus-mode-break.spec.ts (4 tests)
- flowtime-timer-bug-5117.spec.ts (2 tests)

All tests now pass consistently without retries.
2026-01-16 22:34:50 +01:00
Johannes Millan
213d0ec010 chore(plugins): remove debug logging from procrastination-buster i18n 2026-01-16 22:34:50 +01:00
Johannes Millan
7401116bfb fix(plugins): reactively sync plugin i18n language with global config
Changed PluginI18nService constructor to use an effect() instead of
reading the language config once. This ensures the plugin i18n service
correctly picks up the language when config is loaded from persistence,
not just when it's manually changed.

This fixes the issue where plugins always started in English even when
the user had a different language selected, because the service was
initialized before the user's config was loaded.
2026-01-16 22:34:50 +01:00
Johannes Millan
9be6bf7c27 fix(plugins): initialize current language on plugin mount
Fixed i18n to fetch and use the current language when the plugin
initializes, instead of always defaulting to English. Now the plugin
will show the correct language immediately on first load, and also
update reactively when the language changes.

Changes:
- Added getCurrentLanguage() call in useTranslate initialization
- Changed onMount to createEffect for reactive language loading
- Updated both App.tsx and ProcrastinationInfo.tsx to use createEffect
- Applied fixes to both procrastination-buster and boilerplate
- Added debug logging to troubleshoot language change events

This fixes the issue where plugins always started in English regardless
of the user's selected language.
2026-01-16 22:34:50 +01:00
Johannes Millan
fb05e7be3e chore(plugins): remove debug logging from procrastination-buster 2026-01-16 22:34:50 +01:00
Johannes Millan
de264aff48 fix(plugins): fix i18n message protocol for iframe communication
Fixed the message passing between plugin iframes and plugin.ts to use
the proper PLUGIN_MESSAGE/PLUGIN_MESSAGE_RESPONSE protocol instead of
custom messages. This ensures translations and other messages are
correctly routed through the plugin bridge.

Changes:
- Updated useTranslate to use PLUGIN_MESSAGE type
- Listen for PLUGIN_MESSAGE_RESPONSE instead of custom response
- Wrap message in { type, payload } structure
- Updated plugin.ts to read from message.payload
- Added debug logging for troubleshooting
- Applied fixes to both procrastination-buster and boilerplate
2026-01-16 22:34:50 +01:00
Johannes Millan
1df40ab02d fix(plugins): fix translation loading in procrastination-buster
Changed message.data to message.payload in the onMessage handler
to match the structure sent by useTranslate hook. This fixes the
issue where translations were not loading in the UI.
2026-01-16 22:34:50 +01:00
Johannes Millan
92fd9301fe fix(plugins): remove duplicate side panel registration in procrastination-buster
Remove manual registerSidePanelButton() call since the side panel button
is already automatically registered via manifest.json with 'sidePanel: true'.

This fixes:
- Duplicate side panel button warning
- Plugin loading in both side panel and main view simultaneously

The manifest-based registration is sufficient and avoids duplication.
2026-01-16 22:34:50 +01:00
Johannes Millan
91fe3652dc fix(plugins): copy directories recursively in build script
Add copyRecursive() helper function to handle both files and directories
when copying plugin builds to bundled-plugins. This ensures i18n folders
and other directories are properly copied.

Previously, only files were copied (checking isFile()), which caused i18n
folders to be skipped. Now all three plugin build commands (procrastination-
buster, sync-md, ai-productivity-prompts) properly copy directory trees.

Fixes: 404 errors for i18n/de.json and other directory contents
2026-01-16 22:34:50 +01:00
Johannes Millan
cbc36012d8 test(e2e): fix add-to-today subtask tests
- Add Escape key press after creating subtasks to force exit from edit mode
- Simplify first test to remove both parent and subtask from Today, then use keyboard shortcut (most reliable)
- Fix context menu test to click sun icon button in quick-access area instead of searching for text
- Simplify "should NOT add subtask" test to avoid unreliable task counting
- Add proper wait times for Angular change detection cycles

All 5 tests now passing consistently.
2026-01-16 22:34:50 +01:00
Johannes Millan
ba0e9ce002 fix(plugins): resolve PluginHooks runtime error in procrastination-buster
Replace PluginHooks.LANGUAGE_CHANGE enum reference with string literal
'languageChange' to fix runtime error. The type-only import of PluginHooks
was not available at runtime, causing "PluginHooks is not defined" error
when installing the plugin.

The hook registration now uses the string value directly:
- Before: plugin.registerHook(PluginHooks.LANGUAGE_CHANGE, ...)
- After: plugin.registerHook('languageChange', ...)
2026-01-16 22:34:50 +01:00
Johannes Millan
0e0c04915c fix(tasks): prevent dueDay update on filtered subtasks in planTasksForToday
Fixes bug where planTasksForToday was setting dueDay on all taskIds,
including subtasks that were filtered out from being added to TODAY_TAG
(e.g., subtasks whose parents are already in Today). This caused state
inconsistencies where subtasks would have today's dueDay but not be in
the TODAY_TAG.

Now only updates dueDay for tasks that are either:
1. Being added to TODAY_TAG (newTasksForToday), OR
2. Already in TODAY_TAG but have incorrect dueDay

Also improves E2E test selectors:
- Use proper DOM structure (.task-list-inner > task)
- Add hover timeout for Angular change detection
- Fix context menu selector to use Material menu pattern
2026-01-16 22:34:50 +01:00
Johannes Millan
ce17c00690 feat(plugins): add German translations to procrastination-buster
- Add comprehensive de.json with 80 German translation keys
- Update manifest.json to include German language support
- Translate all UI strings: home, navigation, strategies, info
- Translate all 8 procrastination types with emotions and strategies
- Translate educational content for understanding procrastination

All translation keys match between en.json and de.json for consistency.
2026-01-16 22:34:50 +01:00
Johannes Millan
2550f91cb7 feat(plugins): add i18n support to procrastination-buster plugin
- Add comprehensive English translations (en.json) for all UI strings
- Add useTranslate() hook for reactive translations
- Update manifest.json with i18n configuration
- Add i18n message handlers to plugin.ts
- Create getProcrastinationTypes() for dynamic translation loading
- Update App.tsx to use translations throughout
- Update ProcrastinationInfo.tsx with full translation support
- All 8 procrastination types, strategies, and info content now translatable

The plugin now supports internationalization with complete English translations
and can easily be extended to support additional languages.
2026-01-16 22:34:50 +01:00
Johannes Millan
eb120baf1b feat(plugins): add i18n support to boilerplate-solid-js
- Add useTranslate() hook for reactive translations in SolidJS
- Include example translation files (en.json, de.json)
- Update Vite plugin to copy i18n folder during build
- Add i18n message handlers to plugin.ts
- Demonstrate i18n usage in App.tsx with ~10 translation keys
- Update documentation with comprehensive i18n guide
- Add i18n to features list in main plugin-dev README

The boilerplate now provides a complete working example of multi-language
plugin support, making it easy for developers to create internationalized
plugins.
2026-01-16 22:34:50 +01:00
Johannes Millan
6087b63878 fix(tasks): add subtasks to Today via Add to Today button
Fixes issue where clicking "Add to Today" button or using Ctrl+T
keyboard shortcut on subtasks had no effect. The action dispatch
was missing the parentTaskMap parameter needed by the reducer to
properly handle parent-child task relationships.

- Add parentTaskMap to planTasksForToday action in task.component.ts
- Add parentTaskMap to planTasksForToday action in task-context-menu
- Add comprehensive unit tests for subtask scenarios
- Add E2E tests for button, keyboard shortcut, and context menu

Fixes #6028
2026-01-16 22:34:50 +01:00
Johannes Millan
f2145deaeb feat(plugins): improve i18n performance and developer experience
- Load translation files in parallel for 3-5x faster plugin loading
- Add dev-only warnings for missing translation keys and plugins
- Replace split/join interpolation with efficient regex-based approach
- Add comprehensive unit tests for new warning functionality
2026-01-16 22:34:49 +01:00
Johannes Millan
ce4e61fd94 fix(ci): grant write permissions to Claude Code action
The Claude Code GitHub Action was failing with 403 errors when trying
to create comments on issues due to read-only permissions. Updated
contents, pull-requests, and issues permissions from read to write.
2026-01-16 22:34:49 +01:00
Johannes Millan
f421d2387a fix(e2e): add robust overlay cleanup to prevent blocked clicks
Angular Material overlay backdrops were not being properly cleared between
tag operations, causing subsequent clicks to timeout when overlays blocked
element interactions.

Added ensureOverlaysClosed() helper with:
- Early exit if no overlays present (performance)
- Escape key dismissal with retry for stacked overlays
- Logging for debugging when fallbacks trigger
- Uses Playwright's native locator.waitFor() instead of waitForFunction()
- Cleanup at operation start (prevent blocking) and end (clean state)

Benefits:
- Eliminates fixed timeouts, uses smart waiting (tests run 2x faster)
- Handles edge cases like stacked overlays
- Provides visibility into when overlays are unexpectedly present

Fixes 4 failing tests:
- Tag CRUD: remove tag via context menu
- Tag CRUD: delete tag and update tasks
- Tag CRUD: navigate to tag view
- Menu: toggle tags via submenu
2026-01-16 22:34:49 +01:00
Johannes Millan
e8054b1b3d fix(focus-mode): prevent CPU spike on task completion
Refactored updateBanner$ effect from selector-based to action-based pattern
to prevent excessive re-evaluation that caused 95-107% CPU spikes when
marking tasks as done with Focus Mode enabled.

Changes:
- Converted updateBanner$ from combineLatest([10 selectors]) to action-based
  pattern that only fires on relevant Focus Mode actions
- Added throttling (500ms) to limit banner updates to max 2/second
- Added skipWhileApplyingRemoteOps guards to setTaskBarProgress$ and
  playTickSound$ effects to prevent duplicate operations during sync
- Added distinctUntilChanged to flatDoneTodayNr$ selector to reduce
  unnecessary task list filtering

Fixes #6001
2026-01-16 22:34:49 +01:00
Johannes Millan
5b1a843196 fix(e2e): add robust overlay cleanup to prevent blocked clicks
Angular Material overlay backdrops were not being properly cleared between
tag operations, causing subsequent clicks to timeout when overlays blocked
element interactions. Added waitForOverlaysToClose() helper with multiple
fallback strategies (natural close, Escape key, retry) to ensure clean state.

Fixes 4 failing tests:
- Tag CRUD: remove tag via context menu
- Tag CRUD: delete tag and update tasks
- Tag CRUD: navigate to tag view
- Menu: toggle tags via submenu
2026-01-16 22:34:49 +01:00
Ivan Kalashnikov
9e3e622a9b fix(config): add missing MatTabLabel import to config page component 2026-01-17 02:17:49 +07:00
Ivan Kalashnikov
b8e0683f07 feat(config): implement tabbed configuration UI with language and tracking settings 2026-01-17 02:15:02 +07:00
Johannes Millan
7f4e5381d0 fix(plugins): wire up translation loading to i18n service (CRITICAL)
Fixes the critical issue where translations were loaded but never
passed to PluginI18nService, making the i18n system non-functional.

Changes:
- Inject PluginI18nService in PluginService
- Load translations into i18n service in 3 locations:
  - _loadPluginLazy() for lazy-loaded plugins
  - _loadPlugin() for file-based plugins
  - _loadUploadedPlugin() for cached plugins
- Improve LANGUAGE_CHANGE hook type guard
  - Use explicit LanguageCode type predicate
  - Remove non-null assertion (no longer needed)

This makes api.translate() functional for all plugin loading paths.
2026-01-16 18:48:41 +01:00
Johannes Millan
5caef4132f fix(plugins): fix i18n-related test failures
- Add global config initial state to plugin-hooks.effects tests
  - Provide localization config to prevent undefined access
  - Fixes 6 failing tests in taskUpdate$ suite

- Add PluginI18nService mock to plugin-runner tests
  - Mock translate, getCurrentLanguage, and translation loading methods
  - Fixes 2 failing tests due to missing Store provider

All 6377 tests now passing
2026-01-16 18:11:12 +01:00
Johannes Millan
1858a09429 test(plugins): add comprehensive i18n tests (Phase 8)
- Add plugin-i18n.service.spec.ts with 21 unit tests
  - Translation loading and fallback chain
  - Parameter interpolation
  - Nested key lookup
  - Language switching
  - Edge cases (empty objects, numeric values)

- Add plugin-i18n-date.util.spec.ts with 31 unit tests
  - Date formatting in multiple locales
  - All format types (short, medium, long, time, datetime)
  - Input parsing (Date, ISO string, timestamp)
  - Invalid input handling
  - Edge cases (leap years, boundaries, midnight/noon)

- Fix TypeScript error in plugin-hooks.effects.ts
  - Add filter before distinctUntilChanged to handle null/undefined
  - Use non-null assertion after filter

All 52 tests passing
2026-01-16 18:01:50 +01:00
Johannes Millan
5bb8b24c82 docs(plugins): add comprehensive i18n documentation
Phase 7: Create documentation

- Create PLUGIN_I18N.md with complete i18n guide
  - Quick start guide with file structure
  - Manifest configuration details
  - Translation file format and best practices
  - Complete API documentation (translate, formatDate, getCurrentLanguage)
  - Language change hook documentation
  - Full list of supported languages (24 languages)
  - Complete working example with multi-language support
  - Best practices and troubleshooting sections
  - Migration guide from hard-coded strings
  - Testing and performance considerations

- Update README.md with i18n section
  - Add i18n API methods to Plugin API section
  - Add languageChange hook to hooks list
  - Add i18n example to usage section
  - Add i18n files to optional files list
  - Add i18n best practice
  - Link to comprehensive PLUGIN_I18N.md guide

Documentation provides complete guide for plugin developers to add
multi-language support to their plugins with working examples.
2026-01-16 17:55:34 +01:00