Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

- Install generator — `rails generate solid_stack_web:install` creates `config/initializers/solid_stack_web.rb` with every config option documented inline and injects the mount line into `config/routes.rb`
- `SolidStackWeb.mount_path` — returns the path at which the engine is mounted in the host app, derived automatically from routes; use `link_to "Dashboard", SolidStackWeb.mount_path` to link to the dashboard without hardcoding the path
- Accessibility pass — skip-to-content link; ARIA labels on all navigation elements; `scope="col"` on every table header; visually-hidden "Actions" label on empty action-column headers; `aria-sort` on active sort columns in stats and cache entries; `aria_label: "Pagination"` on all pagination navs; `.sqw-sr-only` and `.sqw-skip-link` CSS utilities added to base stylesheet

## [0.8.0] - 2026-05-26

Expand Down
1 change: 0 additions & 1 deletion ROADMAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ The path to v1.0.0 is staged: first achieve feature parity with `solid_queue_das
> _Make it easy to adopt and easy to contribute to._

### Remaining
- **Accessibility pass** — keyboard navigation, ARIA labels on interactive elements, sufficient colour contrast in both themes
- **Query optimisation** — eliminate N+1 queries across all list views; add covering indexes to the dummy app schema
- **Error pages** — engine-scoped 404/500 views so errors stay within the dashboard chrome
- **Changelog-driven upgrade notes** — `UPGRADING.md` for any breaking configuration changes
Expand Down
12 changes: 12 additions & 0 deletions app/assets/stylesheets/solid_stack_web/_01_base.css
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,15 @@ a:hover { text-decoration: underline; }
.sqw-monospace { font-family: ui-monospace, "SFMono-Regular", Menlo, monospace; font-size: 13px; }
.sqw-muted { color: var(--muted); }
.sqw-truncate { max-width: 280px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.sqw-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;
}

.sqw-skip-link {
position: absolute; top: -100%; left: 0; z-index: 9999;
padding: 0.5rem 1rem; background: var(--accent); color: #fff;
font-weight: 600; text-decoration: none; border-radius: 0 0 4px 0;
}
.sqw-skip-link:focus { top: 0; }
11 changes: 6 additions & 5 deletions app/views/layouts/solid_stack_web/application.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,11 @@
<%= javascript_importmap_tags "solid_stack_web" %>
</head>
<body data-controller="theme">
<a href="#main-content" class="sqw-skip-link">Skip to main content</a>
<header class="sqw-header">
<div class="sqw-header__inner">
<%= link_to "Solid Stack", root_path, class: "sqw-header__logo" %>
<nav class="sqw-nav">
<nav class="sqw-nav" aria-label="Main navigation">
<%= link_to "Queue", jobs_path,
class: "sqw-nav__link#{" sqw-nav__link--active" if current_section == :queue}" %>
<%= link_to "Cache", cache_path,
Expand All @@ -28,7 +29,7 @@
</header>

<% if current_section == :cache %>
<nav class="sqw-subnav">
<nav class="sqw-subnav" aria-label="Cache section">
<div class="sqw-subnav__inner">
<%= link_to "Overview", cache_path,
class: "sqw-subnav__link#{" sqw-subnav__link--active" if controller_name == "cache"}" %>
Expand All @@ -39,7 +40,7 @@
<% end %>

<% if current_section == :cable %>
<nav class="sqw-subnav">
<nav class="sqw-subnav" aria-label="Cable section">
<div class="sqw-subnav__inner">
<%= link_to "Overview", cable_path,
class: "sqw-subnav__link#{" sqw-subnav__link--active" if controller_name == "cable"}" %>
Expand All @@ -48,7 +49,7 @@
<% end %>

<% if current_section == :queue %>
<nav class="sqw-subnav">
<nav class="sqw-subnav" aria-label="Queue section">
<div class="sqw-subnav__inner">
<%= link_to "Jobs", jobs_path,
class: "sqw-subnav__link#{" sqw-subnav__link--active" if controller_name == "jobs"}" %>
Expand All @@ -68,7 +69,7 @@
</nav>
<% end %>

<main class="sqw-main">
<main id="main-content" class="sqw-main">
<div id="sqw-flash-container">
<% flash.each do |type, message| %>
<div class="sqw-flash sqw-flash--<%= type %>"><%= message %></div>
Expand Down
6 changes: 3 additions & 3 deletions app/views/solid_stack_web/cable/index.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,9 @@
<table class="sqw-table">
<thead>
<tr>
<th>Channel</th>
<th>Messages</th>
<th>Last Message</th>
<th scope="col">Channel</th>
<th scope="col">Messages</th>
<th scope="col">Last Message</th>
</tr>
</thead>
<tbody>
Expand Down
8 changes: 4 additions & 4 deletions app/views/solid_stack_web/cable_messages/index.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@
<table class="sqw-table">
<thead>
<tr>
<th>ID</th>
<th>Payload</th>
<th>Sent</th>
<th scope="col">ID</th>
<th scope="col">Payload</th>
<th scope="col">Sent</th>
</tr>
</thead>
<tbody>
Expand All @@ -42,7 +42,7 @@
<% end %>
</tbody>
</table>
<%== @pagy.series_nav if @pagy.pages > 1 %>
<%== @pagy.series_nav(aria_label: "Pagination") if @pagy.pages > 1 %>
<% else %>
<div class="sqw-empty">
<% if @search.present? %>
Expand Down
10 changes: 5 additions & 5 deletions app/views/solid_stack_web/cache/index.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@
<table class="sqw-table">
<thead>
<tr>
<th>Range</th>
<th>Entries</th>
<th></th>
<th scope="col">Range</th>
<th scope="col">Entries</th>
<th scope="col"><span class="sqw-sr-only">Distribution</span></th>
</tr>
</thead>
<tbody>
Expand All @@ -48,8 +48,8 @@
<table class="sqw-table">
<thead>
<tr>
<th>Key</th>
<th>Size</th>
<th scope="col">Key</th>
<th scope="col">Size</th>
</tr>
</thead>
<tbody>
Expand Down
6 changes: 3 additions & 3 deletions app/views/solid_stack_web/cache_entries/index.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
<thead>
<tr>
<% [["key", "Key"], ["byte_size", "Size"], ["created_at", "Created"]].each do |col, label| %>
<th>
<th scope="col">
<% next_dir = (@sort["column"] == col && @sort["direction"] == "desc") ? "asc" : "desc" %>
<%= link_to cache_entries_path(q: @search, column: col, direction: next_dir) do %>
<%= label %>
Expand All @@ -36,7 +36,7 @@
<% end %>
</th>
<% end %>
<th></th>
<th scope="col"><span class="sqw-sr-only">Actions</span></th>
</tr>
</thead>
<tbody>
Expand All @@ -58,7 +58,7 @@
<% end %>
</tbody>
</table>
<%== @pagy.series_nav if @pagy.pages > 1 %>
<%== @pagy.series_nav(aria_label: "Pagination") if @pagy.pages > 1 %>
<% else %>
<div class="sqw-empty">
<% if @search.present? %>
Expand Down
14 changes: 7 additions & 7 deletions app/views/solid_stack_web/failed_jobs/index.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,14 @@
<table class="sqw-table">
<thead>
<tr>
<th><input type="checkbox" class="sqw-checkbox" aria-label="Select all"
<th scope="col"><input type="checkbox" class="sqw-checkbox" aria-label="Select all"
data-selection-target="selectAll"
data-action="change->selection#selectAll"></th>
<th>Job Class</th>
<th>Queue</th>
<th>Error</th>
<th>Failed At</th>
<th></th>
<th scope="col">Job Class</th>
<th scope="col">Queue</th>
<th scope="col">Error</th>
<th scope="col">Failed At</th>
<th scope="col"><span class="sqw-sr-only">Actions</span></th>
</tr>
</thead>
<tbody>
Expand All @@ -62,7 +62,7 @@
<% end %>
</tbody>
</table>
<%== @pagy.series_nav if @pagy.pages > 1 %>
<%== @pagy.series_nav(aria_label: "Pagination") if @pagy.pages > 1 %>
</div>
<% else %>
<div class="sqw-empty">
Expand Down
10 changes: 5 additions & 5 deletions app/views/solid_stack_web/history/index.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,10 @@
<table class="sqw-table">
<thead>
<tr>
<th>Job Class</th>
<th>Queue</th>
<th>Duration</th>
<th>Finished At</th>
<th scope="col">Job Class</th>
<th scope="col">Queue</th>
<th scope="col">Duration</th>
<th scope="col">Finished At</th>
</tr>
</thead>
<tbody>
Expand All @@ -66,7 +66,7 @@
<% end %>
</tbody>
</table>
<%== @pagy.series_nav if @pagy.pages > 1 %>
<%== @pagy.series_nav(aria_label: "Pagination") if @pagy.pages > 1 %>
</div>
<% else %>
<div class="sqw-empty">
Expand Down
16 changes: 8 additions & 8 deletions app/views/solid_stack_web/jobs/index.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -96,16 +96,16 @@
<thead>
<tr>
<% if SolidStackWeb::Job::DISCARDABLE.include?(@status) %>
<th><input type="checkbox" class="sqw-checkbox" aria-label="Select all"
<th scope="col"><input type="checkbox" class="sqw-checkbox" aria-label="Select all"
data-selection-target="selectAll"
data-action="change->selection#selectAll"></th>
<% end %>
<th>Job Class</th>
<th>Queue</th>
<th>Priority</th>
<th>Enqueued At</th>
<% if @status == "scheduled" %><th>Scheduled At</th><% end %>
<th></th>
<th scope="col">Job Class</th>
<th scope="col">Queue</th>
<th scope="col">Priority</th>
<th scope="col">Enqueued At</th>
<% if @status == "scheduled" %><th scope="col">Scheduled At</th><% end %>
<th scope="col"><span class="sqw-sr-only">Actions</span></th>
</tr>
</thead>
<tbody>
Expand Down Expand Up @@ -149,7 +149,7 @@
<% end %>
</tbody>
</table>
<%== @pagy.series_nav if @pagy.pages > 1 %>
<%== @pagy.series_nav(aria_label: "Pagination") if @pagy.pages > 1 %>
</div>
<% else %>
<%= render "empty" %>
Expand Down
10 changes: 5 additions & 5 deletions app/views/solid_stack_web/processes/index.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@
<table class="sqw-table">
<thead>
<tr>
<th>Kind</th>
<th>Name</th>
<th>PID</th>
<th>Host</th>
<th>Last Heartbeat</th>
<th scope="col">Kind</th>
<th scope="col">Name</th>
<th scope="col">PID</th>
<th scope="col">Host</th>
<th scope="col">Last Heartbeat</th>
</tr>
</thead>
<tbody>
Expand Down
10 changes: 5 additions & 5 deletions app/views/solid_stack_web/queues/index.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@
<table class="sqw-table">
<thead>
<tr>
<th>Name</th>
<th>Size</th>
<th>Depth (12h)</th>
<th>Status</th>
<th></th>
<th scope="col">Name</th>
<th scope="col">Size</th>
<th scope="col">Depth (12h)</th>
<th scope="col">Status</th>
<th scope="col"><span class="sqw-sr-only">Actions</span></th>
</tr>
</thead>
<tbody>
Expand Down
10 changes: 5 additions & 5 deletions app/views/solid_stack_web/queues/show.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,10 @@
<table class="sqw-table">
<thead>
<tr>
<th>Job Class</th>
<th>Priority</th>
<th>Enqueued At</th>
<th></th>
<th scope="col">Job Class</th>
<th scope="col">Priority</th>
<th scope="col">Enqueued At</th>
<th scope="col"><span class="sqw-sr-only">Actions</span></th>
</tr>
</thead>
<tbody>
Expand All @@ -59,7 +59,7 @@
<% end %>
</tbody>
</table>
<%== @pagy.series_nav if @pagy.pages > 1 %>
<%== @pagy.series_nav(aria_label: "Pagination") if @pagy.pages > 1 %>
<% else %>
<div class="sqw-empty">
<p>No ready jobs in <strong><%= @queue_name %></strong>.</p>
Expand Down
16 changes: 8 additions & 8 deletions app/views/solid_stack_web/recurring_tasks/index.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@
<table class="sqw-table">
<thead>
<tr>
<th>Key</th>
<th>Schedule</th>
<th>Job / Command</th>
<th>Queue</th>
<th>Next Run</th>
<th>Last Run</th>
<th>Type</th>
<th></th>
<th scope="col">Key</th>
<th scope="col">Schedule</th>
<th scope="col">Job / Command</th>
<th scope="col">Queue</th>
<th scope="col">Next Run</th>
<th scope="col">Last Run</th>
<th scope="col">Type</th>
<th scope="col"><span class="sqw-sr-only">Actions</span></th>
</tr>
</thead>
<tbody>
Expand Down
2 changes: 1 addition & 1 deletion app/views/solid_stack_web/stats/index.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
["min", "Min"],
["max", "Max"]
].each do |col, label| %>
<th>
<th scope="col" <%= "aria-sort=\"#{@direction == 'asc' ? 'ascending' : 'descending'}\"".html_safe if @sort == col %>>
<% next_dir = (@sort == col && @direction == "desc") ? "asc" : "desc" %>
<%= link_to stats_path(sort: col, direction: next_dir) do %>
<%= label %>
Expand Down