Commit Graph

3 Commits

Author SHA1 Message Date
m
ba2408eb51 feat(paliadin/inline-widget): t-paliad-161 Slice C — floating button + slide-out drawer
The inline Paliadin chat surface — reachable from every authenticated
page, replacing the standalone /paliadin route as the primary entry
point. The standalone page survives as the dedicated full-screen mode
(the drawer's "↗ fullscreen" action links to it).

Components:

- frontend/src/components/PaliadinWidget.tsx — emits the floating
  trigger button (bottom-right, lime , owner-revealed by JS), a
  scrim, and the right-edge slide-out drawer with header (reset /
  fullscreen / close), context chip, message stream, empty-state
  starter list, and textarea+send form. Loads /assets/paliadin-widget.js.

- frontend/src/client/paliadin-widget.ts — runtime. /api/me probe
  reveals the trigger when caller matches PaliadinOwnerEmail (with
  optional is_paliadin_owner flag fast-path); Cmd+J / Ctrl+J shortcut
  toggles open/close (Cmd+K stays reserved for global search per
  client/search.ts). Uses computePaliadinContext() (Slice B) per send
  so route + entity + selection flow into every turn. SSE consumer
  writes assistant bubbles; localStorage persists per-session history.

- frontend/src/client/paliadin-starters.ts — per-route starter prompt
  registry. 14 routes covered (dashboard, projects.*, deadlines.*,
  appointments.*, agenda, events, inbox, tools.*, glossary, courts) +
  a _default fallback. Bilingual (DE/EN); prompts ending in `: ` seed
  the textarea for the user to finish; fully-formed prompts auto-send.

- 39 authenticated TSX pages get a `<PaliadinWidget />` element after
  `<Footer />` via a mechanical pass. paliadin.tsx (the standalone)
  is intentionally excluded — its dedicated UI is the widget's
  fullscreen escape hatch, not a place to overlay another widget.

- frontend/build.ts registers the new bundle.
- frontend/src/styles/global.css gains ~280 lines of widget CSS
  (trigger / scrim / drawer / header / context-chip / messages /
   bubbles / starters / form / send-btn) using only existing tokens.
   Mobile (≤640px): drawer goes full-screen; trigger lifts above
   bottom-nav slots.
- 11 new i18n keys × 2 langs = 22 entries under paliadin.widget.*.

Visibility predicate (paliadin-context.shouldSendContext) hides the
widget on /paliadin, /login, /onboarding. Owner-only gate stays on
PaliadinOwnerEmail.

Build clean: i18n 1955 → 1966 keys, IIFE-wrapped 218KB bundle, go test
green.

Refs: docs/design-paliadin-inline-2026-05-08.md §3, §5.
2026-05-08 19:54:18 +02:00
m
35f307d61d fix(i18n): Sicht → Ansicht (custom views) — m's call: View is always Ansicht. Sweep applied to /views + /views/editor + sidebar + onboarding strings. Approval-context 'Sicht' (visibility-tier in derived team) left as-is — different semantic. 2026-05-07 22:22:33 +02:00
m
fdde9eb754 feat(t-paliad-144 A2): frontend Custom Views UI
Phase A2 of the data-display-model rethink. Builds on A1's API contract
(merged as cda4b40). User-visible.

What lands:

- TSX shells for /views (the view runner) and /views/new + /views/{slug}/edit
  (the editor). One TSX per page; client/views.ts + views-editor.ts
  hydrate.

- Three render-shape components in client/views/: shape-list.ts (table
  for density=comfortable, compact one-line stream for density=compact —
  the activity-feed look without a separate "activity" shape per Q4 lock-
  in 2026-05-07), shape-cards.ts (day-grouped chronological), and
  shape-calendar.ts (month grid with day-pills, mobile cards-fallback
  notice on viewports <600px per design §9 trade-off 8).

- Generic view shell that resolves a slug to a system view (via
  /api/views/system) or a user view (via /api/user-views), runs it via
  POST /api/views/{slug}/run, dispatches to the matching shape, exposes
  a 3-button shape switcher that swaps the live render without re-fetching,
  and surfaces the inaccessible-projects toast when the substrate flags
  some IDs (Q17 fail-open attribution).

- View editor with widgets for name/slug/icon, sources (4 checkboxes),
  scope mode (all_visible / my_subtree / personal_only), time horizon
  (six fixed options), shape, and list density. Slug regex enforced
  client-side mirroring the server validator. Save → POST/PATCH; delete
  → simple yes/no confirm (Q25 lock-in).

- Sidebar "Meine Sichten" group between Arbeit and Werkzeuge. Renders
  empty server-side; client/sidebar.ts.initUserViewsGroup() hydrates from
  GET /api/user-views on mount, injecting one nav item per saved view
  + an always-present "+ Neue Sicht" trailing entry. show_count=true
  views get a sidebar badge updated by a fire-and-forget run query.

- Page handlers /views (most-recently-used redirect or onboarding shell),
  /views/{slug}, /views/new, /views/{slug}/edit. All gateOnboarded.

- 91 new i18n keys (DE+EN) covering nav.group.user_views, view shell,
  shape labels, source/kind/horizon/scope vocabulary, editor form,
  empty/error/onboarding states.

- ~250 lines of CSS for the views shell, list/cards/calendar shapes,
  Meine Sichten sidebar group.

- build.ts registers views.tsx + views-editor.tsx page renderers and
  the two client bundles.

Frontend builds clean (i18n codegen 1700→1791 keys), backend builds +
vets clean, all tests pass, IIFE wrap intact on the new bundles.
2026-05-07 13:15:55 +02:00