mirror of
https://github.com/optim-enterprises-bv/OptimCloud-gw-ui.git
synced 2025-10-29 17:32:20 +00:00
[WIFI-12257] Display GPS location on device page
Signed-off-by: Charles <charles.bourque96@gmail.com>
This commit is contained in:
79
package-lock.json
generated
79
package-lock.json
generated
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "ucentral-client",
|
"name": "ucentral-client",
|
||||||
"version": "2.9.0(5)",
|
"version": "2.9.0(7)",
|
||||||
"lockfileVersion": 2,
|
"lockfileVersion": 2,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "ucentral-client",
|
"name": "ucentral-client",
|
||||||
"version": "2.9.0(5)",
|
"version": "2.9.0(7)",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@chakra-ui/icons": "^2.0.11",
|
"@chakra-ui/icons": "^2.0.11",
|
||||||
@@ -16,6 +16,8 @@
|
|||||||
"@emotion/react": "^11.10.4",
|
"@emotion/react": "^11.10.4",
|
||||||
"@emotion/styled": "^11.10.4",
|
"@emotion/styled": "^11.10.4",
|
||||||
"@fontsource/inter": "^4.5.14",
|
"@fontsource/inter": "^4.5.14",
|
||||||
|
"@googlemaps/react-wrapper": "^1.1.35",
|
||||||
|
"@googlemaps/typescript-guards": "^2.0.3",
|
||||||
"@react-spring/web": "^9.5.5",
|
"@react-spring/web": "^9.5.5",
|
||||||
"@tanstack/react-query": "^4.12.0",
|
"@tanstack/react-query": "^4.12.0",
|
||||||
"@textea/json-viewer": "^2.10.0",
|
"@textea/json-viewer": "^2.10.0",
|
||||||
@@ -24,6 +26,7 @@
|
|||||||
"chakra-react-select": "^4.3.0",
|
"chakra-react-select": "^4.3.0",
|
||||||
"chart.js": "^3.9.1",
|
"chart.js": "^3.9.1",
|
||||||
"dagre": "^0.8.5",
|
"dagre": "^0.8.5",
|
||||||
|
"fast-equals": "^4.0.3",
|
||||||
"formik": "^2.2.9",
|
"formik": "^2.2.9",
|
||||||
"framer-motion": "^7.6.1",
|
"framer-motion": "^7.6.1",
|
||||||
"i18next": "^22.0.0",
|
"i18next": "^22.0.0",
|
||||||
@@ -54,6 +57,7 @@
|
|||||||
"zustand": "^4.1.2"
|
"zustand": "^4.1.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@types/google.maps": "^3.51.0",
|
||||||
"@types/node": "^18.11.2",
|
"@types/node": "^18.11.2",
|
||||||
"@types/react": "^18.0.21",
|
"@types/react": "^18.0.21",
|
||||||
"@types/react-csv": "^1.1.3",
|
"@types/react-csv": "^1.1.3",
|
||||||
@@ -2848,6 +2852,30 @@
|
|||||||
"version": "4.5.14",
|
"version": "4.5.14",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/@googlemaps/js-api-loader": {
|
||||||
|
"version": "1.15.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@googlemaps/js-api-loader/-/js-api-loader-1.15.1.tgz",
|
||||||
|
"integrity": "sha512-AsnEgNsB7S/VdrHGEQUaUM2e5tmjFGKBAfzR/AqO8O7TPq/jQGvoRw5liPBw4EMF38RDsHmKDV89q/X+qiUREQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"fast-deep-equal": "^3.1.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@googlemaps/react-wrapper": {
|
||||||
|
"version": "1.1.35",
|
||||||
|
"resolved": "https://registry.npmjs.org/@googlemaps/react-wrapper/-/react-wrapper-1.1.35.tgz",
|
||||||
|
"integrity": "sha512-vK+BDQMHN0Oqr66cW3ZPWVK43BUmJJBu6P8T74tc6/fKpUJUlFEaZsupgIIRRRDW9ejB8uGagUmwOnA2gdcvbw==",
|
||||||
|
"dependencies": {
|
||||||
|
"@googlemaps/js-api-loader": "^1.13.2"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": ">=16.8.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@googlemaps/typescript-guards": {
|
||||||
|
"version": "2.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/@googlemaps/typescript-guards/-/typescript-guards-2.0.3.tgz",
|
||||||
|
"integrity": "sha512-3iHuO8H0jPehftsMK0kgyJzPYU/g/oiTRw+wu/yltqSZ7wJPt3vfsJHkPiuRpQjbnnWygX+T3mkRGyK/eyZ/lw=="
|
||||||
|
},
|
||||||
"node_modules/@humanwhocodes/config-array": {
|
"node_modules/@humanwhocodes/config-array": {
|
||||||
"version": "0.10.7",
|
"version": "0.10.7",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
@@ -3501,6 +3529,12 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/@types/google.maps": {
|
||||||
|
"version": "3.51.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/google.maps/-/google.maps-3.51.0.tgz",
|
||||||
|
"integrity": "sha512-44/oQYjc5D6kxBcI3Qk9rk3IIOMwnlEMWDV7pwPJ2YI89s5Q1OzDrFvR7QJ3LFrpVXEhig+gyagFg54+foinFg==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"node_modules/@types/json-schema": {
|
"node_modules/@types/json-schema": {
|
||||||
"version": "7.0.11",
|
"version": "7.0.11",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
@@ -5529,7 +5563,6 @@
|
|||||||
},
|
},
|
||||||
"node_modules/fast-deep-equal": {
|
"node_modules/fast-deep-equal": {
|
||||||
"version": "3.1.3",
|
"version": "3.1.3",
|
||||||
"dev": true,
|
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/fast-diff": {
|
"node_modules/fast-diff": {
|
||||||
@@ -5537,6 +5570,11 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "Apache-2.0"
|
"license": "Apache-2.0"
|
||||||
},
|
},
|
||||||
|
"node_modules/fast-equals": {
|
||||||
|
"version": "4.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/fast-equals/-/fast-equals-4.0.3.tgz",
|
||||||
|
"integrity": "sha512-G3BSX9cfKttjr+2o1O22tYMLq0DPluZnYtq1rXumE1SpL/F/SLIfHx08WYQoWSIpeMYf8sRbJ8++71+v6Pnxfg=="
|
||||||
|
},
|
||||||
"node_modules/fast-glob": {
|
"node_modules/fast-glob": {
|
||||||
"version": "3.2.12",
|
"version": "3.2.12",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
@@ -11427,6 +11465,27 @@
|
|||||||
"@fontsource/inter": {
|
"@fontsource/inter": {
|
||||||
"version": "4.5.14"
|
"version": "4.5.14"
|
||||||
},
|
},
|
||||||
|
"@googlemaps/js-api-loader": {
|
||||||
|
"version": "1.15.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@googlemaps/js-api-loader/-/js-api-loader-1.15.1.tgz",
|
||||||
|
"integrity": "sha512-AsnEgNsB7S/VdrHGEQUaUM2e5tmjFGKBAfzR/AqO8O7TPq/jQGvoRw5liPBw4EMF38RDsHmKDV89q/X+qiUREQ==",
|
||||||
|
"requires": {
|
||||||
|
"fast-deep-equal": "^3.1.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"@googlemaps/react-wrapper": {
|
||||||
|
"version": "1.1.35",
|
||||||
|
"resolved": "https://registry.npmjs.org/@googlemaps/react-wrapper/-/react-wrapper-1.1.35.tgz",
|
||||||
|
"integrity": "sha512-vK+BDQMHN0Oqr66cW3ZPWVK43BUmJJBu6P8T74tc6/fKpUJUlFEaZsupgIIRRRDW9ejB8uGagUmwOnA2gdcvbw==",
|
||||||
|
"requires": {
|
||||||
|
"@googlemaps/js-api-loader": "^1.13.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"@googlemaps/typescript-guards": {
|
||||||
|
"version": "2.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/@googlemaps/typescript-guards/-/typescript-guards-2.0.3.tgz",
|
||||||
|
"integrity": "sha512-3iHuO8H0jPehftsMK0kgyJzPYU/g/oiTRw+wu/yltqSZ7wJPt3vfsJHkPiuRpQjbnnWygX+T3mkRGyK/eyZ/lw=="
|
||||||
|
},
|
||||||
"@humanwhocodes/config-array": {
|
"@humanwhocodes/config-array": {
|
||||||
"version": "0.10.7",
|
"version": "0.10.7",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
@@ -11788,6 +11847,12 @@
|
|||||||
"version": "0.0.39",
|
"version": "0.0.39",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"@types/google.maps": {
|
||||||
|
"version": "3.51.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/google.maps/-/google.maps-3.51.0.tgz",
|
||||||
|
"integrity": "sha512-44/oQYjc5D6kxBcI3Qk9rk3IIOMwnlEMWDV7pwPJ2YI89s5Q1OzDrFvR7QJ3LFrpVXEhig+gyagFg54+foinFg==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"@types/json-schema": {
|
"@types/json-schema": {
|
||||||
"version": "7.0.11",
|
"version": "7.0.11",
|
||||||
"dev": true
|
"dev": true
|
||||||
@@ -13027,13 +13092,17 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"fast-deep-equal": {
|
"fast-deep-equal": {
|
||||||
"version": "3.1.3",
|
"version": "3.1.3"
|
||||||
"dev": true
|
|
||||||
},
|
},
|
||||||
"fast-diff": {
|
"fast-diff": {
|
||||||
"version": "1.2.0",
|
"version": "1.2.0",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"fast-equals": {
|
||||||
|
"version": "4.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/fast-equals/-/fast-equals-4.0.3.tgz",
|
||||||
|
"integrity": "sha512-G3BSX9cfKttjr+2o1O22tYMLq0DPluZnYtq1rXumE1SpL/F/SLIfHx08WYQoWSIpeMYf8sRbJ8++71+v6Pnxfg=="
|
||||||
|
},
|
||||||
"fast-glob": {
|
"fast-glob": {
|
||||||
"version": "3.2.12",
|
"version": "3.2.12",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "ucentral-client",
|
"name": "ucentral-client",
|
||||||
"version": "2.9.0(5)",
|
"version": "2.9.0(7)",
|
||||||
"description": "",
|
"description": "",
|
||||||
"private": true,
|
"private": true,
|
||||||
"main": "index.tsx",
|
"main": "index.tsx",
|
||||||
@@ -22,12 +22,15 @@
|
|||||||
"@emotion/react": "^11.10.4",
|
"@emotion/react": "^11.10.4",
|
||||||
"@emotion/styled": "^11.10.4",
|
"@emotion/styled": "^11.10.4",
|
||||||
"@fontsource/inter": "^4.5.14",
|
"@fontsource/inter": "^4.5.14",
|
||||||
|
"@googlemaps/react-wrapper": "^1.1.35",
|
||||||
|
"@googlemaps/typescript-guards": "^2.0.3",
|
||||||
"@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.3.0",
|
||||||
"dagre": "^0.8.5",
|
"dagre": "^0.8.5",
|
||||||
"formik": "^2.2.9",
|
"formik": "^2.2.9",
|
||||||
|
"fast-equals": "^4.0.3",
|
||||||
"framer-motion": "^7.6.1",
|
"framer-motion": "^7.6.1",
|
||||||
"i18next": "^22.0.0",
|
"i18next": "^22.0.0",
|
||||||
"i18next-browser-languagedetector": "^6.1.8",
|
"i18next-browser-languagedetector": "^6.1.8",
|
||||||
@@ -60,6 +63,7 @@
|
|||||||
"zustand": "^4.1.2"
|
"zustand": "^4.1.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@types/google.maps": "^3.51.0",
|
||||||
"@types/node": "^18.11.2",
|
"@types/node": "^18.11.2",
|
||||||
"@types/react": "^18.0.21",
|
"@types/react": "^18.0.21",
|
||||||
"@types/react-csv": "^1.1.3",
|
"@types/react-csv": "^1.1.3",
|
||||||
|
|||||||
@@ -79,8 +79,11 @@
|
|||||||
"live_view_help": "Hilfe zur Live-Ansicht",
|
"live_view_help": "Hilfe zur Live-Ansicht",
|
||||||
"memory": "Erinnerung",
|
"memory": "Erinnerung",
|
||||||
"memory_used": "Verwendeter Speicher",
|
"memory_used": "Verwendeter Speicher",
|
||||||
"missing_board": "Die Analytics-Überwachung an diesem Veranstaltungsort ist nicht mehr aktiv. Bitte starten Sie die Überwachung über das obere Menü neu",
|
"missing_board": "Analytics-Überwachung an diesem Ort ist nicht mehr aktiv. Klicken Sie hier, um die Überwachung neu zu starten",
|
||||||
"mode": "Modus",
|
"mode": "Modus",
|
||||||
|
"monitoring": "Überwachung",
|
||||||
|
"no_board": "Keine Überwachung",
|
||||||
|
"no_board_description": "Sie überwachen diesen Veranstaltungsort derzeit nicht, klicken Sie hier, um zu beginnen",
|
||||||
"noise": "Lärm",
|
"noise": "Lärm",
|
||||||
"packets": "Pakete",
|
"packets": "Pakete",
|
||||||
"radio": "RADIO",
|
"radio": "RADIO",
|
||||||
@@ -91,6 +94,8 @@
|
|||||||
"retries": "Wiederholungen",
|
"retries": "Wiederholungen",
|
||||||
"search_serials": "Zeitschriften suchen",
|
"search_serials": "Zeitschriften suchen",
|
||||||
"stop_monitoring": "Beenden Sie die Überwachung",
|
"stop_monitoring": "Beenden Sie die Überwachung",
|
||||||
|
"stop_monitoring_success": "Überwachungsort gestoppt!",
|
||||||
|
"stop_monitoring_warning": "Bist du sicher? Dadurch werden alle aufgezeichneten Überwachungsdaten für diesen Veranstaltungsort gelöscht",
|
||||||
"temperature": "Temperatur",
|
"temperature": "Temperatur",
|
||||||
"title": "ANALYTICS",
|
"title": "ANALYTICS",
|
||||||
"total_data": "Gesamtdaten",
|
"total_data": "Gesamtdaten",
|
||||||
@@ -675,7 +680,8 @@
|
|||||||
"test_digicert_creds": "Anmeldeinformationen testen",
|
"test_digicert_creds": "Anmeldeinformationen testen",
|
||||||
"title": "Entitäten",
|
"title": "Entitäten",
|
||||||
"tree": "Entitätsbaum",
|
"tree": "Entitätsbaum",
|
||||||
"venues_under_root": "Veranstaltungsorte können nicht direkt unter der Root-Entität erstellt werden. Bitte erstellen Sie neue Entitäten und erstellen Sie Veranstaltungsorte unter diesen."
|
"update_success": "Entität aktualisiert!",
|
||||||
|
"venues_under_root": "Veranstaltungsorte können nicht direkt unter der Root-Entität erstellt werden"
|
||||||
},
|
},
|
||||||
"footer": {
|
"footer": {
|
||||||
"powered_by": "Unterstützt von",
|
"powered_by": "Unterstützt von",
|
||||||
@@ -769,13 +775,17 @@
|
|||||||
"city": "Stadt",
|
"city": "Stadt",
|
||||||
"claim_explanation": "Um Standorte zu beanspruchen, können Sie die folgende Tabelle verwenden",
|
"claim_explanation": "Um Standorte zu beanspruchen, können Sie die folgende Tabelle verwenden",
|
||||||
"country": "Land",
|
"country": "Land",
|
||||||
|
"elevation": "Elevation",
|
||||||
"geocode": "Geo-Code",
|
"geocode": "Geo-Code",
|
||||||
|
"lat": "Breite",
|
||||||
|
"longitude": "Längengrad",
|
||||||
"one": "Ort",
|
"one": "Ort",
|
||||||
"other": "Standorte",
|
"other": "Standorte",
|
||||||
"postal": "Postleitzahl",
|
"postal": "Postleitzahl",
|
||||||
"state": "Bundesstaat / Provinz",
|
"state": "Bundesstaat / Provinz",
|
||||||
"title": "Standorte",
|
"title": "Standorte",
|
||||||
"to_claim": "Standorte zu beanspruchen"
|
"to_claim": "Standorte zu beanspruchen",
|
||||||
|
"view_gps": ""
|
||||||
},
|
},
|
||||||
"login": {
|
"login": {
|
||||||
"access_policy": "Zugangsrichtlinien",
|
"access_policy": "Zugangsrichtlinien",
|
||||||
@@ -1037,6 +1047,9 @@
|
|||||||
"os": "Betriebssystem",
|
"os": "Betriebssystem",
|
||||||
"processors": "Prozessoren",
|
"processors": "Prozessoren",
|
||||||
"reload_chosen_subsystems": "Ausgewählte Subsysteme neu laden",
|
"reload_chosen_subsystems": "Ausgewählte Subsysteme neu laden",
|
||||||
|
"secrets": "Systemgeheimnisse",
|
||||||
|
"secrets_create": "Geheimnis erstellen",
|
||||||
|
"secrets_one": "Systemgeheimnis",
|
||||||
"start": "Start",
|
"start": "Start",
|
||||||
"subsystems": "Subsysteme",
|
"subsystems": "Subsysteme",
|
||||||
"success_reload": "Reload-Befehl erfolgreich gesendet!",
|
"success_reload": "Reload-Befehl erfolgreich gesendet!",
|
||||||
@@ -1107,6 +1120,7 @@
|
|||||||
"successfully_update_devices": " {{num}} Geräte werden aktualisiert!",
|
"successfully_update_devices": " {{num}} Geräte werden aktualisiert!",
|
||||||
"title": "Veranstaltungsorte",
|
"title": "Veranstaltungsorte",
|
||||||
"update_all_devices": "Alle Gerätekonfigurationen aktualisieren",
|
"update_all_devices": "Alle Gerätekonfigurationen aktualisieren",
|
||||||
|
"update_success": "Veranstaltungsort aktualisiert!",
|
||||||
"upgrade_all_devices": "Aktualisieren Sie alle Geräte auf die neueste Firmware",
|
"upgrade_all_devices": "Aktualisieren Sie alle Geräte auf die neueste Firmware",
|
||||||
"upgrade_all_devices_error": "Fehler beim Aktualisieren von Geräten: {{e}}",
|
"upgrade_all_devices_error": "Fehler beim Aktualisieren von Geräten: {{e}}",
|
||||||
"upgrade_all_devices_success": "Upgrade von Geräten erfolgreich gestartet!",
|
"upgrade_all_devices_success": "Upgrade von Geräten erfolgreich gestartet!",
|
||||||
|
|||||||
@@ -79,8 +79,11 @@
|
|||||||
"live_view_help": "Live View Help",
|
"live_view_help": "Live View Help",
|
||||||
"memory": "Memory",
|
"memory": "Memory",
|
||||||
"memory_used": "Memory Used",
|
"memory_used": "Memory Used",
|
||||||
"missing_board": "Analytics monitoring on this venue is no longer active, please restart monitoring using the top menu",
|
"missing_board": "Analytics monitoring on this venue is no longer active. Click here to restart monitoring",
|
||||||
"mode": "Mode",
|
"mode": "Mode",
|
||||||
|
"monitoring": "Monitoring",
|
||||||
|
"no_board": "No Monitoring",
|
||||||
|
"no_board_description": "You are not monitoring this Venue at the moment, click here to start",
|
||||||
"noise": "Noise",
|
"noise": "Noise",
|
||||||
"packets": "Packets",
|
"packets": "Packets",
|
||||||
"radio": "Radio",
|
"radio": "Radio",
|
||||||
@@ -91,6 +94,8 @@
|
|||||||
"retries": "Retries",
|
"retries": "Retries",
|
||||||
"search_serials": "Search Serials",
|
"search_serials": "Search Serials",
|
||||||
"stop_monitoring": "Stop Monitoring",
|
"stop_monitoring": "Stop Monitoring",
|
||||||
|
"stop_monitoring_success": "Stopped Monitoring Venue!",
|
||||||
|
"stop_monitoring_warning": "Are you sure? This will erase all recorded monitoring data for this venue",
|
||||||
"temperature": "Temperature",
|
"temperature": "Temperature",
|
||||||
"title": "Analytics",
|
"title": "Analytics",
|
||||||
"total_data": "Total Data",
|
"total_data": "Total Data",
|
||||||
@@ -675,7 +680,8 @@
|
|||||||
"test_digicert_creds": "Test Credentials",
|
"test_digicert_creds": "Test Credentials",
|
||||||
"title": "Entities",
|
"title": "Entities",
|
||||||
"tree": "Entity Tree",
|
"tree": "Entity Tree",
|
||||||
"venues_under_root": "Venues cannot be created directly under the root entity. Please create new entities and create venues under these."
|
"update_success": "Entity updated!",
|
||||||
|
"venues_under_root": "Venues cannot be created directly under the root entity"
|
||||||
},
|
},
|
||||||
"footer": {
|
"footer": {
|
||||||
"powered_by": "Powered By",
|
"powered_by": "Powered By",
|
||||||
@@ -769,13 +775,17 @@
|
|||||||
"city": "City",
|
"city": "City",
|
||||||
"claim_explanation": "To claim locations you can use the table below",
|
"claim_explanation": "To claim locations you can use the table below",
|
||||||
"country": "Country",
|
"country": "Country",
|
||||||
|
"elevation": "Elevation",
|
||||||
"geocode": "Geo Code",
|
"geocode": "Geo Code",
|
||||||
|
"lat": "Latitude",
|
||||||
|
"longitude": "Longitude",
|
||||||
"one": "Location",
|
"one": "Location",
|
||||||
"other": "Locations",
|
"other": "Locations",
|
||||||
"postal": "ZIP/Postal Code",
|
"postal": "ZIP/Postal Code",
|
||||||
"state": "State/Province",
|
"state": "State/Province",
|
||||||
"title": "Locations",
|
"title": "Locations",
|
||||||
"to_claim": "Locations to claim"
|
"to_claim": "Locations to claim",
|
||||||
|
"view_gps": "View GPS Location"
|
||||||
},
|
},
|
||||||
"login": {
|
"login": {
|
||||||
"access_policy": "Access Policy",
|
"access_policy": "Access Policy",
|
||||||
@@ -1037,6 +1047,9 @@
|
|||||||
"os": "Operating System",
|
"os": "Operating System",
|
||||||
"processors": "Processors",
|
"processors": "Processors",
|
||||||
"reload_chosen_subsystems": "Reload Chosen Subsystems",
|
"reload_chosen_subsystems": "Reload Chosen Subsystems",
|
||||||
|
"secrets": "System Secrets",
|
||||||
|
"secrets_create": "Create Secret",
|
||||||
|
"secrets_one": "System Secret",
|
||||||
"start": "Start",
|
"start": "Start",
|
||||||
"subsystems": "Subsystems",
|
"subsystems": "Subsystems",
|
||||||
"success_reload": "Successfully sent reload command!",
|
"success_reload": "Successfully sent reload command!",
|
||||||
@@ -1107,6 +1120,7 @@
|
|||||||
"successfully_update_devices": "Updating {{num}} devices!",
|
"successfully_update_devices": "Updating {{num}} devices!",
|
||||||
"title": "Venues",
|
"title": "Venues",
|
||||||
"update_all_devices": "Update All Device Configurations",
|
"update_all_devices": "Update All Device Configurations",
|
||||||
|
"update_success": "Venue updated!",
|
||||||
"upgrade_all_devices": "Upgrade All Devices to Latest Firmware",
|
"upgrade_all_devices": "Upgrade All Devices to Latest Firmware",
|
||||||
"upgrade_all_devices_error": "Error upgrading devices: {{e}}",
|
"upgrade_all_devices_error": "Error upgrading devices: {{e}}",
|
||||||
"upgrade_all_devices_success": "Successfully started upgrading devices!",
|
"upgrade_all_devices_success": "Successfully started upgrading devices!",
|
||||||
|
|||||||
@@ -79,8 +79,11 @@
|
|||||||
"live_view_help": "Ayuda de visualización en vivo",
|
"live_view_help": "Ayuda de visualización en vivo",
|
||||||
"memory": "Memoria",
|
"memory": "Memoria",
|
||||||
"memory_used": "Memoria usada",
|
"memory_used": "Memoria usada",
|
||||||
"missing_board": "El monitoreo analítico en este lugar ya no está activo, reinicie el monitoreo usando el menú superior",
|
"missing_board": "El monitoreo analítico en este lugar ya no está activo. Haga clic aquí para reiniciar el monitoreo",
|
||||||
"mode": "Modo",
|
"mode": "Modo",
|
||||||
|
"monitoring": "Vigilancia",
|
||||||
|
"no_board": "Sin monitoreo",
|
||||||
|
"no_board_description": "No está monitoreando este lugar en este momento, haga clic aquí para comenzar",
|
||||||
"noise": "Ruido",
|
"noise": "Ruido",
|
||||||
"packets": "Paquetes",
|
"packets": "Paquetes",
|
||||||
"radio": "RADIO",
|
"radio": "RADIO",
|
||||||
@@ -91,6 +94,8 @@
|
|||||||
"retries": "Reintentos",
|
"retries": "Reintentos",
|
||||||
"search_serials": "Buscar seriales",
|
"search_serials": "Buscar seriales",
|
||||||
"stop_monitoring": "Dejar de monitorear",
|
"stop_monitoring": "Dejar de monitorear",
|
||||||
|
"stop_monitoring_success": "¡Se detuvo el lugar de monitoreo!",
|
||||||
|
"stop_monitoring_warning": "¿Está seguro? Esto borrará todos los datos de monitoreo grabados para este lugar.",
|
||||||
"temperature": "temperatura",
|
"temperature": "temperatura",
|
||||||
"title": "ANALÍTICA",
|
"title": "ANALÍTICA",
|
||||||
"total_data": "Datos totales",
|
"total_data": "Datos totales",
|
||||||
@@ -675,7 +680,8 @@
|
|||||||
"test_digicert_creds": "Credenciales de prueba",
|
"test_digicert_creds": "Credenciales de prueba",
|
||||||
"title": "entidades",
|
"title": "entidades",
|
||||||
"tree": "Árbol de entidades",
|
"tree": "Árbol de entidades",
|
||||||
"venues_under_root": "Los lugares no se pueden crear directamente bajo la entidad raíz. Cree nuevas entidades y cree lugares bajo estas."
|
"update_success": "¡Entidad actualizada!",
|
||||||
|
"venues_under_root": "Los lugares no se pueden crear directamente bajo la entidad raíz"
|
||||||
},
|
},
|
||||||
"footer": {
|
"footer": {
|
||||||
"powered_by": "energizado por",
|
"powered_by": "energizado por",
|
||||||
@@ -769,13 +775,17 @@
|
|||||||
"city": "ciudad",
|
"city": "ciudad",
|
||||||
"claim_explanation": "Para reclamar ubicaciones, puede usar la tabla a continuación",
|
"claim_explanation": "Para reclamar ubicaciones, puede usar la tabla a continuación",
|
||||||
"country": "País",
|
"country": "País",
|
||||||
|
"elevation": "Elevación",
|
||||||
"geocode": "Código geográfico",
|
"geocode": "Código geográfico",
|
||||||
|
"lat": "Latitud",
|
||||||
|
"longitude": "Longitud",
|
||||||
"one": "Ubicación",
|
"one": "Ubicación",
|
||||||
"other": "Ubicaciones",
|
"other": "Ubicaciones",
|
||||||
"postal": "código postal",
|
"postal": "código postal",
|
||||||
"state": "Provincia del estado",
|
"state": "Provincia del estado",
|
||||||
"title": "Ubicaciones",
|
"title": "Ubicaciones",
|
||||||
"to_claim": "Ubicaciones para reclamar"
|
"to_claim": "Ubicaciones para reclamar",
|
||||||
|
"view_gps": ""
|
||||||
},
|
},
|
||||||
"login": {
|
"login": {
|
||||||
"access_policy": "Política de acceso",
|
"access_policy": "Política de acceso",
|
||||||
@@ -1037,6 +1047,9 @@
|
|||||||
"os": "sistema operativo",
|
"os": "sistema operativo",
|
||||||
"processors": "Procesadores",
|
"processors": "Procesadores",
|
||||||
"reload_chosen_subsystems": "Recargar subsistemas elegidos",
|
"reload_chosen_subsystems": "Recargar subsistemas elegidos",
|
||||||
|
"secrets": "Secretos del sistema",
|
||||||
|
"secrets_create": "Crear secreto",
|
||||||
|
"secrets_one": "Secreto del sistema",
|
||||||
"start": "comienzo",
|
"start": "comienzo",
|
||||||
"subsystems": "Subsistemas",
|
"subsystems": "Subsistemas",
|
||||||
"success_reload": "¡Comando de recarga enviado con éxito!",
|
"success_reload": "¡Comando de recarga enviado con éxito!",
|
||||||
@@ -1107,6 +1120,7 @@
|
|||||||
"successfully_update_devices": "¡Actualizando {{num}} dispositivos!",
|
"successfully_update_devices": "¡Actualizando {{num}} dispositivos!",
|
||||||
"title": "Sedes",
|
"title": "Sedes",
|
||||||
"update_all_devices": "Actualizar todas las configuraciones de dispositivos",
|
"update_all_devices": "Actualizar todas las configuraciones de dispositivos",
|
||||||
|
"update_success": "Lugar actualizado!",
|
||||||
"upgrade_all_devices": "Actualice todos los dispositivos al firmware más reciente",
|
"upgrade_all_devices": "Actualice todos los dispositivos al firmware más reciente",
|
||||||
"upgrade_all_devices_error": "Error al actualizar dispositivos: {{e}}",
|
"upgrade_all_devices_error": "Error al actualizar dispositivos: {{e}}",
|
||||||
"upgrade_all_devices_success": "¡Comenzó con éxito la actualización de dispositivos!",
|
"upgrade_all_devices_success": "¡Comenzó con éxito la actualización de dispositivos!",
|
||||||
|
|||||||
@@ -79,8 +79,11 @@
|
|||||||
"live_view_help": "Aide sur l'affichage en direct",
|
"live_view_help": "Aide sur l'affichage en direct",
|
||||||
"memory": "mémoire",
|
"memory": "mémoire",
|
||||||
"memory_used": "Mémoire utilisée",
|
"memory_used": "Mémoire utilisée",
|
||||||
"missing_board": "La surveillance analytique sur ce lieu n'est plus active, veuillez redémarrer la surveillance en utilisant le menu du haut",
|
"missing_board": "La surveillance analytique sur ce site n'est plus active. Cliquez ici pour redémarrer la surveillance",
|
||||||
"mode": "Mode",
|
"mode": "Mode",
|
||||||
|
"monitoring": "surveillance",
|
||||||
|
"no_board": "Aucune surveillance",
|
||||||
|
"no_board_description": "Vous ne surveillez pas ce lieu pour le moment, cliquez ici pour commencer",
|
||||||
"noise": "Bruit",
|
"noise": "Bruit",
|
||||||
"packets": "Paquets",
|
"packets": "Paquets",
|
||||||
"radio": "Radio",
|
"radio": "Radio",
|
||||||
@@ -91,6 +94,8 @@
|
|||||||
"retries": "Tentatives",
|
"retries": "Tentatives",
|
||||||
"search_serials": "Rechercher des publications en série",
|
"search_serials": "Rechercher des publications en série",
|
||||||
"stop_monitoring": "Arrêter la surveillance",
|
"stop_monitoring": "Arrêter la surveillance",
|
||||||
|
"stop_monitoring_success": "Lieu de surveillance arrêté !",
|
||||||
|
"stop_monitoring_warning": "Êtes-vous sûr? Cela effacera toutes les données de surveillance enregistrées pour ce lieu",
|
||||||
"temperature": "Température",
|
"temperature": "Température",
|
||||||
"title": "ANALYTIQUE",
|
"title": "ANALYTIQUE",
|
||||||
"total_data": "Données totales",
|
"total_data": "Données totales",
|
||||||
@@ -675,7 +680,8 @@
|
|||||||
"test_digicert_creds": "Tester les informations d'identification",
|
"test_digicert_creds": "Tester les informations d'identification",
|
||||||
"title": "Entités",
|
"title": "Entités",
|
||||||
"tree": "Arborescence des entités",
|
"tree": "Arborescence des entités",
|
||||||
"venues_under_root": "Les sites ne peuvent pas être créés directement sous l'entité racine. Veuillez créer de nouvelles entités et créer des lieux sous celles-ci."
|
"update_success": "Entité mise à jour !",
|
||||||
|
"venues_under_root": "Les lieux ne peuvent pas être créés directement sous l'entité racine"
|
||||||
},
|
},
|
||||||
"footer": {
|
"footer": {
|
||||||
"powered_by": "Alimenté par",
|
"powered_by": "Alimenté par",
|
||||||
@@ -769,13 +775,17 @@
|
|||||||
"city": "Ville",
|
"city": "Ville",
|
||||||
"claim_explanation": "Pour revendiquer des emplacements, vous pouvez utiliser le tableau ci-dessous",
|
"claim_explanation": "Pour revendiquer des emplacements, vous pouvez utiliser le tableau ci-dessous",
|
||||||
"country": "Pays",
|
"country": "Pays",
|
||||||
|
"elevation": "Élévation",
|
||||||
"geocode": "Geo code",
|
"geocode": "Geo code",
|
||||||
|
"lat": "Latitude",
|
||||||
|
"longitude": "Longitude",
|
||||||
"one": "Emplacement",
|
"one": "Emplacement",
|
||||||
"other": "Emplacements",
|
"other": "Emplacements",
|
||||||
"postal": "Zip / code postal",
|
"postal": "Zip / code postal",
|
||||||
"state": "Etat / Province",
|
"state": "Etat / Province",
|
||||||
"title": "Emplacements",
|
"title": "Emplacements",
|
||||||
"to_claim": "Emplacements à réclamer"
|
"to_claim": "Emplacements à réclamer",
|
||||||
|
"view_gps": ""
|
||||||
},
|
},
|
||||||
"login": {
|
"login": {
|
||||||
"access_policy": "Politique d'accès",
|
"access_policy": "Politique d'accès",
|
||||||
@@ -1037,6 +1047,9 @@
|
|||||||
"os": "Système opérateur",
|
"os": "Système opérateur",
|
||||||
"processors": "Processeurs",
|
"processors": "Processeurs",
|
||||||
"reload_chosen_subsystems": "Recharger les sous-systèmes choisis",
|
"reload_chosen_subsystems": "Recharger les sous-systèmes choisis",
|
||||||
|
"secrets": "Secrets du système",
|
||||||
|
"secrets_create": "Créer un secret",
|
||||||
|
"secrets_one": "Code secret du système",
|
||||||
"start": "Début",
|
"start": "Début",
|
||||||
"subsystems": "Sous-systèmes",
|
"subsystems": "Sous-systèmes",
|
||||||
"success_reload": "Commande de rechargement envoyée avec succès !",
|
"success_reload": "Commande de rechargement envoyée avec succès !",
|
||||||
@@ -1107,6 +1120,7 @@
|
|||||||
"successfully_update_devices": "Mise à jour de {{num}} appareils !",
|
"successfully_update_devices": "Mise à jour de {{num}} appareils !",
|
||||||
"title": "Les lieux",
|
"title": "Les lieux",
|
||||||
"update_all_devices": "Mettre à jour toutes les configurations de périphérique",
|
"update_all_devices": "Mettre à jour toutes les configurations de périphérique",
|
||||||
|
"update_success": "Lieu mis à jour !",
|
||||||
"upgrade_all_devices": "Mettre à niveau tous les appareils vers le dernier micrologiciel",
|
"upgrade_all_devices": "Mettre à niveau tous les appareils vers le dernier micrologiciel",
|
||||||
"upgrade_all_devices_error": "Erreur lors de la mise à jour des appareils : {{e}}",
|
"upgrade_all_devices_error": "Erreur lors de la mise à jour des appareils : {{e}}",
|
||||||
"upgrade_all_devices_success": "La mise à niveau des appareils a démarré avec succès !",
|
"upgrade_all_devices_success": "La mise à niveau des appareils a démarré avec succès !",
|
||||||
|
|||||||
@@ -79,8 +79,11 @@
|
|||||||
"live_view_help": "Ajuda da visualização ao vivo",
|
"live_view_help": "Ajuda da visualização ao vivo",
|
||||||
"memory": "Memória",
|
"memory": "Memória",
|
||||||
"memory_used": "Memória Usada",
|
"memory_used": "Memória Usada",
|
||||||
"missing_board": "O monitoramento analítico neste local não está mais ativo, reinicie o monitoramento usando o menu superior",
|
"missing_board": "O monitoramento analítico neste local não está mais ativo. Clique aqui para reiniciar o monitoramento",
|
||||||
"mode": "Modo",
|
"mode": "Modo",
|
||||||
|
"monitoring": "Monitoramento",
|
||||||
|
"no_board": "Sem monitoramento",
|
||||||
|
"no_board_description": "Você não está monitorando este local no momento, clique aqui para começar",
|
||||||
"noise": "Barulho",
|
"noise": "Barulho",
|
||||||
"packets": "Pacotes",
|
"packets": "Pacotes",
|
||||||
"radio": "Rádio",
|
"radio": "Rádio",
|
||||||
@@ -91,6 +94,8 @@
|
|||||||
"retries": "Novas tentativas",
|
"retries": "Novas tentativas",
|
||||||
"search_serials": "Pesquisar séries",
|
"search_serials": "Pesquisar séries",
|
||||||
"stop_monitoring": "Parar o monitoramento",
|
"stop_monitoring": "Parar o monitoramento",
|
||||||
|
"stop_monitoring_success": "Local de monitoramento interrompido!",
|
||||||
|
"stop_monitoring_warning": "Tem certeza? Isso apagará todos os dados de monitoramento gravados para este local",
|
||||||
"temperature": "Temperatura",
|
"temperature": "Temperatura",
|
||||||
"title": "Analytics",
|
"title": "Analytics",
|
||||||
"total_data": "Dados totais",
|
"total_data": "Dados totais",
|
||||||
@@ -675,7 +680,8 @@
|
|||||||
"test_digicert_creds": "Credenciais de teste",
|
"test_digicert_creds": "Credenciais de teste",
|
||||||
"title": "Entidades",
|
"title": "Entidades",
|
||||||
"tree": "Árvore de entidades",
|
"tree": "Árvore de entidades",
|
||||||
"venues_under_root": "Os locais não podem ser criados diretamente na entidade raiz. Por favor, crie novas entidades e crie locais sob elas."
|
"update_success": "Entidade atualizada!",
|
||||||
|
"venues_under_root": "Os locais não podem ser criados diretamente na entidade raiz"
|
||||||
},
|
},
|
||||||
"footer": {
|
"footer": {
|
||||||
"powered_by": "Distribuído por",
|
"powered_by": "Distribuído por",
|
||||||
@@ -769,13 +775,17 @@
|
|||||||
"city": "Cidade",
|
"city": "Cidade",
|
||||||
"claim_explanation": "Para reivindicar locais, você pode usar a tabela abaixo",
|
"claim_explanation": "Para reivindicar locais, você pode usar a tabela abaixo",
|
||||||
"country": "País",
|
"country": "País",
|
||||||
|
"elevation": "elevação",
|
||||||
"geocode": "Código geográfico",
|
"geocode": "Código geográfico",
|
||||||
|
"lat": "Latitude",
|
||||||
|
"longitude": "Longitude",
|
||||||
"one": "Localização",
|
"one": "Localização",
|
||||||
"other": "Localizações",
|
"other": "Localizações",
|
||||||
"postal": "CEP / Código Postal",
|
"postal": "CEP / Código Postal",
|
||||||
"state": "Estado / Província",
|
"state": "Estado / Província",
|
||||||
"title": "Localizações",
|
"title": "Localizações",
|
||||||
"to_claim": "Locais para reivindicar"
|
"to_claim": "Locais para reivindicar",
|
||||||
|
"view_gps": ""
|
||||||
},
|
},
|
||||||
"login": {
|
"login": {
|
||||||
"access_policy": "Política de Acesso",
|
"access_policy": "Política de Acesso",
|
||||||
@@ -1037,6 +1047,9 @@
|
|||||||
"os": "Sistema Operacional",
|
"os": "Sistema Operacional",
|
||||||
"processors": "Processadores",
|
"processors": "Processadores",
|
||||||
"reload_chosen_subsystems": "Recarregar Subsistemas Escolhidos",
|
"reload_chosen_subsystems": "Recarregar Subsistemas Escolhidos",
|
||||||
|
"secrets": "Segredos do sistema",
|
||||||
|
"secrets_create": "Criar Segredo",
|
||||||
|
"secrets_one": "Segredo do sistema",
|
||||||
"start": "Começar",
|
"start": "Começar",
|
||||||
"subsystems": "Subsistemas",
|
"subsystems": "Subsistemas",
|
||||||
"success_reload": "Comando de recarga enviado com sucesso!",
|
"success_reload": "Comando de recarga enviado com sucesso!",
|
||||||
@@ -1107,6 +1120,7 @@
|
|||||||
"successfully_update_devices": "Atualizando {{num}} dispositivos!",
|
"successfully_update_devices": "Atualizando {{num}} dispositivos!",
|
||||||
"title": "Locais",
|
"title": "Locais",
|
||||||
"update_all_devices": "Atualizar todas as configurações do dispositivo",
|
"update_all_devices": "Atualizar todas as configurações do dispositivo",
|
||||||
|
"update_success": "Local atualizado!",
|
||||||
"upgrade_all_devices": "Atualize todos os dispositivos para o firmware mais recente",
|
"upgrade_all_devices": "Atualize todos os dispositivos para o firmware mais recente",
|
||||||
"upgrade_all_devices_error": "Erro ao atualizar dispositivos: {{e}}",
|
"upgrade_all_devices_error": "Erro ao atualizar dispositivos: {{e}}",
|
||||||
"upgrade_all_devices_success": "Atualização de dispositivos iniciada com sucesso!",
|
"upgrade_all_devices_success": "Atualização de dispositivos iniciada com sucesso!",
|
||||||
|
|||||||
27
src/components/Maps/GoogleMap/Marker.tsx
Normal file
27
src/components/Maps/GoogleMap/Marker.tsx
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
import * as React from 'react';
|
||||||
|
|
||||||
|
const _GoogleMapMarker = (options: google.maps.MarkerOptions) => {
|
||||||
|
const [marker, setMarker] = React.useState<google.maps.Marker>();
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
if (!marker) {
|
||||||
|
setMarker(new google.maps.Marker());
|
||||||
|
}
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
if (marker) {
|
||||||
|
marker.setMap(null);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}, [marker]);
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
if (marker) {
|
||||||
|
marker.setOptions(options);
|
||||||
|
}
|
||||||
|
}, [marker, options]);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const GoogleMapMarker = React.memo(_GoogleMapMarker);
|
||||||
89
src/components/Maps/GoogleMap/index.tsx
Normal file
89
src/components/Maps/GoogleMap/index.tsx
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
import * as React from 'react';
|
||||||
|
import { isLatLngLiteral } from '@googlemaps/typescript-guards';
|
||||||
|
import { createCustomEqual } from 'fast-equals';
|
||||||
|
|
||||||
|
const deepCompareEqualsForMaps = createCustomEqual((deepEqual) =>
|
||||||
|
// @ts-ignore
|
||||||
|
(a: number | google.maps.LatLng | google.maps.LatLngLiteral, b: number | google.maps.LatLng | google.maps.LatLngLiteral) => {
|
||||||
|
if (
|
||||||
|
isLatLngLiteral(a) ||
|
||||||
|
a instanceof google.maps.LatLng ||
|
||||||
|
isLatLngLiteral(b) ||
|
||||||
|
b instanceof google.maps.LatLng
|
||||||
|
) {
|
||||||
|
return new google.maps.LatLng(a).equals(new google.maps.LatLng(b));
|
||||||
|
}
|
||||||
|
|
||||||
|
// @ts-ignore
|
||||||
|
return deepEqual(a, b);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
const useDeepCompareMemoize = (value: unknown) => {
|
||||||
|
const ref = React.useRef<unknown>();
|
||||||
|
|
||||||
|
if (!deepCompareEqualsForMaps(value, ref.current)) {
|
||||||
|
ref.current = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ref.current;
|
||||||
|
};
|
||||||
|
|
||||||
|
const useDeepCompareEffectForMaps = (callback: React.EffectCallback, dependencies: unknown[]) => {
|
||||||
|
React.useEffect(callback, dependencies.map(useDeepCompareMemoize));
|
||||||
|
};
|
||||||
|
|
||||||
|
export interface GoogleMapProps extends google.maps.MapOptions {
|
||||||
|
style: { [key: string]: string };
|
||||||
|
onClick?: (e: google.maps.MapMouseEvent) => void;
|
||||||
|
onIdle?: (map: google.maps.Map) => void;
|
||||||
|
children?: React.ReactNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
const _GoogleMap = ({ style, onClick, onIdle, children, ...options }: GoogleMapProps) => {
|
||||||
|
const ref = React.useRef<HTMLDivElement>(null);
|
||||||
|
const [map, setMap] = React.useState<google.maps.Map>();
|
||||||
|
|
||||||
|
// because React does not do deep comparisons, a custom hook is used
|
||||||
|
useDeepCompareEffectForMaps(() => {
|
||||||
|
if (map) {
|
||||||
|
map.setOptions(options);
|
||||||
|
}
|
||||||
|
}, [map, options]);
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
if (ref.current && !map) {
|
||||||
|
setMap(new window.google.maps.Map(ref.current, {}));
|
||||||
|
}
|
||||||
|
}, [ref, map]);
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
if (map) {
|
||||||
|
['click', 'idle'].forEach((eventName) => google.maps.event.clearListeners(map, eventName));
|
||||||
|
|
||||||
|
if (onClick) {
|
||||||
|
map.addListener('click', onClick);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (onIdle) {
|
||||||
|
map.addListener('idle', () => onIdle(map));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, [map, onClick, onIdle]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<div ref={ref} style={style} />
|
||||||
|
{React.Children.map(children, (child) => {
|
||||||
|
if (React.isValidElement(child)) {
|
||||||
|
// set the map prop on the child component
|
||||||
|
// @ts-ignore
|
||||||
|
return React.cloneElement(child, { map });
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
})}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const GoogleMap = React.memo(_GoogleMap);
|
||||||
83
src/hooks/Network/Secrets.ts
Normal file
83
src/hooks/Network/Secrets.ts
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
import { QueryFunctionContext, useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
|
||||||
|
import { axiosSec } from 'constants/axiosInstances';
|
||||||
|
|
||||||
|
export type SecretName = 'google.maps.apikey' | string;
|
||||||
|
|
||||||
|
export type Secret = {
|
||||||
|
key: SecretName;
|
||||||
|
value: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type SecretDictionaryValue = {
|
||||||
|
key: SecretName;
|
||||||
|
description: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
const getSecret = async (context: QueryFunctionContext<string[], unknown>) =>
|
||||||
|
axiosSec.get(`/systemSecret/${context.queryKey[1]}`).then(({ data }: { data: Secret }) => data);
|
||||||
|
|
||||||
|
export const useGetSystemSecret = ({ secret }: { secret: SecretName }) =>
|
||||||
|
useQuery(['secrets', secret], getSecret, {
|
||||||
|
staleTime: 1000 * 60 * 10,
|
||||||
|
refetchInterval: 1000 * 60 * 10,
|
||||||
|
});
|
||||||
|
|
||||||
|
const getAllSecrets = async () =>
|
||||||
|
axiosSec.get('/systemSecret/0?all=true').then(({ data }: { data: { secrets: Secret[] } }) => data.secrets);
|
||||||
|
|
||||||
|
export const useGetAllSystemSecrets = () => {
|
||||||
|
const queryClient = useQueryClient();
|
||||||
|
|
||||||
|
return useQuery(['secrets'], getAllSecrets, {
|
||||||
|
staleTime: 1000 * 60 * 10,
|
||||||
|
refetchInterval: 1000 * 60 * 10,
|
||||||
|
onSuccess: (data) => {
|
||||||
|
for (const secret of data) {
|
||||||
|
queryClient.setQueryData(['secrets', secret.key], secret);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const getSecretsDictionary = async () =>
|
||||||
|
axiosSec
|
||||||
|
.get('/systemSecret/0?dictionary=true')
|
||||||
|
.then(({ data }: { data: { knownKeys: SecretDictionaryValue[] } }) => data.knownKeys);
|
||||||
|
|
||||||
|
export const useGetSystemSecretsDictionary = () =>
|
||||||
|
useQuery(['secrets', 'dictionary'], getSecretsDictionary, {
|
||||||
|
staleTime: 1000 * 60 * 10,
|
||||||
|
refetchInterval: 1000 * 60 * 10,
|
||||||
|
});
|
||||||
|
|
||||||
|
const updateSecret = async ({ key, value }: { key: string; value: string }) =>
|
||||||
|
axiosSec.put(`/systemSecret/${key}?value=${value}`, { key, value });
|
||||||
|
|
||||||
|
export const useUpdateSystemSecret = () => {
|
||||||
|
const queryClient = useQueryClient();
|
||||||
|
return useMutation(updateSecret, {
|
||||||
|
onSuccess: () => {
|
||||||
|
queryClient.invalidateQueries(['secrets']);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export const useCreateSystemSecret = () => {
|
||||||
|
const queryClient = useQueryClient();
|
||||||
|
return useMutation(updateSecret, {
|
||||||
|
onSuccess: () => {
|
||||||
|
queryClient.invalidateQueries(['secrets']);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const deleteSecret = async (key: string) => axiosSec.delete(`/systemSecret/${key}`);
|
||||||
|
|
||||||
|
export const useDeleteSystemSecret = () => {
|
||||||
|
const queryClient = useQueryClient();
|
||||||
|
return useMutation(deleteSecret, {
|
||||||
|
onSuccess: () => {
|
||||||
|
queryClient.invalidateQueries(['secrets']);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
import { useQuery, useQueryClient } from '@tanstack/react-query';
|
import { useQuery } from '@tanstack/react-query';
|
||||||
import { axiosGw } from 'constants/axiosInstances';
|
import { axiosGw } from 'constants/axiosInstances';
|
||||||
import { AxiosError } from 'models/Axios';
|
import { AxiosError } from 'models/Axios';
|
||||||
|
|
||||||
@@ -160,6 +160,11 @@ export type DeviceStatistics = {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
gps?: {
|
||||||
|
elevation: string;
|
||||||
|
latitude: string;
|
||||||
|
longitude: string;
|
||||||
|
};
|
||||||
version?: number;
|
version?: number;
|
||||||
};
|
};
|
||||||
const getLastStats = (serialNumber?: string) =>
|
const getLastStats = (serialNumber?: string) =>
|
||||||
@@ -175,7 +180,7 @@ export const useGetDeviceLastStats = ({
|
|||||||
onError?: (e: AxiosError) => void;
|
onError?: (e: AxiosError) => void;
|
||||||
}) =>
|
}) =>
|
||||||
useQuery(['device', serialNumber, 'last-statistics'], () => getLastStats(serialNumber), {
|
useQuery(['device', serialNumber, 'last-statistics'], () => getLastStats(serialNumber), {
|
||||||
enabled: serialNumber !== undefined && serialNumber !== '' && false,
|
enabled: serialNumber !== undefined && serialNumber !== '',
|
||||||
staleTime: 1000 * 60,
|
staleTime: 1000 * 60,
|
||||||
onError,
|
onError,
|
||||||
});
|
});
|
||||||
@@ -195,24 +200,12 @@ export const useGetDeviceNewestStats = ({
|
|||||||
serialNumber?: string;
|
serialNumber?: string;
|
||||||
limit: number;
|
limit: number;
|
||||||
onError?: (e: AxiosError) => void;
|
onError?: (e: AxiosError) => void;
|
||||||
}) => {
|
}) =>
|
||||||
const queryClient = useQueryClient();
|
useQuery(['deviceStatistics', serialNumber, 'newest', { limit }], getNewestStats(limit, serialNumber), {
|
||||||
|
|
||||||
return useQuery(['deviceStatistics', serialNumber, 'newest', { limit }], getNewestStats(limit, serialNumber), {
|
|
||||||
enabled: serialNumber !== undefined && serialNumber !== '',
|
enabled: serialNumber !== undefined && serialNumber !== '',
|
||||||
staleTime: 1000 * 60,
|
staleTime: 1000 * 60,
|
||||||
onSuccess: (response) => {
|
|
||||||
const entry = response.data[0];
|
|
||||||
// If we have a valid entry, we prefill lastStats, if not we trigger a fetch of the last statistics
|
|
||||||
if (entry) {
|
|
||||||
queryClient.setQueryData(['device', serialNumber, 'last-statistics'], entry.data);
|
|
||||||
} else {
|
|
||||||
queryClient.fetchQuery(['device', serialNumber, 'last-statistics']);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onError,
|
onError,
|
||||||
});
|
});
|
||||||
};
|
|
||||||
|
|
||||||
const getOuis = (macs?: string[]) => async () =>
|
const getOuis = (macs?: string[]) => async () =>
|
||||||
axiosGw.get(`/ouis?macList=${macs?.join(',')}`).then((response) => response.data) as Promise<{
|
axiosGw.get(`/ouis?macList=${macs?.join(',')}`).then((response) => response.data) as Promise<{
|
||||||
|
|||||||
75
src/pages/Device/LocationDisplayButton.tsx
Normal file
75
src/pages/Device/LocationDisplayButton.tsx
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
import * as React from 'react';
|
||||||
|
import { Box, Button, Flex, FormControl, FormLabel, useDisclosure } from '@chakra-ui/react';
|
||||||
|
import { Wrapper } from '@googlemaps/react-wrapper';
|
||||||
|
import { Globe } from 'phosphor-react';
|
||||||
|
import { useTranslation } from 'react-i18next';
|
||||||
|
import { GoogleMap } from 'components/Maps/GoogleMap';
|
||||||
|
import { GoogleMapMarker } from 'components/Maps/GoogleMap/Marker';
|
||||||
|
import { Modal } from 'components/Modals/Modal';
|
||||||
|
import { useGetSystemSecret } from 'hooks/Network/Secrets';
|
||||||
|
import { useGetDeviceLastStats } from 'hooks/Network/Statistics';
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
serialNumber: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
const LocationDisplayButton = ({ serialNumber }: Props) => {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
const { isOpen, onOpen, onClose } = useDisclosure();
|
||||||
|
const getGoogleApiKey = useGetSystemSecret({ secret: 'google.maps.apikey' });
|
||||||
|
const getLastStats = useGetDeviceLastStats({ serialNumber });
|
||||||
|
|
||||||
|
const location: google.maps.LatLngLiteral | undefined = React.useMemo(() => {
|
||||||
|
if (!getLastStats.data?.gps) return undefined;
|
||||||
|
|
||||||
|
try {
|
||||||
|
return {
|
||||||
|
lat: Number.parseFloat(getLastStats.data.gps.latitude),
|
||||||
|
lng: Number.parseFloat(getLastStats.data.gps.longitude),
|
||||||
|
};
|
||||||
|
} catch (e) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
}, [getLastStats.data?.gps]);
|
||||||
|
|
||||||
|
if (!location) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Button variant="link" onClick={onOpen} rightIcon={<Globe size={20} />} colorScheme="blue">
|
||||||
|
{t('locations.view_gps')}
|
||||||
|
</Button>
|
||||||
|
<Modal isOpen={isOpen} onClose={onClose} title={t('locations.one')}>
|
||||||
|
<Box w="100%" h="100%">
|
||||||
|
<Flex mb={4}>
|
||||||
|
<FormControl w="unset">
|
||||||
|
<FormLabel>{t('locations.lat')}</FormLabel>
|
||||||
|
<pre>{location.lat}</pre>
|
||||||
|
</FormControl>
|
||||||
|
<FormControl w="unset" mx={4}>
|
||||||
|
<FormLabel>{t('locations.longitude')}</FormLabel>
|
||||||
|
<pre>{location.lng}</pre>
|
||||||
|
</FormControl>
|
||||||
|
<FormControl w="unset">
|
||||||
|
<FormLabel>{t('locations.elevation')}</FormLabel>
|
||||||
|
<pre>{getLastStats.data?.gps?.elevation}</pre>
|
||||||
|
</FormControl>
|
||||||
|
</Flex>
|
||||||
|
{getGoogleApiKey.data ? (
|
||||||
|
<Box h="500px">
|
||||||
|
<Wrapper apiKey={getGoogleApiKey.data.value}>
|
||||||
|
<GoogleMap center={location} style={{ flexGrow: '1', height: '100%' }} zoom={10}>
|
||||||
|
<GoogleMapMarker position={location} />
|
||||||
|
</GoogleMap>
|
||||||
|
</Wrapper>
|
||||||
|
</Box>
|
||||||
|
) : null}
|
||||||
|
</Box>
|
||||||
|
</Modal>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default LocationDisplayButton;
|
||||||
@@ -38,7 +38,7 @@ const ViewLastStatsModal = ({ serialNumber }: Props) => {
|
|||||||
if (getLastStats.data) {
|
if (getLastStats.data) {
|
||||||
setValue(JSON.stringify(getLastStats.data, null, 2));
|
setValue(JSON.stringify(getLastStats.data, null, 2));
|
||||||
}
|
}
|
||||||
}, [getLastStats.data]);
|
}, [getLastStats.data, isOpen]);
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Tooltip label={t('statistics.last_stats')}>
|
<Tooltip label={t('statistics.last_stats')}>
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import { Flex, Grid, GridItem, Heading, Image, Tag } from '@chakra-ui/react';
|
import { Box, Flex, Grid, GridItem, Heading, Image, Tag } from '@chakra-ui/react';
|
||||||
import ReactCountryFlag from 'react-country-flag';
|
import ReactCountryFlag from 'react-country-flag';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
import LocationDisplayButton from './LocationDisplayButton';
|
||||||
import { Card } from 'components/Containers/Card';
|
import { Card } from 'components/Containers/Card';
|
||||||
import { CardBody } from 'components/Containers/Card/CardBody';
|
import { CardBody } from 'components/Containers/Card/CardBody';
|
||||||
import FormattedDate from 'components/InformationDisplays/FormattedDate';
|
import FormattedDate from 'components/InformationDisplays/FormattedDate';
|
||||||
@@ -90,11 +91,12 @@ const DeviceSummary = ({ serialNumber }: Props) => {
|
|||||||
{!getDevice.data?.locale || getDevice.data?.locale === '' ? (
|
{!getDevice.data?.locale || getDevice.data?.locale === '' ? (
|
||||||
'-'
|
'-'
|
||||||
) : (
|
) : (
|
||||||
<>
|
<Box mr={2}>
|
||||||
<ReactCountryFlag style={ICON_STYLE} countryCode={getDevice.data.locale} svg />
|
<ReactCountryFlag style={ICON_STYLE} countryCode={getDevice.data.locale} svg />
|
||||||
{COUNTRY_LIST.find(({ value }) => value === getDevice.data.locale)?.label}
|
{COUNTRY_LIST.find(({ value }) => value === getDevice.data.locale)?.label}
|
||||||
</>
|
</Box>
|
||||||
)}
|
)}
|
||||||
|
<LocationDisplayButton serialNumber={serialNumber} />
|
||||||
</GridItem>
|
</GridItem>
|
||||||
<GridItem colSpan={1} alignContent="center" alignItems="center">
|
<GridItem colSpan={1} alignContent="center" alignItems="center">
|
||||||
<Heading size="sm">{t('analytics.last_contact')}:</Heading>
|
<Heading size="sm">{t('analytics.last_contact')}:</Heading>
|
||||||
|
|||||||
Reference in New Issue
Block a user