mirror of
https://github.com/PerpetualSoftware/pad.git
synced 2026-09-21 01:53:33 +00:00
f9a248f4da
* feat(web): print-format the item detail page (TASK-622) Layer item-page print formatting on top of the base stylesheet added in TASK-621: - Title row renders as plain text (large, serif-friendly, no button affordance); issue ref prefix stays as a subtle prefix. - Meta info (created/updated + actor) keeps as small-print subtitle. - Properties panel becomes a definition-list block (label / value grid) wrapped in a light card, with form widgets stripped so the selected value reads as plain text. - Content layout stacks the fields panel above the markdown body (no side-by-side columns in print). - Code context section, relationships list, and child items stay. - Comments / activity / version timeline are hidden entirely. - Action buttons, breadcrumb, share/move/delete controls, edit-mode toggle, add-relationship form, save-status chip, link-delete buttons are all stripped. Rendered markdown (.prose) gets a print tune-up in app.css: 11pt body, inline URL suffix on external links (skipped for wiki-links and fragment links), break-inside guards on code / images / tables, light-palette overrides for code blocks and blockquotes. Editor overlays (bubble menu, link popover, slash menu, mobile toolbar, table toolbar, editor toolbar) are hidden in print. Parent: PLAN-620. * fix(web): keep relationship status chips + print title during edit mode (PR #153) Address Codex P2 review comments on TASK-622: - Relationship rows: previously hid the entire `.link-row-actions` wrapper, which silently dropped the `.link-status` chip alongside the destructive delete button. Hide only `.link-delete-btn` so the status stays visible in print. - Title during inline edit: the screen renders either a `.title` button (read) or a `.title-input` textarea (edit); previous rules displayed the button and hid the textarea, so printing while editing produced a title-less page. Apply the same print typography to both, turning the textarea into a non-interactive, borderless plain-text heading. * fix(web): preserve checkbox field state in print output (PR #153) Address Codex P2 review comment on TASK-622. The form-widget strip rule `.field-value button { border: none; background: transparent; }` killed the visual state of `.toggle` (the checkbox field's switch button), since it renders state purely via styling — no text label. The printed page would lose the on/off signal entirely. Exempt `.toggle` from the strip rule via `:not(.toggle)` and add a dedicated print style that renders the toggle as an outlined 11pt box; when the field is on, overlay a check mark via `::after`. The toggle-knob is hidden (it's the sliding switch visual, not useful in print). * fix(web): print URL suffixes for SafeLink + print raw markdown legibly (PR #153) Address Codex P2 review comments on TASK-622: - Rich-editor links (Tiptap SafeLink extension) render with `data-href` instead of `href`, so the print suffix rule `.prose a[href]::after` never fired for the main document body. Add a parallel selector `.prose a[data-href]::after { content: " (" attr(data-href) ")"; }` plus matching skips for internal data-href wiki-links. - The Markdown editor's raw textarea had no print styling. Printing while the Markdown tab was active either clipped the textarea to its screen height or rendered with dark-theme chrome. Add a @media print block to `RawMarkdownEditor.svelte` that flattens the textarea into a plain monospace flow: no border, no background, auto height, visible overflow, page-break-inside: auto. Content prints as markdown source -- not ideal, but readable and content-preserving. * fix(web): hoist FieldEditor print strip rules to global scope (PR #153) Address Codex P2: the `.field-value select / input / button / .toggle` print overrides were defined inside the item detail page's scoped style block. Svelte scoped selectors don't cross component boundaries, so the form widgets rendered inside `FieldEditor` kept their interactive styling in print preview -- selects rendered with their screen chrome, toggles disappeared, etc. Move these rules into app.css's @media print block (which applies globally) and leave a note in +page.svelte explaining why. The `.assignment-select` rule stays in +page.svelte because those selects are inline in this template and correctly scoped.
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