FE: skeleton uplift + docs

This commit is contained in:
jokob-sk
2026-06-29 11:23:32 +10:00
parent 214959f5a1
commit 20ac84078f
27 changed files with 291 additions and 253 deletions

View File

@@ -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).
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.

View File

@@ -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.

View File

@@ -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).

View File

@@ -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**

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 126 KiB

After

Width:  |  Height:  |  Size: 178 KiB

View File

@@ -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 () {

View File

@@ -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 ===== */

View File

@@ -130,7 +130,7 @@
require 'deviceDetailsEdit.php';
?>
</div>
<div class="tab-pane fade table-responsive" id="panSessions">
<div class="tab-pane fade" id="panSessions">
<?php
require 'deviceDetailsSessions.php';
?>
@@ -140,13 +140,13 @@
require 'deviceDetailsTools.php';
?>
</div>
<div class="tab-pane fade table-responsive" id="panPresence">
<div class="tab-pane fade" id="panPresence">
<?php
// Include the other page
include 'deviceDetailsPresence.php';
?>
</div>
<div class="tab-pane fade table-responsive" id="panEvents">
<div class="tab-pane fade " id="panEvents">
<?php
// Include the other page
include 'deviceDetailsEvents.php';
@@ -586,7 +586,7 @@ window.onload = function() {
// -----------------------------------------------------------------------------
function hideDeviceDetailsSkeleton() {
$('#device-details-skeleton').fadeOut(50, function() { $(this).remove(); });
$('#device-details-skeleton').fadeOut(0, function() { $(this).remove(); });
}
// Fallback: remove main skeleton and all tab pane skeletons if init stalls

View File

@@ -671,7 +671,7 @@ function toggleFieldLock(mac, fieldName) {
// -----------------------------------------------------------------------------
function hideDetailsTabSkeleton() {
$('#skel-tab-details').fadeOut(50, function() { $(this).hide(); });
$('#skel-tab-details').fadeOut(0, function() { $(this).hide(); });
}
function showDetailsTabSkeleton() {
var $skel = $('#skel-tab-details');

View File

@@ -38,6 +38,9 @@ function loadEventsData() {
return;
}
showEventsTabSkeleton();
showSpinner();
const hideConnections = $('#chkHideConnectionEvents')[0].checked;
let period = $("#period").val();
@@ -204,7 +207,7 @@ deviceEventsPageUpdater();
// -----------------------------------------------------------------------------
function hideEventsTabSkeleton() {
$('#skel-tab-events').fadeOut(50, function() { $(this).hide(); });
$('#skel-tab-events').fadeOut(0, function() { $(this).hide(); });
}
function showEventsTabSkeleton() {
var $skel = $('#skel-tab-events');

View File

@@ -213,7 +213,7 @@ devicePresencePageUpdater();
// -----------------------------------------------------------------------------
function hidePresenceTabSkeleton() {
$('#skel-tab-presence').fadeOut(50, function() { $(this).hide(); });
$('#skel-tab-presence').fadeOut(0, function() { $(this).hide(); });
}
function showPresenceTabSkeleton() {

View File

@@ -180,7 +180,7 @@ deviceSessionsPageUpdater();
// -----------------------------------------------------------------------------
function hideSessionsTabSkeleton() {
$('#skel-tab-sessions').fadeOut(50, function() { $(this).hide(); });
$('#skel-tab-sessions').fadeOut(0, function() { $(this).hide(); });
}
function showSessionsTabSkeleton() {

View File

@@ -729,7 +729,7 @@
function hideToolsTabSkeleton() {
$('#skel-tab-tools').fadeOut(50, function() { $(this).hide(); });
$('#skel-tab-tools').fadeOut(0, function() { $(this).hide(); });
}
function showToolsTabSkeleton() {

View File

@@ -185,7 +185,7 @@
// -----------------------------------------------------------------------------
function hideDevicesSkeleton() {
$('#devices-skeleton').fadeOut(50, function() { $(this).remove(); });
$('#devices-skeleton').fadeOut(0, function() { $(this).remove(); });
}
// Fallback: ensure skeleton is removed even if DataTable fails to initialize

View File

@@ -258,7 +258,7 @@ function getEvents(type) {
}
function hideEventsSkeleton() {
$('#events-skeleton').fadeOut(50, function () { $(this).remove(); });
$('#events-skeleton').fadeOut(0, function () { $(this).remove(); });
}
window.addEventListener('load', function () {

View File

@@ -145,57 +145,57 @@ $db->close();
</ul>
<div class="tab-content spinnerTarget">
<div class="tab-pane active" id="tab_DBTools">
<?php require 'php/templates/skel_tab_maint_dbtools.php'; ?>
<div class="db_info_table">
<div class="db_info_table_row">
<div class="db_tools_table_cell_a" >
<button type="button" class="btn btn-default pa-btn pa-btn-delete bg-red dbtools-button" id="btnDeleteMAC" onclick="askDeleteDevicesWithEmptyMACs()"><?= lang('Maintenance_Tool_del_empty_macs');?></button>
</div>
<div class="db_tools_table_cell_b"><?= lang('Maintenance_Tool_del_empty_macs_text');?></div>
</div>
<div class="db_info_table_row">
<div class="db_tools_table_cell_a" >
<button type="button" class="btn btn-default pa-btn pa-btn-delete bg-red dbtools-button" id="btnDeleteMAC" onclick="askDeleteAllDevices()"><?= lang('Maintenance_Tool_del_alldev');?></button>
</div>
<div class="db_tools_table_cell_b"><?= lang('Maintenance_Tool_del_alldev_text');?></div>
</div>
<div class="db_info_table_row">
<div class="db_tools_table_cell_a" >
<button type="button" class="btn btn-default pa-btn pa-btn-delete bg-red dbtools-button" id="btnDeleteUnknown" onclick="askDeleteUnknown()"><?= lang('Maintenance_Tool_del_unknowndev');?></button>
</div>
<div class="db_tools_table_cell_b"><?= lang('Maintenance_Tool_del_unknowndev_text');?></div>
</div>
<div class="db_info_table_row">
<div class="db_tools_table_cell_a" >
<button type="button" class="btn btn-default pa-btn pa-btn-delete bg-red dbtools-button" id="btnDeleteEvents" onclick="askDeleteEvents()"><?= lang('Maintenance_Tool_del_allevents');?></button>
</div>
<div class="db_tools_table_cell_b"><?= lang('Maintenance_Tool_del_allevents_text');?></div>
</div>
<div class="db_info_table_row">
<div class="db_tools_table_cell_a" >
<button type="button" class="btn btn-default pa-btn pa-btn-delete bg-red dbtools-button" id="btnDeleteEvents30" onclick="askDeleteEvents30()"><?= lang('Maintenance_Tool_del_allevents30');?></button>
</div>
<div class="db_tools_table_cell_b"><?= lang('Maintenance_Tool_del_allevents30_text');?></div>
</div>
<div class="db_info_table_row">
<div class="db_tools_table_cell_a" >
<button type="button" class="btn btn-default pa-btn pa-btn-delete bg-red dbtools-button" id="btnUnlockFields" onclick="askUnlockFields()"><?= lang('Maintenance_Tool_UnlockFields');?></button>
</div>
<div class="db_tools_table_cell_b"><?= lang('Maintenance_Tool_UnlockFields_text');?></div>
</div>
<div class="db_info_table_row">
<div class="db_tools_table_cell_a" >
<button type="button" class="btn btn-default pa-btn pa-btn-delete bg-red dbtools-button" id="btnDeleteActHistory" onclick="askDeleteActHistory()"><?= lang('Maintenance_Tool_del_ActHistory');?></button>
</div>
<div class="db_tools_table_cell_b"><?= lang('Maintenance_Tool_del_ActHistory_text');?></div>
</div>
<div class="db_info_table_row">
<div class="db_tools_table_cell_a" >
<button type="button" class="btn btn-default pa-btn pa-btn-delete bg-red dbtools-button" id="btnRestartServer" onclick="askRestartBackend()"><?= lang('Maint_RestartServer');?></button>
</div>
<div class="db_tools_table_cell_b"><?= lang('Maint_Restart_Server_noti_text');?></div>
</div>
</div>
<?php require 'php/templates/skel_tab_maint_dbtools.php'; ?>
<div class="db_info_table">
<div class="db_info_table_row">
<div class="db_tools_table_cell_a" >
<button type="button" class="btn btn-default pa-btn pa-btn-delete bg-red dbtools-button" id="btnDeleteMAC" onclick="askDeleteDevicesWithEmptyMACs()"><?= lang('Maintenance_Tool_del_empty_macs');?></button>
</div>
<div class="db_tools_table_cell_b"><?= lang('Maintenance_Tool_del_empty_macs_text');?></div>
</div>
<div class="db_info_table_row">
<div class="db_tools_table_cell_a" >
<button type="button" class="btn btn-default pa-btn pa-btn-delete bg-red dbtools-button" id="btnDeleteMAC" onclick="askDeleteAllDevices()"><?= lang('Maintenance_Tool_del_alldev');?></button>
</div>
<div class="db_tools_table_cell_b"><?= lang('Maintenance_Tool_del_alldev_text');?></div>
</div>
<div class="db_info_table_row">
<div class="db_tools_table_cell_a" >
<button type="button" class="btn btn-default pa-btn pa-btn-delete bg-red dbtools-button" id="btnDeleteUnknown" onclick="askDeleteUnknown()"><?= lang('Maintenance_Tool_del_unknowndev');?></button>
</div>
<div class="db_tools_table_cell_b"><?= lang('Maintenance_Tool_del_unknowndev_text');?></div>
</div>
<div class="db_info_table_row">
<div class="db_tools_table_cell_a" >
<button type="button" class="btn btn-default pa-btn pa-btn-delete bg-red dbtools-button" id="btnDeleteEvents" onclick="askDeleteEvents()"><?= lang('Maintenance_Tool_del_allevents');?></button>
</div>
<div class="db_tools_table_cell_b"><?= lang('Maintenance_Tool_del_allevents_text');?></div>
</div>
<div class="db_info_table_row">
<div class="db_tools_table_cell_a" >
<button type="button" class="btn btn-default pa-btn pa-btn-delete bg-red dbtools-button" id="btnDeleteEvents30" onclick="askDeleteEvents30()"><?= lang('Maintenance_Tool_del_allevents30');?></button>
</div>
<div class="db_tools_table_cell_b"><?= lang('Maintenance_Tool_del_allevents30_text');?></div>
</div>
<div class="db_info_table_row">
<div class="db_tools_table_cell_a" >
<button type="button" class="btn btn-default pa-btn pa-btn-delete bg-red dbtools-button" id="btnUnlockFields" onclick="askUnlockFields()"><?= lang('Maintenance_Tool_UnlockFields');?></button>
</div>
<div class="db_tools_table_cell_b"><?= lang('Maintenance_Tool_UnlockFields_text');?></div>
</div>
<div class="db_info_table_row">
<div class="db_tools_table_cell_a" >
<button type="button" class="btn btn-default pa-btn pa-btn-delete bg-red dbtools-button" id="btnDeleteActHistory" onclick="askDeleteActHistory()"><?= lang('Maintenance_Tool_del_ActHistory');?></button>
</div>
<div class="db_tools_table_cell_b"><?= lang('Maintenance_Tool_del_ActHistory_text');?></div>
</div>
<div class="db_info_table_row">
<div class="db_tools_table_cell_a" >
<button type="button" class="btn btn-default pa-btn pa-btn-delete bg-red dbtools-button" id="btnRestartServer" onclick="askRestartBackend()"><?= lang('Maint_RestartServer');?></button>
</div>
<div class="db_tools_table_cell_b"><?= lang('Maint_Restart_Server_noti_text');?></div>
</div>
</div>
</div>
<!-- ---------------------------Backup restore -------------------------------------------- -->
@@ -878,10 +878,10 @@ window.onload = function asyncFooter() {
</script>
<script>
function hideMaintDBToolsSkeleton() { $('#skel-tab-maint-dbtools').fadeOut(50, function() { $(this).remove(); }); }
function hideMaintBackupSkeleton() { $('#skel-tab-maint-backup').fadeOut(50, function() { $(this).remove(); }); }
function hideMaintLoggingSkeleton() { $('#skel-tab-maint-logging').fadeOut(50, function() { $(this).remove(); }); }
function hideMaintMultiEditSkeleton() { $('#skel-tab-maint-multiedit').fadeOut(50, function() { $(this).remove(); }); }
function hideMaintDBToolsSkeleton() { $('#skel-tab-maint-dbtools').fadeOut(0, function() { $(this).remove(); }); }
function hideMaintBackupSkeleton() { $('#skel-tab-maint-backup').fadeOut(0, function() { $(this).remove(); }); }
function hideMaintLoggingSkeleton() { $('#skel-tab-maint-logging').fadeOut(0, function() { $(this).remove(); }); }
function hideMaintMultiEditSkeleton() { $('#skel-tab-maint-multiedit').fadeOut(0, function() { $(this).remove(); }); }
// Static tabs: content is PHP-rendered — dismiss immediately, no waiting for onload
hideMaintDBToolsSkeleton();

View File

@@ -1,6 +1,7 @@
<!-- Details Tab Skeleton ================================================== -->
<div id="skel-tab-details" class="skel-tab-pane spinnerTarget">
<div class="skel-detail-form col-lg-12 col-sm-12 col-xs-12">
<!-- <div class="skel-detail-form col-lg-12 col-sm-12 col-xs-12"> -->
<div class="skel-detail-form-tab clearfix">
<div class="col-lg-4 col-sm-6 col-xs-12">
<div class="skel-form-row">
<span class="skel-form-label skel-shimmer"></span>

View File

@@ -14,7 +14,7 @@
</div>
<!-- Right content area -->
<div class="skel-plugins-body col-sm-10">
<div class="skel-plugins-body nav-tabs-custom col-sm-10">
<!-- Sub-tab bar -->
<div class="skel-tabs-bar" style="border-radius: 0 4px 0 0; margin-bottom: 0;">
<span class="skel-tab skel-shimmer"></span>
@@ -22,7 +22,7 @@
<span class="skel-tab skel-shimmer"></span>
</div>
<!-- Data table -->
<div class="skel-table-box" style="border-top: none; border-radius: 0 0 4px 4px;">
<div class="skel-table-box tab-content" style="border-top: none; border-radius: 0 0 4px 4px;">
<div class="skel-table-header-row">
<?php for ($j = 0; $j < 5; $j++): ?>
<span class="skel-th skel-shimmer"></span>
@@ -36,10 +36,10 @@
</div>
<?php endfor; ?>
</div>
<div class="skel-form-footer col-sm-12 padding-5px">
<span class="skel-form-btn skel-shimmer"></span>
<span class="skel-form-btn skel-shimmer"></span>
</div>
</div>
</div>
<div class="skel-form-footer col-sm-12 padding-5px">
<span class="skel-form-btn skel-shimmer"></span>
<span class="skel-form-btn skel-shimmer"></span>
</div>
</div>
</div>

View File

@@ -6,7 +6,6 @@
<!-- Page ------------------------------------------------------------------ -->
<div class="content-wrapper integrations-plugins" id="pluginsPage">
<?php require 'php/templates/skel_plugins.php'; ?>
<?php
require 'pluginsCore.php';
?>

View File

@@ -8,6 +8,7 @@
?>
<!-- Main content ---------------------------------------------------------- -->
<?php require 'php/templates/skel_plugins.php'; ?>
<section class="content">
<div class="plugin-filters hidden" >
<div class="input-group col-sm-12">
@@ -667,7 +668,7 @@ function initializeDataTables(prefix, colDefinitions, pluginObj) {
// Fade out the skeleton only after the first draw so there is no gap
// between the skeleton disappearing and the table rows appearing.
initComplete: function() {
$(skelId).fadeOut(50, function() { $(this).hide(); });
$(skelId).fadeOut(0, function() { $(this).hide(); });
},
createdRow: function(row, data) {
$(row).attr('data-my-index', data.index);
@@ -877,7 +878,12 @@ else
}
function hidePluginsSkeleton() {
$('#plugins-skeleton').fadeOut(50, function() { $(this).remove(); });
$('#plugins-skeleton').fadeOut(0, function() { $(this).hide(); });
}
function showPluginsSkeleton() {
var $skel = $('#plugins-skeleton');
$skel.stop(true, true).fadeIn();
}
window.addEventListener('load', function() {

View File

@@ -511,7 +511,7 @@ function getDevicesPresence (status) {
function hidePresenceSkeleton() {
hideSpinner();
$('#presence-skeleton').fadeOut(50, function() { $(this).remove(); });
$('#presence-skeleton').fadeOut(0, function() { $(this).remove(); });
}
window.addEventListener('load', function() {

View File

@@ -186,7 +186,7 @@
<!-- /.content -->
<script>
function hideReportSkeleton() {
$('#report-skeleton').fadeOut(50, function() { $(this).remove(); });
$('#report-skeleton').fadeOut(0, function() { $(this).remove(); });
}
window.addEventListener('load', function() {
setTimeout(hideReportSkeleton, 15000);

View File

@@ -74,10 +74,10 @@
<div class="tab-pane fade" data-php-file="systeminfoNetwork.php" id="panNetwork">
<?php require 'php/templates/skel_tab_sysinfo_network.php'; ?>
</div>
<div class="tab-pane fade table-responsive" data-php-file="systeminfoStorage.php" id="panStorage">
<div class="tab-pane fade" data-php-file="systeminfoStorage.php" id="panStorage">
<?php require 'php/templates/skel_tab_sysinfo_storage.php'; ?>
</div>
<div class="tab-pane fade table-responsive" data-php-file="systeminfoInitCheck.php" id="panInitCheck">
<div class="tab-pane fade" data-php-file="systeminfoInitCheck.php" id="panInitCheck">
<?php require 'php/templates/skel_tab_sysinfo_initcheck.php'; ?>
</div>
</div>

View File

@@ -7,32 +7,32 @@
require_once $_SERVER['DOCUMENT_ROOT'] . '/php/templates/globals.php';
?>
<div class="col-md-12">
<div class="py-5">
<div class="mt-4 text-center" id="check-status-plc" >
<div class="col-12 col-lg-12 col-sm-12 col-xs-12">
<div class="col-12 col-lg-12 col-sm-12 col-xs-12 text-center" id="check-status-plc" >
<div class="alert alert-warning">
<i class="fa-solid fa-spinner fa-spin text-secondary"></i> <?= lang('Maintenance_InitCheck_Checking');?>
</div>
</div>
<div class="mt-4 text-center" id="check-status" style="display: none;">
<div class="col-12 col-lg-12 col-sm-12 col-xs-12 text-center" id="check-status" style="display: none;">
<div class="alert alert-success">
<i class="fa-solid fa-check text-success"></i> <?= lang('Maintenance_InitCheck_Success');?>
</div>
</div>
<div class="col-12">
<div class="col-12 col-lg-12 col-sm-12 col-xs-12">
<div class="d-flex flex-wrap gap-2 w-100" id="file-check-list"></div>
</div>
<div class="col-12">
<div class="text-center box box-secondary col-md-6">
<div class="col-12 col-lg-12 col-sm-12 col-xs-12">
<div class="text-center">
<p class="text-muted"><?= lang('Maintenance_InitCheck_QuickSetupGuide');?></p>
</div>
</div>
<div class="col-12">
<div class="col-md-12 center text-center" >
<button type="button" class=" col-md-12 btn btn-default bg-green " onclick="retryCheck()"><?= lang('Maintenance_ReCheck');?></button>
</div>
<div class="col-12 col-lg-12 col-sm-12 col-xs-12 init-check-button">
<div class="col-12 col-lg-12 col-sm-12 col-xs-12 " >
<button type="button" class="col-12 col-lg-12 col-sm-12 col-xs-12 btn btn-default bg-green " onclick="retryCheck()"><?= lang('Maintenance_ReCheck');?></button>
</div>
</div>
</div>
</div>
<script>

View File

@@ -218,7 +218,7 @@ require 'php/templates/header.php';
});
function hideNotificationsSkeleton() {
$('#notifications-skeleton').fadeOut(50, function () { $(this).remove(); });
$('#notifications-skeleton').fadeOut(0, function () { $(this).remove(); });
}
window.addEventListener('load', function () {

View File

@@ -1379,7 +1379,7 @@ $(document).ready(function () {
function hideWorkflowsSkeleton() {
hideSpinner();
$('#workflows-skeleton').fadeOut(50, function() { $(this).remove(); });
$('#workflows-skeleton').fadeOut(0, function() { $(this).remove(); });
}
window.addEventListener('load', function() {

View File

@@ -5,21 +5,20 @@ edit_uri: blob/main/docs/
docs_dir: docs
use_directory_urls: true
site_description: >-
The main documentation resource for NetAlertX - a network scanner and presence detector
The main documentation resource for NetAlertX - Network visibility & Asset intelligence application
# static_dir: docs/img
nav:
- Home: index.md
- Installation:
- Installation options: INSTALLATION.md
- Quick setup: INITIAL_SETUP.md
- Docker:
- Docker Guide: DOCKER_INSTALLATION.md
- Docker guide: DOCKER_INSTALLATION.md
- Docker Compose: DOCKER_COMPOSE.md
- Docker File Permissions: FILE_PERMISSIONS.md
- Docker Updates: UPDATES.md
- Docker Maintenance: DOCKER_MAINTENANCE.md
- Docker Startup Troubleshooting:
- Docker file permissions: FILE_PERMISSIONS.md
- Docker updates: UPDATES.md
- Docker maintenance: DOCKER_MAINTENANCE.md
- Docker startup troubleshooting:
- ARP flux sysctls: docker-troubleshooting/arp-flux-sysctls.md
- Aufs capabilities: docker-troubleshooting/aufs-capabilities.md
- Excessive capabilities: docker-troubleshooting/excessive-capabilities.md
@@ -33,11 +32,11 @@ nav:
- Read only: docker-troubleshooting/read-only-filesystem.md
- Running as root: docker-troubleshooting/running-as-root.md
- Other:
- Synology Guide: SYNOLOGY_GUIDE.md
- Synology guide: SYNOLOGY_GUIDE.md
- Portainer Stacks: DOCKER_PORTAINER.md
- Community Guides: COMMUNITY_GUIDES.md
- Community guides: COMMUNITY_GUIDES.md
- Bare-metal (Experimental): HW_INSTALL.md
- Migration Guide: MIGRATION.md
- Migration guide: MIGRATION.md
- Help:
- Common issues: COMMON_ISSUES.md
- Setup:
@@ -45,20 +44,20 @@ nav:
- Subnets: SUBNETS.md
- Enable Plugins: PLUGINS.md
- Backups: BACKUPS.md
- Security Features: SECURITY_FEATURES.md
- Security Considerations: SECURITY.md
- Security features: SECURITY_FEATURES.md
- Security considerations: SECURITY.md
- Advanced guides:
- Remote Networks: REMOTE_NETWORKS.md
- Notifications Guide: NOTIFICATIONS.md
- Notification Text Templates: NOTIFICATION_TEMPLATES.md
- Remote networks: REMOTE_NETWORKS.md
- Notifications guide: NOTIFICATIONS.md
- Notification text templates: NOTIFICATION_TEMPLATES.md
- Custom PUID/GUID: PUID_PGID_SECURITY.md
- Name Resolution: NAME_RESOLUTION.md
- Authelia: AUTHELIA.md
- Performance: PERFORMANCE.md
- Name resolution: NAME_RESOLUTION.md
- Authelia guide: AUTHELIA.md
- Performance guide: PERFORMANCE.md
- Reverse DNS: REVERSE_DNS.md
- Reverse Proxy: REVERSE_PROXY.md
- Reverse proxy: REVERSE_PROXY.md
- Workflows: WORKFLOWS.md
- Workflow Examples: WORKFLOW_EXAMPLES.md
- Workflow examples: WORKFLOW_EXAMPLES.md
- Docker Swarm: DOCKER_SWARM.md
- Best practice guides:
- NOC / Eyes-on-glass dashboard: ADVISORY_EYES_ON_GLASS.md
@@ -67,67 +66,67 @@ nav:
- Help:
- Common issues: COMMON_ISSUES.md
- Random MAC: RANDOM_MAC.md
- Incorrect Offline Detection: FIX_OFFLINE_DETECTION.md
- Incorrect offline detection: FIX_OFFLINE_DETECTION.md
- Device guides:
- Editing Devices:
- Editing devices:
- Management: DEVICE_MANAGEMENT.md
- Bulk Editing: DEVICES_BULK_EDITING.md
- Custom Properties: CUSTOM_PROPERTIES.md
- Device Display Settings: DEVICE_DISPLAY_SETTINGS.md
- Device Views Filtering: DEVICE_FILTERS.md
- Session Info: SESSION_INFO.md
- Bulk editing: DEVICES_BULK_EDITING.md
- Custom properties: CUSTOM_PROPERTIES.md
- Device display settings: DEVICE_DISPLAY_SETTINGS.md
- Device views filtering: DEVICE_FILTERS.md
- Session info: SESSION_INFO.md
- Field Lock/Unlock: DEVICE_FIELD_LOCK.md
- Device Source Fields: DEVICE_SOURCE_FIELDS.md
- Icons and Topology:
- Device source fields: DEVICE_SOURCE_FIELDS.md
- Icons and network topology:
- Icons: ICONS.md
- Network Topology: NETWORK_TREE.md
- Network topology: NETWORK_TREE.md
- Other guides:
- Pi-hole Guide: PIHOLE_GUIDE.md
- Pi-hole guide: PIHOLE_GUIDE.md
- Home Assistant: HOME_ASSISTANT.md
- Emails: SMTP.md
- Common email services: SMTP.md
- Rest import: REST_IMPORT.md
- Webhooks (n8n): WEBHOOK_N8N.md
- Troubleshooting:
- General Tips: DEBUG_TIPS.md
- Common Issues: COMMON_ISSUES.md
- Inspecting Logs: LOGGING.md
- API Server Issues: DEBUG_API_SERVER.md
- Invalid JSON Issues: DEBUG_INVALID_JSON.md
- PHP Issues: DEBUG_PHP.md
- Plugin Issues: DEBUG_PLUGINS.md
- Web UI Port Issues: WEB_UI_PORT_DEBUG.md
- Workflows Issues: WORKFLOWS_DEBUGGING.md
- General tips: DEBUG_TIPS.md
- Common issues: COMMON_ISSUES.md
- Inspecting logs: LOGGING.md
- API server issues: DEBUG_API_SERVER.md
- Invalid JSON issues: DEBUG_INVALID_JSON.md
- PHP backend issues: DEBUG_PHP.md
- Plugin issues: DEBUG_PLUGINS.md
- Web UI port issues: WEB_UI_PORT_DEBUG.md
- Workflows issues: WORKFLOWS_DEBUGGING.md
- Development:
- Plugin and app development:
- Environment Setup: DEV_ENV_SETUP.md
- Environment setup: DEV_ENV_SETUP.md
- Builds: BUILDS.md
- Devcontainer: DEV_DEVCONTAINER.md
- Devcontainer Ports: DEV_PORTS_HOST_MODE.md
- Custom Plugins:
- Devcontainer ports: DEV_PORTS_HOST_MODE.md
- Custom plugins:
- Overview: PLUGINS_DEV.md
- Quick Start: PLUGINS_DEV_QUICK_START.md
- Data Contract: PLUGINS_DEV_DATA_CONTRACT.md
- Settings System: PLUGINS_DEV_SETTINGS.md
- Data Sources: PLUGINS_DEV_DATASOURCES.md
- UI Components: PLUGINS_DEV_UI_COMPONENTS.md
- Config Lifecycle: PLUGINS_DEV_CONFIG.md
- Frontend Development: FRONTEND_DEVELOPMENT.md
- Quick start: PLUGINS_DEV_QUICK_START.md
- Data contract: PLUGINS_DEV_DATA_CONTRACT.md
- Settings system: PLUGINS_DEV_SETTINGS.md
- Data sources: PLUGINS_DEV_DATASOURCES.md
- UI components: PLUGINS_DEV_UI_COMPONENTS.md
- Config lifecycle: PLUGINS_DEV_CONFIG.md
- Frontend development: FRONTEND_DEVELOPMENT.md
- Database: DATABASE.md
- Settings: SETTINGS_SYSTEM.md
- Versions: VERSIONS.md
- Icon and Type guessing: DEVICE_HEURISTICS.md
- Icon and type guessing: DEVICE_HEURISTICS.md
- API:
- Overview: API.md
- Devices Collection: API_DEVICES.md
- Devices collection: API_DEVICES.md
- Device: API_DEVICE.md
- Device Field Lock: API_DEVICE_FIELD_LOCK.md
- Device field Lock: API_DEVICE_FIELD_LOCK.md
- Sessions: API_SESSIONS.md
- Settings: API_SETTINGS.md
- Events: API_EVENTS.md
- Messaging in-app: API_MESSAGING_IN_APP.md
- Metrics: API_METRICS.md
- Net Tools: API_NETTOOLS.md
- Online History: API_ONLINEHISTORY.md
- Net tools: API_NETTOOLS.md
- Online history: API_ONLINEHISTORY.md
- Sync: API_SYNC.md
- Logs: API_LOGS.md
- SSE: API_SSE.md
@@ -137,7 +136,7 @@ nav:
- Tests: API_TESTS.md
- SUPERSEDED OLD API Overview: API_OLD.md
- Integrations:
- Webhook Secret: WEBHOOK_SECRET.md
- Webhook secret: WEBHOOK_SECRET.md
- Helper scripts: HELPER_SCRIPTS.md