The scrollable time grid already shows all 24 hours and auto-scrolls
to the preferred start hour on load, making the start/end hour
filter controls redundant. Removed from sidebar, header, and
full settings modal.
v1.75.1
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Instead of relying on CSS position:sticky (unreliable on iOS Safari),
adds a fixed overlay bar at the top of the viewport that shows the
current day name as the user scrolls through stacked day columns.
Uses IntersectionObserver to track which day header is near the
viewport top. Appears after scrolling past 80px, with blur backdrop.
v1.75.0
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Log the event ID decomposition, update payload, and Graph API
response status to diagnose why recurring event updates aren't
persisting for Outlook.
v1.74.8
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Reduced cache stale threshold from 15 minutes to 2 minutes
- Reduced background sync polling from 15 minutes to 2 minutes
- Added visibilitychange listener: syncs calendars and tasks when
the user switches back to the tab (catches external edits in
Apple Calendar, Google Calendar, etc.)
v1.74.7
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Instead of force-refreshing all calendar providers after create/update/delete,
now only the specific connection that owns the modified calendar is refreshed.
This significantly speeds up recurring event operations when multiple
providers are connected.
v1.74.6
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Calendar events now use --weekly-task-font, --weekly-task-size,
and --weekly-task-weight instead of separate event font variables,
so events and tasks always look consistent.
v1.74.5
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Dots pulse sequentially (. . .) to give clear visual feedback
that the operation is still in progress.
v1.74.4
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Always show provider icon (Google/Apple/Outlook/Synology) at
bottom-right of event blocks using FontAwesome icons
- Save button shows "Erstelle..." / "Creating..." while saving
instead of just "..." to reduce user confusion during sync
v1.74.3
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
All create, update, and delete operations now trigger an immediate
forced refresh from providers instead of relying on stale cache.
Previously, deleting recurring events left ghost instances visible
until the next background sync cycle.
v1.74.2
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Show provider icon (Google/Apple/Outlook/Synology) left of calendar color dot
- Hide URL field when Synology calendar is selected (not supported)
- Force refresh after creating recurring events so all instances show immediately
(previously only the first occurrence appeared until next sync cycle)
v1.74.1
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Compact, icon-driven layout inspired by Google Calendar:
- Icon-row layout with left-aligned icons for each field
- Color accent bar and save button match selected calendar color
- Toggle switch for all-day instead of checkbox
- Compact From/To time inputs
- Tighter spacing throughout, smaller font sizes
- German translations for all labels
- Footer bar with subtle background
- Shorter delete buttons for recurring events (This/Future/All)
v1.74.0
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Fixed weekly-days-grid applying fixed height in non-time-grid views
(simple/list), which broke the scroll context for sticky headers
- Reordered mobile FAB menu: Aufgabe, Termin, Projekt, Fokus, Suchen
- Changed "Suche" to "Suchen" in FAB menu
v1.73.3
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
overflow-x: hidden on .simple-view .weekly-day-column was creating a
scrolling context that broke position: sticky on the day header.
Changed to overflow-x: clip which clips content without affecting sticky.
v1.73.2
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Non-passive touchmove listener was permanently attached to document,
breaking browser scroll optimizations. Now only attached during active
long-press and removed immediately after.
v1.73.1
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Tap and hold (~500ms) on an empty time slot to activate, then drag to
select time range. Opens calendar event modal with pre-filled times.
Includes haptic vibration feedback on activation. Normal tap and scroll
gestures are not affected.
v1.73.0
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Collision detection rewritten to check duration-based overlap instead
of exact startTime match. Rolling tasks find the next truly free slot.
v1.72.2
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Events created or updated via the API were missing the calendar's
backgroundColor, causing them to render without their provider color.
v1.72.1
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Drag on empty time slots to create calendar events with pre-filled time range
- Rolling tasks now work per-task without requiring global autoRolling setting
- Add firstDayOfWeek to Outlook weekly recurrence patterns
- Add debug logging for Outlook recurrence creation
v1.72.0
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Outlook Graph API returns datetimes in the user's timezone without Z suffix
by default. The sync path already requested UTC and appended Z, but
create/update responses did not. This caused the optimistic UI update to
show events 1 hour off until the next sync corrected it.
Fix: add Prefer: outlook.timezone="UTC" header to create/update calls
and normalize response datetimes with Z suffix.
v1.71.3
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Cache PrismaClient globally in ALL environments (was only cached in dev).
Without this, production could create multiple PrismaClient instances,
each with its own connection pool, exhausting the database connections.
v1.71.2
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
iCloud returned 501 Not Implemented for updateObject calls.
Switch to updateCalendarObject which properly sends CalDAV PUT requests.
Fixed in both Apple Calendar and Synology Calendar update + recurring delete paths.
v1.71.1
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Strip HTML tags from descriptions before sending to CalDAV providers (Apple/Synology)
- Show event location underneath time in calendar event blocks (like Google Calendar)
- Fix German umlaut rendering by adding latin-ext font subset
- Fix CalDAV event updates losing TZID on DTSTART/DTEND (Apple Calendar recurring edit fix)
- Add error logging for CalDAV PUT responses
- Reduce wasted space when all-day events section is collapsed (24px max)
- Fix quotes with missing umlauts (ä, ö, ü, ß)
v1.71.0
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Redesigned drag/resize and modal recurring edit dialogs with radio buttons
(This event / This and following / All events) with descriptions
- Added German/English i18n to both recurring edit dialogs
- Repeat-on day buttons now respect weekStartDay setting (Mon/Sun start)
- Added language prop to CalendarEventModal
v1.70.0
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When editing a recurring calendar event (via modal or drag/resize),
the user is now asked whether changes apply to just this instance or
all events in the series.
- Modal: Save button shows "This event" / "All events" options for
recurring events
- Drag/resize: centered overlay prompt with same options + cancel
- API PATCH: editMode=all routes update to the series master ID
(recurringEventId) instead of the instance ID
- Cancel on drag prompt reverts to original position
v1.69.0
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Root cause: background calendar sync every 2min with forceRefresh:true
+ task sync every 5min + cache stale threshold of 2min = 12,500+
Google Calendar + 8,800 Google Tasks API calls/day for a single user.
Changes:
- Calendar background sync: 2min → 15min
- Task sync polling: 5min → 15min
- Cache stale threshold: 2min → 15min
- Remove forceRefresh:true from background sync (let staleness check
decide naturally)
- Remove redundant 8s re-fetch after background sync
- User actions (create/update/delete) still sync immediately
Expected reduction: ~10-15x fewer external API calls.
v1.68.1
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Cross-day drag now works: getEventsForSlot uses drag state's current
start time to assign the dragged event to the correct day column
- Add showCalendarProviderIcon to Prisma schema, profile API GET/PATCH
so the setting persists across sessions (was frontend-only before)
- DB migration applied via prisma db push
v1.68.0
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Calendar providers return descriptions with HTML tags (e.g. <p>test</p>).
Strip them before displaying in the hover tooltip.
v1.67.1
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Fix Google recurring events missing isRecurring flag (recurringEventId
was not mapped from Google API response)
- Add note icon (FileText) on events with descriptions, tooltip on hover
- Cross-day drag-and-drop: detect day column under cursor and shift date
- Fix event detail popup opening after drag/resize by setting ref before
async operations
- Add data-date attribute to day columns for drag target detection
- Use CSS class for icon row layout to prevent overlap
v1.67.0
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Recurring events appeared twice on their creation day because both the
series master (from POST cache) and the expanded instance (from sync)
had different IDs. Now filters out masters when instances exist, and
also deduplicates by title+startTime+calendarId as a fallback.
v1.66.1
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add resize handles (top/bottom) on hover to change event duration, and
drag-to-move support with live preview and 5-minute snapping. Includes
3px dead zone to distinguish clicks from drags, optimistic UI updates
with server rollback on failure, and recurring/provider icons on
time-grid events. Also fixes Google delete 410 Gone and Outlook delete
404/encodeURIComponent issues.
v1.66.0
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The base .time-slot-event and .simple-view .time-slot-event CSS had
left: 0 and right: 0 (with !important) which overrode the inline
overlap layout positioning. Removed so events can be placed side by
side when they overlap.
v1.65.1
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Overlapping calendar events on the same time slot are now rendered
side by side instead of stacked on top of each other. Uses a greedy
column assignment algorithm to compute layout per day.
- Outlook delete/update: use /me/events/{id} as primary endpoint
(without encodeURIComponent) instead of calendar-scoped endpoint,
with fallback. Fixes ErrorItemNotFound for recurring series masters.
v1.65.0
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Adds a toggle in Calendar settings to show the provider icon
(Google/Apple/Outlook/Synology) in the bottom-right corner of
calendar event blocks. The recurring icon is grouped alongside
when both are visible.
v1.64.0
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When the calendar-scoped Graph API endpoint returns 404 for series
master or instance IDs, fall back to /me/events/{id} which handles
these cases. Fixes ErrorItemNotFound on delete/update of recurring
Outlook events.
v1.63.5
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When updating Apple/Synology events that have DTSTART with a TZID
parameter, convert the incoming UTC dateTime to local time in that
timezone before writing back. Prevents ICAL.js from storing UTC
values under a local timezone, which caused +1h shifts on update.
v1.63.4
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Display the browser-detected timezone (e.g. Europe/Berlin) as a
read-only field in the Localisation settings tab.
v1.63.3
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add icalTimeToUtcDate() helper to Apple/Synology parsers that
correctly converts ICAL.Time with unresolved TZIDs to UTC dates
(fixes +1h shift on Synology/Apple recurring events across DST)
- Add recurring icon (Repeat) to bottom-right of all calendar event
blocks when event.isRecurring is true
v1.63.2
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Google: add timeZone to start/end objects when recurrence is present
(fixes "Missing time zone definition for start time" error)
- Outlook: pass user timezone instead of UTC for event create/update,
convert UTC dateTime to local representation (fixes +1h DST shift
on recurring instances)
- Outlook: use instance ID for single-occurrence delete instead of
series master ID (fixes ErrorItemNotFound on delete)
v1.63.1
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Adds a fourth delete option for recurring events: delete this instance
and all past occurrences. For CalDAV (Apple/Synology), this moves
DTSTART forward to the next occurrence. Includes optimistic UI removal.
v1.63.0
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Outlook returns dateTime without Z suffix despite timeZone being UTC,
causing JS to parse as local time (1h shift). Now appends Z for UTC dates.
- Added frontend deduplication to prevent stacked rendering of duplicate events.
- Added Outlook event debug logging for recurring event investigation.
v1.62.3
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Google and Outlook event mappings were missing isRecurring and
recurringEventId fields, so the modal never showed recurring delete
options and displayed recurring events as "Repeat: Never".
v1.62.2
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Events fetched via /calendarView must be addressed via
/me/calendars/{calendarId}/events/{eventId}, not /me/events/{eventId}.
The latter returns ErrorItemNotFound for calendar-view instance IDs.
v1.62.1
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When deleting a recurring calendar event, users now choose between
deleting just this instance, this and future instances, or all instances.
Supports Google, Apple (iCloud), and Synology CalDAV providers.
v1.62.0
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Use TZID-based local time (instead of UTC 'Z') for DTSTART/DTEND
when creating recurring CalDAV events, preventing DST-related time
shifts (e.g. 13:40 CET showing as 14:40 CEST after clock change)
- Send browser timezone from CalendarEventModal to server
- Guard against NaN event duration (missing/invalid endTime) which
caused event blocks to stretch to end of day
v1.61.1
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Store calendar colors (backgroundColor) from Apple and Synology
during connection setup
- Auto-refresh missing colors for existing Apple/Synology connections
- Show color dots next to calendar names in settings
- Add "Custom..." recurrence option with interval (every N days/weeks/
months/years) and day-of-week selection for weekly recurrence
- Generate proper RRULE with INTERVAL and BYDAY for all providers
- Generate proper Outlook Graph recurrence with custom intervals
v1.61.0
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Fetch and display Outlook calendar colors from Microsoft Graph API
instead of hardcoded blue
- Add recurrence end options to calendar event modal: Never, On Date
(UNTIL), or After X occurrences (COUNT)
- Pass recurrence end parameters through to RRULE generation for all
providers (Google, Apple, Synology, Outlook)
v1.60.0
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Move project icons from flex siblings into the text span so that
multi-line task titles wrap around the icon instead of leaving
empty space below it.
v1.59.4
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>