162 lines
6.2 KiB
Markdown
162 lines
6.2 KiB
Markdown
# 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`.
|
|
|
|
### Files Flow
|
|
|
|
- **Component:** `lib/components/files/FilesTab.svelte` — self-contained file browser
|
|
- **API services:** `lib/services/files.js`, `lib/services/nodes.js`
|
|
- **Events emitted:**
|
|
- `on:openNote` — when a .md file linked to a note is opened
|
|
- `on:refreshParent` — after file operations that modify the tree
|
|
- `on:error` — on operation failures
|
|
- `on:rename` — requests parent to show rename modal
|
|
- `on:confirm` — requests parent to show confirm dialog
|
|
- **Public methods:**
|
|
- `resetToNode(nodeId)` — reset state when selected node changes
|
|
- `filesHandleKeydown(e)` — keyboard handler for files tab
|
|
- **.md → note editor flow:** Handled inside FilesTab via `CheckFileAction` Wails call. If action is 'note', emits `openNote`. If 'external', opens in system viewer. Otherwise shows built-in preview.
|
|
- **File preview:** `FilePreviewModal.svelte` (already existed), invoked by FilesTab
|
|
- **Import dialog:** Inline in FilesTab template (moved from App.svelte)
|
|
|
|
## Build & Verification
|
|
|
|
- `npm run build` in `frontend/` directory
|
|
- `go test ./...` from project root
|
|
- `bash scripts/build.sh gui` for full GUI binary
|
|
- Manual smoke testing via Wails dev server
|