From c9cb1f3fba81794ebeb4bf835304bec1a967708e Mon Sep 17 00:00:00 2001
From: "Jokob @NetAlertX" <96159884+jokob-sk@users.noreply.github.com>
Date: Fri, 13 Mar 2026 13:08:26 +0000
Subject: [PATCH] Add db_count to DeviceResult and update GraphQL response
handling; localize Device_NoMatch_Title in multiple languages
---
front/devices.php | 11 +++++++----
front/php/templates/language/ar_ar.json | 1 +
front/php/templates/language/ca_ca.json | 1 +
front/php/templates/language/cs_cz.json | 1 +
front/php/templates/language/de_de.json | 1 +
front/php/templates/language/en_us.json | 1 +
front/php/templates/language/es_es.json | 1 +
front/php/templates/language/fa_fa.json | 1 +
front/php/templates/language/fr_fr.json | 1 +
front/php/templates/language/id_id.json | 1 +
front/php/templates/language/it_it.json | 1 +
front/php/templates/language/ja_jp.json | 1 +
front/php/templates/language/nb_no.json | 1 +
front/php/templates/language/pl_pl.json | 1 +
front/php/templates/language/pt_br.json | 1 +
front/php/templates/language/pt_pt.json | 1 +
front/php/templates/language/ru_ru.json | 1 +
front/php/templates/language/sv_sv.json | 1 +
front/php/templates/language/tr_tr.json | 1 +
front/php/templates/language/uk_ua.json | 1 +
front/php/templates/language/vi_vn.json | 1 +
front/php/templates/language/zh_cn.json | 1 +
server/api_server/graphql_endpoint.py | 9 +++++++--
23 files changed, 35 insertions(+), 6 deletions(-)
diff --git a/front/devices.php b/front/devices.php
index fdb8f458..a3345f74 100755
--- a/front/devices.php
+++ b/front/devices.php
@@ -767,6 +767,7 @@ function initializeDatatable (status) {
${_gqlFields}
}
count
+ db_count
}
}
`;
@@ -807,9 +808,10 @@ function initializeDatatable (status) {
console.log("Raw response:", res);
const json = res["data"];
- // Set the total number of records for pagination at the *root level* so DataTables sees them
- res.recordsTotal = json.devices.count || 0;
- res.recordsFiltered = json.devices.count || 0;
+ // recordsTotal = raw DB count (before filters/search) so DataTables uses emptyTable
+ // only when the DB is genuinely empty, and zeroRecords when a filter returns nothing.
+ res.recordsTotal = json.devices.db_count || 0;
+ res.recordsFiltered = json.devices.count || 0;
// console.log("recordsTotal:", res.recordsTotal, "recordsFiltered:", res.recordsFiltered);
// console.log("tableRows:", tableRows);
@@ -1049,7 +1051,8 @@ function initializeDatatable (status) {
// Processing
'processing' : true,
'language' : {
- emptyTable: buildEmptyDeviceTableMessage(getString('Device_NextScan_Imminent')),
+ emptyTable: buildEmptyDeviceTableMessage(getString('Device_NextScan_Imminent')),
+ zeroRecords: "= lang('Device_NoMatch_Title');?>",
"lengthMenu": "= lang('Device_Tablelenght');?>",
"search": "= lang('Device_Searchbox');?>: ",
"paginate": {
diff --git a/front/php/templates/language/ar_ar.json b/front/php/templates/language/ar_ar.json
index 98ec45a4..c55ceb2e 100644
--- a/front/php/templates/language/ar_ar.json
+++ b/front/php/templates/language/ar_ar.json
@@ -208,6 +208,7 @@
"Device_NoData_Help": "",
"Device_NoData_Scanning": "",
"Device_NoData_Title": "",
+ "Device_NoMatch_Title": "",
"Device_Save_Failed": "",
"Device_Save_Unauthorized": "",
"Device_Saved_Success": "",
diff --git a/front/php/templates/language/ca_ca.json b/front/php/templates/language/ca_ca.json
index 67b4292b..64057edb 100644
--- a/front/php/templates/language/ca_ca.json
+++ b/front/php/templates/language/ca_ca.json
@@ -208,6 +208,7 @@
"Device_NoData_Help": "",
"Device_NoData_Scanning": "",
"Device_NoData_Title": "",
+ "Device_NoMatch_Title": "",
"Device_Save_Failed": "Problemes guardant el dispositiu",
"Device_Save_Unauthorized": "Token invàlid - No autoritzat",
"Device_Saved_Success": "S'ha guardat el dispositiu",
diff --git a/front/php/templates/language/cs_cz.json b/front/php/templates/language/cs_cz.json
index d03f5774..4627c5e2 100644
--- a/front/php/templates/language/cs_cz.json
+++ b/front/php/templates/language/cs_cz.json
@@ -208,6 +208,7 @@
"Device_NoData_Help": "",
"Device_NoData_Scanning": "",
"Device_NoData_Title": "",
+ "Device_NoMatch_Title": "",
"Device_Save_Failed": "",
"Device_Save_Unauthorized": "",
"Device_Saved_Success": "",
diff --git a/front/php/templates/language/de_de.json b/front/php/templates/language/de_de.json
index 77d4ca40..73c59bd6 100644
--- a/front/php/templates/language/de_de.json
+++ b/front/php/templates/language/de_de.json
@@ -212,6 +212,7 @@
"Device_NoData_Help": "",
"Device_NoData_Scanning": "",
"Device_NoData_Title": "",
+ "Device_NoMatch_Title": "",
"Device_Save_Failed": "",
"Device_Save_Unauthorized": "",
"Device_Saved_Success": "Gerät erfolgreich gespeichert",
diff --git a/front/php/templates/language/en_us.json b/front/php/templates/language/en_us.json
index a51bbdfc..69f3e195 100755
--- a/front/php/templates/language/en_us.json
+++ b/front/php/templates/language/en_us.json
@@ -208,6 +208,7 @@
"Device_NoData_Help": "If devices don't appear after the scan, check your SCAN_SUBNETS setting and documentation.",
"Device_NoData_Scanning": "Waiting for the first scan - this may take several minutes after the initial setup.",
"Device_NoData_Title": "No devices found yet",
+ "Device_NoMatch_Title": "No devices match the current filter",
"Device_Save_Failed": "Failed to save device",
"Device_Save_Unauthorized": "Unauthorized - invalid API token",
"Device_Saved_Success": "Device saved successfully",
diff --git a/front/php/templates/language/es_es.json b/front/php/templates/language/es_es.json
index 577e1fda..dc24a969 100644
--- a/front/php/templates/language/es_es.json
+++ b/front/php/templates/language/es_es.json
@@ -210,6 +210,7 @@
"Device_NoData_Help": "",
"Device_NoData_Scanning": "",
"Device_NoData_Title": "",
+ "Device_NoMatch_Title": "",
"Device_Save_Failed": "Fallo al guardar el dispositivo",
"Device_Save_Unauthorized": "No autorizado - Token de API inválido",
"Device_Saved_Success": "Dispositivo guardado exitósamente",
diff --git a/front/php/templates/language/fa_fa.json b/front/php/templates/language/fa_fa.json
index 8cac2dd3..577ab676 100644
--- a/front/php/templates/language/fa_fa.json
+++ b/front/php/templates/language/fa_fa.json
@@ -208,6 +208,7 @@
"Device_NoData_Help": "",
"Device_NoData_Scanning": "",
"Device_NoData_Title": "",
+ "Device_NoMatch_Title": "",
"Device_Save_Failed": "",
"Device_Save_Unauthorized": "",
"Device_Saved_Success": "",
diff --git a/front/php/templates/language/fr_fr.json b/front/php/templates/language/fr_fr.json
index 4765004f..6c9cbd39 100644
--- a/front/php/templates/language/fr_fr.json
+++ b/front/php/templates/language/fr_fr.json
@@ -208,6 +208,7 @@
"Device_NoData_Help": "Si les appareils n'apparaissent pas après le scan, vérifiez vos paramètres SCAN_SUBNETS et la documentation.",
"Device_NoData_Scanning": "En attente du premier scan - cela peut prendre quelques minutes après le premier paramétrage.",
"Device_NoData_Title": "Aucun appareil trouvé pour le moment",
+ "Device_NoMatch_Title": "",
"Device_Save_Failed": "Erreur à l'enregistrement de l'appareil",
"Device_Save_Unauthorized": "Non autorisé - Jeton d'API invalide",
"Device_Saved_Success": "Appareil enregistré avec succès",
diff --git a/front/php/templates/language/id_id.json b/front/php/templates/language/id_id.json
index c114cb5c..9bff957a 100644
--- a/front/php/templates/language/id_id.json
+++ b/front/php/templates/language/id_id.json
@@ -208,6 +208,7 @@
"Device_NoData_Help": "",
"Device_NoData_Scanning": "",
"Device_NoData_Title": "",
+ "Device_NoMatch_Title": "",
"Device_Save_Failed": "",
"Device_Save_Unauthorized": "",
"Device_Saved_Success": "",
diff --git a/front/php/templates/language/it_it.json b/front/php/templates/language/it_it.json
index 7d741386..07c1f08f 100644
--- a/front/php/templates/language/it_it.json
+++ b/front/php/templates/language/it_it.json
@@ -208,6 +208,7 @@
"Device_NoData_Help": "Se i dispositivi non vengono visualizzati dopo la scansione, controlla l'impostazione SCAN_SUBNETS e la documentazione.",
"Device_NoData_Scanning": "In attesa della prima scansione: potrebbero volerci diversi minuti dopo la configurazione iniziale.",
"Device_NoData_Title": "Ancora nessun dispositivo trovato",
+ "Device_NoMatch_Title": "",
"Device_Save_Failed": "Impossibile salvare il dispositivo",
"Device_Save_Unauthorized": "Non autorizzato: token API non valido",
"Device_Saved_Success": "Dispositivo salvato correttamente",
diff --git a/front/php/templates/language/ja_jp.json b/front/php/templates/language/ja_jp.json
index 7ef5302a..31cfb382 100644
--- a/front/php/templates/language/ja_jp.json
+++ b/front/php/templates/language/ja_jp.json
@@ -208,6 +208,7 @@
"Device_NoData_Help": "スキャン後にデバイスが表示されない場合は、SCAN_SUBNETS設定とドキュメントを確認してください。",
"Device_NoData_Scanning": "最初のスキャンを待機中 - 初期設定後、数分かかる場合があります。",
"Device_NoData_Title": "デバイスが見つかりません",
+ "Device_NoMatch_Title": "",
"Device_Save_Failed": "デバイスの保存に失敗しました",
"Device_Save_Unauthorized": "許可されていない - 無効なAPIトークン",
"Device_Saved_Success": "デバイスが正常に保存されました",
diff --git a/front/php/templates/language/nb_no.json b/front/php/templates/language/nb_no.json
index 3fc67966..504732b6 100644
--- a/front/php/templates/language/nb_no.json
+++ b/front/php/templates/language/nb_no.json
@@ -208,6 +208,7 @@
"Device_NoData_Help": "",
"Device_NoData_Scanning": "",
"Device_NoData_Title": "",
+ "Device_NoMatch_Title": "",
"Device_Save_Failed": "",
"Device_Save_Unauthorized": "",
"Device_Saved_Success": "",
diff --git a/front/php/templates/language/pl_pl.json b/front/php/templates/language/pl_pl.json
index 1e46dc20..94f1f7d9 100644
--- a/front/php/templates/language/pl_pl.json
+++ b/front/php/templates/language/pl_pl.json
@@ -208,6 +208,7 @@
"Device_NoData_Help": "",
"Device_NoData_Scanning": "",
"Device_NoData_Title": "",
+ "Device_NoMatch_Title": "",
"Device_Save_Failed": "",
"Device_Save_Unauthorized": "",
"Device_Saved_Success": "",
diff --git a/front/php/templates/language/pt_br.json b/front/php/templates/language/pt_br.json
index 2005b90e..b120aa80 100644
--- a/front/php/templates/language/pt_br.json
+++ b/front/php/templates/language/pt_br.json
@@ -208,6 +208,7 @@
"Device_NoData_Help": "",
"Device_NoData_Scanning": "",
"Device_NoData_Title": "",
+ "Device_NoMatch_Title": "",
"Device_Save_Failed": "",
"Device_Save_Unauthorized": "",
"Device_Saved_Success": "",
diff --git a/front/php/templates/language/pt_pt.json b/front/php/templates/language/pt_pt.json
index b60aa27d..bdba833e 100644
--- a/front/php/templates/language/pt_pt.json
+++ b/front/php/templates/language/pt_pt.json
@@ -208,6 +208,7 @@
"Device_NoData_Help": "",
"Device_NoData_Scanning": "",
"Device_NoData_Title": "",
+ "Device_NoMatch_Title": "",
"Device_Save_Failed": "",
"Device_Save_Unauthorized": "",
"Device_Saved_Success": "",
diff --git a/front/php/templates/language/ru_ru.json b/front/php/templates/language/ru_ru.json
index 020eceb4..22e67343 100644
--- a/front/php/templates/language/ru_ru.json
+++ b/front/php/templates/language/ru_ru.json
@@ -208,6 +208,7 @@
"Device_NoData_Help": "Если устройства не отображаются после сканирования, проверьте настройку SCAN_SUBNETS и документацию.",
"Device_NoData_Scanning": "Ожидание первого сканирования — это может занять несколько минут после первоначальной настройки.",
"Device_NoData_Title": "Устройства пока не найдены",
+ "Device_NoMatch_Title": "",
"Device_Save_Failed": "Не удалось сохранить устройство",
"Device_Save_Unauthorized": "Не авторизован - недействительный токен API",
"Device_Saved_Success": "Устройство успешно сохранено",
diff --git a/front/php/templates/language/sv_sv.json b/front/php/templates/language/sv_sv.json
index c114cb5c..9bff957a 100644
--- a/front/php/templates/language/sv_sv.json
+++ b/front/php/templates/language/sv_sv.json
@@ -208,6 +208,7 @@
"Device_NoData_Help": "",
"Device_NoData_Scanning": "",
"Device_NoData_Title": "",
+ "Device_NoMatch_Title": "",
"Device_Save_Failed": "",
"Device_Save_Unauthorized": "",
"Device_Saved_Success": "",
diff --git a/front/php/templates/language/tr_tr.json b/front/php/templates/language/tr_tr.json
index e9e3d63c..12745894 100644
--- a/front/php/templates/language/tr_tr.json
+++ b/front/php/templates/language/tr_tr.json
@@ -208,6 +208,7 @@
"Device_NoData_Help": "",
"Device_NoData_Scanning": "",
"Device_NoData_Title": "",
+ "Device_NoMatch_Title": "",
"Device_Save_Failed": "",
"Device_Save_Unauthorized": "",
"Device_Saved_Success": "",
diff --git a/front/php/templates/language/uk_ua.json b/front/php/templates/language/uk_ua.json
index 3fe7e7ca..41ef856e 100644
--- a/front/php/templates/language/uk_ua.json
+++ b/front/php/templates/language/uk_ua.json
@@ -208,6 +208,7 @@
"Device_NoData_Help": "",
"Device_NoData_Scanning": "",
"Device_NoData_Title": "",
+ "Device_NoMatch_Title": "",
"Device_Save_Failed": "Не вдалося зберегти пристрій",
"Device_Save_Unauthorized": "Неавторизовано – недійсний токен API",
"Device_Saved_Success": "Пристрій успішно збережено",
diff --git a/front/php/templates/language/vi_vn.json b/front/php/templates/language/vi_vn.json
index c114cb5c..9bff957a 100644
--- a/front/php/templates/language/vi_vn.json
+++ b/front/php/templates/language/vi_vn.json
@@ -208,6 +208,7 @@
"Device_NoData_Help": "",
"Device_NoData_Scanning": "",
"Device_NoData_Title": "",
+ "Device_NoMatch_Title": "",
"Device_Save_Failed": "",
"Device_Save_Unauthorized": "",
"Device_Saved_Success": "",
diff --git a/front/php/templates/language/zh_cn.json b/front/php/templates/language/zh_cn.json
index 17321914..8591a191 100644
--- a/front/php/templates/language/zh_cn.json
+++ b/front/php/templates/language/zh_cn.json
@@ -208,6 +208,7 @@
"Device_NoData_Help": "",
"Device_NoData_Scanning": "",
"Device_NoData_Title": "",
+ "Device_NoMatch_Title": "",
"Device_Save_Failed": "保存设备失败",
"Device_Save_Unauthorized": "未授权 - API 令牌无效",
"Device_Saved_Success": "设备保存成功",
diff --git a/server/api_server/graphql_endpoint.py b/server/api_server/graphql_endpoint.py
index 0396ed7d..ba417d84 100755
--- a/server/api_server/graphql_endpoint.py
+++ b/server/api_server/graphql_endpoint.py
@@ -108,6 +108,7 @@ class Device(ObjectType):
class DeviceResult(ObjectType):
devices = List(Device)
count = Int()
+ db_count = Int(description="Total device count in the database, before any status/filter/search is applied")
# --- SETTINGS ---
@@ -198,7 +199,7 @@ class Query(ObjectType):
devices_data = json.load(f)["data"]
except (FileNotFoundError, json.JSONDecodeError) as e:
mylog("none", f"[graphql_schema] Error loading devices data: {e}")
- return DeviceResult(devices=[], count=0)
+ return DeviceResult(devices=[], count=0, db_count=0)
# Int fields that may arrive from the DB as empty strings — coerce to None
_INT_FIELDS = [
@@ -223,6 +224,10 @@ class Query(ObjectType):
mylog("trace", f"[graphql_schema] devices_data: {devices_data}")
+ # Raw DB count — before any status, filter, or search is applied.
+ # Used by the frontend to distinguish "no devices in DB" from "filter returned nothing".
+ db_count = len(devices_data)
+
# initialize total_count
total_count = len(devices_data)
@@ -439,7 +444,7 @@ class Query(ObjectType):
# Convert dict objects to Device instances to enable field resolution
devices = [Device(**device) for device in devices_data]
- return DeviceResult(devices=devices, count=total_count)
+ return DeviceResult(devices=devices, count=total_count, db_count=db_count)
# --- SETTINGS ---
settings = Field(SettingResult, filters=List(FilterOptionsInput))