diff options
author | Simon Rettberg | 2020-04-20 11:49:17 +0200 |
---|---|---|
committer | Simon Rettberg | 2020-04-20 11:49:17 +0200 |
commit | 5eaa4292c6db2c1ee1282c938c899dc5b88db65f (patch) | |
tree | 137eaa063302b055ddec03e2c4c3ff5c084f11bf /modules-available/statistics/templates | |
parent | [serversetup-bwlp-ipxe] Fix: Imported PXELINUX entries are invalid (diff) | |
download | slx-admin-5eaa4292c6db2c1ee1282c938c899dc5b88db65f.tar.gz slx-admin-5eaa4292c6db2c1ee1282c938c899dc5b88db65f.tar.xz slx-admin-5eaa4292c6db2c1ee1282c938c899dc5b88db65f.zip |
[statistics] New filter UI
Diffstat (limited to 'modules-available/statistics/templates')
5 files changed, 110 insertions, 230 deletions
diff --git a/modules-available/statistics/templates/cpumodels.html b/modules-available/statistics/templates/cpumodels.html index d89a5b2f..2e36a287 100644 --- a/modules-available/statistics/templates/cpumodels.html +++ b/modules-available/statistics/templates/cpumodels.html @@ -19,11 +19,11 @@ <tr id="{{id}}" class="{{collapse}}"> <td data-sort-value="{{systemmodel}}" class="text-left text-nowrap filter-col" data-filter-col="systemmodel"> <table style="width:100%; table-layout: fixed;"><tr><td style="overflow:hidden;text-overflow: ellipsis;"> - <a class="filter-val" data-filter-val="{{systemmodel}}" href="?do=Statistics&show=summary&filters={{query}}~,~systemmodel={{urlsystemmodel}}">{{systemmodel}}</a> + <a class="filter-val" data-filter-val="{{systemmodel}}" href="#">{{systemmodel}}</a> </td></tr></table> </td> <td data-sort-value="{{cores}}" class="text-right filter-col" data-filter-col="realcores"> - <a class="filter-val" data-filter-val="{{cores}}" href="?do=Statistics&show=summary&filters={{query}}~,~realcores={{cores}}">{{cores}}</a> + <a class="filter-val" data-filter-val="{{cores}}" href="#">{{cores}}</a> </td> <td class="text-right">{{count}}</td> </tr> diff --git a/modules-available/statistics/templates/filterbox.html b/modules-available/statistics/templates/filterbox.html index f71c918d..34f4d3a6 100644 --- a/modules-available/statistics/templates/filterbox.html +++ b/modules-available/statistics/templates/filterbox.html @@ -1,201 +1,104 @@ -<div id="modal-add-filter" class="modal fade" role="dialog" style="position: absolute"> - <div class="modal-dialog" role="document"> - <div class="modal-content"> - <div class="modal-header"> - <b>{{lang_add_filter}}</b> - </div> - <form class="form-inline center" onsubmit="$('#add-btn').click(); return false"> - <div class="modal-body"> - <div class="form-group"> - <select id="columnSelect" name="column" class="form-control col-4-xs"> </select> - </div> - <div class="form-group"> - <select id="operatorSelect" name="operator" class="form-control col-4-xs"> </select> - </div> - <div class="form-group"> - <input name="argument" id="argumentInput" class="form-control col-4-xs"> - <select name="argument" id="argumentSelect" class="form-control col-4-xs"> </select> - </div> +<a href="#top" class="btn btn-default to-top-btn"><span class="glyphicon glyphicon-menu-up"></span></a> +<h1>{{lang_moduleHeading}}</h1> + +<form id="query-form" method="GET" action="?do=statistics" role="form"> + <input type="hidden" name="show" value="{{show}}"> + <input type="hidden" name="do" value="statistics"> + <div class="btn-group pull-right"> + <button type="submit" hidden><!-- first button, so hitting enter in the form fields doesn't jump to summary --> + <button class="btn btn-default {{statButtonClass}}" type="submit" name="show" value="summary" + {{perms.view.summary.disabled}}> + <span class="glyphicon glyphicon-stats"></span> + {{lang_showVisualization}} + </button> + <button class="btn btn-default {{listButtonClass}}" type="submit" name="show" value="list" + {{perms.view.list.disabled}}> + <span class="glyphicon glyphicon-list"></span> + {{lang_showList}} + </button> + </div> + + <h3>{{lang_labelFilter}}</h3> + <div class="filter-list"> + {{#columns}} + <div class="{{collapse}} row filter-row" id="filter-{{key}}"> + <div class="col-sm-4 col-xs-12"> + <div class="checkbox checkbox-inline text-nowrap"> + <input id="check-{{key}}" type="checkbox" name="filter[{{key}}]" value="1" class="filter-enable" + {{checked}}> + <label for="check-{{key}}">{{name}}</label> </div> - <div class="modal-footer"> - <button type="button" class="btn btn-default" data-dismiss="modal">{{lang_cancel}}</button> - <button id="add-btn" type="button" class="btn btn-success" onclick="addFilterFromForm()"> - <span class="glyphicon glyphicon-plus"></span> - {{lang_add}} - </button> - </div> - </form> + </div> + <div class="col-sm-2 col-xs-3"> + <select name="op[{{key}}]" class="form-control enable-check op"> + {{#op}} + <option {{selected}}>{{op}}</option> + {{/op}} + </select> + </div> + <div class="col-sm-6 col-xs-9"> + {{#input}} + <input name="arg[{{key}}]" type="{{.}}" class="form-control enable-check {{inputclass}} arg" + value="{{currentvalue}}" placeholder="{{placeholder}}"> + {{/input}} + {{#enum}} + <select name="arg[{{key}}]" class="form-control enable-check arg"> + {{#values}} + <option value="{{key}}" {{disabled}} {{selected}}>{{value}}</option> + {{/values}} + </select> + {{/enum}} + </div> </div> + <div class="clearfix"></div><!-- fixes jumping around of items on firefox --> + {{/columns}} </div> -</div> - -<a href="#top" class="btn btn-default to-top-btn"><span class="glyphicon glyphicon-menu-up"></span></a> - - -<div class="col-md-12"> - <!-- use GET here, to avoid the "resend form?" confirmation, and anyway this is stateless, so GET makes more sense --> - <form id="queryForm" method="GET" action="?do=Statistics" class="" role="form"> - <input type="hidden" name="show" value="{{show}}"> - <button type="submit" hidden></button> - - - <div class="btn-group pull-right"> - <button class="btn btn-default {{statButtonClass}}" type="submit" name="show" value="summary" {{perms.view.summary.disabled}}> - <span class="glyphicon glyphicon-stats"></span> - {{lang_showVisualization}} + <div class="row"> + <div class="col-md-12 col-sm-10 col-xs-12"> + <button type="submit" class="btn btn-primary pull-right"> + <span class="glyphicon glyphicon-ok"></span> + {{lang_apply}} </button> - <button class="btn btn-default {{listButtonClass}}" type="submit" name="show" value="list" {{perms.view.list.disabled}}> - <span class="glyphicon glyphicon-list"></span> - {{lang_showList}} + <button type="button" class="btn btn-default" id="filter-expand"> + <span class="glyphicon glyphicon-arrow-down"></span> + {{lang_more}} </button> </div> - <h1>{{lang_moduleHeading}}</h1> - - <br/> - - <input type="hidden" name="do" value="statistics"> - <input type="hidden" name="sortColumn" id="sortColumn" value="{{sortColumn}}"/> - <input type="hidden" name="sortDirection" id="sortDirection" value="{{sortDirection}}"/> - - <label for="filterInput">{{lang_labelFilter}}</label> - <div class="row"> - <div class="col-md-12"> - <div class="input-group"> - <input type="text" name="filters" class="" id="filterInput"/> - <span class="input-group-btn" style=" width: 1%; padding-bottom: 5px;"> - <button type="button" class="btn btn-success" onclick="popupFilter(null)"> - <span class="glyphicon glyphicon-plus"></span> - {{lang_add_filter}} - </button> - </span> - </div> - </div> - </div> - - <br/> - </form> -</div> + </div> + <div class="clearfix slx-space"></div> +</form> <script type="application/javascript"><!-- -var filterSelectize; - -var slxFilterNames = { - machineuuid: '{{lang_uuid}}', - macaddr: '{{lang_macAddr}}', - firstseen: '{{lang_firstSeen}}', - lastseen: '{{lang_lastSeen}}', - lastboot: '{{lang_lastBoot}}', - logintime: '{{lang_lastLogin}}', - realcores: '{{lang_cores}}', - systemmodel: '{{lang_model}}', - cpumodel: '{{lang_cpuModel}}', - hddgb: '{{lang_tmpGb}}', - gbram: '{{lang_gbRam}}', - kvmstate: '{{lang_kvmSupport}}', - badsectors: '{{lang_reallocatedSectors}}', - clientip: '{{lang_ip}}', - state: '{{lang_usageState}}', - location: '{{lang_location}}', - currentuser: '{{lang_currentUser}}', - subnet: '{{lang_subnet}}', - runtime: '{{lang_runtimeHours}}', - hostname: '{{lang_hostname}}', - live_swapfree: '{{lang_swapFree}}', - live_memfree: '{{lang_memFree}}', - live_tmpfree: '{{lang_tmpFree}}' -}; - -slxLocations = {{{locations}}}; - -var slxFilterDel = '{{delimiter}}'; -var $modal, $queryForm; - - document.addEventListener("DOMContentLoaded", function () { - /* some objects */ - var $columnSelect = $('#columnSelect'); - $modal = $('#modal-add-filter'); - $queryForm = $('#queryForm'); - - var columns= {{{columns}}}; + $('.is-date').datepicker({format : 'yyyy-mm-dd'}); - /* add options to column select */ - for (var key in columns) { - $columnSelect.append($('<option>', { - value: key, text: (slxFilterNames[key] ? slxFilterNames[key] : key) })); - }; - - - /* initialize selectize */ - filterSelectize = $('#filterInput').selectize({ - delimiter: slxFilterDel, - persist: false, - plugins: ['remove_button'], - create: function(input) { - return {value: input, text: input} - }, - onChange: function() { - // if (initComplete && !$('#filterInput').is(':focus')) { - // reload(); - // } - }, - onItemRemove: function(value) { - refresh(); - } - })[0].selectize; - /* add query */ - var str = "{{{query}}}"; - var eExp = /^(\w+)\s*([=><!~]+)\s*(.*)$/; - str.split(slxFilterDel).forEach(function(v) { - if (v.trim().length === 0) - return; - var match = eExp.exec(v); - if (match && match.length === 4) { - addFilter(match[1], match[2], match[3]); - } else { - filterSelectize.addOption({value: v, text: v}); - filterSelectize.addItem(v); - } + $('#filter-expand').click(function() { + $('#query-form .filter-row.collapse').show(); + $(this).remove(); }); - $('#columnSelect').on('change', function() { - $('#operatorSelect option').remove(); - var col = $('#columnSelect').val(); - var opS = $('#operatorSelect'); - columns[col]['op'].sort(myOpSort); - columns[col]['op'].forEach(function (v) { - $(opS).append($('<option>', { - value: v, text: v - })); + // Cosmetic - less clutter in URL + $('#query-form').submit(function(e) { + $(this).find('.filter-row').each(function() { + var $row = $(this); + if ($row.find('.filter-enable').prop('checked')) + return; + $row.find('input, select').prop('name', ''); }); - /* also set the type of the input */ - if (columns[col]['type'] === 'date') { - $('#argumentInput').datepicker({format : 'yyyy-mm-dd'}); - $('#argumentSelect').hide(); - } else if(columns[col]['type'] === 'enum') { - $('#argumentSelect').empty(); - $('#argumentInput').hide(); - $('#argumentSelect').show(); - columns[col]['values'].forEach(function (v) { - var t = v; - var disabled = (col === 'location'); - if (col === 'location' && slxLocations['L' + v]) { - t = slxLocations['L' + v].pad + ' ' + slxLocations['L' + v].name; - disabled = slxLocations['L' + v].disabled; - } - $('#argumentSelect').append($('<option>', { value: v, text: t, disabled: disabled })); - }); - } else { - $('#argumentInput').datepicker('remove'); - $('#argumentSelect option').remove(); - $('#argumentInput').show(); - $('#argumentSelect').hide(); - } }); + var check = function() { + $(this).closest('.filter-row').find('.filter-enable:visible').prop('checked', true); + }; + + // This sucks - we need to wait a bit otherwise datepicker triggers change + setTimeout(function() { + $('.enable-check').change(check).keypress(check); + }, 100); + $('.filter-col').each(function(idx, elem) { var e = $(elem); var col = e.data('filter-col'); @@ -203,7 +106,7 @@ document.addEventListener("DOMContentLoaded", function () { e.find('.filter-val').each(function(idx, elem) { var e = $(elem); var val = e.data('filter-val'); - if (!val) return; + if (val === null || val === undefined) return; e.click(function(ev) { ev.preventDefault(); addFilter(col, '=', val); @@ -214,58 +117,35 @@ document.addEventListener("DOMContentLoaded", function () { }, false); -window.addEventListener('unload', function() { - filterSelectize.clear(); -}); - function popupFilter(field) { - if (field != null) { - $('#columnSelect').val(field); - } - $('#columnSelect').change(); - $modal.modal('show'); -} - -function addFilterFromForm() { - var argument1 = $('#argumentInput').val(); - var argument2 = $('#argumentSelect').val(); - var argument = argument1 ? argument1 : argument2; - var col = $('#columnSelect').val(); - var op = $('#operatorSelect').val(); - - addFilter(col, op, argument); - refresh(); // TODO: AJAX + var $row = addFilter(field, null, null); + if ($row !== null) { + $row.find('.arg').focus(); + $row.removeClass('slx-focus') + setTimeout(function() { $row.addClass('slx-focus'); }, 10); + } } -function addFilter(col, op, argument) { - var filterValue = col + ' ' + op + ' ' + argument; - var filterText = filterValue; - var displayArgument = argument; - if (col === 'location' && slxLocations['L' + argument]) { - displayArgument = slxLocations['L' + argument].name; +function addFilter(field, op, argument) { + if (field === null) + return null; + var $row = $('#filter-' + field); + if ($row.length === 0) + return null; + if (argument !== null) { + $row.find('.op').val(op); + $row.find('.arg').val(argument); } - if (slxFilterNames[col]) { - filterText = slxFilterNames[col] + ' ' + op + ' ' + displayArgument; + // Enable checkbox only if we got a predefined value, or if argument is in a select, as the user might want the preselected item and doesn't notice the checkbox is unchecked + if (argument !== null || $row.find('select.arg').length !== 0) { + $row.find('.filter-enable').prop('checked', true); } - filterSelectize.addOption({value: filterValue, text: filterText}); - filterSelectize.addItem(filterValue); -} - -function toggleSort(field) { - $('#sort').val(field + ' ' + order); - refresh(); -} - -/* equal sign should always be first, the rest doesn't matter*/ -function myOpSort(a,b) { - if (a === '=') { return -1; } - else if (a === b) {return 0} - else { return 1;} - + $row.show(); + return $row; } function refresh() { - $queryForm.submit(); /* TODO: use AJAX */ + $('#query-form').submit(); } // --></script> diff --git a/modules-available/statistics/templates/id44.html b/modules-available/statistics/templates/id44.html index de1c71ad..ec0dac09 100644 --- a/modules-available/statistics/templates/id44.html +++ b/modules-available/statistics/templates/id44.html @@ -17,7 +17,7 @@ {{#rows}} <tr id="tmpid{{gb}}" class="{{class}} {{collapse}}"> <td data-sort-value="{{gb}}" class="text-left text-nowrap"> - <a class="filter-val" data-filter-val="{{gb}}" href="?do=Statistics&show=summary&filters={{query}}~,~hddgb={{gb}}">{{gb}} GiB</a> + <a class="filter-val" data-filter-val="{{gb}}" href="#">{{gb}} GiB</a> </td> <td class="text-right">{{count}}</td> </tr> diff --git a/modules-available/statistics/templates/kvmstate.html b/modules-available/statistics/templates/kvmstate.html index efa3bad3..4f8994d1 100644 --- a/modules-available/statistics/templates/kvmstate.html +++ b/modules-available/statistics/templates/kvmstate.html @@ -17,7 +17,7 @@ {{#rows}} <tr id="kvm{{kvmstate}}"> <td data-sort-value="{{kvmstate}}" class="text-left text-nowrap"> - <a class="filter-val" data-filter-val="{{kvmstate}}" href="?do=Statistics&show=summary&filters={{query}}~,~kvmstate={{kvmstate}}">{{kvmstate}}</a> + <a class="filter-val" data-filter-val="{{kvmstate}}" href="#">{{kvmstate}}</a> </td> <td class="text-right">{{count}}</td> </tr> diff --git a/modules-available/statistics/templates/memory.html b/modules-available/statistics/templates/memory.html index cfb86062..f6f4c446 100644 --- a/modules-available/statistics/templates/memory.html +++ b/modules-available/statistics/templates/memory.html @@ -17,7 +17,7 @@ {{#rows}} <tr id="ramid{{gb}}" class="{{class}} {{collapse}}"> <td class="text-left text-nowrap" data-sort-value="{{gb}}"> - <a class="filter-val" data-filter-val="{{gb}}" href="?do=Statistics&show=summary&filters={{query}}~,~gbram={{gb}}">{{gb}} GiB</a> + <a class="filter-val" data-filter-val="{{gb}}" href="#">{{gb}} GiB</a> </td> <td class="text-right">{{count}}</td> </tr> |