admin UI: allow to control columns visibility and ordering

Signed-off-by: Nicola Murino <nicola.murino@gmail.com>
This commit is contained in:
Nicola Murino
2022-05-22 11:45:49 +02:00
parent 1a33b5bb53
commit f536c64043
26 changed files with 679 additions and 397 deletions

View File

@@ -2,6 +2,10 @@
{{define "title"}}{{.Title}}{{end}}
{{define "extra_css"}}
<link href="{{.StaticURL}}/vendor/bootstrap-select/css/bootstrap-select.min.css" rel="stylesheet">
{{end}}
{{define "page_body"}}
<div class="card shadow mb-4">
<div class="card-header py-3">
@@ -44,7 +48,7 @@
<div class="form-group row">
<label for="idStatus" class="col-sm-2 col-form-label">Status</label>
<div class="col-sm-10">
<select class="form-control" id="idStatus" name="status">
<select class="form-control selectpicker" id="idStatus" name="status">
<option value="1" {{if eq .Admin.Status 1 }}selected{{end}}>Active</option>
<option value="0" {{if eq .Admin.Status 0 }}selected{{end}}>Inactive</option>
</select>
@@ -67,7 +71,7 @@
<div class="form-group row">
<label for="idPermissions" class="col-sm-2 col-form-label">Permissions</label>
<div class="col-sm-10">
<select class="form-control" id="idPermissions" name="permissions" required multiple>
<select class="form-control selectpicker" id="idPermissions" name="permissions" required multiple>
{{range $validPerm := .Admin.GetValidPerms}}
<option value="{{$validPerm}}" {{range $perm :=$.Admin.Permissions }}
{{if eq $perm $validPerm}}selected{{end}}{{end}}>{{$validPerm}}
@@ -115,4 +119,8 @@
</form>
</div>
</div>
{{end}}
{{define "extra_js"}}
<script src="{{.StaticURL}}/vendor/bootstrap-select/js/bootstrap-select.min.js"></script>
{{end}}

View File

@@ -8,6 +8,7 @@
<link href="{{.StaticURL}}/vendor/datatables/fixedHeader.bootstrap4.min.css" rel="stylesheet">
<link href="{{.StaticURL}}/vendor/datatables/responsive.bootstrap4.min.css" rel="stylesheet">
<link href="{{.StaticURL}}/vendor/datatables/select.bootstrap4.min.css" rel="stylesheet">
<link href="{{.StaticURL}}/vendor/datatables/colReorder.bootstrap4.min.css" rel="stylesheet">
{{end}}
{{define "page_body"}}
@@ -32,9 +33,12 @@
<th>ID</th>
<th>Username</th>
<th>Status</th>
{{if .HasMFA }}<th>MFA</th>{{end}}
<th>Permissions</th>
<th>Other</th>
<th>Last login</th>
<th>MFA</th>
<th>Allow list</th>
<th>Email</th>
<th>Description</th>
</tr>
</thead>
<tbody>
@@ -43,9 +47,12 @@
<td>{{.ID}}</td>
<td>{{.Username}}</td>
<td>{{if eq .Status 1 }}Active{{else}}Inactive{{end}}</td>
{{if $.HasMFA }}<td>{{if .Filters.TOTPConfig.Enabled }}Enabled{{else}}-{{end}}</td>{{end}}
<td>{{.GetPermissionsAsString}}</td>
<td>{{.GetInfoString}}</td>
<td>{{.GetLastLoginAsString}}</td>
<td>{{if .Filters.TOTPConfig.Enabled }}Enabled{{else}}Disabled{{end}}</td>
<td>{{.GetAllowedIPAsString}}</td>
<td>{{.Email}}</td>
<td>{{.Description}}</td>
</tr>
{{end}}
@@ -89,11 +96,13 @@
<script src="{{.StaticURL}}/vendor/datatables/dataTables.bootstrap4.min.js"></script>
<script src="{{.StaticURL}}/vendor/datatables/dataTables.buttons.min.js"></script>
<script src="{{.StaticURL}}/vendor/datatables/buttons.bootstrap4.min.js"></script>
<script src="{{.StaticURL}}/vendor/datatables/buttons.colVis.min.js"></script>
<script src="{{.StaticURL}}/vendor/datatables/dataTables.fixedHeader.min.js"></script>
<script src="{{.StaticURL}}/vendor/datatables/dataTables.responsive.min.js"></script>
<script src="{{.StaticURL}}/vendor/datatables/responsive.bootstrap4.min.js"></script>
<script src="{{.StaticURL}}/vendor/datatables/dataTables.select.min.js"></script>
<script src="{{.StaticURL}}/vendor/datatables/ellipsis.js"></script>
<script src="{{.StaticURL}}/vendor/datatables/dataTables.colReorder.min.js"></script>
<script type="text/javascript">
function deleteAction() {
@@ -169,18 +178,46 @@
"style": "single",
"blurable": true
},
"colReorder": {
"enable": true,
"fixedColumnsLeft": 2
},
"stateSave": true,
"stateDuration": 0,
"buttons": [],
"buttons": [
{
"text": "Column visibility",
"extend": "colvis",
"columns": ":not(.noVis)"
}
],
"columnDefs": [
{
"targets": [0],
"visible": false,
"searchable": false
"searchable": false,
"className": "noVis"
},
{
"targets": [1],
"className": "noVis"
},
{
"targets": [3],
"render": $.fn.dataTable.render.ellipsis(40, true)
"render": $.fn.dataTable.render.ellipsis(70, true)
},
{
"targets": [4],
"render": $.fn.dataTable.render.datetime()
},
{
"targets": [6],
"render": $.fn.dataTable.render.ellipsis(60, true),
"visible": false,
},
{
"targets": [5,7,8],
"visible": false,
}
],
"scrollX": false,

View File

@@ -80,6 +80,7 @@
<script src="{{.StaticURL}}/vendor/datatables/dataTables.bootstrap4.min.js"></script>
<script src="{{.StaticURL}}/vendor/datatables/dataTables.buttons.min.js"></script>
<script src="{{.StaticURL}}/vendor/datatables/buttons.bootstrap4.min.js"></script>
<script src="{{.StaticURL}}/vendor/datatables/buttons.colVis.min.js"></script>
<script src="{{.StaticURL}}/vendor/datatables/dataTables.fixedHeader.min.js"></script>
<script src="{{.StaticURL}}/vendor/datatables/dataTables.responsive.min.js"></script>
<script src="{{.StaticURL}}/vendor/datatables/responsive.bootstrap4.min.js"></script>
@@ -148,14 +149,25 @@
"style": "single",
"blurable": true
},
"buttons": [],
"lengthChange": false,
"buttons": [
{
"text": "Column visibility",
"extend": "colvis",
"columns": ":not(.noVis)"
}
],
"lengthChange": true,
"columnDefs": [
{
"targets": [0],
"visible": false,
"searchable": false
"searchable": false,
"className": "noVis"
},
{
"targets": [1],
"className": "noVis"
}
],
"scrollX": false,
"scrollY": false,
@@ -169,7 +181,7 @@
new $.fn.dataTable.FixedHeader( table );
table.button().add(0, 'refresh');
table.button().add(0,'pageLength');
//table.button().add(0,'pageLength');
{{if .LoggedAdmin.HasPermission "close_conns"}}
table.button().add(0,'disconnect');

View File

@@ -184,7 +184,6 @@ function deleteAction() {
"scrollY": false,
"responsive": true,
"language": {
"processing": '<i class="fas fa-spinner fa-spin fa-3x fa-fw"></i><span class="sr-only">Loading...</span>',
"loadingRecords": "",
"emptyTable": "No records found"
},

View File

@@ -8,6 +8,7 @@
<link href="{{.StaticURL}}/vendor/datatables/fixedHeader.bootstrap4.min.css" rel="stylesheet">
<link href="{{.StaticURL}}/vendor/datatables/responsive.bootstrap4.min.css" rel="stylesheet">
<link href="{{.StaticURL}}/vendor/datatables/select.bootstrap4.min.css" rel="stylesheet">
<link href="{{.StaticURL}}/vendor/datatables/colReorder.bootstrap4.min.css" rel="stylesheet">
{{end}}
{{define "page_body"}}
@@ -28,19 +29,25 @@
<table class="table table-hover nowrap" id="dataTable" width="100%" cellspacing="0">
<thead>
<tr>
<th></th>
<th>Name</th>
<th>Storage</th>
<th>Description</th>
<th>Associated users</th>
<th>Associated groups</th>
<th>Quota</th>
<th>Used by</th>
</tr>
</thead>
<tbody>
{{range .Folders}}
<tr>
<td>{{.GetLastQuotaUpdateAsString}}</td>
<td>{{.Name}}</td>
<td>{{.GetStorageDescrition}}</td>
<td>{{.GetQuotaSummary}}</td>
<td>{{.Description}}</td>
<td>{{.GetUsersAsString}}</td>
<td>{{.GetGroupsAsString}}</td>
<td>{{.GetQuotaSummary}}</td>
</tr>
{{end}}
@@ -83,17 +90,19 @@
<script src="{{.StaticURL}}/vendor/datatables/dataTables.bootstrap4.min.js"></script>
<script src="{{.StaticURL}}/vendor/datatables/dataTables.buttons.min.js"></script>
<script src="{{.StaticURL}}/vendor/datatables/buttons.bootstrap4.min.js"></script>
<script src="{{.StaticURL}}/vendor/datatables/buttons.colVis.min.js"></script>
<script src="{{.StaticURL}}/vendor/datatables/dataTables.fixedHeader.min.js"></script>
<script src="{{.StaticURL}}/vendor/datatables/dataTables.responsive.min.js"></script>
<script src="{{.StaticURL}}/vendor/datatables/responsive.bootstrap4.min.js"></script>
<script src="{{.StaticURL}}/vendor/datatables/dataTables.select.min.js"></script>
<script src="{{.StaticURL}}/vendor/datatables/ellipsis.js"></script>
<script src="{{.StaticURL}}/vendor/datatables/dataTables.colReorder.min.js"></script>
<script type="text/javascript">
function deleteAction() {
var table = $('#dataTable').DataTable();
table.button('delete:name').enable(false);
var folderName = table.row({ selected: true }).data()[0];
var folderName = table.row({ selected: true }).data()[1];
var path = '{{.FolderURL}}' + "/" + fixedEncodeURIComponent(folderName);
$('#deleteModal').modal('hide');
$.ajax({
@@ -141,7 +150,7 @@ function deleteAction() {
name: 'edit',
titleAttr: "Edit",
action: function (e, dt, node, config) {
var folderName = table.row({ selected: true }).data()[0];
var folderName = table.row({ selected: true }).data()[1];
var path = '{{.FolderURL}}' + "/" + fixedEncodeURIComponent(folderName);
window.location.href = path;
},
@@ -155,7 +164,7 @@ function deleteAction() {
action: function (e, dt, node, config) {
var selectedRows = table.rows({ selected: true }).count();
if (selectedRows == 1){
var folderName = table.row({ selected: true }).data()[0];
var folderName = table.row({ selected: true }).data()[1];
var path = '{{.FolderTemplateURL}}' + "?from=" + encodeURIComponent(folderName);
window.location.href = path;
} else {
@@ -175,11 +184,12 @@ function deleteAction() {
};
$.fn.dataTable.ext.buttons.quota_scan = {
text: 'Quota scan',
text: '<i class="fas fa-redo-alt"></i>',
name: 'quota_scan',
titleAttr: 'Quota Scan',
action: function (e, dt, node, config) {
dt.button('quota_scan:name').enable(false);
var folderName = dt.row({ selected: true }).data()[0];
var folderName = dt.row({ selected: true }).data()[1];
var path = '{{.FolderQuotaScanURL}}'+ "/" + fixedEncodeURIComponent(folderName);
$.ajax({
url: path,
@@ -223,21 +233,61 @@ function deleteAction() {
"style": "single",
"blurable": true
},
"colReorder": {
"enable": true,
"fixedColumnsLeft": 2
},
"stateSave": true,
"stateDuration": 0,
"buttons": [],
"buttons": [
{
"text": "Column visibility",
"extend": "colvis",
"columns": ":not(.noVis)"
}
],
"columnDefs": [
{
"targets": [0],
"visible": false,
"className": "noVis"
},
{
"targets": [1],
"render": $.fn.dataTable.render.ellipsis(50, true)
"className": "noVis"
},
{
"targets": [2],
"render": $.fn.dataTable.render.ellipsis(60, true)
"render": $.fn.dataTable.render.ellipsis(50, true)
},
{
"targets": [3],
"visible": false
},
{
"targets": [4],
"render": $.fn.dataTable.render.ellipsis(40, true)
},
{
"targets": [5],
"visible": false,
"render": $.fn.dataTable.render.ellipsis(40, true)
},
{
"targets": [6],
"visible": false,
"render": function ( data, type, row, meta ) {
if (type !== 'display') {
return data;
}
if (row[0] !== ""){
var dateFn = $.fn.dataTable.render.datetime();
var formattedDate = dateFn(row[0], type);
data = `${data}. Updated at: ${formattedDate}`;
}
var ellipsisFn = $.fn.dataTable.render.ellipsis(60, true);
return ellipsisFn(data, type);
}
}
],
"scrollX": false,
@@ -246,7 +296,7 @@ function deleteAction() {
"language": {
"emptyTable": "No folder defined"
},
"order": [[0, 'asc']]
"order": [[1, 'asc']]
});
new $.fn.dataTable.FixedHeader( table );

View File

@@ -8,6 +8,7 @@
<link href="{{.StaticURL}}/vendor/datatables/fixedHeader.bootstrap4.min.css" rel="stylesheet">
<link href="{{.StaticURL}}/vendor/datatables/responsive.bootstrap4.min.css" rel="stylesheet">
<link href="{{.StaticURL}}/vendor/datatables/select.bootstrap4.min.css" rel="stylesheet">
<link href="{{.StaticURL}}/vendor/datatables/colReorder.bootstrap4.min.css" rel="stylesheet">
{{end}}
{{define "page_body"}}
@@ -32,10 +33,16 @@
<th>ID</th>
<th>Username</th>
<th>Status</th>
{{if .HasMFA }}<th>MFA</th>{{end}}
<th>Last login</th>
<th>Description</th>
<th>Email</th>
<th>Storage</th>
<th>Groups</th>
<th>MFA</th>
<th>Bandwidth</th>
<th>Quota</th>
<th>Other</th>
<th></th>
</tr>
</thead>
<tbody>
@@ -44,10 +51,16 @@
<td>{{.ID}}</td>
<td>{{.Username}}</td>
<td>{{.GetStatusAsString}}</td>
{{if $.HasMFA }}<td>{{.GetMFAStatusAsString}}</td>{{end}}
<td>{{.GetLastLoginAsString}}</td>
<td>{{.Description}}</td>
<td>{{.Email}}</td>
<td>{{.GetStorageDescrition}}</td>
<td>{{.GetGroupsAsString}}</td>
<td>{{.GetMFAStatusAsString}}</td>
<td>{{.GetBandwidthAsString}}</td>
<td>{{.GetQuotaSummary}}</td>
<td>{{.GetInfoString}}</td>
<td>{{.GetLastQuotaUpdateAsString}}</td>
</tr>
{{end}}
</tbody>
@@ -90,11 +103,13 @@
<script src="{{.StaticURL}}/vendor/datatables/dataTables.bootstrap4.min.js"></script>
<script src="{{.StaticURL}}/vendor/datatables/dataTables.buttons.min.js"></script>
<script src="{{.StaticURL}}/vendor/datatables/buttons.bootstrap4.min.js"></script>
<script src="{{.StaticURL}}/vendor/datatables/buttons.colVis.min.js"></script>
<script src="{{.StaticURL}}/vendor/datatables/dataTables.fixedHeader.min.js"></script>
<script src="{{.StaticURL}}/vendor/datatables/dataTables.responsive.min.js"></script>
<script src="{{.StaticURL}}/vendor/datatables/responsive.bootstrap4.min.js"></script>
<script src="{{.StaticURL}}/vendor/datatables/dataTables.select.min.js"></script>
<script src="{{.StaticURL}}/vendor/datatables/ellipsis.js"></script>
<script src="{{.StaticURL}}/vendor/datatables/dataTables.colReorder.min.js"></script>
<script type="text/javascript">
function deleteAction() {
@@ -187,8 +202,9 @@
};
$.fn.dataTable.ext.buttons.quota_scan = {
text: 'Quota scan',
text: '<i class="fas fa-redo-alt"></i>',
name: 'quota_scan',
titleAttr: 'Quota Scan',
action: function (e, dt, node, config) {
dt.button('quota_scan:name').enable(false);
var username = dt.row({ selected: true }).data()[1];
@@ -235,22 +251,68 @@
"style": "single",
"blurable": true
},
"colReorder": {
"enable": true,
"fixedColumnsLeft": 2
},
"stateSave": true,
"stateDuration": 0,
"buttons": [],
"buttons": [
{
"text": "Column visibility",
"extend": "colvis",
"columns": ":not(.noVis)"
}
],
"columnDefs": [
{
"targets": [0],
"targets": [0,12],
"visible": false,
"searchable": false
"searchable": false,
"className": "noVis"
},
{
"targets": [1],
"className": "noVis"
},
{
"targets": [3],
"render": $.fn.dataTable.render.datetime()
},
{
"targets": [4,5,8],
"visible": false
},
{
"targets": [6,7],
"visible": false,
"render": $.fn.dataTable.render.ellipsis(50, true)
},
{
"targets": [9],
"visible": false,
"render": $.fn.dataTable.render.ellipsis(40, true)
},
{
"targets": [4],
"render": $.fn.dataTable.render.ellipsis(70, true)
"targets": [10],
"visible": false,
"render": function ( data, type, row, meta ) {
if (type !== 'display') {
return data;
}
if (row[12] !== ""){
var dateFn = $.fn.dataTable.render.datetime();
var formattedDate = dateFn(row[12], type);
data = `${data}. Updated at: ${formattedDate}`;
}
var ellipsisFn = $.fn.dataTable.render.ellipsis(70, true);
return ellipsisFn(data, type);
}
},
{
"targets": [11],
"visible": false,
"render": $.fn.dataTable.render.ellipsis(100, true)
}
],
"scrollX": false,