<!--
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"/>
<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 {{- if .CSPNonce}} nonce="{{.CSPNonce}}"{{- end}} src="{{.StaticURL}}/assets/plugins/custom/datatables/datatables.bundle.js"></script>
<script {{- if .CSPNonce}} nonce="{{.CSPNonce}}"{{- end}} src="{{.StaticURL}}/vendor/glightbox/glightbox.min.js"></script>
<script {{- if .CSPNonce}} nonce="{{.CSPNonce}}"{{- end}} src="{{.StaticURL}}/vendor/pdfobject/pdfobject.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");
                clearChilds(dirBrowserNav);
                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 = $("#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;
                }
                if (dirName.includes("/")){
                    errTxtEl.text('"/" is not allowed in file or directory names');
                    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();
                    openMediaPlayer(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 getMoveOrCopyItems() {
        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 checkMoveCopyItems(items) {
        let hasSlash = items.some(item => item.targetName.includes("/"));
        if (hasSlash){
            return [];
        }
        return items;
    }

    function doCopy() {
        let items = getMoveOrCopyItems();
        if (items.length == 0){
            return;
        }
        let errDivEl = $('#errorMsg');
        let errTxtEl = $('#errorTxt');
        errDivEl.addClass("d-none");
        items = checkMoveCopyItems(items)
        if (items.length == 0){
            errTxtEl.text('"/" is not allowed in file or directory names');
            errDivEl.removeClass("d-none");
            return;
        }
        keepAlive();
        let keepAliveTimer = setInterval(keepAlive, 300000);
        let hasError = false;
        let index = 0;

        $('#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();
    }

    function doMove() {
        let items = getMoveOrCopyItems();
        if (items.length == 0){
            return;
        }
        let errDivEl = $('#errorMsg');
        let errTxtEl = $('#errorTxt');
        errDivEl.addClass("d-none");
        items = checkMoveCopyItems(items)
        if (items.length == 0){
            errTxtEl.text('"/" is not allowed in file or directory names');
            errDivEl.removeClass("d-none");
            return;
        }
        keepAlive();
        let keepAliveTimer = setInterval(keepAlive, 300000);
        let hasError = false;
        let index = 0;

        $('#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;
        }
        if (newName.includes("/")){
            errTxtEl.text('"/" is not allowed in file or directory names');
            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 = $("#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;
        }
        if (dirName.includes("/")){
            errTxtEl.text('"/" is not allowed in file or directory names');
            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 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}}' + encodeURIComponent("/" + 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 openMediaPlayer(name, url){
        $("#video_title").text(name);
        $("#video_player").attr("src", url);
        $("#video_player").get(0).load();
        $('#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());
                });
            }
        });

        dropzone.on("addedfile", file => {
            file.previewElement.querySelector(".dz-progress").style.display = 'none';
        });

        $('#modal_video_player').on('hide.bs.modal', function () {
            $("#video_player").get(0).pause();
            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" width="100%" height="auto" controls preload="metadata">
                    Your browser does not support HTML5 video.
                </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}}