<div class="panel panel-default">
    <div class="panel-heading">
        <h3 class="panel-title pull-left"><i class="fa fa-history"></i> Operation Log</h3>
        <div class="pull-right">
            <select id="puq-filter-target-type" class="input-sm" style="margin-right:6px;">
                <option value="">All targets</option>
                <option value="server">server</option>
                <option value="service">service</option>
                <option value="group">group</option>
                <option value="dns_zone">dns_zone</option>
                <option value="dns_record">dns_record</option>
            </select>
            <input type="text" id="puq-filter-target-id" class="input-sm" placeholder="Target ID" style="width:90px;margin-right:6px;">
            <input type="text" id="puq-filter-operation" class="input-sm" placeholder="Operation…" style="width:160px;margin-right:6px;">
            <select id="puq-filter-status" class="input-sm" style="margin-right:6px;">
                <option value="">All status</option>
                <option value="success">success</option>
                <option value="error">error</option>
                <option value="info">info</option>
                <option value="skipped">skipped</option>
            </select>
            <select id="puq-filter-limit" class="input-sm" style="margin-right:6px;">
                <option value="100">100</option>
                <option value="200" selected>200</option>
                <option value="500">500</option>
                <option value="1000">1000</option>
            </select>
            <button class="btn btn-default btn-sm" id="puq-refresh"><i class="fa fa-sync"></i></button>
        </div>
        <div class="clearfix"></div>
    </div>
    <div class="panel-body">
        <p class="text-muted small">
            Per-step history of long-running operations (collect_status,
            apply_group_template, run_custom_command, service_action, …).
            For high-level audit, see <code>puqWebHosting_event_log</code>.
        </p>
        <table class="table table-striped table-bordered table-condensed" id="puq-data-table">
            <thead>
                <tr>
                    <th style="width:60px;">ID</th>
                    <th style="width:140px;">Started</th>
                    <th>Target</th>
                    <th>Operation</th>
                    <th>Step</th>
                    <th style="width:80px;">Status</th>
                    <th>Message</th>
                    <th style="width:60px;"></th>
                </tr>
            </thead>
            <tbody><tr><td colspan="8" class="text-center"><i class="fa fa-spinner fa-spin"></i> Loading…</td></tr></tbody>
        </table>
    </div>
</div>

<div class="modal fade" id="puq-log-detail-modal" tabindex="-1" role="dialog">
    <div class="modal-dialog modal-lg" role="document">
        <div class="modal-content">
            <div class="modal-header">
                <button type="button" class="close" data-dismiss="modal">&times;</button>
                <h4 class="modal-title">Log entry</h4>
            </div>
            <div class="modal-body" id="puq-log-detail-body">
                <em class="text-muted">Loading…</em>
            </div>
        </div>
    </div>
</div>

{literal}
<script>
(function(){
    var baseUrl = '{/literal}{$meta.admin_module_url}&ajax={literal}';
    var badge = window.statusBadge;
    function load() {
        var params = {
            target_type: $('#puq-filter-target-type').val(),
            target_id: $('#puq-filter-target-id').val(),
            operation: $('#puq-filter-operation').val(),
            limit: $('#puq-filter-limit').val(),
        };
        puqAjax({
            container: '#puq-data-table',
            loadingCaption: 'Loading log…',
            url: baseUrl + 'operationLog', data: params,
            success: function(r) {
                var $tbody = $('#puq-data-table tbody').empty();
                if (r.status !== 'success' || !r.data.length) {
                    $tbody.append('<tr><td colspan="8" class="text-center text-muted">No log entries.</td></tr>');
                    return;
                }
                var statusFilter = $('#puq-filter-status').val();
                r.data.forEach(function(e) {
                    // Client-side status filter (the backend doesn't filter by status,
                    // but trimming here is cheap)
                    if (statusFilter !== '' && e.status !== statusFilter) return;
                    var targetCell = esc(e.target_type) + (e.target_id ? ' #' + e.target_id : '');
                    var msg = (e.message || '');
                    if (msg.length > 140) msg = msg.substring(0, 140) + '…';
                    $tbody.append(
                        '<tr data-id="' + e.id + '">' +
                        '<td>' + e.id + '</td>' +
                        '<td class="small">' + esc(e.started_at || e.created_at || '—') + '</td>' +
                        '<td>' + targetCell + '</td>' +
                        '<td><code>' + esc(e.operation) + '</code></td>' +
                        '<td class="small">' + esc(e.step || '') + '</td>' +
                        '<td>' + badge(e.status) + '</td>' +
                        '<td class="small">' + esc(msg) + '</td>' +
                        '<td><button class="btn btn-xs btn-default puq-show-detail" title="Show full entry"><i class="fa fa-search"></i></button></td>' +
                        '</tr>'
                    );
                });
            }
        });
    }

    $(document).ready(function(){
        load();

        $('#puq-filter-target-type, #puq-filter-status, #puq-filter-limit').on('change', load);
        $('#puq-filter-target-id, #puq-filter-operation').on('keyup', function(e){
            if (e.key === 'Enter') load();
        });
        $('#puq-refresh').on('click', function() {
            var btn = this;
            btnSpinner(btn);
            setTimeout(function(){ load(); btnRestore(btn, 'sync', ''); }, 200);
        });

        $('#puq-data-table').on('click', '.puq-show-detail', function(){
            var id = $(this).closest('tr').data('id');
            var row = $(this).closest('tr');
            // Re-read fresh; cheap because operationLog returns a small window.
            $.ajax({ url: baseUrl + 'operationLog', data: { limit: 1000 }, dataType: 'json', success: function(r){
                var entry = (r.data || []).filter(function(x){ return parseInt(x.id, 10) === parseInt(id, 10); })[0];
                if (!entry) { $('#puq-log-detail-body').html('<span class="text-danger">Entry not found.</span>'); }
                else {
                    var html = '<table class="table table-condensed">';
                    ['id','operation','target_type','target_id','step','status','started_at','finished_at','created_at'].forEach(function(k){
                        html += '<tr><th style="width:140px;">' + k + '</th><td>' + esc(entry[k] == null ? '' : entry[k]) + '</td></tr>';
                    });
                    html += '<tr><th>message</th><td><pre style="white-space:pre-wrap;max-height:300px;overflow:auto;">' + esc(entry.message || '') + '</pre></td></tr>';
                    if (entry.error_detail) html += '<tr><th>error_detail</th><td><pre class="text-danger" style="white-space:pre-wrap;max-height:300px;overflow:auto;">' + esc(entry.error_detail) + '</pre></td></tr>';
                    html += '</table>';
                    $('#puq-log-detail-body').html(html);
                }
                $('#puq-log-detail-modal').modal('show');
            }});
        });
    });
})();
</script>
{/literal}
