Skip to content

Commit 8b0e07e

Browse files
authored
Add a checkbox to select all issues/PRs (#20177)
1 parent 3bd8f50 commit 8b0e07e

File tree

2 files changed

+33
-8
lines changed

2 files changed

+33
-8
lines changed

templates/repo/issue/list.tmpl

+6
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,12 @@
2828
<div class="ui divider"></div>
2929
<div id="issue-filters" class="ui stackable grid">
3030
<div class="six wide column">
31+
{{if $.CanWriteIssuesOrPulls}}
32+
<div class="ui checkbox issue-checkbox-all vm">
33+
<input type="checkbox"></input>
34+
<label></label>
35+
</div>
36+
{{end}}
3137
{{template "repo/issue/openclose" .}}
3238
</div>
3339
<div class="ten wide right aligned column">

web_src/js/features/common-issue.js

+27-8
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,34 @@ import $ from 'jquery';
22
import {updateIssuesMeta} from './repo-issue.js';
33

44
export function initCommonIssue() {
5-
$('.issue-checkbox').on('click', () => {
6-
const numChecked = $('.issue-checkbox').children('input:checked').length;
7-
if (numChecked > 0) {
8-
$('#issue-filters').addClass('hide');
9-
$('#issue-actions').removeClass('hide');
5+
const $issueSelectAllWrapper = $('.issue-checkbox-all');
6+
const $issueSelectAll = $('.issue-checkbox-all input');
7+
const $issueCheckboxes = $('.issue-checkbox input');
8+
9+
const syncIssueSelectionState = () => {
10+
const $checked = $issueCheckboxes.filter(':checked');
11+
const anyChecked = $checked.length !== 0;
12+
const allChecked = anyChecked && $checked.length === $issueCheckboxes.length;
13+
14+
if (allChecked) {
15+
$issueSelectAll.prop({'checked': true, 'indeterminate': false});
16+
} else if (anyChecked) {
17+
$issueSelectAll.prop({'checked': false, 'indeterminate': true});
1018
} else {
11-
$('#issue-filters').removeClass('hide');
12-
$('#issue-actions').addClass('hide');
19+
$issueSelectAll.prop({'checked': false, 'indeterminate': false});
1320
}
21+
// if any issue is selected, show the action panel, otherwise show the filter panel
22+
$('#issue-filters').toggle(!anyChecked);
23+
$('#issue-actions').toggle(anyChecked);
24+
// there are two panels but only one select-all checkbox, so move the checkbox to the visible panel
25+
$('#issue-filters, #issue-actions').filter(':visible').find('.column:first').prepend($issueSelectAllWrapper);
26+
};
27+
28+
$issueCheckboxes.on('change', syncIssueSelectionState);
29+
30+
$issueSelectAll.on('change', () => {
31+
$issueCheckboxes.prop('checked', $issueSelectAll.is(':checked'));
32+
syncIssueSelectionState();
1433
});
1534

1635
$('.issue-action').on('click', async function () {
@@ -41,7 +60,7 @@ export function initCommonIssue() {
4160
});
4261

4362
// NOTICE: This event trigger targets Firefox caching behaviour, as the checkboxes stay
44-
// checked after reload trigger ckecked event, if checkboxes are checked on load
63+
// checked after reload trigger checked event, if checkboxes are checked on load
4564
$('.issue-checkbox input[type="checkbox"]:checked').first().each((_, e) => {
4665
e.checked = false;
4766
$(e).trigger('click');

0 commit comments

Comments
 (0)