diff --git a/server/src/static/assets/js/filter.js b/server/src/static/assets/js/filter.js index 94de0351..8225c46d 100644 --- a/server/src/static/assets/js/filter.js +++ b/server/src/static/assets/js/filter.js @@ -14,22 +14,21 @@ document.addEventListener('DOMContentLoaded', function() { }); }); -function sortTable(header, table, sortOrderFunc) { - var SORTABLE_STATES = { - none: 0, - ascending: -1, - descending: 1, - ORDER: ['none', 'ascending', 'descending'], - }; - +/** + * Sorts the specified table by the specified ordering + * @param {HTMLTableCellElement} header + * @param {HTMLTableElement} table + * @param {String} newOrder + */ +function sortTable(header, table, newOrder) { // Get index of column based on position of header cell in // We assume there is only one row in the table head. var col = [].slice.call(table.tHead.rows[0].cells).indexOf(header); - - // Based on the current aria-sort value, get the next state. - var newOrder = SORTABLE_STATES.ORDER.indexOf(header.getAttribute('aria-sort')) + 1; - newOrder = newOrder > SORTABLE_STATES.ORDER.length - 1 ? 0 : newOrder; - newOrder = SORTABLE_STATES.ORDER[newOrder]; + const sortDirectionMap = { + none: 0, + ascending: -1, + descending: 1, + }; // Reset all header sorts. var headerSorts = table.querySelectorAll('[aria-sort]'); @@ -43,7 +42,7 @@ function sortTable(header, table, sortOrderFunc) { // Get the direction of the sort and assume only one tbody. // For this example only assume one tbody. - var direction = SORTABLE_STATES[newOrder]; + var direction = sortDirectionMap[newOrder]; var body = table.tBodies[0]; // Convert the HTML element list to an array. @@ -56,6 +55,10 @@ function sortTable(header, table, sortOrderFunc) { return a.getAttribute('data-index') - b.getAttribute('data-index'); }); } else { + sortOrderFunc = defaultSortOrder; + if (header.hasAttribute("use-outcome-sort")) { + sortOrderFunc = outcomeSortOrder; + } // Sort based on a cell contents newRows.sort(function (rowA, rowB) { return sortOrderFunc(rowA.cells[col], rowB.cells[col], direction); @@ -65,6 +68,37 @@ function sortTable(header, table, sortOrderFunc) { for (i = 0, ii = body.rows.length; i < ii; i += 1) { body.appendChild(newRows[i]); } + + // Change url parameters based on sort order for the agents table + if (table.id == "agentsTable") { + var pageURL = new URL(window.location.href); + pageURL.searchParams.set("tableId", table.id); + pageURL.searchParams.set("headerId", header.id); + pageURL.searchParams.set("sortOrder", newOrder); + window.history.replaceState(null, null, pageURL); + } +} + +/** + * Cycles through sort order states and applies the designated sort order to the + * specified table. + * @param {HTMLTableCellElement} header + * @param {HTMLTableElement} table + */ +function cycleTableSort(header, table) { + var SORTABLE_STATES = { + none: 0, + ascending: -1, + descending: 1, + ORDER: ['none', 'ascending', 'descending'], + }; + + // Based on the current aria-sort value, get the next state. + var newOrder = SORTABLE_STATES.ORDER.indexOf(header.getAttribute('aria-sort')) + 1; + newOrder = newOrder > SORTABLE_STATES.ORDER.length - 1 ? 0 : newOrder; + newOrder = SORTABLE_STATES.ORDER[newOrder]; + + sortTable(header, table, newOrder); } /** @@ -105,15 +139,9 @@ function outcomeSortOrder(cellA, cellB, direction) { } function setupClickableHeader(table, header) { - if (header.hasAttribute("use-outcome-sort")) { - header.addEventListener('click', function () { - sortTable(header, table, outcomeSortOrder); - }); - } else { - header.addEventListener('click', function () { - sortTable(header, table, defaultSortOrder); - }); - } + header.addEventListener('click', function () { + cycleTableSort(header, table); + }); } /** @@ -136,9 +164,36 @@ function setupSortableTable(table) { } } +/** + * Gets URL parameters and uses them to sort the specified table. + * Currently only supports the agent table. + */ +function sortTableFromURL() { + // Get url parameters for table sort ordering if specified + const queryString = window.location.search; + const urlParams = new URLSearchParams(queryString); + const tableId = urlParams.get("tableId"); + // Only url parameters for the agents table is supported + if (tableId != "agentsTable") { + return; + } + const headerId = urlParams.get("headerId"); + var sortOrder = urlParams.get("sortOrder"); + const validSortOrders = ["ascending", "descending", "none"]; + if (!validSortOrders.includes(sortOrder)) { + sortOrder = "none" + } + var table = document.getElementById(tableId); + var header = document.getElementById(headerId); + if (table == null || header == null) { + return; + } + sortTable(header, table, sortOrder); +} + // Make all tables on the page sortable. var tables = document.querySelectorAll('table'); - for (var i = 0, ii = tables.length; i < ii; i += 1) { setupSortableTable(tables[i]); } +sortTableFromURL() diff --git a/server/src/templates/agents.html b/server/src/templates/agents.html index 3f64f69c..cb4faf50 100644 --- a/server/src/templates/agents.html +++ b/server/src/templates/agents.html @@ -17,18 +17,18 @@

- +
- - - - + + +
+ The number of consecutively successful / failed provisioning attempts Outcome NameStateUpdated AtNameStateUpdated At Job ID