diff options
-rw-r--r-- | interface/index.html | 9 | ||||
-rw-r--r-- | interface/js/app/history.js | 3 | ||||
-rw-r--r-- | interface/js/app/libft.js | 110 | ||||
-rw-r--r-- | 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); |