1c0a7cb850
Phase 4 — New Widget Types: - Clock/Weather, System Stats, RSS/Feed, Calendar, Markdown, Metric/Counter, Link Group, Camera/Stream widgets - Backend services with caching for each data source - Full creation form with dynamic config fields per type Phase 5 — Visual & Styling Enhancements: - Glassmorphism card style (solid/glass/outline) - Board-level themes with per-board hue/saturation - Animated SVG status rings replacing static dots - Card size options (compact/medium/large) - Custom CSS injection (admin + per-board, sanitized) - Wallpaper backgrounds with blur/overlay/parallax Phase 6 — Functional Features: - Favorites bar with drag-and-drop reordering - Recent apps tracking with privacy toggle - Uptime dashboard page (/status, guest-accessible) - Notifications system (Discord/Slack/Telegram/HTTP webhooks) - App tags with filtering in board view - Multi-URL app cards with expandable sub-links - Personal API tokens with scoped permissions - Audit log with retention and admin viewer Phase 7 — Quality of Life: - Onboarding wizard (5-step first-launch setup) - App URL health preview with favicon/title detection - Board templates (4 built-in + custom import/export) - Keyboard shortcut overlay (j/k nav, 1-9 boards, ? help) 212 files changed, 15641 insertions, 980 deletions. Build, lint, type check, and 222 tests all pass.
13 KiB
13 KiB
Phase 6: Functional Features — Frontend
Status: ✅ Complete Parent plan: PLAN.md Domain: frontend
Objective
Build all frontend UI for the 8 functional features: favorites bar, recent apps, uptime dashboard page, notifications, tag management + filtering, multi-URL app cards, API token management, and audit log viewer.
Tasks
6.1 Favorites Bar
- Create
src/lib/components/layout/FavoritesBar.svelte- Horizontal bar at top of board view, below header
- Shows favorite app icons in compact format (icon + name)
- Drag-and-drop reordering within the bar (svelte-dnd-action)
- Click opens app URL; right-click or long-press to remove
- Add-to-favorites button on app widget context menu
- Create
src/lib/stores/favorites.svelte.ts- Fetch favorites from
/api/favoriteson init - Methods: add, remove, reorder (optimistic updates with API sync)
- Fetch favorites from
- Integrate FavoritesBar into board layout (show when user has favorites)
6.2 Recent Apps Section
- Create
src/lib/components/board/RecentAppsSection.svelte- Auto-generated section at top of default board
- Shows last 10 unique apps the user clicked
- Compact app cards (icon + name + last used time)
- "Clear history" button
- Respects user's
trackRecentAppspreference
- Update app click handling to record clicks via
/api/recent-appsPOST - Add privacy toggle in user settings (trackRecentApps)
6.3 Uptime Dashboard Page
- Create
src/routes/status/+page.svelte— public status page - Create
src/routes/status/+page.server.ts— load uptime data (guest-accessible)- Time range selector: 24h / 7d / 30d
- Per-app: name, current status, uptime percentage, avg response time
- Sparkline chart (larger than widget version) with hover tooltips
- Incident timeline: colored blocks showing up/down periods
- Summary header: total apps, apps online, overall uptime %
- Add "Status Page" link to sidebar navigation
6.4 Notifications UI
- Create
src/lib/components/notifications/NotificationBell.svelte- Bell icon in header with unread count badge
- Click opens notification dropdown/panel
- List of recent notifications with read/unread state
- "Mark all as read" button
- Link to full notification history
- Create
src/lib/components/notifications/NotificationHistory.svelte- Full page or modal with paginated notification list
- Filter by app, event type
- Timestamp, app name, event description
- Create
src/lib/components/notifications/NotificationChannelForm.svelte- Form to add/edit notification channels
- Dynamic fields based on channel type (Discord: webhook URL, Slack: webhook URL, Telegram: bot token + chat ID, HTTP: URL + method)
- "Send Test" button
- Enable/disable toggle per channel
- Create
src/routes/settings/notifications/+page.svelte— notification preferences page - Create
src/lib/stores/notifications.svelte.ts- Track unread count, poll for new notifications
6.5 Tag Management & Filtering
- Create
src/lib/components/admin/TagManager.svelte- Admin page to CRUD tags (name + color picker)
- Table/grid of existing tags with edit/delete
- Create
src/lib/components/app/TagBadge.svelte- Small colored badge showing tag name
- Used in app cards (large card size) and app edit forms
- Create
src/lib/components/board/TagFilter.svelte- Filter bar within board view
- Toggle buttons for each tag (active/inactive)
- When active, only show apps with selected tags
- "Clear filters" button
- Add tag assignment to app edit form (multi-select from existing tags)
- Add tag management page to admin panel navigation
6.6 Multi-URL App Cards
- Update
src/lib/components/widget/AppWidget.svelte- If app has secondary links, show expand indicator
- On hover/click expand to reveal sub-links list
- Each sub-link: icon + label, click opens in new tab
- Primary URL is the main card click target
- Smooth expand/collapse animation (slide transition)
- Create
src/lib/components/app/AppLinksEditor.svelte- Used in app edit form
- Add/remove/reorder secondary links
- Each link: label input + URL input + optional icon picker
- Drag-and-drop reorder
6.7 API Token Management
- Create
src/routes/settings/api-tokens/+page.svelte - Create
src/routes/settings/api-tokens/+page.server.ts - Create
src/lib/components/settings/ApiTokenList.svelte- Table of user's API tokens: name, scope, created, last used, expires
- Revoke button per token
- Create
src/lib/components/settings/ApiTokenCreateForm.svelte- Form: name, scope (read/write/admin dropdown), expiry (optional date picker)
- On submit: show generated token ONCE (copyable, warning: won't be shown again)
- Add "API Tokens" link to user settings navigation
6.8 Audit Log Viewer
- Create
src/routes/admin/audit-log/+page.svelte - Create
src/routes/admin/audit-log/+page.server.ts - Create
src/lib/components/admin/AuditLogTable.svelte- Paginated table: timestamp, user, action, entity, details
- Filters: action type dropdown, entity type dropdown, user select, date range
- Details column: expandable JSON view for action details
- Export to CSV button
- Add "Audit Log" link to admin panel navigation
Files to Modify/Create
src/lib/components/layout/FavoritesBar.svelte— newsrc/lib/stores/favorites.svelte.ts— newsrc/lib/components/board/RecentAppsSection.svelte— newsrc/routes/status/+page.svelte— newsrc/routes/status/+page.server.ts— newsrc/lib/components/notifications/NotificationBell.svelte— newsrc/lib/components/notifications/NotificationHistory.svelte— newsrc/lib/components/notifications/NotificationChannelForm.svelte— newsrc/routes/settings/notifications/+page.svelte— newsrc/lib/stores/notifications.svelte.ts— newsrc/lib/components/admin/TagManager.svelte— newsrc/lib/components/app/TagBadge.svelte— newsrc/lib/components/board/TagFilter.svelte— newsrc/lib/components/widget/AppWidget.svelte— modifysrc/lib/components/app/AppLinksEditor.svelte— newsrc/routes/settings/api-tokens/+page.svelte— newsrc/routes/settings/api-tokens/+page.server.ts— newsrc/lib/components/settings/ApiTokenList.svelte— newsrc/lib/components/settings/ApiTokenCreateForm.svelte— newsrc/routes/admin/audit-log/+page.svelte— newsrc/routes/admin/audit-log/+page.server.ts— newsrc/lib/components/admin/AuditLogTable.svelte— new- Various existing layout/navigation components — modify
Acceptance Criteria
- Favorites bar persists across board navigation, syncs with backend
- Recent apps section shows only when user has click history and tracking enabled
- Uptime dashboard is guest-accessible and shows meaningful uptime data
- Notification bell shows unread count, dropdown works correctly
- Tags are assignable to apps and filterable in board view
- Multi-URL app cards expand/collapse smoothly
- API token is shown only once on creation, copyable
- Audit log shows paginated, filterable history for admin
- All UIs are responsive and work in dark/light mode
Notes
- Follow existing component patterns (Svelte 5 runes, Tailwind, Bits UI primitives)
- Favorites bar uses svelte-dnd-action like existing widget reordering
- Notification polling: check every 60s for new notifications (simple setInterval)
- Status page is a new top-level route, not nested under boards
- API token display: show once in a modal with copy button, then redirect to token list
Review Checklist
- All tasks completed
- Code follows project conventions
- No unintended side effects
- Build passes (Big Bang: code quality check only)
- Tests pass (Big Bang: skipped for intermediate phase)
Handoff to Next Phase
What was done
- 6.1 Favorites Bar: Created
FavoritesBar.sveltewith drag-and-drop reordering (svelte-dnd-action), compact icon+name display, remove button, and right-click remove. Createdfavorites.svelte.tsstore with load/add/remove/reorder methods and optimistic updates. Integrated favorites loading in root+layout.svelte. Added context menu to AppWidget with "Add to favorites" / "Remove from favorites" toggle. - 6.2 Recent Apps: Created
RecentAppsSection.svelteshowing last 10 clicked apps with time-ago formatting, collapsible section, and clear history button. RespectstrackRecentAppspreference. Updated AppWidget to record clicks viaPOST /api/recent-appson every app link click. - 6.3 Uptime Dashboard: Created
/statusroute with+page.server.ts(loads uptime data, guest-accessible) and+page.sveltewith summary cards (total/online/uptime%), time range selector (24h/7d/30d), per-app status rows with sparklines, and incidents section. Added "Status" link to sidebar navigation. - 6.4 Notifications UI: Created
NotificationBell.svelte(bell icon in header with unread badge, dropdown with notification list, mark all as read). CreatedNotificationHistory.svelte(paginated table with event type filter). CreatedNotificationChannelForm.svelte(dynamic form for Discord/Slack/Telegram/HTTP with send test button). Created/settings/notificationspage with channels tab and history tab. Creatednotifications.svelte.tsstore with 60s polling. Added bell to Header for authenticated users. - 6.5 Tag Management & Filtering: Created
TagManager.svelte(admin CRUD with color picker, inline edit, delete confirmation). CreatedTagBadge.svelte(colored badge with optional remove button). CreatedTagFilter.svelte(toggle buttons for each tag, clear filters). Added tags display to AppWidget large card size. Added/admin/tagspage and nav link. - 6.6 Multi-URL App Cards: Updated
AppWidget.svelteto show expandable sub-links with slide transition for all card sizes (compact/medium/large). Links section shows expand/collapse chevron with count. CreatedAppLinksEditor.sveltewith drag-and-drop reorder, add/remove links, and save to API. - 6.7 API Token Management: Created
/settings/api-tokensroute with+page.server.ts(list tokens, create with form action, revoke with form action). CreatedApiTokenList.svelte(table with scope badges, expiry status, revoke with confirmation). CreatedApiTokenCreateForm.svelte(name, scope dropdown, optional expiry). Token shown once after creation with copy button and warning. Added API Tokens link to user menu and settings page. - 6.8 Audit Log Viewer: Created
/admin/audit-logroute with+page.server.ts(paginated, filtered query). CreatedAuditLogTable.svelte(filterable table with action/entity/date filters, expandable JSON details, CSV export, pagination). Added "Audit Log" link to admin navigation.
What the next phase needs to know
- FavoritesBar is a standalone component but not yet integrated into the board view page -- the root layout loads favorites, and the component can be placed in Board.svelte or the board page.
- RecentAppsSection is a standalone component that needs to be placed in the board view page (e.g., above the sections in Board.svelte).
- The NotificationBell is now in the Header and polls every 60 seconds when authenticated.
- TagFilter component takes
activeTagsandonFilterChangeprops but the filtering logic (hiding apps without selected tags) needs to be wired into the Board or Section component. - AppWidget now depends on
favoritesstore (imported at module level) -- this is safe since the store is a singleton. - The
trackRecentAppsuser preference is available via the User model but is not yet exposed in a settings toggle UI -- it defaults totrue. - API token page uses SvelteKit form actions (
?/createand?/revoke) withuse:enhance. - The admin layout now has 5 nav items: Users, Groups, Tags, Audit Log, Settings.
- Status page is guest-accessible (no auth required in the server loader).
Potential concerns
- The favorites store is loaded eagerly in
+layout.sveltefor all authenticated users. If the user has no favorites, this is a wasted API call (returns empty array). Consider lazy loading. - The context menu for AppWidget favorites uses
position: fixedwith client coordinates, which may not position correctly when the page is scrolled. A more robust solution would use a popover library. - AppWidget now wraps medium/large cards in a
<div>instead of a single<a>tag (to support the expandable links section below the link). This changes the click behavior slightly -- the primary URL is still the main<a>, but the outer container is not a link anymore. - NotificationBell polling could accumulate if multiple instances are mounted (unlikely with current layout, but worth noting).
- The AuditLogTable CSV export only exports the currently loaded page of results, not all results.