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
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@ adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

### Fixed

- The failed-jobs selection bar's "apply to all N matching" button always
retried, even when you meant to discard. It is now two explicit buttons,
"Retry all" and "Discard all".

## [0.5.2] - 2026-07-27

### Fixed
Expand Down

Large diffs are not rendered by default.

8 changes: 4 additions & 4 deletions app/assets/flightdeck/manifest.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
{
"flightdeck.css": {
"file": "flightdeck-00403457c5d9.css",
"digest": "00403457c5d9",
"sha256": "00403457c5d9dd7455ccced13249ca5aa8f953e4532163f4493d58c561157350",
"file": "flightdeck-3967b9e6c506.css",
"digest": "3967b9e6c506",
"sha256": "3967b9e6c506b57edf0cde8de68e1138f3400e7901b7690bca660f1cfe27e219",
"content_type": "text/css; charset=utf-8",
"size": 118411
"size": 118446
},
"flightdeck.js": {
"file": "flightdeck-747ab6d1a6fa.js",
Expand Down
13 changes: 9 additions & 4 deletions app/views/flightdeck/jobs/_list.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,15 @@
formaction="<%= bulk_discard_jobs_path(list_filters.merge(state: :failed)) %>"
data-turbo-confirm="Permanently discard the selected jobs? This cannot be undone.">Discard selected</button>
<span class="spacer"></span>
<button type="submit" name="scope" value="all" class="fd-btn sm"
data-turbo-confirm="Retry all failed jobs matching the current filter?">
or apply to all <%= fd_count(query.count, capped: query.count_capped?) %> matching
</button>
<%# Each "all matching" button names its own action: a single neutral
"apply to all" button inherited the form's action and silently
retried when the user meant to discard. %>
<span class="fd-bulkbar-all">or all <%= fd_count(query.count, capped: query.count_capped?) %> matching:</span>
<button type="submit" name="scope" value="all" class="fd-btn sm primary"
data-turbo-confirm="Retry all failed jobs matching the current filter?">Retry all</button>
<button type="submit" name="scope" value="all" class="fd-btn sm danger"
formaction="<%= bulk_discard_jobs_path(list_filters.merge(state: :failed)) %>"
data-turbo-confirm="Permanently discard all failed jobs matching the current filter? This cannot be undone.">Discard all</button>
</div>

<div class="fd-card">
Expand Down
1 change: 1 addition & 0 deletions assets-src/input.css
Original file line number Diff line number Diff line change
Expand Up @@ -658,6 +658,7 @@ input[type="checkbox"] { accent-color: var(--accent); width: 14px; height: 14px;
margin-bottom: 12px; font-size: 13px; color: var(--accent-ink);
}
.fd-bulkbar .spacer { flex: 1; }
.fd-bulkbar-all { color: var(--ink-3); }
.fd-group-row td {
background: var(--panel-2); font: 500 11px/1.6 var(--font-mono); color: var(--ink-2);
letter-spacing: .03em; padding: 6px 14px;
Expand Down
18 changes: 18 additions & 0 deletions test/integration/jobs_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,24 @@ class Flightdeck::JobsTest < FlightdeckIntegrationTest
assert_select "input[type=checkbox][name='job_ids[]']", count: 3
end

# The bulk bar is one form posting to the retry endpoint, so every button that
# is not a retry must carry its own formaction. A neutral "apply to all"
# button once inherited the form action and retried when discard was meant.
test "every destructive button in the bulk bar posts to the discard endpoint" do
2.times { create_failed_job }

get_fd "/flightdeck/jobs?state=failed"

assert_response :success
assert_select ".fd-bulkbar button[formaction^=?]", "/flightdeck/jobs/discard", count: 2
assert_select ".fd-bulkbar button[name=scope][value=all]", count: 2 do |buttons|
assert_equal 1, buttons.count { |b| b["formaction"].to_s.start_with?("/flightdeck/jobs/discard") },
"one all-matching button must discard"
assert_equal 1, buttons.count { |b| b["formaction"].blank? },
"one all-matching button must fall through to the form's retry action"
end
end

test "the job detail page renders the error, arguments, metadata and timeline" do
job = create_failed_job(class_name: "Billing::ChargeSubscriptionJob",
queue_name: "critical",
Expand Down