Add IP field, ping service, status endpoint and UI; update README
This commit is contained in:
29
README.md
29
README.md
@ -6,6 +6,8 @@ Ein moderner Wake-on-LAN Manager, entwickelt mit Go und einer schönen Web-Oberf
|
||||
|
||||
- **PC-Verwaltung**: Hinzufügen, Anzeigen, Bearbeiten und Löschen von PC-Einträgen
|
||||
- **Wake-on-LAN**: Ein-Klick-Aufwecken von Computern über MAC-Adressen
|
||||
- **IP-Adressverwaltung**: Pro Gerät wird eine IP-Adresse gespeichert
|
||||
- **Online-Status (Ping)**: Geräte können per Ping geprüft und im UI als Online/Offline angezeigt werden
|
||||
- **Moderne Web-Oberfläche**: Responsive Design mit Bootstrap und FontAwesome
|
||||
- **SQLite-Datenbank**: Einfache lokale Datenspeicherung
|
||||
- **Cross-Platform**: Läuft auf Windows und Linux
|
||||
@ -91,17 +93,23 @@ Falls weder Kommandozeilenparameter noch Umgebungsvariable gesetzt sind, wird Po
|
||||
### PC hinzufügen
|
||||
1. Geben Sie den Namen des PCs ein
|
||||
2. Geben Sie die MAC-Adresse im Format `XX:XX:XX:XX:XX:XX` ein
|
||||
3. Klicken Sie auf "PC hinzufügen"
|
||||
3. Geben Sie die IP-Adresse des PCs ein (z. B. `192.168.0.10`)
|
||||
4. Klicken Sie auf "PC hinzufügen"
|
||||
|
||||
### PC bearbeiten
|
||||
1. Klicken Sie auf den "Bearbeiten"-Button neben dem gewünschten PC
|
||||
2. Ändern Sie Name und/oder MAC-Adresse
|
||||
2. Ändern Sie Name, MAC-Adresse und/oder IP-Adresse
|
||||
3. Klicken Sie auf "Speichern"
|
||||
|
||||
### PC aufwecken
|
||||
- Klicken Sie auf den "Aufwecken"-Button neben dem gewünschten PC
|
||||
- Das System sendet automatisch ein Wake-on-LAN Paket
|
||||
|
||||
### Online-Status prüfen (Ping)
|
||||
- Klicken Sie auf den Button "Status aktualisieren" in der Tabelle
|
||||
- Die Online/Offline-Badges werden pro Gerät aktualisiert
|
||||
- Optional kann ein automatisches Intervall ergänzt werden (siehe Entwicklung)
|
||||
|
||||
### PC löschen
|
||||
- Klicken Sie auf den "Löschen"-Button neben dem gewünschten PC
|
||||
- Bestätigen Sie die Löschung
|
||||
@ -261,11 +269,22 @@ medi-wol/
|
||||
- `PUT /api/pcs/:id` - PC aktualisieren
|
||||
- `DELETE /api/pcs/:id` - PC löschen
|
||||
- `POST /api/pcs/:id/wake` - PC aufwecken
|
||||
- `GET /api/pcs/status` - Online-Status aller PCs abrufen (Ping)
|
||||
|
||||
## Datenbank
|
||||
|
||||
Die Anwendung verwendet SQLite als lokale Datenbank. Die Datenbankdatei `medi-wol.db` wird automatisch im Projektverzeichnis erstellt.
|
||||
|
||||
### Tabellenstruktur `pcs`
|
||||
| Spalte | Typ | Hinweis |
|
||||
|-------------|----------|------------------------|
|
||||
| id | INTEGER | Primärschlüssel |
|
||||
| name | TEXT | Pflichtfeld |
|
||||
| mac | TEXT | Pflichtfeld, eindeutig |
|
||||
| ip | TEXT | Pflichtfeld |
|
||||
| created_at | DATETIME | Automatisch |
|
||||
| updated_at | DATETIME | Automatisch |
|
||||
|
||||
## Wake-on-LAN
|
||||
|
||||
Das System sendet Magic Packets an die gespeicherten MAC-Adressen. Stellen Sie sicher, dass:
|
||||
@ -285,6 +304,12 @@ go run cmd/server/main.go
|
||||
go run cmd/server/main.go -port 9090
|
||||
```
|
||||
|
||||
#### Hinweise zum Ping
|
||||
- Der Ping wird aktuell über den Button "Status aktualisieren" ausgelöst (`GET /api/pcs/status`).
|
||||
- Unter Windows wird der Systembefehl `ping -n 1 -w 1000 <IP>` verwendet, unter Linux/macOS `ping -c 1 -W 1 <IP>`.
|
||||
- Falls ICMP blockiert ist, wird als Fallback eine kurze TCP-Portprobe versucht (80, sonst 22).
|
||||
- Optional kann ein automatisches Intervall im Frontend ergänzt werden (z. B. alle 30s).
|
||||
|
||||
### Build für Produktion
|
||||
```bash
|
||||
# Windows
|
||||
|
||||
@ -65,12 +65,13 @@ func main() {
|
||||
r.PUT("/api/pcs/:id", pcHandler.UpdatePC)
|
||||
r.DELETE("/api/pcs/:id", pcHandler.DeletePC)
|
||||
r.POST("/api/pcs/:id/wake", pcHandler.WakePC)
|
||||
r.GET("/api/pcs/status", pcHandler.GetPCStatus)
|
||||
|
||||
// Server starten
|
||||
serverAddr := fmt.Sprintf(":%d", port)
|
||||
log.Printf("Server startet auf Port %d...", port)
|
||||
log.Printf("Web-Oberfläche verfügbar unter: http://localhost%s", serverAddr)
|
||||
|
||||
|
||||
if err := r.Run(serverAddr); err != nil {
|
||||
log.Fatal("Fehler beim Starten des Servers:", err)
|
||||
}
|
||||
|
||||
@ -27,6 +27,7 @@ func InitDB() (*DB, error) {
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
name TEXT NOT NULL,
|
||||
mac TEXT NOT NULL UNIQUE,
|
||||
ip TEXT NOT NULL,
|
||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
||||
);`
|
||||
@ -36,13 +37,19 @@ func InitDB() (*DB, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Füge IP-Spalte hinzu, falls sie nicht existiert
|
||||
_, err = db.Exec("ALTER TABLE pcs ADD COLUMN ip TEXT DEFAULT ''")
|
||||
if err != nil {
|
||||
// Spalte existiert bereits, ignorieren
|
||||
}
|
||||
|
||||
log.Println("Datenbank erfolgreich initialisiert")
|
||||
return &DB{db}, nil
|
||||
}
|
||||
|
||||
// GetAllPCs holt alle PCs aus der Datenbank
|
||||
func (db *DB) GetAllPCs() ([]models.PC, error) {
|
||||
rows, err := db.Query("SELECT id, name, mac, created_at, updated_at FROM pcs ORDER BY name")
|
||||
rows, err := db.Query("SELECT id, name, mac, ip, created_at, updated_at FROM pcs ORDER BY name")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -51,7 +58,7 @@ func (db *DB) GetAllPCs() ([]models.PC, error) {
|
||||
var pcs []models.PC
|
||||
for rows.Next() {
|
||||
var pc models.PC
|
||||
err := rows.Scan(&pc.ID, &pc.Name, &pc.MAC, &pc.CreatedAt, &pc.UpdatedAt)
|
||||
err := rows.Scan(&pc.ID, &pc.Name, &pc.MAC, &pc.IP, &pc.CreatedAt, &pc.UpdatedAt)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -62,11 +69,11 @@ func (db *DB) GetAllPCs() ([]models.PC, error) {
|
||||
}
|
||||
|
||||
// CreatePC erstellt einen neuen PC-Eintrag
|
||||
func (db *DB) CreatePC(name, mac string) (*models.PC, error) {
|
||||
func (db *DB) CreatePC(name, mac, ip string) (*models.PC, error) {
|
||||
now := time.Now()
|
||||
result, err := db.Exec(
|
||||
"INSERT INTO pcs (name, mac, created_at, updated_at) VALUES (?, ?, ?, ?)",
|
||||
name, mac, now, now,
|
||||
"INSERT INTO pcs (name, mac, ip, created_at, updated_at) VALUES (?, ?, ?, ?, ?)",
|
||||
name, mac, ip, now, now,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -81,17 +88,18 @@ func (db *DB) CreatePC(name, mac string) (*models.PC, error) {
|
||||
ID: int(id),
|
||||
Name: name,
|
||||
MAC: mac,
|
||||
IP: ip,
|
||||
CreatedAt: now,
|
||||
UpdatedAt: now,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// UpdatePC aktualisiert einen bestehenden PC-Eintrag
|
||||
func (db *DB) UpdatePC(id int, name, mac string) (*models.PC, error) {
|
||||
func (db *DB) UpdatePC(id int, name, mac, ip string) (*models.PC, error) {
|
||||
now := time.Now()
|
||||
_, err := db.Exec(
|
||||
"UPDATE pcs SET name = ?, mac = ?, updated_at = ? WHERE id = ?",
|
||||
name, mac, now, id,
|
||||
"UPDATE pcs SET name = ?, mac = ?, ip = ?, updated_at = ? WHERE id = ?",
|
||||
name, mac, ip, now, id,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -101,6 +109,7 @@ func (db *DB) UpdatePC(id int, name, mac string) (*models.PC, error) {
|
||||
ID: id,
|
||||
Name: name,
|
||||
MAC: mac,
|
||||
IP: ip,
|
||||
UpdatedAt: now,
|
||||
}, nil
|
||||
}
|
||||
@ -115,9 +124,9 @@ func (db *DB) DeletePC(id int) error {
|
||||
func (db *DB) GetPCByID(id int) (*models.PC, error) {
|
||||
var pc models.PC
|
||||
err := db.QueryRow(
|
||||
"SELECT id, name, mac, created_at, updated_at FROM pcs WHERE id = ?",
|
||||
"SELECT id, name, mac, ip, created_at, updated_at FROM pcs WHERE id = ?",
|
||||
id,
|
||||
).Scan(&pc.ID, &pc.Name, &pc.MAC, &pc.CreatedAt, &pc.UpdatedAt)
|
||||
).Scan(&pc.ID, &pc.Name, &pc.MAC, &pc.IP, &pc.CreatedAt, &pc.UpdatedAt)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@ -3,6 +3,7 @@ package handlers
|
||||
import (
|
||||
"medi-wol/internal/database"
|
||||
"medi-wol/internal/models"
|
||||
"medi-wol/internal/ping"
|
||||
"medi-wol/internal/wol"
|
||||
"net/http"
|
||||
"strconv"
|
||||
@ -12,15 +13,17 @@ import (
|
||||
|
||||
// PCHandler verwaltet die HTTP-Anfragen für PC-Operationen
|
||||
type PCHandler struct {
|
||||
db *database.DB
|
||||
wolService *wol.Service
|
||||
db *database.DB
|
||||
wolService *wol.Service
|
||||
pingService *ping.PingService
|
||||
}
|
||||
|
||||
// NewPCHandler erstellt einen neuen PC-Handler
|
||||
func NewPCHandler(db *database.DB, wolService *wol.Service) *PCHandler {
|
||||
return &PCHandler{
|
||||
db: db,
|
||||
wolService: wolService,
|
||||
db: db,
|
||||
wolService: wolService,
|
||||
pingService: ping.NewPingService(),
|
||||
}
|
||||
}
|
||||
|
||||
@ -69,7 +72,7 @@ func (h *PCHandler) CreatePC(c *gin.Context) {
|
||||
}
|
||||
|
||||
// PC erstellen
|
||||
pc, err := h.db.CreatePC(req.Name, req.MAC)
|
||||
pc, err := h.db.CreatePC(req.Name, req.MAC, req.IP)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, models.PCResponse{
|
||||
Success: false,
|
||||
@ -116,7 +119,7 @@ func (h *PCHandler) UpdatePC(c *gin.Context) {
|
||||
}
|
||||
|
||||
// PC aktualisieren
|
||||
pc, err := h.db.UpdatePC(id, req.Name, req.MAC)
|
||||
pc, err := h.db.UpdatePC(id, req.Name, req.MAC, req.IP)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, models.PCResponse{
|
||||
Success: false,
|
||||
@ -196,3 +199,33 @@ func (h *PCHandler) WakePC(c *gin.Context) {
|
||||
Message: "Wake-on-LAN Paket erfolgreich gesendet an " + pc.Name,
|
||||
})
|
||||
}
|
||||
|
||||
// GetPCStatus gibt den Online-Status aller PCs zurück
|
||||
func (h *PCHandler) GetPCStatus(c *gin.Context) {
|
||||
pcs, err := h.db.GetAllPCs()
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, models.PCResponse{
|
||||
Success: false,
|
||||
Message: "Fehler beim Laden der PCs: " + err.Error(),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// Online-Status für alle PCs überprüfen
|
||||
var statusList []models.PCStatus
|
||||
for _, pc := range pcs {
|
||||
online := h.pingService.IsOnline(pc.IP)
|
||||
statusList = append(statusList, models.PCStatus{
|
||||
ID: pc.ID,
|
||||
Name: pc.Name,
|
||||
MAC: pc.MAC,
|
||||
IP: pc.IP,
|
||||
Online: online,
|
||||
})
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"success": true,
|
||||
"status": statusList,
|
||||
})
|
||||
}
|
||||
|
||||
@ -9,7 +9,8 @@ type PC struct {
|
||||
ID int `json:"id" db:"id"`
|
||||
Name string `json:"name" db:"name"`
|
||||
MAC string `json:"mac" db:"mac"`
|
||||
CreatedAt time.Time `json:"created_at" db:"created_at"`
|
||||
IP string `json:"ip" db:"ip"`
|
||||
CreatedAt time.Time `json:"created_at" db:"updated_at"`
|
||||
UpdatedAt time.Time `json:"updated_at" db:"updated_at"`
|
||||
}
|
||||
|
||||
@ -17,12 +18,14 @@ type PC struct {
|
||||
type CreatePCRequest struct {
|
||||
Name string `json:"name" binding:"required"`
|
||||
MAC string `json:"mac" binding:"required"`
|
||||
IP string `json:"ip" binding:"required"`
|
||||
}
|
||||
|
||||
// UpdatePCRequest repräsentiert die Anfrage zum Aktualisieren eines PCs
|
||||
type UpdatePCRequest struct {
|
||||
Name string `json:"name" binding:"required"`
|
||||
MAC string `json:"mac" binding:"required"`
|
||||
IP string `json:"ip" binding:"required"`
|
||||
}
|
||||
|
||||
// PCResponse repräsentiert die Antwort für PC-Operationen
|
||||
@ -32,3 +35,12 @@ type PCResponse struct {
|
||||
PC *PC `json:"pc,omitempty"`
|
||||
PCs []PC `json:"pcs,omitempty"`
|
||||
}
|
||||
|
||||
// PCStatus repräsentiert den Online-Status eines PCs
|
||||
type PCStatus struct {
|
||||
ID int `json:"id"`
|
||||
Name string `json:"name"`
|
||||
MAC string `json:"mac"`
|
||||
IP string `json:"ip"`
|
||||
Online bool `json:"online"`
|
||||
}
|
||||
|
||||
81
internal/ping/ping.go
Normal file
81
internal/ping/ping.go
Normal file
@ -0,0 +1,81 @@
|
||||
package ping
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"os/exec"
|
||||
"runtime"
|
||||
"time"
|
||||
)
|
||||
|
||||
// PingService bietet Funktionen zum Überprüfen des Online-Status von PCs
|
||||
type PingService struct{}
|
||||
|
||||
// NewPingService erstellt eine neue Instanz des Ping-Services
|
||||
func NewPingService() *PingService {
|
||||
return &PingService{}
|
||||
}
|
||||
|
||||
// IsOnline überprüft, ob ein PC online ist
|
||||
func (ps *PingService) IsOnline(ip string) bool {
|
||||
if ip == "" {
|
||||
return false
|
||||
}
|
||||
|
||||
// Verwende system-spezifischen Ping-Befehl
|
||||
switch runtime.GOOS {
|
||||
case "windows":
|
||||
return ps.pingWindows(ip)
|
||||
case "linux", "darwin":
|
||||
return ps.pingUnix(ip)
|
||||
default:
|
||||
return ps.pingGeneric(ip)
|
||||
}
|
||||
}
|
||||
|
||||
// pingWindows führt einen Ping unter Windows aus
|
||||
func (ps *PingService) pingWindows(ip string) bool {
|
||||
cmd := exec.Command("ping", "-n", "1", "-w", "1000", ip)
|
||||
err := cmd.Run()
|
||||
return err == nil
|
||||
}
|
||||
|
||||
// pingUnix führt einen Ping unter Unix-Systemen aus
|
||||
func (ps *PingService) pingUnix(ip string) bool {
|
||||
cmd := exec.Command("ping", "-c", "1", "-W", "1", ip)
|
||||
err := cmd.Run()
|
||||
return err == nil
|
||||
}
|
||||
|
||||
// pingGeneric ist eine plattformunabhängige Alternative
|
||||
func (ps *PingService) pingGeneric(ip string) bool {
|
||||
// Versuche TCP-Verbindung auf Port 80 (HTTP)
|
||||
conn, err := net.DialTimeout("tcp", fmt.Sprintf("%s:80", ip), 2*time.Second)
|
||||
if err != nil {
|
||||
// Versuche TCP-Verbindung auf Port 22 (SSH)
|
||||
conn, err = net.DialTimeout("tcp", fmt.Sprintf("%s:22", ip), 2*time.Second)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
}
|
||||
defer conn.Close()
|
||||
return true
|
||||
}
|
||||
|
||||
// CheckAllPCs überprüft den Online-Status aller PCs
|
||||
func (ps *PingService) CheckAllPCs(pcs []interface{}) map[int]bool {
|
||||
results := make(map[int]bool)
|
||||
|
||||
for _, pc := range pcs {
|
||||
// Type assertion für PC-Interface
|
||||
if pcMap, ok := pc.(map[string]interface{}); ok {
|
||||
if id, ok := pcMap["id"].(float64); ok {
|
||||
if ip, ok := pcMap["ip"].(string); ok {
|
||||
results[int(id)] = ps.IsOnline(ip)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return results
|
||||
}
|
||||
@ -39,6 +39,11 @@ class PCManager {
|
||||
document.getElementById('clearSearchBtn').addEventListener('click', () => {
|
||||
this.clearSearch();
|
||||
});
|
||||
|
||||
// Status aktualisieren Button
|
||||
document.getElementById('refreshStatusBtn').addEventListener('click', () => {
|
||||
this.refreshStatus();
|
||||
});
|
||||
}
|
||||
|
||||
async loadPCs() {
|
||||
@ -129,6 +134,13 @@ class PCManager {
|
||||
<tr>
|
||||
<td><strong>${this.escapeHtml(pc.name)}</strong></td>
|
||||
<td><code>${this.escapeHtml(pc.mac)}</code></td>
|
||||
<td><code>${this.escapeHtml(pc.ip || 'N/A')}</code></td>
|
||||
<td>
|
||||
<span class="badge ${pc.online ? 'bg-success' : 'bg-danger'}" id="status-${pc.id}">
|
||||
<i class="fas fa-${pc.online ? 'wifi' : 'times'}"></i>
|
||||
${pc.online ? 'Online' : 'Offline'}
|
||||
</span>
|
||||
</td>
|
||||
<td>${new Date(pc.created_at).toLocaleDateString('de-DE')}</td>
|
||||
<td>
|
||||
<div class="btn-group" role="group">
|
||||
@ -136,7 +148,7 @@ class PCManager {
|
||||
title="PC aufwecken">
|
||||
<i class="fas fa-power-off"></i> Aufwecken
|
||||
</button>
|
||||
<button class="btn btn-warning btn-sm" onclick="pcManager.editPC(${pc.id}, '${this.escapeHtml(pc.name)}', '${this.escapeHtml(pc.mac)}')"
|
||||
<button class="btn btn-warning btn-sm" onclick="pcManager.editPC(${pc.id}, '${this.escapeHtml(pc.name)}', '${this.escapeHtml(pc.mac)}', '${this.escapeHtml(pc.ip || '')}')"
|
||||
title="PC bearbeiten">
|
||||
<i class="fas fa-edit"></i> Bearbeiten
|
||||
</button>
|
||||
@ -153,8 +165,9 @@ class PCManager {
|
||||
async addPC() {
|
||||
const name = document.getElementById('pcName').value.trim();
|
||||
const mac = document.getElementById('macAddress').value.trim();
|
||||
const ip = document.getElementById('ipAddress').value.trim();
|
||||
|
||||
if (!name || !mac) {
|
||||
if (!name || !mac || !ip) {
|
||||
this.showNotification('Warnung', 'Bitte füllen Sie alle Felder aus', 'warning');
|
||||
return;
|
||||
}
|
||||
@ -165,7 +178,7 @@ class PCManager {
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({ name, mac })
|
||||
body: JSON.stringify({ name, mac, ip })
|
||||
});
|
||||
|
||||
const data = await response.json();
|
||||
@ -182,11 +195,12 @@ class PCManager {
|
||||
}
|
||||
}
|
||||
|
||||
editPC(id, name, mac) {
|
||||
editPC(id, name, mac, ip) {
|
||||
// Modal mit PC-Daten füllen
|
||||
document.getElementById('editPCId').value = id;
|
||||
document.getElementById('editPCName').value = name;
|
||||
document.getElementById('editMACAddress').value = mac;
|
||||
document.getElementById('editIPAddress').value = ip;
|
||||
|
||||
// Modal öffnen
|
||||
const editModal = new bootstrap.Modal(document.getElementById('editPCModal'));
|
||||
@ -197,8 +211,9 @@ class PCManager {
|
||||
const id = document.getElementById('editPCId').value;
|
||||
const name = document.getElementById('editPCName').value.trim();
|
||||
const mac = document.getElementById('editMACAddress').value.trim();
|
||||
const ip = document.getElementById('editIPAddress').value.trim();
|
||||
|
||||
if (!name || !mac) {
|
||||
if (!name || !mac || !ip) {
|
||||
this.showNotification('Warnung', 'Bitte füllen Sie alle Felder aus', 'warning');
|
||||
return;
|
||||
}
|
||||
@ -209,7 +224,7 @@ class PCManager {
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({ name, mac })
|
||||
body: JSON.stringify({ name, mac, ip })
|
||||
});
|
||||
|
||||
const data = await response.json();
|
||||
@ -288,6 +303,33 @@ class PCManager {
|
||||
bsToast.show();
|
||||
}
|
||||
|
||||
async refreshStatus() {
|
||||
try {
|
||||
const response = await fetch('/api/pcs/status');
|
||||
const data = await response.json();
|
||||
|
||||
if (data.success) {
|
||||
// Status für jeden PC aktualisieren
|
||||
data.status.forEach(pcStatus => {
|
||||
const statusElement = document.getElementById(`status-${pcStatus.id}`);
|
||||
if (statusElement) {
|
||||
statusElement.className = `badge ${pcStatus.online ? 'bg-success' : 'bg-danger'}`;
|
||||
statusElement.innerHTML = `
|
||||
<i class="fas fa-${pcStatus.online ? 'wifi' : 'times'}"></i>
|
||||
${pcStatus.online ? 'Online' : 'Offline'}
|
||||
`;
|
||||
}
|
||||
});
|
||||
|
||||
this.showNotification('Info', 'Online-Status aktualisiert', 'info');
|
||||
} else {
|
||||
this.showNotification('Fehler', data.message, 'danger');
|
||||
}
|
||||
} catch (error) {
|
||||
this.showNotification('Fehler', 'Fehler beim Aktualisieren des Online-Status', 'danger');
|
||||
}
|
||||
}
|
||||
|
||||
escapeHtml(text) {
|
||||
const div = document.createElement('div');
|
||||
div.textContent = text;
|
||||
|
||||
@ -31,19 +31,26 @@
|
||||
<div class="card-body">
|
||||
<form id="addPCForm">
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<div class="col-md-4">
|
||||
<div class="mb-3">
|
||||
<label for="pcName" class="form-label">PC-Name</label>
|
||||
<input type="text" class="form-control" id="pcName" required>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<div class="col-md-4">
|
||||
<div class="mb-3">
|
||||
<label for="macAddress" class="form-label">MAC-Adresse</label>
|
||||
<input type="text" class="form-control" id="macAddress"
|
||||
placeholder="XX:XX:XX:XX:XX:XX" required>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div class="mb-3">
|
||||
<label for="ipAddress" class="form-label">IP-Adresse</label>
|
||||
<input type="text" class="form-control" id="ipAddress"
|
||||
placeholder="192.168.1.100" required>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary">
|
||||
<i class="fas fa-save"></i> PC hinzufügen
|
||||
@ -81,6 +88,9 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6 text-end">
|
||||
<button class="btn btn-outline-info me-2" id="refreshStatusBtn" title="Online-Status aktualisieren">
|
||||
<i class="fas fa-sync-alt"></i> Status aktualisieren
|
||||
</button>
|
||||
<span class="badge bg-primary" id="resultCount">0 PCs gefunden</span>
|
||||
</div>
|
||||
</div>
|
||||
@ -91,6 +101,8 @@
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>MAC-Adresse</th>
|
||||
<th>IP-Adresse</th>
|
||||
<th>Status</th>
|
||||
<th>Erstellt am</th>
|
||||
<th>Aktionen</th>
|
||||
</tr>
|
||||
@ -136,6 +148,11 @@
|
||||
<input type="text" class="form-control" id="editMACAddress"
|
||||
placeholder="XX:XX:XX:XX:XX:XX" required>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="editIPAddress" class="form-label">IP-Adresse</label>
|
||||
<input type="text" class="form-control" id="editIPAddress"
|
||||
placeholder="192.168.1.100" required>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
|
||||
Reference in New Issue
Block a user