servercontrol/templates/server/index.html.twig

131 lines
5.1 KiB
Twig

{% extends 'base.html.twig' %}
{% block title %}Servers - ServerControl{% endblock %}
{% block body %}
<div class="d-flex justify-content-between align-items-center mb-4">
<h1 class="h3">Servers</h1>
{% if is_granted('ROLE_ADMIN') %}
<a href="{{ path('app_server_new') }}" class="btn btn-primary">
<i class="bi bi-plus-lg me-1"></i>Add Server
</a>
{% endif %}
</div>
<div class="card mb-4">
<div class="card-body">
<form method="get" class="row g-3">
<div class="col-md-6">
<input type="text" class="form-control" name="search" placeholder="Search by name or IP..."
value="{{ search ?? '' }}">
</div>
<div class="col-md-4">
<select class="form-select" name="status">
<option value="">All statuses</option>
<option value="online" {% if status == 'online' %}selected{% endif %}>Online</option>
<option value="offline" {% if status == 'offline' %}selected{% endif %}>Offline</option>
<option value="unknown" {% if status == 'unknown' %}selected{% endif %}>Unknown</option>
</select>
</div>
<div class="col-md-2">
<button class="btn btn-outline-secondary w-100">Filter</button>
</div>
</form>
</div>
</div>
{% if servers|length == 0 %}
<div class="alert alert-info">Aucun serveur trouver.</div>
{% else %}
<div class="table-responsive card">
<table class="table table-hover mb-0">
<thead class="table-dark">
<tr>
<th>Name</th>
<th>IP Address</th>
<th>SSH Port</th>
<th>Status</th>
<th>Owner</th>
<th>Added</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
{% for server in servers %}
<tr>
<td><strong>{{ server.name }}</strong></td>
<td><code>{{ server.ipAddress }}</code></td>
<td>{{ server.sshPort }}</td>
<td>
<span class="status-{{ server.lastStatus }}" id="status-{{ server.id }}">
<i class="bi bi-circle-fill me-1" style="font-size:.5rem;"></i>
{{ server.lastStatus|capitalize }}
</span>
</td>
<td>{{ server.owner.pseudo }}</td>
<td>{{ server.createdAt|date('d/m/Y') }}</td>
<td>
<a href="{{ path('app_server_show', {id: server.id}) }}" class="btn btn-sm btn-outline-primary">
<i class="bi bi-eye"></i>
</a>
{% if is_granted('ROLE_ADMIN') %}
<a href="{{ path('app_server_edit', {id: server.id}) }}" class="btn btn-sm btn-outline-secondary">
<i class="bi bi-pencil"></i>
</a>
<button class="btn btn-sm btn-outline-danger" data-bs-toggle="modal"
data-bs-target="#deleteModal{{ server.id }}">
<i class="bi bi-trash"></i>
</button>
{% endif %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<div class="mt-3 d-flex justify-content-center">
{{ knp_pagination_render(servers) }}
</div>
{% for server in servers %}
<div class="modal fade" id="deleteModal{{ server.id }}" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Delete Server</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
Êtes-vous sûre de vouloir suprimmer <strong>{{ server.name }}</strong> ?
Tout les services et journaux associé seront supprimés.
</div>
<div class="modal-footer">
<button class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
<form method="post" action="{{ path('app_server_delete', {id: server.id}) }}">
<input type="hidden" name="_token" value="{{ csrf_token('delete_server_' ~ server.id) }}">
<button class="btn btn-danger">Delete</button>
</form>
</div>
</div>
</div>
</div>
{% endfor %}
{% endif %}
{% endblock %}
{% block javascripts %}
<script>
function refreshStatuses() {
document.querySelectorAll('[id^="status-"]').forEach(el => {
const id = el.id.replace('status-', '');
fetch(`/server/${id}/status`)
.then(r => r.json())
.then(data => {
el.className = `status-${data.status}`;
el.innerHTML = `<i class="bi bi-circle-fill me-1" style="font-size:.5rem;"></i>${data.status.charAt(0).toUpperCase() + data.status.slice(1)}`;
}).catch(() => {});
});
}
setInterval(refreshStatuses, 30000);
</script>
{% endblock %}