Beim Vermessen der Struktur zeigte sich: In WeeklyView.tsx stecken acht
eigenstaendige Komponenten mit zusammen rund 1.870 Zeilen, die gar nichts
mit der Wochenansicht zu tun haben. Sie haben bereits eigene Props -- der
Schnitt braucht also kein Props-Design, nur die richtigen Importe.
Drei davon sind jetzt heraus, unter src/components/weekly/. Die Symbolliste
projectIconsGlobal ist zu ProjectIcon gewandert, wo sie als einzige
gebraucht wird.
11.556 -> 11.148 Zeilen.
Der scharfe Typecheck aus v1.118.1 hat sich hier zum ersten Mal richtig
ausgezahlt: Er nannte in 19 Sekunden praezise jeden fehlenden Import, in
mehreren schnellen Runden. Vor C1 haette der Build all das stumm
durchgewunken -- und die Fehler waeren erst im Browser aufgeschlagen.
Verifiziert: Typecheck 0 Fehler, npm run build Exit 0, 63 Unit-Tests gruen.
v1.119.1
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
typescript.ignoreBuildErrors steht jetzt auf false. Ein erfolgreicher Build
ist damit wieder ein Beleg dafuer, dass der Code uebersetzbar ist.
Die Ursache der 30-Minuten-Laufzeit war nicht die Groesse von WeeklyView.tsx,
wie ich vermutet hatte, sondern das include-Muster **/* in tsconfig.json. Auf
src/**/* eingegrenzt laeuft der volle Typecheck in 19 Sekunden.
Die sieben gefundenen Fehler:
- notion-calendar.ts rief notion.databases.query() auf. Die Methode gibt es
in @notionhq/client v5 nicht mehr -- die Notion-Anbindung war zur Laufzeit
schlicht kaputt und niemandem aufgefallen. Migriert auf dataSources.query(),
aber mangels Notion-Zugang ungetestet. Gespeicherte Verbindungen enthalten
alte database_ids und muessen neu eingerichtet werden.
- WeeklyView.tsx importierte isAllDayEvent noch aus format statt date-utils
-- mein eigener Fehler aus v1.118.0, der ohne scharfen Typecheck
durchgerutscht war.
- Export-Helfer lagen in einer route.ts, wo Next.js nur Route-Handler
erlaubt; SettingsSidebar importierte sie von dort und zog einen
Server-Handler in den Client-Graphen. Jetzt in src/lib/export-fields.ts.
- push-notifications.ts: BufferSource-Cast fuer applicationServerKey.
- web-push hat keine Typen; lokale Deklaration statt neuer Abhaengigkeit.
Verifiziert: npm run build Exit 0 mit scharfem Typecheck, 63 Unit-Tests gruen.
v1.118.1
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Dritter Schnitt an WeeklyView.tsx (D1):
- src/lib/weekly/device-settings.ts: Cookie-Helfer plus die vier
Schluessellisten, die bewusst nur im Cookie und nicht in der Datenbank
gehalten werden
- src/lib/weekly/format.ts: stripHtml, invertColor, isAllDayEvent,
getSomedaySlotCount
11.655 -> 11.556 Zeilen. Mit npm run build verifiziert (Exit 0).
Damit sind die reinen Funktionen ohne Komponenten-State heraus, insgesamt
11.906 -> 11.556 (rund 3 %). Der Rest ist die Komponente selbst: JSX und
Handler auf gemeinsamem State. Jeder weitere Schnitt braucht echtes
Props-Design statt Verschieben.
v1.117.7
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Zweiter Schnitt an WeeklyView.tsx (D1). 13 reine Funktionen ohne
Komponenten-State: getStartOfWeek, getDayName, getTimeSlots, formatHour,
getWeekNumber, formatCustomHeader und weitere.
11.830 -> 11.655 Zeilen. Mit npm run build verifiziert (Exit 0).
Nebenbefund: getWeekNumber existiert im Projekt dreimal -- hier, in
WeekPrintModal.tsx und in api/user/export-week-view/route.ts. Das Ersetzen
der Duplikate steht in TODO.md; vorher gehoeren die drei Implementierungen
auf Gleichheit geprueft.
v1.117.6
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Erster Schritt der Aufteilung von WeeklyView.tsx (D1). Die sieben gemeinsamen
Typen lagen in der Komponentendatei; SettingsSidebar und GridTaskBlock
importierten sie von dort und zogen sich damit die gesamte
11.900-Zeilen-Komponente in ihren Abhaengigkeitsgraphen.
WeeklyView.tsx re-exportiert die Typen weiterhin, bestehende Importe bleiben
also unveraendert -- kein Anfassen der beiden Importeure noetig.
11.906 -> 11.830 Zeilen. Mit npm run build verifiziert: Exit 0, 36 Seiten
generiert, /tasks unveraendert bei 265 kB.
v1.117.5
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Event titles were coloured with color-mix(... 78%, black), which stayed so
close to the event's own colour that it barely separated from the tinted
background. Mixing 30% of the colour into a dark slate keeps the calendar
colour recognisable while making the text properly legible.
v1.116.4
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The drop preview and the empty-slot input were keyed by date.getDay(), which
is only unique inside a 7-day window. At 21 days every column sharing the
hovered column's weekday lit up — the mirrored drop targets, one per Tuesday.
The invisible half was worse: handleDrop resolved its target with
visibleDays.find(d => d.getDay() === dayOfWeek), so dropping on the second or
third Tuesday scheduled the task on the first one. Both now use the column's
own date; handleDragOver/handleDrop take a Date instead of a weekday number.
Task rendering was already date-based, so only drag state was affected.
v1.115.3
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Add a "Custom" option next to the 1/2/3/5/7 presets where any number of
days from 1 to 31 can be typed. The seven duplicated preset button rows
are replaced by a shared DaysSelector component with panel/header/menu
variants.
The day grid and all-day grid only had CSS for cols-1/2/3/5/7, so any
other count silently fell back to five columns; both now derive
grid-template-columns from the actual day count.
v1.115.0
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Focus Mode now shows a SKIP button that moves to the next task of the day
without completing the current one. Skipped task ids are tracked in
WeeklyView and filtered out of the focus queue, so completing a task still
picks the correct next one; the list is cleared when Focus Mode closes.
The timer resets on each new task, and the button is disabled when no other
task is left for today.
Also drops the standalone "Element Colors" and "Weekend Colors" sections from
Styling settings (those controls live in the CSS Variables panel since
1.113.1) and enlarges the CSS variable swatches.
v1.114.0
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Adds a "CSS Variables" panel to the Styling tab with a color picker and
description for every color token in globals.css (base, sidebar, design
token aliases, event colors, all-day chips), plus a "Custom CSS" textarea
that loads after the default stylesheet and can override any rule.
Overrides are stored per-user (customCssVars, customCss) and applied on
the root container's inline style, so they take precedence over themes
and per-field settings.
v1.113.0
After dragging a calendar event to a new time or date, trigger
fetchCalendarEvents on both the old and new date context so the
move is reflected instantly without waiting for the next poll cycle.
Applies to both non-recurring and recurring drag confirms.
v1.112.2
- Calendar icon is now a standalone button to the left of the << < Today > >> cluster
- Uses its own ref (navDatePickerBtnRef) so SimpleDatePicker anchors and
opens directly below the icon instead of at the center date display
- Removed separator inside nav pill (no longer needed)
v1.112.1
- Eye icon now opens a combined vis-display flyout (visibility toggles
+ appearance settings in one panel, with divider)
- History flyout reduced to undo+redo only; Refresh moved back to
standalone rail icon
- Navigation flyout stays open when clicking prev/next day/week
(removed setFlyoutSection(null) from all nav button handlers,
both desktop and mobile)
- Mobile rail mirrors desktop flyout structure (vis-display, history,
nav, refresh standalone)
v1.110.7
- Nav arrows (5 icons) → single ArrowLeftRight flyout with prev/next week/day + today
- Undo/Redo/Refresh/Print (4 icons) → single Undo2 history flyout
- Removed duplicate standalone dark mode toggle (already in Appearance flyout)
- Same flyout sections added to mobile icon rail
- Nav flyout also added to mobile rail
v1.110.6
Was calling setShowSubHourSlots (local state) + saveSetting, but effectiveShowSubHourSlots
reads from profile via getEffective — so the toggle had no visible effect. Fixed all 5
occurrences to use saveViewSetting("showSubHourSlots", ..., true) matching the Settings
sidebar behavior.
v1.110.3
- PanelLeftOpen in header now toggles the icon rail open/close
- Close button in rail uses same PanelLeftOpen icon for visual consistency
- Removed nav arrows (prev/next day/week, today) from rail — available in Quick Settings
- Removed Printer from rail (rarely used on mobile)
- Added SlidersHorizontal (Quick Settings) to bottom of rail
v1.110.2
- PanelLeftOpen in mobile header now opens Quick Settings (left panel)
- Added "Icon Rail" link at bottom of Quick Settings to open the icon sidebar
- Mobile icon sidebar now matches collapsed desktop left rail: View, Columns,
Slot, Plus, Repeat, Goal, Visibility, Appearance flyouts (tap-to-toggle),
Undo, Redo, Refresh, Print, dark mode, Settings, Sign out
v1.110.1
- Someday task edit: add icon/checkbox column spacers before the
textarea so the edit field aligns exactly with the task text column
- Settings tabs: remove outer padding, use space-around + nowrap so all
9 icons fit in a single row without wrapping
- Mobile: left sidebar rail (PanelLeftOpen button) — slides in from
left with nav controls (prev/next day/week, today), actions (search,
calendar jump, projects, focus, quick settings), and bottom controls
(dark mode, settings, sign out). CSS class .mobile-left-sidebar and
.mobile-rail-btn added for easy customization.
v1.110.0
SomedayAddTask now accepts showProjectIcons and showTaskCheckboxes props.
The bottom add-task row renders as a flex layout with matching spacers
for the icon column (18px) and checkbox column (16px), so the input
field left-edge exactly aligns with the task name column. Right-padding
keeps the input from extending into the provider icon column.
v1.109.1
- Completed tasks in someday lists now always render below all active
tasks. Slot system builds from incomplete tasks only; done tasks get
their own section at the bottom outside the droppable slots.
- "Add task..." input right margin increased to 24px so its right edge
stops before the provider icon (G) column, matching task row layout.
v1.109.0
The ANY DAY label/icon div sits at the flex-end of the tab bar but
appeared misaligned with the tab buttons. margin-bottom: 6px brings
it to the correct visual baseline.
v1.108.4
ListVisualsPopover used position:absolute which was clipped by the
weekly-someday-list card's overflow:hidden. Now uses position:fixed
anchored to the card's bounding rect. IconPicker sub-panel also
updated to position:fixed. Stabilized mousedown listener (onCloseRef
pattern, empty deps).
v1.108.3
The ⚡ priority and delegation icons were still rendering inside the
text span (after the checkbox). Now ALL task icons (project, priority,
delegation) are consolidated into the single fixed-width 18px column
before the checkbox for someday tasks. Tasks with no icon get an empty
placeholder so checkboxes and task names stay column-aligned.
v1.108.1
- Fix tab double-click popover not showing: tab bar overflow-x:auto was
clipping the position:absolute popover. Now uses position:fixed anchored
to the button's bounding rect, captured on dblclick. Also stabilizes
the outside-click listener (onCloseRef pattern, empty deps).
- Restructure someday task item order to: [project icon column] [checkbox]
[task name]. Fixed-width 18px icon column (placeholder when no project)
keeps all checkboxes and task names vertically aligned.
v1.108.0
CSS:
- Active tab no longer shows accent underline; instead border-bottom matches
the someday area bg (#f9f9f9 / #1a1a1b dark), creating a raised browser-tab
look where the active tab visually merges with the content below
- margin-bottom: -1px to cover the tab bar border-bottom on active tab
JSX:
- Double-click on any tab now opens TabVisualsPopover (edit tab)
- Pencil icon and dissolve-X button removed from tab wrappers
- TabVisualsPopover extended with: rename input, dissolve button
(dissolve removes the tab grouping; lists are kept)
- onRename and onDissolve props added to TabVisualsPopover
v1.107.3
Tabs:
- Pill-shaped tabs (border-radius: 20px) with proper background on inactive
- Inactive tabs now use readable dark text (--weekly-text) instead of
barely-visible --weekly-text-light
- Active tab: accent color + white text + glow shadow (box-shadow)
- Count badges: larger, higher contrast, 700 font-weight
- Tab bar: taller padding (8px), thicker bottom border (2px)
Cards:
- Rounded corners (10px), border + subtle drop shadow
- Cards now 240px wide (was 300px) for better density
- Grid padding changed from padding-bottom only to full 12px padding
- List header has subtle tinted background + reduced height (48px)
- Title font tweaked to 0.85rem/700 (was 1.15rem/800) to match card size
- Add-task button padding aligned to card edges (12px horizontal)
- Removed p-2 Tailwind class that was double-padding the card
v1.107.0
Left section was missing opacity-0 group-hover:opacity-100 Tailwind classes
after the useLeftRail display:none change. Restored fade-in-on-hover
conditionally when top-toolbar mode is active.
v1.106.6
- Remove hover blur/opacity on header center section when left rail is active
(group-hover:opacity-20 blur only applies in top-toolbar mode)
- Add min-height to desktop header so it doesn't collapse when both left/right
sections are hidden in left-rail mode
- User icon in left rail now opens Settings on the Account tab directly
- Add Menu Position toggle (Left/Top) to Settings > General tab so users
can find and change toolbar layout from the settings menu
- Replace FolderPlus with Briefcase icon for Projects in left rail to match
the Settings sidebar's Projects tab icon
v1.106.4
- Right header section now also gets display:none when useLeftRail is true,
so neither the left nor right header controls are visible in left-rail mode
- Replaced UserMenu (which positions from the right edge) with an inline
dropdown in the left rail that opens to the right of the rail at left:52px,
correctly positioned and functional
- Added LogOut icon to lucide imports
v1.106.3
1. Header left-section (view switcher, days, slot) is now display:none when
in left-rail mode — previously it was opacity-0 on hover so both were
visible simultaneously.
2. Left rail bottom now has two distinct buttons:
- ⚙ Settings (cogwheel) → opens full SettingsSidebar
- 👤 User → opens UserMenu (same as header avatar, with profile/sign-out)
Previously a single User icon opened the settings instead.
v1.106.2
Add a "Menüposition / Menu position" segmented toggle (Left / Top) in
the expanded left-rail preferences panel and in the top-mode overlay.
- "Left" (default): persistent left rail; header toolbar controls are
de-emphasised (fade in on hover only since they are duplicated).
- "Top": left rail hidden entirely; header controls always visible;
PanelLeftOpen button in header opens the full settings overlay.
Persisted via saveSetting("menuPosition", …) so the choice survives
page reloads.
v1.106.1
Replace the overlay quick-settings panel with a persistent fixed-left
toolbar on desktop. Collapsed (44 px) shows icon-only buttons; expanded
(240 px) shows the full labelled panel. Hovering a settings icon in
collapsed mode opens a flyout panel (view, columns, slot, visibility,
appearance). Mobile overlay behaviour is unchanged.
v1.106.0
Switch panel background to --paper, all dividers to --line, section
labels to --ink-3, active view/days/slot buttons to --accent/--ink.
Soften panel shadow to 4% opacity. No logic, structure, or API changes.
v1.105.2
Trim desktop header height (py-2 → py-1.5) and switch border to --line
token. Update .weekly-header CSS class to use --line. Add baseline
letter-spacing: -0.005em to body. No logic, structure, or API changes.
v1.105.1
Give the bottom-of-list "Add task..." input a framed background (white
with a subtle border in light mode, slate-800 with a darker border in
night mode) plus a small radius and padding, so it visually matches user
expectations of an input. The inline slot-editor that appears when you
click on an empty slot keeps the transparent look so it blends with the
surrounding task rows.
v1.104.1
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Pull-sync now runs on visibilitychange + window focus (in addition to mount
and the slow 15-min safety-net interval), throttled to one call per 5s. The
moment the user returns to the tab the app reconciles, so an Outlook-side
checkbox/star/title change shows up within a second of refocusing the tab
instead of after a 15-minute wait.
To keep this cheap, the Microsoft Graph delta endpoint
(/me/todo/lists/{id}/tasks/delta) is used when we have a stored deltaToken
for a synced list — typically a few hundred bytes per call when nothing
changed. Tokens are persisted on SomedayList.syncDeltaToken (new column,
migration applied) and refreshed each call. On 410 Gone (token expired
>30 days) we fall back to a full fetch and prime a new chain. Delta also
brings remote deletions (@removed) so they propagate locally without
needing a full list scan.
v1.104.0
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The previous timestamp gate (`if (remoteUpdated <= localUpdated) continue`)
hid genuine remote-side changes because every prior no-op pull bumped
lastSyncedAt to "now", making it newer than the Outlook lastModifiedDateTime
of a subsequent star toggle. Now the pull does a per-field comparison and
only writes lastSyncedAt when at least one field actually changed. Same fix
applied to the Google Tasks pull branch for consistency.
Also run a pull-sync once on mount instead of waiting up to 15 min, so
remote-side changes show up immediately on next page load.
v1.103.2
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- deleteCachedEvent now removes every cached row that belongs to the same
recurring series (master id + all "<masterId>::*" instances + rows whose
recurringEventId matches the master), so deleting "all occurrences" no
longer leaves orphan rows that resurface on the next read.
- getPriorityBadge: surface the yellow star whenever a task is marked
important (e.g. a starred Outlook To-Do task pulled in via sync), even
when the active priority style is Eisenhower / ABCDE / Ivy Lee.
v1.103.1
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- Outlook recurring delete: also delete the specific instance after the master
to clean up orphaned first occurrences.
- CachedCalendarEvent gains busyStatus column (migration applied) so showAs
changes from Outlook flow back into the weekly view.
- Outlook create/update now round-trip the full event (busyStatus, visibility,
attendees, reminders, recurrence link) via a shared response mapper.
- MS To-Do importance ('high' star) ⇄ local importance flag in pull-sync,
push-sync, initial import, and local-task POST/PATCH; dueDateTime ⇄
scheduledDate added to pull-sync.
- Local task PATCH now fires a best-effort push to Outlook/Google/Synology so
any field change keeps both sides aligned.
- AnyDay list delete dialog now offers Cancel / hide locally / delete on both
sides; new deleteMsTodoList + deleteGoogleTaskList helpers.
v1.103.0
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- Add Show/Hide Priority Icons toggle in left settings panel under Project Icons
- Projects sidebar: move Add Project form to the top, add per-project
filter button (filters tasks across all views), expand/collapse to show
tasks underneath each project name, active-filter banner with clear
- Intro hints on first load: briefly reveal hidden header controls then
fade out, and bounce-scroll the main grid to reveal off-screen tasks
v1.102.0
Wave-2 user feedback (points 4–6):
- Language picker: replace emoji flags (which don't render reliably on
Windows) with inline-SVG flag components for GB/DE/FR/ES/IT. Used
in both the Settings localisation tab and the onboarding wizard.
- Timezone: replace the read-only Intl.DateTimeFormat display with a
real <select> over a curated list of major IANA zones. Each option
shows "(UTC±hh:mm) CODE — Region" and the list is sorted by current
offset, then code, then IANA name.
- Multi-timezone: new ExtraTimezonesEditor in the localisation tab lets
users pin additional zones (stored in user.viewSettings.extraTimezones
to avoid a migration). The time-grid axis now renders the equivalent
hour for each pinned zone next to the local label, helpful for
scheduling across regions.
v1.100.0
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>