sftpgo/templates/webclient/files.html

1955 lines
85 KiB
HTML
Raw Normal View History

<!--
Copyright (C) 2023 Nicola Murino
This WebUI uses the KeenThemes Mega Bundle, a proprietary theme:
https://keenthemes.com/products/templates-mega-bundle
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).
-->
{{template "base" .}}
{{- 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" />
</div>
</div>
<div class="card-toolbar">
<div class="d-flex justify-content-end" data-kt-filemanager-table-toolbar="base">
{{- if .CanCreateDirs}}
<button id="id_create_dir_button" type="button" class="btn btn-flex btn-light-primary me-3">
<i class="ki-duotone ki-add-folder fs-2">
<span class="path1"></span>
<span class="path2"></span>
</i>
New Folder
</button>
{{- 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
</button>
{{- end}}
</div>
<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>
</div>
<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>
</div>
{{- 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}}
{{- 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}}
{{- 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}}
{{- end}}
{{- 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}}
</div>
</div>
{{- end}}
</div>
</div>
</div>
<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>
</div>
</div>
<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" />
<button class="btn btn-icon btn-light-primary me-3" id="file_manager_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>
<button class="btn btn-icon btn-light-danger" id="file_manager_cancel_folder">
<i class="ki-duotone ki-cross fs-1">
<span class="path1"></span>
<span class="path2"></span>
</i>
</button>
</div>
<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>
</div>
</div>
{{- 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"/>
<link href="{{.StaticURL}}/vendor/video-js/video-js.min.css" rel="stylesheet" type="text/css"/>
<style {{- if .CSPNonce}} nonce="{{.CSPNonce}}"{{- end}}>
.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>
<script src="{{.StaticURL}}/vendor/pdfobject/pdfobject.min.js"></script>
<script src="{{.StaticURL}}/vendor/video-js/video.min.js"></script>
<script type="text/javascript" {{- if .CSPNonce}} nonce="{{.CSPNonce}}"{{- end}}>
//{{- if not .ShareUploadBaseURL}}
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"]
//{{- end}}
function keepAlive() {
//{{- if not .ShareUploadBaseURL}}
axios.get('{{.PingURL}}',{
timeout: 15000,
responseType: 'text'
}).catch(function (error){});
//{{- end}}
}
//{{- 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>
<a href="#" class="text-gray-700 text-hover-primary" data-dirbrowser-table-row="open">${data}</a>
</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']
});
dt.on('draw', function () {
let dirBrowserNav = document.getElementById("dirs_browser_nav");
while (dirBrowserNav.firstChild) {
dirBrowserNav.removeChild(dirBrowserNav.firstChild);
}
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);
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);
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);
}
}
}
$('#move_copy_folder').val(p);
handleRowActions();
});
}
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');
let cancelButton = document.querySelector('#dirsbrowser_cancel_folder');
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;
cancelButton.disabled = true;
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;
cancelButton.disabled = false;
$('#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;
cancelButton.disabled = false;
});
});
}
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']);
});
});
}
return {
init: function (url, dirPath) {
curDir = dirPath;
if (dt) {
dt.ajax.url(url).load();
return;
}
initDatatable(url);
handleCreateNewFolder();
}
}
}();
//{{- end}}
</script>
<script type="text/javascript" {{- if .CSPNonce}} nonce="{{.CSPNonce}}"{{- end}}>
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;
}
},
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;
}
},
{ 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;
}
},
{
data: "size",
render: function (data, type) {
if (type === 'display') {
if (data || data === 0){
return fileSizeIEC(data);
}
return "";
}
return data;
}
},
{ 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, '&quot;');
previewDiv = `<div class="ms-2" data-kt-filemanger-table="view_item">
<a href="${row['url']}" data-gallery="gallery" data-glightbox="description: &lt;span class=&quot;fs-5 fw-bold&quot;&gt;${desc}&lt;/span&gt;" 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">
<a href="#" class="btn btn-sm btn-icon btn-light btn-active-light-primary" data-kt-filemanager-table-action="view_media">
<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">
<a href="#" class="menu-link px-3" data-kt-filemanager-table-action="rename">Rename</a>
</div>
{{- end}}
{{- if or .CanRename .CanAddFiles}}
<div class="menu-item px-3">
<a href="#" class="menu-link px-3" data-kt-filemanager-table-action="move_or_copy">Move or copy</a>
</div>
{{- end}}
{{- if .CanShare}}
<div class="menu-item px-3">
<a href="#" class="menu-link px-3" data-kt-filemanager-table-action="share">Share</a>
</div>
{{- end}}
{{- if .CanDelete}}
<div class="menu-item px-3">
<a href="#" class="menu-link text-danger px-3" data-kt-filemanager-table-action="delete">Delete</a>
</div>
{{- end}}
</div>
</div>
{{- end}}
{{- end}}`;
return `<div class="d-flex justify-content-end">
${previewDiv}
${more}
</div>
`;
}
return "";
}
}
],
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
}
],
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;
}
let checkbox = target.querySelector('.form-check-input');
if (!checkbox) {
return;
}
if (target.classList.contains('row-selected')) {
checkbox.checked = true;
} else {
checkbox.checked = false;
}
});
}
toggleToolbars();
handleRowActions();
});
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--;
}
handleToogleToolbar(pageSelected, totalSelected);
});
}
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');
}
}
}
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();
openVideoPlayer(rowData["name"], rowData["url"]);
});
});
}
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
});
}
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();
});
}
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();
});
}
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}}');
});
}
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');
});
}
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;
}
keepAlive();
let keepAliveTimer = setInterval(keepAlive, 300000);
$('#loading_message').text("");
KTApp.showPageLoading();
function deleteSelected() {
if (index >= selectedRowsIdx.length || hasError){
clearInterval(keepAliveTimer);
KTApp.hidePageLoading();
if (!hasError){
location.reload();
}
return;
}
let meta = dt.row(selectedRowsIdx[index]).data()['meta'];
let attrs = getDeleteReqAttrs(meta);
let deleteTxt = "";
if (selectedRowsIdx.length > 1){
let name = getNameFromMeta(meta);
deleteTxt = `Delete ${index+1}/${selectedRowsIdx.length}: ${name}`;
}
$('#loading_message').text(deleteTxt);
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();
});
toggleToolbars();
}
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();
}
}
}();
function getNameFromMeta(meta) {
return meta.split('_').slice(1).join('_');
}
function getTypeFromMeta(meta) {
return meta.split('_')[0];
}
//{{- if not .ShareUploadBaseURL}}
function onDirBrowserClick(dirPath) {
KTDatatablesFoldersExplorer.init('{{.DirsURL}}?dirtree=1&path='+dirPath, dirPath);
}
function moveOrCopyItem(meta) {
$('#errorMsg').addClass("d-none");
$('#move_copy_name_container').removeClass("d-none");
$('#move_copy_source').val(meta);
$('#move_copy_name').val(getNameFromMeta(meta));
$('#modal_move_or_copy').modal('show');
KTDatatablesFoldersExplorer.init('{{.DirsURL}}?dirtree=1&path={{.CurrentDir}}', '{{.CurrentDir}}');
}
function getMoveOtCopyItems() {
let items = [];
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);
}
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 {
let meta = $('#move_copy_source').val();
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");
$('#loading_message').text("");
KTApp.showPageLoading();
function copyItem() {
if (index >= items.length || hasError){
clearInterval(keepAliveTimer);
KTApp.hidePageLoading();
if (!hasError){
location.reload();
}
return;
}
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;
}
}).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;
}
}
errTxtEl.text(errorMessage);
errDivEl.removeClass("d-none");
copyItem();
});
}
copyItem();
2021-11-22 11:25:36 +00:00
}
function doMove() {
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");
$('#loading_message').text("");
KTApp.showPageLoading();
function moveItem() {
if (index >= items.length || hasError){
clearInterval(keepAliveTimer);
KTApp.hidePageLoading();
if (!hasError){
location.reload();
}
return;
}
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;
}
}).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;
}
}
errTxtEl.text(errorMessage);
errDivEl.removeClass("d-none");
moveItem();
});
}
moveItem();
}
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);
return { path, reqTimeout}
}
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;
}
}
errTxtEl.text(errorMessage);
errDivEl.removeClass("d-none");
});
}
});
}
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");
let oldName = getNameFromMeta(meta);
$('#rename_old_name').val(meta);
$('#rename_new_name').val(oldName);
$('#rename_title').text(`Rename "${oldName}"`);
$('#modal_rename').modal('show');
}
function doRename() {
let meta = $('#rename_old_name').val();
let oldName = getNameFromMeta(meta);
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;
}
}).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;
}
if (error.response.data.error) {
errorMessage += ": " + error.response.data.error;
}
}
errTxtEl.text(errorMessage);
errDivEl.removeClass("d-none");
});
}
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();
}
function hideCreateNewFolder(sender) {
if (sender == 0){
$('#file_manager_new_folder').addClass("d-none");
} else {
$('#dirsbrowser_new_folder').addClass("d-none");
}
}
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');
let cancelButton = document.querySelector('#file_manager_cancel_folder');
errDivEl.addClass("d-none");
if (!dirName){
errTxtEl.text("Folder name is required");
errDivEl.removeClass("d-none");
return;
}
let path = '{{.DirsURL}}?path={{.CurrentDir}}' + encodeURIComponent("/"+dirName);
submitButton.setAttribute('data-kt-indicator', 'on');
submitButton.disabled = true;
cancelButton.disabled = true;
axios.post(path, null, {
timeout: 15000,
headers: {
'X-CSRF-TOKEN': '{{.CSRFToken}}'
},
validateStatus: function (status) {
return status == 201;
}
}).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;
}
}
errTxtEl.text(errorMessage);
errDivEl.removeClass("d-none");
submitButton.removeAttribute('data-kt-indicator');
submitButton.disabled = false;
cancelButton.disabled = false;
});
}
//{{- end}}
var player;
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) {
location.reload();
}
return;
}
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 = "";
}
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}}'
},
onUploadProgress: function (progressEvent) {
if (!progressEvent.total){
return;
}
const percentage = Math.round((100 * progressEvent.loaded) / progressEvent.total);
if (percentage > 0 && percentage < 100){
$('#loading_message').text(`${uploadTxt} ${percentage}%`);
}
},
validateStatus: function (status) {
return status == 201;
}
}).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;
}
}
index++;
has_errors = true;
$('#errorTxt').text(errorMessage);
$('#errorMsg').removeClass("d-none");
uploadFile();
});
}
uploadFile();
}
function openVideoPlayer(name, url){
let extension = name.slice((name.lastIndexOf(".") - 1 >>> 0) + 2).toLowerCase();
let videoType = 'video/mp4';
if (extension == 'webm') {
videoType = 'video/webm';
} else if (extension == 'ogg' || extension == 'ogv') {
videoType = 'video/ogg';
} else if (extension == 'mp3') {
videoType = 'audio/mpeg';
} else if (extension == 'wav') {
videoType = 'audio/wav';
}
if (!player){
player = videojs('video_player', {
controls: true,
autoplay: false,
preload: 'auto'
});
}
$("#video_title").text(name);
$('#modal_video_player').modal('show');
player.src({
type: videoType,
src: url
});
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());
});
}
});
dropzone.on("addedfile", file => {
file.previewElement.querySelector(".dz-progress").style.display = 'none';
});
$('#modal_video_player').on('hide.bs.modal', function () {
player.pause();
player.reset();
if (playerKeepAlive != null) {
clearInterval(playerKeepAlive);
playerKeepAlive = null;
}
});
//{{- if not .ShareUploadBaseURL}}
$('#modal_rename').on('shown.bs.modal', function () {
let newNameEl = $('#rename_new_name');
newNameEl.focus();
newNameEl.select();
});
//{{- end}}
// 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");
});
}
});
</script>
{{- 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">
<span class="fs-6 text-gray-900 fw-semibold">Disk quota</span>
{{- 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">
<span class="fs-6 text-gray-900 fw-semibold">Transfer quota</span>
{{- 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>
<!-- <span class="fs-7 fw-semibold text-gray-500">Upload up to 30 files</span> -->
</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">
<video id="video_player" class="video-js vjs-big-play-centered vjs-fluid">
<p class="vjs-no-js">To view this video please enable JavaScript, and consider upgrading to a web browser that supports HTML5 video</p>
</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>
<button id="id_do_rename_button" type="button" class="btn btn-primary" data-bs-dismiss="modal">Submit</button>
</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">
Choose target folder
</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>
<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">
<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">
<button id="id_dir_browser_create_dir" type="button" class="btn btn-flex btn-primary">
<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>
<button class="btn btn-icon btn-light-danger" id="dirsbrowser_cancel_folder">
<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>
<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>
<div class="form-floating" id="move_copy_name_container">
<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 }}
<button id="id_copy_button" type="button" class="btn btn-light-primary me-5" data-bs-dismiss="modal">Copy</button>
{{- end}}
{{- if .CanRename }}
<button id="id_move_button" type="button" class="btn btn-primary" data-bs-dismiss="modal">Move</button>
{{- end}}
</div>
</div>
</div>
</div>
{{- end}}
{{- end}}