diff --git a/CHANGELOG.md b/CHANGELOG.md index 844e7a7..3d66a99 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added +- Empty-state improvements — all list views now show a contextual title and an actionable hint; search result empty states include a "Clear search" link; history and stats link to active jobs; processes and recurring tasks explain what to do next - Inline notifications — bulk and single-job actions now surface a flash notice; Turbo Stream discard responses prepend the message to the page without a full reload; bulk discard/retry counts are shown ("3 jobs discarded") - Dark mode — toggle button in the header switches between light and dark palettes; preference persisted in `localStorage`; respects `prefers-color-scheme` on first visit; driven entirely by CSS custom properties on `[data-theme="dark"]` diff --git a/README.md b/README.md index 0530615..8aa40af 100644 --- a/README.md +++ b/README.md @@ -49,6 +49,7 @@ The dashboard will be available at `/solid_stack` (or whatever path you choose). - **Auto-refresh** — dashboard, jobs, processes, and history views poll automatically; pauses when the tab is hidden or a checkbox is checked; intervals configurable via `dashboard_refresh_interval` and `default_refresh_interval` - **Turbo Stream** job discard — removes the row inline without a full page reload - **Dark mode** — toggle button in the header switches between light and dark palettes; preference persisted in `localStorage`; respects `prefers-color-scheme` on first visit +- **Empty-state improvements** — all list views show a contextual title and an actionable hint; search empty states include a "Clear search" link; filters-active history view offers "Clear filters"; processes and recurring tasks explain the next step - **Inline notifications** — bulk and single-job actions surface a flash notice; Turbo Stream discard responses inject the message inline without a full page reload; bulk actions report the affected count ("3 jobs discarded") ### Configuration diff --git a/ROADMAP.md b/ROADMAP.md index 0991d69..ae7bbc7 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -11,7 +11,6 @@ The path to v1.0.0 is staged: first achieve feature parity with `solid_queue_das > _Make the interface feel fast and operational, not just functional._ ### Added -- **Empty-state improvements** — contextual empty states per section with actionable next steps - **Responsive layout** — stats cards and tables adapt to narrow viewports - **CSS audit** — review all inline styles, consolidate utility classes, remove duplication, and enforce consistent use of CSS custom properties across all stylesheets diff --git a/app/assets/stylesheets/solid_stack_web/_04_table.css b/app/assets/stylesheets/solid_stack_web/_04_table.css index 9130597..0b1ce4e 100644 --- a/app/assets/stylesheets/solid_stack_web/_04_table.css +++ b/app/assets/stylesheets/solid_stack_web/_04_table.css @@ -42,3 +42,15 @@ text-align: center; color: var(--muted); } + +.sqw-empty__title { + font-size: 15px; + font-weight: 600; + color: var(--text); + margin-bottom: 0.375rem; +} + +.sqw-empty__hint { + font-size: 13px; + margin-top: 0.375rem; +} diff --git a/app/views/solid_stack_web/cable/index.html.erb b/app/views/solid_stack_web/cable/index.html.erb index 552b21d..35c9d2b 100644 --- a/app/views/solid_stack_web/cable/index.html.erb +++ b/app/views/solid_stack_web/cable/index.html.erb @@ -69,6 +69,12 @@ <% else %>
-

<%= @search.present? ? "No channels matching “#{@search}”.".html_safe : "No cable messages." %>

+ <% if @search.present? %> +

No channels matching “<%= @search %>”

+

<%= link_to "Clear search", cable_path %>

+ <% else %> +

No cable messages

+

Messages will appear here once clients connect and broadcast over Action Cable.

+ <% end %>
<% end %> diff --git a/app/views/solid_stack_web/cable_messages/index.html.erb b/app/views/solid_stack_web/cable_messages/index.html.erb index 6ec0143..36036fe 100644 --- a/app/views/solid_stack_web/cable_messages/index.html.erb +++ b/app/views/solid_stack_web/cable_messages/index.html.erb @@ -45,6 +45,12 @@ <%== @pagy.series_nav if @pagy.pages > 1 %> <% else %>
-

<%= @search.present? ? "No messages matching “#{@search}”.".html_safe : "No messages for this channel." %>

+ <% if @search.present? %> +

No messages matching “<%= @search %>”

+

<%= link_to "Clear search", cable_channel_messages_path(params[:channel_hash]) %>

+ <% else %> +

No messages for this channel

+

Messages may have been purged or the channel has gone quiet. <%= link_to "Back to channels →", cable_path %>

+ <% end %>
<% end %> \ No newline at end of file diff --git a/app/views/solid_stack_web/cache_entries/index.html.erb b/app/views/solid_stack_web/cache_entries/index.html.erb index 17a6fc0..f0c6ae7 100644 --- a/app/views/solid_stack_web/cache_entries/index.html.erb +++ b/app/views/solid_stack_web/cache_entries/index.html.erb @@ -61,6 +61,12 @@ <%== @pagy.series_nav if @pagy.pages > 1 %> <% else %>
-

<%= @search.present? ? "No entries matching “#{@search}”.".html_safe : "No cache entries." %>

+ <% if @search.present? %> +

No entries matching “<%= @search %>”

+

<%= link_to "Clear search", cache_entries_path %>

+ <% else %> +

No cache entries

+

Entries will appear here once your application writes to the cache.

+ <% end %>
<% end %> \ No newline at end of file diff --git a/app/views/solid_stack_web/failed_jobs/index.html.erb b/app/views/solid_stack_web/failed_jobs/index.html.erb index af5d173..bebd9a0 100644 --- a/app/views/solid_stack_web/failed_jobs/index.html.erb +++ b/app/views/solid_stack_web/failed_jobs/index.html.erb @@ -66,7 +66,8 @@ <% else %>
-

No failed jobs.

+

No failed jobs

+

All clear — your jobs are running without errors.

<% end %> \ No newline at end of file diff --git a/app/views/solid_stack_web/history/index.html.erb b/app/views/solid_stack_web/history/index.html.erb index 8919841..33180e4 100644 --- a/app/views/solid_stack_web/history/index.html.erb +++ b/app/views/solid_stack_web/history/index.html.erb @@ -70,7 +70,13 @@ <% else %>
-

No finished jobs found.

+ <% if @search.present? || @queue.present? || @period.present? %> +

No finished jobs match your filters

+

<%= link_to "Clear filters", history_path %>

+ <% else %> +

No finished jobs yet

+

Completed jobs will appear here once workers process them.

+ <% end %>
<% end %> <% end %> \ No newline at end of file diff --git a/app/views/solid_stack_web/jobs/_empty.html.erb b/app/views/solid_stack_web/jobs/_empty.html.erb index 64edb77..119a236 100644 --- a/app/views/solid_stack_web/jobs/_empty.html.erb +++ b/app/views/solid_stack_web/jobs/_empty.html.erb @@ -1,3 +1,20 @@
-

No <%= @status %> jobs.

-
+ <% if @search.present? %> +

No <%= @status %> jobs matching “<%= @search %>”

+

<%= link_to "Clear search", jobs_path(status: @status) %>

+ <% else %> +

No <%= @status %> jobs

+

+ <% case @status %> + <% when "ready" %> + Jobs will appear here once they are enqueued and ready to be picked up. + <% when "scheduled" %> + No jobs are scheduled to run in the future. + <% when "claimed" %> + No jobs are currently being processed by a worker. + <% when "blocked" %> + No jobs are blocked by concurrency controls. + <% end %> +

+ <% end %> + \ No newline at end of file diff --git a/app/views/solid_stack_web/processes/index.html.erb b/app/views/solid_stack_web/processes/index.html.erb index 512e933..3dbf02f 100644 --- a/app/views/solid_stack_web/processes/index.html.erb +++ b/app/views/solid_stack_web/processes/index.html.erb @@ -29,7 +29,8 @@ <% else %>
-

No active processes.

+

No active processes

+

Start a Solid Queue worker to begin processing jobs.

<% end %> <% end %> diff --git a/app/views/solid_stack_web/queues/index.html.erb b/app/views/solid_stack_web/queues/index.html.erb index 664ca68..1bb9aa9 100644 --- a/app/views/solid_stack_web/queues/index.html.erb +++ b/app/views/solid_stack_web/queues/index.html.erb @@ -44,6 +44,7 @@ <% else %>
-

No queues with ready jobs.

+

No queues with ready jobs

+

Workers are idle or all jobs are in another state. <%= link_to "Check job statuses →", jobs_path %>

<% end %> \ No newline at end of file diff --git a/app/views/solid_stack_web/recurring_tasks/index.html.erb b/app/views/solid_stack_web/recurring_tasks/index.html.erb index cce359f..e3e3a8f 100644 --- a/app/views/solid_stack_web/recurring_tasks/index.html.erb +++ b/app/views/solid_stack_web/recurring_tasks/index.html.erb @@ -62,6 +62,7 @@ <% else %>
-

No recurring tasks configured.

+

No recurring tasks configured

+

Define recurring tasks in your Solid Queue configuration to see them here.

<% end %> \ No newline at end of file diff --git a/app/views/solid_stack_web/stats/index.html.erb b/app/views/solid_stack_web/stats/index.html.erb index 00de830..0866a60 100644 --- a/app/views/solid_stack_web/stats/index.html.erb +++ b/app/views/solid_stack_web/stats/index.html.erb @@ -43,6 +43,7 @@ <% else %>
-

No finished jobs yet.

+

No finished jobs yet

+

Performance stats appear here once jobs complete. <%= link_to "View active jobs →", jobs_path %>

<% end %> \ No newline at end of file diff --git a/spec/requests/solid_stack_web/history_spec.rb b/spec/requests/solid_stack_web/history_spec.rb index 0dc45eb..4368308 100644 --- a/spec/requests/solid_stack_web/history_spec.rb +++ b/spec/requests/solid_stack_web/history_spec.rb @@ -35,7 +35,7 @@ def finished_job(class_name: "TestJob", queue_name: "default", duration: 30, fin it "shows an empty state when no finished jobs exist" do get "#{engine_root}/history" - expect(response.body).to include("No finished jobs found") + expect(response.body).to include("No finished jobs yet") end it "displays class name, queue, duration, and finished_at columns" do