mirror of
https://github.com/optim-enterprises-bv/OptimCloud-gw-ui.git
synced 2025-10-28 17:02:21 +00:00
[WIFI-13282] Add support for OLS
Signed-off-by: Charles <charles.bourque96@gmail.com>
This commit is contained in:
340
package-lock.json
generated
340
package-lock.json
generated
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "ucentral-client",
|
"name": "ucentral-client",
|
||||||
"version": "3.0.0(6)",
|
"version": "3.0.1(2)",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "ucentral-client",
|
"name": "ucentral-client",
|
||||||
"version": "3.0.0(6)",
|
"version": "3.0.1(2)",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@chakra-ui/anatomy": "^2.1.1",
|
"@chakra-ui/anatomy": "^2.1.1",
|
||||||
@@ -88,6 +88,7 @@
|
|||||||
"lint-staged": "^13.2.1",
|
"lint-staged": "^13.2.1",
|
||||||
"prettier": "^2.8.7",
|
"prettier": "^2.8.7",
|
||||||
"vite-plugin-pwa": "^0.14.7",
|
"vite-plugin-pwa": "^0.14.7",
|
||||||
|
"vite-plugin-svgr": "^4.2.0",
|
||||||
"vite-tsconfig-paths": "^4.2.0"
|
"vite-tsconfig-paths": "^4.2.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -3955,9 +3956,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@rollup/pluginutils": {
|
"node_modules/@rollup/pluginutils": {
|
||||||
"version": "5.0.2",
|
"version": "5.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.0.tgz",
|
||||||
"integrity": "sha512-pTd9rIsP92h+B6wWwFbW8RkZv4hiR/xKsqre4SIuAOaOEQRxi0lqLke9k2/7WegC85GgUs9pjmOjCUi3In4vwA==",
|
"integrity": "sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/estree": "^1.0.0",
|
"@types/estree": "^1.0.0",
|
||||||
@@ -3968,7 +3969,7 @@
|
|||||||
"node": ">=14.0.0"
|
"node": ">=14.0.0"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"rollup": "^1.20.0||^2.0.0||^3.0.0"
|
"rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0"
|
||||||
},
|
},
|
||||||
"peerDependenciesMeta": {
|
"peerDependenciesMeta": {
|
||||||
"rollup": {
|
"rollup": {
|
||||||
@@ -3997,6 +3998,245 @@
|
|||||||
"sourcemap-codec": "^1.4.8"
|
"sourcemap-codec": "^1.4.8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@svgr/babel-plugin-add-jsx-attribute": {
|
||||||
|
"version": "8.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-8.0.0.tgz",
|
||||||
|
"integrity": "sha512-b9MIk7yhdS1pMCZM8VeNfUlSKVRhsHZNMl5O9SfaX0l0t5wjdgu4IDzGB8bpnGBBOjGST3rRFVsaaEtI4W6f7g==",
|
||||||
|
"dev": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">=14"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/gregberge"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@babel/core": "^7.0.0-0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@svgr/babel-plugin-remove-jsx-attribute": {
|
||||||
|
"version": "8.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-attribute/-/babel-plugin-remove-jsx-attribute-8.0.0.tgz",
|
||||||
|
"integrity": "sha512-BcCkm/STipKvbCl6b7QFrMh/vx00vIP63k2eM66MfHJzPr6O2U0jYEViXkHJWqXqQYjdeA9cuCl5KWmlwjDvbA==",
|
||||||
|
"dev": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">=14"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/gregberge"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@babel/core": "^7.0.0-0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@svgr/babel-plugin-remove-jsx-empty-expression": {
|
||||||
|
"version": "8.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-empty-expression/-/babel-plugin-remove-jsx-empty-expression-8.0.0.tgz",
|
||||||
|
"integrity": "sha512-5BcGCBfBxB5+XSDSWnhTThfI9jcO5f0Ai2V24gZpG+wXF14BzwxxdDb4g6trdOux0rhibGs385BeFMSmxtS3uA==",
|
||||||
|
"dev": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">=14"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/gregberge"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@babel/core": "^7.0.0-0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@svgr/babel-plugin-replace-jsx-attribute-value": {
|
||||||
|
"version": "8.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@svgr/babel-plugin-replace-jsx-attribute-value/-/babel-plugin-replace-jsx-attribute-value-8.0.0.tgz",
|
||||||
|
"integrity": "sha512-KVQ+PtIjb1BuYT3ht8M5KbzWBhdAjjUPdlMtpuw/VjT8coTrItWX6Qafl9+ji831JaJcu6PJNKCV0bp01lBNzQ==",
|
||||||
|
"dev": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">=14"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/gregberge"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@babel/core": "^7.0.0-0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@svgr/babel-plugin-svg-dynamic-title": {
|
||||||
|
"version": "8.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-dynamic-title/-/babel-plugin-svg-dynamic-title-8.0.0.tgz",
|
||||||
|
"integrity": "sha512-omNiKqwjNmOQJ2v6ge4SErBbkooV2aAWwaPFs2vUY7p7GhVkzRkJ00kILXQvRhA6miHnNpXv7MRnnSjdRjK8og==",
|
||||||
|
"dev": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">=14"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/gregberge"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@babel/core": "^7.0.0-0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@svgr/babel-plugin-svg-em-dimensions": {
|
||||||
|
"version": "8.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-em-dimensions/-/babel-plugin-svg-em-dimensions-8.0.0.tgz",
|
||||||
|
"integrity": "sha512-mURHYnu6Iw3UBTbhGwE/vsngtCIbHE43xCRK7kCw4t01xyGqb2Pd+WXekRRoFOBIY29ZoOhUCTEweDMdrjfi9g==",
|
||||||
|
"dev": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">=14"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/gregberge"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@babel/core": "^7.0.0-0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@svgr/babel-plugin-transform-react-native-svg": {
|
||||||
|
"version": "8.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-react-native-svg/-/babel-plugin-transform-react-native-svg-8.1.0.tgz",
|
||||||
|
"integrity": "sha512-Tx8T58CHo+7nwJ+EhUwx3LfdNSG9R2OKfaIXXs5soiy5HtgoAEkDay9LIimLOcG8dJQH1wPZp/cnAv6S9CrR1Q==",
|
||||||
|
"dev": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">=14"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/gregberge"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@babel/core": "^7.0.0-0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@svgr/babel-plugin-transform-svg-component": {
|
||||||
|
"version": "8.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-svg-component/-/babel-plugin-transform-svg-component-8.0.0.tgz",
|
||||||
|
"integrity": "sha512-DFx8xa3cZXTdb/k3kfPeaixecQLgKh5NVBMwD0AQxOzcZawK4oo1Jh9LbrcACUivsCA7TLG8eeWgrDXjTMhRmw==",
|
||||||
|
"dev": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/gregberge"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@babel/core": "^7.0.0-0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@svgr/babel-preset": {
|
||||||
|
"version": "8.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@svgr/babel-preset/-/babel-preset-8.1.0.tgz",
|
||||||
|
"integrity": "sha512-7EYDbHE7MxHpv4sxvnVPngw5fuR6pw79SkcrILHJ/iMpuKySNCl5W1qcwPEpU+LgyRXOaAFgH0KhwD18wwg6ug==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@svgr/babel-plugin-add-jsx-attribute": "8.0.0",
|
||||||
|
"@svgr/babel-plugin-remove-jsx-attribute": "8.0.0",
|
||||||
|
"@svgr/babel-plugin-remove-jsx-empty-expression": "8.0.0",
|
||||||
|
"@svgr/babel-plugin-replace-jsx-attribute-value": "8.0.0",
|
||||||
|
"@svgr/babel-plugin-svg-dynamic-title": "8.0.0",
|
||||||
|
"@svgr/babel-plugin-svg-em-dimensions": "8.0.0",
|
||||||
|
"@svgr/babel-plugin-transform-react-native-svg": "8.1.0",
|
||||||
|
"@svgr/babel-plugin-transform-svg-component": "8.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=14"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/gregberge"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@babel/core": "^7.0.0-0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@svgr/core": {
|
||||||
|
"version": "8.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@svgr/core/-/core-8.1.0.tgz",
|
||||||
|
"integrity": "sha512-8QqtOQT5ACVlmsvKOJNEaWmRPmcojMOzCz4Hs2BGG/toAp/K38LcsMRyLp349glq5AzJbCEeimEoxaX6v/fLrA==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/core": "^7.21.3",
|
||||||
|
"@svgr/babel-preset": "8.1.0",
|
||||||
|
"camelcase": "^6.2.0",
|
||||||
|
"cosmiconfig": "^8.1.3",
|
||||||
|
"snake-case": "^3.0.4"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=14"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/gregberge"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@svgr/core/node_modules/cosmiconfig": {
|
||||||
|
"version": "8.3.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.6.tgz",
|
||||||
|
"integrity": "sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"import-fresh": "^3.3.0",
|
||||||
|
"js-yaml": "^4.1.0",
|
||||||
|
"parse-json": "^5.2.0",
|
||||||
|
"path-type": "^4.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=14"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/d-fischer"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"typescript": ">=4.9.5"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"typescript": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@svgr/hast-util-to-babel-ast": {
|
||||||
|
"version": "8.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@svgr/hast-util-to-babel-ast/-/hast-util-to-babel-ast-8.0.0.tgz",
|
||||||
|
"integrity": "sha512-EbDKwO9GpfWP4jN9sGdYwPBU0kdomaPIL2Eu4YwmgP+sJeXT+L7bMwJUBnhzfH8Q2qMBqZ4fJwpCyYsAN3mt2Q==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/types": "^7.21.3",
|
||||||
|
"entities": "^4.4.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=14"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/gregberge"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@svgr/plugin-jsx": {
|
||||||
|
"version": "8.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@svgr/plugin-jsx/-/plugin-jsx-8.1.0.tgz",
|
||||||
|
"integrity": "sha512-0xiIyBsLlr8quN+WyuxooNW9RJ0Dpr8uOnH/xrCVO8GLUcwHISwj1AG0k+LFzteTkAA0GbX0kj9q6Dk70PTiPA==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/core": "^7.21.3",
|
||||||
|
"@svgr/babel-preset": "8.1.0",
|
||||||
|
"@svgr/hast-util-to-babel-ast": "8.0.0",
|
||||||
|
"svg-parser": "^2.0.4"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=14"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/gregberge"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@svgr/core": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@tanstack/query-core": {
|
"node_modules/@tanstack/query-core": {
|
||||||
"version": "4.29.1",
|
"version": "4.29.1",
|
||||||
"resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-4.29.1.tgz",
|
"resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-4.29.1.tgz",
|
||||||
@@ -4969,6 +5209,18 @@
|
|||||||
"node": ">=6"
|
"node": ">=6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/camelcase": {
|
||||||
|
"version": "6.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz",
|
||||||
|
"integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==",
|
||||||
|
"dev": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/caniuse-lite": {
|
"node_modules/caniuse-lite": {
|
||||||
"version": "1.0.30001480",
|
"version": "1.0.30001480",
|
||||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001480.tgz",
|
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001480.tgz",
|
||||||
@@ -5399,6 +5651,16 @@
|
|||||||
"csstype": "^3.0.2"
|
"csstype": "^3.0.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/dot-case": {
|
||||||
|
"version": "3.0.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz",
|
||||||
|
"integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"no-case": "^3.0.4",
|
||||||
|
"tslib": "^2.0.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/duplexer": {
|
"node_modules/duplexer": {
|
||||||
"version": "0.1.2",
|
"version": "0.1.2",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
@@ -5431,6 +5693,18 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/entities": {
|
||||||
|
"version": "4.5.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
|
||||||
|
"integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
|
||||||
|
"dev": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.12"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/fb55/entities?sponsor=1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/error-ex": {
|
"node_modules/error-ex": {
|
||||||
"version": "1.3.2",
|
"version": "1.3.2",
|
||||||
"resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
|
"resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
|
||||||
@@ -6408,14 +6682,15 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/follow-redirects": {
|
"node_modules/follow-redirects": {
|
||||||
"version": "1.15.2",
|
"version": "1.15.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.4.tgz",
|
||||||
|
"integrity": "sha512-Cr4D/5wlrb0z9dgERpUL3LrmPKVDsETIJhaCMeDfuFYcqa5bldGV6wBsAN6X/vxlXQtFBMrXdXxdL8CbDTGniw==",
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
"type": "individual",
|
"type": "individual",
|
||||||
"url": "https://github.com/sponsors/RubenVerborgh"
|
"url": "https://github.com/sponsors/RubenVerborgh"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=4.0"
|
"node": ">=4.0"
|
||||||
},
|
},
|
||||||
@@ -7945,6 +8220,15 @@
|
|||||||
"loose-envify": "cli.js"
|
"loose-envify": "cli.js"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/lower-case": {
|
||||||
|
"version": "2.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz",
|
||||||
|
"integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"tslib": "^2.0.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/lru-cache": {
|
"node_modules/lru-cache": {
|
||||||
"version": "6.0.0",
|
"version": "6.0.0",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
@@ -8084,6 +8368,16 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/no-case": {
|
||||||
|
"version": "3.0.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz",
|
||||||
|
"integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"lower-case": "^2.0.2",
|
||||||
|
"tslib": "^2.0.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/node-fetch": {
|
"node_modules/node-fetch": {
|
||||||
"version": "2.6.7",
|
"version": "2.6.7",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
@@ -9368,6 +9662,16 @@
|
|||||||
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
|
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/snake-case": {
|
||||||
|
"version": "3.0.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/snake-case/-/snake-case-3.0.4.tgz",
|
||||||
|
"integrity": "sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"dot-case": "^3.0.4",
|
||||||
|
"tslib": "^2.0.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/source-map": {
|
"node_modules/source-map": {
|
||||||
"version": "0.5.7",
|
"version": "0.5.7",
|
||||||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
|
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
|
||||||
@@ -9695,6 +9999,12 @@
|
|||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/svg-parser": {
|
||||||
|
"version": "2.0.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/svg-parser/-/svg-parser-2.0.4.tgz",
|
||||||
|
"integrity": "sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"node_modules/temp": {
|
"node_modules/temp": {
|
||||||
"version": "0.9.4",
|
"version": "0.9.4",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
@@ -10208,6 +10518,20 @@
|
|||||||
"workbox-window": "^6.5.4"
|
"workbox-window": "^6.5.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/vite-plugin-svgr": {
|
||||||
|
"version": "4.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/vite-plugin-svgr/-/vite-plugin-svgr-4.2.0.tgz",
|
||||||
|
"integrity": "sha512-SC7+FfVtNQk7So0XMjrrtLAbEC8qjFPifyD7+fs/E6aaNdVde6umlVVh0QuwDLdOMu7vp5RiGFsB70nj5yo0XA==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@rollup/pluginutils": "^5.0.5",
|
||||||
|
"@svgr/core": "^8.1.0",
|
||||||
|
"@svgr/plugin-jsx": "^8.1.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"vite": "^2.6.0 || 3 || 4 || 5"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/vite-tsconfig-paths": {
|
"node_modules/vite-tsconfig-paths": {
|
||||||
"version": "4.2.0",
|
"version": "4.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/vite-tsconfig-paths/-/vite-tsconfig-paths-4.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/vite-tsconfig-paths/-/vite-tsconfig-paths-4.2.0.tgz",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "ucentral-client",
|
"name": "ucentral-client",
|
||||||
"version": "3.0.0(6)",
|
"version": "3.0.1(2)",
|
||||||
"description": "",
|
"description": "",
|
||||||
"private": true,
|
"private": true,
|
||||||
"main": "index.tsx",
|
"main": "index.tsx",
|
||||||
@@ -94,6 +94,7 @@
|
|||||||
"lint-staged": "^13.2.1",
|
"lint-staged": "^13.2.1",
|
||||||
"prettier": "^2.8.7",
|
"prettier": "^2.8.7",
|
||||||
"vite-plugin-pwa": "^0.14.7",
|
"vite-plugin-pwa": "^0.14.7",
|
||||||
|
"vite-plugin-svgr": "^4.2.0",
|
||||||
"vite-tsconfig-paths": "^4.2.0"
|
"vite-tsconfig-paths": "^4.2.0"
|
||||||
},
|
},
|
||||||
"browserslist": {
|
"browserslist": {
|
||||||
|
|||||||
BIN
public/devices/edgecore_ecs4125.png
Normal file
BIN
public/devices/edgecore_ecs4125.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 33 KiB |
@@ -54,6 +54,7 @@ const DeviceActionDropdown = ({
|
|||||||
}: Props) => {
|
}: Props) => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const toast = useToast();
|
const toast = useToast();
|
||||||
|
const deviceType = device?.deviceType ?? 'AP';
|
||||||
const connectColor = useColorModeValue('blackAlpha', 'gray');
|
const connectColor = useColorModeValue('blackAlpha', 'gray');
|
||||||
const addEventListeners = useControllerStore((state) => state.addEventListeners);
|
const addEventListeners = useControllerStore((state) => state.addEventListeners);
|
||||||
const { refetch: getRtty, isFetching: isRtty } = useGetDeviceRtty({
|
const { refetch: getRtty, isFetching: isRtty } = useGetDeviceRtty({
|
||||||
@@ -172,7 +173,7 @@ const DeviceActionDropdown = ({
|
|||||||
isLoading={isRtty}
|
isLoading={isRtty}
|
||||||
onClick={handleConnectClick}
|
onClick={handleConnectClick}
|
||||||
colorScheme={connectColor}
|
colorScheme={connectColor}
|
||||||
hidden={isCompact}
|
hidden={isCompact || deviceType !== 'AP'}
|
||||||
/>
|
/>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
<Tooltip label={t('controller.configure.title')}>
|
<Tooltip label={t('controller.configure.title')}>
|
||||||
@@ -205,7 +206,7 @@ const DeviceActionDropdown = ({
|
|||||||
isDisabled={isDisabled}
|
isDisabled={isDisabled}
|
||||||
onClick={handleOpenScan}
|
onClick={handleOpenScan}
|
||||||
colorScheme="teal"
|
colorScheme="teal"
|
||||||
hidden={isCompact}
|
hidden={isCompact || deviceType !== 'AP'}
|
||||||
/>
|
/>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
<Menu>
|
<Menu>
|
||||||
@@ -221,7 +222,7 @@ const DeviceActionDropdown = ({
|
|||||||
<Portal>
|
<Portal>
|
||||||
<MenuList maxH="315px" overflowY="auto">
|
<MenuList maxH="315px" overflowY="auto">
|
||||||
<MenuItem onClick={handleBlinkClick}>{t('commands.blink')}</MenuItem>
|
<MenuItem onClick={handleBlinkClick}>{t('commands.blink')}</MenuItem>
|
||||||
<MenuItem onClick={handleOpenConfigure} hidden={!isCompact}>
|
<MenuItem onClick={handleOpenConfigure} hidden={!isCompact || deviceType !== 'AP'}>
|
||||||
{t('controller.configure.title')}
|
{t('controller.configure.title')}
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
<MenuItem onClick={handleConnectClick} hidden={!isCompact}>
|
<MenuItem onClick={handleConnectClick} hidden={!isCompact}>
|
||||||
@@ -239,7 +240,7 @@ const DeviceActionDropdown = ({
|
|||||||
<MenuItem onClick={handleUpdateToLatest} hidden>
|
<MenuItem onClick={handleUpdateToLatest} hidden>
|
||||||
{t('premium.toolbox.upgrade_to_latest')}
|
{t('premium.toolbox.upgrade_to_latest')}
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
<MenuItem onClick={handleOpenScan} hidden={!isCompact}>
|
<MenuItem onClick={handleOpenScan} hidden={!isCompact || deviceType !== 'AP'}>
|
||||||
{t('commands.wifiscan')}
|
{t('commands.wifiscan')}
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
</MenuList>
|
</MenuList>
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ export const ResponsiveTag = React.memo(({ label, icon, tooltip, isCompact, ...p
|
|||||||
return (
|
return (
|
||||||
<Tooltip label={tooltip ?? label}>
|
<Tooltip label={tooltip ?? label}>
|
||||||
<Tag size="lg" colorScheme="blue" {...props}>
|
<Tag size="lg" colorScheme="blue" {...props}>
|
||||||
<TagLeftIcon boxSize="18px" as={icon} />
|
<TagLeftIcon boxSize="18px" as={icon} mt={-0.5} />
|
||||||
<TagLabel>{label}</TagLabel>
|
<TagLabel>{label}</TagLabel>
|
||||||
</Tag>
|
</Tag>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
|||||||
1
src/custom.d.ts
vendored
1
src/custom.d.ts
vendored
@@ -8,3 +8,4 @@ declare module '*.png' {
|
|||||||
const value: string;
|
const value: string;
|
||||||
export = value;
|
export = value;
|
||||||
}
|
}
|
||||||
|
/// <reference types="vite-plugin-svgr/client" />
|
||||||
|
|||||||
@@ -10,14 +10,19 @@ import { DeviceRttyApiResponse, GatewayDevice, WifiScanCommand, WifiScanResult }
|
|||||||
import { Note } from 'models/Note';
|
import { Note } from 'models/Note';
|
||||||
import { PageInfo } from 'models/Table';
|
import { PageInfo } from 'models/Table';
|
||||||
|
|
||||||
const getDeviceCount = () =>
|
export const DEVICE_PLATFORMS = ['ALL', 'AP', 'SWITCH'] as const;
|
||||||
axiosGw.get('devices?countOnly=true').then((response) => response.data) as Promise<{ count: number }>;
|
export type DevicePlatform = (typeof DEVICE_PLATFORMS)[number];
|
||||||
|
|
||||||
export const useGetDeviceCount = ({ enabled }: { enabled: boolean }) => {
|
const getDeviceCount = (platform: DevicePlatform) =>
|
||||||
|
axiosGw.get(`devices?countOnly=true&platform=${platform}`).then((response) => response.data) as Promise<{
|
||||||
|
count: number;
|
||||||
|
}>;
|
||||||
|
|
||||||
|
export const useGetDeviceCount = ({ enabled, platform = 'ALL' }: { enabled: boolean; platform?: DevicePlatform }) => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const toast = useToast();
|
const toast = useToast();
|
||||||
|
|
||||||
return useQuery(['devices', 'count'], getDeviceCount, {
|
return useQuery(['devices', 'count', { platform }], () => getDeviceCount(platform), {
|
||||||
enabled,
|
enabled,
|
||||||
onError: (e: AxiosError) => {
|
onError: (e: AxiosError) => {
|
||||||
if (!toast.isActive('inventory-fetching-error'))
|
if (!toast.isActive('inventory-fetching-error'))
|
||||||
@@ -96,25 +101,27 @@ export const getSingleDeviceWithStatus = (serialNumber: string) =>
|
|||||||
})
|
})
|
||||||
.catch(() => undefined);
|
.catch(() => undefined);
|
||||||
|
|
||||||
const getDevices = (limit: number, offset: number) =>
|
const getDevices = (limit: number, offset: number, platform: DevicePlatform) =>
|
||||||
axiosGw
|
axiosGw
|
||||||
.get(`devices?deviceWithStatus=true&limit=${limit}&offset=${offset}`)
|
.get(`devices?deviceWithStatus=true&limit=${limit}&offset=${offset}&platform=${platform}`)
|
||||||
.then((response) => response.data) as Promise<{ devicesWithStatus: DeviceWithStatus[] }>;
|
.then((response) => response.data) as Promise<{ devicesWithStatus: DeviceWithStatus[] }>;
|
||||||
|
|
||||||
export const useGetDevices = ({
|
export const useGetDevices = ({
|
||||||
pageInfo,
|
pageInfo,
|
||||||
enabled,
|
enabled,
|
||||||
onError,
|
onError,
|
||||||
|
platform = 'ALL',
|
||||||
}: {
|
}: {
|
||||||
pageInfo?: PageInfo;
|
pageInfo?: PageInfo;
|
||||||
enabled: boolean;
|
enabled: boolean;
|
||||||
onError?: (e: AxiosError) => void;
|
onError?: (e: AxiosError) => void;
|
||||||
|
platform?: DevicePlatform;
|
||||||
}) => {
|
}) => {
|
||||||
const offset = pageInfo?.limit !== undefined ? pageInfo.limit * pageInfo.index : 0;
|
const offset = pageInfo?.limit !== undefined ? pageInfo.limit * pageInfo.index : 0;
|
||||||
|
|
||||||
return useQuery(
|
return useQuery(
|
||||||
['devices', 'all', { limit: pageInfo?.limit, offset }],
|
['devices', 'all', { limit: pageInfo?.limit, offset, platform }],
|
||||||
() => getDevices(pageInfo?.limit || 0, offset),
|
() => getDevices(pageInfo?.limit || 0, offset, platform),
|
||||||
{
|
{
|
||||||
keepPreviousData: true,
|
keepPreviousData: true,
|
||||||
enabled: enabled && pageInfo !== undefined,
|
enabled: enabled && pageInfo !== undefined,
|
||||||
@@ -124,22 +131,28 @@ export const useGetDevices = ({
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const getAllDevices = async () => {
|
const getAllDevices = async (platform: DevicePlatform) => {
|
||||||
let offset = 0;
|
let offset = 0;
|
||||||
let devices: DeviceWithStatus[] = [];
|
let devices: DeviceWithStatus[] = [];
|
||||||
let devicesResponse: { devicesWithStatus: DeviceWithStatus[] };
|
let devicesResponse: { devicesWithStatus: DeviceWithStatus[] };
|
||||||
do {
|
do {
|
||||||
// eslint-disable-next-line no-await-in-loop
|
// eslint-disable-next-line no-await-in-loop
|
||||||
devicesResponse = await getDevices(500, offset);
|
devicesResponse = await getDevices(500, offset, platform);
|
||||||
devices = devices.concat(devicesResponse.devicesWithStatus);
|
devices = devices.concat(devicesResponse.devicesWithStatus);
|
||||||
offset += 500;
|
offset += 500;
|
||||||
} while (devicesResponse.devicesWithStatus.length === 500);
|
} while (devicesResponse.devicesWithStatus.length === 500);
|
||||||
return devices;
|
return devices;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useGetAllDevicesWithStatus = ({ onError }: { onError?: (e: AxiosError) => void }) => {
|
export const useGetAllDevicesWithStatus = ({
|
||||||
|
onError,
|
||||||
|
platform = 'ALL',
|
||||||
|
}: {
|
||||||
|
onError?: (e: AxiosError) => void;
|
||||||
|
platform?: DevicePlatform;
|
||||||
|
}) => {
|
||||||
const { isReady } = useEndpointStatus('owgw');
|
const { isReady } = useEndpointStatus('owgw');
|
||||||
return useQuery(['devices', 'all', 'full'], getAllDevices, {
|
return useQuery(['devices', 'all', 'full', { platform }], () => getAllDevices(platform), {
|
||||||
enabled: isReady && false,
|
enabled: isReady && false,
|
||||||
onError,
|
onError,
|
||||||
});
|
});
|
||||||
@@ -432,3 +445,19 @@ export const useUpdateDevice = ({ serialNumber }: { serialNumber: string }) => {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const deleteDeviceBatch = async (pattern: string) => {
|
||||||
|
if (pattern.length < 6) throw new Error('Pattern must be at least 6 characters long');
|
||||||
|
|
||||||
|
axiosGw.delete(`devices?macPattern=${pattern}`);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const useDeleteDeviceBatch = () => {
|
||||||
|
const queryClient = useQueryClient();
|
||||||
|
|
||||||
|
return useMutation(deleteDeviceBatch, {
|
||||||
|
onSuccess: () => {
|
||||||
|
queryClient.invalidateQueries(['devices']);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|||||||
@@ -2,7 +2,24 @@ import { useQuery } from '@tanstack/react-query';
|
|||||||
import { axiosGw } from 'constants/axiosInstances';
|
import { axiosGw } from 'constants/axiosInstances';
|
||||||
import { AxiosError } from 'models/Axios';
|
import { AxiosError } from 'models/Axios';
|
||||||
|
|
||||||
type DeviceInterfaceStatistics = {
|
export type DeviceLinkState = {
|
||||||
|
carrier?: number;
|
||||||
|
counters?: {
|
||||||
|
collisions: number;
|
||||||
|
multicast: number;
|
||||||
|
rx_bytes: number;
|
||||||
|
rx_dropped: number;
|
||||||
|
rx_errors: number;
|
||||||
|
rx_packets: number;
|
||||||
|
tx_bytes: number;
|
||||||
|
tx_dropped: number;
|
||||||
|
tx_errors: number;
|
||||||
|
tx_packets: number;
|
||||||
|
};
|
||||||
|
duplex?: string;
|
||||||
|
speed?: number;
|
||||||
|
};
|
||||||
|
export type DeviceInterfaceStatistics = {
|
||||||
clients: {
|
clients: {
|
||||||
ipv4_addresses?: string[];
|
ipv4_addresses?: string[];
|
||||||
ipv6_addresses?: string[];
|
ipv6_addresses?: string[];
|
||||||
@@ -138,18 +155,10 @@ export type DeviceStatistics = {
|
|||||||
};
|
};
|
||||||
'link-state'?: {
|
'link-state'?: {
|
||||||
downstream: {
|
downstream: {
|
||||||
eth1?: {
|
[key: string]: DeviceLinkState;
|
||||||
carrier?: number;
|
|
||||||
duplex?: string;
|
|
||||||
speed?: number;
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
upstream: {
|
upstream: {
|
||||||
eth0?: {
|
[key: string]: DeviceLinkState;
|
||||||
carrier?: number;
|
|
||||||
duplex?: string;
|
|
||||||
speed?: number;
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
'lldp-peers'?: {
|
'lldp-peers'?: {
|
||||||
@@ -190,6 +199,7 @@ export const useGetDeviceLastStats = ({
|
|||||||
useQuery(['device', serialNumber, 'last-statistics'], () => getLastStats(serialNumber), {
|
useQuery(['device', serialNumber, 'last-statistics'], () => getLastStats(serialNumber), {
|
||||||
enabled: serialNumber !== undefined && serialNumber !== '',
|
enabled: serialNumber !== undefined && serialNumber !== '',
|
||||||
staleTime: 1000 * 60,
|
staleTime: 1000 * 60,
|
||||||
|
refetchInterval: 1000 * 60,
|
||||||
onError,
|
onError,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
182
src/pages/Device/SwitchPortExamination/LinkStateTable.tsx
Normal file
182
src/pages/Device/SwitchPortExamination/LinkStateTable.tsx
Normal file
@@ -0,0 +1,182 @@
|
|||||||
|
import * as React from 'react';
|
||||||
|
import { Alert, AlertDescription, AlertIcon, Center } from '@chakra-ui/react';
|
||||||
|
import { DeviceLinkState } from 'hooks/Network/Statistics';
|
||||||
|
import DataCell from 'components/TableCells/DataCell';
|
||||||
|
import { DataGridColumn, useDataGrid } from 'components/DataTables/DataGrid/useDataGrid';
|
||||||
|
import { DataGrid } from 'components/DataTables/DataGrid';
|
||||||
|
import { uppercaseFirstLetter } from 'helpers/stringHelper';
|
||||||
|
|
||||||
|
type Row = DeviceLinkState & { name: string };
|
||||||
|
const dataCell = (v: number) => <DataCell bytes={v} />;
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
statistics?: Row[];
|
||||||
|
refetch: () => void;
|
||||||
|
isFetching: boolean;
|
||||||
|
type: 'upstream' | 'downstream';
|
||||||
|
};
|
||||||
|
|
||||||
|
const LinkStateTable = ({ statistics, refetch, isFetching, type }: Props) => {
|
||||||
|
const tableController = useDataGrid({
|
||||||
|
tableSettingsId: 'switch.link-state.table',
|
||||||
|
defaultOrder: [
|
||||||
|
'carrier',
|
||||||
|
'name',
|
||||||
|
'duplex',
|
||||||
|
'speed',
|
||||||
|
'rx_bytes',
|
||||||
|
'rx_dropped',
|
||||||
|
'rx_error',
|
||||||
|
'rx_packets',
|
||||||
|
'tx_bytes',
|
||||||
|
'tx_dropped',
|
||||||
|
'tx_error',
|
||||||
|
],
|
||||||
|
defaultSortBy: [{ id: 'name', desc: false }],
|
||||||
|
});
|
||||||
|
|
||||||
|
const columns: DataGridColumn<Row>[] = React.useMemo(
|
||||||
|
(): DataGridColumn<Row>[] => [
|
||||||
|
{
|
||||||
|
id: 'carrier',
|
||||||
|
header: '',
|
||||||
|
accessorKey: '',
|
||||||
|
cell: ({ cell }) => (cell.row.original.carrier ? '🟢' : '🔴'),
|
||||||
|
meta: {
|
||||||
|
customWidth: '35px',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'name',
|
||||||
|
header: 'Name',
|
||||||
|
accessorKey: 'name',
|
||||||
|
meta: {
|
||||||
|
customWidth: '35px',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'duplex',
|
||||||
|
header: 'Duplex',
|
||||||
|
accessorKey: 'duplex',
|
||||||
|
cell: ({ cell }) => (cell.row.original.duplex ? uppercaseFirstLetter(cell.row.original.duplex) : '-'),
|
||||||
|
meta: {
|
||||||
|
customWidth: '35px',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'speed',
|
||||||
|
header: 'Speed',
|
||||||
|
accessorKey: 'speed',
|
||||||
|
cell: ({ cell }) => `${(cell.row.original.speed ?? 0) / 1000} Gbps`,
|
||||||
|
meta: {
|
||||||
|
customWidth: '35px',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'rx_bytes',
|
||||||
|
header: 'Rx',
|
||||||
|
accessorKey: 'rx_bytes',
|
||||||
|
cell: ({ cell }) => dataCell(cell.row.original.counters?.rx_bytes ?? 0),
|
||||||
|
meta: {
|
||||||
|
customWidth: '35px',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'rx_dropped',
|
||||||
|
header: 'Rx Dropped',
|
||||||
|
accessorKey: 'rx_dropped',
|
||||||
|
cell: ({ cell }) => dataCell(cell.row.original.counters?.rx_dropped ?? 0),
|
||||||
|
meta: {
|
||||||
|
customWidth: '35px',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'rx_error',
|
||||||
|
header: 'Rx Errors',
|
||||||
|
accessorKey: 'rx_error',
|
||||||
|
cell: ({ cell }) => dataCell(cell.row.original.counters?.rx_errors ?? 0),
|
||||||
|
meta: {
|
||||||
|
customWidth: '35px',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'rx_packets',
|
||||||
|
header: 'Rx Packets',
|
||||||
|
accessorKey: 'counters.rx_packets',
|
||||||
|
cell: ({ cell }) => (cell.row.original.counters?.rx_packets ?? 0).toLocaleString(),
|
||||||
|
meta: {
|
||||||
|
customWidth: '35px',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'tx_bytes',
|
||||||
|
header: 'Tx',
|
||||||
|
accessorKey: 'tx_bytes',
|
||||||
|
cell: ({ cell }) => dataCell(cell.row.original.counters?.tx_bytes ?? 0),
|
||||||
|
meta: {
|
||||||
|
customWidth: '35px',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'tx_dropped',
|
||||||
|
header: 'Tx Dropped',
|
||||||
|
accessorKey: 'tx_dropped',
|
||||||
|
cell: ({ cell }) => dataCell(cell.row.original.counters?.tx_dropped ?? 0),
|
||||||
|
meta: {
|
||||||
|
customWidth: '35px',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'tx_error',
|
||||||
|
header: 'Tx Errors',
|
||||||
|
accessorKey: 'tx_error',
|
||||||
|
cell: ({ cell }) => dataCell(cell.row.original.counters?.tx_errors ?? 0),
|
||||||
|
meta: {
|
||||||
|
customWidth: '35px',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'tx_packets',
|
||||||
|
header: 'Tx Packets',
|
||||||
|
accessorKey: 'counters.tx_packets',
|
||||||
|
cell: ({ cell }) => (cell.row.original.counters?.tx_packets ?? 0).toLocaleString(),
|
||||||
|
meta: {
|
||||||
|
customWidth: '35px',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
[],
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!statistics || statistics?.length === 0) {
|
||||||
|
return (
|
||||||
|
<Center>
|
||||||
|
<Alert status="info">
|
||||||
|
<AlertIcon />
|
||||||
|
<AlertDescription>
|
||||||
|
There are currently no {type} link-states provided in this devices statistics
|
||||||
|
</AlertDescription>
|
||||||
|
</Alert>
|
||||||
|
</Center>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<DataGrid<Row>
|
||||||
|
controller={tableController}
|
||||||
|
header={{
|
||||||
|
title: '',
|
||||||
|
objectListed: 'Statistics',
|
||||||
|
}}
|
||||||
|
columns={columns}
|
||||||
|
isLoading={isFetching}
|
||||||
|
data={statistics ?? []}
|
||||||
|
options={{
|
||||||
|
refetch,
|
||||||
|
isHidingControls: true,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default LinkStateTable;
|
||||||
170
src/pages/Device/SwitchPortExamination/SwitchInterfaceTable.tsx
Normal file
170
src/pages/Device/SwitchPortExamination/SwitchInterfaceTable.tsx
Normal file
@@ -0,0 +1,170 @@
|
|||||||
|
import * as React from 'react';
|
||||||
|
import { Alert, AlertDescription, AlertIcon, Center } from '@chakra-ui/react';
|
||||||
|
import { DeviceInterfaceStatistics, DeviceStatistics } from 'hooks/Network/Statistics';
|
||||||
|
import DataCell from 'components/TableCells/DataCell';
|
||||||
|
import { DataGridColumn, useDataGrid } from 'components/DataTables/DataGrid/useDataGrid';
|
||||||
|
import DurationCell from 'components/TableCells/DurationCell';
|
||||||
|
import { DataGrid } from 'components/DataTables/DataGrid';
|
||||||
|
|
||||||
|
const dataCell = (v: number) => <DataCell bytes={v} />;
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
statistics: DeviceStatistics;
|
||||||
|
refetch: () => void;
|
||||||
|
isFetching: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
const SwitchInterfaceTable = ({ statistics, refetch, isFetching }: Props) => {
|
||||||
|
const tableController = useDataGrid({
|
||||||
|
tableSettingsId: 'switch.interfaces.table',
|
||||||
|
defaultOrder: [
|
||||||
|
'name',
|
||||||
|
'uptime',
|
||||||
|
'clients',
|
||||||
|
'rx_bytes',
|
||||||
|
'rx_dropped',
|
||||||
|
'rx_error',
|
||||||
|
'rx_packets',
|
||||||
|
'tx_bytes',
|
||||||
|
'tx_dropped',
|
||||||
|
'tx_error',
|
||||||
|
],
|
||||||
|
defaultSortBy: [{ id: 'name', desc: false }],
|
||||||
|
});
|
||||||
|
|
||||||
|
const columns: DataGridColumn<DeviceInterfaceStatistics>[] = React.useMemo(
|
||||||
|
(): DataGridColumn<DeviceInterfaceStatistics>[] => [
|
||||||
|
{
|
||||||
|
id: 'name',
|
||||||
|
header: 'Name',
|
||||||
|
accessorKey: 'name',
|
||||||
|
meta: {
|
||||||
|
customWidth: '35px',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'uptime',
|
||||||
|
header: 'Uptime',
|
||||||
|
|
||||||
|
accessorKey: 'uptime',
|
||||||
|
cell: ({ cell }) => <DurationCell seconds={cell.row.original.uptime} />,
|
||||||
|
meta: {
|
||||||
|
customWidth: '35px',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'clients',
|
||||||
|
header: 'Clients',
|
||||||
|
|
||||||
|
accessorKey: 'clients',
|
||||||
|
cell: ({ cell }) => cell.row.original.clients?.length ?? 0,
|
||||||
|
meta: {
|
||||||
|
customWidth: '35px',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'rx_bytes',
|
||||||
|
header: 'Rx',
|
||||||
|
accessorKey: 'rx_bytes',
|
||||||
|
cell: ({ cell }) => dataCell(cell.row.original.counters?.rx_bytes ?? 0),
|
||||||
|
meta: {
|
||||||
|
customWidth: '35px',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'rx_dropped',
|
||||||
|
header: 'Rx Dropped',
|
||||||
|
accessorKey: 'rx_dropped',
|
||||||
|
cell: ({ cell }) => dataCell(cell.row.original.counters?.rx_dropped ?? 0),
|
||||||
|
meta: {
|
||||||
|
customWidth: '35px',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'rx_error',
|
||||||
|
header: 'Rx Errors',
|
||||||
|
accessorKey: 'rx_error',
|
||||||
|
cell: ({ cell }) => dataCell(cell.row.original.counters?.rx_errors ?? 0),
|
||||||
|
meta: {
|
||||||
|
customWidth: '35px',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'rx_packets',
|
||||||
|
header: 'Rx Packets',
|
||||||
|
accessorKey: 'counters.rx_packets',
|
||||||
|
cell: ({ cell }) => (cell.row.original.counters?.rx_packets ?? 0).toLocaleString(),
|
||||||
|
meta: {
|
||||||
|
customWidth: '35px',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'tx_bytes',
|
||||||
|
header: 'Tx',
|
||||||
|
accessorKey: 'tx_bytes',
|
||||||
|
cell: ({ cell }) => dataCell(cell.row.original.counters?.tx_bytes ?? 0),
|
||||||
|
meta: {
|
||||||
|
customWidth: '35px',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'tx_dropped',
|
||||||
|
header: 'Tx Dropped',
|
||||||
|
accessorKey: 'tx_dropped',
|
||||||
|
cell: ({ cell }) => dataCell(cell.row.original.counters?.tx_dropped ?? 0),
|
||||||
|
meta: {
|
||||||
|
customWidth: '35px',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'tx_error',
|
||||||
|
header: 'Tx Errors',
|
||||||
|
accessorKey: 'tx_error',
|
||||||
|
cell: ({ cell }) => dataCell(cell.row.original.counters?.tx_errors ?? 0),
|
||||||
|
meta: {
|
||||||
|
customWidth: '35px',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'tx_packets',
|
||||||
|
header: 'Tx Packets',
|
||||||
|
accessorKey: 'counters.tx_packets',
|
||||||
|
cell: ({ cell }) => (cell.row.original.counters?.tx_packets ?? 0).toLocaleString(),
|
||||||
|
meta: {
|
||||||
|
customWidth: '35px',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
[],
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!statistics.interfaces) {
|
||||||
|
return (
|
||||||
|
<Center>
|
||||||
|
<Alert status="info">
|
||||||
|
<AlertIcon />
|
||||||
|
<AlertDescription>There are currently no interfaces provided in this devices statistics</AlertDescription>
|
||||||
|
</Alert>
|
||||||
|
</Center>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<DataGrid<DeviceInterfaceStatistics>
|
||||||
|
controller={tableController}
|
||||||
|
header={{
|
||||||
|
title: '',
|
||||||
|
objectListed: 'Statistics',
|
||||||
|
}}
|
||||||
|
columns={columns}
|
||||||
|
isLoading={isFetching}
|
||||||
|
data={statistics.interfaces ?? []}
|
||||||
|
options={{
|
||||||
|
refetch,
|
||||||
|
isHidingControls: true,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default SwitchInterfaceTable;
|
||||||
96
src/pages/Device/SwitchPortExamination/index.tsx
Normal file
96
src/pages/Device/SwitchPortExamination/index.tsx
Normal file
@@ -0,0 +1,96 @@
|
|||||||
|
import * as React from 'react';
|
||||||
|
import { Spinner, Tab, TabList, TabPanel, TabPanels, Tabs } from '@chakra-ui/react';
|
||||||
|
import LinkStateTable from './LinkStateTable';
|
||||||
|
import SwitchInterfaceTable from './SwitchInterfaceTable';
|
||||||
|
import { DeviceLinkState, useGetDeviceLastStats } from 'hooks/Network/Statistics';
|
||||||
|
import { Card } from 'components/Containers/Card';
|
||||||
|
import { CardBody } from 'components/Containers/Card/CardBody';
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
serialNumber: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
const SwitchPortExamination = ({ serialNumber }: Props) => {
|
||||||
|
const [tabIndex, setTabIndex] = React.useState(0);
|
||||||
|
|
||||||
|
const handleTabsChange = React.useCallback((index: number) => {
|
||||||
|
setTabIndex(index);
|
||||||
|
}, []);
|
||||||
|
const getStats = useGetDeviceLastStats({ serialNumber });
|
||||||
|
|
||||||
|
const upLinkStates: (DeviceLinkState & { name: string })[] = React.useMemo(() => {
|
||||||
|
if (!getStats.data || !getStats.data['link-state']?.upstream) return [];
|
||||||
|
|
||||||
|
return Object.entries(getStats.data['link-state']?.upstream).map(([name, value]) => ({
|
||||||
|
...value,
|
||||||
|
name,
|
||||||
|
}));
|
||||||
|
}, [getStats.data]);
|
||||||
|
const downLinkStates: (DeviceLinkState & { name: string })[] = React.useMemo(() => {
|
||||||
|
if (!getStats.data || !getStats.data['link-state']?.downstream) return [];
|
||||||
|
|
||||||
|
return Object.entries(getStats.data['link-state']?.downstream).map(([name, value]) => ({
|
||||||
|
...value,
|
||||||
|
name,
|
||||||
|
}));
|
||||||
|
}, [getStats.data]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Card p={0} mb={4}>
|
||||||
|
<CardBody p={0} display="block">
|
||||||
|
<Tabs index={tabIndex} onChange={handleTabsChange} variant="enclosed" w="100%">
|
||||||
|
<TabList>
|
||||||
|
<Tab fontSize="lg" fontWeight="bold">
|
||||||
|
Interfaces
|
||||||
|
</Tab>
|
||||||
|
<Tab fontSize="lg" fontWeight="bold">
|
||||||
|
Link-State (Up)
|
||||||
|
</Tab>
|
||||||
|
<Tab fontSize="lg" fontWeight="bold">
|
||||||
|
Link-State (Down)
|
||||||
|
</Tab>
|
||||||
|
</TabList>
|
||||||
|
<TabPanels>
|
||||||
|
<TabPanel>
|
||||||
|
{getStats.data ? (
|
||||||
|
<SwitchInterfaceTable
|
||||||
|
statistics={getStats.data}
|
||||||
|
refetch={getStats.refetch}
|
||||||
|
isFetching={getStats.isFetching}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<Spinner size="xl" />
|
||||||
|
)}
|
||||||
|
</TabPanel>
|
||||||
|
<TabPanel>
|
||||||
|
{getStats.data ? (
|
||||||
|
<LinkStateTable
|
||||||
|
statistics={upLinkStates}
|
||||||
|
refetch={getStats.refetch}
|
||||||
|
isFetching={getStats.isFetching}
|
||||||
|
type="upstream"
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<Spinner size="xl" />
|
||||||
|
)}
|
||||||
|
</TabPanel>
|
||||||
|
<TabPanel>
|
||||||
|
{getStats.data ? (
|
||||||
|
<LinkStateTable
|
||||||
|
statistics={downLinkStates}
|
||||||
|
refetch={getStats.refetch}
|
||||||
|
isFetching={getStats.isFetching}
|
||||||
|
type="downstream"
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<Spinner size="xl" />
|
||||||
|
)}
|
||||||
|
</TabPanel>
|
||||||
|
</TabPanels>
|
||||||
|
</Tabs>
|
||||||
|
</CardBody>
|
||||||
|
</Card>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default SwitchPortExamination;
|
||||||
@@ -42,10 +42,13 @@ import FactoryResetModal from 'components/Modals/FactoryResetModal';
|
|||||||
import { FirmwareUpgradeModal } from 'components/Modals/FirmwareUpgradeModal';
|
import { FirmwareUpgradeModal } from 'components/Modals/FirmwareUpgradeModal';
|
||||||
import { RebootModal } from 'components/Modals/RebootModal';
|
import { RebootModal } from 'components/Modals/RebootModal';
|
||||||
import { useScriptModal } from 'components/Modals/ScriptModal/useScriptModal';
|
import { useScriptModal } from 'components/Modals/ScriptModal/useScriptModal';
|
||||||
|
import ethernetConnected from './ethernetIconConnected.svg?react';
|
||||||
|
import ethernetDisconnected from './ethernetIconDisconnected.svg?react';
|
||||||
import { TelemetryModal } from 'components/Modals/TelemetryModal';
|
import { TelemetryModal } from 'components/Modals/TelemetryModal';
|
||||||
import { TraceModal } from 'components/Modals/TraceModal';
|
import { TraceModal } from 'components/Modals/TraceModal';
|
||||||
import { WifiScanModal } from 'components/Modals/WifiScanModal';
|
import { WifiScanModal } from 'components/Modals/WifiScanModal';
|
||||||
import { useDeleteDevice, useGetDevice, useGetDeviceHealthChecks, useGetDeviceStatus } from 'hooks/Network/Devices';
|
import { useDeleteDevice, useGetDevice, useGetDeviceHealthChecks, useGetDeviceStatus } from 'hooks/Network/Devices';
|
||||||
|
import SwitchPortExamination from './SwitchPortExamination';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
serialNumber: string;
|
serialNumber: string;
|
||||||
@@ -119,11 +122,15 @@ const DevicePageWrapper = ({ serialNumber }: Props) => {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let icon = getStatus.data.connected ? WifiHigh : WifiSlash;
|
||||||
|
if (getDevice.data?.deviceType === 'SWITCH')
|
||||||
|
icon = getStatus.data.connected ? ethernetConnected : ethernetDisconnected;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ResponsiveTag
|
<ResponsiveTag
|
||||||
label={getStatus?.data?.connected ? t('common.connected') : t('common.disconnected')}
|
label={getStatus?.data?.connected ? t('common.connected') : t('common.disconnected')}
|
||||||
colorScheme={getStatus?.data?.connected ? 'green' : 'red'}
|
colorScheme={getStatus?.data?.connected ? 'green' : 'red'}
|
||||||
icon={getStatus.data.connected ? WifiHigh : WifiSlash}
|
icon={icon}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}, [getStatus.data, getDevice.data]);
|
}, [getStatus.data, getDevice.data]);
|
||||||
@@ -318,7 +325,11 @@ const DevicePageWrapper = ({ serialNumber }: Props) => {
|
|||||||
<DeviceSummary serialNumber={serialNumber} />
|
<DeviceSummary serialNumber={serialNumber} />
|
||||||
<DeviceDetails serialNumber={serialNumber} />
|
<DeviceDetails serialNumber={serialNumber} />
|
||||||
<DeviceStatisticsCard serialNumber={serialNumber} />
|
<DeviceStatisticsCard serialNumber={serialNumber} />
|
||||||
<WifiAnalysisCard serialNumber={serialNumber} />
|
{getDevice.data?.deviceType === 'AP' ? (
|
||||||
|
<WifiAnalysisCard serialNumber={serialNumber} />
|
||||||
|
) : (
|
||||||
|
<SwitchPortExamination serialNumber={serialNumber} />
|
||||||
|
)}
|
||||||
<DeviceLogsCard serialNumber={serialNumber} />
|
<DeviceLogsCard serialNumber={serialNumber} />
|
||||||
{getDevice.data && getDevice.data?.hasRADIUSSessions > 0 ? (
|
{getDevice.data && getDevice.data?.hasRADIUSSessions > 0 ? (
|
||||||
<RadiusClientsCard serialNumber={serialNumber} />
|
<RadiusClientsCard serialNumber={serialNumber} />
|
||||||
|
|||||||
2
src/pages/Device/ethernetIconConnected.svg
Normal file
2
src/pages/Device/ethernetIconConnected.svg
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<svg viewBox="0 0 24 24" id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg"><defs><style>.cls-1{fill:none;stroke:#48BB78;stroke-miterlimit:10;stroke-width:1.91px;}</style></defs><rect class="cls-1" x="1.5" y="1.5" width="21" height="21" rx="1.91"/><polygon class="cls-1" points="5.32 6.27 5.32 13.91 7.23 13.91 7.23 15.82 10.09 15.82 10.09 17.73 13.91 17.73 13.91 15.82 16.77 15.82 16.77 13.91 18.68 13.91 18.68 6.27 5.32 6.27"/><line class="cls-1" x1="8.18" y1="9.14" x2="8.18" y2="6.27"/><line class="cls-1" x1="12" y1="9.14" x2="12" y2="6.27"/><line class="cls-1" x1="15.82" y1="9.14" x2="15.82" y2="6.27"/></svg>
|
||||||
|
After Width: | Height: | Size: 673 B |
2
src/pages/Device/ethernetIconDisconnected.svg
Normal file
2
src/pages/Device/ethernetIconDisconnected.svg
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<svg viewBox="0 0 24 24" id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg"><defs><style>.cls-1{fill:none;stroke:#FC8181;stroke-miterlimit:10;stroke-width:1.91px;}</style></defs><rect class="cls-1" x="1.5" y="1.5" width="21" height="21" rx="1.91"/><polygon class="cls-1" points="5.32 6.27 5.32 13.91 7.23 13.91 7.23 15.82 10.09 15.82 10.09 17.73 13.91 17.73 13.91 15.82 16.77 15.82 16.77 13.91 18.68 13.91 18.68 6.27 5.32 6.27"/><line class="cls-1" x1="8.18" y1="9.14" x2="8.18" y2="6.27"/><line class="cls-1" x1="12" y1="9.14" x2="12" y2="6.27"/><line class="cls-1" x1="15.82" y1="9.14" x2="15.82" y2="6.27"/></svg>
|
||||||
|
After Width: | Height: | Size: 673 B |
Binary file not shown.
|
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 3.1 KiB |
@@ -1,5 +1,16 @@
|
|||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import { Box, Center, Image, Link, Tag, TagLabel, TagRightIcon, Tooltip, useDisclosure } from '@chakra-ui/react';
|
import {
|
||||||
|
Box,
|
||||||
|
Center,
|
||||||
|
Image,
|
||||||
|
Link,
|
||||||
|
Select,
|
||||||
|
Tag,
|
||||||
|
TagLabel,
|
||||||
|
TagRightIcon,
|
||||||
|
Tooltip,
|
||||||
|
useDisclosure,
|
||||||
|
} from '@chakra-ui/react';
|
||||||
import {
|
import {
|
||||||
CheckCircle,
|
CheckCircle,
|
||||||
Heart,
|
Heart,
|
||||||
@@ -38,7 +49,7 @@ import { TraceModal } from 'components/Modals/TraceModal';
|
|||||||
import { WifiScanModal } from 'components/Modals/WifiScanModal';
|
import { WifiScanModal } from 'components/Modals/WifiScanModal';
|
||||||
import DataCell from 'components/TableCells/DataCell';
|
import DataCell from 'components/TableCells/DataCell';
|
||||||
import NumberCell from 'components/TableCells/NumberCell';
|
import NumberCell from 'components/TableCells/NumberCell';
|
||||||
import { DeviceWithStatus, useGetDeviceCount, useGetDevices } from 'hooks/Network/Devices';
|
import { DevicePlatform, DeviceWithStatus, useGetDeviceCount, useGetDevices } from 'hooks/Network/Devices';
|
||||||
import { FirmwareAgeResponse, useGetFirmwareAges } from 'hooks/Network/Firmware';
|
import { FirmwareAgeResponse, useGetFirmwareAges } from 'hooks/Network/Firmware';
|
||||||
|
|
||||||
const fourDigitNumber = (v?: number) => {
|
const fourDigitNumber = (v?: number) => {
|
||||||
@@ -72,6 +83,7 @@ const DeviceListCard = () => {
|
|||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const [serialNumber, setSerialNumber] = React.useState<string>('');
|
const [serialNumber, setSerialNumber] = React.useState<string>('');
|
||||||
|
const [platform, setPlatform] = React.useState<DevicePlatform>('ALL');
|
||||||
const scanModalProps = useDisclosure();
|
const scanModalProps = useDisclosure();
|
||||||
const resetModalProps = useDisclosure();
|
const resetModalProps = useDisclosure();
|
||||||
const upgradeModalProps = useDisclosure();
|
const upgradeModalProps = useDisclosure();
|
||||||
@@ -110,13 +122,14 @@ const DeviceListCard = () => {
|
|||||||
'actions',
|
'actions',
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
const getCount = useGetDeviceCount({ enabled: true });
|
const getCount = useGetDeviceCount({ enabled: true, platform });
|
||||||
const getDevices = useGetDevices({
|
const getDevices = useGetDevices({
|
||||||
pageInfo: {
|
pageInfo: {
|
||||||
limit: tableController.pageInfo.pageSize,
|
limit: tableController.pageInfo.pageSize,
|
||||||
index: tableController.pageInfo.pageIndex,
|
index: tableController.pageInfo.pageIndex,
|
||||||
},
|
},
|
||||||
enabled: true,
|
enabled: true,
|
||||||
|
platform,
|
||||||
});
|
});
|
||||||
const getAges = useGetFirmwareAges({
|
const getAges = useGetFirmwareAges({
|
||||||
serialNumbers: getDevices.data?.devicesWithStatus.map((device) => device.serialNumber),
|
serialNumbers: getDevices.data?.devicesWithStatus.map((device) => device.serialNumber),
|
||||||
@@ -556,12 +569,7 @@ const DeviceListCard = () => {
|
|||||||
header: t('analytics.last_connected'),
|
header: t('analytics.last_connected'),
|
||||||
footer: '',
|
footer: '',
|
||||||
accessorKey: 'lastRecordedContact',
|
accessorKey: 'lastRecordedContact',
|
||||||
cell: (v) =>
|
cell: (v) => dateCell(v.cell.row.original.lastRecordedContact),
|
||||||
dateCell(
|
|
||||||
v.cell.row.original.lastContact !== 0
|
|
||||||
? v.cell.row.original.lastContact
|
|
||||||
: v.cell.row.original.lastRecordedContact,
|
|
||||||
),
|
|
||||||
enableSorting: false,
|
enableSorting: false,
|
||||||
meta: {
|
meta: {
|
||||||
headerOptions: {
|
headerOptions: {
|
||||||
@@ -719,7 +727,21 @@ const DeviceListCard = () => {
|
|||||||
header={{
|
header={{
|
||||||
title: `${getCount.data?.count ?? 0} ${t('devices.title')}`,
|
title: `${getCount.data?.count ?? 0} ${t('devices.title')}`,
|
||||||
objectListed: t('devices.title'),
|
objectListed: t('devices.title'),
|
||||||
leftContent: <GlobalSearchBar />,
|
leftContent: (
|
||||||
|
<>
|
||||||
|
<GlobalSearchBar />
|
||||||
|
<Select
|
||||||
|
value={platform}
|
||||||
|
onChange={(e) => setPlatform(e.target.value as DevicePlatform)}
|
||||||
|
w="max-content"
|
||||||
|
ml={2}
|
||||||
|
>
|
||||||
|
<option value="ALL">All</option>
|
||||||
|
<option value="AP">APs</option>
|
||||||
|
<option value="SWITCH">Switches</option>
|
||||||
|
</Select>
|
||||||
|
</>
|
||||||
|
),
|
||||||
otherButtons: (
|
otherButtons: (
|
||||||
<ExportDevicesTableButton currentPageSerialNumbers={data.map((device) => device.serialNumber)} />
|
<ExportDevicesTableButton currentPageSerialNumbers={data.map((device) => device.serialNumber)} />
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import { defineConfig } from 'vite';
|
|||||||
import tsconfigPaths from 'vite-tsconfig-paths';
|
import tsconfigPaths from 'vite-tsconfig-paths';
|
||||||
import react from '@vitejs/plugin-react';
|
import react from '@vitejs/plugin-react';
|
||||||
import { VitePWA } from 'vite-plugin-pwa';
|
import { VitePWA } from 'vite-plugin-pwa';
|
||||||
|
import svgr from 'vite-plugin-svgr';
|
||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
plugins: [
|
plugins: [
|
||||||
@@ -15,10 +16,11 @@ export default defineConfig({
|
|||||||
/* other options */
|
/* other options */
|
||||||
},
|
},
|
||||||
manifest: {
|
manifest: {
|
||||||
name: 'OpenWiFi Controller App',
|
name: 'Arilia Controller App',
|
||||||
short_name: 'OpenWiFiController',
|
short_name: 'AriController',
|
||||||
description: 'OpenWiFi Controller App',
|
description: 'Arilia Controller Work App',
|
||||||
theme_color: '#000000',
|
theme_color: '#000000',
|
||||||
|
|
||||||
icons: [
|
icons: [
|
||||||
{
|
{
|
||||||
src: 'android-chrome-192x192.png',
|
src: 'android-chrome-192x192.png',
|
||||||
@@ -44,13 +46,14 @@ export default defineConfig({
|
|||||||
],
|
],
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
|
svgr(),
|
||||||
],
|
],
|
||||||
build: {
|
build: {
|
||||||
outDir: './build',
|
outDir: './build',
|
||||||
chunkSizeWarningLimit: 1000,
|
chunkSizeWarningLimit: 1000,
|
||||||
},
|
},
|
||||||
server: {
|
server: {
|
||||||
port: 3000,
|
port: 3001,
|
||||||
open: true,
|
open: true,
|
||||||
},
|
},
|
||||||
esbuild: {
|
esbuild: {
|
||||||
|
|||||||
Reference in New Issue
Block a user