mirror of
https://github.com/PerpetualSoftware/pad.git
synced 2026-09-24 03:16:43 +00:00
634e834f22
* feat(board): Trello-style inline draft card creation (TASK-1676) Replace the lane `+` direct-navigate (TASK-1671) with an inline draft card. Clicking `+` (or "Add item here") opens an editable card in the lane — no item exists yet. Enter creates it (group value pre-filled) and opens it; blur keeps the card without saving; Escape hides it but retains the text so reopening restores it (until reload). Drafts are per-lane and in-memory. A beforeNavigate guard intercepts in-app navigation while any lane has unsaved draft text and shows a Save / Discard / Stay dialog: Save creates all pending drafts (in place, no navigate) then proceeds, Discard drops them, Stay cancels. Reload/tab-close aren't guarded (nav.to is null) — drafts intentionally live only until reload. quickCreateInColumn now takes (groupValue, title, navigate) and returns the created item / throws so the draft can be restored on failure. The draft card renders above the dndzone so it isn't draggable. * fix(board): lift draft state to page + clear-each-on-save per Codex review (round 1) (1) BoardView unmounts on a board↔list view switch, which destroyed unsaved inline drafts and bypassed the leave guard. Move the draft state (draftText/draftOpen) to the page and bind it into BoardView, and move the beforeNavigate guard + Save/Discard/Stay dialog to the page (always mounted). A draft now survives view switches (state persists; the card just isn't rendered off-board) and the guard fires regardless of view. (2) leaveSaveAll cleared all drafts only after the whole loop, so a retry after a partial failure re-created already-saved drafts. Clear each draft as its create succeeds. * fix(board): only guard true leaves, not same-page URL syncs per Codex review (round 2) beforeNavigate fired on every goto while a draft existed — including the replaceState query/view-state syncs from updateUrlFilters (view toggle, filters, search). Switching Board→List or tweaking a filter wrongly opened the Save/Discard dialog. Skip navigations whose destination pathname equals the current one (internal same-page sync); the draft survives those as page state, so only true page leaves are guarded. * fix(board): don't guard willUnload navigations per Codex review (round 3) For native/external navigations (willUnload), goto can't replay the leave after cancel, so Save/Discard could strand the user. Skip guarding willUnload (and full-unload) navigations — treated like reload, drafts intentionally lost — so the replay path is always a client-side goto. * fix(board): replay Back/Forward with history.go to preserve history per Codex review (round 4) Cancelling a popstate (Back/Forward) navigation then replaying via goto(url) pushed the target as a new history entry, corrupting Back. Capture nav.type/nav.delta and replay popstate with history.go(delta); non-popstate leaves still replay with goto.
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