Skip to content

Commit 25b34c9

Browse files
authored
Merge pull request #24038 from opf/bug/op-19622-multi-select-workflows-cannot-bulk-select-unselect-rows-columns
[OP-19622] Multi-select workflows cannot bulk select/unselect rows/columns
2 parents 470a383 + f6f62c5 commit 25b34c9

4 files changed

Lines changed: 78 additions & 7 deletions

File tree

frontend/src/stimulus/controllers/checkable.controller.spec.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ describe('CheckableController', () => {
7272
expect(inputs.every((i) => !i.checked)).toBe(true);
7373
});
7474

75-
it('dispatches input event', () => {
75+
it('dispatches a bubbling change event', () => {
7676
const dispatchSpy = vi.spyOn(inputs[0], 'dispatchEvent');
7777

7878
controller.toggleAll(new Event('click'));
@@ -81,9 +81,8 @@ describe('CheckableController', () => {
8181

8282
const eventArg = vi.mocked(dispatchSpy).mock.lastCall![0];
8383

84-
expect(eventArg.type).toBe('input');
85-
expect(eventArg.bubbles).toBe(false);
86-
expect(eventArg.cancelable).toBe(true);
84+
expect(eventArg.type).toBe('change');
85+
expect(eventArg.bubbles).toBe(true);
8786
});
8887

8988
it('checkAll calls toggleChecked(true)', () => {

frontend/src/stimulus/controllers/checkable.controller.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -147,13 +147,18 @@ export default class CheckableController extends Controller<HTMLElement> {
147147

148148
private toggleChecked(checkboxes:HTMLInputElement[], checked?:boolean) {
149149
// If all are checked -> uncheck all.
150-
// If mixed or none checked -> check all.
151-
const allChecked = checkboxes.every((checkbox) => checkbox.checked);
150+
// If mixed, indeterminate or none checked -> check all.
151+
const allChecked = checkboxes.every((checkbox) => checkbox.checked && !checkbox.indeterminate);
152152
checked ??= !allChecked;
153153

154154
checkboxes.forEach((checkbox) => {
155+
// Programmatically setting `checked` does not clear the indeterminate
156+
// flag the way a native click does, so clear it explicitly.
157+
checkbox.indeterminate = false;
155158
checkbox.checked = checked;
156-
checkbox.dispatchEvent(new Event('input', { bubbles: false, cancelable: true }));
159+
// Dispatch a bubbling `change` so form-level listeners
160+
// react just as they would to a native checkbox toggle.
161+
checkbox.dispatchEvent(new Event('change', { bubbles: true }));
157162
});
158163
}
159164
}

spec/features/workflows/edit_multi_role_spec.rb

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,65 @@
263263
click_button "Save"
264264
expect_flash(message: "Successful update.")
265265
end
266+
267+
it "bulk-checks an indeterminate cell when toggling its column" do
268+
expect(page).to have_field workflow_checkbox(0, 1), checked: false
269+
expect(indeterminate?(workflow_checkbox(0, 1))).to be true
270+
271+
toggle_select_all_in_column(1)
272+
273+
expect(page).to have_field workflow_checkbox(0, 1), checked: true
274+
expect(indeterminate?(workflow_checkbox(0, 1))).to be false
275+
276+
click_button "Save"
277+
expect_flash(message: "Successful update.")
278+
279+
expect_transition(role, 0, 1, exist: true)
280+
expect_transition(role2, 0, 1, exist: true)
281+
end
282+
283+
it "bulk-checks an indeterminate cell when toggling its row" do
284+
expect(page).to have_field workflow_checkbox(0, 1), checked: false
285+
expect(indeterminate?(workflow_checkbox(0, 1))).to be true
286+
287+
toggle_select_all_in_row(0)
288+
289+
expect(page).to have_field workflow_checkbox(0, 1), checked: true
290+
expect(indeterminate?(workflow_checkbox(0, 1))).to be false
291+
292+
click_button "Save"
293+
expect_flash(message: "Successful update.")
294+
295+
expect_transition(role, 0, 1, exist: true)
296+
expect_transition(role2, 0, 1, exist: true)
297+
end
298+
299+
it "bulk-unchecks an indeterminate cell when toggling its column twice" do
300+
expect(page).to have_field workflow_checkbox(0, 1), checked: false
301+
expect(indeterminate?(workflow_checkbox(0, 1))).to be true
302+
303+
toggle_select_all_in_column(1) # check all
304+
toggle_select_all_in_column(1) # uncheck all
305+
306+
expect(page).to have_field workflow_checkbox(0, 1), checked: false
307+
expect(indeterminate?(workflow_checkbox(0, 1))).to be false
308+
309+
click_button "Save"
310+
expect_flash(message: "Successful update.")
311+
312+
expect_transition(role, 0, 1, exist: false)
313+
expect_transition(role2, 0, 1, exist: false)
314+
end
315+
316+
it "marks the form dirty when bulk-toggling a column" do
317+
expect(page).to have_field workflow_checkbox(0, 1), checked: false
318+
expect(indeterminate?(workflow_checkbox(0, 1))).to be true
319+
320+
toggle_select_all_in_column(1)
321+
322+
click_link "User is author"
323+
expect(page).to have_dialog("Save changes before continuing?")
324+
end
266325
end
267326

268327
context "when deselecting all roles in the select panel" do

spec/support/workflows/edit_helpers.rb

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,14 @@ def remove_status_via_dialog(status)
6969
end
7070
end
7171

72+
def toggle_select_all_in_column(to_index)
73+
find(:button, accessible_name: "Toggle transitions from all old statuses to #{statuses[to_index].name}").click
74+
end
75+
76+
def toggle_select_all_in_row(from_index)
77+
find(:button, accessible_name: "Toggle transitions from #{statuses[from_index].name} to all new statuses").click
78+
end
79+
7280
def indeterminate?(checkbox_id)
7381
page.evaluate_script("document.getElementById('#{checkbox_id}')?.indeterminate ?? false")
7482
end

0 commit comments

Comments
 (0)