| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642 |
- {{template "base" .}}
- {{define "title"}}{{.Title}}{{end}}
- {{define "extra_css"}}
- <link href="{{.StaticURL}}/vendor/datatables/dataTables.bootstrap4.min.css" rel="stylesheet">
- <link href="{{.StaticURL}}/vendor/datatables/buttons.bootstrap4.min.css" rel="stylesheet">
- <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/dataTables.checkboxes.css" rel="stylesheet">
- <style>
- div.dataTables_wrapper span.selected-info,
- div.dataTables_wrapper span.selected-item {
- margin-left: 0.5em;
- }
- </style>
- {{end}}
- {{define "page_body"}}
- <div id="errorMsg" class="card mb-4 border-left-warning" style="display: none;">
- <div id="errorTxt" class="card-body text-form-error"></div>
- </div>
- <div class="card shadow mb-4">
- <div class="card-header py-3">
- <h6 class="m-0 font-weight-bold"><a href="{{.FilesURL}}?path=%2F"><i class="fas fa-home"></i> Home</a> {{range .Paths}}{{if eq .Href ""}}/{{.DirName}}{{else}}<a href="{{.Href}}">/{{.DirName}}</a>{{end}}{{end}}</h6>
- </div>
- <div class="card-body">
- {{if .Error}}
- <div class="card mb-4 border-left-warning">
- <div class="card-body text-form-error">{{.Error}}</div>
- </div>
- {{end}}
- <div class="table-responsive">
- <table class="table table-hover nowrap" id="dataTable" width="100%" cellspacing="0">
- <thead>
- <tr>
- <th></th>
- <th>Type</th>
- <th>Name</th>
- <th>Size</th>
- <th>Last modified</th>
- </tr>
- </thead>
- </table>
- </div>
- </div>
- </div>
- {{end}}
- {{define "dialog"}}
- <div class="modal fade" id="createDirModal" tabindex="-1" role="dialog" aria-labelledby="deleteModalLabel"
- aria-hidden="true">
- <div class="modal-dialog" role="document">
- <div class="modal-content">
- <div class="modal-header">
- <h5 class="modal-title" id="deleteModalLabel">
- Create a new directory
- </h5>
- <button class="close" type="button" data-dismiss="modal" aria-label="Close">
- <span aria-hidden="true">×</span>
- </button>
- </div>
- <form id="create_dir_form" action="" method="POST">
- <div class="modal-body">
- <div class="form-group">
- <label for="directory_name" class="col-form-label">Name</label>
- <input type="text" class="form-control" id="directory_name" required>
- </div>
- </div>
- <div class="modal-footer">
- <button class="btn btn-secondary" type="button" data-dismiss="modal">Cancel</button>
- <button type="submit" class="btn btn-primary">Submit</button>
- </div>
- </form>
- </div>
- </div>
- </div>
- <div class="modal fade" id="uploadFilesModal" tabindex="-1" role="dialog" aria-labelledby="uploadFilesModalLabel"
- aria-hidden="true">
- <div class="modal-dialog" role="document">
- <div class="modal-content">
- <div class="modal-header">
- <h5 class="modal-title" id="uploadFilesModalLabel">
- Upload one or more files
- </h5>
- <button class="close" type="button" data-dismiss="modal" aria-label="Close">
- <span aria-hidden="true">×</span>
- </button>
- </div>
- <form id="upload_files_form" action="" method="POST" enctype="multipart/form-data">
- <div class="modal-body">
- <input type="file" class="form-control-file" id="files_name" name="filename" required multiple>
- </div>
- <div class="modal-footer">
- <button class="btn btn-secondary" type="button" data-dismiss="modal">Cancel</button>
- <button type="submit" class="btn btn-primary">Submit</button>
- </div>
- </form>
- </div>
- </div>
- </div>
- <div class="modal fade" id="renameModal" tabindex="-1" role="dialog" aria-labelledby="renameModalLabel"
- aria-hidden="true">
- <div class="modal-dialog" role="document">
- <div class="modal-content">
- <div class="modal-header">
- <h5 class="modal-title" id="renameModalLabel">
- Rename the selected item
- </h5>
- <button class="close" type="button" data-dismiss="modal" aria-label="Close">
- <span aria-hidden="true">×</span>
- </button>
- </div>
- <form id="rename_form" action="" method="POST">
- <div class="modal-body">
- <div class="form-group">
- <label for="rename_old_name" class="col-form-label">Old name</label>
- <input type="text" class="form-control" id="rename_old_name" readonly>
- </div>
- <div class="form-group">
- <label for="rename_new_name" class="col-form-label">New name</label>
- <input type="text" class="form-control" id="rename_new_name" required>
- </div>
- </div>
- <div class="modal-footer">
- <button class="btn btn-secondary" type="button" data-dismiss="modal">Cancel</button>
- <button type="submit" class="btn btn-primary">Submit</button>
- </div>
- </form>
- </div>
- </div>
- </div>
- <div class="modal fade" id="deleteModal" tabindex="-1" role="dialog" aria-labelledby="deleteModalLabel"
- aria-hidden="true">
- <div class="modal-dialog" role="document">
- <div class="modal-content">
- <div class="modal-header">
- <h5 class="modal-title" id="deleteModalLabel">
- Confirmation required
- </h5>
- <button class="close" type="button" data-dismiss="modal" aria-label="Close">
- <span aria-hidden="true">×</span>
- </button>
- </div>
- <div class="modal-body">Do you want to delete the selected item?</div>
- <div class="modal-footer">
- <button class="btn btn-secondary" type="button" data-dismiss="modal">
- Cancel
- </button>
- <a class="btn btn-warning" href="#" onclick="deleteAction()">
- Delete
- </a>
- </div>
- </div>
- </div>
- </div>
- {{end}}
- {{define "extra_js"}}
- <script src="{{.StaticURL}}/vendor/datatables/jquery.dataTables.min.js"></script>
- <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/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.checkboxes.min.js"></script>
- <script type="text/javascript">
- function getIconForFile(filename) {
- var extension = filename.slice((filename.lastIndexOf(".") - 1 >>> 0) + 2).toLowerCase();
- switch (extension) {
- case "doc":
- case "docx":
- case "odt":
- case "wps":
- return "far fa-file-word";
- case "ppt":
- case "pptx":
- return "far fa-file-powerpoint";
- case "xls":
- case "xlsx":
- case "ods":
- return "far fa-file-excel";
- case "pdf":
- return "far fa-file-pdf";
- case "webm":
- case "mkv":
- case "flv":
- case "vob":
- case "ogv":
- case "ogg":
- case "avi":
- case "ts":
- case "mov":
- case "wmv":
- case "asf":
- case "mpeg":
- case "mpv":
- case "3gp":
- return "far fa-file-video";
- case "jpeg":
- case "jpg":
- case "png":
- case "gif":
- case "webp":
- case "tiff":
- case "psd":
- case "bmp":
- case "svg":
- case "jp2":
- return "far fa-file-image";
- case "go":
- case "sh":
- case "bat":
- case "java":
- case "php":
- case "cs":
- case "asp":
- case "aspx":
- case "css":
- case "html":
- case "xhtml":
- case "htm":
- case "js":
- case "jsp":
- case "py":
- case "rb":
- case "cgi":
- case "c":
- case "cpp":
- case "h":
- case "hpp":
- case "kt":
- case "ktm":
- case "kts":
- case "swift":
- case "r":
- return "far fa-file-code";
- case "zip":
- case "zipx":
- case "rar":
- case "tar":
- case "gz":
- case "bz2":
- case "zstd":
- case "zst":
- case "sz":
- case "lz":
- case "lz4":
- case "xz":
- case "jar":
- return "far fa-file-archive";
- case "txt":
- case "rtf":
- case "json":
- case "xml":
- case "yaml":
- case "toml":
- case "log":
- case "csv":
- case "ini":
- case "cfg":
- return "far fa-file-alt";
- default:
- return "far fa-file";
- }
- }
- function getNameFromTypeName(typeName) {
- return typeName.split('_').slice(1).join('_');
- }
- function getTypeFromTypeName(typeName) {
- return typeName.split('_')[0];
- }
- function deleteAction() {
- var table = $('#dataTable').DataTable();
- table.button('delete:name').enable(false);
- var selected = table.column(0).checkboxes.selected()[0];
- var itemType = getTypeFromTypeName(selected);
- var itemName = getNameFromTypeName(selected);
- var path;
- if (itemType == "1"){
- path = '{{.DirsURL}}';
- } else {
- path = '{{.FilesURL}}';
- }
- path+='?path={{.CurrentDir}}'+fixedEncodeURIComponent("/"+itemName);
- $('#deleteModal').modal('hide');
- $.ajax({
- url: path,
- type: 'DELETE',
- dataType: 'json',
- headers: { 'X-CSRF-TOKEN': '{{.CSRFToken}}' },
- timeout: 15000,
- success: function (result) {
- location.reload();
- },
- error: function ($xhr, textStatus, errorThrown) {
- var txt = "Unable to delete the selected item";
- if ($xhr) {
- var json = $xhr.responseJSON;
- if (json) {
- if (json.message) {
- txt = json.message;
- }
- if (json.error) {
- txt += ": " + json.error;
- }
- }
- }
- $('#errorTxt').text(txt);
- $('#errorMsg').show();
- setTimeout(function () {
- $('#errorMsg').hide();
- }, 5000);
- }
- });
- }
- $(document).ready(function () {
- $("#create_dir_form").submit(function (event) {
- event.preventDefault();
- $('#createDirModal').modal('hide');
- var dirName = replaceSlash($("#directory_name").val());
- var path = '{{.DirsURL}}?path={{.CurrentDir}}' + fixedEncodeURIComponent("/"+dirName);
- $.ajax({
- url: path,
- type: 'POST',
- dataType: 'json',
- headers: { 'X-CSRF-TOKEN': '{{.CSRFToken}}' },
- timeout: 15000,
- success: function (result) {
- location.reload();
- },
- error: function ($xhr, textStatus, errorThrown) {
- var txt = "Unable to create the requested directory";
- if ($xhr) {
- var json = $xhr.responseJSON;
- if (json) {
- if (json.message) {
- txt = json.message;
- }
- if (json.error) {
- txt += ": " + json.error;
- }
- }
- }
- $('#errorTxt').text(txt);
- $('#errorMsg').show();
- setTimeout(function () {
- $('#errorMsg').hide();
- }, 5000);
- }
- });
- });
- $("#upload_files_form").submit(function (event){
- event.preventDefault();
- $('uploadFilesModal').modal('hide');
- var path = '{{.FilesURL}}?path={{.CurrentDir}}';
- $.ajax({
- url: path,
- type: 'POST',
- data: new FormData(this),
- processData: false,
- contentType: false,
- headers: { 'X-CSRF-TOKEN': '{{.CSRFToken}}' },
- timeout: 15000,
- success: function (result) {
- location.reload();
- },
- error: function ($xhr, textStatus, errorThrown) {
- var txt = "Error uploading files";
- if ($xhr) {
- var json = $xhr.responseJSON;
- if (json) {
- if (json.message) {
- txt = json.message;
- }
- if (json.error) {
- txt += ": " + json.error;
- }
- }
- }
- $('#errorTxt').text(txt);
- $('#errorMsg').show();
- setTimeout(function () {
- $('#errorMsg').hide();
- }, 5000);
- }
- });
- });
- $("#rename_form").submit(function (event){
- event.preventDefault();
- var table = $('#dataTable').DataTable();
- table.button('rename:name').enable(false);
- var selected = table.column(0).checkboxes.selected()[0];
- var itemType = getTypeFromTypeName(selected);
- var itemName = getNameFromTypeName(selected);
- var targetName = replaceSlash($("#rename_new_name").val());
- var path;
- if (itemType == "1"){
- path = '{{.DirsURL}}';
- } else {
- path = '{{.FilesURL}}';
- }
- path+='?path={{.CurrentDir}}'+fixedEncodeURIComponent("/"+itemName)+'&target={{.CurrentDir}}'+fixedEncodeURIComponent("/"+targetName);
- $('renameModal').modal('hide');
- $.ajax({
- url: path,
- type: 'PATCH',
- dataType: 'json',
- headers: { 'X-CSRF-TOKEN': '{{.CSRFToken}}' },
- timeout: 15000,
- success: function (result) {
- location.reload();
- },
- error: function ($xhr, textStatus, errorThrown) {
- var txt = "Error renaming item";
- if ($xhr) {
- var json = $xhr.responseJSON;
- if (json) {
- if (json.message) {
- txt = json.message;
- }
- if (json.error) {
- txt += ": " + json.error;
- }
- }
- }
- $('#errorTxt').text(txt);
- $('#errorMsg').show();
- setTimeout(function () {
- $('#errorMsg').hide();
- }, 5000);
- }
- });
- });
- $.fn.dataTable.ext.buttons.refresh = {
- text: '<i class="fas fa-sync-alt"></i>',
- name: 'refresh',
- titleAttr: "Refresh",
- action: function (e, dt, node, config) {
- location.reload();
- }
- };
- $.fn.dataTable.ext.buttons.download = {
- text: '<i class="fas fa-download"></i>',
- name: 'download',
- titleAttr: "Download Zip",
- action: function (e, dt, node, config) {
- var filesArray = [];
- var selected = dt.column(0).checkboxes.selected();
- for (i = 0; i < selected.length; i++) {
- filesArray.push(getNameFromTypeName(selected[i]));
- }
- var files = fixedEncodeURIComponent(JSON.stringify(filesArray));
- var downloadURL = '{{.DownloadURL}}';
- var currentDir = '{{.CurrentDir}}';
- window.location = `${downloadURL}?path=${currentDir}&files=${files}`;
- },
- enabled: false
- };
- $.fn.dataTable.ext.buttons.addFiles = {
- text: '<i class="fas fa-file-upload"></i>',
- name: 'addFiles',
- titleAttr: "Upload files",
- action: function (e, dt, node, config) {
- $('#uploadFilesModal').modal('show');
- },
- enabled: true
- };
- $.fn.dataTable.ext.buttons.addDirectory = {
- text: '<i class="fas fa-folder-plus"></i>',
- name: 'addDirectory',
- titleAttr: "Add directory",
- action: function (e, dt, node, config) {
- $("#directory_name").val("");
- $('#createDirModal').modal('show');
- },
- enabled: true
- };
- $.fn.dataTable.ext.buttons.rename = {
- text: '<i class="fas fa-edit"></i>',
- name: 'rename',
- titleAttr: "Rename",
- action: function (e, dt, node, config) {
- var selected = table.column(0).checkboxes.selected()[0];
- var itemName = getNameFromTypeName(selected);
- $("#rename_old_name").val(itemName);
- $("#rename_new_name").val("");
- $('#renameModal').modal('show');
- },
- enabled: false
- };
- $.fn.dataTable.ext.buttons.delete = {
- text: '<i class="fas fa-trash"></i>',
- name: 'delete',
- titleAttr: "Delete",
- action: function (e, dt, node, config) {
- $('#deleteModal').modal('show');
- },
- enabled: false
- };
- var table = $('#dataTable').DataTable({
- "ajax": {
- "url": "{{.DirsURL}}?path={{.CurrentDir}}",
- "dataSrc": "",
- "error": function ($xhr, textStatus, errorThrown) {
- $(".dataTables_processing").hide();
- var txt = "Failed to get directory listing";
- if ($xhr) {
- var json = $xhr.responseJSON;
- if (json) {
- if (json.message){
- txt += ": " + json.message;
- } else {
- txt += ": " + json.error;
- }
- }
- }
- $('#errorTxt').text(txt);
- $('#errorMsg').show();
- setTimeout(function () {
- $('#errorMsg').hide();
- }, 10000);
- }
- },
- "deferRender": true,
- "processing": true,
- "columns": [
- { "data": "type_name" },
- { "data": "type" },
- {
- "data": "name",
- "render": function (data, type, row) {
- if (type === 'display') {
- if (row["type"] == "1") {
- return `<i class="fas fa-folder"></i> <a href="${row['url']}">${data}</a>`;
- }
- if (row["size"] == "") {
- return `<i class="fas fa-external-link-alt"></i> <a href="${row['url']}">${data}</a>`;
- }
- var icon = getIconForFile(data);
- return `<i class="${icon}"></i> <a href="${row['url']}">${data}</a>`;
- }
- return data;
- }
- },
- { "data": "size" },
- { "data": "last_modified" }
- ],
- "buttons": [],
- "lengthChange": false,
- "columnDefs": [
- {
- "targets": [0],
- "checkboxes": {
- "selectCallback": function (nodes, selected) {
- var selectedItems = table.column(0).checkboxes.selected().length;
- var selectedText = "";
- if (selectedItems == 1) {
- selectedText = "1 item selected";
- } else if (selectedItems > 1) {
- selectedText = `${selectedItems} items selected`;
- }
- table.button('download:name').enable(selectedItems > 0);
- {{if .CanRename}}
- table.button('rename:name').enable(selectedItems == 1);
- {{end}}
- {{if .CanDelete}}
- table.button('delete:name').enable(selectedItems == 1);
- {{end}}
- $('#dataTable_info').find('span').remove();
- $("#dataTable_info").append('<span class="selected-info"><span class="selected-item">' + selectedText + '</span></span>');
- }
- },
- "orderable": false,
- "searchable": false
- },
- {
- "targets": [1],
- "visible": false,
- "searchable": false
- },
- {
- "targets": [3, 4],
- "searchable": false
- }
- ],
- "scrollX": false,
- "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 files or folders"
- },
- "initComplete": function (settings, json) {
- table.button().add(0, 'refresh');
- table.button().add(0, 'pageLength');
- table.button().add(0, 'download');
- {{if .CanDelete}}
- table.button().add(0, 'delete');
- {{end}}
- {{if .CanRename}}
- table.button().add(0, 'rename');
- {{end}}
- {{if .CanCreateDirs}}
- table.button().add(0, 'addDirectory');
- {{end}}
- {{if .CanAddFiles}}
- table.button().add(0, 'addFiles');
- {{end}}
- table.buttons().container().appendTo('#dataTable_wrapper .col-md-6:eq(0)');
- },
- "orderFixed": [1, 'asc'],
- "order": [[2, 'asc']]
- });
- new $.fn.dataTable.FixedHeader(table);
- $.fn.dataTable.ext.errMode = 'none';
- });
- </script>
- {{end}}
|