Merge branch 'release/0.0.3'
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
REACT_APP_AUTH_CALLBACK_URL=https://ota-admin.cec-euprd.fiskerinc.com
|
||||
REACT_APP_AUTH_SERVICE_URL=https://gw.cec-prd.fiskerinc.com/compute_auth
|
||||
REACT_APP_CERT_SERVICE_URL=https://gw.cec-prd.fiskerinc.com/certificate
|
||||
REACT_APP_ENV=cec-euprd
|
||||
REACT_APP_MAGNA_PROVIDER=Magna
|
||||
REACT_APP_MAGNA_GROUP_ID=68273225-9da4-4fa7-aea5-38e16ec471fe
|
||||
REACT_APP_OTA_SERVICE_URL=https://gw.cec-euprd.fiskerinc.com/ota_update
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
REACT_APP_AUTH_CALLBACK_URL=https://ota-admin.cec-prd.fiskerinc.com
|
||||
REACT_APP_AUTH_SERVICE_URL=https://gw.cec-prd.fiskerinc.com/compute_auth
|
||||
REACT_APP_CERT_SERVICE_URL=https://gw.cec-prd.fiskerinc.com/certificate
|
||||
REACT_APP_ENV=cec-prd
|
||||
REACT_APP_MAGNA_PROVIDER=Magna
|
||||
REACT_APP_MAGNA_GROUP_ID=68273225-9da4-4fa7-aea5-38e16ec471fe
|
||||
REACT_APP_OTA_SERVICE_URL=https://gw.cec-prd.fiskerinc.com/ota_update
|
||||
|
||||
1
.env.dev
1
.env.dev
@@ -1,6 +1,7 @@
|
||||
REACT_APP_AUTH_CALLBACK_URL=https://dev-ota-admin.cloud.fiskerinc.com
|
||||
REACT_APP_AUTH_SERVICE_URL=https://dev-gw.cloud.fiskerinc.com/compute_auth
|
||||
REACT_APP_CERT_SERVICE_URL=https://dev-gw.cloud.fiskerinc.com/certificate
|
||||
REACT_APP_ENV=dev
|
||||
REACT_APP_MAGNA_PROVIDER=Fisker-QA
|
||||
REACT_APP_MAGNA_GROUP_ID=efcc3025-e2d8-4212-8227-805c7be39d2c
|
||||
REACT_APP_OTA_SERVICE_URL=https://dev-gw.cloud.fiskerinc.com/ota_update
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
REACT_APP_AUTH_CALLBACK_URL=http://localhost:3000
|
||||
REACT_APP_AUTH_SERVICE_URL=http://localhost/compute_auth
|
||||
REACT_APP_CERT_SERVICE_URL=http://localhost/certificate
|
||||
REACT_APP_ENV=local
|
||||
REACT_APP_MAGNA_PROVIDER=Fisker-QA
|
||||
REACT_APP_MAGNA_GROUP_ID=efcc3025-e2d8-4212-8227-805c7be39d2c
|
||||
REACT_APP_OTA_SERVICE_URL=http://localhost/ota_update
|
||||
|
||||
1
.env.prd
1
.env.prd
@@ -1,6 +1,7 @@
|
||||
REACT_APP_AUTH_CALLBACK_URL=https://ota-admin.cloud.fiskerinc.com
|
||||
REACT_APP_AUTH_SERVICE_URL=https://gw.cloud.fiskerinc.com/compute_auth
|
||||
REACT_APP_CERT_SERVICE_URL=https://gw.cloud.fiskerinc.com/certificate
|
||||
REACT_APP_ENV=prd
|
||||
REACT_APP_MAGNA_PROVIDER=Magna
|
||||
REACT_APP_MAGNA_GROUP_ID=68273225-9da4-4fa7-aea5-38e16ec471fe
|
||||
REACT_APP_OTA_SERVICE_URL=https://gw.cloud.fiskerinc.com/ota_update
|
||||
|
||||
1
.env.stg
1
.env.stg
@@ -1,6 +1,7 @@
|
||||
REACT_APP_AUTH_CALLBACK_URL=https://stg-ota-admin.cloud.fiskerinc.com
|
||||
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_ENV=stg
|
||||
REACT_APP_MAGNA_PROVIDER=Magna
|
||||
REACT_APP_MAGNA_GROUP_ID=68273225-9da4-4fa7-aea5-38e16ec471fe
|
||||
REACT_APP_OTA_SERVICE_URL=https://stg-gw.cloud.fiskerinc.com/ota_update
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
REACT_APP_AUTH_CALLBACK_URL=http://localhost:3000
|
||||
REACT_APP_AUTH_SERVICE_URL=http://localhost/compute_auth
|
||||
REACT_APP_CERT_SERVICE_URL=http://localhost/certificate
|
||||
REACT_APP_ENV=local
|
||||
REACT_APP_MAGNA_PROVIDER=Magna
|
||||
REACT_APP_MAGNA_GROUP_ID=68273225-9da4-4fa7-aea5-38e16ec471fe
|
||||
REACT_APP_OTA_SERVICE_URL=http://localhost/ota_update
|
||||
|
||||
29
.eslintrc.json
Normal file
29
.eslintrc.json
Normal file
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"env": {
|
||||
"browser": true,
|
||||
"es6": true,
|
||||
"jest": true,
|
||||
"node": true
|
||||
},
|
||||
"extends": [
|
||||
"eslint:recommended",
|
||||
"plugin:react/jsx-runtime",
|
||||
"react-app",
|
||||
"react-app/jest"
|
||||
],
|
||||
"overrides": [],
|
||||
"parserOptions": {
|
||||
"ecmaVersion": "latest",
|
||||
"sourceType": "module"
|
||||
},
|
||||
"plugins": [
|
||||
"react"
|
||||
],
|
||||
"rules": {
|
||||
"no-unused-vars": "warn"
|
||||
},
|
||||
"ignorePatterns": [
|
||||
"build/**/*",
|
||||
"*.test.*"
|
||||
]
|
||||
}
|
||||
4
.github/workflows/blackduck.yml
vendored
4
.github/workflows/blackduck.yml
vendored
@@ -11,3 +11,7 @@ jobs:
|
||||
uses: Fisker-Inc/github-actions/.github/workflows/blackduck.yml@main
|
||||
with:
|
||||
project: ota-admin-portal
|
||||
secrets:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
blackduck-url: ${{ secrets.BLACKDUCK_URL }}
|
||||
blackduck-api-token: ${{ secrets.BLACKDUCK_API_KEY }}
|
||||
10
.github/workflows/pr.yml
vendored
Normal file
10
.github/workflows/pr.yml
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
name: Pull Request Jira Check
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened, edited, synchronize, reopened]
|
||||
|
||||
|
||||
jobs:
|
||||
prcheck:
|
||||
uses: Fisker-Inc/github-actions/.github/workflows/pr.yml@main
|
||||
4
.github/workflows/test.yml
vendored
4
.github/workflows/test.yml
vendored
@@ -11,12 +11,12 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Use Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v2
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: "16"
|
||||
cache: "npm"
|
||||
|
||||
1244
package-lock.json
generated
1244
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -68,6 +68,8 @@
|
||||
"node": "^16.13.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"eslint": "^8.32.0",
|
||||
"eslint-plugin-react": "^7.32.1",
|
||||
"react-test-renderer": "^17.0.2"
|
||||
},
|
||||
"jest": {
|
||||
|
||||
@@ -1778,6 +1778,13 @@ exports[`App Route /issue-info authenticated 1`] = `
|
||||
:
|
||||
FISKER123
|
||||
</p>
|
||||
<p>
|
||||
<b>
|
||||
Driver ID
|
||||
</b>
|
||||
:
|
||||
valid-cognito-id-1
|
||||
</p>
|
||||
<p>
|
||||
<b>
|
||||
VIN
|
||||
@@ -9959,6 +9966,16 @@ exports[`App Route /vehicle-status authenticated 1`] = `
|
||||
3
|
||||
</p>
|
||||
</div>
|
||||
<div
|
||||
class="MuiGrid-root makeStyles-textCenterAlign-0 MuiGrid-item MuiGrid-grid-md-12"
|
||||
>
|
||||
<p>
|
||||
<b>
|
||||
DebugMask
|
||||
</b>
|
||||
:
|
||||
</p>
|
||||
</div>
|
||||
<div
|
||||
class="MuiGrid-root makeStyles-textCenterAlign-0 MuiGrid-item MuiGrid-grid-md-12"
|
||||
>
|
||||
|
||||
@@ -137,6 +137,16 @@ exports[`VehicleDetailsTab Render 1`] = `
|
||||
3
|
||||
</p>
|
||||
</div>
|
||||
<div
|
||||
class="MuiGrid-root makeStyles-textCenterAlign-0 MuiGrid-item MuiGrid-grid-md-12"
|
||||
>
|
||||
<p>
|
||||
<b>
|
||||
DebugMask
|
||||
</b>
|
||||
:
|
||||
</p>
|
||||
</div>
|
||||
<div
|
||||
class="MuiGrid-root makeStyles-textCenterAlign-0 MuiGrid-item MuiGrid-grid-md-12"
|
||||
>
|
||||
|
||||
@@ -32,6 +32,9 @@ const MainForm = ({ vin }) => {
|
||||
providers,
|
||||
} = useUserContext();
|
||||
|
||||
const ENV = process.env.REACT_APP_ENV;
|
||||
const showDebugMask = (ENV === 'local' || ENV === 'dev' || ENV === 'stg')
|
||||
|
||||
useEffect(() => {
|
||||
(async () => {
|
||||
try {
|
||||
@@ -120,6 +123,13 @@ const MainForm = ({ vin }) => {
|
||||
</p>
|
||||
</Grid>
|
||||
)}
|
||||
{showDebugMask && (
|
||||
<Grid item md={12} className={classes.textCenterAlign}>
|
||||
<p>
|
||||
<b>DebugMask</b>: {vehicle.debug_mask}
|
||||
</p>
|
||||
</Grid>
|
||||
)}
|
||||
<Grid item md={12} className={classes.textCenterAlign}>
|
||||
<RoleWrap
|
||||
groups={groups}
|
||||
|
||||
@@ -80,6 +80,29 @@ exports[`CarUpdatesTab Render 1`] = `
|
||||
</svg>
|
||||
</span>
|
||||
</th>
|
||||
<th
|
||||
class="MuiTableCell-root MuiTableCell-head MuiTableCell-alignCenter"
|
||||
scope="col"
|
||||
>
|
||||
<span
|
||||
aria-disabled="false"
|
||||
class="MuiButtonBase-root MuiTableSortLabel-root"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
>
|
||||
Username
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
class="MuiSvgIcon-root MuiTableSortLabel-icon MuiTableSortLabel-iconDirectionAsc"
|
||||
focusable="false"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
d="M20 12l-1.41-1.41L13 16.17V4h-2v12.17l-5.58-5.59L4 12l8 8 8-8z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</th>
|
||||
<th
|
||||
class="MuiTableCell-root MuiTableCell-head MuiTableCell-alignCenter"
|
||||
scope="col"
|
||||
|
||||
@@ -145,6 +145,16 @@ exports[`DetailsTab Render 1`] = `
|
||||
3
|
||||
</p>
|
||||
</div>
|
||||
<div
|
||||
class="MuiGrid-root makeStyles-textCenterAlign-0 MuiGrid-item MuiGrid-grid-md-12"
|
||||
>
|
||||
<p>
|
||||
<b>
|
||||
DebugMask
|
||||
</b>
|
||||
:
|
||||
</p>
|
||||
</div>
|
||||
<div
|
||||
class="MuiGrid-root makeStyles-textCenterAlign-0 MuiGrid-item MuiGrid-grid-md-12"
|
||||
>
|
||||
|
||||
@@ -272,6 +272,16 @@ exports[`CarStatus Render 1`] = `
|
||||
:
|
||||
</p>
|
||||
</div>
|
||||
<div
|
||||
class="MuiGrid-root makeStyles-textCenterAlign-0 MuiGrid-item MuiGrid-grid-md-12"
|
||||
>
|
||||
<p>
|
||||
<b>
|
||||
DebugMask
|
||||
</b>
|
||||
:
|
||||
</p>
|
||||
</div>
|
||||
<div
|
||||
class="MuiGrid-root makeStyles-textCenterAlign-0 MuiGrid-item MuiGrid-grid-md-12"
|
||||
>
|
||||
|
||||
@@ -931,6 +931,43 @@ exports[`VehicleUpdate Render 1`] = `
|
||||
</fieldset>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="MuiFormControl-root MuiTextField-root MuiFormControl-marginNormal MuiFormControl-fullWidth"
|
||||
>
|
||||
<label
|
||||
class="MuiFormLabel-root MuiInputLabel-root MuiInputLabel-formControl MuiInputLabel-animated MuiInputLabel-shrink MuiInputLabel-outlined"
|
||||
data-shrink="true"
|
||||
for="debug_mask"
|
||||
id="debug_mask-label"
|
||||
>
|
||||
DebugMask
|
||||
</label>
|
||||
<div
|
||||
class="MuiInputBase-root MuiOutlinedInput-root MuiInputBase-fullWidth MuiInputBase-formControl"
|
||||
>
|
||||
<input
|
||||
aria-invalid="false"
|
||||
class="MuiInputBase-input MuiOutlinedInput-input"
|
||||
id="debug_mask"
|
||||
maxlength="255"
|
||||
name="debug_mask"
|
||||
type="text"
|
||||
value=""
|
||||
/>
|
||||
<fieldset
|
||||
aria-hidden="true"
|
||||
class="PrivateNotchedOutline-root-0 MuiOutlinedInput-notchedOutline"
|
||||
>
|
||||
<legend
|
||||
class="PrivateNotchedOutline-legendLabelled-0 PrivateNotchedOutline-legendNotched-0"
|
||||
>
|
||||
<span>
|
||||
DebugMask
|
||||
</span>
|
||||
</legend>
|
||||
</fieldset>
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
class="MuiButtonBase-root MuiButton-root MuiButton-contained makeStyles-submit-0 MuiButton-containedPrimary MuiButton-fullWidth"
|
||||
tabindex="0"
|
||||
|
||||
@@ -46,6 +46,10 @@ const MainForm = () => {
|
||||
const [dataLoggerEnabled, setDataLoggerEnabled] = useState(false);
|
||||
const [maxMemBufferSize, setMaxMemBufferSize] = useState(0);
|
||||
const [maxDiskBufferSize, setMaxDiskBufferSize] = useState(0);
|
||||
const debugMaskEl = useRef(null);
|
||||
|
||||
const ENV = process.env.REACT_APP_ENV;
|
||||
const showDebugMask = (ENV === 'local' || ENV === 'dev' || ENV === 'stg')
|
||||
|
||||
useEffect(() => {
|
||||
setTitle("Update Vehicle");
|
||||
@@ -93,6 +97,11 @@ const MainForm = () => {
|
||||
setMaxMemBufferSize(vehicle.canbus.max_mem_buffer_size ?? maxMemBufferSize);
|
||||
setMaxDiskBufferSize(vehicle.canbus.max_disk_buffer_size ?? maxDiskBufferSize);
|
||||
}
|
||||
|
||||
if (showDebugMask) {
|
||||
debugMaskEl.current.value = vehicle.debug_mask ?? ""
|
||||
}
|
||||
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [vehicle]);
|
||||
|
||||
@@ -136,7 +145,8 @@ const MainForm = () => {
|
||||
data_logger_enabled: canbusEnabled ? dataLoggerEnabled : false,
|
||||
max_mem_buffer_size: canbusEnabled ? parseInt(maxMemBufferSize) : 0,
|
||||
max_disk_buffer_size: canbusEnabled && dataLoggerEnabled ? parseInt(maxDiskBufferSize) : 0
|
||||
}
|
||||
},
|
||||
debug_mask: debugMaskEl.current.value
|
||||
};
|
||||
|
||||
const result = await updateVehicle(vin, formData, token);
|
||||
@@ -379,6 +389,24 @@ const MainForm = () => {
|
||||
required
|
||||
fullWidth
|
||||
/>
|
||||
{showDebugMask && (
|
||||
<TextField
|
||||
id="debug_mask"
|
||||
name="debug_mask"
|
||||
label="DebugMask"
|
||||
InputLabelProps={{
|
||||
shrink: true
|
||||
}}
|
||||
defaultValue=""
|
||||
variant="outlined"
|
||||
margin="normal"
|
||||
inputProps={{
|
||||
maxLength: "255",
|
||||
}}
|
||||
fullWidth
|
||||
inputRef={debugMaskEl}
|
||||
/>
|
||||
)}
|
||||
<Button
|
||||
type="submit"
|
||||
disabled={busy}
|
||||
|
||||
@@ -177,6 +177,7 @@ export const CarUpdatesProvider = ({ children }) => {
|
||||
|
||||
applyProgressStatuses(result.statuses);
|
||||
} catch (e) {
|
||||
throw new Error(`Get update progress error. ${e}`);
|
||||
} finally {
|
||||
setBusy(false);
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@ let carUpdateLog = {
|
||||
{
|
||||
id: 90,
|
||||
carupdate_id: 283,
|
||||
username: "test username 1",
|
||||
status: "package_install_complete",
|
||||
error_code: 0,
|
||||
created: "2021-08-23T17:06:38.410115Z",
|
||||
@@ -38,6 +39,7 @@ let carUpdateLog = {
|
||||
{
|
||||
id: 89,
|
||||
carupdate_id: 283,
|
||||
username: "test username 2",
|
||||
status: "package_install_start",
|
||||
error_code: 0,
|
||||
info: "TEST",
|
||||
@@ -47,6 +49,7 @@ let carUpdateLog = {
|
||||
{
|
||||
id: 88,
|
||||
carupdate_id: 284,
|
||||
username: "test username 3",
|
||||
status: "install_approval_await",
|
||||
error_code: 0,
|
||||
info: "TEST",
|
||||
|
||||
@@ -14,6 +14,7 @@ import { Link } from "react-router-dom";
|
||||
|
||||
import { logger } from "../../../services/monitoring";
|
||||
import { LocalDateTimeString } from "../../../utils/dates";
|
||||
import { Permissions } from "../../../utils/roles";
|
||||
import {
|
||||
CarUpdatesProvider,
|
||||
useCarUpdatesContext
|
||||
@@ -34,6 +35,10 @@ const tableColumns = [
|
||||
id: "update_package_id",
|
||||
label: "Name",
|
||||
},
|
||||
{
|
||||
id: "username",
|
||||
label: "Username",
|
||||
},
|
||||
{
|
||||
id: "status",
|
||||
label: "Status",
|
||||
@@ -167,6 +172,9 @@ const MainForm = ({ vin, token }) => {
|
||||
{updateName(row)}
|
||||
</Link>
|
||||
</TableCell>
|
||||
<TableCell align="center">
|
||||
{row.username}
|
||||
</TableCell>
|
||||
<TableCell align="center">
|
||||
{row.status}
|
||||
{row.progress > -1 && (
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import React from "react";
|
||||
|
||||
import { LocalDateTimeString } from "../../utils/dates";
|
||||
import { ValidateLocationByParam } from "../../utils/locations"
|
||||
import useStyles from "../useStyles";
|
||||
|
||||
const keyValueTemplate = (key, value) => (
|
||||
@@ -83,6 +84,9 @@ const DigitalTwin = (props) => {
|
||||
<div className={classes.popupSection}>
|
||||
<h3>Location</h3>
|
||||
{Object.entries(location).map((value) => {
|
||||
if (ValidateLocationByParam(value[0], value[1]) === false) {
|
||||
return keyValueTemplate(value[0], "Invalid")
|
||||
}
|
||||
if (value[0] === "altitude") {
|
||||
return keyValueTemplate(value[0], value[1]);
|
||||
} else {
|
||||
|
||||
@@ -26,7 +26,9 @@ export default class ErrorBoundary extends Component {
|
||||
if (this.state.hasError) {
|
||||
try {
|
||||
logger.error(this.state.error.stack);
|
||||
} catch (e) {}
|
||||
} catch (e) {
|
||||
logger.error(e);
|
||||
}
|
||||
|
||||
if (this.state.error && this.state.error.name === "ChunkLoadError") {
|
||||
reload();
|
||||
|
||||
@@ -44,6 +44,9 @@ const MainForm = ({ id }) => {
|
||||
<p>
|
||||
<b>ID</b>: {id}
|
||||
</p>
|
||||
<p>
|
||||
<b>Driver ID</b>: {issue.driver_id}
|
||||
</p>
|
||||
<p>
|
||||
<b>VIN</b>: {issue.vin}
|
||||
</p>
|
||||
|
||||
@@ -44,7 +44,7 @@ const Component = () => {
|
||||
const retrieveAndStoreLocations = (accessToken) => {
|
||||
return getLocations(accessToken)
|
||||
.then((result) => {
|
||||
if (result.data != null) {
|
||||
if (result.data != null && ValidateLocationData(result.data) !== false) {
|
||||
const points = result.data.map((point) => [
|
||||
point.latitude,
|
||||
point.longitude,
|
||||
|
||||
22
src/utils/locations.js
Normal file
22
src/utils/locations.js
Normal file
@@ -0,0 +1,22 @@
|
||||
export const ValidateLocationData = (location) => {
|
||||
if (Math.abs(location.latitude) > 90 || Math.abs(location.longitude) > 180) {
|
||||
return false;
|
||||
}
|
||||
if (location.altitude === 1401) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
export const ValidateLocationByParam = (parameter, value) => {
|
||||
switch (parameter) {
|
||||
case "latitude":
|
||||
return Math.abs(value) <= 90;
|
||||
case "longitude":
|
||||
return Math.abs(value) <= 180;
|
||||
case "altitude":
|
||||
return value !== 1401;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user