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 @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Added

- 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"]`

## [0.6.0] - 2026-05-26
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
- **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

Expand Down
3 changes: 1 addition & 2 deletions ROADMAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,7 @@ 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
o- **Empty-state improvements** — contextual empty states per section with actionable next steps
- **Inline notifications** — flash-style Turbo Stream feedback on bulk actions
- **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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,17 @@ class SelectionsController < ApplicationController
before_action :set_ids

def create
count = @ids.size
SolidQueue::FailedExecution.where(id: @ids).each(&:retry)
redirect_to failed_jobs_path
redirect_to failed_jobs_path, notice: "#{count} #{count == 1 ? "job" : "jobs"} retried."
rescue => e
redirect_to failed_jobs_path, alert: "Could not retry jobs: #{e.message}"
end

def destroy
job_ids = SolidQueue::FailedExecution.where(id: @ids).pluck(:job_id)
SolidQueue::Job.where(id: job_ids).destroy_all
redirect_to failed_jobs_path
count = SolidQueue::Job.where(id: job_ids).destroy_all.size
redirect_to failed_jobs_path, notice: "#{count} #{count == 1 ? "job" : "jobs"} discarded."
rescue => e
redirect_to failed_jobs_path, alert: "Could not discard jobs: #{e.message}"
end
Expand Down
3 changes: 2 additions & 1 deletion app/controllers/solid_stack_web/failed_jobs_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ def destroy
@execution = ::SolidQueue::FailedExecution.find(params[:id])
@execution.job.destroy!
@executions_remain = ::SolidQueue::FailedExecution.exists?
@notice = "Job discarded."

respond_to do |format|
format.html { redirect_to failed_jobs_path }
Expand All @@ -35,7 +36,7 @@ def destroy
def retry
execution = ::SolidQueue::FailedExecution.find(params[:id])
execution.retry
redirect_to failed_jobs_path
redirect_to failed_jobs_path, notice: "Job retried."
end

private
Expand Down
4 changes: 2 additions & 2 deletions app/controllers/solid_stack_web/jobs/selections_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,15 @@ def destroy

ids = Array(params[:job_ids]).map(&:to_i).reject(&:zero?)
job_ids = Job::EXECUTION_MODELS[status].where(id: ids).pluck(:job_id)
SolidQueue::Job.where(id: job_ids).destroy_all
count = SolidQueue::Job.where(id: job_ids).destroy_all.size

redirect_to jobs_path(
status: status,
q: params[:q].presence,
queue: params[:queue].presence,
period: params[:period].presence_in(PERIOD_DURATIONS.keys),
priority: params[:priority].presence
)
), notice: "#{count} #{count == 1 ? "job" : "jobs"} discarded."
rescue ArgumentError => e
redirect_to jobs_path(status: params[:status]), alert: e.message
end
Expand Down
6 changes: 4 additions & 2 deletions app/controllers/solid_stack_web/jobs_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,17 @@ def destroy
@execution = Job::EXECUTION_MODELS[@status].find(params[:id])
@execution.job.destroy!
@executions_remain = Job::EXECUTION_MODELS[@status].exists?
@notice = "Job discarded."

respond_to do |format|
format.html { redirect_to jobs_path(status: @status, q: @search, queue: @queue, period: @period, priority: @priority) }
format.turbo_stream
end
else
job_ids = filtered_scope.pluck(:job_id)
SolidQueue::Job.where(id: job_ids).destroy_all
redirect_to jobs_path(status: @status, q: @search, queue: @queue, period: @period, priority: @priority)
count = SolidQueue::Job.where(id: job_ids).destroy_all.size
redirect_to jobs_path(status: @status, q: @search, queue: @queue, period: @period, priority: @priority),
notice: "#{count} #{count == 1 ? "job" : "jobs"} discarded."
end
end

Expand Down
8 changes: 5 additions & 3 deletions app/views/layouts/solid_stack_web/application.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,11 @@
<% end %>

<main class="sqw-main">
<% flash.each do |type, message| %>
<div class="sqw-flash sqw-flash--<%= type %>"><%= message %></div>
<% end %>
<div id="sqw-flash-container">
<% flash.each do |type, message| %>
<div class="sqw-flash sqw-flash--<%= type %>"><%= message %></div>
<% end %>
</div>
<%= yield %>
</main>
</body>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
<%= turbo_stream.prepend "sqw-flash-container",
partial: "solid_stack_web/shared/flash",
locals: { type: "notice", message: @notice } %>
<% if @executions_remain %>
<%= turbo_stream.remove "execution_#{@execution.id}" %>
<% else %>
Expand Down
3 changes: 3 additions & 0 deletions app/views/solid_stack_web/jobs/destroy.turbo_stream.erb
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
<%= turbo_stream.prepend "sqw-flash-container",
partial: "solid_stack_web/shared/flash",
locals: { type: "notice", message: @notice } %>
<% if @executions_remain %>
<%= turbo_stream.remove "execution_#{@execution.id}" %>
<% else %>
Expand Down
1 change: 1 addition & 0 deletions app/views/solid_stack_web/shared/_flash.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<div class="sqw-flash sqw-flash--<%= type %>"><%= message %></div>