CEC-3119 Magna access (#235)
* CEC-3119 Magna access * Clean up * Update test provider
This commit is contained in:
@@ -3,3 +3,5 @@ REACT_APP_CERT_SERVICE_URL=https://gw.cec-prd.fiskerinc.com/certificate
|
|||||||
REACT_APP_UPLOAD_SERVICE_URL=https://gw.cec-prd.fiskerinc.com/ota_update
|
REACT_APP_UPLOAD_SERVICE_URL=https://gw.cec-prd.fiskerinc.com/ota_update
|
||||||
REACT_APP_AUTH_CALLBACK_URL=https://ota-admin.cec-prd.fiskerinc.com
|
REACT_APP_AUTH_CALLBACK_URL=https://ota-admin.cec-prd.fiskerinc.com
|
||||||
REACT_APP_SUPERSET_URL=https://superset.cec-prd.fiskerinc.com
|
REACT_APP_SUPERSET_URL=https://superset.cec-prd.fiskerinc.com
|
||||||
|
REACT_APP_MAGNA_PROVIDER=Magna
|
||||||
|
REACT_APP_MAGNA_GROUP_ID=68273225-9da4-4fa7-aea5-38e16ec471fe
|
||||||
|
|||||||
4
.env.dev
4
.env.dev
@@ -2,4 +2,6 @@ REACT_APP_CERT_SERVICE_URL=https://dev-gw.cloud.fiskerinc.com/certificate
|
|||||||
REACT_APP_AUTH_SERVICE_URL=https://dev-gw.cloud.fiskerinc.com/compute_auth
|
REACT_APP_AUTH_SERVICE_URL=https://dev-gw.cloud.fiskerinc.com/compute_auth
|
||||||
REACT_APP_UPLOAD_SERVICE_URL=https://dev-gw.cloud.fiskerinc.com/ota_update
|
REACT_APP_UPLOAD_SERVICE_URL=https://dev-gw.cloud.fiskerinc.com/ota_update
|
||||||
REACT_APP_AUTH_CALLBACK_URL=https://dev-ota-admin.cloud.fiskerinc.com
|
REACT_APP_AUTH_CALLBACK_URL=https://dev-ota-admin.cloud.fiskerinc.com
|
||||||
REACT_APP_SUPERSET_URL=https://dev-superset-new.cloud.fiskerinc.com
|
REACT_APP_SUPERSET_URL=https://dev-superset-new.cloud.fiskerinc.com
|
||||||
|
REACT_APP_MAGNA_PROVIDER=Fisker-QA
|
||||||
|
REACT_APP_MAGNA_GROUP_ID=efcc3025-e2d8-4212-8227-805c7be39d2c
|
||||||
|
|||||||
@@ -3,4 +3,5 @@ REACT_APP_CERT_SERVICE_URL=http://localhost/certificate
|
|||||||
REACT_APP_UPLOAD_SERVICE_URL=http://localhost/ota_update
|
REACT_APP_UPLOAD_SERVICE_URL=http://localhost/ota_update
|
||||||
REACT_APP_AUTH_CALLBACK_URL=http://localhost:3000
|
REACT_APP_AUTH_CALLBACK_URL=http://localhost:3000
|
||||||
REACT_APP_SUPERSET_URL=https://dev-superset-new.cloud.fiskerinc.com
|
REACT_APP_SUPERSET_URL=https://dev-superset-new.cloud.fiskerinc.com
|
||||||
REACT_APP_SUPERSET_KEYS_LIST=0b01ac72-9ef4-4a5f-be34-b1ac0bf972cc
|
REACT_APP_MAGNA_PROVIDER=Fisker-QA
|
||||||
|
REACT_APP_MAGNA_GROUP_ID=efcc3025-e2d8-4212-8227-805c7be39d2c
|
||||||
2
.env.prd
2
.env.prd
@@ -3,3 +3,5 @@ REACT_APP_CERT_SERVICE_URL=https://gw.cloud.fiskerinc.com/certificate
|
|||||||
REACT_APP_UPLOAD_SERVICE_URL=https://gw.cloud.fiskerinc.com/ota_update
|
REACT_APP_UPLOAD_SERVICE_URL=https://gw.cloud.fiskerinc.com/ota_update
|
||||||
REACT_APP_AUTH_CALLBACK_URL=https://ota-admin.cloud.fiskerinc.com
|
REACT_APP_AUTH_CALLBACK_URL=https://ota-admin.cloud.fiskerinc.com
|
||||||
REACT_APP_SUPERSET_URL=https://superset.cloud.fiskerinc.com
|
REACT_APP_SUPERSET_URL=https://superset.cloud.fiskerinc.com
|
||||||
|
REACT_APP_MAGNA_PROVIDER=Magna
|
||||||
|
REACT_APP_MAGNA_GROUP_ID=68273225-9da4-4fa7-aea5-38e16ec471fe
|
||||||
|
|||||||
4
.env.stg
4
.env.stg
@@ -2,4 +2,6 @@ REACT_APP_AUTH_SERVICE_URL=https://stg-gw.cloud.fiskerinc.com/compute_auth
|
|||||||
REACT_APP_CERT_SERVICE_URL=https://stg-gw.cloud.fiskerinc.com/certificate
|
REACT_APP_CERT_SERVICE_URL=https://stg-gw.cloud.fiskerinc.com/certificate
|
||||||
REACT_APP_UPLOAD_SERVICE_URL=https://stg-gw.cloud.fiskerinc.com/ota_update
|
REACT_APP_UPLOAD_SERVICE_URL=https://stg-gw.cloud.fiskerinc.com/ota_update
|
||||||
REACT_APP_AUTH_CALLBACK_URL=https://stg-ota-admin.cloud.fiskerinc.com
|
REACT_APP_AUTH_CALLBACK_URL=https://stg-ota-admin.cloud.fiskerinc.com
|
||||||
REACT_APP_SUPERSET_URL=https://stg-superset.cloud.fiskerinc.com
|
REACT_APP_SUPERSET_URL=https://stg-superset.cloud.fiskerinc.com
|
||||||
|
REACT_APP_MAGNA_PROVIDER=Fisker-QA
|
||||||
|
REACT_APP_MAGNA_GROUP_ID=efcc3025-e2d8-4212-8227-805c7be39d2c
|
||||||
|
|||||||
@@ -2,4 +2,6 @@ REACT_APP_AUTH_SERVICE_URL=http://localhost/compute_auth
|
|||||||
REACT_APP_UPLOAD_SERVICE_URL=http://localhost/ota_update
|
REACT_APP_UPLOAD_SERVICE_URL=http://localhost/ota_update
|
||||||
REACT_APP_AUTH_CALLBACK_URL=http://localhost:3000
|
REACT_APP_AUTH_CALLBACK_URL=http://localhost:3000
|
||||||
REACT_APP_SUPERSET_URL=https://dev-superset.cloud.fiskerinc.com
|
REACT_APP_SUPERSET_URL=https://dev-superset.cloud.fiskerinc.com
|
||||||
REACT_APP_CERT_SERVICE_URL=http://localhost/certificate
|
REACT_APP_CERT_SERVICE_URL=http://localhost/certificate
|
||||||
|
REACT_APP_MAGNA_PROVIDER=Magna
|
||||||
|
REACT_APP_MAGNA_GROUP_ID=68273225-9da4-4fa7-aea5-38e16ec471fe
|
||||||
|
|||||||
77
package-lock.json
generated
77
package-lock.json
generated
@@ -37,7 +37,8 @@
|
|||||||
"react-router-hash-link": "^2.4.3",
|
"react-router-hash-link": "^2.4.3",
|
||||||
"react-scripts": "5.0.0",
|
"react-scripts": "5.0.0",
|
||||||
"usehooks-ts": "^2.7.1",
|
"usehooks-ts": "^2.7.1",
|
||||||
"web-vitals": "^2.1.4"
|
"web-vitals": "^2.1.4",
|
||||||
|
"webpack": "^5.74.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"react-test-renderer": "^17.0.2"
|
"react-test-renderer": "^17.0.2"
|
||||||
@@ -5607,9 +5608,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/acorn": {
|
"node_modules/acorn": {
|
||||||
"version": "8.7.0",
|
"version": "8.8.1",
|
||||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz",
|
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz",
|
||||||
"integrity": "sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==",
|
"integrity": "sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==",
|
||||||
"bin": {
|
"bin": {
|
||||||
"acorn": "bin/acorn"
|
"acorn": "bin/acorn"
|
||||||
},
|
},
|
||||||
@@ -8028,9 +8029,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/enhanced-resolve": {
|
"node_modules/enhanced-resolve": {
|
||||||
"version": "5.9.2",
|
"version": "5.10.0",
|
||||||
"resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.9.2.tgz",
|
"resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.10.0.tgz",
|
||||||
"integrity": "sha512-GIm3fQfwLJ8YZx2smuHpBKkXC1yOk+OBEmKckVyL0i/ea8mqDEykK3ld5dgH1QYPNyT/lIllxV2LULnxCHaHkA==",
|
"integrity": "sha512-T0yTFjdpldGY8PmuXXR0PyQ1ufZpEGiHVrp7zHKB7jdR4qlmZHhONVM5AQOAWXuF/w3dnHbEQVrNptJgt7F+cQ==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"graceful-fs": "^4.2.4",
|
"graceful-fs": "^4.2.4",
|
||||||
"tapable": "^2.2.0"
|
"tapable": "^2.2.0"
|
||||||
@@ -11602,11 +11603,6 @@
|
|||||||
"node": ">=4"
|
"node": ">=4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/json-parse-better-errors": {
|
|
||||||
"version": "1.0.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz",
|
|
||||||
"integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw=="
|
|
||||||
},
|
|
||||||
"node_modules/json-parse-even-better-errors": {
|
"node_modules/json-parse-even-better-errors": {
|
||||||
"version": "2.3.1",
|
"version": "2.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz",
|
||||||
@@ -16635,9 +16631,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/watchpack": {
|
"node_modules/watchpack": {
|
||||||
"version": "2.3.1",
|
"version": "2.4.0",
|
||||||
"resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz",
|
||||||
"integrity": "sha512-x0t0JuydIo8qCNctdDrn1OzH/qDzk2+rdCOC3YzumZ42fiMqmQ7T3xQurykYMhYfHaPHTp4ZxAx2NfUo1K6QaA==",
|
"integrity": "sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"glob-to-regexp": "^0.4.1",
|
"glob-to-regexp": "^0.4.1",
|
||||||
"graceful-fs": "^4.1.2"
|
"graceful-fs": "^4.1.2"
|
||||||
@@ -16668,33 +16664,33 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/webpack": {
|
"node_modules/webpack": {
|
||||||
"version": "5.70.0",
|
"version": "5.74.0",
|
||||||
"resolved": "https://registry.npmjs.org/webpack/-/webpack-5.70.0.tgz",
|
"resolved": "https://registry.npmjs.org/webpack/-/webpack-5.74.0.tgz",
|
||||||
"integrity": "sha512-ZMWWy8CeuTTjCxbeaQI21xSswseF2oNOwc70QSKNePvmxE7XW36i7vpBMYZFAUHPwQiEbNGCEYIOOlyRbdGmxw==",
|
"integrity": "sha512-A2InDwnhhGN4LYctJj6M1JEaGL7Luj6LOmyBHjcI8529cm5p6VXiTIW2sn6ffvEAKmveLzvu4jrihwXtPojlAA==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/eslint-scope": "^3.7.3",
|
"@types/eslint-scope": "^3.7.3",
|
||||||
"@types/estree": "^0.0.51",
|
"@types/estree": "^0.0.51",
|
||||||
"@webassemblyjs/ast": "1.11.1",
|
"@webassemblyjs/ast": "1.11.1",
|
||||||
"@webassemblyjs/wasm-edit": "1.11.1",
|
"@webassemblyjs/wasm-edit": "1.11.1",
|
||||||
"@webassemblyjs/wasm-parser": "1.11.1",
|
"@webassemblyjs/wasm-parser": "1.11.1",
|
||||||
"acorn": "^8.4.1",
|
"acorn": "^8.7.1",
|
||||||
"acorn-import-assertions": "^1.7.6",
|
"acorn-import-assertions": "^1.7.6",
|
||||||
"browserslist": "^4.14.5",
|
"browserslist": "^4.14.5",
|
||||||
"chrome-trace-event": "^1.0.2",
|
"chrome-trace-event": "^1.0.2",
|
||||||
"enhanced-resolve": "^5.9.2",
|
"enhanced-resolve": "^5.10.0",
|
||||||
"es-module-lexer": "^0.9.0",
|
"es-module-lexer": "^0.9.0",
|
||||||
"eslint-scope": "5.1.1",
|
"eslint-scope": "5.1.1",
|
||||||
"events": "^3.2.0",
|
"events": "^3.2.0",
|
||||||
"glob-to-regexp": "^0.4.1",
|
"glob-to-regexp": "^0.4.1",
|
||||||
"graceful-fs": "^4.2.9",
|
"graceful-fs": "^4.2.9",
|
||||||
"json-parse-better-errors": "^1.0.2",
|
"json-parse-even-better-errors": "^2.3.1",
|
||||||
"loader-runner": "^4.2.0",
|
"loader-runner": "^4.2.0",
|
||||||
"mime-types": "^2.1.27",
|
"mime-types": "^2.1.27",
|
||||||
"neo-async": "^2.6.2",
|
"neo-async": "^2.6.2",
|
||||||
"schema-utils": "^3.1.0",
|
"schema-utils": "^3.1.0",
|
||||||
"tapable": "^2.1.1",
|
"tapable": "^2.1.1",
|
||||||
"terser-webpack-plugin": "^5.1.3",
|
"terser-webpack-plugin": "^5.1.3",
|
||||||
"watchpack": "^2.3.1",
|
"watchpack": "^2.4.0",
|
||||||
"webpack-sources": "^3.2.3"
|
"webpack-sources": "^3.2.3"
|
||||||
},
|
},
|
||||||
"bin": {
|
"bin": {
|
||||||
@@ -21520,9 +21516,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"acorn": {
|
"acorn": {
|
||||||
"version": "8.7.0",
|
"version": "8.8.1",
|
||||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz",
|
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz",
|
||||||
"integrity": "sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ=="
|
"integrity": "sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA=="
|
||||||
},
|
},
|
||||||
"acorn-globals": {
|
"acorn-globals": {
|
||||||
"version": "6.0.0",
|
"version": "6.0.0",
|
||||||
@@ -23304,9 +23300,9 @@
|
|||||||
"integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k="
|
"integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k="
|
||||||
},
|
},
|
||||||
"enhanced-resolve": {
|
"enhanced-resolve": {
|
||||||
"version": "5.9.2",
|
"version": "5.10.0",
|
||||||
"resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.9.2.tgz",
|
"resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.10.0.tgz",
|
||||||
"integrity": "sha512-GIm3fQfwLJ8YZx2smuHpBKkXC1yOk+OBEmKckVyL0i/ea8mqDEykK3ld5dgH1QYPNyT/lIllxV2LULnxCHaHkA==",
|
"integrity": "sha512-T0yTFjdpldGY8PmuXXR0PyQ1ufZpEGiHVrp7zHKB7jdR4qlmZHhONVM5AQOAWXuF/w3dnHbEQVrNptJgt7F+cQ==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"graceful-fs": "^4.2.4",
|
"graceful-fs": "^4.2.4",
|
||||||
"tapable": "^2.2.0"
|
"tapable": "^2.2.0"
|
||||||
@@ -25886,11 +25882,6 @@
|
|||||||
"resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz",
|
"resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz",
|
||||||
"integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA=="
|
"integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA=="
|
||||||
},
|
},
|
||||||
"json-parse-better-errors": {
|
|
||||||
"version": "1.0.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz",
|
|
||||||
"integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw=="
|
|
||||||
},
|
|
||||||
"json-parse-even-better-errors": {
|
"json-parse-even-better-errors": {
|
||||||
"version": "2.3.1",
|
"version": "2.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz",
|
||||||
@@ -29497,9 +29488,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"watchpack": {
|
"watchpack": {
|
||||||
"version": "2.3.1",
|
"version": "2.4.0",
|
||||||
"resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz",
|
||||||
"integrity": "sha512-x0t0JuydIo8qCNctdDrn1OzH/qDzk2+rdCOC3YzumZ42fiMqmQ7T3xQurykYMhYfHaPHTp4ZxAx2NfUo1K6QaA==",
|
"integrity": "sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"glob-to-regexp": "^0.4.1",
|
"glob-to-regexp": "^0.4.1",
|
||||||
"graceful-fs": "^4.1.2"
|
"graceful-fs": "^4.1.2"
|
||||||
@@ -29524,33 +29515,33 @@
|
|||||||
"integrity": "sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w=="
|
"integrity": "sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w=="
|
||||||
},
|
},
|
||||||
"webpack": {
|
"webpack": {
|
||||||
"version": "5.70.0",
|
"version": "5.74.0",
|
||||||
"resolved": "https://registry.npmjs.org/webpack/-/webpack-5.70.0.tgz",
|
"resolved": "https://registry.npmjs.org/webpack/-/webpack-5.74.0.tgz",
|
||||||
"integrity": "sha512-ZMWWy8CeuTTjCxbeaQI21xSswseF2oNOwc70QSKNePvmxE7XW36i7vpBMYZFAUHPwQiEbNGCEYIOOlyRbdGmxw==",
|
"integrity": "sha512-A2InDwnhhGN4LYctJj6M1JEaGL7Luj6LOmyBHjcI8529cm5p6VXiTIW2sn6ffvEAKmveLzvu4jrihwXtPojlAA==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@types/eslint-scope": "^3.7.3",
|
"@types/eslint-scope": "^3.7.3",
|
||||||
"@types/estree": "^0.0.51",
|
"@types/estree": "^0.0.51",
|
||||||
"@webassemblyjs/ast": "1.11.1",
|
"@webassemblyjs/ast": "1.11.1",
|
||||||
"@webassemblyjs/wasm-edit": "1.11.1",
|
"@webassemblyjs/wasm-edit": "1.11.1",
|
||||||
"@webassemblyjs/wasm-parser": "1.11.1",
|
"@webassemblyjs/wasm-parser": "1.11.1",
|
||||||
"acorn": "^8.4.1",
|
"acorn": "^8.7.1",
|
||||||
"acorn-import-assertions": "^1.7.6",
|
"acorn-import-assertions": "^1.7.6",
|
||||||
"browserslist": "^4.14.5",
|
"browserslist": "^4.14.5",
|
||||||
"chrome-trace-event": "^1.0.2",
|
"chrome-trace-event": "^1.0.2",
|
||||||
"enhanced-resolve": "^5.9.2",
|
"enhanced-resolve": "^5.10.0",
|
||||||
"es-module-lexer": "^0.9.0",
|
"es-module-lexer": "^0.9.0",
|
||||||
"eslint-scope": "5.1.1",
|
"eslint-scope": "5.1.1",
|
||||||
"events": "^3.2.0",
|
"events": "^3.2.0",
|
||||||
"glob-to-regexp": "^0.4.1",
|
"glob-to-regexp": "^0.4.1",
|
||||||
"graceful-fs": "^4.2.9",
|
"graceful-fs": "^4.2.9",
|
||||||
"json-parse-better-errors": "^1.0.2",
|
"json-parse-even-better-errors": "^2.3.1",
|
||||||
"loader-runner": "^4.2.0",
|
"loader-runner": "^4.2.0",
|
||||||
"mime-types": "^2.1.27",
|
"mime-types": "^2.1.27",
|
||||||
"neo-async": "^2.6.2",
|
"neo-async": "^2.6.2",
|
||||||
"schema-utils": "^3.1.0",
|
"schema-utils": "^3.1.0",
|
||||||
"tapable": "^2.1.1",
|
"tapable": "^2.1.1",
|
||||||
"terser-webpack-plugin": "^5.1.3",
|
"terser-webpack-plugin": "^5.1.3",
|
||||||
"watchpack": "^2.3.1",
|
"watchpack": "^2.4.0",
|
||||||
"webpack-sources": "^3.2.3"
|
"webpack-sources": "^3.2.3"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|||||||
10
package.json
10
package.json
@@ -32,7 +32,8 @@
|
|||||||
"react-router-hash-link": "^2.4.3",
|
"react-router-hash-link": "^2.4.3",
|
||||||
"react-scripts": "5.0.0",
|
"react-scripts": "5.0.0",
|
||||||
"usehooks-ts": "^2.7.1",
|
"usehooks-ts": "^2.7.1",
|
||||||
"web-vitals": "^2.1.4"
|
"web-vitals": "^2.1.4",
|
||||||
|
"webpack": "^5.74.0"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "env-cmd -f .env.local react-scripts start",
|
"start": "env-cmd -f .env.local react-scripts start",
|
||||||
@@ -51,7 +52,10 @@
|
|||||||
"extends": [
|
"extends": [
|
||||||
"react-app",
|
"react-app",
|
||||||
"react-app/jest"
|
"react-app/jest"
|
||||||
]
|
],
|
||||||
|
"rules": {
|
||||||
|
"no-console": "warn"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"browserslist": [
|
"browserslist": [
|
||||||
">0.2%",
|
">0.2%",
|
||||||
@@ -82,4 +86,4 @@
|
|||||||
"lcov"
|
"lcov"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ import {
|
|||||||
waitForElementToBeRemoved,
|
waitForElementToBeRemoved,
|
||||||
} from "@testing-library/react";
|
} from "@testing-library/react";
|
||||||
import { setToken } from "../Contexts/UserContext";
|
import { setToken } from "../Contexts/UserContext";
|
||||||
import { TEST_AUTH_OBJECT } from "../../utils/testing";
|
import {TEST_AUTH_OBJECT, TEST_AUTH_OBJECT_FISKER} from "../../utils/testing";
|
||||||
import App from ".";
|
import App from ".";
|
||||||
import addSnapshotSerializer from "../../utils/snapshot";
|
import addSnapshotSerializer from "../../utils/snapshot";
|
||||||
|
|
||||||
@@ -35,7 +35,7 @@ const check = async (path, selector, compare) => {
|
|||||||
let container
|
let container
|
||||||
await act(async () => {
|
await act(async () => {
|
||||||
container = await renderRoute(path);
|
container = await renderRoute(path);
|
||||||
})
|
});
|
||||||
expect(container.querySelector(selector).innerHTML).toEqual(compare);
|
expect(container.querySelector(selector).innerHTML).toEqual(compare);
|
||||||
expect(container).toMatchSnapshot();
|
expect(container).toMatchSnapshot();
|
||||||
};
|
};
|
||||||
@@ -117,57 +117,57 @@ describe("App", () => {
|
|||||||
await check("/page-not-found", "h1", "Page Not Found");
|
await check("/page-not-found", "h1", "Page Not Found");
|
||||||
});
|
});
|
||||||
it("Route / authenticated", async () => {
|
it("Route / authenticated", async () => {
|
||||||
setToken(TEST_AUTH_OBJECT);
|
setToken(TEST_AUTH_OBJECT_FISKER);
|
||||||
await sleepAndCheck("/", "h6", "Home");
|
await sleepAndCheck("/", "h6", "Home");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Route /home authenticated", async () => {
|
it("Route /home authenticated", async () => {
|
||||||
setToken(TEST_AUTH_OBJECT);
|
setToken(TEST_AUTH_OBJECT_FISKER);
|
||||||
await sleepAndCheck("/home", "h6", "Home");
|
await sleepAndCheck("/home", "h6", "Home");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Route /page-not-found authenticated", async () => {
|
it("Route /page-not-found authenticated", async () => {
|
||||||
setToken(TEST_AUTH_OBJECT);
|
setToken(TEST_AUTH_OBJECT_FISKER);
|
||||||
await check("/page-not-found", "h1", "Page Not Found");
|
await check("/page-not-found", "h1", "Page Not Found");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Route /packages authenticated", async () => {
|
it("Route /packages authenticated", async () => {
|
||||||
setToken(TEST_AUTH_OBJECT);
|
setToken(TEST_AUTH_OBJECT_FISKER);
|
||||||
await check("/packages", "h6", "Deployments");
|
await check("/packages", "h6", "Deployments");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Route /package-status authenticated", async () => {
|
it("Route /package-status authenticated", async () => {
|
||||||
setToken(TEST_AUTH_OBJECT);
|
setToken(TEST_AUTH_OBJECT_FISKER);
|
||||||
await check("/package-status/1", "h6", "Manifest Test Manifest 1.0");
|
await check("/package-status/1", "h6", "Manifest Test Manifest 1.0");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Route /package-deploy authenticated", async () => {
|
it("Route /package-deploy authenticated", async () => {
|
||||||
setToken(TEST_AUTH_OBJECT);
|
setToken(TEST_AUTH_OBJECT_FISKER);
|
||||||
await check("/package-deploy/1", "h6", "Deploy Test Manifest 1.0");
|
await check("/package-deploy/1", "h6", "Deploy Test Manifest 1.0");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Route /vehicle-add authenticated", async () => {
|
it("Route /vehicle-add authenticated", async () => {
|
||||||
setToken(TEST_AUTH_OBJECT);
|
setToken(TEST_AUTH_OBJECT_FISKER);
|
||||||
await check("/vehicle-add", "h6", "Add Vehicle");
|
await check("/vehicle-add", "h6", "Add Vehicle");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Route /vehicles authenticated", async () => {
|
it("Route /vehicles authenticated", async () => {
|
||||||
setToken(TEST_AUTH_OBJECT);
|
setToken(TEST_AUTH_OBJECT_FISKER);
|
||||||
await check("/vehicles", "h6", "Vehicles");
|
await check("/vehicles", "h6", "Vehicles");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Route /vehicle-status authenticated", async () => {
|
it("Route /vehicle-status authenticated", async () => {
|
||||||
setToken(TEST_AUTH_OBJECT);
|
setToken(TEST_AUTH_OBJECT_FISKER);
|
||||||
await check("/vehicle-status/FISKER123", "h6", "Vehicle FISKER123 Details");
|
await check("/vehicle-status/FISKER123", "h6", "Vehicle FISKER123 Details");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Route /tools/certificates/add authenticated", async () => {
|
it("Route /tools/certificates/add authenticated", async () => {
|
||||||
setToken(TEST_AUTH_OBJECT);
|
setToken(TEST_AUTH_OBJECT_FISKER);
|
||||||
await check("/tools/certificates/add", "h6", "Create Certificate");
|
await sleepAndCheck("/tools/certificates/add", "h6", "Create Certificate");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Route /tools/sms/send authenticated", async () => {
|
it("Route /tools/sms/send authenticated", async () => {
|
||||||
setToken(TEST_AUTH_OBJECT);
|
setToken(TEST_AUTH_OBJECT_FISKER);
|
||||||
await check("/tools/sms/send", "h6", "Send SMS");
|
await sleepAndCheck("/tools/sms/send", "h6", "Send SMS");
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ exports[`App Route / authenticated 1`] = `
|
|||||||
<span
|
<span
|
||||||
class="MuiButton-label"
|
class="MuiButton-label"
|
||||||
>
|
>
|
||||||
John
|
Anvar
|
||||||
</span>
|
</span>
|
||||||
<span
|
<span
|
||||||
class="MuiTouchRipple-root"
|
class="MuiTouchRipple-root"
|
||||||
@@ -270,6 +270,42 @@ exports[`App Route / authenticated 1`] = `
|
|||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
|
<li>
|
||||||
|
<a
|
||||||
|
aria-disabled="false"
|
||||||
|
class="MuiButtonBase-root MuiListItem-root MuiListItem-gutters MuiListItem-button"
|
||||||
|
href="/suppliers"
|
||||||
|
role="button"
|
||||||
|
tabindex="0"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="MuiListItemIcon-root"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
aria-hidden="true"
|
||||||
|
class="MuiSvgIcon-root"
|
||||||
|
focusable="false"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M5 2c0-.55-.45-1-1-1s-1 .45-1 1v4H1v6h6V6H5V2zm4 14c0 1.3.84 2.4 2 2.82V23h2v-4.18c1.16-.41 2-1.51 2-2.82v-2H9v2zm-8 0c0 1.3.84 2.4 2 2.82V23h2v-4.18C6.16 18.4 7 17.3 7 16v-2H1v2zM21 6V2c0-.55-.45-1-1-1s-1 .45-1 1v4h-2v6h6V6h-2zm-8-4c0-.55-.45-1-1-1s-1 .45-1 1v4H9v6h6V6h-2V2zm4 14c0 1.3.84 2.4 2 2.82V23h2v-4.18c1.16-.41 2-1.51 2-2.82v-2h-6v2z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="MuiListItemText-root"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="MuiTypography-root MuiListItemText-primary MuiTypography-body1 MuiTypography-displayBlock"
|
||||||
|
>
|
||||||
|
Suppliers
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<span
|
||||||
|
class="MuiTouchRipple-root"
|
||||||
|
/>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
<span>
|
<span>
|
||||||
<li>
|
<li>
|
||||||
<a
|
<a
|
||||||
@@ -594,7 +630,7 @@ exports[`App Route /home authenticated 1`] = `
|
|||||||
<span
|
<span
|
||||||
class="MuiButton-label"
|
class="MuiButton-label"
|
||||||
>
|
>
|
||||||
John
|
Anvar
|
||||||
</span>
|
</span>
|
||||||
<span
|
<span
|
||||||
class="MuiTouchRipple-root"
|
class="MuiTouchRipple-root"
|
||||||
@@ -829,6 +865,42 @@ exports[`App Route /home authenticated 1`] = `
|
|||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
|
<li>
|
||||||
|
<a
|
||||||
|
aria-disabled="false"
|
||||||
|
class="MuiButtonBase-root MuiListItem-root MuiListItem-gutters MuiListItem-button"
|
||||||
|
href="/suppliers"
|
||||||
|
role="button"
|
||||||
|
tabindex="0"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="MuiListItemIcon-root"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
aria-hidden="true"
|
||||||
|
class="MuiSvgIcon-root"
|
||||||
|
focusable="false"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M5 2c0-.55-.45-1-1-1s-1 .45-1 1v4H1v6h6V6H5V2zm4 14c0 1.3.84 2.4 2 2.82V23h2v-4.18c1.16-.41 2-1.51 2-2.82v-2H9v2zm-8 0c0 1.3.84 2.4 2 2.82V23h2v-4.18C6.16 18.4 7 17.3 7 16v-2H1v2zM21 6V2c0-.55-.45-1-1-1s-1 .45-1 1v4h-2v6h6V6h-2zm-8-4c0-.55-.45-1-1-1s-1 .45-1 1v4H9v6h6V6h-2V2zm4 14c0 1.3.84 2.4 2 2.82V23h2v-4.18c1.16-.41 2-1.51 2-2.82v-2h-6v2z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="MuiListItemText-root"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="MuiTypography-root MuiListItemText-primary MuiTypography-body1 MuiTypography-displayBlock"
|
||||||
|
>
|
||||||
|
Suppliers
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<span
|
||||||
|
class="MuiTouchRipple-root"
|
||||||
|
/>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
<span>
|
<span>
|
||||||
<li>
|
<li>
|
||||||
<a
|
<a
|
||||||
@@ -1189,7 +1261,7 @@ exports[`App Route /package-deploy authenticated 1`] = `
|
|||||||
<span
|
<span
|
||||||
class="MuiButton-label"
|
class="MuiButton-label"
|
||||||
>
|
>
|
||||||
John
|
Anvar
|
||||||
</span>
|
</span>
|
||||||
<span
|
<span
|
||||||
class="MuiTouchRipple-root"
|
class="MuiTouchRipple-root"
|
||||||
@@ -1424,6 +1496,42 @@ exports[`App Route /package-deploy authenticated 1`] = `
|
|||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
|
<li>
|
||||||
|
<a
|
||||||
|
aria-disabled="false"
|
||||||
|
class="MuiButtonBase-root MuiListItem-root MuiListItem-gutters MuiListItem-button"
|
||||||
|
href="/suppliers"
|
||||||
|
role="button"
|
||||||
|
tabindex="0"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="MuiListItemIcon-root"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
aria-hidden="true"
|
||||||
|
class="MuiSvgIcon-root"
|
||||||
|
focusable="false"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M5 2c0-.55-.45-1-1-1s-1 .45-1 1v4H1v6h6V6H5V2zm4 14c0 1.3.84 2.4 2 2.82V23h2v-4.18c1.16-.41 2-1.51 2-2.82v-2H9v2zm-8 0c0 1.3.84 2.4 2 2.82V23h2v-4.18C6.16 18.4 7 17.3 7 16v-2H1v2zM21 6V2c0-.55-.45-1-1-1s-1 .45-1 1v4h-2v6h6V6h-2zm-8-4c0-.55-.45-1-1-1s-1 .45-1 1v4H9v6h6V6h-2V2zm4 14c0 1.3.84 2.4 2 2.82V23h2v-4.18c1.16-.41 2-1.51 2-2.82v-2h-6v2z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="MuiListItemText-root"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="MuiTypography-root MuiListItemText-primary MuiTypography-body1 MuiTypography-displayBlock"
|
||||||
|
>
|
||||||
|
Suppliers
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<span
|
||||||
|
class="MuiTouchRipple-root"
|
||||||
|
/>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
<span>
|
<span>
|
||||||
<li>
|
<li>
|
||||||
<a
|
<a
|
||||||
@@ -2148,7 +2256,7 @@ exports[`App Route /package-status authenticated 1`] = `
|
|||||||
<span
|
<span
|
||||||
class="MuiButton-label"
|
class="MuiButton-label"
|
||||||
>
|
>
|
||||||
John
|
Anvar
|
||||||
</span>
|
</span>
|
||||||
<span
|
<span
|
||||||
class="MuiTouchRipple-root"
|
class="MuiTouchRipple-root"
|
||||||
@@ -2383,6 +2491,42 @@ exports[`App Route /package-status authenticated 1`] = `
|
|||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
|
<li>
|
||||||
|
<a
|
||||||
|
aria-disabled="false"
|
||||||
|
class="MuiButtonBase-root MuiListItem-root MuiListItem-gutters MuiListItem-button"
|
||||||
|
href="/suppliers"
|
||||||
|
role="button"
|
||||||
|
tabindex="0"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="MuiListItemIcon-root"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
aria-hidden="true"
|
||||||
|
class="MuiSvgIcon-root"
|
||||||
|
focusable="false"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M5 2c0-.55-.45-1-1-1s-1 .45-1 1v4H1v6h6V6H5V2zm4 14c0 1.3.84 2.4 2 2.82V23h2v-4.18c1.16-.41 2-1.51 2-2.82v-2H9v2zm-8 0c0 1.3.84 2.4 2 2.82V23h2v-4.18C6.16 18.4 7 17.3 7 16v-2H1v2zM21 6V2c0-.55-.45-1-1-1s-1 .45-1 1v4h-2v6h6V6h-2zm-8-4c0-.55-.45-1-1-1s-1 .45-1 1v4H9v6h6V6h-2V2zm4 14c0 1.3.84 2.4 2 2.82V23h2v-4.18c1.16-.41 2-1.51 2-2.82v-2h-6v2z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="MuiListItemText-root"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="MuiTypography-root MuiListItemText-primary MuiTypography-body1 MuiTypography-displayBlock"
|
||||||
|
>
|
||||||
|
Suppliers
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<span
|
||||||
|
class="MuiTouchRipple-root"
|
||||||
|
/>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
<span>
|
<span>
|
||||||
<li>
|
<li>
|
||||||
<a
|
<a
|
||||||
@@ -2825,7 +2969,7 @@ exports[`App Route /packages authenticated 1`] = `
|
|||||||
<span
|
<span
|
||||||
class="MuiButton-label"
|
class="MuiButton-label"
|
||||||
>
|
>
|
||||||
John
|
Anvar
|
||||||
</span>
|
</span>
|
||||||
<span
|
<span
|
||||||
class="MuiTouchRipple-root"
|
class="MuiTouchRipple-root"
|
||||||
@@ -3060,6 +3204,42 @@ exports[`App Route /packages authenticated 1`] = `
|
|||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
|
<li>
|
||||||
|
<a
|
||||||
|
aria-disabled="false"
|
||||||
|
class="MuiButtonBase-root MuiListItem-root MuiListItem-gutters MuiListItem-button"
|
||||||
|
href="/suppliers"
|
||||||
|
role="button"
|
||||||
|
tabindex="0"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="MuiListItemIcon-root"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
aria-hidden="true"
|
||||||
|
class="MuiSvgIcon-root"
|
||||||
|
focusable="false"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M5 2c0-.55-.45-1-1-1s-1 .45-1 1v4H1v6h6V6H5V2zm4 14c0 1.3.84 2.4 2 2.82V23h2v-4.18c1.16-.41 2-1.51 2-2.82v-2H9v2zm-8 0c0 1.3.84 2.4 2 2.82V23h2v-4.18C6.16 18.4 7 17.3 7 16v-2H1v2zM21 6V2c0-.55-.45-1-1-1s-1 .45-1 1v4h-2v6h6V6h-2zm-8-4c0-.55-.45-1-1-1s-1 .45-1 1v4H9v6h6V6h-2V2zm4 14c0 1.3.84 2.4 2 2.82V23h2v-4.18c1.16-.41 2-1.51 2-2.82v-2h-6v2z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="MuiListItemText-root"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="MuiTypography-root MuiListItemText-primary MuiTypography-body1 MuiTypography-displayBlock"
|
||||||
|
>
|
||||||
|
Suppliers
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<span
|
||||||
|
class="MuiTouchRipple-root"
|
||||||
|
/>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
<span>
|
<span>
|
||||||
<li>
|
<li>
|
||||||
<a
|
<a
|
||||||
@@ -3482,25 +3662,6 @@ exports[`App Route /packages authenticated 1`] = `
|
|||||||
/>
|
/>
|
||||||
</svg>
|
</svg>
|
||||||
</a>
|
</a>
|
||||||
<span>
|
|
||||||
<a
|
|
||||||
class=""
|
|
||||||
href="/packages"
|
|
||||||
title="Delete \\"Test Manifest 1.0\\""
|
|
||||||
>
|
|
||||||
<svg
|
|
||||||
aria-hidden="true"
|
|
||||||
aria-label="Delete Test Manifest 1.0"
|
|
||||||
class="MuiSvgIcon-root"
|
|
||||||
focusable="false"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
d="M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
</a>
|
|
||||||
</span>
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
@@ -3729,7 +3890,7 @@ exports[`App Route /page-not-found authenticated 1`] = `
|
|||||||
<span
|
<span
|
||||||
class="MuiButton-label"
|
class="MuiButton-label"
|
||||||
>
|
>
|
||||||
John
|
Anvar
|
||||||
</span>
|
</span>
|
||||||
<span
|
<span
|
||||||
class="MuiTouchRipple-root"
|
class="MuiTouchRipple-root"
|
||||||
@@ -3964,6 +4125,42 @@ exports[`App Route /page-not-found authenticated 1`] = `
|
|||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
|
<li>
|
||||||
|
<a
|
||||||
|
aria-disabled="false"
|
||||||
|
class="MuiButtonBase-root MuiListItem-root MuiListItem-gutters MuiListItem-button"
|
||||||
|
href="/suppliers"
|
||||||
|
role="button"
|
||||||
|
tabindex="0"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="MuiListItemIcon-root"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
aria-hidden="true"
|
||||||
|
class="MuiSvgIcon-root"
|
||||||
|
focusable="false"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M5 2c0-.55-.45-1-1-1s-1 .45-1 1v4H1v6h6V6H5V2zm4 14c0 1.3.84 2.4 2 2.82V23h2v-4.18c1.16-.41 2-1.51 2-2.82v-2H9v2zm-8 0c0 1.3.84 2.4 2 2.82V23h2v-4.18C6.16 18.4 7 17.3 7 16v-2H1v2zM21 6V2c0-.55-.45-1-1-1s-1 .45-1 1v4h-2v6h6V6h-2zm-8-4c0-.55-.45-1-1-1s-1 .45-1 1v4H9v6h6V6h-2V2zm4 14c0 1.3.84 2.4 2 2.82V23h2v-4.18c1.16-.41 2-1.51 2-2.82v-2h-6v2z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="MuiListItemText-root"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="MuiTypography-root MuiListItemText-primary MuiTypography-body1 MuiTypography-displayBlock"
|
||||||
|
>
|
||||||
|
Suppliers
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<span
|
||||||
|
class="MuiTouchRipple-root"
|
||||||
|
/>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
<span>
|
<span>
|
||||||
<li>
|
<li>
|
||||||
<a
|
<a
|
||||||
@@ -4251,7 +4448,7 @@ exports[`App Route /tools/certificates/add authenticated 1`] = `
|
|||||||
<span
|
<span
|
||||||
class="MuiButton-label"
|
class="MuiButton-label"
|
||||||
>
|
>
|
||||||
John
|
Anvar
|
||||||
</span>
|
</span>
|
||||||
<span
|
<span
|
||||||
class="MuiTouchRipple-root"
|
class="MuiTouchRipple-root"
|
||||||
@@ -4486,6 +4683,42 @@ exports[`App Route /tools/certificates/add authenticated 1`] = `
|
|||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
|
<li>
|
||||||
|
<a
|
||||||
|
aria-disabled="false"
|
||||||
|
class="MuiButtonBase-root MuiListItem-root MuiListItem-gutters MuiListItem-button"
|
||||||
|
href="/suppliers"
|
||||||
|
role="button"
|
||||||
|
tabindex="0"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="MuiListItemIcon-root"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
aria-hidden="true"
|
||||||
|
class="MuiSvgIcon-root"
|
||||||
|
focusable="false"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M5 2c0-.55-.45-1-1-1s-1 .45-1 1v4H1v6h6V6H5V2zm4 14c0 1.3.84 2.4 2 2.82V23h2v-4.18c1.16-.41 2-1.51 2-2.82v-2H9v2zm-8 0c0 1.3.84 2.4 2 2.82V23h2v-4.18C6.16 18.4 7 17.3 7 16v-2H1v2zM21 6V2c0-.55-.45-1-1-1s-1 .45-1 1v4h-2v6h6V6h-2zm-8-4c0-.55-.45-1-1-1s-1 .45-1 1v4H9v6h6V6h-2V2zm4 14c0 1.3.84 2.4 2 2.82V23h2v-4.18c1.16-.41 2-1.51 2-2.82v-2h-6v2z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="MuiListItemText-root"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="MuiTypography-root MuiListItemText-primary MuiTypography-body1 MuiTypography-displayBlock"
|
||||||
|
>
|
||||||
|
Suppliers
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<span
|
||||||
|
class="MuiTouchRipple-root"
|
||||||
|
/>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
<span>
|
<span>
|
||||||
<li>
|
<li>
|
||||||
<a
|
<a
|
||||||
@@ -5006,7 +5239,7 @@ exports[`App Route /tools/sms/send authenticated 1`] = `
|
|||||||
<span
|
<span
|
||||||
class="MuiButton-label"
|
class="MuiButton-label"
|
||||||
>
|
>
|
||||||
John
|
Anvar
|
||||||
</span>
|
</span>
|
||||||
<span
|
<span
|
||||||
class="MuiTouchRipple-root"
|
class="MuiTouchRipple-root"
|
||||||
@@ -5241,6 +5474,42 @@ exports[`App Route /tools/sms/send authenticated 1`] = `
|
|||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
|
<li>
|
||||||
|
<a
|
||||||
|
aria-disabled="false"
|
||||||
|
class="MuiButtonBase-root MuiListItem-root MuiListItem-gutters MuiListItem-button"
|
||||||
|
href="/suppliers"
|
||||||
|
role="button"
|
||||||
|
tabindex="0"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="MuiListItemIcon-root"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
aria-hidden="true"
|
||||||
|
class="MuiSvgIcon-root"
|
||||||
|
focusable="false"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M5 2c0-.55-.45-1-1-1s-1 .45-1 1v4H1v6h6V6H5V2zm4 14c0 1.3.84 2.4 2 2.82V23h2v-4.18c1.16-.41 2-1.51 2-2.82v-2H9v2zm-8 0c0 1.3.84 2.4 2 2.82V23h2v-4.18C6.16 18.4 7 17.3 7 16v-2H1v2zM21 6V2c0-.55-.45-1-1-1s-1 .45-1 1v4h-2v6h6V6h-2zm-8-4c0-.55-.45-1-1-1s-1 .45-1 1v4H9v6h6V6h-2V2zm4 14c0 1.3.84 2.4 2 2.82V23h2v-4.18c1.16-.41 2-1.51 2-2.82v-2h-6v2z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="MuiListItemText-root"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="MuiTypography-root MuiListItemText-primary MuiTypography-body1 MuiTypography-displayBlock"
|
||||||
|
>
|
||||||
|
Suppliers
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<span
|
||||||
|
class="MuiTouchRipple-root"
|
||||||
|
/>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
<span>
|
<span>
|
||||||
<li>
|
<li>
|
||||||
<a
|
<a
|
||||||
@@ -5627,7 +5896,7 @@ exports[`App Route /vehicle-add authenticated 1`] = `
|
|||||||
<span
|
<span
|
||||||
class="MuiButton-label"
|
class="MuiButton-label"
|
||||||
>
|
>
|
||||||
John
|
Anvar
|
||||||
</span>
|
</span>
|
||||||
<span
|
<span
|
||||||
class="MuiTouchRipple-root"
|
class="MuiTouchRipple-root"
|
||||||
@@ -5862,6 +6131,42 @@ exports[`App Route /vehicle-add authenticated 1`] = `
|
|||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
|
<li>
|
||||||
|
<a
|
||||||
|
aria-disabled="false"
|
||||||
|
class="MuiButtonBase-root MuiListItem-root MuiListItem-gutters MuiListItem-button"
|
||||||
|
href="/suppliers"
|
||||||
|
role="button"
|
||||||
|
tabindex="0"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="MuiListItemIcon-root"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
aria-hidden="true"
|
||||||
|
class="MuiSvgIcon-root"
|
||||||
|
focusable="false"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M5 2c0-.55-.45-1-1-1s-1 .45-1 1v4H1v6h6V6H5V2zm4 14c0 1.3.84 2.4 2 2.82V23h2v-4.18c1.16-.41 2-1.51 2-2.82v-2H9v2zm-8 0c0 1.3.84 2.4 2 2.82V23h2v-4.18C6.16 18.4 7 17.3 7 16v-2H1v2zM21 6V2c0-.55-.45-1-1-1s-1 .45-1 1v4h-2v6h6V6h-2zm-8-4c0-.55-.45-1-1-1s-1 .45-1 1v4H9v6h6V6h-2V2zm4 14c0 1.3.84 2.4 2 2.82V23h2v-4.18c1.16-.41 2-1.51 2-2.82v-2h-6v2z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="MuiListItemText-root"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="MuiTypography-root MuiListItemText-primary MuiTypography-body1 MuiTypography-displayBlock"
|
||||||
|
>
|
||||||
|
Suppliers
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<span
|
||||||
|
class="MuiTouchRipple-root"
|
||||||
|
/>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
<span>
|
<span>
|
||||||
<li>
|
<li>
|
||||||
<a
|
<a
|
||||||
@@ -6806,7 +7111,7 @@ exports[`App Route /vehicle-status authenticated 1`] = `
|
|||||||
<span
|
<span
|
||||||
class="MuiButton-label"
|
class="MuiButton-label"
|
||||||
>
|
>
|
||||||
John
|
Anvar
|
||||||
</span>
|
</span>
|
||||||
<span
|
<span
|
||||||
class="MuiTouchRipple-root"
|
class="MuiTouchRipple-root"
|
||||||
@@ -7041,6 +7346,42 @@ exports[`App Route /vehicle-status authenticated 1`] = `
|
|||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
|
<li>
|
||||||
|
<a
|
||||||
|
aria-disabled="false"
|
||||||
|
class="MuiButtonBase-root MuiListItem-root MuiListItem-gutters MuiListItem-button"
|
||||||
|
href="/suppliers"
|
||||||
|
role="button"
|
||||||
|
tabindex="0"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="MuiListItemIcon-root"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
aria-hidden="true"
|
||||||
|
class="MuiSvgIcon-root"
|
||||||
|
focusable="false"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M5 2c0-.55-.45-1-1-1s-1 .45-1 1v4H1v6h6V6H5V2zm4 14c0 1.3.84 2.4 2 2.82V23h2v-4.18c1.16-.41 2-1.51 2-2.82v-2H9v2zm-8 0c0 1.3.84 2.4 2 2.82V23h2v-4.18C6.16 18.4 7 17.3 7 16v-2H1v2zM21 6V2c0-.55-.45-1-1-1s-1 .45-1 1v4h-2v6h6V6h-2zm-8-4c0-.55-.45-1-1-1s-1 .45-1 1v4H9v6h6V6h-2V2zm4 14c0 1.3.84 2.4 2 2.82V23h2v-4.18c1.16-.41 2-1.51 2-2.82v-2h-6v2z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="MuiListItemText-root"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="MuiTypography-root MuiListItemText-primary MuiTypography-body1 MuiTypography-displayBlock"
|
||||||
|
>
|
||||||
|
Suppliers
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<span
|
||||||
|
class="MuiTouchRipple-root"
|
||||||
|
/>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
<span>
|
<span>
|
||||||
<li>
|
<li>
|
||||||
<a
|
<a
|
||||||
@@ -7195,7 +7536,6 @@ exports[`App Route /vehicle-status authenticated 1`] = `
|
|||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
aria-controls="tabpanel-2"
|
aria-controls="tabpanel-2"
|
||||||
aria-selected="false"
|
|
||||||
class="MuiButtonBase-root MuiTab-root MuiTab-textColorInherit"
|
class="MuiButtonBase-root MuiTab-root MuiTab-textColorInherit"
|
||||||
id="tab-2"
|
id="tab-2"
|
||||||
role="tab"
|
role="tab"
|
||||||
@@ -7213,7 +7553,6 @@ exports[`App Route /vehicle-status authenticated 1`] = `
|
|||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
aria-controls="tabpanel-3"
|
aria-controls="tabpanel-3"
|
||||||
aria-selected="false"
|
|
||||||
class="MuiButtonBase-root MuiTab-root MuiTab-textColorInherit"
|
class="MuiButtonBase-root MuiTab-root MuiTab-textColorInherit"
|
||||||
id="tab-3"
|
id="tab-3"
|
||||||
role="tab"
|
role="tab"
|
||||||
@@ -7231,7 +7570,6 @@ exports[`App Route /vehicle-status authenticated 1`] = `
|
|||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
aria-controls="tabpanel-4"
|
aria-controls="tabpanel-4"
|
||||||
aria-selected="false"
|
|
||||||
class="MuiButtonBase-root MuiTab-root MuiTab-textColorInherit"
|
class="MuiButtonBase-root MuiTab-root MuiTab-textColorInherit"
|
||||||
id="tab-4"
|
id="tab-4"
|
||||||
role="tab"
|
role="tab"
|
||||||
@@ -7249,7 +7587,6 @@ exports[`App Route /vehicle-status authenticated 1`] = `
|
|||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
aria-controls="tabpanel-5"
|
aria-controls="tabpanel-5"
|
||||||
aria-selected="false"
|
|
||||||
class="MuiButtonBase-root MuiTab-root MuiTab-textColorInherit"
|
class="MuiButtonBase-root MuiTab-root MuiTab-textColorInherit"
|
||||||
id="tab-5"
|
id="tab-5"
|
||||||
role="tab"
|
role="tab"
|
||||||
@@ -7267,7 +7604,6 @@ exports[`App Route /vehicle-status authenticated 1`] = `
|
|||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
aria-controls="tabpanel-6"
|
aria-controls="tabpanel-6"
|
||||||
aria-selected="false"
|
|
||||||
class="MuiButtonBase-root MuiTab-root MuiTab-textColorInherit"
|
class="MuiButtonBase-root MuiTab-root MuiTab-textColorInherit"
|
||||||
id="tab-6"
|
id="tab-6"
|
||||||
role="tab"
|
role="tab"
|
||||||
@@ -7397,23 +7733,6 @@ exports[`App Route /vehicle-status authenticated 1`] = `
|
|||||||
/>
|
/>
|
||||||
</svg>
|
</svg>
|
||||||
</a>
|
</a>
|
||||||
<a
|
|
||||||
class=""
|
|
||||||
href="/vehicle-status/FISKER123"
|
|
||||||
title="Delete \\"FISKER123\\""
|
|
||||||
>
|
|
||||||
<svg
|
|
||||||
aria-hidden="true"
|
|
||||||
aria-label="Delete \\"FISKER123\\""
|
|
||||||
class="MuiSvgIcon-root"
|
|
||||||
focusable="false"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
d="M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
</a>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div />
|
<div />
|
||||||
@@ -7616,7 +7935,7 @@ exports[`App Route /vehicles authenticated 1`] = `
|
|||||||
<span
|
<span
|
||||||
class="MuiButton-label"
|
class="MuiButton-label"
|
||||||
>
|
>
|
||||||
John
|
Anvar
|
||||||
</span>
|
</span>
|
||||||
<span
|
<span
|
||||||
class="MuiTouchRipple-root"
|
class="MuiTouchRipple-root"
|
||||||
@@ -7851,6 +8170,42 @@ exports[`App Route /vehicles authenticated 1`] = `
|
|||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
|
<li>
|
||||||
|
<a
|
||||||
|
aria-disabled="false"
|
||||||
|
class="MuiButtonBase-root MuiListItem-root MuiListItem-gutters MuiListItem-button"
|
||||||
|
href="/suppliers"
|
||||||
|
role="button"
|
||||||
|
tabindex="0"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="MuiListItemIcon-root"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
aria-hidden="true"
|
||||||
|
class="MuiSvgIcon-root"
|
||||||
|
focusable="false"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M5 2c0-.55-.45-1-1-1s-1 .45-1 1v4H1v6h6V6H5V2zm4 14c0 1.3.84 2.4 2 2.82V23h2v-4.18c1.16-.41 2-1.51 2-2.82v-2H9v2zm-8 0c0 1.3.84 2.4 2 2.82V23h2v-4.18C6.16 18.4 7 17.3 7 16v-2H1v2zM21 6V2c0-.55-.45-1-1-1s-1 .45-1 1v4h-2v6h6V6h-2zm-8-4c0-.55-.45-1-1-1s-1 .45-1 1v4H9v6h6V6h-2V2zm4 14c0 1.3.84 2.4 2 2.82V23h2v-4.18c1.16-.41 2-1.51 2-2.82v-2h-6v2z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="MuiListItemText-root"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="MuiTypography-root MuiListItemText-primary MuiTypography-body1 MuiTypography-displayBlock"
|
||||||
|
>
|
||||||
|
Suppliers
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<span
|
||||||
|
class="MuiTouchRipple-root"
|
||||||
|
/>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
<span>
|
<span>
|
||||||
<li>
|
<li>
|
||||||
<a
|
<a
|
||||||
@@ -7960,22 +8315,7 @@ exports[`App Route /vehicles authenticated 1`] = `
|
|||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="MuiGrid-root makeStyles-textJustifyAlign-0 MuiGrid-item MuiGrid-grid-md-4"
|
class="MuiGrid-root makeStyles-textJustifyAlign-0 MuiGrid-item MuiGrid-grid-md-4"
|
||||||
>
|
/>
|
||||||
<a
|
|
||||||
href="/vehicle-add"
|
|
||||||
>
|
|
||||||
<svg
|
|
||||||
aria-hidden="true"
|
|
||||||
class="MuiSvgIcon-root MuiSvgIcon-fontSizeLarge"
|
|
||||||
focusable="false"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm5 11h-4v4h-2v-4H7v-2h4V7h2v4h4v2z"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
<div
|
<div
|
||||||
class="MuiGrid-root makeStyles-textCenterAlign-0 MuiGrid-item MuiGrid-grid-md-4"
|
class="MuiGrid-root makeStyles-textCenterAlign-0 MuiGrid-item MuiGrid-grid-md-4"
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import {TEST_AUTH_OBJECT_FISKER} from "../../../utils/testing";
|
||||||
|
|
||||||
jest.mock("../../Contexts/CANFiltersContext");
|
jest.mock("../../Contexts/CANFiltersContext");
|
||||||
jest.mock("../../Contexts/StatusContext");
|
jest.mock("../../Contexts/StatusContext");
|
||||||
jest.mock("../../Contexts/UserContext");
|
jest.mock("../../Contexts/UserContext");
|
||||||
@@ -8,7 +10,6 @@ import { BrowserRouter } from "react-router-dom";
|
|||||||
import { CANFiltersProvider } from "../../Contexts/CANFiltersContext";
|
import { CANFiltersProvider } from "../../Contexts/CANFiltersContext";
|
||||||
import { StatusProvider } from "../../Contexts/StatusContext";
|
import { StatusProvider } from "../../Contexts/StatusContext";
|
||||||
import { UserProvider, setToken } from "../../Contexts/UserContext";
|
import { UserProvider, setToken } from "../../Contexts/UserContext";
|
||||||
import { TEST_AUTH_OBJECT } from "../../../utils/testing";
|
|
||||||
import MainForm from "./index";
|
import MainForm from "./index";
|
||||||
import addSnapshotSerializer from "../../../utils/snapshot";
|
import addSnapshotSerializer from "../../../utils/snapshot";
|
||||||
|
|
||||||
@@ -35,7 +36,7 @@ describe("CANFiltersAdd", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("Render", async () => {
|
it("Render", async () => {
|
||||||
setToken(TEST_AUTH_OBJECT);
|
setToken(TEST_AUTH_OBJECT_FISKER);
|
||||||
const container = await renderCANFiltersAdd();
|
const container = await renderCANFiltersAdd();
|
||||||
expect(container).toMatchSnapshot();
|
expect(container).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -250,23 +250,6 @@ exports[`CANFiltersTable Render 1`] = `
|
|||||||
/>
|
/>
|
||||||
</svg>
|
</svg>
|
||||||
</a>
|
</a>
|
||||||
<a
|
|
||||||
class=""
|
|
||||||
href="/"
|
|
||||||
title="Delete \\"123\\""
|
|
||||||
>
|
|
||||||
<svg
|
|
||||||
aria-hidden="true"
|
|
||||||
aria-label="Delete 123"
|
|
||||||
class="MuiSvgIcon-root"
|
|
||||||
focusable="false"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
d="M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
</a>
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr
|
<tr
|
||||||
@@ -313,23 +296,6 @@ exports[`CANFiltersTable Render 1`] = `
|
|||||||
/>
|
/>
|
||||||
</svg>
|
</svg>
|
||||||
</a>
|
</a>
|
||||||
<a
|
|
||||||
class=""
|
|
||||||
href="/"
|
|
||||||
title="Delete \\"456-789\\""
|
|
||||||
>
|
|
||||||
<svg
|
|
||||||
aria-hidden="true"
|
|
||||||
aria-label="Delete 456-789"
|
|
||||||
class="MuiSvgIcon-root"
|
|
||||||
focusable="false"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
d="M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
</a>
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr
|
<tr
|
||||||
@@ -376,23 +342,6 @@ exports[`CANFiltersTable Render 1`] = `
|
|||||||
/>
|
/>
|
||||||
</svg>
|
</svg>
|
||||||
</a>
|
</a>
|
||||||
<a
|
|
||||||
class=""
|
|
||||||
href="/"
|
|
||||||
title="Delete \\"1\\""
|
|
||||||
>
|
|
||||||
<svg
|
|
||||||
aria-hidden="true"
|
|
||||||
aria-label="Delete 1"
|
|
||||||
class="MuiSvgIcon-root"
|
|
||||||
focusable="false"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
d="M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
</a>
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
import React, { useEffect, useState } from "react";
|
|
||||||
import { Link } from 'react-router-dom';
|
|
||||||
import {
|
import {
|
||||||
Grid,
|
Grid,
|
||||||
Table,
|
Table,
|
||||||
@@ -12,46 +10,46 @@ import {
|
|||||||
} from "@material-ui/core";
|
} from "@material-ui/core";
|
||||||
import AddCircleIcon from "@material-ui/icons/AddCircle";
|
import AddCircleIcon from "@material-ui/icons/AddCircle";
|
||||||
import DeleteIcon from "@material-ui/icons/Delete";
|
import DeleteIcon from "@material-ui/icons/Delete";
|
||||||
import EditIcon from '@material-ui/icons/Edit';
|
import EditIcon from "@material-ui/icons/Edit";
|
||||||
import clsx from "clsx";
|
import clsx from "clsx";
|
||||||
|
import React, { useEffect, useState } from "react";
|
||||||
|
import { Link } from "react-router-dom";
|
||||||
|
|
||||||
|
import { logger } from "../../../services/monitoring";
|
||||||
|
import { hasRole, Permissions } from "../../../utils/roles";
|
||||||
|
import { trimIfMoreThan } from "../../../utils/strings";
|
||||||
import {
|
import {
|
||||||
CANFiltersProvider,
|
CANFiltersProvider,
|
||||||
useCANFiltersContext,
|
useCANFiltersContext,
|
||||||
} from "../../Contexts/CANFiltersContext";
|
} from "../../Contexts/CANFiltersContext";
|
||||||
import TableHeaderSortable from "../../Table/HeaderSortable";
|
|
||||||
import {
|
|
||||||
useUserContext
|
|
||||||
} from "../../Contexts/UserContext"
|
|
||||||
import { useStatusContext } from "../../Contexts/StatusContext";
|
import { useStatusContext } from "../../Contexts/StatusContext";
|
||||||
import useStyles from "../../useStyles";
|
import { useUserContext } from "../../Contexts/UserContext";
|
||||||
import SearchField from "../../Controls/SearchField";
|
import SearchField from "../../Controls/SearchField";
|
||||||
import { logger } from "../../../services/monitoring";
|
import TableHeaderSortable from "../../Table/HeaderSortable";
|
||||||
import { Roles, hasRole } from "../../../utils/roles";
|
import { useLocalStorage } from "../../useLocalStorage";
|
||||||
import {useLocalStorage} from "../../useLocalStorage";
|
import useStyles from "../../useStyles";
|
||||||
import {trimIfMoreThan} from "../../../utils/strings";
|
|
||||||
|
|
||||||
const tableColumns = [
|
const tableColumns = [
|
||||||
{
|
{
|
||||||
id: "can_id",
|
id: "can_id",
|
||||||
label: "CAN ID"
|
label: "CAN ID",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: "interval",
|
id: "interval",
|
||||||
label: "Interval (ms)"
|
label: "Interval (ms)",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: "fleet",
|
id: "fleet",
|
||||||
label: "Fleet"
|
label: "Fleet",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: "edge_mask",
|
id: "edge_mask",
|
||||||
label: "Edge mask"
|
label: "Edge mask",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: "",
|
id: "",
|
||||||
label: "Actions"
|
label: "Actions",
|
||||||
}
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
const PAGE_SIZE = "CAN_FILTER_TABLE_PAGE_SIZE";
|
const PAGE_SIZE = "CAN_FILTER_TABLE_PAGE_SIZE";
|
||||||
@@ -63,9 +61,16 @@ const MainForm = ({ vin }) => {
|
|||||||
const [pageIndex, setPageIndex] = useState(0);
|
const [pageIndex, setPageIndex] = useState(0);
|
||||||
const [orderBy, setOrderBy] = useState("id");
|
const [orderBy, setOrderBy] = useState("id");
|
||||||
const [order, setOrder] = useState("desc");
|
const [order, setOrder] = useState("desc");
|
||||||
const { getFilters, deleteFilter, filters, totalFilters } = useCANFiltersContext();
|
const { getFilters, deleteFilter, filters, totalFilters } =
|
||||||
|
useCANFiltersContext();
|
||||||
const { setMessage } = useStatusContext();
|
const { setMessage } = useStatusContext();
|
||||||
const { token: { idToken: { jwtToken: token } }, groups } = useUserContext();
|
const {
|
||||||
|
token: {
|
||||||
|
idToken: { jwtToken: token },
|
||||||
|
},
|
||||||
|
groups,
|
||||||
|
providers,
|
||||||
|
} = useUserContext();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
(async () => {
|
(async () => {
|
||||||
@@ -118,7 +123,7 @@ const MainForm = ({ vin }) => {
|
|||||||
const onDelete = async (can_id) => {
|
const onDelete = async (can_id) => {
|
||||||
try {
|
try {
|
||||||
await deleteFilter(vin, can_id, token);
|
await deleteFilter(vin, can_id, token);
|
||||||
setMessage(`Deleted ${can_id}`)
|
setMessage(`Deleted ${can_id}`);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
setMessage(e.message);
|
setMessage(e.message);
|
||||||
logger.warn(e.stack);
|
logger.warn(e.stack);
|
||||||
@@ -126,24 +131,24 @@ const MainForm = ({ vin }) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const Actions = (row) => {
|
const Actions = (row) => {
|
||||||
if(row.fleet != null) {
|
if (row.fleet != null) {
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let actions = [];
|
let actions = [];
|
||||||
if (hasRole([Roles.CREATE], groups)) {
|
if (hasRole(groups, Permissions.FiskerCreate, providers)) {
|
||||||
actions.push({
|
actions.push({
|
||||||
tip: `Update "${row.can_id}"`,
|
tip: `Update "${row.can_id}"`,
|
||||||
link: `/filter-update?vin=${vin}&can_id=${row.can_id}&interval=${row.interval}`,
|
link: `/filter-update?vin=${vin}&can_id=${row.can_id}&interval=${row.interval}`,
|
||||||
icon: <EditIcon aria-label={`Update ${row.can_id}`} />
|
icon: <EditIcon aria-label={`Update ${row.can_id}`} />,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (hasRole([Roles.DELETE], groups)) {
|
if (hasRole(groups, Permissions.FiskerDelete, providers)) {
|
||||||
actions.push({
|
actions.push({
|
||||||
tip: `Delete "${row.can_id}"`,
|
tip: `Delete "${row.can_id}"`,
|
||||||
id: row.can_id,
|
id: row.can_id,
|
||||||
icon: <DeleteIcon aria-label={`Delete ${row.can_id}`} />
|
icon: <DeleteIcon aria-label={`Delete ${row.can_id}`} />,
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
if (actions.length === 0) return ["No actions"];
|
if (actions.length === 0) return ["No actions"];
|
||||||
|
|
||||||
@@ -177,7 +182,7 @@ const MainForm = ({ vin }) => {
|
|||||||
</Link>
|
</Link>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid item md={8} className={classes.textCenterAlign}>
|
<Grid item md={8} className={classes.textCenterAlign}>
|
||||||
<SearchField classes={classes} onSearch={onSearch}/>
|
<SearchField classes={classes} onSearch={onSearch} />
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Table>
|
<Table>
|
||||||
@@ -196,7 +201,9 @@ const MainForm = ({ vin }) => {
|
|||||||
<TableCell align="center">
|
<TableCell align="center">
|
||||||
<Link to={`/fleet/${row.fleet}`}>{row.fleet}</Link>
|
<Link to={`/fleet/${row.fleet}`}>{row.fleet}</Link>
|
||||||
</TableCell>
|
</TableCell>
|
||||||
<TableCell align="center">{trimIfMoreThan(row.edge_mask, 15, "...")}</TableCell>
|
<TableCell align="center">
|
||||||
|
{trimIfMoreThan(row.edge_mask, 15, "...")}
|
||||||
|
</TableCell>
|
||||||
<TableCell align="center">{Actions(row)}</TableCell>
|
<TableCell align="center">{Actions(row)}</TableCell>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
))}
|
))}
|
||||||
@@ -219,7 +226,7 @@ const MainForm = ({ vin }) => {
|
|||||||
</TableRow>
|
</TableRow>
|
||||||
</TableFooter>
|
</TableFooter>
|
||||||
</Table>
|
</Table>
|
||||||
</div >
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import { BrowserRouter } from "react-router-dom";
|
|||||||
import { CANFiltersProvider } from "../../Contexts/CANFiltersContext";
|
import { CANFiltersProvider } from "../../Contexts/CANFiltersContext";
|
||||||
import { StatusProvider } from "../../Contexts/StatusContext";
|
import { StatusProvider } from "../../Contexts/StatusContext";
|
||||||
import { UserProvider, setToken } from "../../Contexts/UserContext";
|
import { UserProvider, setToken } from "../../Contexts/UserContext";
|
||||||
import { TEST_AUTH_OBJECT } from "../../../utils/testing";
|
import {TEST_AUTH_OBJECT_FISKER} from "../../../utils/testing";
|
||||||
import MainForm from "./index";
|
import MainForm from "./index";
|
||||||
import addSnapshotSerializer from "../../../utils/snapshot";
|
import addSnapshotSerializer from "../../../utils/snapshot";
|
||||||
|
|
||||||
@@ -37,7 +37,7 @@ describe("CANFiltersTable", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("Render", async () => {
|
it("Render", async () => {
|
||||||
setToken(TEST_AUTH_OBJECT);
|
setToken(TEST_AUTH_OBJECT_FISKER);
|
||||||
const container = await renderCANFiltersTable();
|
const container = await renderCANFiltersTable();
|
||||||
expect(container).toMatchSnapshot();
|
expect(container).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import { BrowserRouter } from "react-router-dom";
|
|||||||
import { CANFiltersProvider } from "../../Contexts/CANFiltersContext";
|
import { CANFiltersProvider } from "../../Contexts/CANFiltersContext";
|
||||||
import { StatusProvider } from "../../Contexts/StatusContext";
|
import { StatusProvider } from "../../Contexts/StatusContext";
|
||||||
import { UserProvider, setToken } from "../../Contexts/UserContext";
|
import { UserProvider, setToken } from "../../Contexts/UserContext";
|
||||||
import { TEST_AUTH_OBJECT } from "../../../utils/testing";
|
import { TEST_AUTH_OBJECT_FISKER } from "../../../utils/testing";
|
||||||
import MainForm from "./index";
|
import MainForm from "./index";
|
||||||
import addSnapshotSerializer from "../../../utils/snapshot";
|
import addSnapshotSerializer from "../../../utils/snapshot";
|
||||||
|
|
||||||
@@ -34,7 +34,7 @@ describe("CANFiltersUpdate", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("Render", async () => {
|
it("Render", async () => {
|
||||||
setToken(TEST_AUTH_OBJECT);
|
setToken(TEST_AUTH_OBJECT_FISKER);
|
||||||
const container = await renderCANFiltersUpdate();
|
const container = await renderCANFiltersUpdate();
|
||||||
expect(container).toMatchSnapshot();
|
expect(container).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import { BrowserRouter } from "react-router-dom";
|
|||||||
import { VehicleProvider } from "../../Contexts/VehicleContext";
|
import { VehicleProvider } from "../../Contexts/VehicleContext";
|
||||||
import { StatusProvider } from "../../Contexts/StatusContext";
|
import { StatusProvider } from "../../Contexts/StatusContext";
|
||||||
import { UserProvider, setToken } from "../../Contexts/UserContext";
|
import { UserProvider, setToken } from "../../Contexts/UserContext";
|
||||||
import { TEST_AUTH_OBJECT } from "../../../utils/testing";
|
import { TEST_AUTH_OBJECT_FISKER } from "../../../utils/testing";
|
||||||
import MainForm from "./index";
|
import MainForm from "./index";
|
||||||
import addSnapshotSerializer from "../../../utils/snapshot";
|
import addSnapshotSerializer from "../../../utils/snapshot";
|
||||||
|
|
||||||
@@ -36,7 +36,7 @@ describe("VehicleAddForm", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("Render", async () => {
|
it("Render", async () => {
|
||||||
setToken(TEST_AUTH_OBJECT);
|
setToken(TEST_AUTH_OBJECT_FISKER);
|
||||||
const container = await renderVehicleAdd();
|
const container = await renderVehicleAdd();
|
||||||
expect(container).toMatchSnapshot();
|
expect(container).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -22,22 +22,7 @@ exports[`VehicleTable Render 1`] = `
|
|||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="MuiGrid-root makeStyles-textJustifyAlign-0 MuiGrid-item MuiGrid-grid-md-4"
|
class="MuiGrid-root makeStyles-textJustifyAlign-0 MuiGrid-item MuiGrid-grid-md-4"
|
||||||
>
|
/>
|
||||||
<a
|
|
||||||
href="/vehicle-add"
|
|
||||||
>
|
|
||||||
<svg
|
|
||||||
aria-hidden="true"
|
|
||||||
class="MuiSvgIcon-root MuiSvgIcon-fontSizeLarge"
|
|
||||||
focusable="false"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm5 11h-4v4h-2v-4H7v-2h4V7h2v4h4v2z"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
<div
|
<div
|
||||||
class="MuiGrid-root makeStyles-textCenterAlign-0 MuiGrid-item MuiGrid-grid-md-4"
|
class="MuiGrid-root makeStyles-textCenterAlign-0 MuiGrid-item MuiGrid-grid-md-4"
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -1,16 +1,18 @@
|
|||||||
import React, { useEffect, useState } from "react";
|
|
||||||
import { Checkbox, FormControlLabel, Grid, MenuItem } from "@material-ui/core";
|
import { Checkbox, FormControlLabel, Grid, MenuItem } from "@material-ui/core";
|
||||||
import AddCircleIcon from "@material-ui/icons/AddCircle";
|
import AddCircleIcon from "@material-ui/icons/AddCircle";
|
||||||
import { Link } from "react-router-dom";
|
|
||||||
import clsx from "clsx";
|
import clsx from "clsx";
|
||||||
|
import React, { useEffect, useState } from "react";
|
||||||
|
import { Link } from "react-router-dom";
|
||||||
|
|
||||||
import { VehicleProvider } from "../../Contexts/VehicleContext";
|
import { Permissions } from "../../../utils/roles";
|
||||||
import { useUserContext } from "../../Contexts/UserContext";
|
|
||||||
import { useStatusContext } from "../../Contexts/StatusContext";
|
import { useStatusContext } from "../../Contexts/StatusContext";
|
||||||
import useStyles from "../../useStyles";
|
import { useUserContext } from "../../Contexts/UserContext";
|
||||||
import SearchField from "../../Controls/SearchField";
|
import { VehicleProvider } from "../../Contexts/VehicleContext";
|
||||||
import CarSelectionTable from "../../Controls/CarSelectionTable";
|
import CarSelectionTable from "../../Controls/CarSelectionTable";
|
||||||
import OptionsDropdown from "../../Controls/OptionsDropdown";
|
import OptionsDropdown from "../../Controls/OptionsDropdown";
|
||||||
|
import { RoleWrap } from "../../Controls/RoleWrap";
|
||||||
|
import SearchField from "../../Controls/SearchField";
|
||||||
|
import useStyles from "../../useStyles";
|
||||||
|
|
||||||
const MainForm = () => {
|
const MainForm = () => {
|
||||||
const classes = useStyles();
|
const classes = useStyles();
|
||||||
@@ -22,6 +24,8 @@ const MainForm = () => {
|
|||||||
token: {
|
token: {
|
||||||
idToken: { jwtToken: token },
|
idToken: { jwtToken: token },
|
||||||
},
|
},
|
||||||
|
groups,
|
||||||
|
providers,
|
||||||
} = useUserContext();
|
} = useUserContext();
|
||||||
|
|
||||||
const handleSearch = (query) => {
|
const handleSearch = (query) => {
|
||||||
@@ -30,11 +34,11 @@ const MainForm = () => {
|
|||||||
|
|
||||||
const handleOnline = (event) => {
|
const handleOnline = (event) => {
|
||||||
setOnline(event.target.checked);
|
setOnline(event.target.checked);
|
||||||
}
|
};
|
||||||
|
|
||||||
const handleOnlineHMI = (event) => {
|
const handleOnlineHMI = (event) => {
|
||||||
setOnlineHMI(event.target.checked);
|
setOnlineHMI(event.target.checked);
|
||||||
}
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setTitle("Vehicles");
|
setTitle("Vehicles");
|
||||||
@@ -46,30 +50,34 @@ const MainForm = () => {
|
|||||||
<div className={clsx(classes.paper, classes.tableSize)}>
|
<div className={clsx(classes.paper, classes.tableSize)}>
|
||||||
<Grid container className={classes.root} spacing={2}>
|
<Grid container className={classes.root} spacing={2}>
|
||||||
<Grid item md={4} className={classes.textJustifyAlign}>
|
<Grid item md={4} className={classes.textJustifyAlign}>
|
||||||
<Link to="/vehicle-add">
|
<RoleWrap
|
||||||
<AddCircleIcon fontSize="large" />
|
groups={groups}
|
||||||
</Link>
|
providers={providers}
|
||||||
|
rolesPerProvider={Permissions.FiskerDelete}
|
||||||
|
>
|
||||||
|
<Link to="/vehicle-add">
|
||||||
|
<AddCircleIcon fontSize="large" />
|
||||||
|
</Link>
|
||||||
|
</RoleWrap>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid item md={4} className={classes.textCenterAlign}>
|
<Grid item md={4} className={classes.textCenterAlign}>
|
||||||
<SearchField classes={classes} onSearch={handleSearch} />
|
<SearchField classes={classes} onSearch={handleSearch} />
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid item md={2} className={classes.textJustifyAlign}>
|
<Grid item md={2} className={classes.textJustifyAlign}>
|
||||||
<OptionsDropdown listId='filter-menu'>
|
<OptionsDropdown listId="filter-menu">
|
||||||
<MenuItem>
|
<MenuItem>
|
||||||
<FormControlLabel control={
|
<FormControlLabel
|
||||||
<Checkbox
|
control={<Checkbox checked={online} onChange={handleOnline} />}
|
||||||
checked={online}
|
label="Only online"
|
||||||
onChange={handleOnline}
|
/>
|
||||||
/>
|
|
||||||
} label="Only online" />
|
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
<MenuItem>
|
<MenuItem>
|
||||||
<FormControlLabel control={
|
<FormControlLabel
|
||||||
<Checkbox
|
control={
|
||||||
checked={onlineHMI}
|
<Checkbox checked={onlineHMI} onChange={handleOnlineHMI} />
|
||||||
onChange={handleOnlineHMI}
|
}
|
||||||
/>
|
label="Only online HMI"
|
||||||
} label="Only online HMI" />
|
/>
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
</OptionsDropdown>
|
</OptionsDropdown>
|
||||||
</Grid>
|
</Grid>
|
||||||
@@ -79,7 +87,11 @@ const MainForm = () => {
|
|||||||
classes={classes}
|
classes={classes}
|
||||||
token={token}
|
token={token}
|
||||||
multiSelect={false}
|
multiSelect={false}
|
||||||
search={{ search, online: online? true : null, online_hmi: onlineHMI? true : null }}
|
search={{
|
||||||
|
search,
|
||||||
|
online: online ? true : null,
|
||||||
|
online_hmi: onlineHMI ? true : null,
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import { BrowserRouter } from "react-router-dom";
|
|||||||
import { VehicleProvider } from "../../Contexts/VehicleContext";
|
import { VehicleProvider } from "../../Contexts/VehicleContext";
|
||||||
import { StatusProvider } from "../../Contexts/StatusContext";
|
import { StatusProvider } from "../../Contexts/StatusContext";
|
||||||
import { UserProvider, setToken } from "../../Contexts/UserContext";
|
import { UserProvider, setToken } from "../../Contexts/UserContext";
|
||||||
import { TEST_AUTH_OBJECT } from "../../../utils/testing";
|
import { TEST_AUTH_OBJECT_FISKER } from "../../../utils/testing";
|
||||||
import MainForm from "./index";
|
import MainForm from "./index";
|
||||||
import addSnapshotSerializer from "../../../utils/snapshot";
|
import addSnapshotSerializer from "../../../utils/snapshot";
|
||||||
|
|
||||||
@@ -39,7 +39,7 @@ describe("VehicleTable", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("Render", async () => {
|
it("Render", async () => {
|
||||||
setToken(TEST_AUTH_OBJECT);
|
setToken(TEST_AUTH_OBJECT_FISKER);
|
||||||
const container = await renderVehicleTable();
|
const container = await renderVehicleTable();
|
||||||
expect(container).toMatchSnapshot();
|
expect(container).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import { render, waitFor } from "@testing-library/react";
|
|||||||
import { BrowserRouter } from "react-router-dom";
|
import { BrowserRouter } from "react-router-dom";
|
||||||
|
|
||||||
import { setToken } from "../../Contexts/UserContext";
|
import { setToken } from "../../Contexts/UserContext";
|
||||||
import { TEST_AUTH_OBJECT } from "../../../utils/testing";
|
import { TEST_AUTH_OBJECT_FISKER } from "../../../utils/testing";
|
||||||
import CANFiltersTab from "./CANFiltersTab";
|
import CANFiltersTab from "./CANFiltersTab";
|
||||||
import addSnapshotSerializer from "../../../utils/snapshot";
|
import addSnapshotSerializer from "../../../utils/snapshot";
|
||||||
|
|
||||||
@@ -31,7 +31,7 @@ describe("CANFiltersTab", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("Render", async () => {
|
it("Render", async () => {
|
||||||
setToken(TEST_AUTH_OBJECT);
|
setToken(TEST_AUTH_OBJECT_FISKER);
|
||||||
const container = await renderCANFiltersTab();
|
const container = await renderCANFiltersTab();
|
||||||
expect(container).toMatchSnapshot();
|
expect(container).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import { render, waitFor } from "@testing-library/react";
|
|||||||
import { BrowserRouter } from "react-router-dom";
|
import { BrowserRouter } from "react-router-dom";
|
||||||
import CANSignalsTab from "./CANSignalsTab";
|
import CANSignalsTab from "./CANSignalsTab";
|
||||||
import {setToken} from "../../Contexts/UserContext";
|
import {setToken} from "../../Contexts/UserContext";
|
||||||
import {TEST_AUTH_OBJECT} from "../../../utils/testing";
|
import { TEST_AUTH_OBJECT_FISKER } from "../../../utils/testing";
|
||||||
|
|
||||||
const renderCANSignalsTab = async () => {
|
const renderCANSignalsTab = async () => {
|
||||||
const { container } = render(
|
const { container } = render(
|
||||||
@@ -31,7 +31,7 @@ describe("CANSignalsTab", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("Render", async () => {
|
it("Render", async () => {
|
||||||
setToken(TEST_AUTH_OBJECT);
|
setToken(TEST_AUTH_OBJECT_FISKER);
|
||||||
const container = await renderCANSignalsTab();
|
const container = await renderCANSignalsTab();
|
||||||
expect(container).toMatchSnapshot();
|
expect(container).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import { BrowserRouter } from "react-router-dom";
|
|||||||
import { CANFiltersProvider } from "../../Contexts/CANFiltersContext";
|
import { CANFiltersProvider } from "../../Contexts/CANFiltersContext";
|
||||||
import { StatusProvider } from "../../Contexts/StatusContext";
|
import { StatusProvider } from "../../Contexts/StatusContext";
|
||||||
import { UserProvider, setToken } from "../../Contexts/UserContext";
|
import { UserProvider, setToken } from "../../Contexts/UserContext";
|
||||||
import { TEST_AUTH_OBJECT } from "../../../utils/testing";
|
import { TEST_AUTH_OBJECT_FISKER } from "../../../utils/testing";
|
||||||
import MainForm from "./CarUpdatesTab";
|
import MainForm from "./CarUpdatesTab";
|
||||||
import addSnapshotSerializer from "../../../utils/snapshot";
|
import addSnapshotSerializer from "../../../utils/snapshot";
|
||||||
|
|
||||||
@@ -39,7 +39,7 @@ describe("CarUpdatesTab", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("Render", async () => {
|
it("Render", async () => {
|
||||||
setToken(TEST_AUTH_OBJECT);
|
setToken(TEST_AUTH_OBJECT_FISKER);
|
||||||
const container = await renderCarUpdatesTab();
|
const container = await renderCarUpdatesTab();
|
||||||
expect(container).toMatchSnapshot();
|
expect(container).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -101,23 +101,6 @@ exports[`VehicleDetailsTab Render 1`] = `
|
|||||||
/>
|
/>
|
||||||
</svg>
|
</svg>
|
||||||
</a>
|
</a>
|
||||||
<a
|
|
||||||
class=""
|
|
||||||
href="/"
|
|
||||||
title="Delete \\"TESTVIN1234567890\\""
|
|
||||||
>
|
|
||||||
<svg
|
|
||||||
aria-hidden="true"
|
|
||||||
aria-label="Delete \\"TESTVIN1234567890\\""
|
|
||||||
class="MuiSvgIcon-root"
|
|
||||||
focusable="false"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
d="M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
</a>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div />
|
<div />
|
||||||
|
|||||||
@@ -1,28 +1,36 @@
|
|||||||
|
import { Grid, Tooltip } from "@material-ui/core";
|
||||||
|
import DeleteIcon from "@material-ui/icons/Delete";
|
||||||
|
import EditIcon from "@material-ui/icons/Edit";
|
||||||
|
import clsx from "clsx";
|
||||||
import React, { useEffect, useState } from "react";
|
import React, { useEffect, useState } from "react";
|
||||||
import { Redirect } from "react-router";
|
import { Redirect } from "react-router";
|
||||||
import { Link } from 'react-router-dom';
|
import { Link } from "react-router-dom";
|
||||||
import {
|
|
||||||
Grid,
|
|
||||||
Tooltip,
|
|
||||||
} from "@material-ui/core";
|
|
||||||
import EditIcon from "@material-ui/icons/Edit"
|
|
||||||
import DeleteIcon from "@material-ui/icons/Delete";
|
|
||||||
import clsx from "clsx";
|
|
||||||
|
|
||||||
import { useUserContext } from "../../../Contexts/UserContext"
|
|
||||||
import { useStatusContext } from "../../../Contexts/StatusContext";
|
|
||||||
import useStyles from "../../../useStyles";
|
|
||||||
import { logger } from "../../../../services/monitoring";
|
import { logger } from "../../../../services/monitoring";
|
||||||
import { useVehicleContext, VehicleProvider } from "../../../Contexts/VehicleContext";
|
import { Permissions } from "../../../../utils/roles";
|
||||||
|
import { useStatusContext } from "../../../Contexts/StatusContext";
|
||||||
|
import { useUserContext } from "../../../Contexts/UserContext";
|
||||||
|
import {
|
||||||
|
useVehicleContext,
|
||||||
|
VehicleProvider
|
||||||
|
} from "../../../Contexts/VehicleContext";
|
||||||
|
import { RoleWrap } from "../../../Controls/RoleWrap";
|
||||||
import DeleteConfirmation from "../../../DeleteConfirmation";
|
import DeleteConfirmation from "../../../DeleteConfirmation";
|
||||||
|
import useStyles from "../../../useStyles";
|
||||||
|
|
||||||
const MainForm = ({ vin }) => {
|
const MainForm = ({ vin }) => {
|
||||||
const classes = useStyles();
|
const classes = useStyles();
|
||||||
const { setMessage } = useStatusContext();
|
const { setMessage } = useStatusContext();
|
||||||
const { vehicle, getVehicle, deleteVehicle } = useVehicleContext();
|
const { vehicle, getVehicle, deleteVehicle } = useVehicleContext();
|
||||||
const [redirect, setRedirect] = useState(null);
|
const [redirect, setRedirect] = useState(null);
|
||||||
const [showDeleteModal, setShowDeleteModal] = useState(false)
|
const [showDeleteModal, setShowDeleteModal] = useState(false);
|
||||||
const { token: { idToken: { jwtToken: token } } } = useUserContext();
|
const {
|
||||||
|
token: {
|
||||||
|
idToken: { jwtToken: token },
|
||||||
|
},
|
||||||
|
groups,
|
||||||
|
providers,
|
||||||
|
} = useUserContext();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
(async () => {
|
(async () => {
|
||||||
@@ -40,7 +48,7 @@ const MainForm = ({ vin }) => {
|
|||||||
const onDelete = async () => {
|
const onDelete = async () => {
|
||||||
try {
|
try {
|
||||||
await deleteVehicle(vin, token);
|
await deleteVehicle(vin, token);
|
||||||
setMessage(`Deleted ${vin}`)
|
setMessage(`Deleted ${vin}`);
|
||||||
setRedirect(`/vehicles`);
|
setRedirect(`/vehicles`);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
setMessage(e.message);
|
setMessage(e.message);
|
||||||
@@ -56,36 +64,67 @@ const MainForm = ({ vin }) => {
|
|||||||
<div className={clsx(classes.paper, classes.tableSize)}>
|
<div className={clsx(classes.paper, classes.tableSize)}>
|
||||||
<Grid container className={classes.root} spacing={2}>
|
<Grid container className={classes.root} spacing={2}>
|
||||||
<Grid item md={12} className={classes.textCenterAlign}>
|
<Grid item md={12} className={classes.textCenterAlign}>
|
||||||
<p><b>VIN</b>: {vin}</p>
|
<p>
|
||||||
|
<b>VIN</b>: {vin}
|
||||||
|
</p>
|
||||||
{vehicle.log_level != null && (
|
{vehicle.log_level != null && (
|
||||||
<p><b>Log Level</b>: {vehicle.log_level}</p>
|
<p>
|
||||||
|
<b>Log Level</b>: {vehicle.log_level}
|
||||||
|
</p>
|
||||||
)}
|
)}
|
||||||
</Grid>
|
</Grid>
|
||||||
{vehicle.canbus && (
|
{vehicle.canbus && (
|
||||||
<Grid item md={12} className={classes.textCenterAlign}>
|
<Grid item md={12} className={classes.textCenterAlign}>
|
||||||
<b>CANBus</b>
|
<b>CANBus</b>
|
||||||
<p><b>Enabled</b>: {vehicle.canbus.enabled.toString()}</p>
|
<p>
|
||||||
<p><b>Max Memory Buffer Size</b>: {vehicle.canbus.max_mem_buffer_size ?? "Default"}</p>
|
<b>Enabled</b>: {vehicle.canbus.enabled.toString()}
|
||||||
<p><b>Enabled</b>: {vehicle.canbus.data_logger_enabled.toString()}</p>
|
</p>
|
||||||
<p><b>Max Disk Buffer Size</b>: {vehicle.canbus.max_disk_buffer_size ?? "Default"}</p>
|
<p>
|
||||||
<p><b>Filters</b>: {vehicle.canbus.filters ? vehicle.canbus.filters.length : 0}</p>
|
<b>Max Memory Buffer Size</b>: {vehicle.canbus.max_mem_buffer_size ?? "Default"}
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<b>Enabled</b>: {vehicle.canbus.data_logger_enabled.toString()}
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<b>Max Disk Buffer Size</b>: {vehicle.canbus.max_disk_buffer_size ?? "Default"}
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<b>Filters</b>: {vehicle.canbus.filters ? vehicle.canbus.filters.length : 0}
|
||||||
|
</p>
|
||||||
</Grid>
|
</Grid>
|
||||||
)}
|
)}
|
||||||
<Grid item md={12} className={classes.textCenterAlign}>
|
<Grid item md={12} className={classes.textCenterAlign}>
|
||||||
<Tooltip key={`update-${vin}`} title={`Update "${vin}"`}>
|
<RoleWrap
|
||||||
<Link to={`/vehicle-update?vin=${vin}`} style={{ margin: 5 }}>
|
groups={groups}
|
||||||
<EditIcon aria-label={`Update "${vin}"`} />
|
providers={providers}
|
||||||
</Link>
|
rolesPerProvider={Permissions.FiskerCreate}
|
||||||
</Tooltip>
|
>
|
||||||
<Tooltip key={`delete-${vin}`} title={`Delete "${vin}"`}>
|
<Tooltip key={`update-${vin}`} title={`Update "${vin}"`}>
|
||||||
<Link to="#" onClick={() => setShowDeleteModal(true)}>
|
<Link to={`/vehicle-update?vin=${vin}`} style={{ margin: 5 }}>
|
||||||
<DeleteIcon aria-label={`Delete "${vin}"`} />
|
<EditIcon aria-label={`Update "${vin}"`} />
|
||||||
</Link>
|
</Link>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
</RoleWrap>
|
||||||
|
<RoleWrap
|
||||||
|
groups={groups}
|
||||||
|
providers={providers}
|
||||||
|
rolesPerProvider={Permissions.FiskerDelete}
|
||||||
|
>
|
||||||
|
<Tooltip key={`delete-${vin}`} title={`Delete "${vin}"`}>
|
||||||
|
<Link to="#" onClick={() => setShowDeleteModal(true)}>
|
||||||
|
<DeleteIcon aria-label={`Delete "${vin}"`} />
|
||||||
|
</Link>
|
||||||
|
</Tooltip>
|
||||||
|
</RoleWrap>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
<DeleteConfirmation message={vin} open={showDeleteModal} close={()=> setShowDeleteModal(false)} deleteFunction={onDelete}/>
|
<DeleteConfirmation
|
||||||
</div >
|
message={vin}
|
||||||
|
open={showDeleteModal}
|
||||||
|
close={() => setShowDeleteModal(false)}
|
||||||
|
deleteFunction={onDelete}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import routeData from "react-router";
|
|||||||
import { VehicleProvider } from "../../../Contexts/VehicleContext";
|
import { VehicleProvider } from "../../../Contexts/VehicleContext";
|
||||||
import { StatusProvider } from "../../../Contexts/StatusContext";
|
import { StatusProvider } from "../../../Contexts/StatusContext";
|
||||||
import { UserProvider, setToken } from "../../../Contexts/UserContext";
|
import { UserProvider, setToken } from "../../../Contexts/UserContext";
|
||||||
import { TEST_AUTH_OBJECT } from "../../../../utils/testing";
|
import { TEST_AUTH_OBJECT_FISKER }from "../../../../utils/testing";
|
||||||
import MainForm from "./index";
|
import MainForm from "./index";
|
||||||
import addSnapshotSerializer from "../../../../utils/snapshot";
|
import addSnapshotSerializer from "../../../../utils/snapshot";
|
||||||
|
|
||||||
@@ -42,7 +42,7 @@ describe("VehicleDetailsTab", () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
it("Render", async () => {
|
it("Render", async () => {
|
||||||
setToken(TEST_AUTH_OBJECT);
|
setToken(TEST_AUTH_OBJECT_FISKER);
|
||||||
const container = await renderVehicleDetailsTab();
|
const container = await renderVehicleDetailsTab();
|
||||||
expect(container).toMatchSnapshot();
|
expect(container).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import { MemoryRouter, Route } from "react-router-dom";
|
|||||||
import { VehicleProvider } from "../../Contexts/VehicleContext";
|
import { VehicleProvider } from "../../Contexts/VehicleContext";
|
||||||
import { StatusProvider } from "../../Contexts/StatusContext";
|
import { StatusProvider } from "../../Contexts/StatusContext";
|
||||||
import { UserProvider, setToken } from "../../Contexts/UserContext";
|
import { UserProvider, setToken } from "../../Contexts/UserContext";
|
||||||
import { TEST_AUTH_OBJECT } from "../../../utils/testing";
|
import { TEST_AUTH_OBJECT_FISKER } from "../../../utils/testing";
|
||||||
import MainForm from "./DetailsTab";
|
import MainForm from "./DetailsTab";
|
||||||
import addSnapshotSerializer from "../../../utils/snapshot";
|
import addSnapshotSerializer from "../../../utils/snapshot";
|
||||||
|
|
||||||
@@ -41,7 +41,7 @@ describe("DetailsTab", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("Render", async () => {
|
it("Render", async () => {
|
||||||
setToken(TEST_AUTH_OBJECT);
|
setToken(TEST_AUTH_OBJECT_FISKER);
|
||||||
const container = await renderDetailsTab();
|
const container = await renderDetailsTab();
|
||||||
expect(container).toMatchSnapshot();
|
expect(container).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import { render, waitFor } from "@testing-library/react";
|
|||||||
|
|
||||||
import { StatusProvider } from "../../Contexts/StatusContext";
|
import { StatusProvider } from "../../Contexts/StatusContext";
|
||||||
import { UserProvider, setToken } from "../../Contexts/UserContext";
|
import { UserProvider, setToken } from "../../Contexts/UserContext";
|
||||||
import { TEST_AUTH_OBJECT } from "../../../utils/testing";
|
import { TEST_AUTH_OBJECT_FISKER } from "../../../utils/testing";
|
||||||
import DigitalTwinTab from "./DigitalTwinTab";
|
import DigitalTwinTab from "./DigitalTwinTab";
|
||||||
import addSnapshotSerializer from "../../../utils/snapshot";
|
import addSnapshotSerializer from "../../../utils/snapshot";
|
||||||
|
|
||||||
@@ -34,7 +34,7 @@ describe("DigitalTwinTab", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("Render", async () => {
|
it("Render", async () => {
|
||||||
setToken(TEST_AUTH_OBJECT);
|
setToken(TEST_AUTH_OBJECT_FISKER);
|
||||||
const container = await renderDetailsTab();
|
const container = await renderDetailsTab();
|
||||||
expect(container).toMatchSnapshot();
|
expect(container).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import { BrowserRouter } from "react-router-dom";
|
|||||||
import {StatusProvider} from "../../Contexts/StatusContext";
|
import {StatusProvider} from "../../Contexts/StatusContext";
|
||||||
import {VehicleProvider} from "../../Contexts/VehicleContext";
|
import {VehicleProvider} from "../../Contexts/VehicleContext";
|
||||||
import {setToken, UserProvider} from "../../Contexts/UserContext";
|
import {setToken, UserProvider} from "../../Contexts/UserContext";
|
||||||
import {TEST_AUTH_OBJECT} from "../../../utils/testing";
|
import { TEST_AUTH_OBJECT_FISKER } from "../../../utils/testing";
|
||||||
import addSnapshotSerializer from "../../../utils/snapshot";
|
import addSnapshotSerializer from "../../../utils/snapshot";
|
||||||
import FleetsTab from "./FleetsTab";
|
import FleetsTab from "./FleetsTab";
|
||||||
|
|
||||||
@@ -40,7 +40,7 @@ describe("FleetsTab", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("Render", async () => {
|
it("Render", async () => {
|
||||||
setToken(TEST_AUTH_OBJECT);
|
setToken(TEST_AUTH_OBJECT_FISKER);
|
||||||
const container = await renderFleetsTab();
|
const container = await renderFleetsTab();
|
||||||
expect(container).toMatchSnapshot();
|
expect(container).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import {StatusProvider} from "../../Contexts/StatusContext";
|
|||||||
import {setToken, UserProvider} from "../../Contexts/UserContext";
|
import {setToken, UserProvider} from "../../Contexts/UserContext";
|
||||||
import RemoteCommandsTab from "./RemoteCommandsTab";
|
import RemoteCommandsTab from "./RemoteCommandsTab";
|
||||||
import addSnapshotSerializer from "../../../utils/snapshot";
|
import addSnapshotSerializer from "../../../utils/snapshot";
|
||||||
import {TEST_AUTH_OBJECT} from "../../../utils/testing";
|
import { TEST_AUTH_OBJECT_FISKER } from "../../../utils/testing";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
|
||||||
const renderRemoteCommandsTab = async () => {
|
const renderRemoteCommandsTab = async () => {
|
||||||
@@ -33,7 +33,7 @@ describe("RemoteCommandsTab", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("Render", async () => {
|
it("Render", async () => {
|
||||||
setToken(TEST_AUTH_OBJECT);
|
setToken(TEST_AUTH_OBJECT_FISKER);
|
||||||
const container = await renderRemoteCommandsTab();
|
const container = await renderRemoteCommandsTab();
|
||||||
expect(container).toMatchSnapshot();
|
expect(container).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -249,23 +249,6 @@ exports[`CANFiltersTab Render 1`] = `
|
|||||||
/>
|
/>
|
||||||
</svg>
|
</svg>
|
||||||
</a>
|
</a>
|
||||||
<a
|
|
||||||
class=""
|
|
||||||
href="/"
|
|
||||||
title="Delete \\"123\\""
|
|
||||||
>
|
|
||||||
<svg
|
|
||||||
aria-hidden="true"
|
|
||||||
aria-label="Delete 123"
|
|
||||||
class="MuiSvgIcon-root"
|
|
||||||
focusable="false"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
d="M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
</a>
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr
|
<tr
|
||||||
@@ -312,23 +295,6 @@ exports[`CANFiltersTab Render 1`] = `
|
|||||||
/>
|
/>
|
||||||
</svg>
|
</svg>
|
||||||
</a>
|
</a>
|
||||||
<a
|
|
||||||
class=""
|
|
||||||
href="/"
|
|
||||||
title="Delete \\"456-789\\""
|
|
||||||
>
|
|
||||||
<svg
|
|
||||||
aria-hidden="true"
|
|
||||||
aria-label="Delete 456-789"
|
|
||||||
class="MuiSvgIcon-root"
|
|
||||||
focusable="false"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
d="M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
</a>
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr
|
<tr
|
||||||
@@ -375,23 +341,6 @@ exports[`CANFiltersTab Render 1`] = `
|
|||||||
/>
|
/>
|
||||||
</svg>
|
</svg>
|
||||||
</a>
|
</a>
|
||||||
<a
|
|
||||||
class=""
|
|
||||||
href="/"
|
|
||||||
title="Delete \\"1\\""
|
|
||||||
>
|
|
||||||
<svg
|
|
||||||
aria-hidden="true"
|
|
||||||
aria-label="Delete 1"
|
|
||||||
class="MuiSvgIcon-root"
|
|
||||||
focusable="false"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
d="M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
</a>
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
|
|||||||
@@ -109,23 +109,6 @@ exports[`DetailsTab Render 1`] = `
|
|||||||
/>
|
/>
|
||||||
</svg>
|
</svg>
|
||||||
</a>
|
</a>
|
||||||
<a
|
|
||||||
class=""
|
|
||||||
href="/testroute/TESTVIN1234567890"
|
|
||||||
title="Delete \\"TESTVIN1234567890\\""
|
|
||||||
>
|
|
||||||
<svg
|
|
||||||
aria-hidden="true"
|
|
||||||
aria-label="Delete \\"TESTVIN1234567890\\""
|
|
||||||
class="MuiSvgIcon-root"
|
|
||||||
focusable="false"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
d="M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
</a>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div />
|
<div />
|
||||||
|
|||||||
@@ -67,7 +67,6 @@ exports[`CarStatus Render 1`] = `
|
|||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
aria-controls="tabpanel-2"
|
aria-controls="tabpanel-2"
|
||||||
aria-selected="false"
|
|
||||||
class="MuiButtonBase-root MuiTab-root MuiTab-textColorInherit"
|
class="MuiButtonBase-root MuiTab-root MuiTab-textColorInherit"
|
||||||
id="tab-2"
|
id="tab-2"
|
||||||
role="tab"
|
role="tab"
|
||||||
@@ -85,7 +84,6 @@ exports[`CarStatus Render 1`] = `
|
|||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
aria-controls="tabpanel-3"
|
aria-controls="tabpanel-3"
|
||||||
aria-selected="false"
|
|
||||||
class="MuiButtonBase-root MuiTab-root MuiTab-textColorInherit"
|
class="MuiButtonBase-root MuiTab-root MuiTab-textColorInherit"
|
||||||
id="tab-3"
|
id="tab-3"
|
||||||
role="tab"
|
role="tab"
|
||||||
@@ -103,7 +101,6 @@ exports[`CarStatus Render 1`] = `
|
|||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
aria-controls="tabpanel-4"
|
aria-controls="tabpanel-4"
|
||||||
aria-selected="false"
|
|
||||||
class="MuiButtonBase-root MuiTab-root MuiTab-textColorInherit"
|
class="MuiButtonBase-root MuiTab-root MuiTab-textColorInherit"
|
||||||
id="tab-4"
|
id="tab-4"
|
||||||
role="tab"
|
role="tab"
|
||||||
@@ -121,7 +118,6 @@ exports[`CarStatus Render 1`] = `
|
|||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
aria-controls="tabpanel-5"
|
aria-controls="tabpanel-5"
|
||||||
aria-selected="false"
|
|
||||||
class="MuiButtonBase-root MuiTab-root MuiTab-textColorInherit"
|
class="MuiButtonBase-root MuiTab-root MuiTab-textColorInherit"
|
||||||
id="tab-5"
|
id="tab-5"
|
||||||
role="tab"
|
role="tab"
|
||||||
@@ -139,7 +135,6 @@ exports[`CarStatus Render 1`] = `
|
|||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
aria-controls="tabpanel-6"
|
aria-controls="tabpanel-6"
|
||||||
aria-selected="false"
|
|
||||||
class="MuiButtonBase-root MuiTab-root MuiTab-textColorInherit"
|
class="MuiButtonBase-root MuiTab-root MuiTab-textColorInherit"
|
||||||
id="tab-6"
|
id="tab-6"
|
||||||
role="tab"
|
role="tab"
|
||||||
@@ -217,23 +212,6 @@ exports[`CarStatus Render 1`] = `
|
|||||||
/>
|
/>
|
||||||
</svg>
|
</svg>
|
||||||
</a>
|
</a>
|
||||||
<a
|
|
||||||
class=""
|
|
||||||
href="/"
|
|
||||||
title="Delete \\"TESTVIN1234567890\\""
|
|
||||||
>
|
|
||||||
<svg
|
|
||||||
aria-hidden="true"
|
|
||||||
aria-label="Delete \\"TESTVIN1234567890\\""
|
|
||||||
class="MuiSvgIcon-root"
|
|
||||||
focusable="false"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
d="M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
</a>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div />
|
<div />
|
||||||
|
|||||||
@@ -1,19 +1,22 @@
|
|||||||
|
import { Box, Tab, Tabs } from "@material-ui/core";
|
||||||
|
import clsx from "clsx";
|
||||||
import React, { useEffect } from "react";
|
import React, { useEffect } from "react";
|
||||||
import { useParams } from "react-router";
|
import { useParams } from "react-router";
|
||||||
import { useLocation } from "react-router-dom";
|
import { useLocation } from "react-router-dom";
|
||||||
import clsx from "clsx";
|
|
||||||
import { Box, Tab, Tabs } from "@material-ui/core";
|
|
||||||
|
|
||||||
import CarDetailsTab from "./DetailsTab";
|
import { Permissions } from "../../../utils/roles";
|
||||||
import CarUpdatesTab from "./CarUpdatesTab";
|
|
||||||
import CANFiltersTab from "./CANFiltersTab";
|
|
||||||
import DigitalTwinTab from "./DigitalTwinTab";
|
|
||||||
import TabPanel from "../../Controls/TabPanel";
|
|
||||||
import { useStatusContext } from "../../Contexts/StatusContext";
|
import { useStatusContext } from "../../Contexts/StatusContext";
|
||||||
|
import { useUserContext } from "../../Contexts/UserContext";
|
||||||
|
import { RoleWrap } from "../../Controls/RoleWrap";
|
||||||
|
import TabPanel from "../../Controls/TabPanel";
|
||||||
import useStyles from "../../useStyles";
|
import useStyles from "../../useStyles";
|
||||||
|
import CANFiltersTab from "./CANFiltersTab";
|
||||||
import CANSignalsTab from "./CANSignalsTab";
|
import CANSignalsTab from "./CANSignalsTab";
|
||||||
import RemoteCommandsTab from "./RemoteCommandsTab";
|
import CarUpdatesTab from "./CarUpdatesTab";
|
||||||
|
import CarDetailsTab from "./DetailsTab";
|
||||||
|
import DigitalTwinTab from "./DigitalTwinTab";
|
||||||
import FleetsTab from "./FleetsTab";
|
import FleetsTab from "./FleetsTab";
|
||||||
|
import RemoteCommandsTab from "./RemoteCommandsTab";
|
||||||
|
|
||||||
const tabHashes = ["details", "updates", "filters"];
|
const tabHashes = ["details", "updates", "filters"];
|
||||||
|
|
||||||
@@ -24,6 +27,8 @@ const CarStatus = () => {
|
|||||||
const { hash } = useLocation();
|
const { hash } = useLocation();
|
||||||
const [tabIndex, setTabIndex] = React.useState(0);
|
const [tabIndex, setTabIndex] = React.useState(0);
|
||||||
|
|
||||||
|
const { groups, providers } = useUserContext();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const key = hash.replace("#", "");
|
const key = hash.replace("#", "");
|
||||||
const index = tabHashes.findIndex((element) => element === key);
|
const index = tabHashes.findIndex((element) => element === key);
|
||||||
@@ -63,12 +68,18 @@ const CarStatus = () => {
|
|||||||
>
|
>
|
||||||
<Tab label="Details" {...tabProps(0)} />
|
<Tab label="Details" {...tabProps(0)} />
|
||||||
<Tab label="Car Updates" {...tabProps(1)} />
|
<Tab label="Car Updates" {...tabProps(1)} />
|
||||||
<Tab label="CAN Filters" {...tabProps(2)} />
|
<RoleWrap
|
||||||
<Tab label="Digital Twin" {...tabProps(3)} />
|
groups={groups}
|
||||||
<Tab label="CAN Signals" {...tabProps(4)} />
|
providers={providers}
|
||||||
<Tab label="Remote Commands" {...tabProps(5)} />
|
rolesPerProvider={Permissions.FiskerRead}
|
||||||
<Tab label="Fleets" {...tabProps(6)} />
|
>
|
||||||
|
<Tab label="CAN Filters" {...tabProps(2)} />
|
||||||
|
<Tab label="Digital Twin" {...tabProps(3)} />
|
||||||
|
|
||||||
|
<Tab label="CAN Signals" {...tabProps(4)} />
|
||||||
|
<Tab label="Remote Commands" {...tabProps(5)} />
|
||||||
|
<Tab label="Fleets" {...tabProps(6)} />
|
||||||
|
</RoleWrap>
|
||||||
</Tabs>
|
</Tabs>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
@@ -80,25 +91,30 @@ const CarStatus = () => {
|
|||||||
<CarUpdatesTab />
|
<CarUpdatesTab />
|
||||||
</TabPanel>
|
</TabPanel>
|
||||||
|
|
||||||
<TabPanel value={tabIndex} index={2}>
|
<RoleWrap
|
||||||
<CANFiltersTab />
|
groups={groups}
|
||||||
</TabPanel>
|
providers={providers}
|
||||||
|
rolesPerProvider={Permissions.FiskerRead}
|
||||||
|
>
|
||||||
|
<TabPanel value={tabIndex} index={2}>
|
||||||
|
<CANFiltersTab />
|
||||||
|
</TabPanel>
|
||||||
|
<TabPanel value={tabIndex} index={3}>
|
||||||
|
<DigitalTwinTab vin={vin} />
|
||||||
|
</TabPanel>
|
||||||
|
|
||||||
<TabPanel value={tabIndex} index={3}>
|
<TabPanel value={tabIndex} index={4} className={classes.fullWidth}>
|
||||||
<DigitalTwinTab vin={vin} />
|
<CANSignalsTab vin={vin} />
|
||||||
</TabPanel>
|
</TabPanel>
|
||||||
|
|
||||||
<TabPanel value={tabIndex} index={4} className={classes.fullWidth}>
|
<TabPanel value={tabIndex} index={5} className={classes.fullWidth}>
|
||||||
<CANSignalsTab vin={vin} />
|
<RemoteCommandsTab vin={vin} />
|
||||||
</TabPanel>
|
</TabPanel>
|
||||||
|
|
||||||
<TabPanel value={tabIndex} index={5} className={classes.fullWidth}>
|
<TabPanel value={tabIndex} index={6} className={classes.fullWidth}>
|
||||||
<RemoteCommandsTab vin={vin} />
|
<FleetsTab vin={vin} />
|
||||||
</TabPanel>
|
</TabPanel>
|
||||||
|
</RoleWrap>
|
||||||
<TabPanel value={tabIndex} index={6} className={classes.fullWidth}>
|
|
||||||
<FleetsTab vin={vin} />
|
|
||||||
</TabPanel>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import routeData from "react-router";
|
|||||||
import { CANFiltersProvider } from "../../Contexts/CANFiltersContext";
|
import { CANFiltersProvider } from "../../Contexts/CANFiltersContext";
|
||||||
import { StatusProvider } from "../../Contexts/StatusContext";
|
import { StatusProvider } from "../../Contexts/StatusContext";
|
||||||
import { UserProvider, setToken } from "../../Contexts/UserContext";
|
import { UserProvider, setToken } from "../../Contexts/UserContext";
|
||||||
import { TEST_AUTH_OBJECT } from "../../../utils/testing";
|
import { TEST_AUTH_OBJECT_FISKER } from "../../../utils/testing";
|
||||||
import CarStatus from "./index";
|
import CarStatus from "./index";
|
||||||
import addSnapshotSerializer from "../../../utils/snapshot";
|
import addSnapshotSerializer from "../../../utils/snapshot";
|
||||||
|
|
||||||
@@ -45,7 +45,7 @@ describe("CarStatus", () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
it("Render", async () => {
|
it("Render", async () => {
|
||||||
setToken(TEST_AUTH_OBJECT);
|
setToken(TEST_AUTH_OBJECT_FISKER);
|
||||||
const container = await renderCarStatus();
|
const container = await renderCarStatus();
|
||||||
expect(container).toMatchSnapshot();
|
expect(container).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import { BrowserRouter } from "react-router-dom";
|
|||||||
import { VehicleProvider } from "../../Contexts/VehicleContext";
|
import { VehicleProvider } from "../../Contexts/VehicleContext";
|
||||||
import { StatusProvider } from "../../Contexts/StatusContext";
|
import { StatusProvider } from "../../Contexts/StatusContext";
|
||||||
import { UserProvider, setToken } from "../../Contexts/UserContext";
|
import { UserProvider, setToken } from "../../Contexts/UserContext";
|
||||||
import { TEST_AUTH_OBJECT } from "../../../utils/testing";
|
import { TEST_AUTH_OBJECT_FISKER } from "../../../utils/testing";
|
||||||
import MainForm from "./index";
|
import MainForm from "./index";
|
||||||
import addSnapshotSerializer from "../../../utils/snapshot";
|
import addSnapshotSerializer from "../../../utils/snapshot";
|
||||||
|
|
||||||
@@ -36,7 +36,7 @@ describe("VehicleUpdate", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("Render", async () => {
|
it("Render", async () => {
|
||||||
setToken(TEST_AUTH_OBJECT);
|
setToken(TEST_AUTH_OBJECT_FISKER);
|
||||||
const container = await renderVehicleUpdate();
|
const container = await renderVehicleUpdate();
|
||||||
expect(container).toMatchSnapshot();
|
expect(container).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import React, { useContext, useEffect, useState } from "react";
|
|||||||
import auth from "../../services/auth";
|
import auth from "../../services/auth";
|
||||||
import getTimerWorker from "../../services/getTimerWorker";
|
import getTimerWorker from "../../services/getTimerWorker";
|
||||||
import { parsePayload } from "../../utils/jwt";
|
import { parsePayload } from "../../utils/jwt";
|
||||||
import { getGroups } from "../../utils/roles";
|
import {getGroups, getProviders} from "../../utils/roles";
|
||||||
|
|
||||||
const UserContext = React.createContext();
|
const UserContext = React.createContext();
|
||||||
|
|
||||||
@@ -10,6 +10,7 @@ export const UserProvider = ({ children }) => {
|
|||||||
const [fetching, setFetching] = useState(false);
|
const [fetching, setFetching] = useState(false);
|
||||||
const [token, setToken] = useState(null);
|
const [token, setToken] = useState(null);
|
||||||
const [groups, setGroups] = useState(null);
|
const [groups, setGroups] = useState(null);
|
||||||
|
const [providers, setProviders] = useState(null);
|
||||||
const [error, setError] = useState(null);
|
const [error, setError] = useState(null);
|
||||||
let timer;
|
let timer;
|
||||||
|
|
||||||
@@ -73,6 +74,7 @@ export const UserProvider = ({ children }) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
setGroups(getGroups(idToken));
|
setGroups(getGroups(idToken));
|
||||||
|
setProviders(getProviders(idToken));
|
||||||
startSessionTimer();
|
startSessionTimer();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
setError(`Verify error. ${e.message}`);
|
setError(`Verify error. ${e.message}`);
|
||||||
@@ -106,6 +108,7 @@ export const UserProvider = ({ children }) => {
|
|||||||
|
|
||||||
const signOut = () => {
|
const signOut = () => {
|
||||||
setGroups(null);
|
setGroups(null);
|
||||||
|
setProviders(null);
|
||||||
setToken(null);
|
setToken(null);
|
||||||
if (localStorage) {
|
if (localStorage) {
|
||||||
localStorage.removeItem("token");
|
localStorage.removeItem("token");
|
||||||
@@ -153,6 +156,7 @@ export const UserProvider = ({ children }) => {
|
|||||||
error,
|
error,
|
||||||
fetching,
|
fetching,
|
||||||
groups,
|
groups,
|
||||||
|
providers,
|
||||||
token,
|
token,
|
||||||
getAuthorizeURL,
|
getAuthorizeURL,
|
||||||
getLogoutURL,
|
getLogoutURL,
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
|
|
||||||
import { getGroups } from "../../../utils/roles";
|
import {getGroups, getProviders} from "../../../utils/roles";
|
||||||
|
|
||||||
let token = null;
|
let token = null;
|
||||||
let groups = null;
|
let groups = null;
|
||||||
|
let providers = null;
|
||||||
let fetching = false;
|
let fetching = false;
|
||||||
let error = null;
|
let error = null;
|
||||||
let signInResp = {};
|
let signInResp = {};
|
||||||
@@ -20,6 +21,7 @@ export const useUserContext = () => ({
|
|||||||
error,
|
error,
|
||||||
fetching,
|
fetching,
|
||||||
groups,
|
groups,
|
||||||
|
providers,
|
||||||
token,
|
token,
|
||||||
getAuthorizeURL: jest.fn(() => authorizeURL),
|
getAuthorizeURL: jest.fn(() => authorizeURL),
|
||||||
getLogoutURL: jest.fn(() => logoutURL),
|
getLogoutURL: jest.fn(() => logoutURL),
|
||||||
@@ -35,8 +37,10 @@ export const setToken = (val) => {
|
|||||||
token = val;
|
token = val;
|
||||||
if (!val || !val.idToken || !val.idToken.jwtToken) {
|
if (!val || !val.idToken || !val.idToken.jwtToken) {
|
||||||
groups = null;
|
groups = null;
|
||||||
|
providers = null
|
||||||
} else {
|
} else {
|
||||||
groups = getGroups(val.idToken.jwtToken);
|
groups = getGroups(val.idToken.jwtToken);
|
||||||
|
providers = getProviders(val.idToken.jwtToken);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -6,14 +6,14 @@ import { render, waitFor } from "@testing-library/react";
|
|||||||
import { CarUpdatesProvider } from "../../Contexts/CarUpdatesContext";
|
import { CarUpdatesProvider } from "../../Contexts/CarUpdatesContext";
|
||||||
import CarUpdateStatusTable from "../CarUpdateStatusTable";
|
import CarUpdateStatusTable from "../CarUpdateStatusTable";
|
||||||
import { StatusProvider } from "../../Contexts/StatusContext";
|
import { StatusProvider } from "../../Contexts/StatusContext";
|
||||||
import { TEST_AUTH_OBJECT } from "../../../utils/testing";
|
import { TEST_AUTH_OBJECT_FISKER } from "../../../utils/testing";
|
||||||
import addSnapshotSerializer from "../../../utils/snapshot";
|
import addSnapshotSerializer from "../../../utils/snapshot";
|
||||||
|
|
||||||
const renderCarUpdateStatusTable = async () => {
|
const renderCarUpdateStatusTable = async () => {
|
||||||
const { container } = render(
|
const { container } = render(
|
||||||
<StatusProvider>
|
<StatusProvider>
|
||||||
<CarUpdatesProvider>
|
<CarUpdatesProvider>
|
||||||
<CarUpdateStatusTable carupdateid={283} token={TEST_AUTH_OBJECT} />
|
<CarUpdateStatusTable carupdateid={283} token={TEST_AUTH_OBJECT_FISKER} />
|
||||||
</CarUpdatesProvider>
|
</CarUpdatesProvider>
|
||||||
</StatusProvider>
|
</StatusProvider>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
import React, { useEffect, useState } from "react";
|
|
||||||
import {
|
import {
|
||||||
LinearProgress,
|
LinearProgress,
|
||||||
Table,
|
Table,
|
||||||
@@ -9,19 +8,22 @@ import {
|
|||||||
TableRow,
|
TableRow,
|
||||||
Tooltip,
|
Tooltip,
|
||||||
} from "@material-ui/core";
|
} from "@material-ui/core";
|
||||||
import { Link } from "react-router-dom";
|
|
||||||
import CancelIcon from "@material-ui/icons/Cancel";
|
import CancelIcon from "@material-ui/icons/Cancel";
|
||||||
|
import React, { useEffect, useState } from "react";
|
||||||
|
import { Link } from "react-router-dom";
|
||||||
|
|
||||||
|
import { logger } from "../../../services/monitoring";
|
||||||
import { LocalDateTimeString } from "../../../utils/dates";
|
import { LocalDateTimeString } from "../../../utils/dates";
|
||||||
import TableHeaderSortable from "../../Table/HeaderSortable";
|
|
||||||
import {
|
import {
|
||||||
CarUpdatesProvider,
|
CarUpdatesProvider,
|
||||||
useCarUpdatesContext,
|
useCarUpdatesContext,
|
||||||
} from "../../Contexts/CarUpdatesContext";
|
} from "../../Contexts/CarUpdatesContext";
|
||||||
import { useStatusContext } from "../../Contexts/StatusContext";
|
import { useStatusContext } from "../../Contexts/StatusContext";
|
||||||
import useStyles from "../../useStyles";
|
import { useUserContext } from "../../Contexts/UserContext";
|
||||||
import { logger } from "../../../services/monitoring";
|
import TableHeaderSortable from "../../Table/HeaderSortable";
|
||||||
import { useLocalStorage } from "../../useLocalStorage";
|
import { useLocalStorage } from "../../useLocalStorage";
|
||||||
|
import useStyles from "../../useStyles";
|
||||||
|
import { RoleWrap } from "../RoleWrap";
|
||||||
|
|
||||||
const tableColumns = [
|
const tableColumns = [
|
||||||
{
|
{
|
||||||
@@ -68,6 +70,8 @@ const MainForm = ({ vin, token }) => {
|
|||||||
} = useCarUpdatesContext();
|
} = useCarUpdatesContext();
|
||||||
const { setMessage } = useStatusContext();
|
const { setMessage } = useStatusContext();
|
||||||
|
|
||||||
|
const { groups, providers } = useUserContext();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
(async () => {
|
(async () => {
|
||||||
try {
|
try {
|
||||||
@@ -176,11 +180,17 @@ const MainForm = ({ vin, token }) => {
|
|||||||
{LocalDateTimeString(row.updated)}
|
{LocalDateTimeString(row.updated)}
|
||||||
</TableCell>
|
</TableCell>
|
||||||
<TableCell>
|
<TableCell>
|
||||||
<Tooltip key={row.vin} title={`Send cancel for ${row.vin}`}>
|
<RoleWrap
|
||||||
<Link to="#" onClick={() => sendCancel(row)}>
|
groups={groups}
|
||||||
<CancelIcon />
|
providers={providers}
|
||||||
</Link>
|
rolesPerProvider={Permissions.FiskerCreate}
|
||||||
</Tooltip>
|
>
|
||||||
|
<Tooltip key={row.vin} title={`Send cancel for ${row.vin}`}>
|
||||||
|
<Link to="#" onClick={() => sendCancel(row)}>
|
||||||
|
<CancelIcon />
|
||||||
|
</Link>
|
||||||
|
</Tooltip>
|
||||||
|
</RoleWrap>
|
||||||
</TableCell>
|
</TableCell>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
))}
|
))}
|
||||||
|
|||||||
@@ -0,0 +1,23 @@
|
|||||||
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
|
exports[`RoleWrap RoleWrap with access, child renders 1`] = `
|
||||||
|
<div>
|
||||||
|
<div
|
||||||
|
data-testid="test-role-wrap-child"
|
||||||
|
>
|
||||||
|
Test
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`RoleWrap RoleWrap without access, child does not render 1`] = `<div />`;
|
||||||
|
|
||||||
|
exports[`RoleWrap RoleWrap without access, eitherComponent renders 1`] = `
|
||||||
|
<div>
|
||||||
|
<div
|
||||||
|
data-testid="test-role-wrap-child"
|
||||||
|
>
|
||||||
|
Either
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
19
src/components/Controls/RoleWrap/index.js
Normal file
19
src/components/Controls/RoleWrap/index.js
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
import {hasRole} from "../../../utils/roles";
|
||||||
|
import React from "react";
|
||||||
|
|
||||||
|
export const RoleWrap = (props) => {
|
||||||
|
const {groups, rolesPerProvider, providers} = props;
|
||||||
|
|
||||||
|
const eitherComponent = props["eitherComponent"] || null;
|
||||||
|
|
||||||
|
if (!hasRole(groups, rolesPerProvider, providers)) {
|
||||||
|
return eitherComponent != null ? eitherComponent : <></>;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<React.Fragment>
|
||||||
|
{props.children}
|
||||||
|
</React.Fragment>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
70
src/components/Controls/RoleWrap/index.test.js
Normal file
70
src/components/Controls/RoleWrap/index.test.js
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
import { render, screen } from "@testing-library/react";
|
||||||
|
import { Permissions, Providers, Roles } from "../../../utils/roles";
|
||||||
|
import addSnapshotSerializer from "../../../utils/snapshot";
|
||||||
|
import { RoleWrap } from "./index";
|
||||||
|
|
||||||
|
const selector = "test-role-wrap-child";
|
||||||
|
|
||||||
|
const renderRoleWrap = async (
|
||||||
|
groups,
|
||||||
|
providers,
|
||||||
|
rolesPerProvider,
|
||||||
|
eitherComponent
|
||||||
|
) => {
|
||||||
|
const { container } = render(
|
||||||
|
<RoleWrap
|
||||||
|
groups={groups}
|
||||||
|
providers={providers}
|
||||||
|
rolesPerProvider={rolesPerProvider}
|
||||||
|
eitherComponent={eitherComponent}
|
||||||
|
>
|
||||||
|
<div data-testid={selector}>Test</div>
|
||||||
|
</RoleWrap>
|
||||||
|
);
|
||||||
|
return container;
|
||||||
|
};
|
||||||
|
|
||||||
|
describe("RoleWrap", () => {
|
||||||
|
beforeAll(() => {
|
||||||
|
addSnapshotSerializer(expect);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("RoleWrap with access, child renders", async () => {
|
||||||
|
const view = await renderRoleWrap(
|
||||||
|
[Roles.READ],
|
||||||
|
[Providers.FISKER],
|
||||||
|
Permissions.FiskerRead,
|
||||||
|
null
|
||||||
|
);
|
||||||
|
const childComponent = screen.getByTestId(selector);
|
||||||
|
expect(childComponent).toHaveTextContent("Test");
|
||||||
|
|
||||||
|
expect(view).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("RoleWrap without access, child does not render", async () => {
|
||||||
|
const view = await renderRoleWrap(
|
||||||
|
[Roles.READ],
|
||||||
|
[Providers.FISKER],
|
||||||
|
Permissions.FiskerCreate,
|
||||||
|
null
|
||||||
|
);
|
||||||
|
const childComponent = screen.queryByTestId(selector);
|
||||||
|
expect(childComponent).toBeNull();
|
||||||
|
|
||||||
|
expect(view).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("RoleWrap without access, eitherComponent renders", async () => {
|
||||||
|
const view = await renderRoleWrap(
|
||||||
|
[Roles.READ],
|
||||||
|
[Providers.FISKER],
|
||||||
|
Permissions.FiskerCreate,
|
||||||
|
<div data-testid={selector}>Either</div>
|
||||||
|
);
|
||||||
|
const childComponent = screen.getByTestId(selector);
|
||||||
|
expect(childComponent).toHaveTextContent("Either");
|
||||||
|
|
||||||
|
expect(view).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -8,7 +8,7 @@ import { BrowserRouter } from "react-router-dom";
|
|||||||
import { FleetProvider } from "../../Contexts/FleetContext";
|
import { FleetProvider } from "../../Contexts/FleetContext";
|
||||||
import { StatusProvider } from "../../Contexts/StatusContext";
|
import { StatusProvider } from "../../Contexts/StatusContext";
|
||||||
import { UserProvider, setToken } from "../../Contexts/UserContext";
|
import { UserProvider, setToken } from "../../Contexts/UserContext";
|
||||||
import { TEST_AUTH_OBJECT } from "../../../utils/testing";
|
import { TEST_AUTH_OBJECT_FISKER } from "../../../utils/testing";
|
||||||
import MainForm from "./index";
|
import MainForm from "./index";
|
||||||
import addSnapshotSerializer from "../../../utils/snapshot";
|
import addSnapshotSerializer from "../../../utils/snapshot";
|
||||||
|
|
||||||
@@ -36,7 +36,7 @@ describe("FleetAddForm", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("Render", async () => {
|
it("Render", async () => {
|
||||||
setToken(TEST_AUTH_OBJECT);
|
setToken(TEST_AUTH_OBJECT_FISKER);
|
||||||
const container = await renderFleetAdd();
|
const container = await renderFleetAdd();
|
||||||
expect(container).toMatchSnapshot();
|
expect(container).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import { BrowserRouter } from "react-router-dom";
|
|||||||
import { FleetProvider } from "../../../../Contexts/FleetContext";
|
import { FleetProvider } from "../../../../Contexts/FleetContext";
|
||||||
import { StatusProvider } from "../../../../Contexts/StatusContext";
|
import { StatusProvider } from "../../../../Contexts/StatusContext";
|
||||||
import { UserProvider, setToken } from "../../../../Contexts/UserContext";
|
import { UserProvider, setToken } from "../../../../Contexts/UserContext";
|
||||||
import { TEST_AUTH_OBJECT } from "../../../../../utils/testing";
|
import { TEST_AUTH_OBJECT_FISKER }from "../../../../../utils/testing";
|
||||||
import MainForm from "./index";
|
import MainForm from "./index";
|
||||||
import addSnapshotSerializer from "../../../../../utils/snapshot";
|
import addSnapshotSerializer from "../../../../../utils/snapshot";
|
||||||
|
|
||||||
@@ -34,7 +34,7 @@ describe("FleetCANFilterAdd", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("Render", async () => {
|
it("Render", async () => {
|
||||||
setToken(TEST_AUTH_OBJECT);
|
setToken(TEST_AUTH_OBJECT_FISKER);
|
||||||
const container = await renderFleetCANFilterAdd();
|
const container = await renderFleetCANFilterAdd();
|
||||||
expect(container).toMatchSnapshot();
|
expect(container).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -221,23 +221,6 @@ exports[`FleetCANFiltersTable Render 1`] = `
|
|||||||
/>
|
/>
|
||||||
</svg>
|
</svg>
|
||||||
</a>
|
</a>
|
||||||
<a
|
|
||||||
class=""
|
|
||||||
href="/"
|
|
||||||
title="Delete \\"123-456\\""
|
|
||||||
>
|
|
||||||
<svg
|
|
||||||
aria-hidden="true"
|
|
||||||
aria-label="Delete 123-456"
|
|
||||||
class="MuiSvgIcon-root"
|
|
||||||
focusable="false"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
d="M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
</a>
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr
|
<tr
|
||||||
@@ -277,23 +260,6 @@ exports[`FleetCANFiltersTable Render 1`] = `
|
|||||||
/>
|
/>
|
||||||
</svg>
|
</svg>
|
||||||
</a>
|
</a>
|
||||||
<a
|
|
||||||
class=""
|
|
||||||
href="/"
|
|
||||||
title="Delete \\"1\\""
|
|
||||||
>
|
|
||||||
<svg
|
|
||||||
aria-hidden="true"
|
|
||||||
aria-label="Delete 1"
|
|
||||||
class="MuiSvgIcon-root"
|
|
||||||
focusable="false"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
d="M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
</a>
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr
|
<tr
|
||||||
@@ -333,23 +299,6 @@ exports[`FleetCANFiltersTable Render 1`] = `
|
|||||||
/>
|
/>
|
||||||
</svg>
|
</svg>
|
||||||
</a>
|
</a>
|
||||||
<a
|
|
||||||
class=""
|
|
||||||
href="/"
|
|
||||||
title="Delete \\"1000\\""
|
|
||||||
>
|
|
||||||
<svg
|
|
||||||
aria-hidden="true"
|
|
||||||
aria-label="Delete 1000"
|
|
||||||
class="MuiSvgIcon-root"
|
|
||||||
focusable="false"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
d="M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
</a>
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
import React, { useEffect, useState } from "react";
|
|
||||||
import { Link } from 'react-router-dom';
|
|
||||||
import {
|
import {
|
||||||
Grid,
|
Grid,
|
||||||
Table,
|
Table,
|
||||||
@@ -12,37 +10,42 @@ import {
|
|||||||
} from "@material-ui/core";
|
} from "@material-ui/core";
|
||||||
import AddCircleIcon from "@material-ui/icons/AddCircle";
|
import AddCircleIcon from "@material-ui/icons/AddCircle";
|
||||||
import DeleteIcon from "@material-ui/icons/Delete";
|
import DeleteIcon from "@material-ui/icons/Delete";
|
||||||
import EditIcon from '@material-ui/icons/Edit';
|
import EditIcon from "@material-ui/icons/Edit";
|
||||||
import clsx from "clsx";
|
import clsx from "clsx";
|
||||||
|
import React, { useEffect, useState } from "react";
|
||||||
|
import { Link } from "react-router-dom";
|
||||||
|
|
||||||
import TableHeaderSortable from "../../../../Table/HeaderSortable";
|
|
||||||
import { useUserContext } from "../../../../Contexts/UserContext"
|
|
||||||
import { useStatusContext } from "../../../../Contexts/StatusContext";
|
|
||||||
import { FleetProvider, useFleetContext } from "../../../../Contexts/FleetContext"
|
|
||||||
import useStyles from "../../../../useStyles";
|
|
||||||
import SearchField from "../../../../Controls/SearchField";
|
|
||||||
import { logger } from "../../../../../services/monitoring";
|
import { logger } from "../../../../../services/monitoring";
|
||||||
import { Roles, hasRole } from "../../../../../utils/roles";
|
import { hasRole, Permissions } from "../../../../../utils/roles";
|
||||||
import {useLocalStorage} from "../../../../useLocalStorage";
|
import { trimIfMoreThan } from "../../../../../utils/strings";
|
||||||
import {trimIfMoreThan} from "../../../../../utils/strings"
|
import {
|
||||||
|
FleetProvider,
|
||||||
|
useFleetContext,
|
||||||
|
} from "../../../../Contexts/FleetContext";
|
||||||
|
import { useStatusContext } from "../../../../Contexts/StatusContext";
|
||||||
|
import { useUserContext } from "../../../../Contexts/UserContext";
|
||||||
|
import SearchField from "../../../../Controls/SearchField";
|
||||||
|
import TableHeaderSortable from "../../../../Table/HeaderSortable";
|
||||||
|
import { useLocalStorage } from "../../../../useLocalStorage";
|
||||||
|
import useStyles from "../../../../useStyles";
|
||||||
|
|
||||||
const tableColumns = [
|
const tableColumns = [
|
||||||
{
|
{
|
||||||
id: "can_id",
|
id: "can_id",
|
||||||
label: "CAN ID"
|
label: "CAN ID",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: "interval",
|
id: "interval",
|
||||||
label: "Interval (ms)"
|
label: "Interval (ms)",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: "edge_mask",
|
id: "edge_mask",
|
||||||
label: "Edge mask"
|
label: "Edge mask",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: "",
|
id: "",
|
||||||
label: "Actions"
|
label: "Actions",
|
||||||
}
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
const PAGE_SIZE = "FLEET_STATUS_CAN_FILTER_TABLE_PAGE_SIZE";
|
const PAGE_SIZE = "FLEET_STATUS_CAN_FILTER_TABLE_PAGE_SIZE";
|
||||||
@@ -54,8 +57,19 @@ const MainForm = ({ name }) => {
|
|||||||
const [order, setOrder] = useState("desc");
|
const [order, setOrder] = useState("desc");
|
||||||
const classes = useStyles();
|
const classes = useStyles();
|
||||||
const { setMessage } = useStatusContext();
|
const { setMessage } = useStatusContext();
|
||||||
const { fleetCANFilters, totalFleetCANFilters, getFleetCANFilters, deleteFleetCANFilter } = useFleetContext();
|
const {
|
||||||
const { token: { idToken: { jwtToken: token } }, groups } = useUserContext();
|
fleetCANFilters,
|
||||||
|
totalFleetCANFilters,
|
||||||
|
getFleetCANFilters,
|
||||||
|
deleteFleetCANFilter,
|
||||||
|
} = useFleetContext();
|
||||||
|
const {
|
||||||
|
token: {
|
||||||
|
idToken: { jwtToken: token },
|
||||||
|
},
|
||||||
|
groups,
|
||||||
|
providers,
|
||||||
|
} = useUserContext();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
(async () => {
|
(async () => {
|
||||||
@@ -107,7 +121,7 @@ const MainForm = ({ name }) => {
|
|||||||
const onDelete = async (can_id) => {
|
const onDelete = async (can_id) => {
|
||||||
try {
|
try {
|
||||||
await deleteFleetCANFilter(name, can_id, token);
|
await deleteFleetCANFilter(name, can_id, token);
|
||||||
setMessage(`Deleted ${can_id}`)
|
setMessage(`Deleted ${can_id}`);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
setMessage(e.message);
|
setMessage(e.message);
|
||||||
logger.warn(e.stack);
|
logger.warn(e.stack);
|
||||||
@@ -116,19 +130,19 @@ const MainForm = ({ name }) => {
|
|||||||
|
|
||||||
const Actions = (row) => {
|
const Actions = (row) => {
|
||||||
let actions = [];
|
let actions = [];
|
||||||
if (hasRole([Roles.CREATE], groups)) {
|
if (hasRole(groups, Permissions.FiskerCreate, providers)) {
|
||||||
actions.push({
|
actions.push({
|
||||||
tip: `Update "${row.can_id}"`,
|
tip: `Update "${row.can_id}"`,
|
||||||
link: `/fleet/${name}/filter-update?name=${name}&can_id=${row.can_id}&interval=${row.interval}`,
|
link: `/fleet/${name}/filter-update?name=${name}&can_id=${row.can_id}&interval=${row.interval}`,
|
||||||
icon: <EditIcon aria-label={`Update ${row.can_id}`} />
|
icon: <EditIcon aria-label={`Update ${row.can_id}`} />,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (hasRole([Roles.DELETE], groups)) {
|
if (hasRole(groups, Permissions.FiskerDelete, providers)) {
|
||||||
actions.push({
|
actions.push({
|
||||||
tip: `Delete "${row.can_id}"`,
|
tip: `Delete "${row.can_id}"`,
|
||||||
id: row.can_id,
|
id: row.can_id,
|
||||||
icon: <DeleteIcon aria-label={`Delete ${row.can_id}`} />
|
icon: <DeleteIcon aria-label={`Delete ${row.can_id}`} />,
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
if (actions.length === 0) return ["No actions"];
|
if (actions.length === 0) return ["No actions"];
|
||||||
|
|
||||||
@@ -157,7 +171,10 @@ const MainForm = ({ name }) => {
|
|||||||
<div className={clsx(classes.paper, classes.tableSize)}>
|
<div className={clsx(classes.paper, classes.tableSize)}>
|
||||||
<Grid container className={classes.root} spacing={2}>
|
<Grid container className={classes.root} spacing={2}>
|
||||||
<Grid item md={4} className={classes.textJustifyAlign}>
|
<Grid item md={4} className={classes.textJustifyAlign}>
|
||||||
<Link to={`/fleet/${name}/filter-add`} className={classes.labelInline}>
|
<Link
|
||||||
|
to={`/fleet/${name}/filter-add`}
|
||||||
|
className={classes.labelInline}
|
||||||
|
>
|
||||||
<AddCircleIcon fontSize="large" />
|
<AddCircleIcon fontSize="large" />
|
||||||
</Link>
|
</Link>
|
||||||
</Grid>
|
</Grid>
|
||||||
@@ -174,11 +191,13 @@ const MainForm = ({ name }) => {
|
|||||||
onSortRequest={handleSort}
|
onSortRequest={handleSort}
|
||||||
/>
|
/>
|
||||||
<TableBody>
|
<TableBody>
|
||||||
{fleetCANFilters.map(row => (
|
{fleetCANFilters.map((row) => (
|
||||||
<TableRow key={row.can_id}>
|
<TableRow key={row.can_id}>
|
||||||
<TableCell align="center">{row.can_id}</TableCell>
|
<TableCell align="center">{row.can_id}</TableCell>
|
||||||
<TableCell align="center">{row.interval}</TableCell>
|
<TableCell align="center">{row.interval}</TableCell>
|
||||||
<TableCell align="center">{trimIfMoreThan(row.edge_mask, 15, "...")}</TableCell>
|
<TableCell align="center">
|
||||||
|
{trimIfMoreThan(row.edge_mask, 15, "...")}
|
||||||
|
</TableCell>
|
||||||
<TableCell align="center">{Actions(row)}</TableCell>
|
<TableCell align="center">{Actions(row)}</TableCell>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
))}
|
))}
|
||||||
@@ -201,7 +220,7 @@ const MainForm = ({ name }) => {
|
|||||||
</TableRow>
|
</TableRow>
|
||||||
</TableFooter>
|
</TableFooter>
|
||||||
</Table>
|
</Table>
|
||||||
</div >
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import { BrowserRouter } from "react-router-dom";
|
|||||||
import { FleetProvider } from "../../../../Contexts/FleetContext";
|
import { FleetProvider } from "../../../../Contexts/FleetContext";
|
||||||
import { StatusProvider } from "../../../../Contexts/StatusContext";
|
import { StatusProvider } from "../../../../Contexts/StatusContext";
|
||||||
import { UserProvider, setToken } from "../../../../Contexts/UserContext";
|
import { UserProvider, setToken } from "../../../../Contexts/UserContext";
|
||||||
import { TEST_AUTH_OBJECT } from "../../../../../utils/testing";
|
import { TEST_AUTH_OBJECT_FISKER }from "../../../../../utils/testing";
|
||||||
import MainForm from "./index";
|
import MainForm from "./index";
|
||||||
import addSnapshotSerializer from "../../../../../utils/snapshot";
|
import addSnapshotSerializer from "../../../../../utils/snapshot";
|
||||||
|
|
||||||
@@ -37,7 +37,7 @@ describe("FleetCANFiltersTable", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("Render", async () => {
|
it("Render", async () => {
|
||||||
setToken(TEST_AUTH_OBJECT);
|
setToken(TEST_AUTH_OBJECT_FISKER);
|
||||||
const container = await renderFleetCANFiltersTable();
|
const container = await renderFleetCANFiltersTable();
|
||||||
expect(container).toMatchSnapshot();
|
expect(container).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import { BrowserRouter } from "react-router-dom";
|
|||||||
import { FleetProvider } from "../../../../Contexts/FleetContext";
|
import { FleetProvider } from "../../../../Contexts/FleetContext";
|
||||||
import { StatusProvider } from "../../../../Contexts/StatusContext";
|
import { StatusProvider } from "../../../../Contexts/StatusContext";
|
||||||
import { UserProvider, setToken } from "../../../../Contexts/UserContext";
|
import { UserProvider, setToken } from "../../../../Contexts/UserContext";
|
||||||
import { TEST_AUTH_OBJECT } from "../../../../../utils/testing";
|
import { TEST_AUTH_OBJECT_FISKER } from "../../../../../utils/testing";
|
||||||
import MainForm from "./index";
|
import MainForm from "./index";
|
||||||
import addSnapshotSerializer from "../../../../../utils/snapshot";
|
import addSnapshotSerializer from "../../../../../utils/snapshot";
|
||||||
|
|
||||||
@@ -34,7 +34,7 @@ describe("FleetCANFilterUpdate", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("Render", async () => {
|
it("Render", async () => {
|
||||||
setToken(TEST_AUTH_OBJECT);
|
setToken(TEST_AUTH_OBJECT_FISKER);
|
||||||
const container = await renderFleetCANFilterUpdate();
|
const container = await renderFleetCANFilterUpdate();
|
||||||
expect(container).toMatchSnapshot();
|
expect(container).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import { render, waitFor } from "@testing-library/react";
|
|||||||
import { BrowserRouter } from "react-router-dom";
|
import { BrowserRouter } from "react-router-dom";
|
||||||
|
|
||||||
import { setToken } from "../../Contexts/UserContext";
|
import { setToken } from "../../Contexts/UserContext";
|
||||||
import { TEST_AUTH_OBJECT } from "../../../utils/testing";
|
import { TEST_AUTH_OBJECT_FISKER } from "../../../utils/testing";
|
||||||
import CANFiltersTab from "./CANFiltersTab";
|
import CANFiltersTab from "./CANFiltersTab";
|
||||||
import addSnapshotSerializer from "../../../utils/snapshot";
|
import addSnapshotSerializer from "../../../utils/snapshot";
|
||||||
|
|
||||||
@@ -31,7 +31,7 @@ describe("CANFiltersTab", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("Render", async () => {
|
it("Render", async () => {
|
||||||
setToken(TEST_AUTH_OBJECT);
|
setToken(TEST_AUTH_OBJECT_FISKER);
|
||||||
const container = await renderCANFitlersTab();
|
const container = await renderCANFitlersTab();
|
||||||
expect(container).toMatchSnapshot();
|
expect(container).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import routeData from "react-router";
|
|||||||
import { FleetProvider } from "../../../Contexts/FleetContext";
|
import { FleetProvider } from "../../../Contexts/FleetContext";
|
||||||
import { StatusProvider } from "../../../Contexts/StatusContext";
|
import { StatusProvider } from "../../../Contexts/StatusContext";
|
||||||
import { UserProvider, setToken } from "../../../Contexts/UserContext";
|
import { UserProvider, setToken } from "../../../Contexts/UserContext";
|
||||||
import { TEST_AUTH_OBJECT } from "../../../../utils/testing";
|
import { TEST_AUTH_OBJECT_FISKER }from "../../../../utils/testing";
|
||||||
import MainForm from "./index";
|
import MainForm from "./index";
|
||||||
import addSnapshotSerializer from "../../../../utils/snapshot";
|
import addSnapshotSerializer from "../../../../utils/snapshot";
|
||||||
|
|
||||||
@@ -42,7 +42,7 @@ describe("FleetDetailsTab", () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
it("Render", async () => {
|
it("Render", async () => {
|
||||||
setToken(TEST_AUTH_OBJECT);
|
setToken(TEST_AUTH_OBJECT_FISKER);
|
||||||
const container = await renderFleetDetailsTab();
|
const container = await renderFleetDetailsTab();
|
||||||
expect(container).toMatchSnapshot();
|
expect(container).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import { MemoryRouter, Route } from "react-router-dom";
|
|||||||
import { FleetProvider } from "../../Contexts/FleetContext";
|
import { FleetProvider } from "../../Contexts/FleetContext";
|
||||||
import { StatusProvider } from "../../Contexts/StatusContext";
|
import { StatusProvider } from "../../Contexts/StatusContext";
|
||||||
import { UserProvider, setToken } from "../../Contexts/UserContext";
|
import { UserProvider, setToken } from "../../Contexts/UserContext";
|
||||||
import { TEST_AUTH_OBJECT } from "../../../utils/testing";
|
import { TEST_AUTH_OBJECT_FISKER } from "../../../utils/testing";
|
||||||
import MainForm from "./DetailsTab";
|
import MainForm from "./DetailsTab";
|
||||||
import addSnapshotSerializer from "../../../utils/snapshot";
|
import addSnapshotSerializer from "../../../utils/snapshot";
|
||||||
|
|
||||||
@@ -41,7 +41,7 @@ describe("DetailsTab", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("Render", async () => {
|
it("Render", async () => {
|
||||||
setToken(TEST_AUTH_OBJECT);
|
setToken(TEST_AUTH_OBJECT_FISKER);
|
||||||
const container = await renderDetailsTab();
|
const container = await renderDetailsTab();
|
||||||
expect(container).toMatchSnapshot();
|
expect(container).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import { BrowserRouter } from "react-router-dom";
|
|||||||
import { FleetProvider } from "../../../../Contexts/FleetContext";
|
import { FleetProvider } from "../../../../Contexts/FleetContext";
|
||||||
import { StatusProvider } from "../../../../Contexts/StatusContext";
|
import { StatusProvider } from "../../../../Contexts/StatusContext";
|
||||||
import { UserProvider, setToken } from "../../../../Contexts/UserContext";
|
import { UserProvider, setToken } from "../../../../Contexts/UserContext";
|
||||||
import { TEST_AUTH_OBJECT } from "../../../../../utils/testing";
|
import { TEST_AUTH_OBJECT_FISKER }from "../../../../../utils/testing";
|
||||||
import MainForm from "./index";
|
import MainForm from "./index";
|
||||||
import addSnapshotSerializer from "../../../../../utils/snapshot";
|
import addSnapshotSerializer from "../../../../../utils/snapshot";
|
||||||
|
|
||||||
@@ -36,7 +36,7 @@ describe("FleetVehicleAdd", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("Render", async () => {
|
it("Render", async () => {
|
||||||
setToken(TEST_AUTH_OBJECT);
|
setToken(TEST_AUTH_OBJECT_FISKER);
|
||||||
const container = await renderFleetVehicleAdd();
|
const container = await renderFleetVehicleAdd();
|
||||||
expect(container).toMatchSnapshot();
|
expect(container).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -153,26 +153,7 @@ exports[`FleetVehiclesTable Render 1`] = `
|
|||||||
<td
|
<td
|
||||||
class="MuiTableCell-root MuiTableCell-body MuiTableCell-alignCenter"
|
class="MuiTableCell-root MuiTableCell-body MuiTableCell-alignCenter"
|
||||||
>
|
>
|
||||||
<span>
|
No actions
|
||||||
<a
|
|
||||||
class=""
|
|
||||||
href="/"
|
|
||||||
title="Delete \\"USWESTVIN12345678\\""
|
|
||||||
>
|
|
||||||
<svg
|
|
||||||
aria-hidden="true"
|
|
||||||
aria-label="Delete USWESTVIN12345678"
|
|
||||||
class="MuiSvgIcon-root"
|
|
||||||
focusable="false"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
d="M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
</a>
|
|
||||||
<div />
|
|
||||||
</span>
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr
|
<tr
|
||||||
@@ -190,26 +171,7 @@ exports[`FleetVehiclesTable Render 1`] = `
|
|||||||
<td
|
<td
|
||||||
class="MuiTableCell-root MuiTableCell-body MuiTableCell-alignCenter"
|
class="MuiTableCell-root MuiTableCell-body MuiTableCell-alignCenter"
|
||||||
>
|
>
|
||||||
<span>
|
No actions
|
||||||
<a
|
|
||||||
class=""
|
|
||||||
href="/"
|
|
||||||
title="Delete \\"USWESTVIN12345679\\""
|
|
||||||
>
|
|
||||||
<svg
|
|
||||||
aria-hidden="true"
|
|
||||||
aria-label="Delete USWESTVIN12345679"
|
|
||||||
class="MuiSvgIcon-root"
|
|
||||||
focusable="false"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
d="M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
</a>
|
|
||||||
<div />
|
|
||||||
</span>
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr
|
<tr
|
||||||
@@ -227,26 +189,7 @@ exports[`FleetVehiclesTable Render 1`] = `
|
|||||||
<td
|
<td
|
||||||
class="MuiTableCell-root MuiTableCell-body MuiTableCell-alignCenter"
|
class="MuiTableCell-root MuiTableCell-body MuiTableCell-alignCenter"
|
||||||
>
|
>
|
||||||
<span>
|
No actions
|
||||||
<a
|
|
||||||
class=""
|
|
||||||
href="/"
|
|
||||||
title="Delete \\"USWESTVIN12345670\\""
|
|
||||||
>
|
|
||||||
<svg
|
|
||||||
aria-hidden="true"
|
|
||||||
aria-label="Delete USWESTVIN12345670"
|
|
||||||
class="MuiSvgIcon-root"
|
|
||||||
focusable="false"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
d="M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
</a>
|
|
||||||
<div />
|
|
||||||
</span>
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
import React, { useEffect, useState } from "react";
|
|
||||||
import { Link } from 'react-router-dom';
|
|
||||||
import {
|
import {
|
||||||
Grid,
|
Grid,
|
||||||
Table,
|
Table,
|
||||||
@@ -13,27 +11,32 @@ import {
|
|||||||
import AddCircleIcon from "@material-ui/icons/AddCircle";
|
import AddCircleIcon from "@material-ui/icons/AddCircle";
|
||||||
import DeleteIcon from "@material-ui/icons/Delete";
|
import DeleteIcon from "@material-ui/icons/Delete";
|
||||||
import clsx from "clsx";
|
import clsx from "clsx";
|
||||||
|
import React, { useEffect, useState } from "react";
|
||||||
|
import { Link } from "react-router-dom";
|
||||||
|
|
||||||
import TableHeaderSortable from "../../../../Table/HeaderSortable";
|
|
||||||
import { useUserContext } from "../../../../Contexts/UserContext"
|
|
||||||
import { useStatusContext } from "../../../../Contexts/StatusContext";
|
|
||||||
import { FleetProvider, useFleetContext } from "../../../../Contexts/FleetContext"
|
|
||||||
import useStyles from "../../../../useStyles";
|
|
||||||
import SearchField from "../../../../Controls/SearchField";
|
|
||||||
import { logger } from "../../../../../services/monitoring";
|
import { logger } from "../../../../../services/monitoring";
|
||||||
import { Roles, hasRole } from "../../../../../utils/roles";
|
import { hasRole, Permissions } from "../../../../../utils/roles";
|
||||||
import { useLocalStorage } from "../../../../useLocalStorage";
|
import {
|
||||||
|
FleetProvider,
|
||||||
|
useFleetContext,
|
||||||
|
} from "../../../../Contexts/FleetContext";
|
||||||
|
import { useStatusContext } from "../../../../Contexts/StatusContext";
|
||||||
|
import { useUserContext } from "../../../../Contexts/UserContext";
|
||||||
|
import SearchField from "../../../../Controls/SearchField";
|
||||||
import DeleteConfirmation from "../../../../DeleteConfirmation";
|
import DeleteConfirmation from "../../../../DeleteConfirmation";
|
||||||
|
import TableHeaderSortable from "../../../../Table/HeaderSortable";
|
||||||
|
import { useLocalStorage } from "../../../../useLocalStorage";
|
||||||
|
import useStyles from "../../../../useStyles";
|
||||||
|
|
||||||
const tableColumns = [
|
const tableColumns = [
|
||||||
{
|
{
|
||||||
id: "vin",
|
id: "vin",
|
||||||
label: "VIN"
|
label: "VIN",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: "",
|
id: "",
|
||||||
label: "Actions"
|
label: "Actions",
|
||||||
}
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
const PAGE_SIZE = "FLEET_STATUS_VEHICLES_TABLE_PAGE_SIZE";
|
const PAGE_SIZE = "FLEET_STATUS_VEHICLES_TABLE_PAGE_SIZE";
|
||||||
@@ -44,11 +47,22 @@ const MainForm = ({ name }) => {
|
|||||||
const [orderBy, setOrderBy] = useState("id");
|
const [orderBy, setOrderBy] = useState("id");
|
||||||
const [order, setOrder] = useState("desc");
|
const [order, setOrder] = useState("desc");
|
||||||
const [search, setSearch] = useState("");
|
const [search, setSearch] = useState("");
|
||||||
const [showDeleteModal, setShowDeleteModal] = useState(false)
|
const [showDeleteModal, setShowDeleteModal] = useState(false);
|
||||||
const classes = useStyles();
|
const classes = useStyles();
|
||||||
const { setMessage } = useStatusContext();
|
const { setMessage } = useStatusContext();
|
||||||
const { fleetVehicles, totalFleetVehicles, getFleetVehicles, deleteFleetVehicle } = useFleetContext();
|
const {
|
||||||
const { token: { idToken: { jwtToken: token } }, groups } = useUserContext();
|
fleetVehicles,
|
||||||
|
totalFleetVehicles,
|
||||||
|
getFleetVehicles,
|
||||||
|
deleteFleetVehicle,
|
||||||
|
} = useFleetContext();
|
||||||
|
const {
|
||||||
|
token: {
|
||||||
|
idToken: { jwtToken: token },
|
||||||
|
},
|
||||||
|
groups,
|
||||||
|
providers,
|
||||||
|
} = useUserContext();
|
||||||
|
|
||||||
const handleSearch = (query) => {
|
const handleSearch = (query) => {
|
||||||
setSearch(query);
|
setSearch(query);
|
||||||
@@ -105,7 +119,7 @@ const MainForm = ({ name }) => {
|
|||||||
const onDelete = async (vin) => {
|
const onDelete = async (vin) => {
|
||||||
try {
|
try {
|
||||||
await deleteFleetVehicle(name, { vin: vin }, token);
|
await deleteFleetVehicle(name, { vin: vin }, token);
|
||||||
setMessage(`Deleted ${vin}`)
|
setMessage(`Deleted ${vin}`);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
setMessage(e.message);
|
setMessage(e.message);
|
||||||
logger.warn(e.stack);
|
logger.warn(e.stack);
|
||||||
@@ -114,12 +128,12 @@ const MainForm = ({ name }) => {
|
|||||||
|
|
||||||
const Actions = (vin) => {
|
const Actions = (vin) => {
|
||||||
let actions = [];
|
let actions = [];
|
||||||
if (hasRole([Roles.DELETE], groups)) {
|
if (hasRole(groups, Permissions.FiskerDelete, providers)) {
|
||||||
actions.push({
|
actions.push({
|
||||||
tip: `Delete "${vin}"`,
|
tip: `Delete "${vin}"`,
|
||||||
id: vin,
|
id: vin,
|
||||||
icon: <DeleteIcon aria-label={`Delete ${vin}`} />
|
icon: <DeleteIcon aria-label={`Delete ${vin}`} />,
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
if (actions.length === 0) return ["No actions"];
|
if (actions.length === 0) return ["No actions"];
|
||||||
|
|
||||||
@@ -140,9 +154,13 @@ const MainForm = ({ name }) => {
|
|||||||
{action.icon}
|
{action.icon}
|
||||||
</Link>
|
</Link>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
<DeleteConfirmation message={action.id} open={showDeleteModal} close={() => setShowDeleteModal(false)} deleteFunction={() => onDelete(action.id)} />
|
<DeleteConfirmation
|
||||||
|
message={action.id}
|
||||||
|
open={showDeleteModal}
|
||||||
|
close={() => setShowDeleteModal(false)}
|
||||||
|
deleteFunction={() => onDelete(action.id)}
|
||||||
|
/>
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -152,7 +170,10 @@ const MainForm = ({ name }) => {
|
|||||||
<div className={clsx(classes.paper, classes.tableSize)}>
|
<div className={clsx(classes.paper, classes.tableSize)}>
|
||||||
<Grid container className={classes.root} spacing={2}>
|
<Grid container className={classes.root} spacing={2}>
|
||||||
<Grid item md={4} className={classes.textJustifyAlign}>
|
<Grid item md={4} className={classes.textJustifyAlign}>
|
||||||
<Link to={`/fleet/${name}/vehicle-add`} className={classes.labelInline}>
|
<Link
|
||||||
|
to={`/fleet/${name}/vehicle-add`}
|
||||||
|
className={classes.labelInline}
|
||||||
|
>
|
||||||
<AddCircleIcon fontSize="large" />
|
<AddCircleIcon fontSize="large" />
|
||||||
</Link>
|
</Link>
|
||||||
</Grid>
|
</Grid>
|
||||||
@@ -169,7 +190,7 @@ const MainForm = ({ name }) => {
|
|||||||
onSortRequest={handleSort}
|
onSortRequest={handleSort}
|
||||||
/>
|
/>
|
||||||
<TableBody>
|
<TableBody>
|
||||||
{fleetVehicles.map(vin => (
|
{fleetVehicles.map((vin) => (
|
||||||
<TableRow key={vin}>
|
<TableRow key={vin}>
|
||||||
<TableCell align="center">
|
<TableCell align="center">
|
||||||
<Link to={`/vehicle-status/${vin}`}>{vin}</Link>
|
<Link to={`/vehicle-status/${vin}`}>{vin}</Link>
|
||||||
@@ -196,7 +217,7 @@ const MainForm = ({ name }) => {
|
|||||||
</TableRow>
|
</TableRow>
|
||||||
</TableFooter>
|
</TableFooter>
|
||||||
</Table>
|
</Table>
|
||||||
</div >
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import { BrowserRouter } from "react-router-dom";
|
|||||||
import { FleetProvider } from "../../../../Contexts/FleetContext";
|
import { FleetProvider } from "../../../../Contexts/FleetContext";
|
||||||
import { StatusProvider } from "../../../../Contexts/StatusContext";
|
import { StatusProvider } from "../../../../Contexts/StatusContext";
|
||||||
import { UserProvider, setToken } from "../../../../Contexts/UserContext";
|
import { UserProvider, setToken } from "../../../../Contexts/UserContext";
|
||||||
import { TEST_AUTH_OBJECT } from "../../../../../utils/testing";
|
import { TEST_AUTH_OBJECT_FISKER }from "../../../../../utils/testing";
|
||||||
import MainForm from "./index";
|
import MainForm from "./index";
|
||||||
import addSnapshotSerializer from "../../../../../utils/snapshot";
|
import addSnapshotSerializer from "../../../../../utils/snapshot";
|
||||||
|
|
||||||
@@ -39,7 +39,7 @@ describe("FleetVehiclesTable", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("Render", async () => {
|
it("Render", async () => {
|
||||||
setToken(TEST_AUTH_OBJECT);
|
setToken(TEST_AUTH_OBJECT_FISKER);
|
||||||
const container = await renderFleetVehiclesTable();
|
const container = await renderFleetVehiclesTable();
|
||||||
expect(container).toMatchSnapshot();
|
expect(container).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import { render, waitFor } from "@testing-library/react";
|
|||||||
import { BrowserRouter } from "react-router-dom";
|
import { BrowserRouter } from "react-router-dom";
|
||||||
|
|
||||||
import { setToken } from "../../Contexts/UserContext";
|
import { setToken } from "../../Contexts/UserContext";
|
||||||
import { TEST_AUTH_OBJECT } from "../../../utils/testing";
|
import { TEST_AUTH_OBJECT_FISKER } from "../../../utils/testing";
|
||||||
import VehiclesTab from "./VehiclesTab";
|
import VehiclesTab from "./VehiclesTab";
|
||||||
import addSnapshotSerializer from "../../../utils/snapshot";
|
import addSnapshotSerializer from "../../../utils/snapshot";
|
||||||
|
|
||||||
@@ -31,7 +31,7 @@ describe("VehiclesTab", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("Render", async () => {
|
it("Render", async () => {
|
||||||
setToken(TEST_AUTH_OBJECT);
|
setToken(TEST_AUTH_OBJECT_FISKER);
|
||||||
const container = await renderVehiclesTab();
|
const container = await renderVehiclesTab();
|
||||||
expect(container).toMatchSnapshot();
|
expect(container).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -220,23 +220,6 @@ exports[`CANFiltersTab Render 1`] = `
|
|||||||
/>
|
/>
|
||||||
</svg>
|
</svg>
|
||||||
</a>
|
</a>
|
||||||
<a
|
|
||||||
class=""
|
|
||||||
href="/"
|
|
||||||
title="Delete \\"123-456\\""
|
|
||||||
>
|
|
||||||
<svg
|
|
||||||
aria-hidden="true"
|
|
||||||
aria-label="Delete 123-456"
|
|
||||||
class="MuiSvgIcon-root"
|
|
||||||
focusable="false"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
d="M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
</a>
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr
|
<tr
|
||||||
@@ -276,23 +259,6 @@ exports[`CANFiltersTab Render 1`] = `
|
|||||||
/>
|
/>
|
||||||
</svg>
|
</svg>
|
||||||
</a>
|
</a>
|
||||||
<a
|
|
||||||
class=""
|
|
||||||
href="/"
|
|
||||||
title="Delete \\"1\\""
|
|
||||||
>
|
|
||||||
<svg
|
|
||||||
aria-hidden="true"
|
|
||||||
aria-label="Delete 1"
|
|
||||||
class="MuiSvgIcon-root"
|
|
||||||
focusable="false"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
d="M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
</a>
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr
|
<tr
|
||||||
@@ -332,23 +298,6 @@ exports[`CANFiltersTab Render 1`] = `
|
|||||||
/>
|
/>
|
||||||
</svg>
|
</svg>
|
||||||
</a>
|
</a>
|
||||||
<a
|
|
||||||
class=""
|
|
||||||
href="/"
|
|
||||||
title="Delete \\"1000\\""
|
|
||||||
>
|
|
||||||
<svg
|
|
||||||
aria-hidden="true"
|
|
||||||
aria-label="Delete 1000"
|
|
||||||
class="MuiSvgIcon-root"
|
|
||||||
focusable="false"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
d="M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
</a>
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
|
|||||||
@@ -152,26 +152,7 @@ exports[`VehiclesTab Render 1`] = `
|
|||||||
<td
|
<td
|
||||||
class="MuiTableCell-root MuiTableCell-body MuiTableCell-alignCenter"
|
class="MuiTableCell-root MuiTableCell-body MuiTableCell-alignCenter"
|
||||||
>
|
>
|
||||||
<span>
|
No actions
|
||||||
<a
|
|
||||||
class=""
|
|
||||||
href="/"
|
|
||||||
title="Delete \\"USWESTVIN12345678\\""
|
|
||||||
>
|
|
||||||
<svg
|
|
||||||
aria-hidden="true"
|
|
||||||
aria-label="Delete USWESTVIN12345678"
|
|
||||||
class="MuiSvgIcon-root"
|
|
||||||
focusable="false"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
d="M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
</a>
|
|
||||||
<div />
|
|
||||||
</span>
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr
|
<tr
|
||||||
@@ -189,26 +170,7 @@ exports[`VehiclesTab Render 1`] = `
|
|||||||
<td
|
<td
|
||||||
class="MuiTableCell-root MuiTableCell-body MuiTableCell-alignCenter"
|
class="MuiTableCell-root MuiTableCell-body MuiTableCell-alignCenter"
|
||||||
>
|
>
|
||||||
<span>
|
No actions
|
||||||
<a
|
|
||||||
class=""
|
|
||||||
href="/"
|
|
||||||
title="Delete \\"USWESTVIN12345679\\""
|
|
||||||
>
|
|
||||||
<svg
|
|
||||||
aria-hidden="true"
|
|
||||||
aria-label="Delete USWESTVIN12345679"
|
|
||||||
class="MuiSvgIcon-root"
|
|
||||||
focusable="false"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
d="M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
</a>
|
|
||||||
<div />
|
|
||||||
</span>
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr
|
<tr
|
||||||
@@ -226,26 +188,7 @@ exports[`VehiclesTab Render 1`] = `
|
|||||||
<td
|
<td
|
||||||
class="MuiTableCell-root MuiTableCell-body MuiTableCell-alignCenter"
|
class="MuiTableCell-root MuiTableCell-body MuiTableCell-alignCenter"
|
||||||
>
|
>
|
||||||
<span>
|
No actions
|
||||||
<a
|
|
||||||
class=""
|
|
||||||
href="/"
|
|
||||||
title="Delete \\"USWESTVIN12345670\\""
|
|
||||||
>
|
|
||||||
<svg
|
|
||||||
aria-hidden="true"
|
|
||||||
aria-label="Delete USWESTVIN12345670"
|
|
||||||
class="MuiSvgIcon-root"
|
|
||||||
focusable="false"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
d="M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
</a>
|
|
||||||
<div />
|
|
||||||
</span>
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import routeData from "react-router";
|
|||||||
import { FleetProvider } from "../../Contexts/FleetContext";
|
import { FleetProvider } from "../../Contexts/FleetContext";
|
||||||
import { StatusProvider } from "../../Contexts/StatusContext";
|
import { StatusProvider } from "../../Contexts/StatusContext";
|
||||||
import { UserProvider, setToken } from "../../Contexts/UserContext";
|
import { UserProvider, setToken } from "../../Contexts/UserContext";
|
||||||
import { TEST_AUTH_OBJECT } from "../../../utils/testing";
|
import { TEST_AUTH_OBJECT_FISKER } from "../../../utils/testing";
|
||||||
import FleetStatus from "./index";
|
import FleetStatus from "./index";
|
||||||
import addSnapshotSerializer from "../../../utils/snapshot";
|
import addSnapshotSerializer from "../../../utils/snapshot";
|
||||||
|
|
||||||
@@ -45,7 +45,7 @@ describe("FleetStatus", () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
it("Render", async () => {
|
it("Render", async () => {
|
||||||
setToken(TEST_AUTH_OBJECT);
|
setToken(TEST_AUTH_OBJECT_FISKER);
|
||||||
const container = await renderCarStatus();
|
const container = await renderCarStatus();
|
||||||
expect(container).toMatchSnapshot();
|
expect(container).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import { BrowserRouter } from "react-router-dom";
|
|||||||
import { FleetProvider } from "../../Contexts/FleetContext";
|
import { FleetProvider } from "../../Contexts/FleetContext";
|
||||||
import { StatusProvider } from "../../Contexts/StatusContext";
|
import { StatusProvider } from "../../Contexts/StatusContext";
|
||||||
import { UserProvider, setToken } from "../../Contexts/UserContext";
|
import { UserProvider, setToken } from "../../Contexts/UserContext";
|
||||||
import { TEST_AUTH_OBJECT } from "../../../utils/testing";
|
import { TEST_AUTH_OBJECT_FISKER } from "../../../utils/testing";
|
||||||
import MainForm from "./index";
|
import MainForm from "./index";
|
||||||
import addSnapshotSerializer from "../../../utils/snapshot";
|
import addSnapshotSerializer from "../../../utils/snapshot";
|
||||||
|
|
||||||
@@ -39,7 +39,7 @@ describe("FleetTable", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("Render", async () => {
|
it("Render", async () => {
|
||||||
setToken(TEST_AUTH_OBJECT);
|
setToken(TEST_AUTH_OBJECT_FISKER);
|
||||||
const container = await renderFleetTable();
|
const container = await renderFleetTable();
|
||||||
expect(container).toMatchSnapshot();
|
expect(container).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import { BrowserRouter } from "react-router-dom";
|
|||||||
import { FleetProvider } from "../../Contexts/FleetContext";
|
import { FleetProvider } from "../../Contexts/FleetContext";
|
||||||
import { StatusProvider } from "../../Contexts/StatusContext";
|
import { StatusProvider } from "../../Contexts/StatusContext";
|
||||||
import { UserProvider, setToken } from "../../Contexts/UserContext";
|
import { UserProvider, setToken } from "../../Contexts/UserContext";
|
||||||
import { TEST_AUTH_OBJECT } from "../../../utils/testing";
|
import { TEST_AUTH_OBJECT_FISKER } from "../../../utils/testing";
|
||||||
import MainForm from "./index";
|
import MainForm from "./index";
|
||||||
import addSnapshotSerializer from "../../../utils/snapshot";
|
import addSnapshotSerializer from "../../../utils/snapshot";
|
||||||
|
|
||||||
@@ -36,7 +36,7 @@ describe("FleetUpdate", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("Render", async () => {
|
it("Render", async () => {
|
||||||
setToken(TEST_AUTH_OBJECT);
|
setToken(TEST_AUTH_OBJECT_FISKER);
|
||||||
const container = await renderFleetUpdate();
|
const container = await renderFleetUpdate();
|
||||||
expect(container).toMatchSnapshot();
|
expect(container).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,17 +1,17 @@
|
|||||||
import React from "react";
|
|
||||||
import { List } from "@material-ui/core";
|
import { List } from "@material-ui/core";
|
||||||
import HomeIcon from "@material-ui/icons/Home";
|
|
||||||
import DirectionsCarIcon from "@material-ui/icons/DirectionsCar";
|
|
||||||
import CommuteIcon from "@material-ui/icons/Commute";
|
|
||||||
import CloudDownloadIcon from "@material-ui/icons/CloudDownload";
|
|
||||||
import AssessmentIcon from "@material-ui/icons/Assessment";
|
import AssessmentIcon from "@material-ui/icons/Assessment";
|
||||||
import BuildIcon from "@material-ui/icons/Build";
|
import BuildIcon from "@material-ui/icons/Build";
|
||||||
|
import CloudDownloadIcon from "@material-ui/icons/CloudDownload";
|
||||||
|
import CommuteIcon from "@material-ui/icons/Commute";
|
||||||
|
import DirectionsCarIcon from "@material-ui/icons/DirectionsCar";
|
||||||
|
import HomeIcon from "@material-ui/icons/Home";
|
||||||
import SettingsInputCompositeIcon from "@material-ui/icons/SettingsInputComposite";
|
import SettingsInputCompositeIcon from "@material-ui/icons/SettingsInputComposite";
|
||||||
|
import { default as React, useEffect, useState } from "react";
|
||||||
|
|
||||||
|
import { hasRole, Permissions } from "../../utils/roles";
|
||||||
import { useUserContext } from "../Contexts/UserContext";
|
import { useUserContext } from "../Contexts/UserContext";
|
||||||
import { Roles, hasRole } from "../../utils/roles";
|
|
||||||
import { ExpandableSideMenuItem, MenuItem } from "./MenuItem";
|
|
||||||
import SupersetDashboardList from "../SupersetDashboardList/SupersetDashboardList";
|
import SupersetDashboardList from "../SupersetDashboardList/SupersetDashboardList";
|
||||||
|
import { ExpandableSideMenuItem, MenuItem } from "./MenuItem";
|
||||||
|
|
||||||
const menuData = [
|
const menuData = [
|
||||||
{
|
{
|
||||||
@@ -24,65 +24,60 @@ const menuData = [
|
|||||||
label: "Deployments",
|
label: "Deployments",
|
||||||
to: "/packages",
|
to: "/packages",
|
||||||
icon: <CloudDownloadIcon />,
|
icon: <CloudDownloadIcon />,
|
||||||
roles: [Roles.READ, Roles.CREATE],
|
rolesPerProvider: Permissions.FiskerMagnaRead,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Vehicles",
|
label: "Vehicles",
|
||||||
to: "/vehicles",
|
to: "/vehicles",
|
||||||
icon: <DirectionsCarIcon />,
|
icon: <DirectionsCarIcon />,
|
||||||
roles: [Roles.READ, Roles.CREATE],
|
rolesPerProvider: Permissions.FiskerMagnaRead,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Fleets",
|
label: "Fleets",
|
||||||
to: "/fleets",
|
to: "/fleets",
|
||||||
icon: <CommuteIcon />,
|
icon: <CommuteIcon />,
|
||||||
roles: [Roles.READ, Roles.CREATE],
|
rolesPerProvider: Permissions.FiskerRead,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Datascope",
|
label: "Datascope",
|
||||||
to: null,
|
to: null,
|
||||||
icon: <AssessmentIcon />,
|
icon: <AssessmentIcon />,
|
||||||
roles: [Roles.READ, Roles.CREATE],
|
rolesPerProvider: Permissions.FiskerRead,
|
||||||
component: SupersetDashboardList
|
component: SupersetDashboardList,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Suppliers",
|
label: "Suppliers",
|
||||||
to: "/suppliers",
|
to: "/suppliers",
|
||||||
icon: <SettingsInputCompositeIcon />,
|
icon: <SettingsInputCompositeIcon />,
|
||||||
roles: [Roles.APPROVESUPPLIERS],
|
rolesPerProvider: Permissions.FiskerSupplierAdmin,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Tools",
|
label: "Tools",
|
||||||
to: "/tools/certificates/add",
|
to: "/tools/certificates/add",
|
||||||
icon: <BuildIcon />,
|
icon: <BuildIcon />,
|
||||||
roles: [Roles.CERTIFICATES, Roles.APPROVESUPPLIERS],
|
rolesPerProvider: Permissions.FiskerTools,
|
||||||
submenus: [
|
submenus: [
|
||||||
{
|
{
|
||||||
label: "Certificate",
|
label: "Certificate",
|
||||||
to: "/tools/certificates/add",
|
to: "/tools/certificates/add",
|
||||||
roles: [Roles.CERTIFICATES],
|
rolesPerProvider: Permissions.FiskerCertificate,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "SMS",
|
label: "SMS",
|
||||||
to: "/tools/sms/send",
|
to: "/tools/sms/send",
|
||||||
roles: [Roles.CREATE],
|
rolesPerProvider: Permissions.FiskerCreate,
|
||||||
}
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
||||||
const SideMenu = () => {
|
const SideMenu = () => {
|
||||||
const { groups } = useUserContext();
|
const { groups, providers } = useUserContext();
|
||||||
|
const [menu, setMenu] = useState(menuData);
|
||||||
const menu = menuData.reduce((result, item) => {
|
|
||||||
if (hasRole(item.roles, groups)) {
|
|
||||||
result.push(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
filterAccessible(groups, providers, setMenu);
|
||||||
|
}, [groups, providers]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<List>
|
<List>
|
||||||
@@ -96,4 +91,14 @@ const SideMenu = () => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default SideMenu;
|
const filterAccessible = (groups, providers, setMenu) => {
|
||||||
|
const filteredMenu = menuData.reduce((result, item) => {
|
||||||
|
if (hasRole(groups, item.rolesPerProvider, providers)) {
|
||||||
|
result.push(item);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}, []);
|
||||||
|
setMenu(filteredMenu);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default SideMenu;
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
jest.mock("../Contexts/UserContext");
|
jest.mock("../Contexts/UserContext");
|
||||||
jest.mock("../../services/superset")
|
jest.mock("../../services/superset");
|
||||||
|
|
||||||
import { render, waitFor, screen } from "@testing-library/react";
|
import { render, screen, waitFor } from "@testing-library/react";
|
||||||
import { BrowserRouter } from "react-router-dom";
|
import { BrowserRouter } from "react-router-dom";
|
||||||
import { UserProvider, setToken } from "../Contexts/UserContext";
|
|
||||||
import { TEST_AUTH_OBJECT } from "../../utils/testing";
|
|
||||||
import SideMenu from "./SideMenu";
|
|
||||||
import addSnapshotSerializer from "../../utils/snapshot";
|
import addSnapshotSerializer from "../../utils/snapshot";
|
||||||
|
import { TEST_AUTH_OBJECT_FISKER } from "../../utils/testing";
|
||||||
|
import { setToken, UserProvider } from "../Contexts/UserContext";
|
||||||
|
import SideMenu from "./SideMenu";
|
||||||
|
|
||||||
const renderMenu = async () => {
|
const renderMenu = async () => {
|
||||||
const { container } = render(
|
const { container } = render(
|
||||||
@@ -23,15 +23,20 @@ const renderMenu = async () => {
|
|||||||
describe("SideMenu", () => {
|
describe("SideMenu", () => {
|
||||||
beforeAll(() => {
|
beforeAll(() => {
|
||||||
addSnapshotSerializer(expect);
|
addSnapshotSerializer(expect);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Unauthenticated", async () => {
|
||||||
|
setToken({ idToken: { jwtToken: null } });
|
||||||
|
const container = await renderMenu();
|
||||||
|
expect(container).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Authenticated", async () => {
|
it("Authenticated", async () => {
|
||||||
setToken(TEST_AUTH_OBJECT);
|
setToken(TEST_AUTH_OBJECT_FISKER);
|
||||||
const container = await renderMenu();
|
const container = await renderMenu();
|
||||||
await waitFor(() => {
|
await waitFor(() => {
|
||||||
expect(screen.getByText('Datascope')).toBeInTheDocument()
|
expect(screen.getByText("Datascope")).toBeInTheDocument();
|
||||||
})
|
});
|
||||||
expect(container).toMatchSnapshot();
|
expect(container).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -213,6 +213,42 @@ exports[`SideMenu Authenticated 1`] = `
|
|||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
|
<li>
|
||||||
|
<a
|
||||||
|
aria-disabled="false"
|
||||||
|
class="MuiButtonBase-root MuiListItem-root MuiListItem-gutters MuiListItem-button"
|
||||||
|
href="/suppliers"
|
||||||
|
role="button"
|
||||||
|
tabindex="0"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="MuiListItemIcon-root"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
aria-hidden="true"
|
||||||
|
class="MuiSvgIcon-root"
|
||||||
|
focusable="false"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M5 2c0-.55-.45-1-1-1s-1 .45-1 1v4H1v6h6V6H5V2zm4 14c0 1.3.84 2.4 2 2.82V23h2v-4.18c1.16-.41 2-1.51 2-2.82v-2H9v2zm-8 0c0 1.3.84 2.4 2 2.82V23h2v-4.18C6.16 18.4 7 17.3 7 16v-2H1v2zM21 6V2c0-.55-.45-1-1-1s-1 .45-1 1v4h-2v6h6V6h-2zm-8-4c0-.55-.45-1-1-1s-1 .45-1 1v4H9v6h6V6h-2V2zm4 14c0 1.3.84 2.4 2 2.82V23h2v-4.18c1.16-.41 2-1.51 2-2.82v-2h-6v2z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="MuiListItemText-root"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="MuiTypography-root MuiListItemText-primary MuiTypography-body1 MuiTypography-displayBlock"
|
||||||
|
>
|
||||||
|
Suppliers
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<span
|
||||||
|
class="MuiTouchRipple-root"
|
||||||
|
/>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
<span>
|
<span>
|
||||||
<li>
|
<li>
|
||||||
<a
|
<a
|
||||||
@@ -303,3 +339,52 @@ exports[`SideMenu Authenticated 1`] = `
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
exports[`SideMenu Unauthenticated 1`] = `
|
||||||
|
<div>
|
||||||
|
<div
|
||||||
|
data-testid="mocked-userprovider"
|
||||||
|
>
|
||||||
|
<ul
|
||||||
|
class="MuiList-root MuiList-padding"
|
||||||
|
>
|
||||||
|
<li>
|
||||||
|
<a
|
||||||
|
aria-disabled="false"
|
||||||
|
class="MuiButtonBase-root MuiListItem-root MuiListItem-gutters MuiListItem-button"
|
||||||
|
href="/home"
|
||||||
|
role="button"
|
||||||
|
tabindex="0"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="MuiListItemIcon-root"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
aria-hidden="true"
|
||||||
|
class="MuiSvgIcon-root"
|
||||||
|
focusable="false"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M10 20v-6h4v6h5v-8h3L12 3 2 12h3v8z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="MuiListItemText-root"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="MuiTypography-root MuiListItemText-primary MuiTypography-body1 MuiTypography-displayBlock"
|
||||||
|
>
|
||||||
|
Home
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<span
|
||||||
|
class="MuiTouchRipple-root"
|
||||||
|
/>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import { ManifestsProvider } from "../../Contexts/ManifestsContext";
|
|||||||
import { UserProvider, setToken } from "../../Contexts/UserContext";
|
import { UserProvider, setToken } from "../../Contexts/UserContext";
|
||||||
import { StatusProvider } from "../../Contexts/StatusContext";
|
import { StatusProvider } from "../../Contexts/StatusContext";
|
||||||
import ManifestDetails from ".";
|
import ManifestDetails from ".";
|
||||||
import { TEST_AUTH_OBJECT } from "../../../utils/testing";
|
import { TEST_AUTH_OBJECT_FISKER } from "../../../utils/testing";
|
||||||
import addSnapshotSerializer from "../../../utils/snapshot";
|
import addSnapshotSerializer from "../../../utils/snapshot";
|
||||||
|
|
||||||
const TestComponent = (opened) => (
|
const TestComponent = (opened) => (
|
||||||
@@ -26,7 +26,7 @@ const TestComponent = (opened) => (
|
|||||||
|
|
||||||
describe("Manifest Details Component", () => {
|
describe("Manifest Details Component", () => {
|
||||||
beforeAll(() => {
|
beforeAll(() => {
|
||||||
setToken(TEST_AUTH_OBJECT);
|
setToken(TEST_AUTH_OBJECT_FISKER);
|
||||||
addSnapshotSerializer(expect);
|
addSnapshotSerializer(expect);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
import React, { useEffect, useState } from "react";
|
|
||||||
import { Link } from "react-router-dom";
|
|
||||||
import {
|
import {
|
||||||
Grid,
|
Grid,
|
||||||
Table,
|
Table,
|
||||||
@@ -10,28 +8,30 @@ import {
|
|||||||
TableRow,
|
TableRow,
|
||||||
Tooltip,
|
Tooltip,
|
||||||
} from "@material-ui/core";
|
} from "@material-ui/core";
|
||||||
|
import DeleteIcon from "@material-ui/icons/Delete";
|
||||||
import SendIcon from "@material-ui/icons/Send";
|
import SendIcon from "@material-ui/icons/Send";
|
||||||
import VisibilityIcon from "@material-ui/icons/Visibility";
|
import VisibilityIcon from "@material-ui/icons/Visibility";
|
||||||
import DeleteIcon from "@material-ui/icons/Delete";
|
|
||||||
import clsx from "clsx";
|
import clsx from "clsx";
|
||||||
|
import React, { useEffect, useState } from "react";
|
||||||
|
import { Link } from "react-router-dom";
|
||||||
|
|
||||||
import {
|
|
||||||
useManifestsContext,
|
|
||||||
ManifestsProvider,
|
|
||||||
} from "../../Contexts/ManifestsContext";
|
|
||||||
import { useUserContext } from "../../Contexts/UserContext";
|
|
||||||
import { useStatusContext } from "../../Contexts/StatusContext";
|
|
||||||
import useStyles from "../../useStyles";
|
|
||||||
import { LocalDateTimeString } from "../../../utils/dates";
|
|
||||||
import TableHeaderSortable from "../../Table/HeaderSortable";
|
|
||||||
import SearchField from "../../Controls/SearchField";
|
|
||||||
import { logger } from "../../../services/monitoring";
|
|
||||||
import ECUList from "../../Controls/ECUList";
|
|
||||||
import { Roles, hasRole } from "../../../utils/roles";
|
|
||||||
import { useLocalStorage } from "../../useLocalStorage";
|
|
||||||
import { TYPE_MANIFEST_SOFTWARE } from "../../../utils/manifest_types";
|
|
||||||
import DeleteConfirmation from "../../DeleteConfirmation";
|
|
||||||
import EditIcon from "@material-ui/icons/Edit";
|
import EditIcon from "@material-ui/icons/Edit";
|
||||||
|
import { logger } from "../../../services/monitoring";
|
||||||
|
import { LocalDateTimeString } from "../../../utils/dates";
|
||||||
|
import { TYPE_MANIFEST_SOFTWARE } from "../../../utils/manifest_types";
|
||||||
|
import { hasRole, Permissions } from "../../../utils/roles";
|
||||||
|
import {
|
||||||
|
ManifestsProvider,
|
||||||
|
useManifestsContext,
|
||||||
|
} from "../../Contexts/ManifestsContext";
|
||||||
|
import { useStatusContext } from "../../Contexts/StatusContext";
|
||||||
|
import { useUserContext } from "../../Contexts/UserContext";
|
||||||
|
import ECUList from "../../Controls/ECUList";
|
||||||
|
import SearchField from "../../Controls/SearchField";
|
||||||
|
import DeleteConfirmation from "../../DeleteConfirmation";
|
||||||
|
import TableHeaderSortable from "../../Table/HeaderSortable";
|
||||||
|
import { useLocalStorage } from "../../useLocalStorage";
|
||||||
|
import useStyles from "../../useStyles";
|
||||||
|
|
||||||
const tableColumns = [
|
const tableColumns = [
|
||||||
{
|
{
|
||||||
@@ -71,7 +71,7 @@ const formatManifestType = (type) => {
|
|||||||
default:
|
default:
|
||||||
return "Standard";
|
return "Standard";
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
const PAGE_SIZE = "MANIFEST_LIST_PAGE_SIZE";
|
const PAGE_SIZE = "MANIFEST_LIST_PAGE_SIZE";
|
||||||
|
|
||||||
@@ -95,6 +95,7 @@ const MainForm = () => {
|
|||||||
idToken: { jwtToken: token },
|
idToken: { jwtToken: token },
|
||||||
},
|
},
|
||||||
groups,
|
groups,
|
||||||
|
providers,
|
||||||
} = useUserContext();
|
} = useUserContext();
|
||||||
|
|
||||||
const sortHandler = (event, property) => {
|
const sortHandler = (event, property) => {
|
||||||
@@ -155,7 +156,7 @@ const MainForm = () => {
|
|||||||
setDeleteId(id);
|
setDeleteId(id);
|
||||||
setDeleteRowName(`${row.name} ${row.version}`);
|
setDeleteRowName(`${row.name} ${row.version}`);
|
||||||
setShowDeleteModal(true);
|
setShowDeleteModal(true);
|
||||||
}
|
};
|
||||||
|
|
||||||
const onDelete = async (manifest_id) => {
|
const onDelete = async (manifest_id) => {
|
||||||
try {
|
try {
|
||||||
@@ -168,29 +169,30 @@ const MainForm = () => {
|
|||||||
|
|
||||||
const Actions = (row) => {
|
const Actions = (row) => {
|
||||||
let actions = [];
|
let actions = [];
|
||||||
if (hasRole([Roles.CREATE, Roles.READ], groups)) {
|
if (hasRole(groups, Permissions.FiskerMagnaRead, providers)) {
|
||||||
actions.push({
|
actions.push({
|
||||||
tip: `Status "${row.name} ${row.version}"`,
|
tip: `Status "${row.name} ${row.version}"`,
|
||||||
link: `/package-status/${row.id}`,
|
link: `/package-status/${row.id}`,
|
||||||
icon: (
|
icon: (
|
||||||
<VisibilityIcon aria-label={`Status ${row.name} ${row.version}`} />
|
<VisibilityIcon aria-label={`Status ${row.name} ${row.version}`} />
|
||||||
),
|
),
|
||||||
}, {
|
|
||||||
tip: `Update "${row.name} ${row.version}"`,
|
|
||||||
link: `/package-update/${row.id}`,
|
|
||||||
icon: (
|
|
||||||
<EditIcon aria-label={`Update ${row.name} ${row.version}`} />
|
|
||||||
),
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (hasRole([Roles.CREATE], groups)) {
|
if (hasRole(groups, Permissions.FiskerRead, providers)) {
|
||||||
|
actions.push({
|
||||||
|
tip: `Update "${row.name} ${row.version}"`,
|
||||||
|
link: `/package-update/${row.id}`,
|
||||||
|
icon: <EditIcon aria-label={`Update ${row.name} ${row.version}`} />,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (hasRole(groups, Permissions.FiskerMagnaCreate, providers)) {
|
||||||
actions.push({
|
actions.push({
|
||||||
tip: `Deploy "${row.name} ${row.version}"`,
|
tip: `Deploy "${row.name} ${row.version}"`,
|
||||||
link: `/package-deploy/${row.id}`,
|
link: `/package-deploy/${row.id}`,
|
||||||
icon: <SendIcon aria-label={`Deploy ${row.name} ${row.version}`} />,
|
icon: <SendIcon aria-label={`Deploy ${row.name} ${row.version}`} />,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (hasRole([Roles.DELETE], groups)) {
|
if (hasRole(groups, Permissions.FiskerDelete, providers)) {
|
||||||
actions.push({
|
actions.push({
|
||||||
tip: `Delete "${row.name} ${row.version}"`,
|
tip: `Delete "${row.name} ${row.version}"`,
|
||||||
id: row.id,
|
id: row.id,
|
||||||
@@ -257,7 +259,9 @@ const MainForm = () => {
|
|||||||
)}
|
)}
|
||||||
</TableCell>
|
</TableCell>
|
||||||
<TableCell align="center">{row.version}</TableCell>
|
<TableCell align="center">{row.version}</TableCell>
|
||||||
<TableCell align="center">{formatManifestType(row.type)}</TableCell>
|
<TableCell align="center">
|
||||||
|
{formatManifestType(row.type)}
|
||||||
|
</TableCell>
|
||||||
<TableCell align="center">
|
<TableCell align="center">
|
||||||
{LocalDateTimeString(row.created)}
|
{LocalDateTimeString(row.created)}
|
||||||
</TableCell>
|
</TableCell>
|
||||||
@@ -290,7 +294,8 @@ const MainForm = () => {
|
|||||||
message={deleteRowName}
|
message={deleteRowName}
|
||||||
open={showDeleteModal}
|
open={showDeleteModal}
|
||||||
close={() => setShowDeleteModal(false)}
|
close={() => setShowDeleteModal(false)}
|
||||||
deleteFunction={() => onDelete(deleteId)} />
|
deleteFunction={() => onDelete(deleteId)}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,6 +1,3 @@
|
|||||||
import React, { useEffect, useState } from "react";
|
|
||||||
import { useParams } from "react-router";
|
|
||||||
import { Link } from "react-router-dom";
|
|
||||||
import {
|
import {
|
||||||
LinearProgress,
|
LinearProgress,
|
||||||
Table,
|
Table,
|
||||||
@@ -14,22 +11,27 @@ import {
|
|||||||
} from "@material-ui/core";
|
} from "@material-ui/core";
|
||||||
import CancelIcon from "@material-ui/icons/Cancel";
|
import CancelIcon from "@material-ui/icons/Cancel";
|
||||||
import clsx from "clsx";
|
import clsx from "clsx";
|
||||||
|
import React, { useEffect, useState } from "react";
|
||||||
|
import { useParams } from "react-router";
|
||||||
|
import { Link } from "react-router-dom";
|
||||||
|
|
||||||
import {
|
import { logger } from "../../../services/monitoring";
|
||||||
ManifestsProvider,
|
import { LocalDateTimeString } from "../../../utils/dates";
|
||||||
useManifestsContext,
|
import { Permissions } from "../../../utils/roles";
|
||||||
} from "../../Contexts/ManifestsContext";
|
|
||||||
import {
|
import {
|
||||||
CarUpdatesProvider,
|
CarUpdatesProvider,
|
||||||
useCarUpdatesContext,
|
useCarUpdatesContext,
|
||||||
} from "../../Contexts/CarUpdatesContext";
|
} from "../../Contexts/CarUpdatesContext";
|
||||||
import { useUserContext } from "../../Contexts/UserContext";
|
import {
|
||||||
|
ManifestsProvider,
|
||||||
|
useManifestsContext,
|
||||||
|
} from "../../Contexts/ManifestsContext";
|
||||||
import { useStatusContext } from "../../Contexts/StatusContext";
|
import { useStatusContext } from "../../Contexts/StatusContext";
|
||||||
import useStyles from "../../useStyles";
|
import { useUserContext } from "../../Contexts/UserContext";
|
||||||
import { LocalDateTimeString } from "../../../utils/dates";
|
import { RoleWrap } from "../../Controls/RoleWrap";
|
||||||
import { logger } from "../../../services/monitoring";
|
|
||||||
import ManifestDetails from "../Details";
|
|
||||||
import { useLocalStorage } from "../../useLocalStorage";
|
import { useLocalStorage } from "../../useLocalStorage";
|
||||||
|
import useStyles from "../../useStyles";
|
||||||
|
import ManifestDetails from "../Details";
|
||||||
|
|
||||||
const PAGE_SIZE = "MANIFEST_STATUS_PAGE_SIZE";
|
const PAGE_SIZE = "MANIFEST_STATUS_PAGE_SIZE";
|
||||||
|
|
||||||
@@ -52,6 +54,8 @@ const MainForm = () => {
|
|||||||
token: {
|
token: {
|
||||||
idToken: { jwtToken: token },
|
idToken: { jwtToken: token },
|
||||||
},
|
},
|
||||||
|
groups,
|
||||||
|
providers,
|
||||||
} = useUserContext();
|
} = useUserContext();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -172,11 +176,18 @@ const MainForm = () => {
|
|||||||
{LocalDateTimeString(row.updated)}
|
{LocalDateTimeString(row.updated)}
|
||||||
</TableCell>
|
</TableCell>
|
||||||
<TableCell>
|
<TableCell>
|
||||||
<Tooltip key={row.vin} title={`Send cancel for ${row.vin}`}>
|
<RoleWrap
|
||||||
<Link to="#" onClick={() => sendCancel(row)}>
|
groups={groups}
|
||||||
<CancelIcon />
|
providers={providers}
|
||||||
</Link>
|
rolesPerProvider={Permissions.FiskerCreate}
|
||||||
</Tooltip>
|
eitherComponent={<>No action</>}
|
||||||
|
>
|
||||||
|
<Tooltip key={row.vin} title={`Send cancel for ${row.vin}`}>
|
||||||
|
<Link to="#" onClick={() => sendCancel(row)}>
|
||||||
|
<CancelIcon />
|
||||||
|
</Link>
|
||||||
|
</Tooltip>
|
||||||
|
</RoleWrap>
|
||||||
</TableCell>
|
</TableCell>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
))}
|
))}
|
||||||
|
|||||||
@@ -49,9 +49,7 @@ const MainForm = () => {
|
|||||||
const onSubmit = async (e) => {
|
const onSubmit = async (e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
try {
|
try {
|
||||||
const data = {name, type};
|
const result = await updateManifest(manifest_id, {name, type}, token);
|
||||||
console.log(data);
|
|
||||||
const result = await updateManifest(manifest_id, data, token);
|
|
||||||
if (!result || result.error) return;
|
if (!result || result.error) return;
|
||||||
|
|
||||||
setMessage(`Updated manifest ${manifest_id}`);
|
setMessage(`Updated manifest ${manifest_id}`);
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import { ManifestsProvider } from "../../Contexts/ManifestsContext";
|
|||||||
import { UserProvider, setToken } from "../../Contexts/UserContext";
|
import { UserProvider, setToken } from "../../Contexts/UserContext";
|
||||||
import { StatusProvider } from "../../Contexts/StatusContext";
|
import { StatusProvider } from "../../Contexts/StatusContext";
|
||||||
import ManifestUpdate from ".";
|
import ManifestUpdate from ".";
|
||||||
import { TEST_AUTH_OBJECT } from "../../../utils/testing";
|
import { TEST_AUTH_OBJECT_FISKER } from "../../../utils/testing";
|
||||||
import addSnapshotSerializer from "../../../utils/snapshot";
|
import addSnapshotSerializer from "../../../utils/snapshot";
|
||||||
|
|
||||||
const renderManifestUpdate = async () => {
|
const renderManifestUpdate = async () => {
|
||||||
@@ -33,12 +33,12 @@ const renderManifestUpdate = async () => {
|
|||||||
|
|
||||||
describe("Manifest Details Component", () => {
|
describe("Manifest Details Component", () => {
|
||||||
beforeAll(() => {
|
beforeAll(() => {
|
||||||
setToken(TEST_AUTH_OBJECT);
|
setToken(TEST_AUTH_OBJECT_FISKER);
|
||||||
addSnapshotSerializer(expect);
|
addSnapshotSerializer(expect);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Render", async () => {
|
it("Render", async () => {
|
||||||
setToken(TEST_AUTH_OBJECT);
|
setToken(TEST_AUTH_OBJECT_FISKER);
|
||||||
const view = await renderManifestUpdate();
|
const view = await renderManifestUpdate();
|
||||||
expect(view).toMatchSnapshot();
|
expect(view).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ export const TYPES = {
|
|||||||
PROTECTED: 2,
|
PROTECTED: 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
export const AuthRoute = ({ token, type, roles, groups, ...others }) => {
|
export const AuthRoute = ({ token, type, groups, rolesPerGroup, providers, ...others }) => {
|
||||||
if (type === TYPES.PROTECTED && !token) {
|
if (type === TYPES.PROTECTED && !token) {
|
||||||
return <Redirect to="/" />;
|
return <Redirect to="/" />;
|
||||||
} else if (type === TYPES.GUEST && token) {
|
} else if (type === TYPES.GUEST && token) {
|
||||||
@@ -16,8 +16,9 @@ export const AuthRoute = ({ token, type, roles, groups, ...others }) => {
|
|||||||
} else if (
|
} else if (
|
||||||
type === TYPES.PROTECTED &&
|
type === TYPES.PROTECTED &&
|
||||||
token &&
|
token &&
|
||||||
roles &&
|
rolesPerGroup &&
|
||||||
!hasRole(roles, groups)
|
providers &&
|
||||||
|
!hasRole(groups, rolesPerGroup, providers)
|
||||||
) {
|
) {
|
||||||
return <Redirect to="/home" />;
|
return <Redirect to="/home" />;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
import React, { Suspense } from "react";
|
import React, { Suspense } from "react";
|
||||||
import { Switch } from "react-router-dom";
|
import { Switch } from "react-router-dom";
|
||||||
|
|
||||||
import { AuthRoute, TYPES } from "../Routes/AuthRoute";
|
import { Permissions } from "../../utils/roles";
|
||||||
import { MessageBar } from "../MessageBar";
|
|
||||||
import { useUserContext } from "../Contexts/UserContext";
|
import { useUserContext } from "../Contexts/UserContext";
|
||||||
import { Roles } from "../../utils/roles";
|
import { MessageBar } from "../MessageBar";
|
||||||
|
import { AuthRoute, TYPES } from "../Routes/AuthRoute";
|
||||||
|
|
||||||
const CANFilterCreate = React.lazy(() => import("../CANFilter/Add"));
|
const CANFilterCreate = React.lazy(() => import("../CANFilter/Add"));
|
||||||
const CANFilterUpdate = React.lazy(() => import("../CANFilter/Update"));
|
const CANFilterUpdate = React.lazy(() => import("../CANFilter/Update"));
|
||||||
@@ -39,7 +39,7 @@ const SuppliersList = React.lazy(() => import("../Suppliers/List"));
|
|||||||
const SupplierDetails = React.lazy(() => import("../Suppliers/Details"));
|
const SupplierDetails = React.lazy(() => import("../Suppliers/Details"));
|
||||||
const Datascope = React.lazy(() => import("../Dashboard"));
|
const Datascope = React.lazy(() => import("../Dashboard"));
|
||||||
const SiteRoutes = () => {
|
const SiteRoutes = () => {
|
||||||
const { token, groups } = useUserContext();
|
const { token, groups, providers } = useUserContext();
|
||||||
return (
|
return (
|
||||||
<Suspense fallback={"Loading..."}>
|
<Suspense fallback={"Loading..."}>
|
||||||
<MessageBar />
|
<MessageBar />
|
||||||
@@ -57,7 +57,8 @@ const SiteRoutes = () => {
|
|||||||
type={TYPES.PROTECTED}
|
type={TYPES.PROTECTED}
|
||||||
token={token}
|
token={token}
|
||||||
groups={groups}
|
groups={groups}
|
||||||
roles={[Roles.CREATE]}
|
rolesPerGroup={Permissions.FiskerCreate}
|
||||||
|
providers={providers}
|
||||||
/>
|
/>
|
||||||
<AuthRoute
|
<AuthRoute
|
||||||
path="/filter-update"
|
path="/filter-update"
|
||||||
@@ -65,7 +66,8 @@ const SiteRoutes = () => {
|
|||||||
type={TYPES.PROTECTED}
|
type={TYPES.PROTECTED}
|
||||||
token={token}
|
token={token}
|
||||||
groups={groups}
|
groups={groups}
|
||||||
roles={[Roles.CREATE]}
|
rolesPerGroup={Permissions.FiskerCreate}
|
||||||
|
providers={providers}
|
||||||
/>
|
/>
|
||||||
<AuthRoute
|
<AuthRoute
|
||||||
path="/fleets"
|
path="/fleets"
|
||||||
@@ -73,7 +75,8 @@ const SiteRoutes = () => {
|
|||||||
type={TYPES.PROTECTED}
|
type={TYPES.PROTECTED}
|
||||||
token={token}
|
token={token}
|
||||||
groups={groups}
|
groups={groups}
|
||||||
roles={[Roles.READ, Roles.CREATE]}
|
rolesPerGroup={Permissions.FiskerRead}
|
||||||
|
providers={providers}
|
||||||
/>
|
/>
|
||||||
<AuthRoute
|
<AuthRoute
|
||||||
path="/fleet/:name/vehicle-add"
|
path="/fleet/:name/vehicle-add"
|
||||||
@@ -81,7 +84,8 @@ const SiteRoutes = () => {
|
|||||||
type={TYPES.PROTECTED}
|
type={TYPES.PROTECTED}
|
||||||
token={token}
|
token={token}
|
||||||
groups={groups}
|
groups={groups}
|
||||||
roles={[Roles.READ, Roles.CREATE]}
|
rolesPerGroup={Permissions.FiskerCreate}
|
||||||
|
providers={providers}
|
||||||
/>
|
/>
|
||||||
<AuthRoute
|
<AuthRoute
|
||||||
path="/fleet/:name/filter-add"
|
path="/fleet/:name/filter-add"
|
||||||
@@ -89,7 +93,8 @@ const SiteRoutes = () => {
|
|||||||
type={TYPES.PROTECTED}
|
type={TYPES.PROTECTED}
|
||||||
token={token}
|
token={token}
|
||||||
groups={groups}
|
groups={groups}
|
||||||
roles={[Roles.READ, Roles.CREATE]}
|
rolesPerGroup={Permissions.FiskerCreate}
|
||||||
|
providers={providers}
|
||||||
/>
|
/>
|
||||||
<AuthRoute
|
<AuthRoute
|
||||||
path="/fleet/:name/filter-update"
|
path="/fleet/:name/filter-update"
|
||||||
@@ -97,7 +102,8 @@ const SiteRoutes = () => {
|
|||||||
type={TYPES.PROTECTED}
|
type={TYPES.PROTECTED}
|
||||||
token={token}
|
token={token}
|
||||||
groups={groups}
|
groups={groups}
|
||||||
roles={[Roles.READ, Roles.CREATE]}
|
rolesPerGroup={Permissions.FiskerCreate}
|
||||||
|
providers={providers}
|
||||||
/>
|
/>
|
||||||
<AuthRoute
|
<AuthRoute
|
||||||
path="/fleet/:name"
|
path="/fleet/:name"
|
||||||
@@ -105,7 +111,8 @@ const SiteRoutes = () => {
|
|||||||
type={TYPES.PROTECTED}
|
type={TYPES.PROTECTED}
|
||||||
token={token}
|
token={token}
|
||||||
groups={groups}
|
groups={groups}
|
||||||
roles={[Roles.READ, Roles.CREATE]}
|
rolesPerGroup={Permissions.FiskerRead}
|
||||||
|
providers={providers}
|
||||||
/>
|
/>
|
||||||
<AuthRoute
|
<AuthRoute
|
||||||
path="/fleet-add"
|
path="/fleet-add"
|
||||||
@@ -113,7 +120,8 @@ const SiteRoutes = () => {
|
|||||||
type={TYPES.PROTECTED}
|
type={TYPES.PROTECTED}
|
||||||
token={token}
|
token={token}
|
||||||
groups={groups}
|
groups={groups}
|
||||||
roles={[Roles.CREATE]}
|
rolesPerGroup={Permissions.FiskerCreate}
|
||||||
|
providers={providers}
|
||||||
/>
|
/>
|
||||||
<AuthRoute
|
<AuthRoute
|
||||||
path="/fleet-update"
|
path="/fleet-update"
|
||||||
@@ -121,7 +129,8 @@ const SiteRoutes = () => {
|
|||||||
type={TYPES.PROTECTED}
|
type={TYPES.PROTECTED}
|
||||||
token={token}
|
token={token}
|
||||||
groups={groups}
|
groups={groups}
|
||||||
roles={[Roles.CREATE]}
|
rolesPerGroup={Permissions.FiskerCreate}
|
||||||
|
providers={providers}
|
||||||
/>
|
/>
|
||||||
<AuthRoute
|
<AuthRoute
|
||||||
path="/home"
|
path="/home"
|
||||||
@@ -135,7 +144,8 @@ const SiteRoutes = () => {
|
|||||||
type={TYPES.PROTECTED}
|
type={TYPES.PROTECTED}
|
||||||
token={token}
|
token={token}
|
||||||
groups={groups}
|
groups={groups}
|
||||||
roles={[Roles.READ, Roles.CREATE]}
|
rolesPerGroup={Permissions.FiskerMagnaRead}
|
||||||
|
providers={providers}
|
||||||
/>
|
/>
|
||||||
<AuthRoute
|
<AuthRoute
|
||||||
path="/package-deploy/:manifest_id"
|
path="/package-deploy/:manifest_id"
|
||||||
@@ -143,7 +153,8 @@ const SiteRoutes = () => {
|
|||||||
type={TYPES.PROTECTED}
|
type={TYPES.PROTECTED}
|
||||||
token={token}
|
token={token}
|
||||||
groups={groups}
|
groups={groups}
|
||||||
roles={[Roles.CREATE]}
|
rolesPerGroup={Permissions.FiskerMagnaCreate}
|
||||||
|
providers={providers}
|
||||||
/>
|
/>
|
||||||
<AuthRoute
|
<AuthRoute
|
||||||
path="/package-status/:manifest_id"
|
path="/package-status/:manifest_id"
|
||||||
@@ -151,7 +162,8 @@ const SiteRoutes = () => {
|
|||||||
type={TYPES.PROTECTED}
|
type={TYPES.PROTECTED}
|
||||||
token={token}
|
token={token}
|
||||||
groups={groups}
|
groups={groups}
|
||||||
roles={[Roles.READ, Roles.CREATE]}
|
rolesPerGroup={Permissions.FiskerMagnaRead}
|
||||||
|
providers={providers}
|
||||||
/>
|
/>
|
||||||
<AuthRoute
|
<AuthRoute
|
||||||
path="/package-update/:manifest_id"
|
path="/package-update/:manifest_id"
|
||||||
@@ -159,7 +171,8 @@ const SiteRoutes = () => {
|
|||||||
type={TYPES.PROTECTED}
|
type={TYPES.PROTECTED}
|
||||||
token={token}
|
token={token}
|
||||||
groups={groups}
|
groups={groups}
|
||||||
roles={[Roles.READ, Roles.CREATE]}
|
rolesPerGroup={Permissions.FiskerRead}
|
||||||
|
providers={providers}
|
||||||
/>
|
/>
|
||||||
<AuthRoute
|
<AuthRoute
|
||||||
path="/vehicles"
|
path="/vehicles"
|
||||||
@@ -167,7 +180,8 @@ const SiteRoutes = () => {
|
|||||||
type={TYPES.PROTECTED}
|
type={TYPES.PROTECTED}
|
||||||
token={token}
|
token={token}
|
||||||
groups={groups}
|
groups={groups}
|
||||||
roles={[Roles.READ, Roles.CREATE]}
|
rolesPerGroup={Permissions.FiskerMagnaRead}
|
||||||
|
providers={providers}
|
||||||
/>
|
/>
|
||||||
<AuthRoute
|
<AuthRoute
|
||||||
path="/vehicle-add"
|
path="/vehicle-add"
|
||||||
@@ -175,7 +189,8 @@ const SiteRoutes = () => {
|
|||||||
type={TYPES.PROTECTED}
|
type={TYPES.PROTECTED}
|
||||||
token={token}
|
token={token}
|
||||||
groups={groups}
|
groups={groups}
|
||||||
roles={[Roles.CREATE]}
|
rolesPerGroup={Permissions.FiskerCreate}
|
||||||
|
providers={providers}
|
||||||
/>
|
/>
|
||||||
<AuthRoute
|
<AuthRoute
|
||||||
path="/vehicle-status/:vin/:carupdateid"
|
path="/vehicle-status/:vin/:carupdateid"
|
||||||
@@ -183,7 +198,8 @@ const SiteRoutes = () => {
|
|||||||
type={TYPES.PROTECTED}
|
type={TYPES.PROTECTED}
|
||||||
token={token}
|
token={token}
|
||||||
groups={groups}
|
groups={groups}
|
||||||
roles={[Roles.READ, Roles.CREATE]}
|
rolesPerGroup={Permissions.FiskerMagnaRead}
|
||||||
|
providers={providers}
|
||||||
/>
|
/>
|
||||||
<AuthRoute
|
<AuthRoute
|
||||||
path="/vehicle-status/:vin"
|
path="/vehicle-status/:vin"
|
||||||
@@ -191,7 +207,8 @@ const SiteRoutes = () => {
|
|||||||
type={TYPES.PROTECTED}
|
type={TYPES.PROTECTED}
|
||||||
token={token}
|
token={token}
|
||||||
groups={groups}
|
groups={groups}
|
||||||
roles={[Roles.READ, Roles.CREATE]}
|
rolesPerGroup={Permissions.FiskerMagnaRead}
|
||||||
|
providers={providers}
|
||||||
/>
|
/>
|
||||||
<AuthRoute
|
<AuthRoute
|
||||||
path="/vehicle-update"
|
path="/vehicle-update"
|
||||||
@@ -199,7 +216,8 @@ const SiteRoutes = () => {
|
|||||||
type={TYPES.PROTECTED}
|
type={TYPES.PROTECTED}
|
||||||
token={token}
|
token={token}
|
||||||
groups={groups}
|
groups={groups}
|
||||||
roles={[Roles.CREATE]}
|
rolesPerGroup={Permissions.FiskerCreate}
|
||||||
|
providers={providers}
|
||||||
/>
|
/>
|
||||||
<AuthRoute
|
<AuthRoute
|
||||||
path="/tools/certificates/add"
|
path="/tools/certificates/add"
|
||||||
@@ -207,7 +225,8 @@ const SiteRoutes = () => {
|
|||||||
type={TYPES.PROTECTED}
|
type={TYPES.PROTECTED}
|
||||||
token={token}
|
token={token}
|
||||||
groups={groups}
|
groups={groups}
|
||||||
roles={[Roles.CERTIFICATES]}
|
rolesPerGroup={Permissions.FiskerCertificate}
|
||||||
|
providers={providers}
|
||||||
/>
|
/>
|
||||||
<AuthRoute
|
<AuthRoute
|
||||||
path="/tools/sms/send"
|
path="/tools/sms/send"
|
||||||
@@ -215,7 +234,8 @@ const SiteRoutes = () => {
|
|||||||
type={TYPES.PROTECTED}
|
type={TYPES.PROTECTED}
|
||||||
token={token}
|
token={token}
|
||||||
groups={groups}
|
groups={groups}
|
||||||
roles={[Roles.CREATE]}
|
rolesPerGroup={Permissions.FiskerCreate}
|
||||||
|
providers={providers}
|
||||||
/>
|
/>
|
||||||
<AuthRoute
|
<AuthRoute
|
||||||
path="/suppliers"
|
path="/suppliers"
|
||||||
@@ -223,7 +243,8 @@ const SiteRoutes = () => {
|
|||||||
type={TYPES.PROTECTED}
|
type={TYPES.PROTECTED}
|
||||||
token={token}
|
token={token}
|
||||||
groups={groups}
|
groups={groups}
|
||||||
roles={[Roles.APPROVESUPPLIERS]}
|
rolesPerGroup={Permissions.FiskerSupplierAdmin}
|
||||||
|
providers={providers}
|
||||||
/>
|
/>
|
||||||
<AuthRoute
|
<AuthRoute
|
||||||
path="/supplier/:email"
|
path="/supplier/:email"
|
||||||
@@ -231,7 +252,8 @@ const SiteRoutes = () => {
|
|||||||
type={TYPES.PROTECTED}
|
type={TYPES.PROTECTED}
|
||||||
token={token}
|
token={token}
|
||||||
groups={groups}
|
groups={groups}
|
||||||
roles={[Roles.APPROVESUPPLIERS]}
|
rolesPerGroup={Permissions.FiskerSupplierAdmin}
|
||||||
|
providers={providers}
|
||||||
/>
|
/>
|
||||||
<AuthRoute
|
<AuthRoute
|
||||||
path="/datascope"
|
path="/datascope"
|
||||||
@@ -239,7 +261,8 @@ const SiteRoutes = () => {
|
|||||||
type={TYPES.PROTECTED}
|
type={TYPES.PROTECTED}
|
||||||
token={token}
|
token={token}
|
||||||
groups={groups}
|
groups={groups}
|
||||||
roles={[Roles.READ, Roles.CREATE]}
|
rolesPerGroup={Permissions.FiskerRead}
|
||||||
|
providers={providers}
|
||||||
/>
|
/>
|
||||||
<PageNotFound />
|
<PageNotFound />
|
||||||
</Switch>
|
</Switch>
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ import { BrowserRouter } from "react-router-dom";
|
|||||||
import { SupplierProvider } from "../../Contexts/SupplierContext";
|
import { SupplierProvider } from "../../Contexts/SupplierContext";
|
||||||
import { StatusProvider } from "../../Contexts/StatusContext";
|
import { StatusProvider } from "../../Contexts/StatusContext";
|
||||||
import { UserProvider, setToken } from "../../Contexts/UserContext";
|
import { UserProvider, setToken } from "../../Contexts/UserContext";
|
||||||
import { TEST_AUTH_OBJECT } from "../../../utils/testing";
|
import { TEST_AUTH_OBJECT_FISKER } from "../../../utils/testing";
|
||||||
import MainForm from "./index";
|
import MainForm from "./index";
|
||||||
import addSnapshotSerializer from "../../../utils/snapshot";
|
import addSnapshotSerializer from "../../../utils/snapshot";
|
||||||
|
|
||||||
@@ -43,7 +43,7 @@ describe("Supplier page", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("Render", async () => {
|
it("Render", async () => {
|
||||||
setToken(TEST_AUTH_OBJECT);
|
setToken(TEST_AUTH_OBJECT_FISKER);
|
||||||
const container = await renderSupplierDetailsPage();
|
const container = await renderSupplierDetailsPage();
|
||||||
expect(container).toMatchSnapshot();
|
expect(container).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import { BrowserRouter } from "react-router-dom";
|
|||||||
import { SupplierProvider } from "../../Contexts/SupplierContext";
|
import { SupplierProvider } from "../../Contexts/SupplierContext";
|
||||||
import { StatusProvider } from "../../Contexts/StatusContext";
|
import { StatusProvider } from "../../Contexts/StatusContext";
|
||||||
import { UserProvider, setToken } from "../../Contexts/UserContext";
|
import { UserProvider, setToken } from "../../Contexts/UserContext";
|
||||||
import { TEST_AUTH_OBJECT } from "../../../utils/testing";
|
import { TEST_AUTH_OBJECT_FISKER } from "../../../utils/testing";
|
||||||
import MainForm from "./index";
|
import MainForm from "./index";
|
||||||
import addSnapshotSerializer from "../../../utils/snapshot";
|
import addSnapshotSerializer from "../../../utils/snapshot";
|
||||||
|
|
||||||
@@ -38,7 +38,7 @@ describe("Suppliers page", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("Render", async () => {
|
it("Render", async () => {
|
||||||
setToken(TEST_AUTH_OBJECT);
|
setToken(TEST_AUTH_OBJECT_FISKER);
|
||||||
const container = await renderSuppliersPage();
|
const container = await renderSuppliersPage();
|
||||||
expect(container).toMatchSnapshot();
|
expect(container).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -6,16 +6,12 @@ export const Roles = {
|
|||||||
DELETE: "8f78dce7-f5f9-4033-a10c-c9c7408bfcfe",
|
DELETE: "8f78dce7-f5f9-4033-a10c-c9c7408bfcfe",
|
||||||
CERTIFICATES: "746f34b0-9ba0-4b5d-8d84-0256a9c8e390",
|
CERTIFICATES: "746f34b0-9ba0-4b5d-8d84-0256a9c8e390",
|
||||||
APPROVESUPPLIERS: "a6c9805e-80b2-42b2-bfbb-9df52e5504d8",
|
APPROVESUPPLIERS: "a6c9805e-80b2-42b2-bfbb-9df52e5504d8",
|
||||||
|
MAGNAGROUP: process.env.REACT_APP_MAGNA_GROUP_ID,
|
||||||
};
|
};
|
||||||
|
|
||||||
export const hasRoleToken = (roles, token) => {
|
export const Providers = {
|
||||||
if (!roles || roles.length === 0) return true;
|
FISKER: "Fisker",
|
||||||
|
MAGNA: process.env.REACT_APP_MAGNA_PROVIDER,
|
||||||
const groups = getGroups(token);
|
|
||||||
|
|
||||||
if (!groups) return false;
|
|
||||||
|
|
||||||
return hasRole(roles, groups);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getGroups = (token) => {
|
export const getGroups = (token) => {
|
||||||
@@ -26,13 +22,54 @@ export const getGroups = (token) => {
|
|||||||
return payload["custom:groups"];
|
return payload["custom:groups"];
|
||||||
};
|
};
|
||||||
|
|
||||||
export const hasRole = (roles, groups) => {
|
export const getProviders = (token) => {
|
||||||
if (!roles || roles.length === 0) return true;
|
const payload = parsePayload(token);
|
||||||
if (!groups) return false;
|
|
||||||
|
|
||||||
for (let role of roles) {
|
if (!payload || !payload["identities"] || payload["identities"].length === 0)
|
||||||
if (groups.indexOf(role) > -1) return true;
|
return null;
|
||||||
|
|
||||||
|
return payload["identities"].map((identity) => identity["providerName"]);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const hasRole = (userGroups, rolesPerProvider, userProviders) => {
|
||||||
|
if (!rolesPerProvider || rolesPerProvider.length === 0) return true;
|
||||||
|
|
||||||
|
if (!userGroups || userGroups.length === 0) return false;
|
||||||
|
|
||||||
|
if (rolesPerProvider && userProviders) {
|
||||||
|
for (const provider of userProviders) {
|
||||||
|
if (rolesPerProvider[provider]) {
|
||||||
|
const rolesForProvider = rolesPerProvider[provider];
|
||||||
|
if (!rolesForProvider || rolesForProvider.length === 0) return true;
|
||||||
|
if (
|
||||||
|
rolesForProvider.filter((role) => userGroups.includes(role)).length >
|
||||||
|
0
|
||||||
|
) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const Permissions = {
|
||||||
|
FiskerRead: { [Providers.FISKER]: [Roles.CREATE, Roles.READ] },
|
||||||
|
FiskerCreate: { [Providers.FISKER]: [Roles.CREATE] },
|
||||||
|
FiskerDelete: { [Providers.FISKER]: [Roles.DELETE] },
|
||||||
|
FiskerSupplierAdmin: { [Providers.FISKER]: [Roles.APPROVESUPPLIERS] },
|
||||||
|
FiskerCertificate: { [Providers.FISKER]: [Roles.CERTIFICATES] },
|
||||||
|
FiskerTools: {
|
||||||
|
[Providers.FISKER]: [Roles.APPROVESUPPLIERS, Roles.CERTIFICATES],
|
||||||
|
},
|
||||||
|
Magna: { [Providers.MAGNA]: [Roles.MAGNAGROUP] },
|
||||||
|
FiskerMagnaRead: {
|
||||||
|
[Providers.FISKER]: [Roles.CREATE, Roles.READ],
|
||||||
|
[Providers.MAGNA]: [Roles.MAGNAGROUP],
|
||||||
|
},
|
||||||
|
FiskerMagnaCreate: {
|
||||||
|
[Providers.FISKER]: [Roles.CREATE],
|
||||||
|
[Providers.MAGNA]: [Roles.MAGNAGROUP],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|||||||
@@ -1,10 +1,28 @@
|
|||||||
|
import {
|
||||||
import { hasRoleToken, Roles } from "./roles";
|
getGroups,
|
||||||
import { TEST_TOKEN } from "./testing";
|
getProviders,
|
||||||
|
hasRole,
|
||||||
|
Permissions,
|
||||||
|
Providers,
|
||||||
|
Roles,
|
||||||
|
} from "./roles";
|
||||||
|
import { TEST_EXPECTED_GROUPS, TEST_TOKEN } from "./testing";
|
||||||
|
|
||||||
describe("Roles Helper", () => {
|
describe("Roles Helper", () => {
|
||||||
it("Check roles", () => {
|
it("Check roles", () => {
|
||||||
expect(hasRoleToken([Roles.CREATE], TEST_TOKEN)).toEqual(true);
|
expect(
|
||||||
expect(hasRoleToken([Roles.READ], TEST_TOKEN)).toEqual(false);
|
hasRole([Roles.CREATE], Permissions.FiskerCreate, [Providers.FISKER])
|
||||||
})
|
).toEqual(true);
|
||||||
|
expect(
|
||||||
|
hasRole([Roles.READ], Permissions.FiskerCreate, [Providers.FISKER])
|
||||||
|
).toEqual(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Get groups", () => {
|
||||||
|
expect(getGroups(TEST_TOKEN)).toEqual(TEST_EXPECTED_GROUPS);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Get providers", () => {
|
||||||
|
expect(getProviders(TEST_TOKEN)).toEqual(["AzureAD"]);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -5,5 +5,13 @@ export const TEST_AUTH_OBJECT = {
|
|||||||
jwtToken: TEST_TOKEN,
|
jwtToken: TEST_TOKEN,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const TEST_TOKEN_FISKER =
|
||||||
|
"eyJraWQiOiJlUTNuZFJLaUVcL084VUZ5RHFsYjN0S1RzWG00SzVPMlc4NXd3VWkzT2tNZz0iLCJhbGciOiJSUzI1NiJ9.eyJhdF9oYXNoIjoiODIwNTViMm9CUl9HQURiMXVyU3V3dyIsInN1YiI6ImEwZDAzMzA5LWQxYzMtNGNhZi05Zjc3LWJlMDE5N2ZlOGE1OSIsImNvZ25pdG86Z3JvdXBzIjpbInVzLXdlc3QtMl9BV3dqTFh5bTJfRmlza2VyIl0sImVtYWlsX3ZlcmlmaWVkIjpmYWxzZSwiaXNzIjoiaHR0cHM6XC9cL2NvZ25pdG8taWRwLnVzLXdlc3QtMi5hbWF6b25hd3MuY29tXC91cy13ZXN0LTJfQVd3akxYeW0yIiwiY29nbml0bzp1c2VybmFtZSI6ImZpc2tlcl9hdW1hcm92QGZpc2tlcmluYy5jb20iLCJnaXZlbl9uYW1lIjoiQW52YXIiLCJjdXN0b206Z3JvdXBzIjoiWzhkODI3OGE1LTljMGUtNGM3Zi05MThhLTgxMWZkMWQyMzZlNCwgNzQ2ZjM0YjAtOWJhMC00YjVkLThkODQtMDI1NmE5YzhlMzkwLCA2MDcxZWFiYS1kNjY2LTRjMDMtODE3Yi1jMjgyYTk1MWI5NjYsIGFjYmQ3MmM5LTlmZjMtNDZhOC04M2JhLWM2ZmE1ZGYzZjI2NCwgNzM3ZTQ0OWMtMjMwOS00NjllLWFhNDgtNDZlNjg5MTk4M2MwLCBmNjNiNjQzMC0xMjg4LTQwYTgtYWE0OS04NDM4NTE1MGQ2YTgsIDg3NzcwYWVhLTkxNjItNDA5ZS1hYTcwLTEwZDBkMWRlNTkwMiwgYTZjOTgwNWUtODBiMi00MmIyLWJmYmItOWRmNTJlNTUwNGQ4LCBiYWZjMTdhNy1lYzY0LTQ5ZDktYTJhNy1kYWZjMjhkY2IwMzcsIDI0NDljMDY2LTkxNDYtNDRhNy1iNGU2LTQ4MjgwMzFkOTU4ZCwgZWZjYzMwMjUtZTJkOC00MjEyLTgyMjctODA1YzdiZTM5ZDJjLCAyNzNjN2MwZC01MWQzLTRhMzEtOTQ0My1jNDM2NzU3MmVlNGYsIDcwZmU1OWM2LTFkNjktNGRmZS05N2I5LWZhZTQzMjE1MTAxOSwgODY5NTZhMmYtOGQ0Ni00N2ZmLTliMjktZjk5MDc5YWUzYzFkLCBiMGU4MmU4My0yYzk0LTRiMjQtYjljNy1lNzc4MTZmMjU5N2RdIiwiYXVkIjoiN2NrMnRmb3FhdmM3MmM0NWhoN3RnZTQya2QiLCJjdXN0b206c2Vzc2lvbi1kdXJhdGlvbiI6IjkwMCIsImlkZW50aXRpZXMiOlt7InVzZXJJZCI6ImF1bWFyb3ZAZmlza2VyaW5jLmNvbSIsInByb3ZpZGVyTmFtZSI6IkZpc2tlciIsInByb3ZpZGVyVHlwZSI6IlNBTUwiLCJpc3N1ZXIiOiJodHRwczpcL1wvc3RzLndpbmRvd3MubmV0XC81YWE0YjY0MC1jOWZjLTRhOWItYjNhMy1kNGE3ZDAwOGZiNWVcLyIsInByaW1hcnkiOiJ0cnVlIiwiZGF0ZUNyZWF0ZWQiOiIxNjY0ODA3MDE1NzQ3In1dLCJ0b2tlbl91c2UiOiJpZCIsImF1dGhfdGltZSI6MTY2Nzc1NjIzOCwiZXhwIjoxNjY3NzU5ODM4LCJpYXQiOjE2Njc3NTYyMzgsImZhbWlseV9uYW1lIjoiVW1hcm92IiwiZW1haWwiOiJhdW1hcm92QGZpc2tlcmluYy5jb20ifQ.ZZC7tgMMjRpRNJcGdp7ftXJQJ6pjzP45SJAcfJRZC4oUHG-h5BI1bGKEKmslWdK09GEH1cN7YDGQg8ufkKOyncm-J5DRNvj27fN--Lapkg1Q0bHT8pwMDXRjPUbazLEwEvfo1yGyLBOBopxdisQvv9km8-UH3Xy7a7IsCOWx51xKsgMWho4w4BK1PQUBpUrG0h-tno7-7nHO4gwr4urCtDPIoMjsq_lF77LDvM3SBdCH28ogaoDE3ogd1tbBpwHXtOhnp-FMp85I2Vk-pI_KsiW3RXr50OdeAVEfFLFKhjCCoB5RR6pKxWJXs-7BN91Tnn7SYgfAWt5Wa2cxBxMUDg"
|
||||||
|
export const TEST_AUTH_OBJECT_FISKER = {
|
||||||
|
idToken: {
|
||||||
|
jwtToken: TEST_TOKEN_FISKER
|
||||||
|
},
|
||||||
|
}
|
||||||
export const TEST_EXPECTED_GROUPS =
|
export const TEST_EXPECTED_GROUPS =
|
||||||
"[2914e67f-fb85-4b78-b79d-656f4f37faa1, 8d8278a5-9c0e-4c7f-918a-811fd1d236e4, 746f34b0-9ba0-4b5d-8d84-0256a9c8e390, 6c3cf98d-0ada-48c6-ae94-b171cfa275fc, acbd72c9-9ff3-46a8-83ba-c6fa5df3f264, 5e59a619-c890-4472-91c2-d5eae5d8fa18, 56ef4bec-d739-4ddf-a003-ecc813085b8d, 929b0470-f7eb-4e18-9f97-22ac2c591a10, 131e6257-fdb7-426a-9825-1cd918802fba, 1ac794cc-76ac-47f6-bee6-d6666998f0fd, 87770aea-9162-409e-aa70-10d0d1de5902, 5dea6c32-6575-4527-9254-e50d27ae5e92, bafc17a7-ec64-49d9-a2a7-dafc28dcb037, 2449c066-9146-44a7-b4e6-4828031d958d, efcc3025-e2d8-4212-8227-805c7be39d2c, 8f78dce7-f5f9-4033-a10c-c9c7408bfcfe, cf653183-c829-4eed-a6ce-453fa1017cd9, 783c5979-f5e7-4cb6-b14e-c3553dde956a, 5515a98f-4668-4121-8e8d-fee2825699cf, 86956a2f-8d46-47ff-9b29-f99079ae3c1d, c4d4361c-8882-47b4-8641-fd3ab68ae722, 972ad095-16b7-40ad-a464-f5dbf417a8cd, 7bcdcdb2-3279-44bf-a998-771bab4b33e1]";
|
"[2914e67f-fb85-4b78-b79d-656f4f37faa1, 8d8278a5-9c0e-4c7f-918a-811fd1d236e4, 746f34b0-9ba0-4b5d-8d84-0256a9c8e390, 6c3cf98d-0ada-48c6-ae94-b171cfa275fc, acbd72c9-9ff3-46a8-83ba-c6fa5df3f264, 5e59a619-c890-4472-91c2-d5eae5d8fa18, 56ef4bec-d739-4ddf-a003-ecc813085b8d, 929b0470-f7eb-4e18-9f97-22ac2c591a10, 131e6257-fdb7-426a-9825-1cd918802fba, 1ac794cc-76ac-47f6-bee6-d6666998f0fd, 87770aea-9162-409e-aa70-10d0d1de5902, 5dea6c32-6575-4527-9254-e50d27ae5e92, bafc17a7-ec64-49d9-a2a7-dafc28dcb037, 2449c066-9146-44a7-b4e6-4828031d958d, efcc3025-e2d8-4212-8227-805c7be39d2c, 8f78dce7-f5f9-4033-a10c-c9c7408bfcfe, cf653183-c829-4eed-a6ce-453fa1017cd9, 783c5979-f5e7-4cb6-b14e-c3553dde956a, 5515a98f-4668-4121-8e8d-fee2825699cf, 86956a2f-8d46-47ff-9b29-f99079ae3c1d, c4d4361c-8882-47b4-8641-fd3ab68ae722, 972ad095-16b7-40ad-a464-f5dbf417a8cd, 7bcdcdb2-3279-44bf-a998-771bab4b33e1]";
|
||||||
|
|||||||
Reference in New Issue
Block a user