From a08d5809a65302ae9356bf84ac47915d8cf1316e Mon Sep 17 00:00:00 2001 From: Paul Adamsen <117673433+pauladamseniii@users.noreply.github.com> Date: Fri, 6 Jan 2023 13:41:22 -0500 Subject: [PATCH 01/13] CEC-2628 - Display IP in digital twin in portal (#251) --- .../Status/__snapshots__/DigitalTwinTab.test.jsx.snap | 11 +++++++++++ src/components/Contexts/__mocks__/VehicleContext.jsx | 11 +++++++---- src/components/DigitalTwin/index.js | 7 ++++++- src/components/VehicleMap/index.jsx | 1 + 4 files changed, 25 insertions(+), 5 deletions(-) diff --git a/src/components/Cars/Status/__snapshots__/DigitalTwinTab.test.jsx.snap b/src/components/Cars/Status/__snapshots__/DigitalTwinTab.test.jsx.snap index 607b45f..7340395 100644 --- a/src/components/Cars/Status/__snapshots__/DigitalTwinTab.test.jsx.snap +++ b/src/components/Cars/Status/__snapshots__/DigitalTwinTab.test.jsx.snap @@ -130,6 +130,17 @@ exports[`DigitalTwinTab Render 1`] = ` 1000000

+
+

+ + Trex IP + + : + 172.20.0.17:49850 +

+
diff --git a/src/components/Contexts/__mocks__/VehicleContext.jsx b/src/components/Contexts/__mocks__/VehicleContext.jsx index cf6bfba..f31d80c 100644 --- a/src/components/Contexts/__mocks__/VehicleContext.jsx +++ b/src/components/Contexts/__mocks__/VehicleContext.jsx @@ -70,6 +70,7 @@ let vehicleState = { temperature: 26, }, trex_version: "1000000", + ip: "172.20.0.17:49850", updated: "2022-07-26T00:26:38.880381Z", }, }; @@ -146,10 +147,12 @@ export const useVehicleContext = () => ({ command, parameters, })), - getFleets: jest.fn((vin, search,_token) => {return { - data: ["fleet1", "fleet2"], - total: 2, - }}), + getFleets: jest.fn((vin, search, _token) => { + return { + data: ["fleet1", "fleet2"], + total: 2, + } + }), }); export const setBusy = (val) => { diff --git a/src/components/DigitalTwin/index.js b/src/components/DigitalTwin/index.js index 44f0090..8129ce9 100644 --- a/src/components/DigitalTwin/index.js +++ b/src/components/DigitalTwin/index.js @@ -14,7 +14,7 @@ const mapOpenCloseState = (value) => const DigitalTwin = (props) => { const classes = useStyles(); - const { battery, doors, location, trex_version, updated, windows } = props; + const { battery, doors, location, trex_version, ip, updated, windows } = props; return (
@@ -51,6 +51,11 @@ const DigitalTwin = (props) => { {keyValueTemplate("Trex Version", trex_version)}
)} + {ip && ( +
+ {keyValueTemplate("Trex IP", ip)} +
+ )} {updated != null && (
{keyValueTemplate("Updated at", LocalDateTimeString(updated))} diff --git a/src/components/VehicleMap/index.jsx b/src/components/VehicleMap/index.jsx index c685dac..ff61861 100644 --- a/src/components/VehicleMap/index.jsx +++ b/src/components/VehicleMap/index.jsx @@ -193,6 +193,7 @@ const Component = () => { location={carState.location} windows={carState.windows} trex_version={carState.trex_version} + ip={carState.ip} updated={carState.updated} className={classes.popup} onClose={handleClose} From 097d58656af076b9b91f5122d3d614672d656cff Mon Sep 17 00:00:00 2001 From: John Wu <76966357+jwu-fisker@users.noreply.github.com> Date: Fri, 6 Jan 2023 19:06:20 -0800 Subject: [PATCH 02/13] CEC-3453 Update security dll instructions (#252) --- .../Magna/SecurityDLL/__snapshots__/index.test.jsx.snap | 8 +++++--- src/components/Magna/SecurityDLL/result.jsx | 3 ++- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/components/Magna/SecurityDLL/__snapshots__/index.test.jsx.snap b/src/components/Magna/SecurityDLL/__snapshots__/index.test.jsx.snap index 92bf6cf..74b39c3 100644 --- a/src/components/Magna/SecurityDLL/__snapshots__/index.test.jsx.snap +++ b/src/components/Magna/SecurityDLL/__snapshots__/index.test.jsx.snap @@ -4,11 +4,13 @@ exports[`Magna Security DLL page Security DLL Result page 1`] = `

- Click to download your certificates and security.dll. -
+ Please click the links below to download the certificate.pem, key.pem and the security.dll (either the 32-bit or 64-bit version to match your application). Install all files in the same folder, and then run your application of choice to connect to the Fisker cloud. +

+

- DLL will not work unless certificate.pem and key.pem are placed next to the DLL + Important Note: + Certificates expire in one month from the time they are generated. They have to be re-downloaded again to connect to the Fisker cloud.

  • diff --git a/src/components/Magna/SecurityDLL/result.jsx b/src/components/Magna/SecurityDLL/result.jsx index c81b511..f26ba06 100644 --- a/src/components/Magna/SecurityDLL/result.jsx +++ b/src/components/Magna/SecurityDLL/result.jsx @@ -8,7 +8,8 @@ const CertMimeType = "application/x-pem-file"; const Result = ({ public_key, private_key }) => ( <> -

    Click to download your certificates and security.dll.
    DLL will not work unless certificate.pem and key.pem are placed next to the DLL

    +

    Please click the links below to download the certificate.pem, key.pem and the security.dll (either the 32-bit or 64-bit version to match your application). Install all files in the same folder, and then run your application of choice to connect to the Fisker cloud.

    +

    Important Note: Certificates expire in one month from the time they are generated. They have to be re-downloaded again to connect to the Fisker cloud.

@@ -5798,6 +7648,42 @@ exports[`App Route /tools/sms/send authenticated 1`] = ` /> +
  • + +
    + +
    +
    + + Issues + +
    + +
    +
  • +
  • + +
    + +
    +
    + + Issues + +
    + +
    +
  • +
  • + +
    + +
    +
    + + Issues + +
    + +
    +
  • +
  • + +
    + +
    +
    + + Issues + +
    + +
    +
  • - -
    -
    -

    - Rows per page: -

    -
    - - -
    -

    - 0-0 of 0 -

    -
    - - -
    -
    - +

    + No Car Updates found +

    diff --git a/src/components/Contexts/IssueContext.jsx b/src/components/Contexts/IssueContext.jsx new file mode 100644 index 0000000..570929a --- /dev/null +++ b/src/components/Contexts/IssueContext.jsx @@ -0,0 +1,55 @@ +import React, { useContext, useState, useMemo, useCallback } from "react"; +import api from "../../services/issueAPI"; + +const IssueContext = React.createContext(); + +export const IssueProvider = ({ children }) => { + const [issue, setIssue] = useState({}); + const [issues, setIssues] = useState([]); + const [totalIssues, setTotalIssues] = useState(0); + + const getIssue = useCallback(async (id, token) => { + const result = await api.getIssue(id, token); + if (result.error) throw new Error(`Get issue error. ${result.message}`); + + setIssue(result.data ?? []); + return result; + }, []); + + const getIssues = useCallback(async (search,token) => { + const result = await api.getIssues(search,token); + if (result.error) { + setIssues([]); + throw new Error(`Get issues error. ${result.message}`); + } + setIssues(result.data ?? []); + if (result.total) { + setTotalIssues(result.total); + } + }, []); + + const deleteIssue = useCallback(async (id, token) => { + const result = await api.deleteIssue(id, token); + if (result.error) + throw new Error(`Delete issue error. ${result.message}`); + return result; + }, []); + + const value = useMemo(() => ({ + totalIssues, + issue, + issues, + + deleteIssue, + getIssue, + getIssues, + }), [totalIssues, issue, issues, deleteIssue, getIssue, getIssues]); + + return ( + + {children} + + ); +}; + +export const useIssueContext = () => useContext(IssueContext); diff --git a/src/components/Contexts/IssueContext.test.jsx b/src/components/Contexts/IssueContext.test.jsx new file mode 100644 index 0000000..b529158 --- /dev/null +++ b/src/components/Contexts/IssueContext.test.jsx @@ -0,0 +1,102 @@ +jest.mock("../../services/issueAPI"); + +import { + render, + cleanup, + screen, + fireEvent, + waitFor, +} from "@testing-library/react"; +import { IssueProvider, useIssueContext } from "./IssueContext"; + +const checkIssueResult = (issue) => { + expect(screen.getByTestId("issue").innerHTML).toEqual(issue); +}; + +const checkIssuesResult = (issues) => { + expect(screen.getByTestId("issues").innerHTML).toEqual(issues); +}; + +describe("IssueContext", () => { + describe("getIssues", () => { + beforeEach(() => { + const TestComp = () => { + const { issues, getIssues } = useIssueContext(); + + return ( + <> +
    {JSON.stringify(issues)}
    +
  • +
  • + +
    + +
    +
    + + Issues + +
    + +
    +
  • `; +exports[`SideMenu Magna Authenticated 1`] = ` +
    +
    + +
    +
    +`; + exports[`SideMenu Unauthenticated 1`] = `
    import("../CANFilter/Add")); const CANFilterUpdate = React.lazy(() => import("../CANFilter/Update")); +const IssuesList = React.lazy(() => import("../Issues/List")) +const IssueInfo = React.lazy(() => import("../Issues/Info")) const CarsList = React.lazy(() => import("../Cars/List")); const CarStatus = React.lazy(() => import("../Cars/Status")); const CarUpdateStatus = React.lazy(() => import("../Cars/UpdateStatus")); @@ -175,6 +177,24 @@ const SiteRoutes = () => { rolesPerGroup={Permissions.FiskerRead} providers={providers} /> + } + type={TYPES.PROTECTED} + token={token} + groups={groups} + rolesPerGroup={Permissions.FiskerRead} + providers={providers} + /> + } + type={TYPES.PROTECTED} + token={token} + groups={groups} + rolesPerGroup={Permissions.FiskerRead} + providers={providers} + /> } diff --git a/src/components/SupersetDashboardList/SupersetDashboardList.jsx b/src/components/SupersetDashboardList/SupersetDashboardList.jsx index cce2712..23714d6 100644 --- a/src/components/SupersetDashboardList/SupersetDashboardList.jsx +++ b/src/components/SupersetDashboardList/SupersetDashboardList.jsx @@ -1,4 +1,4 @@ -import React, { useState, useEffect } from "react"; +import React, { useEffect, useState } from "react"; import { useUserContext } from "../Contexts/UserContext"; import supersetAPI from "../../services/superset"; @@ -29,10 +29,11 @@ const SupersetDashboardList = () => { internalEffect(token) } - + return () => { + setDashboardList([]); + } }, [groups, token]) - return (
      {dashboardList.map((subitem, index) => ( diff --git a/src/services/__mocks__/issueAPI.js b/src/services/__mocks__/issueAPI.js new file mode 100644 index 0000000..2f7459d --- /dev/null +++ b/src/services/__mocks__/issueAPI.js @@ -0,0 +1,11 @@ +const issueAPI = { + getIssues: async (token) => { + return { "data": [{ "id": 18, "vin": "1GNGC26RXXJ407648", "title": "sometitle", "description": "2343242", "driver_id": "valid-cognito-id-1", "timestamp": "2022-12-09T23:16:38.074858Z" }, { "id": 19, "vin": "1GNGC26RXXJ407648", "title": "sometitle", "description": "2343242", "driver_id": "valid-cognito-id-1", "timestamp": "2022-12-09T23:16:38.074858Z" }, { "id": 20, "vin": "1GNGC26RXXJ407648", "title": "sometitle", "description": "2343242", "driver_id": "valid-cognito-id-1", "timestamp": "2022-12-09T23:16:38.074858Z" }, { "id": 21, "vin": "1GNGC26RXXJ407648", "title": "sometitle", "description": "2343242", "driver_id": "valid-cognito-id-1", "timestamp": "2022-12-09T23:16:38.074858Z" }, { "id": 22, "vin": "1GNGC26RXXJ407648", "title": "sometitle", "description": "2343242", "driver_id": "valid-cognito-id-1", "timestamp": "2022-12-09T23:16:38.074858Z" }, { "id": 25, "vin": "1GNGC26RXXJ407648", "title": "Example HMI Problem", "description": "HMI blue screen", "driver_id": "0b6b1930-b20a-4fce-967a-efac6a01fd10", "timestamp": "2022-12-19T22:25:03.848855Z" }, { "id": 26, "vin": "1GNGC26RXXJ407648", "title": "sometitle", "description": "2343242", "driver_id": "valid-cognito-id-1", "timestamp": "2022-12-09T23:16:38.074858Z" }, { "id": 27, "vin": "1GNGC26RXXJ407648", "title": "sometitle", "description": "2343242", "driver_id": "valid-cognito-id-1", "timestamp": "2022-12-09T23:16:38.074858Z" }, { "id": 28, "vin": "1GNGC26RXXJ407648", "title": "sometitle", "description": "2343242", "driver_id": "valid-cognito-id-1", "timestamp": "2022-12-09T23:16:38.074858Z" }], "total": 9 } + }, + getIssue: async (token) => { + return { "data": { "id": 18, "vin": "1GNGC26RXXJ407648", "title": "sometitle", "description": "2343242", "driver_id": "valid-cognito-id-1", "timestamp": "2022-12-09T23:16:38.074858Z", "images": [{ "id": 15, "image": "SGVsbG8x", "issue_id": 18 }] } } + } +} + + +export default issueAPI; \ No newline at end of file diff --git a/src/services/__mocks__/superset.js b/src/services/__mocks__/superset.js index cd2af34..9c02e96 100644 --- a/src/services/__mocks__/superset.js +++ b/src/services/__mocks__/superset.js @@ -1,4 +1,7 @@ const SupersetAPI = { + getGuestToken: async () => { + return "" + }, getEmbeddedDashboards: async () => { return [{ title: "test title", @@ -7,7 +10,8 @@ const SupersetAPI = { }, SupersetDashboardID: () => { return "11111100-0000-1111-1111-000000000000" - } + }, + SupersetDashboardURL: () => (null), } export default SupersetAPI \ No newline at end of file diff --git a/src/services/__mocks__/suppliersAPI.js b/src/services/__mocks__/suppliersAPI.js index 7c4f2e0..9b8e4ea 100644 --- a/src/services/__mocks__/suppliersAPI.js +++ b/src/services/__mocks__/suppliersAPI.js @@ -59,6 +59,9 @@ const suppliersAPI = { if (index >= 0) data[index] = supplier; return supplier; }, + getManufactureCert: async () => { + return {public_key:"-----BEGIN CERTIFICATE-----\nTEST\n-----END CERTIFICATE-----",private_key:"-----BEGIN RSA PRIVATE KEY-----\nTEST\n-----END RSA PRIVATE KEY-----","serial_number":"66:c8:45:20:bd:75:04:79:e8:5e:0e:46:5b:5c:1a:21:8b:ea:81:9f","type":"rsa"} + }, }; export default suppliersAPI; diff --git a/src/services/issueAPI.js b/src/services/issueAPI.js new file mode 100644 index 0000000..b329b8f --- /dev/null +++ b/src/services/issueAPI.js @@ -0,0 +1,45 @@ +import { + addQueryParams, errorHandler, fetchRespHandler, getAuthHeaderOptions +} from "../utils/http"; + +const API_ENDPOINT = process.env.REACT_APP_OTA_SERVICE_URL; + +const issuesAPI = { + deleteIssue: async (id, token) => + fetch(`${API_ENDPOINT}/issues/${id}`, { + method: "DELETE", + headers: Object.assign( + { "Content-Type": "application/json" }, + getAuthHeaderOptions(token) + ), + }) + .then(fetchRespHandler) + .catch(errorHandler), + + getIssue: async (id, token) => + fetch(`${API_ENDPOINT}/issues/${id}`, { + method: "GET", + headers: Object.assign( + { "Content-Type": "application/json" }, + getAuthHeaderOptions(token) + ), + }) + .then(fetchRespHandler) + .catch(errorHandler), + + getIssues: async (search, token) => { + const u = addQueryParams(`${API_ENDPOINT}/issues`, search); + return fetch(u, { + method: "GET", + headers: Object.assign( + { "Content-Type": "application/json" }, + getAuthHeaderOptions(token) + ), + }) + .then(fetchRespHandler) + .catch(errorHandler); + }, + +}; + +export default issuesAPI; diff --git a/src/services/superset.js b/src/services/superset.js index 7d827bc..54d6036 100644 --- a/src/services/superset.js +++ b/src/services/superset.js @@ -1,5 +1,5 @@ import { - addQueryParams, getAuthHeaderOptions + addQueryParams, getAuthHeaderOptions } from "../utils/http"; //Added the token we got from the first authorization and set it as the auth token, and that allowed us to hit the request From 8698a3158668961d85eb090401b62db6d64e5297 Mon Sep 17 00:00:00 2001 From: das31 <31259710+das31@users.noreply.github.com> Date: Mon, 9 Jan 2023 15:01:01 -0500 Subject: [PATCH 04/13] Cec 2752 small fix (#253) * first commit * removed comments * remove more comments * fix build issues * fix unused vars * update snapshot * fix test * Fix connect ECONNREFUSED 127.0.0.1:80 * Test Magna side menu * attempt to pass test * fix test * remove comments * fix some code smells * fix test * resolve comments * fix bug * resolved comments * resolve comments * resolve comments * update snapshot * resolved comments * small fix Co-authored-by: jwu-fisker --- src/components/Controls/IssueSelectionTable/index.jsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/Controls/IssueSelectionTable/index.jsx b/src/components/Controls/IssueSelectionTable/index.jsx index 98380ae..3dc8c5f 100644 --- a/src/components/Controls/IssueSelectionTable/index.jsx +++ b/src/components/Controls/IssueSelectionTable/index.jsx @@ -44,7 +44,7 @@ const tableColumns = [ label: "Driver ID", }, { - id: "timestamp", + id: "created_at", label: "Created", }, { @@ -67,7 +67,7 @@ const IssueSelectionTable = (props) => { const [pageSize, setPageSize] = useLocalStorage(PAGE_SIZE, 10); const [pageIndex, setPageIndex] = useState(0); - const [orderBy, setOrderBy] = useState("timestamp"); + const [orderBy, setOrderBy] = useState("created_at"); const [order, setOrder] = useState("asc"); const { getIssues, issues, totalIssues } = useIssueContext(); const { groups, providers } = useUserContext(); From c10835bec9c0f076fb8645a70248ccc8cd74076e Mon Sep 17 00:00:00 2001 From: das31 <31259710+das31@users.noreply.github.com> Date: Thu, 12 Jan 2023 15:39:10 -0500 Subject: [PATCH 05/13] fix warnings (#256) --- .../App/__snapshots__/App.test.js.snap | 120 +----------------- .../__snapshots__/CarUpdatesTab.test.jsx.snap | 4 +- .../Controls/CarUpdatesTable/index.jsx | 2 +- .../Controls/IssueSelectionTable/index.jsx | 4 +- 4 files changed, 7 insertions(+), 123 deletions(-) diff --git a/src/components/App/__snapshots__/App.test.js.snap b/src/components/App/__snapshots__/App.test.js.snap index 348551e..3ecf212 100644 --- a/src/components/App/__snapshots__/App.test.js.snap +++ b/src/components/App/__snapshots__/App.test.js.snap @@ -2639,124 +2639,8 @@ exports[`App Route /issues authenticated 1`] = ` - -
      -
      -

      - Rows per page: -

      -
      - - -
      -

      - 1-NaN of undefined -

      -
      - - -
      -
      + + No issues found diff --git a/src/components/Cars/Status/__snapshots__/CarUpdatesTab.test.jsx.snap b/src/components/Cars/Status/__snapshots__/CarUpdatesTab.test.jsx.snap index 7468285..d4fb153 100644 --- a/src/components/Cars/Status/__snapshots__/CarUpdatesTab.test.jsx.snap +++ b/src/components/Cars/Status/__snapshots__/CarUpdatesTab.test.jsx.snap @@ -164,9 +164,9 @@ exports[`CarUpdatesTab Render 1`] = ` -

      + No Car Updates found -

      + diff --git a/src/components/Controls/CarUpdatesTable/index.jsx b/src/components/Controls/CarUpdatesTable/index.jsx index 19882c9..4ea66ca 100644 --- a/src/components/Controls/CarUpdatesTable/index.jsx +++ b/src/components/Controls/CarUpdatesTable/index.jsx @@ -198,7 +198,7 @@ const MainForm = ({ vin, token }) => { {totalCarUpdates === 0 ? ( -

      No Car Updates found

      + No Car Updates found ) : ( { const [pageIndex, setPageIndex] = useState(0); const [orderBy, setOrderBy] = useState("created_at"); const [order, setOrder] = useState("asc"); - const { getIssues, issues, totalIssues } = useIssueContext(); + const { getIssues, issues, totalIssues = 0 } = useIssueContext(); const { groups, providers } = useUserContext(); const { setMessage } = useStatusContext(); @@ -182,7 +182,7 @@ const IssueSelectionTable = (props) => { {totalIssues === 0 ? ( -

      No issues found

      + No issues found ) : ( Date: Thu, 12 Jan 2023 21:02:48 -0500 Subject: [PATCH 06/13] CEC-1711-fix-digital-twin (#257) * first commit * remove comments * resolve comments: * update snapshot --- .../DigitalTwinTab.test.jsx.snap | 35 ++++++++++++++++ src/components/DigitalTwin/index.js | 40 ++++++++++++++++++- 2 files changed, 73 insertions(+), 2 deletions(-) diff --git a/src/components/Cars/Status/__snapshots__/DigitalTwinTab.test.jsx.snap b/src/components/Cars/Status/__snapshots__/DigitalTwinTab.test.jsx.snap index 7340395..a22fa67 100644 --- a/src/components/Cars/Status/__snapshots__/DigitalTwinTab.test.jsx.snap +++ b/src/components/Cars/Status/__snapshots__/DigitalTwinTab.test.jsx.snap @@ -91,6 +91,41 @@ exports[`DigitalTwinTab Render 1`] = ` closed

      +
      +

      + Door Locks +

      +

      + + driver + + : + Closed +

      +

      + + all + + : + Locked +

      +
      +
      +

      + Sunroof +

      +

      + + sunroof + + : + closed +

      +
      diff --git a/src/components/DigitalTwin/index.js b/src/components/DigitalTwin/index.js index 8129ce9..20acbfe 100644 --- a/src/components/DigitalTwin/index.js +++ b/src/components/DigitalTwin/index.js @@ -14,7 +14,7 @@ const mapOpenCloseState = (value) => const DigitalTwin = (props) => { const classes = useStyles(); - const { battery, doors, location, trex_version, ip, updated, windows } = props; + const { battery, doors, location, trex_version, ip, updated, windows, sunroof, dbc, door_locks } = props; return (
      @@ -28,10 +28,41 @@ const DigitalTwin = (props) => { {Object.entries(doors).map(mapOpenCloseState)}
      )} + {door_locks != null && ( +
      +

      Door Locks

      + {Object.entries(door_locks).map((value) => { + if (value[0] === "driver") { + return keyValueTemplate(value[0], value[1] ? "Open" : "Closed"); + } else { + return keyValueTemplate(value[0], value[1] ?"Unlocked" : "Locked" ); + } + })} +
      + )} {windows != null && (

      Windows

      - {Object.entries(windows).map(mapOpenCloseState)} + {Object.entries(windows).map((value) => { + if (value[1] === 0) { + return keyValueTemplate(value[0], "closed"); + } else { + return keyValueTemplate(value[0], `${value[1]}% open`); + } + })} +
      + )} + {sunroof != null && ( +
      +

      Sunroof

      + {/* {Object.entries(sunroof).map(mapOpenCloseState)} */} + {Object.entries(sunroof).map((value) => { + if (value[1] === 0) { + return keyValueTemplate(value[0], "closed"); + } else { + return keyValueTemplate(value[0], `${value[1]}% open`); + } + })}
      )} {location != null && ( @@ -61,6 +92,11 @@ const DigitalTwin = (props) => { {keyValueTemplate("Updated at", LocalDateTimeString(updated))}
      )} + {dbc != null && ( +
      + {keyValueTemplate("DBC version", dbc)} +
      + )}
    ); }; From 5137e001cab6f540a69b91fcc1b5017dda1cc7a4 Mon Sep 17 00:00:00 2001 From: syedghousemohiddin <119524179+syedghousemohiddin@users.noreply.github.com> Date: Fri, 13 Jan 2023 10:53:41 -0800 Subject: [PATCH 07/13] Added blackduck.yml to scan the repo (#255) --- .github/workflows/blackduck.yml | 41 ++++++--------------------------- 1 file changed, 7 insertions(+), 34 deletions(-) diff --git a/.github/workflows/blackduck.yml b/.github/workflows/blackduck.yml index f69b1a3..3fe8da2 100644 --- a/.github/workflows/blackduck.yml +++ b/.github/workflows/blackduck.yml @@ -1,40 +1,13 @@ name: Blackduck on: - schedule: - # run scans twice a month - - cron: "0 2 1,15 * *" + schedule: + # run scans twice a month + - cron: '0 2 1,15 * *' jobs: blackduck: - runs-on: ubuntu-latest - steps: - - name: Checkout Code - uses: actions/checkout@v2 - - - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v2 - with: - node-version: "16" - cache: "npm" - - run: npm install - - run: npm run build - - # ota-admin-portal - - name: Run Synopsys Detect - ota-admin-portal - uses: synopsys-sig/detect-action@v0.3.2 - env: - DETECT_PROJECT_NAME: ota-admin-portal - DETECT_EXCLUDED_DIRECTORIES: node_modules - DETECT_PROJECT_VERSION_NAME: default - DETECT_NPM_INCLUDE_DEV_DEPENDENCIES: "FALSE" - # DETECT_DETECTOR_SEARCH_EXCLUSION_DEFAULTS: "true" - DETECT_DETECTOR_SEARCH_DEPTH: 0 - DETECT_DETECTOR_SEARCH_CONTINUE: "true" - - with: - github-token: ${{ secrets.GITHUB_TOKEN }} - detect-version: 7.9.0 - blackduck-url: ${{ secrets.BLACKDUCK_URL }} - blackduck-api-token: ${{ secrets.BLACKDUCK_API_KEY }} - scan-mode: INTELLIGENT + name: Blackduck scan + uses: Fisker-Inc/github-actions/.github/workflows/blackduck.yml@main + with: + project: ota-admin-portal From 7d14144b81043f156e1eb2e26ce6dd04d4c6d3c5 Mon Sep 17 00:00:00 2001 From: das31 <31259710+das31@users.noreply.github.com> Date: Fri, 13 Jan 2023 16:30:20 -0500 Subject: [PATCH 08/13] CEC-1711-fix-digital-twin-ver2 (#258) * first commit * fix build error --- src/components/DigitalTwin/index.js | 19 ++++++++++++++++--- src/components/VehicleMap/index.jsx | 11 +---------- 2 files changed, 17 insertions(+), 13 deletions(-) diff --git a/src/components/DigitalTwin/index.js b/src/components/DigitalTwin/index.js index 20acbfe..82b41dd 100644 --- a/src/components/DigitalTwin/index.js +++ b/src/components/DigitalTwin/index.js @@ -14,7 +14,7 @@ const mapOpenCloseState = (value) => const DigitalTwin = (props) => { const classes = useStyles(); - const { battery, doors, location, trex_version, ip, updated, windows, sunroof, dbc, door_locks } = props; + const { battery, doors, location, trex_version, ip, updated, windows,misc_windows ,sunroof, dbc, door_locks } = props; return (
    @@ -47,7 +47,21 @@ const DigitalTwin = (props) => { if (value[1] === 0) { return keyValueTemplate(value[0], "closed"); } else { - return keyValueTemplate(value[0], `${value[1]}% open`); + const percentOpen = Math.min(value[1], 100); + return keyValueTemplate(value[0], `${percentOpen}% open`); + } + })} +
    + )} + {misc_windows != null && ( +
    +

    Misc Windows

    + {Object.entries(misc_windows).map((value) => { + if (value[1] === 0) { + return keyValueTemplate(value[0], "closed"); + } else { + const percentOpen = Math.min(value[1], 100); + return keyValueTemplate(value[0], `${percentOpen}% open`); } })}
    @@ -55,7 +69,6 @@ const DigitalTwin = (props) => { {sunroof != null && (

    Sunroof

    - {/* {Object.entries(sunroof).map(mapOpenCloseState)} */} {Object.entries(sunroof).map((value) => { if (value[1] === 0) { return keyValueTemplate(value[0], "closed"); diff --git a/src/components/VehicleMap/index.jsx b/src/components/VehicleMap/index.jsx index ff61861..2069e51 100644 --- a/src/components/VehicleMap/index.jsx +++ b/src/components/VehicleMap/index.jsx @@ -185,16 +185,7 @@ const Component = () => { {carState ? ( From 19ad3791684811c4d0e59faef0a9829becfe93ff Mon Sep 17 00:00:00 2001 From: das31 <31259710+das31@users.noreply.github.com> Date: Fri, 13 Jan 2023 17:27:01 -0500 Subject: [PATCH 09/13] CEC-1711-fix-digital-twin-ver3 (#259) --- src/components/DigitalTwin/index.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/components/DigitalTwin/index.js b/src/components/DigitalTwin/index.js index 82b41dd..2ddd5ad 100644 --- a/src/components/DigitalTwin/index.js +++ b/src/components/DigitalTwin/index.js @@ -14,7 +14,7 @@ const mapOpenCloseState = (value) => const DigitalTwin = (props) => { const classes = useStyles(); - const { battery, doors, location, trex_version, ip, updated, windows,misc_windows ,sunroof, dbc, door_locks } = props; + const { battery, doors, location, trex_version, ip, updated, windows, misc_windows, sunroof, dbc, door_locks } = props; return (
    @@ -35,7 +35,7 @@ const DigitalTwin = (props) => { if (value[0] === "driver") { return keyValueTemplate(value[0], value[1] ? "Open" : "Closed"); } else { - return keyValueTemplate(value[0], value[1] ?"Unlocked" : "Locked" ); + return keyValueTemplate(value[0], value[1] ? "Unlocked" : "Locked"); } })}
    @@ -73,7 +73,8 @@ const DigitalTwin = (props) => { if (value[1] === 0) { return keyValueTemplate(value[0], "closed"); } else { - return keyValueTemplate(value[0], `${value[1]}% open`); + const percentOpen = Math.min(value[1], 100); + return keyValueTemplate(value[0], `${percentOpen}% open`); } })}
    From c5a5839d41d2cf9c55e01f46134e6349840505bd Mon Sep 17 00:00:00 2001 From: John Wu <76966357+jwu-fisker@users.noreply.github.com> Date: Fri, 13 Jan 2023 15:29:31 -0800 Subject: [PATCH 10/13] CEC-3519 Add car version history (#260) * CEC-3519 Add car version history CEC-3455 Delete button is icon and remove column CEC-3496 Fix Issue delete * smell * Remove tab from issues details page * Fix date format --- .../App/__snapshots__/App.test.js.snap | 330 ++++++++++-------- src/components/Cars/Status/CarUpdatesTab.jsx | 16 +- .../Cars/Status/CarUpdatesTab.test.jsx | 7 +- src/components/Cars/Status/ECUsTab.jsx | 36 ++ src/components/Cars/Status/ECUsTab.test.jsx | 44 +++ .../__snapshots__/CarUpdatesTab.test.jsx.snap | 167 +++------ .../__snapshots__/ECUsTab.test.jsx.snap | 309 ++++++++++++++++ .../Status/__snapshots__/index.test.jsx.snap | 34 +- src/components/Cars/Status/index.jsx | 6 + src/components/Contexts/VehicleContext.jsx | 12 + .../Controls/CarVersionLogTable/index.jsx | 136 ++++++++ .../Controls/IssueSelectionTable/index.jsx | 46 +-- src/components/Issues/Info/Details/index.jsx | 4 +- src/components/Issues/Info/index.jsx | 71 +--- src/services/__mocks__/vehiclesAPI.js | 21 +- src/services/vehiclesAPI.js | 15 +- 16 files changed, 889 insertions(+), 365 deletions(-) create mode 100644 src/components/Cars/Status/ECUsTab.jsx create mode 100644 src/components/Cars/Status/ECUsTab.test.jsx create mode 100644 src/components/Cars/Status/__snapshots__/ECUsTab.test.jsx.snap create mode 100644 src/components/Controls/CarVersionLogTable/index.jsx diff --git a/src/components/App/__snapshots__/App.test.js.snap b/src/components/App/__snapshots__/App.test.js.snap index 3ecf212..fe162bb 100644 --- a/src/components/App/__snapshots__/App.test.js.snap +++ b/src/components/App/__snapshots__/App.test.js.snap @@ -1752,115 +1752,64 @@ exports[`App Route /issue-info authenticated 1`] = ` class="makeStyles-paper-0 makeStyles-tableSize-0" >
    -
    -
    -
    - -
    - -
    -
    -
    -
    + Issue Details +
    -
    - Issue Details -
    -
    -
    -

    - - ID - - : - FISKER123 -

    -

    - - VIN - - : - 1GNGC26RXXJ407648 -

    -

    - - Title - - : - sometitle -

    -

    - - Description - - : - 2343242 -

    -

    - - timestamp - - : - 2022-12-09T23:16:38.074858Z -

    - Issue images -
    -
    +

    + + ID + + : + FISKER123 +

    +

    + + VIN + + : + 1GNGC26RXXJ407648 +

    +

    + + Title + + : + sometitle +

    +

    + + Description + + : + 2343242 +

    +

    + + timestamp + + : + 12/9/2022 11:16:38 PM +

    + Issue images
    @@ -2472,29 +2421,6 @@ exports[`App Route /issues authenticated 1`] = ` - - - Description - - - sometitle - - 2343242 - @@ -2616,11 +2537,6 @@ exports[`App Route /issues authenticated 1`] = ` > sometitle - - 2343242 - @@ -2639,8 +2555,122 @@ exports[`App Route /issues authenticated 1`] = ` - - No issues found + +
    +
    +

    + Rows per page: +

    +
    + + +
    +

    + 0-0 of 0 +

    +
    + + +
    +
    @@ -9623,8 +9653,12 @@ exports[`App Route /vehicle-status authenticated 1`] = ` class="MuiTabs-root" >
    +
    - Remote Commands + ECUs + + Remote Commands + + + + +
    diff --git a/src/components/Cars/Status/index.jsx b/src/components/Cars/Status/index.jsx index d2d8cec..1ea797f 100644 --- a/src/components/Cars/Status/index.jsx +++ b/src/components/Cars/Status/index.jsx @@ -14,6 +14,7 @@ import CANSignalsTab from "./CANSignalsTab"; import CarUpdatesTab from "./CarUpdatesTab"; import CarDetailsTab from "./DetailsTab"; import DigitalTwinTab from "./DigitalTwinTab"; +import ECUsTab from "./ECUsTab"; import FleetsTab from "./FleetsTab"; import RemoteCommandsTab from "./RemoteCommandsTab"; @@ -41,6 +42,10 @@ const TabViews = [ label: "CAN Signals", component: CANSignalsTab, }, + { + label: "ECUs", + component: ECUsTab, + }, { label: "Remote Commands", component: RemoteCommandsTab, @@ -110,6 +115,7 @@ const CarStatus = () => { value={tabIndex} onChange={handleTabChange} aria-label="car tabs" + variant="scrollable" indicatorColor="secondary"> {tabs.map((item, index) => )} diff --git a/src/components/Contexts/VehicleContext.jsx b/src/components/Contexts/VehicleContext.jsx index cf4062a..412c64e 100644 --- a/src/components/Contexts/VehicleContext.jsx +++ b/src/components/Contexts/VehicleContext.jsx @@ -233,6 +233,17 @@ export const VehicleProvider = ({ children }) => { } } + const getVersionLog = async (search, token) => { + try { + setBusy(true); + const result = await api.getVersionLog(search, token); + if (result.error) throw new Error(`Get version log error. ${result.message}`); + return result; + } finally { + setBusy(false); + } + }; + return ( { sendCommand, updateVehicle, getFleets, + getVersionLog, }} > {children} diff --git a/src/components/Controls/CarVersionLogTable/index.jsx b/src/components/Controls/CarVersionLogTable/index.jsx new file mode 100644 index 0000000..fc91563 --- /dev/null +++ b/src/components/Controls/CarVersionLogTable/index.jsx @@ -0,0 +1,136 @@ +import { + Table, + TableBody, + TableCell, + TableFooter, + TablePagination, + TableRow +} from "@material-ui/core"; +import clsx from "clsx"; +import React, { useEffect, useState } from "react"; + +import { logger } from "../../../services/monitoring"; +import { LocalDateTimeString } from "../../../utils/dates"; +import { useStatusContext } from "../../Contexts/StatusContext"; +import { useVehicleContext } from "../../Contexts/VehicleContext"; +import TableHeaderSortable from "../../Table/HeaderSortable"; +import { useLocalStorage } from "../../useLocalStorage"; + +const tableColumns = [ + { + id: "version_source", + label: "Type", + }, + { + id: "version", + label: "Version", + }, + { + id: "created_at", + label: "Date", + }, +]; + +const PAGE_SIZE = "CAR_VERSIONLOG_TABLE_PAGE_SIZE"; + +const CarVersionLogTable = ({ vin, token, classes }) => { + const [versions, setVersions] = useState([]); + const [total, setTotal] = useState(0); + const [pageSize, setPageSize] = useLocalStorage(PAGE_SIZE, 10); + const [pageIndex, setPageIndex] = useState(0); + const [orderBy, setOrderBy] = useState("created_at"); + const [order, setOrder] = useState("desc"); + const { getVersionLog } = useVehicleContext(); + const { setMessage } = useStatusContext(); + + useEffect(() => { + (async () => { + try { + if (!vin || !token) return; + const result = await getVersionLog( + { + vin, + limit: pageSize, + offset: pageSize * pageIndex, + order: `${orderBy} ${order}`, + }, + token + ); + setVersions(result.data); + if (result.total > -1) setTotal(result.total); + } catch (e) { + setMessage(e.message); + logger.warn(e.stack); + } + })(); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [vin, token, pageIndex, pageSize, orderBy, order]); + + const handleChangePageIndex = (event, newIndex) => { + setPageIndex(newIndex); + }; + + const handleChangePageSize = (event) => { + setPageSize(parseInt(event.target.value, 10)); + setPageIndex(0); + }; + + const handleSort = (event, property) => { + try { + if (property === orderBy) { + if (order === "asc") { + setOrder("desc"); + } else { + setOrder("asc"); + } + } else { + setOrderBy(property); + setOrder("asc"); + } + } catch (e) { + logger.warn(e.stack); + } + }; + + return ( +
    + + + + {versions && versions.map((row, i) => ( + + {row.version_source} + {row.version} + {LocalDateTimeString(row.created_at)} + + ))} + + + + + + +
    +
    + ); +}; + +export default CarVersionLogTable; diff --git a/src/components/Controls/IssueSelectionTable/index.jsx b/src/components/Controls/IssueSelectionTable/index.jsx index 7dc40cb..9ef35d6 100644 --- a/src/components/Controls/IssueSelectionTable/index.jsx +++ b/src/components/Controls/IssueSelectionTable/index.jsx @@ -1,26 +1,26 @@ -import React, { useEffect, useState } from "react"; -import { Link } from "react-router-dom"; -import PropTypes from "prop-types"; import { Table, TableBody, TableCell, TableFooter, TablePagination, - TableRow, - Button, + TableRow } from "@material-ui/core"; +import DeleteIcon from "@material-ui/icons/Delete"; import clsx from "clsx"; +import PropTypes from "prop-types"; +import React, { useEffect, useState } from "react"; +import { Link } from "react-router-dom"; +import { logger } from "../../../services/monitoring"; +import { LocalDateTimeString } from "../../../utils/dates"; +import { Permissions } from "../../../utils/roles"; import { useIssueContext } from "../../Contexts/IssueContext"; import { useStatusContext } from "../../Contexts/StatusContext"; -import { LocalDateTimeString } from "../../../utils/dates"; +import { useUserContext } from "../../Contexts/UserContext"; import TableHeaderSortable from "../../Table/HeaderSortable"; -import { logger } from "../../../services/monitoring"; import { useLocalStorage } from "../../useLocalStorage"; import { RoleWrap } from "../RoleWrap"; -import { useUserContext } from "../../Contexts/UserContext"; -import { Permissions } from "../../../utils/roles"; const tableColumns = [ { @@ -35,10 +35,6 @@ const tableColumns = [ id: "title", label: "Title", }, - { - id: "description", - label: "Description", - }, { id: "driver_id", label: "Driver ID", @@ -69,7 +65,7 @@ const IssueSelectionTable = (props) => { const [pageIndex, setPageIndex] = useState(0); const [orderBy, setOrderBy] = useState("created_at"); const [order, setOrder] = useState("asc"); - const { getIssues, issues, totalIssues = 0 } = useIssueContext(); + const { deleteIssue, getIssues, issues, totalIssues = 0 } = useIssueContext(); const { groups, providers } = useUserContext(); const { setMessage } = useStatusContext(); @@ -132,12 +128,19 @@ const IssueSelectionTable = (props) => { setPageIndex(0); }, [search]); - const { deleteIssue } = useIssueContext(); const handleDelete = (id) => { deleteIssue(id, token).then(() => { - getIssues(token) + getIssues( + { + limit: pageSize, + offset: pageSize * pageIndex, + order: `${orderBy} ${order}`, + }, + token + ); }); }; + return (
    @@ -161,7 +164,6 @@ const IssueSelectionTable = (props) => { {row.vin}{row.title} - {row.description || ""}{row.driver_id} {LocalDateTimeString(row.timestamp)} @@ -172,7 +174,9 @@ const IssueSelectionTable = (props) => { rolesPerProvider={Permissions.FiskerDelete} > - + handleDelete(row.id)}> + + @@ -181,12 +185,9 @@ const IssueSelectionTable = (props) => { - {totalIssues === 0 ? ( - - ) : ( { onPageChange={handleChangePageIndex} onRowsPerPageChange={handleChangePageSize} /> - )}
    No issues found
    diff --git a/src/components/Issues/Info/Details/index.jsx b/src/components/Issues/Info/Details/index.jsx index c3031aa..f0dddf5 100644 --- a/src/components/Issues/Info/Details/index.jsx +++ b/src/components/Issues/Info/Details/index.jsx @@ -2,6 +2,7 @@ import { Grid } from "@material-ui/core"; import clsx from "clsx"; import React, { useEffect } from "react"; +import { LocalDateTimeString } from "../../../../utils/dates"; import { logger } from "../../../../services/monitoring"; import { useStatusContext } from "../../../Contexts/StatusContext"; import { useUserContext } from "../../../Contexts/UserContext"; @@ -11,7 +12,6 @@ import { } from "../../../Contexts/IssueContext"; import useStyles from "../../../useStyles"; - const MainForm = ({ id }) => { const classes = useStyles(); const { setMessage } = useStatusContext(); @@ -55,7 +55,7 @@ const MainForm = ({ id }) => { Description: {issue.description}

    - timestamp: {issue.timestamp} + timestamp: {LocalDateTimeString(issue.timestamp)}

    {issue.images && issue.images.map((image, index) => ( Issue images diff --git a/src/components/Issues/Info/index.jsx b/src/components/Issues/Info/index.jsx index bfa6deb..39942af 100644 --- a/src/components/Issues/Info/index.jsx +++ b/src/components/Issues/Info/index.jsx @@ -1,55 +1,15 @@ -import { Box, Tab, Tabs } from "@material-ui/core"; import clsx from "clsx"; -import React, { useEffect, useState } from "react"; +import React, { useEffect } from "react"; import { useParams } from "react-router"; -import { useLocation } from "react-router-dom"; -import { hasRole } from "../../../utils/roles"; import { useStatusContext } from "../../Contexts/StatusContext"; -import { useUserContext } from "../../Contexts/UserContext"; -import TabPanel from "../../Controls/TabPanel"; import useStyles from "../../useStyles"; import IssueDetailsTab from "./DetailsTab"; - -const tabHashes = ["details", "updates", "filters"]; - -const TabViews = [ - { - label: "Details", - component: IssueDetailsTab, - }, - -]; - -const filterTabs = (data, groups, providers) => { - return data.reduce((result, item) => { - if (hasRole(groups, item.rolesPerProvider, providers)) { - result.push(item); - } - return result; - }, []); -}; - const IssueInfo = () => { const { id } = useParams(); const classes = useStyles(); const { setTitle, setSitePath } = useStatusContext(); - const { hash } = useLocation(); - const [tabIndex, setTabIndex] = useState(0); - const [tabs, setTabs] = useState([]); - const { groups, providers } = useUserContext(); - - useEffect(() => { - const data = filterTabs(TabViews, groups, providers); - setTabs(data); - }, [groups, providers]); - - useEffect(() => { - const key = hash.replace("#", ""); - const index = tabHashes.findIndex((element) => element === key); - if (index >= 0) setTabIndex(index); - }, [hash]); useEffect(() => { const title = `Issue ${id} Details`; @@ -66,39 +26,12 @@ const IssueInfo = () => { // eslint-disable-next-line react-hooks/exhaustive-deps }, [id]); - const handleTabChange = (_event, newIndex) => { - setTabIndex(newIndex); - }; - return (
    - - - {tabs.map((item, index) => )} - - - {tabs.map((item, index) => ( - - - - ))} +
    ); }; -function tabProps(index) { - return { - id: `tab-${index}`, - "aria-controls": `tabpanel-${index}`, - }; -} - export default IssueInfo; diff --git a/src/services/__mocks__/vehiclesAPI.js b/src/services/__mocks__/vehiclesAPI.js index ccd7537..d18a88b 100644 --- a/src/services/__mocks__/vehiclesAPI.js +++ b/src/services/__mocks__/vehiclesAPI.js @@ -116,7 +116,26 @@ const vehiclesAPI = { }, getCANSignals: async (vin, vehicle) => { return signals; - } + }, + getVersionLog: async (vin) => ({ + "data": [ + { + "id": 1, + "vin": "${vin}", + "version_source": "TREX", + "version": "0.9.56", + "created_at": "2023-01-13T02:11:33.327214Z" + }, + { + "id": 2, + "vin": "${vin}", + "version_source": "DBC", + "version": "386c18977a1be3cda60c953e5902c680dbe82b89523f2527e80cd9db863db991", + "created_at": "2023-01-13T02:11:33.330932Z" + } + ], + "total": 2 + }) }; export default vehiclesAPI; diff --git a/src/services/vehiclesAPI.js b/src/services/vehiclesAPI.js index 86a2bc8..9d8d0db 100644 --- a/src/services/vehiclesAPI.js +++ b/src/services/vehiclesAPI.js @@ -1,5 +1,5 @@ import { - addQueryParams, errorHandler, fetchRespHandler, getAuthHeaderOptions + addQueryParams, errorHandler, fetchRespHandler, getAuthHeaderOptions } from "../utils/http"; const API_ENDPOINT = process.env.REACT_APP_OTA_SERVICE_URL; @@ -172,6 +172,19 @@ const vehiclesAPI = { }) .then(fetchRespHandler) .catch(errorHandler), + + getVersionLog: async ({vin, ...search}, token) => { + const u = addQueryParams(`${API_ENDPOINT}/vehicle/${vin}/version/logs`, search); + return fetch(u, { + method: "GET", + headers: Object.assign( + { "Content-Type": "application/json" }, + getAuthHeaderOptions(token) + ), + }) + .then(fetchRespHandler) + .catch(errorHandler) + }, }; export default vehiclesAPI; From e7e879ab133fcaa84db9cfb08bdaf42878bc496f Mon Sep 17 00:00:00 2001 From: John Wu <76966357+jwu-fisker@users.noreply.github.com> Date: Fri, 13 Jan 2023 16:14:46 -0800 Subject: [PATCH 11/13] CEC-3455 fix issue details label (#263) --- src/components/App/__snapshots__/App.test.js.snap | 2 +- src/components/Issues/Info/Details/index.jsx | 11 +++++------ 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/components/App/__snapshots__/App.test.js.snap b/src/components/App/__snapshots__/App.test.js.snap index fe162bb..89e8f20 100644 --- a/src/components/App/__snapshots__/App.test.js.snap +++ b/src/components/App/__snapshots__/App.test.js.snap @@ -1801,7 +1801,7 @@ exports[`App Route /issue-info authenticated 1`] = `

    - timestamp + Created : 12/9/2022 11:16:38 PM diff --git a/src/components/Issues/Info/Details/index.jsx b/src/components/Issues/Info/Details/index.jsx index f0dddf5..307eafc 100644 --- a/src/components/Issues/Info/Details/index.jsx +++ b/src/components/Issues/Info/Details/index.jsx @@ -2,14 +2,13 @@ import { Grid } from "@material-ui/core"; import clsx from "clsx"; import React, { useEffect } from "react"; -import { LocalDateTimeString } from "../../../../utils/dates"; import { logger } from "../../../../services/monitoring"; +import { LocalDateTimeString } from "../../../../utils/dates"; +import { + IssueProvider, useIssueContext +} from "../../../Contexts/IssueContext"; import { useStatusContext } from "../../../Contexts/StatusContext"; import { useUserContext } from "../../../Contexts/UserContext"; -import { - useIssueContext, - IssueProvider -} from "../../../Contexts/IssueContext"; import useStyles from "../../../useStyles"; const MainForm = ({ id }) => { @@ -55,7 +54,7 @@ const MainForm = ({ id }) => { Description: {issue.description}

    - timestamp: {LocalDateTimeString(issue.timestamp)} + Created: {LocalDateTimeString(issue.timestamp)}

    {issue.images && issue.images.map((image, index) => ( Issue images From 17896b4c5c081fa4e5e68a8ddd7deedaf7287974 Mon Sep 17 00:00:00 2001 From: Rafi Greenberg <72412693+rafi-fisker@users.noreply.github.com> Date: Fri, 13 Jan 2023 16:16:53 -0800 Subject: [PATCH 12/13] bump superset embedded (#262) --- package-lock.json | 20 +++++++++++--------- package.json | 4 ++-- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/package-lock.json b/package-lock.json index 87ab3df..b14475f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17,7 +17,7 @@ "@material-ui/icons": "^4.11.3", "@material-ui/pickers": "^3.3.10", "@mui/material": "^5.10.14", - "@superset-ui/embedded-sdk": "^0.1.0-alpha.7", + "@superset-ui/embedded-sdk": "^0.1.0-alpha.8", "@testing-library/jest-dom": "^5.16.4", "@testing-library/react": "^12.1.4", "@testing-library/user-event": "^13.5.0", @@ -4821,11 +4821,12 @@ } }, "node_modules/@superset-ui/embedded-sdk": { - "version": "0.1.0-alpha.7", - "resolved": "https://registry.npmjs.org/@superset-ui/embedded-sdk/-/embedded-sdk-0.1.0-alpha.7.tgz", - "integrity": "sha512-sBzfSnPvRw15D6A053t4gpKDydHaAjyn88By1Z3Vl3PWZScW6sTHh8n/5A69qMSJVorqFQ3g0IUquTF8sutGEQ==", + "version": "0.1.0-alpha.8", + "resolved": "https://registry.npmjs.org/@superset-ui/embedded-sdk/-/embedded-sdk-0.1.0-alpha.8.tgz", + "integrity": "sha512-X07s8uMbvQDEMe5GRyKXhVW5XzPm+yV4KQSo7WifWz7TdqLUT+rjNsL4jZAGAoO0/n0Fj7gFoDpT6bGlSULe5g==", "dependencies": { - "@superset-ui/switchboard": "^0.18.26-0" + "@superset-ui/switchboard": "^0.18.26-0", + "jwt-decode": "^3.1.2" } }, "node_modules/@superset-ui/switchboard": { @@ -21106,11 +21107,12 @@ } }, "@superset-ui/embedded-sdk": { - "version": "0.1.0-alpha.7", - "resolved": "https://registry.npmjs.org/@superset-ui/embedded-sdk/-/embedded-sdk-0.1.0-alpha.7.tgz", - "integrity": "sha512-sBzfSnPvRw15D6A053t4gpKDydHaAjyn88By1Z3Vl3PWZScW6sTHh8n/5A69qMSJVorqFQ3g0IUquTF8sutGEQ==", + "version": "0.1.0-alpha.8", + "resolved": "https://registry.npmjs.org/@superset-ui/embedded-sdk/-/embedded-sdk-0.1.0-alpha.8.tgz", + "integrity": "sha512-X07s8uMbvQDEMe5GRyKXhVW5XzPm+yV4KQSo7WifWz7TdqLUT+rjNsL4jZAGAoO0/n0Fj7gFoDpT6bGlSULe5g==", "requires": { - "@superset-ui/switchboard": "^0.18.26-0" + "@superset-ui/switchboard": "^0.18.26-0", + "jwt-decode": "^3.1.2" } }, "@superset-ui/switchboard": { diff --git a/package.json b/package.json index 0198a1f..f584165 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "@material-ui/icons": "^4.11.3", "@material-ui/pickers": "^3.3.10", "@mui/material": "^5.10.14", - "@superset-ui/embedded-sdk": "^0.1.0-alpha.7", + "@superset-ui/embedded-sdk": "^0.1.0-alpha.8", "@testing-library/jest-dom": "^5.16.4", "@testing-library/react": "^12.1.4", "@testing-library/user-event": "^13.5.0", @@ -87,4 +87,4 @@ "lcov" ] } -} +} \ No newline at end of file From f2674464a9bdc26a718226ca897d94c4500e6e11 Mon Sep 17 00:00:00 2001 From: John Wu <76966357+jwu-fisker@users.noreply.github.com> Date: Fri, 13 Jan 2023 17:04:29 -0800 Subject: [PATCH 13/13] CEC-1711 fix digital twin dbc (#265) --- .../Status/__snapshots__/DigitalTwinTab.test.jsx.snap | 11 +++++++++++ src/components/Contexts/__mocks__/VehicleContext.jsx | 1 + src/components/DigitalTwin/index.js | 8 ++++---- 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/src/components/Cars/Status/__snapshots__/DigitalTwinTab.test.jsx.snap b/src/components/Cars/Status/__snapshots__/DigitalTwinTab.test.jsx.snap index a22fa67..0858fd3 100644 --- a/src/components/Cars/Status/__snapshots__/DigitalTwinTab.test.jsx.snap +++ b/src/components/Cars/Status/__snapshots__/DigitalTwinTab.test.jsx.snap @@ -187,6 +187,17 @@ exports[`DigitalTwinTab Render 1`] = ` 7/26/2022 12:26:38 AM

    +
    +

    + + DBC version + + : + d439abd3662dd20099f49dd8f43f7b145202e961caa2b5aba2c6154c8096348b +

    +
    diff --git a/src/components/Contexts/__mocks__/VehicleContext.jsx b/src/components/Contexts/__mocks__/VehicleContext.jsx index f31d80c..c545745 100644 --- a/src/components/Contexts/__mocks__/VehicleContext.jsx +++ b/src/components/Contexts/__mocks__/VehicleContext.jsx @@ -70,6 +70,7 @@ let vehicleState = { temperature: 26, }, trex_version: "1000000", + dbc_version: "d439abd3662dd20099f49dd8f43f7b145202e961caa2b5aba2c6154c8096348b", ip: "172.20.0.17:49850", updated: "2022-07-26T00:26:38.880381Z", }, diff --git a/src/components/DigitalTwin/index.js b/src/components/DigitalTwin/index.js index 2ddd5ad..a0c1141 100644 --- a/src/components/DigitalTwin/index.js +++ b/src/components/DigitalTwin/index.js @@ -1,7 +1,7 @@ import React from "react"; -import useStyles from "../useStyles"; import { LocalDateTimeString } from "../../utils/dates"; +import useStyles from "../useStyles"; const keyValueTemplate = (key, value) => (

    @@ -14,7 +14,7 @@ const mapOpenCloseState = (value) => const DigitalTwin = (props) => { const classes = useStyles(); - const { battery, doors, location, trex_version, ip, updated, windows, misc_windows, sunroof, dbc, door_locks } = props; + const { battery, doors, location, trex_version, ip, updated, windows, misc_windows, sunroof, dbc_version, door_locks } = props; return (

    @@ -106,9 +106,9 @@ const DigitalTwin = (props) => { {keyValueTemplate("Updated at", LocalDateTimeString(updated))}
    )} - {dbc != null && ( + {dbc_version != null && (
    - {keyValueTemplate("DBC version", dbc)} + {keyValueTemplate("DBC version", dbc_version)}
    )}