commit 02b8285: [WebUI] Add column display mode settings
moisseev
moiseev at mezonplus.ru
Mon Jul 29 17:54:31 UTC 2024
Author: moisseev
Date: 2024-03-16 14:08:56 +0300
URL: https://github.com/rspamd/rspamd/commit/02b82858aa48ba25fb9db236e167c9c757e87e2b (refs/pull/4877/head)
[WebUI] Add column display mode settings
for Scan and History tables
---
interface/index.html | 9 ++++
interface/js/app/history.js | 3 +-
interface/js/app/libft.js | 110 +++++++++++++++++++++++++++++++++++++++++++-
interface/js/app/upload.js | 5 +-
4 files changed, 123 insertions(+), 4 deletions(-)
diff --git a/interface/index.html b/interface/index.html
index 27865c611..5b3187309 100644
--- a/interface/index.html
+++ b/interface/index.html
@@ -537,6 +537,10 @@
</select>
<label for="scan_page_size" class="ms-2">Rows per page:</label>
<input id="scan_page_size" class="form-control ms-1" value="25" min="1" type="number">
+ <button class="btn btn-outline-secondary btn-sm ms-2 d-flex align-items-center dropdown-toggle ft-columns-btn" type="button" data-bs-toggle="dropdown" data-bs-auto-close="outside" aria-expanded="false" disabled>
+ <i class="fas fa-columns me-1"></i>Columns
+ </button>
+ <div class="dropdown-menu ft-columns-dropdown p-2"></div>
<button class="btn btn-secondary btn-sm ms-2 d-flex align-items-center" id="cleanScanHistory" disabled>
<i class="fas fa-trash-alt me-1"></i>Clean history
</button>
@@ -649,6 +653,11 @@
</select>
<label for="history_page_size" class="ms-2">Rows per page:</label>
<input id="history_page_size" class="form-control ms-1" value="25" min="1" type="number">
+ <button class="btn btn-outline-secondary btn-sm ms-2 d-flex align-items-center dropdown-toggle ft-columns-btn" type="button" data-bs-toggle="dropdown" data-bs-auto-close="outside" aria-expanded="false" disabled>
+ <i class="fas fa-columns me-1"></i>Columns
+ </button>
+ <div class="dropdown-menu ft-columns-dropdown p-2"></div>
+
<button class="btn btn-danger btn-sm ms-2 d-flex align-items-center ro-hide" id="resetHistory">
<i class="fas fa-times-circle me-1"></i>Reset
</button>
diff --git a/interface/js/app/history.js b/interface/js/app/history.js
index a429b21ca..e486c1060 100644
--- a/interface/js/app/history.js
+++ b/interface/js/app/history.js
@@ -192,7 +192,8 @@ define(["jquery", "app/common", "app/libft", "footable"],
// Is there a way to get an event when the table is destroyed?
setTimeout(() => {
libft.initHistoryTable(data, items, "history", get_history_columns(data), false,
- () => $("#refresh, #updateHistory").removeAttr("disabled"));
+ () => $("#refresh, #updateHistory, #history .ft-columns-dropdown .btn-dropdown-apply")
+ .removeAttr("disabled"));
}, 200);
}
prevVersion = version;
diff --git a/interface/js/app/libft.js b/interface/js/app/libft.js
index faf16489b..2b2428385 100644
--- a/interface/js/app/libft.js
+++ b/interface/js/app/libft.js
@@ -4,6 +4,7 @@ define(["jquery", "app/common", "footable"],
($, common) => {
"use strict";
const ui = {};
+ const columnsCustom = JSON.parse(localStorage.getItem("columns")) || {};
let pageSizeTimerId = null;
let pageSizeInvocationCounter = 0;
@@ -230,13 +231,15 @@ define(["jquery", "app/common", "footable"],
};
ui.destroyTable = function (table) {
+ $("#" + table + " .ft-columns-btn.show").trigger("click.bs.dropdown"); // Hide dropdown
+ $("#" + table + " .ft-columns-btn").attr("disabled", true);
if (common.tables[table]) {
common.tables[table].destroy();
delete common.tables[table];
}
};
- ui.initHistoryTable = function (data, items, table, columns, expandFirst, postdrawCallback) {
+ ui.initHistoryTable = function (data, items, table, columnsDefault, expandFirst, postdrawCallback) {
/* eslint-disable no-underscore-dangle */
FooTable.Cell.extend("collapse", function () {
// call the original method
@@ -318,6 +321,10 @@ define(["jquery", "app/common", "footable"],
});
/* eslint-enable consistent-this, no-underscore-dangle, one-var-declaration-per-line */
+ const columns = (table in columnsCustom)
+ ? columnsDefault.map((column) => $.extend({}, column, columnsCustom[table][column.name]))
+ : columnsDefault.map((column) => column);
+
common.tables[table] = FooTable.init("#historyTable_" + table, {
columns: columns,
rows: items,
@@ -350,6 +357,107 @@ define(["jquery", "app/common", "footable"],
"postdraw.ft.table": postdrawCallback
}
});
+
+ // Column options dropdown
+ (() => {
+ function updateValue(checked, column, cellIdx) {
+ const option = ["breakpoints", "visible"][cellIdx];
+ const value = [(checked) ? "all" : column.breakpoints, !checked][cellIdx];
+
+ FooTable.get("#historyTable_" + table).columns.get(column.name)[option] = value;
+ return value;
+ }
+
+ const tbody = $("<tbody/>", {class: "table-group-divider"});
+ $("#" + table + " .ft-columns-dropdown").empty().append(
+ $("<table/>", {class: "table table-sm table-striped text-center"}).append(
+ $("<thead/>").append(
+ $("<tr/>").append(
+ $("<th/>", {text: "Row", title: "Display column cells in a detail row on all screen widths"}),
+ $("<th/>", {text: "Hidden", title: "Hide column completely"}),
+ $("<th/>", {text: "Column name", class: "text-start"})
+ )
+ ),
+ tbody
+ ),
+ $("<button/>", {
+ type: "button",
+ class: "btn btn-xs btn-secondary float-start",
+ text: "Reset to default",
+ click: () => {
+ columnsDefault.forEach((column, i) => {
+ const row = tbody[0].rows[i];
+ [(column.breakpoints === "all"), (column.visible === false)].forEach((checked, cellIdx) => {
+ if (row.cells[cellIdx].getElementsByTagName("input")[0].checked !== checked) {
+ row.cells[cellIdx].getElementsByTagName("input")[0].checked = checked;
+
+ updateValue(checked, column, cellIdx);
+ delete columnsCustom[table];
+ }
+ });
+ });
+ }
+ }),
+ $("<button/>", {
+ type: "button",
+ class: "btn btn-xs btn-primary float-end btn-dropdown-apply",
+ text: "Apply",
+ title: "Save settings and redraw the table",
+ click: (e) => {
+ $(e.target).attr("disabled", true);
+ FooTable.get("#historyTable_" + table).draw();
+ localStorage.setItem("columns", JSON.stringify(columnsCustom));
+ }
+ })
+ );
+
+ function checkbox(i, column, cellIdx) {
+ const option = ["breakpoints", "visible"][cellIdx];
+ return $("<td/>").append($("<input/>", {
+ "type": "checkbox",
+ "class": "form-check-input",
+ "data-table": table,
+ "data-name": column.name,
+ "checked": (option === "breakpoints" && column.breakpoints === "all") ||
+ (option === "visible" && column.visible === false),
+ "disabled": (option === "breakpoints" && columnsDefault[i].breakpoints === "all")
+ }).change((e) => {
+ const value = updateValue(e.target.checked, columnsDefault[i], cellIdx);
+ if (value == null) { // eslint-disable-line no-eq-null, eqeqeq
+ delete columnsCustom[table][column.name][option];
+ } else {
+ $.extend(true, columnsCustom, {
+ [table]: {
+ [column.name]: {
+ [option]: value
+ }
+ }
+ });
+ }
+ }));
+ }
+
+ $.each(columns, (i, column) => {
+ tbody.append(
+ $("<tr/>").append(
+ checkbox(i, column, 0),
+ checkbox(i, column, 1),
+ $("<td/>", {
+ class: "text-start",
+ text: () => {
+ switch (column.name) {
+ case "passthrough_module": return "Pass-through module";
+ case "symbols": return "Symbols";
+ default: return column.title;
+ }
+ }
+ })
+ )
+ );
+ });
+
+ $("#" + table + " .ft-columns-btn").removeAttr("disabled");
+ })();
};
ui.preprocess_item = function (item) {
diff --git a/interface/js/app/upload.js b/interface/js/app/upload.js
index c464ef30f..5f330002b 100644
--- a/interface/js/app/upload.js
+++ b/interface/js/app/upload.js
@@ -76,7 +76,7 @@ define(["jquery", "app/common", "app/libft"],
}
function enable_disable_scan_btn(disable) {
- $("#scan button:not(#cleanScanHistory, #scanOptionsToggle)")
+ $("#scan button:not(#cleanScanHistory, #scanOptionsToggle, .ft-columns-btn)")
.prop("disabled", (disable || $.trim($("textarea").val()).length === 0));
}
@@ -128,7 +128,8 @@ define(["jquery", "app/common", "app/libft"],
}, ++filesIdx);
} else {
enable_disable_scan_btn();
- $("#cleanScanHistory").removeAttr("disabled");
+ $("#cleanScanHistory, #scan .ft-columns-dropdown .btn-dropdown-apply")
+ .removeAttr("disabled");
$("html, body").animate({
scrollTop: $("#scanResult").offset().top
}, 1000);
More information about the Commits
mailing list