Simplify domain management by using the same page for both locations where domains can be edited. This removes a large amount of duplicated code, each prone to its own bugs.

Signed-off-by: DL6ER <dl6er@dl6er.de>
This commit is contained in:
DL6ER
2020-02-14 20:21:01 +01:00
parent 843e46d84a
commit 2d975b8bac
9 changed files with 98 additions and 629 deletions

View File

@@ -11,6 +11,7 @@ var table;
var groups = [];
var token = $("#token").html();
var GETDict = {};
var showtype = "all";
function get_groups() {
$.post(
@@ -32,6 +33,10 @@ $(document).ready(function() {
GETDict[item.split("=")[0]] = item.split("=")[1];
});
if ("type" in GETDict && (GETDict.type === "white" || GETDict.type === "black")) {
showtype = GETDict.type;
}
$("#btnAdd").on("click", addDomain);
get_groups();
@@ -46,7 +51,7 @@ function initTable() {
table = $("#domainsTable").DataTable({
ajax: {
url: "scripts/pi-hole/php/groups.php",
data: { action: "get_domains", token: token },
data: { action: "get_domains", showtype: showtype, token: token },
type: "POST"
},
order: [[0, "asc"]],
@@ -74,20 +79,32 @@ function initTable() {
'<code id="domain" title="' + tooltip + '">' + data.domain + "</code>"
);
$("td:eq(1)", row).html(
'<select id="type" class="form-control">' +
var whitelist_options = "";
if (showtype === "all" || showtype === "white") {
whitelist_options =
'<option value="0"' +
(data.type === 0 ? " selected" : "") +
">Exact whitelist</option>" +
'<option value="1"' +
(data.type === 1 ? " selected" : "") +
">Exact blacklist</option>" +
'<option value="2"' +
(data.type === 2 ? " selected" : "") +
">Regex whitelist</option>" +
">Regex whitelist</option>";
}
var blacklist_options = "";
if (showtype === "all" || showtype === "black") {
blacklist_options =
'<option value="1"' +
(data.type === 1 ? " selected " : " ") +
">Exact blacklist</option>" +
'<option value="3"' +
(data.type === 3 ? " selected" : "") +
">Regex blacklist</option>" +
">Regex blacklist</option>";
}
$("td:eq(1)", row).html(
'<select id="type" class="form-control">' +
whitelist_options +
blacklist_options +
"</select>"
);
$("#type", row).on("change", editDomain);
@@ -113,21 +130,30 @@ function initTable() {
$("#comment", row).val(data.comment);
$("#comment", row).on("change", editDomain);
$("td:eq(4)", row).empty();
$("td:eq(4)", row).append('<select id="multiselect" multiple="multiple"></select>');
var sel = $("#multiselect", row);
// Add all known groups
for (var i = 0; i < groups.length; i++) {
var extra = "";
if (!groups[i].enabled) {
extra = " (disabled)";
// Show group assignment field only if in full domain management mode
if (showtype === "all") {
$("td:eq(4)", row).empty();
$("td:eq(4)", row).append('<select id="multiselect" multiple="multiple"></select>');
var sel = $("#multiselect", row);
// Add all known groups
for (var i = 0; i < groups.length; i++) {
var extra = "";
if (!groups[i].enabled) {
extra = " (disabled)";
}
sel.append(
$("<option />")
.val(groups[i].id)
.text(groups[i].name + extra)
);
}
sel.append(
$("<option />")
.val(groups[i].id)
.text(groups[i].name + extra)
);
// Select assigned groups
sel.val(data.groups);
// Initialize multiselect
sel.multiselect({ includeSelectAllOption: true });
sel.on("change", editDomain);
}
// Highlight row
@@ -137,19 +163,17 @@ function initTable() {
.addClass("highlight");
}
// Select assigned groups
sel.val(data.groups);
// Initialize multiselect
sel.multiselect({ includeSelectAllOption: true });
sel.on("change", editDomain);
var button =
'<button class="btn btn-danger btn-xs deleteDomain" type="button" data-id="' +
data.id +
'">' +
'<span class="glyphicon glyphicon-trash"></span>' +
"</button>";
$("td:eq(5)", row).html(button);
if (showtype === "all") {
$("td:eq(5)", row).html(button);
} else {
$("td:eq(4)", row).html(button);
}
},
dom:
"<'row'<'col-sm-4'l><'col-sm-8'f>>" +
@@ -179,6 +203,8 @@ function initTable() {
data.search.search = "";
// Reset visibility of ID column
data.columns[0].visible = false;
// Show group assignment column only on full page
data.columns[5].visible = showtype === "all";
// Apply loaded state to table
return data;
},

View File

@@ -1,287 +0,0 @@
/* Pi-hole: A black hole for Internet advertisements
* (c) 2017 Pi-hole, LLC (https://pi-hole.net)
* Network-wide ad blocking via your own hardware.
*
* This file is copyright under the latest version of the EUPL.
* Please see LICENSE file for your rights under this license. */
// IE likes to cache too much :P
$.ajaxSetup({ cache: false });
// Get PHP info
var token = $("#token").text();
var listType = $("#list-type").html();
var fullName = listType === "white" ? "Whitelist" : "Blacklist";
function addListEntry(entry, index, list, button, type) {
var disabled = [];
if (entry.enabled === "0") disabled.push("individual");
// For entry.group_enabled we either get "0" (= disabled by a group),
// "1" (= enabled by a group), or "" (= not managed by a group)
if (entry.group_enabled === "0") disabled.push("group");
var used = disabled.length === 0 ? "used" : "not-used";
var comment = entry.comment.length > 0 ? "&nbsp;-&nbsp;" + entry.comment : "";
var disabled_message =
disabled.length > 0 ? "&nbsp;-&nbsp;disabled due to " + disabled.join(" + ") + " setting" : "";
var date_added = new Date(parseInt(entry.date_added) * 1000);
var date_modified = new Date(parseInt(entry.date_modified) * 1000);
var tooltip =
"Added: " + date_added.toLocaleString() + "\nModified: " + date_modified.toLocaleString();
list.append(
'<li id="' +
index +
'" class="list-group-item ' +
used +
' clearfix">' +
'<span title="' +
tooltip +
'" data-toggle="tooltip" data-placement="right">' +
entry.domain +
comment +
disabled_message +
"</span>" +
'<button class="btn btn-danger btn-xs pull-right" type="button">' +
'<span class="glyphicon glyphicon-trash"></span></button></li>'
);
// Handle button
$(button + " #" + index).on("click", "button", function() {
sub(index, entry.domain, type);
});
}
function refresh(fade) {
var list = $("#list");
var listw = $("#list-regex");
if (fade) {
list.fadeOut(100);
listw.fadeOut(100);
}
$.ajax({
url: "scripts/pi-hole/php/get.php",
method: "get",
data: { list: listType },
success: function(response) {
list.html("");
listw.html("");
if (
(listType === "black" &&
response.blacklist.length === 0 &&
response.regex_blacklist.length === 0) ||
(listType === "white" &&
response.whitelist.length === 0 &&
response.regex_whitelist.length === 0)
) {
$("h3").hide();
list.html(
'<div class="alert alert-info" role="alert">Your ' + fullName + " is empty!</div>"
);
} else {
var data, data2;
if (listType === "white") {
data = response.whitelist.sort();
data2 = response.regex_whitelist.sort();
} else if (listType === "black") {
data = response.blacklist.sort();
data2 = response.regex_blacklist.sort();
}
if (data.length > 0) {
$("#h3-exact").fadeIn(100);
}
if (data2.length > 0) {
$("#h3-regex").fadeIn(100);
}
data.forEach(function(entry, index) {
addListEntry(entry, index, list, "#list", "exact");
});
data2.forEach(function(entry, index) {
addListEntry(entry, index, listw, "#list-regex", listType + "_regex");
});
}
list.fadeIn(100);
listw.fadeIn(100);
},
error: function() {
$("#alFailure").show();
}
});
}
window.addEventListener("load", refresh(false));
function sub(index, entry, arg) {
var list = "#list";
var heading = "#h3-exact";
var locallistType = listType;
if (arg === "black_regex" || arg === "white_regex") {
list = "#list-regex";
heading = "#h3-regex";
locallistType = arg;
}
var alInfo = $("#alInfo");
var alSuccess = $("#alSuccess");
var alFailure = $("#alFailure");
var err = $("#err");
var msg = $("#success-message");
var domain = $(list + " #" + index);
domain.hide("highlight");
$.ajax({
url: "scripts/pi-hole/php/sub.php",
method: "post",
data: { domain: entry, list: locallistType, token: token },
success: function(response) {
if (response.indexOf("Success") === -1) {
alFailure.show();
err.html(response);
alFailure.delay(8000).fadeOut(2000, function() {
alFailure.hide();
});
alInfo.delay(8000).fadeOut(2000, function() {
alInfo.hide();
});
} else {
alSuccess.show();
msg.html(response);
alSuccess.delay(1000).fadeOut(2000, function() {
alSuccess.hide();
});
alInfo.delay(1000).fadeOut(2000, function() {
alInfo.hide();
});
domain.remove();
if ($(list + " li").length === 0) {
$(heading).fadeOut(100);
}
}
},
error: function() {
alert("Failed to remove the domain!");
domain.show({ queue: true });
}
});
}
function add(type) {
var domain = $("#domain");
if (domain.val().length === 0) {
return;
}
var comment = $("#comment");
var alInfo = $("#alInfo");
var alSuccess = $("#alSuccess");
var alFailure = $("#alFailure");
var alWarning = $("#alWarning");
var err = $("#err");
var msg = $("#success-message");
alInfo.show();
alSuccess.hide();
alFailure.hide();
alWarning.hide();
$.ajax({
url: "scripts/pi-hole/php/add.php",
method: "post",
data: { domain: domain.val().trim(), comment: comment.val(), list: type, token: token },
success: function(response) {
if (response.indexOf("Success") === -1) {
alFailure.show();
err.html(response);
alFailure.delay(8000).fadeOut(2000, function() {
alFailure.hide();
});
alInfo.delay(8000).fadeOut(2000, function() {
alInfo.hide();
});
} else {
alSuccess.show();
msg.html(response);
alSuccess.delay(1000).fadeOut(2000, function() {
alSuccess.hide();
});
alInfo.delay(1000).fadeOut(2000, function() {
alInfo.hide();
});
domain.val("");
comment.val("");
refresh(true);
}
},
error: function() {
alFailure.show();
err.html("");
alFailure.delay(1000).fadeOut(2000, function() {
alFailure.hide();
});
alInfo.delay(1000).fadeOut(2000, function() {
alInfo.hide();
});
}
});
}
// Handle enter button for adding domains
$(document).keypress(function(e) {
if (e.which === 13 && $("#domain,#comment").is(":focus")) {
// Enter was pressed, and the input has focus
add(listType);
}
});
// Handle buttons
$("#btnAdd").on("click", function() {
add(listType);
});
$("#btnAddWildcard").on("click", function() {
add(listType + "_wild");
});
$("#btnAddRegex").on("click", function() {
add(listType + "_regex");
});
$("#btnRefresh").on("click", function() {
refresh(true);
});
// Handle hiding of alerts
$(function() {
$("[data-hide]").on("click", function() {
$(this)
.closest("." + $(this).attr("data-hide"))
.hide();
});
});
// Wrap form-group's buttons to next line when viewed on a small screen
$(window).on("resize", function() {
if ($(window).width() < 991) {
$(".form-group.input-group")
.removeClass("input-group")
.addClass("input-group-block");
$(".form-group.input-group-block > input").css("margin-bottom", "5px");
$(".form-group.input-group-block > .input-group-btn")
.removeClass("input-group-btn")
.addClass("btn-block text-center");
} else {
$(".form-group.input-group-block")
.removeClass("input-group-block")
.addClass("input-group");
$(".form-group.input-group > input").css("margin-bottom", "");
$(".form-group.input-group > .btn-block.text-center")
.removeClass("btn-block text-center")
.addClass("input-group-btn");
}
});
$(document).ready(function() {
$(window).trigger("resize");
});