<!--
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 "extra_css"}}
<link href="{{.StaticURL}}/assets/plugins/custom/datatables/datatables.bundle.css" rel="stylesheet" type="text/css"/>
{{- end}}

{{- define "page_body"}}
{{- template "errmsg" ""}}
<div class="card shadow-sm">
    <div class="card-header bg-light">
        <h3 data-i18n="share.view_manage" class="card-title section-title">View and manage shares</h3>
    </div>
    <div id="card_body" class="card-body">
        <div id="loader" class="align-items-center text-center my-10">
            <span class="spinner-border w-15px h-15px text-muted align-middle me-2"></span>
            <span data-i18n="general.loading" class="text-gray-700">Loading...</span>
        </div>
        <div id="card_content" class="d-none">
            <div class="d-flex flex-stack flex-wrap mb-5">
                <div class="d-flex align-items-center position-relative my-2">
                    <i class="ki-solid ki-magnifier fs-1 position-absolute ms-6"></i>
                    <input name="search" data-i18n="[placeholder]general.search" type="text" data-table-filter="search"
                        class="form-control rounded-1 w-250px ps-15 me-5" placeholder="Search" />
                </div>
                <div class="d-flex justify-content-end my-2" data-table-toolbar="base">
                    <a href="{{.ShareURL}}" class="btn btn-primary">
                        <i class="ki-duotone ki-plus fs-2"></i>
                        <span data-i18n="general.add">Add</span>
                    </a>
                </div>
            </div>

            <table id="dataTable" 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 data-i18n="general.name">Name</th>
                        <th data-i18n="share.scope">Scope</th>
                        <th data-i18n="general.info">Info</th>
                        <th class="min-w-100px"></th>
                    </tr>
                </thead>
                <tbody id="table_body" class="text-gray-800 fw-semibold"></tbody>
            </table>
        </div>
    </div>
</div>
{{- end}}

{{- define "modals"}}
<div class="modal fade" id="link_modal" tabindex="-1">
    <div class="modal-dialog" role="document">
        <div class="modal-content">
            <div class="modal-header border-0">
                <h3 data-i18n="share.access_links_title" class="modal-title">
                    Share access links
                </h3>
                <div data-i18n="[aria-label]general.close" class="btn btn-icon btn-sm btn-active-light-primary" data-bs-dismiss="modal" aria-label="Close">
                    <i class="ki-solid ki-cross fs-2x text-gray-700"></i>
                </div>
            </div>
            <div class="modal-body fs-5">
                <div id="readShare" class="mb-5">
                    <div class="mb-3">
                        <h4 data-i18n="share.link_single_title">Single zip file</h4>
                        <p data-i18n="share.link_single_desc">You can download shared content as a single zip file</p>
                        <div class="d-flex">
                            <button id="readLinkCopy" type="button" class="btn btn-flex btn-light-primary btn-clipboard-copy me-3">
                                <i class="ki-duotone ki-fasten fs-2">
                                    <span class="path1"></span>
                                    <span class="path2"></span>
                                </i>
                                <span data-i18n="general.copy_link">Copy link</span>
                            </button>
                            <a id="readLink" href="#" target="_blank" type="button" class="btn btn-flex btn-primary">
                                <i class="ki-duotone ki-folder-down fs-2">
                                    <span class="path1"></span>
                                    <span class="path2"></span>
                                </i>
                                <span data-i18n="fs.download">Download</span>
                            </a>
                        </div>
                    </div>
                    <hr>
                    <div class="mb-3 mt-10">
                        <h4 data-i18n="share.link_dir_title">Single directory</h4>
                        <p data-i18n="share.link_dir_desc">If the share consists of a single directory you can browse and download files</p>
                        <button id="readBrowseLinkCopy" data-clipboard-target="#readBrowseLink" type="button" class="btn btn-flex btn-light-primary btn-clipboard-copy me-3">
                            <i class="ki-duotone ki-fasten fs-2">
                                <span class="path1"></span>
                                <span class="path2"></span>
                            </i>
                            <span data-i18n="general.copy_link">Copy link</span>
                        </button>
                        <a id="readBrowseLink" href="#" target="_blank" type="button" class="btn btn-flex btn-primary">
                            <i class="ki-duotone ki-arrow-up-right fs-2">
                                <span class="path1"></span>
                                <span class="path2"></span>
                            </i>
                            <span data-i18n="share.go">Go to share</span>
                        </a>
                    </div>
                    <hr>
                    <div class="mt-10">
                        <h4 data-i18n="share.link_uncompressed_title">Uncompressed file</h4>
                        <p data-i18n="share.link_uncompressed_desc">If the share consists of a single file you can download it uncompressed</p>
                        <button id="readUncompressedLinkCopy"  data-clipboard-target="#readUncompressedLink" type="button" class="btn btn-flex btn-light-primary btn-clipboard-copy me-3">
                            <i class="ki-duotone ki-fasten fs-2">
                                <span class="path1"></span>
                                <span class="path2"></span>
                            </i>
                            <span data-i18n="general.copy_link">Copy link</span>
                        </button>
                        <a id="readUncompressedLink" href="#" target="_blank" type="button" class="btn btn-flex btn-primary">
                            <i class="ki-duotone ki-folder-down fs-2">
                                <span class="path1"></span>
                                <span class="path2"></span>
                            </i>
                            <span data-i18n="fs.download">Download</span>
                        </a>
                    </div>
                </div>
                <div id="writeShare" class="mb-5">
                    <p data-i18n="share.upload_desc">You can upload one or more files to the shared directory</p>
                    <button id="writePageLinkCopy"  data-clipboard-target="#writePageLink" type="button" class="btn btn-flex btn-light-primary btn-clipboard-copy me-3">
                        <i class="ki-duotone ki-fasten fs-2">
                            <span class="path1"></span>
                            <span class="path2"></span>
                        </i>
                        <span data-i18n="general.copy_link">Copy link</span>
                    </button>
                    <a id="writePageLink" href="#" target="_blank" type="button" class="btn btn-flex btn-primary">
                        <i class="ki-duotone ki-folder-up fs-2">
                            <span class="path1"></span>
                            <span class="path2"></span>
                        </i>
                        <span data-i18n="fs.upload.text">Upload</span>
                    </a>
                </div>
                <div data-i18n="share.expired_desc" id="expiredShare" class="fw-semibold fs-4 mb-5">
                    This share is no longer accessible because it has expired
                </div>
            </div>
        </div>
    </div>
</div>
{{end}}

{{- define "extra_js"}}
<script {{- if .CSPNonce}} nonce="{{.CSPNonce}}"{{- end}} src="{{.StaticURL}}/assets/plugins/custom/datatables/datatables.bundle.js"></script>
<script type="text/javascript" {{- if .CSPNonce}} nonce="{{.CSPNonce}}"{{- end}}>

    function deleteAction(shareID) {
        ModalAlert.fire({
            text: $.t('general.delete_confirm_generic'),
            icon: "warning",
            confirmButtonText: $.t('general.delete_confirm_btn'),
            cancelButtonText: $.t('general.cancel'),
            customClass: {
                confirmButton: "btn btn-danger",
                cancelButton: 'btn btn-secondary'
            }
        }).then((result) => {
            if (result.isConfirmed){
                $('#loading_message').text("");
                KTApp.showPageLoading();
                let path = '{{.ShareURL}}' + "/" + encodeURIComponent(shareID);

                axios.delete(path, {
                    timeout: 15000,
                    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 = "general.delete_error_403";
                                break;
                            case 404:
                                errorMessage = "general.delete_error_404";
                                break;
                        }
                    }
                    if (!errorMessage){
                        errorMessage = "general.delete_error_generic";
                    }
                    ModalAlert.fire({
                        text: $.t(errorMessage),
                        icon: "warning",
                        confirmButtonText: $.t('general.ok'),
                        customClass: {
                            confirmButton: "btn btn-primary"
                        }
                    });
                });
            }
        });
    }

    function editAction(shareID) {
        window.location.replace('{{.ShareURL}}' + "/" + encodeURIComponent(shareID));
    }

    function showShareLink(shareID, shareScope, expiresAt) {
        if (expiresAt < Date.now()) {
            $('#expiredShare').show();
            $('#writeShare').hide();
            $('#readShare').hide();
        } else {
            let shareURL = '{{.BasePublicSharesURL}}' + "/" + encodeURIComponent(shareID);
            if (shareScope == '1') {
                $('#expiredShare').hide();
                $('#writeShare').hide();
                $('#readShare').show();
                $('#readLink').attr("href", shareURL + "/download");
                $('#readLink').attr("title", shareURL + "/download");
                $('#readLinkCopy').attr("data-clipboard-text",getCurrentURI()+shareURL + "/download");
                $('#readUncompressedLink').attr("href", shareURL + "/download?compress=false");
                $('#readUncompressedLink').attr("title", shareURL + "/download?compress=false");
                $('#readUncompressedLinkCopy').attr("data-clipboard-text",getCurrentURI()+shareURL + "/download?compress=false");
                $('#readBrowseLink').attr("href", shareURL + "/browse");
                $('#readBrowseLink').attr("title", shareURL + "/browse");
                $('#readBrowseLinkCopy').attr("data-clipboard-text",getCurrentURI()+shareURL + "/browse");
            } else {
                $('#expiredShare').hide();
                $('#writeShare').show();
                $('#readShare').hide();
                $('#writePageLink').attr("href", shareURL + "/upload");
                $('#writePageLink').attr("title", shareURL + "/upload");
                $('#writePageLinkCopy').attr("data-clipboard-text",getCurrentURI()+shareURL + "/upload");
            }
        }
        $('#link_modal').modal('show');
    }

    var sharesDatatable = function(){
        var dt;

        var initDatatable = function () {
            dt = $('#dataTable').DataTable({
                ajax: {
                    url: "{{.SharesURL}}/json",
                    dataSrc: "",
                    error: function ($xhr, textStatus, errorThrown) {
                        $(".dt-processing").hide();
                        $('#loader').addClass("d-none");
                        let txt = "";
                        if ($xhr) {
                            let json = $xhr.responseJSON;
                            if (json) {
                                if (json.message){
                                    txt = json.message;
                                }
                            }
                        }
                        if (!txt){
                            txt = "general.error500";
                        }
                        setI18NData($('#errorTxt'), txt);
                        $('#errorMsg').removeClass("d-none");
                    }
                },
                columns: [
                    {
                        data: "name",
                        render: function(data, type, row) {
                            if (type === 'display') {
                                return escapeHTML(data);
                            }
                            return data;
                        }
                    },
                    {
                        data: "scope",
                        render: function (data, type, row) {
                            if (type === 'display') {
                                switch (data){
                                    case 2:
                                        return $.t('share.scope_write');
                                    case 3:
                                        return $.t('share.scope_read_write');
                                    default:
                                        return $.t('share.scope_read');
                                }
                            }
                            return data;
                        }
                    },
                    {
                        data: "expires_at",
                        defaultContent: 0,
                        searchable: false,
                        orderable: false,
                        render: function (data, type, row) {
                            if (type === 'display') {
                                let info = "";
                                if (row.expires_at && row.expires_at > 0){
                                    info+= $.t('share.expiration_date', {
                                        val: row.expires_at,
                                        formatParams: {
                                            val: { year: 'numeric', month: 'numeric', day: 'numeric' },
                                        }
                                    });
                                }
                                if (row.last_use_at && row.last_use_at > 0){
                                    info+= $.t('share.last_use', {
                                        val: row.last_use_at,
                                        formatParams: {
                                            val: { year: 'numeric', month: 'numeric', day: 'numeric' },
                                        }
                                    });
                                }
                                let used_tokens = 0;
                                if (row.used_tokens && row.used_tokens > 0){
                                    used_tokens = row.used_tokens;
                                }
                                if (row.max_tokens && row.max_tokens > 0){
                                    info+= $.t('share.usage', {used: used_tokens, total: row.max_tokens});
                                } else {
                                    info+= $.t('share.used_tokens', {used: used_tokens});
                                }
                                if (row.password){
                                    info+= $.t('share.password_protected')
                                }
                                return info;
                            }
                            return data;
                        }
                    },
                    {
                        data: "id",
                        searchable: false,
                        orderable: false,
                        className: 'text-end',
                        render: function (data, type, row) {
                            if (type === 'display') {
                                return `<div class="d-flex justify-content-end">
                                    <div class="ms-2">
                                        <a href="#" class="btn btn-sm btn-icon btn-light btn-active-light-primary" data-table-action="show_link">
                                            <i class="ki-duotone ki-fasten fs-5 m-0">
                                                <span class="path1"></span>
                                                <span class="path2"></span>
                                            </i>
                                        </a>
                                    </div>
                                    <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-6 w-150px py-4" data-kt-menu="true">
                                            <div class="menu-item px-3">
                                                <a data-i18n="general.edit" href="#" class="menu-link px-3" data-table-action="edit_row">Edit</a>
                                            </div>
                                            <div class="menu-item px-3">
                                                <a data-i18n="general.delete" href="#" class="menu-link text-danger px-3" data-table-action="delete_row">Delete</a>
                                            </div>
                                        </div>
                                    </div>
                                </div>`;
                            }
                            return "";
                        }
                    }
                ],
                deferRender: true,
                stateSave: true,
                stateDuration: 0,
                stateLoadParams: function (settings, data) {
                        if (data.search.search){
                            const filterSearch = document.querySelector('[data-table-filter="search"]');
                            filterSearch.value = data.search.search;
                        }
                    },
                language: {
                    info: $.t('datatable.info'),
                    infoEmpty: $.t('datatable.info_empty'),
                    infoFiltered: $.t('datatable.info_filtered'),
                    loadingRecords: "",
                    processing: $.t('datatable.processing'),
                    zeroRecords: "",
                    emptyTable: $.t('share.no_share')
                },
                order: [[1, 'asc']],
                initComplete: function(settings, json) {
                    $('#loader').addClass("d-none");
                    $('#card_content').removeClass("d-none");
                    let api = $.fn.dataTable.Api(settings);
                    api.columns.adjust().draw("page");
                    drawAction();
                }
            });

            dt.on('draw', drawAction);
        }

        function drawAction() {
            KTMenu.createInstances();
            handleRowActions();
            $('#table_body').localize();
        }

        var handleSearchDatatable = function () {
            const filterSearch = $(document.querySelector('[data-table-filter="search"]'));
            filterSearch.off("keyup");
            filterSearch.on('keyup', function (e) {
                dt.rows().deselect();
                dt.search(e.target.value).draw();
            });
        }

        function handleRowActions() {
            const editButtons = document.querySelectorAll('[data-table-action="edit_row"]');

            editButtons.forEach(d => {
                let el = $(d);
                el.off("click");
                el.on("click", function(e){
                    e.preventDefault();
                    const parent = e.target.closest('tr');
                    editAction(dt.row(parent).data()["id"]);
                });
            });

            const deleteButtons = document.querySelectorAll('[data-table-action="delete_row"]');

            deleteButtons.forEach(d => {
                let el = $(d);
                el.off("click");
                el.on("click", function(e){
                    e.preventDefault();
                    const parent = e.target.closest('tr');
                    deleteAction(dt.row(parent).data()["id"]);
                });
            });

            const showLinkButtons = document.querySelectorAll('[data-table-action="show_link"]');

            showLinkButtons.forEach(d => {
                let el = $(d);
                el.off("click");
                el.on("click", function(e){
                    e.preventDefault();
                    let rowData = dt.row(e.target.closest('tr')).data();
                    showShareLink(rowData["id"], rowData["scope"], rowData["expires_at"]);
                });
            });
        }

        return {
            init: function () {
                initDatatable();
                handleSearchDatatable();
            }
        }
    }();

    $(document).on("i18nshow", function(){
        sharesDatatable.init();

        var clipboard = new ClipboardJS('.btn-clipboard-copy',{
            container: document.getElementById('link_modal')
        });

        clipboard.on('success', function (e) {
            e.trigger.querySelectorAll('span').forEach(spanEl => {
                if (spanEl.getAttribute('data-i18n')){
                    e.trigger.classList.remove("btn-light-primary");
                    e.trigger.classList.add("btn-success");
                    setI18NData($(spanEl),"general.copied");
                    setTimeout(function(){
                        e.trigger.classList.remove("btn-success");
                        e.trigger.classList.add("btn-light-primary");
                        setI18NData($(spanEl),"general.copy_link");
                    }, 3000)
                }
            });
            e.clearSelection();
        });

    });
</script>
{{end}}