diff --git a/.gitignore b/.gitignore index e3f4cf7..4531a25 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,8 @@ /pkg/ /tmp/ /spec/dummy/db/*.sqlite3 +/spec/dummy/db/*.sqlite3-shm +/spec/dummy/db/*.sqlite3-wal /spec/dummy/log/ /spec/dummy/tmp/ /coverage/ diff --git a/CHANGELOG.md b/CHANGELOG.md index adf76b0..9a5585a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,27 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Added + +- Hamburger toggle nav for viewports narrower than 576px — three-bar button opens a full-width dropdown with vertically stacked links; no JS file required +- `sqd-grid-2` utility class for responsive two-column layouts (collapses to one column at ≤768px) +- `.sqd-sr-only` utility class for visually-hidden text +- `:focus-visible` focus ring (2px primary blue) for keyboard navigation +- `aria-expanded` on the mobile nav toggle, kept in sync on open/close +- `role="status"` on notice flash messages and `role="alert"` on alert flash messages +- `aria-label="Main"` on the primary navigation landmark +- `aria-current="page"` on the active navigation link +- `scope="col"` on all table header cells +- Visually-hidden "Actions" label on empty action column headers + +### Changed + +- Navbar title and links constrained to the same max-width as page content so they align horizontally with the dashboard +- Page headers stack vertically on mobile (≤640px) +- Stat grid uses a smaller minimum cell width on mobile +- Cards scroll horizontally on mobile to accommodate wide tables +- Main content padding reduced on mobile + ## [0.4.0] - 2026-05-18 ### Added diff --git a/app/assets/stylesheets/solid_queue_web/application.css b/app/assets/stylesheets/solid_queue_web/application.css index 72cf657..96342e0 100644 --- a/app/assets/stylesheets/solid_queue_web/application.css +++ b/app/assets/stylesheets/solid_queue_web/application.css @@ -4,6 +4,24 @@ *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; } +.sqd-sr-only { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + white-space: nowrap; + border: 0; +} + +:focus-visible { + outline: 2px solid var(--primary); + outline-offset: 2px; + border-radius: 2px; +} + :root { --bg: #f8f9fa; --surface: #ffffff; @@ -30,6 +48,11 @@ body { .sqd-header { background: var(--surface); border-bottom: 1px solid var(--border); +} + +.sqd-header__inner { + max-width: 1200px; + margin: 0 auto; padding: 0 1.5rem; display: flex; align-items: center; @@ -67,6 +90,28 @@ body { color: var(--text); } +.sqd-nav-toggle { + display: none; + flex-direction: column; + justify-content: center; + gap: 5px; + width: 36px; + height: 36px; + padding: 6px; + margin-left: auto; + background: none; + border: 1px solid var(--border); + border-radius: 5px; + cursor: pointer; +} + +.sqd-nav-toggle span { + display: block; + height: 2px; + background: var(--text); + border-radius: 1px; +} + .sqd-main { max-width: 1200px; margin: 0 auto; @@ -344,8 +389,84 @@ nav.pagy a[aria-disabled="true"] { color: var(--muted); cursor: default; } gap: 1.5rem; } +.sqd-grid-2 { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 1rem; +} + @media (max-width: 768px) { .sqd-detail-grid { grid-template-columns: 1fr; } + .sqd-grid-2 { grid-template-columns: 1fr; } +} + +@media (max-width: 640px) { + .sqd-main { + padding: 1.5rem 1rem; + } + + .sqd-page-header { + flex-direction: column; + align-items: flex-start; + gap: 0.75rem; + } + + .sqd-card { + overflow-x: auto; + } + + .sqd-card__header { + flex-wrap: wrap; + } + + .sqd-stats { + grid-template-columns: repeat(auto-fill, minmax(120px, 1fr)); + } + + .sqd-truncate { + max-width: 160px; + } +} + +@media (max-width: 576px) { + .sqd-header { + position: relative; + } + + .sqd-header__inner { + padding: 0 1rem; + } + + .sqd-nav-toggle { + display: flex; + } + + .sqd-nav-wrapper { + display: none; + position: absolute; + top: 100%; + left: 0; + right: 0; + background: var(--surface); + border-bottom: 1px solid var(--border); + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08); + z-index: 50; + padding: 0.5rem; + } + + .sqd-nav-wrapper.sqd-nav--open { + display: block; + } + + .sqd-nav { + flex-direction: column; + gap: 0.25rem; + } + + .sqd-nav a { + padding: 0.5rem 0.75rem; + font-size: 14px; + } } .sqd-detail-section { padding: 1.25rem; } diff --git a/app/views/layouts/solid_queue_web/application.html.erb b/app/views/layouts/solid_queue_web/application.html.erb index 9e3b061..d11ad2f 100644 --- a/app/views/layouts/solid_queue_web/application.html.erb +++ b/app/views/layouts/solid_queue_web/application.html.erb @@ -11,24 +11,34 @@
- <%= link_to "Solid Queue", root_path, class: "sqd-header__title" %> - +
+ <%= link_to "Solid Queue", root_path, class: "sqd-header__title" %> + +
+ +
+
<% if notice.present? %> -
<%= notice %>
+
<%= notice %>
<% end %> <% if alert.present? %> -
<%= alert %>
+ <% end %> <%= yield %> diff --git a/app/views/solid_queue_web/failed_jobs/index.html.erb b/app/views/solid_queue_web/failed_jobs/index.html.erb index 59ab09d..28b9d24 100644 --- a/app/views/solid_queue_web/failed_jobs/index.html.erb +++ b/app/views/solid_queue_web/failed_jobs/index.html.erb @@ -21,11 +21,11 @@ - - - - - + + + + + diff --git a/app/views/solid_queue_web/jobs/index.html.erb b/app/views/solid_queue_web/jobs/index.html.erb index 0993472..f7f6089 100644 --- a/app/views/solid_queue_web/jobs/index.html.erb +++ b/app/views/solid_queue_web/jobs/index.html.erb @@ -29,12 +29,12 @@
Job ClassQueueErrorFailed AtJob ClassQueueErrorFailed AtActions
- - - - - - <% if discardable %><% end %> + + + + + + <% if discardable %><% end %> diff --git a/app/views/solid_queue_web/processes/index.html.erb b/app/views/solid_queue_web/processes/index.html.erb index f1505d6..7d1f0ba 100644 --- a/app/views/solid_queue_web/processes/index.html.erb +++ b/app/views/solid_queue_web/processes/index.html.erb @@ -7,13 +7,13 @@
Job ClassQueuePriorityScheduled AtEnqueued AtJob ClassQueuePriorityScheduled AtEnqueued AtActions
- - - - - - - + + + + + + + diff --git a/app/views/solid_queue_web/queues/index.html.erb b/app/views/solid_queue_web/queues/index.html.erb index 8878542..b86670b 100644 --- a/app/views/solid_queue_web/queues/index.html.erb +++ b/app/views/solid_queue_web/queues/index.html.erb @@ -7,11 +7,11 @@
KindNamePIDHostDetailsLast HeartbeatStatusKindNamePIDHostDetailsLast HeartbeatStatus
- - - - - + + + + +
NameSizeLatencyStatusNameSizeLatencyStatusActions