fix(web): window/table polish — opaque windows, sortable columns, sticky-header scrollbar, viewport-clamped windows
- 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:
@@ -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 }))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user