diff --git a/docs/API.md b/docs/API.md index 8c9c3767..3ad69a96 100755 --- a/docs/API.md +++ b/docs/API.md @@ -1,4 +1,4 @@ -# NetAlertX API Documentation +# API Documentation This API provides programmatic access to **devices, events, sessions, metrics, network tools, and sync** in NetAlertX. It is implemented as a **REST and GraphQL server**. All requests require authentication via **API Token** (`API_TOKEN` setting) unless explicitly noted. For example, to authorize a GraphQL request, you need to use a `Authorization: Bearer API_TOKEN` header as per example below: diff --git a/docs/DEVICE_MANAGEMENT.md b/docs/DEVICE_MANAGEMENT.md index dc95ee7e..f106da24 100755 --- a/docs/DEVICE_MANAGEMENT.md +++ b/docs/DEVICE_MANAGEMENT.md @@ -1,8 +1,8 @@ -# NetAlertX - Device Management +# Device Management The Main Info section is where most of the device identifiable information is stored and edited. Some of the information is autodetected via various plugins. Initial values for most of the fields can be specified in the `NEWDEV` plugin. -> [!NOTE] +> [!NOTE] > > You can multi-edit devices by selecting them in the main Devices view, from the Mainetence section, or via the CSV Export functionality under Maintenance. More info can be found in the [Devices Bulk-editing docs](./DEVICES_BULK_EDITING.md). @@ -14,23 +14,23 @@ The Main Info section is where most of the device identifiable information is st - **MAC**: MAC addres of the device. Not editable, unless creating a new dummy device. - **Last IP**: IP addres of the device. Not editable, unless creating a new dummy device. - **Name**: Friendly device name. Autodetected via various 🆎 Name discovery [plugins](https://github.com/jokob-sk/NetAlertX/blob/main/docs/PLUGINS.md). The app attaches `(IP match)` if the name is discovered via an IP match and not MAC match which could mean the name could be incorrect as IPs might change. - - **Icon**: Partially autodetected. Select an existing or [add a custom icon](./ICONS.md). You can also auto-apply the same icon on all devices of the same type. + - **Icon**: Partially autodetected. Select an existing or [add a custom icon](./ICONS.md). You can also auto-apply the same icon on all devices of the same type. - **Owner**: Device owner (The list is self-populated with existing owners and you can add custom values). - **Type**: Select a device type from the dropdown list (`Smartphone`, `Tablet`, - `Laptop`, `TV`, `router`, etc.) or add a new device type. If you want the device to act as a **Network device** (and be able to be a network node in the Network view), select a type under Network Devices or add a new Network Device type in Settings. More information can be found in the [Network Setup docs](./NETWORK_TREE.md). + `Laptop`, `TV`, `router`, etc.) or add a new device type. If you want the device to act as a **Network device** (and be able to be a network node in the Network view), select a type under Network Devices or add a new Network Device type in Settings. More information can be found in the [Network Setup docs](./NETWORK_TREE.md). - **Vendor**: The manufacturing vendor. Automatically updated by NetAlertX when empty or unknown, can be edited. - **Group**: Select a group (`Always on`, `Personal`, `Friends`, etc.) or type your own Group name. - - **Location**: Select the location, usually a room, where the device is located (`Kitchen`, `Attic`, `Living room`, etc.) or add a custom Location. + - **Location**: Select the location, usually a room, where the device is located (`Kitchen`, `Attic`, `Living room`, etc.) or add a custom Location. - **Comments**: Add any comments for the device, such as a serial number, or maintenance information. -> [!NOTE] +> [!NOTE] > -> Please note the above usage of the fields are only suggestions. You can use most of these fields for other purposes, such as storing the network interface, company owning a device, or similar. +> Please note the above usage of the fields are only suggestions. You can use most of these fields for other purposes, such as storing the network interface, company owning a device, or similar. ## Dummy devices -You can create dummy devices from the Devices listing screen. +You can create dummy devices from the Devices listing screen.  @@ -39,12 +39,12 @@ The **MAC** field and the **Last IP** field will then become editable.  -> [!NOTE] +> [!NOTE] > > You can couple this with the `ICMP` plugin which can be used to monitor the status of these devices, if they are actual devices reachable with the `ping` command. If not, you can use a loopback IP address so they appear online, such as `0.0.0.0` or `127.0.0.1`. -## Copying data from an existing device. +## Copying data from an existing device. -To speed up device population you can also copy data from an existing device. This can be done from the **Tools** tab on the Device details. +To speed up device population you can also copy data from an existing device. This can be done from the **Tools** tab on the Device details. diff --git a/docs/HELPER_SCRIPTS.md b/docs/HELPER_SCRIPTS.md index 628ea19b..fa4ea6b3 100755 --- a/docs/HELPER_SCRIPTS.md +++ b/docs/HELPER_SCRIPTS.md @@ -1,4 +1,4 @@ -# NetAlertX Community Helper Scripts Overview +# Community Helper Scripts Overview This page provides an overview of community-contributed scripts for NetAlertX. These scripts are not actively maintained and are provided as-is. @@ -14,8 +14,8 @@ You can find all scripts in this [scripts GitHub folder](https://github.com/joko ## Important Notes -> [!NOTE] -> These scripts are community-supplied and not actively maintained. Use at your own discretion. +> [!NOTE] +> These scripts are community-supplied and not actively maintained. Use at your own discretion. For detailed usage instructions, refer to each script's documentation in each [scripts GitHub folder](https://github.com/jokob-sk/NetAlertX/tree/main/scripts). diff --git a/docs/HW_INSTALL.md b/docs/HW_INSTALL.md index 814230da..e34535cf 100755 --- a/docs/HW_INSTALL.md +++ b/docs/HW_INSTALL.md @@ -5,7 +5,7 @@ To download and install NetAlertX on the hardware/server directly use the `curl` > [!NOTE] > This is an Experimental feature 🧪 and it relies on community support. > -> 🙏 Looking for maintainers for this installation method 🙂 Current community volunteers: +> 🙏 Looking for maintainers for this installation method 🙂 Current community volunteers: > - [slammingprogramming](https://github.com/slammingprogramming) > - [ingoratsdorf](https://github.com/ingoratsdorf) > @@ -13,8 +13,7 @@ To download and install NetAlertX on the hardware/server directly use the `curl` > Data loss is a possibility, **it is recommended to install NetAlertX using the supplied Docker image**. > [!WARNING] -> A warning to the installation method below: Piping to bash is [controversial](https://pi-hole.net/2016/07/25/curling-and-piping-to-bash) and may -be dangerous, as you cannot see the code that's about to be executed on your system. +> A warning to the installation method below: Piping to bash is [controversial](https://pi-hole.net/2016/07/25/curling-and-piping-to-bash) and may be dangerous, as you cannot see the code that's about to be executed on your system. If you trust this repo, you can download the install script via one of the methods (curl/wget) below and it will fo its best to install NetAlertX on your system. @@ -40,7 +39,7 @@ Some facts about what and where something will be changed/installed by the HW in - Only tested to work on the system listed in the install directory. - **EXPERIMENTAL** and not recommended way to install NetAlertX. -> [!TIP] +> [!TIP] > If the below fails try grabbing and installing one of the [previous releases](https://github.com/jokob-sk/NetAlertX/releases) and run the installation from the zip package. These commands will download the `install.debian12.sh` script from the GitHub repository, make it executable with `chmod`, and then run it using `./install.debian12.sh`. @@ -81,7 +80,7 @@ wget https://raw.githubusercontent.com/jokob-sk/NetAlertX/main/install/ubuntu24/ > [!NOTE] > Use this on a clean LXC/VM for Debian 13 OR Ubuntu 24. -> The Scipt will detect OS and build acordingly. +> The Scipt will detect OS and build acordingly. > Maintained by [JVKeller](https://github.com/JVKeller) ### Installation via wget diff --git a/docs/MIGRATION.md b/docs/MIGRATION.md index fb112405..d1d08e1b 100755 --- a/docs/MIGRATION.md +++ b/docs/MIGRATION.md @@ -218,7 +218,7 @@ services: ### 1.3 Migration from NetAlertX `v25.10.1` -Starting from v25.10.1, the container uses a [more secure, read-only runtime environment](./SECURITY_FEATURES.md), which requires all writable paths (e.g., logs, API cache, temporary data) to be mounted as `tmpfs` or permanent writable volumes, with sufficient access [permissions](./FILE_PERMISSIONS.md). +Starting from v25.10.1, the container uses a [more secure, read-only runtime environment](./SECURITY_FEATURES.md), which requires all writable paths (e.g., logs, API cache, temporary data) to be mounted as `tmpfs` or permanent writable volumes, with sufficient access [permissions](./FILE_PERMISSIONS.md). The data location has also hanged from `/app/db` and `/app/config` to `/data/db` and `/data/config`. See detailed steps below. #### STEPS: @@ -234,8 +234,8 @@ services: network_mode: "host" restart: unless-stopped volumes: - - /local_data_dir/config:/data/config - - /local_data_dir/db:/data/db + - /local_data_dir/config:/app/config + - /local_data_dir/db:/app/db # (optional) useful for debugging if you have issues setting up the container - /local_data_dir/logs:/tmp/log environment: @@ -284,10 +284,8 @@ services: - NET_BIND_SERVICE # 🆕 New line restart: unless-stopped volumes: - - /local_data_dir/config:/data/config - - /local_data_dir/db:/data/db - # (optional) useful for debugging if you have issues setting up the container - #- /local_data_dir/logs:/tmp/log + - /local_data_dir/config:/data/config # 🆕 This has changed from /app to /data + - /local_data_dir/db:/data/db # 🆕 This has changed from /app to /data # Ensuring the timezone is the same as on the server - make sure also the TIMEZONE setting is configured - /etc/localtime:/etc/localtime:ro # 🆕 New line environment: diff --git a/docs/SESSION_INFO.md b/docs/SESSION_INFO.md index 757a9746..092b9288 100755 --- a/docs/SESSION_INFO.md +++ b/docs/SESSION_INFO.md @@ -1,62 +1,64 @@ -# Sessions Section in Device View +# Sessions Section – Device View -The **Sessions Section** provides details about a device's connection history. This data is automatically detected and cannot be edited by the user. +The **Sessions Section** shows a device’s connection history. All data is automatically detected and **cannot be edited**. -  + --- ## Key Fields -1. **Date and Time of First Connection** - - **Description:** Displays the first detected connection time for the device. - - **Editability:** Uneditable (auto-detected). - - **Source:** Automatically captured when the device is first added to the system. - -2. **Date and Time of Last Connection** - - **Description:** Shows the most recent time the device was online. - - **Editability:** Uneditable (auto-detected). - - **Source:** Updated with every new connection event. - -3. **Offline Devices with Missing or Conflicting Data** - - **Description:** Handles cases where a device is offline but has incomplete or conflicting session data (e.g., missing start times). - - **Handling:** The system flags these cases for review and attempts to infer missing details. +| Field | Description | Editable? | +| ------------------------------ | ------------------------------------------------------------------------------------------------ | --------------- | +| **First Connection** | The first time the device was detected on the network. | ❌ Auto-detected | +| **Last Connection** | The most recent time the device was online. | ❌ Auto-detected | --- -## How Sessions are Discovered and Calculated +## How Session Information Works ### 1. Detecting New Devices -When a device is first detected in the network, the system logs it in the events table: -`INSERT INTO Events (eve_MAC, eve_IP, eve_DateTime, eve_EventType, eve_AdditionalInfo, eve_PendingAlertEmail) SELECT cur_MAC, cur_IP, '{startTime}', 'New Device', cur_Vendor, 1 FROM CurrentScan WHERE NOT EXISTS (SELECT 1 FROM Devices WHERE devMac = cur_MAC)` +* New devices are automatically detected when they first appear on the network. +* A **New Device** record is created, capturing the MAC, IP, vendor, and detection time. -- Devices scanned in the current cycle (**CurrentScan**) are checked against the **Devices** table. -- If a device is new: - - A **New Device** event is logged. - - The device’s MAC, IP, vendor, and detection time are recorded. +### 2. Recording Connection Sessions -### 2. Logging Connection Sessions -When a new connection is detected, the system creates a session record: +* Every time a device connects, a session entry is created. +* Captured details include: -`INSERT INTO Sessions (ses_MAC, ses_IP, ses_EventTypeConnection, ses_DateTimeConnection, ses_EventTypeDisconnection, ses_DateTimeDisconnection, ses_StillConnected, ses_AdditionalInfo) SELECT cur_MAC, cur_IP, 'Connected', '{startTime}', NULL, NULL, 1, cur_Vendor FROM CurrentScan WHERE NOT EXISTS (SELECT 1 FROM Sessions WHERE ses_MAC = cur_MAC)` - -- A new session is logged in the **Sessions** table if no prior session exists. -- Fields like `MAC`, `IP`, `Connection Type`, and `Connection Time` are populated. -- The `Still Connected` flag is set to `1` (active connection). + * Connection type (wired or wireless) + * Connection time + * Device details (MAC, IP, vendor) ### 3. Handling Missing or Conflicting Data -- Devices with incomplete or conflicting session data (e.g., missing start times) are detected. -- The system flags these records and attempts corrections by inferring details from available data. + +* **Triggers:** + Devices are flagged when session data is incomplete, inconsistent, or conflicting. Examples include: + + * Missing first or last connection timestamps + * Overlapping session records + * Sessions showing a device as connected and disconnected at the same time + +* **System response:** + + * Automatically highlights affected devices in the **Sessions Section**. + * Attempts to **infer missing information** from available data, such as: + + * Estimating first or last connection times from nearby session events + * Correcting overlapping session periods + * Reconciling conflicting connection statuses + +* **User impact:** + + * Users do **not** need to manually fix session data. + * The system ensures the device’s connection history remains as accurate as possible for monitoring and reporting. ### 4. Updating Sessions -- When a device reconnects, its session is updated with a new connection timestamp. -- When a device disconnects: - - The **Disconnection Time** is recorded. - - The `Still Connected` flag is set to `0`. -The session information is then used to display the device presence under **Monitoring** -> **Presence**. +* **Reconnect:** Updates session with the new connection timestamp. +* **Disconnect:** Records disconnection time and marks the device as offline. + +This session information feeds directly into **Monitoring → Presence**, providing a live view of which devices are currently online.  - - diff --git a/docs/UPDATES.md b/docs/UPDATES.md index 2ac560d8..2d398dde 100755 --- a/docs/UPDATES.md +++ b/docs/UPDATES.md @@ -1,7 +1,8 @@ # Docker Update Strategies to upgrade NetAlertX -> [!WARNING] +> [!WARNING] > For versions prior to `v25.6.7` upgrade to version `v25.5.24` first (`docker pull ghcr.io/jokob-sk/netalertx:25.5.24`) as later versions don't support a full upgrade. Alternatively, devices and settings can be migrated manually, e.g. via [CSV import](./DEVICES_BULK_EDITING.md). +> See the [Migration guide](./MIGRATION.md) for details. This guide outlines approaches for updating Docker containers, usually when upgrading to a newer version of NetAlertX. Each method offers different benefits depending on the situation. Here are the methods: @@ -15,7 +16,7 @@ You can choose any approach that fits your workflow. > In the examples I assume that the container name is `netalertx` and the image name is `netalertx` as well. > [!NOTE] -> See also [Backup strategies](./BACKUPS.md) to be on the safe side. +> See also [Backup strategies](./BACKUPS.md) to be on the safe side. ## 1. Manual Updates @@ -48,7 +49,7 @@ sudo docker-compose up --pull always -d ## 2. Dockcheck for Bulk Container Updates -Always check the [Dockcheck](https://github.com/mag37/dockcheck) docs if encountering issues with the guide below. +Always check the [Dockcheck](https://github.com/mag37/dockcheck) docs if encountering issues with the guide below. Dockcheck is a useful tool if you have multiple containers to update and some flexibility for handling potential issues that might arise during mass updates. Dockcheck allows you to inspect each container and decide when to update. @@ -74,7 +75,7 @@ sudo ./dockcheck.sh ## 3. Automated Updates with Watchtower -Always check the [watchtower](https://github.com/containrrr/watchtower) docs if encountering issues with the guide below. +Always check the [watchtower](https://github.com/containrrr/watchtower) docs if encountering issues with the guide below. Watchtower monitors your Docker containers and automatically updates them when new images are available. This is ideal for ongoing updates without manual intervention. @@ -96,7 +97,7 @@ docker run -d \ --interval 300 # Check for updates every 5 minutes ``` -#### 3. Run Watchtower to update only NetAlertX: +#### 3. Run Watchtower to update only NetAlertX: You can specify which containers to monitor by listing them. For example, to monitor netalertx only: diff --git a/front/css/app.css b/front/css/app.css index 5d15b426..8c67112e 100755 --- a/front/css/app.css +++ b/front/css/app.css @@ -1,6 +1,6 @@ /* ----------------------------------------------------------------------------- # NetAlertX -# Open Source Network Guard / WIFI & LAN intrusion detector +# Open Source Network Guard / WIFI & LAN intrusion detector # # app.css - Front module. CSS styles #------------------------------------------------------------------------------- @@ -36,7 +36,7 @@ a[target="_blank"] { display: inline-block; /* Needed for positioning */ padding-right: 0.6em; /* Space for the icon */ } - + a[target="_blank"]::after { content: '↗'; position: absolute; @@ -55,7 +55,7 @@ a[target="_blank"] { right: -7px; top: 1px; } */ - + /* .select2-container--default .select2-selection--multiple .select2-selection__choice { padding-right: 15px !important; @@ -70,6 +70,11 @@ a[target="_blank"] { opacity: 1; } +[data-is-valid="0"] { + /* border: 1px solid red; */ + background-color: #ff4b4b; +} + /* ----------------------------------------------------------------------------- Helper Classes ----------------------------------------------------------------------------- */ @@ -100,7 +105,7 @@ a[target="_blank"] { background-color: black; font-family: 'Courier New', monospace; font-size: .85em; - + } .logs-row textarea { @@ -110,12 +115,12 @@ a[target="_blank"] { display:contents; position: relative; padding: 0.4em - + } #tab_Logging .actions .toggle{ - margin: 0.5em; + margin: 0.5em; height: 3em; } @@ -134,8 +139,8 @@ a[target="_blank"] { } .log-area { - padding: 3px; - width:100%; + padding: 3px; + width:100%; border-bottom-width: 1px; border-bottom-style: solid; border-color: #606060; @@ -246,7 +251,7 @@ a[target="_blank"] { { padding:8px; color: white; -} +} .header-status { @@ -262,7 +267,7 @@ a[target="_blank"] { position: absolute; top: 3px; margin-left: 15px; - display: none; + display: none; } @@ -298,9 +303,9 @@ body .NetAlertX-logo { - border-color:transparent !important; - height: 50px !important; - width: 50px !important; + border-color:transparent !important; + height: 50px !important; + width: 50px !important; margin-top:15px !important; border-radius: 1px !important; } @@ -327,7 +332,7 @@ body .content-wrapper, .right-side, .main-footer { - margin-left: 150px; + margin-left: 150px; } @@ -740,7 +745,7 @@ body text-decoration: underline; } -#ticker-message +#ticker-message { color:#FFFFFF; } @@ -774,7 +779,7 @@ body .file-checking .icon-wrap{ width: 200px; overflow: hidden; - text-overflow: ellipsis; + text-overflow: ellipsis; display: block; } @@ -788,7 +793,7 @@ body .file-checking .file-name-wrap{ overflow: hidden; - text-overflow: ellipsis; + text-overflow: ellipsis; display: flex; padding: 5px; } @@ -796,7 +801,7 @@ body .file-checking{ display: block; overflow: hidden; - text-overflow: ellipsis; + text-overflow: ellipsis; } @@ -854,16 +859,16 @@ body .db_tools_table_cell_a { display: table-cell; - text-align: center; - padding: 10px; - min-width: 180px; - width: 20%; + text-align: center; + padding: 10px; + min-width: 180px; + width: 20%; vertical-align: middle; } .db_tools_table_cell_b { display: table-cell; - text-align: justify; - font-size: 16px; + text-align: justify; + font-size: 16px; vertical-align: middle; padding: 10px; } @@ -876,12 +881,12 @@ height: 50px; } .nav-tabs-custom .tab-content { - background-color: white; - + background-color: white; + } @media (max-width: 767px) { - .nav-tabs-custom .tab-content { + .nav-tabs-custom .tab-content { overflow: scroll; } } @@ -898,7 +903,7 @@ height: 50px; font-size: 16px !important; } -.deviceSelector +.deviceSelector { display: block; } @@ -935,7 +940,7 @@ height: 50px; height: 10px; display: inline-block; /* background: #fff; */ - opacity: .75; + opacity: .75; } /* --------------------------------------------------------- */ @@ -979,32 +984,32 @@ height: 50px; } /* .setting_input{ width:70%; - + } .setting_name { - width:30%; + width:30%; } */ } @media (min-width: 768px) { -.setting_description { +.setting_description { /* color: green; */ display: block; } /* .setting_input{ - width:40%; + width:40%; } .setting_name { - width:19%; + width:19%; } */ } /* Hide unusable buttons on the settings page for the NEWDEV plugin*/ -#settingsPage #add_option_NEWDEV_devGroup, -#settingsPage #add_option_NEWDEV_devLocation, +#settingsPage #add_option_NEWDEV_devGroup, +#settingsPage #add_option_NEWDEV_devLocation, #settingsPage #add_option_NEWDEV_devOwner, #settingsPage #copy_icons_NEWDEV_devIcon, #settingsPage #add_icon_NEWDEV_devIcon, @@ -1024,11 +1029,11 @@ height: 50px; #settingsPage .small-box .inner .card-title { overflow: hidden; - text-overflow: ellipsis; + text-overflow: ellipsis; white-space: nowrap; color: white; } - + .settingswrap { @@ -1048,13 +1053,13 @@ height: 50px; .padding-bottom { padding-bottom: 100px; -} +} .settings-group -{ +{ font-size: 20px; padding-top: 7px; - padding-bottom: 9px; + padding-bottom: 9px; } .overview-section .small-box .icon @@ -1069,7 +1074,7 @@ height: 50px; } .overview-group -{ +{ font-size: 20px; padding-top: 7px; padding-bottom: 9px; @@ -1082,8 +1087,8 @@ height: 50px; } -#settingsPage .table_row { - padding: 3px; +#settingsPage .table_row { + padding: 3px; /* width:100%; */ /* display: flex; */ border-bottom-width: 1px; @@ -1102,7 +1107,7 @@ height: 50px; .setting_name { /* width:19%; */ - font-weight: 300; + font-weight: 300; } @@ -1111,24 +1116,24 @@ height: 50px; display:none !important; } -.center +.center { margin: 0; - position: relative; + position: relative; left: 50%; -ms-transform: translate(-50%, -50%); transform: translate(-50%, -50%); } -.top-margin +.top-margin { margin-top: 50px; } /* Settings */ -#settingsPage .overview-setting-value{ - display:unset; +#settingsPage .overview-setting-value{ + display:unset; } @@ -1165,7 +1170,7 @@ height: 50px; } .text-overflow-hidden -{ +{ overflow: hidden; text-overflow: clip; } @@ -1175,9 +1180,9 @@ height: 50px; padding: 10px; /* background-color: #272c30; */ margin: 10px; - + } -#settingsPage .panel-heading:hover{ +#settingsPage .panel-heading:hover{ background-color: #272c30; } @@ -1185,12 +1190,12 @@ height: 50px; font-size: medium; /* background-color: #272c30; */ margin: 10px; - + } -.settings_content input[type=checkbox] -{ - width: auto +.settings_content input[type=checkbox] +{ + width: auto } .override{ @@ -1212,7 +1217,7 @@ height: 50px; input[readonly] { /* Apply styles to the readonly input */ background-color: #646566 !important; - color: #e6e6e6; + color: #e6e6e6; cursor: not-allowed; } @@ -1300,7 +1305,7 @@ input[readonly] { /* margin-bottom:20px; */ } -#settingsPage .select2-selection +#settingsPage .select2-selection { width: initial; display: inline-block; @@ -1314,8 +1319,8 @@ input[readonly] { #settingsPage .select2-selection { background-color: rgb(96, 96, 96); -} -#settingsPage .select2-container +} +#settingsPage .select2-container { width: 100% !important; } @@ -1398,7 +1403,7 @@ input[readonly] { backdrop-filter: brightness(50%); } -.iconPreviewSelector +.iconPreviewSelector { text-align: center; padding: 15px; @@ -1440,7 +1445,7 @@ input[readonly] { } -.dummyDevice +.dummyDevice { text-align: end; } @@ -1461,7 +1466,7 @@ input[readonly] { } .info-icon-nav -{ +{ top: -6px; position: absolute; z-index: 1; @@ -1538,7 +1543,7 @@ input[readonly] { } #panDetails .input-group { - + min-height: 40px; } @@ -1583,7 +1588,7 @@ input[readonly] { } .devicePropAction -{ +{ width: 1.2em; height: 1.2em; display: inline-block; @@ -1593,11 +1598,11 @@ input[readonly] { } .devicePropAction:hover -{ +{ font-size: larger; padding: 0em; margin: 0em; - + } @@ -1607,7 +1612,7 @@ input[readonly] { display: block; float:inline-end; height: 2em; -} +} #panDetails .dataTables_wrapper .bottom .dataTables_info { @@ -1636,22 +1641,22 @@ input[readonly] { height: 14px; } -#deviceDetailsEdit .select2-container--default .select2-selection--multiple .select2-selection__choice +#deviceDetailsEdit .select2-container--default .select2-selection--multiple .select2-selection__choice { height: 20px; } -#deviceDetailsEdit .select2-container--disabled +#deviceDetailsEdit .select2-container--disabled { - background-color: #606060; + background-color: #606060; } -#deviceDetailsEdit .select2-container--default .select2-selection--multiple .select2-selection__choice span +#deviceDetailsEdit .select2-container--default .select2-selection--multiple .select2-selection__choice span { font-size: 14px; } -#deviceDetailsEdit .select2-selection +#deviceDetailsEdit .select2-selection { width: initial; display: inline-block; @@ -1681,7 +1686,7 @@ input[readonly] { font-size: 14px; } .custom-badge -{ +{ border: 1px solid #aaa; border-radius: 4px; border-style: solid; @@ -1716,7 +1721,7 @@ input[readonly] { } -#deviceDetailsEdit .select2-container +#deviceDetailsEdit .select2-container { width: 100% !important; } @@ -1799,7 +1804,7 @@ input[readonly] { z-index: 5; } #networkTree .netNodeText -{ +{ position: absolute; } #networkTree .netPort @@ -1812,7 +1817,7 @@ input[readonly] { #networkTree .portBckgIcon { opacity: 0.3; - display: initial; + display: initial; float: left; width: 1em; } @@ -1822,7 +1827,7 @@ input[readonly] { margin-left: 16px; /* border: solid; border-color:#606060; */ - position: relative; + position: relative; } #networkTree .netIcon { @@ -1850,8 +1855,8 @@ input[readonly] { } #hover-box .devName -{ - font-size: larger; +{ + font-size: larger; display: contents; } @@ -1910,7 +1915,7 @@ input[readonly] { #networkTree .highlightedNode { /* border: solid; */ - border-color:var(--color-lightblue); + border-color:var(--color-lightblue); box-shadow: var(--color-lightblue) 0px 0px 20px; } @@ -1968,7 +1973,7 @@ input[readonly] { } .sort-btn { - + right: 5px; top: 50%; transform: translateY(-50%); @@ -2020,7 +2025,7 @@ input[readonly] { } .plugin-filters -{ +{ margin: 7px; margin-right: 7px; margin-bottom: 9px; @@ -2054,7 +2059,7 @@ input[readonly] { } .plugin-content #tabs-content-location -{ +{ margin: 0px; padding-top: 0; } @@ -2066,7 +2071,7 @@ input[readonly] { } .plugin-content .tab-content -{ +{ padding-top: 10px; } @@ -2103,7 +2108,7 @@ input[readonly] { @media (max-width: 500px) { .header-server-time { - display: none; + display: none; } } @@ -2234,12 +2239,12 @@ input[readonly] { display: grid; } -#workflowContainerWrap .panel-collapse +#workflowContainerWrap .panel-collapse { padding: 5px; } -.workflows +.workflows { max-width: 800px; } @@ -2285,7 +2290,7 @@ input[readonly] { color: #000; } -.workflows .button-container +.workflows .button-container { /* display: contents; */ text-align: center; @@ -2305,7 +2310,7 @@ input[readonly] { margin: 5px; } -.workflows .button-container +.workflows .button-container { padding-right: 0px !important; padding-left: 0px !important; @@ -2318,19 +2323,19 @@ input[readonly] { /* .button-container button { - width:100%; + width:100%; } */ .red-hover-text:hover { - color: var(--color-red) !important; + color: var(--color-red) !important; } .green-hover-text:hover { color: var(--color-green) !important; } - + .workflows .bckg-icon-1-line { font-size: 3em; @@ -2362,7 +2367,7 @@ input[readonly] { z-index: 1; } -.workflows .workflow-card +.workflows .workflow-card { display: block; } @@ -2372,7 +2377,7 @@ input[readonly] { padding: 10px; } -.workflow-card, .actions-list +.workflow-card, .actions-list { display: contents; padding: 5px; @@ -2384,7 +2389,7 @@ input[readonly] { z-index:1; } -.condition +.condition { padding: 5px; padding-left: 10px; diff --git a/front/js/modal.js b/front/js/modal.js index 54073067..dbcf5e10 100755 --- a/front/js/modal.js +++ b/front/js/modal.js @@ -96,7 +96,7 @@ function showModalInput( btnOK = getString("Gen_Okay"), callbackFunction = null, triggeredBy = null, - defaultValue = "" + defaultValue = "" ) { prefix = "modal-input"; @@ -121,7 +121,7 @@ function showModalInput( setTimeout(function () { $(`#${prefix}-textarea`).focus(); }, 500); - + } // ----------------------------------------------------------------------------- @@ -143,7 +143,7 @@ function showModalFieldInput( $(`#${prefix}-OK`).html(btnOK); if (callbackFunction != null) { - + modalCallbackFunction = callbackFunction; } @@ -181,11 +181,11 @@ function showModalPopupForm( $(`#${prefix}-cancel`).html(btnCancel); $(`#${prefix}-OK`).html(btnOK); - // if curValue not null + // if curValue not null if (curValue) { - initialValues = JSON.parse(atob(curValue)); + initialValues = JSON.parse(atob(curValue)); } outputHtml = ""; @@ -193,7 +193,7 @@ function showModalPopupForm( if (Array.isArray(popupFormJson)) { popupFormJson.forEach((field, index) => { // You'll need to define these or map them from `field` - const setKey = field.function || `field_${index}`; + const setKey = field.function || `field_${index}`; const setName = getString(`${parentSettingKey}_popupform_${setKey}_name`); const labelClasses = "col-sm-2"; // example, or from your obj.labelClasses const inputClasses = "col-sm-10"; // example, or from your obj.inputClasses @@ -207,9 +207,9 @@ function showModalPopupForm( } } - const fieldOptionsOverride = field.type?.elements[0]?.elementOptions || []; + const fieldOptionsOverride = field.type?.elements[0]?.elementOptions || []; const setValue = initialValue; - const setType = JSON.stringify(field.type); + const setType = JSON.stringify(field.type); const setEvents = field.events || []; // default to empty array if missing const setObj = { setKey, setValue, setType, setEvents }; @@ -218,17 +218,17 @@ function showModalPopupForm(
${getSetting(prefix + "_" + set)}
-