fix(web): window/table polish — opaque windows, sortable columns, sticky-header scrollbar, viewport-clamped windows
Some checks failed
ci / build-test (push) Has been cancelled
ci / docker-build (push) Has been cancelled
ci / web (push) Has been cancelled
Desktop App / Build Linux (amd64) (push) Has been cancelled
Desktop App / Attach to Release (push) Has been cancelled

- Windows: make floating windows fully opaque (drop backdrop-blur/color-mix
  transparency), add margin around windows, reduce Overview padding to p-2.
- DataTable: fix Toolbar always rendering an empty padded bar (children
  slot was always truthy regardless of actual content); split header/body
  into separate tables so the scrollbar no longer overlaps the sticky
  header; make sort work for derived/synthetic columns by sorting on the
  column's accessor instead of a nonexistent row key.
- Overview: enable sorting on Status and Task columns via accessors.
- TaskContextPanel: give the Activity pane more height by default (Scope
  30% / Activity 70%), fixing that the saved split sizes were never
  actually applied to the bound Pane sizes.
- windows.ts: clamp new/resized windows to the desktop viewport so
  content-heavy entity windows can't grow taller than the visible screen;
  fixes a bad defaultSize.height ('30vh', an invalid non-numeric value)
  that had silently left window height unconstrained.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-21 18:08:40 +02:00
parent 1c12d40712
commit c151a66627
5 changed files with 99 additions and 87 deletions

View File

@@ -18,6 +18,26 @@ import { heading } from '$lib/tasks'
export const SESSION_PREFIX = 'session:'
export const wm = createManager({ defaultSize: { width: 480, height: 560 } })
// New windows (and manual resizing) must never exceed the visible desktop
// area — without this, a content-heavy entity window (many Details/
// Relations/Tasks sections) grows taller than the viewport with no way to
// reach its own titlebar controls. Clamps requested width/height down to
// the current viewport and caps maxWidth/maxHeight the same way, so
// dragging a resize handle can't push it past the edge either.
function clampToDesktop<T extends { width?: number; height?: number; maxWidth?: number; maxHeight?: number }>(
init: T
): T {
const { viewport } = wm.getState()
if (viewport.width <= 0 || viewport.height <= 0) return init
return {
...init,
width: init.width !== undefined ? Math.min(init.width, viewport.width) : undefined,
height: init.height !== undefined ? Math.min(init.height, viewport.height) : undefined,
maxWidth: Math.min(init.maxWidth ?? viewport.width, viewport.width),
maxHeight: Math.min(init.maxHeight ?? viewport.height, viewport.height)
}
}
export const dk = createDesktop(wm, {
// topEdge:'maximize' + preview gives the classic drag-to-top-maximizes
// affordance; magnetism/keyboard are wmkit defaults worth turning on now
@@ -94,14 +114,14 @@ export function openAppWindow(appId: string): void {
wm.focus(id)
return
}
wm.open({
wm.open(clampToDesktop({
id,
title: app.title,
width: app.width,
height: app.height,
minWidth: app.minWidth,
minHeight: app.minHeight
})
}))
}
// Opens a window for the entity, or focuses (and restores, if minimized) the
@@ -115,7 +135,7 @@ export function openEntityWindow(slug: string | null): void {
wm.focus(slug)
return
}
wm.open({ id: slug, title: slug })
wm.open(clampToDesktop({ id: slug, title: slug }))
}
// Singleton "compose a new task" window — the Tasks app's New Task button
@@ -132,7 +152,7 @@ export function openNewTaskWindow(): void {
wm.focus(NEW_TASK_WINDOW_ID)
return
}
wm.open({ id: NEW_TASK_WINDOW_ID, title: 'New task', width: 900, height: 640, minWidth: 600, minHeight: 400 })
wm.open(clampToDesktop({ id: NEW_TASK_WINDOW_ID, title: 'New task', width: 900, height: 640, minWidth: 600, minHeight: 400 }))
}
// Same dedupe/restore/focus pattern as openEntityWindow, for a task/session's
@@ -149,5 +169,5 @@ export function openTaskWindow(sessionId: string | null, title: string): void {
wm.focus(id)
return
}
wm.open({ id, title, width: 900, height: 640, minWidth: 600, minHeight: 400 })
wm.open(clampToDesktop({ id, title, width: 900, height: 640, minWidth: 600, minHeight: 400 }))
}