123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067 |
- <!--
- 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 "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 data-i18n="[placeholder]general.search" 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" data-i18n="fs.new_folder" 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" data-i18n="fs.upload.text" 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 data-i18n="fs.select_across_pages" 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 data-i18n="fs.actions" 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 data-i18n="fs.download" 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 data-i18n="fs.move_copy" 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 data-i18n="fs.share" 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 data-i18n="general.delete" 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 data-i18n="fs.home" 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 data-i18n="[placeholder]fs.create_folder_msg" 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 data-i18n="general.name" class="min-w-250px">Name</th>
- <th data-i18n="general.size" class="min-w-10px">Size</th>
- <th data-i18n="general.last_modified" 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 = "";
- if ($xhr) {
- let json = $xhr.responseJSON;
- if (json) {
- if (json.message) {
- txt = json.message;
- }
- }
- }
- if (!txt){
- txt = "fs.dir_list.err_generic";
- }
- setI18NData($('#errorModalTxt'), 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: {
- info: $.t('datatable.info'),
- infoEmpty: $.t('datatable.info_empty'),
- infoFiltered: $.t('datatable.info_filtered'),
- loadingRecords: "",
- processing: $.t('datatable.processing'),
- zeroRecords: "",
- emptyTable: $.t('fs.no_more_subfolders')
- },
- 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 = $.t('fs.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){
- setI18NData(errTxtEl, "fs.folder_name_required");
- errDivEl.removeClass("d-none");
- return;
- }
- if (dirName.includes("/")){
- setI18NData(errTxtEl, "fs.invalid_name");
- 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 = "";
- if (error && error.response) {
- switch (error.response.status) {
- case 403:
- errorMessage = "fs.create_dir.err_403";
- break;
- case 429:
- errorMessage = "fs.create_dir.err_429";
- break;
- }
- }
- if (!errorMessage){
- errorMessage = "fs.create_dir.err_generic";
- }
- setI18NData(errTxtEl, 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 = "";
- if ($xhr) {
- let json = $xhr.responseJSON;
- if (json) {
- if (json.message){
- txt = json.message;
- }
- }
- }
- if (!txt){
- txt = "fs.dir_list.err_generic";
- }
- setI18NData($('#errorTxt'), 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",
- render: function (data, type, row) {
- if (type === 'display') {
- if (data){
- return $.t('general.datetime', {
- val: new Date(data),
- formatParams: {
- val: { year: 'numeric', month: 'numeric', day: 'numeric', hour: 'numeric', minute: 'numeric' },
- }
- });
- }
- return ""
- }
- return data;
- }
- },
- {
- data: "edit_url",
- className: 'text-end',
- render: function (data, type, row) {
- if (type === 'display') {
- let previewDiv = "";
- if (row["type"] == "2") {
- let filename = escapeHTML(row["name"]);
- let extension = filename.slice((filename.lastIndexOf(".") - 1 >>> 0) + 2).toLowerCase();
- switch (extension) {
- case "jpeg":
- case "jpg":
- case "png":
- case "gif":
- case "webp":
- case "bmp":
- case "svg":
- case "ico":
- let desc = escapeHTML(filename).replace(/"/g, '"');
- previewDiv = `<div class="ms-2" data-kt-filemanger-table="view_item">
- <a href="${row['url']}" data-gallery="gallery" data-glightbox="description: <span class="fs-5 fw-bold">${desc}</span>" class="btn btn-sm btn-icon btn-light btn-active-light-primary glightbox">
- <i class="ki-duotone ki-eye fs-5 m-0">
- <span class="path1"></span>
- <span class="path2"></span>
- <span class="path3"></span>
- </i>
- </a>
- </div>`;
- break;
- case "mp4":
- case "mov":
- case "webm":
- case "ogv":
- case "ogg":
- case "mp3":
- case "wav":
- previewDiv = `<div class="ms-2" data-kt-filemanger-table="view_item">
- <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 data-i18n="general.rename" 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 data-i18n="fs.move_copy" 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 data-i18n="fs.share" 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 data-i18n="general.delete" 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: {
- info: $.t('datatable.info'),
- infoEmpty: $.t('datatable.info_empty'),
- infoFiltered: $.t('datatable.info_filtered'),
- loadingRecords: "",
- processing: $.t('datatable.processing'),
- zeroRecords: "",
- emptyTable: $.t('fs.no_files_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();
- $('#file_manager_list_body').localize();
- });
- 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 = $.t('general.selected_items', { count: totalSelected});
- }
- 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: $.t('general.delete_multi_confirm'),
- icon: "warning",
- confirmButtonText: $.t('general.delete'),
- cancelButtonText: $.t('general.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){
- deleteTxt = $.t('fs.deleting', {
- idx : index + 1,
- total: selectedRowsIdx.length,
- name: getNameFromMeta(meta)
- });
- }
- $('#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;
- if (error && error.response) {
- switch (error.response.status) {
- case 403:
- if (deleted > 0){
- errorMessage = "fs.delete_multi.err_403_partial";
- } else {
- errorMessage = "fs.delete_multi.err_403";
- }
- break;
- case 429:
- if (deleted > 0){
- errorMessage = "fs.delete_multi.err_429_partial";
- } else {
- errorMessage = "fs.delete_multi.err_429";
- }
- break;
- }
- }
- if (!errorMessage){
- if (deleted > 0){
- errorMessage = "fs.delete_multi.err_generic_partial";
- } else {
- errorMessage = "fs.delete_multi.err_generic";
- }
- }
- setI18NData(errTxtEl, 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){
- setI18NData(errTxtEl, "fs.invalid_name");
- 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) {
- msgTxt = $.t('fs.copying', {
- idx: index + 1,
- total: items.length,
- name: `${sourcePath} => ${targetPath}`
- });
- $('#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 = "";
- if (error && error.response) {
- switch (error.response.status) {
- case 403:
- errorMessage = "fs.copy.err_403";
- break;
- case 429:
- errorMessage = "fs.copy.err_429";
- break;
- }
- }
- if (!errorMessage){
- errorMessage = "fs.copy.err_generic";
- }
- setI18NData(errTxtEl, 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){
- setI18NData(errTxtEl, "fs.invalid_name");
- 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) {
- msgTxt = $.t('fs.moving', {
- idx: index + 1,
- total: items.length,
- name: `${sourcePath} => ${targetPath}`
- });
- $('#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 = "";
- if (error && error.response) {
- switch (error.response.status) {
- case 403:
- errorMessage = "fs.move.err_403";
- break;
- case 429:
- errorMessage = "fs.move.err_429";
- break;
- }
- }
- if (!errorMessage){
- errorMessage = "fs.move.err_generic";
- }
- setI18NData(errTxtEl, 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: $.t('general.delete_confirm', {name: itemName}),
- icon: "warning",
- confirmButtonText: $.t('general.delete'),
- cancelButtonText: $.t('general.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;
- if (error && error.response) {
- switch (error.response.status) {
- case 403:
- errorMessage = "fs.delete.err_403";
- break;
- case 429:
- errorMessage = "fs.delete.err_429";
- break;
- }
- }
- if (!errorMessage){
- errorMessage = "fs.delete.err_generic";
- }
- errTxtEl.removeAttr("data-i18n")
- errTxtEl.text($.t(errorMessage, {name: itemName}));
- 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){
- setI18NData(errTxtEl, "general.name_required");
- errDivEl.removeClass("d-none");
- return;
- }
- if (newName == oldName){
- setI18NData(errTxtEl, "general.name_different");
- errDivEl.removeClass("d-none");
- return;
- }
- if (newName.includes("/")){
- setI18NData(errTxtEl, "fs.invalid_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;
- if (error && error.response) {
- switch (error.response.status) {
- case 403:
- errorMessage = "fs.rename.err_403";
- break;
- case 429:
- errorMessage = "fs.rename.err_429";
- break;
- }
- }
- if (!errorMessage){
- errorMessage = "fs.rename.err_generic";
- }
- errTxtEl.removeAttr("data-i18n")
- errTxtEl.text($.t(errorMessage, {name: oldName}));
- 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){
- setI18NData(errTxtEl, "fs.folder_name_required");
- errDivEl.removeClass("d-none");
- return;
- }
- if (dirName.includes("/")){
- setI18NData(errTxtEl, "fs.invalid_name");
- 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 = "";
- if (error && error.response) {
- switch (error.response.status) {
- case 403:
- errorMessage = "fs.create_dir.err_403";
- break;
- case 429:
- errorMessage = "fs.create_dir.err_429";
- break;
- }
- }
- if (!errorMessage){
- errorMessage = "fs.create_dir.err_generic";
- }
- setI18NData(errTxtEl, 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.error("unable to get last modified time from file: " + e.message);
- lastModified = "";
- }
- let uploadTxt = f.name;
- if (files.length > 1){
- uploadTxt = $.t('fs.uploading', {
- idx: index + 1,
- total: files.length,
- name: 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;
- if (error && error.response) {
- switch (error.response.status) {
- case 403:
- errorMessage = "fs.upload.err_403";
- break;
- case 429:
- errorMessage = "fs.upload.err_429";
- break;
- }
- }
- if (!errorMessage){
- errorMessage = "fs.upload.err_generic";
- }
- index++;
- has_errors = true;
- setI18NData($('#errorTxt'), 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);
- }
- $(document).on("i18nshow", 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-375px" data-kt-menu="true">
- <div class="card">
- <div class="card-header">
- <h3 class="card-title"><span data-i18n="fs.quota_usage.title" class="text-gray-700 fw-bold 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 data-i18n="fs.quota_usage.disk" 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">
- <span {{if gt $percentage 0}}data-i18n="fs.quota_usage.size_percentage" data-i18n-options='{ "val": "{{$size}}", "percentage": {{$percentage}} }'{{else}}data-i18n="fs.quota_usage.size" data-i18n-options='{ "val": "{{$size}}" }'{{end}}></span>
- </div>
- {{- end}}
- {{- if $files}}
- {{- $percentage := .QuotaUsage.GetQuotaFilesPercentage}}
- <div class="{{if .QuotaUsage.IsQuotaFilesLow}}text-warning{{else}}text-gray-700{{end}} fw-semibold fs-6">
- <span {{if gt $percentage 0}}data-i18n="fs.quota_usage.files_percentage" data-i18n-options='{ "val": "{{$files}}", "percentage": {{$percentage}} }'{{else}}data-i18n="fs.quota_usage.files" data-i18n-options='{ "val": "{{$files}}" }'{{end}}></span>
- </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 data-i18n="fs.quota_usage.transfer" 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">
- <span {{if gt $percentage 0}}data-i18n="fs.quota_usage.total_percentage" data-i18n-options='{ "val": "{{$total}}", "percentage": {{$percentage}} }'{{else}}data-i18n="fs.quota_usage.total" data-i18n-options='{ "val": "{{$total}}" }'{{end}}>
- </span>
- </div>
- {{- end}}
- {{- if $download}}
- {{$percentage := .QuotaUsage.GetDownloadTransferQuotaPercentage}}
- <div class="{{if .QuotaUsage.IsDownloadTransferQuotaLow}}text-warning{{else}}text-gray-700{{end}} fw-semibold fs-6">
- <span {{if gt $percentage 0}}data-i18n="fs.quota_usage.downloads_percentage" data-i18n-options='{ "val": "{{$download}}", "percentage": {{$percentage}} }'{{else}}data-i18n="fs.quota_usage.downloads" data-i18n-options='{ "val": "{{$download}}" }'{{end}}>
- </span>
- </div>
- {{- end}}
- {{- if $upload}}
- {{$percentage := .QuotaUsage.GetUploadTransferQuotaPercentage}}
- <div class="{{if .QuotaUsage.IsUploadTransferQuotaLow}}text-warning{{else}}text-gray-700{{end}} fw-semibold fs-6">
- <span {{if gt $percentage 0}}data-i18n="fs.quota_usage.uploads_percentage" data-i18n-options='{ "val": "{{$upload}}", "percentage": {{$percentage}} }'{{else}}data-i18n="fs.quota_usage.uploads" data-i18n-options='{ "val": "{{$upload}}" }'{{end}}>
- </span>
- </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 data-i18n="fs.upload.text" class="modal-title">Upload files</h3>
- <div data-i18n="[aria-label]general.close" 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 data-i18n="fs.upload.message" 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 data-i18n="general.cancel" type="button" class="btn btn-light me-5" data-bs-dismiss="modal">Cancel</button>
- <button data-i18n="general.submit" 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 data-i18n="[aria-label]general.close" 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">
- <span data-i18n="general.html5_media_not_supported"></span>
- </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 data-i18n="[aria-label]general.close" 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 data-i18n="fs.rename.new_name" for="rename_new_name" class="form-label"></label>
- <input id="rename_new_name" type="text" class="form-control"/>
- </div>
- </div>
- <div class="modal-footer border-0">
- <button data-i18n="general.cancel" type="button" class="btn btn-secondary me-5" data-bs-dismiss="modal">Cancel</button>
- <button data-i18n="general.submit" 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 data-i18n="general.choose_target_folder" class="modal-title">
- Choose target folder
- </h3>
- <div data-i18n="[aria-label]general.close" 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 rounded border-warning border border-dashed bg-light-warning d-flex align-items-center p-5 mb-10">
- <i class="ki-duotone ki-information 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>
- <span data-i18n="general.add"></span>
- </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 data-i18n="[placeholder]fs.create_folder_msg" 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 data-i18n="general.name" 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 data-i18n="general.source_name" 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 data-i18n="general.target_folder" 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 data-i18n="general.dest_name" for="move_copy_name">Destination name</label>
- </div>
- </div>
- <div class="modal-footer border-0">
- {{- if .CanAddFiles }}
- <button data-i18n="fs.copy.msg" id="id_copy_button" type="button" class="btn btn-light-primary me-5" data-bs-dismiss="modal">Copy</button>
- {{- end}}
- {{- if .CanRename }}
- <button data-i18n="fs.move.msg" id="id_move_button" type="button" class="btn btn-primary" data-bs-dismiss="modal">Move</button>
- {{- end}}
- </div>
- </div>
- </div>
- </div>
- {{- end}}
- {{- end}}
|