2022-07-17 18:16:00 +00:00
|
|
|
<!--
|
2023-11-04 09:54:52 +00:00
|
|
|
Copyright (C) 2023 Nicola Murino
|
2022-07-17 18:16:00 +00:00
|
|
|
|
2023-11-04 09:54:52 +00:00
|
|
|
This WebUI uses the KeenThemes Mega Bundle, a proprietary theme:
|
2022-07-17 18:16:00 +00:00
|
|
|
|
2023-11-04 09:54:52 +00:00
|
|
|
https://keenthemes.com/products/templates-mega-bundle
|
2022-07-17 18:16:00 +00:00
|
|
|
|
2023-11-04 09:54:52 +00:00
|
|
|
KeenThemes HTML/CSS/JS components are allowed for use only within the
|
|
|
|
SFTPGo product and restricted to be used in a resealable HTML template
|
|
|
|
that can compete with KeenThemes products anyhow.
|
|
|
|
|
|
|
|
This WebUI is allowed for use only within the SFTPGo product and
|
|
|
|
therefore cannot be used in derivative works/products without an
|
|
|
|
explicit grant from the SFTPGo Team (support@sftpgo.com).
|
2022-07-17 18:16:00 +00:00
|
|
|
-->
|
2021-05-06 19:35:43 +00:00
|
|
|
{{template "base" .}}
|
|
|
|
|
2023-11-04 09:54:52 +00:00
|
|
|
{{- define "title"}}{{.Title}}{{- end}}
|
|
|
|
{{- define "page_body"}}
|
|
|
|
{{- template "errmsg" .Error}}
|
|
|
|
<div class="card card-flush shadow-sm">
|
|
|
|
<div class="card-header pt-8">
|
|
|
|
<div class="card-title">
|
|
|
|
<div class="d-flex align-items-center position-relative my-1">
|
|
|
|
<i class="ki-duotone ki-magnifier fs-1 position-absolute ms-6">
|
|
|
|
<span class="path1"></span>
|
|
|
|
<span class="path2"></span>
|
|
|
|
</i>
|
|
|
|
<input type="text" data-kt-filemanager-table-filter="search" class="form-control form-control-solid w-250px ps-15" placeholder="Search Files & Folders" />
|
2023-06-16 19:06:21 +00:00
|
|
|
</div>
|
2021-05-06 19:35:43 +00:00
|
|
|
</div>
|
2023-11-04 09:54:52 +00:00
|
|
|
<div class="card-toolbar">
|
|
|
|
<div class="d-flex justify-content-end" data-kt-filemanager-table-toolbar="base">
|
|
|
|
{{- if .CanCreateDirs}}
|
2023-11-13 21:09:55 +00:00
|
|
|
<button id="id_create_dir_button" type="button" class="btn btn-flex btn-light-primary me-3">
|
2023-11-04 09:54:52 +00:00
|
|
|
<i class="ki-duotone ki-add-folder fs-2">
|
|
|
|
<span class="path1"></span>
|
|
|
|
<span class="path2"></span>
|
|
|
|
</i>
|
|
|
|
New Folder
|
2021-07-26 18:55:49 +00:00
|
|
|
</button>
|
2023-11-04 09:54:52 +00:00
|
|
|
{{- end}}
|
|
|
|
{{- if .CanAddFiles}}
|
|
|
|
<button type="button" class="btn btn-flex btn-primary" data-bs-toggle="modal" data-bs-target="#modal_upload">
|
|
|
|
<i class="ki-duotone ki-folder-up fs-2">
|
|
|
|
<span class="path1"></span>
|
|
|
|
<span class="path2"></span>
|
|
|
|
</i>
|
|
|
|
Upload Files
|
2021-07-26 18:55:49 +00:00
|
|
|
</button>
|
2023-11-04 09:54:52 +00:00
|
|
|
{{- end}}
|
2021-07-26 18:55:49 +00:00
|
|
|
</div>
|
2023-11-04 09:54:52 +00:00
|
|
|
<div class="d-flex justify-content-end align-items-center d-none" data-kt-filemanager-table-toolbar="selected">
|
|
|
|
<div class="fw-bold me-5">
|
|
|
|
<span class="me-2" data-kt-filemanager-table-select="selected_count"></span>
|
2021-07-26 18:55:49 +00:00
|
|
|
</div>
|
2023-11-04 09:54:52 +00:00
|
|
|
<div class="form-check form-switch form-check-custom form-check-solid me-5" data-kt-filemanager-table-select="select_all_pages_container">
|
|
|
|
<input class="form-check-input" type="checkbox" id="id_select_all_pages" data-kt-filemanager-table-select="select_all_pages" />
|
|
|
|
<label class="form-check-label fw-semibold text-gray-900" for="id_select_all_pages">
|
|
|
|
Select across pages
|
|
|
|
</label>
|
2021-07-26 18:55:49 +00:00
|
|
|
</div>
|
2023-11-04 09:54:52 +00:00
|
|
|
{{- if or .CanDownload .CanDelete}}
|
|
|
|
<div>
|
|
|
|
<button type="button" class="btn btn-light-primary rotate" data-kt-menu-trigger="click" data-kt-menu-placement="bottom">
|
|
|
|
Actions
|
|
|
|
<i class="ki-duotone ki-down fs-3 rotate-180 ms-3 me-0"></i>
|
|
|
|
</button>
|
|
|
|
<div class="menu menu-sub menu-sub-dropdown menu-column menu-rounded menu-gray-800 menu-state-bg-light-primary fw-semibold w-auto min-w-200 mw-300px py-4" data-kt-menu="true">
|
|
|
|
{{- if .CanDownload}}
|
|
|
|
<div class="menu-item px-3">
|
|
|
|
<a href="#" class="menu-link px-3 fs-6" data-kt-filemanager-table-select="download_selected">
|
|
|
|
Download
|
|
|
|
</a>
|
|
|
|
</div>
|
|
|
|
{{- end}}
|
2023-11-06 18:10:35 +00:00
|
|
|
{{- if not .ShareUploadBaseURL}}
|
|
|
|
{{- if or .CanRename .CanAddFiles}}
|
|
|
|
<div class="menu-item px-3">
|
|
|
|
<a href="#" class="menu-link px-3 fs-6" data-kt-filemanager-table-select="move_or_copy_selected">
|
|
|
|
Move or copy
|
|
|
|
</a>
|
|
|
|
</div>
|
|
|
|
{{- end}}
|
2023-11-06 17:46:12 +00:00
|
|
|
{{- if .CanShare}}
|
|
|
|
<div class="menu-item px-3">
|
|
|
|
<a href="#" class="menu-link px-3 fs-6" data-kt-filemanager-table-select="share_selected">
|
|
|
|
Share
|
|
|
|
</a>
|
|
|
|
</div>
|
|
|
|
{{- end}}
|
2023-11-06 18:10:35 +00:00
|
|
|
{{- end}}
|
2023-11-04 09:54:52 +00:00
|
|
|
{{- if .CanDelete}}
|
|
|
|
<div class="menu-item px-3">
|
|
|
|
<a href="#" class="menu-link px-3 text-danger fs-6" data-kt-filemanager-table-select="delete_selected">
|
|
|
|
Delete
|
|
|
|
</a>
|
|
|
|
</div>
|
|
|
|
{{- end}}
|
2022-12-30 18:30:16 +00:00
|
|
|
</div>
|
|
|
|
</div>
|
2023-11-04 09:54:52 +00:00
|
|
|
{{- end}}
|
2021-07-26 18:55:49 +00:00
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
2023-11-04 09:54:52 +00:00
|
|
|
<div class="card-body">
|
|
|
|
<div class="d-flex flex-stack">
|
|
|
|
<div class="badge badge-lg badge-light-primary">
|
|
|
|
<div class="d-flex align-items-center flex-wrap">
|
|
|
|
<i class="ki-duotone ki-home fs-1 text-primary me-3"></i>
|
|
|
|
<a href="{{.FilesURL}}?path=%2F">Home</a>
|
|
|
|
{{- range .Paths}}
|
|
|
|
<i class="ki-duotone ki-right fs-2x text-primary mx-1"></i>
|
|
|
|
{{- if eq .Href ""}}
|
|
|
|
<span>{{.DirName}}</span>
|
|
|
|
{{- else}}
|
|
|
|
<a href="{{.Href}}">{{.DirName}}</a>
|
|
|
|
{{- end}}
|
|
|
|
{{- end}}
|
|
|
|
</div>
|
2021-07-26 18:55:49 +00:00
|
|
|
</div>
|
|
|
|
</div>
|
2023-11-04 09:54:52 +00:00
|
|
|
<div id="file_manager_new_folder" class="d-flex align-items-center py-7 d-none">
|
|
|
|
<span>
|
|
|
|
<i class="ki-duotone ki-folder fs-2x text-primary me-4">
|
|
|
|
<span class="path1"></span>
|
|
|
|
<span class="path2"></span>
|
|
|
|
</i>
|
|
|
|
</span>
|
|
|
|
<input id="file_manager_new_folder_input" type="text" name="new_folder_name" placeholder="Enter the new folder name" class="form-control mw-250px me-3" />
|
2023-11-13 21:09:55 +00:00
|
|
|
<button class="btn btn-icon btn-light-primary me-3" id="file_manager_add_folder">
|
2023-11-04 09:54:52 +00:00
|
|
|
<span class="indicator-label">
|
|
|
|
<i class="ki-duotone ki-check fs-1"></i>
|
|
|
|
</span>
|
|
|
|
<span class="indicator-progress">
|
|
|
|
<span class="spinner-border spinner-border-sm align-middle"></span>
|
|
|
|
</span>
|
|
|
|
</button>
|
2023-11-13 21:09:55 +00:00
|
|
|
<button class="btn btn-icon btn-light-danger" id="file_manager_cancel_folder">
|
2023-11-04 09:54:52 +00:00
|
|
|
<i class="ki-duotone ki-cross fs-1">
|
|
|
|
<span class="path1"></span>
|
|
|
|
<span class="path2"></span>
|
|
|
|
</i>
|
|
|
|
</button>
|
2022-07-21 16:42:22 +00:00
|
|
|
</div>
|
2023-11-04 09:54:52 +00:00
|
|
|
<table id="file_manager_list" class="table align-middle table-row-dashed fs-6 gy-5">
|
|
|
|
<thead>
|
|
|
|
<tr class="text-start text-muted fw-bold fs-6 gs-0">
|
|
|
|
<th class="w-10px pe-2">
|
|
|
|
<div class="form-check form-check-sm form-check-custom form-check-solid me-3">
|
|
|
|
<input id="select_checkbox" class="form-check-input" type="checkbox"/>
|
|
|
|
</div>
|
|
|
|
</th>
|
|
|
|
<th></th>
|
|
|
|
<th class="min-w-250px">Name</th>
|
|
|
|
<th class="min-w-10px">Size</th>
|
|
|
|
<th class="min-w-125px">Last Modified</th>
|
|
|
|
<th class="w-125px"></th>
|
|
|
|
</tr>
|
|
|
|
</thead>
|
|
|
|
<tbody id="file_manager_list_body" class="text-gray-700 fw-semibold">
|
|
|
|
</tbody>
|
|
|
|
</table>
|
2022-07-21 16:42:22 +00:00
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
|
2023-11-04 09:54:52 +00:00
|
|
|
{{- end}}
|
|
|
|
|
|
|
|
{{- define "extra_css"}}
|
|
|
|
<link href="{{.StaticURL}}/assets/plugins/custom/datatables/datatables.bundle.css" rel="stylesheet" type="text/css"/>
|
|
|
|
<link href="{{.StaticURL}}/vendor/glightbox/glightbox.min.css" rel="stylesheet" type="text/css"/>
|
2023-11-15 17:48:16 +00:00
|
|
|
<style {{- if .CSPNonce}} nonce="{{.CSPNonce}}"{{- end}}>
|
2023-11-04 09:54:52 +00:00
|
|
|
.gslide-description-bg {
|
|
|
|
background: var(--bs-app-bg-color) !important;
|
|
|
|
opacity: 0.9;
|
|
|
|
}
|
|
|
|
</style>
|
|
|
|
{{- end}}
|
|
|
|
|
|
|
|
{{- define "extra_js"}}
|
|
|
|
<script src="{{.StaticURL}}/assets/plugins/custom/datatables/datatables.bundle.js"></script>
|
|
|
|
<script src="{{.StaticURL}}/vendor/glightbox/glightbox.min.js"></script>
|
2021-11-25 18:24:32 +00:00
|
|
|
<script src="{{.StaticURL}}/vendor/pdfobject/pdfobject.min.js"></script>
|
2023-11-15 17:48:16 +00:00
|
|
|
<script type="text/javascript" {{- if .CSPNonce}} nonce="{{.CSPNonce}}"{{- end}}>
|
2023-11-16 17:55:14 +00:00
|
|
|
//{{- if not .ShareUploadBaseURL}}
|
2023-11-04 09:54:52 +00:00
|
|
|
const supportedEditExtensions = ["csv", "bat", "dyalog", "apl", "asc", "pgp", "sig", "asn", "asn1", "b", "bf",
|
|
|
|
"c", "h", "ino", "cpp", "c++", "cc", "cxx", "hpp", "h++", "hh", "hxx", "cob", "cpy", "cbl", "cs", "clj",
|
|
|
|
"cljc", "cljx", "cljs", "gss", "cmake", "cmake.in", "coffee", "cl", "lisp", "el", "cyp", "cypher",
|
|
|
|
"pyx", "pxd", "pxi", "cr", "css", "cql", "d", "dart", "diff", "patch", "dtd", "dylan", "dyl", "intr",
|
|
|
|
"ecl", "edn", "e", "elm", "ejs", "erb", "erl", "sql", "factor", "forth", "fth", "4th", "f", "for", "f77",
|
|
|
|
"f90", "f95", "fsharp", "s", "go", "groovy", "gradle", "haml", "hs", "lhs", "hx", "hxml", "aspx",
|
|
|
|
"html", "htm", "handlebars", "hbs", "pro", "jade", "pug", "java", "jsp", "js", "json", "map", "jsonld",
|
|
|
|
"jsx", "j2", "jinja", "jinja2", "jl", "kt", "less", "ls", "lua", "markdown", "md", "mkd", "m", "nb", "wl",
|
|
|
|
"wls", "mo", "mps", "mbox", "nsh", "nsi", "nt", "nq", "m", "mm", "ml", "mli", "mll", "mly", "oz", "p",
|
|
|
|
"pas", "pl", "pm", "php", "php3", "php4", "php5", "php7", "phtml", "pig", "txt", "text", "conf", "def",
|
|
|
|
"list", "log", "pls", "ps1", "psd1", "psm1", "properties", "ini", "in", "proto", "BUILD", "bzl", "py",
|
|
|
|
"pyw", "pp", "q", "r", "rst", "spec", "rb", "rs", "sas", "sass", "scala", "scm", "ss", "scss", "sh",
|
|
|
|
"ksh", "bash", "siv", "sieve", "slim", "st", "tpl", "sml", "sig", "fun", "smackspec", "soy", "rq", "sparql",
|
|
|
|
"nut", "styl", "swift", "text", "ltx", "tex", "v", "sv", "svh", "tcl", "textile", "toml", "1", "2", "3", "4",
|
|
|
|
"5", "6", "7", "8", "9", "ttcn", "ttcn3", "ttcnpp", "cfg", "ttl", "ts", "tsx", "webidl", "vb", "vbs",
|
|
|
|
"vtl", "vhd", "vhdl", "vue", "xml", "xsl", "xsd", "svg", "xy", "xquery", "ys", "yaml", "yml", "z80",
|
|
|
|
"mscgen", "mscin", "msc", "xu", "msgenny", "wat", "wast"];
|
|
|
|
const supportedEditFilenames = ["readme", "dockerfile", "pkgbuild"]
|
2023-11-16 17:55:14 +00:00
|
|
|
//{{- end}}
|
2023-11-04 09:54:52 +00:00
|
|
|
function keepAlive() {
|
|
|
|
//{{- if not .ShareUploadBaseURL}}
|
2023-11-06 18:58:39 +00:00
|
|
|
axios.get('{{.PingURL}}',{
|
|
|
|
timeout: 15000,
|
|
|
|
responseType: 'text'
|
2023-11-04 09:54:52 +00:00
|
|
|
}).catch(function (error){});
|
|
|
|
//{{- end}}
|
2021-12-03 17:33:08 +00:00
|
|
|
}
|
|
|
|
|
2023-11-04 09:54:52 +00:00
|
|
|
//{{- if not .ShareUploadBaseURL}}
|
|
|
|
var KTDatatablesFoldersExplorer = function () {
|
|
|
|
var dt;
|
|
|
|
var curDir;
|
|
|
|
|
|
|
|
var initDatatable = function (dirsURL) {
|
|
|
|
$('#errorModalMsg').addClass("d-none");
|
|
|
|
dt = $("#dirsbrowser_list").DataTable({
|
|
|
|
ajax: {
|
|
|
|
url: dirsURL,
|
|
|
|
dataSrc: "",
|
|
|
|
error: function ($xhr, textStatus, errorThrown) {
|
|
|
|
$(".dataTables_processing").hide();
|
|
|
|
let txt = "Failed to get directory listing";
|
|
|
|
if ($xhr) {
|
|
|
|
let json = $xhr.responseJSON;
|
|
|
|
if (json) {
|
|
|
|
if (json.message) {
|
|
|
|
txt += ": " + json.message;
|
|
|
|
} else {
|
|
|
|
txt += ": " + json.error;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
$('#errorModalTxt').text(txt);
|
|
|
|
$('#errorModalMsg').removeClass("d-none");
|
|
|
|
}
|
|
|
|
},
|
|
|
|
deferRender: true,
|
|
|
|
processing: true,
|
|
|
|
stateSave: false,
|
|
|
|
columns: [
|
|
|
|
{
|
|
|
|
data: "meta"
|
|
|
|
},
|
|
|
|
{
|
|
|
|
data: "name",
|
|
|
|
render: function (data, type, row) {
|
|
|
|
if (type === 'display') {
|
|
|
|
data = escapeHTML(data);
|
|
|
|
return `<div class="d-flex align-items-center">
|
|
|
|
<i class="ki-duotone ki-folder fs-1 text-primary me-4">
|
|
|
|
<i class="path1"></i>
|
|
|
|
<i class="path2"></i>
|
|
|
|
</i>
|
2023-11-16 17:55:14 +00:00
|
|
|
<a href="#" class="text-gray-700 text-hover-primary" data-dirbrowser-table-row="open">${data}</a>
|
2023-11-04 09:54:52 +00:00
|
|
|
</div>`
|
|
|
|
}
|
|
|
|
return data;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
],
|
|
|
|
lengthChange: true,
|
|
|
|
columnDefs: [
|
|
|
|
{
|
|
|
|
targets: 0,
|
|
|
|
visible: false,
|
|
|
|
searchable: false
|
|
|
|
},
|
|
|
|
{
|
|
|
|
targets: 1,
|
|
|
|
visible: true,
|
|
|
|
searchable: true
|
|
|
|
}
|
|
|
|
],
|
|
|
|
language: {
|
|
|
|
loadingRecords: "",
|
|
|
|
emptyTable: "No more subfolders in here"
|
|
|
|
},
|
|
|
|
order: [1, 'asc']
|
|
|
|
});
|
2021-12-08 18:25:22 +00:00
|
|
|
|
2023-11-04 09:54:52 +00:00
|
|
|
dt.on('draw', function () {
|
2023-11-16 17:55:14 +00:00
|
|
|
let dirBrowserNav = document.getElementById("dirs_browser_nav");
|
2023-11-18 19:06:31 +00:00
|
|
|
clearChilds(dirBrowserNav);
|
2023-11-16 17:55:14 +00:00
|
|
|
let mainNavIcon = document.createElement("i");
|
|
|
|
mainNavIcon.classList.add("ki-duotone", "ki-home", "fs-1", "text-primary", "me-3");
|
|
|
|
let mainNavLink = document.createElement("a");
|
|
|
|
mainNavLink.textContent = "Home";
|
|
|
|
mainNavLink.href = "#";
|
|
|
|
mainNavLink.addEventListener("click", function(e){
|
|
|
|
e.preventDefault();
|
|
|
|
onDirBrowserClick("%2F");
|
|
|
|
});
|
|
|
|
dirBrowserNav.appendChild(mainNavIcon);
|
|
|
|
dirBrowserNav.appendChild(mainNavLink);
|
|
|
|
|
2023-11-04 09:54:52 +00:00
|
|
|
let p = "/";
|
|
|
|
if (curDir && curDir != "%2F") {
|
|
|
|
p = decodeURIComponent(curDir.replace(/\+/g, '%20'));
|
|
|
|
const dirPaths = p.split("/");
|
|
|
|
let fullPath = "%2F";
|
|
|
|
for (idx in dirPaths) {
|
|
|
|
let dir = dirPaths[idx];
|
|
|
|
if (dir) {
|
|
|
|
if (fullPath.endsWith("%2F")){
|
|
|
|
fullPath += encodeURIComponent(dir);
|
|
|
|
} else {
|
|
|
|
fullPath += encodeURIComponent("/" + dir);
|
|
|
|
}
|
|
|
|
dir = escapeHTML(dir);
|
2023-11-16 17:55:14 +00:00
|
|
|
let navIcon = document.createElement("i");
|
|
|
|
navIcon.classList.add("ki-duotone", "ki-right", "fs-2x", "text-primary", "mx-1");
|
|
|
|
let navLink = document.createElement("a");
|
|
|
|
navLink.textContent = dir;
|
|
|
|
navLink.href = "#";
|
|
|
|
let pathCopy = fullPath
|
|
|
|
navLink.addEventListener("click", function(e){
|
|
|
|
e.preventDefault();
|
|
|
|
onDirBrowserClick(pathCopy);
|
|
|
|
});
|
|
|
|
dirBrowserNav.appendChild(navIcon);
|
|
|
|
dirBrowserNav.appendChild(navLink);
|
2023-11-04 09:54:52 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2023-11-16 17:55:14 +00:00
|
|
|
|
2023-11-04 09:54:52 +00:00
|
|
|
$('#move_copy_folder').val(p);
|
2023-11-16 17:55:14 +00:00
|
|
|
handleRowActions();
|
2023-11-04 09:54:52 +00:00
|
|
|
});
|
2021-12-03 17:33:08 +00:00
|
|
|
}
|
|
|
|
|
2023-11-04 09:54:52 +00:00
|
|
|
var handleCreateNewFolder = function() {
|
|
|
|
$('#dirsbrowser_add_folder').click(function(){
|
|
|
|
let errDivEl = $('#errorModalMsg');
|
|
|
|
let errTxtEl = $('#errorModalTxt');
|
|
|
|
let dirName = replaceSlash($("#dirsbrowser_new_folder_input").val());
|
|
|
|
let submitButton = document.querySelector('#dirsbrowser_add_folder');
|
2023-11-06 18:10:35 +00:00
|
|
|
let cancelButton = document.querySelector('#dirsbrowser_cancel_folder');
|
2023-11-04 09:54:52 +00:00
|
|
|
errDivEl.addClass("d-none");
|
|
|
|
if (!dirName){
|
|
|
|
errTxtEl.text("Folder name is required");
|
|
|
|
errDivEl.removeClass("d-none");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
let path = '{{.DirsURL}}?path='+ curDir + encodeURIComponent("/"+dirName);
|
|
|
|
submitButton.setAttribute('data-kt-indicator', 'on');
|
|
|
|
submitButton.disabled = true;
|
2023-11-06 18:10:35 +00:00
|
|
|
cancelButton.disabled = true;
|
2023-11-04 09:54:52 +00:00
|
|
|
|
|
|
|
axios.post(path, null, {
|
|
|
|
timeout: 15000,
|
|
|
|
headers: {
|
|
|
|
'X-CSRF-TOKEN': '{{.CSRFToken}}'
|
|
|
|
},
|
|
|
|
validateStatus: function (status) {
|
|
|
|
return status == 201;
|
|
|
|
}
|
|
|
|
}).then(function (response) {
|
|
|
|
dt.ajax.reload();
|
|
|
|
errDivEl.addClass("d-none");
|
|
|
|
submitButton.removeAttribute('data-kt-indicator');
|
|
|
|
submitButton.disabled = false;
|
2023-11-06 18:10:35 +00:00
|
|
|
cancelButton.disabled = false;
|
2023-11-04 09:54:52 +00:00
|
|
|
$('#dirsbrowser_new_folder').addClass("d-none");
|
|
|
|
}).catch(function (error) {
|
|
|
|
let errorMessage = "Unable to create the new folder";
|
|
|
|
if (error && error.response) {
|
|
|
|
if (error.response.data.message) {
|
|
|
|
errorMessage = error.response.data.message;
|
|
|
|
}
|
|
|
|
if (error.response.data.error) {
|
|
|
|
errorMessage += ": " + error.response.data.error;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
errTxtEl.text(errorMessage);
|
|
|
|
errDivEl.removeClass("d-none");
|
|
|
|
submitButton.removeAttribute('data-kt-indicator');
|
|
|
|
submitButton.disabled = false;
|
2023-11-06 18:10:35 +00:00
|
|
|
cancelButton.disabled = false;
|
2023-11-04 09:54:52 +00:00
|
|
|
});
|
|
|
|
});
|
2021-12-03 17:33:08 +00:00
|
|
|
}
|
2023-11-04 09:54:52 +00:00
|
|
|
|
2023-11-16 17:55:14 +00:00
|
|
|
function handleRowActions(){
|
|
|
|
const openLinks = document.querySelectorAll('[data-dirbrowser-table-row="open"]');
|
|
|
|
|
|
|
|
openLinks.forEach(d => {
|
|
|
|
d.addEventListener("click", function(e){
|
|
|
|
e.preventDefault();
|
|
|
|
const parent = e.target.closest('tr');
|
|
|
|
onDirBrowserClick(dt.row(parent).data()['dir_path']);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2023-11-04 09:54:52 +00:00
|
|
|
return {
|
|
|
|
init: function (url, dirPath) {
|
|
|
|
curDir = dirPath;
|
|
|
|
if (dt) {
|
|
|
|
dt.ajax.url(url).load();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
initDatatable(url);
|
|
|
|
handleCreateNewFolder();
|
|
|
|
}
|
2021-12-03 17:33:08 +00:00
|
|
|
}
|
2023-11-04 09:54:52 +00:00
|
|
|
}();
|
|
|
|
//{{- end}}
|
|
|
|
</script>
|
|
|
|
|
2023-11-15 17:48:16 +00:00
|
|
|
<script type="text/javascript" {{- if .CSPNonce}} nonce="{{.CSPNonce}}"{{- end}}>
|
2023-11-04 09:54:52 +00:00
|
|
|
var KTDatatablesServerSide = function () {
|
|
|
|
// Shared variables
|
|
|
|
//var table;
|
|
|
|
var dt;
|
|
|
|
var lightbox;
|
|
|
|
|
|
|
|
|
|
|
|
// Private functions
|
|
|
|
var initDatatable = function () {
|
|
|
|
$('#errorMsg').addClass("d-none");
|
|
|
|
dt = $("#file_manager_list").DataTable({
|
|
|
|
ajax: {
|
|
|
|
url: "{{.DirsURL}}?path={{.CurrentDir}}",
|
|
|
|
dataSrc: "",
|
|
|
|
error: function ($xhr, textStatus, errorThrown) {
|
|
|
|
$(".dataTables_processing").hide();
|
|
|
|
let txt = "Failed to get directory listing";
|
|
|
|
if ($xhr) {
|
|
|
|
let json = $xhr.responseJSON;
|
|
|
|
if (json) {
|
|
|
|
if (json.message){
|
|
|
|
txt += ": " + json.message;
|
|
|
|
} else {
|
|
|
|
txt += ": " + json.error;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
$('#errorTxt').text(txt);
|
|
|
|
$('#errorMsg').removeClass("d-none");
|
|
|
|
}
|
|
|
|
},
|
|
|
|
deferRender: true,
|
|
|
|
processing: true,
|
|
|
|
lengthMenu: [ 10, 25, 50, 100, 250, 500 ],
|
|
|
|
select: {
|
|
|
|
style: 'multi',
|
|
|
|
selector: 'td:first-child input[type="checkbox"]',
|
|
|
|
className: 'row-selected'
|
|
|
|
},
|
|
|
|
stateSave: true,
|
|
|
|
stateDuration: 0,
|
|
|
|
stateSaveParams: function (settings, data) {
|
|
|
|
data.sftpgo_dir = '{{.CurrentDir}}';
|
|
|
|
},
|
|
|
|
stateLoadParams: function (settings, data) {
|
|
|
|
if (!data.sftpgo_dir || data.sftpgo_dir != '{{.CurrentDir}}'){
|
|
|
|
data.start = 0;
|
|
|
|
data.search.search = "";
|
|
|
|
}
|
|
|
|
if (data.search.search){
|
|
|
|
const filterSearch = document.querySelector('[data-kt-filemanager-table-filter="search"]');
|
|
|
|
filterSearch.value = data.search.search;
|
2021-12-08 18:25:22 +00:00
|
|
|
}
|
2023-11-04 09:54:52 +00:00
|
|
|
},
|
|
|
|
columns: [
|
|
|
|
{
|
|
|
|
data: "meta",
|
|
|
|
render: function (data, type) {
|
|
|
|
if (type == 'display'){
|
|
|
|
return `
|
|
|
|
<div class="form-check form-check-sm form-check-custom form-check-solid">
|
|
|
|
<input class="form-check-input" type="checkbox" />
|
|
|
|
</div>`;
|
|
|
|
}
|
|
|
|
return data;
|
2021-12-08 18:25:22 +00:00
|
|
|
}
|
2023-11-04 09:54:52 +00:00
|
|
|
},
|
|
|
|
{ data: "type" },
|
|
|
|
{
|
|
|
|
data: "name",
|
|
|
|
render: function (data, type, row) {
|
|
|
|
if (type === 'display') {
|
|
|
|
data = escapeHTML(data);
|
|
|
|
let icon_name = "ki-file";
|
|
|
|
|
|
|
|
if (row["type"] == "1") {
|
|
|
|
icon_name = "ki-folder";
|
|
|
|
} else if (row["size"] === "") {
|
|
|
|
icon_name = "ki-file-right"
|
|
|
|
}
|
|
|
|
|
|
|
|
return `<div class="d-flex align-items-center">
|
|
|
|
<i class="ki-duotone ${icon_name} fs-2x text-primary me-4">
|
|
|
|
<i class="path1"></i>
|
|
|
|
<i class="path2"></i>
|
|
|
|
</i>
|
|
|
|
<a href="${row['url']}" class="text-gray-800 text-hover-primary">${data}</a>
|
|
|
|
</div>`
|
|
|
|
}
|
|
|
|
return data;
|
2021-12-08 18:25:22 +00:00
|
|
|
}
|
2023-11-04 09:54:52 +00:00
|
|
|
},
|
|
|
|
{
|
|
|
|
data: "size",
|
|
|
|
render: function (data, type) {
|
|
|
|
if (type === 'display') {
|
|
|
|
if (data || data === 0){
|
|
|
|
return fileSizeIEC(data);
|
|
|
|
}
|
|
|
|
return "";
|
|
|
|
}
|
|
|
|
return data;
|
2021-12-08 18:25:22 +00:00
|
|
|
}
|
2023-11-04 09:54:52 +00:00
|
|
|
},
|
|
|
|
{ data: "last_modified" },
|
|
|
|
{
|
|
|
|
data: "edit_url",
|
|
|
|
className: 'text-end',
|
|
|
|
render: function (data, type, row) {
|
|
|
|
if (type === 'display') {
|
|
|
|
let previewDiv = "";
|
|
|
|
if (row["type"] == "2") {
|
|
|
|
let filename = escapeHTML(row["name"]);
|
|
|
|
let extension = filename.slice((filename.lastIndexOf(".") - 1 >>> 0) + 2).toLowerCase();
|
|
|
|
switch (extension) {
|
|
|
|
case "jpeg":
|
|
|
|
case "jpg":
|
|
|
|
case "png":
|
|
|
|
case "gif":
|
|
|
|
case "webp":
|
|
|
|
case "bmp":
|
|
|
|
case "svg":
|
|
|
|
case "ico":
|
|
|
|
let desc = escapeHTML(filename).replace(/"/g, '"');
|
|
|
|
previewDiv = `<div class="ms-2" data-kt-filemanger-table="view_item">
|
|
|
|
<a href="${row['url']}" data-gallery="gallery" data-glightbox="description: <span class="fs-5 fw-bold">${desc}</span>" class="btn btn-sm btn-icon btn-light btn-active-light-primary glightbox">
|
|
|
|
<i class="ki-duotone ki-eye fs-5 m-0">
|
|
|
|
<span class="path1"></span>
|
|
|
|
<span class="path2"></span>
|
|
|
|
<span class="path3"></span>
|
|
|
|
</i>
|
|
|
|
</a>
|
|
|
|
</div>`;
|
|
|
|
break;
|
|
|
|
case "mp4":
|
|
|
|
case "mov":
|
|
|
|
case "webm":
|
|
|
|
case "ogv":
|
|
|
|
case "ogg":
|
|
|
|
case "mp3":
|
|
|
|
case "wav":
|
|
|
|
previewDiv = `<div class="ms-2" data-kt-filemanger-table="view_item">
|
2023-11-16 17:55:14 +00:00
|
|
|
<a href="#" class="btn btn-sm btn-icon btn-light btn-active-light-primary" data-kt-filemanager-table-action="view_media">
|
2023-11-04 09:54:52 +00:00
|
|
|
<i class="ki-duotone ki-eye fs-5 m-0">
|
|
|
|
<span class="path1"></span>
|
|
|
|
<span class="path2"></span>
|
|
|
|
<span class="path3"></span>
|
|
|
|
</i>
|
|
|
|
</a>
|
|
|
|
</div>`;
|
|
|
|
break;
|
|
|
|
case "pdf":
|
|
|
|
if (PDFObject.supportsPDFs){
|
|
|
|
let view_url = row['url'];
|
|
|
|
view_url = view_url.replace('{{.FilesURL}}','{{.ViewPDFURL}}');
|
|
|
|
previewDiv = `<div class="ms-2" data-kt-filemanger-table="view_item">
|
|
|
|
<a href="${view_url}" target="_blank" class="btn btn-sm btn-icon btn-light btn-active-light-primary">
|
|
|
|
<i class="ki-duotone ki-eye fs-5 m-0">
|
|
|
|
<span class="path1"></span>
|
|
|
|
<span class="path2"></span>
|
|
|
|
<span class="path3"></span>
|
|
|
|
</i>
|
|
|
|
</a>
|
|
|
|
</div>`;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
//{{- if not .ShareUploadBaseURL}}
|
|
|
|
if (data && (supportedEditExtensions.includes(extension) || supportedEditFilenames.includes(filename.toLowerCase()))){
|
|
|
|
previewDiv = `<div class="ms-2" data-kt-filemanger-table="view_item">
|
|
|
|
<a href="${data}" target="_blank" class="btn btn-sm btn-icon btn-light btn-active-light-primary">
|
|
|
|
<i class="ki-duotone ki-eye fs-5 m-0">
|
|
|
|
<span class="path1"></span>
|
|
|
|
<span class="path2"></span>
|
|
|
|
<span class="path3"></span>
|
|
|
|
</i>
|
|
|
|
</a>
|
|
|
|
</div>`;
|
|
|
|
}
|
|
|
|
//{{- end}}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
let more = `{{- if not .ShareUploadBaseURL}}
|
|
|
|
{{- if or .CanRename .CanAddFiles .CanShare .CanDelete }}
|
|
|
|
<div class="ms-2">
|
|
|
|
<button type="button" class="btn btn-sm btn-icon btn-light btn-active-light-primary" data-kt-menu-trigger="click" data-kt-menu-placement="bottom-end">
|
|
|
|
<i class="ki-duotone ki-dots-square fs-5 m-0">
|
|
|
|
<span class="path1"></span>
|
|
|
|
<span class="path2"></span>
|
|
|
|
<span class="path3"></span>
|
|
|
|
<span class="path4"></span>
|
|
|
|
</i>
|
|
|
|
</button>
|
|
|
|
<div class="menu menu-sub menu-sub-dropdown menu-column menu-rounded menu-gray-700 menu-state-bg-light-primary fw-semibold fs-7 w-150px py-4" data-kt-menu="true">
|
|
|
|
{{- if .CanRename}}
|
|
|
|
<div class="menu-item px-3">
|
2023-11-16 17:55:14 +00:00
|
|
|
<a href="#" class="menu-link px-3" data-kt-filemanager-table-action="rename">Rename</a>
|
2023-11-04 09:54:52 +00:00
|
|
|
</div>
|
|
|
|
{{- end}}
|
|
|
|
{{- if or .CanRename .CanAddFiles}}
|
|
|
|
<div class="menu-item px-3">
|
2023-11-16 17:55:14 +00:00
|
|
|
<a href="#" class="menu-link px-3" data-kt-filemanager-table-action="move_or_copy">Move or copy</a>
|
2023-11-04 09:54:52 +00:00
|
|
|
</div>
|
|
|
|
{{- end}}
|
|
|
|
{{- if .CanShare}}
|
|
|
|
<div class="menu-item px-3">
|
2023-11-16 17:55:14 +00:00
|
|
|
<a href="#" class="menu-link px-3" data-kt-filemanager-table-action="share">Share</a>
|
2023-11-04 09:54:52 +00:00
|
|
|
</div>
|
|
|
|
{{- end}}
|
|
|
|
{{- if .CanDelete}}
|
|
|
|
<div class="menu-item px-3">
|
2023-11-16 17:55:14 +00:00
|
|
|
<a href="#" class="menu-link text-danger px-3" data-kt-filemanager-table-action="delete">Delete</a>
|
2023-11-04 09:54:52 +00:00
|
|
|
</div>
|
|
|
|
{{- end}}
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
{{- end}}
|
|
|
|
{{- end}}`;
|
|
|
|
return `<div class="d-flex justify-content-end">
|
|
|
|
${previewDiv}
|
|
|
|
${more}
|
|
|
|
</div>
|
|
|
|
`;
|
|
|
|
}
|
|
|
|
return "";
|
2021-12-08 18:25:22 +00:00
|
|
|
}
|
|
|
|
}
|
2023-11-04 09:54:52 +00:00
|
|
|
],
|
|
|
|
lengthChange: true,
|
|
|
|
columnDefs: [
|
|
|
|
{
|
|
|
|
targets: 0,
|
|
|
|
orderable: false,
|
|
|
|
searchable: false,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
targets: 1,
|
|
|
|
visible: false,
|
|
|
|
searchable: false
|
|
|
|
},
|
|
|
|
{
|
|
|
|
targets: 2,
|
|
|
|
visible: true,
|
|
|
|
searchable: true
|
|
|
|
},
|
|
|
|
{
|
|
|
|
targets: [3,4],
|
|
|
|
searchable: false
|
|
|
|
},
|
|
|
|
{
|
|
|
|
targets: 5,
|
|
|
|
orderable: false,
|
|
|
|
searchable: false
|
2021-12-08 18:25:22 +00:00
|
|
|
}
|
2023-11-04 09:54:52 +00:00
|
|
|
],
|
|
|
|
language: {
|
|
|
|
loadingRecords: "",
|
|
|
|
emptyTable: "No files or folders"
|
|
|
|
},
|
|
|
|
orderFixed: [1, 'asc'],
|
|
|
|
order: [2, 'asc']
|
|
|
|
});
|
|
|
|
|
|
|
|
//table = dt.$;
|
|
|
|
|
|
|
|
dt.on('draw', function () {
|
|
|
|
lightbox.reload();
|
|
|
|
KTMenu.createInstances();
|
|
|
|
|
|
|
|
let targets = document.querySelectorAll('#file_manager_list_body tr');
|
|
|
|
if (targets) {
|
|
|
|
KTUtil.each(targets, function (target) {
|
|
|
|
if (!target){
|
|
|
|
return;
|
2021-12-03 17:33:08 +00:00
|
|
|
}
|
2023-11-04 09:54:52 +00:00
|
|
|
let checkbox = target.querySelector('.form-check-input');
|
|
|
|
if (!checkbox) {
|
|
|
|
return;
|
2021-12-08 18:25:22 +00:00
|
|
|
}
|
2023-11-04 09:54:52 +00:00
|
|
|
if (target.classList.contains('row-selected')) {
|
|
|
|
checkbox.checked = true;
|
|
|
|
} else {
|
|
|
|
checkbox.checked = false;
|
2021-12-08 18:25:22 +00:00
|
|
|
}
|
2023-11-04 09:54:52 +00:00
|
|
|
});
|
2021-12-08 18:25:22 +00:00
|
|
|
}
|
2023-11-04 09:54:52 +00:00
|
|
|
toggleToolbars();
|
2023-11-16 17:55:14 +00:00
|
|
|
handleRowActions();
|
2023-11-04 09:54:52 +00:00
|
|
|
});
|
2021-12-08 18:25:22 +00:00
|
|
|
|
2023-11-04 09:54:52 +00:00
|
|
|
dt.on('user-select', function(e, dt, type, cell, originalEvent){
|
|
|
|
let pageSelected = dt.rows({ selected: true, page: 'current' }).count();
|
|
|
|
let totalSelected = dt.rows({ selected: true, search: 'applied' }).count();
|
|
|
|
if (totalSelected > pageSelected){
|
|
|
|
let currentIndexes = [];
|
|
|
|
dt.rows({ page: 'current' }).every(function (rowIdx, tableLoop, rowLoop){
|
|
|
|
currentIndexes.push(rowIdx);
|
|
|
|
});
|
|
|
|
|
|
|
|
dt.rows().deselect();
|
|
|
|
currentIndexes.forEach((idx) => {
|
|
|
|
dt.row(idx).select();
|
|
|
|
});
|
|
|
|
|
|
|
|
totalSelected = dt.rows({ selected: true, search: 'applied' }).count();
|
|
|
|
}
|
|
|
|
if ($(originalEvent.target).is(':checked')){
|
|
|
|
pageSelected++;
|
|
|
|
totalSelected++;
|
|
|
|
} else {
|
|
|
|
pageSelected--;
|
|
|
|
totalSelected--;
|
|
|
|
}
|
2021-12-03 17:33:08 +00:00
|
|
|
|
2023-11-04 09:54:52 +00:00
|
|
|
handleToogleToolbar(pageSelected, totalSelected);
|
|
|
|
});
|
2021-12-03 17:33:08 +00:00
|
|
|
}
|
|
|
|
|
2023-11-04 09:54:52 +00:00
|
|
|
function handleToogleToolbar(pageSelected, totalSelected) {
|
|
|
|
const toolbarBase = document.querySelector('[data-kt-filemanager-table-toolbar="base"]');
|
|
|
|
const toolbarSelected = document.querySelector('[data-kt-filemanager-table-toolbar="selected"]');
|
|
|
|
const selectedCount = document.querySelector('[data-kt-filemanager-table-select="selected_count"]');
|
|
|
|
const selectAllContainer = document.querySelector('[data-kt-filemanager-table-select="select_all_pages_container"]');
|
|
|
|
const selectAllCheck = document.querySelector('[data-kt-filemanager-table-select="select_all_pages"]');
|
|
|
|
|
|
|
|
if (pageSelected > 0) {
|
|
|
|
let pageTotal = dt.rows({ page: 'current' }).count();
|
|
|
|
if (pageSelected === pageTotal){
|
|
|
|
selectAllContainer.classList.remove("d-none");
|
|
|
|
$('#select_checkbox').prop("checked", true);
|
|
|
|
} else {
|
|
|
|
$('#select_checkbox').prop("checked", false);
|
|
|
|
selectAllCheck.checked = false;
|
|
|
|
selectAllContainer.classList.add('d-none');
|
|
|
|
}
|
|
|
|
if (selectedCount){
|
|
|
|
selectedCount.innerHTML = `${totalSelected} Selected`;
|
|
|
|
}
|
|
|
|
if (toolbarBase){
|
|
|
|
toolbarBase.classList.add('d-none');
|
|
|
|
}
|
|
|
|
if (toolbarSelected){
|
|
|
|
toolbarSelected.classList.remove('d-none');
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
$('#select_checkbox').prop("checked", false);
|
|
|
|
selectAllCheck.checked = false;
|
|
|
|
if (toolbarBase) {
|
|
|
|
toolbarBase.classList.remove('d-none');
|
|
|
|
}
|
|
|
|
if (toolbarBase) {
|
|
|
|
toolbarSelected.classList.add('d-none');
|
|
|
|
}
|
|
|
|
}
|
2021-12-03 17:33:08 +00:00
|
|
|
}
|
2021-05-27 07:40:46 +00:00
|
|
|
|
2023-11-16 17:55:14 +00:00
|
|
|
function handleRowActions() {
|
|
|
|
const renameButtons = document.querySelectorAll('[data-kt-filemanager-table-action="rename"]');
|
|
|
|
|
|
|
|
renameButtons.forEach(d => {
|
|
|
|
d.addEventListener("click", function(e){
|
|
|
|
e.preventDefault();
|
|
|
|
const parent = e.target.closest('tr');
|
|
|
|
renameItem(dt.row(parent).data()["meta"]);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
const moveCopyButtons = document.querySelectorAll('[data-kt-filemanager-table-action="move_or_copy"]');
|
|
|
|
|
|
|
|
moveCopyButtons.forEach(d => {
|
|
|
|
d.addEventListener("click", function(e){
|
|
|
|
e.preventDefault();
|
|
|
|
const parent = e.target.closest('tr');
|
|
|
|
moveOrCopyItem(dt.row(parent).data()["meta"]);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
const shareButtons = document.querySelectorAll('[data-kt-filemanager-table-action="share"]');
|
|
|
|
|
|
|
|
shareButtons.forEach(d => {
|
|
|
|
d.addEventListener("click", function(e){
|
|
|
|
e.preventDefault();
|
|
|
|
const parent = e.target.closest('tr');
|
|
|
|
shareItem(dt.row(parent).data()["meta"]);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
const deleteButtons = document.querySelectorAll('[data-kt-filemanager-table-action="delete"]');
|
|
|
|
|
|
|
|
deleteButtons.forEach(d => {
|
|
|
|
d.addEventListener("click", function(e){
|
|
|
|
e.preventDefault();
|
|
|
|
const parent = e.target.closest('tr');
|
|
|
|
deleteItem(dt.row(parent).data()["meta"]);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
const viewMediaLinks = document.querySelectorAll('[data-kt-filemanager-table-action="view_media"]');
|
|
|
|
|
|
|
|
viewMediaLinks.forEach(d => {
|
|
|
|
d.addEventListener("click", function(e){
|
|
|
|
e.preventDefault();
|
|
|
|
const parent = e.target.closest('tr');
|
|
|
|
let rowData = dt.row(parent).data();
|
2023-11-17 20:42:22 +00:00
|
|
|
openMediaPlayer(rowData["name"], rowData["url"]);
|
2023-11-16 17:55:14 +00:00
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2023-11-04 09:54:52 +00:00
|
|
|
var initLightbox = function() {
|
|
|
|
lightbox = GLightbox({
|
|
|
|
slideHTML: `<div class="gslide">
|
|
|
|
<div class="gslide-inner-content">
|
|
|
|
<div class="ginner-container">
|
|
|
|
<div class="gslide-media">
|
|
|
|
</div>
|
|
|
|
<div class="gslide-description gslide-description-bg">
|
|
|
|
<div class="gdesc-inner">
|
|
|
|
<h4 class="gslide-title"></h4>
|
|
|
|
<div class="gslide-desc"></div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>`,
|
|
|
|
preload: false,
|
|
|
|
closeOnOutsideClick: false
|
|
|
|
});
|
|
|
|
}
|
2021-12-10 17:43:26 +00:00
|
|
|
|
2023-11-04 09:54:52 +00:00
|
|
|
var handleSearchDatatable = function () {
|
|
|
|
const filterSearch = document.querySelector('[data-kt-filemanager-table-filter="search"]');
|
|
|
|
filterSearch.addEventListener('keyup', function (e) {
|
|
|
|
dt.rows().deselect();
|
|
|
|
dt.search(e.target.value, true, false).draw();
|
|
|
|
});
|
|
|
|
}
|
2021-12-10 17:43:26 +00:00
|
|
|
|
2023-11-04 09:54:52 +00:00
|
|
|
var initToggleToolbar = function () {
|
|
|
|
const selectAllCheck = document.querySelector('[data-kt-filemanager-table-select="select_all_pages"]');
|
|
|
|
if (selectAllCheck){
|
|
|
|
selectAllCheck.addEventListener('change', function(e){
|
|
|
|
if (this.checked){
|
|
|
|
dt.rows({ search: 'applied' }).select();
|
|
|
|
} else {
|
|
|
|
let selectedIndexes = [];
|
|
|
|
dt.rows({ selected: true, page: 'current' }).every(function (rowIdx, tableLoop, rowLoop){
|
|
|
|
selectedIndexes.push(rowIdx);
|
|
|
|
});
|
|
|
|
dt.rows().deselect();
|
|
|
|
selectedIndexes.forEach((idx) => {
|
|
|
|
dt.row(idx).select();
|
|
|
|
});
|
|
|
|
}
|
|
|
|
toggleToolbars();
|
|
|
|
})
|
|
|
|
}
|
|
|
|
const downloadButton = document.querySelector('[data-kt-filemanager-table-select="download_selected"]');
|
|
|
|
if (downloadButton){
|
|
|
|
downloadButton.addEventListener('click', function(e){
|
|
|
|
let filesArray = [];
|
|
|
|
dt.rows({ selected: true, search: 'applied' }).every(function (rowIdx, tableLoop, rowLoop){
|
|
|
|
let row = dt.row(rowIdx);
|
|
|
|
filesArray.push(getNameFromMeta(row.data()['meta']));
|
|
|
|
});
|
|
|
|
let token = "{{.CSRFToken}}";
|
|
|
|
let downloadURL = '{{.DownloadURL}}';
|
|
|
|
let currentDir = '{{.CurrentDir}}';
|
|
|
|
let ts = new Date().getTime().toString();
|
|
|
|
let files = JSON.stringify(filesArray);
|
|
|
|
$(`<form method="post" action="${downloadURL}?path=${currentDir}&_=${ts}" target="_blank">
|
|
|
|
<input type="hidden" name="_form_token" value="${token}">
|
|
|
|
<textarea name="files" hidden>${files}</textarea>
|
|
|
|
</form>`).appendTo('body').submit().remove();
|
|
|
|
});
|
|
|
|
}
|
2021-12-10 17:43:26 +00:00
|
|
|
|
2023-11-06 18:10:35 +00:00
|
|
|
const moveOrCopyButton = document.querySelector('[data-kt-filemanager-table-select="move_or_copy_selected"]');
|
|
|
|
if (moveOrCopyButton){
|
|
|
|
moveOrCopyButton.addEventListener('click', function(e){
|
|
|
|
$('#errorMsg').addClass("d-none");
|
|
|
|
$('#move_copy_name_container').addClass("d-none");
|
|
|
|
$('#move_copy_source').val("");
|
|
|
|
$('#modal_move_or_copy').modal('show');
|
|
|
|
KTDatatablesFoldersExplorer.init('{{.DirsURL}}?dirtree=1&path={{.CurrentDir}}', '{{.CurrentDir}}');
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2023-11-06 17:46:12 +00:00
|
|
|
const shareButton = document.querySelector('[data-kt-filemanager-table-select="share_selected"]');
|
|
|
|
if (shareButton){
|
|
|
|
shareButton.addEventListener('click', function(e){
|
|
|
|
let filesArray = [];
|
|
|
|
dt.rows({ selected: true, search: 'applied' }).every(function (rowIdx, tableLoop, rowLoop){
|
|
|
|
let row = dt.row(rowIdx);
|
|
|
|
filesArray.push(getNameFromMeta(row.data()['meta']));
|
|
|
|
});
|
|
|
|
let files = encodeURIComponent(JSON.stringify(filesArray));
|
|
|
|
let shareURL = '{{.ShareURL}}';
|
|
|
|
let currentDir = '{{.CurrentDir}}';
|
|
|
|
let ts = new Date().getTime().toString();
|
|
|
|
window.open(`${shareURL}?path=${currentDir}&files=${files}&_=${ts}`,'_blank');
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2023-11-04 09:54:52 +00:00
|
|
|
const deleteButton = document.querySelector('[data-kt-filemanager-table-select="delete_selected"]');
|
|
|
|
if (deleteButton) {
|
|
|
|
deleteButton.addEventListener('click', function(e){
|
|
|
|
ModalAlert.fire({
|
|
|
|
text: "Do you want to delete the selected item/s? This action is irreversible",
|
|
|
|
icon: "warning",
|
|
|
|
confirmButtonText: "Delete",
|
|
|
|
cancelButtonText: 'Cancel',
|
|
|
|
customClass: {
|
|
|
|
confirmButton: "btn btn-danger",
|
|
|
|
cancelButton: 'btn btn-secondary'
|
|
|
|
}
|
|
|
|
}).then((result) => {
|
|
|
|
if (result.isConfirmed){
|
|
|
|
let hasError = false;
|
|
|
|
let deleted = 0;
|
|
|
|
let index = 0;
|
|
|
|
let errDivEl = $('#errorMsg');
|
|
|
|
let errTxtEl = $('#errorTxt');
|
|
|
|
errDivEl.addClass("d-none");
|
|
|
|
let selectedRowsIdx = [];
|
|
|
|
dt.rows({ selected: true, search: 'applied' }).every(function (rowIdx, tableLoop, rowLoop){
|
|
|
|
selectedRowsIdx.push(rowIdx);
|
|
|
|
});
|
|
|
|
if (selectedRowsIdx.length == 0){
|
|
|
|
return;
|
|
|
|
}
|
2023-11-06 18:10:35 +00:00
|
|
|
keepAlive();
|
|
|
|
let keepAliveTimer = setInterval(keepAlive, 300000);
|
2023-11-04 09:54:52 +00:00
|
|
|
$('#loading_message').text("");
|
|
|
|
KTApp.showPageLoading();
|
|
|
|
|
|
|
|
function deleteSelected() {
|
|
|
|
if (index >= selectedRowsIdx.length || hasError){
|
2023-11-06 18:10:35 +00:00
|
|
|
clearInterval(keepAliveTimer);
|
2023-11-04 09:54:52 +00:00
|
|
|
KTApp.hidePageLoading();
|
|
|
|
if (!hasError){
|
|
|
|
location.reload();
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
let meta = dt.row(selectedRowsIdx[index]).data()['meta'];
|
|
|
|
let attrs = getDeleteReqAttrs(meta);
|
2023-11-06 18:10:35 +00:00
|
|
|
let deleteTxt = "";
|
|
|
|
if (selectedRowsIdx.length > 1){
|
|
|
|
let name = getNameFromMeta(meta);
|
|
|
|
deleteTxt = `Delete ${index+1}/${selectedRowsIdx.length}: ${name}`;
|
|
|
|
}
|
|
|
|
$('#loading_message').text(deleteTxt);
|
2023-11-04 09:54:52 +00:00
|
|
|
axios.delete(attrs.path,{
|
|
|
|
timeout: attrs.reqTimeout,
|
|
|
|
headers: {
|
|
|
|
'X-CSRF-TOKEN': '{{.CSRFToken}}'
|
|
|
|
},
|
|
|
|
validateStatus: function (status) {
|
|
|
|
return status == 200;
|
|
|
|
}
|
|
|
|
}).then(function(response){
|
|
|
|
index++;
|
|
|
|
deleted++;
|
|
|
|
deleteSelected();
|
|
|
|
}).catch(function(error){
|
|
|
|
index++;
|
|
|
|
hasError = true;
|
|
|
|
let errorMessage = "Unable to delete the selected item/s";
|
|
|
|
if (deleted > 0){
|
|
|
|
errorMessage = "Not all the selected items have been deleted, please reload the page";
|
|
|
|
}
|
|
|
|
if (error && error.response) {
|
|
|
|
if (error.response.data.message) {
|
|
|
|
errorMessage = error.response.data.message;
|
|
|
|
}
|
|
|
|
if (error.response.data.error) {
|
|
|
|
errorMessage += ": " + error.response.data.error;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
errTxtEl.text(errorMessage);
|
|
|
|
errDivEl.removeClass("d-none");
|
|
|
|
deleteSelected();
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
deleteSelected();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
$('#select_checkbox').on("click", function(){
|
|
|
|
let targets = document.querySelectorAll('#file_manager_list_body .form-check-input');
|
|
|
|
if (!targets){
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
dt.rows().deselect();
|
|
|
|
let isChecked = $(this).is(':checked');
|
|
|
|
if (isChecked){
|
|
|
|
dt.rows({page: 'current'}).select();
|
|
|
|
}
|
|
|
|
KTUtil.each(targets, function (target) {
|
|
|
|
if (target){
|
|
|
|
target.checked = isChecked;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
toggleToolbars();
|
|
|
|
});
|
2022-07-21 16:42:22 +00:00
|
|
|
|
2023-11-04 09:54:52 +00:00
|
|
|
toggleToolbars();
|
2021-05-27 07:40:46 +00:00
|
|
|
}
|
2023-11-04 09:54:52 +00:00
|
|
|
|
|
|
|
var toggleToolbars = function () {
|
|
|
|
let pageSelected = dt.rows({ selected: true, page: 'current' }).count();
|
|
|
|
let totalSelected = dt.rows({ selected: true , search: 'applied'}).count();
|
|
|
|
handleToogleToolbar(pageSelected, totalSelected);
|
|
|
|
}
|
|
|
|
|
|
|
|
return {
|
|
|
|
init: function () {
|
|
|
|
initLightbox();
|
|
|
|
initDatatable();
|
|
|
|
handleSearchDatatable();
|
|
|
|
initToggleToolbar();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}();
|
2021-05-27 07:40:46 +00:00
|
|
|
|
2021-10-09 12:17:28 +00:00
|
|
|
function getNameFromMeta(meta) {
|
|
|
|
return meta.split('_').slice(1).join('_');
|
2021-07-26 18:55:49 +00:00
|
|
|
}
|
|
|
|
|
2021-10-09 12:17:28 +00:00
|
|
|
function getTypeFromMeta(meta) {
|
|
|
|
return meta.split('_')[0];
|
2021-07-26 18:55:49 +00:00
|
|
|
}
|
|
|
|
|
2023-11-04 09:54:52 +00:00
|
|
|
//{{- if not .ShareUploadBaseURL}}
|
|
|
|
function onDirBrowserClick(dirPath) {
|
|
|
|
KTDatatablesFoldersExplorer.init('{{.DirsURL}}?dirtree=1&path='+dirPath, dirPath);
|
|
|
|
}
|
2021-11-30 17:40:50 +00:00
|
|
|
|
2023-11-04 09:54:52 +00:00
|
|
|
function moveOrCopyItem(meta) {
|
|
|
|
$('#errorMsg').addClass("d-none");
|
2023-11-06 18:10:35 +00:00
|
|
|
$('#move_copy_name_container').removeClass("d-none");
|
2023-11-04 09:54:52 +00:00
|
|
|
$('#move_copy_source').val(meta);
|
2023-11-16 17:55:14 +00:00
|
|
|
$('#move_copy_name').val(getNameFromMeta(meta));
|
2023-11-04 09:54:52 +00:00
|
|
|
$('#modal_move_or_copy').modal('show');
|
|
|
|
KTDatatablesFoldersExplorer.init('{{.DirsURL}}?dirtree=1&path={{.CurrentDir}}', '{{.CurrentDir}}');
|
|
|
|
}
|
|
|
|
|
2023-11-06 18:10:35 +00:00
|
|
|
function getMoveOtCopyItems() {
|
|
|
|
let items = [];
|
2023-11-04 09:54:52 +00:00
|
|
|
let targetDir = $("#move_copy_folder").val();
|
|
|
|
if (targetDir != "/") {
|
|
|
|
targetDir = targetDir.endsWith('/') ? targetDir.slice(0, -1) : targetDir;
|
|
|
|
}
|
|
|
|
if (targetDir.trim() == ""){
|
|
|
|
targetDir = "{{.CurrentDir}}";
|
|
|
|
} else {
|
|
|
|
targetDir = encodeURIComponent(targetDir);
|
|
|
|
}
|
2023-11-06 18:10:35 +00:00
|
|
|
|
|
|
|
if ($('#move_copy_name_container').hasClass("d-none")){
|
|
|
|
let dt = $('#file_manager_list').DataTable();
|
|
|
|
dt.rows({ selected: true, search: 'applied' }).every(function (rowIdx, tableLoop, rowLoop){
|
|
|
|
let row = dt.row(rowIdx);
|
|
|
|
let sourceName = getNameFromMeta(row.data()['meta']);
|
|
|
|
items.push({
|
|
|
|
targetDir: targetDir,
|
|
|
|
sourceName: sourceName,
|
|
|
|
targetName: sourceName
|
|
|
|
});
|
|
|
|
});
|
|
|
|
} else {
|
2023-11-16 17:55:14 +00:00
|
|
|
let meta = $('#move_copy_source').val();
|
2023-11-06 18:10:35 +00:00
|
|
|
let sourceName = getNameFromMeta(meta);
|
|
|
|
items.push({
|
|
|
|
targetDir: targetDir,
|
|
|
|
sourceName: sourceName,
|
|
|
|
targetName: $("#move_copy_name").val()
|
|
|
|
});
|
|
|
|
}
|
|
|
|
return items;
|
|
|
|
}
|
|
|
|
|
|
|
|
function doCopy() {
|
|
|
|
let items = getMoveOtCopyItems();
|
|
|
|
if (items.length == 0){
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
keepAlive();
|
|
|
|
let keepAliveTimer = setInterval(keepAlive, 300000);
|
|
|
|
let hasError = false;
|
|
|
|
let index = 0;
|
|
|
|
let errDivEl = $('#errorMsg');
|
|
|
|
let errTxtEl = $('#errorTxt');
|
|
|
|
errDivEl.addClass("d-none");
|
2021-11-30 17:40:50 +00:00
|
|
|
|
2023-11-04 09:54:52 +00:00
|
|
|
$('#loading_message').text("");
|
|
|
|
KTApp.showPageLoading();
|
2021-11-30 17:40:50 +00:00
|
|
|
|
2023-11-06 18:10:35 +00:00
|
|
|
function copyItem() {
|
|
|
|
if (index >= items.length || hasError){
|
|
|
|
clearInterval(keepAliveTimer);
|
|
|
|
KTApp.hidePageLoading();
|
|
|
|
if (!hasError){
|
|
|
|
location.reload();
|
|
|
|
}
|
|
|
|
return;
|
2023-11-04 09:54:52 +00:00
|
|
|
}
|
2023-11-06 18:10:35 +00:00
|
|
|
let item = items[index];
|
|
|
|
let sourcePath = decodeURIComponent('{{.CurrentDir}}');
|
|
|
|
if (!sourcePath.endsWith('/')){
|
|
|
|
sourcePath+="/";
|
|
|
|
}
|
|
|
|
sourcePath+=item.sourceName;
|
|
|
|
|
|
|
|
let targetPath = decodeURIComponent(item.targetDir);
|
|
|
|
if (!targetPath.endsWith('/')){
|
|
|
|
targetPath+="/";
|
|
|
|
}
|
|
|
|
targetPath+=item.targetName;
|
|
|
|
|
|
|
|
if (items.length > 1){
|
|
|
|
let msgTxt = `${sourcePath} => ${targetPath}`;
|
|
|
|
msgTxt = `Copy ${index+1}/${items.length}: ${msgTxt}`;
|
|
|
|
$('#loading_message').text(msgTxt);
|
|
|
|
}
|
|
|
|
let path = '{{.FileActionsURL}}/copy';
|
|
|
|
path+='?path={{.CurrentDir}}'+encodeURIComponent("/"+item.sourceName)+'&target='+item.targetDir+encodeURIComponent("/"+item.targetName);
|
|
|
|
|
|
|
|
axios.post(path, null, {
|
|
|
|
timeout: 180000,
|
|
|
|
headers: {
|
|
|
|
'X-CSRF-TOKEN': '{{.CSRFToken}}'
|
|
|
|
},
|
|
|
|
validateStatus: function (status) {
|
|
|
|
return status == 200;
|
2023-11-04 09:54:52 +00:00
|
|
|
}
|
2023-11-06 18:10:35 +00:00
|
|
|
}).then(function (response) {
|
|
|
|
index++;
|
|
|
|
copyItem();
|
|
|
|
}).catch(function (error) {
|
|
|
|
index++;
|
|
|
|
hasError = true;
|
|
|
|
let errorMessage = "Error copying item";
|
|
|
|
if (error && error.response) {
|
|
|
|
if (error.response.data.message) {
|
|
|
|
errorMessage = error.response.data.message;
|
|
|
|
}
|
|
|
|
if (error.response.data.error) {
|
|
|
|
errorMessage += ": " + error.response.data.error;
|
|
|
|
}
|
2021-11-30 17:40:50 +00:00
|
|
|
}
|
2023-11-06 18:10:35 +00:00
|
|
|
errTxtEl.text(errorMessage);
|
|
|
|
errDivEl.removeClass("d-none");
|
|
|
|
copyItem();
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
copyItem();
|
2021-11-22 11:25:36 +00:00
|
|
|
}
|
|
|
|
|
2023-11-04 09:54:52 +00:00
|
|
|
function doMove() {
|
2023-11-06 18:10:35 +00:00
|
|
|
let items = getMoveOtCopyItems();
|
|
|
|
if (items.length == 0){
|
|
|
|
return;
|
2023-11-04 09:54:52 +00:00
|
|
|
}
|
2023-11-06 18:10:35 +00:00
|
|
|
keepAlive();
|
|
|
|
let keepAliveTimer = setInterval(keepAlive, 300000);
|
|
|
|
let hasError = false;
|
|
|
|
let index = 0;
|
|
|
|
let errDivEl = $('#errorMsg');
|
|
|
|
let errTxtEl = $('#errorTxt');
|
|
|
|
errDivEl.addClass("d-none");
|
2022-11-19 11:31:03 +00:00
|
|
|
|
2023-11-04 09:54:52 +00:00
|
|
|
$('#loading_message').text("");
|
|
|
|
KTApp.showPageLoading();
|
2022-07-21 16:42:22 +00:00
|
|
|
|
2023-11-06 18:10:35 +00:00
|
|
|
function moveItem() {
|
|
|
|
if (index >= items.length || hasError){
|
|
|
|
clearInterval(keepAliveTimer);
|
|
|
|
KTApp.hidePageLoading();
|
|
|
|
if (!hasError){
|
|
|
|
location.reload();
|
|
|
|
}
|
|
|
|
return;
|
2021-11-30 17:40:50 +00:00
|
|
|
}
|
2023-11-06 18:10:35 +00:00
|
|
|
let item = items[index];
|
|
|
|
let sourcePath = decodeURIComponent('{{.CurrentDir}}');
|
|
|
|
if (!sourcePath.endsWith('/')){
|
|
|
|
sourcePath+="/";
|
|
|
|
}
|
|
|
|
sourcePath+=item.sourceName;
|
|
|
|
|
|
|
|
let targetPath = decodeURIComponent(item.targetDir);
|
|
|
|
if (!targetPath.endsWith('/')){
|
|
|
|
targetPath+="/";
|
|
|
|
}
|
|
|
|
targetPath+=item.targetName;
|
|
|
|
|
|
|
|
if (items.length > 1){
|
|
|
|
let msgTxt = `${sourcePath} => ${targetPath}`;
|
|
|
|
msgTxt = `Move ${index+1}/${items.length}: ${msgTxt}`;
|
|
|
|
$('#loading_message').text(msgTxt);
|
|
|
|
}
|
|
|
|
let path = '{{.FileActionsURL}}/move';
|
|
|
|
path+='?path={{.CurrentDir}}'+encodeURIComponent("/"+item.sourceName)+'&target='+item.targetDir+encodeURIComponent("/"+item.targetName);
|
|
|
|
|
|
|
|
axios.post(path, null, {
|
|
|
|
timeout: 180000,
|
|
|
|
headers: {
|
|
|
|
'X-CSRF-TOKEN': '{{.CSRFToken}}'
|
|
|
|
},
|
|
|
|
validateStatus: function (status) {
|
|
|
|
return status == 200;
|
2022-11-19 11:31:03 +00:00
|
|
|
}
|
2023-11-06 18:10:35 +00:00
|
|
|
}).then(function (response) {
|
|
|
|
index++;
|
|
|
|
moveItem();
|
|
|
|
}).catch(function (error) {
|
|
|
|
index++;
|
|
|
|
hasError = true;
|
|
|
|
let errorMessage = "Error moving item";
|
|
|
|
if (error && error.response) {
|
|
|
|
if (error.response.data.message) {
|
|
|
|
errorMessage = error.response.data.message;
|
|
|
|
}
|
|
|
|
if (error.response.data.error) {
|
|
|
|
errorMessage += ": " + error.response.data.error;
|
|
|
|
}
|
2023-11-04 09:54:52 +00:00
|
|
|
}
|
2023-11-06 18:10:35 +00:00
|
|
|
errTxtEl.text(errorMessage);
|
|
|
|
errDivEl.removeClass("d-none");
|
|
|
|
moveItem();
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
moveItem();
|
2023-11-04 09:54:52 +00:00
|
|
|
}
|
2022-11-19 11:31:03 +00:00
|
|
|
|
2023-11-04 09:54:52 +00:00
|
|
|
function getDeleteReqAttrs(meta) {
|
|
|
|
let path;
|
|
|
|
let reqTimeout = 15000;
|
|
|
|
let itemType = getTypeFromMeta(meta);
|
|
|
|
let itemName = getNameFromMeta(meta);
|
|
|
|
if (itemType == "1"){
|
|
|
|
path = '{{.DirsURL}}';
|
|
|
|
reqTimeout = 120000
|
|
|
|
} else {
|
|
|
|
path = '{{.FilesURL}}';
|
|
|
|
}
|
|
|
|
path+='?path={{.CurrentDir}}'+encodeURIComponent("/"+itemName);
|
2022-11-19 11:31:03 +00:00
|
|
|
|
2023-11-04 09:54:52 +00:00
|
|
|
return { path, reqTimeout}
|
|
|
|
}
|
2022-11-19 11:31:03 +00:00
|
|
|
|
2023-11-04 09:54:52 +00:00
|
|
|
function deleteItem(meta) {
|
|
|
|
let errDivEl = $('#errorMsg');
|
|
|
|
let errTxtEl = $('#errorTxt');
|
|
|
|
errDivEl.addClass("d-none");
|
|
|
|
let itemName = getNameFromMeta(meta);
|
|
|
|
|
|
|
|
ModalAlert.fire({
|
|
|
|
text: `Do you want to delete "${itemName}"? This action is irreversible`,
|
|
|
|
icon: "warning",
|
|
|
|
confirmButtonText: "Delete",
|
|
|
|
cancelButtonText: 'Cancel',
|
|
|
|
customClass: {
|
|
|
|
confirmButton: "btn btn-danger",
|
|
|
|
cancelButton: 'btn btn-secondary'
|
|
|
|
}
|
|
|
|
}).then((result) => {
|
|
|
|
if (result.isConfirmed){
|
|
|
|
$('#loading_message').text("");
|
|
|
|
KTApp.showPageLoading();
|
|
|
|
let attrs = getDeleteReqAttrs(meta);
|
|
|
|
|
|
|
|
axios.delete(attrs.path, {
|
|
|
|
timeout: attrs.reqTimeout,
|
|
|
|
headers: {
|
|
|
|
'X-CSRF-TOKEN': '{{.CSRFToken}}'
|
|
|
|
},
|
|
|
|
validateStatus: function (status) {
|
|
|
|
return status == 200;
|
|
|
|
}
|
|
|
|
}).then(function(response){
|
|
|
|
location.reload();
|
|
|
|
}).catch(function(error){
|
|
|
|
KTApp.hidePageLoading();
|
|
|
|
let errorMessage = `Unable to delete "${itemName}"`;
|
|
|
|
if (error && error.response) {
|
|
|
|
if (error.response.data.message) {
|
|
|
|
errorMessage = error.response.data.message;
|
|
|
|
}
|
|
|
|
if (error.response.data.error) {
|
|
|
|
errorMessage += ": " + error.response.data.error;
|
2022-11-19 11:31:03 +00:00
|
|
|
}
|
|
|
|
}
|
2023-11-04 09:54:52 +00:00
|
|
|
errTxtEl.text(errorMessage);
|
|
|
|
errDivEl.removeClass("d-none");
|
2022-11-19 11:31:03 +00:00
|
|
|
});
|
|
|
|
}
|
2023-11-04 09:54:52 +00:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
function shareItem(meta) {
|
|
|
|
let filesArray = [];
|
|
|
|
filesArray.push(getNameFromMeta(meta));
|
|
|
|
let files = encodeURIComponent(JSON.stringify(filesArray));
|
|
|
|
let shareURL = '{{.ShareURL}}';
|
|
|
|
let currentDir = '{{.CurrentDir}}';
|
|
|
|
let ts = new Date().getTime().toString();
|
|
|
|
window.open(`${shareURL}?path=${currentDir}&files=${files}&_=${ts}`,'_blank');
|
|
|
|
}
|
|
|
|
|
|
|
|
function renameItem(meta) {
|
|
|
|
$('#errorMsg').addClass("d-none");
|
2023-11-16 17:55:14 +00:00
|
|
|
let oldName = getNameFromMeta(meta);
|
2023-11-04 09:54:52 +00:00
|
|
|
$('#rename_old_name').val(meta);
|
|
|
|
$('#rename_new_name').val(oldName);
|
|
|
|
$('#rename_title').text(`Rename "${oldName}"`);
|
|
|
|
$('#modal_rename').modal('show');
|
|
|
|
}
|
2022-11-19 11:31:03 +00:00
|
|
|
|
2023-11-04 09:54:52 +00:00
|
|
|
function doRename() {
|
2023-11-16 17:55:14 +00:00
|
|
|
let meta = $('#rename_old_name').val();
|
|
|
|
let oldName = getNameFromMeta(meta);
|
2023-11-04 09:54:52 +00:00
|
|
|
let newName = $('#rename_new_name').val();
|
|
|
|
let errDivEl = $('#errorMsg');
|
|
|
|
let errTxtEl = $('#errorTxt');
|
|
|
|
if (!newName){
|
|
|
|
errTxtEl.text("New name is required");
|
|
|
|
errDivEl.removeClass("d-none");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (newName == oldName){
|
|
|
|
errTxtEl.text("The new name must be different from the current name");
|
|
|
|
errDivEl.removeClass("d-none");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
let path = '{{.FileActionsURL}}/move';
|
|
|
|
path+='?path={{.CurrentDir}}'+encodeURIComponent("/"+oldName)+'&target={{.CurrentDir}}'+encodeURIComponent("/"+newName);
|
|
|
|
axios.post(path, null, {
|
|
|
|
timeout: 15000,
|
|
|
|
headers: {
|
|
|
|
'X-CSRF-TOKEN': '{{.CSRFToken}}'
|
|
|
|
},
|
|
|
|
validateStatus: function (status) {
|
|
|
|
return status == 200;
|
2022-11-19 11:31:03 +00:00
|
|
|
}
|
2023-11-04 09:54:52 +00:00
|
|
|
}).then(function (response) {
|
|
|
|
location.reload();
|
|
|
|
}).catch(function (error) {
|
|
|
|
let errorMessage = `Unable to rename "${oldName}"`;
|
|
|
|
if (error && error.response) {
|
|
|
|
if (error.response.data.message) {
|
|
|
|
errorMessage = error.response.data.message;
|
2021-07-26 18:55:49 +00:00
|
|
|
}
|
2023-11-04 09:54:52 +00:00
|
|
|
if (error.response.data.error) {
|
|
|
|
errorMessage += ": " + error.response.data.error;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
errTxtEl.text(errorMessage);
|
|
|
|
errDivEl.removeClass("d-none");
|
2021-07-26 18:55:49 +00:00
|
|
|
});
|
2023-11-04 09:54:52 +00:00
|
|
|
}
|
2021-07-26 18:55:49 +00:00
|
|
|
|
2023-11-04 09:54:52 +00:00
|
|
|
function showCreateNewFolder(sender) {
|
|
|
|
if (sender == 0) {
|
|
|
|
$('#file_manager_new_folder').removeClass("d-none");
|
|
|
|
$('#errorMsg').addClass("d-none");
|
|
|
|
let el = $('#file_manager_new_folder_input');
|
|
|
|
el.val("");
|
|
|
|
el.focus();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
$('#dirsbrowser_new_folder').removeClass("d-none");
|
|
|
|
$('#errorModalMsg').addClass("d-none");
|
|
|
|
let el = $('#dirsbrowser_new_folder_input');
|
|
|
|
el.val("");
|
|
|
|
el.focus();
|
|
|
|
}
|
2021-12-08 18:25:22 +00:00
|
|
|
|
2023-11-04 09:54:52 +00:00
|
|
|
function hideCreateNewFolder(sender) {
|
|
|
|
if (sender == 0){
|
|
|
|
$('#file_manager_new_folder').addClass("d-none");
|
|
|
|
} else {
|
|
|
|
$('#dirsbrowser_new_folder').addClass("d-none");
|
|
|
|
}
|
|
|
|
}
|
2021-12-08 18:25:22 +00:00
|
|
|
|
2023-11-04 09:54:52 +00:00
|
|
|
function createNewFolder() {
|
|
|
|
let errDivEl = $('#errorMsg');
|
|
|
|
let errTxtEl = $('#errorTxt');
|
|
|
|
let dirName = replaceSlash($("#file_manager_new_folder_input").val());
|
|
|
|
let submitButton = document.querySelector('#file_manager_add_folder');
|
2023-11-06 18:10:35 +00:00
|
|
|
let cancelButton = document.querySelector('#file_manager_cancel_folder');
|
2023-11-04 09:54:52 +00:00
|
|
|
errDivEl.addClass("d-none");
|
|
|
|
if (!dirName){
|
|
|
|
errTxtEl.text("Folder name is required");
|
|
|
|
errDivEl.removeClass("d-none");
|
|
|
|
return;
|
|
|
|
}
|
2021-11-30 17:40:50 +00:00
|
|
|
|
2023-11-04 09:54:52 +00:00
|
|
|
let path = '{{.DirsURL}}?path={{.CurrentDir}}' + encodeURIComponent("/"+dirName);
|
|
|
|
submitButton.setAttribute('data-kt-indicator', 'on');
|
|
|
|
submitButton.disabled = true;
|
2023-11-06 18:10:35 +00:00
|
|
|
cancelButton.disabled = true;
|
2021-07-26 18:55:49 +00:00
|
|
|
|
2023-11-04 09:54:52 +00:00
|
|
|
axios.post(path, null, {
|
|
|
|
timeout: 15000,
|
|
|
|
headers: {
|
|
|
|
'X-CSRF-TOKEN': '{{.CSRFToken}}'
|
|
|
|
},
|
|
|
|
validateStatus: function (status) {
|
|
|
|
return status == 201;
|
2021-12-25 16:13:23 +00:00
|
|
|
}
|
2023-11-04 09:54:52 +00:00
|
|
|
}).then(function (response) {
|
|
|
|
location.reload();
|
|
|
|
}).catch(function (error) {
|
|
|
|
let errorMessage = "Unable to create the new folder";
|
|
|
|
if (error && error.response) {
|
|
|
|
if (error.response.data.message) {
|
|
|
|
errorMessage = error.response.data.message;
|
|
|
|
}
|
|
|
|
if (error.response.data.error) {
|
|
|
|
errorMessage += ": " + error.response.data.error;
|
2021-07-26 18:55:49 +00:00
|
|
|
}
|
|
|
|
}
|
2023-11-04 09:54:52 +00:00
|
|
|
errTxtEl.text(errorMessage);
|
|
|
|
errDivEl.removeClass("d-none");
|
|
|
|
submitButton.removeAttribute('data-kt-indicator');
|
|
|
|
submitButton.disabled = false;
|
2023-11-06 18:10:35 +00:00
|
|
|
cancelButton.disabled = false;
|
2021-07-26 18:55:49 +00:00
|
|
|
});
|
2023-11-04 09:54:52 +00:00
|
|
|
}
|
|
|
|
//{{- end}}
|
2021-07-26 18:55:49 +00:00
|
|
|
|
2023-11-04 09:54:52 +00:00
|
|
|
var playerKeepAlive;
|
|
|
|
|
|
|
|
function uploadFiles(files) {
|
|
|
|
keepAlive();
|
|
|
|
let keepAliveTimer = setInterval(keepAlive, 300000);
|
|
|
|
|
|
|
|
let has_errors = false;
|
|
|
|
let index = 0;
|
|
|
|
let success = 0;
|
|
|
|
$('#errorMsg').addClass("d-none");
|
|
|
|
$('#loading_message').text("");
|
|
|
|
KTApp.showPageLoading();
|
|
|
|
|
|
|
|
function uploadFile() {
|
|
|
|
if (index >= files.length || has_errors) {
|
|
|
|
//console.log("upload done, index: "+index+" has errors: "+has_errors+" ok: "+success);
|
|
|
|
clearInterval(keepAliveTimer);
|
|
|
|
KTApp.hidePageLoading();
|
|
|
|
if (!has_errors) {
|
2022-12-30 18:30:16 +00:00
|
|
|
location.reload();
|
|
|
|
}
|
2023-11-04 09:54:52 +00:00
|
|
|
return;
|
|
|
|
}
|
2022-12-30 18:30:16 +00:00
|
|
|
|
2023-11-04 09:54:52 +00:00
|
|
|
let f = files[index];
|
|
|
|
let uploadPath;
|
|
|
|
//{{- if .ShareUploadBaseURL}}
|
|
|
|
uploadPath = '{{.ShareUploadBaseURL}}' + fixedEncodeURIComponent("/"+escapeHTML(f.name));
|
|
|
|
//{{- else}}
|
|
|
|
uploadPath = '{{.FileURL}}?path={{.CurrentDir}}' + encodeURIComponent("/" + f.name);
|
|
|
|
//{{- end}}
|
|
|
|
let lastModified;
|
|
|
|
try {
|
|
|
|
lastModified = f.lastModified;
|
|
|
|
} catch (e) {
|
|
|
|
console.log("unable to get last modified time from file: " + e.message);
|
|
|
|
lastModified = "";
|
2021-05-06 19:35:43 +00:00
|
|
|
}
|
2021-12-10 17:43:26 +00:00
|
|
|
|
2023-11-04 09:54:52 +00:00
|
|
|
let uploadTxt = f.name;
|
|
|
|
if (files.length > 1){
|
|
|
|
uploadTxt = `Upload ${index+1}/${files.length}: ${uploadTxt}`;
|
|
|
|
}
|
|
|
|
|
|
|
|
$('#loading_message').text(uploadTxt);
|
|
|
|
|
|
|
|
axios.post(uploadPath, f, {
|
|
|
|
headers: {
|
|
|
|
'X-SFTPGO-MTIME': lastModified,
|
|
|
|
'X-CSRF-TOKEN': '{{.CSRFToken}}'
|
2021-05-27 07:40:46 +00:00
|
|
|
},
|
2023-11-04 09:54:52 +00:00
|
|
|
onUploadProgress: function (progressEvent) {
|
|
|
|
if (!progressEvent.total){
|
|
|
|
return;
|
2023-06-04 19:45:31 +00:00
|
|
|
}
|
2023-11-04 09:54:52 +00:00
|
|
|
const percentage = Math.round((100 * progressEvent.loaded) / progressEvent.total);
|
|
|
|
if (percentage > 0 && percentage < 100){
|
|
|
|
$('#loading_message').text(`${uploadTxt} ${percentage}%`);
|
2021-10-09 12:17:28 +00:00
|
|
|
}
|
2021-12-03 17:33:08 +00:00
|
|
|
},
|
2023-11-04 09:54:52 +00:00
|
|
|
validateStatus: function (status) {
|
|
|
|
return status == 201;
|
2021-10-09 12:17:28 +00:00
|
|
|
}
|
2023-11-04 09:54:52 +00:00
|
|
|
}).then(function (response) {
|
|
|
|
index++;
|
|
|
|
success++;
|
|
|
|
uploadFile();
|
|
|
|
}).catch(function (error) {
|
|
|
|
let errorMessage = "Error uploading files";
|
|
|
|
if (error && error.response) {
|
|
|
|
if (error.response.data.message) {
|
|
|
|
errorMessage = error.response.data.message;
|
|
|
|
}
|
|
|
|
if (error.response.data.error) {
|
|
|
|
errorMessage += ": " + error.response.data.error;
|
|
|
|
}
|
2021-05-06 19:35:43 +00:00
|
|
|
}
|
2023-11-04 09:54:52 +00:00
|
|
|
index++;
|
|
|
|
has_errors = true;
|
|
|
|
$('#errorTxt').text(errorMessage);
|
|
|
|
$('#errorMsg').removeClass("d-none");
|
|
|
|
uploadFile();
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
uploadFile();
|
|
|
|
}
|
|
|
|
|
2023-11-17 20:42:22 +00:00
|
|
|
function openMediaPlayer(name, url){
|
2023-11-16 17:55:14 +00:00
|
|
|
$("#video_title").text(name);
|
2023-11-17 20:42:22 +00:00
|
|
|
$("#video_player").attr("src", url);
|
|
|
|
$("#video_player").get(0).load();
|
2023-11-04 09:54:52 +00:00
|
|
|
$('#modal_video_player').modal('show');
|
|
|
|
keepAlive();
|
|
|
|
playerKeepAlive = setInterval(keepAlive, 300000);
|
|
|
|
}
|
|
|
|
|
|
|
|
// On document ready
|
|
|
|
KTUtil.onDOMContentLoaded(function () {
|
|
|
|
KTDatatablesServerSide.init();
|
|
|
|
|
|
|
|
var dropzone = new Dropzone("#upload_files", {
|
|
|
|
url: "{{.FilesURL}}?path={{.CurrentDir}}",
|
|
|
|
paramName: "filenames",
|
|
|
|
maxFiles: 250,
|
|
|
|
maxFilesize: null,
|
|
|
|
autoQueue: false,
|
|
|
|
addRemoveLinks: true,
|
|
|
|
autoProcessQueue: false,
|
|
|
|
filesizeBase: 1000,
|
|
|
|
init: function() {
|
|
|
|
var dropzone = this;
|
|
|
|
$("#upload_files_button").click(function(){
|
|
|
|
uploadFiles(dropzone.getAcceptedFiles());
|
|
|
|
});
|
|
|
|
}
|
2021-05-06 19:35:43 +00:00
|
|
|
});
|
|
|
|
|
2023-11-04 09:54:52 +00:00
|
|
|
dropzone.on("addedfile", file => {
|
|
|
|
file.previewElement.querySelector(".dz-progress").style.display = 'none';
|
|
|
|
});
|
|
|
|
|
|
|
|
$('#modal_video_player').on('hide.bs.modal', function () {
|
2023-11-17 20:42:22 +00:00
|
|
|
$("#video_player").get(0).pause();
|
2023-11-04 09:54:52 +00:00
|
|
|
if (playerKeepAlive != null) {
|
|
|
|
clearInterval(playerKeepAlive);
|
|
|
|
playerKeepAlive = null;
|
|
|
|
}
|
|
|
|
});
|
2021-05-06 19:35:43 +00:00
|
|
|
|
2023-11-04 09:54:52 +00:00
|
|
|
//{{- if not .ShareUploadBaseURL}}
|
|
|
|
$('#modal_rename').on('shown.bs.modal', function () {
|
|
|
|
let newNameEl = $('#rename_new_name');
|
|
|
|
newNameEl.focus();
|
|
|
|
newNameEl.select();
|
|
|
|
});
|
|
|
|
//{{- end}}
|
2023-11-13 21:09:55 +00:00
|
|
|
|
|
|
|
// onclick handlers
|
|
|
|
var createDirBtn = $('#id_create_dir_button');
|
|
|
|
if (createDirBtn){
|
|
|
|
createDirBtn.on("click", function (){
|
|
|
|
showCreateNewFolder(0);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
var dirBrowserCreateDir = $('#id_dir_browser_create_dir');
|
|
|
|
if (dirBrowserCreateDir){
|
|
|
|
dirBrowserCreateDir.on("click", function(){
|
|
|
|
showCreateNewFolder(1);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
var fileManagerAddFolder = $('#file_manager_add_folder');
|
|
|
|
if (fileManagerAddFolder){
|
|
|
|
fileManagerAddFolder.on("click", function() {
|
|
|
|
createNewFolder();
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
var fileManagerCancelCreateFolder = $('#file_manager_cancel_folder');
|
|
|
|
if (fileManagerCancelCreateFolder){
|
|
|
|
fileManagerCancelCreateFolder.on("click", function(){
|
|
|
|
hideCreateNewFolder(0);
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
var dirBrowserCancelCreateFolder = $('#dirsbrowser_cancel_folder');
|
|
|
|
if (dirBrowserCancelCreateFolder){
|
|
|
|
dirBrowserCancelCreateFolder.on("click", function(){
|
|
|
|
hideCreateNewFolder(1);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
var doRenameBtn = $('#id_do_rename_button');
|
|
|
|
if (doRenameBtn){
|
|
|
|
doRenameBtn.on("click", function() {
|
|
|
|
doRename();
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
var doCopyBtn = $('#id_copy_button');
|
|
|
|
if (doCopyBtn){
|
|
|
|
doCopyBtn.on("click", function(){
|
|
|
|
doCopy();
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
var doMoveBtn = $('#id_move_button');
|
|
|
|
if (doMoveBtn){
|
|
|
|
doMoveBtn.on("click", function(){
|
|
|
|
doMove();
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
var dismissErrorModalBtn = $('#id_dismiss_error_modal_msg');
|
|
|
|
if (dismissErrorModalBtn){
|
|
|
|
dismissErrorModalBtn.on("click",function(){
|
|
|
|
$('#errorModalMsg').addClass("d-none");
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2021-05-06 19:35:43 +00:00
|
|
|
});
|
|
|
|
</script>
|
2023-11-04 09:54:52 +00:00
|
|
|
{{- end}}
|
|
|
|
|
|
|
|
{{- define "additionalnavitems"}}
|
|
|
|
{{- if .QuotaUsage.HasQuotaInfo}}
|
|
|
|
<div class="d-flex align-items-center ms-2 ms-lg-3">
|
|
|
|
<div class="btn btn-icon btn-active-light-primary position-relative w-35px h-35px w-md-40px h-md-40px" data-kt-menu-trigger="{default:'click', lg: 'hover'}" data-kt-menu-attach="parent" data-kt-menu-placement="bottom-end">
|
|
|
|
<i class="ki-duotone {{if .QuotaUsage.IsQuotaLow}}ki-information-5 text-warning{{else}}ki-information-2{{end}} fs-2">
|
|
|
|
<span class="path1"></span>
|
|
|
|
<span class="path2"></span>
|
|
|
|
<span class="path3"></span>
|
|
|
|
</i>
|
|
|
|
</div>
|
|
|
|
<div class="menu menu-sub menu-sub-dropdown menu-column w-350px" data-kt-menu="true">
|
|
|
|
<div class="card">
|
|
|
|
<div class="card-header">
|
|
|
|
<h3 class="card-title"><span class="text-gray-700 fw-semibold fs-6">Quota usage</span></h3>
|
|
|
|
</div>
|
|
|
|
<div class="card-body p-0">
|
|
|
|
{{- if .QuotaUsage.HasDiskQuota}}
|
|
|
|
{{- $size := .QuotaUsage.GetQuotaSize}}
|
|
|
|
{{- $files := .QuotaUsage.GetQuotaFiles}}
|
|
|
|
<div class="d-flex align-items-center bg-hover-lighten py-3 px-9">
|
|
|
|
<div class="symbol symbol-40px symbol-circle me-5">
|
|
|
|
<span class="symbol-label {{ if .QuotaUsage.IsDiskQuotaLow }}bg-light-warning{{end}}">
|
|
|
|
<i class="ki-duotone ki-external-drive {{ if .QuotaUsage.IsDiskQuotaLow }}text-warning{{end}} fs-1">
|
|
|
|
<span class="path1"></span>
|
|
|
|
<span class="path2"></span>
|
|
|
|
<span class="path3"></span>
|
|
|
|
<span class="path4"></span>
|
|
|
|
<span class="path5"></span>
|
|
|
|
</i>
|
|
|
|
</span>
|
|
|
|
</div>
|
|
|
|
<div class="mb-1 pe-3 flex-grow-1">
|
2023-11-12 15:28:21 +00:00
|
|
|
<span class="fs-6 text-gray-900 fw-semibold">Disk quota</span>
|
2023-11-04 09:54:52 +00:00
|
|
|
{{- if $size}}
|
|
|
|
{{- $percentage := .QuotaUsage.GetQuotaSizePercentage}}
|
|
|
|
<div class="{{if .QuotaUsage.IsQuotaSizeLow}}text-warning{{else}}text-gray-700{{end}} fw-semibold fs-6">Size: {{$size}}{{if gt $percentage 0}} ({{$percentage}}%){{end}}</div>
|
|
|
|
{{- end}}
|
|
|
|
{{- if $files}}
|
|
|
|
{{- $percentage := .QuotaUsage.GetQuotaFilesPercentage}}
|
|
|
|
<div class="{{if .QuotaUsage.IsQuotaFilesLow}}text-warning{{else}}text-gray-700{{end}} fw-semibold fs-6">Files: {{$files}}{{if gt $percentage 0}} ({{$percentage}}%){{end}}</div>
|
|
|
|
{{- end}}
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
{{- end}}
|
|
|
|
{{- if .QuotaUsage.HasTranferQuota}}
|
|
|
|
{{- $total := .QuotaUsage.GetTotalTransferQuota}}
|
|
|
|
{{- $upload := .QuotaUsage.GetUploadTransferQuota}}
|
|
|
|
{{- $download := .QuotaUsage.GetDownloadTransferQuota}}
|
|
|
|
<div class="d-flex align-items-center bg-hover-lighten py-3 px-9">
|
|
|
|
<div class="symbol symbol-40px symbol-circle me-5">
|
|
|
|
<span class="symbol-label {{ if .QuotaUsage.IsTransferQuotaLow }}bg-light-warning{{end}}">
|
|
|
|
<i class="ki-duotone ki-arrow-right-left {{ if .QuotaUsage.IsTransferQuotaLow }}text-warning{{end}} fs-1">
|
|
|
|
<span class="path1"></span>
|
|
|
|
<span class="path2"></span>
|
|
|
|
</i>
|
|
|
|
</span>
|
|
|
|
</div>
|
|
|
|
<div class="mb-1 pe-3 flex-grow-1">
|
2023-11-12 15:28:21 +00:00
|
|
|
<span class="fs-6 text-gray-900 fw-semibold">Transfer quota</span>
|
2023-11-04 09:54:52 +00:00
|
|
|
{{- if $total}}
|
|
|
|
{{$percentage := .QuotaUsage.GetTotalTransferQuotaPercentage}}
|
|
|
|
<div class="{{if .QuotaUsage.IsTotalTransferQuotaLow}}text-warning{{else}}text-gray-700{{end}} fw-semibold fs-6">Total: {{$total}}{{if gt $percentage 0}} ({{$percentage}}%){{end}}</div>
|
|
|
|
{{- end}}
|
|
|
|
{{- if $download}}
|
|
|
|
{{$percentage := .QuotaUsage.GetDownloadTransferQuotaPercentage}}
|
|
|
|
<div class="{{if .QuotaUsage.IsDownloadTransferQuotaLow}}text-warning{{else}}text-gray-700{{end}} fw-semibold fs-6">Download: {{$download}}{{if gt $percentage 0}} ({{$percentage}}%){{end}}</div>
|
|
|
|
{{- end}}
|
|
|
|
{{- if $upload}}
|
|
|
|
{{$percentage := .QuotaUsage.GetUploadTransferQuotaPercentage}}
|
|
|
|
<div class="{{if .QuotaUsage.IsUploadTransferQuotaLow}}text-warning{{else}}text-gray-700{{end}} fw-semibold fs-6">Upload: {{$upload}}{{if gt $percentage 0}} ({{$percentage}}%){{end}}</div>
|
|
|
|
{{- end}}
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
{{- end}}
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
{{- end}}
|
|
|
|
{{- end}}
|
|
|
|
|
|
|
|
{{- define "modals"}}
|
|
|
|
<div class="modal fade" tabindex="-1" id="modal_upload">
|
|
|
|
<div class="modal-dialog modal-dialog-centered mw-600px">
|
|
|
|
<div class="modal-content">
|
|
|
|
<div class="modal-header border-0">
|
|
|
|
<h3 class="modal-title">Upload files</h3>
|
|
|
|
<div class="btn btn-icon btn-sm btn-active-color-primary" data-bs-dismiss="modal" aria-label="Close">
|
|
|
|
<i class="ki-duotone ki-cross fs-1"><span class="path1"></span><span class="path2"></span></i>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div class="modal-body">
|
|
|
|
<form id="upload_files_form" action="{{.FilesURL}}?path={{.CurrentDir}}" method="POST" enctype="multipart/form-data">
|
|
|
|
<div class="fv-row">
|
|
|
|
<div class="dropzone" id="upload_files">
|
|
|
|
<div class="dz-message needsclick align-items-center">
|
|
|
|
<i class="ki-duotone ki-file-up fs-3x text-primary"><span class="path1"></span><span class="path2"></span></i>
|
|
|
|
<div class="ms-4">
|
|
|
|
<h3 class="fs-5 fw-bold text-gray-900 mb-1">Drop files here or click to upload.</h3>
|
2023-11-13 21:09:55 +00:00
|
|
|
<!-- <span class="fs-7 fw-semibold text-gray-500">Upload up to 30 files</span> -->
|
2023-11-04 09:54:52 +00:00
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</form>
|
|
|
|
</div>
|
|
|
|
<div class="modal-footer border-0">
|
|
|
|
<button type="button" class="btn btn-light me-5" data-bs-dismiss="modal">Cancel</button>
|
|
|
|
<button type="button" id="upload_files_button" class="btn btn-primary" data-bs-dismiss="modal">Submit</button>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div class="modal fade" tabindex="-1" id="modal_video_player" data-bs-backdrop="static" data-bs-keyboard="false">
|
|
|
|
<div class="modal-dialog modal-dialog-centered modal-lg">
|
|
|
|
<div class="modal-content">
|
|
|
|
<div class="modal-header border-0">
|
|
|
|
<h5 class="modal-title">
|
|
|
|
<span id="video_title"></span>
|
|
|
|
</h5>
|
|
|
|
<div class="btn btn-icon btn-sm btn-active-color-primary" data-bs-dismiss="modal" aria-label="Close">
|
|
|
|
<i class="ki-duotone ki-cross fs-1"><span class="path1"></span><span class="path2"></span></i>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div class="modal-body">
|
2023-11-17 20:42:22 +00:00
|
|
|
<video id="video_player" width="100%" height="auto" controls preload="metadata">
|
|
|
|
Your browser does not support HTML5 video.
|
2023-11-04 09:54:52 +00:00
|
|
|
</video>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
{{- if not .ShareUploadBaseURL}}
|
|
|
|
<div class="modal fade" tabindex="-1" id="modal_rename">
|
|
|
|
<div class="modal-dialog modal-dialog-centered">
|
|
|
|
<div class="modal-content">
|
|
|
|
<div class="modal-header border-0">
|
|
|
|
<h5 class="modal-title">
|
|
|
|
<span id="rename_title"></span>
|
|
|
|
</h5>
|
|
|
|
<div class="btn btn-icon btn-sm btn-active-color-primary" data-bs-dismiss="modal" aria-label="Close">
|
|
|
|
<i class="ki-duotone ki-cross fs-1"><span class="path1"></span><span class="path2"></span></i>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div class="modal-body">
|
|
|
|
<input id="rename_old_name" type="text" class="d-none"/>
|
|
|
|
<div class="mb-10">
|
|
|
|
<label for="rename_new_name" class="form-label">New name</label>
|
|
|
|
<input id="rename_new_name" type="text" class="form-control"/>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div class="modal-footer border-0">
|
|
|
|
<button type="button" class="btn btn-secondary me-5" data-bs-dismiss="modal">Cancel</button>
|
2023-11-13 21:09:55 +00:00
|
|
|
<button id="id_do_rename_button" type="button" class="btn btn-primary" data-bs-dismiss="modal">Submit</button>
|
2023-11-04 09:54:52 +00:00
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div class="modal fade" tabindex="-1" id="modal_move_or_copy">
|
|
|
|
<div class="modal-dialog modal-dialog-centered modal-lg">
|
|
|
|
<div class="modal-content">
|
|
|
|
<div class="modal-header border-0">
|
|
|
|
<h3 class="modal-title">
|
2023-11-06 18:10:35 +00:00
|
|
|
Choose target folder
|
2023-11-04 09:54:52 +00:00
|
|
|
</h3>
|
|
|
|
<div class="btn btn-icon btn-sm btn-active-color-primary" data-bs-dismiss="modal" aria-label="Close">
|
|
|
|
<i class="ki-duotone ki-cross fs-1"><span class="path1"></span><span class="path2"></span></i>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div class="modal-body">
|
|
|
|
<div id="errorModalMsg" class="d-none alert alert-dismissible bg-light-warning d-flex align-items-center p-5 mb-10">
|
|
|
|
<i class="ki-duotone ki-information-5 fs-3x text-warning me-5"><span class="path1"></span><span class="path2"></span><span class="path3"></span></i>
|
|
|
|
<div class="text-gray-700 fw-bold fs-5 d-flex flex-column pe-0 pe-sm-10">
|
|
|
|
<span id="errorModalTxt"></span>
|
|
|
|
</div>
|
2023-11-13 21:09:55 +00:00
|
|
|
<button id="id_dismiss_error_modal_msg" type="button" class="position-absolute position-sm-relative m-2 m-sm-0 top-0 end-0 btn btn-icon btn-sm btn-active-light-primary ms-sm-auto">
|
2023-11-04 09:54:52 +00:00
|
|
|
<i class="ki-duotone ki-cross fs-2x text-primary"><span class="path1"></span><span class="path2"></span></i>
|
|
|
|
</button>
|
|
|
|
</div>
|
|
|
|
<div class="row">
|
|
|
|
<div class="col-md-9 align-items-center d-flex flex-stack">
|
|
|
|
<div class="badge badge-lg badge-light-primary">
|
|
|
|
<div id="dirs_browser_nav" class="d-flex align-items-center flex-wrap">
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div class="col-md-3 align-items-center d-flex justify-content-end">
|
2023-11-13 21:09:55 +00:00
|
|
|
<button id="id_dir_browser_create_dir" type="button" class="btn btn-flex btn-primary">
|
2023-11-04 09:54:52 +00:00
|
|
|
<i class="ki-duotone ki-add-folder fs-2">
|
|
|
|
<span class="path1"></span>
|
|
|
|
<span class="path2"></span>
|
|
|
|
</i>
|
|
|
|
Add
|
|
|
|
</button>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div id="dirsbrowser_new_folder" class="d-flex align-items-center py-7 d-none">
|
|
|
|
<span>
|
|
|
|
<i class="ki-duotone ki-folder fs-2x text-primary me-4">
|
|
|
|
<span class="path1"></span>
|
|
|
|
<span class="path2"></span>
|
|
|
|
</i>
|
|
|
|
</span>
|
|
|
|
<input id="dirsbrowser_new_folder_input" type="text" name="new_folder_name" placeholder="Enter the new folder name" class="form-control mw-250px me-3" />
|
|
|
|
<button class="btn btn-icon btn-light-primary me-3" id="dirsbrowser_add_folder">
|
|
|
|
<span class="indicator-label">
|
|
|
|
<i class="ki-duotone ki-check fs-1"></i>
|
|
|
|
</span>
|
|
|
|
<span class="indicator-progress">
|
|
|
|
<span class="spinner-border spinner-border-sm align-middle"></span>
|
|
|
|
</span>
|
|
|
|
</button>
|
2023-11-13 21:09:55 +00:00
|
|
|
<button class="btn btn-icon btn-light-danger" id="dirsbrowser_cancel_folder">
|
2023-11-04 09:54:52 +00:00
|
|
|
<i class="ki-duotone ki-cross fs-1">
|
|
|
|
<span class="path1"></span>
|
|
|
|
<span class="path2"></span>
|
|
|
|
</i>
|
|
|
|
</button>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<table id="dirsbrowser_list" class="table align-middle table-row-dashed fs-6 gy-5">
|
|
|
|
<thead>
|
|
|
|
<tr class="text-start text-muted fw-bold fs-7 text-uppercase gs-0">
|
|
|
|
<th></th>
|
|
|
|
<th class="min-w-250px">Name</th>
|
|
|
|
</tr>
|
|
|
|
</thead>
|
|
|
|
<tbody id="dirsbrowser_list_body" class="text-gray-600 fw-semibold">
|
|
|
|
</tbody>
|
|
|
|
</table>
|
|
|
|
|
|
|
|
<div class="form-floating d-none">
|
|
|
|
<input type="text" class="form-control form-control-solid" id="move_copy_source"/>
|
|
|
|
<label for="move_copy_source">Source name</label>
|
|
|
|
</div>
|
2021-05-06 19:35:43 +00:00
|
|
|
|
2023-11-04 09:54:52 +00:00
|
|
|
<div class="form-floating mb-5 mt-7">
|
|
|
|
<input type="text" class="form-control form-control-solid" id="move_copy_folder"/>
|
|
|
|
<label for="move_copy_folder">Target folder</label>
|
|
|
|
</div>
|
|
|
|
|
2023-11-06 18:10:35 +00:00
|
|
|
<div class="form-floating" id="move_copy_name_container">
|
2023-11-04 09:54:52 +00:00
|
|
|
<input type="text" class="form-control form-control-solid" id="move_copy_name"/>
|
|
|
|
<label for="move_copy_name">Destination name</label>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
<div class="modal-footer border-0">
|
|
|
|
{{- if .CanAddFiles }}
|
2023-11-13 21:09:55 +00:00
|
|
|
<button id="id_copy_button" type="button" class="btn btn-light-primary me-5" data-bs-dismiss="modal">Copy</button>
|
2023-11-04 09:54:52 +00:00
|
|
|
{{- end}}
|
|
|
|
{{- if .CanRename }}
|
2023-11-13 21:09:55 +00:00
|
|
|
<button id="id_move_button" type="button" class="btn btn-primary" data-bs-dismiss="modal">Move</button>
|
2023-11-04 09:54:52 +00:00
|
|
|
{{- end}}
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
{{- end}}
|
|
|
|
{{- end}}
|