mirror of
https://github.com/drakkan/sftpgo.git
synced 2025-12-09 08:15:13 +03:00
admin UI: allow to control columns visibility and ordering
Signed-off-by: Nicola Murino <nicola.murino@gmail.com>
This commit is contained in:
@@ -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}}
|
||||
@@ -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,
|
||||
|
||||
@@ -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');
|
||||
|
||||
@@ -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"
|
||||
},
|
||||
|
||||
@@ -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 );
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user