mirror of
https://github.com/PerpetualSoftware/pad.git
synced 2026-09-24 11:26:34 +00:00
45d032cb09
* fix(web): graph node click/dbl-click + Open as real link (TASK-1788) Three interaction fixes for the per-item graph (TASK-1787 follow-up): - Click-to-select and double-click-to-zoom didn't fire. Root cause: the viewport called setPointerCapture on pointerdown, which suppressed the SVG nodes' click/dblclick events. Now drag/capture engages only after the pointer moves past a 4px threshold, so a plain press still produces a node click; a gesture that became a pan suppresses the trailing click via a flag. - Open actions are now real <a href> links (controls "Open ↗" and the detail panel "Open item ↗"), so cmd/ctrl-click opens the item in a new tab; a plain click is a normal SvelteKit navigation that closes the drawer via the ?graph URL effect. Replaced the onOpenItem callback prop with an itemHref builder. Parent: PLAN-1780. * fix(web): robust pan/click suppression per Codex review (round 1) - Clear suppressClick when the drag gesture ends (deferred one tick so the trailing click is still suppressed) instead of waiting for the next node click. Fixes a pan ending on empty canvas leaving the flag set and swallowing the next intentional click. - Guard onPointerMove on e.buttons: if the primary button isn't held (press ended off-viewport before a drag engaged, so no pointerup was seen), abort instead of starting a ghost pan when the pointer returns. Parent: PLAN-1780.
Pad Web UI
SvelteKit 2 + Svelte 5 frontend for Pad, compiled to static files and embedded into the Go binary.
Development
npm install
npm run dev # Dev server at localhost:5173 (proxies API to localhost:7777)
npm run build # Production build to build/
npm run check # Type checking with svelte-check
When developing, run the Go backend separately with make dev from the project root.
Building for Production
Do not build in isolation. Always use make build from the project root — this builds the web frontend, then compiles the Go binary with the build output embedded via //go:embed.
Stack
- Svelte 5 with runes (
$state,$derived,$effect) - SvelteKit 2 with
adapter-static(SPA mode) - Tiptap block editor with markdown round-trip
- svelte-dnd-action for drag-and-drop in board/list views
- SSE for real-time updates
- TypeScript throughout
Structure
src/
routes/ SvelteKit pages
+layout.svelte App shell (sidebar + main)
+page.svelte Landing/redirect
[workspace]/
+page.svelte Dashboard (collections, phases, activity)
+layout.svelte SSE connection per workspace
[collection]/
+page.svelte Collection view (board/list)
[collection]/[item]/
+page.svelte Item detail + editor
conventions/ Purpose-built conventions page
playbooks/ Purpose-built playbooks page
settings/ Workspace settings
lib/
api/client.ts HTTP API client
components/
layout/ Sidebar, navigation
editor/ Tiptap editor, raw markdown editor
fields/ FieldEditor, relation picker
items/ ItemCard, ItemDetail
collections/ BoardView, ListView
common/ StatusBadge, badges, modals
search/ CommandPalette
activity/ ActivityFeed
stores/ Svelte 5 reactive stores
workspace.svelte.ts Workspace state
collections.svelte.ts Collection + item state
ui.svelte.ts Sidebar, mobile state
types/index.ts TypeScript types and constants
app.css Global styles and design tokens