Redesign writing assistant UI: right-side panel, diff view, proofread, floating inline assist
- sectionParser.ts: add parseFallbackSections() — splits heading-less notes by paragraph boundaries; single-line ≤120 char paragraphs become pseudo-headings so Q&A-style notes get individual selectable sections in the assist panel - useAssist.ts: add DiffLine type + computeDiff() (LCS line diff), isProofreading ref, diff computed, proofread() method (full-document one-click), reset isProofreading in accept() and reject() - NoteEditorView + TaskEditorView: complete layout redesign - Assist panel moves from bottom 33% to right-side 320px column (flex-row) - ✨ Assist toggle button in toolbar, state persisted to localStorage - Floating ✨ pill button (teleported to <body>) above text selections; click opens panel with selection pre-loaded and instruction textarea focused - Proofread button in panel header: sends entire document, labels streaming as "Proofreading document..." and review as "Document proofread" - Review state shows LCS line-level diff (red removed, green added); "Show full text" toggle switches to rendered proposal - Mobile (≤768px): panel drops to bottom 45% height - theme.css: add global .inline-assist-btn styles for teleported floating button - Site-wide max-width increase: list/chat/settings views 960px→1200px; viewer layout 1200px→1400px (content area 960px→1100px); editor pages already at 1400px Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+13
-7
@@ -12,7 +12,7 @@
|
||||
> Include file-level details in the commit body when the change is non-trivial.
|
||||
|
||||
## Last Updated
|
||||
2026-02-19 — Phase 12: persistent context sidebar, note title in chat, expanded tool suite
|
||||
2026-02-19 — Phase 13: Writing assistant UI redesign (right-side panel, diff view, proofread, floating inline assist, fallback section detection, increased site-wide max-width)
|
||||
|
||||
## Project Overview
|
||||
Fabled Assistant is a self-hosted note-taking and task-tracking application with
|
||||
@@ -285,14 +285,14 @@ fabledassistant/
|
||||
│ ├── App.vue # Shell: .app-shell (100dvh flex column) with AppHeader + .app-content (flex:1, scrollable) wrapping router-view; starts status polling + loads settings on mount
|
||||
│ ├── main.ts # App init, imports theme.css
|
||||
│ ├── assets/
|
||||
│ │ └── theme.css # CSS custom properties: light/dark themes, body reset, design tokens, responsive breakpoints (480/768/1024), utility classes (.hide-mobile/.hide-desktop), mobile touch targets
|
||||
│ │ └── theme.css # CSS custom properties: light/dark themes, body reset, design tokens, responsive breakpoints (480/768/1024), utility classes (.hide-mobile/.hide-desktop), mobile touch targets; global .inline-assist-btn (teleported floating pill)
|
||||
│ ├── api/
|
||||
│ │ └── client.ts # ApiError class, apiGet/apiPost/apiPut/apiPatch/apiDelete + apiSSEStream (fetch+ReadableStream), apiStreamPost (legacy), auto 401→login redirect
|
||||
│ ├── composables/
|
||||
│ │ ├── useTheme.ts # Theme toggle, localStorage, prefers-color-scheme
|
||||
│ │ ├── useShortcuts.ts # Shared showShortcuts ref + open/close/toggle helpers (used by App.vue + AppHeader.vue)
|
||||
│ │ ├── useAutocomplete.ts # Legacy textarea autocomplete (replaced by Tiptap suggestion extensions)
|
||||
│ │ └── useAssist.ts # AI Assist composable: section parsing, target selection, two-step POST+SSE streaming (apiPost → apiSSEStream), accept/reject; watches body ref for auto-sync
|
||||
│ │ └── useAssist.ts # AI Assist composable: section parsing, target selection, two-step POST+SSE streaming (apiPost → apiSSEStream), accept/reject, proofread (full-document), LCS line diff (DiffLine/computeDiff), isProofreading ref; watches body ref for auto-sync
|
||||
│ ├── stores/
|
||||
│ │ ├── auth.ts # Auth state: user, isAuthenticated, isAdmin, login/register/logout/checkAuth
|
||||
│ │ ├── notes.ts # CRUD + tag filter, resolveTitle, convertToTask, convertToNote, fetchBacklinks, fetchAllTags (with toast errors)
|
||||
@@ -315,7 +315,8 @@ fabledassistant/
|
||||
│ ├── utils/
|
||||
│ │ ├── tags.ts # extractTags(), linkifyTags() (with (?<!&) to skip HTML entities), linkifyWikilinks()
|
||||
│ │ ├── markdown.ts # renderMarkdown() (full) + renderPreview() (strips links/images) — decodes HTML entities before marked, replaces ' after sanitization
|
||||
│ │ └── markdownSerializer.ts # Tiptap JSON → markdown serializer: handles all StarterKit nodes + marks
|
||||
│ │ ├── markdownSerializer.ts # Tiptap JSON → markdown serializer: handles all StarterKit nodes + marks
|
||||
│ │ └── sectionParser.ts # parseMarkdownSections() (heading-based) + parseFallbackSections() (paragraph/Q&A-style — single-line ≤120 char paragraphs become pseudo-headings)
|
||||
│ ├── views/
|
||||
│ │ ├── LoginView.vue # Login form with error display, link to register
|
||||
│ │ ├── RegisterView.vue # Register form with password confirmation; shows "closed" message when registration disabled
|
||||
@@ -325,10 +326,10 @@ fabledassistant/
|
||||
│ │ ├── HomeView.vue # Actionable dashboard: overdue, due today, due this week, high priority, in progress tasks; recent chats with inline chat input; recently edited notes; model warming on mount
|
||||
│ │ ├── SettingsView.vue # Settings page: assistant name, model catalog, data export/restore (admin)
|
||||
│ │ ├── NotesListView.vue # Note list: search, sort, tag filter pills, pagination
|
||||
│ │ ├── NoteEditorView.vue # Create/edit: Tiptap editor, sticky toolbar, AI Assist panel (bottom 1/3), LLM tag suggestions, Ctrl+S, unsaved guard
|
||||
│ │ ├── NoteEditorView.vue # Create/edit: Tiptap editor, sticky toolbar, AI Assist panel (right-side 320px, collapsible), line-level diff view, Proofread action, floating inline ✨ pill on text selection, LLM tag suggestions, Ctrl+S, unsaved guard
|
||||
│ │ ├── NoteViewerView.vue # Markdown render, wikilink auto-create, convert-to-task, backlinks, table of contents sidebar
|
||||
│ │ ├── TasksListView.vue # Task list: search, status/priority filters, sort, pagination
|
||||
│ │ ├── TaskEditorView.vue # Create/edit task: Tiptap editor, sticky toolbar, AI Assist panel, LLM tag suggestions, Ctrl+S, dirty guard
|
||||
│ │ ├── TaskEditorView.vue # Create/edit task: Tiptap editor, sticky toolbar, AI Assist panel (right-side 320px, collapsible), line-level diff view, Proofread action, floating inline ✨ pill on text selection, LLM tag suggestions, Ctrl+S, dirty guard
|
||||
│ │ └── TaskViewerView.vue # Task detail: rendered markdown, badges, convert-to-note, backlinks, table of contents sidebar
|
||||
│ ├── components/
|
||||
│ │ ├── LogsView.vue # Admin log viewer: stats summary, category/search/date filters, paginated table with expandable detail rows
|
||||
@@ -512,7 +513,7 @@ When adding a new migration, follow these conventions:
|
||||
- Task attributes: status (todo/in_progress/done), priority (none/low/medium/high), due_date
|
||||
- Obsidian-style `[[wikilinks]]` with auto-create on click, backlinks ("what links here")
|
||||
- Tiptap WYSIWYG editor with markdown round-trip, tag/wikilink autocomplete and decorations, sticky toolbar
|
||||
- AI Assist panel in editor: background LLM generation via SSE with section targeting, accept/reject
|
||||
- AI Assist panel (right-side 320px, toggle persisted to localStorage): section targeting, floating ✨ pill on text selection, full-document Proofread action, line-level diff view in review state (LCS algorithm), "Show full text" toggle, accept/reject; panel collapses to bottom 45% on mobile (≤768px)
|
||||
- Table of contents sidebar on note/task viewers (auto-generated from headings, hidden ≤1200px)
|
||||
- Inline edit buttons on NoteCard/TaskCard (hover on desktop, always visible on touch)
|
||||
- Search (ILIKE), sort, tag filter pills, pagination on list views
|
||||
@@ -660,6 +661,7 @@ When adding a new migration, follow these conventions:
|
||||
- App shell: navbar always visible, 100dvh flex layout, all views fit within viewport
|
||||
- Toast notifications (success/error/warning, 4s auto-dismiss)
|
||||
- DOMPurify sanitization on all rendered markdown
|
||||
- **Site-wide max-width:** List/chat/settings views 1200px; editor pages 1400px; note/task viewer layout 1400px (content area 1100px)
|
||||
|
||||
### Infrastructure
|
||||
- Multi-stage Dockerfile: Node build → Python runtime, auto-migration on startup
|
||||
@@ -684,3 +686,7 @@ When adding a new migration, follow these conventions:
|
||||
- Application-level rate limiting on auth endpoints
|
||||
- Security headers middleware (CSP, X-Frame-Options, etc.) — currently handled at reverse proxy level
|
||||
- Session invalidation on user deletion
|
||||
- **Note relation map (Obsidian-style graph):** Interactive force-directed graph visualizing connections between
|
||||
notes via wikilinks (`[[Title]]`) and shared tags. Nodes = notes/tasks; edges = wikilink references or
|
||||
tag co-occurrence. Clicking a node navigates to that note. Filter by tag or depth. Useful for discovering
|
||||
clusters of related notes and orphaned notes with no connections.
|
||||
|
||||
Reference in New Issue
Block a user