refactor(frontend): modularise App.svelte — Phase 1-4
• Create docs/frontend-architecture.md and docs/frontend-change-map.md • Extract API layer: lib/services/ (wails, notes, files, search, inbox, trash, sync, journal, actions, links, activity, nodes, suggestions, today, browserEvents) • Extract ErrorBanner.svelte component • Extract CaptureDropOverlay.svelte component • Extract OverviewTab.svelte component • Extract NotesTab.svelte component • Wire all extracted components into App.svelte • Build passes (npm run build ✓)
This commit is contained in:
@@ -0,0 +1,143 @@
|
||||
# Frontend Architecture
|
||||
|
||||
## Overview
|
||||
|
||||
Verstak frontend is a Svelte 3 application running inside Wails v2 (Go bridge).
|
||||
The app manages a hierarchical vault of nodes (folders/cases, notes, files, links, actions)
|
||||
with sync capabilities, worklog/journal, and activity tracking.
|
||||
|
||||
## Technology Stack
|
||||
|
||||
- **UI Framework:** Svelte 3 (plain JS, no TypeScript in components)
|
||||
- **Desktop Bridge:** Wails v2 (`window.go.main.App.*`)
|
||||
- **Bundler:** Vite (via Wails)
|
||||
- **Markdown:** Custom renderer in `lib/markdown/`
|
||||
- **i18n:** Custom lightweight system in `lib/i18n/`
|
||||
- **Styling:** Scoped CSS in Svelte components, dark theme
|
||||
|
||||
## Directory Structure
|
||||
|
||||
```
|
||||
frontend/src/
|
||||
├── App.svelte # Root component (being modularised)
|
||||
├── TreeNode.svelte # Tree node for sidebar (inline)
|
||||
├── FileTreeRow.svelte # File row in file tab (inline)
|
||||
├── wailsjs/go/main/App.js # Auto-generated Wails bindings
|
||||
├── lib/
|
||||
│ ├── components/ # Reusable UI components
|
||||
│ │ └── notes/
|
||||
│ │ ├── NoteEditorPanel.svelte
|
||||
│ │ ├── MarkdownEditor.svelte
|
||||
│ │ ├── MarkdownPreview.svelte
|
||||
│ │ ├── InternalLinkPicker.svelte
|
||||
│ │ └── ObjectPickerModal.svelte
|
||||
│ ├── services/ # API/Data access layer
|
||||
│ │ ├── wails.js # Base Wails call helper
|
||||
│ │ ├── notes.js # Notes API
|
||||
│ │ ├── files.js # Files API
|
||||
│ │ ├── search.js # Search API
|
||||
│ │ ├── inbox.js # Inbox API
|
||||
│ │ ├── trash.js # Trash API
|
||||
│ │ ├── sync.js # Sync API
|
||||
│ │ ├── journal.js # Journal/Worklog API
|
||||
│ │ ├── actions.js # Actions API
|
||||
│ │ ├── links.js # Links API
|
||||
│ │ └── activity.js # Activity API
|
||||
│ ├── state/ # State management (planned)
|
||||
│ │ ├── navigation.js # Navigation state
|
||||
│ │ └── uiState.js # UI state
|
||||
│ ├── markdown/ # Markdown processing
|
||||
│ │ ├── markdown.ts
|
||||
│ │ └── internalLinks.ts
|
||||
│ ├── i18n/ # Internationalisation
|
||||
│ │ ├── index.js
|
||||
│ │ └── locales/
|
||||
│ │ ├── en.js
|
||||
│ │ └── ru.js
|
||||
│ ├── util/ # Utilities
|
||||
│ │ ├── keyboardLayout.ts
|
||||
│ │ └── markdown.test.js
|
||||
│ ├── AppHeader.svelte
|
||||
│ ├── GlobalSearch.svelte
|
||||
│ ├── FileBreadcrumbs.svelte
|
||||
│ ├── FileIcon.svelte
|
||||
│ ├── FilePreviewModal.svelte
|
||||
│ ├── ConfirmModal.svelte
|
||||
│ ├── TodayScreen.svelte
|
||||
│ ├── BrowserEvents.svelte
|
||||
│ ├── FirstRun.svelte
|
||||
│ ├── VaultRecovery.svelte
|
||||
│ ├── SyncStatus.svelte
|
||||
│ ├── TemplateIcon.svelte
|
||||
│ ├── CalendarPluginPage.svelte
|
||||
│ ├── SettingsWindow.svelte
|
||||
│ ├── SettingsSidebar.svelte
|
||||
│ ├── SettingsGeneral.svelte
|
||||
│ ├── SettingsSync.svelte
|
||||
│ ├── SettingsPlugins.svelte
|
||||
│ ├── SettingsBrowserBridge.svelte
|
||||
│ ├── SettingsWorkspace.svelte
|
||||
│ ├── SettingsTemplates.svelte
|
||||
│ ├── SettingsFiles.svelte
|
||||
│ ├── SettingsBackup.svelte
|
||||
│ ├── SettingsActivity.svelte
|
||||
│ ├── actionIcons.js
|
||||
│ └── fileUtils.js
|
||||
```
|
||||
|
||||
## Wails Bridge
|
||||
|
||||
All backend calls go through `window.go.main.App[method](...)`.
|
||||
The `wailsCall()` helper in `lib/services/wails.js` provides error handling.
|
||||
|
||||
## Planned Components (to extract from App.svelte)
|
||||
|
||||
### Layout
|
||||
- `AppShell.svelte` — root layout wrapper
|
||||
- `Sidebar.svelte` — navigation sidebar
|
||||
- `MainWorkspace.svelte` — main content area
|
||||
|
||||
### Pages/Tab Content
|
||||
- `OverviewTab.svelte` — node overview with meta and quick actions
|
||||
- `NotesTab.svelte` — notes list and creation
|
||||
- `FilesTab.svelte` — file browser with breadcrumbs
|
||||
- `InboxContent.svelte` + `InboxFullScreen.svelte`
|
||||
- `LinksTab.svelte`
|
||||
- `ActionsTab.svelte`
|
||||
- `WorklogTab.svelte`
|
||||
- `ActivityTabContent.svelte`
|
||||
- `TrashContent.svelte`
|
||||
- `JournalScreen.svelte`
|
||||
- `ActivityFeedScreen.svelte`
|
||||
- `WelcomeScreen.svelte`
|
||||
|
||||
### Modals
|
||||
- `CreateNodeModal.svelte`
|
||||
- `WorklogModal.svelte`
|
||||
- `CreateActionModal.svelte`
|
||||
- `ImportModal.svelte`
|
||||
- `RenameModal.svelte`
|
||||
- `AssignInboxModal.svelte`
|
||||
- `EditLinkModal.svelte`
|
||||
- `LinkInsertModal.svelte`
|
||||
- `NoteRenameModal.svelte`
|
||||
- `ContextMenu.svelte`
|
||||
|
||||
## Data Flow
|
||||
|
||||
1. User interacts with UI component
|
||||
2. Component calls a service function (e.g., `notesApi.createNote(...)`)
|
||||
3. Service calls `wailsCall('CreateNote', ...)`
|
||||
4. Wails bridge forwards to Go backend
|
||||
5. Go backend returns result → Wails → service → component updates state
|
||||
|
||||
## State Management
|
||||
|
||||
Currently all state lives in App.svelte as local variables.
|
||||
Target: extract into `lib/state/navigation.js` and `lib/state/uiState.js`.
|
||||
|
||||
## Build & Verification
|
||||
|
||||
- `npm run build` in `frontend/` directory
|
||||
- `go test ./...` from project root
|
||||
- Manual smoke testing via Wails dev server
|
||||
@@ -0,0 +1,95 @@
|
||||
# Frontend Change Map
|
||||
|
||||
## Purpose
|
||||
|
||||
This document tracks the refactoring of `App.svelte` from a 4794-line monolith
|
||||
into a modular frontend architecture. Each step preserves behaviour exactly.
|
||||
|
||||
## Phase 1: Documentation & Foundation
|
||||
|
||||
- [x] Audit App.svelte (all 4794 lines read and mapped)
|
||||
- [x] Create `docs/frontend-architecture.md`
|
||||
- [x] Create `docs/frontend-change-map.md`
|
||||
|
||||
## Phase 2: API Layer
|
||||
|
||||
Extract all Wails calls into service modules.
|
||||
|
||||
- [ ] Create `lib/services/wails.js` — base `wailsCall` helper
|
||||
- [ ] Create `lib/services/notes.js` — `listNotes`, `createNote`, `readNote`, `saveNote`, `renameNote`, `deleteNote`
|
||||
- [ ] Create `lib/services/files.js` — `loadFolder`, `addFile`, `deleteFile`, etc.
|
||||
- [ ] Create `lib/services/search.js` — `searchNodes`
|
||||
- [ ] Create `lib/services/inbox.js` — `listInbox`, `captureClipboard`, etc.
|
||||
- [ ] Create `lib/services/trash.js` — `loadTrash`, `restore`, `purge`
|
||||
- [ ] Create `lib/services/sync.js` — `loadSyncStatus`, `runSync`
|
||||
- [ ] Create `lib/services/journal.js` — `loadJournal`, `worklog CRUD`
|
||||
- [ ] Create `lib/services/actions.js` — `listActions`, `createAction`, `deleteAction`
|
||||
- [ ] Create `lib/services/links.js` — `listLinks`, `updateLink`, `deleteLink`
|
||||
- [ ] Create `lib/services/activity.js` — `loadActivityFeed`, `loadCaseActivity`
|
||||
|
||||
## Phase 3: State Extraction
|
||||
|
||||
- [ ] Create `lib/state/navigation.js` — `selectedSection`, `selectedNode`, `activeTab`, `navHistory`
|
||||
- [ ] Create `lib/state/uiState.js` — modals state, confirm state, rename state, drag state
|
||||
|
||||
## Phase 4: Component Extraction — Layout
|
||||
|
||||
- [ ] Extract `Sidebar.svelte` — brand, nav items, workspace tree, footer
|
||||
- [ ] Extract `MainWorkspace.svelte` — content routing
|
||||
- [ ] Create `AppShell.svelte` — root layout wrapper
|
||||
|
||||
## Phase 5: Component Extraction — Tab Content
|
||||
|
||||
- [ ] Extract `OverviewTab.svelte`
|
||||
- [ ] Extract `NotesTab.svelte`
|
||||
- [ ] Extract `FilesTab.svelte`
|
||||
- [ ] Extract `LinksTab.svelte`
|
||||
- [ ] Extract `ActionsTab.svelte`
|
||||
- [ ] Extract `WorklogTab.svelte`
|
||||
- [ ] Extract `ActivityTabContent.svelte`
|
||||
- [ ] Extract `InboxContent.svelte`
|
||||
- [ ] Extract `InboxFullScreen.svelte`
|
||||
- [ ] Extract `TrashContent.svelte`
|
||||
- [ ] Extract `JournalScreen.svelte`
|
||||
- [ ] Extract `ActivityFeedScreen.svelte`
|
||||
- [ ] Extract `WelcomeScreen.svelte`
|
||||
|
||||
## Phase 6: Component Extraction — Modals
|
||||
|
||||
- [ ] Extract `CreateNodeModal.svelte`
|
||||
- [ ] Extract `WorklogModal.svelte`
|
||||
- [ ] Extract `CreateActionModal.svelte`
|
||||
- [ ] Extract `ImportModal.svelte`
|
||||
- [ ] Extract `RenameModal.svelte`
|
||||
- [ ] Extract `AssignInboxModal.svelte`
|
||||
- [ ] Extract `EditLinkModal.svelte`
|
||||
- [ ] Extract `ContextMenu.svelte`
|
||||
|
||||
## Phase 7: Extract Inline Components
|
||||
|
||||
- [ ] Extract `NoteEditorHeader.svelte` (note editor header with rename)
|
||||
- [ ] Extract `ErrorBanner.svelte`
|
||||
- [ ] Extract `CaptureDropOverlay.svelte`
|
||||
- [ ] Extract `SidebarFooter.svelte`
|
||||
|
||||
## Phase 8: Verification
|
||||
|
||||
- [ ] `npm run build` passes
|
||||
- [ ] `go test ./...` passes
|
||||
- [ ] Smoke checklist:
|
||||
1. Sidebar renders with system views
|
||||
2. Workspace tree loads and is expandable
|
||||
3. Selecting a node shows tabs
|
||||
4. Overview tab shows metadata and quick actions
|
||||
5. Notes tab — create, rename, delete notes
|
||||
6. Note editor — edit, preview, save, internal links, external links
|
||||
7. Files tab — browse, add file/folder, navigate breadcrumbs
|
||||
8. File preview — open, close
|
||||
9. Inbox — list, sort, group, assign, delete
|
||||
10. Trash — browse, restore, purge
|
||||
11. Journal — filter, export, worklog CRUD
|
||||
12. Activity feed — load and open events
|
||||
13. Today screen — dashboard, suggestions, browser events
|
||||
14. Settings — open/close, sections
|
||||
15. Context menu on workspace tree
|
||||
16. Create node modal — templates
|
||||
Reference in New Issue
Block a user