From 0f58fbfb969d4645dee0dcfdc8fec755be197ef3 Mon Sep 17 00:00:00 2001 From: RD WebDesign Date: Mon, 27 Nov 2023 02:48:18 -0300 Subject: [PATCH 1/4] Tweak the lists user interface, specially the icons - add a new column for list type; - separate status and type icons; - move the code responsible for the icons to dedicated functions; - use the same icons for block/allow everywhere; - use the same style (solid circle) for every status icon (except history). Signed-off-by: RD WebDesign --- groups-lists.lp | 1 + scripts/pi-hole/js/groups-lists.js | 97 +++++++++++++++++------------- style/pi-hole.css | 1 + 3 files changed, 56 insertions(+), 43 deletions(-) diff --git a/groups-lists.lp b/groups-lists.lp index 7671a5db..8aee83ba 100644 --- a/groups-lists.lp +++ b/groups-lists.lp @@ -73,6 +73,7 @@ mg.include('scripts/pi-hole/lua/header_authenticated.lp','r') ID + Address Status Comment diff --git a/scripts/pi-hole/js/groups-lists.js b/scripts/pi-hole/js/groups-lists.js index 44aceb35..e9fe5626 100644 --- a/scripts/pi-hole/js/groups-lists.js +++ b/scripts/pi-hole/js/groups-lists.js @@ -62,6 +62,7 @@ function format(data) { return ( "" + '
Type of this list:' + + setTypeIcon(data.type) + data.type + 'list
Health status of this list:' + statusText + @@ -99,6 +100,46 @@ function format(data) { ); } +// Define the status icon element +function setStatusIcon(statusCode) { + var statusIcon; + + switch (statusCode) { + case 1: + statusIcon = "fa-check-circle"; + break; + case 2: + statusIcon = "fa-history"; + break; + case 3: + statusIcon = "fa-exclamation-circle"; + break; + case 4: + statusIcon = "fa-times-circle"; + break; + default: + statusIcon = "fa-question-circle"; + break; + } + + return ""; +} + +// Define the status icon element +function setTypeIcon(type) { + //Add red ban icon if data["type"] is "block" + //Add green check icon if data["type"] is "allow" + let typeIcon = + " "; + if (type === "block") { + typeIcon = " "; + } else if (type === "allow") { + typeIcon = " "; + } + + return typeIcon; +} + // eslint-disable-next-line no-unused-vars function initTable() { table = $("#listsTable").DataTable({ @@ -113,6 +154,7 @@ function initTable() { { data: "id", visible: false }, { data: null, visible: true, orderable: false, width: "15px" }, { data: "status", searchable: false, class: "details-control" }, + { data: "type", searchable: false, class: "details-control" }, { data: "address" }, { data: "enabled", searchable: false }, { data: "comment" }, @@ -146,54 +188,23 @@ function initTable() { $(row).attr("data-id", dataId); $(row).attr("data-type", data.type); - var statusCode = 0, - statusIcon; + var statusCode = 0; // If there is no status or the list is disabled, we keep // status 0 (== unknown) if (data.status !== null && data.enabled) { statusCode = parseInt(data.status, 10); } - switch (statusCode) { - case 1: - statusIcon = "fa-check"; - break; - case 2: - statusIcon = "fa-history"; - break; - case 3: - statusIcon = "fa-exclamation-circle"; - break; - case 4: - statusIcon = "fa-times"; - break; - default: - statusIcon = "fa-question-circle"; - break; - } - - // Add red minus sign icon if data["type"] is "block" - // Add green plus sign icon if data["type"] is "allow" - let status = - ""; - if (data.type === "block") { - status = ""; - } else if (data.type === "allow") { - status = ""; - } - $("td:eq(1)", row).addClass("list-status-" + statusCode); - $("td:eq(1)", row).html( - "" + - status - ); + $("td:eq(1)", row).html(setStatusIcon(statusCode)); + + $("td:eq(2)", row).addClass("list-type-" + statusCode); + $("td:eq(2)", row).html(setTypeIcon(data.type)); if (data.address.startsWith("file://")) { // Local files cannot be downloaded from a distant client so don't show // a link to such a list here - $("td:eq(2)", row).html( + $("td:eq(3)", row).html( '' + @@ -201,7 +212,7 @@ function initTable() { "" ); } else { - $("td:eq(2)", row).html( + $("td:eq(3)", row).html( ''); + $("td:eq(5)", row).html(''); var commentEl = $("#comment_" + dataId, row); commentEl.val(data.comment); commentEl.on("change", editList); - $("td:eq(5)", row).empty(); - $("td:eq(5)", row).append( + $("td:eq(6)", row).empty(); + $("td:eq(6)", row).append( '' ); var selectEl = $("#multiselect_" + dataId, row); @@ -312,7 +323,7 @@ function initTable() { '">' + '' + ""; - $("td:eq(6)", row).html(button); + $("td:eq(7)", row).html(button); }, dom: "<'row'<'col-sm-6'l><'col-sm-6'f>>" + diff --git a/style/pi-hole.css b/style/pi-hole.css index 1dceed62..e2e134ec 100644 --- a/style/pi-hole.css +++ b/style/pi-hole.css @@ -516,6 +516,7 @@ tfoot.add-new-item > tr > th { td.details-control { cursor: pointer; + text-align: center; } .dataTables-child td { From e69b7eaa81c9d9702513ff551e5299b91ec786ce Mon Sep 17 00:00:00 2001 From: RD WebDesign Date: Mon, 27 Nov 2023 18:23:06 -0300 Subject: [PATCH 2/4] Reduce concatenation using template literals Signed-off-by: RD WebDesign --- scripts/pi-hole/js/groups-lists.js | 88 +++++++++++++++++------------- 1 file changed, 49 insertions(+), 39 deletions(-) diff --git a/scripts/pi-hole/js/groups-lists.js b/scripts/pi-hole/js/groups-lists.js index e9fe5626..0c7f54aa 100644 --- a/scripts/pi-hole/js/groups-lists.js +++ b/scripts/pi-hole/js/groups-lists.js @@ -59,45 +59,55 @@ function format(data) { } // Compile extra info for displaying - return ( - "" + - '" + - "
Type of this list:' + - setTypeIcon(data.type) + - data.type + - 'list
Health status of this list:' + - statusText + - '
This list was added to Pi-hole  ' + - utils.datetimeRelative(data.date_added) + - " (" + - utils.datetime(data.date_added, false) + - ')
Database entry was last modified  ' + - utils.datetimeRelative(data.date_modified) + - " (" + - utils.datetime(data.date_modified, false) + - ')
The list contents were last updated  ' + - (data.date_updated > 0 - ? utils.datetimeRelative(data.date_updated) + - " (" + - utils.datetime(data.date_updated, false) + - ")" - : "N/A") + - '
Number of entries on this list:  ' + - (data.number !== null && numbers === true - ? parseInt(data.number, 10).toLocaleString() - : "N/A") + - (data.abp_entries !== null && parseInt(data.abp_entries, 10) > 0 && numbers === true - ? " (out of which " + parseInt(data.abp_entries, 10).toLocaleString() + " are in ABP-style)" - : "") + - '
Number of non-domains on this list:  " + - (data.invalid_domains !== null && numbers === true - ? parseInt(data.invalid_domains, 10).toLocaleString() - : "N/A") + - '
Database ID of this list:' + - data.id + - "
" - ); + var dateAddedISO = utils.datetime(data.date_added, false), + dateModifiedISO = utils.datetime(data.date_modified, false), + dateUpdated = + data.date_updated > 0 + ? utils.datetimeRelative(data.date_updated) + + " (" + + utils.datetime(data.date_updated, false) + + ")" + : "N/A", + numberOfEntries = + (data.number !== null && numbers === true + ? parseInt(data.number, 10).toLocaleString() + : "N/A") + + (data.abp_entries !== null && parseInt(data.abp_entries, 10) > 0 && numbers === true + ? " (out of which " + parseInt(data.abp_entries, 10).toLocaleString() + " are in ABP-style)" + : ""), + nonDomains = + data.invalid_domains !== null && numbers === true + ? parseInt(data.invalid_domains, 10).toLocaleString() + : "N/A"; + + return ` + + + + + + + + + + + + + + + + + + + + + + + + + + +
Type of this list:${setTypeIcon(data.type)}${data.type}list
Health status of this list:${statusText}
This list was added to Pi-hole  ${utils.datetimeRelative(data.date_added)} (${dateAddedISO})
Database entry was last modified  ${utils.datetimeRelative(data.date_modified)} (${dateModifiedISO})
The list contents were last updated  ${dateUpdated}
Number of entries on this list:  ${numberOfEntries}
Number of non-domains on this list:  ${nonDomains}
Database ID of this list:${data.id}
`; } // Define the status icon element From 44bc14d38e09727034d01bdf5b077afc20d0886e Mon Sep 17 00:00:00 2001 From: RD WebDesign Date: Mon, 27 Nov 2023 18:29:36 -0300 Subject: [PATCH 3/4] Move status text definition to a dedicated function Signed-off-by: RD WebDesign --- scripts/pi-hole/js/groups-lists.js | 75 +++++++++++++++++------------- 1 file changed, 43 insertions(+), 32 deletions(-) diff --git a/scripts/pi-hole/js/groups-lists.js b/scripts/pi-hole/js/groups-lists.js index 0c7f54aa..5caef0f0 100644 --- a/scripts/pi-hole/js/groups-lists.js +++ b/scripts/pi-hole/js/groups-lists.js @@ -23,39 +23,10 @@ $(function () { function format(data) { // Generate human-friendly status string - var statusText = "Unknown"; + var statusText = setStatusText(data, true); var numbers = true; - if (data.status !== null) { - switch (parseInt(data.status, 10)) { - case 0: - statusText = - data.enabled === 0 - ? "List is disabled and not checked" - : "List was not downloaded so far"; - numbers = false; - break; - case 1: - statusText = 'List download was successful (OK)'; - break; - case 2: - statusText = - 'List unchanged upstream, Pi-hole used a local copy (OK)'; - break; - case 3: - statusText = - 'List unavailable, Pi-hole used a local copy (check list)'; - break; - case 4: - statusText = - 'List unavailable, there is no local copy of this list available on your Pi-hole (replace list)'; - numbers = false; - break; - - default: - statusText = - 'Unknown (' + parseInt(data.status, 10) + ")"; - break; - } + if (data.status === 0 || data.status === 4) { + numbers = false; } // Compile extra info for displaying @@ -135,6 +106,46 @@ function setStatusIcon(statusCode) { return ""; } +// Define human-friendly status string +function setStatusText(data, showdetails = false) { + var statusText = "Unknown", + statusDetails = ""; + if (data.status !== null) { + switch (parseInt(data.status, 10)) { + case 0: + statusText = + data.enabled === 0 + ? "List is disabled and not checked" + : "List was not downloaded so far"; + break; + case 1: + statusText = "List download was successful"; + statusDetails = ' (OK)'; + break; + case 2: + statusText = "List unchanged upstream, Pi-hole used a local copy"; + statusDetails = ' (OK)'; + break; + case 3: + statusText = "List unavailable, Pi-hole used a local copy"; + statusDetails = ' (check list)'; + break; + case 4: + statusText = + "List unavailable, there is no local copy of this list available on your Pi-hole"; + statusDetails = ' (replace list)'; + break; + + default: + statusText = "Unknown"; + statusDetails = ' (' + parseInt(data.status, 10) + ")"; + break; + } + } + + return statusText + (showdetails === true ? statusDetails : ""); +} + // Define the status icon element function setTypeIcon(type) { //Add red ban icon if data["type"] is "block" From a14972f05598fe53114f658052bfbec1dad3bb87 Mon Sep 17 00:00:00 2001 From: RD WebDesign Date: Mon, 27 Nov 2023 18:32:56 -0300 Subject: [PATCH 4/4] Use the status text as part of the icon tooltip Signed-off-by: RD WebDesign --- scripts/pi-hole/js/groups-lists.js | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/scripts/pi-hole/js/groups-lists.js b/scripts/pi-hole/js/groups-lists.js index 5caef0f0..7c29048c 100644 --- a/scripts/pi-hole/js/groups-lists.js +++ b/scripts/pi-hole/js/groups-lists.js @@ -82,8 +82,10 @@ function format(data) { } // Define the status icon element -function setStatusIcon(statusCode) { - var statusIcon; +function setStatusIcon(data) { + var statusCode = parseInt(data.status, 10), + statusTitle = setStatusText(data) + "\nClick for details about this list", + statusIcon; switch (statusCode) { case 1: @@ -103,7 +105,7 @@ function setStatusIcon(statusCode) { break; } - return ""; + return ""; } // Define human-friendly status string @@ -146,19 +148,21 @@ function setStatusText(data, showdetails = false) { return statusText + (showdetails === true ? statusDetails : ""); } -// Define the status icon element +// Define the type icon element function setTypeIcon(type) { //Add red ban icon if data["type"] is "block" //Add green check icon if data["type"] is "allow" - let typeIcon = - " "; + let iconClass = "fa-question text-orange", + title = "This list is of unknown type"; if (type === "block") { - typeIcon = " "; + iconClass = "fa-ban text-red"; + title = "This is a blocklist"; } else if (type === "allow") { - typeIcon = " "; + iconClass = "fa-check text-green"; + title = "This is an allowlist"; } - return typeIcon; + return ` `; } // eslint-disable-next-line no-unused-vars @@ -217,7 +221,7 @@ function initTable() { } $("td:eq(1)", row).addClass("list-status-" + statusCode); - $("td:eq(1)", row).html(setStatusIcon(statusCode)); + $("td:eq(1)", row).html(setStatusIcon(data)); $("td:eq(2)", row).addClass("list-type-" + statusCode); $("td:eq(2)", row).html(setTypeIcon(data.type));