mirror of
https://github.com/optim-enterprises-bv/OptimCloud-gw-ui.git
synced 2025-11-01 02:37:45 +00:00
[WIFI-12506] Added radius search and radius clients tile
Signed-off-by: Charles <charles.bourque96@gmail.com>
This commit is contained in:
@@ -3,3 +3,4 @@ build
|
|||||||
dist
|
dist
|
||||||
node_modules
|
node_modules
|
||||||
.github
|
.github
|
||||||
|
/helm
|
||||||
|
|||||||
72
package-lock.json
generated
72
package-lock.json
generated
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "ucentral-client",
|
"name": "ucentral-client",
|
||||||
"version": "2.10.0(11)",
|
"version": "2.10.0(14)",
|
||||||
"lockfileVersion": 2,
|
"lockfileVersion": 2,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "ucentral-client",
|
"name": "ucentral-client",
|
||||||
"version": "2.10.0(11)",
|
"version": "2.10.0(14)",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@chakra-ui/icons": "^2.0.11",
|
"@chakra-ui/icons": "^2.0.11",
|
||||||
@@ -24,7 +24,7 @@
|
|||||||
"@textea/json-viewer": "^2.10.0",
|
"@textea/json-viewer": "^2.10.0",
|
||||||
"axios": "^1.1.3",
|
"axios": "^1.1.3",
|
||||||
"buffer": "^6.0.3",
|
"buffer": "^6.0.3",
|
||||||
"chakra-react-select": "^4.3.0",
|
"chakra-react-select": "^4.6.0",
|
||||||
"chart.js": "^3.9.1",
|
"chart.js": "^3.9.1",
|
||||||
"dagre": "^0.8.5",
|
"dagre": "^0.8.5",
|
||||||
"fast-equals": "^4.0.3",
|
"fast-equals": "^4.0.3",
|
||||||
@@ -2839,14 +2839,16 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@floating-ui/core": {
|
"node_modules/@floating-ui/core": {
|
||||||
"version": "1.0.1",
|
"version": "1.2.6",
|
||||||
"license": "MIT"
|
"resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.2.6.tgz",
|
||||||
|
"integrity": "sha512-EvYTiXet5XqweYGClEmpu3BoxmsQ4hkj3QaYA6qEnigCWffTP3vNRwBReTdrwDwo7OoJ3wM8Uoe9Uk4n+d4hfg=="
|
||||||
},
|
},
|
||||||
"node_modules/@floating-ui/dom": {
|
"node_modules/@floating-ui/dom": {
|
||||||
"version": "1.0.2",
|
"version": "1.2.6",
|
||||||
"license": "MIT",
|
"resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.2.6.tgz",
|
||||||
|
"integrity": "sha512-02vxFDuvuVPs22iJICacezYJyf7zwwOCWkPNkWNBr1U0Qt1cKFYzWvxts0AmqcOQGwt/3KJWcWIgtbUU38keyw==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@floating-ui/core": "^1.0.1"
|
"@floating-ui/core": "^1.2.6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@fontsource/inter": {
|
"node_modules/@fontsource/inter": {
|
||||||
@@ -4387,15 +4389,17 @@
|
|||||||
"license": "CC-BY-4.0"
|
"license": "CC-BY-4.0"
|
||||||
},
|
},
|
||||||
"node_modules/chakra-react-select": {
|
"node_modules/chakra-react-select": {
|
||||||
"version": "4.3.0",
|
"version": "4.6.0",
|
||||||
"license": "MIT",
|
"resolved": "https://registry.npmjs.org/chakra-react-select/-/chakra-react-select-4.6.0.tgz",
|
||||||
|
"integrity": "sha512-Ckcs+ofX5LxCc0oOz4SorDIRqF/afd5tAQOa694JVJiIckYorUmZASEUSSDdXaZltsUAtJE11CUmEZgVVsk9Eg==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"react-select": "^5.5.0"
|
"react-select": "5.7.0"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@chakra-ui/form-control": "^2.0.0",
|
"@chakra-ui/form-control": "^2.0.0",
|
||||||
"@chakra-ui/icon": "^3.0.0",
|
"@chakra-ui/icon": "^3.0.0",
|
||||||
"@chakra-ui/layout": "^2.0.0",
|
"@chakra-ui/layout": "^2.0.0",
|
||||||
|
"@chakra-ui/media-query": "^3.0.0",
|
||||||
"@chakra-ui/menu": "^2.0.0",
|
"@chakra-ui/menu": "^2.0.0",
|
||||||
"@chakra-ui/spinner": "^2.0.0",
|
"@chakra-ui/spinner": "^2.0.0",
|
||||||
"@chakra-ui/system": "^2.0.0",
|
"@chakra-ui/system": "^2.0.0",
|
||||||
@@ -7979,15 +7983,16 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/react-select": {
|
"node_modules/react-select": {
|
||||||
"version": "5.5.2",
|
"version": "5.7.0",
|
||||||
"license": "MIT",
|
"resolved": "https://registry.npmjs.org/react-select/-/react-select-5.7.0.tgz",
|
||||||
|
"integrity": "sha512-lJGiMxCa3cqnUr2Jjtg9YHsaytiZqeNOKeibv6WF5zbK/fPegZ1hg3y/9P1RZVLhqBTs0PfqQLKuAACednYGhQ==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/runtime": "^7.12.0",
|
"@babel/runtime": "^7.12.0",
|
||||||
"@emotion/cache": "^11.4.0",
|
"@emotion/cache": "^11.4.0",
|
||||||
"@emotion/react": "^11.8.1",
|
"@emotion/react": "^11.8.1",
|
||||||
"@floating-ui/dom": "^1.0.1",
|
"@floating-ui/dom": "^1.0.1",
|
||||||
"@types/react-transition-group": "^4.4.0",
|
"@types/react-transition-group": "^4.4.0",
|
||||||
"memoize-one": "^5.0.0",
|
"memoize-one": "^6.0.0",
|
||||||
"prop-types": "^15.6.0",
|
"prop-types": "^15.6.0",
|
||||||
"react-transition-group": "^4.3.0",
|
"react-transition-group": "^4.3.0",
|
||||||
"use-isomorphic-layout-effect": "^1.1.2"
|
"use-isomorphic-layout-effect": "^1.1.2"
|
||||||
@@ -7997,6 +8002,11 @@
|
|||||||
"react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0"
|
"react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/react-select/node_modules/memoize-one": {
|
||||||
|
"version": "6.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-6.0.0.tgz",
|
||||||
|
"integrity": "sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw=="
|
||||||
|
},
|
||||||
"node_modules/react-style-singleton": {
|
"node_modules/react-style-singleton": {
|
||||||
"version": "2.2.1",
|
"version": "2.2.1",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
@@ -9129,7 +9139,8 @@
|
|||||||
},
|
},
|
||||||
"node_modules/use-isomorphic-layout-effect": {
|
"node_modules/use-isomorphic-layout-effect": {
|
||||||
"version": "1.1.2",
|
"version": "1.1.2",
|
||||||
"license": "MIT",
|
"resolved": "https://registry.npmjs.org/use-isomorphic-layout-effect/-/use-isomorphic-layout-effect-1.1.2.tgz",
|
||||||
|
"integrity": "sha512-49L8yCO3iGT/ZF9QttjwLF/ZD9Iwto5LnH5LmEdk/6cFmXddqi2ulF0edxTwjj+7mqvpVVGQWvbXZdn32wRSHA==",
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"react": "^16.8.0 || ^17.0.0 || ^18.0.0"
|
"react": "^16.8.0 || ^17.0.0 || ^18.0.0"
|
||||||
},
|
},
|
||||||
@@ -11486,12 +11497,16 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@floating-ui/core": {
|
"@floating-ui/core": {
|
||||||
"version": "1.0.1"
|
"version": "1.2.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.2.6.tgz",
|
||||||
|
"integrity": "sha512-EvYTiXet5XqweYGClEmpu3BoxmsQ4hkj3QaYA6qEnigCWffTP3vNRwBReTdrwDwo7OoJ3wM8Uoe9Uk4n+d4hfg=="
|
||||||
},
|
},
|
||||||
"@floating-ui/dom": {
|
"@floating-ui/dom": {
|
||||||
"version": "1.0.2",
|
"version": "1.2.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.2.6.tgz",
|
||||||
|
"integrity": "sha512-02vxFDuvuVPs22iJICacezYJyf7zwwOCWkPNkWNBr1U0Qt1cKFYzWvxts0AmqcOQGwt/3KJWcWIgtbUU38keyw==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@floating-ui/core": "^1.0.1"
|
"@floating-ui/core": "^1.2.6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@fontsource/inter": {
|
"@fontsource/inter": {
|
||||||
@@ -12379,9 +12394,11 @@
|
|||||||
"version": "1.0.30001422"
|
"version": "1.0.30001422"
|
||||||
},
|
},
|
||||||
"chakra-react-select": {
|
"chakra-react-select": {
|
||||||
"version": "4.3.0",
|
"version": "4.6.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/chakra-react-select/-/chakra-react-select-4.6.0.tgz",
|
||||||
|
"integrity": "sha512-Ckcs+ofX5LxCc0oOz4SorDIRqF/afd5tAQOa694JVJiIckYorUmZASEUSSDdXaZltsUAtJE11CUmEZgVVsk9Eg==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"react-select": "^5.5.0"
|
"react-select": "5.7.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"chalk": {
|
"chalk": {
|
||||||
@@ -14532,17 +14549,26 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"react-select": {
|
"react-select": {
|
||||||
"version": "5.5.2",
|
"version": "5.7.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-select/-/react-select-5.7.0.tgz",
|
||||||
|
"integrity": "sha512-lJGiMxCa3cqnUr2Jjtg9YHsaytiZqeNOKeibv6WF5zbK/fPegZ1hg3y/9P1RZVLhqBTs0PfqQLKuAACednYGhQ==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@babel/runtime": "^7.12.0",
|
"@babel/runtime": "^7.12.0",
|
||||||
"@emotion/cache": "^11.4.0",
|
"@emotion/cache": "^11.4.0",
|
||||||
"@emotion/react": "^11.8.1",
|
"@emotion/react": "^11.8.1",
|
||||||
"@floating-ui/dom": "^1.0.1",
|
"@floating-ui/dom": "^1.0.1",
|
||||||
"@types/react-transition-group": "^4.4.0",
|
"@types/react-transition-group": "^4.4.0",
|
||||||
"memoize-one": "^5.0.0",
|
"memoize-one": "^6.0.0",
|
||||||
"prop-types": "^15.6.0",
|
"prop-types": "^15.6.0",
|
||||||
"react-transition-group": "^4.3.0",
|
"react-transition-group": "^4.3.0",
|
||||||
"use-isomorphic-layout-effect": "^1.1.2"
|
"use-isomorphic-layout-effect": "^1.1.2"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"memoize-one": {
|
||||||
|
"version": "6.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-6.0.0.tgz",
|
||||||
|
"integrity": "sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw=="
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"react-style-singleton": {
|
"react-style-singleton": {
|
||||||
@@ -15209,6 +15235,8 @@
|
|||||||
},
|
},
|
||||||
"use-isomorphic-layout-effect": {
|
"use-isomorphic-layout-effect": {
|
||||||
"version": "1.1.2",
|
"version": "1.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/use-isomorphic-layout-effect/-/use-isomorphic-layout-effect-1.1.2.tgz",
|
||||||
|
"integrity": "sha512-49L8yCO3iGT/ZF9QttjwLF/ZD9Iwto5LnH5LmEdk/6cFmXddqi2ulF0edxTwjj+7mqvpVVGQWvbXZdn32wRSHA==",
|
||||||
"requires": {}
|
"requires": {}
|
||||||
},
|
},
|
||||||
"use-sidecar": {
|
"use-sidecar": {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "ucentral-client",
|
"name": "ucentral-client",
|
||||||
"version": "2.10.0(11)",
|
"version": "2.10.0(14)",
|
||||||
"description": "",
|
"description": "",
|
||||||
"private": true,
|
"private": true,
|
||||||
"main": "index.tsx",
|
"main": "index.tsx",
|
||||||
@@ -27,7 +27,7 @@
|
|||||||
"@react-spring/web": "^9.5.5",
|
"@react-spring/web": "^9.5.5",
|
||||||
"axios": "^1.1.3",
|
"axios": "^1.1.3",
|
||||||
"buffer": "^6.0.3",
|
"buffer": "^6.0.3",
|
||||||
"chakra-react-select": "^4.3.0",
|
"chakra-react-select": "^4.6.0",
|
||||||
"dagre": "^0.8.5",
|
"dagre": "^0.8.5",
|
||||||
"formik": "^2.2.9",
|
"formik": "^2.2.9",
|
||||||
"fast-equals": "^4.0.3",
|
"fast-equals": "^4.0.3",
|
||||||
|
|||||||
@@ -356,6 +356,7 @@
|
|||||||
"error_pushes_one": "Fehler (könnte an einer fehlerhaften Konfiguration liegen): {{count}}",
|
"error_pushes_one": "Fehler (könnte an einer fehlerhaften Konfiguration liegen): {{count}}",
|
||||||
"error_pushes_other": "Fehler (können auf eine fehlerhafte Konfiguration zurückzuführen sein): {{count}}",
|
"error_pushes_other": "Fehler (können auf eine fehlerhafte Konfiguration zurückzuführen sein): {{count}}",
|
||||||
"expert_name": "Expertenmodus",
|
"expert_name": "Expertenmodus",
|
||||||
|
"expert_name_explanation": "Sie können den Expertenmodus verwenden, um Ihre Konfiguration direkt zu ändern, einschließlich des Hinzufügens von Werten, die derzeit nicht von der Benutzeroberfläche unterstützt werden. Bitte verwenden Sie dieses Format: { \"interfaces\": [ ... ], \"globals\": { ... }, ...etc }",
|
||||||
"explanation": "Erläuterung",
|
"explanation": "Erläuterung",
|
||||||
"firewall": "Firewall",
|
"firewall": "Firewall",
|
||||||
"firmware_upgrade": "Firmware-Aktualisierung",
|
"firmware_upgrade": "Firmware-Aktualisierung",
|
||||||
@@ -522,6 +523,7 @@
|
|||||||
"ouis_explanation": "OUIs von Geräten, die sich mit diesem Firmware-Server verbunden haben",
|
"ouis_explanation": "OUIs von Geräten, die sich mit diesem Firmware-Server verbunden haben",
|
||||||
"outdated_one": "Firmware {{count}} Tag alt",
|
"outdated_one": "Firmware {{count}} Tag alt",
|
||||||
"outdated_other": "Firmware {{count}} Tage alt",
|
"outdated_other": "Firmware {{count}} Tage alt",
|
||||||
|
"outdated_unknown": "Firmware unbekannten Alters",
|
||||||
"release": "Veröffentlichung",
|
"release": "Veröffentlichung",
|
||||||
"show_dev_releases": "Entwicklerversionen",
|
"show_dev_releases": "Entwicklerversionen",
|
||||||
"status_explanation": "Verbindungsstatus von Geräten, die sich mit diesem Firmware-Server verbunden haben",
|
"status_explanation": "Verbindungsstatus von Geräten, die sich mit diesem Firmware-Server verbunden haben",
|
||||||
@@ -537,6 +539,14 @@
|
|||||||
"queue": {
|
"queue": {
|
||||||
"title": "Ereigniswarteschlange"
|
"title": "Ereigniswarteschlange"
|
||||||
},
|
},
|
||||||
|
"radius": {
|
||||||
|
"calling_station_id": "Stations",
|
||||||
|
"input_octets": "Eingang",
|
||||||
|
"output_octets": "Ausgabe",
|
||||||
|
"radius_clients": "Radius-Kunden",
|
||||||
|
"session_time": "Sitzungszeit",
|
||||||
|
"username": "Nutzername"
|
||||||
|
},
|
||||||
"stats": {
|
"stats": {
|
||||||
"load": "Belastung (1 | 5 | 15 m.)",
|
"load": "Belastung (1 | 5 | 15 m.)",
|
||||||
"seconds_ago": " Vor {{s}} Sekunden",
|
"seconds_ago": " Vor {{s}} Sekunden",
|
||||||
@@ -712,7 +722,7 @@
|
|||||||
"invalid_ipv6": "Ungültige IPv6-Adresse (Bsp.: 2001:db8:3333:4444:5555:6666:7777:8888)",
|
"invalid_ipv6": "Ungültige IPv6-Adresse (Bsp.: 2001:db8:3333:4444:5555:6666:7777:8888)",
|
||||||
"invalid_json": "Ungültige JSON-Zeichenfolge",
|
"invalid_json": "Ungültige JSON-Zeichenfolge",
|
||||||
"invalid_lease_time": "Ungültiger Lease-Time-Wert! Sie müssen im digitUnit-Format vorliegen. Zum Beispiel: 6d2h5m, was 6 Tage, 2 Stunden und 5 Minuten bedeutet. Hier sind die akzeptierten Einheiten: m, h, d. Wenn Sie eine Einheit nicht verwenden möchten, lassen Sie sie vollständig weg. Anstatt also 0d2h0m zu sagen, verwenden Sie 2h",
|
"invalid_lease_time": "Ungültiger Lease-Time-Wert! Sie müssen im digitUnit-Format vorliegen. Zum Beispiel: 6d2h5m, was 6 Tage, 2 Stunden und 5 Minuten bedeutet. Hier sind die akzeptierten Einheiten: m, h, d. Wenn Sie eine Einheit nicht verwenden möchten, lassen Sie sie vollständig weg. Anstatt also 0d2h0m zu sagen, verwenden Sie 2h",
|
||||||
"invalid_mac_uc": "Ungültiger UC-MAC-Wert, zum Beispiel: 00:00:5e:00:53:af",
|
"invalid_mac_uc": "Ungültiger MAC-Wert, zum Beispiel: 00:00:5e:00:53:af",
|
||||||
"invalid_password": "Ungültiges Passwort, bitte sehen Sie sich die Passwortrichtlinie an",
|
"invalid_password": "Ungültiges Passwort, bitte sehen Sie sich die Passwortrichtlinie an",
|
||||||
"invalid_phone_number": "Ungültige Telefonnummer",
|
"invalid_phone_number": "Ungültige Telefonnummer",
|
||||||
"invalid_phone_numbers": "Mindestens eine der Telefonnummern ist ungültig. Bitte geben Sie sie ohne Symbole und Leerzeichen oder in diesem Format an: +1(123)123-1234",
|
"invalid_phone_numbers": "Mindestens eine der Telefonnummern ist ungültig. Bitte geben Sie sie ohne Symbole und Leerzeichen oder in diesem Format an: +1(123)123-1234",
|
||||||
@@ -1072,14 +1082,23 @@
|
|||||||
"version": "Ausführung"
|
"version": "Ausführung"
|
||||||
},
|
},
|
||||||
"table": {
|
"table": {
|
||||||
|
"columns": "Säulen",
|
||||||
"columns_hidden_one": "{{count}} Spalte ausgeblendet",
|
"columns_hidden_one": "{{count}} Spalte ausgeblendet",
|
||||||
"columns_hidden_other": "{{count}} Spalten ausgeblendet",
|
"columns_hidden_other": "{{count}} Spalten ausgeblendet",
|
||||||
|
"display_column": "Anzeige",
|
||||||
|
"drag_always_show": "Sie können diese Spalte nicht ausblenden, aber ihre Position ändern",
|
||||||
|
"drag_explanation": "Ziehen und Ablegen zum Neuordnen und Ändern der Spaltensichtbarkeit",
|
||||||
|
"drag_locked": "Diese Säule ist in ihrer Position arretiert",
|
||||||
"first_page": "Erste Seite",
|
"first_page": "Erste Seite",
|
||||||
"go_to_page": "Zur Seite gehen",
|
"go_to_page": "Zur Seite gehen",
|
||||||
|
"hide_column": "verbergen",
|
||||||
"last_page": "Letzte Seite",
|
"last_page": "Letzte Seite",
|
||||||
"next_page": "Nächste Seite",
|
"next_page": "Nächste Seite",
|
||||||
"page": "Seite",
|
"page": "Seite",
|
||||||
"previous_page": "Vorherige Seite"
|
"preferences": "Tabelleneinstellungen",
|
||||||
|
"previous_page": "Vorherige Seite",
|
||||||
|
"reset": "Einstellungen zurücksetzen",
|
||||||
|
"settings": "die Einstellungen"
|
||||||
},
|
},
|
||||||
"user": {
|
"user": {
|
||||||
"email_not_validated": "E-Mail nicht validiert",
|
"email_not_validated": "E-Mail nicht validiert",
|
||||||
|
|||||||
@@ -356,6 +356,7 @@
|
|||||||
"error_pushes_one": "Error (could be because of bad configuration): {{count}}",
|
"error_pushes_one": "Error (could be because of bad configuration): {{count}}",
|
||||||
"error_pushes_other": "Errors (could be because of bad configuration): {{count}}",
|
"error_pushes_other": "Errors (could be because of bad configuration): {{count}}",
|
||||||
"expert_name": "Expert Mode",
|
"expert_name": "Expert Mode",
|
||||||
|
"expert_name_explanation": "You can use expert mode to directly modify your configuration, including adding values that are not currently supported by the UI. Please use this format: { \"interfaces\": [ ... ], \"globals\": { ... }, ...etc }",
|
||||||
"explanation": "Explanation",
|
"explanation": "Explanation",
|
||||||
"firewall": "Firewall",
|
"firewall": "Firewall",
|
||||||
"firmware_upgrade": "Firmware Upgrade",
|
"firmware_upgrade": "Firmware Upgrade",
|
||||||
@@ -522,6 +523,7 @@
|
|||||||
"ouis_explanation": "OUIs of devices that have connected to this firmware server",
|
"ouis_explanation": "OUIs of devices that have connected to this firmware server",
|
||||||
"outdated_one": "Firmware {{count}} day old",
|
"outdated_one": "Firmware {{count}} day old",
|
||||||
"outdated_other": "Firmware {{count}} days old",
|
"outdated_other": "Firmware {{count}} days old",
|
||||||
|
"outdated_unknown": "Firmware of unknown age",
|
||||||
"release": "Release",
|
"release": "Release",
|
||||||
"show_dev_releases": "Dev Releases",
|
"show_dev_releases": "Dev Releases",
|
||||||
"status_explanation": "Connection status of devices that have connected to this firmware server",
|
"status_explanation": "Connection status of devices that have connected to this firmware server",
|
||||||
@@ -537,6 +539,14 @@
|
|||||||
"queue": {
|
"queue": {
|
||||||
"title": "Event Queue"
|
"title": "Event Queue"
|
||||||
},
|
},
|
||||||
|
"radius": {
|
||||||
|
"calling_station_id": "Station",
|
||||||
|
"input_octets": "Input",
|
||||||
|
"output_octets": "Output",
|
||||||
|
"radius_clients": "Radius Clients",
|
||||||
|
"session_time": "Session Time",
|
||||||
|
"username": "Username"
|
||||||
|
},
|
||||||
"stats": {
|
"stats": {
|
||||||
"load": "Load (1 | 5 | 15 m.)",
|
"load": "Load (1 | 5 | 15 m.)",
|
||||||
"seconds_ago": "{{s}} seconds ago",
|
"seconds_ago": "{{s}} seconds ago",
|
||||||
@@ -712,7 +722,7 @@
|
|||||||
"invalid_ipv6": "Invalid IPv6 address (ex.: 2001:db8:3333:4444:5555:6666:7777:8888)",
|
"invalid_ipv6": "Invalid IPv6 address (ex.: 2001:db8:3333:4444:5555:6666:7777:8888)",
|
||||||
"invalid_json": "Invalid JSON string",
|
"invalid_json": "Invalid JSON string",
|
||||||
"invalid_lease_time": "Invalid lease time value! They need to be in the digitUnit format. For example: 6d2h5m, which means 6 days, 2 hours and 5 minutes. Here are the accepted units: m, h, d. If you do not want to use a unit, omit it completely. So instead of saying 0d2h0m, use 2h",
|
"invalid_lease_time": "Invalid lease time value! They need to be in the digitUnit format. For example: 6d2h5m, which means 6 days, 2 hours and 5 minutes. Here are the accepted units: m, h, d. If you do not want to use a unit, omit it completely. So instead of saying 0d2h0m, use 2h",
|
||||||
"invalid_mac_uc": "Invalid UC-MAC value, for example: 00:00:5e:00:53:af",
|
"invalid_mac_uc": "Invalid MAC value, for example: 00:00:5e:00:53:af",
|
||||||
"invalid_password": "Invalid password, please look at the password policy",
|
"invalid_password": "Invalid password, please look at the password policy",
|
||||||
"invalid_phone_number": "Invalid Phone Number",
|
"invalid_phone_number": "Invalid Phone Number",
|
||||||
"invalid_phone_numbers": "One or more of the phone numbers are invalid. Please provide them without symbols and spaces, or in this format: +1(123)123-1234",
|
"invalid_phone_numbers": "One or more of the phone numbers are invalid. Please provide them without symbols and spaces, or in this format: +1(123)123-1234",
|
||||||
@@ -753,8 +763,8 @@
|
|||||||
"success_remove_claim": "Successfully removed claim on: {{serial}}",
|
"success_remove_claim": "Successfully removed claim on: {{serial}}",
|
||||||
"successful_reboots": "Started Rebooting: {{count}}",
|
"successful_reboots": "Started Rebooting: {{count}}",
|
||||||
"successful_upgrades": "Successful upgrades: {{count}}",
|
"successful_upgrades": "Successful upgrades: {{count}}",
|
||||||
"tag_one": "Tag",
|
"tag_one": "Device",
|
||||||
"tags": "Inventory Tags",
|
"tags": "Inventory Devices",
|
||||||
"title": "Inventory",
|
"title": "Inventory",
|
||||||
"warning_reboots": "Not connected: {{count}}",
|
"warning_reboots": "Not connected: {{count}}",
|
||||||
"warning_upgrades": "Devices not connected: {{count}}"
|
"warning_upgrades": "Devices not connected: {{count}}"
|
||||||
@@ -1072,14 +1082,23 @@
|
|||||||
"version": "Version"
|
"version": "Version"
|
||||||
},
|
},
|
||||||
"table": {
|
"table": {
|
||||||
|
"columns": "Columns",
|
||||||
"columns_hidden_one": "{{count}} Column Hidden",
|
"columns_hidden_one": "{{count}} Column Hidden",
|
||||||
"columns_hidden_other": "{{count}} Columns Hidden",
|
"columns_hidden_other": "{{count}} Columns Hidden",
|
||||||
|
"display_column": "Display",
|
||||||
|
"drag_always_show": "You cannot hide this column but can change its position ",
|
||||||
|
"drag_explanation": "Drag and drop to reorder and change column visibility",
|
||||||
|
"drag_locked": "This column is locked in its position",
|
||||||
"first_page": "First Page",
|
"first_page": "First Page",
|
||||||
"go_to_page": "Go to page",
|
"go_to_page": "Go to page",
|
||||||
|
"hide_column": "Hide",
|
||||||
"last_page": "Last Page",
|
"last_page": "Last Page",
|
||||||
"next_page": "Next Page",
|
"next_page": "Next Page",
|
||||||
"page": "Page",
|
"page": "Page",
|
||||||
"previous_page": "Previous Page"
|
"preferences": "Table Preferences",
|
||||||
|
"previous_page": "Previous Page",
|
||||||
|
"reset": "Reset Preferences",
|
||||||
|
"settings": "Settings"
|
||||||
},
|
},
|
||||||
"user": {
|
"user": {
|
||||||
"email_not_validated": "email not validated",
|
"email_not_validated": "email not validated",
|
||||||
|
|||||||
@@ -356,6 +356,7 @@
|
|||||||
"error_pushes_one": "Error (podría deberse a una mala configuración): {{count}}",
|
"error_pushes_one": "Error (podría deberse a una mala configuración): {{count}}",
|
||||||
"error_pushes_other": "Errores (pueden deberse a una mala configuración): {{count}}",
|
"error_pushes_other": "Errores (pueden deberse a una mala configuración): {{count}}",
|
||||||
"expert_name": "Modo experto",
|
"expert_name": "Modo experto",
|
||||||
|
"expert_name_explanation": "Puede usar el modo experto para modificar directamente su configuración, incluida la adición de valores que actualmente no son compatibles con la interfaz de usuario. Utilice este formato: { \"interfaces\": [ ... ], \"globals\": { ... }, ...etc }",
|
||||||
"explanation": "Explicación",
|
"explanation": "Explicación",
|
||||||
"firewall": "cortafuegos",
|
"firewall": "cortafuegos",
|
||||||
"firmware_upgrade": "Actualización de firmware",
|
"firmware_upgrade": "Actualización de firmware",
|
||||||
@@ -522,6 +523,7 @@
|
|||||||
"ouis_explanation": "OUI de dispositivos que se han conectado a este servidor de firmware",
|
"ouis_explanation": "OUI de dispositivos que se han conectado a este servidor de firmware",
|
||||||
"outdated_one": "Firmware {{count}} día de antigüedad",
|
"outdated_one": "Firmware {{count}} día de antigüedad",
|
||||||
"outdated_other": "Firmware de {{count}} días de antigüedad",
|
"outdated_other": "Firmware de {{count}} días de antigüedad",
|
||||||
|
"outdated_unknown": "Firmware de antigüedad desconocida",
|
||||||
"release": "Lanzamiento",
|
"release": "Lanzamiento",
|
||||||
"show_dev_releases": "Lanzamientos de desarrollo",
|
"show_dev_releases": "Lanzamientos de desarrollo",
|
||||||
"status_explanation": "Estado de conexión de los dispositivos que se han conectado a este servidor de firmware",
|
"status_explanation": "Estado de conexión de los dispositivos que se han conectado a este servidor de firmware",
|
||||||
@@ -537,6 +539,14 @@
|
|||||||
"queue": {
|
"queue": {
|
||||||
"title": "Cola de eventos"
|
"title": "Cola de eventos"
|
||||||
},
|
},
|
||||||
|
"radius": {
|
||||||
|
"calling_station_id": "Estación",
|
||||||
|
"input_octets": "entrada",
|
||||||
|
"output_octets": "salida",
|
||||||
|
"radius_clients": "Clientes de radio",
|
||||||
|
"session_time": "Tiempo de sesión",
|
||||||
|
"username": "Nombre de usuario"
|
||||||
|
},
|
||||||
"stats": {
|
"stats": {
|
||||||
"load": "Carga (1 | 5 | 15 m.)",
|
"load": "Carga (1 | 5 | 15 m.)",
|
||||||
"seconds_ago": " Hace {{s}} segundos",
|
"seconds_ago": " Hace {{s}} segundos",
|
||||||
@@ -712,7 +722,7 @@
|
|||||||
"invalid_ipv6": "Dirección IPv6 no válida (ej.: 2001:db8:3333:4444:5555:6666:7777:8888)",
|
"invalid_ipv6": "Dirección IPv6 no válida (ej.: 2001:db8:3333:4444:5555:6666:7777:8888)",
|
||||||
"invalid_json": "Cadena JSON no válida",
|
"invalid_json": "Cadena JSON no válida",
|
||||||
"invalid_lease_time": "¡Valor de tiempo de arrendamiento no válido! Deben estar en el formato digitUnit. Por ejemplo: 6d2h5m, lo que significa 6 días, 2 horas y 5 minutos. Estas son las unidades aceptadas: m, h, d. Si no desea utilizar una unidad, omítala por completo. Entonces, en lugar de decir 0d2h0m, usa 2h",
|
"invalid_lease_time": "¡Valor de tiempo de arrendamiento no válido! Deben estar en el formato digitUnit. Por ejemplo: 6d2h5m, lo que significa 6 días, 2 horas y 5 minutos. Estas son las unidades aceptadas: m, h, d. Si no desea utilizar una unidad, omítala por completo. Entonces, en lugar de decir 0d2h0m, usa 2h",
|
||||||
"invalid_mac_uc": "Valor de UC-MAC no válido, por ejemplo: 00:00:5e:00:53:af",
|
"invalid_mac_uc": "Valor de MAC no válido, por ejemplo: 00:00:5e:00:53:af",
|
||||||
"invalid_password": "Contraseña no válida, consulte la política de contraseñas",
|
"invalid_password": "Contraseña no válida, consulte la política de contraseñas",
|
||||||
"invalid_phone_number": "Numero de telefono invalido",
|
"invalid_phone_number": "Numero de telefono invalido",
|
||||||
"invalid_phone_numbers": "Uno o más de los números de teléfono no son válidos. Proporciónelos sin símbolos ni espacios, o en este formato: +1(123)123-1234",
|
"invalid_phone_numbers": "Uno o más de los números de teléfono no son válidos. Proporciónelos sin símbolos ni espacios, o en este formato: +1(123)123-1234",
|
||||||
@@ -1072,14 +1082,23 @@
|
|||||||
"version": "Versión"
|
"version": "Versión"
|
||||||
},
|
},
|
||||||
"table": {
|
"table": {
|
||||||
|
"columns": "Columnas",
|
||||||
"columns_hidden_one": "{{count}} columna oculta",
|
"columns_hidden_one": "{{count}} columna oculta",
|
||||||
"columns_hidden_other": "{{count}} columnas ocultas",
|
"columns_hidden_other": "{{count}} columnas ocultas",
|
||||||
|
"display_column": "Monitor",
|
||||||
|
"drag_always_show": "No puede ocultar esta columna pero puede cambiar su posición",
|
||||||
|
"drag_explanation": "Arrastre y suelte para reordenar y cambiar la visibilidad de las columnas",
|
||||||
|
"drag_locked": "Esta columna está bloqueada en su posición.",
|
||||||
"first_page": "Primera pagina",
|
"first_page": "Primera pagina",
|
||||||
"go_to_page": "Ir a la página",
|
"go_to_page": "Ir a la página",
|
||||||
|
"hide_column": "Esconder",
|
||||||
"last_page": "Ultima pagina",
|
"last_page": "Ultima pagina",
|
||||||
"next_page": "Siguiente página",
|
"next_page": "Siguiente página",
|
||||||
"page": "Página",
|
"page": "Página",
|
||||||
"previous_page": "Página anterior"
|
"preferences": "Preferencias de mesa",
|
||||||
|
"previous_page": "Página anterior",
|
||||||
|
"reset": "Reiniciar preferencias",
|
||||||
|
"settings": "Ajustes"
|
||||||
},
|
},
|
||||||
"user": {
|
"user": {
|
||||||
"email_not_validated": "correo electrónico no validado",
|
"email_not_validated": "correo electrónico no validado",
|
||||||
|
|||||||
@@ -356,6 +356,7 @@
|
|||||||
"error_pushes_one": "Erreur (peut être due à une mauvaise configuration) : {{count}}",
|
"error_pushes_one": "Erreur (peut être due à une mauvaise configuration) : {{count}}",
|
||||||
"error_pushes_other": "Erreurs (peut-être dues à une mauvaise configuration) : {{count}}",
|
"error_pushes_other": "Erreurs (peut-être dues à une mauvaise configuration) : {{count}}",
|
||||||
"expert_name": "Mode expert",
|
"expert_name": "Mode expert",
|
||||||
|
"expert_name_explanation": "Vous pouvez utiliser le mode expert pour modifier directement votre configuration, notamment en ajoutant des valeurs qui ne sont pas actuellement prises en charge par l'interface utilisateur. Veuillez utiliser ce format : { \"interfaces\": [ ... ], \"globals\": { ... }, ...etc }",
|
||||||
"explanation": "Explication",
|
"explanation": "Explication",
|
||||||
"firewall": "Pare-feu",
|
"firewall": "Pare-feu",
|
||||||
"firmware_upgrade": "Mise à jour du firmware",
|
"firmware_upgrade": "Mise à jour du firmware",
|
||||||
@@ -522,6 +523,7 @@
|
|||||||
"ouis_explanation": "OUI des appareils qui se sont connectés à ce serveur de firmware",
|
"ouis_explanation": "OUI des appareils qui se sont connectés à ce serveur de firmware",
|
||||||
"outdated_one": "Micrologiciel vieux de {{count}} jours",
|
"outdated_one": "Micrologiciel vieux de {{count}} jours",
|
||||||
"outdated_other": "Micrologiciel vieux de {{count}} jours",
|
"outdated_other": "Micrologiciel vieux de {{count}} jours",
|
||||||
|
"outdated_unknown": "Firmware d'âge inconnu",
|
||||||
"release": "libération",
|
"release": "libération",
|
||||||
"show_dev_releases": "Versions de développement",
|
"show_dev_releases": "Versions de développement",
|
||||||
"status_explanation": "État de connexion des appareils qui se sont connectés à ce serveur de micrologiciel",
|
"status_explanation": "État de connexion des appareils qui se sont connectés à ce serveur de micrologiciel",
|
||||||
@@ -537,6 +539,14 @@
|
|||||||
"queue": {
|
"queue": {
|
||||||
"title": "File d'attente d'événements"
|
"title": "File d'attente d'événements"
|
||||||
},
|
},
|
||||||
|
"radius": {
|
||||||
|
"calling_station_id": "Station",
|
||||||
|
"input_octets": "Contribution",
|
||||||
|
"output_octets": "Sortie",
|
||||||
|
"radius_clients": "Clients rayon",
|
||||||
|
"session_time": "Temps de session",
|
||||||
|
"username": "Nom d'utilisateur"
|
||||||
|
},
|
||||||
"stats": {
|
"stats": {
|
||||||
"load": "Charge (1 | 5 | 15 m.)",
|
"load": "Charge (1 | 5 | 15 m.)",
|
||||||
"seconds_ago": " Il y a {{s}} secondes",
|
"seconds_ago": " Il y a {{s}} secondes",
|
||||||
@@ -712,7 +722,7 @@
|
|||||||
"invalid_ipv6": "Adresse IPv6 invalide (ex. : 2001:db8:3333:4444:5555:6666:7777:8888)",
|
"invalid_ipv6": "Adresse IPv6 invalide (ex. : 2001:db8:3333:4444:5555:6666:7777:8888)",
|
||||||
"invalid_json": "Chaîne JSON non valide",
|
"invalid_json": "Chaîne JSON non valide",
|
||||||
"invalid_lease_time": "Valeur de durée de bail non valide ! Ils doivent être au format digitUnit. Par exemple : 6d2h5m, ce qui signifie 6 jours, 2 heures et 5 minutes. Voici les unités acceptées : m, h, d. Si vous ne voulez pas utiliser une unité, omettez-la complètement. Donc au lieu de dire 0d2h0m, utilisez 2h",
|
"invalid_lease_time": "Valeur de durée de bail non valide ! Ils doivent être au format digitUnit. Par exemple : 6d2h5m, ce qui signifie 6 jours, 2 heures et 5 minutes. Voici les unités acceptées : m, h, d. Si vous ne voulez pas utiliser une unité, omettez-la complètement. Donc au lieu de dire 0d2h0m, utilisez 2h",
|
||||||
"invalid_mac_uc": "Valeur UC-MAC non valide, par exemple : 00:00:5e:00:53:af",
|
"invalid_mac_uc": "Valeur MAC non valide, par exemple : 00:00:5e:00:53:af",
|
||||||
"invalid_password": "Mot de passe invalide, veuillez consulter la politique de mot de passe",
|
"invalid_password": "Mot de passe invalide, veuillez consulter la politique de mot de passe",
|
||||||
"invalid_phone_number": "Numéro de téléphone invalide",
|
"invalid_phone_number": "Numéro de téléphone invalide",
|
||||||
"invalid_phone_numbers": "Un ou plusieurs des numéros de téléphone sont invalides. Veuillez les fournir sans symboles ni espaces, ou dans ce format : +1(123)123-1234",
|
"invalid_phone_numbers": "Un ou plusieurs des numéros de téléphone sont invalides. Veuillez les fournir sans symboles ni espaces, ou dans ce format : +1(123)123-1234",
|
||||||
@@ -1072,14 +1082,23 @@
|
|||||||
"version": "Version"
|
"version": "Version"
|
||||||
},
|
},
|
||||||
"table": {
|
"table": {
|
||||||
|
"columns": "Les colonnes",
|
||||||
"columns_hidden_one": "{{count}} Colonne masquée",
|
"columns_hidden_one": "{{count}} Colonne masquée",
|
||||||
"columns_hidden_other": "{{count}} colonnes masquées",
|
"columns_hidden_other": "{{count}} colonnes masquées",
|
||||||
|
"display_column": "Afficher",
|
||||||
|
"drag_always_show": "Vous ne pouvez pas masquer cette colonne, mais vous pouvez modifier sa position",
|
||||||
|
"drag_explanation": "Glisser-déposer pour réorganiser et modifier la visibilité des colonnes",
|
||||||
|
"drag_locked": "Cette colonne est verrouillée dans sa position",
|
||||||
"first_page": "Première page",
|
"first_page": "Première page",
|
||||||
"go_to_page": "Aller à la page",
|
"go_to_page": "Aller à la page",
|
||||||
|
"hide_column": "Cacher",
|
||||||
"last_page": "Dernière page",
|
"last_page": "Dernière page",
|
||||||
"next_page": "Page suivante",
|
"next_page": "Page suivante",
|
||||||
"page": "Page",
|
"page": "Page",
|
||||||
"previous_page": "Page précédente"
|
"preferences": "Préférences de tableau",
|
||||||
|
"previous_page": "Page précédente",
|
||||||
|
"reset": "Remettre à zéro les préférences",
|
||||||
|
"settings": "Réglages"
|
||||||
},
|
},
|
||||||
"user": {
|
"user": {
|
||||||
"email_not_validated": "Mail non valide",
|
"email_not_validated": "Mail non valide",
|
||||||
|
|||||||
@@ -356,6 +356,7 @@
|
|||||||
"error_pushes_one": "Erro (pode ser devido à configuração incorreta): {{count}}",
|
"error_pushes_one": "Erro (pode ser devido à configuração incorreta): {{count}}",
|
||||||
"error_pushes_other": "Erros (podem ser devido à configuração incorreta): {{count}}",
|
"error_pushes_other": "Erros (podem ser devido à configuração incorreta): {{count}}",
|
||||||
"expert_name": "MODO EXPERT",
|
"expert_name": "MODO EXPERT",
|
||||||
|
"expert_name_explanation": "Você pode usar o modo especialista para modificar diretamente sua configuração, incluindo a adição de valores que não são atualmente suportados pela interface do usuário. Use este formato: { \"interfaces\": [ ... ], \"globals\": { ... }, ...etc }",
|
||||||
"explanation": "Explicação",
|
"explanation": "Explicação",
|
||||||
"firewall": "Firewall",
|
"firewall": "Firewall",
|
||||||
"firmware_upgrade": "Atualização de firmware",
|
"firmware_upgrade": "Atualização de firmware",
|
||||||
@@ -522,6 +523,7 @@
|
|||||||
"ouis_explanation": "OUIs de dispositivos que se conectaram a este servidor de firmware",
|
"ouis_explanation": "OUIs de dispositivos que se conectaram a este servidor de firmware",
|
||||||
"outdated_one": "Firmware com {{count}} dias",
|
"outdated_one": "Firmware com {{count}} dias",
|
||||||
"outdated_other": "Firmware com {{count}} dias",
|
"outdated_other": "Firmware com {{count}} dias",
|
||||||
|
"outdated_unknown": "Firmware de idade desconhecida",
|
||||||
"release": "LANÇAMENTO",
|
"release": "LANÇAMENTO",
|
||||||
"show_dev_releases": "Lançamentos do desenvolvedor",
|
"show_dev_releases": "Lançamentos do desenvolvedor",
|
||||||
"status_explanation": "Status da conexão dos dispositivos que se conectaram a este servidor de firmware",
|
"status_explanation": "Status da conexão dos dispositivos que se conectaram a este servidor de firmware",
|
||||||
@@ -537,6 +539,14 @@
|
|||||||
"queue": {
|
"queue": {
|
||||||
"title": "Fila de Eventos"
|
"title": "Fila de Eventos"
|
||||||
},
|
},
|
||||||
|
"radius": {
|
||||||
|
"calling_station_id": "estação",
|
||||||
|
"input_octets": "Entrada",
|
||||||
|
"output_octets": "Saída",
|
||||||
|
"radius_clients": "Clientes Radius",
|
||||||
|
"session_time": "Tempo de sessão",
|
||||||
|
"username": "Nome de usuário"
|
||||||
|
},
|
||||||
"stats": {
|
"stats": {
|
||||||
"load": "Carga (1 | 5 | 15 m.)",
|
"load": "Carga (1 | 5 | 15 m.)",
|
||||||
"seconds_ago": "{{s}} segundos atrás",
|
"seconds_ago": "{{s}} segundos atrás",
|
||||||
@@ -712,7 +722,7 @@
|
|||||||
"invalid_ipv6": "Endereço IPv6 inválido (ex.: 2001:db8:3333:4444:5555:6666:7777:8888)",
|
"invalid_ipv6": "Endereço IPv6 inválido (ex.: 2001:db8:3333:4444:5555:6666:7777:8888)",
|
||||||
"invalid_json": "Sequência JSON inválida",
|
"invalid_json": "Sequência JSON inválida",
|
||||||
"invalid_lease_time": "Valor de tempo de locação inválido! Eles precisam estar no formato digitUnit. Por exemplo: 6d2h5m, que significa 6 dias, 2 horas e 5 minutos. Aqui estão as unidades aceitas: m, h, d. Se você não quiser usar uma unidade, omita-a completamente. Então, em vez de dizer 0d2h0m, use 2h",
|
"invalid_lease_time": "Valor de tempo de locação inválido! Eles precisam estar no formato digitUnit. Por exemplo: 6d2h5m, que significa 6 dias, 2 horas e 5 minutos. Aqui estão as unidades aceitas: m, h, d. Se você não quiser usar uma unidade, omita-a completamente. Então, em vez de dizer 0d2h0m, use 2h",
|
||||||
"invalid_mac_uc": "Valor UC-MAC inválido, por exemplo: 00:00:5e:00:53:af",
|
"invalid_mac_uc": "Valor MAC inválido, por exemplo: 00:00:5e:00:53:af",
|
||||||
"invalid_password": "Senha inválida, consulte a política de senha",
|
"invalid_password": "Senha inválida, consulte a política de senha",
|
||||||
"invalid_phone_number": "Número de telefone inválido",
|
"invalid_phone_number": "Número de telefone inválido",
|
||||||
"invalid_phone_numbers": "Um ou mais números de telefone são inválidos. Forneça-os sem símbolos e espaços ou neste formato: +1(123)123-1234",
|
"invalid_phone_numbers": "Um ou mais números de telefone são inválidos. Forneça-os sem símbolos e espaços ou neste formato: +1(123)123-1234",
|
||||||
@@ -1072,14 +1082,23 @@
|
|||||||
"version": "Versão"
|
"version": "Versão"
|
||||||
},
|
},
|
||||||
"table": {
|
"table": {
|
||||||
|
"columns": "Colunas",
|
||||||
"columns_hidden_one": "{{count}} Coluna oculta",
|
"columns_hidden_one": "{{count}} Coluna oculta",
|
||||||
"columns_hidden_other": "{{count}} Colunas ocultas",
|
"columns_hidden_other": "{{count}} Colunas ocultas",
|
||||||
|
"display_column": "Exibição",
|
||||||
|
"drag_always_show": "Você não pode ocultar esta coluna, mas pode alterar sua posição",
|
||||||
|
"drag_explanation": "Arraste e solte para reordenar e alterar a visibilidade da coluna",
|
||||||
|
"drag_locked": "Esta coluna está travada em sua posição",
|
||||||
"first_page": "Primeira Página",
|
"first_page": "Primeira Página",
|
||||||
"go_to_page": "Vá para página",
|
"go_to_page": "Vá para página",
|
||||||
|
"hide_column": "Ocultar",
|
||||||
"last_page": "Última Página",
|
"last_page": "Última Página",
|
||||||
"next_page": "Próxima página",
|
"next_page": "Próxima página",
|
||||||
"page": "Página",
|
"page": "Página",
|
||||||
"previous_page": "Página anterior"
|
"preferences": "Preferências de Tabela",
|
||||||
|
"previous_page": "Página anterior",
|
||||||
|
"reset": "Reiniciar preferências",
|
||||||
|
"settings": "Definições"
|
||||||
},
|
},
|
||||||
"user": {
|
"user": {
|
||||||
"email_not_validated": "e-mail não validado",
|
"email_not_validated": "e-mail não validado",
|
||||||
|
|||||||
@@ -1,79 +0,0 @@
|
|||||||
import * as React from 'react';
|
|
||||||
import { Heading } from '@chakra-ui/react';
|
|
||||||
import { Select } from 'chakra-react-select';
|
|
||||||
import { useTranslation } from 'react-i18next';
|
|
||||||
import { useNavigate } from 'react-router-dom';
|
|
||||||
import { useAuth } from 'contexts/AuthProvider';
|
|
||||||
import { useControllerDeviceSearch } from 'contexts/ControllerSocketProvider/hooks/Commands/useDeviceSearch';
|
|
||||||
import { useControllerStore } from 'contexts/ControllerSocketProvider/useStore';
|
|
||||||
|
|
||||||
const DeviceSearchBar = () => {
|
|
||||||
const { t } = useTranslation();
|
|
||||||
const navigate = useNavigate();
|
|
||||||
const { token } = useAuth();
|
|
||||||
const { startWebSocket, isWebSocketOpen } = useControllerStore((state) => ({
|
|
||||||
startWebSocket: state.startWebSocket,
|
|
||||||
isWebSocketOpen: state.isWebSocketOpen,
|
|
||||||
}));
|
|
||||||
const { inputValue, results, onInputChange } = useControllerDeviceSearch({
|
|
||||||
minLength: 2,
|
|
||||||
});
|
|
||||||
|
|
||||||
const NoOptionsMessage = React.useCallback(
|
|
||||||
() => (
|
|
||||||
<Heading size="sm" textAlign="center">
|
|
||||||
{isWebSocketOpen ? t('common.no_devices_found') : `${t('controller.devices.connecting')}...`}
|
|
||||||
</Heading>
|
|
||||||
),
|
|
||||||
[t, isWebSocketOpen],
|
|
||||||
);
|
|
||||||
const onClick = React.useCallback((v: { value: string }) => {
|
|
||||||
navigate(`/devices/${v.value}`);
|
|
||||||
}, []);
|
|
||||||
const onChange = React.useCallback((v: string) => {
|
|
||||||
if ((v.length === 0 || v.match('^[a-fA-F0-9-*]+$')) && v.length <= 13) onInputChange(v);
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
const onFocus = () => {
|
|
||||||
if (!isWebSocketOpen && token && token.length > 0) {
|
|
||||||
startWebSocket(token, 0);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
return (
|
|
||||||
<Select
|
|
||||||
chakraStyles={{
|
|
||||||
control: (provided) => ({
|
|
||||||
...provided,
|
|
||||||
borderRadius: '15px',
|
|
||||||
color: 'unset',
|
|
||||||
}),
|
|
||||||
input: (provided) => ({
|
|
||||||
...provided,
|
|
||||||
width: '140px',
|
|
||||||
}),
|
|
||||||
dropdownIndicator: (provided) => ({
|
|
||||||
...provided,
|
|
||||||
backgroundColor: 'unset',
|
|
||||||
border: 'unset',
|
|
||||||
}),
|
|
||||||
menu: (provided) => ({
|
|
||||||
...provided,
|
|
||||||
color: 'black',
|
|
||||||
}),
|
|
||||||
}}
|
|
||||||
components={{ NoOptionsMessage }}
|
|
||||||
// @ts-ignore
|
|
||||||
options={results.map((v: string) => ({ label: v, value: v }))}
|
|
||||||
filterOption={() => true}
|
|
||||||
inputValue={inputValue}
|
|
||||||
value={inputValue}
|
|
||||||
placeholder={t('common.search')}
|
|
||||||
onInputChange={onChange}
|
|
||||||
onFocus={onFocus}
|
|
||||||
// @ts-ignore
|
|
||||||
onChange={onClick}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default DeviceSearchBar;
|
|
||||||
155
src/components/GlobalSearchBar/index.tsx
Normal file
155
src/components/GlobalSearchBar/index.tsx
Normal file
@@ -0,0 +1,155 @@
|
|||||||
|
import * as React from 'react';
|
||||||
|
import { Tooltip, useColorModeValue } from '@chakra-ui/react';
|
||||||
|
import {
|
||||||
|
AsyncSelect,
|
||||||
|
ChakraStylesConfig,
|
||||||
|
GroupBase,
|
||||||
|
LoadingIndicatorProps,
|
||||||
|
OptionBase,
|
||||||
|
OptionsOrGroups,
|
||||||
|
chakraComponents,
|
||||||
|
} from 'chakra-react-select';
|
||||||
|
import { useNavigate } from 'react-router-dom';
|
||||||
|
import { useControllerStore } from 'contexts/ControllerSocketProvider/useStore';
|
||||||
|
import debounce from 'helpers/debounce';
|
||||||
|
import { getUsernameRadiusSessions } from 'hooks/Network/Radius';
|
||||||
|
|
||||||
|
const chakraStyles: ChakraStylesConfig<SearchOption, false, GroupBase<SearchOption>> = {
|
||||||
|
dropdownIndicator: (provided) => ({
|
||||||
|
...provided,
|
||||||
|
width: '32px',
|
||||||
|
}),
|
||||||
|
placeholder: (provided) => ({
|
||||||
|
...provided,
|
||||||
|
lineHeight: '1',
|
||||||
|
}),
|
||||||
|
container: (provided) => ({
|
||||||
|
...provided,
|
||||||
|
width: '320px',
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
|
||||||
|
interface SearchOption extends OptionBase {
|
||||||
|
label: string;
|
||||||
|
value: string;
|
||||||
|
type: 'serial' | 'radius-username' | 'radius-mac';
|
||||||
|
}
|
||||||
|
|
||||||
|
const asyncComponents = {
|
||||||
|
LoadingIndicator: (props: LoadingIndicatorProps<SearchOption, false, GroupBase<SearchOption>>) => {
|
||||||
|
const { color, emptyColor } = useColorModeValue(
|
||||||
|
{
|
||||||
|
color: 'blue.500',
|
||||||
|
emptyColor: 'blue.100',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color: 'blue.300',
|
||||||
|
emptyColor: 'blue.900',
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<chakraComponents.LoadingIndicator
|
||||||
|
color={color}
|
||||||
|
emptyColor={emptyColor}
|
||||||
|
speed="750ms"
|
||||||
|
spinnerSize="md"
|
||||||
|
thickness="3px"
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const GlobalSearchBar = () => {
|
||||||
|
const navigate = useNavigate();
|
||||||
|
const store = useControllerStore((state) => ({
|
||||||
|
searchSerialNumber: state.searchSerialNumber,
|
||||||
|
}));
|
||||||
|
|
||||||
|
const onNewSearch = React.useCallback(
|
||||||
|
async (v: string, callback: (options: OptionsOrGroups<SearchOption, GroupBase<SearchOption>>) => void) => {
|
||||||
|
if (v.length < 3) return callback([]);
|
||||||
|
|
||||||
|
if (v.includes('rad:')) {
|
||||||
|
const trimmed = v.replace('rad:', '').trim();
|
||||||
|
if (trimmed.length < 3) return callback([]);
|
||||||
|
const cleaned = trimmed.toLowerCase();
|
||||||
|
return getUsernameRadiusSessions(cleaned)
|
||||||
|
.then((res) =>
|
||||||
|
callback(
|
||||||
|
res
|
||||||
|
.map((r) => ({
|
||||||
|
label: r.serialNumber,
|
||||||
|
value: r.serialNumber,
|
||||||
|
type: 'radius-username',
|
||||||
|
}))
|
||||||
|
.filter(({ value }, i, a) => a.findIndex((t) => t.value === value) === i) as SearchOption[],
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.then(() => callback([]));
|
||||||
|
}
|
||||||
|
if (v.match('^[a-fA-F0-9-*]+$')) {
|
||||||
|
await store
|
||||||
|
.searchSerialNumber(v)
|
||||||
|
.then((res) => {
|
||||||
|
callback(
|
||||||
|
res.map((r) => ({
|
||||||
|
label: r,
|
||||||
|
value: r,
|
||||||
|
type: 'serial',
|
||||||
|
})),
|
||||||
|
);
|
||||||
|
})
|
||||||
|
.catch(() => []);
|
||||||
|
}
|
||||||
|
return callback([]);
|
||||||
|
},
|
||||||
|
[],
|
||||||
|
);
|
||||||
|
|
||||||
|
const debouncedNewSearch = React.useCallback(
|
||||||
|
debounce(
|
||||||
|
// @ts-ignore
|
||||||
|
({
|
||||||
|
v,
|
||||||
|
callback,
|
||||||
|
}: {
|
||||||
|
v: string;
|
||||||
|
callback: (options: OptionsOrGroups<SearchOption, GroupBase<SearchOption>>) => void;
|
||||||
|
}) => {
|
||||||
|
onNewSearch(v as string, callback);
|
||||||
|
},
|
||||||
|
300,
|
||||||
|
),
|
||||||
|
[],
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Tooltip
|
||||||
|
label={`Search serial numbers and radius clients. For radius clients you can either use the client's username (rad:client@client.com)
|
||||||
|
or use the client's station ID (rad:11:22:33:44:55:66)`}
|
||||||
|
shouldWrapChildren
|
||||||
|
placement="left"
|
||||||
|
>
|
||||||
|
<AsyncSelect<SearchOption, false, GroupBase<SearchOption>>
|
||||||
|
name="global_search"
|
||||||
|
chakraStyles={chakraStyles}
|
||||||
|
closeMenuOnSelect
|
||||||
|
placeholder="Search MACs or radius clients"
|
||||||
|
components={asyncComponents}
|
||||||
|
loadOptions={(inputValue, callback) => {
|
||||||
|
debouncedNewSearch({ v: inputValue, callback });
|
||||||
|
}}
|
||||||
|
value={null}
|
||||||
|
onChange={(newValue) => {
|
||||||
|
if (newValue) {
|
||||||
|
navigate(`/devices/${newValue.value}`);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</Tooltip>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default GlobalSearchBar;
|
||||||
@@ -3,6 +3,7 @@ import { v4 as uuid } from 'uuid';
|
|||||||
import create from 'zustand';
|
import create from 'zustand';
|
||||||
import { ControllerSocketRawMessage, SocketEventCallback, SocketWebSocketNotificationData } from './utils';
|
import { ControllerSocketRawMessage, SocketEventCallback, SocketWebSocketNotificationData } from './utils';
|
||||||
import { axiosGw } from 'constants/axiosInstances';
|
import { axiosGw } from 'constants/axiosInstances';
|
||||||
|
import { randomIntId } from 'helpers/stringHelper';
|
||||||
import { DevicesStats, DeviceWithStatus } from 'hooks/Network/Devices';
|
import { DevicesStats, DeviceWithStatus } from 'hooks/Network/Devices';
|
||||||
import { NotificationType } from 'models/Socket';
|
import { NotificationType } from 'models/Socket';
|
||||||
|
|
||||||
@@ -122,6 +123,7 @@ export type ControllerStoreState = {
|
|||||||
lastSearchResults: string[];
|
lastSearchResults: string[];
|
||||||
setLastSearchResults: (result: string[]) => void;
|
setLastSearchResults: (result: string[]) => void;
|
||||||
errors: { str: string; timestamp: Date }[];
|
errors: { str: string; timestamp: Date }[];
|
||||||
|
searchSerialNumber: (serialNumber: string, timeout?: number) => Promise<string[]>;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useControllerStore = create<ControllerStoreState>((set, get) => ({
|
export const useControllerStore = create<ControllerStoreState>((set, get) => ({
|
||||||
@@ -169,14 +171,24 @@ export const useControllerStore = create<ControllerStoreState>((set, get) => ({
|
|||||||
id: uuid(),
|
id: uuid(),
|
||||||
};
|
};
|
||||||
|
|
||||||
const eventsToFire = get().eventListeners.filter(
|
const eventsToFire = get().eventListeners.filter((event) => {
|
||||||
({ type, serialNumber }) => type === msg.type && serialNumber === msg.serialNumber,
|
if (event.type === 'DEVICE_CONNECTION' || event.type === 'DEVICE_DISCONNECTION') {
|
||||||
);
|
return event.serialNumber === msg.serialNumber;
|
||||||
|
}
|
||||||
|
if (msg.type === 'DEVICE_SEARCH_RESULTS' && event.type === 'DEVICE_SEARCH_RESULTS') {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
if (eventsToFire.length > 0) {
|
if (eventsToFire.length > 0) {
|
||||||
for (const event of eventsToFire) {
|
for (const event of eventsToFire) {
|
||||||
|
if (event.type === 'DEVICE_SEARCH_RESULTS' && msg.type === 'DEVICE_SEARCH_RESULTS') {
|
||||||
|
event.callback(msg.serialNumbers);
|
||||||
|
} else if (event.type === 'DEVICE_CONNECTION' || event.type === 'DEVICE_DISCONNECTION') {
|
||||||
event.callback();
|
event.callback();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return set((state) => ({
|
return set((state) => ({
|
||||||
allMessages:
|
allMessages:
|
||||||
@@ -211,6 +223,37 @@ export const useControllerStore = create<ControllerStoreState>((set, get) => ({
|
|||||||
const ws = get().webSocket;
|
const ws = get().webSocket;
|
||||||
if (ws) ws.send(str);
|
if (ws) ws.send(str);
|
||||||
},
|
},
|
||||||
|
searchSerialNumber: async (serialNumber: string, timeout = 1000 * 5): Promise<string[]> =>
|
||||||
|
new Promise((resolve, reject) => {
|
||||||
|
const timer = setTimeout(() => {
|
||||||
|
reject(new Error(`Promise timed out after ${timeout} ms`));
|
||||||
|
}, timeout);
|
||||||
|
const ws = get().webSocket;
|
||||||
|
if (ws) {
|
||||||
|
const id = randomIntId();
|
||||||
|
get().addEventListeners([
|
||||||
|
{
|
||||||
|
id: uuid(),
|
||||||
|
type: 'DEVICE_SEARCH_RESULTS',
|
||||||
|
searchId: id,
|
||||||
|
callback: (serialNumbers: string[]) => {
|
||||||
|
clearTimeout(timer);
|
||||||
|
resolve(serialNumbers);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
ws.send(
|
||||||
|
JSON.stringify({
|
||||||
|
command: 'serial_number_search',
|
||||||
|
serial_prefix: serialNumber,
|
||||||
|
id: randomIntId(),
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
clearTimeout(timer);
|
||||||
|
reject(new Error('No websocket connection'));
|
||||||
|
}
|
||||||
|
}),
|
||||||
startWebSocket: (token: string, tries = 0) => {
|
startWebSocket: (token: string, tries = 0) => {
|
||||||
const newTries = tries + 1;
|
const newTries = tries + 1;
|
||||||
if (tries <= 10) {
|
if (tries <= 10) {
|
||||||
|
|||||||
@@ -116,9 +116,16 @@ export type SocketWebSocketNotificationData =
|
|||||||
log?: undefined;
|
log?: undefined;
|
||||||
message: InitialSocketMessage;
|
message: InitialSocketMessage;
|
||||||
};
|
};
|
||||||
export type SocketEventCallback = {
|
export type SocketEventCallback =
|
||||||
|
| {
|
||||||
id: string;
|
id: string;
|
||||||
type: 'DEVICE_CONNECTION' | 'DEVICE_DISCONNECTION';
|
type: 'DEVICE_CONNECTION' | 'DEVICE_DISCONNECTION';
|
||||||
serialNumber: string;
|
serialNumber: string;
|
||||||
callback: () => void;
|
callback: () => void;
|
||||||
|
}
|
||||||
|
| {
|
||||||
|
id: string;
|
||||||
|
type: 'DEVICE_SEARCH_RESULTS';
|
||||||
|
searchId: number;
|
||||||
|
callback: (serialNumbers: string[]) => void;
|
||||||
};
|
};
|
||||||
|
|||||||
48
src/hooks/Network/Radius.ts
Normal file
48
src/hooks/Network/Radius.ts
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
import { QueryFunctionContext, useQuery } from '@tanstack/react-query';
|
||||||
|
import { axiosGw } from 'constants/axiosInstances';
|
||||||
|
|
||||||
|
export type RadiusSession = {
|
||||||
|
started: number;
|
||||||
|
lastTransaction: number;
|
||||||
|
inputPackets: number;
|
||||||
|
outputPackets: number;
|
||||||
|
inputOctets: number;
|
||||||
|
outputOctets: number;
|
||||||
|
inputGigaWords: number;
|
||||||
|
outputGigaWords: number;
|
||||||
|
sessionTime: number;
|
||||||
|
serialNumber: string;
|
||||||
|
destination: string;
|
||||||
|
userName: string;
|
||||||
|
accountingSessionId: string;
|
||||||
|
accountingMultiSessionId: string;
|
||||||
|
callingStationId: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getDeviceRadiusSessions = async (mac: string) =>
|
||||||
|
axiosGw.get(`/radiusSessions/${mac}`).then((res) => res.data.sessions as RadiusSession[]);
|
||||||
|
const getDeviceSessions = async (context: QueryFunctionContext<[string, string]>) =>
|
||||||
|
getDeviceRadiusSessions(context.queryKey[1]);
|
||||||
|
export const useGetDeviceRadiusSessions = ({ serialNumber }: { serialNumber: string }) =>
|
||||||
|
useQuery(['radius-sessions', serialNumber], getDeviceSessions, {
|
||||||
|
keepPreviousData: true,
|
||||||
|
staleTime: 1000 * 60,
|
||||||
|
});
|
||||||
|
|
||||||
|
export const getUsernameRadiusSessions = async (username: string) =>
|
||||||
|
axiosGw.get(`/radiusSessions/0?userName=${username}`).then((res) => res.data.sessions as RadiusSession[]);
|
||||||
|
const getUserSessions = async (context: QueryFunctionContext<[string, string, string]>) =>
|
||||||
|
getUsernameRadiusSessions(context.queryKey[2]);
|
||||||
|
export const useGetUserRadiusSessions = ({ userName }: { userName: string }) =>
|
||||||
|
useQuery(['radius-sessions', 'username', userName], getUserSessions, {
|
||||||
|
staleTime: 1000 * 60,
|
||||||
|
});
|
||||||
|
|
||||||
|
export const getStationRadiusSessions = async (station: string) =>
|
||||||
|
axiosGw.get(`/radiusSessions/0?mac=${station}`).then((res) => res.data.sessions as RadiusSession[]);
|
||||||
|
const getStationSessions = async (context: QueryFunctionContext<[string, string, string]>) =>
|
||||||
|
getStationRadiusSessions(context.queryKey[2]);
|
||||||
|
export const useGetStationRadiusSessions = ({ station }: { station: string }) =>
|
||||||
|
useQuery(['radius-sessions', 'station', station], getStationSessions, {
|
||||||
|
staleTime: 1000 * 60,
|
||||||
|
});
|
||||||
@@ -11,6 +11,8 @@ export interface GatewayDevice {
|
|||||||
entity: string;
|
entity: string;
|
||||||
firmware: string;
|
firmware: string;
|
||||||
fwUpdatePolicy: string;
|
fwUpdatePolicy: string;
|
||||||
|
hasGPS: boolean;
|
||||||
|
hasRADIUSSessions: number;
|
||||||
lastConfigurationChange: number;
|
lastConfigurationChange: number;
|
||||||
lastConfigurationDownload: number;
|
lastConfigurationDownload: number;
|
||||||
lastFWUpdate: number;
|
lastFWUpdate: number;
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import { Note } from './Note';
|
import { Note } from './Note';
|
||||||
|
|
||||||
|
|
||||||
export type UserRole =
|
export type UserRole =
|
||||||
| 'root'
|
| 'root'
|
||||||
| 'admin'
|
| 'admin'
|
||||||
|
|||||||
132
src/pages/Device/RadiusClients/Table.tsx
Normal file
132
src/pages/Device/RadiusClients/Table.tsx
Normal file
@@ -0,0 +1,132 @@
|
|||||||
|
/* eslint-disable react/no-unstable-nested-components */
|
||||||
|
import * as React from 'react';
|
||||||
|
import { Box } from '@chakra-ui/react';
|
||||||
|
import { useTranslation } from 'react-i18next';
|
||||||
|
import { DataGrid } from 'components/DataTables/DataGrid';
|
||||||
|
import { DataGridColumn, useDataGrid } from 'components/DataTables/DataGrid/useDataGrid';
|
||||||
|
import DataCell from 'components/TableCells/DataCell';
|
||||||
|
import DurationCell from 'components/TableCells/DurationCell';
|
||||||
|
import { RadiusSession } from 'hooks/Network/Radius';
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
sessions: RadiusSession[];
|
||||||
|
refetch: () => void;
|
||||||
|
isFetching: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
const DeviceRadiusClientsTable = ({ sessions, refetch, isFetching }: Props) => {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
const tableController = useDataGrid({
|
||||||
|
tableSettingsId: 'gateway.device_radius_sessions.table',
|
||||||
|
defaultSortBy: [
|
||||||
|
{
|
||||||
|
id: 'callingStationId',
|
||||||
|
desc: false,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
const columns: DataGridColumn<RadiusSession>[] = React.useMemo(
|
||||||
|
(): DataGridColumn<RadiusSession>[] => [
|
||||||
|
{
|
||||||
|
id: 'callingStationId',
|
||||||
|
header: t('controller.radius.calling_station_id'),
|
||||||
|
accessorKey: 'callingStationId',
|
||||||
|
cell: ({ cell }) => {
|
||||||
|
let { callingStationId } = cell.row.original;
|
||||||
|
callingStationId = callingStationId.replace(/-/g, ':').toLowerCase();
|
||||||
|
return (
|
||||||
|
<div className="flex items-center">
|
||||||
|
<div className="flex-1">{callingStationId}</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
meta: {
|
||||||
|
customWidth: '150px',
|
||||||
|
isMonospace: true,
|
||||||
|
alwaysShow: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'userName',
|
||||||
|
header: t('controller.radius.username'),
|
||||||
|
accessorKey: 'userName',
|
||||||
|
meta: {
|
||||||
|
alwaysShow: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'sessionTime',
|
||||||
|
header: t('controller.radius.session_time'),
|
||||||
|
accessorKey: 'sessionTime',
|
||||||
|
cell: ({ cell }) => {
|
||||||
|
const { sessionTime } = cell.row.original;
|
||||||
|
return <DurationCell seconds={sessionTime} />;
|
||||||
|
},
|
||||||
|
meta: {
|
||||||
|
customWidth: '120px',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'inputOctets',
|
||||||
|
header: t('controller.radius.input_octets'),
|
||||||
|
accessorKey: 'inputOctets',
|
||||||
|
cell: ({ cell }) => {
|
||||||
|
const { inputOctets } = cell.row.original;
|
||||||
|
return (
|
||||||
|
<Box textAlign="right">
|
||||||
|
<DataCell bytes={inputOctets} showZerosAs="-" />
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
meta: {
|
||||||
|
customWidth: '40px',
|
||||||
|
customMinWidth: '40px',
|
||||||
|
headerStyleProps: {
|
||||||
|
textAlign: 'right',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'outputOctets',
|
||||||
|
header: t('controller.radius.output_octets'),
|
||||||
|
accessorKey: 'outputOctets',
|
||||||
|
cell: ({ cell }) => {
|
||||||
|
const { outputOctets } = cell.row.original;
|
||||||
|
return (
|
||||||
|
<Box textAlign="right">
|
||||||
|
<DataCell bytes={outputOctets} showZerosAs="-" />
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
meta: {
|
||||||
|
customWidth: '40px',
|
||||||
|
customMinWidth: '40px',
|
||||||
|
headerStyleProps: {
|
||||||
|
textAlign: 'right',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
[t],
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<DataGrid<RadiusSession>
|
||||||
|
controller={tableController}
|
||||||
|
header={{
|
||||||
|
title: `${t('controller.radius.radius_clients')} (${sessions.length})`,
|
||||||
|
objectListed: t('controller.radius.radius_clients'),
|
||||||
|
}}
|
||||||
|
columns={columns}
|
||||||
|
data={sessions}
|
||||||
|
isLoading={isFetching}
|
||||||
|
options={{
|
||||||
|
refetch,
|
||||||
|
minimumHeight: '200px',
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default DeviceRadiusClientsTable;
|
||||||
32
src/pages/Device/RadiusClients/index.tsx
Normal file
32
src/pages/Device/RadiusClients/index.tsx
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
import * as React from 'react';
|
||||||
|
import { Box } from '@chakra-ui/react';
|
||||||
|
import DeviceRadiusClientsTable from './Table';
|
||||||
|
import { Card } from 'components/Containers/Card';
|
||||||
|
import { CardBody } from 'components/Containers/Card/CardBody';
|
||||||
|
import { useGetDeviceRadiusSessions } from 'hooks/Network/Radius';
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
serialNumber: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
const RadiusClientsCard = ({ serialNumber }: Props) => {
|
||||||
|
const getRadiusClients = useGetDeviceRadiusSessions({ serialNumber });
|
||||||
|
|
||||||
|
if (!getRadiusClients.data || getRadiusClients.data.length === 0) return null;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Card mb={4}>
|
||||||
|
<CardBody>
|
||||||
|
<Box w="100%">
|
||||||
|
<DeviceRadiusClientsTable
|
||||||
|
sessions={getRadiusClients.data}
|
||||||
|
refetch={getRadiusClients.refetch}
|
||||||
|
isFetching={getRadiusClients.isFetching}
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
</CardBody>
|
||||||
|
</Card>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default RadiusClientsCard;
|
||||||
@@ -29,6 +29,7 @@ import { useNavigate } from 'react-router-dom';
|
|||||||
import DeviceDetails from './Details';
|
import DeviceDetails from './Details';
|
||||||
import DeviceLogsCard from './LogsCard';
|
import DeviceLogsCard from './LogsCard';
|
||||||
import DeviceNotes from './Notes';
|
import DeviceNotes from './Notes';
|
||||||
|
import RadiusClientsCard from './RadiusClients';
|
||||||
import RestrictionsCard from './RestrictionsCard';
|
import RestrictionsCard from './RestrictionsCard';
|
||||||
import DeviceStatisticsCard from './StatisticsCard';
|
import DeviceStatisticsCard from './StatisticsCard';
|
||||||
import DeviceSummary from './Summary';
|
import DeviceSummary from './Summary';
|
||||||
@@ -38,7 +39,7 @@ import DeviceActionDropdown from 'components/Buttons/DeviceActionDropdown';
|
|||||||
import { RefreshButton } from 'components/Buttons/RefreshButton';
|
import { RefreshButton } from 'components/Buttons/RefreshButton';
|
||||||
import { Card } from 'components/Containers/Card';
|
import { Card } from 'components/Containers/Card';
|
||||||
import { CardHeader } from 'components/Containers/Card/CardHeader';
|
import { CardHeader } from 'components/Containers/Card/CardHeader';
|
||||||
import DeviceSearchBar from 'components/DeviceSearchBar';
|
import GlobalSearchBar from 'components/GlobalSearchBar';
|
||||||
import FormattedDate from 'components/InformationDisplays/FormattedDate';
|
import FormattedDate from 'components/InformationDisplays/FormattedDate';
|
||||||
import { ConfigureModal } from 'components/Modals/ConfigureModal';
|
import { ConfigureModal } from 'components/Modals/ConfigureModal';
|
||||||
import { EventQueueModal } from 'components/Modals/EventQueueModal';
|
import { EventQueueModal } from 'components/Modals/EventQueueModal';
|
||||||
@@ -194,7 +195,7 @@ const DevicePageWrapper = ({ serialNumber }: Props) => {
|
|||||||
</HStack>
|
</HStack>
|
||||||
<Spacer />
|
<Spacer />
|
||||||
<HStack spacing={2}>
|
<HStack spacing={2}>
|
||||||
<DeviceSearchBar />
|
<GlobalSearchBar />
|
||||||
<DeleteButton isCompact onClick={onDeleteOpen} />
|
<DeleteButton isCompact onClick={onDeleteOpen} />
|
||||||
{getDevice?.data && (
|
{getDevice?.data && (
|
||||||
<DeviceActionDropdown
|
<DeviceActionDropdown
|
||||||
@@ -244,7 +245,7 @@ const DevicePageWrapper = ({ serialNumber }: Props) => {
|
|||||||
</HStack>
|
</HStack>
|
||||||
<Spacer />
|
<Spacer />
|
||||||
<HStack spacing={2}>
|
<HStack spacing={2}>
|
||||||
<DeviceSearchBar />
|
<GlobalSearchBar />
|
||||||
<DeleteButton isCompact onClick={onDeleteOpen} />
|
<DeleteButton isCompact onClick={onDeleteOpen} />
|
||||||
{getDevice?.data && (
|
{getDevice?.data && (
|
||||||
<DeviceActionDropdown
|
<DeviceActionDropdown
|
||||||
@@ -319,6 +320,9 @@ const DevicePageWrapper = ({ serialNumber }: Props) => {
|
|||||||
<DeviceStatisticsCard serialNumber={serialNumber} />
|
<DeviceStatisticsCard serialNumber={serialNumber} />
|
||||||
<WifiAnalysisCard serialNumber={serialNumber} />
|
<WifiAnalysisCard serialNumber={serialNumber} />
|
||||||
<DeviceLogsCard serialNumber={serialNumber} />
|
<DeviceLogsCard serialNumber={serialNumber} />
|
||||||
|
{getDevice.data && getDevice.data?.hasRADIUSSessions > 0 ? (
|
||||||
|
<RadiusClientsCard serialNumber={serialNumber} />
|
||||||
|
) : null}
|
||||||
<RestrictionsCard serialNumber={serialNumber} />
|
<RestrictionsCard serialNumber={serialNumber} />
|
||||||
<Box />
|
<Box />
|
||||||
<DeviceNotes serialNumber={serialNumber} />
|
<DeviceNotes serialNumber={serialNumber} />
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ import DeviceUptimeCell from './Uptime';
|
|||||||
import { CardBody } from 'components/Containers/Card/CardBody';
|
import { CardBody } from 'components/Containers/Card/CardBody';
|
||||||
import { DataGrid } from 'components/DataTables/DataGrid';
|
import { DataGrid } from 'components/DataTables/DataGrid';
|
||||||
import { DataGridColumn, useDataGrid } from 'components/DataTables/DataGrid/useDataGrid';
|
import { DataGridColumn, useDataGrid } from 'components/DataTables/DataGrid/useDataGrid';
|
||||||
import DeviceSearchBar from 'components/DeviceSearchBar';
|
import GlobalSearchBar from 'components/GlobalSearchBar';
|
||||||
import FormattedDate from 'components/InformationDisplays/FormattedDate';
|
import FormattedDate from 'components/InformationDisplays/FormattedDate';
|
||||||
import { ConfigureModal } from 'components/Modals/ConfigureModal';
|
import { ConfigureModal } from 'components/Modals/ConfigureModal';
|
||||||
import { EventQueueModal } from 'components/Modals/EventQueueModal';
|
import { EventQueueModal } from 'components/Modals/EventQueueModal';
|
||||||
@@ -644,7 +644,7 @@ const DeviceListCard = () => {
|
|||||||
header={{
|
header={{
|
||||||
title: `${getCount.data?.count} ${t('devices.title')}`,
|
title: `${getCount.data?.count} ${t('devices.title')}`,
|
||||||
objectListed: t('devices.title'),
|
objectListed: t('devices.title'),
|
||||||
leftContent: <DeviceSearchBar />,
|
leftContent: <GlobalSearchBar />,
|
||||||
}}
|
}}
|
||||||
columns={columns}
|
columns={columns}
|
||||||
data={data}
|
data={data}
|
||||||
|
|||||||
Reference in New Issue
Block a user