From 058edb63ba05ddf7699b8bb8247cb2f298070d2b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 25 Jul 2022 18:06:17 -0700 Subject: [PATCH 1/7] Bump terser from 5.12.0 to 5.14.2 (#170) Bumps [terser](https://github.com/terser/terser) from 5.12.0 to 5.14.2. - [Release notes](https://github.com/terser/terser/releases) - [Changelog](https://github.com/terser/terser/blob/master/CHANGELOG.md) - [Commits](https://github.com/terser/terser/compare/v5.12.0...v5.14.2) --- updated-dependencies: - dependency-name: terser dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 187 +++++++++++++++++----------------------------- 1 file changed, 68 insertions(+), 119 deletions(-) diff --git a/package-lock.json b/package-lock.json index 50501fd..ea0312a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4038,6 +4038,19 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", + "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", + "dependencies": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, "node_modules/@jridgewell/resolve-uri": { "version": "3.0.5", "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.0.5.tgz", @@ -4046,15 +4059,32 @@ "node": ">=6.0.0" } }, + "node_modules/@jridgewell/set-array": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", + "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/source-map": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.2.tgz", + "integrity": "sha512-m7O9o2uR8k2ObDysZYzdfhb08VuEml5oWGiosa1VdaPZ/A6QyPkAJuwN0Q1lhULOf6B7MtQmHENS743hWtCrgw==", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.0", + "@jridgewell/trace-mapping": "^0.3.9" + } + }, "node_modules/@jridgewell/sourcemap-codec": { "version": "1.4.11", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.11.tgz", "integrity": "sha512-Fg32GrJo61m+VqYSdRSjRXMjQ06j8YIYfcTqndLYVAaHmroZHLJZCydsWBOTDqXS2v+mjxohBWEMfg97GXmYQg==" }, "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.4.tgz", - "integrity": "sha512-vFv9ttIedivx0ux3QSjhgtCVjPZd5l46ZOMDSCwnH1yUO2e964gO8LZGyv2QkqcgR6TnBU1v+1IFqmeoG+0UJQ==", + "version": "0.3.14", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.14.tgz", + "integrity": "sha512-bJWEfQ9lPTvm3SneWwRFVLzrh6nhjwqw7TUFFBEMzwvg7t7PCDenf2lDwqo4NQXzdpgBXyFgDWnQA+2vkruksQ==", "dependencies": { "@jridgewell/resolve-uri": "^3.0.3", "@jridgewell/sourcemap-codec": "^1.4.10" @@ -7895,60 +7925,6 @@ "node": ">=8.0.0" } }, - "node_modules/env-cmd/node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/env-cmd/node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "engines": { - "node": ">=8" - } - }, - "node_modules/env-cmd/node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/env-cmd/node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "engines": { - "node": ">=8" - } - }, - "node_modules/env-cmd/node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, "node_modules/error-ex": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", @@ -15929,13 +15905,13 @@ } }, "node_modules/terser": { - "version": "5.12.0", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.12.0.tgz", - "integrity": "sha512-R3AUhNBGWiFc77HXag+1fXpAxTAFRQTJemlJKjAgD9r8xXTpjNKqIXwHM/o7Rh+O0kUJtS3WQVdBeMKFk5sw9A==", + "version": "5.14.2", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.14.2.tgz", + "integrity": "sha512-oL0rGeM/WFQCUd0y2QrWxYnq7tfSuKBiqTjRPWrRgB46WD/kiwHwF8T23z78H6Q6kGCuuHcPB+KULHRdxvVGQA==", "dependencies": { + "@jridgewell/source-map": "^0.3.2", "acorn": "^8.5.0", "commander": "^2.20.0", - "source-map": "~0.7.2", "source-map-support": "~0.5.20" }, "bin": { @@ -15983,14 +15959,6 @@ "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" }, - "node_modules/terser/node_modules/source-map": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", - "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", - "engines": { - "node": ">= 8" - } - }, "node_modules/test-exclude": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", @@ -20213,20 +20181,44 @@ } } }, + "@jridgewell/gen-mapping": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", + "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", + "requires": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + } + }, "@jridgewell/resolve-uri": { "version": "3.0.5", "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.0.5.tgz", "integrity": "sha512-VPeQ7+wH0itvQxnG+lIzWgkysKIr3L9sslimFW55rHMdGu/qCQ5z5h9zq4gI8uBtqkpHhsF4Z/OwExufUCThew==" }, + "@jridgewell/set-array": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", + "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==" + }, + "@jridgewell/source-map": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.2.tgz", + "integrity": "sha512-m7O9o2uR8k2ObDysZYzdfhb08VuEml5oWGiosa1VdaPZ/A6QyPkAJuwN0Q1lhULOf6B7MtQmHENS743hWtCrgw==", + "requires": { + "@jridgewell/gen-mapping": "^0.3.0", + "@jridgewell/trace-mapping": "^0.3.9" + } + }, "@jridgewell/sourcemap-codec": { "version": "1.4.11", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.11.tgz", "integrity": "sha512-Fg32GrJo61m+VqYSdRSjRXMjQ06j8YIYfcTqndLYVAaHmroZHLJZCydsWBOTDqXS2v+mjxohBWEMfg97GXmYQg==" }, "@jridgewell/trace-mapping": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.4.tgz", - "integrity": "sha512-vFv9ttIedivx0ux3QSjhgtCVjPZd5l46ZOMDSCwnH1yUO2e964gO8LZGyv2QkqcgR6TnBU1v+1IFqmeoG+0UJQ==", + "version": "0.3.14", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.14.tgz", + "integrity": "sha512-bJWEfQ9lPTvm3SneWwRFVLzrh6nhjwqw7TUFFBEMzwvg7t7PCDenf2lDwqo4NQXzdpgBXyFgDWnQA+2vkruksQ==", "requires": { "@jridgewell/resolve-uri": "^3.0.3", "@jridgewell/sourcemap-codec": "^1.4.10" @@ -23058,44 +23050,6 @@ "requires": { "commander": "^4.0.0", "cross-spawn": "^7.0.0" - }, - "dependencies": { - "cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "requires": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - } - }, - "path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==" - }, - "shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "requires": { - "shebang-regex": "^3.0.0" - } - }, - "shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==" - }, - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "requires": { - "isexe": "^2.0.0" - } - } } }, "error-ex": { @@ -28831,13 +28785,13 @@ } }, "terser": { - "version": "5.12.0", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.12.0.tgz", - "integrity": "sha512-R3AUhNBGWiFc77HXag+1fXpAxTAFRQTJemlJKjAgD9r8xXTpjNKqIXwHM/o7Rh+O0kUJtS3WQVdBeMKFk5sw9A==", + "version": "5.14.2", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.14.2.tgz", + "integrity": "sha512-oL0rGeM/WFQCUd0y2QrWxYnq7tfSuKBiqTjRPWrRgB46WD/kiwHwF8T23z78H6Q6kGCuuHcPB+KULHRdxvVGQA==", "requires": { + "@jridgewell/source-map": "^0.3.2", "acorn": "^8.5.0", "commander": "^2.20.0", - "source-map": "~0.7.2", "source-map-support": "~0.5.20" }, "dependencies": { @@ -28845,11 +28799,6 @@ "version": "2.20.3", "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" - }, - "source-map": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", - "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==" } } }, From b70afa53125801ea448f23e9032899998b69cdcd Mon Sep 17 00:00:00 2001 From: John Wu <76966357+jwu-fisker@users.noreply.github.com> Date: Tue, 26 Jul 2022 09:19:48 -0700 Subject: [PATCH 2/7] CEC-1450 Show Trex version (#169) * CEC-1450 Show Trex version * Code smells * Clean up * Fixes * Optimize test --- .../App/__snapshots__/App.test.js.snap | 24 +++ src/components/Cars/Status/DigitalTwinTab.jsx | 64 ++++++++ .../Cars/Status/DigitalTwinTab.test.jsx | 36 +++++ .../DigitalTwinTab.test.jsx.snap | 143 ++++++++++++++++++ .../Status/__snapshots__/index.test.jsx.snap | 24 +++ src/components/Cars/Status/index.jsx | 32 ++-- .../Contexts/__mocks__/VehicleContext.jsx | 61 +++++++- src/components/DigitalTwin/index.js | 60 ++++++++ src/components/VehicleMap/index.jsx | 3 +- src/components/VehicleMap/popup.jsx | 123 +++++++-------- 10 files changed, 479 insertions(+), 91 deletions(-) create mode 100644 src/components/Cars/Status/DigitalTwinTab.jsx create mode 100644 src/components/Cars/Status/DigitalTwinTab.test.jsx create mode 100644 src/components/Cars/Status/__snapshots__/DigitalTwinTab.test.jsx.snap create mode 100644 src/components/DigitalTwin/index.js diff --git a/src/components/App/__snapshots__/App.test.js.snap b/src/components/App/__snapshots__/App.test.js.snap index f76157a..e5d83d8 100644 --- a/src/components/App/__snapshots__/App.test.js.snap +++ b/src/components/App/__snapshots__/App.test.js.snap @@ -7484,6 +7484,24 @@ exports[`App Route /vehicle-status authenticated 1`] = ` class="MuiTouchRipple-root" /> + + diff --git a/src/components/Cars/Status/DigitalTwinTab.jsx b/src/components/Cars/Status/DigitalTwinTab.jsx new file mode 100644 index 0000000..de84bb1 --- /dev/null +++ b/src/components/Cars/Status/DigitalTwinTab.jsx @@ -0,0 +1,64 @@ +import React, { useEffect, useState } from "react"; +import clsx from "clsx"; +import { Typography } from "@material-ui/core"; + +import useStyles from "../../useStyles"; +import DigitalTwin from "../../DigitalTwin"; +import { + useVehicleContext, + VehicleProvider, +} from "../../Contexts/VehicleContext"; +import { useStatusContext } from "../../Contexts/StatusContext"; +import { useUserContext } from "../../Contexts/UserContext"; +import { logger } from "../../../services/monitoring"; + +const Main = (props) => { + const { getState } = useVehicleContext(); + const { + token: { + idToken: { jwtToken: token }, + }, + } = useUserContext(); + const { setMessage } = useStatusContext(); + const classes = useStyles(); + const [carState, setCarState] = useState(null); + const { vin } = props; + + useEffect(() => { + if (!vin) return; + (async () => { + try { + const result = await getState(token, vin); + setCarState(result.data); + } catch (e) { + setMessage(e.message); + logger.warn(e.stack); + } + })(); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [vin]); + + return ( +
+ + Digital Twin + + {carState && ( + <> +
+ Connected: {carState.online.toString()} +
+ + + )} +
+ ); +}; + +const DigitalTwinTab = (props) => ( + +
+ +); + +export default DigitalTwinTab; diff --git a/src/components/Cars/Status/DigitalTwinTab.test.jsx b/src/components/Cars/Status/DigitalTwinTab.test.jsx new file mode 100644 index 0000000..164d5d0 --- /dev/null +++ b/src/components/Cars/Status/DigitalTwinTab.test.jsx @@ -0,0 +1,36 @@ +jest.mock("../../Contexts/VehicleContext"); +jest.mock("../../Contexts/StatusContext"); +jest.mock("../../Contexts/UserContext"); +jest.mock("@material-ui/core/utils/unstable_useId", () => + jest.fn().mockReturnValue("mui-test-id") +); + +import React from "react"; +import { render, waitFor } from "@testing-library/react"; + +import { StatusProvider } from "../../Contexts/StatusContext"; +import { UserProvider, setToken } from "../../Contexts/UserContext"; +import { TEST_AUTH_OBJECT } from "../../../utils/testing"; +import DigitalTwinTab from "./DigitalTwinTab"; + +const renderDetailsTab = async () => { + const { container } = render( + + + + + + ); + await waitFor(() => { + /* render */ + }); + return container; +}; + +describe("DigitalTwinTab", () => { + it("Render", async () => { + setToken(TEST_AUTH_OBJECT); + const container = await renderDetailsTab(); + expect(container).toMatchSnapshot(); + }); +}); diff --git a/src/components/Cars/Status/__snapshots__/DigitalTwinTab.test.jsx.snap b/src/components/Cars/Status/__snapshots__/DigitalTwinTab.test.jsx.snap new file mode 100644 index 0000000..a6b4e6c --- /dev/null +++ b/src/components/Cars/Status/__snapshots__/DigitalTwinTab.test.jsx.snap @@ -0,0 +1,143 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`DigitalTwinTab Render 1`] = ` +
+
+
+
+
+
+ Digital Twin +
+
+ + Connected + + : + false +
+
+

+ + Battery + + : + 95% +

+
+

+ Doors +

+

+ + hood + + : + closed +

+

+ + left_front + + : + closed +

+

+ + left_rear + + : + closed +

+

+ + right_front + + : + closed +

+

+ + right_rear + + : + closed +

+

+ + trunk + + : + closed +

+
+
+

+ Location +

+

+ + altitude + + : + 17 +

+

+ + longitude + + : + -122.414° +

+

+ + latitude + + : + 37.764° +

+
+
+

+ + Trex Version + + : + 1000000 +

+
+
+

+ + Updated at + + : + 7/26/2022 12:26:38 AM +

+
+
+
+
+
+
+
+`; diff --git a/src/components/Cars/Status/__snapshots__/index.test.jsx.snap b/src/components/Cars/Status/__snapshots__/index.test.jsx.snap index e1bc42d..90b88f5 100644 --- a/src/components/Cars/Status/__snapshots__/index.test.jsx.snap +++ b/src/components/Cars/Status/__snapshots__/index.test.jsx.snap @@ -83,6 +83,24 @@ exports[`CarStatus Render 1`] = ` class="MuiTouchRipple-root" /> + + diff --git a/src/components/Cars/Status/index.jsx b/src/components/Cars/Status/index.jsx index d65ecc2..3086a59 100644 --- a/src/components/Cars/Status/index.jsx +++ b/src/components/Cars/Status/index.jsx @@ -7,15 +7,12 @@ import { Box, Tab, Tabs } from "@material-ui/core"; import CarDetailsTab from "./DetailsTab"; import CarUpdatesTab from "./CarUpdatesTab"; import CANFiltersTab from "./CANFiltersTab"; +import DigitalTwinTab from "./DigitalTwinTab"; import TabPanel from "../../Controls/TabPanel"; import { useStatusContext } from "../../Contexts/StatusContext"; import useStyles from "../../useStyles"; -const tabHashes = [ - "details", - "updates", - "filters" -] +const tabHashes = ["details", "updates", "filters"]; const CarStatus = () => { const { vin } = useParams(); @@ -25,8 +22,8 @@ const CarStatus = () => { const [tabIndex, setTabIndex] = React.useState(0); useEffect(() => { - const key = hash.replace("#", "") - const index = tabHashes.findIndex(element => element === key); + const key = hash.replace("#", ""); + const index = tabHashes.findIndex((element) => element === key); if (index >= 0) setTabIndex(index); }, [hash]); @@ -51,11 +48,20 @@ const CarStatus = () => { return (
- - + + + @@ -70,14 +76,18 @@ const CarStatus = () => { -
+ + + + + ); }; function tabProps(index) { return { id: `tab-${index}`, - "aria-controls": `tabpanel-${index}` + "aria-controls": `tabpanel-${index}`, }; } diff --git a/src/components/Contexts/__mocks__/VehicleContext.jsx b/src/components/Contexts/__mocks__/VehicleContext.jsx index 94c13d2..81cefda 100644 --- a/src/components/Contexts/__mocks__/VehicleContext.jsx +++ b/src/components/Contexts/__mocks__/VehicleContext.jsx @@ -5,17 +5,17 @@ let busy = false; const filters = [ { can_id: "123-456", - interval: 789 + interval: 789, }, { can_id: "1", - interval: 1000 + interval: 1000, }, { can_id: "1000", - interval: 1 - } -] + interval: 1, + }, +]; let vehicle = { vin: "3C4PDCBG0ET127145", @@ -24,8 +24,55 @@ let vehicle = { trim: "Basic", ecu_list: "ECUA 2.0.0, ECUB 2.1.1", log_level: "info", - canbus: { enabled: true, data_logger_enabled: true, max_mem_buffer_size: 1, max_disk_buffer_size: 2, filters: filters }, + canbus: { + enabled: true, + data_logger_enabled: true, + max_mem_buffer_size: 1, + max_disk_buffer_size: 2, + filters: filters, + }, }; +let vehicleState = { + data: { + online: false, + battery: { + percent: 95, + }, + max_range: { + max_miles: 577, + }, + doors: { + hood: false, + left_front: false, + left_rear: false, + right_front: false, + right_rear: false, + trunk: false, + }, + location: { + altitude: 17, + longitude: -122.414, + latitude: 37.764, + }, + door_locks: { + driver: false, + all: false, + }, + sunroof: { + sunroof: 0, + }, + cabin_climate: { + cabin_temperature: 0, + internal_temperature: 29, + }, + ambient_temperature: { + temperature: 26, + }, + trex_version: "1000000", + updated: "2022-07-26T00:26:38.880381Z", + }, +}; + let vehicles = []; let models = ["Ocean", "PEAR"]; let years = [2023, 2024]; @@ -83,7 +130,7 @@ export const useVehicleContext = () => ({ getModels: jest.fn(() => { models = ["Ocean", "PEAR"]; }), - getState: jest.fn(), + getState: jest.fn(() => vehicleState), getYears: jest.fn(() => { years = [2023, 2024]; }), diff --git a/src/components/DigitalTwin/index.js b/src/components/DigitalTwin/index.js new file mode 100644 index 0000000..d868d45 --- /dev/null +++ b/src/components/DigitalTwin/index.js @@ -0,0 +1,60 @@ +import React from "react"; + +import useStyles from "../useStyles"; +import { LocalDateTimeString } from "../../utils/dates"; + +const keyValueTemplate = (key, value) => ( +

+ {key}: {value} +

+); +const openCloseState = (value) => (value ? "open" : "closed"); +const mapOpenCloseState = (value) => + keyValueTemplate(value[0], openCloseState(value[1])); + +const DigitalTwin = (props) => { + const classes = useStyles(); + const { battery, doors, location, trex_version, updated, windows } = props; + + return ( +
+ {battery != null && keyValueTemplate("Battery", `${battery.percent}%`)} + {doors != null && ( +
+

Doors

+ {Object.entries(doors).map(mapOpenCloseState)} +
+ )} + {windows != null && ( +
+

Windows

+ {Object.entries(windows).map(mapOpenCloseState)} +
+ )} + {location != null && ( +
+

Location

+ {Object.entries(location).map((value) => { + if (value[0] === "altitude") { + return keyValueTemplate(value[0], value[1]); + } else { + return keyValueTemplate(value[0], `${value[1]}°`); + } + })} +
+ )} + {trex_version && ( +
+ {keyValueTemplate("Trex Version", trex_version)} +
+ )} + {updated != null && ( +
+ {keyValueTemplate("Updated at", LocalDateTimeString(updated))} +
+ )} +
+ ); +}; + +export default DigitalTwin; diff --git a/src/components/VehicleMap/index.jsx b/src/components/VehicleMap/index.jsx index b66abd8..5006802 100644 --- a/src/components/VehicleMap/index.jsx +++ b/src/components/VehicleMap/index.jsx @@ -179,7 +179,8 @@ const Component = () => { doors={carState.doors} location={carState.location} windows={carState.windows} - updatedAt={carState.updated} + trex_version={carState.trex_version} + updated={carState.updated} className={classes.popup} onClose={handleClose} /> diff --git a/src/components/VehicleMap/popup.jsx b/src/components/VehicleMap/popup.jsx index 8451d24..b990691 100644 --- a/src/components/VehicleMap/popup.jsx +++ b/src/components/VehicleMap/popup.jsx @@ -1,84 +1,63 @@ import React from "react"; -import Dialog from '@material-ui/core/Dialog'; -import MuiDialogTitle from '@material-ui/core/DialogTitle'; -import IconButton from '@material-ui/core/IconButton'; -import CloseIcon from '@material-ui/icons/Close'; -import Typography from '@material-ui/core/Typography'; +import Dialog from "@material-ui/core/Dialog"; +import MuiDialogTitle from "@material-ui/core/DialogTitle"; +import IconButton from "@material-ui/core/IconButton"; +import CloseIcon from "@material-ui/icons/Close"; +import Typography from "@material-ui/core/Typography"; import useStyles from "../useStyles"; -import { LocalDateTimeString } from "../../utils/dates"; +import DigitalTwin from "../DigitalTwin"; const VehiclePopUp = (props) => { - const classes = useStyles(); - const { vin, online, battery, doors, location, updatedAt, windows, onClose } = props; + const classes = useStyles(); + const { vin, online, battery, doors, location, windows, onClose } = props; - return ( - - {vin} -
-

Connected: {online.toString()}

- {online && ( -
- {battery != null && ( -

Battery: {battery.percent}%

- )} - {doors != null && ( -
-

Doors

- {Object.entries(doors).map((value) => (

{value[0]}: {value[1] ? "open" : "closed"}

))} -
- )} - {windows != null && ( -
-

Windows

- {Object.entries(windows).map((value) => (

{value[0]}: {value[1] ? "open" : "closed"}

))} -
- )} - {location != null && ( -
-

Location

- {Object.entries(location).map((value) => { - if (value[0] === "altitude") { - return (

{value[0]}: {value[1]}

); - } else { - return (

{value[0]}: {value[1]}°

) - } - })} -
- )} - {updatedAt != null && ( -
-

Updated at: {LocalDateTimeString(updatedAt)}

-
- )} -
- )} - {(!online || (battery == null && doors == null && location == null && windows == null)) && ( -

No vehicle data to display.

- )} -
-
- ); + return ( + + + {vin} + +
+

+ Connected: {online.toString()} +

+ {online && } + {(!online || + (battery == null && + doors == null && + location == null && + windows == null)) &&

No vehicle data to display.

} +
+
+ ); }; const DialogTitle = (props) => { - const { children, onClose, ...other } = props; - const classes = useStyles(); - return ( - - {children} - {onClose ? ( - - - - ) : null} - - ); + const { children, onClose, ...other } = props; + const classes = useStyles(); + return ( + + {children} + {onClose ? ( + + + + ) : null} + + ); }; export { VehiclePopUp }; From 00af90902e5921f77831c35045923a12f257c238 Mon Sep 17 00:00:00 2001 From: arpanetus Date: Tue, 2 Aug 2022 01:11:11 +0600 Subject: [PATCH 3/7] CEC-758 Add SMS send page and result (#173) * Add SMS send and result pages * Update snapshot Co-authored-by: jwu-fisker --- src/components/App/App.test.js | 9 + .../App/__snapshots__/App.test.js.snap | 982 ++++++++++++++++-- src/components/Certificates/Add/index.jsx | 2 +- src/components/Contexts/SMSContext.jsx | 63 ++ src/components/Layouts/SideMenu.jsx | 6 + .../__snapshots__/SideMenu.test.jsx.snap | 22 + src/components/Routes/SiteRoutes.jsx | 9 + src/components/SMS/Send/SendForm.jsx | 92 ++ src/components/SMS/Send/ViewResult.jsx | 39 + src/components/SMS/Send/ViewResult.test.jsx | 21 + .../__snapshots__/ViewResult.test.jsx.snap | 39 + src/components/SMS/Send/index.jsx | 68 ++ src/services/smsAPI.js | 27 + 13 files changed, 1307 insertions(+), 72 deletions(-) create mode 100644 src/components/Contexts/SMSContext.jsx create mode 100644 src/components/SMS/Send/SendForm.jsx create mode 100644 src/components/SMS/Send/ViewResult.jsx create mode 100644 src/components/SMS/Send/ViewResult.test.jsx create mode 100644 src/components/SMS/Send/__snapshots__/ViewResult.test.jsx.snap create mode 100644 src/components/SMS/Send/index.jsx create mode 100644 src/services/smsAPI.js diff --git a/src/components/App/App.test.js b/src/components/App/App.test.js index b78ce25..e92f442 100644 --- a/src/components/App/App.test.js +++ b/src/components/App/App.test.js @@ -132,6 +132,10 @@ describe("App", () => { await check("/tools/certificates/add", "span.MuiButton-label", "Sign In"); }); + it("Route /tools/sms/send unauthenticated", async () => { + await check("/tools/sms/send", "span.MuiButton-label", "Sign In"); + }) + it("Route /page-not-found unauthenticated", async () => { await check("/page-not-found", "h1", "Page Not Found"); }); @@ -189,4 +193,9 @@ describe("App", () => { setToken(TEST_AUTH_OBJECT); await check("/tools/certificates/add", "h6", "Create Certificate"); }); + + it("Route /tools/sms/send authenticated", async () => { + setToken(TEST_AUTH_OBJECT); + await check("/tools/sms/send", "h6", "Send SMS"); + }); }); diff --git a/src/components/App/__snapshots__/App.test.js.snap b/src/components/App/__snapshots__/App.test.js.snap index e5d83d8..ebc871d 100644 --- a/src/components/App/__snapshots__/App.test.js.snap +++ b/src/components/App/__snapshots__/App.test.js.snap @@ -310,6 +310,28 @@ exports[`App Route / authenticated 1`] = ` /> +
  • + +
    + + SMS + +
    + +
    +
  • @@ -808,6 +830,28 @@ exports[`App Route /home authenticated 1`] = ` /> +
  • + +
    + + SMS + +
    + +
    +
  • @@ -1342,6 +1386,28 @@ exports[`App Route /package-create authenticated 1`] = ` /> +
  • + +
    + + SMS + +
    + +
    +
  • @@ -1399,10 +1465,10 @@ exports[`App Route /package-create authenticated 1`] = ` />