add eslint airbnb rules
parent
0956687fbb
commit
d70e46583a
|
@ -1,9 +1,39 @@
|
||||||
{
|
{
|
||||||
|
"env": {
|
||||||
|
"browser": true,
|
||||||
|
"es6": true
|
||||||
|
},
|
||||||
"extends": [
|
"extends": [
|
||||||
"react-app",
|
"react-app",
|
||||||
"react-app/jest"
|
"react-app/jest",
|
||||||
|
"airbnb",
|
||||||
|
"airbnb/hooks"
|
||||||
],
|
],
|
||||||
"rules": {
|
"rules": {
|
||||||
"no-trailing-spaces": "warn"
|
// disallow use of unary operators, ++ and --
|
||||||
|
// http://eslint.org/docs/rules/no-plusplus
|
||||||
|
// retropilot: we allow them in the for loop
|
||||||
|
"no-plusplus": ["error", { "allowForLoopAfterthoughts": true }],
|
||||||
|
|
||||||
|
// disallow use of the continue statement
|
||||||
|
// https://eslint.org/docs/rules/no-continue
|
||||||
|
// retropilot: we allow use of the continue statement
|
||||||
|
"no-continue": "off",
|
||||||
|
|
||||||
|
// disallow use of variables before they are defined
|
||||||
|
// http://eslint.org/docs/rules/no-use-before-define
|
||||||
|
// retropilot: permit referencing functions before they're defined
|
||||||
|
"no-use-before-define": ["error", { "functions": false }],
|
||||||
|
|
||||||
|
// specify the maximum length of a line in your program
|
||||||
|
// https://eslint.org/docs/rules/max-len
|
||||||
|
// retropilot: ignore comments
|
||||||
|
"max-len": ["error", 100, 2, {
|
||||||
|
"ignoreUrls": true,
|
||||||
|
"ignoreComments": true,
|
||||||
|
"ignoreRegExpLiterals": true,
|
||||||
|
"ignoreStrings": true,
|
||||||
|
"ignoreTemplateLiterals": true
|
||||||
|
}]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
{
|
{
|
||||||
"name": "app",
|
"name": "retropilot-client",
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"lockfileVersion": 2,
|
"lockfileVersion": 2,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "app",
|
"name": "retropilot-client",
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@emotion/react": "^11.7.1",
|
"@emotion/react": "^11.7.1",
|
||||||
|
@ -30,6 +30,9 @@
|
||||||
"react-scripts": "4.0.3",
|
"react-scripts": "4.0.3",
|
||||||
"styled-components": "^5.3.3",
|
"styled-components": "^5.3.3",
|
||||||
"web-vitals": "^1.1.2"
|
"web-vitals": "^1.1.2"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"eslint-config-airbnb": "^19.0.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@babel/code-frame": {
|
"node_modules/@babel/code-frame": {
|
||||||
|
@ -5256,9 +5259,9 @@
|
||||||
"integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA=="
|
"integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA=="
|
||||||
},
|
},
|
||||||
"node_modules/axe-core": {
|
"node_modules/axe-core": {
|
||||||
"version": "4.3.3",
|
"version": "4.3.5",
|
||||||
"resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.3.3.tgz",
|
"resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.3.5.tgz",
|
||||||
"integrity": "sha512-/lqqLAmuIPi79WYfRpy2i8z+x+vxU3zX2uAm0gs1q52qTuKwolOj1P8XbufpXcsydrpKx2yGn2wzAnxCMV86QA==",
|
"integrity": "sha512-WKTW1+xAzhMS5dJsxWkliixlO/PqC4VhmO9T4juNYcaTg9jzWiJsou6m5pxWYGfigWbwzJWeFY6z47a+4neRXA==",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=4"
|
"node": ">=4"
|
||||||
}
|
}
|
||||||
|
@ -8374,6 +8377,55 @@
|
||||||
"url": "https://opencollective.com/eslint"
|
"url": "https://opencollective.com/eslint"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/eslint-config-airbnb": {
|
||||||
|
"version": "19.0.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/eslint-config-airbnb/-/eslint-config-airbnb-19.0.4.tgz",
|
||||||
|
"integrity": "sha512-T75QYQVQX57jiNgpF9r1KegMICE94VYwoFQyMGhrvc+lB8YF2E/M/PYDaQe1AJcWaEgqLE+ErXV1Og/+6Vyzew==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"eslint-config-airbnb-base": "^15.0.0",
|
||||||
|
"object.assign": "^4.1.2",
|
||||||
|
"object.entries": "^1.1.5"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "^10.12.0 || ^12.22.0 || ^14.17.0 || >=16.0.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"eslint": "^7.32.0 || ^8.2.0",
|
||||||
|
"eslint-plugin-import": "^2.25.3",
|
||||||
|
"eslint-plugin-jsx-a11y": "^6.5.1",
|
||||||
|
"eslint-plugin-react": "^7.28.0",
|
||||||
|
"eslint-plugin-react-hooks": "^4.3.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/eslint-config-airbnb-base": {
|
||||||
|
"version": "15.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-15.0.0.tgz",
|
||||||
|
"integrity": "sha512-xaX3z4ZZIcFLvh2oUNvcX5oEofXda7giYmuplVxoOg5A7EXJMrUyqRgR+mhDhPK8LZ4PttFOBvCYDbX3sUoUig==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"confusing-browser-globals": "^1.0.10",
|
||||||
|
"object.assign": "^4.1.2",
|
||||||
|
"object.entries": "^1.1.5",
|
||||||
|
"semver": "^6.3.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "^10.12.0 || >=12.0.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"eslint": "^7.32.0 || ^8.2.0",
|
||||||
|
"eslint-plugin-import": "^2.25.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/eslint-config-airbnb-base/node_modules/semver": {
|
||||||
|
"version": "6.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
|
||||||
|
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
|
||||||
|
"dev": true,
|
||||||
|
"bin": {
|
||||||
|
"semver": "bin/semver.js"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/eslint-config-react-app": {
|
"node_modules/eslint-config-react-app": {
|
||||||
"version": "6.0.0",
|
"version": "6.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/eslint-config-react-app/-/eslint-config-react-app-6.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/eslint-config-react-app/-/eslint-config-react-app-6.0.0.tgz",
|
||||||
|
@ -8436,13 +8488,12 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/eslint-module-utils": {
|
"node_modules/eslint-module-utils": {
|
||||||
"version": "2.7.1",
|
"version": "2.7.2",
|
||||||
"resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.1.tgz",
|
"resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.2.tgz",
|
||||||
"integrity": "sha512-fjoetBXQZq2tSTWZ9yWVl2KuFrTZZH3V+9iD1V1RfpDgxzJR+mPd/KZmMiA8gbPqdBzpNiEHOuT7IYEWxrH0zQ==",
|
"integrity": "sha512-zquepFnWCY2ISMFwD/DqzaM++H+7PDzOpUvotJWm/y1BAFt5R4oeULgdrTejKqLkz7MA/tgstsUMNYc7wNdTrg==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"debug": "^3.2.7",
|
"debug": "^3.2.7",
|
||||||
"find-up": "^2.1.0",
|
"find-up": "^2.1.0"
|
||||||
"pkg-dir": "^2.0.0"
|
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=4"
|
"node": ">=4"
|
||||||
|
@ -8517,17 +8568,6 @@
|
||||||
"node": ">=4"
|
"node": ">=4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/eslint-module-utils/node_modules/pkg-dir": {
|
|
||||||
"version": "2.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz",
|
|
||||||
"integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=",
|
|
||||||
"dependencies": {
|
|
||||||
"find-up": "^2.1.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=4"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/eslint-plugin-flowtype": {
|
"node_modules/eslint-plugin-flowtype": {
|
||||||
"version": "5.10.0",
|
"version": "5.10.0",
|
||||||
"resolved": "https://registry.npmjs.org/eslint-plugin-flowtype/-/eslint-plugin-flowtype-5.10.0.tgz",
|
"resolved": "https://registry.npmjs.org/eslint-plugin-flowtype/-/eslint-plugin-flowtype-5.10.0.tgz",
|
||||||
|
@ -8544,23 +8584,23 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/eslint-plugin-import": {
|
"node_modules/eslint-plugin-import": {
|
||||||
"version": "2.25.2",
|
"version": "2.25.4",
|
||||||
"resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.25.2.tgz",
|
"resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.25.4.tgz",
|
||||||
"integrity": "sha512-qCwQr9TYfoBHOFcVGKY9C9unq05uOxxdklmBXLVvcwo68y5Hta6/GzCZEMx2zQiu0woKNEER0LE7ZgaOfBU14g==",
|
"integrity": "sha512-/KJBASVFxpu0xg1kIBn9AUa8hQVnszpwgE7Ld0lKAlx7Ie87yzEzCgSkekt+le/YVhiaosO4Y14GDAOc41nfxA==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"array-includes": "^3.1.4",
|
"array-includes": "^3.1.4",
|
||||||
"array.prototype.flat": "^1.2.5",
|
"array.prototype.flat": "^1.2.5",
|
||||||
"debug": "^2.6.9",
|
"debug": "^2.6.9",
|
||||||
"doctrine": "^2.1.0",
|
"doctrine": "^2.1.0",
|
||||||
"eslint-import-resolver-node": "^0.3.6",
|
"eslint-import-resolver-node": "^0.3.6",
|
||||||
"eslint-module-utils": "^2.7.0",
|
"eslint-module-utils": "^2.7.2",
|
||||||
"has": "^1.0.3",
|
"has": "^1.0.3",
|
||||||
"is-core-module": "^2.7.0",
|
"is-core-module": "^2.8.0",
|
||||||
"is-glob": "^4.0.3",
|
"is-glob": "^4.0.3",
|
||||||
"minimatch": "^3.0.4",
|
"minimatch": "^3.0.4",
|
||||||
"object.values": "^1.1.5",
|
"object.values": "^1.1.5",
|
||||||
"resolve": "^1.20.0",
|
"resolve": "^1.20.0",
|
||||||
"tsconfig-paths": "^3.11.0"
|
"tsconfig-paths": "^3.12.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=4"
|
"node": ">=4"
|
||||||
|
@ -8626,27 +8666,28 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/eslint-plugin-jsx-a11y": {
|
"node_modules/eslint-plugin-jsx-a11y": {
|
||||||
"version": "6.4.1",
|
"version": "6.5.1",
|
||||||
"resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.5.1.tgz",
|
||||||
"integrity": "sha512-0rGPJBbwHoGNPU73/QCLP/vveMlM1b1Z9PponxO87jfr6tuH5ligXbDT6nHSSzBC8ovX2Z+BQu7Bk5D/Xgq9zg==",
|
"integrity": "sha512-sVCFKX9fllURnXT2JwLN5Qgo24Ug5NF6dxhkmxsMEUZhXRcGg+X3e1JbJ84YePQKBl5E0ZjAH5Q4rkdcGY99+g==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/runtime": "^7.11.2",
|
"@babel/runtime": "^7.16.3",
|
||||||
"aria-query": "^4.2.2",
|
"aria-query": "^4.2.2",
|
||||||
"array-includes": "^3.1.1",
|
"array-includes": "^3.1.4",
|
||||||
"ast-types-flow": "^0.0.7",
|
"ast-types-flow": "^0.0.7",
|
||||||
"axe-core": "^4.0.2",
|
"axe-core": "^4.3.5",
|
||||||
"axobject-query": "^2.2.0",
|
"axobject-query": "^2.2.0",
|
||||||
"damerau-levenshtein": "^1.0.6",
|
"damerau-levenshtein": "^1.0.7",
|
||||||
"emoji-regex": "^9.0.0",
|
"emoji-regex": "^9.2.2",
|
||||||
"has": "^1.0.3",
|
"has": "^1.0.3",
|
||||||
"jsx-ast-utils": "^3.1.0",
|
"jsx-ast-utils": "^3.2.1",
|
||||||
"language-tags": "^1.0.5"
|
"language-tags": "^1.0.5",
|
||||||
|
"minimatch": "^3.0.4"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=4.0"
|
"node": ">=4.0"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"eslint": "^3 || ^4 || ^5 || ^6 || ^7"
|
"eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/eslint-plugin-jsx-a11y/node_modules/emoji-regex": {
|
"node_modules/eslint-plugin-jsx-a11y/node_modules/emoji-regex": {
|
||||||
|
@ -8655,41 +8696,41 @@
|
||||||
"integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg=="
|
"integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg=="
|
||||||
},
|
},
|
||||||
"node_modules/eslint-plugin-react": {
|
"node_modules/eslint-plugin-react": {
|
||||||
"version": "7.26.1",
|
"version": "7.28.0",
|
||||||
"resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.26.1.tgz",
|
"resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.28.0.tgz",
|
||||||
"integrity": "sha512-Lug0+NOFXeOE+ORZ5pbsh6mSKjBKXDXItUD2sQoT+5Yl0eoT82DqnXeTMfUare4QVCn9QwXbfzO/dBLjLXwVjQ==",
|
"integrity": "sha512-IOlFIRHzWfEQQKcAD4iyYDndHwTQiCMcJVJjxempf203jnNLUnW34AXLrV33+nEXoifJE2ZEGmcjKPL8957eSw==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"array-includes": "^3.1.3",
|
"array-includes": "^3.1.4",
|
||||||
"array.prototype.flatmap": "^1.2.4",
|
"array.prototype.flatmap": "^1.2.5",
|
||||||
"doctrine": "^2.1.0",
|
"doctrine": "^2.1.0",
|
||||||
"estraverse": "^5.2.0",
|
"estraverse": "^5.3.0",
|
||||||
"jsx-ast-utils": "^2.4.1 || ^3.0.0",
|
"jsx-ast-utils": "^2.4.1 || ^3.0.0",
|
||||||
"minimatch": "^3.0.4",
|
"minimatch": "^3.0.4",
|
||||||
"object.entries": "^1.1.4",
|
"object.entries": "^1.1.5",
|
||||||
"object.fromentries": "^2.0.4",
|
"object.fromentries": "^2.0.5",
|
||||||
"object.hasown": "^1.0.0",
|
"object.hasown": "^1.1.0",
|
||||||
"object.values": "^1.1.4",
|
"object.values": "^1.1.5",
|
||||||
"prop-types": "^15.7.2",
|
"prop-types": "^15.7.2",
|
||||||
"resolve": "^2.0.0-next.3",
|
"resolve": "^2.0.0-next.3",
|
||||||
"semver": "^6.3.0",
|
"semver": "^6.3.0",
|
||||||
"string.prototype.matchall": "^4.0.5"
|
"string.prototype.matchall": "^4.0.6"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=4"
|
"node": ">=4"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"eslint": "^3 || ^4 || ^5 || ^6 || ^7"
|
"eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/eslint-plugin-react-hooks": {
|
"node_modules/eslint-plugin-react-hooks": {
|
||||||
"version": "4.2.0",
|
"version": "4.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.3.0.tgz",
|
||||||
"integrity": "sha512-623WEiZJqxR7VdxFCKLI6d6LLpwJkGPYKODnkH3D7WpOG5KM8yWueBd8TLsNAetEJNF5iJmolaAKO3F8yzyVBQ==",
|
"integrity": "sha512-XslZy0LnMn+84NEG9jSGR6eGqaZB3133L8xewQo3fQagbQuGt7a63gf+P1NGKZavEYEC3UXaWEAA/AqDkuN6xA==",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=10"
|
"node": ">=10"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0"
|
"eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/eslint-plugin-react/node_modules/doctrine": {
|
"node_modules/eslint-plugin-react/node_modules/doctrine": {
|
||||||
|
@ -8704,9 +8745,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/eslint-plugin-react/node_modules/estraverse": {
|
"node_modules/eslint-plugin-react/node_modules/estraverse": {
|
||||||
"version": "5.2.0",
|
"version": "5.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
|
||||||
"integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==",
|
"integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=4.0"
|
"node": ">=4.0"
|
||||||
}
|
}
|
||||||
|
@ -19939,9 +19980,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/tsconfig-paths": {
|
"node_modules/tsconfig-paths": {
|
||||||
"version": "3.11.0",
|
"version": "3.12.0",
|
||||||
"resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.11.0.tgz",
|
"resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.12.0.tgz",
|
||||||
"integrity": "sha512-7ecdYDnIdmv639mmDwslG6KQg1Z9STTz1j7Gcz0xa+nshh/gKDAHcPxRbWOsA3SPp0tXP2leTcY9Kw+NAkfZzA==",
|
"integrity": "sha512-e5adrnOYT6zqVnWqZu7i/BQ3BnhzvGbjEjejFXO20lKIKpwTaupkCPgEfv4GZK1IBciJUEhYs3J3p75FdaTFVg==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/json5": "^0.0.29",
|
"@types/json5": "^0.0.29",
|
||||||
"json5": "^1.0.1",
|
"json5": "^1.0.1",
|
||||||
|
@ -25990,9 +26031,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"axe-core": {
|
"axe-core": {
|
||||||
"version": "4.3.3",
|
"version": "4.3.5",
|
||||||
"resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.3.3.tgz",
|
"resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.3.5.tgz",
|
||||||
"integrity": "sha512-/lqqLAmuIPi79WYfRpy2i8z+x+vxU3zX2uAm0gs1q52qTuKwolOj1P8XbufpXcsydrpKx2yGn2wzAnxCMV86QA=="
|
"integrity": "sha512-WKTW1+xAzhMS5dJsxWkliixlO/PqC4VhmO9T4juNYcaTg9jzWiJsou6m5pxWYGfigWbwzJWeFY6z47a+4neRXA=="
|
||||||
},
|
},
|
||||||
"axios": {
|
"axios": {
|
||||||
"version": "0.24.0",
|
"version": "0.24.0",
|
||||||
|
@ -28635,6 +28676,37 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"eslint-config-airbnb": {
|
||||||
|
"version": "19.0.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/eslint-config-airbnb/-/eslint-config-airbnb-19.0.4.tgz",
|
||||||
|
"integrity": "sha512-T75QYQVQX57jiNgpF9r1KegMICE94VYwoFQyMGhrvc+lB8YF2E/M/PYDaQe1AJcWaEgqLE+ErXV1Og/+6Vyzew==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"eslint-config-airbnb-base": "^15.0.0",
|
||||||
|
"object.assign": "^4.1.2",
|
||||||
|
"object.entries": "^1.1.5"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"eslint-config-airbnb-base": {
|
||||||
|
"version": "15.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-15.0.0.tgz",
|
||||||
|
"integrity": "sha512-xaX3z4ZZIcFLvh2oUNvcX5oEofXda7giYmuplVxoOg5A7EXJMrUyqRgR+mhDhPK8LZ4PttFOBvCYDbX3sUoUig==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"confusing-browser-globals": "^1.0.10",
|
||||||
|
"object.assign": "^4.1.2",
|
||||||
|
"object.entries": "^1.1.5",
|
||||||
|
"semver": "^6.3.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"semver": {
|
||||||
|
"version": "6.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
|
||||||
|
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
|
||||||
|
"dev": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"eslint-config-react-app": {
|
"eslint-config-react-app": {
|
||||||
"version": "6.0.0",
|
"version": "6.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/eslint-config-react-app/-/eslint-config-react-app-6.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/eslint-config-react-app/-/eslint-config-react-app-6.0.0.tgz",
|
||||||
|
@ -28672,13 +28744,12 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"eslint-module-utils": {
|
"eslint-module-utils": {
|
||||||
"version": "2.7.1",
|
"version": "2.7.2",
|
||||||
"resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.1.tgz",
|
"resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.2.tgz",
|
||||||
"integrity": "sha512-fjoetBXQZq2tSTWZ9yWVl2KuFrTZZH3V+9iD1V1RfpDgxzJR+mPd/KZmMiA8gbPqdBzpNiEHOuT7IYEWxrH0zQ==",
|
"integrity": "sha512-zquepFnWCY2ISMFwD/DqzaM++H+7PDzOpUvotJWm/y1BAFt5R4oeULgdrTejKqLkz7MA/tgstsUMNYc7wNdTrg==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"debug": "^3.2.7",
|
"debug": "^3.2.7",
|
||||||
"find-up": "^2.1.0",
|
"find-up": "^2.1.0"
|
||||||
"pkg-dir": "^2.0.0"
|
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"debug": {
|
"debug": {
|
||||||
|
@ -28731,14 +28802,6 @@
|
||||||
"version": "3.0.0",
|
"version": "3.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
|
||||||
"integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU="
|
"integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU="
|
||||||
},
|
|
||||||
"pkg-dir": {
|
|
||||||
"version": "2.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz",
|
|
||||||
"integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=",
|
|
||||||
"requires": {
|
|
||||||
"find-up": "^2.1.0"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -28752,23 +28815,23 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"eslint-plugin-import": {
|
"eslint-plugin-import": {
|
||||||
"version": "2.25.2",
|
"version": "2.25.4",
|
||||||
"resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.25.2.tgz",
|
"resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.25.4.tgz",
|
||||||
"integrity": "sha512-qCwQr9TYfoBHOFcVGKY9C9unq05uOxxdklmBXLVvcwo68y5Hta6/GzCZEMx2zQiu0woKNEER0LE7ZgaOfBU14g==",
|
"integrity": "sha512-/KJBASVFxpu0xg1kIBn9AUa8hQVnszpwgE7Ld0lKAlx7Ie87yzEzCgSkekt+le/YVhiaosO4Y14GDAOc41nfxA==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"array-includes": "^3.1.4",
|
"array-includes": "^3.1.4",
|
||||||
"array.prototype.flat": "^1.2.5",
|
"array.prototype.flat": "^1.2.5",
|
||||||
"debug": "^2.6.9",
|
"debug": "^2.6.9",
|
||||||
"doctrine": "^2.1.0",
|
"doctrine": "^2.1.0",
|
||||||
"eslint-import-resolver-node": "^0.3.6",
|
"eslint-import-resolver-node": "^0.3.6",
|
||||||
"eslint-module-utils": "^2.7.0",
|
"eslint-module-utils": "^2.7.2",
|
||||||
"has": "^1.0.3",
|
"has": "^1.0.3",
|
||||||
"is-core-module": "^2.7.0",
|
"is-core-module": "^2.8.0",
|
||||||
"is-glob": "^4.0.3",
|
"is-glob": "^4.0.3",
|
||||||
"minimatch": "^3.0.4",
|
"minimatch": "^3.0.4",
|
||||||
"object.values": "^1.1.5",
|
"object.values": "^1.1.5",
|
||||||
"resolve": "^1.20.0",
|
"resolve": "^1.20.0",
|
||||||
"tsconfig-paths": "^3.11.0"
|
"tsconfig-paths": "^3.12.0"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"debug": {
|
"debug": {
|
||||||
|
@ -28812,21 +28875,22 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"eslint-plugin-jsx-a11y": {
|
"eslint-plugin-jsx-a11y": {
|
||||||
"version": "6.4.1",
|
"version": "6.5.1",
|
||||||
"resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.5.1.tgz",
|
||||||
"integrity": "sha512-0rGPJBbwHoGNPU73/QCLP/vveMlM1b1Z9PponxO87jfr6tuH5ligXbDT6nHSSzBC8ovX2Z+BQu7Bk5D/Xgq9zg==",
|
"integrity": "sha512-sVCFKX9fllURnXT2JwLN5Qgo24Ug5NF6dxhkmxsMEUZhXRcGg+X3e1JbJ84YePQKBl5E0ZjAH5Q4rkdcGY99+g==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@babel/runtime": "^7.11.2",
|
"@babel/runtime": "^7.16.3",
|
||||||
"aria-query": "^4.2.2",
|
"aria-query": "^4.2.2",
|
||||||
"array-includes": "^3.1.1",
|
"array-includes": "^3.1.4",
|
||||||
"ast-types-flow": "^0.0.7",
|
"ast-types-flow": "^0.0.7",
|
||||||
"axe-core": "^4.0.2",
|
"axe-core": "^4.3.5",
|
||||||
"axobject-query": "^2.2.0",
|
"axobject-query": "^2.2.0",
|
||||||
"damerau-levenshtein": "^1.0.6",
|
"damerau-levenshtein": "^1.0.7",
|
||||||
"emoji-regex": "^9.0.0",
|
"emoji-regex": "^9.2.2",
|
||||||
"has": "^1.0.3",
|
"has": "^1.0.3",
|
||||||
"jsx-ast-utils": "^3.1.0",
|
"jsx-ast-utils": "^3.2.1",
|
||||||
"language-tags": "^1.0.5"
|
"language-tags": "^1.0.5",
|
||||||
|
"minimatch": "^3.0.4"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"emoji-regex": {
|
"emoji-regex": {
|
||||||
|
@ -28837,24 +28901,24 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"eslint-plugin-react": {
|
"eslint-plugin-react": {
|
||||||
"version": "7.26.1",
|
"version": "7.28.0",
|
||||||
"resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.26.1.tgz",
|
"resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.28.0.tgz",
|
||||||
"integrity": "sha512-Lug0+NOFXeOE+ORZ5pbsh6mSKjBKXDXItUD2sQoT+5Yl0eoT82DqnXeTMfUare4QVCn9QwXbfzO/dBLjLXwVjQ==",
|
"integrity": "sha512-IOlFIRHzWfEQQKcAD4iyYDndHwTQiCMcJVJjxempf203jnNLUnW34AXLrV33+nEXoifJE2ZEGmcjKPL8957eSw==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"array-includes": "^3.1.3",
|
"array-includes": "^3.1.4",
|
||||||
"array.prototype.flatmap": "^1.2.4",
|
"array.prototype.flatmap": "^1.2.5",
|
||||||
"doctrine": "^2.1.0",
|
"doctrine": "^2.1.0",
|
||||||
"estraverse": "^5.2.0",
|
"estraverse": "^5.3.0",
|
||||||
"jsx-ast-utils": "^2.4.1 || ^3.0.0",
|
"jsx-ast-utils": "^2.4.1 || ^3.0.0",
|
||||||
"minimatch": "^3.0.4",
|
"minimatch": "^3.0.4",
|
||||||
"object.entries": "^1.1.4",
|
"object.entries": "^1.1.5",
|
||||||
"object.fromentries": "^2.0.4",
|
"object.fromentries": "^2.0.5",
|
||||||
"object.hasown": "^1.0.0",
|
"object.hasown": "^1.1.0",
|
||||||
"object.values": "^1.1.4",
|
"object.values": "^1.1.5",
|
||||||
"prop-types": "^15.7.2",
|
"prop-types": "^15.7.2",
|
||||||
"resolve": "^2.0.0-next.3",
|
"resolve": "^2.0.0-next.3",
|
||||||
"semver": "^6.3.0",
|
"semver": "^6.3.0",
|
||||||
"string.prototype.matchall": "^4.0.5"
|
"string.prototype.matchall": "^4.0.6"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"doctrine": {
|
"doctrine": {
|
||||||
|
@ -28866,9 +28930,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"estraverse": {
|
"estraverse": {
|
||||||
"version": "5.2.0",
|
"version": "5.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
|
||||||
"integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ=="
|
"integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA=="
|
||||||
},
|
},
|
||||||
"resolve": {
|
"resolve": {
|
||||||
"version": "2.0.0-next.3",
|
"version": "2.0.0-next.3",
|
||||||
|
@ -28887,9 +28951,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"eslint-plugin-react-hooks": {
|
"eslint-plugin-react-hooks": {
|
||||||
"version": "4.2.0",
|
"version": "4.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.3.0.tgz",
|
||||||
"integrity": "sha512-623WEiZJqxR7VdxFCKLI6d6LLpwJkGPYKODnkH3D7WpOG5KM8yWueBd8TLsNAetEJNF5iJmolaAKO3F8yzyVBQ==",
|
"integrity": "sha512-XslZy0LnMn+84NEG9jSGR6eGqaZB3133L8xewQo3fQagbQuGt7a63gf+P1NGKZavEYEC3UXaWEAA/AqDkuN6xA==",
|
||||||
"requires": {}
|
"requires": {}
|
||||||
},
|
},
|
||||||
"eslint-plugin-testing-library": {
|
"eslint-plugin-testing-library": {
|
||||||
|
@ -37426,9 +37490,9 @@
|
||||||
"integrity": "sha512-csd+vJOb/gkzvcCHgTGSChYpy5f1/XKNsmvBGO4JXS+z1v2HobugDz4s1IeFXM3wZB44uczs+eazB5Q/ccdhQw=="
|
"integrity": "sha512-csd+vJOb/gkzvcCHgTGSChYpy5f1/XKNsmvBGO4JXS+z1v2HobugDz4s1IeFXM3wZB44uczs+eazB5Q/ccdhQw=="
|
||||||
},
|
},
|
||||||
"tsconfig-paths": {
|
"tsconfig-paths": {
|
||||||
"version": "3.11.0",
|
"version": "3.12.0",
|
||||||
"resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.11.0.tgz",
|
"resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.12.0.tgz",
|
||||||
"integrity": "sha512-7ecdYDnIdmv639mmDwslG6KQg1Z9STTz1j7Gcz0xa+nshh/gKDAHcPxRbWOsA3SPp0tXP2leTcY9Kw+NAkfZzA==",
|
"integrity": "sha512-e5adrnOYT6zqVnWqZu7i/BQ3BnhzvGbjEjejFXO20lKIKpwTaupkCPgEfv4GZK1IBciJUEhYs3J3p75FdaTFVg==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@types/json5": "^0.0.29",
|
"@types/json5": "^0.0.29",
|
||||||
"json5": "^1.0.1",
|
"json5": "^1.0.1",
|
||||||
|
|
|
@ -6,7 +6,9 @@
|
||||||
"start": "react-scripts start",
|
"start": "react-scripts start",
|
||||||
"build": "react-scripts build",
|
"build": "react-scripts build",
|
||||||
"test": "react-scripts test",
|
"test": "react-scripts test",
|
||||||
"eject": "react-scripts eject"
|
"eject": "react-scripts eject",
|
||||||
|
"lint": "eslint src --ext .js,.jsx",
|
||||||
|
"lint:fix": "npm run lint -- --fix"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@emotion/react": "^11.7.1",
|
"@emotion/react": "^11.7.1",
|
||||||
|
@ -32,6 +34,9 @@
|
||||||
"styled-components": "^5.3.3",
|
"styled-components": "^5.3.3",
|
||||||
"web-vitals": "^1.1.2"
|
"web-vitals": "^1.1.2"
|
||||||
},
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"eslint-config-airbnb": "^19.0.4"
|
||||||
|
},
|
||||||
"browserslist": {
|
"browserslist": {
|
||||||
"production": [
|
"production": [
|
||||||
">0.2%",
|
">0.2%",
|
||||||
|
|
33
src/App.js
33
src/App.js
|
@ -1,38 +1,25 @@
|
||||||
import CssBaseline from '@mui/material/CssBaseline';
|
import CssBaseline from '@mui/material/CssBaseline';
|
||||||
import { createTheme, ThemeProvider } from '@mui/material/styles';
|
import { createTheme, ThemeProvider } from '@mui/material/styles';
|
||||||
import React, { useState } from 'react';
|
import React, { useState } from 'react';
|
||||||
import Login from "./components/views/login";
|
import Login from './components/views/login';
|
||||||
import UserAdmin from "./components/views/useradmin";
|
import UserAdmin from './components/views/useradmin';
|
||||||
import GlobalSnack from './components/widgets/globalSnack';
|
import GlobalSnack from './components/widgets/globalSnack';
|
||||||
import DeviceStore from "./context/devices";
|
import DeviceStore from './context/devices';
|
||||||
import ToastStore from "./context/toast";
|
import ToastStore from './context/toast';
|
||||||
import { UserProvider } from "./context/users";
|
import { UserProvider } from './context/users';
|
||||||
import * as authenticationController from "./controllers/authentication";
|
import * as authenticationController from './controllers/authentication';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Connection opened
|
// Connection opened
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
|
const [session, setSession] = useState(false);
|
||||||
|
|
||||||
const [session, setSession] = useState(false)
|
|
||||||
|
|
||||||
authenticationController.getSession().then((res) => {
|
authenticationController.getSession().then((res) => {
|
||||||
setSession(res.data.authenticated)
|
setSession(res.data.authenticated);
|
||||||
|
});
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const theme = React.useMemo(
|
const theme = React.useMemo(
|
||||||
() =>
|
() => createTheme({
|
||||||
createTheme({
|
|
||||||
palette: {
|
palette: {
|
||||||
mode: window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light',
|
mode: window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light',
|
||||||
},
|
},
|
||||||
|
|
|
@ -2,5 +2,5 @@ import { render, screen } from '@testing-library/react';
|
||||||
import App from './App';
|
import App from './App';
|
||||||
|
|
||||||
test('renders learn react link', () => {
|
test('renders learn react link', () => {
|
||||||
render(<p></p>);
|
render(<p />);
|
||||||
});
|
});
|
||||||
|
|
|
@ -6,123 +6,119 @@ import DrivesTable from './tabPane';
|
||||||
|
|
||||||
function DeviceLastSeenMap() {
|
function DeviceLastSeenMap() {
|
||||||
return (
|
return (
|
||||||
<div style={{ height: "500px", width: 'calc(100%)' }}>
|
<div style={{ height: '500px', width: 'calc(100%)' }}>
|
||||||
|
|
||||||
<GoogleMapReact
|
<GoogleMapReact
|
||||||
height="100px"
|
height="100px"
|
||||||
bootstrapURLKeys={{ key: process.env.REACT_APP_GMAPS_API_KEY }}
|
bootstrapURLKeys={{ key: process.env.REACT_APP_GMAPS_API_KEY }}
|
||||||
defaultCenter={{
|
defaultCenter={{
|
||||||
lat: 51.501134,
|
lat: 51.501134,
|
||||||
lng: -0.142318
|
lng: -0.142318,
|
||||||
}}
|
}}
|
||||||
defaultZoom={17}
|
defaultZoom={17}
|
||||||
options={{
|
options={{
|
||||||
styles: [
|
styles: [
|
||||||
{ elementType: "geometry", stylers: [{ color: "#242f3e" }] },
|
{ elementType: 'geometry', stylers: [{ color: '#242f3e' }] },
|
||||||
{ elementType: "labels.text.stroke", stylers: [{ color: "#242f3e" }] },
|
{ elementType: 'labels.text.stroke', stylers: [{ color: '#242f3e' }] },
|
||||||
{ elementType: "labels.text.fill", stylers: [{ color: "#746855" }] },
|
{ elementType: 'labels.text.fill', stylers: [{ color: '#746855' }] },
|
||||||
{
|
{
|
||||||
featureType: "administrative.locality",
|
featureType: 'administrative.locality',
|
||||||
elementType: "labels.text.fill",
|
elementType: 'labels.text.fill',
|
||||||
stylers: [{ color: "#d59563" }],
|
stylers: [{ color: '#d59563' }],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
featureType: "poi",
|
featureType: 'poi',
|
||||||
elementType: "labels.text.fill",
|
elementType: 'labels.text.fill',
|
||||||
stylers: [{ color: "#d59563" }],
|
stylers: [{ color: '#d59563' }],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
featureType: "poi.park",
|
featureType: 'poi.park',
|
||||||
elementType: "geometry",
|
elementType: 'geometry',
|
||||||
stylers: [{ color: "#263c3f" }],
|
stylers: [{ color: '#263c3f' }],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
featureType: "poi.park",
|
featureType: 'poi.park',
|
||||||
elementType: "labels.text.fill",
|
elementType: 'labels.text.fill',
|
||||||
stylers: [{ color: "#6b9a76" }],
|
stylers: [{ color: '#6b9a76' }],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
featureType: "road",
|
featureType: 'road',
|
||||||
elementType: "geometry",
|
elementType: 'geometry',
|
||||||
stylers: [{ color: "#38414e" }],
|
stylers: [{ color: '#38414e' }],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
featureType: "road",
|
featureType: 'road',
|
||||||
elementType: "geometry.stroke",
|
elementType: 'geometry.stroke',
|
||||||
stylers: [{ color: "#212a37" }],
|
stylers: [{ color: '#212a37' }],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
featureType: "road",
|
featureType: 'road',
|
||||||
elementType: "labels.text.fill",
|
elementType: 'labels.text.fill',
|
||||||
stylers: [{ color: "#9ca5b3" }],
|
stylers: [{ color: '#9ca5b3' }],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
featureType: "road.highway",
|
featureType: 'road.highway',
|
||||||
elementType: "geometry",
|
elementType: 'geometry',
|
||||||
stylers: [{ color: "#746855" }],
|
stylers: [{ color: '#746855' }],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
featureType: "road.highway",
|
featureType: 'road.highway',
|
||||||
elementType: "geometry.stroke",
|
elementType: 'geometry.stroke',
|
||||||
stylers: [{ color: "#1f2835" }],
|
stylers: [{ color: '#1f2835' }],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
featureType: "road.highway",
|
featureType: 'road.highway',
|
||||||
elementType: "labels.text.fill",
|
elementType: 'labels.text.fill',
|
||||||
stylers: [{ color: "#f3d19c" }],
|
stylers: [{ color: '#f3d19c' }],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
featureType: "transit",
|
featureType: 'transit',
|
||||||
elementType: "geometry",
|
elementType: 'geometry',
|
||||||
stylers: [{ color: "#2f3948" }],
|
stylers: [{ color: '#2f3948' }],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
featureType: "transit.station",
|
featureType: 'transit.station',
|
||||||
elementType: "labels.text.fill",
|
elementType: 'labels.text.fill',
|
||||||
stylers: [{ color: "#d59563" }],
|
stylers: [{ color: '#d59563' }],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
featureType: "water",
|
featureType: 'water',
|
||||||
elementType: "geometry",
|
elementType: 'geometry',
|
||||||
stylers: [{ color: "#17263c" }],
|
stylers: [{ color: '#17263c' }],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
featureType: "water",
|
featureType: 'water',
|
||||||
elementType: "labels.text.fill",
|
elementType: 'labels.text.fill',
|
||||||
stylers: [{ color: "#515c6d" }],
|
stylers: [{ color: '#515c6d' }],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
featureType: "water",
|
featureType: 'water',
|
||||||
elementType: "labels.text.stroke",
|
elementType: 'labels.text.stroke',
|
||||||
stylers: [{ color: "#17263c" }],
|
stylers: [{ color: '#17263c' }],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export default function SignIn(props) {
|
export default function SignIn(props) {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div style={{
|
<div style={{
|
||||||
height: "100%",
|
height: '100%',
|
||||||
width: "100%",
|
width: '100%',
|
||||||
}}>
|
}}
|
||||||
|
>
|
||||||
|
|
||||||
<Scrollbars autoHeightMin="100%" autoHeightMax="100%">
|
<Scrollbars autoHeightMin="100%" autoHeightMax="100%">
|
||||||
<Grid container style={{padding: 30}}>
|
<Grid container style={{ padding: 30 }}>
|
||||||
<Grid item xs={12}>
|
<Grid item xs={12}>
|
||||||
<DeviceLastSeenMap />
|
<DeviceLastSeenMap />
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
<Grid item xs={12}>
|
<Grid item xs={12}>
|
||||||
<DrivesTable dongleId={props.device.dongle_id}/>
|
<DrivesTable dongleId={props.device.dongle_id} />
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
</Grid>
|
</Grid>
|
||||||
|
@ -131,5 +127,3 @@ export default function SignIn(props) {
|
||||||
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -5,35 +5,26 @@ import Grid from '@mui/material/Grid';
|
||||||
import Typography from '@mui/material/Typography';
|
import Typography from '@mui/material/Typography';
|
||||||
import React, { useEffect } from 'react';
|
import React, { useEffect } from 'react';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const stylezz = {
|
const stylezz = {
|
||||||
margin: '0px 2px 0px 0px',
|
margin: '0px 2px 0px 0px',
|
||||||
}
|
};
|
||||||
|
|
||||||
function timeSince(date) {
|
function timeSince(date) {
|
||||||
|
const seconds = Math.floor((new Date() - date) / 1000);
|
||||||
|
|
||||||
|
|
||||||
var seconds = Math.floor((new Date() - date) / 1000);
|
|
||||||
|
|
||||||
if (seconds / 86400 > 1) {
|
if (seconds / 86400 > 1) {
|
||||||
return Math.floor(seconds / 86400) + `d`;
|
return `${Math.floor(seconds / 86400)}d`;
|
||||||
} else if (seconds / 3600 > 1) {
|
} if (seconds / 3600 > 1) {
|
||||||
return Math.floor(seconds / 3600) + `h`;
|
return `${Math.floor(seconds / 3600)}h`;
|
||||||
} else if (seconds / 60 > 1) {
|
} if (seconds / 60 > 1) {
|
||||||
return Math.floor(seconds / 60) + `m`;
|
return `${Math.floor(seconds / 60)}m`;
|
||||||
} else {
|
|
||||||
return "just now";
|
|
||||||
}
|
}
|
||||||
|
return 'just now';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export default function SignIn(props) {
|
export default function SignIn(props) {
|
||||||
|
|
||||||
const [state, setState] = React.useState({ count: 0, last_seen: 0 });
|
const [state, setState] = React.useState({ count: 0, last_seen: 0 });
|
||||||
const device = props.device;
|
const { device } = props;
|
||||||
|
|
||||||
// Reloads component to update X time ago
|
// Reloads component to update X time ago
|
||||||
// TODO prevent X time ago from being refreshed when the device has been
|
// TODO prevent X time ago from being refreshed when the device has been
|
||||||
|
@ -41,21 +32,18 @@ export default function SignIn(props) {
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setInterval(() => {
|
setInterval(() => {
|
||||||
setState({ ...state, count: state.count + 1 })
|
setState({ ...state, count: state.count + 1 });
|
||||||
}, 60 * 1000)
|
}, 60 * 1000);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
const deviceLastSeen = timeSince(new Date(device.last_seen));
|
const deviceLastSeen = timeSince(new Date(device.last_seen));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<ButtonBase style={{ padding: '10px' }}>
|
<ButtonBase style={{ padding: '10px' }}>
|
||||||
<Grid container spacing={2}>
|
<Grid container spacing={2}>
|
||||||
<Grid item xs={4}>
|
<Grid item xs={4}>
|
||||||
<img src="/c3.webp" style={{ width: "100%" }} alt="device icon"/>
|
<img src="/c3.webp" style={{ width: '100%' }} alt="device icon" />
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid item xs={8} style={{ textAlign: 'left' }}>
|
<Grid item xs={8} style={{ textAlign: 'left' }}>
|
||||||
{/* <TextField
|
{/* <TextField
|
||||||
|
@ -77,16 +65,17 @@ export default function SignIn(props) {
|
||||||
}}
|
}}
|
||||||
fullWidth
|
fullWidth
|
||||||
|
|
||||||
|
/> */}
|
||||||
/>*/}
|
<Typography variant="body2" align="left" gutterBottom>
|
||||||
<Typography variant="body2" align={"left"} gutterBottom>Dongle: {device.dongle_id}</Typography>
|
Dongle:
|
||||||
|
{device.dongle_id}
|
||||||
|
</Typography>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
|
|
||||||
{device.online ?
|
{device.online
|
||||||
<Chip style={{ background: '#004d40', ...stylezz }} label="Online" size="small" variant="outlined" /> :
|
? <Chip style={{ background: '#004d40', ...stylezz }} label="Online" size="small" variant="outlined" />
|
||||||
<Chip style={{ background: '#b71c1c', ...stylezz }} label={`Offline ${deviceLastSeen}`} size="small" variant="outlined" />
|
: <Chip style={{ background: '#b71c1c', ...stylezz }} label={`Offline ${deviceLastSeen}`} size="small" variant="outlined" />}
|
||||||
}
|
|
||||||
|
|
||||||
<Chip style={{ background: '#004d40', ...stylezz }} label="Active" size="small" variant="outlined" />
|
<Chip style={{ background: '#004d40', ...stylezz }} label="Active" size="small" variant="outlined" />
|
||||||
</div>
|
</div>
|
||||||
|
@ -98,5 +87,3 @@ export default function SignIn(props) {
|
||||||
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -13,39 +13,36 @@ import TableHead from '@mui/material/TableHead';
|
||||||
import TableRow from '@mui/material/TableRow';
|
import TableRow from '@mui/material/TableRow';
|
||||||
import Tooltip from '@mui/material/Tooltip';
|
import Tooltip from '@mui/material/Tooltip';
|
||||||
import React, { useContext, useEffect } from 'react';
|
import React, { useContext, useEffect } from 'react';
|
||||||
import { context as DeviceContext } from "./../../../context/devices";
|
import { context as DeviceContext } from '../../../context/devices';
|
||||||
import { context as SnackbarContext } from "./../../../context/toast";
|
import { context as SnackbarContext } from '../../../context/toast';
|
||||||
import * as deviceController from "./../../../controllers/devices";
|
import * as deviceController from '../../../controllers/devices';
|
||||||
import * as helpers from "./../../../controllers/helpers"
|
import * as helpers from '../../../controllers/helpers';
|
||||||
|
|
||||||
|
|
||||||
function loading() {
|
function loading() {
|
||||||
return (
|
return (
|
||||||
<TableRow>
|
<TableRow>
|
||||||
<TableCell ><Skeleton animation="wave" /></TableCell>
|
<TableCell><Skeleton animation="wave" /></TableCell>
|
||||||
<TableCell ><Skeleton animation="wave" /></TableCell>
|
<TableCell><Skeleton animation="wave" /></TableCell>
|
||||||
<TableCell ><Skeleton animation="wave" /></TableCell>
|
<TableCell><Skeleton animation="wave" /></TableCell>
|
||||||
<TableCell ><Skeleton animation="wave" /></TableCell>
|
<TableCell><Skeleton animation="wave" /></TableCell>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export default function EnhancedTable(props) {
|
export default function EnhancedTable(props) {
|
||||||
const [state, dispatch] = useContext(DeviceContext)
|
const [state, dispatch] = useContext(DeviceContext);
|
||||||
|
|
||||||
const [, notifDispatch] = useContext(SnackbarContext)
|
const [, notifDispatch] = useContext(SnackbarContext);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
deviceController.getBootlogs(props.dongleId).then((res) => {
|
deviceController.getBootlogs(props.dongleId).then((res) => {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
dispatch({ type: "update_dongle_bootlogs", dongle_id: props.dongleId, bootlogs: res.data })
|
dispatch({ type: 'update_dongle_bootlogs', dongle_id: props.dongleId, bootlogs: res.data });
|
||||||
}, 1)
|
}, 1);
|
||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
notifDispatch({type: "NEW_TOAST", msg: 'Failed to load bootlogs'})
|
notifDispatch({ type: 'NEW_TOAST', msg: 'Failed to load bootlogs' });
|
||||||
})
|
});
|
||||||
|
}, [dispatch, notifDispatch, props.dongleId]);
|
||||||
}, [dispatch, notifDispatch, props.dongleId])
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box sx={{ width: '100%' }}>
|
<Box sx={{ width: '100%' }}>
|
||||||
|
@ -54,51 +51,48 @@ export default function EnhancedTable(props) {
|
||||||
<Table
|
<Table
|
||||||
sx={{ minWidth: 750 }}
|
sx={{ minWidth: 750 }}
|
||||||
aria-labelledby="tableTitle"
|
aria-labelledby="tableTitle"
|
||||||
size={'small'}
|
size="small"
|
||||||
>
|
>
|
||||||
<TableHead>
|
<TableHead>
|
||||||
<TableRow>
|
<TableRow>
|
||||||
<TableCell >Date</TableCell>
|
<TableCell>Date</TableCell>
|
||||||
<TableCell >File</TableCell>
|
<TableCell>File</TableCell>
|
||||||
<TableCell >File size</TableCell>
|
<TableCell>File size</TableCell>
|
||||||
<TableCell >Actions</TableCell>
|
<TableCell>Actions</TableCell>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
</TableHead>
|
</TableHead>
|
||||||
|
|
||||||
<TableBody>
|
<TableBody>
|
||||||
{/* if you don't need to support IE11, you can replace the `stableSort` call with:
|
{/* if you don't need to support IE11, you can replace the `stableSort` call with:
|
||||||
rows.slice().sort(getComparator(order, orderBy)) */}
|
rows.slice().sort(getComparator(order, orderBy)) */}
|
||||||
{state.dongles[props.dongleId].boot ? state.dongles[props.dongleId].boot.map((row) => {
|
{state.dongles[props.dongleId].boot ? state.dongles[props.dongleId].boot.map((row) => (
|
||||||
return (
|
|
||||||
<TableRow hover>
|
<TableRow hover>
|
||||||
<TableCell >{helpers.formatDate(row.date)}</TableCell>
|
<TableCell>{helpers.formatDate(row.date)}</TableCell>
|
||||||
<TableCell >{row.name}</TableCell>
|
<TableCell>{row.name}</TableCell>
|
||||||
<TableCell >{Math.round(row.size / 1024) + ' MiB'}</TableCell>
|
<TableCell>{`${Math.round(row.size / 1024)} MiB`}</TableCell>
|
||||||
<TableCell>
|
<TableCell>
|
||||||
<Tooltip title="Open in new window">
|
<Tooltip title="Open in new window">
|
||||||
|
|
||||||
<IconButton size="small" onClick={() => window.open(row.permalink, "_blank")}>
|
<IconButton size="small" onClick={() => window.open(row.permalink, '_blank')}>
|
||||||
<OpenInNewIcon fontSize="inherit"/>
|
<OpenInNewIcon fontSize="inherit" />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
|
||||||
<Tooltip title="Preserve">
|
<Tooltip title="Preserve">
|
||||||
<IconButton size="small">
|
<IconButton size="small">
|
||||||
<FavoriteBorderIcon fontSize="inherit"/>
|
<FavoriteBorderIcon fontSize="inherit" />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
|
||||||
<Tooltip title="Delete">
|
<Tooltip title="Delete">
|
||||||
<IconButton size="small">
|
<IconButton size="small">
|
||||||
<DeleteIcon fontSize="inherit"/>
|
<DeleteIcon fontSize="inherit" />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
|
||||||
</TableCell>
|
</TableCell>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
)
|
)) : [1, 1, 1, 1, 1].map(loading) }
|
||||||
|
|
||||||
}) : [1, 1, 1, 1, 1].map(loading) }
|
|
||||||
</TableBody>
|
</TableBody>
|
||||||
</Table>
|
</Table>
|
||||||
</TableContainer>
|
</TableContainer>
|
||||||
|
@ -106,4 +100,3 @@ export default function EnhancedTable(props) {
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
|
||||||
import DeleteIcon from '@mui/icons-material/Delete';
|
import DeleteIcon from '@mui/icons-material/Delete';
|
||||||
import FavoriteBorderIcon from '@mui/icons-material/FavoriteBorder';
|
import FavoriteBorderIcon from '@mui/icons-material/FavoriteBorder';
|
||||||
|
@ -15,13 +15,9 @@ import TableHead from '@mui/material/TableHead';
|
||||||
import TableRow from '@mui/material/TableRow';
|
import TableRow from '@mui/material/TableRow';
|
||||||
import Tooltip from '@mui/material/Tooltip';
|
import Tooltip from '@mui/material/Tooltip';
|
||||||
import React, { useContext, useEffect } from 'react';
|
import React, { useContext, useEffect } from 'react';
|
||||||
import { context as DeviceContext } from "./../../../context/devices";
|
import { context as DeviceContext } from '../../../context/devices';
|
||||||
import * as deviceController from "./../../../controllers/devices";
|
import * as deviceController from '../../../controllers/devices';
|
||||||
import * as helpers from "./../../../controllers/helpers"
|
import * as helpers from '../../../controllers/helpers';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function buildContent(row) {
|
function buildContent(row) {
|
||||||
return (
|
return (
|
||||||
|
@ -29,15 +25,13 @@ function buildContent(row) {
|
||||||
hover
|
hover
|
||||||
>
|
>
|
||||||
|
|
||||||
|
<TableCell>{helpers.formatDate(row.date)}</TableCell>
|
||||||
<TableCell >{helpers.formatDate(row.date)}</TableCell>
|
<TableCell>{row.name}</TableCell>
|
||||||
<TableCell >{row.name}</TableCell>
|
<TableCell>{`${Math.round(row.size / 1024)} MiB`}</TableCell>
|
||||||
<TableCell >{Math.round(row.size / 1024) + ' MiB'}</TableCell>
|
|
||||||
|
|
||||||
|
|
||||||
<TableCell>
|
<TableCell>
|
||||||
<Tooltip title="Open in new window">
|
<Tooltip title="Open in new window">
|
||||||
<IconButton size="small" onClick={() => window.open(row.permalink, "_blank")}>
|
<IconButton size="small" onClick={() => window.open(row.permalink, '_blank')}>
|
||||||
<OpenInNewIcon fontSize="inherit" />
|
<OpenInNewIcon fontSize="inherit" />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
@ -56,31 +50,31 @@ function buildContent(row) {
|
||||||
|
|
||||||
</TableCell>
|
</TableCell>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function loading() {
|
function loading() {
|
||||||
return (
|
return (
|
||||||
<TableRow>
|
<TableRow>
|
||||||
<TableCell ><Skeleton animation="wave" /></TableCell>
|
<TableCell><Skeleton animation="wave" /></TableCell>
|
||||||
<TableCell ><Skeleton animation="wave" /></TableCell>
|
<TableCell><Skeleton animation="wave" /></TableCell>
|
||||||
<TableCell ><Skeleton animation="wave" /></TableCell>
|
<TableCell><Skeleton animation="wave" /></TableCell>
|
||||||
<TableCell ><Skeleton animation="wave" /></TableCell>
|
<TableCell><Skeleton animation="wave" /></TableCell>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function EnhancedTable(props) {
|
export default function EnhancedTable(props) {
|
||||||
// eslint-disable-next-line no-unused-vars
|
// eslint-disable-next-line no-unused-vars
|
||||||
const [state, dispatch] = useContext(DeviceContext)
|
const [state, dispatch] = useContext(DeviceContext);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
deviceController.getCrashlogs(props.dongleId).then((res) => {
|
deviceController.getCrashlogs(props.dongleId).then((res) => {
|
||||||
dispatch({ type: "update_dongle_bootlogs", dongle_id: props.dongleId, bootlogs: res.data })
|
dispatch({ type: 'update_dongle_bootlogs', dongle_id: props.dongleId, bootlogs: res.data });
|
||||||
})
|
});
|
||||||
}, [dispatch, props.dongleId]);
|
}, [dispatch, props.dongleId]);
|
||||||
|
|
||||||
console.log("drives", state.dongles[props.dongleId])
|
console.log('drives', state.dongles[props.dongleId]);
|
||||||
console.log("drives", typeof state.dongles[props.dongleId])
|
console.log('drives', typeof state.dongles[props.dongleId]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box sx={{ width: '100%' }}>
|
<Box sx={{ width: '100%' }}>
|
||||||
|
@ -89,23 +83,21 @@ export default function EnhancedTable(props) {
|
||||||
<Table
|
<Table
|
||||||
sx={{ minWidth: 750 }}
|
sx={{ minWidth: 750 }}
|
||||||
aria-labelledby="tableTitle"
|
aria-labelledby="tableTitle"
|
||||||
size={'small'}
|
size="small"
|
||||||
>
|
>
|
||||||
<TableHead>
|
<TableHead>
|
||||||
<TableRow>
|
<TableRow>
|
||||||
<TableCell >Date</TableCell>
|
<TableCell>Date</TableCell>
|
||||||
<TableCell >File</TableCell>
|
<TableCell>File</TableCell>
|
||||||
<TableCell >File size</TableCell>
|
<TableCell>File size</TableCell>
|
||||||
<TableCell >Actions</TableCell>
|
<TableCell>Actions</TableCell>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
</TableHead>
|
</TableHead>
|
||||||
|
|
||||||
<TableBody>
|
<TableBody>
|
||||||
{state.dongles[props.dongleId].crash ?
|
{state.dongles[props.dongleId].crash
|
||||||
state.dongles[props.dongleId].crash.length > 0 ? state.dongles[props.dongleId].crash.map(buildContent) : <p> No drives </p>
|
? state.dongles[props.dongleId].crash.length > 0 ? state.dongles[props.dongleId].crash.map(buildContent) : <p> No drives </p>
|
||||||
:
|
: [1, 1, 1, 1, 1].map(loading)}
|
||||||
[1, 1, 1, 1, 1].map(loading)
|
|
||||||
}
|
|
||||||
|
|
||||||
</TableBody>
|
</TableBody>
|
||||||
</Table>
|
</Table>
|
||||||
|
@ -115,4 +107,3 @@ export default function EnhancedTable(props) {
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,47 +1,37 @@
|
||||||
import ContentCopyIcon from '@mui/icons-material/ContentCopy';
|
import ContentCopyIcon from '@mui/icons-material/ContentCopy';
|
||||||
import Grid from '@mui/material/Grid';
|
import Grid from '@mui/material/Grid';
|
||||||
import IconButton from '@mui/material/IconButton';
|
import IconButton from '@mui/material/IconButton';
|
||||||
import Skeleton from "@mui/material/Skeleton";
|
import Skeleton from '@mui/material/Skeleton';
|
||||||
import Tooltip from '@mui/material/Tooltip';
|
import Tooltip from '@mui/material/Tooltip';
|
||||||
import Typography from '@mui/material/Typography';
|
import Typography from '@mui/material/Typography';
|
||||||
import React, { useContext } from 'react';
|
import React, { useContext } from 'react';
|
||||||
import { context as DeviceContext } from "./../../../context/devices";
|
import { context as DeviceContext } from '../../../context/devices';
|
||||||
import { context as SnackbarContext } from "./../../../context/toast";
|
import { context as SnackbarContext } from '../../../context/toast';
|
||||||
import * as helpers from "./../../../controllers/helpers"
|
import * as helpers from '../../../controllers/helpers';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
export default function SignIn(props) {
|
export default function SignIn(props) {
|
||||||
|
const [state] = useContext(DeviceContext);
|
||||||
const [state] = useContext(DeviceContext)
|
const [, notifDispatch] = useContext(SnackbarContext);
|
||||||
const [, notifDispatch] = useContext(SnackbarContext)
|
|
||||||
|
|
||||||
function pubKeyClipboard(newClip) {
|
function pubKeyClipboard(newClip) {
|
||||||
navigator.clipboard.writeText(newClip).then(function () {
|
navigator.clipboard.writeText(newClip).then(() => {
|
||||||
notifDispatch({
|
notifDispatch({
|
||||||
type: "NEW_TOAST",
|
type: 'NEW_TOAST',
|
||||||
open: true,
|
open: true,
|
||||||
msg: "Successfully copied to clipboard!"
|
msg: 'Successfully copied to clipboard!',
|
||||||
})
|
});
|
||||||
}, function () {
|
}, () => {
|
||||||
notifDispatch({
|
notifDispatch({
|
||||||
type: "NEW_TOAST",
|
type: 'NEW_TOAST',
|
||||||
open: true,
|
open: true,
|
||||||
msg: "Failed to write to clipboard!"
|
msg: 'Failed to write to clipboard!',
|
||||||
})
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!state.dongles[props.dongleId]) { return (<p>no</p>); }
|
||||||
if (!state.dongles[props.dongleId]) { return (<p>no</p>) }
|
|
||||||
const dongle = state.dongles[props.dongleId];
|
const dongle = state.dongles[props.dongleId];
|
||||||
|
|
||||||
|
|
||||||
if (!dongle) {
|
if (!dongle) {
|
||||||
return (
|
return (
|
||||||
<Grid container>
|
<Grid container>
|
||||||
|
@ -53,7 +43,7 @@ export default function SignIn(props) {
|
||||||
|
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -63,29 +53,47 @@ export default function SignIn(props) {
|
||||||
<Grid container>
|
<Grid container>
|
||||||
<Grid item xs={3}>
|
<Grid item xs={3}>
|
||||||
|
|
||||||
|
<b>Nickname:</b>
|
||||||
<b>Nickname:</b> {dongle.nick_name ? dongle.nick_name : `My ${dongle.device_type}`}<br></br>
|
{' '}
|
||||||
<b>Type:</b> {dongle.device_type}<br></br>
|
{dongle.nick_name ? dongle.nick_name : `My ${dongle.device_type}`}
|
||||||
<b>Serial:</b> {dongle.serial}<br></br>
|
<br />
|
||||||
<b>IMEI:</b> {dongle.imei}<br></br>
|
<b>Type:</b>
|
||||||
<b>Registered:</b> {helpers.formatDate(dongle.created)}<br></br>
|
{' '}
|
||||||
<b>Last Ping:</b> {helpers.formatDate(dongle.last_ping)}<br></br>
|
{dongle.device_type}
|
||||||
<b>Public Key:</b> -----BEGIN PUBLIC KEY-----
|
<br />
|
||||||
|
<b>Serial:</b>
|
||||||
|
{' '}
|
||||||
|
{dongle.serial}
|
||||||
|
<br />
|
||||||
|
<b>IMEI:</b>
|
||||||
|
{' '}
|
||||||
|
{dongle.imei}
|
||||||
|
<br />
|
||||||
|
<b>Registered:</b>
|
||||||
|
{' '}
|
||||||
|
{helpers.formatDate(dongle.created)}
|
||||||
|
<br />
|
||||||
|
<b>Last Ping:</b>
|
||||||
|
{' '}
|
||||||
|
{helpers.formatDate(dongle.last_ping)}
|
||||||
|
<br />
|
||||||
|
<b>Public Key:</b>
|
||||||
|
{' '}
|
||||||
|
-----BEGIN PUBLIC KEY-----
|
||||||
<Tooltip title="Copy public key">
|
<Tooltip title="Copy public key">
|
||||||
<IconButton onClick={() => pubKeyClipboard(dongle.public_key)}>
|
<IconButton onClick={() => pubKeyClipboard(dongle.public_key)}>
|
||||||
<ContentCopyIcon />
|
<ContentCopyIcon />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
<br></br>
|
<br />
|
||||||
|
|
||||||
|
<b>Quota Storage: </b>
|
||||||
<b>Quota Storage: </b>{dongle.storage_used} MB / 200000 MB
|
{dongle.storage_used}
|
||||||
|
{' '}
|
||||||
|
MB / 200000 MB
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
|
|
||||||
</Grid>
|
</Grid>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -13,26 +13,26 @@ import TableHead from '@mui/material/TableHead';
|
||||||
import TableRow from '@mui/material/TableRow';
|
import TableRow from '@mui/material/TableRow';
|
||||||
import Tooltip from '@mui/material/Tooltip';
|
import Tooltip from '@mui/material/Tooltip';
|
||||||
import React, { useContext, useEffect, useState } from 'react';
|
import React, { useContext, useEffect, useState } from 'react';
|
||||||
import { context as DeviceContext } from "./../../../context/devices";
|
import { context as DeviceContext } from '../../../context/devices';
|
||||||
import { context as SnackbarContext } from "./../../../context/toast";
|
import { context as SnackbarContext } from '../../../context/toast';
|
||||||
import * as deviceController from "./../../../controllers/devices";
|
import * as deviceController from '../../../controllers/devices';
|
||||||
import * as helpers from "./../../../controllers/helpers"
|
import * as helpers from '../../../controllers/helpers';
|
||||||
import ViewDrive from "./view_drive"
|
import ViewDrive from './view_drive';
|
||||||
|
|
||||||
export default function EnhancedTable(props) {
|
export default function EnhancedTable(props) {
|
||||||
const [deviceState, dispatch] = useContext(DeviceContext)
|
const [deviceState, dispatch] = useContext(DeviceContext);
|
||||||
const [, notifDispatch] = useContext(SnackbarContext)
|
const [, notifDispatch] = useContext(SnackbarContext);
|
||||||
const [state, setState] = useState({selectedSegment: null})
|
const [state, setState] = useState({ selectedSegment: null });
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
deviceController.getDrives(props.dongleId).then((res) => {
|
deviceController.getDrives(props.dongleId).then((res) => {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
dispatch({ type: "update_dongle_drive", dongle_id: props.dongleId, drives: res.data })
|
dispatch({ type: 'update_dongle_drive', dongle_id: props.dongleId, drives: res.data });
|
||||||
}, 1)
|
}, 1);
|
||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
notifDispatch({type: "NEW_TOAST", msg: 'Failed to load drives'})
|
notifDispatch({ type: 'NEW_TOAST', msg: 'Failed to load drives' });
|
||||||
})
|
});
|
||||||
}, [dispatch, notifDispatch, props.dongleId])
|
}, [dispatch, notifDispatch, props.dongleId]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box sx={{ width: '100%' }}>
|
<Box sx={{ width: '100%' }}>
|
||||||
|
@ -41,7 +41,7 @@ export default function EnhancedTable(props) {
|
||||||
<Table
|
<Table
|
||||||
sx={{ minWidth: 750 }}
|
sx={{ minWidth: 750 }}
|
||||||
aria-labelledby="tableTitle"
|
aria-labelledby="tableTitle"
|
||||||
size={'small'}
|
size="small"
|
||||||
>
|
>
|
||||||
<TableHead>
|
<TableHead>
|
||||||
<TableRow>
|
<TableRow>
|
||||||
|
@ -65,25 +65,27 @@ export default function EnhancedTable(props) {
|
||||||
let metadata;
|
let metadata;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
metadata = JSON.parse(row.metadata)
|
metadata = JSON.parse(row.metadata);
|
||||||
} catch (err) { metadata = {} }
|
} catch (err) { metadata = {}; }
|
||||||
return (
|
return (
|
||||||
<TableRow
|
<TableRow
|
||||||
hover
|
hover
|
||||||
onClick={()=>{state.selectedSegment === index ? setState({...state, selectedSegment: null }) : setState({...state, selectedSegment: index })}}
|
onClick={() => { state.selectedSegment === index ? setState({ ...state, selectedSegment: null }) : setState({ ...state, selectedSegment: index }); }}
|
||||||
>
|
>
|
||||||
<TableCell
|
<TableCell
|
||||||
scope="row"
|
scope="row"
|
||||||
>{row.identifier}</TableCell>
|
>
|
||||||
|
{row.identifier}
|
||||||
|
</TableCell>
|
||||||
|
|
||||||
<TableCell >{metadata.hasOwnProperty('CarParams1') ? metadata.CarParams['CarName'] : "Glorious Skoda"}</TableCell>
|
<TableCell>{metadata.hasOwnProperty('CarParams1') ? metadata.CarParams.CarName : 'Glorious Skoda'}</TableCell>
|
||||||
<TableCell >{metadata.hasOwnProperty('InitData1') ? metadata.InitData['Version'] : "Lemon boy"}</TableCell>
|
<TableCell>{metadata.hasOwnProperty('InitData1') ? metadata.InitData.Version : 'Lemon boy'}</TableCell>
|
||||||
<TableCell >{Math.round(row.filesize / 1024) + ' MiB'}</TableCell>
|
<TableCell>{`${Math.round(row.filesize / 1024)} MiB`}</TableCell>
|
||||||
<TableCell >{helpers.formatDuration(row.duration)}</TableCell>
|
<TableCell>{helpers.formatDuration(row.duration)}</TableCell>
|
||||||
<TableCell >{Math.round(row.distance_meters / 1000)}</TableCell>
|
<TableCell>{Math.round(row.distance_meters / 1000)}</TableCell>
|
||||||
<TableCell >{row.upload_complete.toString()}</TableCell>
|
<TableCell>{row.upload_complete.toString()}</TableCell>
|
||||||
<TableCell >{row.is_processed.toString()}</TableCell>
|
<TableCell>{row.is_processed.toString()}</TableCell>
|
||||||
<TableCell >{helpers.formatDate(row.drive_date)}</TableCell>
|
<TableCell>{helpers.formatDate(row.drive_date)}</TableCell>
|
||||||
|
|
||||||
<TableCell>
|
<TableCell>
|
||||||
<Tooltip title="Open in new window">
|
<Tooltip title="Open in new window">
|
||||||
|
@ -106,13 +108,11 @@ export default function EnhancedTable(props) {
|
||||||
|
|
||||||
</TableCell>
|
</TableCell>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
)
|
);
|
||||||
|
})
|
||||||
|
|
||||||
}) :
|
: [1, 1, 1, 1, 1].map((v) => (
|
||||||
|
<TableRow>
|
||||||
[1, 1, 1, 1, 1].map((v) => (
|
|
||||||
<TableRow
|
|
||||||
>
|
|
||||||
<TableCell padding="checkbox">
|
<TableCell padding="checkbox">
|
||||||
<Skeleton animation="wave" />
|
<Skeleton animation="wave" />
|
||||||
</TableCell>
|
</TableCell>
|
||||||
|
@ -122,19 +122,16 @@ export default function EnhancedTable(props) {
|
||||||
<Skeleton animation="wave" />
|
<Skeleton animation="wave" />
|
||||||
</TableCell>
|
</TableCell>
|
||||||
|
|
||||||
<TableCell ><Skeleton animation="wave" /></TableCell>
|
<TableCell><Skeleton animation="wave" /></TableCell>
|
||||||
<TableCell ><Skeleton animation="wave" /></TableCell>
|
<TableCell><Skeleton animation="wave" /></TableCell>
|
||||||
<TableCell ><Skeleton animation="wave" /></TableCell>
|
<TableCell><Skeleton animation="wave" /></TableCell>
|
||||||
<TableCell ><Skeleton animation="wave" /></TableCell>
|
<TableCell><Skeleton animation="wave" /></TableCell>
|
||||||
<TableCell ><Skeleton animation="wave" /></TableCell>
|
<TableCell><Skeleton animation="wave" /></TableCell>
|
||||||
<TableCell ><Skeleton animation="wave" /></TableCell>
|
<TableCell><Skeleton animation="wave" /></TableCell>
|
||||||
<TableCell ><Skeleton animation="wave" /></TableCell>
|
<TableCell><Skeleton animation="wave" /></TableCell>
|
||||||
<TableCell ><Skeleton animation="wave" /></TableCell>
|
<TableCell><Skeleton animation="wave" /></TableCell>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
))
|
))}
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
</TableBody>
|
</TableBody>
|
||||||
</Table>
|
</Table>
|
||||||
|
@ -145,4 +142,3 @@ export default function EnhancedTable(props) {
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,17 +2,16 @@ import Box from '@mui/material/Box';
|
||||||
import Tab from '@mui/material/Tab';
|
import Tab from '@mui/material/Tab';
|
||||||
import Tabs from '@mui/material/Tabs';
|
import Tabs from '@mui/material/Tabs';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import BootLogsTable from "./boot";
|
import BootLogsTable from './boot';
|
||||||
import Console from './console';
|
import Console from './console';
|
||||||
import CrashLogsTable from "./crash";
|
import CrashLogsTable from './crash';
|
||||||
import DeviceInfo from './device';
|
import DeviceInfo from './device';
|
||||||
import DrivesLogTable from "./drives";
|
import DrivesLogTable from './drives';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function TabPanel(props) {
|
function TabPanel(props) {
|
||||||
const { children, value, index, ...other } = props;
|
const {
|
||||||
|
children, value, index, ...other
|
||||||
|
} = props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
|
@ -31,10 +30,7 @@ function TabPanel(props) {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
export default function SignIn(props) {
|
export default function SignIn(props) {
|
||||||
|
|
||||||
const [value, setValue] = React.useState(0);
|
const [value, setValue] = React.useState(0);
|
||||||
|
|
||||||
const handleChange = (event, newValue) => {
|
const handleChange = (event, newValue) => {
|
||||||
|
@ -45,8 +41,13 @@ export default function SignIn(props) {
|
||||||
<div className="wrapper">
|
<div className="wrapper">
|
||||||
|
|
||||||
<Box sx={{ borderBottom: 1, borderColor: 'divider' }}>
|
<Box sx={{ borderBottom: 1, borderColor: 'divider' }}>
|
||||||
<Tabs value={value} onChange={handleChange} aria-label="basic tabs example" variant="scrollable"
|
<Tabs
|
||||||
scrollButtons="auto">
|
value={value}
|
||||||
|
onChange={handleChange}
|
||||||
|
aria-label="basic tabs example"
|
||||||
|
variant="scrollable"
|
||||||
|
scrollButtons="auto"
|
||||||
|
>
|
||||||
<Tab label="Device" />
|
<Tab label="Device" />
|
||||||
<Tab label="Drives" />
|
<Tab label="Drives" />
|
||||||
<Tab label="Crashes" />
|
<Tab label="Crashes" />
|
||||||
|
@ -72,10 +73,7 @@ export default function SignIn(props) {
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -10,168 +10,169 @@ import TableHead from '@mui/material/TableHead';
|
||||||
import TableRow from '@mui/material/TableRow';
|
import TableRow from '@mui/material/TableRow';
|
||||||
import Tooltip from '@mui/material/Tooltip';
|
import Tooltip from '@mui/material/Tooltip';
|
||||||
import React, { useContext, useState } from 'react';
|
import React, { useContext, useState } from 'react';
|
||||||
import { context as DeviceContext } from "./../../../context/devices";
|
import Typography from '@mui/material/Typography';
|
||||||
import * as deviceController from "./../../../controllers/devices";
|
import { context as DeviceContext } from '../../../context/devices';
|
||||||
import Typography from "@mui/material/Typography"
|
import * as deviceController from '../../../controllers/devices';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
export default function EnhancedTable(props) {
|
export default function EnhancedTable(props) {
|
||||||
const [deviceState] = useContext(DeviceContext)
|
const [deviceState] = useContext(DeviceContext);
|
||||||
|
|
||||||
const [state, setState] = useState({ loading: true, firstReqSent: false, segment: null, drive: null })
|
const [state, setState] = useState({
|
||||||
|
loading: true, firstReqSent: false, segment: null, drive: null,
|
||||||
|
});
|
||||||
|
|
||||||
if (state.drive === null) {
|
if (state.drive === null) {
|
||||||
setState({ ...state, drive: props.drive })
|
setState({ ...state, drive: props.drive });
|
||||||
}
|
}
|
||||||
|
|
||||||
if (props.drive !== state.drive) {
|
if (props.drive !== state.drive) {
|
||||||
setState({ ...state, loading: true, firstReqSent: false, segment: null, drive: props.drive })
|
setState({
|
||||||
|
...state, loading: true, firstReqSent: false, segment: null, drive: props.drive,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const dongle_id = props.dongleId;
|
const dongle_id = props.dongleId;
|
||||||
const drive_id = props.drive;
|
const drive_id = props.drive;
|
||||||
const dongle = deviceState.dongles[dongle_id];
|
const dongle = deviceState.dongles[dongle_id];
|
||||||
console.log("view drive", dongle)
|
console.log('view drive', dongle);
|
||||||
console.log("drives", dongle.drives)
|
console.log('drives', dongle.drives);
|
||||||
if (!dongle || !dongle.drives) return (<p>loading</p>)
|
if (!dongle || !dongle.drives) return (<p>loading</p>);
|
||||||
|
|
||||||
if (state.segment === null) {
|
if (state.segment === null) {
|
||||||
// TODO Make this not run multiple times
|
// TODO Make this not run multiple times
|
||||||
deviceController.getDriveSegments(dongle_id, dongle.drives[drive_id].identifier).then((res) => {
|
deviceController.getDriveSegments(dongle_id, dongle.drives[drive_id].identifier).then((res) => {
|
||||||
console.log("my res", res.data)
|
console.log('my res', res.data);
|
||||||
if (res.data === null) {
|
if (res.data === null) {
|
||||||
setState({ ...state, loading: false, firstReqSent: true, segment: [] })
|
setState({
|
||||||
|
...state, loading: false, firstReqSent: true, segment: [],
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
setState({ ...state, loading: false, firstReqSent: true, segment: res.data })
|
setState({
|
||||||
|
...state, loading: false, firstReqSent: true, segment: res.data,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
});
|
||||||
})
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// test
|
// test
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const drive = dongle.drives[drive_id];
|
const drive = dongle.drives[drive_id];
|
||||||
|
|
||||||
|
let vehicle = '';
|
||||||
|
let version = '';
|
||||||
|
let gitRemote = '';
|
||||||
|
let gitBranch = '';
|
||||||
let vehicle = "";
|
let gitCommit = '';
|
||||||
let version = "";
|
|
||||||
let gitRemote = "";
|
|
||||||
let gitBranch = "";
|
|
||||||
let gitCommit = "";
|
|
||||||
let metadata = {};
|
let metadata = {};
|
||||||
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
metadata = JSON.parse(drive.metadata);
|
metadata = JSON.parse(drive.metadata);
|
||||||
|
|
||||||
if (metadata['InitData']) {
|
if (metadata.InitData) {
|
||||||
version = metadata['InitData']['Version'] || "Unknown";
|
version = metadata.InitData.Version || 'Unknown';
|
||||||
gitRemote = metadata['InitData']['GitRemote'] || "Unknown";
|
gitRemote = metadata.InitData.GitRemote || 'Unknown';
|
||||||
gitBranch = metadata['InitData']['GitBranch'] || "Unknown";
|
gitBranch = metadata.InitData.GitBranch || 'Unknown';
|
||||||
gitCommit = metadata['InitData']['GitCommit'] || "Unknown";
|
gitCommit = metadata.InitData.GitCommit || 'Unknown';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (metadata.CarParams) {
|
||||||
if (metadata['CarParams']) {
|
if (metadata.CarParams.CarName !== undefined) vehicle += `${metadata.CarParams.CarName.toUpperCase()} `;
|
||||||
if (metadata['CarParams']['CarName'] !== undefined) vehicle += (metadata['CarParams']['CarName'].toUpperCase()) + " ";
|
if (metadata.CarParams.CarFingerprint !== undefined) vehicle += (metadata.CarParams.CarFingerprint.toUpperCase());
|
||||||
if (metadata['CarParams']['CarFingerprint'] !== undefined) vehicle += (metadata['CarParams']['CarFingerprint'].toUpperCase())
|
|
||||||
|
|
||||||
}
|
}
|
||||||
} catch (exception) { console.log(exception) }
|
} catch (exception) { console.log(exception); }
|
||||||
|
|
||||||
//const directoryTree = dirTree(config.storagePath + device.dongle_id + "/" + dongleIdHash + "/" + driveIdentifierHash + "/" + drive.identifier);
|
// const directoryTree = dirTree(config.storagePath + device.dongle_id + "/" + dongleIdHash + "/" + driveIdentifierHash + "/" + drive.identifier);
|
||||||
const directoryTree = state.segment;
|
const directoryTree = state.segment;
|
||||||
const driveUrl = "driveurl"
|
const driveUrl = 'driveurl';
|
||||||
var directorySegments = {};
|
const directorySegments = {};
|
||||||
|
|
||||||
if (directoryTree) {
|
if (directoryTree) {
|
||||||
for (var i in directoryTree.children) {
|
for (const i in directoryTree.children) {
|
||||||
// skip any non-directory entries (for example m3u8 file in the drive directory)
|
// skip any non-directory entries (for example m3u8 file in the drive directory)
|
||||||
if (directoryTree.children[i].type !== 'directory') continue;
|
if (directoryTree.children[i].type !== 'directory') continue;
|
||||||
|
|
||||||
var segment = directoryTree.children[i].name;
|
const segment = directoryTree.children[i].name;
|
||||||
|
|
||||||
let logSegment = {}
|
const logSegment = {};
|
||||||
for (var c in directoryTree.children[i].children) {
|
for (const c in directoryTree.children[i].children) {
|
||||||
logSegment[directoryTree.children[i].children[c].name] = {
|
logSegment[directoryTree.children[i].children[c].name] = {
|
||||||
url: `${driveUrl}/${segment}/${directoryTree.children[i].children[c].name}`,
|
url: `${driveUrl}/${segment}/${directoryTree.children[i].children[c].name}`,
|
||||||
name: directoryTree.children[i].children[c].name,
|
name: directoryTree.children[i].children[c].name,
|
||||||
fileSize: directoryTree.children[i].children[c].size
|
fileSize: directoryTree.children[i].children[c].size,
|
||||||
|
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
directorySegments[segment] = logSegment;
|
directorySegments[segment] = logSegment;
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log("output is", directorySegments)
|
console.log('output is', directorySegments);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box sx={{ width: '100%' }}>
|
<Box sx={{ width: '100%' }}>
|
||||||
<Paper sx={{ width: '100%', mb: 2, padding: '20px' }}>
|
<Paper sx={{ width: '100%', mb: 2, padding: '20px' }}>
|
||||||
|
|
||||||
<Typography variant="body1"><b>Vehicle:</b> {vehicle}</Typography>
|
<Typography variant="body1">
|
||||||
<Typography variant="body1"><b>Version:</b> {version}</Typography>
|
<b>Vehicle:</b>
|
||||||
<Typography variant="body1"><b>gitRemote:</b> {gitRemote}</Typography>
|
{' '}
|
||||||
<Typography variant="body1"><b>gitBranch:</b> {gitBranch}</Typography>
|
{vehicle}
|
||||||
<Typography variant="body1"><b>gitCommit:</b> {gitCommit}</Typography>
|
</Typography>
|
||||||
|
<Typography variant="body1">
|
||||||
|
<b>Version:</b>
|
||||||
|
{' '}
|
||||||
|
{version}
|
||||||
|
</Typography>
|
||||||
|
<Typography variant="body1">
|
||||||
|
<b>gitRemote:</b>
|
||||||
|
{' '}
|
||||||
|
{gitRemote}
|
||||||
|
</Typography>
|
||||||
|
<Typography variant="body1">
|
||||||
|
<b>gitBranch:</b>
|
||||||
|
{' '}
|
||||||
|
{gitBranch}
|
||||||
|
</Typography>
|
||||||
|
<Typography variant="body1">
|
||||||
|
<b>gitCommit:</b>
|
||||||
|
{' '}
|
||||||
|
{gitCommit}
|
||||||
|
</Typography>
|
||||||
|
|
||||||
<Typography variant="body2"><b>Fingerprint: </b></Typography>
|
<Typography variant="body2"><b>Fingerprint: </b></Typography>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<TableContainer>
|
<TableContainer>
|
||||||
<Table
|
<Table
|
||||||
sx={{ minWidth: 750 }}
|
sx={{ minWidth: 750 }}
|
||||||
aria-labelledby="tableTitle"
|
aria-labelledby="tableTitle"
|
||||||
size={'small'}
|
size="small"
|
||||||
>
|
>
|
||||||
<TableHead>
|
<TableHead>
|
||||||
<TableRow>
|
<TableRow>
|
||||||
<TableCell >Segment ID</TableCell>
|
<TableCell>Segment ID</TableCell>
|
||||||
<TableCell >File</TableCell>
|
<TableCell>File</TableCell>
|
||||||
<TableCell >File size</TableCell>
|
<TableCell>File size</TableCell>
|
||||||
<TableCell >Actions</TableCell>
|
<TableCell>Actions</TableCell>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
</TableHead>
|
</TableHead>
|
||||||
<TableBody>
|
<TableBody>
|
||||||
{
|
{
|
||||||
directorySegments ? Object.keys(directorySegments).map((key, index) => {
|
directorySegments ? Object.keys(directorySegments).map((key, index) => Object.keys(directorySegments[key]).map((key1, index1) => (
|
||||||
|
|
||||||
|
|
||||||
return Object.keys(directorySegments[key]).map((key1, index1) => (
|
|
||||||
<TableRow hover>
|
<TableRow hover>
|
||||||
<TableCell >{key}</TableCell>
|
<TableCell>{key}</TableCell>
|
||||||
<TableCell >{directorySegments[key][key1].name}</TableCell>
|
<TableCell>{directorySegments[key][key1].name}</TableCell>
|
||||||
<TableCell>{Math.round(directorySegments[key][key1].fileSize / 1024) + ' MiB'}</TableCell>
|
<TableCell>{`${Math.round(directorySegments[key][key1].fileSize / 1024)} MiB`}</TableCell>
|
||||||
|
|
||||||
<TableCell>
|
<TableCell>
|
||||||
<Tooltip title="Open in new window">
|
<Tooltip title="Open in new window">
|
||||||
<IconButton size="small" onClick={() => window.open(directorySegments[key][key1].url, "_blank")}>
|
<IconButton size="small" onClick={() => window.open(directorySegments[key][key1].url, '_blank')}>
|
||||||
<OpenInNewIcon fontSize="inherit" />
|
<OpenInNewIcon fontSize="inherit" />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
</TableCell>
|
</TableCell>
|
||||||
|
|
||||||
|
|
||||||
</TableRow>
|
</TableRow>
|
||||||
))
|
))) : null
|
||||||
|
|
||||||
|
|
||||||
}) : null
|
|
||||||
}
|
}
|
||||||
|
|
||||||
</TableBody>
|
</TableBody>
|
||||||
|
@ -179,7 +180,7 @@ export default function EnhancedTable(props) {
|
||||||
</TableContainer>
|
</TableContainer>
|
||||||
|
|
||||||
</Paper>
|
</Paper>
|
||||||
</Box >
|
</Box>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -195,8 +196,6 @@ var dongleIdHash = crypto.createHmac('sha256', config.applicationSalt).update(de
|
||||||
cabanaUrl = config.cabanaUrl + '?retropilotIdentifier=' + device.dongle_id + '|' + dongleIdHash + '|' + drive.identifier + '|' + driveIdentifierHash + '&retropilotHost=' + encodeURIComponent(config.baseUrl) + '&demo=1"';
|
cabanaUrl = config.cabanaUrl + '?retropilotIdentifier=' + device.dongle_id + '|' + dongleIdHash + '|' + drive.identifier + '|' + driveIdentifierHash + '&retropilotHost=' + encodeURIComponent(config.baseUrl) + '&demo=1"';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
var response = `<html style="font-family: monospace">
|
var response = `<html style="font-family: monospace">
|
||||||
<head>
|
<head>
|
||||||
<link href="https://vjs.zencdn.net/7.11.4/video-js.css" rel="stylesheet" />
|
<link href="https://vjs.zencdn.net/7.11.4/video-js.css" rel="stylesheet" />
|
||||||
|
@ -290,7 +289,6 @@ var dongleIdHash = crypto.createHmac('sha256', config.applicationSalt).update(de
|
||||||
<tr><th>segment</th><th>qcamera</th><th>qlog</th><th>fcamera</th><th>rlog</th><th>dcamera</th><th>processed</th><th>stalled</th></tr>
|
<tr><th>segment</th><th>qcamera</th><th>qlog</th><th>fcamera</th><th>rlog</th><th>dcamera</th><th>processed</th><th>stalled</th></tr>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
|
||||||
var directorySegments = {};
|
var directorySegments = {};
|
||||||
for (var i in directoryTree.children) {
|
for (var i in directoryTree.children) {
|
||||||
// skip any non-directory entries (for example m3u8 file in the drive directory)
|
// skip any non-directory entries (for example m3u8 file in the drive directory)
|
||||||
|
@ -298,7 +296,6 @@ var dongleIdHash = crypto.createHmac('sha256', config.applicationSalt).update(de
|
||||||
|
|
||||||
var segment = directoryTree.children[i].name;
|
var segment = directoryTree.children[i].name;
|
||||||
|
|
||||||
|
|
||||||
var qcamera = '--';
|
var qcamera = '--';
|
||||||
var fcamera = '--';
|
var fcamera = '--';
|
||||||
var dcamera = '--';
|
var dcamera = '--';
|
||||||
|
|
|
@ -1,16 +1,16 @@
|
||||||
import { createTheme, ThemeProvider } from '@mui/material/styles';
|
import { createTheme, ThemeProvider } from '@mui/material/styles';
|
||||||
import React, { useContext, useState } from 'react';
|
import React, { useContext, useState } from 'react';
|
||||||
import { Link } from "react-router-dom";
|
import { Link } from 'react-router-dom';
|
||||||
import { UserContext } from "./../../context/users";
|
import { UserContext } from '../../context/users';
|
||||||
|
|
||||||
const theme = createTheme();
|
const theme = createTheme();
|
||||||
|
|
||||||
export default function SignIn() {
|
export default function SignIn() {
|
||||||
const [loading, setLoading] = useState(false)
|
const [loading, setLoading] = useState(false);
|
||||||
const [ state, dispatch ] = useContext(UserContext)
|
const [state, dispatch] = useContext(UserContext);
|
||||||
console.log("component", state)
|
console.log('component', state);
|
||||||
const handleSubmit = (event) => {
|
const handleSubmit = (event) => {
|
||||||
dispatch({ type: "toggle_button" })
|
dispatch({ type: 'toggle_button' });
|
||||||
|
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
const data = new FormData(event.currentTarget);
|
const data = new FormData(event.currentTarget);
|
||||||
|
@ -20,19 +20,15 @@ export default function SignIn() {
|
||||||
password: data.get('password'),
|
password: data.get('password'),
|
||||||
});
|
});
|
||||||
|
|
||||||
setLoading(true)
|
setLoading(true);
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ThemeProvider theme={theme}>
|
<ThemeProvider theme={theme}>
|
||||||
<p>hello</p>
|
<p>hello</p>
|
||||||
<Link to="/login" variant="body2">
|
<Link to="/login" variant="body2">
|
||||||
{"login?"}
|
login?
|
||||||
</Link>
|
</Link>
|
||||||
</ThemeProvider>
|
</ThemeProvider>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -7,14 +7,14 @@ import Paper from '@mui/material/Paper';
|
||||||
import TextField from '@mui/material/TextField';
|
import TextField from '@mui/material/TextField';
|
||||||
import Typography from '@mui/material/Typography';
|
import Typography from '@mui/material/Typography';
|
||||||
import React, { useContext, useState } from 'react';
|
import React, { useContext, useState } from 'react';
|
||||||
import { UserContext } from "./../../context/users";
|
import { UserContext } from '../../context/users';
|
||||||
|
|
||||||
export default function SignIn() {
|
export default function SignIn() {
|
||||||
const [loading, setLoading] = useState(false)
|
const [loading, setLoading] = useState(false);
|
||||||
const [state, dispatch] = useContext(UserContext)
|
const [state, dispatch] = useContext(UserContext);
|
||||||
console.log("component", state)
|
console.log('component', state);
|
||||||
const handleSubmit = (event) => {
|
const handleSubmit = (event) => {
|
||||||
dispatch({ type: "toggle_button" })
|
dispatch({ type: 'toggle_button' });
|
||||||
|
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
const data = new FormData(event.currentTarget);
|
const data = new FormData(event.currentTarget);
|
||||||
|
@ -24,7 +24,7 @@ export default function SignIn() {
|
||||||
password: data.get('password'),
|
password: data.get('password'),
|
||||||
});
|
});
|
||||||
|
|
||||||
setLoading(true)
|
setLoading(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -41,13 +41,10 @@ export default function SignIn() {
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
}}
|
}}
|
||||||
style={{
|
style={{
|
||||||
padding: '15px'
|
padding: '15px',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<Typography component="h1" variant="h5" align="left">
|
<Typography component="h1" variant="h5" align="left">
|
||||||
Sign in
|
Sign in
|
||||||
</Typography>
|
</Typography>
|
||||||
|
@ -85,20 +82,15 @@ export default function SignIn() {
|
||||||
</LoadingButton>
|
</LoadingButton>
|
||||||
|
|
||||||
<Link href="#" variant="body2">
|
<Link href="#" variant="body2">
|
||||||
{"New Here or Forgotten password?"}
|
New Here or Forgotten password?
|
||||||
</Link>
|
</Link>
|
||||||
</Box>
|
</Box>
|
||||||
</Paper>
|
</Paper>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
|
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
</Container>
|
</Container>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -2,52 +2,41 @@ import Grid from '@mui/material/Grid';
|
||||||
import Paper from '@mui/material/Paper';
|
import Paper from '@mui/material/Paper';
|
||||||
import { Scrollbars } from 'rc-scrollbars';
|
import { Scrollbars } from 'rc-scrollbars';
|
||||||
import React, { useContext } from 'react';
|
import React, { useContext } from 'react';
|
||||||
import { context as DeviceContext } from "./../../context/devices";
|
import { context as DeviceContext } from '../../context/devices';
|
||||||
import DeviceData from './../device/deviceData';
|
import DeviceData from '../device/deviceData';
|
||||||
import DeviceOverview from "./../device/overview";
|
import DeviceOverview from '../device/overview';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
export default function SignIn() {
|
export default function SignIn() {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const [deviceState] = useContext(DeviceContext);
|
const [deviceState] = useContext(DeviceContext);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="wrapper">
|
<div className="wrapper">
|
||||||
|
|
||||||
<Grid container spacing={0} style={{ height: '100%', justify: 'space-around', minHeight: "100%", maxHeight: "100%" }} >
|
<Grid
|
||||||
<Grid item xs={12} md={4} lg={3} sm={6} xl={2} style={{ minHeight: "100%", maxHeight: "100%" }}>
|
container
|
||||||
<Paper style={{ minHeight: "100%", maxHeight: "100%", margin: "0" }}>
|
spacing={0}
|
||||||
<Scrollbars autoHeight={true} autoHeightMin="calc(100vh - 14px)" autoHeightMax="calc(100% - 14px)">
|
style={{
|
||||||
|
height: '100%', justify: 'space-around', minHeight: '100%', maxHeight: '100%',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Grid item xs={12} md={4} lg={3} sm={6} xl={2} style={{ minHeight: '100%', maxHeight: '100%' }}>
|
||||||
|
<Paper style={{ minHeight: '100%', maxHeight: '100%', margin: '0' }}>
|
||||||
|
<Scrollbars autoHeight autoHeightMin="calc(100vh - 14px)" autoHeightMax="calc(100% - 14px)">
|
||||||
<div style={{ padding: '5px' }}>
|
<div style={{ padding: '5px' }}>
|
||||||
{deviceState ? Object.keys(deviceState.dongles).map(key => <DeviceOverview device={deviceState.dongles[key]} />) : <p>no</p>}
|
{deviceState ? Object.keys(deviceState.dongles).map((key) => <DeviceOverview device={deviceState.dongles[key]} />) : <p>no</p>}
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</Scrollbars>
|
</Scrollbars>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</Paper>
|
</Paper>
|
||||||
|
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid item xs={12} md={8} lg={9} sm={6} xl={10}>
|
<Grid item xs={12} md={8} lg={9} sm={6} xl={10}>
|
||||||
{deviceState.dongles['53331425'] ? <DeviceData device={deviceState.dongles['53331425']} /> : <p>no</p>}
|
{deviceState.dongles['53331425'] ? <DeviceData device={deviceState.dongles['53331425']} /> : <p>no</p>}
|
||||||
|
|
||||||
|
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,19 +1,12 @@
|
||||||
import Snackbar from '@mui/material/Snackbar';
|
import Snackbar from '@mui/material/Snackbar';
|
||||||
import React, { useContext } from 'react';
|
import React, { useContext } from 'react';
|
||||||
import { context as DeviceContext } from "./../../context/toast";
|
import { context as DeviceContext } from '../../context/toast';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
export default function Toast(props) {
|
export default function Toast(props) {
|
||||||
const [state, dispatch] = useContext(DeviceContext)
|
const [state, dispatch] = useContext(DeviceContext);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const handleClose = () => {
|
const handleClose = () => {
|
||||||
dispatch({ type: 'CLOSE_TOAST' })
|
dispatch({ type: 'CLOSE_TOAST' });
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -1,12 +1,11 @@
|
||||||
import React, { createContext, useEffect, useReducer } from "react";
|
import React, { createContext, useEffect, useReducer } from 'react';
|
||||||
import * as deviceController from "./../../controllers/devices";
|
import * as deviceController from '../../controllers/devices';
|
||||||
|
|
||||||
function process(state, action) {
|
function process(state, action) {
|
||||||
if (action.type !== "ADD_DATA") { return state }
|
if (action.type !== 'ADD_DATA') { return state; }
|
||||||
|
|
||||||
switch (action.data.command) {
|
switch (action.data.command) {
|
||||||
|
case 'dongle_status':
|
||||||
case "dongle_status":
|
|
||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
dongles: {
|
dongles: {
|
||||||
|
@ -15,102 +14,98 @@ function process(state, action) {
|
||||||
...state.dongles[action.data.data.dongle_id],
|
...state.dongles[action.data.data.dongle_id],
|
||||||
online: action.data.data.online,
|
online: action.data.data.online,
|
||||||
last_seen: action.data.data.time,
|
last_seen: action.data.data.time,
|
||||||
dongle_id: action.data.data.dongle_id
|
dongle_id: action.data.data.dongle_id,
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
}
|
};
|
||||||
default:
|
default:
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export const Reducer = (state, action) => {
|
export const Reducer = (state, action) => {
|
||||||
console.log("input", state, action)
|
console.log('input', state, action);
|
||||||
switch (action.type) {
|
switch (action.type) {
|
||||||
case 'ADD_DATA':
|
case 'ADD_DATA':
|
||||||
return process(state, action);
|
return process(state, action);
|
||||||
case "fetch_all_dongles":
|
case 'fetch_all_dongles':
|
||||||
console.log("fetch", action)
|
console.log('fetch', action);
|
||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
dongles: action.data
|
dongles: action.data,
|
||||||
}
|
};
|
||||||
|
|
||||||
case "update_dongle_drive":
|
case 'update_dongle_drive':
|
||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
dongles: {
|
dongles: {
|
||||||
...state.dongles,
|
...state.dongles,
|
||||||
[action.dongle_id]: {
|
[action.dongle_id]: {
|
||||||
...state.dongles[action.dongle_id],
|
...state.dongles[action.dongle_id],
|
||||||
drives: action.drives
|
drives: action.drives,
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
}
|
};
|
||||||
|
|
||||||
case "update_dongle_bootlogs":
|
case 'update_dongle_bootlogs':
|
||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
dongles: {
|
dongles: {
|
||||||
...state.dongles,
|
...state.dongles,
|
||||||
[action.dongle_id]: {
|
[action.dongle_id]: {
|
||||||
...state.dongles[action.dongle_id],
|
...state.dongles[action.dongle_id],
|
||||||
boot: action.bootlogs
|
boot: action.bootlogs,
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
}
|
};
|
||||||
|
|
||||||
case "update_dongle_crashlogs":
|
case 'update_dongle_crashlogs':
|
||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
dongles: {
|
dongles: {
|
||||||
...state.dongles,
|
...state.dongles,
|
||||||
[action.dongle_id]: {
|
[action.dongle_id]: {
|
||||||
...state.dongles[action.dongle_id],
|
...state.dongles[action.dongle_id],
|
||||||
crash: action.crashlogs
|
crash: action.crashlogs,
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
}
|
};
|
||||||
|
|
||||||
case "user_authentication":
|
case 'user_authentication':
|
||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
user: action.user
|
user: action.user,
|
||||||
}
|
};
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const initialState = {
|
const initialState = {
|
||||||
dongles: {}
|
dongles: {},
|
||||||
};
|
};
|
||||||
|
|
||||||
const Store = ({ children }) => {
|
function Store({ children }) {
|
||||||
console.log("STORE HAS BEEN RERENDERED")
|
console.log('STORE HAS BEEN RERENDERED');
|
||||||
const [state, dispatch] = useReducer(Reducer, initialState);
|
const [state, dispatch] = useReducer(Reducer, initialState);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const ws = new WebSocket('ws://localhost:81');
|
const ws = new WebSocket('ws://localhost:81');
|
||||||
|
|
||||||
ws.onmessage = ({ data }) => {
|
ws.onmessage = ({ data }) => {
|
||||||
data = JSON.parse(data)
|
data = JSON.parse(data);
|
||||||
console.log("Message")
|
console.log('Message');
|
||||||
if (data.id) {
|
if (data.id) {
|
||||||
dispatch({ type: "ADD_DATA", id: data.id, data: data })
|
dispatch({ type: 'ADD_DATA', id: data.id, data });
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
deviceController.getAllDevices().then((devices) => {
|
deviceController.getAllDevices().then((devices) => {
|
||||||
console.log("store", devices)
|
console.log('store', devices);
|
||||||
|
|
||||||
dispatch({ type: "fetch_all_dongles", data: devices })
|
dispatch({ type: 'fetch_all_dongles', data: devices });
|
||||||
})
|
});
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
try {
|
try {
|
||||||
|
@ -119,13 +114,12 @@ const Store = ({ children }) => {
|
||||||
};
|
};
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<context.Provider value={[state, dispatch]}>
|
<context.Provider value={[state, dispatch]}>
|
||||||
{children}
|
{children}
|
||||||
</context.Provider>
|
</context.Provider>
|
||||||
)
|
);
|
||||||
};
|
}
|
||||||
|
|
||||||
export const context = createContext(initialState);
|
export const context = createContext(initialState);
|
||||||
export default Store;
|
export default Store;
|
|
@ -1,20 +1,19 @@
|
||||||
import React, {createContext, useReducer} from "react";
|
import React, { createContext, useReducer } from 'react';
|
||||||
import Reducer from './reducer'
|
import Reducer from './reducer';
|
||||||
|
|
||||||
|
|
||||||
const initialState = {
|
const initialState = {
|
||||||
open: false,
|
open: false,
|
||||||
message: null
|
message: null,
|
||||||
};
|
};
|
||||||
|
|
||||||
const Store = ({children}) => {
|
function Store({ children }) {
|
||||||
const [state, dispatch] = useReducer(Reducer, initialState);
|
const [state, dispatch] = useReducer(Reducer, initialState);
|
||||||
return (
|
return (
|
||||||
<context.Provider value={[state, dispatch]}>
|
<context.Provider value={[state, dispatch]}>
|
||||||
{children}
|
{children}
|
||||||
</context.Provider>
|
</context.Provider>
|
||||||
)
|
);
|
||||||
};
|
}
|
||||||
|
|
||||||
export const context = createContext(initialState);
|
export const context = createContext(initialState);
|
||||||
export default Store;
|
export default Store;
|
|
@ -4,13 +4,13 @@ const Reducer = (state, action) => {
|
||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
open: action.open,
|
open: action.open,
|
||||||
msg: action.message
|
msg: action.message,
|
||||||
};
|
};
|
||||||
case 'CLOSE_TOAST':
|
case 'CLOSE_TOAST':
|
||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
open: false
|
open: false,
|
||||||
}
|
};
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return state;
|
return state;
|
||||||
|
|
|
@ -1,17 +1,17 @@
|
||||||
import React from "react"
|
import React from 'react';
|
||||||
import { reducer, initialState } from "./reducer"
|
import { reducer, initialState } from './reducer';
|
||||||
|
|
||||||
export const UserContext = React.createContext({
|
export const UserContext = React.createContext({
|
||||||
state: initialState,
|
state: initialState,
|
||||||
dispatch: () => null
|
dispatch: () => null,
|
||||||
})
|
});
|
||||||
|
|
||||||
export const UserProvider = ({ children }) => {
|
export function UserProvider({ children }) {
|
||||||
const [state, dispatch] = React.useReducer(reducer, initialState)
|
const [state, dispatch] = React.useReducer(reducer, initialState);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<UserContext.Provider value={[ state, dispatch ]}>
|
<UserContext.Provider value={[state, dispatch]}>
|
||||||
{ children }
|
{ children }
|
||||||
</UserContext.Provider>
|
</UserContext.Provider>
|
||||||
)
|
);
|
||||||
}
|
}
|
|
@ -1,16 +1,16 @@
|
||||||
export const reducer = (state, action) => {
|
export const reducer = (state, action) => {
|
||||||
switch (action.type) {
|
switch (action.type) {
|
||||||
case "sign_out":
|
case 'sign_out':
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
active: !state.active
|
active: !state.active,
|
||||||
}
|
};
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return state
|
return state;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
export const initialState = {
|
export const initialState = {
|
||||||
signedIn: false,
|
signedIn: false,
|
||||||
|
@ -19,4 +19,4 @@ export const initialState = {
|
||||||
username: null,
|
username: null,
|
||||||
JWT: null,
|
JWT: null,
|
||||||
},
|
},
|
||||||
}
|
};
|
||||||
|
|
|
@ -1,9 +1,6 @@
|
||||||
import axios from "axios";
|
import axios from 'axios';
|
||||||
|
|
||||||
|
|
||||||
export async function getSession() {
|
export async function getSession() {
|
||||||
|
const req = await axios.get('http://localhost/retropilot/0/useradmin/session', { withCredentials: true });
|
||||||
const req = await axios.get(`http://localhost/retropilot/0/useradmin/session`, {withCredentials: true});
|
return req.data;
|
||||||
return req.data
|
|
||||||
|
|
||||||
}
|
}
|
|
@ -1,49 +1,43 @@
|
||||||
import axios from "axios";
|
import axios from 'axios';
|
||||||
|
|
||||||
export async function getDrives(dongleId) {
|
export async function getDrives(dongleId) {
|
||||||
const req = await axios.get(`http://localhost/retropilot/0/device/${dongleId}/drives/false`, { withCredentials: true });
|
const req = await axios.get(`http://localhost/retropilot/0/device/${dongleId}/drives/false`, { withCredentials: true });
|
||||||
return req.data
|
return req.data;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getBootlogs(dongleId) {
|
export async function getBootlogs(dongleId) {
|
||||||
const req = await axios.get(`http://localhost/retropilot/0/device/${dongleId}/bootlogs`, { withCredentials: true });
|
const req = await axios.get(`http://localhost/retropilot/0/device/${dongleId}/bootlogs`, { withCredentials: true });
|
||||||
return req.data
|
return req.data;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getCrashlogs(dongleId) {
|
export async function getCrashlogs(dongleId) {
|
||||||
const req = await axios.get(`http://localhost/retropilot/0/device/${dongleId}/crashlogs`, { withCredentials: true });
|
const req = await axios.get(`http://localhost/retropilot/0/device/${dongleId}/crashlogs`, { withCredentials: true });
|
||||||
return req.data
|
return req.data;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getDriveSegments(dongleId, drive_identifier) {
|
export async function getDriveSegments(dongleId, drive_identifier) {
|
||||||
const req = await axios.get(`http://localhost/retropilot/0/device/${dongleId}/drives/${drive_identifier}/segment`, { withCredentials: true });
|
const req = await axios.get(`http://localhost/retropilot/0/device/${dongleId}/drives/${drive_identifier}/segment`, { withCredentials: true });
|
||||||
return req.data
|
return req.data;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getAllDevices() {
|
export async function getAllDevices() {
|
||||||
const req = await axios.get(`http://localhost/retropilot/0/devices`, { withCredentials: true });
|
const req = await axios.get('http://localhost/retropilot/0/devices', { withCredentials: true });
|
||||||
const responseData = req.data
|
const responseData = req.data;
|
||||||
|
|
||||||
let dongles = {}
|
let dongles = {};
|
||||||
|
|
||||||
if (responseData.success === true) {
|
if (responseData.success === true) {
|
||||||
|
responseData.data.map((object) => dongles = {
|
||||||
responseData.data.map((object) => {
|
|
||||||
|
|
||||||
return dongles = {
|
|
||||||
...dongles,
|
...dongles,
|
||||||
[object.dongle_id]: {
|
[object.dongle_id]: {
|
||||||
...object,
|
...object,
|
||||||
online: false,
|
online: false,
|
||||||
// Show when last connected to api instead Athena by default
|
// Show when last connected to api instead Athena by default
|
||||||
last_seen: object.last_ping,
|
last_seen: object.last_ping,
|
||||||
}
|
},
|
||||||
}
|
});
|
||||||
|
|
||||||
})
|
|
||||||
|
|
||||||
return dongles;
|
return dongles;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -1,24 +1,20 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
export function formatDate(timestampMs) {
|
export function formatDate(timestampMs) {
|
||||||
return new Date(timestampMs).toISOString().replace(/T/, ' ').replace(/\..+/, '');
|
return new Date(timestampMs).toISOString().replace(/T/, ' ').replace(/\..+/, '');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export function formatDuration(durationSeconds) {
|
export function formatDuration(durationSeconds) {
|
||||||
durationSeconds = Math.round(durationSeconds);
|
durationSeconds = Math.round(durationSeconds);
|
||||||
const secs = durationSeconds % 60;
|
const secs = durationSeconds % 60;
|
||||||
let mins = Math.floor(durationSeconds / 60);
|
let mins = Math.floor(durationSeconds / 60);
|
||||||
let hours = Math.floor(mins / 60);
|
let hours = Math.floor(mins / 60);
|
||||||
mins = mins % 60;
|
mins %= 60;
|
||||||
const days = Math.floor(hours / 24);
|
const days = Math.floor(hours / 24);
|
||||||
hours = hours % 24;
|
hours %= 24;
|
||||||
|
|
||||||
let response = '';
|
let response = '';
|
||||||
if (days > 0) response += days + 'd ';
|
if (days > 0) response += `${days}d `;
|
||||||
if (hours > 0 || days > 0) response += hours + 'h ';
|
if (hours > 0 || days > 0) response += `${hours}h `;
|
||||||
if (hours > 0 || days > 0 || mins > 0) response += mins + 'm ';
|
if (hours > 0 || days > 0 || mins > 0) response += `${mins}m `;
|
||||||
response += secs + 's';
|
response += `${secs}s`;
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
|
@ -8,7 +8,7 @@ ReactDOM.render(
|
||||||
<React.StrictMode>
|
<React.StrictMode>
|
||||||
<App />
|
<App />
|
||||||
</React.StrictMode>,
|
</React.StrictMode>,
|
||||||
document.getElementById('root')
|
document.getElementById('root'),
|
||||||
);
|
);
|
||||||
|
|
||||||
// If you want to start measuring performance in your app, pass a function
|
// If you want to start measuring performance in your app, pass a function
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
const reportWebVitals = onPerfEntry => {
|
const reportWebVitals = (onPerfEntry) => {
|
||||||
if (onPerfEntry && onPerfEntry instanceof Function) {
|
if (onPerfEntry && onPerfEntry instanceof Function) {
|
||||||
import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
|
import('web-vitals').then(({
|
||||||
|
getCLS, getFID, getFCP, getLCP, getTTFB,
|
||||||
|
}) => {
|
||||||
getCLS(onPerfEntry);
|
getCLS(onPerfEntry);
|
||||||
getFID(onPerfEntry);
|
getFID(onPerfEntry);
|
||||||
getFCP(onPerfEntry);
|
getFCP(onPerfEntry);
|
||||||
|
|
17
src/yeet.js
17
src/yeet.js
|
@ -1,4 +1,4 @@
|
||||||
import React, {useState, useContext} from 'react';
|
import React, { useState, useContext } from 'react';
|
||||||
import Avatar from '@mui/material/Avatar';
|
import Avatar from '@mui/material/Avatar';
|
||||||
import LoadingButton from '@mui/lab/LoadingButton';
|
import LoadingButton from '@mui/lab/LoadingButton';
|
||||||
import CssBaseline from '@mui/material/CssBaseline';
|
import CssBaseline from '@mui/material/CssBaseline';
|
||||||
|
@ -14,20 +14,21 @@ import LockOutlinedIcon from '@mui/icons-material/LockOutlined';
|
||||||
import Typography from '@mui/material/Typography';
|
import Typography from '@mui/material/Typography';
|
||||||
import Container from '@mui/material/Container';
|
import Container from '@mui/material/Container';
|
||||||
import { createTheme, ThemeProvider } from '@mui/material/styles';
|
import { createTheme, ThemeProvider } from '@mui/material/styles';
|
||||||
import { UserContext } from "./context/users"
|
import { UserContext } from './context/users';
|
||||||
|
|
||||||
const theme = createTheme();
|
const theme = createTheme();
|
||||||
|
|
||||||
export default function SignIn() {
|
export default function SignIn() {
|
||||||
const [ state, dispatch ] = useContext(UserContext)
|
const [state, dispatch] = useContext(UserContext);
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ThemeProvider theme={theme}>
|
<ThemeProvider theme={theme}>
|
||||||
{console.log("testing", state)}
|
{console.log('testing', state)}
|
||||||
<p> {JSON.stringify(state)}</p>
|
<p>
|
||||||
|
{' '}
|
||||||
|
{JSON.stringify(state)}
|
||||||
|
</p>
|
||||||
|
|
||||||
</ThemeProvider>
|
</ThemeProvider>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue