diff --git a/docs/HOME_ASSISTANT.md b/docs/HOME_ASSISTANT.md index de66e3b8..a2c226a3 100755 --- a/docs/HOME_ASSISTANT.md +++ b/docs/HOME_ASSISTANT.md @@ -1,82 +1,87 @@ -# Home Assistant integration overview +# Home Assistant integration -NetAlertX comes with MQTT support, allowing you to show all detected devices as devices in Home Assistant. It also supplies a collection of stats, such as number of online devices. +NetAlertX includes MQTT support, allowing detected devices to appear as devices in Home Assistant. It also publishes various statistics, such as the number of online devices. > [!TIP] -> You can install NetAlertX also as a Home Assistant addon [![Home Assistant](https://img.shields.io/badge/Repo-blue?logo=home-assistant&style=for-the-badge&color=0aa8d2&logoColor=fff&label=Add)](https://my.home-assistant.io/redirect/supervisor_add_addon_repository/?repository_url=https%3A%2F%2Fgithub.com%2Falexbelgium%2Fhassio-addons) via the [alexbelgium/hassio-addons](https://github.com/alexbelgium/hassio-addons/) repository. This is only possible if you run a supervised instance of Home Assistant. If not, you can still run NetAlertX in a separate Docker container and follow this guide to configure MQTT. +> You can also install NetAlertX as a Home Assistant Add-on via the [![Home Assistant](https://img.shields.io/badge/Repo-blue?logo=home-assistant\&style=for-the-badge\&color=0aa8d2\&logoColor=fff\&label=Add)](https://my.home-assistant.io/redirect/supervisor_add_addon_repository/?repository_url=https%3A%2F%2Fgithub.com%2Falexbelgium%2Fhassio-addons) from the [alexbelgium/hassio-addons](https://github.com/alexbelgium/hassio-addons/) repository. This is only available for supervised Home Assistant installations. If you're running Home Assistant Container or Home Assistant Core, you can instead run NetAlertX in a separate Docker container. -## ⚠ Note +> [!WARNING] +> +> * Device discovery in Home Assistant takes approximately 10 seconds **per device**. +> * Devices removed from NetAlertX are not automatically removed from Home Assistant. Use [MQTT Explorer](https://mqtt-explorer.com/) to delete them from the MQTT broker if required. +> * For performance reasons, device definitions are not always fully synchronized. To force a complete synchronization, delete the MQTT Plugin Objects as described in the [MQTT plugin](https://github.com/netalertx/NetAlertX/tree/main/front/plugins/_publisher_mqtt#forcing-an-update) documentation. -- Please note that discovery takes about ~10s per device. -- Deleting of devices is not handled automatically. Please use [MQTT Explorer](https://mqtt-explorer.com/) to delete devices in the broker (Home Assistant), if needed. -- For optimization reasons, the devices are not always fully synchronized. You can delete Plugin objects as described in the [MQTT plugin](https://github.com/netalertx/NetAlertX/tree/main/front/plugins/_publisher_mqtt#forcing-an-update) docs to force a full synchronization. +## Mosquitto MQTT setup +1. Enable the Mosquitto MQTT integration in Home Assistant by following the [official documentation](https://www.home-assistant.io/integrations/mqtt/). +2. Create an MQTT username and password on your broker. +3. Record the following information for configuring NetAlertX: -## 🧭 Guide + * MQTT host URL (usually your Home Assistant IP address) + * MQTT broker port + * Username + * Password -> 💡 This guide was tested only with the Mosquitto MQTT broker +4. Open **NetAlertX** → **Settings** → **MQTT**. -1. Enable Mosquitto MQTT in Home Assistant by following the [documentation](https://www.home-assistant.io/integrations/mqtt/) - -2. Configure a user name and password on your broker. - -3. Note down the following details that you will need to configure NetAlertX: - - - MQTT host url (usually your Home Assistant IP) - - MQTT broker port - - User - - Password - -4. Open the _NetAlertX_ > _Settings_ > _MQTT_ settings group - - - Enable MQTT - - Fill in the details from above - - Fill in remaining settings as per description - - set MQTT_RUN to schedule or on_notification depending on requirements + * Enable MQTT. + * Enter the broker details from the previous step. + * Configure the remaining settings as needed. + * Set `MQTT_RUN` to either `schedule` or `on_notification`, depending on your requirements. ![Configuration Example][configuration] -## 📷 Screenshots +### Screenshots - | ![Screen 1][sensors] | ![Screen 2][history] | - |----------------------|----------------------| - | ![Screen 3][list] | ![Screen 4][overview] | +| ![Screen 1][sensors] | ![Screen 2][history] | +| -------------------- | --------------------- | +| ![Screen 3][list] | ![Screen 4][overview] | - - [configuration]: ./img/HOME_ASISSTANT/HomeAssistant-Configuration.png "configuration" - [sensors]: ./img/HOME_ASISSTANT/HomeAssistant-Device-as-Sensors.png "sensors" - [history]: ./img/HOME_ASISSTANT/HomeAssistant-Device-Presence-History.png "history" - [list]: ./img/HOME_ASISSTANT/HomeAssistant-Devices-List.png "list" - [overview]: ./img/HOME_ASISSTANT/HomeAssistant-Overview-Card.png "overview" +[configuration]: ./img/HOME_ASSISTANT/HomeAssistant-Configuration.png "configuration" +[sensors]: ./img/HOME_ASSISTANT/HomeAssistant-Device-as-Sensors.png "sensors" +[history]: ./img/HOME_ASSISTANT/HomeAssistant-Device-Presence-History.png "history" +[list]: ./img/HOME_ASSISTANT/HomeAssistant-Devices-List.png "list" +[overview]: ./img/HOME_ASSISTANT/HomeAssistant-Overview-Card.png "overview" ## Troubleshooting -If you can't see all devices detected, run `sudo arp-scan --interface=eth0 192.168.1.0/24` (change these based on your setup, read [Subnets](./SUBNETS.md) docs for details). This command has to be executed the NetAlertX container, not in the Home Assistant container. +### Missing devices -You can access the NetAlertX container via Portainer on your host or via ssh. The container name will be something like `addon_db21ed7f_netalertx` (you can copy the `db21ed7f_netalertx` part from the browser when accessing the UI of NetAlertX). +If some devices do not appear in Home Assistant, first verify that NetAlertX can detect them by running: -## Accessing the NetAlertX container via SSH +```bash +sudo arp-scan --interface=eth0 192.168.1.0/24 +``` -1. Log into your Home Assistant host via SSH +Replace the interface and subnet with values appropriate for your environment (see the [Subnets](./SUBNETS.md) documentation). + +Run this command **inside the NetAlertX container**, not inside the Home Assistant container. + +### Accessing the NetAlertX container + +You can access the NetAlertX container via Portainer on your host or via SSH. The container name will be something like `addon_db21ed7f_netalertx` (you can copy the `db21ed7f_netalertx` part from the browser URL when accessing the NetAlertX web interface). + +1. Log into your Home Assistant host via SSH. ```bash local@local:~ $ ssh pi@192.168.1.9 ``` -2. Find the NetAlertX container name, in this case `addon_db21ed7f_netalertx` + +2. Find the NetAlertX container name. ```bash pi@raspberrypi:~ $ sudo docker container ls | grep netalertx 06c540d97f67 ghcr.io/alexbelgium/netalertx-armv7:25.3.1 "/init" 6 days ago Up 6 days (healthy) addon_db21ed7f_netalertx ``` -3. SSH into the NetAlertX cointainer +3. Open a shell inside the NetAlertX container. ```bash -pi@raspberrypi:~ $ sudo docker exec -it addon_db21ed7f_netalertx /bin/sh +pi@raspberrypi:~ $ sudo docker exec -it addon_db21ed7f_netalertx /bin/sh / # ``` -4. Execute a test `asrp-scan` scan +4. Run a test `arp-scan`. ```bash / # sudo arp-scan --ignoredups --retry=6 192.168.1.0/24 --interface=eth0 @@ -89,4 +94,4 @@ Starting arp-scan 1.10.0 with 256 hosts (https://github.com/royhills/arp-scan) ... ``` -If your result doesn't contain results similar to the above, double check your subnet, interface and if you are dealing with an inaccessible network segment, read the [Remote networks documentation](./REMOTE_NETWORKS.md). \ No newline at end of file +If your output does not contain devices similar to those shown above, verify that your subnet configuration is correct (see the [Subnets](./SUBNETS.md) documentation), that you are scanning the correct network interface, and that the network segment is reachable. If the devices are located on a different or remote network, refer to the [Remote Networks](./REMOTE_NETWORKS.md) documentation. diff --git a/docs/NOTIFICATIONS.md b/docs/NOTIFICATIONS.md index 882381e3..03a67adf 100755 --- a/docs/NOTIFICATIONS.md +++ b/docs/NOTIFICATIONS.md @@ -24,7 +24,7 @@ The following device properties influence notifications. You can: 2. **Alert Down** - Alerts when a device goes down. This setting overrides a disabled **Alert Events** setting, so you will get a notification of a device going down even if you don't have **Alert Events** ticked. Disabling this will disable down and down reconnected notifications on the device. 3. **Can Sleep** - Marks the device as sleep-capable (e.g. a battery-powered sensor that deep-sleeps between readings). When enabled, offline periods within the **Alert down after (sleep)** (`NTFPRCS_sleep_time`) global window are shown as **Sleeping** (aqua badge 🌙) instead of **Down**, and no down alert is fired during that window. Once the window expires the device falls back to normal down-alert logic. ⚠ Requires **Alert Down** to be enabled — sleeping suppresses the alert during the window only. 4. **Skip repeated notifications**, if for example you know there is a temporary issue and want to pause the same notification for this device for a given time. -5. **Require NICs Online** - Indicates whether this device should be considered online only if all associated NICs (devices with the `nic` relationship type) are online. If disabled, the device is considered online if any NIC is online. If a NIC is online it sets the parent (this) device's status to online irrespectivelly of the detected device's status. The Relationship type is set on the childern device. +5. **Require NICs Online** - Indicates whether this device should be considered online only if all associated NICs (child devices with the `nic` relationship type) are online. When disabled, a single online NIC is sufficient to mark the parent device as online, regardless of the parent's own detected status. The nic relationship type is configured on the child (NIC) device. > [!NOTE] > Please read through the [NTFPRCS plugin](https://github.com/netalertx/NetAlertX/blob/main/front/plugins/notification_processing/README.md) documentation to understand how device and global settings influence the notification processing. diff --git a/docs/PIHOLE_GUIDE.md b/docs/PIHOLE_GUIDE.md index 52d24fbb..f702ccae 100755 --- a/docs/PIHOLE_GUIDE.md +++ b/docs/PIHOLE_GUIDE.md @@ -1,66 +1,78 @@ -# Integration with PiHole +# Integration with Pi-hole -NetAlertX comes with 3 plugins suitable for integrating with your existing PiHole instance. The first plugin uses the v6 API, the second plugin is using a direct SQLite DB connection, the other leverages the `DHCP.leases` file generated by PiHole. You can combine multiple approaches and also supplement scans with other [plugins](/docs/PLUGINS.md). +NetAlertX includes three plugins for integrating with an existing Pi-hole installation. The first plugin imports devices through the Pi-hole v6 API, the second parses the `dhcp.leases` file generated by Pi-hole, and the third reads the Pi-hole SQLite database directly. You can use any of these approaches individually or combine them with each other and other [plugins](/docs/PLUGINS.md). -## Approach 1: `PIHOLEAPI` Plugin - Import devices directly from PiHole v6 API +## Approach 1: `PIHOLEAPI` Plugin - Import devices directly from the Pi-hole v6 API -![PIHOLEAPI sample settings](./img/PIHOLE_GUIDE/PIHOLEAPI_settings.png) - -To use this approach make sure the Web UI password in **Pi-hole** is set. - -| Setting | Description | Recommended value | -| :------------- | :------------- | :-------------| -| `PIHOLEAPI_URL` | Your Pi-hole base URL including port. | `http://192.168.1.82:9880/` | -| `PIHOLEAPI_RUN_SCHD` | If you run multiple device scanner plugins, align the schedules of all plugins to the same value. | `*/5 * * * *` | -| `PIHOLEAPI_PASSWORD` | The Web UI base64 encoded (en-/decoding handled by the app) admin password. | `passw0rd` | -| `PIHOLEAPI_SSL_VERIFY` | Whether to verify HTTPS certificates. Disable only for self-signed certificates. | `False` | -| `PIHOLEAPI_API_MAXCLIENTS` | Maximum number of devices to request from Pi-hole. Defaults are usually fine. | `500` | -| `PIHOLEAPI_FAKE_MAC` | Generate FAKE MAC from IP. | `False` | - -Check the [PiHole API plugin readme](https://github.com/netalertx/NetAlertX/tree/main/front/plugins/pihole_api_scan/) for details and troubleshooting. - -### docker-compose changes - -No changes needed - -## Approach 2: `DHCPLSS` Plugin - Import devices from the PiHole DHCP leases file - -![DHCPLSS sample settings](./img/PIHOLE_GUIDE/DHCPLSS_pihole_settings.png) +To use this approach, make sure a Web UI password is configured in **Pi-hole**. ### Settings -| Setting | Description | Recommended value | -| :------------- | :------------- | :-------------| -| `DHCPLSS_RUN` | When the plugin should run. | `schedule` | -| `DHCPLSS_RUN_SCHD` | If you run multiple device scanner plugins, align the schedules of all plugins to the same value. | `*/5 * * * *` | -| `DHCPLSS_paths_to_check` | You need to map the value in this setting in the `docker-compose.yml` file. The in-container path must contain `pihole` so it's parsed correctly. | `['/etc/pihole/dhcp.leases']` | +![PIHOLEAPI sample settings](./img/PIHOLE_GUIDE/PIHOLEAPI_settings.png) -Check the [DHCPLSS plugin readme](https://github.com/netalertx/NetAlertX/tree/main/front/plugins/dhcp_leases#overview) for details +| Setting | Description | Recommended value | +| :------------------------- | :----------------------------------------------------------------------------------------------- | :-------------------------- | +| `PIHOLEAPI_URL` | Your Pi-hole base URL, including the port. | `http://192.168.1.82:9880/` | +| `PIHOLEAPI_RUN_SCHD` | If you run multiple device scanner plugins, configure them to use the same schedule. | `*/5 * * * *` | +| `PIHOLEAPI_PASSWORD` | The Pi-hole Web UI admin password. NetAlertX automatically handles Base64 encoding and decoding. | `passw0rd` | +| `PIHOLEAPI_SSL_VERIFY` | Whether to verify HTTPS certificates. Disable only when using self-signed certificates. | `False` | +| `PIHOLEAPI_API_MAXCLIENTS` | Maximum number of devices to request from Pi-hole. The default value is usually sufficient. | `500` | +| `PIHOLEAPI_FAKE_MAC` | Generate a deterministic fake MAC address from the IP address. | `False` | + +Check the [PIHOLEAPI plugin README](https://github.com/netalertx/NetAlertX/tree/main/front/plugins/pihole_api_scan/) for additional details and troubleshooting. ### docker-compose changes -| Path | Description | -| :------------- | :------------- | -| `:/etc/pihole/dhcp.leases` | PiHole's `dhcp.leases` file. Required if you want to use PiHole `dhcp.leases` file. This has to be matched with a corresponding `DHCPLSS_paths_to_check` setting entry (the path in the container must contain `pihole`) | +No changes are required. +--- -## Approach 3: `PIHOLE` Plugin - Import devices directly from the PiHole database +## Approach 2: `DHCPLSS` Plugin - Import devices from the Pi-hole DHCP leases file -![DHCPLSS sample settings](./img/PIHOLE_GUIDE/PIHOLE_settings.png) +This approach requires mounting the Pi-hole DHCP leases file (`dhcp.leases`) into the NetAlertX container. This is straightforward when both applications run on the same host. If they run on different hosts, you'll need to synchronize the file or use the `PIHOLEAPI` plugin instead. -| Setting | Description | Recommended value | -| :------------- | :------------- | :-------------| -| `PIHOLE_RUN` | When the plugin should run. | `schedule` | -| `PIHOLE_RUN_SCHD` | If you run multiple device scanner plugins, align the schedules of all plugins to the same value. | `*/5 * * * *` | -| `PIHOLE_DB_PATH` | You need to map the value in this setting in the `docker-compose.yml` file. | `/etc/pihole/pihole-FTL.db` | +### Settings -Check the [PiHole plugin readme](https://github.com/netalertx/NetAlertX/tree/main/front/plugins/pihole_scan) for details +![DHCPLSS sample settings](./img/PIHOLE_GUIDE/DHCPLSS_pihole_settings.png) + +| Setting | Description | Recommended value | +| :----------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------- | :---------------------------- | +| `DHCPLSS_RUN` | When the plugin should run. | `schedule` | +| `DHCPLSS_RUN_SCHD` | If you run multiple device scanner plugins, configure them to use the same schedule. | `*/5 * * * *` | +| `DHCPLSS_paths_to_check` | Path to the mapped `dhcp.leases` file inside the container. The path must include `pihole` so the plugin can identify it as a Pi-hole leases file. | `['/etc/pihole/dhcp.leases']` | + +Check the [DHCPLSS plugin README](https://github.com/netalertx/NetAlertX/tree/main/front/plugins/dhcp_leases#overview) for additional details. ### docker-compose changes -| Path | Description | -| :------------- | :------------- | -| `:/etc/pihole/pihole-FTL.db` | PiHole's `pihole-FTL.db` database file. | +| Path | Description | +| :------------------------- | :--------------------------------------------------------------------------------------------- | +| `:/etc/pihole/dhcp.leases` | Mount Pi-hole's `dhcp.leases` file. This path must match an entry in `DHCPLSS_paths_to_check`. | +--- -Check out other [plugins](/docs/PLUGINS.md) that can help you discover more about your network or check how to scan [Remote networks](./REMOTE_NETWORKS.md). +## Approach 3: `PIHOLE` Plugin - Import devices directly from the Pi-hole database + +This approach requires mounting the Pi-hole database file into the NetAlertX container. This is straightforward when both applications run on the same host. If Pi-hole is running on a different host, you'll need to synchronize the database file into the NetAlertX container. In that scenario, the `PIHOLEAPI` or `DHCPLSS` plugins are usually simpler. + +### Settings + +![PIHOLE sample settings](./img/PIHOLE_GUIDE/PIHOLE_settings.png) + +| Setting | Description | Recommended value | +| :---------------- | :----------------------------------------------------------------------------------- | :-------------------------- | +| `PIHOLE_RUN` | When the plugin should run. | `schedule` | +| `PIHOLE_RUN_SCHD` | If you run multiple device scanner plugins, configure them to use the same schedule. | `*/5 * * * *` | +| `PIHOLE_DB_PATH` | Path to the mapped Pi-hole database file inside the container. | `/etc/pihole/pihole-FTL.db` | + +Check the [PIHOLE plugin README](https://github.com/netalertx/NetAlertX/tree/main/front/plugins/pihole_scan) for additional details. + +### docker-compose changes + +| Path | Description | +| :--------------------------- | :--------------------------------------------- | +| `:/etc/pihole/pihole-FTL.db` | Mount Pi-hole's `pihole-FTL.db` database file. | + +--- + +Explore other [plugins](/docs/PLUGINS.md) to discover additional information about your network, or learn how to scan [remote networks](./REMOTE_NETWORKS.md). diff --git a/docs/REST_IMPORT.md b/docs/REST_IMPORT.md index 0833fba9..dd1afe38 100755 --- a/docs/REST_IMPORT.md +++ b/docs/REST_IMPORT.md @@ -2,7 +2,8 @@ This guide shows you how to configure **OPNsense/Dnsmasq** in the **RSTIMPRT** plugin. - +> [!NOTE] +> See the [detailed documentation for the REST import plugin](https://github.com/netalertx/NetAlertX/tree/main/front/plugins/rest_import/) for additional details. ## 1. Create an OPNsense user 1. In OPNsense, navigate to **System** → **Access** → **Users** @@ -13,16 +14,12 @@ This guide shows you how to configure **OPNsense/Dnsmasq** in the **RSTIMPRT** p ![REST_IMPORT > OPNsense user](./img/REST_IMPORT/opnsense_user.png) - - ## 2. Create an OPNsense API key 1. On the OPNsense Users screen, click the **AP Key** button next to your new user ![REST_IMPORT > OPNsense API key](./img/REST_IMPORT/opnsense_user_api_key.png) 2. Click **Yes** when prompted to generate and download the new key. You'll receive a text file with a `key` and a `secret`. ![REST_IMPORT > API key confirmation](./img/REST_IMPORT/opnsense_user_api_key_confirm.png) - - ## 3. Configure the RSTIMPRT plugin 1. In NetAlertX, navigate to **Settings** → **Core** → **Loaded plugins** and add `RSTIMPRT` 2. Click **Save** diff --git a/docs/img/NOTIFICATIONS/Device-notification-settings.png b/docs/img/NOTIFICATIONS/Device-notification-settings.png index 6f32520d..dcfa7e1a 100755 Binary files a/docs/img/NOTIFICATIONS/Device-notification-settings.png and b/docs/img/NOTIFICATIONS/Device-notification-settings.png differ diff --git a/front/appEventsCore.php b/front/appEventsCore.php index 06ab52f7..f75b0775 100755 --- a/front/appEventsCore.php +++ b/front/appEventsCore.php @@ -185,7 +185,7 @@ $(document).ready(function () { }); function hideAppEventsSkeleton() { - $('#skel-app-events').fadeOut(50, function () { $(this).remove(); }); + $('#skel-app-events').fadeOut(0, function () { $(this).remove(); }); } window.addEventListener('load', function () { diff --git a/front/css/app.css b/front/css/app.css index 1af92acf..e16828de 100755 --- a/front/css/app.css +++ b/front/css/app.css @@ -2533,13 +2533,27 @@ textarea[readonly], } /* ----------------------------------------------------------------------------- - Sys info + InitCheck ----------------------------------------------------------------------------- */ #panInitCheck .row { width: 100%; } +#panInitCheck +{ + display: flow-root; +} + +.init-check-button +{ + margin: 0; + position: relative; + left: 50%; + -ms-transform: translate(-50%, 0%); + transform: translate(-50%, 0%); +} + /* ----------------------------------------------------------------------------- Sys info ----------------------------------------------------------------------------- */ @@ -2664,7 +2678,7 @@ table.dataTable tbody > tr.selected #settings-skeleton, #devices-skeleton, #device-details-skeleton, #events-skeleton, #presence-skeleton, #report-skeleton, #skel-app-events, #notifications-skeleton, #workflows-skeleton, #plugins-skeleton { z-index: 50; } -.skel-tab-pane { z-index: 10; min-height: 400px; background-color: var(--skel-panel-bg);} +.skel-tab-pane { margin: -10px; z-index: 10; min-height: 400px; background-color: var(--skel-panel-bg);} #settings-skeleton { margin: 15px; min-height: 500px; } #devices-skeleton { margin: 15px; top: 50px; min-height: 500px; } #skel-app-events { margin: 15px; top: 50px; min-height: 500px; z-index: inherit;} @@ -2675,7 +2689,7 @@ table.dataTable tbody > tr.selected #notifications-skeleton { margin: 15px; top: 50px; min-height: 400px; } #workflows-skeleton { top: 50px; width: 770px; margin: 0 auto; min-height: 300px; } #plugins-skeleton { top: 50px; padding: 0; min-height: 400px; } -#skel-tab-sessions, #skel-tab-events, #skel-tab-presence { margin: 0px; } +#skel-tab-sessions, #skel-tab-events, #skel-tab-presence {margin: -10px; padding: 20px;} /* Hide scrollbars */ #skel-tab-sessions, #skel-tab-events, #skel-tab-presence { @@ -2782,6 +2796,7 @@ table.dataTable tbody > tr.selected .skel-tabs-bar { display: flex; gap: 4px; padding: 8px 10px 0; border-radius: 4px 4px 0 0; border-bottom: none; } .skel-tab { height: 34px; width: 100px; border-radius: 4px 4px 0 0; flex-shrink: 0; } .skel-detail-form { border-top: none; border-radius: 0 0 4px 4px; padding: 20px 15px; } +.skel-detail-form-tab { border-top: none; border-radius: 0 0 4px 4px; padding: 20px 15px; margin: -10px; } .skel-form-row { gap: 15px; padding: 9px 0; } .skel-form-label { width: 18%; min-width: 100px; } .skel-form-input { height: 32px; } @@ -2805,6 +2820,7 @@ table.dataTable tbody > tr.selected /* ----- Systeminfo tabs -------------------------------------------------- */ .skel-info-tab { padding: 15px; min-height: 360px; } +.skel-info-tab { margin: -10px;} /* ===== /Loading Skeleton ===== */ diff --git a/front/deviceDetails.php b/front/deviceDetails.php index d8b19363..e6236527 100755 --- a/front/deviceDetails.php +++ b/front/deviceDetails.php @@ -130,7 +130,7 @@ require 'deviceDetailsEdit.php'; ?> -
+
@@ -140,13 +140,13 @@ require 'deviceDetailsTools.php'; ?>
-
+
-
+
close();
- -
-
-
- -
-
-
-
-
- -
-
-
-
-
- -
-
-
-
-
- -
-
-
-
-
- -
-
-
-
-
- -
-
-
-
-
- -
-
-
-
-
- -
-
-
-
+ +
+
+
+ +
+
+
+
+
+ +
+
+
+
+
+ +
+
+
+
+
+ +
+
+
+
+
+ +
+
+
+
+
+ +
+
+
+
+
+ +
+
+
+
+
+ +
+
+
+
@@ -878,10 +878,10 @@ window.onload = function asyncFooter() {