mirror of
https://github.com/optim-enterprises-bv/OptimCloud-gw-ui.git
synced 2025-10-29 09:22:21 +00:00
[WIFI-13170] Advanced system page
Signed-off-by: Charles <charles.bourque96@gmail.com>
This commit is contained in:
4
package-lock.json
generated
4
package-lock.json
generated
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "ucentral-client",
|
"name": "ucentral-client",
|
||||||
"version": "2.11.0(16)",
|
"version": "3.0.0(1)",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "ucentral-client",
|
"name": "ucentral-client",
|
||||||
"version": "2.11.0(16)",
|
"version": "3.0.0(1)",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@chakra-ui/anatomy": "^2.1.1",
|
"@chakra-ui/anatomy": "^2.1.1",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "ucentral-client",
|
"name": "ucentral-client",
|
||||||
"version": "2.11.0(16)",
|
"version": "3.0.0(1)",
|
||||||
"description": "",
|
"description": "",
|
||||||
"private": true,
|
"private": true,
|
||||||
"main": "index.tsx",
|
"main": "index.tsx",
|
||||||
|
|||||||
@@ -269,6 +269,7 @@
|
|||||||
"map": "Karte",
|
"map": "Karte",
|
||||||
"max": "Max",
|
"max": "Max",
|
||||||
"min": "MINDEST",
|
"min": "MINDEST",
|
||||||
|
"miscellaneous": "Verschiedenes",
|
||||||
"mode": "Modus",
|
"mode": "Modus",
|
||||||
"model": "Modell",
|
"model": "Modell",
|
||||||
"modified": "Geändert",
|
"modified": "Geändert",
|
||||||
@@ -737,6 +738,7 @@
|
|||||||
"form": {
|
"form": {
|
||||||
"captive_web_root_explanation": "Bitte verwenden Sie nur .tar-Dateien (keine komprimierten Dateien wie z. B. .targz)",
|
"captive_web_root_explanation": "Bitte verwenden Sie nur .tar-Dateien (keine komprimierten Dateien wie z. B. .targz)",
|
||||||
"certificate_file_explanation": "Bitte verwenden Sie eine .pem-Datei, die mit „-----BEGIN CERTIFICATE-----“ beginnt und mit „-----END CERTIFICATE-----“ endet.",
|
"certificate_file_explanation": "Bitte verwenden Sie eine .pem-Datei, die mit „-----BEGIN CERTIFICATE-----“ beginnt und mit „-----END CERTIFICATE-----“ endet.",
|
||||||
|
"invalid_alphanumeric_with_dash": "Akzeptierte Zeichen. sind nur alphanumerisch (Buchstaben & Zahlen)",
|
||||||
"invalid_cidr": "Ungültige CIDR-IPv4-Adresse. Beispiel: 192.168.0.1/12",
|
"invalid_cidr": "Ungültige CIDR-IPv4-Adresse. Beispiel: 192.168.0.1/12",
|
||||||
"invalid_email": "Ungültige E-Mail",
|
"invalid_email": "Ungültige E-Mail",
|
||||||
"invalid_file_content": "Ungültiger Dateiinhalt, bitte bestätigen Sie, dass es sich um ein gültiges Format handelt",
|
"invalid_file_content": "Ungültiger Dateiinhalt, bitte bestätigen Sie, dass es sich um ein gültiges Format handelt",
|
||||||
@@ -763,7 +765,11 @@
|
|||||||
"invalid_static_ipv4_e": "Ungültige Adresse, dieser Bereich ist für Experimente reserviert (Klasse E). Das erste Oktett sollte 223 oder niedriger sein",
|
"invalid_static_ipv4_e": "Ungültige Adresse, dieser Bereich ist für Experimente reserviert (Klasse E). Das erste Oktett sollte 223 oder niedriger sein",
|
||||||
"invalid_third_party": "Ungültige Drittanbieter-JSON-Zeichenfolge. Bitte bestätigen Sie, dass Ihr Wert ein gültiges JSON ist",
|
"invalid_third_party": "Ungültige Drittanbieter-JSON-Zeichenfolge. Bitte bestätigen Sie, dass Ihr Wert ein gültiges JSON ist",
|
||||||
"key_file_explanation": "Bitte verwenden Sie eine .pem-Datei, die mit „-----BEGIN PRIVATE KEY-----“ beginnt und mit „-----END PRIVATE KEY-----“ endet.",
|
"key_file_explanation": "Bitte verwenden Sie eine .pem-Datei, die mit „-----BEGIN PRIVATE KEY-----“ beginnt und mit „-----END PRIVATE KEY-----“ endet.",
|
||||||
|
"max_length": "Maximale Länge von {{max}} Zeichen.",
|
||||||
|
"max_value": "Maximalwert von {{max}}",
|
||||||
|
"min_length": "Mindestlänge von {{min}} Zeichen.",
|
||||||
"min_max_string": "Der Wert muss eine Länge zwischen {{min}} (einschließlich) und {{max}} (einschließlich) haben.",
|
"min_max_string": "Der Wert muss eine Länge zwischen {{min}} (einschließlich) und {{max}} (einschließlich) haben.",
|
||||||
|
"min_value": "Mindestwert von {{min}}",
|
||||||
"missing_interface_upstream": "Sie müssen mindestens eine Upstream-Schnittstelle haben. Im Moment sind alle Ihre Schnittstellen nachgelagert",
|
"missing_interface_upstream": "Sie müssen mindestens eine Upstream-Schnittstelle haben. Im Moment sind alle Ihre Schnittstellen nachgelagert",
|
||||||
"new_email_to_notify": "Neue E-Mail zur Benachrichtigung",
|
"new_email_to_notify": "Neue E-Mail zur Benachrichtigung",
|
||||||
"new_phone_to_notify": "Neues Telefon zu benachrichtigen",
|
"new_phone_to_notify": "Neues Telefon zu benachrichtigen",
|
||||||
@@ -905,6 +911,11 @@
|
|||||||
"one": "Benachrichtigung",
|
"one": "Benachrichtigung",
|
||||||
"other": "Benachrichtigungen"
|
"other": "Benachrichtigungen"
|
||||||
},
|
},
|
||||||
|
"openroaming": {
|
||||||
|
"pool_strategy": "Pool-Strategie",
|
||||||
|
"radius_endpoint_one": "Radiusendpunkt",
|
||||||
|
"radius_endpoint_other": "Radiusendpunkte"
|
||||||
|
},
|
||||||
"operator": {
|
"operator": {
|
||||||
"delete_explanation": "Möchten Sie diesen Operator wirklich löschen? Dieser Vorgang ist nicht umkehrbar",
|
"delete_explanation": "Möchten Sie diesen Operator wirklich löschen? Dieser Vorgang ist nicht umkehrbar",
|
||||||
"delete_operator": "Betreiber löschen",
|
"delete_operator": "Betreiber löschen",
|
||||||
@@ -970,6 +981,27 @@
|
|||||||
"title": "Beschränkungen",
|
"title": "Beschränkungen",
|
||||||
"tty": "TTY-Zugriff"
|
"tty": "TTY-Zugriff"
|
||||||
},
|
},
|
||||||
|
"roaming": {
|
||||||
|
"account_created": "Neues Konto erstellt!",
|
||||||
|
"account_deleted": "Konto gelöscht!",
|
||||||
|
"account_one": "Konto",
|
||||||
|
"account_other": "Konten",
|
||||||
|
"certificate_deleted": "Zertifikat gelöscht!",
|
||||||
|
"certificate_one": "Zertifikat",
|
||||||
|
"certificate_other": "Zertifikate",
|
||||||
|
"city": "Stadt",
|
||||||
|
"common_name": "Gemeinsamen Namen",
|
||||||
|
"country": "Land",
|
||||||
|
"global_reach": "Globale Reichweite",
|
||||||
|
"global_reach_account_id": "Konto-ID",
|
||||||
|
"invalid_certificate": "Ungültiges Zertifikat",
|
||||||
|
"invalid_key": "Ungültiger privater Schlüssel",
|
||||||
|
"location_details_title": "Ort",
|
||||||
|
"organization": "Organisation",
|
||||||
|
"private_key": "Privat Schlüssel",
|
||||||
|
"province": "Provinz",
|
||||||
|
"state": "Zustand"
|
||||||
|
},
|
||||||
"rrm": {
|
"rrm": {
|
||||||
"algorithm": "Algorithmus",
|
"algorithm": "Algorithmus",
|
||||||
"algorithm_other": "Algorithmen",
|
"algorithm_other": "Algorithmen",
|
||||||
@@ -1091,6 +1123,7 @@
|
|||||||
"title": "Abonnenten"
|
"title": "Abonnenten"
|
||||||
},
|
},
|
||||||
"system": {
|
"system": {
|
||||||
|
"advanced": "Erweitert",
|
||||||
"backend_logs": "Back-End-Protokolle",
|
"backend_logs": "Back-End-Protokolle",
|
||||||
"configuration": "Aufbau",
|
"configuration": "Aufbau",
|
||||||
"could_not_retrieve": "Fehler: {{name}} Systeminformationen konnten nicht abgerufen werden",
|
"could_not_retrieve": "Fehler: {{name}} Systeminformationen konnten nicht abgerufen werden",
|
||||||
|
|||||||
@@ -269,6 +269,7 @@
|
|||||||
"map": "Map",
|
"map": "Map",
|
||||||
"max": "Max",
|
"max": "Max",
|
||||||
"min": "Min",
|
"min": "Min",
|
||||||
|
"miscellaneous": "Miscellaneous",
|
||||||
"mode": "Mode",
|
"mode": "Mode",
|
||||||
"model": "Model",
|
"model": "Model",
|
||||||
"modified": "Modified",
|
"modified": "Modified",
|
||||||
@@ -737,6 +738,7 @@
|
|||||||
"form": {
|
"form": {
|
||||||
"captive_web_root_explanation": "Please use .tar files only (no compressed files like .targz, for example)",
|
"captive_web_root_explanation": "Please use .tar files only (no compressed files like .targz, for example)",
|
||||||
"certificate_file_explanation": "Please use a .pem file that starts with \"-----BEGIN CERTIFICATE-----\" and ends with \"-----END CERTIFICATE-----\"",
|
"certificate_file_explanation": "Please use a .pem file that starts with \"-----BEGIN CERTIFICATE-----\" and ends with \"-----END CERTIFICATE-----\"",
|
||||||
|
"invalid_alphanumeric_with_dash": "Accepted chars. are only alphanumeric (letters & numbers)",
|
||||||
"invalid_cidr": "Invalid CIDR IPv4 address. Example: 192.168.0.1/12",
|
"invalid_cidr": "Invalid CIDR IPv4 address. Example: 192.168.0.1/12",
|
||||||
"invalid_email": "Invalid Email",
|
"invalid_email": "Invalid Email",
|
||||||
"invalid_file_content": "Invalid file content, please confirm that it is of the valid format",
|
"invalid_file_content": "Invalid file content, please confirm that it is of the valid format",
|
||||||
@@ -763,7 +765,11 @@
|
|||||||
"invalid_static_ipv4_e": "Invalid address, this range reserved for experiments (class E). The first octet should be 223 or lower",
|
"invalid_static_ipv4_e": "Invalid address, this range reserved for experiments (class E). The first octet should be 223 or lower",
|
||||||
"invalid_third_party": "Invalid Third Party JSON string. Please confirm that your value is a valid JSON",
|
"invalid_third_party": "Invalid Third Party JSON string. Please confirm that your value is a valid JSON",
|
||||||
"key_file_explanation": "Please use a .pem file that starts with \"-----BEGIN PRIVATE KEY-----\" and ends with \"-----END PRIVATE KEY-----\"",
|
"key_file_explanation": "Please use a .pem file that starts with \"-----BEGIN PRIVATE KEY-----\" and ends with \"-----END PRIVATE KEY-----\"",
|
||||||
|
"max_length": "Maximum length of {{max}} chars.",
|
||||||
|
"max_value": "Maximum value of {{max}}",
|
||||||
|
"min_length": "Minimum length of {{min}} chars.",
|
||||||
"min_max_string": "Value needs to be of a length between {{min}} (inclusive) and {{max}} (inclusive)",
|
"min_max_string": "Value needs to be of a length between {{min}} (inclusive) and {{max}} (inclusive)",
|
||||||
|
"min_value": "Minimum value of {{min}}",
|
||||||
"missing_interface_upstream": "You need to have at least one upstream interface. At the moment, all your interfaces are downstream",
|
"missing_interface_upstream": "You need to have at least one upstream interface. At the moment, all your interfaces are downstream",
|
||||||
"new_email_to_notify": "New email to notify",
|
"new_email_to_notify": "New email to notify",
|
||||||
"new_phone_to_notify": "New phone to notify",
|
"new_phone_to_notify": "New phone to notify",
|
||||||
@@ -905,6 +911,11 @@
|
|||||||
"one": "Notification",
|
"one": "Notification",
|
||||||
"other": "Notifications"
|
"other": "Notifications"
|
||||||
},
|
},
|
||||||
|
"openroaming": {
|
||||||
|
"pool_strategy": "Pool Strategy",
|
||||||
|
"radius_endpoint_one": "Radius Endpoint",
|
||||||
|
"radius_endpoint_other": "Radius Endpoints"
|
||||||
|
},
|
||||||
"operator": {
|
"operator": {
|
||||||
"delete_explanation": "Are you sure you want to delete this operator? This operation is not reversible",
|
"delete_explanation": "Are you sure you want to delete this operator? This operation is not reversible",
|
||||||
"delete_operator": "Delete Operator",
|
"delete_operator": "Delete Operator",
|
||||||
@@ -970,6 +981,27 @@
|
|||||||
"title": "Restrictions",
|
"title": "Restrictions",
|
||||||
"tty": "TTY Access"
|
"tty": "TTY Access"
|
||||||
},
|
},
|
||||||
|
"roaming": {
|
||||||
|
"account_created": "New account created!",
|
||||||
|
"account_deleted": "Deleted account!",
|
||||||
|
"account_one": "Account",
|
||||||
|
"account_other": "Accounts",
|
||||||
|
"certificate_deleted": "Deleted certificate!",
|
||||||
|
"certificate_one": "Certificate",
|
||||||
|
"certificate_other": "Certificates",
|
||||||
|
"city": "City",
|
||||||
|
"common_name": "Common Name",
|
||||||
|
"country": "Country",
|
||||||
|
"global_reach": "GlobalReach",
|
||||||
|
"global_reach_account_id": " Account ID",
|
||||||
|
"invalid_certificate": "Invalid certificate",
|
||||||
|
"invalid_key": "Invalid private key",
|
||||||
|
"location_details_title": "Location",
|
||||||
|
"organization": "Organization",
|
||||||
|
"private_key": "Private Key",
|
||||||
|
"province": "Province",
|
||||||
|
"state": "State"
|
||||||
|
},
|
||||||
"rrm": {
|
"rrm": {
|
||||||
"algorithm": "Algorithm",
|
"algorithm": "Algorithm",
|
||||||
"algorithm_other": "Algorithms",
|
"algorithm_other": "Algorithms",
|
||||||
@@ -1091,6 +1123,7 @@
|
|||||||
"title": "Subscribers"
|
"title": "Subscribers"
|
||||||
},
|
},
|
||||||
"system": {
|
"system": {
|
||||||
|
"advanced": "Advanced",
|
||||||
"backend_logs": "Back-End Logs",
|
"backend_logs": "Back-End Logs",
|
||||||
"configuration": "Configuration",
|
"configuration": "Configuration",
|
||||||
"could_not_retrieve": "Error: could not retrieve {{name}} system information",
|
"could_not_retrieve": "Error: could not retrieve {{name}} system information",
|
||||||
|
|||||||
@@ -269,6 +269,7 @@
|
|||||||
"map": "Mapa",
|
"map": "Mapa",
|
||||||
"max": "Max",
|
"max": "Max",
|
||||||
"min": "Min",
|
"min": "Min",
|
||||||
|
"miscellaneous": "Diverso",
|
||||||
"mode": "Modo",
|
"mode": "Modo",
|
||||||
"model": "Modelo",
|
"model": "Modelo",
|
||||||
"modified": "Modificado",
|
"modified": "Modificado",
|
||||||
@@ -737,6 +738,7 @@
|
|||||||
"form": {
|
"form": {
|
||||||
"captive_web_root_explanation": "Utilice únicamente archivos .tar (no archivos comprimidos como .targz, por ejemplo)",
|
"captive_web_root_explanation": "Utilice únicamente archivos .tar (no archivos comprimidos como .targz, por ejemplo)",
|
||||||
"certificate_file_explanation": "Utilice un archivo .pem que comience con \"-----BEGIN CERTIFICATE-----\" y termine con \"-----END CERTIFICATE-----\"",
|
"certificate_file_explanation": "Utilice un archivo .pem que comience con \"-----BEGIN CERTIFICATE-----\" y termine con \"-----END CERTIFICATE-----\"",
|
||||||
|
"invalid_alphanumeric_with_dash": "Caracteres aceptados. son solo alfanuméricos (letras y números)",
|
||||||
"invalid_cidr": "Dirección IPv4 CIDR no válida. Ejemplo: 192.168.0.1/12",
|
"invalid_cidr": "Dirección IPv4 CIDR no válida. Ejemplo: 192.168.0.1/12",
|
||||||
"invalid_email": "Email inválido",
|
"invalid_email": "Email inválido",
|
||||||
"invalid_file_content": "Contenido de archivo no válido, confirme que tiene un formato válido",
|
"invalid_file_content": "Contenido de archivo no válido, confirme que tiene un formato válido",
|
||||||
@@ -763,7 +765,11 @@
|
|||||||
"invalid_static_ipv4_e": "Dirección no válida, este rango reservado para experimentos (clase E). El primer octeto debe ser 223 o inferior",
|
"invalid_static_ipv4_e": "Dirección no válida, este rango reservado para experimentos (clase E). El primer octeto debe ser 223 o inferior",
|
||||||
"invalid_third_party": "Cadena JSON de terceros no válida. Confirme que su valor es un JSON válido",
|
"invalid_third_party": "Cadena JSON de terceros no válida. Confirme que su valor es un JSON válido",
|
||||||
"key_file_explanation": "Utilice un archivo .pem que comience con \"-----BEGIN PRIVATE KEY-----\" y termine con \"-----END PRIVATE KEY-----\"",
|
"key_file_explanation": "Utilice un archivo .pem que comience con \"-----BEGIN PRIVATE KEY-----\" y termine con \"-----END PRIVATE KEY-----\"",
|
||||||
|
"max_length": "Longitud máxima de {{max}} caracteres.",
|
||||||
|
"max_value": "Valor máximo de {{max}}",
|
||||||
|
"min_length": "Longitud mínima de {{min}} caracteres.",
|
||||||
"min_max_string": "El valor debe tener una longitud entre {{min}} (inclusive) y {{max}} (inclusive)",
|
"min_max_string": "El valor debe tener una longitud entre {{min}} (inclusive) y {{max}} (inclusive)",
|
||||||
|
"min_value": "Valor mínimo de {{min}}",
|
||||||
"missing_interface_upstream": "Debe tener al menos una interfaz ascendente. Por el momento, todas sus interfaces están en sentido descendente",
|
"missing_interface_upstream": "Debe tener al menos una interfaz ascendente. Por el momento, todas sus interfaces están en sentido descendente",
|
||||||
"new_email_to_notify": "Nuevo correo electrónico para notificar",
|
"new_email_to_notify": "Nuevo correo electrónico para notificar",
|
||||||
"new_phone_to_notify": "Nuevo teléfono para avisar",
|
"new_phone_to_notify": "Nuevo teléfono para avisar",
|
||||||
@@ -905,6 +911,11 @@
|
|||||||
"one": "Notificación",
|
"one": "Notificación",
|
||||||
"other": "Notificaciones"
|
"other": "Notificaciones"
|
||||||
},
|
},
|
||||||
|
"openroaming": {
|
||||||
|
"pool_strategy": "Estrategia de piscina",
|
||||||
|
"radius_endpoint_one": "Punto final del radio",
|
||||||
|
"radius_endpoint_other": "Puntos finales de radio"
|
||||||
|
},
|
||||||
"operator": {
|
"operator": {
|
||||||
"delete_explanation": "¿Está seguro de que desea eliminar este operador? Esta operación no es reversible.",
|
"delete_explanation": "¿Está seguro de que desea eliminar este operador? Esta operación no es reversible.",
|
||||||
"delete_operator": "Eliminar operador",
|
"delete_operator": "Eliminar operador",
|
||||||
@@ -970,6 +981,27 @@
|
|||||||
"title": "Las restricciones",
|
"title": "Las restricciones",
|
||||||
"tty": "Acceso TTY"
|
"tty": "Acceso TTY"
|
||||||
},
|
},
|
||||||
|
"roaming": {
|
||||||
|
"account_created": "¡Nueva cuenta creada!",
|
||||||
|
"account_deleted": "¡Cuenta eliminada!",
|
||||||
|
"account_one": "Cuenta",
|
||||||
|
"account_other": "Cuentas",
|
||||||
|
"certificate_deleted": "Certificado eliminado!",
|
||||||
|
"certificate_one": "Certificado",
|
||||||
|
"certificate_other": "Certificados",
|
||||||
|
"city": "ciudad",
|
||||||
|
"common_name": "Nombre común",
|
||||||
|
"country": "País",
|
||||||
|
"global_reach": "Alcance global",
|
||||||
|
"global_reach_account_id": "ID de cuenta ",
|
||||||
|
"invalid_certificate": "Certificado inválido",
|
||||||
|
"invalid_key": "Clave privada no válida",
|
||||||
|
"location_details_title": "Ubicación",
|
||||||
|
"organization": "Organización",
|
||||||
|
"private_key": "Llave privada",
|
||||||
|
"province": "Provincia",
|
||||||
|
"state": "Estado"
|
||||||
|
},
|
||||||
"rrm": {
|
"rrm": {
|
||||||
"algorithm": "Algoritmo",
|
"algorithm": "Algoritmo",
|
||||||
"algorithm_other": "Algoritmos",
|
"algorithm_other": "Algoritmos",
|
||||||
@@ -1091,6 +1123,7 @@
|
|||||||
"title": "Suscriptores"
|
"title": "Suscriptores"
|
||||||
},
|
},
|
||||||
"system": {
|
"system": {
|
||||||
|
"advanced": "Avanzado",
|
||||||
"backend_logs": "Registros de back-end",
|
"backend_logs": "Registros de back-end",
|
||||||
"configuration": "Configuración",
|
"configuration": "Configuración",
|
||||||
"could_not_retrieve": "Error: no se pudo recuperar la información del sistema {{name}} ",
|
"could_not_retrieve": "Error: no se pudo recuperar la información del sistema {{name}} ",
|
||||||
|
|||||||
@@ -269,6 +269,7 @@
|
|||||||
"map": "Carte",
|
"map": "Carte",
|
||||||
"max": "Max",
|
"max": "Max",
|
||||||
"min": "Min",
|
"min": "Min",
|
||||||
|
"miscellaneous": "Divers",
|
||||||
"mode": "Mode",
|
"mode": "Mode",
|
||||||
"model": "Modèle",
|
"model": "Modèle",
|
||||||
"modified": "Modifié",
|
"modified": "Modifié",
|
||||||
@@ -737,6 +738,7 @@
|
|||||||
"form": {
|
"form": {
|
||||||
"captive_web_root_explanation": "Veuillez utiliser uniquement des fichiers .tar (pas de fichiers compressés comme .targz, par exemple)",
|
"captive_web_root_explanation": "Veuillez utiliser uniquement des fichiers .tar (pas de fichiers compressés comme .targz, par exemple)",
|
||||||
"certificate_file_explanation": "Veuillez utiliser un fichier .pem qui commence par \"-----BEGIN CERTIFICATE-----\" et se termine par \"-----END CERTIFICATE-----\"",
|
"certificate_file_explanation": "Veuillez utiliser un fichier .pem qui commence par \"-----BEGIN CERTIFICATE-----\" et se termine par \"-----END CERTIFICATE-----\"",
|
||||||
|
"invalid_alphanumeric_with_dash": "Caractères acceptés. sont uniquement alphanumériques (lettres et chiffres)",
|
||||||
"invalid_cidr": "Adresse IPv4 CIDR non valide. Exemple : 192.168.0.1/12",
|
"invalid_cidr": "Adresse IPv4 CIDR non valide. Exemple : 192.168.0.1/12",
|
||||||
"invalid_email": "Email Invalide",
|
"invalid_email": "Email Invalide",
|
||||||
"invalid_file_content": "Contenu de fichier non valide, veuillez confirmer qu'il est au format valide",
|
"invalid_file_content": "Contenu de fichier non valide, veuillez confirmer qu'il est au format valide",
|
||||||
@@ -763,7 +765,11 @@
|
|||||||
"invalid_static_ipv4_e": "Adresse invalide, cette plage est réservée aux expérimentations (classe E). Le premier octet doit être 223 ou moins",
|
"invalid_static_ipv4_e": "Adresse invalide, cette plage est réservée aux expérimentations (classe E). Le premier octet doit être 223 ou moins",
|
||||||
"invalid_third_party": "Chaîne JSON tierce non valide. Veuillez confirmer que votre valeur est un JSON valide",
|
"invalid_third_party": "Chaîne JSON tierce non valide. Veuillez confirmer que votre valeur est un JSON valide",
|
||||||
"key_file_explanation": "Veuillez utiliser un fichier .pem qui commence par \"-----BEGIN PRIVATE KEY-----\" et se termine par \"-----END PRIVATE KEY-----\"",
|
"key_file_explanation": "Veuillez utiliser un fichier .pem qui commence par \"-----BEGIN PRIVATE KEY-----\" et se termine par \"-----END PRIVATE KEY-----\"",
|
||||||
|
"max_length": "Longueur maximale de {{max}} caractères.",
|
||||||
|
"max_value": "Valeur maximale de {{max}}",
|
||||||
|
"min_length": "Longueur minimale de {{min}} caractères.",
|
||||||
"min_max_string": "La valeur doit être d'une longueur comprise entre {{min}} (inclus) et {{max}} (inclus)",
|
"min_max_string": "La valeur doit être d'une longueur comprise entre {{min}} (inclus) et {{max}} (inclus)",
|
||||||
|
"min_value": "Valeur minimale de {{min}}",
|
||||||
"missing_interface_upstream": "Vous devez avoir au moins une interface en amont. Pour le moment, toutes vos interfaces sont en aval",
|
"missing_interface_upstream": "Vous devez avoir au moins une interface en amont. Pour le moment, toutes vos interfaces sont en aval",
|
||||||
"new_email_to_notify": "Nouvel e-mail à notifier",
|
"new_email_to_notify": "Nouvel e-mail à notifier",
|
||||||
"new_phone_to_notify": "Nouveau téléphone à notifier",
|
"new_phone_to_notify": "Nouveau téléphone à notifier",
|
||||||
@@ -905,6 +911,11 @@
|
|||||||
"one": "Notification",
|
"one": "Notification",
|
||||||
"other": "Les notifications"
|
"other": "Les notifications"
|
||||||
},
|
},
|
||||||
|
"openroaming": {
|
||||||
|
"pool_strategy": "Stratégie de pool",
|
||||||
|
"radius_endpoint_one": "Point final de rayon",
|
||||||
|
"radius_endpoint_other": "Points de terminaison du rayon"
|
||||||
|
},
|
||||||
"operator": {
|
"operator": {
|
||||||
"delete_explanation": "Voulez-vous vraiment supprimer cet opérateur ? Cette opération n'est pas réversible",
|
"delete_explanation": "Voulez-vous vraiment supprimer cet opérateur ? Cette opération n'est pas réversible",
|
||||||
"delete_operator": "Supprimer l'opérateur",
|
"delete_operator": "Supprimer l'opérateur",
|
||||||
@@ -970,6 +981,27 @@
|
|||||||
"title": "Restrictions",
|
"title": "Restrictions",
|
||||||
"tty": "Accès ATS"
|
"tty": "Accès ATS"
|
||||||
},
|
},
|
||||||
|
"roaming": {
|
||||||
|
"account_created": "Nouveau compte créé !",
|
||||||
|
"account_deleted": "Compte supprimé !",
|
||||||
|
"account_one": "Compte",
|
||||||
|
"account_other": "Comptes",
|
||||||
|
"certificate_deleted": "Certificat supprimé !",
|
||||||
|
"certificate_one": "Certificat",
|
||||||
|
"certificate_other": "Certificats",
|
||||||
|
"city": "Ville",
|
||||||
|
"common_name": "Nom commun",
|
||||||
|
"country": "Pays",
|
||||||
|
"global_reach": "Portée mondiale",
|
||||||
|
"global_reach_account_id": "ID de compte ",
|
||||||
|
"invalid_certificate": "certificat invalide",
|
||||||
|
"invalid_key": "Clé privée invalide",
|
||||||
|
"location_details_title": "Emplacement",
|
||||||
|
"organization": "Organisation",
|
||||||
|
"private_key": "Clé privée",
|
||||||
|
"province": "province",
|
||||||
|
"state": "Etat"
|
||||||
|
},
|
||||||
"rrm": {
|
"rrm": {
|
||||||
"algorithm": "Algorithme",
|
"algorithm": "Algorithme",
|
||||||
"algorithm_other": "Algorithmes",
|
"algorithm_other": "Algorithmes",
|
||||||
@@ -1091,6 +1123,7 @@
|
|||||||
"title": "Les abonnés"
|
"title": "Les abonnés"
|
||||||
},
|
},
|
||||||
"system": {
|
"system": {
|
||||||
|
"advanced": "Avancée",
|
||||||
"backend_logs": "Journaux principaux",
|
"backend_logs": "Journaux principaux",
|
||||||
"configuration": "Configuration",
|
"configuration": "Configuration",
|
||||||
"could_not_retrieve": "Erreur : impossible de récupérer les informations système {{name}} ",
|
"could_not_retrieve": "Erreur : impossible de récupérer les informations système {{name}} ",
|
||||||
|
|||||||
@@ -269,6 +269,7 @@
|
|||||||
"map": "Mapa",
|
"map": "Mapa",
|
||||||
"max": "máximo",
|
"max": "máximo",
|
||||||
"min": "minuto",
|
"min": "minuto",
|
||||||
|
"miscellaneous": "Diversos",
|
||||||
"mode": "Modo",
|
"mode": "Modo",
|
||||||
"model": "Modelo",
|
"model": "Modelo",
|
||||||
"modified": "Modificado",
|
"modified": "Modificado",
|
||||||
@@ -737,6 +738,7 @@
|
|||||||
"form": {
|
"form": {
|
||||||
"captive_web_root_explanation": "Por favor, use apenas arquivos .tar (sem arquivos compactados como .targz, por exemplo)",
|
"captive_web_root_explanation": "Por favor, use apenas arquivos .tar (sem arquivos compactados como .targz, por exemplo)",
|
||||||
"certificate_file_explanation": "Use um arquivo .pem que comece com \"-----BEGIN CERTIFICATE-----\" e termine com \"-----END CERTIFICATE-----\"",
|
"certificate_file_explanation": "Use um arquivo .pem que comece com \"-----BEGIN CERTIFICATE-----\" e termine com \"-----END CERTIFICATE-----\"",
|
||||||
|
"invalid_alphanumeric_with_dash": "Caracteres aceitos. são apenas alfanuméricos (letras e números)",
|
||||||
"invalid_cidr": "Endereço CIDR IPv4 inválido. Exemplo: 192.168.0.1/12",
|
"invalid_cidr": "Endereço CIDR IPv4 inválido. Exemplo: 192.168.0.1/12",
|
||||||
"invalid_email": "E-mail inválido",
|
"invalid_email": "E-mail inválido",
|
||||||
"invalid_file_content": "Conteúdo de arquivo inválido. Confirme se está no formato válido",
|
"invalid_file_content": "Conteúdo de arquivo inválido. Confirme se está no formato válido",
|
||||||
@@ -763,7 +765,11 @@
|
|||||||
"invalid_static_ipv4_e": "Endereço inválido, este intervalo é reservado para experimentos (classe E). O primeiro octeto deve ser 223 ou inferior",
|
"invalid_static_ipv4_e": "Endereço inválido, este intervalo é reservado para experimentos (classe E). O primeiro octeto deve ser 223 ou inferior",
|
||||||
"invalid_third_party": "String JSON de terceiros inválida. Confirme se seu valor é um JSON válido",
|
"invalid_third_party": "String JSON de terceiros inválida. Confirme se seu valor é um JSON válido",
|
||||||
"key_file_explanation": "Use um arquivo .pem que comece com \"-----BEGIN PRIVATE KEY-----\" e termine com \"-----END PRIVATE KEY-----\"",
|
"key_file_explanation": "Use um arquivo .pem que comece com \"-----BEGIN PRIVATE KEY-----\" e termine com \"-----END PRIVATE KEY-----\"",
|
||||||
|
"max_length": "Comprimento máximo de {{max}} caracteres.",
|
||||||
|
"max_value": "Valor máximo de {{max}}",
|
||||||
|
"min_length": "Comprimento mínimo de {{min}} caracteres.",
|
||||||
"min_max_string": "O valor precisa ter um comprimento entre {{min}} (inclusive) e {{max}} (inclusive)",
|
"min_max_string": "O valor precisa ter um comprimento entre {{min}} (inclusive) e {{max}} (inclusive)",
|
||||||
|
"min_value": "Valor mínimo de {{min}}",
|
||||||
"missing_interface_upstream": "Você precisa ter pelo menos uma interface upstream. No momento, todas as suas interfaces estão downstream",
|
"missing_interface_upstream": "Você precisa ter pelo menos uma interface upstream. No momento, todas as suas interfaces estão downstream",
|
||||||
"new_email_to_notify": "Novo e-mail para notificar",
|
"new_email_to_notify": "Novo e-mail para notificar",
|
||||||
"new_phone_to_notify": "Novo telefone para notificar",
|
"new_phone_to_notify": "Novo telefone para notificar",
|
||||||
@@ -905,6 +911,11 @@
|
|||||||
"one": "Notificação",
|
"one": "Notificação",
|
||||||
"other": "Notificações"
|
"other": "Notificações"
|
||||||
},
|
},
|
||||||
|
"openroaming": {
|
||||||
|
"pool_strategy": "Estratégia de pool",
|
||||||
|
"radius_endpoint_one": "Ponto final do raio",
|
||||||
|
"radius_endpoint_other": "Pontos finais de raio"
|
||||||
|
},
|
||||||
"operator": {
|
"operator": {
|
||||||
"delete_explanation": "Tem certeza de que deseja excluir este operador? Esta operação não é reversível",
|
"delete_explanation": "Tem certeza de que deseja excluir este operador? Esta operação não é reversível",
|
||||||
"delete_operator": "Excluir operador",
|
"delete_operator": "Excluir operador",
|
||||||
@@ -970,6 +981,27 @@
|
|||||||
"title": "RESTRIÇÕES",
|
"title": "RESTRIÇÕES",
|
||||||
"tty": "Acesso TTY"
|
"tty": "Acesso TTY"
|
||||||
},
|
},
|
||||||
|
"roaming": {
|
||||||
|
"account_created": "Nova conta criada!",
|
||||||
|
"account_deleted": "Conta excluída!",
|
||||||
|
"account_one": "Conta",
|
||||||
|
"account_other": "Contas",
|
||||||
|
"certificate_deleted": "Certificado excluído!",
|
||||||
|
"certificate_one": "Certificado",
|
||||||
|
"certificate_other": "Certificados",
|
||||||
|
"city": "Cidade",
|
||||||
|
"common_name": "Nome comum",
|
||||||
|
"country": "País",
|
||||||
|
"global_reach": "Alcance global",
|
||||||
|
"global_reach_account_id": "ID da conta",
|
||||||
|
"invalid_certificate": "Certificado inválido",
|
||||||
|
"invalid_key": "Chave privada inválida",
|
||||||
|
"location_details_title": "Localização",
|
||||||
|
"organization": "Organização",
|
||||||
|
"private_key": "Chave privada",
|
||||||
|
"province": "província",
|
||||||
|
"state": "Estado"
|
||||||
|
},
|
||||||
"rrm": {
|
"rrm": {
|
||||||
"algorithm": "Algoritmo",
|
"algorithm": "Algoritmo",
|
||||||
"algorithm_other": "Algoritmos",
|
"algorithm_other": "Algoritmos",
|
||||||
@@ -1091,6 +1123,7 @@
|
|||||||
"title": "Inscritos"
|
"title": "Inscritos"
|
||||||
},
|
},
|
||||||
"system": {
|
"system": {
|
||||||
|
"advanced": "Avançado",
|
||||||
"backend_logs": "Registros de back-end",
|
"backend_logs": "Registros de back-end",
|
||||||
"configuration": "Configuração",
|
"configuration": "Configuração",
|
||||||
"could_not_retrieve": "Erro: não foi possível recuperar {{name}} informações do sistema",
|
"could_not_retrieve": "Erro: não foi possível recuperar {{name}} informações do sistema",
|
||||||
|
|||||||
173
src/hooks/Network/Simulations.ts
Normal file
173
src/hooks/Network/Simulations.ts
Normal file
@@ -0,0 +1,173 @@
|
|||||||
|
import { QueryFunctionContext, useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
|
||||||
|
import { axiosGw, axiosOwls } from 'constants/axiosInstances';
|
||||||
|
import { AtLeast } from 'models/General';
|
||||||
|
|
||||||
|
export type Simulation = {
|
||||||
|
clientInterval: number;
|
||||||
|
concurrentDeviceS: number;
|
||||||
|
deviceType: string;
|
||||||
|
devices: number;
|
||||||
|
gateway: string;
|
||||||
|
healthCheckInterval: number;
|
||||||
|
id: string;
|
||||||
|
keepAlive: number;
|
||||||
|
key: string;
|
||||||
|
macPrefix: string;
|
||||||
|
minAssociations: number;
|
||||||
|
maxAssociations: number;
|
||||||
|
minClients: number;
|
||||||
|
maxClients: number;
|
||||||
|
name: string;
|
||||||
|
reconnectionInterval: number;
|
||||||
|
simulationLength: number;
|
||||||
|
stateInterval: number;
|
||||||
|
threads: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
const getSimulations = () => async () =>
|
||||||
|
axiosOwls.get(`simulation/*`).then((response) => response.data as { list: Simulation[] });
|
||||||
|
|
||||||
|
export const useGetSimulations = () =>
|
||||||
|
useQuery(['simulations'], getSimulations(), {
|
||||||
|
keepPreviousData: true,
|
||||||
|
staleTime: 30000,
|
||||||
|
});
|
||||||
|
|
||||||
|
const getSimulation = (id?: string) => async () =>
|
||||||
|
axiosOwls.get(`simulation/${id}`).then((response) => response.data as { list: Simulation[] });
|
||||||
|
export const useGetSimulation = ({ id }: { id?: string }) =>
|
||||||
|
useQuery(['simulation', id], getSimulation(id), {
|
||||||
|
keepPreviousData: true,
|
||||||
|
enabled: id !== undefined,
|
||||||
|
staleTime: 30000,
|
||||||
|
});
|
||||||
|
|
||||||
|
const createSimulation = async (newSimulation: Partial<Simulation>) => axiosOwls.post(`simulation/0`, newSimulation);
|
||||||
|
export const useCreateSimulation = () => {
|
||||||
|
const queryClient = useQueryClient();
|
||||||
|
|
||||||
|
return useMutation(createSimulation, {
|
||||||
|
onSuccess: () => {
|
||||||
|
queryClient.invalidateQueries(['simulations']);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const updateSimulation = async (newSimulation: AtLeast<Simulation, 'id'>) =>
|
||||||
|
axiosOwls.put(`simulation/${newSimulation.id}`, newSimulation).then((response) => response.data as Simulation);
|
||||||
|
export const useUpdateSimulation = () => {
|
||||||
|
const queryClient = useQueryClient();
|
||||||
|
|
||||||
|
return useMutation(updateSimulation, {
|
||||||
|
onSuccess: (newSimulation) => {
|
||||||
|
queryClient.setQueryData(['simulation'], newSimulation);
|
||||||
|
queryClient.invalidateQueries(['simulations']);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const deleteSimulation = async ({ id }: { id: string }) => axiosOwls.delete(`simulation/${id}`);
|
||||||
|
export const useDeleteSimulation = () => {
|
||||||
|
const queryClient = useQueryClient();
|
||||||
|
|
||||||
|
return useMutation(deleteSimulation, {
|
||||||
|
onSuccess: () => {
|
||||||
|
queryClient.invalidateQueries(['simulations']);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const startSimulation = async ({ id }: { id: string }) => axiosOwls.post(`operation/${id}?operation=start`);
|
||||||
|
export const useStartSimulation = () => {
|
||||||
|
const queryClient = useQueryClient();
|
||||||
|
|
||||||
|
return useMutation(startSimulation, {
|
||||||
|
onSuccess: () => {
|
||||||
|
queryClient.invalidateQueries(['simulations', 'status']);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
const stopSimulation = async ({ runId, simulationId }: { simulationId: string; runId: string }) =>
|
||||||
|
axiosOwls.post(`operation/${simulationId}?runningId=${runId}&operation=stop`);
|
||||||
|
export const useStopSimulation = () => {
|
||||||
|
const queryClient = useQueryClient();
|
||||||
|
|
||||||
|
return useMutation(stopSimulation, {
|
||||||
|
onSuccess: () => {
|
||||||
|
queryClient.invalidateQueries(['simulations', 'status']);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
const cancelSimulation = async ({ runId, simulationId }: { simulationId: string; runId: string }) =>
|
||||||
|
axiosOwls.post(`operation/${simulationId}?runningId=${runId}&operation=cancel`);
|
||||||
|
export const useCancelSimulation = () => {
|
||||||
|
const queryClient = useQueryClient();
|
||||||
|
|
||||||
|
return useMutation(cancelSimulation, {
|
||||||
|
onSuccess: () => {
|
||||||
|
queryClient.invalidateQueries(['simulations', 'status']);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export type SimulationStatus = {
|
||||||
|
endTime: number;
|
||||||
|
errorDevices: number;
|
||||||
|
id: string;
|
||||||
|
liveDevices: number;
|
||||||
|
msgsRx: number;
|
||||||
|
msgsTx: number;
|
||||||
|
owner: string;
|
||||||
|
rx: number;
|
||||||
|
simulationId: string;
|
||||||
|
startTime: number;
|
||||||
|
state: 'running' | 'completed' | 'cancelled' | 'none';
|
||||||
|
timeToFullDevices: number;
|
||||||
|
tx: number;
|
||||||
|
};
|
||||||
|
const getSimulationsStatus = async () =>
|
||||||
|
axiosOwls.get(`status/*`).then((response) => response.data as SimulationStatus[]);
|
||||||
|
export const useGetSimulationsStatus = () =>
|
||||||
|
useQuery(['simulations', 'status'], getSimulationsStatus, {
|
||||||
|
keepPreviousData: true,
|
||||||
|
staleTime: Infinity,
|
||||||
|
});
|
||||||
|
|
||||||
|
const getSimulationStatus = async (context: QueryFunctionContext<[string, string, string]>) =>
|
||||||
|
axiosOwls.get(`status/${context.queryKey[2]}`).then((response) => response.data as SimulationStatus);
|
||||||
|
export const useGetSimulationStatus = ({ id }: { id: string }) =>
|
||||||
|
useQuery(['simulations', 'status', id], getSimulationStatus, {
|
||||||
|
keepPreviousData: true,
|
||||||
|
staleTime: Infinity,
|
||||||
|
});
|
||||||
|
|
||||||
|
const getSimulationHistory = async (context: QueryFunctionContext<[string, string, string]>) =>
|
||||||
|
axiosOwls.get(`results/${context.queryKey[2]}`).then((response) => response.data.list as SimulationStatus[]);
|
||||||
|
export const useGetSimulationHistory = ({ id }: { id: string }) =>
|
||||||
|
useQuery(['simulations', 'history', id], getSimulationHistory, {
|
||||||
|
keepPreviousData: true,
|
||||||
|
enabled: !!id,
|
||||||
|
});
|
||||||
|
|
||||||
|
const deleteSimulationResult = async ({ id }: { id: string }) => axiosOwls.delete(`results/${id}`);
|
||||||
|
export const useDeleteSimulationResult = () => {
|
||||||
|
const queryClient = useQueryClient();
|
||||||
|
|
||||||
|
return useMutation(deleteSimulationResult, {
|
||||||
|
onSuccess: () => {
|
||||||
|
queryClient.invalidateQueries(['simulations', 'history']);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const deleteSimulatedDevices = async () => axiosGw.delete('devices?simulatedDevices=true');
|
||||||
|
|
||||||
|
export const useDeleteSimulatedDevices = () => {
|
||||||
|
const queryClient = useQueryClient();
|
||||||
|
|
||||||
|
return useMutation(deleteSimulatedDevices, {
|
||||||
|
onSuccess: () => {
|
||||||
|
queryClient.invalidateQueries(['devices']);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
80
src/hooks/useNotification.ts
Normal file
80
src/hooks/useNotification.ts
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
import * as React from 'react';
|
||||||
|
import { useToast } from '@chakra-ui/react';
|
||||||
|
import { useTranslation } from 'react-i18next';
|
||||||
|
import { v4 as uuid } from 'uuid';
|
||||||
|
import { isApiError } from 'models/Axios';
|
||||||
|
|
||||||
|
export type SuccessNotificationProps = {
|
||||||
|
description: string;
|
||||||
|
id?: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type ApiErrorNotificationProps = {
|
||||||
|
e: unknown;
|
||||||
|
fallbackMessage?: string;
|
||||||
|
id?: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const useNotification = () => {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
const toast = useToast();
|
||||||
|
|
||||||
|
const successToast = ({ description, id }: SuccessNotificationProps) => {
|
||||||
|
toast({
|
||||||
|
id: id ?? uuid(),
|
||||||
|
title: t('common.success'),
|
||||||
|
description,
|
||||||
|
status: 'success',
|
||||||
|
duration: 3000,
|
||||||
|
isClosable: true,
|
||||||
|
position: 'top-right',
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const apiErrorToast = ({ e, id, fallbackMessage }: ApiErrorNotificationProps) => {
|
||||||
|
if (isApiError(e)) {
|
||||||
|
toast({
|
||||||
|
id: id ?? uuid(),
|
||||||
|
title: t('common.error'),
|
||||||
|
description: e.response?.data.ErrorDescription,
|
||||||
|
status: 'error',
|
||||||
|
duration: 5000,
|
||||||
|
isClosable: true,
|
||||||
|
position: 'top-right',
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
toast({
|
||||||
|
id: id ?? uuid(),
|
||||||
|
title: t('common.error'),
|
||||||
|
description: fallbackMessage,
|
||||||
|
status: 'error',
|
||||||
|
duration: 5000,
|
||||||
|
isClosable: true,
|
||||||
|
position: 'top-right',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const errorToast = ({ description, id }: SuccessNotificationProps) => {
|
||||||
|
toast({
|
||||||
|
id: id ?? uuid(),
|
||||||
|
title: t('common.error'),
|
||||||
|
description,
|
||||||
|
status: 'error',
|
||||||
|
duration: 5000,
|
||||||
|
isClosable: true,
|
||||||
|
position: 'top-right',
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
return React.useMemo(
|
||||||
|
() => ({
|
||||||
|
successToast,
|
||||||
|
errorToast,
|
||||||
|
apiErrorToast,
|
||||||
|
}),
|
||||||
|
[t],
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export type UseNotificationReturn = ReturnType<typeof useNotification>;
|
||||||
@@ -1,3 +1,6 @@
|
|||||||
import { AxiosError as Err } from 'axios';
|
import { AxiosError as Err, isAxiosError } from 'axios';
|
||||||
|
|
||||||
export type AxiosError = Err<{ ErrorDescription: string; ErrorCode: number }>;
|
export type AxiosError = Err<{ ErrorDescription: string; ErrorCode: number }>;
|
||||||
|
|
||||||
|
export const isApiError = (e: unknown): e is AxiosError =>
|
||||||
|
isAxiosError(e) && (e as AxiosError).response?.data?.ErrorDescription !== undefined;
|
||||||
|
|||||||
93
src/pages/AdvancedSystemPage/index.tsx
Normal file
93
src/pages/AdvancedSystemPage/index.tsx
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
import * as React from 'react';
|
||||||
|
import {
|
||||||
|
Box,
|
||||||
|
Button,
|
||||||
|
Center,
|
||||||
|
Heading,
|
||||||
|
Popover,
|
||||||
|
PopoverArrow,
|
||||||
|
PopoverBody,
|
||||||
|
PopoverCloseButton,
|
||||||
|
PopoverContent,
|
||||||
|
PopoverHeader,
|
||||||
|
PopoverTrigger,
|
||||||
|
Text,
|
||||||
|
} from '@chakra-ui/react';
|
||||||
|
import { Trash } from '@phosphor-icons/react';
|
||||||
|
import { Card } from 'components/Containers/Card';
|
||||||
|
import { CardHeader } from 'components/Containers/Card/CardHeader';
|
||||||
|
import { CardBody } from 'components/Containers/Card/CardBody';
|
||||||
|
import { DeleteButton } from 'components/Buttons/DeleteButton';
|
||||||
|
import { useNotification } from 'hooks/useNotification';
|
||||||
|
import { useDeleteSimulatedDevices } from 'hooks/Network/Simulations';
|
||||||
|
|
||||||
|
const AdvancedSystemPage = () => {
|
||||||
|
const { successToast, apiErrorToast } = useNotification();
|
||||||
|
const deleteSimulatedDevices = useDeleteSimulatedDevices();
|
||||||
|
|
||||||
|
const handleDeleteSimulatedDevices = async () =>
|
||||||
|
deleteSimulatedDevices.mutateAsync(undefined, {
|
||||||
|
onSuccess: () => {
|
||||||
|
successToast({
|
||||||
|
id: 'delete-simulated-devices',
|
||||||
|
description: 'Simulated devices deleted!',
|
||||||
|
});
|
||||||
|
},
|
||||||
|
onError: (e) => {
|
||||||
|
apiErrorToast({
|
||||||
|
id: 'delete-simulated-devices',
|
||||||
|
e,
|
||||||
|
fallbackMessage: 'Error deleting simulated devices',
|
||||||
|
});
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Card>
|
||||||
|
<CardHeader>
|
||||||
|
<Heading size="md">Operations</Heading>
|
||||||
|
</CardHeader>
|
||||||
|
<CardBody>
|
||||||
|
<Box>
|
||||||
|
<Heading size="sm">Delete Simulated Devices</Heading>
|
||||||
|
<Text fontStyle="italic">Delete all simulated devices from the database. This action cannot be undone.</Text>
|
||||||
|
<Popover>
|
||||||
|
{({ onClose }) => (
|
||||||
|
<>
|
||||||
|
<PopoverTrigger>
|
||||||
|
<Button colorScheme="red" rightIcon={<Trash size={20} />}>
|
||||||
|
Delete
|
||||||
|
</Button>
|
||||||
|
</PopoverTrigger>
|
||||||
|
<PopoverContent>
|
||||||
|
<PopoverArrow />
|
||||||
|
<PopoverCloseButton />
|
||||||
|
<PopoverHeader>Confirm</PopoverHeader>
|
||||||
|
<PopoverBody>
|
||||||
|
<Text>Are you sure you want to delete all simulated devices?</Text>
|
||||||
|
<Center mt={4}>
|
||||||
|
<Button onClick={onClose} mr={1}>
|
||||||
|
Cancel
|
||||||
|
</Button>
|
||||||
|
<DeleteButton
|
||||||
|
ml={1}
|
||||||
|
isLoading={deleteSimulatedDevices.isLoading}
|
||||||
|
onClick={async () => {
|
||||||
|
await handleDeleteSimulatedDevices();
|
||||||
|
onClose();
|
||||||
|
}}
|
||||||
|
isCompact={false}
|
||||||
|
/>
|
||||||
|
</Center>
|
||||||
|
</PopoverBody>
|
||||||
|
</PopoverContent>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</Popover>
|
||||||
|
</Box>
|
||||||
|
</CardBody>
|
||||||
|
</Card>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default AdvancedSystemPage;
|
||||||
@@ -2,6 +2,7 @@ import React from 'react';
|
|||||||
import { Barcode, FloppyDisk, Info, ListBullets, TerminalWindow, UsersThree, WifiHigh } from '@phosphor-icons/react';
|
import { Barcode, FloppyDisk, Info, ListBullets, TerminalWindow, UsersThree, WifiHigh } from '@phosphor-icons/react';
|
||||||
import { Route } from 'models/Routes';
|
import { Route } from 'models/Routes';
|
||||||
|
|
||||||
|
const AdvancedSystemPage = React.lazy(() => import('pages/AdvancedSystemPage'));
|
||||||
const DefaultConfigurationsPage = React.lazy(() => import('pages/DefaultConfigurations'));
|
const DefaultConfigurationsPage = React.lazy(() => import('pages/DefaultConfigurations'));
|
||||||
const DefaultFirmwarePage = React.lazy(() => import('pages/DefaultFirmware'));
|
const DefaultFirmwarePage = React.lazy(() => import('pages/DefaultFirmware'));
|
||||||
const DevicePage = React.lazy(() => import('pages/Device'));
|
const DevicePage = React.lazy(() => import('pages/Device'));
|
||||||
@@ -178,6 +179,13 @@ const routes: Route[] = [
|
|||||||
name: 'system.title',
|
name: 'system.title',
|
||||||
icon: () => <Info size={28} weight="bold" />,
|
icon: () => <Info size={28} weight="bold" />,
|
||||||
children: [
|
children: [
|
||||||
|
{
|
||||||
|
id: 'system-advanced',
|
||||||
|
authorized: ['root', 'partner', 'admin', 'csr', 'system'],
|
||||||
|
path: '/systemAdvanced',
|
||||||
|
name: 'system.advanced',
|
||||||
|
component: AdvancedSystemPage,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
id: 'system-configuration',
|
id: 'system-configuration',
|
||||||
authorized: ['root', 'partner', 'admin', 'csr', 'system'],
|
authorized: ['root', 'partner', 'admin', 'csr', 'system'],
|
||||||
|
|||||||
Reference in New Issue
Block a user