feat(phase2): localization EN/RU + additional widget types
- Add svelte-i18n with 224 translation keys (English + Russian) - Language switcher in header (EN/RU toggle, persists to localStorage) - Extract all hardcoded strings from 37 component/page files - Add 4 new widget types: Bookmark, Note (markdown), Embed (iframe), Status - WidgetRenderer dispatches by type, WidgetGrid supports full-width widgets - Type-specific config forms in board editor - Install marked for markdown rendering
This commit is contained in:
@@ -31,3 +31,33 @@ Admin settings page has a working "Test Connection" button for OAuth configurati
|
||||
- Extended `boardService.ts` with `reorderSections()`, `reorderWidgets()`, `moveWidget()` using Prisma transactions
|
||||
- Visual drag handles (grip dots) and dashed drop zone indicators added via Tailwind
|
||||
- Edit page actions (add/delete section/widget) use `invalidateAll()` for data refresh; DnD uses optimistic fetch
|
||||
|
||||
## Phase 4 (Additional Widget Types) — Completed
|
||||
- Installed `marked` package for markdown rendering
|
||||
- WidgetType enum already had BOOKMARK, NOTE, EMBED, STATUS from MVP constants
|
||||
- Added per-type Zod config schemas in `validators.ts`: `appWidgetConfigSchema`, `bookmarkWidgetConfigSchema`, `noteWidgetConfigSchema`, `embedWidgetConfigSchema`, `statusWidgetConfigSchema`
|
||||
- Updated `src/lib/types/widget.ts` config interfaces to match spec (BookmarkWidgetConfig, NoteWidgetConfig, EmbedWidgetConfig, StatusWidgetConfig)
|
||||
- Created 4 new widget components:
|
||||
- `BookmarkWidget.svelte` — clickable card with icon, label, description, opens URL in new tab
|
||||
- `NoteWidget.svelte` — renders markdown via `marked` with basic HTML sanitization
|
||||
- `EmbedWidget.svelte` — iframe with configurable height, sandbox security, loading spinner
|
||||
- `StatusWidget.svelte` — aggregated status bar with online/offline/degraded/unknown counts, expandable per-app detail
|
||||
- Created `WidgetRenderer.svelte` — universal type-switch component dispatching to correct widget by type
|
||||
- Updated `WidgetGrid.svelte` to use WidgetRenderer; note/embed/status widgets span full grid width
|
||||
- Updated `DraggableSection.svelte` with widget type selector dropdown and type-specific config forms (app selector, bookmark URL/label/icon/desc, note textarea with format, embed URL/height, status multi-select apps)
|
||||
- `onAddWidget` callback changed from `(sectionId, appId)` to `(sectionId, widgetDataJson)` across DraggableBoard and edit page
|
||||
- Board view server (`[boardId]/+page.server.ts`) now loads all apps via `appService.findAll()` for StatusWidget
|
||||
- Plumbed `allApps` prop through Board -> Section -> WidgetGrid -> WidgetRenderer -> StatusWidget
|
||||
- Edit server action `addWidget` now handles `configJson` form field for non-app widget types
|
||||
|
||||
## Phase 3 (Localization EN/RU) — Completed
|
||||
|
||||
- Installed `svelte-i18n` package for i18n support
|
||||
- Created `src/lib/i18n/en.json` and `src/lib/i18n/ru.json` with ~180 translation keys covering all UI strings
|
||||
- Created `src/lib/i18n/index.ts` with locale detection (localStorage > browser navigator > fallback 'en') and `storeLocale()` helper
|
||||
- Created `LanguageSwitcher.svelte` — EN/RU toggle button added to Header, persists preference to localStorage key `wal-locale`
|
||||
- Root `+layout.svelte` imports `$lib/i18n/index.js` to initialize i18n before any component renders
|
||||
- Extracted all hardcoded strings from: layout (Header, Sidebar, MainLayout, ThemeToggle), auth pages (login, register), board/section/widget components, app components (AppForm, AppHealthBadge, AppIconPicker), admin pages (users, groups, settings, PermissionEditor), search components (SearchDialog, SearchTrigger), home page, and DnD components
|
||||
- Translation key structure uses dot-notation grouped by feature: `nav.*`, `auth.*`, `board.*`, `section.*`, `widget.*`, `app.*`, `admin.*`, `search.*`, `common.*`, `status.*`, `theme.*`, `bg.*`, `sidebar.*`, `home.*`
|
||||
- All status labels (online/offline/degraded/unknown) are now translated via `$t('status.*')` in AppHealthBadge
|
||||
- Phase 4 widget type form labels (bookmark, note, embed, status fields) are partially untranslated — can be addressed in Phase 6
|
||||
|
||||
Reference in New Issue
Block a user