Skip to content

Commit cba702c

Browse files
authored
Improve table row selection JS (hestiacp#3608)
* Add .js-units-container class * Improve alert copy * Formatting * Improve unit selection JS * Fixup List Backup Exclusions table HTML * Refactor * Add missing classes
1 parent 910c0de commit cba702c

32 files changed

+127
-94
lines changed

web/js/src/index.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ import handleFormSubmit from './formSubmit';
1414
import handleFtpAccountHints from './ftpAccountHints';
1515
import handleFtpAccounts from './ftpAccounts';
1616
import handleIpListDataSource from './ipListDataSource';
17-
import handleListSelectAll from './listSelectAll';
1817
import handleListSorting from './listSorting';
18+
import handleListUnitSelect from './listUnitSelect';
1919
import handleNameServerInput from './nameServerInput';
2020
import handlePasswordInput from './passwordInput';
2121
import handleShortcuts from './shortcuts';
@@ -40,8 +40,8 @@ function initListeners() {
4040
handleEditWebListeners();
4141
handleFormSubmit();
4242
handleFtpAccounts();
43-
handleListSelectAll();
4443
handleListSorting();
44+
handleListUnitSelect();
4545
handleNameServerInput();
4646
handlePasswordInput();
4747
handleStickyToolbar();

web/js/src/listSelectAll.js

Lines changed: 0 additions & 19 deletions
This file was deleted.

web/js/src/listSorting.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ export default function handleListSorting() {
88

99
const toggleButton = document.querySelector('.js-toggle-sorting-menu');
1010
const sortingMenu = document.querySelector('.js-sorting-menu');
11-
const unitsContainer = document.querySelector('.units');
11+
const unitsContainer = document.querySelector('.js-units-container');
1212

1313
if (!toggleButton || !sortingMenu || !unitsContainer) {
1414
return;

web/js/src/listUnitSelect.js

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
// Select unit behavior
2+
export default function handleListUnitSelect() {
3+
const checkboxes = Array.from(document.querySelectorAll('.js-unit-checkbox'));
4+
const units = checkboxes.map((checkbox) => checkbox.closest('.js-unit'));
5+
const selectAllCheckbox = document.querySelector('.js-toggle-all-checkbox');
6+
7+
if (checkboxes.length === 0 || !selectAllCheckbox) {
8+
return;
9+
}
10+
11+
let lastCheckedIndex = null;
12+
13+
checkboxes.forEach((checkbox, index) => {
14+
checkbox.addEventListener('click', (event) => {
15+
const isChecked = checkbox.checked;
16+
updateUnitSelection(units[index], isChecked);
17+
18+
if (event.shiftKey && lastCheckedIndex !== null) {
19+
handleMultiSelect(checkboxes, units, index, lastCheckedIndex, isChecked);
20+
}
21+
22+
lastCheckedIndex = index;
23+
});
24+
});
25+
26+
selectAllCheckbox.addEventListener('change', () => {
27+
const isChecked = selectAllCheckbox.checked;
28+
checkboxes.forEach((checkbox) => (checkbox.checked = isChecked));
29+
units.forEach((unit) => updateUnitSelection(unit, isChecked));
30+
});
31+
}
32+
33+
function updateUnitSelection(unit, isChecked) {
34+
unit.classList.toggle('selected', isChecked);
35+
}
36+
37+
function handleMultiSelect(checkboxes, units, index, lastCheckedIndex, isChecked) {
38+
const rangeStart = Math.min(index, lastCheckedIndex);
39+
const rangeEnd = Math.max(index, lastCheckedIndex);
40+
41+
for (let i = rangeStart; i <= rangeEnd; i++) {
42+
checkboxes[i].checked = isChecked;
43+
updateUnitSelection(units[i], isChecked);
44+
}
45+
}

web/js/src/navigation.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ export function enterFocused() {
2929
}
3030

3131
const activeUnit = document.querySelector(
32-
'.units .l-unit.focus .actions-panel__col.actions-panel__edit a'
32+
'.js-units-container .l-unit.focus .actions-panel__col.actions-panel__edit a'
3333
);
3434
if (activeUnit) {
3535
location.href = activeUnit.getAttribute('href');
@@ -78,9 +78,9 @@ function moveFocusLeftRight(direction) {
7878
}
7979

8080
function moveFocusUpDown(direction) {
81-
const unitSelector = '.units .l-unit:not(.header)';
81+
const unitSelector = '.js-units-container .l-unit:not(.header)';
8282
const units = Array.from(document.querySelectorAll(unitSelector));
83-
const currentFocused = document.querySelector('.units .l-unit.focus');
83+
const currentFocused = document.querySelector('.js-units-container .l-unit.focus');
8484
let index = units.indexOf(currentFocused);
8585

8686
if (index === -1) {

web/js/src/shortcuts.js

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -347,7 +347,7 @@ export default function handleShortcuts() {
347347
.register(
348348
{ key: 'L' },
349349
(_evt) => {
350-
const element = document.querySelector('.units .l-unit.focus .shortcut-l');
350+
const element = document.querySelector('.js-units-container .l-unit.focus .shortcut-l');
351351
if (element) {
352352
executeShortcut(element);
353353
}
@@ -357,7 +357,7 @@ export default function handleShortcuts() {
357357
.register(
358358
{ key: 'S' },
359359
(_evt) => {
360-
const element = document.querySelector('.units .l-unit.focus .shortcut-s');
360+
const element = document.querySelector('.js-units-container .l-unit.focus .shortcut-s');
361361
if (element) {
362362
executeShortcut(element);
363363
}
@@ -367,7 +367,7 @@ export default function handleShortcuts() {
367367
.register(
368368
{ key: 'W' },
369369
(_evt) => {
370-
const element = document.querySelector('.units .l-unit.focus .shortcut-w');
370+
const element = document.querySelector('.js-units-container .l-unit.focus .shortcut-w');
371371
if (element) {
372372
executeShortcut(element);
373373
}
@@ -377,7 +377,7 @@ export default function handleShortcuts() {
377377
.register(
378378
{ key: 'D' },
379379
(_evt) => {
380-
const element = document.querySelector('.units .l-unit.focus .shortcut-d');
380+
const element = document.querySelector('.js-units-container .l-unit.focus .shortcut-d');
381381
if (element) {
382382
executeShortcut(element);
383383
}
@@ -387,7 +387,7 @@ export default function handleShortcuts() {
387387
.register(
388388
{ key: 'R' },
389389
(_evt) => {
390-
const element = document.querySelector('.units .l-unit.focus .shortcut-r');
390+
const element = document.querySelector('.js-units-container .l-unit.focus .shortcut-r');
391391
if (element) {
392392
executeShortcut(element);
393393
}
@@ -397,7 +397,7 @@ export default function handleShortcuts() {
397397
.register(
398398
{ key: 'N' },
399399
(_evt) => {
400-
const element = document.querySelector('.units .l-unit.focus .shortcut-n');
400+
const element = document.querySelector('.js-units-container .l-unit.focus .shortcut-n');
401401
if (element) {
402402
executeShortcut(element);
403403
}
@@ -407,7 +407,7 @@ export default function handleShortcuts() {
407407
.register(
408408
{ key: 'U' },
409409
(_evt) => {
410-
const element = document.querySelector('.units .l-unit.focus .shortcut-u');
410+
const element = document.querySelector('.js-units-container .l-unit.focus .shortcut-u');
411411
if (element) {
412412
executeShortcut(element);
413413
}
@@ -417,7 +417,9 @@ export default function handleShortcuts() {
417417
.register(
418418
{ code: 'Delete' },
419419
(_evt) => {
420-
const element = document.querySelector('.units .l-unit.focus .shortcut-delete');
420+
const element = document.querySelector(
421+
'.js-units-container .l-unit.focus .shortcut-delete'
422+
);
421423
if (element) {
422424
executeShortcut(element);
423425
}
@@ -445,7 +447,9 @@ export default function handleShortcuts() {
445447
const dialog = document.querySelector('dialog[open]');
446448
dialog.querySelector('button[type="submit"]').click();
447449
} else {
448-
const element = document.querySelector('.units .l-unit.focus .shortcut-enter');
450+
const element = document.querySelector(
451+
'.js-units-container .l-unit.focus .shortcut-enter'
452+
);
449453
if (element) {
450454
executeShortcut(element);
451455
} else {

web/templates/pages/list_access_keys.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@
4242
<!-- End toolbar -->
4343

4444
<div class="container">
45-
<div class="units">
45+
<div class="units js-units-container">
4646
<div class="header units-header">
4747
<div class="l-unit__col l-unit__col--right">
4848
<div>

web/templates/pages/list_backup.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
<!-- End toolbar -->
3636

3737
<div class="container">
38-
<div class="units">
38+
<div class="units js-units-container">
3939
<div class="header units-header">
4040
<div class="l-unit__col l-unit__col--right">
4141
<div>
@@ -70,7 +70,7 @@
7070
if (!empty($data[$key]['CRON'])) $cron = _('Yes');
7171
if (!empty($data[$key]['UDIR'])) $udir = _('Yes');
7272
?>
73-
<div class="l-unit animate__animated animate__fadeIn">
73+
<div class="l-unit animate__animated animate__fadeIn js-unit">
7474
<div class="l-unit__col l-unit__col--right">
7575
<div>
7676
<div class="clearfix l-unit__stat-col--left super-compact">

web/templates/pages/list_backup_detail.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
<!-- End toolbar -->
3333

3434
<div class="container">
35-
<div class="units">
35+
<div class="units js-units-container">
3636
<div class="header units-header">
3737
<div class="l-unit__col l-unit__col--right">
3838
<div>
@@ -54,7 +54,7 @@
5454
if (!empty($key)) {
5555
++$i;
5656
?>
57-
<div class="l-unit animate__animated animate__fadeIn">
57+
<div class="l-unit animate__animated animate__fadeIn js-unit">
5858
<div class="l-unit__col l-unit__col--right">
5959
<div class="clearfix l-unit__stat-col--left super-compact">
6060
<input id="check<?= $i ?>" class="js-unit-checkbox" type="checkbox" name="web[]" value="<?= $key ?>">

web/templates/pages/list_backup_exclusions.php

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -24,20 +24,20 @@
2424
</div>
2525
<!-- End toolbar -->
2626

27-
<div class="container units">
28-
<div class="header units-header">
29-
<div class="l-unit__col l-unit__col--right">
30-
<div class="clearfix l-unit__stat-col--left super-compact">&nbsp;</div>
31-
<div class="clearfix l-unit__stat-col--left wide-1"><b><?= _("Type") ?></b></div>
32-
<div class="clearfix l-unit__stat-col--left compact u-text-right"><b>&nbsp;</b></div>
33-
<div class="clearfix l-unit__stat-col--left wide-3"><b><?= _("Value") ?></b></div>
27+
<div class="container">
28+
<div class="units js-units-container">
29+
<div class="header units-header">
30+
<div class="l-unit__col l-unit__col--right">
31+
<div class="clearfix l-unit__stat-col--left super-compact">&nbsp;</div>
32+
<div class="clearfix l-unit__stat-col--left wide-1"><b><?= _("Type") ?></b></div>
33+
<div class="clearfix l-unit__stat-col--left compact u-text-right"><b>&nbsp;</b></div>
34+
<div class="clearfix l-unit__stat-col--left wide-3"><b><?= _("Value") ?></b></div>
35+
</div>
3436
</div>
35-
</div>
3637

37-
<div class="container units animate__animated animate__fadeIn">
3838
<!-- Begin list of backup exclusions by type -->
3939
<?php foreach ($data as $key => $value) { ?>
40-
<div class="l-unit header">
40+
<div class="l-unit animate__animated animate__fadeIn js-unit">
4141
<div class="l-unit__col l-unit__col--right">
4242
<div class="clearfix l-unit__stat-col--left super-compact">&nbsp;</div>
4343
<div class="clearfix l-unit__stat-col--left wide-1"><b><?= $key ?></b></div>

0 commit comments

Comments
 (0)