Gerätelimit drin
Dieser Commit ist enthalten in:
@@ -168,18 +168,24 @@
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if license[9] > 0 %}
|
||||
<div class="d-inline-block" data-bs-toggle="tooltip" title="Telefonnummern">
|
||||
<div class="d-inline-block me-2" data-bs-toggle="tooltip" title="Telefonnummern">
|
||||
📱 {{ license[9] }}
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="d-inline-block" data-bs-toggle="tooltip" title="Geräte">
|
||||
💻 {{ license[11] }}/{{ license[10] }}
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<div class="btn-group btn-group-sm">
|
||||
<button class="btn btn-outline-primary" onclick="toggleLicenseStatus({{ license[0] }}, {{ license[5] }})">
|
||||
<button class="btn btn-outline-primary" onclick="toggleLicenseStatus({{ license[0] }}, {{ license[5] }})" title="Aktivieren/Deaktivieren">
|
||||
<i class="bi bi-power"></i>
|
||||
</button>
|
||||
<a href="/license/edit/{{ license[0] }}{% if request.args.get('show_test') %}?ref=customers-licenses&show_test=true{% endif %}" class="btn btn-outline-secondary">
|
||||
<button class="btn btn-outline-info" onclick="showDeviceManagement({{ license[0] }})" title="Geräte verwalten">
|
||||
<i class="bi bi-laptop"></i>
|
||||
</button>
|
||||
<a href="/license/edit/{{ license[0] }}{% if request.args.get('show_test') %}?ref=customers-licenses&show_test=true{% endif %}" class="btn btn-outline-secondary" title="Bearbeiten">
|
||||
<i class="bi bi-pencil"></i>
|
||||
</a>
|
||||
</div>
|
||||
@@ -253,6 +259,28 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Modal für Geräte-Verwaltung -->
|
||||
<div class="modal fade" id="deviceManagementModal" tabindex="-1">
|
||||
<div class="modal-dialog modal-lg">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title">Geräte verwalten</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
|
||||
</div>
|
||||
<div class="modal-body" id="deviceManagementContent">
|
||||
<div class="text-center">
|
||||
<div class="spinner-border text-primary" role="status">
|
||||
<span class="visually-hidden">Lädt...</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Schließen</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.customer-item {
|
||||
transition: all 0.2s ease;
|
||||
@@ -433,6 +461,11 @@ function updateLicenseView(customerId, licenses) {
|
||||
}
|
||||
}
|
||||
|
||||
// Geräte-Anzeige hinzufügen
|
||||
resourcesHtml += `<div class="resource-group">
|
||||
<span class="resource-icon" data-bs-toggle="tooltip" title="Geräte">💻 ${license.active_devices}/${license.device_limit}</span>
|
||||
</div>`;
|
||||
|
||||
html += `
|
||||
<tr data-license-id="${license.id}">
|
||||
<td>
|
||||
@@ -453,7 +486,10 @@ function updateLicenseView(customerId, licenses) {
|
||||
<button class="btn btn-outline-primary" onclick="toggleLicenseStatus(${license.id}, ${license.is_active})" title="Status ändern">
|
||||
<i class="bi bi-power"></i>
|
||||
</button>
|
||||
<button class="btn btn-outline-info" onclick="showResourceManagement(${license.id})" title="Ressourcen verwalten">
|
||||
<button class="btn btn-outline-info" onclick="showDeviceManagement(${license.id})" title="Geräte verwalten">
|
||||
<i class="bi bi-laptop"></i>
|
||||
</button>
|
||||
<button class="btn btn-outline-secondary" onclick="showResourceManagement(${license.id})" title="Ressourcen verwalten">
|
||||
<i class="bi bi-gear"></i>
|
||||
</button>
|
||||
<a href="/license/edit/${license.id}${window.location.search ? '?ref=customers-licenses&' + window.location.search.substring(1) : ''}" class="btn btn-outline-secondary" title="Bearbeiten">
|
||||
@@ -774,5 +810,124 @@ function quarantineResource(resourceId, resourceValue) {
|
||||
function saveResourceChanges() {
|
||||
alert('Diese Funktion wird noch implementiert');
|
||||
}
|
||||
|
||||
// Geräte-Verwaltung anzeigen
|
||||
function showDeviceManagement(licenseId) {
|
||||
const modal = new bootstrap.Modal(document.getElementById('deviceManagementModal'));
|
||||
modal.show();
|
||||
|
||||
// Lade Geräte-Daten
|
||||
fetch(`/api/license/${licenseId}/devices`)
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (data.success) {
|
||||
let content = `
|
||||
<div class="mb-3">
|
||||
<div class="alert alert-info">
|
||||
<strong>Gerätelimit:</strong> ${data.active_count} von ${data.device_limit} Geräten aktiv
|
||||
</div>
|
||||
</div>`;
|
||||
|
||||
if (data.devices.length === 0) {
|
||||
content += `
|
||||
<div class="text-center py-4">
|
||||
<i class="bi bi-laptop text-muted" style="font-size: 3rem;"></i>
|
||||
<p class="text-muted mt-3">Noch keine Geräte registriert</p>
|
||||
</div>`;
|
||||
} else {
|
||||
content += `
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Gerätename</th>
|
||||
<th>Hardware-ID</th>
|
||||
<th>Betriebssystem</th>
|
||||
<th>Erste Registrierung</th>
|
||||
<th>Letzte Aktivität</th>
|
||||
<th>IP-Adresse</th>
|
||||
<th>Status</th>
|
||||
<th>Aktionen</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>`;
|
||||
|
||||
data.devices.forEach(device => {
|
||||
const statusBadge = device.is_active
|
||||
? '<span class="badge bg-success">Aktiv</span>'
|
||||
: '<span class="badge bg-secondary">Deaktiviert</span>';
|
||||
|
||||
const actionButton = device.is_active
|
||||
? `<button class="btn btn-sm btn-danger" onclick="deactivateDevice(${licenseId}, ${device.id}, '${device.device_name}')">
|
||||
<i class="bi bi-x-circle"></i> Deaktivieren
|
||||
</button>`
|
||||
: '<span class="text-muted">-</span>';
|
||||
|
||||
content += `
|
||||
<tr>
|
||||
<td>${device.device_name}</td>
|
||||
<td><small class="text-muted">${device.hardware_id.substring(0, 12)}...</small></td>
|
||||
<td>${device.operating_system}</td>
|
||||
<td>${device.first_seen}</td>
|
||||
<td>${device.last_seen}</td>
|
||||
<td>${device.ip_address}</td>
|
||||
<td>${statusBadge}</td>
|
||||
<td>${actionButton}</td>
|
||||
</tr>`;
|
||||
});
|
||||
|
||||
content += `
|
||||
</tbody>
|
||||
</table>
|
||||
</div>`;
|
||||
}
|
||||
|
||||
document.getElementById('deviceManagementContent').innerHTML = content;
|
||||
} else {
|
||||
document.getElementById('deviceManagementContent').innerHTML = `
|
||||
<div class="alert alert-danger">
|
||||
<i class="bi bi-exclamation-triangle"></i> ${data.message || 'Fehler beim Laden der Geräte'}
|
||||
</div>`;
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Error loading devices:', error);
|
||||
document.getElementById('deviceManagementContent').innerHTML = `
|
||||
<div class="alert alert-danger">
|
||||
<i class="bi bi-exclamation-triangle"></i> Fehler beim Laden der Geräte
|
||||
</div>`;
|
||||
});
|
||||
}
|
||||
|
||||
// Gerät deaktivieren
|
||||
function deactivateDevice(licenseId, deviceId, deviceName) {
|
||||
if (!confirm(`Möchten Sie das Gerät "${deviceName}" wirklich deaktivieren?`)) {
|
||||
return;
|
||||
}
|
||||
|
||||
fetch(`/api/license/${licenseId}/deactivate-device/${deviceId}`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
}
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (data.success) {
|
||||
// Aktualisiere die Geräte-Ansicht
|
||||
showDeviceManagement(licenseId);
|
||||
// Aktualisiere die Lizenz-Anzeige wenn möglich
|
||||
if (typeof loadCustomerLicenses === 'function' && currentCustomerId) {
|
||||
loadCustomerLicenses(currentCustomerId);
|
||||
}
|
||||
} else {
|
||||
alert(data.message || 'Fehler beim Deaktivieren des Geräts');
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Error deactivating device:', error);
|
||||
alert('Fehler beim Deaktivieren des Geräts');
|
||||
});
|
||||
}
|
||||
</script>
|
||||
{% endblock %}
|
||||
In neuem Issue referenzieren
Einen Benutzer sperren