Adds pending trigger counter to handle operations that occur before
ImmediateUploadService initialization. When triggers are called before
the service is ready, they are queued and replayed when initialization
completes. This prevents race conditions during app startup.
Changes:
- Add _pendingTriggerCount to track triggers before initialization
- Update trigger() to increment counter when not initialized
- Update initialize() to replay queued triggers after setup
- Add unit test for queue replay behavior
- Fix docker-compose.yaml to use NODE_ENV=development for tests
Fixes E2E test: 'handles server storage quota exceeded gracefully'
Also addresses production edge case where fast users might create
tasks during app load before sync service is ready.
- Remove "only" from "English only" text
- Remove language checkmark icon
- Remove special color styling for language section
- Hide minimum version field
Remove trivial "should create" tests and .toBeDefined() assertions
that provide no value. Preserve all meaningful tests including those
with specific value assertions and behavioral tests.
Changes:
- Remove 69 "should create/be created" tests with only toBeTruthy()
- Remove 7 trivial .toBeDefined() tests
- Remove 3 empty describe blocks
- Delete 1 empty test file
- Preserve all skipped tests (xit/xdescribe)
- Preserve tests with toBe(), toEqual(), or multiple assertions
Total: 68 files modified, 1 file deleted, ~317 lines removed
Tests reduced from 6,592 to 6,552 (40 tests removed)
All tests passing ✅
- Add child combinator (>) to sync-btn selector to prevent 28px from
affecting other icons
- Set 20px sizing for all action-nav-right icons except sync button
- Sync button main icon remains at 28px (intentionally larger)
- All other header icons (counters, add, panels) now 20px as before
Fixes#6119
Add a "BETA" badge inline with the SuperSync heading to indicate
the service is in beta testing. Badge includes:
- Orange/amber styling for visibility in light mode
- Lighter orange with dark background for dark mode
- Compact, pill-shaped design consistent with existing badges
Set snackbar duration to 0 for critical Dropbox sync setup errors,
ensuring users have adequate time to read and understand the HTTPS
requirement message (62 words) before it disappears.
This prevents users from missing important actionable guidance about
why sync setup failed, especially on mobile devices where 8-second
auto-dismiss can be easily overlooked.
Dropbox Sync Improvements:
- Change PKCE alerts to thrown errors for better error handling
- Add provider ID to sync auth error logs for debugging
- Improve PKCE error message to guide users to HTTPS requirement
- Add unit tests for PKCE code generation
Testing Improvements:
- Enhance wait-for-supersync.sh to check both health and test endpoints
- Match E2E fixture behavior for more reliable test startup detection
These changes improve error diagnostics and provide clearer guidance
when WebCrypto APIs are unavailable (HTTP contexts).
- Add platform-specific initial day counts (5 mobile, 15 desktop)
- Use LayoutService.isXs() to detect mobile breakpoint
- Add responsive behavior that resets count on resize (before scroll)
- Preserve user's loaded day count after manual scroll
- Add AUTO_LOAD_INCREMENT constant for +7 days on scroll
- Add unit tests for mobile-specific behavior
Update dialog max-height calculations to subtract safe area insets on
notched devices (iPhone X+, Android with notches). This prevents dialog
content from being clipped under the notch or home indicator area.
Changes:
- Standard dialogs: 90vh → calc(90vh - insets)
- Big dialogs: 95vh → calc(95vh - insets)
The env() function gracefully degrades on devices without safe areas
(returns 0px), so there's no visual change on non-notched devices.
When storage quota is exceeded during immediate upload, the error was
silently logged but no alert was shown to the user. This caused the
E2E test "handles server storage quota exceeded gracefully" to fail.
Changes:
- Import handleStorageQuotaError in ImmediateUploadService
- Call handleStorageQuotaError() in catch block before logging
- Preserves silent failure for other transient errors
The fix ensures users are immediately notified of critical storage
quota issues that require action, while maintaining retry behavior
for transient errors.
Fixes failing E2E test in supersync-network-failure.spec.ts
Prevents race condition where upload attempts happen before sync config
is loaded from IndexedDB, eliminating 404 errors to default baseUrl
during app startup and E2E tests.
Increases max-height of mat-mdc-dialog-content from default to 90vh on
mobile viewports (≤599px) to better utilize available screen space and
reduce unnecessary scrolling in dialogs like the schedule task dialog.
Create schedule.constants.ts and schedule-constants.scss with named
constants for viewport thresholds, breakpoints, column widths, and
scrollbar dimensions. Update components to use constants for better
maintainability and documentation.
Add integration test verifying that when a remote DELETE is applied first
but a local UPDATE wins LWW conflict resolution, the entity can be
extracted from the DELETE payload and the UPDATE applied on top of it.
- Add active state CSS reusing magic side nav theme variables
- Switch to routerLinkActive directive for declarative route matching
- Remove manual currentRoute signal tracking
When a remote DELETE is applied before LWW resolution and the local UPDATE
wins (newer timestamp), extract the entity from the DELETE operation payload
to recreate it, preventing data loss from the race condition.
- Created calendar.svg icon for ICAL issue provider
- Registered calendar icon in global theme service
- Updated ISSUE_PROVIDER_ICON_MAP to use 'calendar' instead of 'calendar_month'
- Fixes error: "Unable to find icon with the name :calendar_month"
Prevents the task close button from appearing on mobile screens (≤600px) where task details are shown in the bottom panel, improving UX by avoiding redundant UI elements.
- Fix snackbar selector in supersync edge cases test
- Add polling for plugin navigation stability
- Show error snackbar and status icon on decryption failure
- All 5 failing tests now passing consistently
Resolves issue #6095 where Task View Customizer settings (sort, group, filter)
were being reset on app restart or day change.
Changes:
- Add localStorage keys for sort/group/filter settings
- Initialize signals from localStorage with default fallbacks
- Add effects to auto-persist signal changes to localStorage
- Add 7 comprehensive unit tests for persistence behavior
Settings now persist across app restarts, work context changes, and day boundaries.
Invalid localStorage data gracefully falls back to defaults.
Use Capacitor's native WebView resize mode on iOS instead of CSS-based
workarounds. When keyboard appears, the WebView itself shrinks so 100vh
automatically fits above the keyboard.
- Configure iOS to use `resize: 'native'` (Android keeps `resize: 'body'`)
- Add scrollIntoViewIfNeeded() to scroll focused inputs into view
- Add proper cleanup for keyboard event listeners
- Improve flexbox shrinking in fullscreen markdown dialog
On iOS, dismissing the native share sheet by tapping the background
would cause it to reopen immediately. Two issues were fixed:
1. The Capacitor Share plugin on iOS throws {errorMessage: "Share canceled"}
but the code only checked for error.name === 'AbortError'. This caused
the cancellation to not be detected, falling through to try the Web
Share API as a fallback, opening a second share dialog.
2. Moved the iOS share guard from component level to ShareService. The
component-level guard didn't work because WorkContextMenuComponent is
inside ng-template matMenuContent, so it gets destroyed when the menu
closes, losing the guard state.
- Replace deprecated `selector:` properties with proper Electron `role:` in macOS menu
- Add standard macOS menu items (hide, hideOthers, unhide)
- Ensure before-close handlers always call setDone() to prevent app hanging
- Change sync error dialog from confirm() to alert() since result was ignored
Implement lazy loading for material-icons.const.ts (69.5KB, 3800+ icons) to reduce initial bundle size by ~68KB.
Changes:
- Create MaterialIconsLoaderService with promise caching to prevent concurrent loads
- Update DialogCreateTagComponent to use lazy loader service
- Update IconInputComponent to use lazy loader service
- Add comprehensive unit tests for MaterialIconsLoaderService
- Convert icon input methods to async for lazy loading support
Expected impact: Main bundle reduced by ~69KB, icons loaded on-demand when user focuses icon input fields.
- Replace hardcoded 7-day navigation with responsive day counts
- Desktop (≥1200px): 7 days (full week)
- Tablet (768-1199px): 5 days
- Mobile (480-767px): 3 days
- Small mobile (<480px): 2 days
- Navigation now moves by the number of days currently shown
- Remove horizontal scroll (no longer needed with responsive day count)
This fixes the mobile navigation bug where users saw 3 days but
navigation skipped by 7 days, causing 4 days to be hidden between
each navigation action.
- Move horizontal scroll control to parent .scroll-wrapper element
- Both vertical and horizontal scrollbars now on same container
- Pass isHorizontalScrollMode as input to schedule-week component
- Remove duplicate scroll wrapper from schedule-week
- Maintain responsive column widths based on scroll mode
- Fixes scrollbar positioning and coordination issues
This ensures both scrollbars are managed by the same element, providing
better UX and preventing scrollbar positioning conflicts.