<!--
Copyright (C) 2024 Nicola Murino

This WebUI uses the KeenThemes Bootstrap Templates:

https://keenthemes.com/bootstrap-templates

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"}}
<div class="card shadow-sm">
    <div class="card-header bg-light">
        <h3 data-i18n="connections.view_manage" class="card-title section-title">View and manage connections</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="{{.ConnectionsURL}}" class="btn btn-primary">
                        <i class="ki-solid ki-arrows-circle fs-2"></i>
                        <span data-i18n="general.refresh">Refresh</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>ID</th>
                        <th>Node</th>
                        <th data-i18n="login.username">Username</th>
                        <th data-i18n="connections.started">Started</th>
                        <th data-i18n="connections.remote_address">Remote address</th>
                        <th data-i18n="general.protocol">Protocol</th>
                        <th data-i18n="connections.last_activity">Last activity</th>
                        <th data-i18n="general.info">Info</th>
                        <th></th>
                    </tr>
                </thead>
                <tbody id="table_body" class="text-gray-800 fw-semibold"></tbody>
            </table>

        </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 disconnectAction(connectionID, node) {
        ModalAlert.fire({
            text: $.t('connections.disconnect_confirm'),
            icon: "warning",
            confirmButtonText: $.t('connections.disconnect_confirm_btn'),
            cancelButtonText: $.t('general.cancel'),
            customClass: {
                confirmButton: "btn btn-danger",
                cancelButton: 'btn btn-secondary'
            }
        }).then((result) => {
            if (result.isConfirmed){
                clearLoading();
                KTApp.showPageLoading();
                let path = '{{.ConnectionsURL}}' + "/" + encodeURIComponent(connectionID);
                if (node) {
                    path+="?node="+ encodeURIComponent(node);
                }

                axios.delete(path, {
                    timeout: 15000,
                    headers: {
                        'X-CSRF-TOKEN': '{{.CSRFToken}}'
                    },
                    validateStatus: function (status) {
                        return status == 200;
                    }
                }).then(function(response){
                    setTimeout(function() {
                        location.reload();
                    },250);
                }).catch(function(error){
                    KTApp.hidePageLoading();
                    ModalAlert.fire({
                        text: $.t('connections.disconnect_ko'),
                        icon: "warning",
                        confirmButtonText: $.t('general.ok'),
                        customClass: {
                            confirmButton: "btn btn-primary"
                        }
                    });
                });
            }
        });
    }

    var datatable = function(){
        var dt;

        var initDatatable = function () {
            $('#errorMsg').addClass("d-none");
            dt = $('#dataTable').DataTable({
                ajax: {
                    url: "{{.ConnectionsURL}}/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: "connection_id",
                        visible: false,
                        searchable: false,
                        orderable: false,
                        render: function(data, type, row) {
                            if (type === 'display') {
                                return escapeHTML(data);
                            }
                            return data;
                        }
                    },
                    {
                        data: "node",
                        visible: false,
                        searchable: false,
                        orderable: false,
                        defaultContent: "",
                        render: function(data, type, row) {
                            if (type === 'display') {
                                return escapeHTML(data);
                            }
                            return data;
                        }
                    },
                    {
                        data: "username",
                        defaultContent: "",
                        render: function(data, type, row) {
                            if (type === 'display') {
                                return escapeHTML(data);
                            }
                            return data;
                        }
                    },
                    {
                        data: "connection_time",
                        searchable: false,
                        defaultContent: 0,
                        render: function(data, type, row) {
                            if (type === 'display') {
                                if (data > 0){
                                    return $.t('general.datetime', {
                                        val: parseInt(data, 10),
                                        formatParams: {
                                            val: { year: '2-digit', month: 'numeric', day: 'numeric', hour: 'numeric', minute: 'numeric', second: 'numeric' },
                                        }
                                    });
                                }
                                return ""
                            }
                            return data;
                        }
                    },
                    {
                        data: "remote_address",
                        defaultContent: "",
                        render: function(data, type, row) {
                            if (type === 'display') {
                                return escapeHTML(data);
                            }
                            return data;
                        }
                    },
                    {
                        data: "protocol",
                        defaultContent: "",
                        render: function(data, type, row) {
                            if (type === 'display') {
                                return escapeHTML(data);
                            }
                            return data;
                        }
                    },
                    {
                        data: "last_activity",
                        searchable: false,
                        defaultContent: 0,
                        render: function(data, type, row) {
                            if (type === 'display') {
                                if (data > 0){
                                    return $.t('general.datetime', {
                                        val: parseInt(data, 10),
                                        formatParams: {
                                            val: { year: '2-digit', month: 'numeric', day: 'numeric', hour: 'numeric', minute: 'numeric', second: 'numeric' },
                                        }
                                    });
                                }
                                return ""
                            }
                            return data;
                        }
                    },
                    {
                        data: "active_transfers",
                        searchable: false,
                        orderable: false,
                        render: function (data, type, row) {
                            if (type === 'display') {
                                let result = "";
                                if (row.active_transfers && row.active_transfers.length > 0) {
                                    for (let i = 0; i < row.active_transfers.length; i++) {
                                        if (i > 0){
                                            result+=". ";
                                        }
                                        let transfer = row.active_transfers[i];
                                        let path = escapeHTML(transfer.path);
                                        let elapsed = row.current_time - transfer.start_time;
                                        if (elapsed > 0 && transfer.size > 0) {
                                            let speed = (transfer.size * 1.0) / (elapsed / 1000.0);
                                            if (transfer.operation_type === 'upload') {
                                                result += $.t('connections.upload_info', { path: path, size: fileSizeIEC(transfer.size), speed: humanizeSpeed(speed) });
                                            } else {
                                                result += $.t('connections.download_info', { path: path, size: fileSizeIEC(transfer.size), speed: humanizeSpeed(speed) });
                                            }
                                        } else {
                                            if (transfer.operation_type === 'upload') {
                                                result += $.t('connections.upload', { path: path });
                                            } else {
                                                result += $.t('connections.download', { path: path });
                                            }
                                        }
                                    }
                                }
                                if (row.client_version){
                                    if (result){
                                        result+= ". ";
                                    }
                                    result+= $.t('connections.client', {val: escapeHTML(row.client_version)});
                                }
                                return result;
                            }
                            return "";
                        }
                    },
                    {
                        data: "",
                        searchable: false,
                        orderable: false,
                        className: 'text-end',
                        render: function (data, type, row) {
                            if (type === 'display') {
                                //{{- if .LoggedUser.HasPermission "close_conns"}}
                                return `<div class="d-flex justify-content-end">
                                            <div class="ms-2">
                                                <a href="#" class="btn btn-sm btn-icon btn-light-danger" data-table-action="close_conn">
                                                    <i class="ki-solid ki-cross fs-1"></i>
                                                </a>
                                            </div>
                                    </div>`;
                                //{{- end}}
                            }
                            return "";
                        }
                    },
                ],
                deferRender: true,
                stateSave: true,
                stateDuration: 0,
                colReorder: {
                    enable: true
                },
                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('datatable.no_records')
                },
                order: [[0, '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");
                }
            });

            dt.on('draw.dt', drawAction);
            dt.on('columns-reordered', function(e, settings, details){
                drawAction();
            });
        }

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

        var handleDatatableActions = 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 closeButtons = document.querySelectorAll('[data-table-action="close_conn"]');
            closeButtons.forEach(d => {
                let el = $(d);
                el.off("click");
                el.on("click", function(e){
                    e.preventDefault();
                    const parent = e.target.closest('tr');
                    let data = dt.row(parent).data();
                    disconnectAction(data.connection_id, data.node);
                });
            });
        }

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

    $(document).on("i18nshow", function(){
        datatable.init();
    });
</script>
{{- end}}