Skip to content

style(ui): redesign dashboard as list-rows with package DNA bar#21

Merged
fullstackjam merged 1 commit into
mainfrom
style/dashboard-list-rows
Jun 26, 2026
Merged

style(ui): redesign dashboard as list-rows with package DNA bar#21
fullstackjam merged 1 commit into
mainfrom
style/dashboard-list-rows

Conversation

@fullstackjam

Copy link
Copy Markdown
Member

Summary

  • Align the dashboard with the updated OpenBoot Redesign mockup: configs now render as a single-column list of rows instead of a 3-column card grid.
  • New ConfigRow.svelte — each row shows a package DNA bar (cli=accent / cask=amber / npm=#7aa2e3 segments, brightening within each group), right-aligned stats (installs / cli·apps / updated date), and a hero click-to-copy install command alongside edit and more (…) actions. All existing actions preserved (Share/Duplicate/Export/Push/Delete moved into the … menu).
  • ContextMenu.svelte gains a backward-compatible square trigger variant (40×40) for the row's … button; ConfigCard / /preview are untouched.
  • Dashboard stats line tokens aligned to the mockup (.85rem, --text-secondary, muted separator).

Test plan

  • npm run validate — lint + check + 281 tests + build all pass
  • Rendered ConfigRow live via /preview (temporary, reverted): row layout, DNA gradient, stats, and copy button match the mockup in dark mode; light mode uses the same shared token system as the shipped pages
  • After deploy: visit /dashboard (logged in) and confirm rows + copy/edit/menu actions work

🤖 Generated with Claude Code

https://claude.ai/code/session_01Rp5Ri2TcfaCozPfpkrTDkw

Aligns the dashboard with the updated OpenBoot Redesign mockup. Configs
now render as a single-column list of rows instead of a card grid. Each
row shows a package "DNA" bar (cli/cask/npm segments, brightening within
each group), right-aligned stats, and a hero click-to-copy install
command alongside edit and more (…) actions.

- Add ConfigRow.svelte for the new dashboard row
- Switch dashboard from ConfigCard grid to a ConfigRow column list
- Add a backward-compatible `square` trigger variant to ContextMenu
- Align the dashboard stats line tokens to the mockup

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Rp5Ri2TcfaCozPfpkrTDkw
@fullstackjam

Copy link
Copy Markdown
Member Author

@claude review

@codecov

codecov Bot commented Jun 26, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@fullstackjam

Copy link
Copy Markdown
Member Author

@claude review

@claude

claude Bot commented Jun 26, 2026

Copy link
Copy Markdown

Claude finished @fullstackjam's task in 1m 25s —— View job


Code Review

  • Gather context and understand request
  • Read changed files (ConfigRow.svelte, ContextMenu.svelte, dashboard/+page.svelte)
  • Analyze for bugs, security issues, best practices, performance
  • Post review findings

Overall this is a clean, well-structured redesign. The DNA bar logic is sound, the component API is minimal and forward-compatible, and the responsive handling is thoughtful. One functional bug stands out and a handful of smaller items are worth addressing.


Bug: missing https:// in install URL

src/lib/components/ConfigRow.svelte, lines 51–53

const installUrl = $derived(
    config.alias ? `openboot.dev/${config.alias}` : `openboot.dev/${username}/${config.slug}`
);

This omits the scheme, so the copied command becomes:

curl -fsSL openboot.dev/user/slug | bash   # ❌ invalid — curl needs https://

Compare with the share modal in +page.svelte (lines 134–137) which correctly prefixes https://. The fix is to add https:// to both template literals here. Fix this →


Minor: clipboard feedback fires even on write failure

src/lib/components/ConfigRow.svelte, lines 56–60

function copyInstall() {
    navigator.clipboard?.writeText(`curl -fsSL ${installUrl} | bash`).catch(() => {});
    copied = true;  // fires regardless of whether clipboard write succeeded
    setTimeout(() => (copied = false), 1600);
}

The copied = true fires unconditionally. If navigator.clipboard is undefined (non-HTTPS context, or clipboard permission denied) or the write promise rejects, the user sees "copied ✓" even though nothing was copied. Chaining .then(() => { copied = true; ... }) would be more accurate.


Minor: duplicated Config interface

ConfigRow.svelte (lines 4–15) and +page.svelte (lines 8–22) each define a local Config interface with overlapping but slightly different shapes. The page version has custom_script, dotfiles_repo, and snapshot which the row component intentionally doesn't need — but divergence here can silently hide type mismatches. Worth extracting to $lib/types.ts as a future cleanup (out of scope for this PR, noting for awareness).


Nit: packages?: any[] typing

ConfigRow.svelte, line 12; +page.svelte, line 16

Both files use any[] for packages. The shape is consistently { name: string; type: string } or a plain string (normalised on line 26). A lightweight type Package = { name: string; type: string } would replace all the (p: any) casts in the $derived chains (lines 25, 31–33).


ContextMenu square variant — looks good

The backward-compatible square = false prop and the 40×40 CSS override are clean. The existing handleClickOutside and toggle logic is unchanged and correct. No issues.


Dashboard page changes — looks good

The switch from grid to config-list flex column is straightforward. The staggered fadeUp animation via animation-delay: {i * 50}ms is a nice touch. The handleAction dispatcher correctly covers all six actions that ConfigRow can emit.


Summary: One real bug (missing https:// in the install command — will produce a broken curl), one UX polish issue (copy feedback fires on clipboard failure), and two housekeeping notes. The overall structure is solid.

@fullstackjam
fullstackjam merged commit eafa9ae into main Jun 26, 2026
7 checks passed
@fullstackjam
fullstackjam deleted the style/dashboard-list-rows branch June 26, 2026 06:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant