{% extends "base.html" %} {% block title %}Lista serwerów - /etc/hosts Manager{% endblock %} {% block extra_css %} {{ super() }} <style> .tooltip-inner { max-width: 300px; text-align: left; } /* Zmniejsz tekst w nagłówku tabeli i wyśrodkuj go */ thead th { font-size: 0.75rem; text-align: center; } /* Klasa zmniejszająca przyciski akcji */ .btn-action { font-size: 0.65rem; padding: 0.25rem 0.4rem; line-height: 1; } form.inline-button button.btn { background-color: #dc3545; /* btn-danger */ border-color: #dc3545; font-size: 0.65rem; padding: 0.25rem 0.4rem; line-height: 1; /* ewentualnie dodatkowe właściwości, aby upodobnić go do linków */ } </style> {% endblock %} {% block content %} <div class="card"> <div class="card-header"> <h2>Lista serwerów</h2> </div> <div class="card-body table-responsive"> <table class="table table-striped align-middle"> <thead> <tr> <th>ID</th> <th>Serwer</th> <th>Użytkownik</th> <th>Port</th> <th>Typ</th> <th>Uwierzytelnianie</th> <th>Wybrany /etc/hosts</th> <th>Auto Deploy</th> <th>Auto Backup</th> <th>Wyłącz <a href="{{ url_for('list_regex_hosts') }}">CIDR / regex</a></th> <th>Wyłącz <a href="{{ url_for('local_defaults') }}">local-defaults</a></th> <th>Akcje</th> </tr> </thead> <tbody> {% for h in hosts %} <tr> <td>{{ h.id }}</td> <td data-bs-toggle="tooltip" data-bs-placement="top" title="{{ h.raw_ip }}"> {% if h.use_daemon and h.type == 'linux' and h.daemon_url %} {{ h.resolved_daemon }} {% else %} {{ h.resolved_hostname }} {% endif %} </td> <td> {% if h.use_daemon and h.type == 'linux' %} <em>—</em> {% else %} {{ h.username }} {% endif %} </td> <td> {% if h.use_daemon and h.type == 'linux' %} <em>—</em> {% else %} {{ h.port }} {% endif %} </td> <td class="text-center"> {% if h.type == 'linux' %} <img src="{{ url_for('static', filename='img/linux.svg') }}" alt="Linux" data-bs-toggle="tooltip" data-bs-placement="top" title="{% if h.use_daemon %}Linux - Używa Linux Demon{% else %}Linux{% endif %}" class="linux-logo" style="width: 40px; height: 40px;"> {% else %} <img src="{{ url_for('static', filename='img/mikrotik.svg') }}" alt="Mikrotik" data-bs-toggle="tooltip" data-bs-placement="top" title="Mikrotik" class="mikrotik-logo" style="width: 40px; height: 40px;"> {% endif %} </td> <td> {% if h.use_daemon and h.type == 'linux' %} <span class="badge bg-secondary" style="font-size: 0.75rem;">- linux daemon -</span> {% else %} {% if h.auth_method == 'password' %} <span class="badge bg-primary" style="font-size: 0.75rem;">Hasło</span> {% elif h.auth_method == 'ssh_key' %} <span class="badge bg-success" style="font-size: 0.75rem;">Klucz SSH</span> {% elif h.auth_method == 'global_key' %} <span class="badge bg-info" style="font-size: 0.75rem;">Globalny klucz</span> {% else %} <span class="badge bg-light text-dark" style="font-size: 0.75rem;">{{ h.auth_method }}</span> {% endif %} {% endif %} </td> <td> {% if h.preferred_hostfile %} {{ h.preferred_hostfile.title }} {% else %} (Default) {% endif %} </td> <td> <form method="POST" action="{{ url_for('update_host_automation', id=h.id) }}" class="d-flex justify-content-center"> <input type="hidden" name="setting" value="auto_deploy"> <div class="form-check form-switch"> <input class="form-check-input" type="checkbox" id="autoDeployCheckbox{{ h.id }}" name="enabled" value="1" onchange="this.form.submit()" {% if h.auto_deploy_enabled %}checked{% endif %}> <label class="form-check-label" for="autoDeployCheckbox{{ h.id }}"></label> </div> </form> </td> <td> <form method="POST" action="{{ url_for('update_host_automation', id=h.id) }}" class="d-flex justify-content-center"> <input type="hidden" name="setting" value="auto_backup"> <div class="form-check form-switch"> <input class="form-check-input" type="checkbox" id="autoBackupCheckbox{{ h.id }}" name="enabled" value="1" onchange="this.form.submit()" {% if h.auto_backup_enabled %}checked{% endif %}> <label class="form-check-label" for="autoBackupCheckbox{{ h.id }}"></label> </div> </form> </td> <td> <form method="POST" action="{{ url_for('update_host_automation', id=h.id) }}" class="d-flex justify-content-center"> <input type="hidden" name="setting" value="disable_regex"> <div class="form-check form-switch"> <input class="form-check-input" type="checkbox" id="disableRegexCheckbox{{ h.id }}" name="enabled" value="1" onchange="this.form.submit()" {% if h.disable_regex_deploy %}checked{% endif %}> <label class="form-check-label" for="disableRegexCheckbox{{ h.id }}"></label> </div> </form> </td> <td> <form method="POST" action="{{ url_for('update_host_automation', id=h.id) }}" class="d-flex justify-content-center"> <input type="hidden" name="setting" value="disable_local_default"> <div class="form-check form-switch"> <input class="form-check-input" type="checkbox" id="disableLocalDefaultCheckbox{{ h.id }}" name="enabled" value="1" onchange="this.form.submit()" {% if h.disable_local_default %}checked{% endif %}> <label class="form-check-label" for="disableLocalDefaultCheckbox{{ h.id }}"></label> </div> </form> </td> <td> <div class="d-flex flex-wrap gap-1"> <a href="{{ url_for('edit_server', id=h.id) }}" class="btn btn-primary btn-sm btn-action">Edytuj</a> {% if h.use_daemon and h.type == 'linux' %} <button class="btn btn-info btn-sm btn-action test-daemon-btn" data-host-id="{{ h.id }}"> Test </button> {% else %} <a href="{{ url_for('test_server_connection', id=h.id) }}" class="btn btn-info btn-sm btn-action">Test</a> {% endif %} <a href="{{ url_for('server_backup', host_id=h.id) }}" class="btn btn-success btn-sm btn-action">Backup</a> <form method="GET" action="{{ url_for('delete_server', id=h.id) }}" class="inline-button d-flex justify-content-center"> <button type="submit" class="btn btn-danger btn-sm btn-action" onclick="return confirm('Czy na pewno chcesz usunąć serwer?')">Usuń</button> </form> </div> </td> </tr> {% endfor %} </tbody> </table> </div> </div> <!-- Modal z informacjami --> <div class="modal fade" id="serverInfoModal" tabindex="-1" aria-hidden="true"> <div class="modal-dialog modal-dialog-centered"> <div class="modal-content"> <div class="modal-header"> <h5 class="modal-title">Informacje o serwerze</h5> <button type="button" class="btn-close" data-bs-dismiss="modal"></button> </div> <div class="modal-body"> <p><strong>Host:</strong> <span id="modal-hostname"></span> (<span id="modal-ip"></span>)</p> <label><strong>CPU:</strong></label> <div class="progress mb-3"> <div id="modal-cpu" class="progress-bar" role="progressbar"></div> </div> <label><strong>Pamięć:</strong></label> <div class="progress mb-3"> <div id="modal-mem" class="progress-bar bg-warning" role="progressbar"></div> </div> <label><strong>Dysk:</strong></label> <div class="progress mb-3"> <div id="modal-disk" class="progress-bar bg-success" role="progressbar"></div> </div> <p><strong>Czas działania:</strong> <span id="modal-uptime"></span></p> </div> <div class="modal-footer"> <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Zamknij</button> </div> </div> </div> </div> <div class="mt-3 text-center"> <a href="{{ url_for('add_server') }}" class="btn btn-secondary">Dodaj nowy serwer</a> <a href="{{ url_for('import_servers') }}" class="btn btn-secondary">Importuj z CSV</a> <a href="{{ url_for('export_servers_to_csv') }}" class="btn btn-secondary">Eksportuj do CSV</a> </div> {% endblock %} {% block extra_js %} {{ super() }} <script> function secondsToDhms(seconds) { seconds = Number(seconds); const d = Math.floor(seconds / (3600 * 24)); const h = Math.floor(seconds % (3600 * 24) / 3600); const m = Math.floor(seconds % 3600 / 60); const s = Math.floor(seconds % 60); return `${d} dni, ${h} godz, ${m} min, ${s} sek`; } document.querySelectorAll('.test-daemon-btn').forEach(btn => { btn.addEventListener('click', function() { const hostId = this.dataset.hostId; fetch(`/server-info/${hostId}`) .then(res => res.json()) .then(data => { if (data.error) { alert(`Błąd: ${data.error}`); return; } document.querySelector('#modal-hostname').textContent = data.hostname; document.querySelector('#modal-ip').textContent = data.ip; const cpu = document.querySelector('#modal-cpu'); cpu.style.width = `${data.cpu}%`; cpu.textContent = `${data.cpu}%`; const mem = document.querySelector('#modal-mem'); mem.style.width = `${data.mem}%`; mem.textContent = `${data.mem}%`; const disk = document.querySelector('#modal-disk'); disk.style.width = `${data.disk}%`; disk.textContent = `${data.disk}%`; document.querySelector('#modal-uptime').textContent = secondsToDhms(data.uptime_seconds); new bootstrap.Modal(document.getElementById('serverInfoModal')).show(); }) .catch(() => alert('Błąd podczas pobierania danych.')); }); }); </script> {% endblock %}