Telemetria: Edycja dashboardu i intalacji
This commit is contained in:
174
prototype/telemetria/devices.php
Normal file
174
prototype/telemetria/devices.php
Normal file
@@ -0,0 +1,174 @@
|
||||
<?php
|
||||
$enablePrototypeComments = true;
|
||||
include '../../header-telemetria.php';
|
||||
?>
|
||||
|
||||
<div class="container-xxl flex-grow-1 container-p-y">
|
||||
<div class="d-flex justify-content-between align-items-center py-3 mb-4">
|
||||
<h4 class="fw-bold mb-0">
|
||||
Telemetria <span class="text-muted fw-light">/ Urządzenia (Sprzęt)</span>
|
||||
</h4>
|
||||
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#addDeviceModal">
|
||||
<i class="bx bx-plus me-1"></i> Dodaj urządzenie
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- Tabela Urządzeń -->
|
||||
<div class="card">
|
||||
<div class="table-responsive text-nowrap">
|
||||
<table class="table table-hover">
|
||||
<thead class="table-light">
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
<th>Adres MAC</th>
|
||||
<th>Nazwa własna</th>
|
||||
<th>Status</th>
|
||||
<th>Ostatnia aktywność</th>
|
||||
<th>Akcje</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="table-border-bottom-0">
|
||||
<tr>
|
||||
<td><strong>1024</strong></td>
|
||||
<td class="text-monospace">00:1B:44:11:3A:B7</td>
|
||||
<td>Nadajnik Główny #1</td>
|
||||
<td><span class="badge bg-label-success"><i class="bx bx-wifi me-1"></i> Online</span></td>
|
||||
<td>Dzisiaj, 14:52:10</td>
|
||||
<td>
|
||||
<button type="button" class="btn btn-icon btn-outline-secondary btn-sm" data-bs-toggle="modal" data-bs-target="#editDeviceModal" title="Edytuj">
|
||||
<i class="bx bx-pencil"></i>
|
||||
</button>
|
||||
<button type="button" class="btn btn-icon btn-outline-danger btn-sm" title="Usuń">
|
||||
<i class="bx bx-trash"></i>
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><strong>1025</strong></td>
|
||||
<td class="text-monospace">00:1B:44:11:4F:C1</td>
|
||||
<td>Moduł zapasowy 1</td>
|
||||
<td><span class="badge bg-label-success"><i class="bx bx-wifi me-1"></i> Online</span></td>
|
||||
<td>Dzisiaj, 14:50:05</td>
|
||||
<td>
|
||||
<button type="button" class="btn btn-icon btn-outline-secondary btn-sm" data-bs-toggle="modal" data-bs-target="#editDeviceModal" title="Edytuj">
|
||||
<i class="bx bx-pencil"></i>
|
||||
</button>
|
||||
<button type="button" class="btn btn-icon btn-outline-danger btn-sm" title="Usuń">
|
||||
<i class="bx bx-trash"></i>
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><strong>1026</strong></td>
|
||||
<td class="text-monospace">00:1B:44:22:9C:E2</td>
|
||||
<td>Sterownik Klimatu Alpha</td>
|
||||
<td><span class="badge bg-label-danger"><i class="bx bx-wifi-off me-1"></i> Offline</span></td>
|
||||
<td>Wczoraj, 18:22:00</td>
|
||||
<td>
|
||||
<button type="button" class="btn btn-icon btn-outline-secondary btn-sm" data-bs-toggle="modal" data-bs-target="#editDeviceModal" title="Edytuj">
|
||||
<i class="bx bx-pencil"></i>
|
||||
</button>
|
||||
<button type="button" class="btn btn-icon btn-outline-danger btn-sm" title="Usuń">
|
||||
<i class="bx bx-trash"></i>
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><strong>1027</strong></td>
|
||||
<td class="text-monospace">00:1B:44:55:00:AA</td>
|
||||
<td>Nowy czujnik testowy</td>
|
||||
<td><span class="badge bg-label-secondary"><i class="bx bx-time me-1"></i> Brak danych</span></td>
|
||||
<td>-</td>
|
||||
<td>
|
||||
<button type="button" class="btn btn-icon btn-outline-secondary btn-sm" data-bs-toggle="modal" data-bs-target="#editDeviceModal" title="Edytuj">
|
||||
<i class="bx bx-pencil"></i>
|
||||
</button>
|
||||
<button type="button" class="btn btn-icon btn-outline-danger btn-sm" title="Usuń">
|
||||
<i class="bx bx-trash"></i>
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Modal Dodawania Urządzenia -->
|
||||
<div class="modal fade" id="addDeviceModal" tabindex="-1" aria-hidden="true">
|
||||
<div class="modal-dialog modal-dialog-centered">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title">Rejestracja nowego urządzenia</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="alert alert-primary" role="alert">
|
||||
<i class="bx bx-info-circle me-1"></i> Numer ID zostanie wygenerowany automatycznie po zapisaniu.
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Adres MAC sprzętu <span class="text-danger">*</span></label>
|
||||
<input type="text" class="form-control text-uppercase" placeholder="np. 00:1B:44:11:3A:B7">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Nazwa własna</label>
|
||||
<input type="text" class="form-control" placeholder="np. Nadajnik Północ">
|
||||
<div class="form-text">Przyjazna nazwa ułatwiająca identyfikację.</div>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Notatki</label>
|
||||
<textarea class="form-control" rows="3" placeholder="Dodatkowe informacje serwisowe, uwagi..."></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-outline-secondary" data-bs-dismiss="modal">Anuluj</button>
|
||||
<button type="button" class="btn btn-primary" data-bs-dismiss="modal">Zapisz urządzenie</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Modal Edycji Urządzenia -->
|
||||
<div class="modal fade" id="editDeviceModal" tabindex="-1" aria-hidden="true">
|
||||
<div class="modal-dialog modal-dialog-centered">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title">Edycja urządzenia</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="mb-3">
|
||||
<label class="form-label">ID</label>
|
||||
<input type="text" class="form-control" value="1024" disabled>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Adres MAC sprzętu <span class="text-danger">*</span></label>
|
||||
<input type="text" class="form-control text-uppercase" value="00:1B:44:11:3A:B7" disabled>
|
||||
<div class="form-text">Adresu fizycznego nie można zmienić. Skontaktuj się ze wsparciem.</div>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Nazwa własna</label>
|
||||
<input type="text" class="form-control" value="Nadajnik Główny #1">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Notatki</label>
|
||||
<textarea class="form-control" rows="3" placeholder="Dodatkowe informacje serwisowe, uwagi...">Wymieniona bateria 10.02.2025.</textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer d-flex justify-content-between">
|
||||
<button type="button" class="btn btn-outline-danger">Resetuj Token</button>
|
||||
<div>
|
||||
<button type="button" class="btn btn-outline-secondary" data-bs-dismiss="modal">Anuluj</button>
|
||||
<button type="button" class="btn btn-primary" data-bs-dismiss="modal">Zapisz zmiany</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="content-backdrop fade"></div>
|
||||
|
||||
<?php include '../../footer.php'; ?>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -82,151 +82,218 @@ include '../../header-telemetria.php';
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
<h6 class="text-muted mb-3">Moduły i Czujniki (<span id="type-label-name">Zbiornik
|
||||
Gazu</span>)</h6>
|
||||
<p class="small text-muted mb-4">Włącz czujniki i moduły, które fizycznie obsługuje ta instalacja.</p>
|
||||
<div class="d-flex justify-content-between align-items-center mb-3">
|
||||
<div>
|
||||
<h6 class="text-muted mb-1">Przypięte Urządzenia (Hardware)</h6>
|
||||
<p class="small text-muted mb-0">Wybierz fizyczne urządzenia z magazynu i przypnij je do tej instalacji.</p>
|
||||
</div>
|
||||
<button type="button" class="btn btn-sm btn-primary" data-bs-toggle="modal" data-bs-target="#assignDeviceModal">
|
||||
<i class="bx bx-link"></i> Przypisz urządzenie
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- Parametry Zbiornik (pokazywane dynamicznie) -->
|
||||
<div id="form-gas" class="dynamic-form-part">
|
||||
<div class="row mb-4">
|
||||
<div class="col-md-3">
|
||||
<div class="form-check form-switch mb-2">
|
||||
<input class="form-check-input" type="checkbox" id="sensorGasLevel" checked onchange="toggleSensorConfig('gasLevel')">
|
||||
<label class="form-check-label fw-bold" for="sensorGasLevel">Poziom napełnienia</label>
|
||||
<div class="card bg-lighter border mb-4">
|
||||
<div class="card-header border-bottom d-flex justify-content-between align-items-center py-3">
|
||||
<div class="d-flex align-items-center">
|
||||
<div class="avatar avatar-sm bg-white border me-2 d-flex justify-content-center align-items-center">
|
||||
<i class="bx bx-chip text-primary"></i>
|
||||
</div>
|
||||
<h6 class="mb-0">Nadajnik Główny #1 <span class="text-muted fw-normal ms-1">(ID: 1024, MAC: 00:1B:44:11:3A:B7)</span></h6>
|
||||
</div>
|
||||
<button class="btn btn-sm btn-outline-danger"><i class="bx bx-unlink"></i> Odłącz</button>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<div class="form-check form-switch mb-2">
|
||||
<input class="form-check-input" type="checkbox" id="sensorGasPressure" checked onchange="toggleSensorConfig('gasPressure')">
|
||||
<label class="form-check-label fw-bold" for="sensorGasPressure">Ciśnienie</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<div class="form-check form-switch mb-2">
|
||||
<input class="form-check-input" type="checkbox" id="sensorGasTemp" onchange="toggleSensorConfig('gasTemp')">
|
||||
<label class="form-check-label fw-bold" for="sensorGasTemp">Temperatura</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<div class="form-check form-switch mb-2">
|
||||
<input class="form-check-input" type="checkbox" id="sensorGasGps" onchange="toggleSensorConfig('gasGps')">
|
||||
<label class="form-check-label fw-bold" for="sensorGasGps">Moduł GPS</label>
|
||||
<div class="card-body pt-3 pb-0">
|
||||
<p class="small text-muted mb-2">Parametry obsługiwane przez to urządzenie:</p>
|
||||
<div class="table-responsive text-nowrap mb-2">
|
||||
<table class="table table-sm table-bordered bg-white">
|
||||
<thead class="table-light">
|
||||
<tr>
|
||||
<th>Klucz</th>
|
||||
<th>Nazwa</th>
|
||||
<th>Ostatnia wartość</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><span class="text-monospace text-muted">gas_level</span></td>
|
||||
<td>Poziom napełnienia</td>
|
||||
<td><span class="badge bg-label-secondary">Brak danych</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><span class="text-monospace text-muted">gas_pressure</span></td>
|
||||
<td>Ciśnienie</td>
|
||||
<td><span class="badge bg-label-secondary">Brak danych</span></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row bg-lighter p-3 rounded mb-3" id="config-gasLevel">
|
||||
<h6 class="mb-3 text-primary"><i class="bx bx-slider-alt"></i> Konfiguracja: Poziom napełnienia</h6>
|
||||
<div class="col-md-6 mb-3">
|
||||
<label class="form-label">Pojemność nominalna (litry)</label>
|
||||
<input type="number" class="form-control" value="2700">
|
||||
<div class="card bg-lighter border mb-4">
|
||||
<div class="card-header border-bottom d-flex justify-content-between align-items-center py-3">
|
||||
<div class="d-flex align-items-center">
|
||||
<div class="avatar avatar-sm bg-white border me-2 d-flex justify-content-center align-items-center">
|
||||
<i class="bx bx-chip text-primary"></i>
|
||||
</div>
|
||||
<h6 class="mb-0">Nadajnik Zapasowy #2 <span class="text-muted fw-normal ms-1">(ID: 1025, MAC: 00:1B:44:11:4F:C1)</span></h6>
|
||||
</div>
|
||||
<button class="btn btn-sm btn-outline-danger"><i class="bx bx-unlink"></i> Odłącz</button>
|
||||
</div>
|
||||
<div class="col-md-6 mb-3">
|
||||
<label class="form-label">Offset sondy (mm)</label>
|
||||
<input type="number" class="form-control" value="0">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row bg-lighter p-3 rounded mb-3" id="config-gasPressure">
|
||||
<h6 class="mb-3 text-primary"><i class="bx bx-tachometer"></i> Konfiguracja: Ciśnienie</h6>
|
||||
<div class="col-md-6 mb-3">
|
||||
<label class="form-label">Maks. ciśnienie bezpieczne (bar)</label>
|
||||
<input type="number" step="0.1" class="form-control" value="15.5">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row bg-lighter p-3 rounded mb-3 d-none" id="config-gasTemp">
|
||||
<h6 class="mb-3 text-primary"><i class="bx bxs-thermometer"></i> Konfiguracja: Temperatura</h6>
|
||||
<div class="col-md-6 mb-3">
|
||||
<label class="form-label">Korekta wskazań (°C)</label>
|
||||
<input type="number" step="0.1" class="form-control" value="0.0">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row bg-lighter p-3 rounded mb-3 d-none" id="config-gasGps">
|
||||
<h6 class="mb-3 text-primary"><i class="bx bx-map"></i> Konfiguracja: GPS</h6>
|
||||
<div class="col-md-12">
|
||||
<p class="small text-muted mb-0">Ten moduł nie wymaga dodatkowej konfiguracji. Raportowanie pozycji odbywa się automatycznie.</p>
|
||||
<div class="card-body pt-3 pb-0">
|
||||
<p class="small text-muted mb-2">Parametry obsługiwane przez to urządzenie:</p>
|
||||
<div class="table-responsive text-nowrap mb-2">
|
||||
<table class="table table-sm table-bordered bg-white">
|
||||
<thead class="table-light">
|
||||
<tr>
|
||||
<th>Klucz</th>
|
||||
<th>Nazwa</th>
|
||||
<th>Ostatnia wartość</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><span class="text-monospace text-muted">gps_lat</span></td>
|
||||
<td>Szerokość geogr. (GPS)</td>
|
||||
<td><span class="badge bg-label-secondary">Brak sygnału</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><span class="text-monospace text-muted">gps_lon</span></td>
|
||||
<td>Długość geogr. (GPS)</td>
|
||||
<td><span class="badge bg-label-secondary">Brak sygnału</span></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Parametry Kurnik (pokazywane dynamicznie) -->
|
||||
<div id="form-farm" class="dynamic-form-part d-none">
|
||||
<div class="row mb-4">
|
||||
<div class="col-md-4">
|
||||
<div class="form-check form-switch mb-2">
|
||||
<input class="form-check-input" type="checkbox" id="sensorFarmTemp" checked>
|
||||
<label class="form-check-label fw-bold" for="sensorFarmTemp">Sensory Temp.</label>
|
||||
<div class="card bg-lighter border mb-4">
|
||||
<div class="card-header border-bottom d-flex justify-content-between align-items-center py-3">
|
||||
<div class="d-flex align-items-center">
|
||||
<div class="avatar avatar-sm bg-white border me-2 d-flex justify-content-center align-items-center">
|
||||
<i class="bx bx-chip text-primary"></i>
|
||||
</div>
|
||||
<h6 class="mb-0">Sterownik Klimatu Alpha <span class="text-muted fw-normal ms-1">(ID: 1026, MAC: 00:1B:44:22:9C:E2)</span></h6>
|
||||
</div>
|
||||
<button class="btn btn-sm btn-outline-danger"><i class="bx bx-unlink"></i> Odłącz</button>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div class="form-check form-switch mb-2">
|
||||
<input class="form-check-input" type="checkbox" id="sensorFarmVent" checked>
|
||||
<label class="form-check-label fw-bold" for="sensorFarmVent">Sterowanie Wentylacją</label>
|
||||
<div class="card-body pt-3 pb-0">
|
||||
<p class="small text-muted mb-2">Parametry obsługiwane przez to urządzenie:</p>
|
||||
<div class="table-responsive text-nowrap mb-2">
|
||||
<table class="table table-sm table-bordered bg-white">
|
||||
<thead class="table-light">
|
||||
<tr>
|
||||
<th>Klucz</th>
|
||||
<th>Nazwa</th>
|
||||
<th>Ostatnia wartość</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><span class="text-monospace text-muted">temp_zone_1</span></td>
|
||||
<td>Temperatura (Strefa 1)</td>
|
||||
<td><span class="badge bg-label-secondary">Brak danych</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><span class="text-monospace text-muted">vent_status</span></td>
|
||||
<td>Status wentylacji</td>
|
||||
<td><span class="badge bg-label-secondary">Brak danych</span></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row bg-lighter p-3 rounded mb-3">
|
||||
<div class="col-md-6 mb-3">
|
||||
<label class="form-label">Liczba stref grzewczych</label>
|
||||
<input type="number" class="form-control" value="2">
|
||||
</div>
|
||||
<div class="col-md-6 mb-3">
|
||||
<label class="form-label">Interwał próbkowania (sekundy)</label>
|
||||
<input type="number" class="form-control" value="60">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Konfigurator Powiadomień -->
|
||||
<hr class="my-4">
|
||||
<div class="d-flex justify-content-between align-items-center mb-3">
|
||||
<h6 class="text-muted mb-0">Konfigurator powiadomień (Alerty)</h6>
|
||||
<button type="button" class="btn btn-sm btn-outline-primary" onclick="addAlertRow()">
|
||||
<button type="button" class="btn btn-sm btn-outline-primary" onclick="addAlertBlock()">
|
||||
<i class="bx bx-plus"></i> Dodaj alert
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div id="alerts-container">
|
||||
<!-- Dynamiczne wiersze alertów -->
|
||||
<div class="row align-items-end mb-3 alert-row">
|
||||
<div class="col-md-3">
|
||||
<label class="form-label">Parametr</label>
|
||||
<select class="form-select">
|
||||
<option>Poziom gazu (%)</option>
|
||||
<option>Ciśnienie (bar)</option>
|
||||
<option>Temperatura (°C)</option>
|
||||
<option>Brak sygnału</option>
|
||||
</select>
|
||||
<!-- Pojedynczy blok alertu -->
|
||||
<div class="card bg-lighter border mb-4 alert-block">
|
||||
<div class="card-header border-bottom d-flex justify-content-between align-items-center py-3">
|
||||
<h6 class="mb-0 text-danger"><i class="bx bx-bell"></i> Nowy Alert</h6>
|
||||
<button type="button" class="btn btn-sm btn-outline-danger" onclick="this.closest('.alert-block').remove()"><i class="bx bx-trash"></i> Usuń ten alert</button>
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<label class="form-label">Warunek</label>
|
||||
<select class="form-select">
|
||||
<option value="<">Mniejszy niż (<)</option>
|
||||
<option value=">">Większy niż (>)</option>
|
||||
<option value="=">Równy (=)</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<label class="form-label">Wartość</label>
|
||||
<input type="number" step="0.1" class="form-control" placeholder="np. 15">
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<label class="form-label">Kanał</label>
|
||||
<select class="form-select">
|
||||
<option>E-mail</option>
|
||||
<option>SMS</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<label class="form-label">Odbiorca</label>
|
||||
<input type="text" class="form-control" placeholder="Adres / Numer">
|
||||
</div>
|
||||
<div class="col-md-1">
|
||||
<button type="button" class="btn btn-icon btn-outline-danger w-100" onclick="this.closest('.alert-row').remove()">
|
||||
<i class="bx bx-trash"></i>
|
||||
<div class="card-body pt-3 pb-2">
|
||||
<div class="d-flex align-items-center mb-3">
|
||||
<p class="small text-muted fw-bold mb-0 me-3">Zasada łączenia warunków:</p>
|
||||
<select class="form-select form-select-sm w-auto border-primary text-primary fw-bold">
|
||||
<option value="AND">Spełnione WSZYSTKIE (AND)</option>
|
||||
<option value="OR">Spełniony DOWOLNY (OR)</option>
|
||||
</select>
|
||||
</div>
|
||||
<p class="small text-muted fw-bold mb-2">Warunki (Wyzwalacze):</p>
|
||||
<div class="conditions-container mb-3">
|
||||
<div class="row align-items-end mb-2 condition-row">
|
||||
<div class="col-md-3">
|
||||
<label class="form-label small">Parametr</label>
|
||||
<select class="form-select form-select-sm">
|
||||
<option>Poziom gazu (%)</option>
|
||||
<option>Ciśnienie (bar)</option>
|
||||
<option>Temperatura (°C)</option>
|
||||
<option>Brak sygnału</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<label class="form-label small">Znak</label>
|
||||
<select class="form-select form-select-sm">
|
||||
<option value="<">Mniejszy niż (<)</option>
|
||||
<option value=">">Większy niż (>)</option>
|
||||
<option value="=">Równy (=)</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<label class="form-label small">Wartość</label>
|
||||
<input type="number" step="0.1" class="form-control form-control-sm">
|
||||
</div>
|
||||
<div class="col-md-2 text-end">
|
||||
<button type="button" class="btn btn-sm btn-outline-danger" onclick="this.closest('.condition-row').remove()">
|
||||
<i class="bx bx-x"></i> Usuń
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button type="button" class="btn btn-sm btn-label-secondary mb-4" onclick="addCondition(this)">
|
||||
<i class="bx bx-plus"></i> Dodaj warunek
|
||||
</button>
|
||||
|
||||
<hr>
|
||||
<p class="small text-muted fw-bold mb-2">Akcje po spełnieniu warunków:</p>
|
||||
<div class="actions-container mb-3">
|
||||
<div class="row align-items-end mb-2 action-row">
|
||||
<div class="col-md-4">
|
||||
<label class="form-label small">Kanał wysyłki</label>
|
||||
<select class="form-select form-select-sm">
|
||||
<option>E-mail</option>
|
||||
<option>SMS</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label small">Odbiorca (Numer lub Email)</label>
|
||||
<input type="text" class="form-control form-control-sm">
|
||||
</div>
|
||||
<div class="col-md-2 text-end">
|
||||
<button type="button" class="btn btn-sm btn-outline-danger" onclick="this.closest('.action-row').remove()">
|
||||
<i class="bx bx-x"></i> Usuń
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<button type="button" class="btn btn-sm btn-label-secondary" onclick="addActionChannel(this)">
|
||||
<i class="bx bx-plus"></i> Dodaj kanał
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -325,61 +392,155 @@ include '../../header-telemetria.php';
|
||||
alert("Token skopiowany do schowka!");
|
||||
}
|
||||
|
||||
function toggleSensorConfig(sensorId) {
|
||||
const checkbox = document.getElementById('sensor' + sensorId.charAt(0).toUpperCase() + sensorId.slice(1));
|
||||
const configDiv = document.getElementById('config-' + sensorId);
|
||||
if (configDiv) {
|
||||
if (checkbox.checked) {
|
||||
configDiv.classList.remove('d-none');
|
||||
} else {
|
||||
configDiv.classList.add('d-none');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Modal Przypisywania Urządzenia
|
||||
function openAssignModal() {
|
||||
var myModal = new bootstrap.Modal(document.getElementById('assignDeviceModal'));
|
||||
myModal.show();
|
||||
}
|
||||
|
||||
function addAlertRow() {
|
||||
function addAlertBlock() {
|
||||
const container = document.getElementById('alerts-container');
|
||||
const rowHTML = `
|
||||
<div class="row align-items-end mb-3 alert-row">
|
||||
const alertHTML = `
|
||||
<div class="card bg-lighter border mb-4 alert-block">
|
||||
<div class="card-header border-bottom d-flex justify-content-between align-items-center py-3">
|
||||
<h6 class="mb-0 text-danger"><i class="bx bx-bell"></i> Nowy Alert</h6>
|
||||
<button type="button" class="btn btn-sm btn-outline-danger" onclick="this.closest('.alert-block').remove()"><i class="bx bx-trash"></i> Usuń ten alert</button>
|
||||
</div>
|
||||
<div class="card-body pt-3 pb-2">
|
||||
<div class="d-flex align-items-center mb-3">
|
||||
<p class="small text-muted fw-bold mb-0 me-3">Zasada łączenia warunków:</p>
|
||||
<select class="form-select form-select-sm w-auto border-primary text-primary fw-bold">
|
||||
<option value="AND">Spełnione WSZYSTKIE (AND)</option>
|
||||
<option value="OR">Spełniony DOWOLNY (OR)</option>
|
||||
</select>
|
||||
</div>
|
||||
<p class="small text-muted fw-bold mb-2">Warunki (Wyzwalacze):</p>
|
||||
<div class="conditions-container mb-3">
|
||||
<div class="row align-items-end mb-2 condition-row">
|
||||
<div class="col-md-3">
|
||||
<label class="form-label small">Parametr</label>
|
||||
<select class="form-select form-select-sm">
|
||||
<option>Poziom gazu (%)</option>
|
||||
<option>Ciśnienie (bar)</option>
|
||||
<option>Temperatura (°C)</option>
|
||||
<option>Brak sygnału</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<label class="form-label small">Znak</label>
|
||||
<select class="form-select form-select-sm">
|
||||
<option value="<">Mniejszy niż (<)</option>
|
||||
<option value=">">Większy niż (>)</option>
|
||||
<option value="=">Równy (=)</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<label class="form-label small">Wartość</label>
|
||||
<input type="number" step="0.1" class="form-control form-control-sm">
|
||||
</div>
|
||||
<div class="col-md-2 text-end">
|
||||
<button type="button" class="btn btn-sm btn-outline-danger" onclick="this.closest('.condition-row').remove()">
|
||||
<i class="bx bx-x"></i> Usuń
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button type="button" class="btn btn-sm btn-label-secondary mb-4" onclick="addCondition(this)">
|
||||
<i class="bx bx-plus"></i> Dodaj warunek
|
||||
</button>
|
||||
|
||||
<hr>
|
||||
<p class="small text-muted fw-bold mb-2">Akcje po spełnieniu warunków:</p>
|
||||
<div class="actions-container mb-3">
|
||||
<div class="row align-items-end mb-2 action-row">
|
||||
<div class="col-md-4">
|
||||
<label class="form-label small">Kanał wysyłki</label>
|
||||
<select class="form-select form-select-sm">
|
||||
<option>E-mail</option>
|
||||
<option>SMS</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label small">Odbiorca (Numer lub Email)</label>
|
||||
<input type="text" class="form-control form-control-sm">
|
||||
</div>
|
||||
<div class="col-md-2 text-end">
|
||||
<button type="button" class="btn btn-sm btn-outline-danger" onclick="this.closest('.action-row').remove()">
|
||||
<i class="bx bx-x"></i> Usuń
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<button type="button" class="btn btn-sm btn-label-secondary" onclick="addActionChannel(this)">
|
||||
<i class="bx bx-plus"></i> Dodaj kanał
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
container.insertAdjacentHTML('beforeend', alertHTML);
|
||||
}
|
||||
|
||||
function addCondition(btn) {
|
||||
const conditionsContainer = btn.previousElementSibling;
|
||||
const conditionHTML = `
|
||||
<div class="row align-items-end mb-2 condition-row">
|
||||
<div class="col-md-3">
|
||||
<label class="form-label">Parametr</label>
|
||||
<select class="form-select">
|
||||
<label class="form-label small">Parametr</label>
|
||||
<select class="form-select form-select-sm">
|
||||
<option>Poziom gazu (%)</option>
|
||||
<option>Ciśnienie (bar)</option>
|
||||
<option>Temperatura (°C)</option>
|
||||
<option>Brak sygnału</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<label class="form-label">Warunek</label>
|
||||
<select class="form-select">
|
||||
<div class="col-md-3">
|
||||
<label class="form-label small">Znak</label>
|
||||
<select class="form-select form-select-sm">
|
||||
<option value="<">Mniejszy niż (<)</option>
|
||||
<option value=">">Większy niż (>)</option>
|
||||
<option value="=">Równy (=)</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<label class="form-label">Wartość</label>
|
||||
<input type="number" step="0.1" class="form-control" placeholder="np. 15">
|
||||
<div class="col-md-4">
|
||||
<label class="form-label small">Wartość</label>
|
||||
<input type="number" step="0.1" class="form-control form-control-sm">
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<label class="form-label">Kanał</label>
|
||||
<select class="form-select">
|
||||
<div class="col-md-2 text-end">
|
||||
<button type="button" class="btn btn-sm btn-outline-danger" onclick="this.closest('.condition-row').remove()">
|
||||
<i class="bx bx-x"></i> Usuń
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
conditionsContainer.insertAdjacentHTML('beforeend', conditionHTML);
|
||||
}
|
||||
|
||||
function addActionChannel(btn) {
|
||||
const actionsContainer = btn.previousElementSibling;
|
||||
const actionHTML = `
|
||||
<div class="row align-items-end mb-2 action-row">
|
||||
<div class="col-md-4">
|
||||
<label class="form-label small">Kanał wysyłki</label>
|
||||
<select class="form-select form-select-sm">
|
||||
<option>E-mail</option>
|
||||
<option>SMS</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<label class="form-label">Odbiorca</label>
|
||||
<input type="text" class="form-control" placeholder="Adres / Numer">
|
||||
<div class="col-md-6">
|
||||
<label class="form-label small">Odbiorca (Numer lub Email)</label>
|
||||
<input type="text" class="form-control form-control-sm">
|
||||
</div>
|
||||
<div class="col-md-1">
|
||||
<button type="button" class="btn btn-icon btn-outline-danger w-100" onclick="this.closest('.alert-row').remove()">
|
||||
<i class="bx bx-trash"></i>
|
||||
<div class="col-md-2 text-end">
|
||||
<button type="button" class="btn btn-sm btn-outline-danger" onclick="this.closest('.action-row').remove()">
|
||||
<i class="bx bx-x"></i> Usuń
|
||||
</button>
|
||||
</div>
|
||||
</div>`;
|
||||
container.insertAdjacentHTML('beforeend', rowHTML);
|
||||
</div>
|
||||
`;
|
||||
actionsContainer.insertAdjacentHTML('beforeend', actionHTML);
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -390,5 +551,31 @@ include '../../header-telemetria.php';
|
||||
}
|
||||
</style>
|
||||
|
||||
<!-- Modal Przypisywania Urządzenia -->
|
||||
<div class="modal fade" id="assignDeviceModal" tabindex="-1" aria-hidden="true">
|
||||
<div class="modal-dialog modal-dialog-centered">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title">Przypisz urządzenie do instalacji</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Wybierz z magazynu (tylko wolne urządzenia)</label>
|
||||
<select class="form-select">
|
||||
<option value="">-- Wybierz urządzenie --</option>
|
||||
<option value="1027">1027 - Nowy czujnik testowy</option>
|
||||
<option value="1030">1030 - Moduł WiFi Zewnętrzny</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-outline-secondary" data-bs-dismiss="modal">Anuluj</button>
|
||||
<button type="button" class="btn btn-primary" data-bs-dismiss="modal">Przypisz urządzenie</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -34,69 +34,93 @@ include '../../header-telemetria.php';
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
<h6 class="text-muted mb-3">Moduły i Czujniki</h6>
|
||||
<p class="small text-muted mb-4">Zarządzaj aktywnymi czujnikami, które fizycznie obsługuje ta instalacja.</p>
|
||||
<div class="d-flex justify-content-between align-items-center mb-3">
|
||||
<div>
|
||||
<h6 class="text-muted mb-1">Przypięte Urządzenia (Hardware)</h6>
|
||||
<p class="small text-muted mb-0">Wybierz fizyczne urządzenia i skonfiguruj, jakie parametry mają przesyłać.</p>
|
||||
</div>
|
||||
<button type="button" class="btn btn-sm btn-primary" data-bs-toggle="modal" data-bs-target="#assignDeviceModal">
|
||||
<i class="bx bx-link"></i> Przypisz urządzenie
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="row mb-4">
|
||||
<div class="col-md-3">
|
||||
<div class="form-check form-switch mb-2">
|
||||
<input class="form-check-input" type="checkbox" id="sensorGasLevel" checked onchange="toggleSensorConfig('gasLevel')">
|
||||
<label class="form-check-label fw-bold" for="sensorGasLevel">Poziom napełnienia</label>
|
||||
<div class="card bg-lighter border mb-4">
|
||||
<div class="card-header border-bottom d-flex justify-content-between align-items-center py-3">
|
||||
<div class="d-flex align-items-center">
|
||||
<div class="avatar avatar-sm bg-white border me-2 d-flex justify-content-center align-items-center">
|
||||
<i class="bx bx-chip text-primary"></i>
|
||||
</div>
|
||||
<h6 class="mb-0">Nadajnik Główny #1 <span class="text-muted fw-normal ms-1">(ID: 1024, MAC: 00:1B:44:11:3A:B7)</span></h6>
|
||||
</div>
|
||||
<button class="btn btn-sm btn-outline-danger"><i class="bx bx-unlink"></i> Odłącz</button>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<div class="form-check form-switch mb-2">
|
||||
<input class="form-check-input" type="checkbox" id="sensorGasPressure" checked onchange="toggleSensorConfig('gasPressure')">
|
||||
<label class="form-check-label fw-bold" for="sensorGasPressure">Ciśnienie</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<div class="form-check form-switch mb-2">
|
||||
<input class="form-check-input" type="checkbox" id="sensorGasTemp" onchange="toggleSensorConfig('gasTemp')">
|
||||
<label class="form-check-label fw-bold" for="sensorGasTemp">Temperatura</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<div class="form-check form-switch mb-2">
|
||||
<input class="form-check-input" type="checkbox" id="sensorGasGps" checked onchange="toggleSensorConfig('gasGps')">
|
||||
<label class="form-check-label fw-bold" for="sensorGasGps">Moduł GPS</label>
|
||||
<div class="card-body pt-3 pb-0">
|
||||
<p class="small text-muted mb-2">Parametry obsługiwane przez to urządzenie:</p>
|
||||
<div class="table-responsive text-nowrap mb-2">
|
||||
<table class="table table-sm table-bordered bg-white">
|
||||
<thead class="table-light">
|
||||
<tr>
|
||||
<th>Klucz</th>
|
||||
<th>Nazwa</th>
|
||||
<th>Ostatnia wartość</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><span class="text-monospace text-muted">gas_level</span></td>
|
||||
<td>Poziom napełnienia</td>
|
||||
<td><span class="badge bg-label-primary">45%</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><span class="text-monospace text-muted">gas_pressure</span></td>
|
||||
<td>Ciśnienie</td>
|
||||
<td><span class="badge bg-label-info">12.5 bar</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><span class="text-monospace text-muted">gas_temp</span></td>
|
||||
<td>Temperatura</td>
|
||||
<td><span class="badge bg-label-warning">15.2 °C</span></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Parametry Zbiornik -->
|
||||
<div class="row bg-lighter p-3 rounded mb-3" id="config-gasLevel">
|
||||
<h6 class="mb-3 text-primary"><i class="bx bx-slider-alt"></i> Konfiguracja: Poziom napełnienia</h6>
|
||||
<div class="col-md-6 mb-3">
|
||||
<label class="form-label">Pojemność nominalna (litry)</label>
|
||||
<input type="number" class="form-control" value="2700">
|
||||
<div class="card bg-lighter border mb-4">
|
||||
<div class="card-header border-bottom d-flex justify-content-between align-items-center py-3">
|
||||
<div class="d-flex align-items-center">
|
||||
<div class="avatar avatar-sm bg-white border me-2 d-flex justify-content-center align-items-center">
|
||||
<i class="bx bx-chip text-primary"></i>
|
||||
</div>
|
||||
<h6 class="mb-0">Nadajnik Zapasowy #2 <span class="text-muted fw-normal ms-1">(ID: 1025, MAC: 00:1B:44:11:4F:C1)</span></h6>
|
||||
</div>
|
||||
<button class="btn btn-sm btn-outline-danger"><i class="bx bx-unlink"></i> Odłącz</button>
|
||||
</div>
|
||||
<div class="col-md-6 mb-3">
|
||||
<label class="form-label">Offset sondy (mm)</label>
|
||||
<input type="number" class="form-control" value="0">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row bg-lighter p-3 rounded mb-3" id="config-gasPressure">
|
||||
<h6 class="mb-3 text-primary"><i class="bx bx-tachometer"></i> Konfiguracja: Ciśnienie</h6>
|
||||
<div class="col-md-6 mb-3">
|
||||
<label class="form-label">Maks. ciśnienie bezpieczne (bar)</label>
|
||||
<input type="number" step="0.1" class="form-control" value="15.5">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row bg-lighter p-3 rounded mb-3 d-none" id="config-gasTemp">
|
||||
<h6 class="mb-3 text-primary"><i class="bx bxs-thermometer"></i> Konfiguracja: Temperatura</h6>
|
||||
<div class="col-md-6 mb-3">
|
||||
<label class="form-label">Korekta wskazań (°C)</label>
|
||||
<input type="number" step="0.1" class="form-control" value="0.0">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row bg-lighter p-3 rounded mb-3" id="config-gasGps">
|
||||
<h6 class="mb-3 text-primary"><i class="bx bx-map"></i> Konfiguracja: GPS</h6>
|
||||
<div class="col-md-12">
|
||||
<p class="small text-muted mb-0">Ten moduł nie wymaga dodatkowej konfiguracji. Raportowanie pozycji odbywa się automatycznie na podstawie satelitów.</p>
|
||||
<div class="card-body pt-3 pb-0">
|
||||
<p class="small text-muted mb-2">Parametry obsługiwane przez to urządzenie:</p>
|
||||
<div class="table-responsive text-nowrap mb-2">
|
||||
<table class="table table-sm table-bordered bg-white">
|
||||
<thead class="table-light">
|
||||
<tr>
|
||||
<th>Klucz</th>
|
||||
<th>Nazwa</th>
|
||||
<th>Ostatnia wartość</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><span class="text-monospace text-muted">gps_lat</span></td>
|
||||
<td>Szerokość geogr. (GPS)</td>
|
||||
<td><span class="badge bg-label-secondary">Brak sygnału</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><span class="text-monospace text-muted">gps_lon</span></td>
|
||||
<td>Długość geogr. (GPS)</td>
|
||||
<td><span class="badge bg-label-secondary">Brak sygnału</span></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -104,89 +128,112 @@ include '../../header-telemetria.php';
|
||||
<hr class="my-4">
|
||||
<div class="d-flex justify-content-between align-items-center mb-3">
|
||||
<h6 class="text-muted mb-0">Konfigurator powiadomień (Alerty)</h6>
|
||||
<button type="button" class="btn btn-sm btn-outline-primary" onclick="addAlertRow()">
|
||||
<button type="button" class="btn btn-sm btn-outline-primary" onclick="addAlertBlock()">
|
||||
<i class="bx bx-plus"></i> Dodaj alert
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div id="alerts-container">
|
||||
<!-- Istniejące alerty (zapisane w systemie) -->
|
||||
<div class="row align-items-end mb-3 alert-row">
|
||||
<div class="col-md-3">
|
||||
<label class="form-label">Parametr</label>
|
||||
<select class="form-select">
|
||||
<option selected>Poziom gazu (%)</option>
|
||||
<option>Ciśnienie (bar)</option>
|
||||
<option>Temperatura (°C)</option>
|
||||
<option>Brak sygnału</option>
|
||||
</select>
|
||||
<!-- Pojedynczy blok alertu -->
|
||||
<div class="card bg-lighter border mb-4 alert-block">
|
||||
<div class="card-header border-bottom d-flex justify-content-between align-items-center py-3">
|
||||
<h6 class="mb-0 text-danger"><i class="bx bx-bell"></i> Alert Systemowy #1</h6>
|
||||
<button type="button" class="btn btn-sm btn-outline-danger" onclick="this.closest('.alert-block').remove()"><i class="bx bx-trash"></i> Usuń ten alert</button>
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<label class="form-label">Warunek</label>
|
||||
<select class="form-select">
|
||||
<option value="<" selected>Mniejszy niż (<)</option>
|
||||
<option value=">">Większy niż (>)</option>
|
||||
<option value="=">Równy (=)</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<label class="form-label">Wartość</label>
|
||||
<input type="number" step="0.1" class="form-control" value="15">
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<label class="form-label">Kanał</label>
|
||||
<select class="form-select">
|
||||
<option>E-mail</option>
|
||||
<option selected>SMS</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<label class="form-label">Odbiorca</label>
|
||||
<input type="text" class="form-control" value="+48 123 456 789">
|
||||
</div>
|
||||
<div class="col-md-1">
|
||||
<button type="button" class="btn btn-icon btn-outline-danger w-100" onclick="this.closest('.alert-row').remove()">
|
||||
<i class="bx bx-trash"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body pt-3 pb-2">
|
||||
<div class="d-flex align-items-center mb-3">
|
||||
<p class="small text-muted fw-bold mb-0 me-3">Zasada łączenia warunków:</p>
|
||||
<select class="form-select form-select-sm w-auto border-primary text-primary fw-bold">
|
||||
<option value="AND">Spełnione WSZYSTKIE (AND)</option>
|
||||
<option value="OR">Spełniony DOWOLNY (OR)</option>
|
||||
</select>
|
||||
</div>
|
||||
<p class="small text-muted fw-bold mb-2">Warunki (Wyzwalacze):</p>
|
||||
<div class="conditions-container mb-3">
|
||||
<div class="row align-items-end mb-2 condition-row">
|
||||
<div class="col-md-3">
|
||||
<label class="form-label small">Parametr</label>
|
||||
<select class="form-select form-select-sm">
|
||||
<option selected>Poziom gazu (%)</option>
|
||||
<option>Ciśnienie (bar)</option>
|
||||
<option>Temperatura (°C)</option>
|
||||
<option>Brak sygnału</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<label class="form-label small">Znak</label>
|
||||
<select class="form-select form-select-sm">
|
||||
<option value="<" selected>Mniejszy niż (<)</option>
|
||||
<option value=">">Większy niż (>)</option>
|
||||
<option value="=">Równy (=)</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<label class="form-label small">Wartość</label>
|
||||
<input type="number" step="0.1" class="form-control form-control-sm" value="15">
|
||||
</div>
|
||||
<div class="col-md-2 text-end">
|
||||
<button type="button" class="btn btn-sm btn-outline-danger" onclick="this.closest('.condition-row').remove()">
|
||||
<i class="bx bx-x"></i> Usuń
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row align-items-end mb-2 condition-row">
|
||||
<div class="col-md-3">
|
||||
<label class="form-label small">Parametr</label>
|
||||
<select class="form-select form-select-sm">
|
||||
<option>Poziom gazu (%)</option>
|
||||
<option selected>Ciśnienie (bar)</option>
|
||||
<option>Temperatura (°C)</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<label class="form-label small">Znak</label>
|
||||
<select class="form-select form-select-sm">
|
||||
<option value="<">Mniejszy niż (<)</option>
|
||||
<option value=">" selected>Większy niż (>)</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<label class="form-label small">Wartość</label>
|
||||
<input type="number" step="0.1" class="form-control form-control-sm" value="10">
|
||||
</div>
|
||||
<div class="col-md-2 text-end">
|
||||
<button type="button" class="btn btn-sm btn-outline-danger" onclick="this.closest('.condition-row').remove()">
|
||||
<i class="bx bx-x"></i> Usuń
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row align-items-end mb-3 alert-row">
|
||||
<div class="col-md-3">
|
||||
<label class="form-label">Parametr</label>
|
||||
<select class="form-select">
|
||||
<option>Poziom gazu (%)</option>
|
||||
<option selected>Ciśnienie (bar)</option>
|
||||
<option>Temperatura (°C)</option>
|
||||
<option>Brak sygnału</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<label class="form-label">Warunek</label>
|
||||
<select class="form-select">
|
||||
<option value="<">Mniejszy niż (<)</option>
|
||||
<option value=">" selected>Większy niż (>)</option>
|
||||
<option value="=">Równy (=)</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<label class="form-label">Wartość</label>
|
||||
<input type="number" step="0.1" class="form-control" value="7.5">
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<label class="form-label">Kanał</label>
|
||||
<select class="form-select">
|
||||
<option>E-mail</option>
|
||||
<option selected>SMS</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<label class="form-label">Odbiorca</label>
|
||||
<input type="text" class="form-control" value="+48 123 456 789">
|
||||
</div>
|
||||
<div class="col-md-1">
|
||||
<button type="button" class="btn btn-icon btn-outline-danger w-100" onclick="this.closest('.alert-row').remove()">
|
||||
<i class="bx bx-trash"></i>
|
||||
<button type="button" class="btn btn-sm btn-label-secondary mb-4" onclick="addCondition(this)">
|
||||
<i class="bx bx-plus"></i> Dodaj warunek
|
||||
</button>
|
||||
|
||||
<hr>
|
||||
<p class="small text-muted fw-bold mb-2">Akcje po spełnieniu warunków:</p>
|
||||
<div class="actions-container mb-3">
|
||||
<div class="row align-items-end mb-2 action-row">
|
||||
<div class="col-md-4">
|
||||
<label class="form-label small">Kanał wysyłki</label>
|
||||
<select class="form-select form-select-sm">
|
||||
<option>E-mail</option>
|
||||
<option selected>SMS</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label small">Odbiorca (Numer lub Email)</label>
|
||||
<input type="text" class="form-control form-control-sm" value="+48 123 456 789">
|
||||
</div>
|
||||
<div class="col-md-2 text-end">
|
||||
<button type="button" class="btn btn-sm btn-outline-danger" onclick="this.closest('.action-row').remove()">
|
||||
<i class="bx bx-x"></i> Usuń
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<button type="button" class="btn btn-sm btn-label-secondary" onclick="addActionChannel(this)">
|
||||
<i class="bx bx-plus"></i> Dodaj kanał
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -206,65 +253,177 @@ include '../../header-telemetria.php';
|
||||
<?php include '../../footer.php'; ?>
|
||||
|
||||
<script>
|
||||
function addAlertRow() {
|
||||
function addAlertBlock() {
|
||||
const container = document.getElementById('alerts-container');
|
||||
const rowHTML = `
|
||||
<div class="row align-items-end mb-3 alert-row">
|
||||
const alertHTML = `
|
||||
<div class="card bg-lighter border mb-4 alert-block">
|
||||
<div class="card-header border-bottom d-flex justify-content-between align-items-center py-3">
|
||||
<h6 class="mb-0 text-danger"><i class="bx bx-bell"></i> Nowy Alert</h6>
|
||||
<button type="button" class="btn btn-sm btn-outline-danger" onclick="this.closest('.alert-block').remove()"><i class="bx bx-trash"></i> Usuń ten alert</button>
|
||||
</div>
|
||||
<div class="card-body pt-3 pb-2">
|
||||
<div class="d-flex align-items-center mb-3">
|
||||
<p class="small text-muted fw-bold mb-0 me-3">Zasada łączenia warunków:</p>
|
||||
<select class="form-select form-select-sm w-auto border-primary text-primary fw-bold">
|
||||
<option value="AND">Spełnione WSZYSTKIE (AND)</option>
|
||||
<option value="OR">Spełniony DOWOLNY (OR)</option>
|
||||
</select>
|
||||
</div>
|
||||
<p class="small text-muted fw-bold mb-2">Warunki (Wyzwalacze):</p>
|
||||
<div class="conditions-container mb-3">
|
||||
<div class="row align-items-end mb-2 condition-row">
|
||||
<div class="col-md-3">
|
||||
<label class="form-label small">Parametr</label>
|
||||
<select class="form-select form-select-sm">
|
||||
<option>Poziom gazu (%)</option>
|
||||
<option>Ciśnienie (bar)</option>
|
||||
<option>Temperatura (°C)</option>
|
||||
<option>Brak sygnału</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<label class="form-label small">Znak</label>
|
||||
<select class="form-select form-select-sm">
|
||||
<option value="<">Mniejszy niż (<)</option>
|
||||
<option value=">">Większy niż (>)</option>
|
||||
<option value="=">Równy (=)</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<label class="form-label small">Wartość</label>
|
||||
<input type="number" step="0.1" class="form-control form-control-sm">
|
||||
</div>
|
||||
<div class="col-md-2 text-end">
|
||||
<button type="button" class="btn btn-sm btn-outline-danger" onclick="this.closest('.condition-row').remove()">
|
||||
<i class="bx bx-x"></i> Usuń
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button type="button" class="btn btn-sm btn-label-secondary mb-4" onclick="addCondition(this)">
|
||||
<i class="bx bx-plus"></i> Dodaj warunek
|
||||
</button>
|
||||
|
||||
<hr>
|
||||
<p class="small text-muted fw-bold mb-2">Akcje po spełnieniu warunków:</p>
|
||||
<div class="actions-container mb-3">
|
||||
<div class="row align-items-end mb-2 action-row">
|
||||
<div class="col-md-4">
|
||||
<label class="form-label small">Kanał wysyłki</label>
|
||||
<select class="form-select form-select-sm">
|
||||
<option>E-mail</option>
|
||||
<option>SMS</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label small">Odbiorca (Numer lub Email)</label>
|
||||
<input type="text" class="form-control form-control-sm">
|
||||
</div>
|
||||
<div class="col-md-2 text-end">
|
||||
<button type="button" class="btn btn-sm btn-outline-danger" onclick="this.closest('.action-row').remove()">
|
||||
<i class="bx bx-x"></i> Usuń
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<button type="button" class="btn btn-sm btn-label-secondary" onclick="addActionChannel(this)">
|
||||
<i class="bx bx-plus"></i> Dodaj kanał
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
container.insertAdjacentHTML('beforeend', alertHTML);
|
||||
}
|
||||
|
||||
function addCondition(btn) {
|
||||
const conditionsContainer = btn.previousElementSibling;
|
||||
const conditionHTML = `
|
||||
<div class="row align-items-end mb-2 condition-row">
|
||||
<div class="col-md-3">
|
||||
<label class="form-label">Parametr</label>
|
||||
<select class="form-select">
|
||||
<label class="form-label small">Parametr</label>
|
||||
<select class="form-select form-select-sm">
|
||||
<option>Poziom gazu (%)</option>
|
||||
<option>Ciśnienie (bar)</option>
|
||||
<option>Temperatura (°C)</option>
|
||||
<option>Brak sygnału</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<label class="form-label">Warunek</label>
|
||||
<select class="form-select">
|
||||
<div class="col-md-3">
|
||||
<label class="form-label small">Znak</label>
|
||||
<select class="form-select form-select-sm">
|
||||
<option value="<">Mniejszy niż (<)</option>
|
||||
<option value=">">Większy niż (>)</option>
|
||||
<option value="=">Równy (=)</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<label class="form-label">Wartość</label>
|
||||
<input type="number" step="0.1" class="form-control" placeholder="np. 15">
|
||||
<div class="col-md-4">
|
||||
<label class="form-label small">Wartość</label>
|
||||
<input type="number" step="0.1" class="form-control form-control-sm">
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<label class="form-label">Kanał</label>
|
||||
<select class="form-select">
|
||||
<div class="col-md-2 text-end">
|
||||
<button type="button" class="btn btn-sm btn-outline-danger" onclick="this.closest('.condition-row').remove()">
|
||||
<i class="bx bx-x"></i> Usuń
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
conditionsContainer.insertAdjacentHTML('beforeend', conditionHTML);
|
||||
}
|
||||
|
||||
function addActionChannel(btn) {
|
||||
const actionsContainer = btn.previousElementSibling;
|
||||
const actionHTML = `
|
||||
<div class="row align-items-end mb-2 action-row">
|
||||
<div class="col-md-4">
|
||||
<label class="form-label small">Kanał wysyłki</label>
|
||||
<select class="form-select form-select-sm">
|
||||
<option>E-mail</option>
|
||||
<option>SMS</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<label class="form-label">Odbiorca</label>
|
||||
<input type="text" class="form-control" placeholder="Adres / Numer">
|
||||
<div class="col-md-6">
|
||||
<label class="form-label small">Odbiorca (Numer lub Email)</label>
|
||||
<input type="text" class="form-control form-control-sm">
|
||||
</div>
|
||||
<div class="col-md-1">
|
||||
<button type="button" class="btn btn-icon btn-outline-danger w-100" onclick="this.closest('.alert-row').remove()">
|
||||
<i class="bx bx-trash"></i>
|
||||
<div class="col-md-2 text-end">
|
||||
<button type="button" class="btn btn-sm btn-outline-danger" onclick="this.closest('.action-row').remove()">
|
||||
<i class="bx bx-x"></i> Usuń
|
||||
</button>
|
||||
</div>
|
||||
</div>`;
|
||||
container.insertAdjacentHTML('beforeend', rowHTML);
|
||||
</div>
|
||||
`;
|
||||
actionsContainer.insertAdjacentHTML('beforeend', actionHTML);
|
||||
}
|
||||
</script>
|
||||
|
||||
<script>
|
||||
function toggleSensorConfig(sensorId) {
|
||||
const checkbox = document.getElementById('sensor' + sensorId.charAt(0).toUpperCase() + sensorId.slice(1));
|
||||
const configDiv = document.getElementById('config-' + sensorId);
|
||||
if (configDiv) {
|
||||
if (checkbox.checked) {
|
||||
configDiv.classList.remove('d-none');
|
||||
} else {
|
||||
configDiv.classList.add('d-none');
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
<!-- Modal Przypisywania Urządzenia -->
|
||||
<div class="modal fade" id="assignDeviceModal" tabindex="-1" aria-hidden="true">
|
||||
<div class="modal-dialog modal-dialog-centered">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title">Przypisz urządzenie do instalacji</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Wybierz z magazynu (tylko wolne urządzenia)</label>
|
||||
<select class="form-select">
|
||||
<option value="">-- Wybierz urządzenie --</option>
|
||||
<option value="1027">1027 - Nowy czujnik testowy</option>
|
||||
<option value="1030">1030 - Moduł WiFi Zewnętrzny</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-outline-secondary" data-bs-dismiss="modal">Anuluj</button>
|
||||
<button type="button" class="btn btn-primary" data-bs-dismiss="modal">Przypisz urządzenie</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -27,6 +27,9 @@ include '../../header-telemetria.php';
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<button type="button" class="btn btn-outline-primary me-2" id="toggleEditModeBtn" onclick="toggleEditMode()">
|
||||
<i class="bx bx-customize me-1"></i> Edytuj dashboard
|
||||
</button>
|
||||
<a href="installation-edit.php" class="btn btn-outline-secondary">
|
||||
<i class="bx bx-pencil me-1"></i> Edytuj instalację
|
||||
</a>
|
||||
@@ -37,7 +40,10 @@ include '../../header-telemetria.php';
|
||||
<div class="row g-4 mb-4">
|
||||
<!-- SVG Zbiornika -->
|
||||
<div class="col-xl-4 col-lg-5 col-md-12">
|
||||
<div class="card border-0 shadow-sm mb-4">
|
||||
<div class="card border-0 shadow-sm mb-4 position-relative">
|
||||
<button type="button" class="btn btn-sm btn-icon btn-primary position-absolute top-0 end-0 m-2 widget-settings-btn d-none zindex-1" onclick="openWidgetConfig('Wizualizacja stanu napełnienia')">
|
||||
<i class="bx bx-cog"></i>
|
||||
</button>
|
||||
<div class="card-header border-bottom">
|
||||
<h5 class="card-title m-0">Wizualizacja stanu napełnienia</h5>
|
||||
</div>
|
||||
@@ -145,7 +151,10 @@ include '../../header-telemetria.php';
|
||||
|
||||
<!-- Poziom gazu w litrach -->
|
||||
<div class="col">
|
||||
<div class="card shadow-sm border-0 border-start border-warning border-3">
|
||||
<div class="card shadow-sm border-0 border-start border-warning border-3 position-relative">
|
||||
<button type="button" class="btn btn-sm btn-icon btn-primary position-absolute top-0 end-0 m-2 widget-settings-btn d-none zindex-1" onclick="openWidgetConfig('Poziom gazu (Wartość / litry)')">
|
||||
<i class="bx bx-cog"></i>
|
||||
</button>
|
||||
<div class="card-body">
|
||||
<div class="d-flex align-items-start justify-content-between">
|
||||
<div class="content-left">
|
||||
@@ -168,7 +177,10 @@ include '../../header-telemetria.php';
|
||||
|
||||
<!-- Ciśnienie -->
|
||||
<div class="col">
|
||||
<div class="card shadow-sm border-0">
|
||||
<div class="card shadow-sm border-0 position-relative">
|
||||
<button type="button" class="btn btn-sm btn-icon btn-primary position-absolute top-0 end-0 m-2 widget-settings-btn d-none zindex-1" onclick="openWidgetConfig('Ciśnienie operacyjne')">
|
||||
<i class="bx bx-cog"></i>
|
||||
</button>
|
||||
<div class="card-body">
|
||||
<div class="d-flex align-items-start justify-content-between">
|
||||
<div class="content-left">
|
||||
@@ -190,7 +202,10 @@ include '../../header-telemetria.php';
|
||||
|
||||
<!-- Temperatura -->
|
||||
<div class="col">
|
||||
<div class="card shadow-sm border-0">
|
||||
<div class="card shadow-sm border-0 position-relative">
|
||||
<button type="button" class="btn btn-sm btn-icon btn-primary position-absolute top-0 end-0 m-2 widget-settings-btn d-none zindex-1" onclick="openWidgetConfig('Temperatura otoczenia')">
|
||||
<i class="bx bx-cog"></i>
|
||||
</button>
|
||||
<div class="card-body">
|
||||
<div class="d-flex align-items-start justify-content-between">
|
||||
<div class="content-left">
|
||||
@@ -212,7 +227,10 @@ include '../../header-telemetria.php';
|
||||
|
||||
<!-- Zasilanie i sieć -->
|
||||
<div class="col">
|
||||
<div class="card shadow-sm border-0">
|
||||
<div class="card shadow-sm border-0 position-relative">
|
||||
<button type="button" class="btn btn-sm btn-icon btn-primary position-absolute top-0 end-0 m-2 widget-settings-btn d-none zindex-1" onclick="openWidgetConfig('Hardware & Sieć')">
|
||||
<i class="bx bx-cog"></i>
|
||||
</button>
|
||||
<div class="card-body">
|
||||
<div class="d-flex align-items-start justify-content-between mb-3">
|
||||
<span class="text-muted text-uppercase small fw-bold"
|
||||
@@ -337,6 +355,34 @@ include '../../header-telemetria.php';
|
||||
</style>
|
||||
|
||||
<script>
|
||||
function toggleEditMode() {
|
||||
document.body.classList.toggle('dashboard-edit-mode');
|
||||
const isEdit = document.body.classList.contains('dashboard-edit-mode');
|
||||
|
||||
document.querySelectorAll('.widget-settings-btn').forEach(btn => {
|
||||
if(isEdit) {
|
||||
btn.classList.remove('d-none');
|
||||
} else {
|
||||
btn.classList.add('d-none');
|
||||
}
|
||||
});
|
||||
|
||||
const toggleBtn = document.getElementById('toggleEditModeBtn');
|
||||
if(isEdit) {
|
||||
toggleBtn.classList.replace('btn-outline-primary', 'btn-primary');
|
||||
toggleBtn.innerHTML = '<i class="bx bx-check me-1"></i> Zakończ edycję';
|
||||
} else {
|
||||
toggleBtn.classList.replace('btn-primary', 'btn-outline-primary');
|
||||
toggleBtn.innerHTML = '<i class="bx bx-customize me-1"></i> Edytuj dashboard';
|
||||
}
|
||||
}
|
||||
|
||||
function openWidgetConfig(widgetName) {
|
||||
document.getElementById('configWidgetName').innerText = widgetName;
|
||||
var myModal = new bootstrap.Modal(document.getElementById('widgetConfigModal'));
|
||||
myModal.show();
|
||||
}
|
||||
|
||||
// Prosty skrypt symulujący ruch danych (Live)
|
||||
setInterval(() => {
|
||||
// Losuj delikatnie ciśnienie
|
||||
@@ -353,6 +399,39 @@ include '../../header-telemetria.php';
|
||||
}, 2000);
|
||||
</script>
|
||||
|
||||
<!-- Modal Konfiguracji Widgetu -->
|
||||
<div class="modal fade" id="widgetConfigModal" tabindex="-1" aria-hidden="true">
|
||||
<div class="modal-dialog modal-dialog-centered">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title">Skonfiguruj widget: <br><span id="configWidgetName" class="text-primary fs-6 fw-bold"></span></h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Wybierz parametr z urządzenia</label>
|
||||
<select class="form-select">
|
||||
<option value="">-- Wybierz --</option>
|
||||
<optgroup label="Urządzenie: 1027 - Moduł WiFi Zewnętrzny">
|
||||
<option>Poziom gazu (%)</option>
|
||||
<option>Ciśnienie (bar)</option>
|
||||
<option>Temperatura otoczenia (°C)</option>
|
||||
</optgroup>
|
||||
<optgroup label="Urządzenie: 1030 - Moduł Zasilania">
|
||||
<option>Napięcie baterii (V)</option>
|
||||
<option>Zasięg GSM (%)</option>
|
||||
</optgroup>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-outline-secondary" data-bs-dismiss="modal">Anuluj</button>
|
||||
<button type="button" class="btn btn-primary" data-bs-dismiss="modal">Zapisz ustawienia</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="content-backdrop fade"></div>
|
||||
|
||||
<?php include '../../footer.php'; ?>
|
||||
|
||||
@@ -31,6 +31,12 @@ $currentPage = basename($_SERVER['PHP_SELF']);
|
||||
<div class="text-truncate" data-i18n="Instalacje">Instalacje</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="menu-item <?php echo ($currentPage == 'devices.php') ? 'active' : ''; ?>">
|
||||
<a href="devices.php" class="menu-link">
|
||||
<i class="menu-icon tf-icons bx bx-chip"></i>
|
||||
<div class="text-truncate" data-i18n="Urządzenia">Urządzenia (Sprzęt)</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="menu-item <?php echo ($currentPage == 'reports.php') ? 'active' : ''; ?>">
|
||||
<a href="reports.php" class="menu-link">
|
||||
<i class="menu-icon tf-icons bx bx-bar-chart-alt-2"></i>
|
||||
|
||||
Reference in New Issue
Block a user