Add restart service for esp8266 and esp32
Add restart feature to status screen Upgrade material-ui Add icons to buttons
This commit is contained in:
parent
69caa841a3
commit
78b9ae101e
188
interface/package-lock.json
generated
188
interface/package-lock.json
generated
@ -1184,21 +1184,19 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@material-ui/core": {
|
"@material-ui/core": {
|
||||||
"version": "4.4.3",
|
"version": "4.7.0",
|
||||||
"resolved": "https://registry.npmjs.org/@material-ui/core/-/core-4.4.3.tgz",
|
"resolved": "https://registry.npmjs.org/@material-ui/core/-/core-4.7.0.tgz",
|
||||||
"integrity": "sha512-Lz8sMFeCrtq5/pbhqClWFHpveL0huixjca0tw7uvh9xKKB7VyyYOyTu7RamSZLxb34UCSMPlobR+KK25Nqzkqw==",
|
"integrity": "sha512-mwLehUo0Q9ZxjuWo7J1uy1/Grh3nRxlOAaWJ3EtKeJP2HwqlSy8bWrcvRQYlapaYIPXa5jN8zWbTwi8Pk30VQg==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@babel/runtime": "^7.4.4",
|
"@babel/runtime": "^7.4.4",
|
||||||
"@material-ui/styles": "^4.4.3",
|
"@material-ui/styles": "^4.6.0",
|
||||||
"@material-ui/system": "^4.4.3",
|
"@material-ui/system": "^4.5.2",
|
||||||
"@material-ui/types": "^4.1.1",
|
"@material-ui/types": "^4.1.1",
|
||||||
"@material-ui/utils": "^4.4.0",
|
"@material-ui/utils": "^4.5.2",
|
||||||
"@types/react-transition-group": "^4.2.0",
|
"@types/react-transition-group": "^4.2.0",
|
||||||
"clsx": "^1.0.2",
|
"clsx": "^1.0.2",
|
||||||
"convert-css-length": "^2.0.1",
|
"convert-css-length": "^2.0.1",
|
||||||
"deepmerge": "^4.0.0",
|
|
||||||
"hoist-non-react-statics": "^3.2.1",
|
"hoist-non-react-statics": "^3.2.1",
|
||||||
"is-plain-object": "^3.0.0",
|
|
||||||
"normalize-scroll-left": "^0.2.0",
|
"normalize-scroll-left": "^0.2.0",
|
||||||
"popper.js": "^1.14.1",
|
"popper.js": "^1.14.1",
|
||||||
"prop-types": "^15.7.2",
|
"prop-types": "^15.7.2",
|
||||||
@ -1206,44 +1204,43 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@material-ui/icons": {
|
"@material-ui/icons": {
|
||||||
"version": "4.4.3",
|
"version": "4.5.1",
|
||||||
"resolved": "https://registry.npmjs.org/@material-ui/icons/-/icons-4.4.3.tgz",
|
"resolved": "https://registry.npmjs.org/@material-ui/icons/-/icons-4.5.1.tgz",
|
||||||
"integrity": "sha512-HVVvUyc/78kmaBd93LkfWyGkXMM+zOMKzUfulWXxaV/fFAZ3N0pD0oHjWUd94zrOoF3tZP9JC7EPlIpIcZSNow==",
|
"integrity": "sha512-YZ/BgJbXX4a0gOuKWb30mBaHaoXRqPanlePam83JQPZ/y4kl+3aW0Wv9tlR70hB5EGAkEJGW5m4ktJwMgxQAeA==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@babel/runtime": "^7.4.4"
|
"@babel/runtime": "^7.4.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@material-ui/styles": {
|
"@material-ui/styles": {
|
||||||
"version": "4.4.3",
|
"version": "4.6.0",
|
||||||
"resolved": "https://registry.npmjs.org/@material-ui/styles/-/styles-4.4.3.tgz",
|
"resolved": "https://registry.npmjs.org/@material-ui/styles/-/styles-4.6.0.tgz",
|
||||||
"integrity": "sha512-kNUdHFWsrvWKIEPx8Xy2/qayqsGMrYmCMq+FIiJiYczVZl5hiS8j5+KayonnpVta/O+Dktk+cxWkVcgwtxMrHg==",
|
"integrity": "sha512-lqqh4UEMdIYcU1Yth4pQyMTah02uAkg3NOT3MirN9FUexdL8pNA6zCHigEgDSfwmvnXyxHhxTkphfy0DRfnt9w==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@babel/runtime": "^7.4.4",
|
"@babel/runtime": "^7.4.4",
|
||||||
"@emotion/hash": "^0.7.1",
|
"@emotion/hash": "^0.7.1",
|
||||||
"@material-ui/types": "^4.1.1",
|
"@material-ui/types": "^4.1.1",
|
||||||
"@material-ui/utils": "^4.1.0",
|
"@material-ui/utils": "^4.5.2",
|
||||||
"clsx": "^1.0.2",
|
"clsx": "^1.0.2",
|
||||||
"csstype": "^2.5.2",
|
"csstype": "^2.5.2",
|
||||||
"deepmerge": "^4.0.0",
|
|
||||||
"hoist-non-react-statics": "^3.2.1",
|
"hoist-non-react-statics": "^3.2.1",
|
||||||
"jss": "10.0.0-alpha.25",
|
"jss": "^10.0.0",
|
||||||
"jss-plugin-camel-case": "10.0.0-alpha.25",
|
"jss-plugin-camel-case": "^10.0.0",
|
||||||
"jss-plugin-default-unit": "10.0.0-alpha.25",
|
"jss-plugin-default-unit": "^10.0.0",
|
||||||
"jss-plugin-global": "10.0.0-alpha.25",
|
"jss-plugin-global": "^10.0.0",
|
||||||
"jss-plugin-nested": "10.0.0-alpha.25",
|
"jss-plugin-nested": "^10.0.0",
|
||||||
"jss-plugin-props-sort": "10.0.0-alpha.25",
|
"jss-plugin-props-sort": "^10.0.0",
|
||||||
"jss-plugin-rule-value-function": "10.0.0-alpha.25",
|
"jss-plugin-rule-value-function": "^10.0.0",
|
||||||
"jss-plugin-vendor-prefixer": "10.0.0-alpha.25",
|
"jss-plugin-vendor-prefixer": "^10.0.0",
|
||||||
"prop-types": "^15.7.2"
|
"prop-types": "^15.7.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@material-ui/system": {
|
"@material-ui/system": {
|
||||||
"version": "4.4.3",
|
"version": "4.5.2",
|
||||||
"resolved": "https://registry.npmjs.org/@material-ui/system/-/system-4.4.3.tgz",
|
"resolved": "https://registry.npmjs.org/@material-ui/system/-/system-4.5.2.tgz",
|
||||||
"integrity": "sha512-Cb05vLXsaCzssXD/iZKa0/qC6YOwbFWnYdnOEdkXZ3Fn2Ytz7rsnMgFejUSQV1luVhUBlEIm8DVz40N25WwW7w==",
|
"integrity": "sha512-h9RWvdM9XKlHHqwiuhyvWdobptQkHli+m2jJFs7i1AI/hmGsIc4reDmS7fInhETgt/Txx7uiAIznfRNIIVHmQw==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@babel/runtime": "^7.4.4",
|
"@babel/runtime": "^7.4.4",
|
||||||
"deepmerge": "^4.0.0",
|
"@material-ui/utils": "^4.5.2",
|
||||||
"prop-types": "^15.7.2"
|
"prop-types": "^15.7.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -1256,9 +1253,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@material-ui/utils": {
|
"@material-ui/utils": {
|
||||||
"version": "4.4.0",
|
"version": "4.5.2",
|
||||||
"resolved": "https://registry.npmjs.org/@material-ui/utils/-/utils-4.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/@material-ui/utils/-/utils-4.5.2.tgz",
|
||||||
"integrity": "sha512-UXoQVwArQEQWXxf2FPs0iJGT+MePQpKr0Qh0CPoLc1OdF0GSMTmQczcqCzwZkeHxHAOq/NkIKM1Pb/ih1Avicg==",
|
"integrity": "sha512-zhbNfHd1gLa8At6RPDG7uMZubHxbY+LtM6IkSfeWi6Lo4Ax80l62YaN1QmUpO1IvGCkn/j62tQX3yObiQZrJsQ==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@babel/runtime": "^7.4.4",
|
"@babel/runtime": "^7.4.4",
|
||||||
"prop-types": "^15.7.2",
|
"prop-types": "^15.7.2",
|
||||||
@ -1486,18 +1483,18 @@
|
|||||||
"integrity": "sha512-ce5d3q03Ex0sy4R14722Rmt6MT07Ua+k4FwDfdcToYJcMKNtRVQvJ6JCAPdAmAnbRb6CsX6aYb9m96NGod9uTw=="
|
"integrity": "sha512-ce5d3q03Ex0sy4R14722Rmt6MT07Ua+k4FwDfdcToYJcMKNtRVQvJ6JCAPdAmAnbRb6CsX6aYb9m96NGod9uTw=="
|
||||||
},
|
},
|
||||||
"@types/react": {
|
"@types/react": {
|
||||||
"version": "16.9.4",
|
"version": "16.9.13",
|
||||||
"resolved": "https://registry.npmjs.org/@types/react/-/react-16.9.4.tgz",
|
"resolved": "https://registry.npmjs.org/@types/react/-/react-16.9.13.tgz",
|
||||||
"integrity": "sha512-ItGNmJvQ0IvWt8rbk5PLdpdQhvBVxAaXI9hDlx7UMd8Ie1iMIuwMNiKeTfmVN517CdplpyXvA22X4zm4jGGZnw==",
|
"integrity": "sha512-LikzRslbiufJYHyzbHSW0GrAiff8QYLMBFeZmSxzCYGXKxi8m/1PHX+rsVOwhr7mJNq+VIu2Dhf7U6mjFERK6w==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@types/prop-types": "*",
|
"@types/prop-types": "*",
|
||||||
"csstype": "^2.2.0"
|
"csstype": "^2.2.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@types/react-transition-group": {
|
"@types/react-transition-group": {
|
||||||
"version": "4.2.2",
|
"version": "4.2.3",
|
||||||
"resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.2.2.tgz",
|
"resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.2.3.tgz",
|
||||||
"integrity": "sha512-YfoaTNqBwbIqpiJ5NNfxfgg5kyFP1Hqf/jqBtSWNv0E+EkkxmN+3VD6U2fu86tlQvdAc1o0SdWhnWFwcRMTn9A==",
|
"integrity": "sha512-Hk8jiuT7iLOHrcjKP/ZVSyCNXK73wJAUz60xm0mVhiRujrdiI++j4duLiL282VGxwAgxetHQFfqA29LgEeSkFA==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@types/react": "*"
|
"@types/react": "*"
|
||||||
}
|
}
|
||||||
@ -4210,11 +4207,6 @@
|
|||||||
"resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz",
|
||||||
"integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ="
|
"integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ="
|
||||||
},
|
},
|
||||||
"deepmerge": {
|
|
||||||
"version": "4.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.0.0.tgz",
|
|
||||||
"integrity": "sha512-YZ1rOP5+kHor4hMAH+HRQnBQHg+wvS1un1hAOuIcxcBy0hzcUf6Jg2a1w65kpoOUnurOfZbERwjI1TfZxNjcww=="
|
|
||||||
},
|
|
||||||
"default-gateway": {
|
"default-gateway": {
|
||||||
"version": "4.2.0",
|
"version": "4.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-4.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-4.2.0.tgz",
|
||||||
@ -4439,12 +4431,27 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"dom-helpers": {
|
"dom-helpers": {
|
||||||
"version": "5.1.0",
|
"version": "5.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.1.3.tgz",
|
||||||
"integrity": "sha512-zRRYDhpiKuAJHasOqCm7lBnsd22nrM4+OYI4ASWCxen+ocTMl7BIAKgGag97TlLiTl6rrau5aPe1VGUm9jQBng==",
|
"integrity": "sha512-nZD1OtwfWGRBWlpANxacBEZrEuLa16o1nh7YopFWeoF68Zt8GGEmzHu6Xv4F3XaFIC+YXtTLrzgqKxFgLEe4jw==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@babel/runtime": "^7.5.5",
|
"@babel/runtime": "^7.6.3",
|
||||||
"csstype": "^2.6.6"
|
"csstype": "^2.6.7"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/runtime": {
|
||||||
|
"version": "7.7.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.7.4.tgz",
|
||||||
|
"integrity": "sha512-r24eVUUr0QqNZa+qrImUk8fn5SPhHq+IfYvIoIMg0do3GdK9sMdiLKP3GYVVaxpPKORgm8KRKaNTEhAjgIpLMw==",
|
||||||
|
"requires": {
|
||||||
|
"regenerator-runtime": "^0.13.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"csstype": {
|
||||||
|
"version": "2.6.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.7.tgz",
|
||||||
|
"integrity": "sha512-9Mcn9sFbGBAdmimWb2gLVDtFJzeKtDGIr76TUqmjZrw9LFXBMSU70lcs+C0/7fyCd6iBDqmksUcCOUIkisPHsQ=="
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"dom-serializer": {
|
"dom-serializer": {
|
||||||
@ -6548,14 +6555,6 @@
|
|||||||
"path-is-inside": "^1.0.1"
|
"path-is-inside": "^1.0.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"is-plain-object": {
|
|
||||||
"version": "3.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-3.0.0.tgz",
|
|
||||||
"integrity": "sha512-tZIpofR+P05k8Aocp7UI/2UTa9lTJSebCXpFFoR9aibpokDj/uXBsJ8luUu0tTVYKkMU6URDUuOfJZ7koewXvg==",
|
|
||||||
"requires": {
|
|
||||||
"isobject": "^4.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"is-promise": {
|
"is-promise": {
|
||||||
"version": "2.1.0",
|
"version": "2.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz",
|
||||||
@ -6630,11 +6629,6 @@
|
|||||||
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
|
||||||
"integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA="
|
"integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA="
|
||||||
},
|
},
|
||||||
"isobject": {
|
|
||||||
"version": "4.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/isobject/-/isobject-4.0.0.tgz",
|
|
||||||
"integrity": "sha512-S/2fF5wH8SJA/kmwr6HYhK/RI/OkhD84k8ntalo0iJjZikgq1XFvR5M8NPT1x5F7fBwCG3qHfnzeP/Vh/ZxCUA=="
|
|
||||||
},
|
|
||||||
"isstream": {
|
"isstream": {
|
||||||
"version": "0.1.2",
|
"version": "0.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
|
||||||
@ -7889,9 +7883,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"jss": {
|
"jss": {
|
||||||
"version": "10.0.0-alpha.25",
|
"version": "10.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/jss/-/jss-10.0.0-alpha.25.tgz",
|
"resolved": "https://registry.npmjs.org/jss/-/jss-10.0.0.tgz",
|
||||||
"integrity": "sha512-zqKnXv181B9vue2yYhmVhc+6ggbbxHF/33rjXfXEjaa22nOvknTI21QDfq3oZ8uCC50kcFp3Z8KU1ghUXdFvIA==",
|
"integrity": "sha512-TPpDFsiBjuERiL+dFDq8QCdiF9oDasPcNqCKLGCo/qED3fNYOQ8PX2lZhknyTiAt3tZrfOFbb0lbQ9lTjPZxsQ==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@babel/runtime": "^7.3.1",
|
"@babel/runtime": "^7.3.1",
|
||||||
"csstype": "^2.6.5",
|
"csstype": "^2.6.5",
|
||||||
@ -7900,13 +7894,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"jss-plugin-camel-case": {
|
"jss-plugin-camel-case": {
|
||||||
"version": "10.0.0-alpha.25",
|
"version": "10.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/jss-plugin-camel-case/-/jss-plugin-camel-case-10.0.0-alpha.25.tgz",
|
"resolved": "https://registry.npmjs.org/jss-plugin-camel-case/-/jss-plugin-camel-case-10.0.0.tgz",
|
||||||
"integrity": "sha512-J5ZEGDTy9ddqdTUPAF4SJQ25u5kiG1ORP8F+ZPEZAkkiMQJp+/Aol4I7xhTS2aW1Lhg8xNxdhdRfBi5yU7wOvg==",
|
"integrity": "sha512-yALDL00+pPR4FJh+k07A8FeDvfoPPuXU48HLy63enAubcVd3DnS+2rgqPXglHDGixIDVkCSXecl/l5GAMjzIbA==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@babel/runtime": "^7.3.1",
|
"@babel/runtime": "^7.3.1",
|
||||||
"hyphenate-style-name": "^1.0.3",
|
"hyphenate-style-name": "^1.0.3",
|
||||||
"jss": "10.0.0-alpha.25"
|
"jss": "10.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"jss-plugin-compose": {
|
"jss-plugin-compose": {
|
||||||
@ -7933,12 +7927,12 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"jss-plugin-default-unit": {
|
"jss-plugin-default-unit": {
|
||||||
"version": "10.0.0-alpha.25",
|
"version": "10.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/jss-plugin-default-unit/-/jss-plugin-default-unit-10.0.0-alpha.25.tgz",
|
"resolved": "https://registry.npmjs.org/jss-plugin-default-unit/-/jss-plugin-default-unit-10.0.0.tgz",
|
||||||
"integrity": "sha512-auOG459B+yEqkojgaXH02SYO9+xjmAxlmP+WbzhVpXqOFJ2CN/kaxd8P4NJZLdj3BQxHiM7WIyMVh786StE+EA==",
|
"integrity": "sha512-sURozIOdCtGg9ap18erQ+ijndAfEGtTaetxfU3H4qwC18Bi+fdvjlY/ahKbuu0ASs7R/+WKCP7UaRZOjUDMcdQ==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@babel/runtime": "^7.3.1",
|
"@babel/runtime": "^7.3.1",
|
||||||
"jss": "10.0.0-alpha.25"
|
"jss": "10.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"jss-plugin-expand": {
|
"jss-plugin-expand": {
|
||||||
@ -7987,40 +7981,40 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"jss-plugin-global": {
|
"jss-plugin-global": {
|
||||||
"version": "10.0.0-alpha.25",
|
"version": "10.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/jss-plugin-global/-/jss-plugin-global-10.0.0-alpha.25.tgz",
|
"resolved": "https://registry.npmjs.org/jss-plugin-global/-/jss-plugin-global-10.0.0.tgz",
|
||||||
"integrity": "sha512-cS98Q8X8jwltuaBZd9eYuxMXxkUL+mJGl2Ok3/nmJzH9nLzj6i7kLxSoDtuJNqsRmbP7ogIXVozJUq9lUu2hlQ==",
|
"integrity": "sha512-80ofWKSQUo62bxLtRoTNe0kFPtHgUbAJeOeR36WEGgWIBEsXLyXOnD5KNnjPqG4heuEkz9eSLccjYST50JnI7Q==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@babel/runtime": "^7.3.1",
|
"@babel/runtime": "^7.3.1",
|
||||||
"jss": "10.0.0-alpha.25"
|
"jss": "10.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"jss-plugin-nested": {
|
"jss-plugin-nested": {
|
||||||
"version": "10.0.0-alpha.25",
|
"version": "10.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/jss-plugin-nested/-/jss-plugin-nested-10.0.0-alpha.25.tgz",
|
"resolved": "https://registry.npmjs.org/jss-plugin-nested/-/jss-plugin-nested-10.0.0.tgz",
|
||||||
"integrity": "sha512-7sk7/6mX1YTgXe+AyeD1zEyKTgIGbbhYtg+wWQcHJlE1flW2JHfcQ5mw84FgHcHQRQ8Dq3l9I3aEY51ev0J1Wg==",
|
"integrity": "sha512-waxxwl/po1hN3azTyixKnr8ReEqUv5WK7WsO+5AWB0bFndML5Yqnt8ARZ90HEg8/P6WlqE/AB2413TkCRZE8bA==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@babel/runtime": "^7.3.1",
|
"@babel/runtime": "^7.3.1",
|
||||||
"jss": "10.0.0-alpha.25",
|
"jss": "10.0.0",
|
||||||
"tiny-warning": "^1.0.2"
|
"tiny-warning": "^1.0.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"jss-plugin-props-sort": {
|
"jss-plugin-props-sort": {
|
||||||
"version": "10.0.0-alpha.25",
|
"version": "10.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/jss-plugin-props-sort/-/jss-plugin-props-sort-10.0.0-alpha.25.tgz",
|
"resolved": "https://registry.npmjs.org/jss-plugin-props-sort/-/jss-plugin-props-sort-10.0.0.tgz",
|
||||||
"integrity": "sha512-8B/6QLQuUX8cIlZbXdjEm5l0jCX4EgacYMcFJhdKwDKEZYeAghpgQQrCKl0/CYHW7iFge5wim67P+uL6QxMzyw==",
|
"integrity": "sha512-41mf22CImjwNdtOG3r+cdC8+RhwNm616sjHx5YlqTwtSJLyLFinbQC/a4PIFk8xqf1qpFH1kEAIw+yx9HaqZ3g==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@babel/runtime": "^7.3.1",
|
"@babel/runtime": "^7.3.1",
|
||||||
"jss": "10.0.0-alpha.25"
|
"jss": "10.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"jss-plugin-rule-value-function": {
|
"jss-plugin-rule-value-function": {
|
||||||
"version": "10.0.0-alpha.25",
|
"version": "10.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/jss-plugin-rule-value-function/-/jss-plugin-rule-value-function-10.0.0-alpha.25.tgz",
|
"resolved": "https://registry.npmjs.org/jss-plugin-rule-value-function/-/jss-plugin-rule-value-function-10.0.0.tgz",
|
||||||
"integrity": "sha512-CQQtWO+/OZRGaFRBSGQUgAci9YlVtdoXcWQKBNo70tmpp+kaXKlFNCYaL3jmHbJHMiwKQYG2RYFQNIrwJ9SGmA==",
|
"integrity": "sha512-Jw+BZ8JIw1f12V0SERqGlBT1JEPWax3vuZpMym54NAXpPb7R1LYHiCTIlaJUyqvIfEy3kiHMtgI+r2whGgRIxQ==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@babel/runtime": "^7.3.1",
|
"@babel/runtime": "^7.3.1",
|
||||||
"jss": "10.0.0-alpha.25"
|
"jss": "10.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"jss-plugin-rule-value-observable": {
|
"jss-plugin-rule-value-observable": {
|
||||||
@ -8070,13 +8064,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"jss-plugin-vendor-prefixer": {
|
"jss-plugin-vendor-prefixer": {
|
||||||
"version": "10.0.0-alpha.25",
|
"version": "10.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/jss-plugin-vendor-prefixer/-/jss-plugin-vendor-prefixer-10.0.0-alpha.25.tgz",
|
"resolved": "https://registry.npmjs.org/jss-plugin-vendor-prefixer/-/jss-plugin-vendor-prefixer-10.0.0.tgz",
|
||||||
"integrity": "sha512-5FXpB/TiwckbrkoDCmd27YsWCESl1K4hAX/oro2/geEXgnVQvDgQOf2eWCsjYO2K1lYPPXtskMfws/Q3eKmbYg==",
|
"integrity": "sha512-qslqvL0MUbWuzXJWdUxpj6mdNUX8jr4FFTo3aZnAT65nmzWL7g8oTr9ZxmTXXgdp7ANhS1QWE7036/Q2isFBpw==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@babel/runtime": "^7.3.1",
|
"@babel/runtime": "^7.3.1",
|
||||||
"css-vendor": "^2.0.6",
|
"css-vendor": "^2.0.6",
|
||||||
"jss": "10.0.0-alpha.25"
|
"jss": "10.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"jss-preset-default": {
|
"jss-preset-default": {
|
||||||
@ -8940,9 +8934,9 @@
|
|||||||
"integrity": "sha512-U+JJi7duF1o+u2pynbp2zXDW2/PADgC30f0GsHZtRh+HOcXHnw137TrNlyxxRvWW5fjKd3bcLHPxofWuCjaeZg=="
|
"integrity": "sha512-U+JJi7duF1o+u2pynbp2zXDW2/PADgC30f0GsHZtRh+HOcXHnw137TrNlyxxRvWW5fjKd3bcLHPxofWuCjaeZg=="
|
||||||
},
|
},
|
||||||
"notistack": {
|
"notistack": {
|
||||||
"version": "0.8.9",
|
"version": "0.9.6",
|
||||||
"resolved": "https://registry.npmjs.org/notistack/-/notistack-0.8.9.tgz",
|
"resolved": "https://registry.npmjs.org/notistack/-/notistack-0.9.6.tgz",
|
||||||
"integrity": "sha512-nRHQVWUfgHnvnKrjRbRX9f+YAnbyh96yRyO5bEP/FCLVLuTZcJOwUr0GZ7Xr/8wK3+hXa9JYpXUkUhSxj1K8NQ==",
|
"integrity": "sha512-vo1zOwhQBxwWiMxwVjeSDXNzJuaM/nfkayv4uRo+9ON9CAtaPSNt15QHeELKkbOSLH29fb7zmoZl4AlkCqhGsA==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"classnames": "^2.2.6",
|
"classnames": "^2.2.6",
|
||||||
"hoist-non-react-statics": "^3.3.0",
|
"hoist-non-react-statics": "^3.3.0",
|
||||||
@ -9526,9 +9520,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"popper.js": {
|
"popper.js": {
|
||||||
"version": "1.15.0",
|
"version": "1.16.0",
|
||||||
"resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.15.0.tgz",
|
"resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.16.0.tgz",
|
||||||
"integrity": "sha512-w010cY1oCUmI+9KwwlWki+r5jxKfTFDVoadl7MSrIujHU5MJ5OR6HTDj6Xo8aoR/QsA56x8jKjA59qGH4ELtrA=="
|
"integrity": "sha512-+G+EkOPoE5S/zChTpmBSSDYmhXJ5PsW8eMhH8cP/CQHMFPBG/kC9Y5IIw6qNYgdJ+/COf0ddY2li28iHaZRSjw=="
|
||||||
},
|
},
|
||||||
"portfinder": {
|
"portfinder": {
|
||||||
"version": "1.0.24",
|
"version": "1.0.24",
|
||||||
|
@ -3,12 +3,12 @@
|
|||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@material-ui/core": "^4.4.3",
|
"@material-ui/core": "^4.7.0",
|
||||||
"@material-ui/icons": "^4.4.3",
|
"@material-ui/icons": "^4.5.1",
|
||||||
"compression-webpack-plugin": "^2.0.0",
|
"compression-webpack-plugin": "^2.0.0",
|
||||||
"jwt-decode": "^2.2.0",
|
"jwt-decode": "^2.2.0",
|
||||||
"moment": "^2.24.0",
|
"moment": "^2.24.0",
|
||||||
"notistack": "^0.8.9",
|
"notistack": "^0.9.6",
|
||||||
"prop-types": "^15.7.2",
|
"prop-types": "^15.7.2",
|
||||||
"react": "^16.10.1",
|
"react": "^16.10.1",
|
||||||
"react-dom": "^16.10.1",
|
"react-dom": "^16.10.1",
|
||||||
|
@ -2,22 +2,16 @@ import React, { Component } from 'react';
|
|||||||
import { Redirect, Route, Switch } from 'react-router';
|
import { Redirect, Route, Switch } from 'react-router';
|
||||||
|
|
||||||
import AppRouting from './AppRouting';
|
import AppRouting from './AppRouting';
|
||||||
|
import { PROJECT_NAME } from './constants/Env';
|
||||||
|
|
||||||
import { SnackbarProvider } from 'notistack';
|
import { SnackbarProvider } from 'notistack';
|
||||||
|
|
||||||
import CssBaseline from '@material-ui/core/CssBaseline';
|
|
||||||
import blueGrey from '@material-ui/core/colors/blueGrey';
|
|
||||||
import indigo from '@material-ui/core/colors/indigo';
|
|
||||||
import orange from '@material-ui/core/colors/orange';
|
|
||||||
import red from '@material-ui/core/colors/red';
|
|
||||||
import green from '@material-ui/core/colors/green';
|
|
||||||
|
|
||||||
import { create } from 'jss';
|
import { create } from 'jss';
|
||||||
import { StylesProvider, jssPreset } from '@material-ui/styles';
|
|
||||||
|
|
||||||
import {
|
import { CssBaseline, IconButton, MuiThemeProvider, createMuiTheme } from '@material-ui/core';
|
||||||
MuiThemeProvider,
|
import { StylesProvider, jssPreset } from '@material-ui/styles';
|
||||||
createMuiTheme
|
import { blueGrey, indigo, orange, red, green } from '@material-ui/core/colors';
|
||||||
} from '@material-ui/core/styles';
|
import CloseIcon from '@material-ui/icons/Close';
|
||||||
|
|
||||||
|
|
||||||
// Our theme
|
// Our theme
|
||||||
const theme = createMuiTheme({
|
const theme = createMuiTheme({
|
||||||
@ -38,11 +32,28 @@ const jss = create(jssPreset());
|
|||||||
const unauthorizedRedirect = () => <Redirect to="/" />;
|
const unauthorizedRedirect = () => <Redirect to="/" />;
|
||||||
|
|
||||||
class App extends Component {
|
class App extends Component {
|
||||||
|
|
||||||
|
notistackRef = React.createRef();
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
document.title = PROJECT_NAME;
|
||||||
|
}
|
||||||
|
|
||||||
|
onClickDismiss = (key) => () => {
|
||||||
|
this.notistackRef.current.closeSnackbar(key);
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<StylesProvider jss={jss}>
|
<StylesProvider jss={jss}>
|
||||||
<MuiThemeProvider theme={theme}>
|
<MuiThemeProvider theme={theme}>
|
||||||
<SnackbarProvider maxSnack={3}>
|
<SnackbarProvider maxSnack={3} anchorOrigin={{ vertical: 'bottom', horizontal: 'left' }}
|
||||||
|
ref={this.notistackRef}
|
||||||
|
action={(key) => (
|
||||||
|
<IconButton onClick={this.onClickDismiss(key)} size="small">
|
||||||
|
<CloseIcon />
|
||||||
|
</IconButton>
|
||||||
|
)}>
|
||||||
<CssBaseline />
|
<CssBaseline />
|
||||||
<Switch>
|
<Switch>
|
||||||
<Route exact path="/unauthorized" component={unauthorizedRedirect} />
|
<Route exact path="/unauthorized" component={unauthorizedRedirect} />
|
||||||
|
@ -13,3 +13,4 @@ export const SYSTEM_STATUS_ENDPOINT = ENDPOINT_ROOT + "systemStatus";
|
|||||||
export const SIGN_IN_ENDPOINT = ENDPOINT_ROOT + "signIn";
|
export const SIGN_IN_ENDPOINT = ENDPOINT_ROOT + "signIn";
|
||||||
export const VERIFY_AUTHORIZATION_ENDPOINT = ENDPOINT_ROOT + "verifyAuthorization";
|
export const VERIFY_AUTHORIZATION_ENDPOINT = ENDPOINT_ROOT + "verifyAuthorization";
|
||||||
export const SECURITY_SETTINGS_ENDPOINT = ENDPOINT_ROOT + "securitySettings";
|
export const SECURITY_SETTINGS_ENDPOINT = ENDPOINT_ROOT + "securitySettings";
|
||||||
|
export const RESTART_ENDPOINT = ENDPOINT_ROOT + "restart";
|
||||||
|
@ -11,6 +11,7 @@ import Divider from '@material-ui/core/Divider';
|
|||||||
import SettingsInputAntennaIcon from '@material-ui/icons/SettingsInputAntenna';
|
import SettingsInputAntennaIcon from '@material-ui/icons/SettingsInputAntenna';
|
||||||
import DeviceHubIcon from '@material-ui/icons/DeviceHub';
|
import DeviceHubIcon from '@material-ui/icons/DeviceHub';
|
||||||
import ComputerIcon from '@material-ui/icons/Computer';
|
import ComputerIcon from '@material-ui/icons/Computer';
|
||||||
|
import RefreshIcon from '@material-ui/icons/Refresh';
|
||||||
|
|
||||||
import { restComponent } from '../components/RestComponent';
|
import { restComponent } from '../components/RestComponent';
|
||||||
import LoadingNotification from '../components/LoadingNotification';
|
import LoadingNotification from '../components/LoadingNotification';
|
||||||
@ -93,7 +94,7 @@ class APStatus extends Component {
|
|||||||
<List>
|
<List>
|
||||||
{this.createListItems(data, classes)}
|
{this.createListItems(data, classes)}
|
||||||
</List>
|
</List>
|
||||||
<Button variant="contained" color="secondary" className={classes.button} onClick={this.props.loadData}>
|
<Button startIcon={<RefreshIcon />} variant="contained" color="secondary" className={classes.button} onClick={this.props.loadData}>
|
||||||
Refresh
|
Refresh
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
|
@ -14,6 +14,7 @@ import DNSIcon from '@material-ui/icons/Dns';
|
|||||||
import TimerIcon from '@material-ui/icons/Timer';
|
import TimerIcon from '@material-ui/icons/Timer';
|
||||||
import UpdateIcon from '@material-ui/icons/Update';
|
import UpdateIcon from '@material-ui/icons/Update';
|
||||||
import AvTimerIcon from '@material-ui/icons/AvTimer';
|
import AvTimerIcon from '@material-ui/icons/AvTimer';
|
||||||
|
import RefreshIcon from '@material-ui/icons/Refresh';
|
||||||
|
|
||||||
import { isSynchronized, ntpStatusHighlight, ntpStatus } from '../constants/NTPStatus';
|
import { isSynchronized, ntpStatusHighlight, ntpStatus } from '../constants/NTPStatus';
|
||||||
import * as Highlight from '../constants/Highlight';
|
import * as Highlight from '../constants/Highlight';
|
||||||
@ -118,7 +119,7 @@ class NTPStatus extends Component {
|
|||||||
<List>
|
<List>
|
||||||
{this.createListItems(data, classes)}
|
{this.createListItems(data, classes)}
|
||||||
</List>
|
</List>
|
||||||
<Button variant="contained" color="secondary" className={classes.button} onClick={this.props.loadData}>
|
<Button startIcon={<RefreshIcon />} variant="contained" color="secondary" className={classes.button} onClick={this.props.loadData}>
|
||||||
Refresh
|
Refresh
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import React, { Component, Fragment } from 'react';
|
import React, { Component, Fragment } from 'react';
|
||||||
|
import { withSnackbar } from 'notistack';
|
||||||
|
|
||||||
import { withStyles } from '@material-ui/core/styles';
|
import { withStyles } from '@material-ui/core/styles';
|
||||||
import Button from '@material-ui/core/Button';
|
import Button from '@material-ui/core/Button';
|
||||||
@ -8,16 +9,24 @@ import ListItemAvatar from '@material-ui/core/ListItemAvatar';
|
|||||||
import ListItemText from '@material-ui/core/ListItemText';
|
import ListItemText from '@material-ui/core/ListItemText';
|
||||||
import Avatar from '@material-ui/core/Avatar';
|
import Avatar from '@material-ui/core/Avatar';
|
||||||
import Divider from '@material-ui/core/Divider';
|
import Divider from '@material-ui/core/Divider';
|
||||||
|
import Dialog from '@material-ui/core/Dialog';
|
||||||
|
import DialogActions from '@material-ui/core/DialogActions';
|
||||||
|
import DialogTitle from '@material-ui/core/DialogTitle';
|
||||||
|
import DialogContent from '@material-ui/core/DialogContent';
|
||||||
|
|
||||||
import DevicesIcon from '@material-ui/icons/Devices';
|
import DevicesIcon from '@material-ui/icons/Devices';
|
||||||
import MemoryIcon from '@material-ui/icons/Memory';
|
import MemoryIcon from '@material-ui/icons/Memory';
|
||||||
import ShowChartIcon from '@material-ui/icons/ShowChart';
|
import ShowChartIcon from '@material-ui/icons/ShowChart';
|
||||||
import SdStorageIcon from '@material-ui/icons/SdStorage';
|
import SdStorageIcon from '@material-ui/icons/SdStorage';
|
||||||
import DataUsageIcon from '@material-ui/icons/DataUsage';
|
import DataUsageIcon from '@material-ui/icons/DataUsage';
|
||||||
|
import AutorenewIcon from '@material-ui/icons/Autorenew';
|
||||||
|
import RefreshIcon from '@material-ui/icons/Refresh';
|
||||||
|
|
||||||
import { SYSTEM_STATUS_ENDPOINT } from '../constants/Endpoints';
|
import { SYSTEM_STATUS_ENDPOINT, RESTART_ENDPOINT } from '../constants/Endpoints';
|
||||||
import { restComponent } from '../components/RestComponent';
|
import { restComponent } from '../components/RestComponent';
|
||||||
import LoadingNotification from '../components/LoadingNotification';
|
import LoadingNotification from '../components/LoadingNotification';
|
||||||
import SectionContent from '../components/SectionContent';
|
import SectionContent from '../components/SectionContent';
|
||||||
|
import { redirectingAuthorizedFetch } from '../authentication/Authentication';
|
||||||
|
|
||||||
const styles = theme => ({
|
const styles = theme => ({
|
||||||
button: {
|
button: {
|
||||||
@ -28,6 +37,16 @@ const styles = theme => ({
|
|||||||
|
|
||||||
class SystemStatus extends Component {
|
class SystemStatus extends Component {
|
||||||
|
|
||||||
|
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
|
||||||
|
this.state = {
|
||||||
|
confirmRestart: false,
|
||||||
|
processing: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
this.props.loadData();
|
this.props.loadData();
|
||||||
}
|
}
|
||||||
@ -90,13 +109,63 @@ class SystemStatus extends Component {
|
|||||||
<List>
|
<List>
|
||||||
{this.createListItems(data, classes)}
|
{this.createListItems(data, classes)}
|
||||||
</List>
|
</List>
|
||||||
<Button variant="contained" color="secondary" className={classes.button} onClick={this.props.loadData}>
|
<Button startIcon={<RefreshIcon />} variant="contained" color="secondary" className={classes.button} onClick={this.props.loadData}>
|
||||||
Refresh
|
Refresh
|
||||||
</Button>
|
</Button>
|
||||||
|
<Button startIcon={<AutorenewIcon />} variant="contained" color="secondary" className={classes.button} onClick={this.onRestart}>
|
||||||
|
Restart
|
||||||
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onRestart = () => {
|
||||||
|
this.setState({ confirmRestart: true });
|
||||||
|
}
|
||||||
|
|
||||||
|
onRestartRejected = () => {
|
||||||
|
this.setState({ confirmRestart: false });
|
||||||
|
}
|
||||||
|
|
||||||
|
onRestartConfirmed = () => {
|
||||||
|
this.setState({ processing: true });
|
||||||
|
redirectingAuthorizedFetch(RESTART_ENDPOINT, { method: 'POST' })
|
||||||
|
.then(response => {
|
||||||
|
if (response.status === 200) {
|
||||||
|
this.props.enqueueSnackbar("Device is restarting", { variant: 'info' });
|
||||||
|
this.setState({ processing: false, confirmRestart: false });
|
||||||
|
} else {
|
||||||
|
throw Error("Invalid status code: " + response.status);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
this.props.enqueueSnackbar(error.message || "Problem restarting device", { variant: 'error' });
|
||||||
|
this.setState({ processing: false, confirmRestart: false });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
renderRestartDialog() {
|
||||||
|
return (
|
||||||
|
<Dialog
|
||||||
|
open={this.state.confirmRestart}
|
||||||
|
onClose={this.onRestartRejected}
|
||||||
|
>
|
||||||
|
<DialogTitle>Confirm Restart</DialogTitle>
|
||||||
|
<DialogContent dividers={true}>
|
||||||
|
Are you sure you want to restart the device?
|
||||||
|
</DialogContent>
|
||||||
|
<DialogActions>
|
||||||
|
<Button startIcon={<AutorenewIcon />} variant="contained" onClick={this.onRestartConfirmed} disabled={this.state.processing} color="primary" autoFocus>
|
||||||
|
Restart
|
||||||
|
</Button>
|
||||||
|
<Button variant="contained" onClick={this.onRestartRejected} color="secondary">
|
||||||
|
Cancel
|
||||||
|
</Button>
|
||||||
|
</DialogActions>
|
||||||
|
</Dialog>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { data, fetched, errorMessage, loadData, classes } = this.props;
|
const { data, fetched, errorMessage, loadData, classes } = this.props;
|
||||||
return (
|
return (
|
||||||
@ -109,9 +178,11 @@ class SystemStatus extends Component {
|
|||||||
() => this.renderSystemStatus(data, classes)
|
() => this.renderSystemStatus(data, classes)
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
{this.renderRestartDialog()}
|
||||||
</SectionContent>
|
</SectionContent>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default restComponent(SYSTEM_STATUS_ENDPOINT, withStyles(styles)(SystemStatus));
|
export default withSnackbar(restComponent(SYSTEM_STATUS_ENDPOINT, withStyles(styles)(SystemStatus)));
|
||||||
|
@ -13,6 +13,7 @@ import DNSIcon from '@material-ui/icons/Dns';
|
|||||||
import SettingsInputComponentIcon from '@material-ui/icons/SettingsInputComponent';
|
import SettingsInputComponentIcon from '@material-ui/icons/SettingsInputComponent';
|
||||||
import SettingsInputAntennaIcon from '@material-ui/icons/SettingsInputAntenna';
|
import SettingsInputAntennaIcon from '@material-ui/icons/SettingsInputAntenna';
|
||||||
import DeviceHubIcon from '@material-ui/icons/DeviceHub';
|
import DeviceHubIcon from '@material-ui/icons/DeviceHub';
|
||||||
|
import RefreshIcon from '@material-ui/icons/Refresh';
|
||||||
|
|
||||||
import SectionContent from '../components/SectionContent';
|
import SectionContent from '../components/SectionContent';
|
||||||
import { WIFI_STATUS_ENDPOINT } from '../constants/Endpoints';
|
import { WIFI_STATUS_ENDPOINT } from '../constants/Endpoints';
|
||||||
@ -130,7 +131,7 @@ class WiFiStatus extends Component {
|
|||||||
<List>
|
<List>
|
||||||
{this.createListItems(data, classes)}
|
{this.createListItems(data, classes)}
|
||||||
</List>
|
</List>
|
||||||
<Button variant="contained" color="secondary" className={classes.button} onClick={this.props.loadData}>
|
<Button startIcon={<RefreshIcon />} variant="contained" color="secondary" className={classes.button} onClick={this.props.loadData}>
|
||||||
Refresh
|
Refresh
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
|
@ -8,6 +8,7 @@ import PasswordValidator from '../components/PasswordValidator';
|
|||||||
import { withStyles } from '@material-ui/core/styles';
|
import { withStyles } from '@material-ui/core/styles';
|
||||||
import Button from '@material-ui/core/Button';
|
import Button from '@material-ui/core/Button';
|
||||||
import MenuItem from '@material-ui/core/MenuItem';
|
import MenuItem from '@material-ui/core/MenuItem';
|
||||||
|
import SaveIcon from '@material-ui/icons/Save';
|
||||||
|
|
||||||
const styles = theme => ({
|
const styles = theme => ({
|
||||||
textField: {
|
textField: {
|
||||||
@ -61,7 +62,7 @@ class APSettingsForm extends React.Component {
|
|||||||
/>
|
/>
|
||||||
</Fragment>
|
</Fragment>
|
||||||
}
|
}
|
||||||
<Button variant="contained" color="primary" className={classes.button} type="submit">
|
<Button startIcon={<SaveIcon />} variant="contained" color="primary" className={classes.button} type="submit">
|
||||||
Save
|
Save
|
||||||
</Button>
|
</Button>
|
||||||
<Button variant="contained" color="secondary" className={classes.button} onClick={onReset}>
|
<Button variant="contained" color="secondary" className={classes.button} onClick={onReset}>
|
||||||
|
@ -18,6 +18,8 @@ import DeleteIcon from '@material-ui/icons/Delete';
|
|||||||
import CloseIcon from '@material-ui/icons/Close';
|
import CloseIcon from '@material-ui/icons/Close';
|
||||||
import CheckIcon from '@material-ui/icons/Check';
|
import CheckIcon from '@material-ui/icons/Check';
|
||||||
import IconButton from '@material-ui/core/IconButton';
|
import IconButton from '@material-ui/core/IconButton';
|
||||||
|
import SaveIcon from '@material-ui/icons/Save';
|
||||||
|
import PersonAddIcon from '@material-ui/icons/PersonAdd';
|
||||||
|
|
||||||
import UserForm from './UserForm';
|
import UserForm from './UserForm';
|
||||||
import { withAuthenticationContext } from '../authentication/Context';
|
import { withAuthenticationContext } from '../authentication/Context';
|
||||||
@ -161,7 +163,7 @@ class ManageUsersForm extends React.Component {
|
|||||||
<TableRow>
|
<TableRow>
|
||||||
<TableCell colSpan={2} />
|
<TableCell colSpan={2} />
|
||||||
<TableCell align="center">
|
<TableCell align="center">
|
||||||
<Button variant="contained" color="secondary" onClick={this.createUser}>
|
<Button startIcon={<PersonAddIcon />} variant="contained" color="secondary" onClick={this.createUser}>
|
||||||
Add User
|
Add User
|
||||||
</Button>
|
</Button>
|
||||||
</TableCell>
|
</TableCell>
|
||||||
@ -176,7 +178,7 @@ class ManageUsersForm extends React.Component {
|
|||||||
</Box>
|
</Box>
|
||||||
</Typography>
|
</Typography>
|
||||||
}
|
}
|
||||||
<Button variant="contained" color="primary" className={classes.button} type="submit" disabled={this.noAdminConfigured()}>
|
<Button startIcon={<SaveIcon />} variant="contained" color="primary" className={classes.button} type="submit" disabled={this.noAdminConfigured()}>
|
||||||
Save
|
Save
|
||||||
</Button>
|
</Button>
|
||||||
<Button variant="contained" color="secondary" className={classes.button} onClick={onReset}>
|
<Button variant="contained" color="secondary" className={classes.button} onClick={onReset}>
|
||||||
|
@ -4,6 +4,7 @@ import { TextValidator, ValidatorForm } from 'react-material-ui-form-validator';
|
|||||||
|
|
||||||
import { withStyles } from '@material-ui/core/styles';
|
import { withStyles } from '@material-ui/core/styles';
|
||||||
import Button from '@material-ui/core/Button';
|
import Button from '@material-ui/core/Button';
|
||||||
|
import SaveIcon from '@material-ui/icons/Save';
|
||||||
|
|
||||||
import isIP from '../validators/isIP';
|
import isIP from '../validators/isIP';
|
||||||
import isHostname from '../validators/isHostname';
|
import isHostname from '../validators/isHostname';
|
||||||
@ -50,7 +51,7 @@ class NTPSettingsForm extends React.Component {
|
|||||||
onChange={handleValueChange('interval')}
|
onChange={handleValueChange('interval')}
|
||||||
margin="normal"
|
margin="normal"
|
||||||
/>
|
/>
|
||||||
<Button variant="contained" color="primary" className={classes.button} type="submit">
|
<Button startIcon={<SaveIcon />} variant="contained" color="primary" className={classes.button} type="submit">
|
||||||
Save
|
Save
|
||||||
</Button>
|
</Button>
|
||||||
<Button variant="contained" color="secondary" className={classes.button} onClick={onReset}>
|
<Button variant="contained" color="secondary" className={classes.button} onClick={onReset}>
|
||||||
|
@ -6,6 +6,7 @@ import Button from '@material-ui/core/Button';
|
|||||||
import Switch from '@material-ui/core/Switch';
|
import Switch from '@material-ui/core/Switch';
|
||||||
import { TextValidator, ValidatorForm } from 'react-material-ui-form-validator';
|
import { TextValidator, ValidatorForm } from 'react-material-ui-form-validator';
|
||||||
import FormControlLabel from '@material-ui/core/FormControlLabel';
|
import FormControlLabel from '@material-ui/core/FormControlLabel';
|
||||||
|
import SaveIcon from '@material-ui/icons/Save';
|
||||||
|
|
||||||
import isIP from '../validators/isIP';
|
import isIP from '../validators/isIP';
|
||||||
import isHostname from '../validators/isHostname';
|
import isHostname from '../validators/isHostname';
|
||||||
@ -69,7 +70,7 @@ class OTASettingsForm extends React.Component {
|
|||||||
onChange={handleValueChange('password')}
|
onChange={handleValueChange('password')}
|
||||||
margin="normal"
|
margin="normal"
|
||||||
/>
|
/>
|
||||||
<Button variant="contained" color="primary" className={classes.button} type="submit">
|
<Button startIcon={<SaveIcon />} variant="contained" color="primary" className={classes.button} type="submit">
|
||||||
Save
|
Save
|
||||||
</Button>
|
</Button>
|
||||||
<Button variant="contained" color="secondary" className={classes.button} onClick={onReset}>
|
<Button variant="contained" color="secondary" className={classes.button} onClick={onReset}>
|
||||||
|
@ -6,6 +6,7 @@ import { withStyles } from '@material-ui/core/styles';
|
|||||||
import Button from '@material-ui/core/Button';
|
import Button from '@material-ui/core/Button';
|
||||||
import Typography from '@material-ui/core/Typography';
|
import Typography from '@material-ui/core/Typography';
|
||||||
import Box from '@material-ui/core/Box';
|
import Box from '@material-ui/core/Box';
|
||||||
|
import SaveIcon from '@material-ui/icons/Save';
|
||||||
|
|
||||||
import PasswordValidator from '../components/PasswordValidator';
|
import PasswordValidator from '../components/PasswordValidator';
|
||||||
import { withAuthenticationContext } from '../authentication/Context';
|
import { withAuthenticationContext } from '../authentication/Context';
|
||||||
@ -46,7 +47,7 @@ class SecuritySettingsForm extends React.Component {
|
|||||||
If you modify the JWT Secret, all users will be logged out.
|
If you modify the JWT Secret, all users will be logged out.
|
||||||
</Box>
|
</Box>
|
||||||
</Typography>
|
</Typography>
|
||||||
<Button variant="contained" color="primary" className={classes.button} type="submit">
|
<Button startIcon={<SaveIcon />} variant="contained" color="primary" className={classes.button} type="submit">
|
||||||
Save
|
Save
|
||||||
</Button>
|
</Button>
|
||||||
<Button variant="contained" color="secondary" className={classes.button} onClick={onReset}>
|
<Button variant="contained" color="secondary" className={classes.button} onClick={onReset}>
|
||||||
|
@ -18,6 +18,7 @@ import Badge from '@material-ui/core/Badge';
|
|||||||
import WifiIcon from '@material-ui/icons/Wifi';
|
import WifiIcon from '@material-ui/icons/Wifi';
|
||||||
import LockIcon from '@material-ui/icons/Lock';
|
import LockIcon from '@material-ui/icons/Lock';
|
||||||
import LockOpenIcon from '@material-ui/icons/LockOpen';
|
import LockOpenIcon from '@material-ui/icons/LockOpen';
|
||||||
|
import PermScanWifiIcon from '@material-ui/icons/PermScanWifi';
|
||||||
|
|
||||||
import { isNetworkOpen, networkSecurityMode } from '../constants/WiFiSecurityModes';
|
import { isNetworkOpen, networkSecurityMode } from '../constants/WiFiSecurityModes';
|
||||||
|
|
||||||
@ -86,7 +87,7 @@ class WiFiNetworkSelector extends Component {
|
|||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
||||||
<Button variant="contained" color="secondary" className={classes.button} onClick={requestNetworkScan} disabled={scanningForNetworks}>
|
<Button startIcon={<PermScanWifiIcon />} variant="contained" color="secondary" className={classes.button} onClick={requestNetworkScan} disabled={scanningForNetworks}>
|
||||||
Scan again...
|
Scan again...
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
|
@ -16,6 +16,7 @@ import IconButton from '@material-ui/core/IconButton';
|
|||||||
import LockIcon from '@material-ui/icons/Lock';
|
import LockIcon from '@material-ui/icons/Lock';
|
||||||
import LockOpenIcon from '@material-ui/icons/LockOpen';
|
import LockOpenIcon from '@material-ui/icons/LockOpen';
|
||||||
import DeleteIcon from '@material-ui/icons/Delete';
|
import DeleteIcon from '@material-ui/icons/Delete';
|
||||||
|
import SaveIcon from '@material-ui/icons/Save';
|
||||||
|
|
||||||
import { TextValidator, ValidatorForm } from 'react-material-ui-form-validator';
|
import { TextValidator, ValidatorForm } from 'react-material-ui-form-validator';
|
||||||
import { isNetworkOpen, networkSecurityMode } from '../constants/WiFiSecurityModes';
|
import { isNetworkOpen, networkSecurityMode } from '../constants/WiFiSecurityModes';
|
||||||
@ -175,7 +176,7 @@ class WiFiSettingsForm extends React.Component {
|
|||||||
/>
|
/>
|
||||||
</Fragment>
|
</Fragment>
|
||||||
}
|
}
|
||||||
<Button variant="contained" color="primary" className={classes.button} type="submit">
|
<Button startIcon={<SaveIcon />} variant="contained" color="primary" className={classes.button} type="submit">
|
||||||
Save
|
Save
|
||||||
</Button>
|
</Button>
|
||||||
<Button variant="contained" color="secondary" className={classes.button} onClick={onReset}>
|
<Button variant="contained" color="secondary" className={classes.button} onClick={onReset}>
|
||||||
|
@ -10,6 +10,7 @@ import Button from '@material-ui/core/Button';
|
|||||||
import Typography from '@material-ui/core/Typography';
|
import Typography from '@material-ui/core/Typography';
|
||||||
import Slider from '@material-ui/core/Slider';
|
import Slider from '@material-ui/core/Slider';
|
||||||
import { makeStyles } from '@material-ui/core/styles';
|
import { makeStyles } from '@material-ui/core/styles';
|
||||||
|
import SaveIcon from '@material-ui/icons/Save';
|
||||||
|
|
||||||
export const DEMO_SETTINGS_ENDPOINT = ENDPOINT_ROOT + "demoSettings";
|
export const DEMO_SETTINGS_ENDPOINT = ENDPOINT_ROOT + "demoSettings";
|
||||||
|
|
||||||
@ -69,7 +70,7 @@ function DemoControllerForm(props) {
|
|||||||
max={255}
|
max={255}
|
||||||
onChange={handleSliderChange('blink_speed')}
|
onChange={handleSliderChange('blink_speed')}
|
||||||
/>
|
/>
|
||||||
<Button variant="contained" color="primary" className={classes.button} type="submit">
|
<Button startIcon={<SaveIcon />} variant="contained" color="primary" className={classes.button} type="submit">
|
||||||
Save
|
Save
|
||||||
</Button>
|
</Button>
|
||||||
<Button variant="contained" color="secondary" className={classes.button} onClick={onReset}>
|
<Button variant="contained" color="secondary" className={classes.button} onClick={onReset}>
|
||||||
|
@ -6,6 +6,7 @@ ESP8266React::ESP8266React(AsyncWebServer* server, FS* fs):
|
|||||||
_apSettingsService(server, fs, &_securitySettingsService),
|
_apSettingsService(server, fs, &_securitySettingsService),
|
||||||
_ntpSettingsService(server, fs, &_securitySettingsService),
|
_ntpSettingsService(server, fs, &_securitySettingsService),
|
||||||
_otaSettingsService(server, fs, &_securitySettingsService),
|
_otaSettingsService(server, fs, &_securitySettingsService),
|
||||||
|
_restartService(server, &_securitySettingsService),
|
||||||
_authenticationService(server, &_securitySettingsService),
|
_authenticationService(server, &_securitySettingsService),
|
||||||
_wifiScanner(server, &_securitySettingsService),
|
_wifiScanner(server, &_securitySettingsService),
|
||||||
_wifiStatus(server, &_securitySettingsService),
|
_wifiStatus(server, &_securitySettingsService),
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
#include <NTPStatus.h>
|
#include <NTPStatus.h>
|
||||||
#include <APStatus.h>
|
#include <APStatus.h>
|
||||||
#include <SystemStatus.h>
|
#include <SystemStatus.h>
|
||||||
|
#include <RestartService.h>
|
||||||
|
|
||||||
class ESP8266React {
|
class ESP8266React {
|
||||||
|
|
||||||
@ -46,8 +47,10 @@ class ESP8266React {
|
|||||||
APSettingsService _apSettingsService;
|
APSettingsService _apSettingsService;
|
||||||
NTPSettingsService _ntpSettingsService;
|
NTPSettingsService _ntpSettingsService;
|
||||||
OTASettingsService _otaSettingsService;
|
OTASettingsService _otaSettingsService;
|
||||||
|
RestartService _restartService;
|
||||||
AuthenticationService _authenticationService;
|
AuthenticationService _authenticationService;
|
||||||
|
|
||||||
|
|
||||||
WiFiScanner _wifiScanner;
|
WiFiScanner _wifiScanner;
|
||||||
WiFiStatus _wifiStatus;
|
WiFiStatus _wifiStatus;
|
||||||
NTPStatus _ntpStatus;
|
NTPStatus _ntpStatus;
|
||||||
|
14
lib/framework/RestartService.cpp
Normal file
14
lib/framework/RestartService.cpp
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
#include <RestartService.h>
|
||||||
|
|
||||||
|
RestartService::RestartService(AsyncWebServer* server, SecurityManager* securityManager) {
|
||||||
|
server->on(RESTART_SERVICE_PATH, HTTP_POST,
|
||||||
|
securityManager->wrapRequest(std::bind(&RestartService::restart, this, std::placeholders::_1), AuthenticationPredicates::IS_ADMIN)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RestartService::restart(AsyncWebServerRequest *request) {
|
||||||
|
request->onDisconnect([](){
|
||||||
|
ESP.restart();
|
||||||
|
});
|
||||||
|
request->send(200);
|
||||||
|
}
|
29
lib/framework/RestartService.h
Normal file
29
lib/framework/RestartService.h
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
#ifndef RestartService_h
|
||||||
|
#define RestartService_h
|
||||||
|
|
||||||
|
#if defined(ESP8266)
|
||||||
|
#include <ESP8266WiFi.h>
|
||||||
|
#include <ESPAsyncTCP.h>
|
||||||
|
#elif defined(ESP_PLATFORM)
|
||||||
|
#include <WiFi.h>
|
||||||
|
#include <AsyncTCP.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <ESPAsyncWebServer.h>
|
||||||
|
#include <SecurityManager.h>
|
||||||
|
|
||||||
|
#define RESTART_SERVICE_PATH "/rest/restart"
|
||||||
|
|
||||||
|
class RestartService {
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
RestartService(AsyncWebServer* server, SecurityManager* securityManager);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
void restart(AsyncWebServerRequest *request);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // end RestartService_h
|
Loading…
Reference in New Issue
Block a user