mirror of
https://github.com/pi-hole/web.git
synced 2025-12-20 10:48:26 +00:00
Fix error displaying when editing groups/clients/domains/lists (#2808)
This commit is contained in:
@@ -81,6 +81,7 @@ mg.include('scripts/pi-hole/lua/header_authenticated.lp','r')
|
|||||||
|
|
||||||
<script src="<?=pihole.fileversion('scripts/vendor/bootstrap-select.min.js')?>"></script>
|
<script src="<?=pihole.fileversion('scripts/vendor/bootstrap-select.min.js')?>"></script>
|
||||||
<script src="<?=pihole.fileversion('scripts/vendor/bootstrap-toggle.min.js')?>"></script>
|
<script src="<?=pihole.fileversion('scripts/vendor/bootstrap-toggle.min.js')?>"></script>
|
||||||
|
<script src="<?=pihole.fileversion('scripts/pi-hole/js/groups-common.js')?>"></script>
|
||||||
<script src="<?=pihole.fileversion('scripts/pi-hole/js/groups.js')?>"></script>
|
<script src="<?=pihole.fileversion('scripts/pi-hole/js/groups.js')?>"></script>
|
||||||
|
|
||||||
<? mg.include('scripts/pi-hole/lua/footer.lp','r')?>
|
<? mg.include('scripts/pi-hole/lua/footer.lp','r')?>
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
* This file is copyright under the latest version of the EUPL.
|
* This file is copyright under the latest version of the EUPL.
|
||||||
* Please see LICENSE file for your rights under this license. */
|
* Please see LICENSE file for your rights under this license. */
|
||||||
|
|
||||||
/* global utils:false, groups:false,, apiFailure:false, updateFtlInfo:false, getGroups:false */
|
/* global utils:false, groups:false,, apiFailure:false, updateFtlInfo:false, getGroups:false, processGroupResult:false */
|
||||||
|
|
||||||
var table;
|
var table;
|
||||||
|
|
||||||
@@ -489,6 +489,16 @@ function editClient() {
|
|||||||
var done = "edited";
|
var done = "edited";
|
||||||
var notDone = "editing";
|
var notDone = "editing";
|
||||||
switch (elem) {
|
switch (elem) {
|
||||||
|
case "enabled_" + client:
|
||||||
|
if (!enabled) {
|
||||||
|
done = "disabled";
|
||||||
|
notDone = "disabling";
|
||||||
|
} else {
|
||||||
|
done = "enabled";
|
||||||
|
notDone = "enabling";
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
case "multiselect_" + client:
|
case "multiselect_" + client:
|
||||||
done = "edited groups of";
|
done = "edited groups of";
|
||||||
notDone = "editing groups of";
|
notDone = "editing groups of";
|
||||||
@@ -516,14 +526,9 @@ function editClient() {
|
|||||||
comment: comment,
|
comment: comment,
|
||||||
enabled: enabled,
|
enabled: enabled,
|
||||||
}),
|
}),
|
||||||
success: function () {
|
success: function (data) {
|
||||||
utils.enableAll();
|
utils.enableAll();
|
||||||
utils.showAlert(
|
processGroupResult(data, "client", done, notDone);
|
||||||
"success",
|
|
||||||
"fas fa-pencil-alt",
|
|
||||||
"Successfully " + done + " client",
|
|
||||||
clientDecoded
|
|
||||||
);
|
|
||||||
table.ajax.reload(null, false);
|
table.ajax.reload(null, false);
|
||||||
},
|
},
|
||||||
error: function (data, exception) {
|
error: function (data, exception) {
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
* This file is copyright under the latest version of the EUPL.
|
* This file is copyright under the latest version of the EUPL.
|
||||||
* Please see LICENSE file for your rights under this license. */
|
* Please see LICENSE file for your rights under this license. */
|
||||||
|
|
||||||
/* global apiFailure:false */
|
/* global apiFailure:false, utils:false */
|
||||||
|
|
||||||
// eslint-disable-next-line no-unused-vars
|
// eslint-disable-next-line no-unused-vars
|
||||||
var groups = [];
|
var groups = [];
|
||||||
@@ -24,3 +24,21 @@ function getGroups() {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// eslint-disable-next-line no-unused-vars
|
||||||
|
function processGroupResult(data, type, done, notDone) {
|
||||||
|
// Loop over data.processed.success and show toasts
|
||||||
|
data.processed.success.forEach(function (item) {
|
||||||
|
utils.showAlert("success", "fas fa-pencil-alt", `Successfully ${done} ${type}`, item);
|
||||||
|
});
|
||||||
|
// Loop over errors and display them
|
||||||
|
data.processed.errors.forEach(function (error) {
|
||||||
|
console.log(error); // eslint-disable-line no-console
|
||||||
|
utils.showAlert(
|
||||||
|
"error",
|
||||||
|
"",
|
||||||
|
`Error while ${notDone} ${type} ${utils.escapeHtml(error.item)}`,
|
||||||
|
error.error
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
* This file is copyright under the latest version of the EUPL.
|
* This file is copyright under the latest version of the EUPL.
|
||||||
* Please see LICENSE file for your rights under this license. */
|
* Please see LICENSE file for your rights under this license. */
|
||||||
|
|
||||||
/* global utils:false, groups:false,, getGroups:false, updateFtlInfo:false, apiFailure:false */
|
/* global utils:false, groups:false,, getGroups:false, updateFtlInfo:false, apiFailure:false, processGroupResult:false */
|
||||||
|
|
||||||
var table;
|
var table;
|
||||||
var GETDict = {};
|
var GETDict = {};
|
||||||
@@ -13,6 +13,7 @@ var GETDict = {};
|
|||||||
$(function () {
|
$(function () {
|
||||||
GETDict = utils.parseQueryString();
|
GETDict = utils.parseQueryString();
|
||||||
|
|
||||||
|
// Tabs: Domain/Regex handling
|
||||||
// sync description fields, reset inactive inputs on tab change
|
// sync description fields, reset inactive inputs on tab change
|
||||||
$('a[data-toggle="tab"]').on("shown.bs.tab", function () {
|
$('a[data-toggle="tab"]').on("shown.bs.tab", function () {
|
||||||
var tabHref = $(this).attr("href");
|
var tabHref = $(this).attr("href");
|
||||||
@@ -34,6 +35,7 @@ $(function () {
|
|||||||
|
|
||||||
$("#add_deny, #add_allow").on("click", addDomain);
|
$("#add_deny, #add_allow").on("click", addDomain);
|
||||||
|
|
||||||
|
// Domain suggestion handling
|
||||||
var suggestTimeout;
|
var suggestTimeout;
|
||||||
$("#new_domain").on("input", function (e) {
|
$("#new_domain").on("input", function (e) {
|
||||||
hideSuggestDomains();
|
hideSuggestDomains();
|
||||||
@@ -45,6 +47,7 @@ $(function () {
|
|||||||
initTable();
|
initTable();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Show a list of suggested domains based on the user's input
|
||||||
function showSuggestDomains(value) {
|
function showSuggestDomains(value) {
|
||||||
function createButton(hostname) {
|
function createButton(hostname) {
|
||||||
// Purposefully omit 'btn' class to save space on padding
|
// Purposefully omit 'btn' class to save space on padding
|
||||||
@@ -134,8 +137,9 @@ function initTable() {
|
|||||||
$("body > .bootstrap-select.dropdown").remove();
|
$("body > .bootstrap-select.dropdown").remove();
|
||||||
},
|
},
|
||||||
rowCallback: function (row, data) {
|
rowCallback: function (row, data) {
|
||||||
var dataId = utils.hexEncode(data.domain);
|
var dataId = utils.hexEncode(data.domain) + "_" + data.type + "_" + data.kind;
|
||||||
$(row).attr("data-id", dataId);
|
$(row).attr("data-id", dataId);
|
||||||
|
// Tooltip for domain
|
||||||
var tooltip =
|
var tooltip =
|
||||||
"Added: " +
|
"Added: " +
|
||||||
utils.datetime(data.date_added, false) +
|
utils.datetime(data.date_added, false) +
|
||||||
@@ -182,6 +186,7 @@ function initTable() {
|
|||||||
var typeEl = $("#type_" + dataId, row);
|
var typeEl = $("#type_" + dataId, row);
|
||||||
typeEl.on("change", editDomain);
|
typeEl.on("change", editDomain);
|
||||||
|
|
||||||
|
// Initialize bootstrap-toggle for status field (enabled/disabled)
|
||||||
$("td:eq(3)", row).html(
|
$("td:eq(3)", row).html(
|
||||||
'<input type="checkbox" id="enabled_' +
|
'<input type="checkbox" id="enabled_' +
|
||||||
dataId +
|
dataId +
|
||||||
@@ -199,12 +204,13 @@ function initTable() {
|
|||||||
});
|
});
|
||||||
statusEl.on("change", editDomain);
|
statusEl.on("change", editDomain);
|
||||||
|
|
||||||
|
// Comment field
|
||||||
$("td:eq(4)", row).html('<input id="comment_' + dataId + '" class="form-control">');
|
$("td:eq(4)", row).html('<input id="comment_' + dataId + '" class="form-control">');
|
||||||
var commentEl = $("#comment_" + dataId, row);
|
var commentEl = $("#comment_" + dataId, row);
|
||||||
commentEl.val(utils.unescapeHtml(data.comment));
|
commentEl.val(utils.unescapeHtml(data.comment));
|
||||||
commentEl.on("change", editDomain);
|
commentEl.on("change", editDomain);
|
||||||
|
|
||||||
// Group assignment field
|
// Group assignment field (multi-select)
|
||||||
$("td:eq(5)", row).empty();
|
$("td:eq(5)", row).empty();
|
||||||
$("td:eq(5)", row).append(
|
$("td:eq(5)", row).append(
|
||||||
'<select class="selectpicker" id="multiselect_' + dataId + '" multiple></select>'
|
'<select class="selectpicker" id="multiselect_' + dataId + '" multiple></select>'
|
||||||
@@ -227,6 +233,7 @@ function initTable() {
|
|||||||
// Select assigned groups
|
// Select assigned groups
|
||||||
selectEl.val(data.groups);
|
selectEl.val(data.groups);
|
||||||
// Initialize bootstrap-select
|
// Initialize bootstrap-select
|
||||||
|
const applyBtn = "#btn_apply_" + dataId;
|
||||||
selectEl
|
selectEl
|
||||||
// fix dropdown if it would stick out right of the viewport
|
// fix dropdown if it would stick out right of the viewport
|
||||||
.on("show.bs.select", function () {
|
.on("show.bs.select", function () {
|
||||||
@@ -242,7 +249,8 @@ function initTable() {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
.on("changed.bs.select", function () {
|
.on("changed.bs.select", function () {
|
||||||
// enable Apply button
|
// enable Apply button if changes were made to the drop-down menu
|
||||||
|
// and have it call editDomain() on click
|
||||||
if ($(applyBtn).prop("disabled")) {
|
if ($(applyBtn).prop("disabled")) {
|
||||||
$(applyBtn)
|
$(applyBtn)
|
||||||
.addClass("btn-success")
|
.addClass("btn-success")
|
||||||
@@ -253,7 +261,9 @@ function initTable() {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
.on("hide.bs.select", function () {
|
.on("hide.bs.select", function () {
|
||||||
// Restore values if drop-down menu is closed without clicking the Apply button
|
// Restore values if drop-down menu is closed without clicking the
|
||||||
|
// Apply button (e.g. by clicking outside) and re-disable the Apply
|
||||||
|
// button
|
||||||
if (!$(applyBtn).prop("disabled")) {
|
if (!$(applyBtn).prop("disabled")) {
|
||||||
$(this).val(data.groups).selectpicker("refresh");
|
$(this).val(data.groups).selectpicker("refresh");
|
||||||
$(applyBtn).removeClass("btn-success").prop("disabled", true).off("click");
|
$(applyBtn).removeClass("btn-success").prop("disabled", true).off("click");
|
||||||
@@ -268,8 +278,6 @@ function initTable() {
|
|||||||
' class="btn btn-block btn-sm" disabled>Apply</button>'
|
' class="btn btn-block btn-sm" disabled>Apply</button>'
|
||||||
);
|
);
|
||||||
|
|
||||||
var applyBtn = "#btn_apply_" + dataId;
|
|
||||||
|
|
||||||
// Highlight row (if url parameter "domainid=" is used)
|
// Highlight row (if url parameter "domainid=" is used)
|
||||||
if ("domainid" in GETDict && data.id === parseInt(GETDict.domainid, 10)) {
|
if ("domainid" in GETDict && data.id === parseInt(GETDict.domainid, 10)) {
|
||||||
$(row).find("td").addClass("highlight");
|
$(row).find("td").addClass("highlight");
|
||||||
@@ -288,7 +296,7 @@ function initTable() {
|
|||||||
},
|
},
|
||||||
select: {
|
select: {
|
||||||
style: "multi",
|
style: "multi",
|
||||||
selector: "td:not(:last-child)",
|
selector: "td:first-child",
|
||||||
info: false,
|
info: false,
|
||||||
},
|
},
|
||||||
buttons: [
|
buttons: [
|
||||||
@@ -433,7 +441,7 @@ function delItems(ids) {
|
|||||||
|
|
||||||
// Get first element from array
|
// Get first element from array
|
||||||
const domainRaw = ids[0];
|
const domainRaw = ids[0];
|
||||||
const domain = utils.hexDecode(domainRaw);
|
const domain = utils.hexDecode(domainRaw.split("_")[0]);
|
||||||
const typestr = $("#old_type_" + domainRaw).val();
|
const typestr = $("#old_type_" + domainRaw).val();
|
||||||
|
|
||||||
// Remove first element from array
|
// Remove first element from array
|
||||||
@@ -449,7 +457,7 @@ function delItems(ids) {
|
|||||||
})
|
})
|
||||||
.done(function () {
|
.done(function () {
|
||||||
utils.enableAll();
|
utils.enableAll();
|
||||||
utils.showAlert("success", "far fa-trash-alt", "Successfully deleted list: ", domain);
|
utils.showAlert("success", "far fa-trash-alt", "Successfully deleted domain: ", domain);
|
||||||
table.row(domainRaw).remove().draw(false);
|
table.row(domainRaw).remove().draw(false);
|
||||||
if (ids.length > 0) {
|
if (ids.length > 0) {
|
||||||
// Recursively delete all remaining items
|
// Recursively delete all remaining items
|
||||||
@@ -581,7 +589,7 @@ function editDomain() {
|
|||||||
var notDone = "editing";
|
var notDone = "editing";
|
||||||
switch (elem) {
|
switch (elem) {
|
||||||
case "enabled_" + domain:
|
case "enabled_" + domain:
|
||||||
if (enabled) {
|
if (!enabled) {
|
||||||
done = "disabled";
|
done = "disabled";
|
||||||
notDone = "disabling";
|
notDone = "disabling";
|
||||||
} else {
|
} else {
|
||||||
@@ -612,7 +620,7 @@ function editDomain() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
utils.disableAll();
|
utils.disableAll();
|
||||||
const domainDecoded = utils.hexDecode(domain);
|
const domainDecoded = utils.hexDecode(domain.split("_")[0]);
|
||||||
utils.showAlert("info", "", "Editing domain...", domain);
|
utils.showAlert("info", "", "Editing domain...", domain);
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url: "/api/domains/" + newTypestr + "/" + encodeURIComponent(domainDecoded),
|
url: "/api/domains/" + newTypestr + "/" + encodeURIComponent(domainDecoded),
|
||||||
@@ -626,14 +634,9 @@ function editDomain() {
|
|||||||
type: oldType,
|
type: oldType,
|
||||||
kind: oldKind,
|
kind: oldKind,
|
||||||
}),
|
}),
|
||||||
success: function () {
|
success: function (data) {
|
||||||
utils.enableAll();
|
utils.enableAll();
|
||||||
utils.showAlert(
|
processGroupResult(data, "domain", done, notDone);
|
||||||
"success",
|
|
||||||
"fas fa-pencil-alt",
|
|
||||||
"Successfully " + done + " domain",
|
|
||||||
domainDecoded
|
|
||||||
);
|
|
||||||
table.ajax.reload(null, false);
|
table.ajax.reload(null, false);
|
||||||
},
|
},
|
||||||
error: function (data, exception) {
|
error: function (data, exception) {
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
* This file is copyright under the latest version of the EUPL.
|
* This file is copyright under the latest version of the EUPL.
|
||||||
* Please see LICENSE file for your rights under this license. */
|
* Please see LICENSE file for your rights under this license. */
|
||||||
|
|
||||||
/* global utils:false, groups:false, apiFailure:false, updateFtlInfo:false, getGroups:false */
|
/* global utils:false, groups:false, apiFailure:false, updateFtlInfo:false, getGroups:false, processGroupResult:false */
|
||||||
|
|
||||||
var table;
|
var table;
|
||||||
var GETDict = {};
|
var GETDict = {};
|
||||||
@@ -549,20 +549,19 @@ function editList() {
|
|||||||
const tr = $(this).closest("tr");
|
const tr = $(this).closest("tr");
|
||||||
const type = tr.attr("data-type");
|
const type = tr.attr("data-type");
|
||||||
const address = tr.attr("data-id");
|
const address = tr.attr("data-id");
|
||||||
const status = tr.find("#enabled_" + address).is(":checked");
|
const enabled = tr.find("#enabled_" + address).is(":checked");
|
||||||
const comment = utils.escapeHtml(tr.find("#comment_" + address).val());
|
const comment = utils.escapeHtml(tr.find("#comment_" + address).val());
|
||||||
// Convert list of string integers to list of integers using map(Number)
|
// Convert list of string integers to list of integers using map(Number)
|
||||||
const groups = tr
|
const groups = tr
|
||||||
.find("#multiselect_" + address)
|
.find("#multiselect_" + address)
|
||||||
.val()
|
.val()
|
||||||
.map(Number);
|
.map(Number);
|
||||||
const enabled = tr.find("#enabled_" + address).is(":checked");
|
|
||||||
|
|
||||||
var done = "edited";
|
var done = "edited";
|
||||||
var notDone = "editing";
|
var notDone = "editing";
|
||||||
switch (elem) {
|
switch (elem) {
|
||||||
case "enabled_" + address:
|
case "enabled_" + address:
|
||||||
if (status) {
|
if (!enabled) {
|
||||||
done = "disabled";
|
done = "disabled";
|
||||||
notDone = "disabling";
|
notDone = "disabling";
|
||||||
} else {
|
} else {
|
||||||
@@ -598,14 +597,9 @@ function editList() {
|
|||||||
enabled: enabled,
|
enabled: enabled,
|
||||||
type: type,
|
type: type,
|
||||||
}),
|
}),
|
||||||
success: function () {
|
success: function (data) {
|
||||||
utils.enableAll();
|
utils.enableAll();
|
||||||
utils.showAlert(
|
processGroupResult(data, "list", done, notDone);
|
||||||
"success",
|
|
||||||
"fas fa-pencil-alt",
|
|
||||||
"Successfully " + done + " list",
|
|
||||||
addressDecoded
|
|
||||||
);
|
|
||||||
table.ajax.reload(null, false);
|
table.ajax.reload(null, false);
|
||||||
},
|
},
|
||||||
error: function (data, exception) {
|
error: function (data, exception) {
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
* This file is copyright under the latest version of the EUPL.
|
* This file is copyright under the latest version of the EUPL.
|
||||||
* Please see LICENSE file for your rights under this license. */
|
* Please see LICENSE file for your rights under this license. */
|
||||||
|
|
||||||
/* global utils:false, apiFailure:false, updateFtlInfo:false */
|
/* global utils:false, apiFailure:false, updateFtlInfo:false, processGroupResult:false */
|
||||||
|
|
||||||
var table,
|
var table,
|
||||||
idNames = {};
|
idNames = {};
|
||||||
@@ -344,10 +344,10 @@ function editGroup() {
|
|||||||
var notDone = "editing";
|
var notDone = "editing";
|
||||||
switch (elem) {
|
switch (elem) {
|
||||||
case "enabled_" + id:
|
case "enabled_" + id:
|
||||||
if (enabled === false) {
|
if (!enabled) {
|
||||||
done = "disabled";
|
done = "disabled";
|
||||||
notDone = "disabling";
|
notDone = "disabling";
|
||||||
} else if (enabled === true) {
|
} else {
|
||||||
done = "enabled";
|
done = "enabled";
|
||||||
notDone = "enabling";
|
notDone = "enabling";
|
||||||
}
|
}
|
||||||
@@ -378,9 +378,10 @@ function editGroup() {
|
|||||||
comment: comment,
|
comment: comment,
|
||||||
enabled: enabled,
|
enabled: enabled,
|
||||||
}),
|
}),
|
||||||
success: function () {
|
success: function (data) {
|
||||||
utils.enableAll();
|
utils.enableAll();
|
||||||
utils.showAlert("success", "fas fa-pencil-alt", "Successfully " + done + " group", oldName);
|
processGroupResult(data, "group", done, notDone);
|
||||||
|
table.ajax.reload(null, false);
|
||||||
},
|
},
|
||||||
error: function (data, exception) {
|
error: function (data, exception) {
|
||||||
apiFailure(data);
|
apiFailure(data);
|
||||||
|
|||||||
@@ -113,6 +113,7 @@ function showAlert(type, icon, title, message) {
|
|||||||
break;
|
break;
|
||||||
case "error":
|
case "error":
|
||||||
options.icon = "fas fa-times";
|
options.icon = "fas fa-times";
|
||||||
|
if (title.length === 0)
|
||||||
options.title = " <strong>Error, something went wrong!</strong><br>";
|
options.title = " <strong>Error, something went wrong!</strong><br>";
|
||||||
settings.delay *= 2;
|
settings.delay *= 2;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user