From 90a03c3c536337ff281e88a4321e86553e7ebe48 Mon Sep 17 00:00:00 2001 From: rjbaarsma Date: Mon, 3 Jun 2024 20:11:51 +0200 Subject: [PATCH 1/2] disabled top row button when no source rows are selected --- securedrop/static/css/journalist.css | 10 +++++++ securedrop/static/js/journalist.js | 40 +++++++++++++++++++++++++++- 2 files changed, 49 insertions(+), 1 deletion(-) diff --git a/securedrop/static/css/journalist.css b/securedrop/static/css/journalist.css index 4a3e5c40ff..ae41f5e39f 100644 --- a/securedrop/static/css/journalist.css +++ b/securedrop/static/css/journalist.css @@ -796,6 +796,16 @@ a.btn, font-size: .8em; } +button[disabled], +button[disabled]:hover, +a#delete-collections-link.disabled, +a#delete-collections-link.disabled:hover { + background: lightgrey; + color: darkgrey; + border:none; + cursor: default; +} + button:not([lang=ar]), a.btn:not([lang=ar]), .btn:not([lang=ar]) { diff --git a/securedrop/static/js/journalist.js b/securedrop/static/js/journalist.js index 55afdd755a..1739c562b7 100644 --- a/securedrop/static/js/journalist.js +++ b/securedrop/static/js/journalist.js @@ -34,6 +34,35 @@ function show(selector, displayStyle = "revert") { }); } +function disableButtons(selector) { + let nodelist = document.querySelectorAll(selector); + Array.prototype.forEach.call(nodelist, function(element) { + element.disabled = true; + element.classList.add("disabled"); + }) +} + +function enableButtons(selector) { + let nodelist = document.querySelectorAll(selector); + Array.prototype.forEach.call(nodelist, function(element) { + element.disabled = false; + element.classList.remove("disabled"); + }) +} + +function disableButtonsIfNoCheckedRows() { + let buttons = 'button[name="action"]'; + let deletelink = 'a#delete-collections-link' + let checkedboxes = document.querySelectorAll(ROW_SELECTOR_PREFIX + ":not(.hidden) input[type=checkbox]:checked"); + if (checkedboxes.length == 0) { + disableButtons(buttons); + disableButtons(deletelink); + } else { + enableButtons(buttons); + enableButtons(deletelink); + } +} + function enhance_ui() { // Add the "quick filter" box for the list of sources let filterContainer = document.getElementById("filter-container"); @@ -107,10 +136,10 @@ function ready(fn) { } ready(function() { + disableButtonsIfNoCheckedRows(); enhance_ui(); let selectAll = document.getElementById("select_all"); - if (selectAll) { selectAll.style.cursor = "pointer"; selectAll.addEventListener("click", function() { @@ -118,6 +147,7 @@ ready(function() { for (let i = 0; i < checkboxes.length; i++) { checkboxes[i].checked = true; } + disableButtonsIfNoCheckedRows(); }); } @@ -129,6 +159,7 @@ ready(function() { for (let i = 0; i < checkboxes.length; i++) { checkboxes[i].checked = false; } + disableButtonsIfNoCheckedRows(); }); } @@ -147,6 +178,11 @@ ready(function() { }); } + let checkboxes = document.querySelectorAll(ROW_SELECTOR_PREFIX + ":not(.hidden) input[type=checkbox]"); + for (let i = 0; i < checkboxes.length; i++) { + checkboxes[i].addEventListener("click", disableButtonsIfNoCheckedRows); + } + // When unread messages are downloaded from the source list, mark // the source read. let unreadLinks = document.querySelectorAll(".unread .unread a"); @@ -247,3 +283,5 @@ ready(function() { } } }); + + From 0ecddf59739452fe69c94fe6a111c27018ce737b Mon Sep 17 00:00:00 2001 From: rjbaarsma Date: Mon, 3 Jun 2024 20:20:40 +0200 Subject: [PATCH 2/2] small refactor for legibility --- securedrop/static/js/journalist.js | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/securedrop/static/js/journalist.js b/securedrop/static/js/journalist.js index 1739c562b7..08e1657665 100644 --- a/securedrop/static/js/journalist.js +++ b/securedrop/static/js/journalist.js @@ -5,6 +5,7 @@ const COLLECTION_SELECTOR_PREFIX = "table"; const ROW_SELECTOR_PREFIX = COLLECTION_SELECTOR_PREFIX + " tr" +const CHECKBOX_SELECTOR = ROW_SELECTOR_PREFIX + ':not(.hidden) input[name="cols_selected"]' function closest(element, selector) { let parent = element.parentNode; @@ -53,7 +54,7 @@ function enableButtons(selector) { function disableButtonsIfNoCheckedRows() { let buttons = 'button[name="action"]'; let deletelink = 'a#delete-collections-link' - let checkedboxes = document.querySelectorAll(ROW_SELECTOR_PREFIX + ":not(.hidden) input[type=checkbox]:checked"); + let checkedboxes = document.querySelectorAll(CHECKBOX_SELECTOR + ":checked"); if (checkedboxes.length == 0) { disableButtons(buttons); disableButtons(deletelink); @@ -143,7 +144,7 @@ ready(function() { if (selectAll) { selectAll.style.cursor = "pointer"; selectAll.addEventListener("click", function() { - let checkboxes = document.querySelectorAll(ROW_SELECTOR_PREFIX + ":not(.hidden) input[type=checkbox]"); + let checkboxes = document.querySelectorAll(CHECKBOX_SELECTOR); for (let i = 0; i < checkboxes.length; i++) { checkboxes[i].checked = true; } @@ -155,7 +156,7 @@ ready(function() { if (selectNone) { selectNone.style.cursor = "pointer"; selectNone.addEventListener("click", function() { - let checkboxes = document.querySelectorAll(ROW_SELECTOR_PREFIX + ":not(.hidden) input[type=checkbox]"); + let checkboxes = document.querySelectorAll(CHECKBOX_SELECTOR); for (let i = 0; i < checkboxes.length; i++) { checkboxes[i].checked = false; } @@ -167,7 +168,7 @@ ready(function() { if (selectUnread) { selectUnread.style.cursor = "pointer"; selectUnread.addEventListener("click", function() { - let checkboxes = document.querySelectorAll(ROW_SELECTOR_PREFIX + " input[type='checkbox']:not(.hidden)"); + let checkboxes = document.querySelectorAll(CHECKBOX_SELECTOR); for (let i = 0; i < checkboxes.length; i++) { if (checkboxes[i].classList.contains("unread-cb")) { checkboxes[i].checked = true; @@ -178,7 +179,7 @@ ready(function() { }); } - let checkboxes = document.querySelectorAll(ROW_SELECTOR_PREFIX + ":not(.hidden) input[type=checkbox]"); + let checkboxes = document.querySelectorAll(CHECKBOX_SELECTOR); for (let i = 0; i < checkboxes.length; i++) { checkboxes[i].addEventListener("click", disableButtonsIfNoCheckedRows); }