Commit Graph

8 Commits

Author SHA1 Message Date
Anso e8f271f5f6 feat(ui): make the core stack flow usable on mobile (#1327)
* feat(ui): make the core stack flow usable on mobile

Below the md breakpoint the app collapses to a single full-width column:
the stack list is full-screen, tapping a stack opens a full-screen detail
with a Health / Logs / Compose segmented control (Logs first) and a back
button, and a bottom tab bar switches Stacks, Fleet, Schedules, and
Settings. Compose is read-only on a phone with a prompt to edit on desktop.

Desktop (md and up) is unchanged: the mobile shell is gated behind a
useIsMobile hook plus max-md/md variants, and the stack-detail blocks are
shared with the desktop two-pane view so it renders identically.

Also generalizes the unsaved-changes guard so leaving a dirty editor (back,
tab bar, hamburger) prompts before discarding; adds 44px touch targets on
list rows, filter chips, and actions; makes log and shell modals full-screen
on mobile; and offsets toasts and the deploy pill above the bottom tab bar.

* fix(ui): keep mobile nav in sync when opening views from outside the bottom bar

On a phone the sidebar activity actions, the node switcher's Manage Nodes, the
profile Settings entry, and the dashboard configuration links set the active
view without flipping the mobile surface to content, so the user stayed on the
stack list and never saw the destination. Route these through the mobile-aware
navigation and settings helpers (a no-op on desktop).
2026-06-07 01:03:13 -04:00
Anso a42cc5bf03 fix(ui): raise toast z-index above dialog overlays (#715) 2026-04-20 18:23:38 -04:00
Anso aa181aa932 feat(ui): redesign toast with accent rail and action slot (#693)
* feat(ui): redesign toast with accent rail and action slot

Align toast with the overlay-surface language from the user menu and
notification panel: left accent rail, tracked-mono kicker above the
message, lucide icons at 1.5px stroke, status-tinted progress bar.

Extend the toast store with an optional options object so callers can
pass an inline action button and override the default duration. Guard
removeToast against no-op dismissals so subscribers are not notified
when nothing changed, and cap the buffered queue at 20 to prevent
unbounded growth under spam.

* fix(ui): avoid impure Date.now in toast ref initializer

useRef(Date.now()) re-evaluates the impure call on every render and
trips the react-hooks/purity lint rule, even though only the first
render's value is retained. Initialize to 0 since the auto-dismiss
effect writes startRef.current = Date.now() before any read path
consumes it.
2026-04-19 11:54:36 -04:00
Anso 089d43b855 fix(ui): standardize toast background to match floating overlay glass style (#451)
Replace bg-card/80 with bg-popover/95 and match the backdrop-blur/saturate
values used by dialogs, dropdowns, and popovers. Remove per-type colored
gradient overlays so color differentiation comes from icons only. Unify the
determinate progress bar gradient with the loading bar's brand gradient.
2026-04-09 09:57:13 -04:00
Anso f6d2199978 feat(resources): add loading toast for prune, delete, and purge operations (#426)
Show a loading notification with spinner and indeterminate progress bar
while Resource Hub operations are in progress, replacing the dead moment
between confirmation and result.
2026-04-08 09:46:27 -04:00
Anso f9ebd1d77c feat: UI polish sprint — 7 items + logs toolbar redesign (#365)
* feat: UI polish sprint — tag filters, toast tokens, logs toolbar, billing portal, editor UX

- Fleet: replace inline tag pills with multi-select combobox dropdown
- Toast: remap all notification colors to oklch design tokens
- Logs: convert floating hover toolbar to permanent pinned toolbar,
  replace all hardcoded colors with design tokens for theme support
- Audit: fix dropdown scroll-lock (modal=false), light theme button contrast
- Resources: remove redundant inner border/bg on tab wrapper
- Editor: add ⌘K/Ctrl+K shortcut hint and handler, standardize button heights
- Billing: signed Lemon Squeezy portal URLs via sencho.io proxy for all tiers
- New MultiSelectCombobox UI component

* feat(editor): replace button row with split-button dropdown

Replace three separate editor buttons (Discard, Save Only, Save & Deploy)
with a compact split-button dropdown. Primary action is "Save & Deploy";
chevron opens dropdown with "Save Only" and "Discard Changes" options.
2026-04-03 20:33:44 -04:00
Anso 28c7a8fd54 feat(auto-update): add auto-update policies and fix image update detection (#297)
* feat(auto-update): add auto-update policies and fix image update detection

Auto-Update Policies (Skipper+ tier):
- New scheduled task action type 'update' for check-then-update flow
- Dedicated AutoUpdatePoliciesView with CRUD, cron presets, and run history
- Conditional tier gating: Skipper gets auto-update, Admiral gets full scheduled ops
- Backend executeUpdate: checks digests, pulls only if newer, atomic redeploy

Image Update Detection fixes (all tiers):
- Fix stack name key mismatch: use working_dir label instead of project label
- Add 5-minute periodic frontend polling for background check results
- Replace fixed 3s timeout with polling-based manual refresh via /api/image-updates/status
- Clear update status after successful stack update

* fix(ui): remove Skipper tier badge from Auto-Update Policies header

* fix(ui): remove auto-update action from Scheduled Operations view

Admiral users have a dedicated Auto-Update view — showing update tasks
in Scheduled Operations too was confusing duplication. Each view now
owns a distinct, non-overlapping set of action types.

* fix(auto-update): fix node-stack linking and add All Stacks option

- Stack dropdown now re-fetches when node selection changes using
  fetchForNode, and resets the selected stack
- Node selector moved above stack selector with stack disabled until
  a node is picked
- Added "All Stacks" wildcard option that checks and updates every
  stack on the selected node
- Backend executeUpdate refactored to iterate over all stacks when
  target_id is "*", with per-stack error isolation

* refactor(ui): replace Select dropdowns with searchable Combobox component

Add a reusable Combobox component with inline search and use it for
Node/Stack selectors in both Auto-Update Policies and Scheduled
Operations dialogs. Also fixes node-stack linking bug where changing
node didn't update the stack list.

* fix(ui): resolve CI TypeScript errors in Combobox and ScheduledOperationsView

Add missing searchPlaceholder prop to ComboboxProps interface and remove
dead 'update' action filter that conflicted with the narrowed type union.

* fix(ui): use Geist Sans font in toast component

The toast renders via React portal on document.body, bypassing the app's
font inheritance. Add explicit font-family declaration using var(--font-sans)
to match Sencho's design system.
2026-04-01 00:22:47 -04:00
Anso d393d06885 Replace Sonner with custom Sera UI-inspired toast system (#296)
* refactor(ui): replace Sonner with custom Sera UI-inspired toast system

Replace the Sonner toast library with a custom implementation inspired by
Sera UI's glassmorphism design. The new system uses an external store pattern
with useSyncExternalStore for React integration, keeping the same
toast.success()/error()/warning() API so all 172 call sites required only
an import path change.

Key changes:
- New toast-store.ts: singleton store with identical API to Sonner
- New toast.tsx: Sera UI-faithful Notification component with Framer Motion
  animations, frosted glass (backdrop-blur-xl), type gradient overlays,
  animated progress bar (green→blue→sky gradient), and hover:scale-105
- Removed sonner and next-themes dependencies
- Rewired all 19 consumer files to import from the new store

* fix(ui): resolve ESLint errors in toast system

- Use const for listeners Set (prefer-const)
- Initialize startRef with 0 instead of Date.now() to satisfy
  react-hooks/purity rule, set actual value inside useEffect
2026-03-31 21:34:49 -04:00