Skip to content

Commit f1fc3c1

Browse files
committed
Show indeterminate checkboxes in workflows matrix
1 parent b8b5574 commit f1fc3c1

3 files changed

Lines changed: 24 additions & 12 deletions

File tree

app/controllers/workflows/tabs_controller.rb

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ def edit
4848

4949
statuses_for_form
5050

51-
if @type && @role && @statuses.any?
51+
if @type && @roles.any? && @statuses.any?
5252
workflows_for_form
5353
end
5454
end
@@ -100,7 +100,7 @@ def status_dialog
100100
current_statuses = if params[:status_ids].present?
101101
Status.where(id: params[:status_ids].map(&:to_i)).order(:position)
102102
elsif @type && @role
103-
statuses_for_role_and_type
103+
statuses_for_roles_and_type
104104
else
105105
Status.none
106106
end
@@ -169,8 +169,8 @@ def statuses_for_form
169169
@has_status_changes = false
170170
@statuses = if @type && params[:status_ids].present?
171171
statuses_from_params
172-
elsif @type && @role
173-
statuses_for_role_and_type
172+
elsif @type && @roles.any?
173+
statuses_for_roles_and_type
174174
elsif @type
175175
@type.statuses
176176
else
@@ -180,18 +180,19 @@ def statuses_for_form
180180

181181
def statuses_from_params
182182
status_ids = params[:status_ids].map(&:to_i)
183-
saved_ids = statuses_for_role_and_type.pluck(:id)
183+
saved_ids = statuses_for_roles_and_type.pluck(:id)
184184
@added_status_ids = status_ids - saved_ids
185185
@has_status_changes = @added_status_ids.any? || (saved_ids - status_ids).any?
186186
Status.where(id: status_ids).order(:position)
187187
end
188188

189-
def statuses_for_role_and_type
190-
@type.statuses(role: @role, tab: @tab)
189+
def statuses_for_roles_and_type
190+
status_ids = @roles.map { |role| @type.statuses(role:, tab: @tab).pluck(:id) }.flatten.uniq
191+
Status.where(id: status_ids)
191192
end
192193

193194
def workflows_for_form
194-
workflows = Workflow.where(role_id: @role.id, type_id: @type.id)
195+
workflows = Workflow.where(role_id: @roles.map(&:id), type_id: @type.id)
195196
@workflows = {}
196197
@workflows["always"] = workflows.select { |w| !w.author && !w.assignee }
197198
@workflows["author"] = workflows.select(&:author)

app/views/workflows/_form.html.erb

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -187,8 +187,9 @@ See COPYRIGHT and LICENSE files for more details.
187187
<% end %>
188188
</th>
189189
<% @statuses.each do |new_status| -%>
190-
<% transition_saved = workflows.any? { it.old_status_id == old_status.id && it.new_status_id == new_status.id }
191-
newly_added_status = @added_status_ids.include?(old_status.id) || @added_status_ids.include?(new_status.id) %>
190+
<% transition_role_ids = workflows.select { it.old_status_id == old_status.id && it.new_status_id == new_status.id }.map(&:role_id).uniq
191+
newly_added_status = @added_status_ids.include?(old_status.id) || @added_status_ids.include?(new_status.id)
192+
some_roles = !transition_role_ids.empty? && transition_role_ids.size < @roles.size && !newly_added_status %>
192193
<td>
193194
<%=
194195
render(Primer::BaseComponent.new(tag: :div, display: :flex, align_items: :center, mx: 1)) do
@@ -198,13 +199,14 @@ See COPYRIGHT and LICENSE files for more details.
198199
name: "status[#{old_status.id}][#{new_status.id}]",
199200
id: "status_#{old_status.id}_#{new_status.id}", # See BUG https://github.com/primer/view_components/issues/3811
200201
value: name,
201-
checked: transition_saved || newly_added_status,
202+
checked: transition_role_ids.any? || newly_added_status,
202203
label: t(".matrix_checkbox_label", old_status: old_status.name, new_status: new_status.name),
203204
visually_hide_label: true,
204205
data: {
205206
checkable_target: "checkbox",
206207
old_status: old_status.id,
207-
new_status: new_status.id
208+
new_status: new_status.id,
209+
indeterminate: (true if some_roles)
208210
}
209211
)
210212
)

frontend/src/stimulus/controllers/dynamic/admin/workflow-checkbox-state.controller.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,9 @@ export default class WorkflowCheckboxStateController extends Controller<HTMLForm
8383
this.applyState(statusCheckboxes);
8484
// Recompute dirty flag: the restored state may differ from DB pristine.
8585
this.onCheckboxChange();
86+
} else {
87+
// Apply indeterminate checkboxes only on fresh server rendered content.
88+
this.initIndeterminateCheckboxes();
8689
}
8790

8891
// Use document-level delegation so this works even when the EditComponent
@@ -284,6 +287,12 @@ export default class WorkflowCheckboxStateController extends Controller<HTMLForm
284287
});
285288
}
286289

290+
private initIndeterminateCheckboxes():void {
291+
this.element.querySelectorAll<HTMLInputElement>('input[type="checkbox"][data-indeterminate="true"]').forEach((cb) => {
292+
cb.indeterminate = true;
293+
});
294+
}
295+
287296
//
288297
// Trigger navigation with dirty-state confirmation.
289298
//

0 commit comments

Comments
 (0)