Compare commits

..

8 Commits

Author SHA1 Message Date
TIP Automation User
61cfa9391f Chg: update image tag in helm values to v2.5.2 2022-07-26 10:29:58 +00:00
Dmitry Dunaev
39fbae1304 [WIFI-1998] Add: gracefull ingress deprecationush
Signed-off-by: Dmitry Dunaev <dmitry@opsfleet.com>
2022-07-21 17:48:14 +03:00
Johann Hoffmann
f5677695d8 Update image tag in helm values to v2.5.1
Signed-off-by: Johann Hoffmann <johann.hoffmann@mailbox.org>
2022-04-29 19:05:44 +02:00
Johann Hoffmann
e036419975 Update image tag in helm values to v2.5.1-RC1
Signed-off-by: Johann Hoffmann <johann.hoffmann@mailbox.org>
2022-04-29 18:08:12 +02:00
Stephane Bourque
df72853118 Merge pull request #88 from Telecominfraproject/WIFI-7818-2.5.1-hotfix
Hotfix for BSSID -> Station ID bug
2022-04-29 08:39:54 -07:00
Charles
f55e8cfe7e Hotfix for BSSID -> Station ID bug 2022-04-29 15:35:16 +01:00
TIP Automation User
9ae67c751c Chg: update image tag in helm values to v2.5.0 2022-03-30 13:48:24 +00:00
TIP Automation User
9e23b51dd0 Chg: update image tag in helm values to v2.5.0-RC1 2022-02-11 16:02:49 +00:00
46 changed files with 304 additions and 1755 deletions

View File

@@ -12,7 +12,6 @@ on:
pull_request:
branches:
- main
- 'release/*'
defaults:
run:
@@ -38,35 +37,3 @@ jobs:
registry: tip-tip-wlan-cloud-ucentral.jfrog.io
registry_user: ucentral
registry_password: ${{ secrets.DOCKER_REGISTRY_PASSWORD }}
- name: Notify on failure via Slack
if: failure() && github.ref == 'refs/heads/main'
uses: rtCamp/action-slack-notify@v2
env:
SLACK_USERNAME: GitHub Actions failure notifier
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }}
SLACK_COLOR: "${{ job.status }}"
SLACK_ICON: https://raw.githubusercontent.com/quintessence/slack-icons/master/images/github-logo-slack-icon.png
SLACK_TITLE: Docker build failed for OWGW-UI service
trigger-deploy-to-dev:
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main'
needs:
- docker
steps:
- name: Checkout actions repo
uses: actions/checkout@v2
with:
repository: Telecominfraproject/.github
path: github
- name: Trigger deployment of the latest version to dev instance and wait for result
uses: ./github/composite-actions/trigger-workflow-and-wait
with:
owner: Telecominfraproject
repo: wlan-testing
workflow: ucentralgw-dev-deployment.yaml
token: ${{ secrets.WLAN_TESTING_PAT }}
ref: master
inputs: '{"force_latest": "true"}'

View File

@@ -4,7 +4,6 @@ on:
pull_request:
branches:
- main
- 'release/*'
types: [ closed ]
defaults:

View File

@@ -1,46 +0,0 @@
name: Release chart package
on:
push:
tags:
- 'v*'
defaults:
run:
shell: bash
jobs:
helm-package:
runs-on: ubuntu-20.04
env:
HELM_REPO_URL: https://tip.jfrog.io/artifactory/tip-wlan-cloud-ucentral-helm/
HELM_REPO_USERNAME: ucentral
steps:
- name: Checkout uCentral assembly chart repo
uses: actions/checkout@v2
with:
path: wlan-cloud-ucentralgw-ui
- name: Build package
working-directory: wlan-cloud-ucentralgw-ui/helm
run: |
helm plugin install https://github.com/aslafy-z/helm-git --version 0.10.0
helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo update
helm dependency update
mkdir dist
helm package . -d dist
- name: Generate GitHub release body
working-directory: wlan-cloud-ucentralgw-ui/helm
run: |
pip3 install yq -q
echo "Docker image - tip-tip-wlan-cloud-ucentral.jfrog.io/owgw-ui:$GITHUB_REF_NAME" > release.txt
echo "Helm charted may be attached to this release" >> release.txt
echo "Deployment artifacts may be found in https://github.com/Telecominfraproject/wlan-cloud-ucentral-deploy/tree/$GITHUB_REF_NAME" >> release.txt
- name: Create GitHub release
uses: softprops/action-gh-release@v1
with:
body_path: wlan-cloud-ucentralgw-ui/helm/release.txt
files: wlan-cloud-ucentralgw-ui/helm/dist/*

View File

@@ -8,12 +8,12 @@ fullnameOverride: ""
images:
owgwui:
repository: tip-tip-wlan-cloud-ucentral.jfrog.io/owgw-ui
tag: v2.6.0-RC2
tag: v2.5.2
pullPolicy: Always
services:
owgwui:
type: ClusterIP
type: NodePort
ports:
http:
servicePort: 80

319
package-lock.json generated
View File

@@ -1,12 +1,12 @@
{
"name": "ucentral-client",
"version": "2.6.26",
"version": "2.5.44",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "ucentral-client",
"version": "2.6.26",
"version": "2.5.44",
"dependencies": {
"@coreui/coreui": "^3.4.0",
"@coreui/icons": "^2.0.1",
@@ -16,7 +16,6 @@
"apexcharts": "^3.27.1",
"axios": "^0.21.1",
"axios-retry": "^3.1.9",
"buffer": "^6.0.3",
"dagre": "^0.8.5",
"i18next": "^20.3.1",
"i18next-browser-languagedetector": "^6.1.2",
@@ -24,7 +23,6 @@
"prop-types": "^15.7.2",
"react": "^17.0.2",
"react-apexcharts": "^1.3.9",
"react-country-flag": "^3.0.2",
"react-csv": "^2.2.2",
"react-dom": "^17.0.2",
"react-flow-renderer": "^9.6.6",
@@ -35,7 +33,7 @@
"react-tooltip": "^4.2.21",
"react-widgets": "^5.1.1",
"sass": "^1.35.1",
"ucentral-libs": "^1.0.61",
"ucentral-libs": "^1.0.60",
"uuid": "^8.3.2"
},
"devDependencies": {
@@ -2946,22 +2944,10 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/ansi-escapes/node_modules/type-fest": {
"version": "0.21.3",
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz",
"integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==",
"dev": true,
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/ansi-html": {
"version": "0.0.7",
"resolved": "https://registry.npmjs.org/ansi-html/-/ansi-html-0.0.7.tgz",
"integrity": "sha512-JoAxEa1DfP9m2xfB/y2r/aKcwXNlltr4+0QSBC4TrLfcxyvepX2Pv0t/xpgGV5bGsDzCYV8SzjWgyCW0T9yYbA==",
"integrity": "sha1-gTWEAhliqenm/QOflA0S9WynhZ4=",
"dev": true,
"engines": [
"node >= 0.8.0"
@@ -3190,9 +3176,9 @@
}
},
"node_modules/async": {
"version": "2.6.4",
"resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz",
"integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==",
"version": "2.6.3",
"resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz",
"integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==",
"dev": true,
"dependencies": {
"lodash": "^4.17.14"
@@ -3433,25 +3419,6 @@
"node": ">=0.10.0"
}
},
"node_modules/base64-js": {
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
"integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/feross"
},
{
"type": "patreon",
"url": "https://www.patreon.com/feross"
},
{
"type": "consulting",
"url": "https://feross.org/support"
}
]
},
"node_modules/batch": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz",
@@ -3594,29 +3561,6 @@
"url": "https://opencollective.com/browserslist"
}
},
"node_modules/buffer": {
"version": "6.0.3",
"resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz",
"integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/feross"
},
{
"type": "patreon",
"url": "https://www.patreon.com/feross"
},
{
"type": "consulting",
"url": "https://feross.org/support"
}
],
"dependencies": {
"base64-js": "^1.3.1",
"ieee754": "^1.2.1"
}
},
"node_modules/buffer-from": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
@@ -3999,9 +3943,9 @@
}
},
"node_modules/cliui/node_modules/ansi-regex": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz",
"integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==",
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
"integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
"dev": true,
"engines": {
"node": ">=6"
@@ -6264,9 +6208,9 @@
}
},
"node_modules/eventsource": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/eventsource/-/eventsource-1.1.1.tgz",
"integrity": "sha512-qV5ZC0h7jYIAOhArFJgSfdyz6rALJyb270714o7ZtNnw2WSJ+eexhKtE0O8LYPRsHZHf2osHKZBxGPvm3kPkCA==",
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/eventsource/-/eventsource-1.1.0.tgz",
"integrity": "sha512-VSJjT5oCNrFvCS6igjzPAt5hBzQ2qPBFIbJ03zLI9SE0mxwZpMw6BfJrbFHm1a141AavMEB8JHmBhWAd66PfCg==",
"dev": true,
"dependencies": {
"original": "^1.0.0"
@@ -6796,9 +6740,9 @@
"dev": true
},
"node_modules/follow-redirects": {
"version": "1.14.9",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.9.tgz",
"integrity": "sha512-MQDfihBQYMcyy5dhRDJUHcw7lb2Pv/TuE6xP1vyraLukNDHKbDxDNaOE3NbCAdKQApno+GPRyo1YAp89yCjK4w==",
"version": "1.14.7",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.7.tgz",
"integrity": "sha512-+hbxoLbFMbRKDwohX8GkTataGqO6Jb7jGwpAlwgy2bIz25XtRm7KEzJM76R1WiNT5SwZkX4Y75SwBolkpmE7iQ==",
"funding": [
{
"type": "individual",
@@ -7829,25 +7773,6 @@
"postcss": "^8.1.0"
}
},
"node_modules/ieee754": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
"integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/feross"
},
{
"type": "patreon",
"url": "https://www.patreon.com/feross"
},
{
"type": "consulting",
"url": "https://feross.org/support"
}
]
},
"node_modules/ignore": {
"version": "4.0.6",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz",
@@ -8507,6 +8432,12 @@
"integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=",
"dev": true
},
"node_modules/json3": {
"version": "3.3.3",
"resolved": "https://registry.npmjs.org/json3/-/json3-3.3.3.tgz",
"integrity": "sha512-c7/8mbUsKigAbLkD5B010BK4D9LZm7A1pNItkEwiUZRpIN66exu/e7YQWysGun+TRKaJp8MhemM+VkfWv42aCA==",
"dev": true
},
"node_modules/json5": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz",
@@ -9170,9 +9101,9 @@
}
},
"node_modules/minimist": {
"version": "1.2.6",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz",
"integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==",
"version": "1.2.5",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
"devOptional": true
},
"node_modules/mixin-deep": {
@@ -9201,9 +9132,9 @@
}
},
"node_modules/moment": {
"version": "2.29.3",
"resolved": "https://registry.npmjs.org/moment/-/moment-2.29.3.tgz",
"integrity": "sha512-c6YRvhEo//6T2Jz/vVtYzqBzwvPT95JBQ+smCytzf7c50oMZRsR/a4w88aD34I+/QVSfnoAnSBFPJHItlOMJVw==",
"version": "2.29.1",
"resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz",
"integrity": "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==",
"engines": {
"node": "*"
}
@@ -10984,17 +10915,6 @@
"react": ">=0.13"
}
},
"node_modules/react-country-flag": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/react-country-flag/-/react-country-flag-3.0.2.tgz",
"integrity": "sha512-JPaz+q3QD0/nZtHBKj5x3O7r/SgSG9kxbymdaIU0RqlDAcorJIe4KV0DFhWIdKh69q5cPVkIVERcMYGZdvXgAA==",
"engines": {
"node": ">=12"
},
"peerDependencies": {
"react": ">=16"
}
},
"node_modules/react-csv": {
"version": "2.2.2",
"resolved": "https://registry.npmjs.org/react-csv/-/react-csv-2.2.2.tgz",
@@ -11795,9 +11715,9 @@
"dev": true
},
"node_modules/semver-regex": {
"version": "3.1.4",
"resolved": "https://registry.npmjs.org/semver-regex/-/semver-regex-3.1.4.tgz",
"integrity": "sha512-6IiqeZNgq01qGf0TId0t3NvKzSvUsjcpdEO3AQNeIjR6A2+ckTnQlDpl4qu1bjRv0RzN3FP9hzFmws3lKqRWkA==",
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/semver-regex/-/semver-regex-3.1.3.tgz",
"integrity": "sha512-Aqi54Mk9uYTjVexLnR67rTyBusmwd04cLkHy9hNvk3+G3nT2Oyg7E0l4XVbOaNwIvQ3hHeYxGcyEy+mKreyBFQ==",
"dev": true,
"engines": {
"node": ">=8"
@@ -12300,22 +12220,17 @@
}
},
"node_modules/sockjs-client": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/sockjs-client/-/sockjs-client-1.6.0.tgz",
"integrity": "sha512-qVHJlyfdHFht3eBFZdKEXKTlb7I4IV41xnVNo8yUKA1UHcPJwgW2SvTq9LhnjjCywSkSK7c/e4nghU0GOoMCRQ==",
"version": "1.5.2",
"resolved": "https://registry.npmjs.org/sockjs-client/-/sockjs-client-1.5.2.tgz",
"integrity": "sha512-ZzRxPBISQE7RpzlH4tKJMQbHM9pabHluk0WBaxAQ+wm/UieeBVBou0p4wVnSQGN9QmpAZygQ0cDIypWuqOFmFQ==",
"dev": true,
"dependencies": {
"debug": "^3.2.7",
"eventsource": "^1.1.0",
"faye-websocket": "^0.11.4",
"debug": "^3.2.6",
"eventsource": "^1.0.7",
"faye-websocket": "^0.11.3",
"inherits": "^2.0.4",
"url-parse": "^1.5.10"
},
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://tidelift.com/funding/github/npm/sockjs-client"
"json3": "^3.3.3",
"url-parse": "^1.5.3"
}
},
"node_modules/sockjs-client/node_modules/debug": {
@@ -13393,12 +13308,10 @@
}
},
"node_modules/type-fest": {
"version": "0.13.1",
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz",
"integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==",
"version": "0.21.3",
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz",
"integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==",
"dev": true,
"optional": true,
"peer": true,
"engines": {
"node": ">=10"
},
@@ -13420,9 +13333,9 @@
}
},
"node_modules/ucentral-libs": {
"version": "1.0.61",
"resolved": "https://registry.npmjs.org/ucentral-libs/-/ucentral-libs-1.0.61.tgz",
"integrity": "sha512-RMUFLC6PMeh4S1MSkDXYjpQfh4yWeZX5Rm5FTRNbfYfaLKuL8CbRZjnuGPFrgABGQRWk5TITxXQASYBpmOq1dQ==",
"version": "1.0.60",
"resolved": "https://registry.npmjs.org/ucentral-libs/-/ucentral-libs-1.0.60.tgz",
"integrity": "sha512-PRw2QTcbnHdrA8rPQhREI1FOKyuZUt48H3KcSGQgHpik2Ni+0una7jRfMFXwOU9yHzxQAlYG0EWLrzBnrKRvGA==",
"dependencies": {
"@coreui/coreui": "^3.4.0",
"@coreui/icons": "^2.0.1",
@@ -13657,9 +13570,9 @@
}
},
"node_modules/url-parse": {
"version": "1.5.10",
"resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz",
"integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==",
"version": "1.5.4",
"resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.4.tgz",
"integrity": "sha512-ITeAByWWoqutFClc/lRZnFplgXgEZr3WJ6XngMM/N9DMIm4K8zXPCZ1Jdu0rERwO84w1WC5wkle2ubwTA4NTBg==",
"dev": true,
"dependencies": {
"querystringify": "^2.1.1",
@@ -14269,7 +14182,7 @@
"node_modules/webpack-dev-server/node_modules/glob-parent": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz",
"integrity": "sha512-E8Ak/2+dZY6fnzlR7+ueWvhsH1SjHr4jjss4YS/h4py44jY9MhK/VFdaZJAWDz6BbL21KeteKxFSFpq8OS5gVA==",
"integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=",
"dev": true,
"dependencies": {
"is-glob": "^3.1.0",
@@ -14891,9 +14804,9 @@
}
},
"node_modules/yargs/node_modules/ansi-regex": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz",
"integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==",
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
"integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
"dev": true,
"engines": {
"node": ">=6"
@@ -17087,20 +17000,12 @@
"dev": true,
"requires": {
"type-fest": "^0.21.3"
},
"dependencies": {
"type-fest": {
"version": "0.21.3",
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz",
"integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==",
"dev": true
}
}
},
"ansi-html": {
"version": "0.0.7",
"resolved": "https://registry.npmjs.org/ansi-html/-/ansi-html-0.0.7.tgz",
"integrity": "sha512-JoAxEa1DfP9m2xfB/y2r/aKcwXNlltr4+0QSBC4TrLfcxyvepX2Pv0t/xpgGV5bGsDzCYV8SzjWgyCW0T9yYbA==",
"integrity": "sha1-gTWEAhliqenm/QOflA0S9WynhZ4=",
"dev": true
},
"ansi-html-community": {
@@ -17263,9 +17168,9 @@
"dev": true
},
"async": {
"version": "2.6.4",
"resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz",
"integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==",
"version": "2.6.3",
"resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz",
"integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==",
"dev": true,
"requires": {
"lodash": "^4.17.14"
@@ -17453,11 +17358,6 @@
}
}
},
"base64-js": {
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
"integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA=="
},
"batch": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz",
@@ -17577,15 +17477,6 @@
"picocolors": "^1.0.0"
}
},
"buffer": {
"version": "6.0.3",
"resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz",
"integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==",
"requires": {
"base64-js": "^1.3.1",
"ieee754": "^1.2.1"
}
},
"buffer-from": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
@@ -17889,9 +17780,9 @@
},
"dependencies": {
"ansi-regex": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz",
"integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==",
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
"integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
"dev": true
},
"emoji-regex": {
@@ -19597,9 +19488,9 @@
"dev": true
},
"eventsource": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/eventsource/-/eventsource-1.1.1.tgz",
"integrity": "sha512-qV5ZC0h7jYIAOhArFJgSfdyz6rALJyb270714o7ZtNnw2WSJ+eexhKtE0O8LYPRsHZHf2osHKZBxGPvm3kPkCA==",
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/eventsource/-/eventsource-1.1.0.tgz",
"integrity": "sha512-VSJjT5oCNrFvCS6igjzPAt5hBzQ2qPBFIbJ03zLI9SE0mxwZpMw6BfJrbFHm1a141AavMEB8JHmBhWAd66PfCg==",
"dev": true,
"requires": {
"original": "^1.0.0"
@@ -20033,9 +19924,9 @@
"dev": true
},
"follow-redirects": {
"version": "1.14.9",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.9.tgz",
"integrity": "sha512-MQDfihBQYMcyy5dhRDJUHcw7lb2Pv/TuE6xP1vyraLukNDHKbDxDNaOE3NbCAdKQApno+GPRyo1YAp89yCjK4w=="
"version": "1.14.7",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.7.tgz",
"integrity": "sha512-+hbxoLbFMbRKDwohX8GkTataGqO6Jb7jGwpAlwgy2bIz25XtRm7KEzJM76R1WiNT5SwZkX4Y75SwBolkpmE7iQ=="
},
"for-in": {
"version": "1.0.2",
@@ -20805,11 +20696,6 @@
"dev": true,
"requires": {}
},
"ieee754": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
"integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA=="
},
"ignore": {
"version": "4.0.6",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz",
@@ -21279,6 +21165,12 @@
"integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=",
"dev": true
},
"json3": {
"version": "3.3.3",
"resolved": "https://registry.npmjs.org/json3/-/json3-3.3.3.tgz",
"integrity": "sha512-c7/8mbUsKigAbLkD5B010BK4D9LZm7A1pNItkEwiUZRpIN66exu/e7YQWysGun+TRKaJp8MhemM+VkfWv42aCA==",
"dev": true
},
"json5": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz",
@@ -21790,9 +21682,9 @@
}
},
"minimist": {
"version": "1.2.6",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz",
"integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==",
"version": "1.2.5",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
"devOptional": true
},
"mixin-deep": {
@@ -21815,9 +21707,9 @@
}
},
"moment": {
"version": "2.29.3",
"resolved": "https://registry.npmjs.org/moment/-/moment-2.29.3.tgz",
"integrity": "sha512-c6YRvhEo//6T2Jz/vVtYzqBzwvPT95JBQ+smCytzf7c50oMZRsR/a4w88aD34I+/QVSfnoAnSBFPJHItlOMJVw=="
"version": "2.29.1",
"resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz",
"integrity": "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ=="
},
"mrmime": {
"version": "1.0.0",
@@ -23091,12 +22983,6 @@
"prop-types": "^15.5.7"
}
},
"react-country-flag": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/react-country-flag/-/react-country-flag-3.0.2.tgz",
"integrity": "sha512-JPaz+q3QD0/nZtHBKj5x3O7r/SgSG9kxbymdaIU0RqlDAcorJIe4KV0DFhWIdKh69q5cPVkIVERcMYGZdvXgAA==",
"requires": {}
},
"react-csv": {
"version": "2.2.2",
"resolved": "https://registry.npmjs.org/react-csv/-/react-csv-2.2.2.tgz",
@@ -23690,9 +23576,9 @@
"dev": true
},
"semver-regex": {
"version": "3.1.4",
"resolved": "https://registry.npmjs.org/semver-regex/-/semver-regex-3.1.4.tgz",
"integrity": "sha512-6IiqeZNgq01qGf0TId0t3NvKzSvUsjcpdEO3AQNeIjR6A2+ckTnQlDpl4qu1bjRv0RzN3FP9hzFmws3lKqRWkA==",
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/semver-regex/-/semver-regex-3.1.3.tgz",
"integrity": "sha512-Aqi54Mk9uYTjVexLnR67rTyBusmwd04cLkHy9hNvk3+G3nT2Oyg7E0l4XVbOaNwIvQ3hHeYxGcyEy+mKreyBFQ==",
"dev": true
},
"send": {
@@ -24116,16 +24002,17 @@
}
},
"sockjs-client": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/sockjs-client/-/sockjs-client-1.6.0.tgz",
"integrity": "sha512-qVHJlyfdHFht3eBFZdKEXKTlb7I4IV41xnVNo8yUKA1UHcPJwgW2SvTq9LhnjjCywSkSK7c/e4nghU0GOoMCRQ==",
"version": "1.5.2",
"resolved": "https://registry.npmjs.org/sockjs-client/-/sockjs-client-1.5.2.tgz",
"integrity": "sha512-ZzRxPBISQE7RpzlH4tKJMQbHM9pabHluk0WBaxAQ+wm/UieeBVBou0p4wVnSQGN9QmpAZygQ0cDIypWuqOFmFQ==",
"dev": true,
"requires": {
"debug": "^3.2.7",
"eventsource": "^1.1.0",
"faye-websocket": "^0.11.4",
"debug": "^3.2.6",
"eventsource": "^1.0.7",
"faye-websocket": "^0.11.3",
"inherits": "^2.0.4",
"url-parse": "^1.5.10"
"json3": "^3.3.3",
"url-parse": "^1.5.3"
},
"dependencies": {
"debug": {
@@ -24957,12 +24844,10 @@
}
},
"type-fest": {
"version": "0.13.1",
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz",
"integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==",
"dev": true,
"optional": true,
"peer": true
"version": "0.21.3",
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz",
"integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==",
"dev": true
},
"type-is": {
"version": "1.6.18",
@@ -24975,9 +24860,9 @@
}
},
"ucentral-libs": {
"version": "1.0.61",
"resolved": "https://registry.npmjs.org/ucentral-libs/-/ucentral-libs-1.0.61.tgz",
"integrity": "sha512-RMUFLC6PMeh4S1MSkDXYjpQfh4yWeZX5Rm5FTRNbfYfaLKuL8CbRZjnuGPFrgABGQRWk5TITxXQASYBpmOq1dQ==",
"version": "1.0.60",
"resolved": "https://registry.npmjs.org/ucentral-libs/-/ucentral-libs-1.0.60.tgz",
"integrity": "sha512-PRw2QTcbnHdrA8rPQhREI1FOKyuZUt48H3KcSGQgHpik2Ni+0una7jRfMFXwOU9yHzxQAlYG0EWLrzBnrKRvGA==",
"requires": {
"@coreui/coreui": "^3.4.0",
"@coreui/icons": "^2.0.1",
@@ -25177,9 +25062,9 @@
}
},
"url-parse": {
"version": "1.5.10",
"resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz",
"integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==",
"version": "1.5.4",
"resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.4.tgz",
"integrity": "sha512-ITeAByWWoqutFClc/lRZnFplgXgEZr3WJ6XngMM/N9DMIm4K8zXPCZ1Jdu0rERwO84w1WC5wkle2ubwTA4NTBg==",
"dev": true,
"requires": {
"querystringify": "^2.1.1",
@@ -25660,7 +25545,7 @@
"glob-parent": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz",
"integrity": "sha512-E8Ak/2+dZY6fnzlR7+ueWvhsH1SjHr4jjss4YS/h4py44jY9MhK/VFdaZJAWDz6BbL21KeteKxFSFpq8OS5gVA==",
"integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=",
"dev": true,
"requires": {
"is-glob": "^3.1.0",
@@ -26098,9 +25983,9 @@
},
"dependencies": {
"ansi-regex": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz",
"integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==",
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
"integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
"dev": true
},
"emoji-regex": {

View File

@@ -1,6 +1,6 @@
{
"name": "ucentral-client",
"version": "2.6.26",
"version": "2.5.44",
"dependencies": {
"@coreui/coreui": "^3.4.0",
"@coreui/icons": "^2.0.1",
@@ -10,7 +10,6 @@
"apexcharts": "^3.27.1",
"axios": "^0.21.1",
"axios-retry": "^3.1.9",
"buffer": "^6.0.3",
"dagre": "^0.8.5",
"i18next": "^20.3.1",
"i18next-browser-languagedetector": "^6.1.2",
@@ -18,7 +17,6 @@
"prop-types": "^15.7.2",
"react": "^17.0.2",
"react-apexcharts": "^1.3.9",
"react-country-flag": "^3.0.2",
"react-csv": "^2.2.2",
"react-dom": "^17.0.2",
"react-flow-renderer": "^9.6.6",
@@ -29,7 +27,7 @@
"react-tooltip": "^4.2.21",
"react-widgets": "^5.1.1",
"sass": "^1.35.1",
"ucentral-libs": "^1.0.61",
"ucentral-libs": "^1.0.60",
"uuid": "^8.3.2"
},
"main": "index.js",

View File

@@ -8,7 +8,6 @@
"factory_reset": "Auf Werkseinstellungen zurückgesetzt",
"firmware_upgrade": "Firmware Aktualisierung",
"reboot": "Gerät neustarten",
"request_ie": "Fordern Sie IEs an",
"telemetry": "Telemetrie",
"title": "Geräte Administrations",
"trace": "Tcpdump starten",
@@ -28,7 +27,6 @@
"error": "Fehler beim Senden des Befehls!",
"error_delete_log": "Fehler beim Versuch zu löschen: {{error}}",
"event_queue": "Ereigniswarteschlange",
"reboot_start": "Der Neustartvorgang hat begonnen!",
"success": "Befehl wurde erfolgreich übermittelt",
"title": "Gerätebefehle",
"unable_queue": "Anfrage für Ereigniswarteschlange kann nicht abgeschlossen werden: {{error}}"
@@ -150,7 +148,6 @@
"need_date": "Du brauchst ein Datum...",
"no": "Nein",
"no_addresses_found": "Keine Adressen gefunden",
"no_clients_found": "Keine Kunden gefunden",
"no_devices_found": "Keine Geräte gefunden",
"no_items": "Keine Gegenstände",
"none": "Keiner",
@@ -329,13 +326,11 @@
"blacklisted_on": "Datum",
"capabilities": "Fähigkeiten",
"certificate_explanation": "Zertifikate der angeschlossenen Geräte",
"count_explanation": "Geräte, die auf diese Gateway-Instanz verweisen",
"edit_blacklist": "Gerät auf der schwarzen Liste bearbeiten",
"error_adding_blacklist": "Fehler beim Hinzufügen des Geräts zur Blacklist: {{error}}",
"error_edit_blacklist": "Fehler beim Bearbeiten der schwarzen Liste: {{error}}",
"error_fetching_device": "Fehler beim Abrufen der Geräteinformationen: {{error}}",
"error_fetching_devices": "Fehler beim Abrufen von Geräten: {{error}}",
"firmware_count_explanation": "Dies ist die Gesamtzahl der Geräte, die diesem Firmware-Server hinzugefügt wurden, einschließlich der Geräte, die derzeit nicht auf den zugehörigen Gateway-Server verweisen.",
"health_explanation": "Zustand der verbundenen Geräte ((Geräte = 100 % * 100 + Geräte > 90 % * 95 + Geräte > 60 % * 75 + Geräte < 60 % * 35) / Verbundene Geräte)",
"memory_explanation": "Anzahl verbundener Geräte mit entsprechendem belegtem Speicher %",
"remove_from_blacklist": "Von der schwarzen Liste entfernen",
@@ -429,7 +424,7 @@
"to_release": "Zu",
"unknown_firmware_status": "Unbekannter Firmware-Status",
"upgrade": "Aktualisierung",
"upgrade_command_submitted": "Aktualisierung läuft...",
"upgrade_command_submitted": "Upgrade-Befehl erfolgreich gesendet",
"upgrade_to_latest": "Neueste",
"upgrade_to_version": "Upgrade auf diese Revision",
"upgrading": "Upgrade durchführen..."
@@ -719,8 +714,6 @@
"telemetry": {
"connection_failed": "Verbindung konnte nicht hergestellt werden. Fehler: {{error}}",
"interval": "Intervall",
"lifetime": "Dauer",
"outputmode": "Ausgabemodus",
"last_update": "Letztes Update",
"types": "Typen"
},
@@ -732,7 +725,7 @@
"title": "Tcpdump",
"trace": "Spur",
"trace_not_successful": "Trace nicht erfolgreich: Gateway hat folgenden Fehler gemeldet: {{error}}",
"wait_for_file": "Warten, bis die Trace-Datei fertig ist?",
"wait_for_file": "Möchten Sie warten, bis die Trace-Datei fertig ist?",
"waiting_directions": "Bitte warten Sie auf die Trace-Datendatei. Dies könnte eine Weile dauern. Sie können das Warten beenden und die Ablaufverfolgungsdatei später aus der Befehlstabelle abrufen.",
"waiting_seconds": "Verstrichene Zeit: {{seconds}} Sekunden"
},

View File

@@ -8,7 +8,6 @@
"factory_reset": "Factory Reset",
"firmware_upgrade": "Firmware Upgrade",
"reboot": "Reboot",
"request_ie": "Request IEs",
"telemetry": "Telemetry",
"title": "Commands",
"trace": "Trace",
@@ -28,7 +27,6 @@
"error": "Error while submitting command!",
"error_delete_log": "Error while trying to delete: {{error}}",
"event_queue": "Event Queue",
"reboot_start": "Reboot process has started!",
"success": "Command submitted successfully, you can look at the Commands log for the result",
"title": "Command History",
"unable_queue": "Unable to complete event queue request: {{error}}"
@@ -150,7 +148,6 @@
"need_date": "You need a date...",
"no": "No",
"no_addresses_found": "No Addresses Found",
"no_clients_found": "No Clients Found",
"no_devices_found": "No Devices Found",
"no_items": "No Items",
"none": "None",
@@ -329,13 +326,11 @@
"blacklisted_on": "Date",
"capabilities": "Capabilities",
"certificate_explanation": "Certificates of connected devices",
"count_explanation": "Devices pointing at this gateway instance",
"edit_blacklist": "Edit Blacklisted Device",
"error_adding_blacklist": "Error adding device to blacklist: {{error}}",
"error_edit_blacklist": "Error editing blacklist: {{error}}",
"error_fetching_device": "Error fetching device information: {{error}}",
"error_fetching_devices": "Error while fetching devices: {{error}}",
"firmware_count_explanation": "This is the total amount of devices that were added to this firmware server, including devices not currently pointing at the related gateway server.",
"health_explanation": "Health of connected devices ((Devices=100% * 100 + Devices>90% * 95 + Devices>60% * 75 + Devices<60% * 35) / ConnectedDevices)",
"memory_explanation": "Amount of connected devices with corresponding memory used percentage",
"remove_from_blacklist": "Remove from blacklist",
@@ -429,7 +424,7 @@
"to_release": "To",
"unknown_firmware_status": "Unknown Firmware Status",
"upgrade": "Upgrade",
"upgrade_command_submitted": "Upgrade in progress...",
"upgrade_command_submitted": "Upgrade Command Submitted Successfully",
"upgrade_to_latest": "Latest",
"upgrade_to_version": "Upgrade to this Revision",
"upgrading": "Upgrading..."
@@ -719,8 +714,6 @@
"telemetry": {
"connection_failed": "Failed to create connection. Error: {{error}}",
"interval": "Interval",
"lifetime": "Duration",
"outputmode": "Output Mode",
"last_update": "Last Update",
"types": "Types"
},
@@ -732,7 +725,7 @@
"title": "Trace",
"trace": "Trace",
"trace_not_successful": "Trace not successful: gateway reported the following error : {{error}}",
"wait_for_file": "Wait until the trace file is ready?",
"wait_for_file": "Would you like to wait until the trace file is ready?",
"waiting_directions": "Please wait for the trace data file. This may take some time. You can exit the wait and retrieve the trace file from the commands table later.",
"waiting_seconds": "Time Elapsed: {{seconds}} seconds"
},

View File

@@ -8,7 +8,6 @@
"factory_reset": "Restablecimiento De Fábrica",
"firmware_upgrade": "Actualización de firmware",
"reboot": "Reiniciar",
"request_ie": "Solicitar IE",
"telemetry": "Telemetria",
"title": "Comandos",
"trace": "Rastro",
@@ -28,7 +27,6 @@
"error": "¡Error al enviar el comando!",
"error_delete_log": "Error al intentar eliminar: {{error}}",
"event_queue": "Cola de eventos",
"reboot_start": "¡El proceso de reinicio ha comenzado!",
"success": "Comando enviado con éxito, puede consultar el registro de Comandos para ver el resultado",
"title": "Historial de Comandos",
"unable_queue": "No se pudo completar la solicitud de cola de eventos: {{error}}"
@@ -150,7 +148,6 @@
"need_date": "Necesitas una cita ...",
"no": "No",
"no_addresses_found": "No se encontraron direcciones",
"no_clients_found": "No se encontraron clientes",
"no_devices_found": "No se encontraron dispositivos",
"no_items": "No hay articulos",
"none": "Ninguna",
@@ -329,13 +326,11 @@
"blacklisted_on": "Fecha",
"capabilities": "capacidades",
"certificate_explanation": "Certificados de dispositivos conectados",
"count_explanation": "Dispositivos que apuntan a esta instancia de puerta de enlace",
"edit_blacklist": "Editar dispositivo incluido en la lista negra",
"error_adding_blacklist": "Error al agregar el dispositivo a la lista negra: {{error}}",
"error_edit_blacklist": "Error al editar la lista negra: {{error}}",
"error_fetching_device": "Error al obtener la información del dispositivo: {{error}}",
"error_fetching_devices": "Error al recuperar dispositivos: {{error}}",
"firmware_count_explanation": "Esta es la cantidad total de dispositivos que se agregaron a este servidor de firmware, incluidos los dispositivos que actualmente no apuntan al servidor de puerta de enlace relacionado.",
"health_explanation": "Estado de los dispositivos conectados ((Dispositivos = 100% * 100 + Dispositivos> 90% * 95 + Dispositivos> 60% * 75 + Dispositivos <60% * 35) / Dispositivos conectados)",
"memory_explanation": "Cantidad de dispositivos conectados con la memoria correspondiente utilizada%",
"remove_from_blacklist": "ELIMINAR DE LA LISTA NEGRA",
@@ -429,7 +424,7 @@
"to_release": "A",
"unknown_firmware_status": "Estado de firmware desconocido",
"upgrade": "Mejorar",
"upgrade_command_submitted": "Actualización en curso...",
"upgrade_command_submitted": "El comando de actualización se envió correctamente",
"upgrade_to_latest": "último",
"upgrade_to_version": "Actualizar a esta revisión",
"upgrading": "Actualizando ..."
@@ -719,8 +714,6 @@
"telemetry": {
"connection_failed": "No se pudo crear la conexión. Error: {{error}}",
"interval": "intervalo",
"lifetime": "Duración",
"outputmode": "Modo salida",
"last_update": "Última actualización",
"types": "Los tipos"
},
@@ -732,7 +725,7 @@
"title": "Rastro",
"trace": "Rastro",
"trace_not_successful": "Seguimiento fallido: la puerta de enlace informó el siguiente error: {{error}}",
"wait_for_file": "¿Esperar hasta que el archivo de rastreo esté listo?",
"wait_for_file": "¿Le gustaría esperar hasta que el archivo de seguimiento esté listo?",
"waiting_directions": "Espere el archivo de datos de seguimiento. Esto puede tomar algo de tiempo. Puede salir de la espera y recuperar el archivo de seguimiento de la tabla de comandos más tarde.",
"waiting_seconds": "Tiempo transcurrido: {{seconds}} segundos"
},

View File

@@ -8,7 +8,6 @@
"factory_reset": "Retour aux paramètres d'usine",
"firmware_upgrade": "Mise à jour du firmware",
"reboot": "Redémarrer",
"request_ie": "Demander des IE",
"telemetry": "Télémétrie",
"title": "Les commandes",
"trace": "Trace",
@@ -28,7 +27,6 @@
"error": "Erreur lors de la soumission de la commande !",
"error_delete_log": "Erreur lors de la tentative de suppression : {{error}}",
"event_queue": "File d'attente d'événements",
"reboot_start": "Le processus de redémarrage a commencé !",
"success": "Commande soumise avec succès, vous pouvez consulter le journal des commandes pour le résultat",
"title": "Historique des commandes",
"unable_queue": "Impossible de terminer la demande de file d'attente d'événements: {{error}}"
@@ -150,7 +148,6 @@
"need_date": "Vous avez besoin d'un rendez-vous...",
"no": "Non",
"no_addresses_found": "Aucune adresse trouvée",
"no_clients_found": "Aucun client trouvé",
"no_devices_found": "Aucun périphérique trouvé",
"no_items": "Pas d'objet",
"none": "Aucun",
@@ -329,13 +326,11 @@
"blacklisted_on": "Rendez-vous amoureux",
"capabilities": "Capacités",
"certificate_explanation": "Certificats des appareils connectés",
"count_explanation": "Périphériques pointant vers cette instance de passerelle",
"edit_blacklist": "Modifier l'appareil sur liste noire",
"error_adding_blacklist": "Erreur lors de l'ajout de l'appareil à la liste noire : {{error}}",
"error_edit_blacklist": "Erreur lors de la modification de la liste noire : {{error}}",
"error_fetching_device": "Erreur lors de la récupération des informations sur l'appareil : {{error}}",
"error_fetching_devices": "Erreur lors de la récupération des appareils : {{error}}",
"firmware_count_explanation": "Il s'agit du nombre total d'appareils qui ont été ajoutés à ce serveur de micrologiciel, y compris les appareils qui ne pointent pas actuellement vers le serveur de passerelle associé.",
"health_explanation": "Santé des appareils connectés ((Appareils = 100 % * 100 + Appareils> 90 % * 95 + Appareils> 60 % * 75 + Appareils < 60 % * 35) / Appareils connectés)",
"memory_explanation": "Nombre d'appareils connectés avec la mémoire correspondante utilisée %",
"remove_from_blacklist": "Supprimer de la liste noire",
@@ -429,7 +424,7 @@
"to_release": "à",
"unknown_firmware_status": "État du micrologiciel inconnu",
"upgrade": "Améliorer",
"upgrade_command_submitted": "Mise à jour en cours...",
"upgrade_command_submitted": "Commande de mise à niveau soumise avec succès",
"upgrade_to_latest": "Dernier",
"upgrade_to_version": "Mettre à niveau vers cette révision",
"upgrading": "Mise à niveau..."
@@ -719,8 +714,6 @@
"telemetry": {
"connection_failed": "Échec de la création de la connexion. Erreur : {{error}}",
"interval": "Intervalle",
"lifetime": "Durée",
"outputmode": "Mode de sortie",
"last_update": "Dernière mise à jour",
"types": "Les types"
},
@@ -732,7 +725,7 @@
"title": "Trace",
"trace": "Trace",
"trace_not_successful": "Trace non réussie : la passerelle a signalé l'erreur suivante : {{error}}",
"wait_for_file": "Attendre que le fichier de trace soit prêt ?",
"wait_for_file": "Souhaitez-vous attendre que le fichier de trace soit prêt ?",
"waiting_directions": "Veuillez attendre le fichier de données de trace. Cela peut prendre un certain temps. Vous pouvez quitter l'attente et récupérer le fichier de trace de la table des commandes plus tard.",
"waiting_seconds": "Temps écoulé : {{seconds}} secondes"
},

View File

@@ -8,7 +8,6 @@
"factory_reset": "Restauração de fábrica",
"firmware_upgrade": "Atualização de firmware",
"reboot": "Reiniciar",
"request_ie": "Solicitar IEs",
"telemetry": "Telemetria",
"title": "Comandos",
"trace": "Vestígio",
@@ -28,7 +27,6 @@
"error": "Erro ao enviar comando!",
"error_delete_log": "Erro ao tentar excluir: {{error}}",
"event_queue": "Fila de Eventos",
"reboot_start": "O processo de reinicialização foi iniciado!",
"success": "Comando enviado com sucesso, você pode consultar o log de Comandos para ver o resultado",
"title": "Histórico de Comandos",
"unable_queue": "Incapaz de completar o pedido de fila de eventos: {{error}}"
@@ -150,7 +148,6 @@
"need_date": "Você precisa de um encontro ...",
"no": "Não",
"no_addresses_found": "Nenhum endereço encontrado",
"no_clients_found": "Nenhum cliente encontrado",
"no_devices_found": "Nenhum dispositivo encontrado",
"no_items": "Nenhum item",
"none": "Nenhum",
@@ -329,13 +326,11 @@
"blacklisted_on": "Encontro",
"capabilities": "Recursos",
"certificate_explanation": "Certificados de dispositivos conectados",
"count_explanation": "Dispositivos apontando para esta instância de gateway",
"edit_blacklist": "Editar dispositivo na lista negra",
"error_adding_blacklist": "Erro ao adicionar dispositivo à lista negra: {{error}}",
"error_edit_blacklist": "Erro ao editar a lista negra: {{error}}",
"error_fetching_device": "Erro ao buscar informações do dispositivo: {{error}}",
"error_fetching_devices": "Erro ao buscar dispositivos: {{error}}",
"firmware_count_explanation": "Esta é a quantidade total de dispositivos que foram adicionados a este servidor de firmware, incluindo dispositivos que não estão apontando para o servidor de gateway relacionado.",
"health_explanation": "Integridade dos dispositivos conectados ((Dispositivos = 100% * 100 + Dispositivos> 90% * 95 + Dispositivos> 60% * 75 + Dispositivos <60% * 35) / Dispositivos Conectados)",
"memory_explanation": "Quantidade de dispositivos conectados com a memória correspondente usada%",
"remove_from_blacklist": "Remover da lista negra",
@@ -429,7 +424,7 @@
"to_release": "Para",
"unknown_firmware_status": "Status de firmware desconhecido",
"upgrade": "Melhorar",
"upgrade_command_submitted": "Atualização em andamento...",
"upgrade_command_submitted": "Comando de atualização enviado com sucesso",
"upgrade_to_latest": "Mais recentes",
"upgrade_to_version": "Atualize para esta revisão",
"upgrading": "Atualizando ..."
@@ -719,8 +714,6 @@
"telemetry": {
"connection_failed": "Falha ao criar conexão. Erro: {{error}}",
"interval": "intervalo",
"lifetime": "Duração",
"outputmode": "Modo saída",
"last_update": "Última atualização",
"types": "Tipos"
},
@@ -732,7 +725,7 @@
"title": "Vestígio",
"trace": "Vestígio",
"trace_not_successful": "O rastreamento não foi bem-sucedido: o gateway relatou o seguinte erro: {{error}}",
"wait_for_file": "Esperar até que o arquivo de rastreamento esteja pronto?",
"wait_for_file": "Você gostaria de esperar até que o arquivo de rastreamento esteja pronto?",
"waiting_directions": "Aguarde o arquivo de dados de rastreamento. Isto pode tomar algum tempo. Você pode sair da espera e recuperar o arquivo de rastreamento da tabela de comandos mais tarde.",
"waiting_seconds": "Tempo decorrido: {{seconds}} segundos"
},

View File

@@ -62,14 +62,12 @@ const BlinkModal = ({ show, toggleModal }) => {
{ headers },
)
.then(() => {
if (chosenPattern !== 'blink') {
addToast({
title: t('common.success'),
body: t('commands.command_success'),
color: 'success',
autohide: true,
});
}
addToast({
title: t('common.success'),
body: t('commands.command_success'),
color: 'success',
autohide: true,
});
toggleModal();
})
.catch(() => {
@@ -147,10 +145,8 @@ const BlinkModal = ({ show, toggleModal }) => {
</CModalBody>
<CModalFooter>
<LoadingButton
label={t('common.submit')}
isLoadingLabel={
chosenPattern === 'blink' ? 'LEDs are blinking... ' : t('common.loading_ellipsis')
}
label={t('blink.set_leds')}
isLoadingLabel={t('common.loading_ellipsis')}
isLoading={waiting}
action={doAction}
block={false}

View File

@@ -358,7 +358,6 @@ const DeviceCommands = () => {
shape="square"
size="sm"
className="mx-2"
disabled={item.completed === 0}
onClick={() => {
toggleDetails(item);
}}

View File

@@ -37,7 +37,7 @@ const ConfigurationDisplay = ({ getData, deviceConfig }) => {
<CopyToClipboardButton
t={t}
size="sm"
content={JSON.stringify(deviceConfig?.configuration ?? {}, null, 4)}
content={JSON.stringify(deviceConfig?.configuration ?? {})}
/>
</h5>
<CRow>

View File

@@ -1,5 +1,4 @@
import {
CAlert,
CButton,
CModal,
CModalHeader,
@@ -101,14 +100,8 @@ const ConfigureModal = ({ show, toggleModal }) => {
});
toggleModal();
})
.catch((e) => {
.catch(() => {
setResponseBody('Error while submitting command!');
addToast({
title: t('common.error'),
body: `${t('common.general_error')}: ${e.response?.data?.ErrorDescription}`,
color: 'danger',
autohide: true,
});
setHadFailure(true);
})
.finally(() => {
@@ -203,9 +196,11 @@ const ConfigureModal = ({ show, toggleModal }) => {
/>
</CCol>
</CRow>
<CAlert color="danger" hidden={!hadSuccess && !hadFailure}>
{responseBody}
</CAlert>
<div hidden={!hadSuccess && !hadFailure}>
<div>
<pre className="ignore">{responseBody}</pre>
</div>
</div>
</CModalBody>
<CModalFooter>
<div hidden={!checkingIfSure}>Are you sure?</div>

View File

@@ -66,16 +66,7 @@ const DeviceDashboard = ({ t, data, loading }) => (
</CCol>
<CCol>
<CWidgetIcon
text={
<div>
<div className="float-left">{t('common.devices')}</div>
<div className="float-left ml-2">
<CPopover content={t('device.count_explanation')}>
<CIcon content={cilInfo} />
</CPopover>
</div>
</div>
}
text={t('common.devices')}
header={<h2>{data.numberOfDevices}</h2>}
color="primary"
iconPadding={false}
@@ -96,10 +87,7 @@ const DeviceDashboard = ({ t, data, loading }) => (
tooltips: {
callbacks: {
title: (item, ds) => ds.labels[item[0].index],
label: (item, ds) =>
`${ds.datasets[0].data[item.index]} devices, (${
data.statusDevices[ds.datasets[0].data[item.index]]
}%)`,
label: (item, ds) => `${ds.datasets[0].data[item.index]}%`,
},
},
legend: {
@@ -132,9 +120,7 @@ const DeviceDashboard = ({ t, data, loading }) => (
callbacks: {
title: (item, ds) => ds.labels[item[0].index],
label: (item, ds) =>
`${ds.datasets[0].data[item.index]} connected devices (${
data.healthDevices[ds.datasets[0].data[item.index]]
}%)`,
`${ds.datasets[0].data[item.index]}${t('common.of_connected')}`,
},
},
legend: {
@@ -163,9 +149,9 @@ const DeviceDashboard = ({ t, data, loading }) => (
callbacks: {
title: (item, ds) => ds.labels[item[0].index],
label: (item, ds) =>
`${ds.datasets[0].data[item.index]} associations (${
data.associationData[ds.datasets[0].data[item.index]]
}%)`,
`${ds.datasets[0].data[item.index]}% of ${
data.totalAssociations
} associations`,
},
},
legend: {
@@ -320,9 +306,7 @@ const DeviceDashboard = ({ t, data, loading }) => (
callbacks: {
title: (item, ds) => ds.labels[item[0].index],
label: (item, ds) =>
`${ds.datasets[0].data[item.index]} connected devices (${
data.certificateData[ds.datasets[0].data[item.index]]
}%)`,
`${ds.datasets[0].data[item.index]}${t('common.of_connected')}`,
},
},
legend: {

View File

@@ -55,12 +55,9 @@ const DeviceDashboard = () => {
const statusColors = [];
const statusLabels = [];
let totalDevices = parsedData.status.reduce((acc, point) => acc + point.value, 0);
parsedData.numberOfDevices = totalDevices;
parsedData.statusDevices = {};
for (const point of parsedData.status) {
statusDs.push(point.value);
statusDs.push(Math.round((point.value / totalDevices) * 100));
statusLabels.push(point.tag);
parsedData.statusDevices[point.value] = Math.round((point.value / totalDevices) * 100);
let color = '';
switch (point.tag) {
case 'connected':
@@ -99,7 +96,7 @@ const DeviceDashboard = () => {
const healthLabels = [];
totalDevices = parsedData.healths.reduce((acc, point) => acc + point.value, 0);
for (const point of parsedData.healths) {
healthDs.push(point.value);
healthDs.push(Math.round((point.value / totalDevices) * 100));
healthLabels.push(point.tag);
let color = '';
switch (point.tag) {
@@ -125,12 +122,6 @@ const DeviceDashboard = () => {
}
healthColors.push(color);
}
parsedData.healthDevices = {
[devicesAt100]: Math.round((devicesAt100 / totalDevices) * 100),
[devicesUp90]: Math.round((devicesUp90 / totalDevices) * 100),
[devicesUp60]: Math.round((devicesUp60 / totalDevices) * 100),
[devicesDown60]: Math.round((devicesDown60 / totalDevices) * 100),
};
parsedData.healths = {
datasets: [
{
@@ -153,12 +144,10 @@ const DeviceDashboard = () => {
const associationsColors = [];
const associationsLabels = [];
const totalAssociations = parsedData.associations.reduce((acc, point) => acc + point.value, 0);
parsedData.associationData = {};
for (let i = 0; i < parsedData.associations.length; i += 1) {
const point = parsedData.associations[i];
associationsDs.push(point.value);
associationsDs.push(Math.round((point.value / totalAssociations) * 100));
associationsLabels.push(point.tag);
parsedData.associationData[point.value] = Math.round((point.value / totalAssociations) * 100);
switch (parsedData.associations[i].tag) {
case '2G':
@@ -269,10 +258,8 @@ const DeviceDashboard = () => {
const certificatesColors = [];
const certificatesLabels = [];
const totalCerts = parsedData.certificates.reduce((acc, point) => acc + point.value, 0);
parsedData.certificateData = {};
for (const point of parsedData.certificates) {
certificatesDs.push(point.value);
parsedData.certificateData[point.value] = Math.round((point.value / totalCerts) * 100);
certificatesDs.push(Math.round((point.value / totalCerts) * 100));
certificatesLabels.push(point.tag);
let color = '';
switch (point.tag) {

View File

@@ -4,7 +4,6 @@ import PropTypes from 'prop-types';
import { useAuth, useToast, useToggle } from 'ucentral-libs';
import axiosInstance from 'utils/axiosInstance';
import { useTranslation } from 'react-i18next';
import { useGlobalWebSocket } from 'contexts/WebSocketProvider';
import Modal from './Modal';
const DeviceFirmwareModal = ({
@@ -20,7 +19,6 @@ const DeviceFirmwareModal = ({
const [loading, setLoading] = useState(false);
const [firmwareVersions, setFirmwareVersions] = useState([]);
const [keepRedirector, toggleKeepRedirector, setKeepRedirector] = useToggle(true);
const { addDeviceListener } = useGlobalWebSocket();
const getPartialFirmware = async (offset) => {
const headers = {
@@ -92,17 +90,6 @@ const DeviceFirmwareModal = ({
headers,
})
.then((response) => {
addDeviceListener({
serialNumber: device.serialNumber,
types: ['device_firmware_upgrade'],
addToast: (title, body) =>
addToast({
title,
body,
color: 'info',
autohide: true,
}),
});
setUpgradeStatus({
loading: false,
result: {

View File

@@ -27,7 +27,6 @@ import ReactTooltip from 'react-tooltip';
import { v4 as createUuid } from 'uuid';
import { cleanBytesString } from 'utils/helper';
import { DeviceBadge, LoadingButton } from 'ucentral-libs';
import ReactCountryFlag from 'react-country-flag';
import styles from './index.module.scss';
const DeviceListTable = ({
@@ -325,18 +324,11 @@ const DeviceListTable = ({
ipAddress: (item) => (
<td className="align-middle">
<CPopover
content={`${item.locale !== '' ? `${item.locale} - ` : ''}${item.ipAddress}`}
content={item.ipAddress ? item.ipAddress : t('common.na')}
placement="top"
>
<div style={{ width: 'calc(8vw)' }} className="text-truncate align-middle">
{item.locale !== '' && item.ipAddress !== '' && (
<ReactCountryFlag
style={{ width: '24px', height: '24px' }}
countryCode={item?.locale}
svg
/>
)}
{` ${item.ipAddress}`}
{item.ipAddress}
</div>
</CPopover>
</td>
@@ -414,8 +406,6 @@ const DeviceListTable = ({
nextClassName="page-item"
nextLinkClassName="page-link"
activeClassName="active"
pageRangeDisplayed={5}
marginPagesDisplayed={1}
/>
</div>
<p className="pr-2 mt-1">{t('common.items_per_page')}</p>

View File

@@ -6,7 +6,6 @@ import { getItem, setItem } from 'utils/localStorageHelper';
import DeviceSearchBar from 'components/DeviceSearchBar';
import DeviceFirmwareModal from 'components/DeviceFirmwareModal';
import FirmwareHistoryModal from 'components/FirmwareHistoryModal';
import { useGlobalWebSocket } from 'contexts/WebSocketProvider';
import { useAuth, useToast } from 'ucentral-libs';
import Table from './Table';
import meshIcon from '../../assets/icons/Mesh.png';
@@ -18,10 +17,8 @@ const DeviceList = () => {
const { t } = useTranslation();
const { addToast } = useToast();
const history = useHistory();
const [overrides, setOverrides] = useState({});
const [page, setPage] = useState(parseInt(sessionStorage.getItem('deviceTable') ?? 0, 10));
const { currentToken, endpoints } = useAuth();
const [deviceToRefresh, setDeviceToRefresh] = useState(undefined);
const [upgradeStatus, setUpgradeStatus] = useState({
loading: false,
});
@@ -39,7 +36,6 @@ const DeviceList = () => {
deviceType: '',
serialNumber: '',
});
const { lastMessage } = useGlobalWebSocket();
const deviceIcons = {
meshIcon,
@@ -60,7 +56,6 @@ const DeviceList = () => {
const getDeviceInformation = (selectedPage = page, devicePerPage = devicesPerPage) => {
setLoading(true);
setOverrides({});
const options = {
headers: {
@@ -360,31 +355,10 @@ const DeviceList = () => {
});
};
const displayDevices = () =>
devices.map((device) => ({
...device,
connected:
overrides[device.serialNumber] !== undefined
? overrides[device.serialNumber]
: device.connected,
}));
useEffect(() => {
getCount();
}, []);
useEffect(() => {
if (deviceToRefresh) refreshDevice(deviceToRefresh.serial);
}, [deviceToRefresh?.timestamp]);
useEffect(() => {
if (lastMessage && lastMessage.type === 'DEVICE') {
const { serialNumber: msgSerial, timestamp } = lastMessage;
if (timestamp !== deviceToRefresh?.timestamp)
setDeviceToRefresh({ serial: msgSerial, timestamp });
}
}, [lastMessage, deviceToRefresh]);
useEffect(() => {
if (upgradeStatus.result !== undefined) {
addToast({
@@ -408,7 +382,7 @@ const DeviceList = () => {
currentPage={page}
t={t}
searchBar={<DeviceSearchBar />}
devices={displayDevices()}
devices={devices}
loading={loading}
updateDevicesPerPage={updateDevicesPerPage}
devicesPerPage={devicesPerPage}

View File

@@ -3,7 +3,7 @@ import PropTypes from 'prop-types';
import { useTranslation } from 'react-i18next';
import { useHistory } from 'react-router-dom';
import { useAuth, DeviceSearchBar as SearchBar } from 'ucentral-libs';
import { toJson } from 'utils/helper';
import { checkIfJson } from 'utils/helper';
const DeviceSearchBar = ({ action }) => {
const { t } = useTranslation();
@@ -44,9 +44,11 @@ const DeviceSearchBar = ({ action }) => {
};
socket.onmessage = (event) => {
const result = toJson(event.data);
if (result && result.serialNumbers) {
setResults(result.serialNumbers);
if (checkIfJson(event.data)) {
const result = JSON.parse(event.data);
if (result.command === 'serial_number_search' && result.serialNumbers) {
setResults(result.serialNumbers);
}
}
};

View File

@@ -65,16 +65,7 @@ const FirmwareDashboard = ({ t, data, loading }) => {
</CCol>
<CCol>
<CWidgetIcon
text={
<div>
<div className="float-left">{t('common.devices')}</div>
<div className="float-left ml-2">
<CPopover content={t('device.firmware_count_explanation')}>
<CIcon content={cilInfo} />
</CPopover>
</div>
</div>
}
text={t('common.devices')}
header={<h2>{data.numberOfDevices}</h2>}
color="primary"
iconPadding={false}
@@ -221,7 +212,7 @@ const FirmwareDashboard = ({ t, data, loading }) => {
tooltips: {
callbacks: {
title: (item, ds) => ds.labels[item[0].index],
label: (item, ds) => `${ds.datasets[0].data[item.index]} devices`,
label: (item, ds) => `${ds.datasets[0].data[item.index]}%`,
},
},
legend: {

View File

@@ -65,12 +65,9 @@ const FirmwareDashboard = () => {
const statusColors = [];
const statusLabels = [];
const totalDevices = parsedData.status.reduce((acc, point) => acc + point.value, 0);
parsedData.statusDevices = {};
parsedData.numberOfDevices = totalDevices;
for (const point of parsedData.status) {
statusDs.push(point.value);
statusDs.push(Math.round((point.value / totalDevices) * 100));
statusLabels.push(point.tag);
parsedData[point.value] = point.value;
let color = '';
switch (point.tag) {
case 'connected':

View File

@@ -5,7 +5,7 @@ import { cilX } from '@coreui/icons';
import PropTypes from 'prop-types';
import { useTranslation } from 'react-i18next';
import axiosInstance from 'utils/axiosInstance';
import { useAuth, useDevice, CopyToClipboardButton } from 'ucentral-libs';
import { useAuth, useDevice } from 'ucentral-libs';
const LatestStatisticsModal = ({ show, toggle }) => {
const { t } = useTranslation();
@@ -51,13 +51,6 @@ const LatestStatisticsModal = ({ show, toggle }) => {
</div>
</CModalHeader>
<CModalBody>
<div style={{ textAlign: 'right' }}>
<CopyToClipboardButton
t={t}
size="lg"
content={JSON.stringify(latestStats ?? {}, null, 4)}
/>
</div>
<pre className="ignore">{JSON.stringify(latestStats, null, 2)}</pre>
</CModalBody>
</CModal>

View File

@@ -4,7 +4,7 @@ import { CSpinner } from '@coreui/react';
import { useTranslation } from 'react-i18next';
import { v4 as createUuid } from 'uuid';
import axiosInstance from 'utils/axiosInstance';
import { useAuth } from 'ucentral-libs';
import { useAuth, useDevice } from 'ucentral-libs';
import {
capitalizeFirstLetter,
datesSameDay,
@@ -14,10 +14,11 @@ import {
} from 'utils/helper';
import DeviceStatisticsChart from './DeviceStatisticsChart';
const StatisticsChartList = ({ deviceSerialNumber, setOptions, section, time }) => {
const StatisticsChartList = ({ setOptions, section, setStart, setEnd, time }) => {
const { t } = useTranslation();
const [loading, setLoading] = useState(false);
const { currentToken, endpoints } = useAuth();
const { deviceSerialNumber } = useDevice();
const [statOptions, setStatOptions] = useState({
interfaceList: [],
memory: [],
@@ -123,27 +124,50 @@ const StatisticsChartList = ({ deviceSerialNumber, setOptions, section, time })
}
// Looping through all the data
const prevTxObj = {};
const prevRxObj = {};
let prevTx = 0;
let prevRx = 0;
for (const log of sortedData) {
// Looping through the interfaces of the log
const version = log.data.version ?? 0;
for (const inter of log.data.interfaces) {
if (version > 0) {
const prevTx = prevTxObj[inter.name] !== undefined ? prevTxObj[inter.name] : 0;
const prevRx = prevTxObj[inter.name] !== undefined ? prevRxObj[inter.name] : 0;
const tx = inter.counters ? Math.floor(inter.counters.tx_bytes / 1024) : 0;
const rx = inter.counters ? Math.floor(inter.counters.rx_bytes / 1024) : 0;
interfaceList[interfaceTypes[inter.name]][0].data.push(Math.max(0, tx - prevTx));
interfaceList[interfaceTypes[inter.name]][1].data.push(Math.max(0, rx - prevRx));
prevTxObj[inter.name] = tx;
prevRxObj[inter.name] = rx;
if (inter.ssids?.length > 0) {
let totalTx = 0;
let totalRx = 0;
for (const ssid of inter.ssids) {
if (ssid.associations) {
for (const assoc of ssid.associations) {
if (version === 0) {
if (assoc.deltas) {
totalTx += assoc.deltas?.tx_bytes ?? 0;
totalRx += assoc.deltas?.rx_bytes ?? 0;
} else {
totalTx += assoc.tx_bytes ?? 0;
totalRx += assoc.rx_bytes ?? 0;
}
} else {
totalTx += assoc.tx_bytes ?? 0;
totalRx += assoc.rx_bytes ?? 0;
}
}
}
}
if (version > 0) {
const tx = Math.floor(totalTx / 1024);
const rx = Math.floor(totalRx / 1024);
interfaceList[interfaceTypes[inter.name]][0].data.push(Math.max(tx - prevTx, 0));
interfaceList[interfaceTypes[inter.name]][1].data.push(Math.max(rx - prevRx, 0));
prevTx = tx;
prevRx = rx;
} else {
interfaceList[interfaceTypes[inter.name]][0].data.push(Math.floor(totalTx / 1024));
interfaceList[interfaceTypes[inter.name]][1].data.push(Math.floor(totalRx / 1024));
}
} else {
interfaceList[interfaceTypes[inter.name]][0].data.push(
inter.counters ? Math.floor(inter.counters.tx_bytes / 1024) : 0,
inter.counters ? Math.floor(inter.counters.tx_bytes) : 0,
);
interfaceList[interfaceTypes[inter.name]][1].data.push(
inter.counters ? Math.floor(inter.counters.rx_bytes / 1024) : 0,
inter.counters ? Math.floor(inter.counters.rx_bytes) : 0,
);
}
}
@@ -243,6 +267,10 @@ const StatisticsChartList = ({ deviceSerialNumber, setOptions, section, time })
}));
setOptions([...sectionOptions, { value: 'memory', label: t('statistics.memory') }]);
setStatOptions({ ...newOptions });
if (sortedData.length > 0) {
setStart(new Date(sortedData[0].recorded * 1000));
setEnd(new Date(sortedData[sortedData.length - 1].recorded * 1000));
}
}
};
@@ -353,10 +381,11 @@ const StatisticsChartList = ({ deviceSerialNumber, setOptions, section, time })
};
StatisticsChartList.propTypes = {
deviceSerialNumber: PropTypes.string.isRequired,
setOptions: PropTypes.func.isRequired,
section: PropTypes.string.isRequired,
time: PropTypes.instanceOf(Object).isRequired,
setStart: PropTypes.func.isRequired,
setEnd: PropTypes.func.isRequired,
};
export default React.memo(StatisticsChartList);

View File

@@ -12,98 +12,55 @@ import {
} from '@coreui/react';
import DatePicker from 'react-widgets/DatePicker';
import { cilSync } from '@coreui/icons';
import { useDevice } from 'ucentral-libs';
import CIcon from '@coreui/icons-react';
import { useGlobalWebSocket } from 'contexts/WebSocketProvider';
import StatisticsChartList from './StatisticsChartList';
import LatestStatisticsmodal from './LatestStatisticsModal';
const getStart = () => {
const date = new Date();
date.setHours(date.getHours() - 1);
return date;
};
const DeviceStatisticsCard = () => {
const { t } = useTranslation();
const [showLatestModal, setShowLatestModal] = useState(false);
const [options, setOptions] = useState([]);
const [section, setSection] = useState('');
const [start, setStart] = useState(null);
const [startError, setStartError] = useState(false);
const [end, setEnd] = useState(null);
const [endError, setEndError] = useState(false);
const { deviceSerialNumber } = useDevice();
const [nextUpdate, setNextUpdate] = useState(undefined);
const { addDeviceListener, removeDeviceListener } = useGlobalWebSocket();
const [time, setTime] = useState({
refreshId: '0',
start: getStart(),
end: new Date().toISOString(),
});
const [time, setTime] = useState({ refreshId: '0', start: null, end: null });
const toggleLatestModal = () => {
setShowLatestModal(!showLatestModal);
};
const modifyStart = (value, refresh = true) => {
const modifyStart = (value) => {
try {
new Date(value).toISOString();
setStartError(false);
if (refresh) setTime({ ...time, refreshId: createUuid(), start: value, isChosen: true });
else setTime({ ...time, start: value, isChosen: true });
setStart(value);
} catch (e) {
setStart('');
setStartError(true);
}
};
const modifyEnd = (value, refresh = true) => {
const modifyEnd = (value) => {
try {
new Date(value).toISOString();
setEndError(false);
if (refresh) setTime({ ...time, refreshId: createUuid(), end: value, isChosen: true });
else setTime({ ...time, end: value, isChosen: true });
setEnd(value);
} catch (e) {
setEnd('');
setEndError(true);
}
};
const refresh = () => {
setTime({ refreshId: createUuid(), start: getStart(), end: new Date().toISOString() });
};
const handleRefreshClick = () => {
refresh();
setTime({ refreshId: createUuid(), start, end });
};
useEffect(() => {
if (section === '' && options.length > 0) setSection(options[0].value);
}, [options]);
useEffect(() => {
if (nextUpdate && !time.isChosen) {
setTime({ refreshId: createUuid(), start: getStart(), end: new Date().toISOString() });
setNextUpdate(undefined);
}
}, [nextUpdate, time]);
useEffect(() => {
setNextUpdate(undefined);
if (deviceSerialNumber) {
addDeviceListener({
serialNumber: deviceSerialNumber,
types: ['device_statistics'],
onTrigger: () => setNextUpdate(1),
});
refresh();
}
return () => {
if (deviceSerialNumber) {
removeDeviceListener({
serialNumber: deviceSerialNumber,
});
}
};
}, [deviceSerialNumber]);
return (
<div>
<CCard className="m-0">
@@ -111,12 +68,7 @@ const DeviceStatisticsCard = () => {
<div className="d-flex flex-row-reverse align-items-center">
<div className="pl-2">
<CPopover content={t('common.refresh')}>
<CButton
size="sm"
color="info"
onClick={handleRefreshClick}
disabled={startError || endError}
>
<CButton size="sm" color="info" onClick={refresh} disabled={startError || endError}>
<CIcon content={cilSync} />
</CButton>
</CPopover>
@@ -125,7 +77,7 @@ const DeviceStatisticsCard = () => {
<DatePicker
includeTime
onChange={(date) => modifyEnd(date)}
value={time.end ? new Date(time.end) : undefined}
value={end ? new Date(end) : undefined}
/>
<CFormText color="danger" hidden={!endError}>
{t('common.invalid_date_explanation')}
@@ -136,7 +88,7 @@ const DeviceStatisticsCard = () => {
<DatePicker
includeTime
onChange={(date) => modifyStart(date)}
value={time.start ? new Date(time.start) : undefined}
value={start ? new Date(start) : undefined}
/>
<CFormText color="danger" hidden={!startError}>
{t('common.invalid_date_explanation')}
@@ -166,10 +118,11 @@ const DeviceStatisticsCard = () => {
</CCardHeader>
<CCardBody className="p-1">
<StatisticsChartList
deviceSerialNumber={deviceSerialNumber}
setOptions={setOptions}
section={section}
time={time}
setStart={setStart}
setEnd={setEnd}
/>
</CCardBody>
</CCard>

View File

@@ -22,13 +22,11 @@ import axiosInstance from 'utils/axiosInstance';
import eventBus from 'utils/eventBus';
import { LoadingButton, useAuth, useDevice, useToast } from 'ucentral-libs';
import SuccessfulActionModalBody from 'components/SuccessfulActionModalBody';
import { useGlobalWebSocket } from 'contexts/WebSocketProvider';
const ActionModal = ({ show, toggleModal }) => {
const { t } = useTranslation();
const { currentToken, endpoints } = useAuth();
const { deviceSerialNumber } = useDevice();
const { addDeviceListener } = useGlobalWebSocket();
const { addToast } = useToast();
const [waiting, setWaiting] = useState(false);
const [result, setResult] = useState(null);
@@ -76,16 +74,11 @@ const ActionModal = ({ show, toggleModal }) => {
{ headers },
)
.then(() => {
addDeviceListener({
serialNumber: deviceSerialNumber,
types: ['device_connection', 'device_disconnection'],
addToast: (title, body) =>
addToast({
title,
body,
color: 'info',
autohide: true,
}),
addToast({
title: t('common.success'),
body: t('commands.command_success'),
color: 'success',
autohide: true,
});
toggleModal();
})

View File

@@ -12,9 +12,6 @@ import {
CRow,
CCol,
CInput,
CFormGroup,
CInputRadio,
CLabel,
CSpinner,
CAlert,
} from '@coreui/react';
@@ -39,14 +36,11 @@ const TelemetryModal = ({ show, toggle }) => {
const [lastMessage, setLastMessage] = useState({});
const [receivedMessages, setReceivedMessages] = useState(0);
const [types, setTypes] = useState([]);
const [chosenMethod, setChosenMethod] = useState('false');
const [lifetime, setLifetime] = useState(5);
const [interval, setInterval] = useState(3);
const [loading, setLoading] = useState(false);
const [lastUpdate, setLastUpdate] = useState('');
const onIntervalChange = (e) => setInterval(e.target.value);
const onLifetimeChange = (e) => setLifetime(e.target.value);
const closeSocket = () => {
if (socket !== null) {
@@ -63,8 +57,6 @@ const TelemetryModal = ({ show, toggle }) => {
const parameters = {
serialNumber: deviceSerialNumber,
interval: parseInt(interval, 10),
lifetime: parseInt(lifetime * 60, 10),
kafka: chosenMethod,
types: types.map((type) => type.value),
};
@@ -80,16 +72,7 @@ const TelemetryModal = ({ show, toggle }) => {
{ headers },
)
.then((response) => {
if (chosenMethod === 'true') {
addToast({
title: t('common.success'),
body: t('commands.command_success'),
color: 'success',
autohide: true,
});
toggle();
}
else if (response.data.uri && response.data.uri !== '') {
if (response.data.uri && response.data.uri !== '') {
setReceivedMessages(0);
setSocket(new WebSocket(response.data.uri));
}
@@ -163,50 +146,6 @@ const TelemetryModal = ({ show, toggle }) => {
/>
</CCol>
</CRow>
<CRow>
<CCol>{`${t('telemetry.lifetime')}: ${lifetime} ${t('common.minutes')}`}</CCol>
</CRow>
<CRow>
<CCol>
<CInput
type="range"
min="1"
max="120"
step="1"
onChange={onLifetimeChange}
value={lifetime}
/>
</CCol>
</CRow>
<CFormGroup row className="mb-0">
<CCol md="3">
<CLabel>{t('telemetry.outputmode')}</CLabel>
</CCol>
<CCol>
<CFormGroup variant="checkbox" onClick={() => setChosenMethod('false')} inline>
<CInputRadio
defaultChecked={chosenMethod === 'false'}
id="traceRadio1"
name="radios"
value="traceOption1"
/>
<CLabel variant="checkbox" htmlFor="traceRadio1">
Websocket
</CLabel>
</CFormGroup>
<CFormGroup variant="checkbox" onClick={() => setChosenMethod('true')} inline>
<CInputRadio
defaultChecked={chosenMethod === 'true'}
id="traceRadio2"
name="radios"
value="traceOption2"
/>
<CLabel variant="checkbox" htmlFor="traceRadio2">
Kafka
</CLabel>
</CFormGroup>
</CCol>
</CFormGroup>
<CRow>
<CCol sm="2" className="pt-2">
{t('telemetry.types')}:
@@ -239,11 +178,6 @@ const TelemetryModal = ({ show, toggle }) => {
{t('telemetry.interval')}: {interval} {t('common.seconds')}
</CCol>
</CRow>
<CRow>
<CCol>
{t('telemetry.lifetime')}: {lifetime} {t('common.minutes')}
</CCol>
</CRow>
<CRow>
<CCol>
{t('telemetry.types')}: {types.map((type) => type.label).join(', ')}

View File

@@ -40,7 +40,7 @@ const TraceModal = ({ show, toggleModal }) => {
const [responseBody, setResponseBody] = useState('');
const [chosenInterface, setChosenInterface] = useState('up');
const [isDeviceConnected, setIsDeviceConnected] = useState(false);
const [waitForTrace, setWaitForTrace] = useState(true);
const [waitForTrace, setWaitForTrace] = useState(false);
const [waitingForTrace, setWaitingForTrace] = useState(false);
const [commandUuid, setCommandUuid] = useState(null);
@@ -49,7 +49,7 @@ const TraceModal = ({ show, toggleModal }) => {
};
useEffect(() => {
setWaitForTrace(true);
setWaitForTrace(false);
setHadSuccess(false);
setHadFailure(false);
setResponseBody('');
@@ -137,19 +137,25 @@ const TraceModal = ({ show, toggleModal }) => {
<CModalBody>
<h6>{t('trace.directions')}</h6>
<CRow className="mt-3">
<CCol md="4" className="pt-2">
{t('contact.type')}
</CCol>
<CCol xs="12" md="8">
<CSelect
custom
value={usingDuration ? 'duration' : 'packets'}
<CCol>
<CButton
disabled={blockFields}
onChange={(e) => setUsingDuration(e.target.value === 'duration')}
block
color="primary"
onClick={() => setUsingDuration(true)}
>
<option value="duration">{t('common.duration')}</option>
<option value="packets">{t('trace.packets')}</option>
</CSelect>
{t('common.duration')}
</CButton>
</CCol>
<CCol>
<CButton
disabled={blockFields}
block
color="primary"
onClick={() => setUsingDuration(false)}
>
{t('trace.packets')}
</CButton>
</CCol>
</CRow>
<CRow className="mt-3">
@@ -214,7 +220,7 @@ const TraceModal = ({ show, toggleModal }) => {
</CCol>
</CRow>
<CRow className="mt-3" hidden={!isDeviceConnected}>
<CCol md="7">
<CCol md="8">
<p>{t('trace.wait_for_file')}</p>
</CCol>
<CCol>

View File

@@ -49,7 +49,7 @@ const WifiAnalysis = () => {
const secondsToLabel = (seconds) =>
compactSecondsToDetailed(seconds, t('common.day'), t('common.days'), t('common.seconds'));
const extractIp = (json, station) => {
const extractIp = (json, bssid) => {
const ips = {
ipV4: [],
ipV6: [],
@@ -57,7 +57,7 @@ const WifiAnalysis = () => {
for (const obj of json.interfaces) {
if ('clients' in obj) {
for (const client of obj.clients) {
if (client.mac === station) {
if (client.mac === bssid) {
ips.ipV4 = ips.ipV4.concat(client.ipv4_addresses ?? []);
ips.ipV6 = ips.ipV6.concat(client.ipv6_addresses ?? []);
}
@@ -151,7 +151,7 @@ const WifiAnalysis = () => {
const data = {
radio: radioInfo,
...extractIp(stat.data, association.station),
...extractIp(stat.data, association.bssid),
station: association.station,
ssid: ssid.ssid,
rssi: association.rssi ? parseDbm(association.rssi) : '-',

View File

@@ -1,187 +0,0 @@
{
"SSID": 0,
"SUPP_RATES": 1,
"FH_PARAMS": 2,
"DS_PARAMS": 3,
"CF_PARAMS": 4,
"TIM": 5,
"IBSS_PARAMS": 6,
"COUNTRY": 7,
"REQUEST": 10,
"QBSS_LOAD": 11,
"EDCA_PARAM_SET": 12,
"TSPEC": 13,
"TCLAS": 14,
"SCHEDULE": 15,
"CHALLENGE": 16,
"PWR_CONSTRAINT": 32,
"PWR_CAPABILITY": 33,
"TPC_REQUEST": 34,
"TPC_REPORT": 35,
"SUPPORTED_CHANNELS": 36,
"CHANNEL_SWITCH": 37,
"MEASURE_REQUEST": 38,
"MEASURE_REPORT": 39,
"QUIET": 40,
"IBSS_DFS": 41,
"ERP_INFO": 42,
"TS_DELAY": 43,
"TCLAS_PROCESSING": 44,
"HT_CAPABILITY": 45,
"QOS_CAPA": 46,
"RSN": 48,
"802_15_COEX": 49,
"EXT_SUPP_RATES": 50,
"AP_CHAN_REPORT": 51,
"NEIGHBOR_REPORT": 52,
"RCPI": 53,
"MOBILITY_DOMAIN": 54,
"FAST_BSS_TRANSITION": 55,
"TIMEOUT_INTERVAL": 56,
"RIC_DATA": 57,
"DSE_REGISTERED_LOCATION": 58,
"SUPPORTED_REGULATORY_CLASSES": 59,
"EXT_CHANSWITCH_ANN": 60,
"HT_OPERATION": 61,
"SECONDARY_CHANNEL_OFFSET": 62,
"BSS_AVG_ACCESS_DELAY": 63,
"ANTENNA_INFO": 64,
"RSNI": 65,
"MEASUREMENT_PILOT_TX_INFO": 66,
"BSS_AVAILABLE_CAPACITY": 67,
"BSS_AC_ACCESS_DELAY": 68,
"TIME_ADVERTISEMENT": 69,
"RRM_ENABLED_CAPABILITIES": 70,
"MULTIPLE_BSSID": 71,
"BSS_COEX_2040": 72,
"BSS_INTOLERANT_CHL_REPORT": 73,
"OVERLAP_BSS_SCAN_PARAM": 74,
"RIC_DESCRIPTOR": 75,
"MMIE": 76,
"ASSOC_COMEBACK_TIME": 77,
"EVENT_REQUEST": 78,
"EVENT_REPORT": 79,
"DIAGNOSTIC_REQUEST": 80,
"DIAGNOSTIC_REPORT": 81,
"LOCATION_PARAMS": 82,
"NON_TX_BSSID_CAP": 83,
"SSID_LIST": 84,
"MULTI_BSSID_IDX": 85,
"FMS_DESCRIPTOR": 86,
"FMS_REQUEST": 87,
"FMS_RESPONSE": 88,
"QOS_TRAFFIC_CAPA": 89,
"BSS_MAX_IDLE_PERIOD": 90,
"TSF_REQUEST": 91,
"TSF_RESPOSNE": 92,
"WNM_SLEEP_MODE": 93,
"TIM_BCAST_REQ": 94,
"TIM_BCAST_RESP": 95,
"COLL_IF_REPORT": 96,
"CHANNEL_USAGE": 97,
"TIME_ZONE": 98,
"DMS_REQUEST": 99,
"DMS_RESPONSE": 100,
"LINK_ID": 101,
"WAKEUP_SCHEDUL": 102,
"CHAN_SWITCH_TIMING": 104,
"PTI_CONTROL": 105,
"PU_BUFFER_STATUS": 106,
"INTERWORKING": 107,
"ADVERTISEMENT_PROTOCOL": 108,
"EXPEDITED_BW_REQ": 109,
"QOS_MAP_SET": 110,
"ROAMING_CONSORTIUM": 111,
"EMERGENCY_ALERT": 112,
"MESH_CONFIG": 113,
"MESH_ID": 114,
"LINK_METRIC_REPORT": 115,
"CONGESTION_NOTIFICATION": 116,
"PEER_MGMT": 117,
"CHAN_SWITCH_PARAM": 118,
"MESH_AWAKE_WINDOW": 119,
"BEACON_TIMING": 120,
"MCCAOP_SETUP_REQ": 121,
"MCCAOP_SETUP_RESP": 122,
"MCCAOP_ADVERT": 123,
"MCCAOP_TEARDOWN": 124,
"GANN": 125,
"RANN": 126,
"EXT_CAPABILITY": 127,
"PREQ": 130,
"PREP": 131,
"PERR": 132,
"PXU": 137,
"PXUC": 138,
"AUTH_MESH_PEER_EXCH": 139,
"MIC": 140,
"DESTINATION_URI": 141,
"UAPSD_COEX": 142,
"WAKEUP_SCHEDULE": 143,
"EXT_SCHEDULE": 144,
"STA_AVAILABILITY": 145,
"DMG_TSPEC": 146,
"DMG_AT": 147,
"DMG_CAP": 148,
"CISCO_VENDOR_SPECIFIC": 150,
"DMG_OPERATION": 151,
"DMG_BSS_PARAM_CHANGE": 152,
"DMG_BEAM_REFINEMENT": 153,
"CHANNEL_MEASURE_FEEDBACK": 154,
"AWAKE_WINDOW": 157,
"MULTI_BAND": 158,
"ADDBA_EXT": 159,
"NEXT_PCP_LIST": 160,
"PCP_HANDOVER": 161,
"DMG_LINK_MARGIN": 162,
"SWITCHING_STREAM": 163,
"SESSION_TRANSITION": 164,
"DYN_TONE_PAIRING_REPORT": 165,
"CLUSTER_REPORT": 166,
"RELAY_CAP": 167,
"RELAY_XFER_PARAM_SET": 168,
"BEAM_LINK_MAINT": 169,
"MULTIPLE_MAC_ADDR": 170,
"U_PID": 171,
"DMG_LINK_ADAPT_ACK": 172,
"MCCAOP_ADV_OVERVIEW": 174,
"QUIET_PERIOD_REQ": 175,
"QUIET_PERIOD_RESP": 177,
"EPAC_POLICY": 182,
"CLISTER_TIME_OFF": 183,
"INTER_AC_PRIO": 184,
"SCS_DESCRIPTOR": 185,
"QLOAD_REPORT": 186,
"HCCA_TXOP_UPDATE_COUNT": 187,
"HL_STREAM_ID": 188,
"GCR_GROUP_ADDR": 189,
"ANTENNA_SECTOR_ID_PATTERN": 190,
"VHT_CAPABILITY": 191,
"VHT_OPERATION": 192,
"EXTENDED_BSS_LOAD": 193,
"WIDE_BW_CHANNEL_SWITCH": 194,
"TX_POWER_ENVELOPE": 195,
"CHANNEL_SWITCH_WRAPPER": 196,
"AID": 197,
"QUIET_CHANNEL": 198,
"OPMODE_NOTIF": 199,
"REDUCED_NEIGHBOR_REPORT": 201,
"AID_REQUEST": 210,
"AID_RESPONSE": 211,
"S1G_BCN_COMPAT": 213,
"S1G_SHORT_BCN_INTERVAL": 214,
"S1G_TWT": 216,
"S1G_CAPABILITIES": 217,
"VENDOR_SPECIFIC": 221,
"QOS_PARAMETER": 222,
"S1G_OPERATION": 232,
"CAG_NUMBER": 237,
"AP_CSN": 239,
"FILS_INDICATION": 240,
"DILS": 241,
"FRAGMENT": 242,
"RSNX": 244,
"EXTENSION": 255
}

View File

@@ -6,11 +6,11 @@ import {
CModalTitle,
CModalBody,
CRow,
CForm,
CSwitch,
CCol,
CSpinner,
CPopover,
CSelect,
} from '@coreui/react';
import CIcon from '@coreui/icons-react';
import { cilCloudDownload, cilGauge, cilX } from '@coreui/icons';
@@ -24,32 +24,16 @@ import { useAuth, useDevice } from 'ucentral-libs';
import WifiChannelTable from 'components/WifiScanResultModal/WifiChannelTable';
import 'react-widgets/styles.css';
import { CSVLink } from 'react-csv';
import Select from 'react-select';
import IeDisplay from 'components/WifiScanResultModal/IeDisplay';
import IE_OPTIONS from './IE_OPTIONS.json';
const getIeOptions = () => {
const arr = [];
for (const [key, value] of Object.entries(IE_OPTIONS)) {
arr.push({
label: `${key} (${value})`,
value,
});
}
return arr;
};
const WifiScanModal = ({ show, toggleModal }) => {
const { t } = useTranslation();
const { currentToken, endpoints } = useAuth();
const { deviceSerialNumber } = useDevice();
const [hadSuccess, setHadSuccess] = useState(false);
const [selectedIes, setSelectedIes] = useState(undefined);
const [ies, setIes] = useState([]);
const [hadFailure, setHadFailure] = useState(false);
const [errorCode, setErrorCode] = useState(0);
const [waiting, setWaiting] = useState(false);
const [dfs, setDfs] = useState(true);
const [bandwidth, setBandwidth] = useState('');
const [activeScan, setActiveScan] = useState(false);
const [hideOptions, setHideOptions] = useState(false);
const [channelList, setChannelList] = useState([]);
@@ -63,26 +47,16 @@ const WifiScanModal = ({ show, toggleModal }) => {
setActiveScan(!activeScan);
};
const onIesChange = (v) => {
if (v.find(({ value }) => value === '*')) {
setIes(getIeOptions());
} else {
setIes(v);
}
};
useEffect(() => {
setHadSuccess(false);
setHadFailure(false);
setWaiting(false);
setChannelList([]);
setCsvData(null);
setBandwidth('');
setDfs(true);
setActiveScan(false);
setHideOptions(false);
setErrorCode(0);
setIes(undefined);
}, [show]);
const parseThroughList = (scanList) => {
@@ -110,7 +84,6 @@ const WifiScanModal = ({ show, toggleModal }) => {
deviceToAdd.SSID = device.meshid && device.meshid.length > 0 ? device.meshid : 'N/A';
}
deviceToAdd.Signal = (dbmNumber - device.signal) * -1;
deviceToAdd.ies = device.ies;
channel.devices.push(deviceToAdd);
}
});
@@ -147,7 +120,7 @@ const WifiScanModal = ({ show, toggleModal }) => {
}
deviceToAdd.Signal = (dbmNumber - device.signal) * -1;
channel.devices.push(deviceToAdd);
listCsv.push({ ...device, ...deviceToAdd, ies: JSON.stringify(device.ies, null, 4) });
listCsv.push({ ...deviceToAdd, ...device });
}
});
});
@@ -162,9 +135,7 @@ const WifiScanModal = ({ show, toggleModal }) => {
const parameters = {
serialNumber: deviceSerialNumber,
override_dfs: dfs,
bandwidth: bandwidth !== '' ? bandwidth : undefined,
activeScan,
ies: ies.length > 0 ? ies.map(({ value }) => value) : undefined,
};
const headers = {
Accept: 'application/json',
@@ -248,13 +219,15 @@ const WifiScanModal = ({ show, toggleModal }) => {
<p className="pl-2">{t('wifi_analysis.override_dfs')}:</p>
</CCol>
<CCol>
<CSwitch
color="primary"
defaultChecked={dfs}
onClick={toggleDfs}
labelOn={t('common.on')}
labelOff={t('common.off')}
/>
<CForm className="pl-4">
<CSwitch
color="primary"
defaultChecked={dfs}
onClick={toggleDfs}
labelOn={t('common.on')}
labelOff={t('common.off')}
/>
</CForm>
</CCol>
</CRow>
<CRow className="mt-3">
@@ -262,48 +235,15 @@ const WifiScanModal = ({ show, toggleModal }) => {
<p className="pl-2">{t('scan.active')}:</p>
</CCol>
<CCol>
<CSwitch
color="primary"
defaultChecked={activeScan}
onClick={toggleActiveScan}
labelOn={t('common.on')}
labelOff={t('common.off')}
/>
</CCol>
</CRow>
<CRow className="mt-3">
<CCol md="3">
<p className="pl-2">Bandwidth:</p>
</CCol>
<CCol>
<CSelect
custom
value={bandwidth}
onChange={(e) => setBandwidth(e.target.value)}
style={{ width: '100px' }}
>
<option value="">Default</option>
<option value="20">20 MHz</option>
<option value="40">40 MHz</option>
<option value="80">80 MHz</option>
</CSelect>
</CCol>
</CRow>
<CRow className="mt-3">
<CCol md="3">
<p className="pl-2">{t('actions.request_ie')}:</p>
</CCol>
<CCol>
<Select
isMulti
closeMenuOnSelect={false}
name="request_ie"
options={[{ label: 'All', value: '*' }, ...getIeOptions()]}
onChange={onIesChange}
value={ies}
className="basic-multi-select"
classNamePrefix="select"
/>
<CForm className="pl-4">
<CSwitch
color="primary"
defaultChecked={activeScan}
onClick={toggleActiveScan}
labelOn={t('common.on')}
labelOff={t('common.off')}
/>
</CForm>
</CCol>
</CRow>
</div>
@@ -332,10 +272,7 @@ const WifiScanModal = ({ show, toggleModal }) => {
</CCol>
</CRow>
)}
{selectedIes && <IeDisplay ies={selectedIes} setIes={setSelectedIes} />}
{selectedIes || channelList === null ? null : (
<WifiChannelTable channels={channelList} setIes={setSelectedIes} />
)}
<WifiChannelTable channels={channelList} />
</div>
</CModalBody>
</CModal>

View File

@@ -1,90 +0,0 @@
import React, { useMemo } from 'react';
import PropTypes from 'prop-types';
import { CButton, CRow, CCol } from '@coreui/react';
import CIcon from '@coreui/icons-react';
import { cilArrowLeft } from '@coreui/icons';
const IeDisplay = ({ ies, setIes }) => {
const handleClick = () => {
setIes(undefined);
};
const display = useMemo(
() =>
ies.map((ie) => {
if (ie.byteArr) {
return (
<CCol sm="6">
<h5
style={{
textDecoration: 'underline',
}}
>
{ie.name}:{' '}
</h5>
<pre>
{ie.byteArr.map((arr, i) => {
const offset = (i * 8).toString(16);
return (
<pre
className="mb-0"
style={{
overflowY: 'auto',
maxHeight: '200px',
}}
>
{offset.length === 1 ? `0${offset}` : offset}: {arr.join(' ')}
</pre>
);
})}
</pre>
</CCol>
);
}
return (
<CCol sm="6">
<h5
style={{
textDecoration: 'underline',
}}
>
{ie.name}:{' '}
</h5>
<pre
style={{
overflowY: 'auto',
maxHeight: '200px',
}}
>
{JSON.stringify(ie.data, null, 4)}
</pre>
</CCol>
);
}),
[ies],
);
return (
<>
<CRow>
<CCol>
<h4>Information Elements</h4>
</CCol>
<CCol className="text-right">
<CButton color="primary" variant="outline" className="ml-2" onClick={handleClick}>
Go Back
<CIcon className="ml-2" content={cilArrowLeft} />
</CButton>
</CCol>
</CRow>
<CRow>{display}</CRow>
</>
);
};
IeDisplay.propTypes = {
ies: PropTypes.instanceOf(Array).isRequired,
setIes: PropTypes.func.isRequired,
};
export default IeDisplay;

View File

@@ -1,18 +1,8 @@
import {
CCard,
CCardTitle,
CCardBody,
CDataTable,
CButton,
CPopover,
CCardHeader,
} from '@coreui/react';
import { CCard, CCardTitle, CCardBody, CDataTable, CCardHeader } from '@coreui/react';
import React from 'react';
import { useTranslation } from 'react-i18next';
import PropTypes from 'prop-types';
import 'react-widgets/styles.css';
import { Buffer } from 'buffer';
import IE_OPTIONS from '../WifiScanModal/IE_OPTIONS.json';
const parseDbm = (value) => {
if (!value) return '-';
@@ -20,66 +10,9 @@ const parseDbm = (value) => {
return 4294967295 + value;
};
const getIeName = (type) => {
for (const [key, value] of Object.entries(IE_OPTIONS)) {
if (value === type) return `${key} (${type})`;
}
return type;
};
const parseIe = ({ name, type, data, content }) => {
try {
if (data) {
const ie = Buffer.from(data, 'base64');
const arr = new Uint16Array(ie);
const finalArr = [];
for (let i = 0; i < arr.length; i += 8) {
const slice = arr.slice(i, i + 8);
finalArr.push(
Object.keys(slice).map((k) => {
const num = slice[k].toString(16);
return num.length === 1 ? `0${num}` : num;
}),
);
}
const finalName = name ? `${name} (${type})` : getIeName(type);
return { name: finalName, byteArr: finalArr };
}
if (content) {
return { name: name ? `${name} (${type})` : getIeName(type), data: content };
}
return { name: name ? `${name} (${type})` : getIeName(type), data: content ?? data };
} catch {
return { name: name ? `${name} (${type}, error while parsing)` : getIeName(type), data };
}
};
const WifiChannelCard = ({ channel, setIes }) => {
const WifiChannelCard = ({ channel }) => {
const { t } = useTranslation();
const columns = [{ key: 'SSID', _style: { width: '70%' } }, { key: 'Signal' }, { key: 'IE' }];
const displayIe = (ies) => {
const parsedIes = ies.map((ie) => parseIe(ie));
const str = ies.map(({ type, data }) => `${type}: ${data}\n`);
return (
<td className="ignore-overflow text-center align-middle">
{str.length > 0 ? (
<CPopover content="View IEs">
<CButton color="primary" size="sm" onClick={() => setIes(parsedIes)}>
{ies.length}
</CButton>
</CPopover>
) : (
ies.length
)}
</td>
);
};
const columns = [{ key: 'SSID', _style: { width: '70%' } }, { key: 'Signal' }];
return (
<CCard>
@@ -96,8 +29,7 @@ const WifiChannelCard = ({ channel, setIes }) => {
fields={columns}
className="text-white"
scopedSlots={{
Signal: (item) => <td className="align-middle">{parseDbm(item.Signal)}</td>,
IE: (item) => displayIe(item.ies),
Signal: (item) => <td>{parseDbm(item.Signal)}</td>,
}}
/>
</div>
@@ -108,7 +40,6 @@ const WifiChannelCard = ({ channel, setIes }) => {
WifiChannelCard.propTypes = {
channel: PropTypes.instanceOf(Object).isRequired,
setIes: PropTypes.func.isRequired,
};
export default WifiChannelCard;

View File

@@ -4,7 +4,7 @@ import { v4 as createUuid } from 'uuid';
import PropTypes from 'prop-types';
import WifiChannelCard from './WifiChannelCard';
const WifiChannelTable = ({ channels, setIes }) => {
const WifiChannelTable = ({ channels }) => {
const sortChannels = () => {
channels.sort((a, b) => (a.channel > b.channel ? 1 : -1));
};
@@ -17,15 +17,13 @@ const WifiChannelTable = ({ channels, setIes }) => {
<CRow>
<CCol>
{channels.map((channel, index) => {
if (index % 2 === 0)
return <WifiChannelCard key={createUuid()} channel={channel} setIes={setIes} />;
if (index % 2 === 0) return <WifiChannelCard key={createUuid()} channel={channel} />;
return <div key={createUuid()} />;
})}
</CCol>
<CCol>
{channels.map((channel, index) => {
if (index % 2 === 1)
return <WifiChannelCard key={createUuid()} channel={channel} setIes={setIes} />;
if (index % 2 === 1) return <WifiChannelCard key={createUuid()} channel={channel} />;
return <div key={createUuid()} />;
})}
</CCol>
@@ -35,7 +33,6 @@ const WifiChannelTable = ({ channels, setIes }) => {
WifiChannelTable.propTypes = {
channels: PropTypes.instanceOf(Array),
setIes: PropTypes.func.isRequired,
};
WifiChannelTable.defaultProps = {

View File

@@ -1,5 +1,5 @@
/* eslint-disable-rule prefer-destructuring */
import React, { useEffect, useMemo, useState } from 'react';
import React, { useCallback } from 'react';
import { useTranslation } from 'react-i18next';
import { CButton, CModal, CModalHeader, CModalBody, CModalTitle, CPopover } from '@coreui/react';
import CIcon from '@coreui/icons-react';
@@ -9,14 +9,12 @@ import { prettyDate, prettyDateForFile } from 'utils/helper';
import { useDevice } from 'ucentral-libs';
import { CSVLink } from 'react-csv';
import WifiChannelTable from './WifiChannelTable';
import IeDisplay from './IeDisplay';
const WifiScanResultModal = ({ show, toggle, scanResults, date }) => {
const { t } = useTranslation();
const { deviceSerialNumber } = useDevice();
const [selectedIes, setSelectedIes] = useState(undefined);
const getData = useMemo(() => {
const getData = useCallback(() => {
if (scanResults === null || scanResults.length === 0) return [];
const dbmNumber = 4294967295;
const listOfChannels = [];
@@ -33,6 +31,7 @@ const WifiScanResultModal = ({ show, toggle, scanResults, date }) => {
channel: channelNumber,
devices: [],
};
scanResults.forEach((device) => {
if (device.channel === channelNumber) {
const deviceToAdd = {};
@@ -42,15 +41,14 @@ const WifiScanResultModal = ({ show, toggle, scanResults, date }) => {
}
deviceToAdd.Signal = (dbmNumber - device.signal) * -1;
channel.devices.push(deviceToAdd);
listCsv.push({ ...deviceToAdd, ...device, ies: JSON.stringify(device.ies, null, 4) });
listCsv.push({ ...deviceToAdd, ...device });
}
});
});
return listCsv;
}, [scanResults]);
const parseThroughList = useMemo(() => {
if (!scanResults) return null;
const parseThroughList = useCallback(() => {
const dbmNumber = 4294967295;
const listOfChannels = [];
@@ -75,7 +73,6 @@ const WifiScanResultModal = ({ show, toggle, scanResults, date }) => {
deviceToAdd.SSID = device.meshid && device.meshid.length > 0 ? device.meshid : 'N/A';
}
deviceToAdd.Signal = (dbmNumber - device.signal) * -1;
deviceToAdd.ies = device.ies;
channel.devices.push(deviceToAdd);
}
});
@@ -85,10 +82,6 @@ const WifiScanResultModal = ({ show, toggle, scanResults, date }) => {
return finalList;
}, [scanResults]);
useEffect(() => {
setSelectedIes(undefined);
}, [show]);
return (
<CModal size="lg" show={show} onClose={toggle}>
<CModalHeader>
@@ -101,7 +94,7 @@ const WifiScanResultModal = ({ show, toggle, scanResults, date }) => {
filename={`wifi_scan_${deviceSerialNumber}_${
date !== '' ? prettyDateForFile(date) : ''
}.csv`}
data={getData}
data={getData()}
>
<CButton color="primary" variant="outline" className="ml-2">
<CIcon content={cilCloudDownload} />
@@ -116,10 +109,7 @@ const WifiScanResultModal = ({ show, toggle, scanResults, date }) => {
</div>
</CModalHeader>
<CModalBody>
{selectedIes && <IeDisplay ies={selectedIes} setIes={setSelectedIes} />}
{selectedIes || scanResults === null ? null : (
<WifiChannelTable channels={parseThroughList} setIes={setSelectedIes} />
)}
{scanResults === null ? null : <WifiChannelTable channels={parseThroughList()} />}
</CModalBody>
</CModal>
);

View File

@@ -1,26 +0,0 @@
import { useCallback, useMemo } from 'react';
import { useToast } from 'ucentral-libs';
const useWebSocketNotification = () => {
const { addToast } = useToast();
const pushNotification = useCallback((notification) => {
addToast({
title: notification.content.title,
body: notification.content.details,
color: 'info',
autohide: true,
});
}, []);
const toReturn = useMemo(
() => ({
pushNotification,
}),
[],
);
return toReturn;
};
export default useWebSocketNotification;

View File

@@ -1,88 +0,0 @@
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import { useAuth } from 'ucentral-libs';
import PropTypes from 'prop-types';
import useWebSocketNotification from './hooks/NotificationContent/useWebSocketNotification';
import useSocketReducer from './useSocketReducer';
import { extractWebSocketResponse } from './utils';
const WebSocketContext = React.createContext({
webSocket: undefined,
isOpen: false,
addDeviceListener: () => {},
});
export const WebSocketProvider = ({ children }) => {
const { currentToken, endpoints } = useAuth();
const [isOpen, setIsOpen] = useState(false);
const ws = useRef(undefined);
const { lastMessage, dispatch } = useSocketReducer();
const { pushNotification } = useWebSocketNotification();
const onMessage = useCallback((message) => {
const result = extractWebSocketResponse(message);
if (result?.type === 'NOTIFICATION') {
dispatch({ type: 'NEW_NOTIFICATION', notification: result.notification });
pushNotification(result.notification);
}
if (result?.type === 'DEVICE_NOTIFICATION') {
dispatch({
type: 'NEW_DEVICE_NOTIFICATION',
serialNumber: result.serialNumber,
subType: result.subType,
});
}
if (result?.type === 'COMMAND') {
dispatch({ type: 'NEW_COMMAND', data: result.data });
}
}, []);
// useEffect for created the WebSocket and 'storing' it in useRef
useEffect(() => {
ws.current = new WebSocket(`${endpoints.owgw.replace('https', 'wss')}/api/v1/ws`);
ws.current.onopen = () => {
setIsOpen(true);
ws.current?.send(`token:${currentToken}`);
};
ws.current.onclose = () => {
setIsOpen(false);
};
ws.current.onerror = () => {
setIsOpen(false);
};
const wsCurrent = ws?.current;
return () => wsCurrent?.close();
}, []);
// useEffect for generating global notifications
useEffect(() => {
if (ws?.current) {
ws.current.addEventListener('message', onMessage);
}
const wsCurrent = ws?.current;
return () => {
if (wsCurrent) wsCurrent.removeEventListener('message', onMessage);
};
}, [ws?.current]);
const values = useMemo(
() => ({
lastMessage,
webSocket: ws.current,
addDeviceListener: ({ serialNumber, types, addToast, onTrigger }) =>
dispatch({ type: 'ADD_DEVICE_LISTENER', serialNumber, types, addToast, onTrigger }),
removeDeviceListener: ({ serialNumber }) =>
dispatch({ type: 'REMOVE_DEVICE_LISTENER', serialNumber }),
isOpen,
}),
[ws, isOpen, lastMessage],
);
return <WebSocketContext.Provider value={values}>{children}</WebSocketContext.Provider>;
};
WebSocketProvider.propTypes = {
children: PropTypes.node.isRequired,
};
export const useGlobalWebSocket = () => React.useContext(WebSocketContext);

View File

@@ -1,98 +0,0 @@
import { useReducer } from 'react';
const titles = {
device_connection: 'Connected',
device_disconnection: 'Disconnected',
device_firmware_upgrade: 'Firmware Upgraded',
};
const bodies = {
device_connection: 'This device has rebooted and is now connected!',
device_disconnection: 'This device has started rebooting and is now disconnected!',
device_firmware_upgrade: 'This device has updated to new firmware!',
};
const reducer = (state, action) => {
switch (action.type) {
case 'NEW_NOTIFICATION': {
const obj = { type: 'NOTIFICATION', data: action.notification, timestamp: new Date() };
return { ...state, lastMessage: obj };
}
case 'NEW_COMMAND': {
const obj = {
type: 'COMMAND',
response: action.data.response,
timestamp: new Date(),
id: action.data.command_response_id,
};
return { ...state, lastMessage: obj };
}
case 'NEW_DEVICE_NOTIFICATION': {
const newListeners = state.deviceListeners;
let obj;
if (action.subType === 'device_connection' || action.subType === 'device_disconnection') {
obj = {
type: 'DEVICE',
isConnected: action.subType === 'device_connection',
serialNumber: action.serialNumber,
timestamp: new Date(),
};
}
for (let i = 0; i < state.deviceListeners.length; i += 1) {
if (
state.deviceListeners[i].serialNumber === action.serialNumber &&
state.deviceListeners[i].type === action.subType
) {
if (state.deviceListeners[i].onTrigger) {
setTimeout(() => state.deviceListeners[i].onTrigger(action.subType), 1000);
} else if (state.deviceListeners[i].addToast) {
state.deviceListeners[i].addToast(
`${action.serialNumber} ${titles[state.deviceListeners[i].type]}`,
bodies[state.deviceListeners[i].type],
);
const found = newListeners.findIndex(
(listener) =>
listener.serialNumber === action.serialNumber && listener.type === action.subType,
);
if (found >= 0) newListeners.splice(found, 1);
}
}
}
return { ...state, lastMessage: obj ?? state.lastMessage, deviceListeners: newListeners };
}
case 'ADD_DEVICE_LISTENER': {
let newListeners = action.types.map((actionType) => ({
type: actionType,
serialNumber: action.serialNumber,
addToast: action.addToast,
onTrigger: action.onTrigger,
}));
newListeners = newListeners.concat(state.deviceListeners);
return { ...state, lastMessage: state.lastMessage, deviceListeners: newListeners };
}
case 'REMOVE_DEVICE_LISTENER': {
const newListeners = state.deviceListeners.filter(
(listener) =>
listener.serialNumber !== action.serialNumber || listener.onTrigger === undefined,
);
return { ...state, lastMessage: state.lastMessage, deviceListeners: newListeners };
}
case 'UNKNOWN': {
const obj = { type: 'UNKNOWN', data: action.newMessage, timestamp: new Date() };
return { ...state, lastMessage: obj };
}
default:
throw new Error();
}
};
const useSocketReducer = () => {
const [{ lastMessage, deviceListeners }, dispatch] = useReducer(reducer, {
deviceListeners: [],
});
return { lastMessage, deviceListeners, dispatch };
};
export default useSocketReducer;

View File

@@ -1,55 +0,0 @@
export const acceptedNotificationTypes = [
'venue_configuration_update',
'entity_configuration_update',
];
export const deviceNotificationTypes = [
'device_connection',
'device_disconnection',
'device_firmware_upgrade',
'device_statistics',
];
export const extractWebSocketResponse = (message) => {
try {
const data = JSON.parse(message.data);
if (data.notification && acceptedNotificationTypes.includes(data.notification.type)) {
const { notification } = data;
return { notification, type: 'NOTIFICATION' };
}
if (data.notification && deviceNotificationTypes.includes(data.notification.type)) {
return {
serialNumber: data.notification.content.serialNumber,
type: 'DEVICE_NOTIFICATION',
subType: data.notification.type,
};
}
if (data.command_response_id) {
return { data, type: 'COMMAND' };
}
} catch {
return undefined;
}
return undefined;
};
export const getStatusFromNotification = (notification) => {
let status = 'success';
if (notification.content.warning?.length > 0) status = 'warning';
if (notification.content.error?.length > 0) status = 'error';
return status;
};
export const getNotificationDescription = (t, notification) => {
if (
notification.content.type === 'venue_configuration_update' ||
notification.content.type === 'entity_configuration_update'
) {
return t('configurations.notification_details', {
success: notification.content.success.length,
warning: notification.content.warning.length,
error: notification.content.error.length,
});
}
return notification.content.details;
};

View File

@@ -5,7 +5,6 @@ import { CSidebarNavItem } from '@coreui/react';
import { cilBarcode, cilRouter, cilSave, cilSettings, cilPeople } from '@coreui/icons';
import CIcon from '@coreui/icons-react';
import { Header, Sidebar, Footer, PageContainer, ToastProvider, useAuth } from 'ucentral-libs';
import { WebSocketProvider } from 'contexts/WebSocketProvider';
const TheLayout = () => {
const [showSidebar, setShowSidebar] = useState('responsive');
@@ -71,9 +70,7 @@ const TheLayout = () => {
/>
<div className="c-body">
<ToastProvider>
<WebSocketProvider>
<PageContainer t={t} routes={routes} redirectTo="/devices" />
</WebSocketProvider>
<PageContainer t={t} routes={routes} redirectTo="/devices" />
</ToastProvider>
</div>
<Footer t={t} version={process.env.VERSION} />

View File

@@ -15,17 +15,12 @@ import {
import CIcon from '@coreui/icons-react';
import { cilSync } from '@coreui/icons';
import { prettyDate } from 'utils/helper';
import { CopyToClipboardButton, HideTextButton, useAuth } from 'ucentral-libs';
import { getCountryFromLocale } from 'utils/countries';
import ReactCountryFlag from 'react-country-flag';
import axiosInstance from 'utils/axiosInstance';
import { CopyToClipboardButton, HideTextButton } from 'ucentral-libs';
import styles from './index.module.scss';
const DeviceDetails = ({ t, loading, getData, status, deviceConfig, lastStats }) => {
const [showPassword, setShowPassword] = useState(false);
const [subName, setSubName] = useState('');
const { currentToken, endpoints } = useAuth();
const toggleShowPassword = () => {
setShowPassword(!showPassword);
@@ -37,51 +32,21 @@ const DeviceDetails = ({ t, loading, getData, status, deviceConfig, lastStats })
return showPassword ? password : '******';
};
const getSubData = async (subId) => {
const options = {
headers: {
Accept: 'application/json',
Authorization: `Bearer ${currentToken}`,
},
};
axiosInstance
.get(`${endpoints.owsec}/api/v1/subuser/${subId}`, options)
.then((response) => setSubName(response.data.name ?? ''))
.catch(() => setSubName(''));
};
const getSubscriber = () => {
if (!deviceConfig?.subscriber || deviceConfig.subscriber === '') return '';
getSubData(deviceConfig.subscriber);
return (
<CLink
className="c-subheader-nav-link align-self-center"
aria-current="page"
href={`${localStorage.getItem('owprov-ui')}/#/subscriber/${deviceConfig.subscriber}`}
target="_blank"
>
{subName !== '' ? subName : deviceConfig.subscriber}
</CLink>
);
};
const displayExtra = (key, value, extraData) => {
if (!extraData || !extraData[key]) return value;
if (!localStorage.getItem('owprov-ui')) return extraData[key].name;
if (!localStorage.getItem('owprov-ui') || key === 'owner') return extraData[key].name;
return (
<CLink
className="c-subheader-nav-link align-self-center"
aria-current="page"
href={`${localStorage.getItem('owprov-ui')}/#/${
key === 'entity' ? 'entity' : 'venue'
}/${value}`}
href={`${localStorage.getItem('owprov-ui')}/#/${key === 'entity' ? 'entity' : 'venue'}/${
extraData[key].id
}`}
target="_blank"
>
{!extraData || !extraData[key] ? value : extraData[key].name}
{extraData[key].name}
</CLink>
);
};
@@ -134,13 +99,13 @@ const DeviceDetails = ({ t, loading, getData, status, deviceConfig, lastStats })
/>
</CCol>
<CCol className="border-left" lg="2" xl="1" xxl="1">
<CLabel>{t('inventory.subscriber')}:</CLabel>
<CLabel>{t('configuration.owner')}:</CLabel>
</CCol>
<CCol lg="2" xl="3" xxl="3">
{getSubscriber()}
{deviceConfig?.owner}
</CCol>
<CCol lg="2" xl="1" xxl="1">
<CLabel>MAC:</CLabel>
<CLabel>{t('common.mac')}:</CLabel>
</CCol>
<CCol className="border-right" lg="2" xl="3" xxl="3">
{deviceConfig?.macAddress}
@@ -152,16 +117,25 @@ const DeviceDetails = ({ t, loading, getData, status, deviceConfig, lastStats })
{deviceConfig?.deviceType}
</CCol>
<CCol className="border-left" lg="2" xl="1" xxl="1">
<CLabel>{t('entity.entity')}:</CLabel>
<CLabel>
{deviceConfig?.venue?.substring(0, 3) === 'ent'
? t('entity.entity')
: t('inventory.venue')}
:
</CLabel>
</CCol>
<CCol lg="2" xl="3" xxl="3">
{deviceConfig?.entity !== ''
{deviceConfig?.venue?.substring(0, 3) === 'ent'
? displayExtra(
'entity',
deviceConfig?.venue?.slice(4),
deviceConfig?.extendedInfo,
)
: ''}
: displayExtra(
'venue',
deviceConfig?.venue?.slice(4),
deviceConfig?.extendedInfo,
)}
</CCol>
<CCol lg="2" xl="1" xxl="1">
<CLabel>{t('common.manufacturer')}:</CLabel>
@@ -175,37 +149,6 @@ const DeviceDetails = ({ t, loading, getData, status, deviceConfig, lastStats })
<CCol lg="2" xl="3" xxl="3">
{prettyDate(deviceConfig?.createdTimestamp)}
</CCol>
<CCol className="border-left" lg="2" xl="1" xxl="1">
<CLabel>{t('inventory.venue')}:</CLabel>
</CCol>
<CCol lg="2" xl="3" xxl="3">
{deviceConfig?.venue !== ''
? displayExtra('venue', deviceConfig?.venue?.slice(4), deviceConfig?.extendedInfo)
: ''}
</CCol>
<CCol lg="2" xl="1" xxl="1">
<CLabel>Locale:</CLabel>
</CCol>
<CCol className="border-right" lg="2" xl="3" xxl="3">
{deviceConfig?.locale !== '' && (
<ReactCountryFlag
style={{ width: '24px', height: '24px' }}
countryCode={deviceConfig?.locale}
svg
/>
)}
{' '}
{deviceConfig?.locale && deviceConfig?.locale !== ''
? `${deviceConfig.locale} - `
: 'Unknown'}
{getCountryFromLocale(deviceConfig?.locale ?? '')}
</CCol>
<CCol lg="2" xl="1" xxl="1">
<CLabel>{t('common.modified')}: </CLabel>
</CCol>
<CCol lg="2" xl="3" xxl="3">
{prettyDate(deviceConfig?.modified)}
</CCol>
<CCol className="border-left" lg="2" xl="1" xxl="1">
<CLabel>{t('configuration.location')}:</CLabel>
</CCol>

View File

@@ -12,7 +12,6 @@ import { useTranslation } from 'react-i18next';
import ConfigurationDisplay from 'components/ConfigurationDisplay';
import WifiAnalysis from 'components/WifiAnalysis';
import CapabilitiesDisplay from 'components/CapabilitiesDisplay';
import { useGlobalWebSocket } from 'contexts/WebSocketProvider';
import NotesTab from './NotesTab';
import DeviceDetails from './Details';
import DeviceStatusCard from './DeviceStatusCard';
@@ -27,7 +26,6 @@ const DevicePage = () => {
const [deviceConfig, setDeviceConfig] = useState(null);
const [error, setError] = useState(false);
const [loading, setLoading] = useState(false);
const { addDeviceListener, removeDeviceListener } = useGlobalWebSocket();
const updateNav = (target) => {
sessionStorage.setItem('devicePageIndex', target);
@@ -117,26 +115,9 @@ const DevicePage = () => {
useEffect(() => {
setError(false);
if (deviceId) {
addDeviceListener({
serialNumber: deviceId,
types: [
'device_connection',
'device_disconnection',
'device_firmware_upgrade',
'device_statistics',
],
onTrigger: () => refresh(),
});
refresh();
getDevice();
getData();
}
return () => {
if (deviceId) {
removeDeviceListener({
serialNumber: deviceId,
});
}
};
}, [deviceId]);
return (

View File

@@ -8,7 +8,7 @@ axiosRetry(axiosInstance, {
retryDelay: () => axiosRetry.exponentialDelay,
});
axiosInstance.defaults.timeout = 160000;
axiosInstance.defaults.timeout = 60000;
axiosInstance.defaults.headers.get.Accept = 'application/json';
axiosInstance.defaults.headers.post.Accept = 'application/json';

View File

@@ -1,253 +0,0 @@
export const COUNTRY_LIST = [
{ value: 'US', label: 'United States' },
{ value: 'CA', label: 'Canada' },
{ value: 'AF', label: 'Afghanistan' },
{ value: 'AX', label: 'Aland Islands' },
{ value: 'AL', label: 'Albania' },
{ value: 'DZ', label: 'Algeria' },
{ value: 'AS', label: 'American Samoa' },
{ value: 'AD', label: 'Andorra' },
{ value: 'AO', label: 'Angola' },
{ value: 'AI', label: 'Anguilla' },
{ value: 'AQ', label: 'Antarctica' },
{ value: 'AG', label: 'Antigua And Barbuda' },
{ value: 'AR', label: 'Argentina' },
{ value: 'AM', label: 'Armenia' },
{ value: 'AN', label: 'Netherlands Antilles' },
{ value: 'AW', label: 'Aruba' },
{ value: 'AU', label: 'Australia' },
{ value: 'AT', label: 'Austria' },
{ value: 'AZ', label: 'Azerbaijan' },
{ value: 'BS', label: 'Bahamas' },
{ value: 'BH', label: 'Bahrain' },
{ value: 'BD', label: 'Bangladesh' },
{ value: 'BB', label: 'Barbados' },
{ value: 'BY', label: 'Belarus' },
{ value: 'BE', label: 'Belgium' },
{ value: 'BZ', label: 'Belize' },
{ value: 'BJ', label: 'Benin' },
{ value: 'BM', label: 'Bermuda' },
{ value: 'BT', label: 'Bhutan' },
{ value: 'BO', label: 'Bolivia' },
{ value: 'BA', label: 'Bosnia And Herzegovina' },
{ value: 'BW', label: 'Botswana' },
{ value: 'BV', label: 'Bouvet Island' },
{ value: 'BR', label: 'Brazil' },
{ value: 'IO', label: 'British Indian Ocean Territory' },
{ value: 'BN', label: 'Brunei Darussalam' },
{ value: 'BG', label: 'Bulgaria' },
{ value: 'BF', label: 'Burkina Faso' },
{ value: 'BI', label: 'Burundi' },
{ value: 'KH', label: 'Cambodia' },
{ value: 'CM', label: 'Cameroon' },
{ value: 'CA', label: 'Canada' },
{ value: 'CV', label: 'Cape Verde' },
{ value: 'KY', label: 'Cayman Islands' },
{ value: 'CF', label: 'Central African Republic' },
{ value: 'TD', label: 'Chad' },
{ value: 'CL', label: 'Chile' },
{ value: 'CN', label: 'China' },
{ value: 'CX', label: 'Christmas Island' },
{ value: 'CC', label: 'Cocos (Keeling) Islands' },
{ value: 'CO', label: 'Colombia' },
{ value: 'KM', label: 'Comoros' },
{ value: 'CG', label: 'Congo' },
{ value: 'CD', label: 'Congo, Democratic Republic' },
{ value: 'CK', label: 'Cook Islands' },
{ value: 'CR', label: 'Costa Rica' },
{ value: 'CI', label: "Cote D'Ivoire" },
{ value: 'HR', label: 'Croatia' },
{ value: 'CU', label: 'Cuba' },
{ value: 'CY', label: 'Cyprus' },
{ value: 'CZ', label: 'Czech Republic' },
{ value: 'DK', label: 'Denmark' },
{ value: 'DJ', label: 'Djibouti' },
{ value: 'DM', label: 'Dominica' },
{ value: 'DO', label: 'Dominican Republic' },
{ value: 'EC', label: 'Ecuador' },
{ value: 'EG', label: 'Egypt' },
{ value: 'SV', label: 'El Salvador' },
{ value: 'GQ', label: 'Equatorial Guinea' },
{ value: 'ER', label: 'Eritrea' },
{ value: 'EE', label: 'Estonia' },
{ value: 'ET', label: 'Ethiopia' },
{ value: 'FK', label: 'Falkland Islands (Malvinas)' },
{ value: 'FO', label: 'Faroe Islands' },
{ value: 'FJ', label: 'Fiji' },
{ value: 'FI', label: 'Finland' },
{ value: 'FR', label: 'France' },
{ value: 'GF', label: 'French Guiana' },
{ value: 'PF', label: 'French Polynesia' },
{ value: 'TF', label: 'French Southern Territories' },
{ value: 'GA', label: 'Gabon' },
{ value: 'GM', label: 'Gambia' },
{ value: 'GE', label: 'Georgia' },
{ value: 'DE', label: 'Germany' },
{ value: 'GH', label: 'Ghana' },
{ value: 'GI', label: 'Gibraltar' },
{ value: 'GR', label: 'Greece' },
{ value: 'GL', label: 'Greenland' },
{ value: 'GD', label: 'Grenada' },
{ value: 'GP', label: 'Guadeloupe' },
{ value: 'GU', label: 'Guam' },
{ value: 'GT', label: 'Guatemala' },
{ value: 'GG', label: 'Guernsey' },
{ value: 'GN', label: 'Guinea' },
{ value: 'GW', label: 'Guinea-Bissau' },
{ value: 'GY', label: 'Guyana' },
{ value: 'HT', label: 'Haiti' },
{ value: 'HM', label: 'Heard Island & Mcdonald Islands' },
{ value: 'VA', label: 'Holy See (Vatican City State)' },
{ value: 'HN', label: 'Honduras' },
{ value: 'HK', label: 'Hong Kong' },
{ value: 'HU', label: 'Hungary' },
{ value: 'IS', label: 'Iceland' },
{ value: 'IN', label: 'India' },
{ value: 'ID', label: 'Indonesia' },
{ value: 'IR', label: 'Iran, Islamic Republic Of' },
{ value: 'IQ', label: 'Iraq' },
{ value: 'IE', label: 'Ireland' },
{ value: 'IM', label: 'Isle Of Man' },
{ value: 'IL', label: 'Israel' },
{ value: 'IT', label: 'Italy' },
{ value: 'JM', label: 'Jamaica' },
{ value: 'JP', label: 'Japan' },
{ value: 'JE', label: 'Jersey' },
{ value: 'JO', label: 'Jordan' },
{ value: 'KZ', label: 'Kazakhstan' },
{ value: 'KE', label: 'Kenya' },
{ value: 'KI', label: 'Kiribati' },
{ value: 'KR', label: 'Korea' },
{ value: 'KW', label: 'Kuwait' },
{ value: 'KG', label: 'Kyrgyzstan' },
{ value: 'LA', label: "Lao People's Democratic Republic" },
{ value: 'LV', label: 'Latvia' },
{ value: 'LB', label: 'Lebanon' },
{ value: 'LS', label: 'Lesotho' },
{ value: 'LR', label: 'Liberia' },
{ value: 'LY', label: 'Libyan Arab Jamahiriya' },
{ value: 'LI', label: 'Liechtenstein' },
{ value: 'LT', label: 'Lithuania' },
{ value: 'LU', label: 'Luxembourg' },
{ value: 'MO', label: 'Macao' },
{ value: 'MK', label: 'Macedonia' },
{ value: 'MG', label: 'Madagascar' },
{ value: 'MW', label: 'Malawi' },
{ value: 'MY', label: 'Malaysia' },
{ value: 'MV', label: 'Maldives' },
{ value: 'ML', label: 'Mali' },
{ value: 'MT', label: 'Malta' },
{ value: 'MH', label: 'Marshall Islands' },
{ value: 'MQ', label: 'Martinique' },
{ value: 'MR', label: 'Mauritania' },
{ value: 'MU', label: 'Mauritius' },
{ value: 'YT', label: 'Mayotte' },
{ value: 'MX', label: 'Mexico' },
{ value: 'FM', label: 'Micronesia, Federated States Of' },
{ value: 'MD', label: 'Moldova' },
{ value: 'MC', label: 'Monaco' },
{ value: 'MN', label: 'Mongolia' },
{ value: 'ME', label: 'Montenegro' },
{ value: 'MS', label: 'Montserrat' },
{ value: 'MA', label: 'Morocco' },
{ value: 'MZ', label: 'Mozambique' },
{ value: 'MM', label: 'Myanmar' },
{ value: 'NA', label: 'Namibia' },
{ value: 'NR', label: 'Nauru' },
{ value: 'NP', label: 'Nepal' },
{ value: 'NL', label: 'Netherlands' },
{ value: 'AN', label: 'Netherlands Antilles' },
{ value: 'NC', label: 'New Caledonia' },
{ value: 'NZ', label: 'New Zealand' },
{ value: 'NI', label: 'Nicaragua' },
{ value: 'NE', label: 'Niger' },
{ value: 'NG', label: 'Nigeria' },
{ value: 'NU', label: 'Niue' },
{ value: 'NF', label: 'Norfolk Island' },
{ value: 'MP', label: 'Northern Mariana Islands' },
{ value: 'NO', label: 'Norway' },
{ value: 'OM', label: 'Oman' },
{ value: 'PK', label: 'Pakistan' },
{ value: 'PW', label: 'Palau' },
{ value: 'PS', label: 'Palestinian Territory, Occupied' },
{ value: 'PA', label: 'Panama' },
{ value: 'PG', label: 'Papua New Guinea' },
{ value: 'PY', label: 'Paraguay' },
{ value: 'PE', label: 'Peru' },
{ value: 'PH', label: 'Philippines' },
{ value: 'PN', label: 'Pitcairn' },
{ value: 'PL', label: 'Poland' },
{ value: 'PT', label: 'Portugal' },
{ value: 'PR', label: 'Puerto Rico' },
{ value: 'QA', label: 'Qatar' },
{ value: 'RE', label: 'Reunion' },
{ value: 'RO', label: 'Romania' },
{ value: 'RU', label: 'Russian Federation' },
{ value: 'RW', label: 'Rwanda' },
{ value: 'BL', label: 'Saint Barthelemy' },
{ value: 'SH', label: 'Saint Helena' },
{ value: 'KN', label: 'Saint Kitts And Nevis' },
{ value: 'LC', label: 'Saint Lucia' },
{ value: 'MF', label: 'Saint Martin' },
{ value: 'PM', label: 'Saint Pierre And Miquelon' },
{ value: 'VC', label: 'Saint Vincent And Grenadines' },
{ value: 'WS', label: 'Samoa' },
{ value: 'SM', label: 'San Marino' },
{ value: 'ST', label: 'Sao Tome And Principe' },
{ value: 'SA', label: 'Saudi Arabia' },
{ value: 'SN', label: 'Senegal' },
{ value: 'RS', label: 'Serbia' },
{ value: 'SC', label: 'Seychelles' },
{ value: 'SL', label: 'Sierra Leone' },
{ value: 'SG', label: 'Singapore' },
{ value: 'SK', label: 'Slovakia' },
{ value: 'SI', label: 'Slovenia' },
{ value: 'SB', label: 'Solomon Islands' },
{ value: 'SO', label: 'Somalia' },
{ value: 'ZA', label: 'South Africa' },
{ value: 'GS', label: 'South Georgia And Sandwich Isl.' },
{ value: 'ES', label: 'Spain' },
{ value: 'LK', label: 'Sri Lanka' },
{ value: 'SD', label: 'Sudan' },
{ value: 'SR', label: 'Surilabel' },
{ value: 'SJ', label: 'Svalbard And Jan Mayen' },
{ value: 'SZ', label: 'Swaziland' },
{ value: 'SE', label: 'Sweden' },
{ value: 'CH', label: 'Switzerland' },
{ value: 'SY', label: 'Syrian Arab Republic' },
{ value: 'TW', label: 'Taiwan' },
{ value: 'TJ', label: 'Tajikistan' },
{ value: 'TZ', label: 'Tanzania' },
{ value: 'TH', label: 'Thailand' },
{ value: 'TL', label: 'Timor-Leste' },
{ value: 'TG', label: 'Togo' },
{ value: 'TK', label: 'Tokelau' },
{ value: 'TO', label: 'Tonga' },
{ value: 'TT', label: 'Trinidad And Tobago' },
{ value: 'TN', label: 'Tunisia' },
{ value: 'TR', label: 'Turkey' },
{ value: 'TM', label: 'Turkmenistan' },
{ value: 'TC', label: 'Turks And Caicos Islands' },
{ value: 'TV', label: 'Tuvalu' },
{ value: 'UG', label: 'Uganda' },
{ value: 'UA', label: 'Ukraine' },
{ value: 'AE', label: 'United Arab Emirates' },
{ value: 'GB', label: 'United Kingdom' },
{ value: 'US', label: 'United States' },
{ value: 'UM', label: 'United States Outlying Islands' },
{ value: 'UY', label: 'Uruguay' },
{ value: 'UZ', label: 'Uzbekistan' },
{ value: 'VU', label: 'Vanuatu' },
{ value: 'VE', label: 'Venezuela' },
{ value: 'VN', label: 'Viet Nam' },
{ value: 'VG', label: 'Virgin Islands, British' },
{ value: 'VI', label: 'Virgin Islands, U.S.' },
{ value: 'WF', label: 'Wallis And Futuna' },
{ value: 'EH', label: 'Western Sahara' },
{ value: 'YE', label: 'Yemen' },
{ value: 'ZM', label: 'Zambia' },
{ value: 'ZW', label: 'Zimbabwe' },
];
export const getCountryFromLocale = (locale) =>
COUNTRY_LIST.find((country) => country.value === locale)?.label ?? '';

View File

@@ -59,14 +59,6 @@ export const checkIfJson = (string) => {
return true;
};
export const toJson = (string) => {
try {
return JSON.parse(string);
} catch (e) {
return undefined;
}
};
export const secondsToDetailed = (
seconds,
dayLabel,