mirror of
https://github.com/Studio-Saelix/sencho.git
synced 2026-08-31 20:58:04 +00:00
feat: add Reduced motion setting and polish chrome, files, and stack-detail (#1501)
A batch of UI/UX polish: - New independent "Reduced motion" appearance setting (separate from Reduced effects). Drives framer-motion via MotionConfig and clamps CSS transitions via data-motion on <html>; toasts are unaffected. Defaults off (OS preference still honored). - Stack-detail Files tab: rename "Files & Volumes" to "Files", add a persisted word-wrap toggle to the file viewer (default on), and add a fullscreen toggle that collapses the Command Center + Logs column so the editor fills the width. - Create Stack > From Git: remove the nested scroll clamp so the deploy toggle and footer are reachable. - Fleet: full-width tab band with icon-only Refresh / Export Dossier, icon-only Check-for-updates / Add-node on the Overview toolbar, theme-aware empty-state headings (calm drops the italic), and fix the Actions card body overlapping the action-row divider. - Snapshots: restyle Restore and Restore all to the ghost button design used by View / Preview / Download, and right-align the per-stack Restore. - Settings sidebar: App Store gradient active style and standard font size. - Compose Doctor: dismiss the high-risk banner (and clear the tab dot) until the findings change, via a shared fingerprint-keyed hook. - Stack-detail Storage: link the "no recent fleet snapshot" warning to the Fleet Snapshots tab (FleetView tabs are now controlled to support the deep link).
This commit is contained in:
@@ -259,19 +259,25 @@ export function OverviewToolbar({
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
className="gap-2 shrink-0 h-9"
|
||||
className="h-9 w-9 p-0 shrink-0"
|
||||
onClick={onCheckUpdates}
|
||||
disabled={checkingUpdates}
|
||||
title="Check for updates"
|
||||
aria-label="Check for updates"
|
||||
>
|
||||
<RefreshCcwDot className={`w-4 h-4 ${checkingUpdates ? 'animate-spin' : ''}`} />
|
||||
Check Updates
|
||||
</Button>
|
||||
)}
|
||||
|
||||
{onAddNode && (
|
||||
<Button size="sm" className="gap-1.5 shrink-0 h-9" onClick={onAddNode}>
|
||||
<Button
|
||||
size="sm"
|
||||
className="h-9 w-9 p-0 shrink-0"
|
||||
onClick={onAddNode}
|
||||
title="Add node"
|
||||
aria-label="Add node"
|
||||
>
|
||||
<Plus className="w-4 h-4" strokeWidth={1.5} />
|
||||
Add node
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -97,17 +97,17 @@ describe('OverviewToolbar', () => {
|
||||
it('renders the Check Updates button and fires onCheckUpdates when provided', () => {
|
||||
const onCheckUpdates = vi.fn();
|
||||
render(<OverviewToolbar {...props({ onCheckUpdates })} />);
|
||||
fireEvent.click(screen.getByRole('button', { name: /Check Updates/ }));
|
||||
fireEvent.click(screen.getByRole('button', { name: /Check for updates/ }));
|
||||
expect(onCheckUpdates).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it('omits the Check Updates button when onCheckUpdates is not provided', () => {
|
||||
render(<OverviewToolbar {...props()} />);
|
||||
expect(screen.queryByRole('button', { name: /Check Updates/ })).not.toBeInTheDocument();
|
||||
expect(screen.queryByRole('button', { name: /Check for updates/ })).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('disables the Check Updates button while a check is in flight', () => {
|
||||
render(<OverviewToolbar {...props({ onCheckUpdates: vi.fn(), checkingUpdates: true })} />);
|
||||
expect(screen.getByRole('button', { name: /Check Updates/ })).toBeDisabled();
|
||||
expect(screen.getByRole('button', { name: /Check for updates/ })).toBeDisabled();
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user