Repository navigation
feat(dashboard): ship Rail redesign and resolve review findings - #82
Open
lorenzocorallo wants to merge 68 commits into
Open
lorenzocorallo wants to merge 68 commits into
lorenzocorallo wants to merge 68 commits into
Conversation
Port the Rail shell, shared primitives, and dashboard pages to production routes and existing server functions. Preserve this checkpoint before applying the correctness review findings.
Render page controls during SSR and preserve scroll on history navigation. Aggregate overview counts on the server, synchronize mutation completion, and retain failed group selections for retry. Share sign-out state, correct navigation activity and search pagination, restore project category ordering, and address the remaining minor review notes with timezone and role-scope coverage.
Contributor
|
Important Review skippedToo many files! This PR contains 221 files, which is 121 over the limit of 100. To get a review, reduce the PR to 100 files or fewer by splitting it into smaller PRs or changing its base branch. Upgrade to a paid plan to raise the limit. This review couldn't start because sufficient usage credits or metered capacity aren't available. Add credits or update usage-based reviews in the billing tab, then retry. ⚙️ Run configuration
⛔ Files ignored due to path filters (2)
📒 Files selected for processing (221)
You can disable this status message by setting the
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
- Adapt dashboard tables, toolbars, and label rows for smaller screens - Keep edit controls stable while saving and refresh data before closing dialogs - Support renaming attributes and preserve local dates in calendar inputs
- Update inline edit action order and document the responsive label row behavior - Add mobile edit and delete actions to label menus - Record the shell dashboard design review
- Add tonal tinted styling for invite, visibility, edit, labels, and delete actions - Document the WhatsApp group action colors in the design spec
- Add a subtle tone outline and tint at rest, with a stronger hover treatment - Update the design spec to match
Replaces the hand-built WhatsApp glyph with the official logo from homarr-labs/dashboard-icons, shared by the rail, the panel and PlatformGlyph. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
dark:bg-input/30 outranked data-checked:bg-primary, so a checked box kept the unchecked fill and its near-black check vanished. The dark fill now applies only while unchecked. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The rule sat between the IT and EN answers; it now divides the two questions from the two answers, replacing the empty spacer. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The inline-edit footer shows "Press Ctrl + Enter to save, Esc to cancel" again (kbd chips, hidden on coarse pointers) and replaces the Cancel/Save text buttons with tinted icon buttons: X (danger) then Check (success), each with a tooltip naming its shortcut. Applies to FAQs, Projects, Associations and Group labels. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The header bar drops its bottom rule and gains 16px top padding at >= 1024, while PageContent starts 12px after it (20px on settings), so the toolbar sits inset like the content instead of lining up with the panel header. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Card order is the order on the website, so a two-column grid made it ambiguous. Projects now stack in one column at every width; CardsSkeleton gains a columns prop so the loading state matches. Associations and Overview keep two columns. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The 36px sm button nearly filled the 44px row, had 6px/10px padding and 12.8px text. It is now a 28px outline button with balanced padding, 13px text matching the cells, a muted icon and the --pn-r-2 radius. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The shell's TooltipProvider now waits 100ms (TOOLTIP_DELAY) instead of 400ms, so icon-button tooltips feel immediate while not flashing as the pointer crosses a row. The rail opts into TOOLTIP_DELAY_SLOW (400ms) on its triggers, since the pointer sweeps it on the way elsewhere; Hint takes a delay prop for other opt-ins. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
router state.location switches as soon as a navigation starts, while <Outlet> keeps the previous page until the next loader resolves. The shell derived the panel from it, so going to Overview removed the panel under the still-visible page (which snapped left by 224px) and coming back added it next to the old Overview, a visible flicker; PageContent's key also remounted the outgoing page. useRenderedPathname reads the deepest rendered match, keeping both in step with what is on screen. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Going between Overview/Account and a service page, the panel slides in from under the rail (220ms --pn-ease-out) and back out (180ms). The content column follows as a layout transform (layout="position"), so its edge stays locked to the panel and no width animates; AnimatePresence popLayout lifts the leaving panel out of the flow at once. No entrance on first paint; with reduced motion the panel switches in a single frame. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The users table packed @username under the name, which read poorly. Username is its own column again (hides before Telegram ID on narrow screens), the name is one line, and a trailing ChevronRight (brighter with a 2px nudge on row hover) shows the row opens the user's detail. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
With classic (non-overlay) scrollbars, a long list showed a scrollbar and a short one did not, so filtering a table to a few rows widened the content by the scrollbar's width and every column moved. scrollbar-gutter: stable keeps the width constant. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Column widths followed the visible rows, so searching or paging the group lists resized Labels and shifted the actions. DataTable columns can now set a fixed width: any width switches the table to table-layout: fixed, the fill column takes the rest and actions use actionsWidth. Group lists fix Labels at 320, Telegram ID at 150 and Tag at 176; ChipOverflow lets chips shrink and truncate (full name in title) while the +n badge stays whole. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Association cards sat at their content height (items-start), so neighbours in the 2-column grid ended at different heights and their links footers were misaligned. The grid now stretches its cells, InlineEditCard lets its content column grow, and the links footer is pinned to the bottom with mt-auto. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Restores the earlier look the team liked: each language sits in its own panel headed by a Languages icon and "IT"/"EN", with an accent border and label while editing (stronger while a field has focus). TranslationGroup puts IT and EN side by side once there is room (>= 560px) and stacks them otherwise; panels set lang so screen readers and the spellchecker use the right language. Projects and Associations use it in view and edit. InlineEditCard gains a viewHeader slot so the actions sit beside the logo row and the body spans the full card width, keeping view and edit bodies equally wide. The unused LanguageChip/LanguageTerm helpers are removed. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Edit mode wrapped a bordered textarea inside the translation panel, so entering edit added a second layer, shrank the text area and moved the text. InlineEditTextarea gains a bare mode (no border, background or padding; 13/20 like the read-only text; one line minimum, grows with its content) and the edit-mode TranslationPanel becomes the field: same size and background as view, with only the accent border and label appearing, stronger while focused. Pressing the panel's padding or header focuses its field with the caret at the end. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Focusing a bare translation field drew the global input focus ring (border + 3px glow) as a box inside the panel. The bare textarea opts out with data-focus-ring="none" (the panel's accent border already shows focus), the invalid-field ring honours the same opt-out, and the panel border turns danger when a field inside is invalid. Also replaces a type assertion in the panel's press handler with an instanceof check, and documents the edit-mode panel in §5.14. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Enter / ⌘+Enter only saved when the record was valid and changed, and otherwise did nothing, which reads as a broken shortcut (reported on macOS, where ⌘+Enter itself is delivered fine). On an unchanged record the shortcut now closes the editor (nothing to save means done); when something required is missing it focuses the first aria-invalid field, else the first empty one, so the blocker is visible. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Switching theme now runs a View Transition: the new theme grows as a clip-path circle from the pressed toggle's icon to the farthest corner in 400ms (--pn-ease-out, so most of the screen flips in the first ~150ms). The root snapshots no longer cross-fade, and element transitions stay suppressed until the reveal ends so colors do not fade inside it. Every toggle passes its click event as the origin; the command palette starts from the rail toggle (data-theme-toggle). Reduced motion or no View Transitions support keeps the instant swap. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
89b6680 reserved the scrollbar gutter only in main, so with classic scrollbars the content was 15px narrower than the header bar: right edges no longer matched, and on wide screens the centered content sat 7.5px left of the toolbar. The header bar now reserves the same gutter (scrollbar-gutter applies to clipping boxes, hence overflow-hidden; menus and tooltips are portaled). Verified on all 16 dashboard routes at 1920px, plus 1440, 1100 and 390px: bar and content edges match. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The rail logo and the Overview item right below it both linked to /dashboard, and the navigation sheet had the same pair (logo link + Overview row): two controls for one destination. The logo is now a non-interactive brand mark in both places (aria-hidden, not focusable, same size and position); Overview stays the one link home. The rail's roving tab-stop indices shift by one accordingly (Home now lands on Overview). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Running a command palette entry closed the dialog, and Base UI returned focus to the element that opened it, usually the rail Search button. After Enter that focus counts as keyboard focus, so the new page showed the button's focus ring and its 'Search ⌘K' tooltip. finalFocus now skips the restore when an entry ran; dismissing with Esc or an outside press still returns focus to where it was. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The category select and its edit/delete icon buttons sat loose in the toolbar, so the buttons could read as page or FAQ actions. They now share one 36px outlined surface (role=group "Category") with a muted "Category" prefix: the borderless select, then square edit and delete buttons, split by thin dividers. The trigger takes the group's right rounding when it ends the group (read-only viewers). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
50df0fd held the reveal's end state with fill: forwards, but a held animation never ends: it stayed attached to the page and applied to the next switch's snapshots, so every turn-on after a turn-off found its old snapshot already clipped to nothing and showed the new theme at once (fine on the first run after a reload, broken on later ones). The reveal is now tracked, cancelled once the transition has finished (the snapshots are gone by then, so nothing changes on screen) and before the next reveal starts. Verified with a four-switch recording: all four runs animate, per-frame brightness has no spikes, and rapid double/triple clicks end in the right theme with no stuck attributes. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The reveal blocked the toggle: during a view transition Chrome delivers every pointer event to <html>, and a second startViewTransition would skip the running one to its end. The reveal is now a small state machine: a hold animation keeps the transition open, a press reverses the clip from its current radius (as often as pressed), and when the clip comes to rest the page is set to that end's theme while the live layer is hidden, then the hold is released. Presses are recognised by position over a data-theme-toggle (a permanent capture listener, since a click straddling a transition's start or end also lands on <html>). The pressed toggle is lifted out of the snapshots with its own view-transition-name so its icon follows every press, and gets an emulated neutral hover tint and pointer cursor. The UI reads the heading theme during a reveal. setTheme, unused, is dropped from useTheme. Verified at 1/4 speed frame by frame (reversals continuous, icon flips per press, hover visible, no brightness spikes) and with 12 random full-speed spam bursts (186 presses, holds 0-80ms): every run ends on the theme the press count predicts, with no stuck attributes, animations or errors. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Clicking quickly through the rail, the section panel or the mobile navigation sheet could highlight their labels in the browser's selection blue. All three are select-none now; page content stays selectable. Verified: drag-selecting across the panel and the rail and triple-clicking a section link select nothing, while dragging over a table still selects its text. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Card-wide hover suggested the whole card could be dragged; only the handle starts a drag. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The image stays hidden over the initials until it decodes, and load results are kept per URL so remounts (category tabs, reloads) do not refetch failing logos. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The rail and sheet avatar rendered a bare img, so a broken picture URL showed the browser's broken-image icon on every page. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
At >= 1024px WhatsApp showed "WhatsApp › Groups" before the toolbar; the rail already names the service, so the toolbar now takes the row as on other pages. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Editing an existing project or association now looks like editing a draft, so the card being changed stands out. Drafts are always in edit mode, so the separate draft prop goes away. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
A focused IT/EN panel now takes the --pn-focus border and 3px ring that inputs use, instead of a slightly stronger accent border. Also updates the stale "host only" note on project links in the design doc. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Ghost icon buttons show no box, so 4px gaps (12px before delete) read as wide spacing between icons. Ghost groups now have no gap; tinted groups keep 4px and the 8px danger separation. The gap is set on the group rather than between siblings, since an open menu inserts focus guards beside its trigger and would otherwise shift the buttons. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Only the header took the hover background, leaving an open item's answers untinted below it. Hovering the header now tints the entire item. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Group rows now lead with a flush ghost pair, copy invite link and open invite link, followed by 8px before the tinted actions. InviteLinkButton becomes InviteLinkActions; the actions column widths follow. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The footer hid once total <= pageSize, so choosing a page size that fit every row removed the rows-per-page control needed to change it back. It now hides only when no page size would split the rows. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
A disabled button that stays focusable ("Not shared") still brightened its icon
on hover, suggesting it could be clicked. Only the tooltip shows now.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The menu holds a single action, moving the project to another category, so the generic ⋮ becomes FolderInput. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Amber flags the missing link as a warning; the reduced opacity and the disabled button (no hover) keep it from reading as clickable. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
InlineEditCard/Row gain leadingActions for actions before Edit; Projects puts "Move project" there. Group rows move "Edit labels" ahead of "Edit group". The rule is recorded in the actions column spec. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…lace navigator.clipboard only exists in secure contexts, so copying failed when the app was opened by LAN/Tailscale address. copyText falls back to a hidden textarea and execCommand there; the onboarding code copy uses it too. The copy button now swaps to a green circle-check or a red circle-x for 1.5s. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- Replace the overflow count tooltip with a scrollable member list - Label the popover with the Azure group name
The copy button's check/x result keeps the button's neutral color and swaps in with a scale, fade and blur spring (instant under reduced motion). IconButton gains an iconNode slot for custom icon content. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The avatar overlap used space-x, a sibling rule that the popover's focus guards broke when it opened, shifting the row; it now uses fixed margins. The +N chip opens on hover (click still works) and lists only the hidden members. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The hovered item takes the panels' background, so they blended into it. A --pn-line border, the card's own line color, keeps them distinct. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Grants and Projects showed a count in each segment while Groups and Reports did not. The Telegram/WhatsApp visibility filter and the Reports segments now show each option's total too, over the whole list so they stay put while searching. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Next to a segmented filter with counts, "6 of 32 groups" only restated numbers
already on the segments. The count now shows only while search or labels narrow
the list beyond the segment, as "{n} groups"; Projects, whose only filter is
the segments, drops it.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Amber drew too much attention and read like the amber labels button. Hidden now uses the neutral tinted tone; visible stays blue. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Small buttons with a leading icon had 6px before the icon, a 4px gap and 10px
after the label, so they looked cramped and lopsided ("Choose PDF"). They now
use 8px / 6px / 10px. The toolbar search now shrinks (to 96px) from 1024px
instead of overflowing onto the count when the row is tight (FAQs).
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The ID and tag cells (Telegram groups, groups by label) are now CopyableText: a click copies the value (tag without "@") with a toast; hover brightens it with a dotted underline and a "Copy …" tooltip. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…d tags Clicking still copies with a toast; the cells now look like plain text, with only the pointer cursor hinting at the action. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Replaces the dashboard layout with the Rail design: service rail, section panel, mobile navigation sheet, command palette and shared page controls. Every section (Overview, Account, Telegram, WhatsApp, Microsoft 365, Web, Reports) now uses the tokens and page templates in
docs/design.md. Routes, server functions and branded service logos are unchanged.Also fixes the review findings (Overview counts and caching, Back scroll restore, loader refresh after mutations, sign-out guard, project order persistence, and smaller notes).
Validation:
pnpm check,typecheck,testandbuildpass. Browser checks ran against a local mock backend at desktop and narrow widths, in light and dark. Auth redirects were checked withAGENT_MODE=false. Not tested: live backend and WebAuthn registration.🤖 Generated with Claude Code