feat: authoritative plugin fields - fix devFQDN + docs + allow filters and columns on new fields

Signed-off-by: jokob-sk <jokob.sk@gmail.com>
This commit is contained in:
jokob-sk
2026-01-30 07:50:21 +11:00
parent 52ac9fce41
commit 229ea770cb
27 changed files with 161 additions and 49 deletions

View File

@@ -138,36 +138,6 @@ The Device Edit form displays lock/unlock buttons for all tracked fields:
2. **Unlock Button** (🔓): Click to allow plugin overwrites again
3. **Source Indicator**: Shows current field source (USER, LOCKED, NEWDEV, or plugin name)
## UI Workflow
### Locking a Field via UI
1. Navigate to Device Details
2. Find the field you want to protect
3. Click the lock button (🔒) next to the field
4. Button changes to unlock (🔓) and source indicator turns red (LOCKED)
5. Field is now protected from plugin overwrites
### Unlocking a Field via UI
1. Find the locked field (button shows 🔓)
2. Click the unlock button
3. Button changes back to lock (🔒) and source resets to NEWDEV
4. Plugins can now update this field again
## Authorization
All lock/unlock operations require:
- Valid API token in `Authorization: Bearer {token}` header
- User must be authenticated to the NetAlertX instance
## Implementation Details
### Backend Logic
The lock/unlock feature is implemented in:
- **API Endpoint**: `/server/api_server/api_server_start.py` - `api_device_field_lock()`
- **Data Model**: `/server/models/device_instance.py` - Authorization checks in `setDeviceData()`
- **Database**: Devices table with `*Source` columns tracking field origins
### Authorization Handler
@@ -179,6 +149,9 @@ The authoritative field update logic prevents plugin overwrites:
4. If source is `NEWDEV` or plugin name, plugin update is accepted
## See Also
- [Device locking](./DEVICE_FIELD_LOCK.md)
- [Device source fields](./DEVICE_SOURCE_FIELDS.md)
- [API Device Endpoints Documentation](./API_DEVICE.md)
- [Authoritative Field Updates System](./PLUGINS_DEV.md#authoritative-fields)
- [Plugin Configuration Reference](./PLUGINS_DEV_CONFIG.md)

View File

@@ -37,7 +37,12 @@ Each locked field has a "source" indicator that shows you why the value is prote
| 📡 **NEWDEV** | Default/unset value | Yes, plugins can update |
| 📡 **Plugin name** | Last updated by a plugin (e.g., UNIFIAPI) | Yes, plugins can update if field in SET_ALWAYS |
## How to Use
Overwrite rules are
> [!TIP]
> You can bulk-unlock devices in the [Multi-edit](./DEVICES_BULK_EDITING.md) dialog. This removes all `USER` and `LOCKED` values from all `*Source` fields of selected devices.
## Usage Examples
### Lock a Field (Prevent Plugin Changes)
@@ -147,13 +152,13 @@ Each locked field has a "source" indicator that shows you why the value is prote
- Check if you accidentally unlocked it
- Open an issue if it persists
## For More Information
## See also
- **Technical details:** See [API_DEVICE_FIELD_LOCK.md](API_DEVICE_FIELD_LOCK.md)
- **Plugin configuration:** See [PLUGINS_DEV_CONFIG.md](PLUGINS_DEV_CONFIG.md)
- **Admin guide:** See [DEVICE_MANAGEMENT.md](DEVICE_MANAGEMENT.md)
---
**Quick Start:** Find a device field you want to protect → Click the lock icon → That's it! The field won't change until you unlock it.
- [Device locking](./DEVICE_FIELD_LOCK.md)
- [Device source fields](./DEVICE_SOURCE_FIELDS.md)
- [API Device Endpoints Documentation](./API_DEVICE.md)
- [Authoritative Field Updates System](./PLUGINS_DEV.md#authoritative-fields)
- [Plugin Configuration Reference](./PLUGINS_DEV_CONFIG.md)
- [Device locking APIs](API_DEVICE_FIELD_LOCK.md)
- [Device management](DEVICE_MANAGEMENT.md)

View File

@@ -0,0 +1,67 @@
# Understanding Device Source Fields and Field Updates
When the system scans a network, it finds various details about devices (like names, IP addresses, and manufacturers). To ensure the data remains accurate without accidentally overwriting manual changes, the system uses a set of "Source Rules."
![Field source and locks](./img/DEVICE_MANAGEMENT/field_sources_and_locks.png)
---
## The "Protection" Levels
Every piece of information for a device has a **Source**. This source determines whether a new scan is allowed to change that value.
| Source Status | Description | Can a Scan Overwrite it? |
| --- | --- | --- |
| **USER** | You manually entered this value. | **Never** |
| **LOCKED** | This value is pinned and protected. | **Never** |
| **NEWDEV** | This value was initialized from `NEWDEV` plugin settings. | **Always** |
| **(Plugin Name)** | The value was found by a specific scanner (e.g., `NBTSCAN`). | **Only if specific rules are met** |
---
## How Scans Update Information
If a field is **not** protected by a `USER` or `LOCKED` status, the system follows these rules to decide if it should update the info:
### 1. The "Empty Field" Rule (Default)
By default, the system is cautious. It will only fill in a piece of information if the current field is **empty** (showing as "unknown," "0.0.0.0," or blank). It won't change for example an existing name unless you tell it to.
### 2. SET_ALWAYS
Some plugins are configured to be "authoritative." If a field is in the **SET_ALWAYS** setting of a plugin:
* The scanner will **always** overwrite the current value with the new one.
* *Note: It will still never overwrite a `USER` or `LOCKED` field.*
### 3. SET_EMPTY
If a field is in the **SET_EMPTY** list:
* The scanner will **only** provide a value if the current field is currently empty.
* This is used for fields where we want to "fill in the blanks" but never change a value once it has been established by any source.
### 4. Automatic Overrides (Live Tracking)
Some fields, like **IP Addresses** (`devLastIP`) and **Full Domain Names** (`devFQDN`), are set to automatically update whenever they change. This ensures that if a device moves to a new IP on your network, the system reflects that change immediately without you having to do anything.
---
## Summary of Field Logic
| If the current value is... | And the Scan finds... | Does it update? |
| --- | --- | --- |
| **USER / LOCKED** | Anything | **No** |
| **Empty** | A new value | **Yes** |
| **A "Plugin" value** | A different value | **No** (Unless `SET_ALWAYS` is on) |
| **An IP Address** | A different IP | **Yes** (Updates automatically) |
## See also:
- [Device locking](./DEVICE_FIELD_LOCK.md)
- [Device source fields](./DEVICE_SOURCE_FIELDS.md)
- [API Device Endpoints Documentation](./API_DEVICE.md)
- [Authoritative Field Updates System](./PLUGINS_DEV.md#authoritative-fields)
- [Plugin Configuration Reference](./PLUGINS_DEV_CONFIG.md)
- [Device locking APIs](API_DEVICE_FIELD_LOCK.md)
- [Device management](DEVICE_MANAGEMENT.md)

View File

@@ -145,14 +145,18 @@ class NetAlertXStateManager {
.attr('data-version', version);
// 3. Update Build Timestamp placeholders
const buildTime = appState["buildTimestamp"] !== undefined ? appState["buildTimestamp"] : "";
const displayTime = (buildTime === 0) ? "UNKNOWN" : buildTime;
const buildTime = appState["buildTimestamp"] || 0;
const displayTime = buildTime ? localizeTimestamp(buildTime) : "UNKNOWN";
$('[data-plc="build-timestamp"]')
.html(displayTime)
.attr('data-build-time', buildTime);
$('[data-plc="build-timestamp"]')
.html(displayTime)
.attr('data-build-time', buildTime);
console.log("[NetAlertX State] UI updated via jQuery");
// console.log("[NetAlertX State] UI updated via jQuery");
} catch (e) {
console.error("[NetAlertX State] Failed to update state display:", e);
}

View File

@@ -668,7 +668,10 @@ function getColumnNameFromLangString(headStringKey) {
"Device_TableHead_CustomProps": "devCustomProps",
"Device_TableHead_FQDN": "devFQDN",
"Device_TableHead_ParentRelType": "devParentRelType",
"Device_TableHead_ReqNicsOnline": "devReqNicsOnline"
"Device_TableHead_ReqNicsOnline": "devReqNicsOnline",
"Device_TableHead_Vlan": "devVlan",
"Device_TableHead_IPv4": "devPrimaryIPv4",
"Device_TableHead_IPv6": "devPrimaryIPv6"
};
return columnNameMap[headStringKey] || "";

View File

@@ -226,6 +226,8 @@
"Device_TableHead_FirstSession": "أول جلسة",
"Device_TableHead_GUID": "معرف فريد",
"Device_TableHead_Group": "المجموعة",
"Device_TableHead_IPv4": "",
"Device_TableHead_IPv6": "",
"Device_TableHead_Icon": "الأيقونة",
"Device_TableHead_LastIP": "آخر عنوان IP",
"Device_TableHead_LastIPOrder": "ترتيب آخر عنوان IP",
@@ -249,6 +251,7 @@
"Device_TableHead_SyncHubNodeName": "اسم عقدة المزامنة",
"Device_TableHead_Type": "النوع",
"Device_TableHead_Vendor": "المصنع",
"Device_TableHead_Vlan": "",
"Device_Table_Not_Network_Device": "ليس جهاز شبكة",
"Device_Table_info": "معلومات الجدول",
"Device_Table_nav_next": "التالي",

View File

@@ -226,6 +226,8 @@
"Device_TableHead_FirstSession": "Primera Sessió",
"Device_TableHead_GUID": "GUID",
"Device_TableHead_Group": "Grup",
"Device_TableHead_IPv4": "",
"Device_TableHead_IPv6": "",
"Device_TableHead_Icon": "Icona",
"Device_TableHead_LastIP": "Darrera IP",
"Device_TableHead_LastIPOrder": "Últim Ordre d'IP",
@@ -249,6 +251,7 @@
"Device_TableHead_SyncHubNodeName": "Node Sync",
"Device_TableHead_Type": "Tipus",
"Device_TableHead_Vendor": "Venedor",
"Device_TableHead_Vlan": "",
"Device_Table_Not_Network_Device": "No configurat com a dispositiu de xarxa",
"Device_Table_info": "Mostrant _INICI_ a_FINAL_ d'entrades_ TOTALS",
"Device_Table_nav_next": "Següent",

View File

@@ -226,6 +226,8 @@
"Device_TableHead_FirstSession": "",
"Device_TableHead_GUID": "",
"Device_TableHead_Group": "",
"Device_TableHead_IPv4": "",
"Device_TableHead_IPv6": "",
"Device_TableHead_Icon": "",
"Device_TableHead_LastIP": "",
"Device_TableHead_LastIPOrder": "",
@@ -249,6 +251,7 @@
"Device_TableHead_SyncHubNodeName": "",
"Device_TableHead_Type": "",
"Device_TableHead_Vendor": "",
"Device_TableHead_Vlan": "",
"Device_Table_Not_Network_Device": "",
"Device_Table_info": "",
"Device_Table_nav_next": "",

View File

@@ -230,6 +230,8 @@
"Device_TableHead_FirstSession": "Erste Sitzung",
"Device_TableHead_GUID": "GUID",
"Device_TableHead_Group": "Gruppe",
"Device_TableHead_IPv4": "",
"Device_TableHead_IPv6": "",
"Device_TableHead_Icon": "Icon",
"Device_TableHead_LastIP": "Letzte IP",
"Device_TableHead_LastIPOrder": "Letzte erhaltene IP",
@@ -253,6 +255,7 @@
"Device_TableHead_SyncHubNodeName": "Synchronisationsknoten",
"Device_TableHead_Type": "Typ",
"Device_TableHead_Vendor": "Hersteller",
"Device_TableHead_Vlan": "",
"Device_Table_Not_Network_Device": "Nicht konfiguriert als Netzwerkgerät",
"Device_Table_info": "Zeige _START_ bis _END_ von _TOTAL_ Einträgen",
"Device_Table_nav_next": "Nächste",

View File

@@ -226,6 +226,8 @@
"Device_TableHead_FirstSession": "First Session",
"Device_TableHead_GUID": "GUID",
"Device_TableHead_Group": "Group",
"Device_TableHead_IPv4": "IPv4",
"Device_TableHead_IPv6": "IPv6",
"Device_TableHead_Icon": "Icon",
"Device_TableHead_LastIP": "Last IP",
"Device_TableHead_LastIPOrder": "Last IP Order",
@@ -249,6 +251,7 @@
"Device_TableHead_SyncHubNodeName": "Sync Node",
"Device_TableHead_Type": "Type",
"Device_TableHead_Vendor": "Vendor",
"Device_TableHead_Vlan": "VLAN",
"Device_Table_Not_Network_Device": "Not configured as a network device",
"Device_Table_info": "Showing _START_ to _END_ of _TOTAL_ entries",
"Device_Table_nav_next": "Next",

View File

@@ -228,6 +228,8 @@
"Device_TableHead_FirstSession": "1ra. sesión",
"Device_TableHead_GUID": "GUID",
"Device_TableHead_Group": "Grupo",
"Device_TableHead_IPv4": "",
"Device_TableHead_IPv6": "",
"Device_TableHead_Icon": "Icon",
"Device_TableHead_LastIP": "Última IP",
"Device_TableHead_LastIPOrder": "Última orden de IP",
@@ -251,6 +253,7 @@
"Device_TableHead_SyncHubNodeName": "Nodo de sincronización",
"Device_TableHead_Type": "Tipo",
"Device_TableHead_Vendor": "Fabricante",
"Device_TableHead_Vlan": "",
"Device_Table_Not_Network_Device": "No está configurado como dispositivo de red",
"Device_Table_info": "Mostrando el INICIO y el FINAL de TODAS las entradas",
"Device_Table_nav_next": "Siguiente",

View File

@@ -226,6 +226,8 @@
"Device_TableHead_FirstSession": "",
"Device_TableHead_GUID": "",
"Device_TableHead_Group": "",
"Device_TableHead_IPv4": "",
"Device_TableHead_IPv6": "",
"Device_TableHead_Icon": "",
"Device_TableHead_LastIP": "",
"Device_TableHead_LastIPOrder": "",
@@ -249,6 +251,7 @@
"Device_TableHead_SyncHubNodeName": "",
"Device_TableHead_Type": "",
"Device_TableHead_Vendor": "",
"Device_TableHead_Vlan": "",
"Device_Table_Not_Network_Device": "",
"Device_Table_info": "",
"Device_Table_nav_next": "",

View File

@@ -226,6 +226,8 @@
"Device_TableHead_FirstSession": "Première session",
"Device_TableHead_GUID": "GUID",
"Device_TableHead_Group": "Groupe",
"Device_TableHead_IPv4": "",
"Device_TableHead_IPv6": "",
"Device_TableHead_Icon": "Icône",
"Device_TableHead_LastIP": "Dernière IP",
"Device_TableHead_LastIPOrder": "Ordre dernière IP",
@@ -249,6 +251,7 @@
"Device_TableHead_SyncHubNodeName": "Noeud de synchro",
"Device_TableHead_Type": "Type",
"Device_TableHead_Vendor": "Fabriquant",
"Device_TableHead_Vlan": "",
"Device_Table_Not_Network_Device": "Non configuré comme appareil du réseau",
"Device_Table_info": "Affiche de _START_ à _END_ sur _TOTAL_ entrées",
"Device_Table_nav_next": "Suivant",
@@ -783,4 +786,4 @@
"settings_system_label": "Système",
"settings_update_item_warning": "Mettre à jour la valeur ci-dessous. Veillez à bien suivre le même format qu'auparavant. <b>Il n'y a pas de pas de contrôle.</b>",
"test_event_tooltip": "Enregistrer d'abord vos modifications avant de tester vôtre paramétrage."
}
}

View File

@@ -226,6 +226,8 @@
"Device_TableHead_FirstSession": "Prima sessione",
"Device_TableHead_GUID": "GUID",
"Device_TableHead_Group": "Gruppo",
"Device_TableHead_IPv4": "",
"Device_TableHead_IPv6": "",
"Device_TableHead_Icon": "Icona",
"Device_TableHead_LastIP": "Ultimo IP",
"Device_TableHead_LastIPOrder": "Ordina per ultimo IP",
@@ -249,6 +251,7 @@
"Device_TableHead_SyncHubNodeName": "Sincronizza nodo",
"Device_TableHead_Type": "Tipo",
"Device_TableHead_Vendor": "Produttore",
"Device_TableHead_Vlan": "",
"Device_Table_Not_Network_Device": "Non configurato come dispositivo di rete",
"Device_Table_info": "Visualizzazione da _START_ a _END_ di _TOTAL_ voci",
"Device_Table_nav_next": "Successivo",
@@ -783,4 +786,4 @@
"settings_system_label": "Sistema",
"settings_update_item_warning": "Aggiorna il valore qui sotto. Fai attenzione a seguire il formato precedente. <b>La convalida non viene eseguita.</b>",
"test_event_tooltip": "Salva le modifiche prima di provare le nuove impostazioni."
}
}

View File

@@ -226,6 +226,8 @@
"Device_TableHead_FirstSession": "初回セッション",
"Device_TableHead_GUID": "GUID",
"Device_TableHead_Group": "グループ",
"Device_TableHead_IPv4": "",
"Device_TableHead_IPv6": "",
"Device_TableHead_Icon": "アイコン",
"Device_TableHead_LastIP": "直近のIP",
"Device_TableHead_LastIPOrder": "直近のIP順",
@@ -249,6 +251,7 @@
"Device_TableHead_SyncHubNodeName": "同期ノード",
"Device_TableHead_Type": "種別",
"Device_TableHead_Vendor": "ベンダー",
"Device_TableHead_Vlan": "",
"Device_Table_Not_Network_Device": "ネットワーク機器として構成されていない",
"Device_Table_info": "_START__END_を表示 / _TOTAL_ 件中",
"Device_Table_nav_next": "次",

View File

@@ -226,6 +226,8 @@
"Device_TableHead_FirstSession": "Første Økt",
"Device_TableHead_GUID": "GUID",
"Device_TableHead_Group": "Gruppe",
"Device_TableHead_IPv4": "",
"Device_TableHead_IPv6": "",
"Device_TableHead_Icon": "Ikon",
"Device_TableHead_LastIP": "Siste IP",
"Device_TableHead_LastIPOrder": "Siste IP Rekkefølge",
@@ -249,6 +251,7 @@
"Device_TableHead_SyncHubNodeName": "Synkroniser Node",
"Device_TableHead_Type": "Type",
"Device_TableHead_Vendor": "Leverandør",
"Device_TableHead_Vlan": "",
"Device_Table_Not_Network_Device": "Ikke konfigurert som en nettverksenhet",
"Device_Table_info": "Showing _START_ to _END_ of _TOTAL_ entries",
"Device_Table_nav_next": "Neste",

View File

@@ -226,6 +226,8 @@
"Device_TableHead_FirstSession": "Pierwsza sesja",
"Device_TableHead_GUID": "GUID",
"Device_TableHead_Group": "Grupa",
"Device_TableHead_IPv4": "",
"Device_TableHead_IPv6": "",
"Device_TableHead_Icon": "Ikona",
"Device_TableHead_LastIP": "Ostatni adres IP",
"Device_TableHead_LastIPOrder": "Kolejność ostatniego adresu IP",
@@ -249,6 +251,7 @@
"Device_TableHead_SyncHubNodeName": "Węzeł synchronizacji",
"Device_TableHead_Type": "Typ",
"Device_TableHead_Vendor": "Producent",
"Device_TableHead_Vlan": "",
"Device_Table_Not_Network_Device": "Nie skonfigurowano jako urządzenie sieciowe",
"Device_Table_info": "Pokazuje _START_ do _END_ z _TOTAL_ wpisów",
"Device_Table_nav_next": "Następna",

View File

@@ -226,6 +226,8 @@
"Device_TableHead_FirstSession": "Primeira sessão",
"Device_TableHead_GUID": "GUID",
"Device_TableHead_Group": "Grupo",
"Device_TableHead_IPv4": "",
"Device_TableHead_IPv6": "",
"Device_TableHead_Icon": "Ícone",
"Device_TableHead_LastIP": "Último IP",
"Device_TableHead_LastIPOrder": "Último pedido de IP",
@@ -249,6 +251,7 @@
"Device_TableHead_SyncHubNodeName": "Nó de sincronização",
"Device_TableHead_Type": "Tipo",
"Device_TableHead_Vendor": "Fornecedor",
"Device_TableHead_Vlan": "",
"Device_Table_Not_Network_Device": "Não configurado como um dispositivo de rede",
"Device_Table_info": "Mostrando _START_ de _END_ do _TOTAL_ entradas",
"Device_Table_nav_next": "Próximo",

View File

@@ -226,6 +226,8 @@
"Device_TableHead_FirstSession": "Primeira sessão",
"Device_TableHead_GUID": "GUID",
"Device_TableHead_Group": "Grupo",
"Device_TableHead_IPv4": "",
"Device_TableHead_IPv6": "",
"Device_TableHead_Icon": "Ícone",
"Device_TableHead_LastIP": "Último IP",
"Device_TableHead_LastIPOrder": "Último pedido de IP",
@@ -249,6 +251,7 @@
"Device_TableHead_SyncHubNodeName": "Nó de sincronização",
"Device_TableHead_Type": "Tipo",
"Device_TableHead_Vendor": "Fornecedor",
"Device_TableHead_Vlan": "",
"Device_Table_Not_Network_Device": "Não configurado como um dispositivo de rede",
"Device_Table_info": "A mostrar _START_ to _END_ of _TOTAL_ entradas",
"Device_Table_nav_next": "Próximo",

View File

@@ -226,6 +226,8 @@
"Device_TableHead_FirstSession": "Первый сеанс",
"Device_TableHead_GUID": "GUID",
"Device_TableHead_Group": "Группа",
"Device_TableHead_IPv4": "",
"Device_TableHead_IPv6": "",
"Device_TableHead_Icon": "Значок",
"Device_TableHead_LastIP": "Последний IP",
"Device_TableHead_LastIPOrder": "Последний IP-запрос",
@@ -249,6 +251,7 @@
"Device_TableHead_SyncHubNodeName": "Узел синхронизации",
"Device_TableHead_Type": "Тип",
"Device_TableHead_Vendor": "Поставщик",
"Device_TableHead_Vlan": "",
"Device_Table_Not_Network_Device": "Не настроено как сетевое устройство",
"Device_Table_info": "Показаны с _START_ по _END_ из _TOTAL_ записей",
"Device_Table_nav_next": "Следующая",

View File

@@ -226,6 +226,8 @@
"Device_TableHead_FirstSession": "",
"Device_TableHead_GUID": "",
"Device_TableHead_Group": "",
"Device_TableHead_IPv4": "",
"Device_TableHead_IPv6": "",
"Device_TableHead_Icon": "",
"Device_TableHead_LastIP": "",
"Device_TableHead_LastIPOrder": "",
@@ -249,6 +251,7 @@
"Device_TableHead_SyncHubNodeName": "",
"Device_TableHead_Type": "",
"Device_TableHead_Vendor": "",
"Device_TableHead_Vlan": "",
"Device_Table_Not_Network_Device": "",
"Device_Table_info": "",
"Device_Table_nav_next": "",

View File

@@ -226,6 +226,8 @@
"Device_TableHead_FirstSession": "İlk Oturum",
"Device_TableHead_GUID": "GUID",
"Device_TableHead_Group": "Grup",
"Device_TableHead_IPv4": "",
"Device_TableHead_IPv6": "",
"Device_TableHead_Icon": "İkon",
"Device_TableHead_LastIP": "Son IP",
"Device_TableHead_LastIPOrder": "Son IP Sırası",
@@ -249,6 +251,7 @@
"Device_TableHead_SyncHubNodeName": "Senkronizasyon Node",
"Device_TableHead_Type": "Tür",
"Device_TableHead_Vendor": "Üretici",
"Device_TableHead_Vlan": "",
"Device_Table_Not_Network_Device": "Ağ cihazı olarak ayarlanmadı",
"Device_Table_info": "Showing _START_ to _END_ of _TOTAL_ entries",
"Device_Table_nav_next": "Sonraki",

View File

@@ -226,6 +226,8 @@
"Device_TableHead_FirstSession": "Перша сесія",
"Device_TableHead_GUID": "GUID",
"Device_TableHead_Group": "Група",
"Device_TableHead_IPv4": "",
"Device_TableHead_IPv6": "",
"Device_TableHead_Icon": "Значок",
"Device_TableHead_LastIP": "Останній IP",
"Device_TableHead_LastIPOrder": "Останнє замовлення IP",
@@ -249,6 +251,7 @@
"Device_TableHead_SyncHubNodeName": "Вузол синхронізації",
"Device_TableHead_Type": "Тип",
"Device_TableHead_Vendor": "Продавець",
"Device_TableHead_Vlan": "",
"Device_Table_Not_Network_Device": "Не налаштовано як мережевий пристрій",
"Device_Table_info": "Показано від _START_ до _END_ із _TOTAL_ записів",
"Device_Table_nav_next": "Далі",
@@ -783,4 +786,4 @@
"settings_system_label": "Система",
"settings_update_item_warning": "Оновіть значення нижче. Слідкуйте за попереднім форматом. <b>Перевірка не виконана.</b>",
"test_event_tooltip": "Перш ніж перевіряти налаштування, збережіть зміни."
}
}

View File

@@ -226,6 +226,8 @@
"Device_TableHead_FirstSession": "加入",
"Device_TableHead_GUID": "GUID",
"Device_TableHead_Group": "组",
"Device_TableHead_IPv4": "",
"Device_TableHead_IPv6": "",
"Device_TableHead_Icon": "图标",
"Device_TableHead_LastIP": "上次 IP",
"Device_TableHead_LastIPOrder": "上次 IP 排序",
@@ -249,6 +251,7 @@
"Device_TableHead_SyncHubNodeName": "同步节点",
"Device_TableHead_Type": "类型",
"Device_TableHead_Vendor": "制造商",
"Device_TableHead_Vlan": "",
"Device_Table_Not_Network_Device": "未配置为网络设备",
"Device_Table_info": "显示第_START_至 END_条_共_TOTAL_条",
"Device_Table_nav_next": "下一页",

View File

@@ -440,7 +440,9 @@
"Device_TableHead_CustomProps",
"Device_TableHead_FQDN",
"Device_TableHead_ParentRelType",
"Device_TableHead_ReqNicsOnline"
"Device_TableHead_ReqNicsOnline",
"Device_TableHead_IPv6",
"Device_TableHead_IPv4"
],
"localized": ["name", "description"],
"name": [
@@ -517,7 +519,8 @@
"Device_TableHead_NetworkSite",
"Device_TableHead_SSID",
"Device_TableHead_SourcePlugin",
"Device_TableHead_ParentRelType"
"Device_TableHead_ParentRelType",
"Device_TableHead_Vlan"
],
"localized": ["name", "description"],
"name": [

View File

@@ -448,4 +448,3 @@ def unlock_fields(conn, mac=None, fields=None, clear_all=False):
}
finally:
conn.close()

View File

@@ -110,6 +110,7 @@ FIELD_SPECS = {
"source_col": "devNameSource",
"empty_values": ["", "null", "(unknown)", "(name not found)"],
"priority": ["NSLOOKUP", "AVAHISCAN", "NBTSCAN", "DIGSCAN", "ARPSCAN", "DHCPLSS", "NEWDEV", "N/A"],
"allow_override_if_changed": True,
},
# ==========================================================