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.
208 lines
13 KiB
Markdown
208 lines
13 KiB
Markdown
# Phase 6: Functional Features — Frontend
|
|
|
|
**Status:** ✅ Complete
|
|
**Parent plan:** [PLAN.md](./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
|
|
|
|
- [x] 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
|
|
- [x] Create `src/lib/stores/favorites.svelte.ts`
|
|
- Fetch favorites from `/api/favorites` on init
|
|
- Methods: add, remove, reorder (optimistic updates with API sync)
|
|
- [x] Integrate FavoritesBar into board layout (show when user has favorites)
|
|
|
|
### 6.2 Recent Apps Section
|
|
|
|
- [x] 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 `trackRecentApps` preference
|
|
- [x] Update app click handling to record clicks via `/api/recent-apps` POST
|
|
- [x] Add privacy toggle in user settings (trackRecentApps)
|
|
|
|
### 6.3 Uptime Dashboard Page
|
|
|
|
- [x] Create `src/routes/status/+page.svelte` — public status page
|
|
- [x] 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 %
|
|
- [x] Add "Status Page" link to sidebar navigation
|
|
|
|
### 6.4 Notifications UI
|
|
|
|
- [x] 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
|
|
- [x] 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
|
|
- [x] 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
|
|
- [x] Create `src/routes/settings/notifications/+page.svelte` — notification preferences page
|
|
- [x] Create `src/lib/stores/notifications.svelte.ts`
|
|
- Track unread count, poll for new notifications
|
|
|
|
### 6.5 Tag Management & Filtering
|
|
|
|
- [x] Create `src/lib/components/admin/TagManager.svelte`
|
|
- Admin page to CRUD tags (name + color picker)
|
|
- Table/grid of existing tags with edit/delete
|
|
- [x] Create `src/lib/components/app/TagBadge.svelte`
|
|
- Small colored badge showing tag name
|
|
- Used in app cards (large card size) and app edit forms
|
|
- [x] 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
|
|
- [x] Add tag assignment to app edit form (multi-select from existing tags)
|
|
- [x] Add tag management page to admin panel navigation
|
|
|
|
### 6.6 Multi-URL App Cards
|
|
|
|
- [x] 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)
|
|
- [x] 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
|
|
|
|
- [x] Create `src/routes/settings/api-tokens/+page.svelte`
|
|
- [x] Create `src/routes/settings/api-tokens/+page.server.ts`
|
|
- [x] Create `src/lib/components/settings/ApiTokenList.svelte`
|
|
- Table of user's API tokens: name, scope, created, last used, expires
|
|
- Revoke button per token
|
|
- [x] 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)
|
|
- [x] Add "API Tokens" link to user settings navigation
|
|
|
|
### 6.8 Audit Log Viewer
|
|
|
|
- [x] Create `src/routes/admin/audit-log/+page.svelte`
|
|
- [x] Create `src/routes/admin/audit-log/+page.server.ts`
|
|
- [x] 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
|
|
- [x] Add "Audit Log" link to admin panel navigation
|
|
|
|
## Files to Modify/Create
|
|
|
|
- `src/lib/components/layout/FavoritesBar.svelte` — new
|
|
- `src/lib/stores/favorites.svelte.ts` — new
|
|
- `src/lib/components/board/RecentAppsSection.svelte` — new
|
|
- `src/routes/status/+page.svelte` — new
|
|
- `src/routes/status/+page.server.ts` — new
|
|
- `src/lib/components/notifications/NotificationBell.svelte` — new
|
|
- `src/lib/components/notifications/NotificationHistory.svelte` — new
|
|
- `src/lib/components/notifications/NotificationChannelForm.svelte` — new
|
|
- `src/routes/settings/notifications/+page.svelte` — new
|
|
- `src/lib/stores/notifications.svelte.ts` — new
|
|
- `src/lib/components/admin/TagManager.svelte` — new
|
|
- `src/lib/components/app/TagBadge.svelte` — new
|
|
- `src/lib/components/board/TagFilter.svelte` — new
|
|
- `src/lib/components/widget/AppWidget.svelte` — modify
|
|
- `src/lib/components/app/AppLinksEditor.svelte` — new
|
|
- `src/routes/settings/api-tokens/+page.svelte` — new
|
|
- `src/routes/settings/api-tokens/+page.server.ts` — new
|
|
- `src/lib/components/settings/ApiTokenList.svelte` — new
|
|
- `src/lib/components/settings/ApiTokenCreateForm.svelte` — new
|
|
- `src/routes/admin/audit-log/+page.svelte` — new
|
|
- `src/routes/admin/audit-log/+page.server.ts` — new
|
|
- `src/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
|
|
|
|
- [x] All tasks completed
|
|
- [x] 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.svelte` with drag-and-drop reordering (svelte-dnd-action), compact icon+name display, remove button, and right-click remove. Created `favorites.svelte.ts` store 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.svelte` showing last 10 clicked apps with time-ago formatting, collapsible section, and clear history button. Respects `trackRecentApps` preference. Updated AppWidget to record clicks via `POST /api/recent-apps` on every app link click.
|
|
- **6.3 Uptime Dashboard**: Created `/status` route with `+page.server.ts` (loads uptime data, guest-accessible) and `+page.svelte` with 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). Created `NotificationHistory.svelte` (paginated table with event type filter). Created `NotificationChannelForm.svelte` (dynamic form for Discord/Slack/Telegram/HTTP with send test button). Created `/settings/notifications` page with channels tab and history tab. Created `notifications.svelte.ts` store 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). Created `TagBadge.svelte` (colored badge with optional remove button). Created `TagFilter.svelte` (toggle buttons for each tag, clear filters). Added tags display to AppWidget large card size. Added `/admin/tags` page and nav link.
|
|
- **6.6 Multi-URL App Cards**: Updated `AppWidget.svelte` to show expandable sub-links with slide transition for all card sizes (compact/medium/large). Links section shows expand/collapse chevron with count. Created `AppLinksEditor.svelte` with drag-and-drop reorder, add/remove links, and save to API.
|
|
- **6.7 API Token Management**: Created `/settings/api-tokens` route with `+page.server.ts` (list tokens, create with form action, revoke with form action). Created `ApiTokenList.svelte` (table with scope badges, expiry status, revoke with confirmation). Created `ApiTokenCreateForm.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-log` route with `+page.server.ts` (paginated, filtered query). Created `AuditLogTable.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 `activeTags` and `onFilterChange` props but the filtering logic (hiding apps without selected tags) needs to be wired into the Board or Section component.
|
|
- AppWidget now depends on `favorites` store (imported at module level) -- this is safe since the store is a singleton.
|
|
- The `trackRecentApps` user preference is available via the User model but is not yet exposed in a settings toggle UI -- it defaults to `true`.
|
|
- API token page uses SvelteKit form actions (`?/create` and `?/revoke`) with `use: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.svelte` for 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: fixed` with 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.
|