Add db_count to DeviceResult and update GraphQL response handling; localize Device_NoMatch_Title in multiple languages

This commit is contained in:
Jokob @NetAlertX
2026-03-13 13:08:26 +00:00
parent 78a8030c6a
commit c9cb1f3fba
23 changed files with 35 additions and 6 deletions

View File

@@ -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": {

View File

@@ -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": "",

View File

@@ -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",

View File

@@ -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": "",

View File

@@ -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",

View File

@@ -208,6 +208,7 @@
"Device_NoData_Help": "If devices don't appear after the scan, check your SCAN_SUBNETS setting and <a href=\"https://docs.netalertx.com/SUBNETS\" target=\"_blank\">documentation</a>.",
"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",

View File

@@ -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",

View File

@@ -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": "",

View File

@@ -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 <a href=\"https://docs.netalertx.com/SUBNETS\" target=\"_blank\">documentation</a>.",
"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",

View File

@@ -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": "",

View File

@@ -208,6 +208,7 @@
"Device_NoData_Help": "Se i dispositivi non vengono visualizzati dopo la scansione, controlla l'impostazione SCAN_SUBNETS e la <a href=\"https://docs.netalertx.com/SUBNETS\" target=\"_blank\">documentazione</a>.",
"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",

View File

@@ -208,6 +208,7 @@
"Device_NoData_Help": "スキャン後にデバイスが表示されない場合は、SCAN_SUBNETS設定と<a href=\"https://docs.netalertx.com/SUBNETS\" target=\"_blank\">ドキュメント</a>を確認してください。",
"Device_NoData_Scanning": "最初のスキャンを待機中 - 初期設定後、数分かかる場合があります。",
"Device_NoData_Title": "デバイスが見つかりません",
"Device_NoMatch_Title": "",
"Device_Save_Failed": "デバイスの保存に失敗しました",
"Device_Save_Unauthorized": "許可されていない - 無効なAPIトークン",
"Device_Saved_Success": "デバイスが正常に保存されました",

View File

@@ -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": "",

View File

@@ -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": "",

View File

@@ -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": "",

View File

@@ -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": "",

View File

@@ -208,6 +208,7 @@
"Device_NoData_Help": "Если устройства не отображаются после сканирования, проверьте настройку SCAN_SUBNETS и <a href=\"https://docs.netalertx.com/SUBNETS\" target=\"_blank\">документацию</a>.",
"Device_NoData_Scanning": "Ожидание первого сканирования — это может занять несколько минут после первоначальной настройки.",
"Device_NoData_Title": "Устройства пока не найдены",
"Device_NoMatch_Title": "",
"Device_Save_Failed": "Не удалось сохранить устройство",
"Device_Save_Unauthorized": "Не авторизован - недействительный токен API",
"Device_Saved_Success": "Устройство успешно сохранено",

View File

@@ -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": "",

View File

@@ -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": "",

View File

@@ -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": "Пристрій успішно збережено",

View File

@@ -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": "",

View File

@@ -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": "设备保存成功",

View File

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