Merge branch 'development' into main
This commit is contained in:
@@ -299,17 +299,17 @@ exports[`App Route /carupdate-deploy authenticated 1`] = `
|
|||||||
data-testid="mocked-userprovider"
|
data-testid="mocked-userprovider"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="makeStyles-root-551"
|
class="makeStyles-root-559"
|
||||||
>
|
>
|
||||||
<header
|
<header
|
||||||
class="MuiPaper-root MuiAppBar-root MuiAppBar-positionFixed MuiAppBar-colorPrimary makeStyles-appBar-552 makeStyles-appBarShift-553 mui-00000fixed MuiPaper-elevation4"
|
class="MuiPaper-root MuiAppBar-root MuiAppBar-positionFixed MuiAppBar-colorPrimary makeStyles-appBar-560 makeStyles-appBarShift-561 mui-00000fixed MuiPaper-elevation4"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="MuiToolbar-root MuiToolbar-regular MuiToolbar-gutters"
|
class="MuiToolbar-root MuiToolbar-regular MuiToolbar-gutters"
|
||||||
>
|
>
|
||||||
<button
|
<button
|
||||||
aria-label="open drawer"
|
aria-label="open drawer"
|
||||||
class="MuiButtonBase-root MuiIconButton-root makeStyles-menuButton-554 MuiIconButton-colorInherit MuiIconButton-edgeStart"
|
class="MuiButtonBase-root MuiIconButton-root makeStyles-menuButton-562 MuiIconButton-colorInherit MuiIconButton-edgeStart"
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
type="button"
|
type="button"
|
||||||
>
|
>
|
||||||
@@ -337,7 +337,7 @@ exports[`App Route /carupdate-deploy authenticated 1`] = `
|
|||||||
Fisker OTA Portal
|
Fisker OTA Portal
|
||||||
</h6>
|
</h6>
|
||||||
<button
|
<button
|
||||||
class="MuiButtonBase-root MuiButton-root MuiButton-text makeStyles-rightToolbar-561 MuiButton-colorInherit"
|
class="MuiButtonBase-root MuiButton-root MuiButton-text makeStyles-rightToolbar-569 MuiButton-colorInherit"
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
type="button"
|
type="button"
|
||||||
>
|
>
|
||||||
@@ -353,13 +353,13 @@ exports[`App Route /carupdate-deploy authenticated 1`] = `
|
|||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
<div
|
<div
|
||||||
class="MuiDrawer-root MuiDrawer-docked makeStyles-drawer-556"
|
class="MuiDrawer-root MuiDrawer-docked makeStyles-drawer-564"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="MuiPaper-root MuiDrawer-paper makeStyles-drawerPaper-557 MuiDrawer-paperAnchorLeft MuiDrawer-paperAnchorDockedLeft MuiPaper-elevation0"
|
class="MuiPaper-root MuiDrawer-paper makeStyles-drawerPaper-565 MuiDrawer-paperAnchorLeft MuiDrawer-paperAnchorDockedLeft MuiPaper-elevation0"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="makeStyles-drawerHeader-558"
|
class="makeStyles-drawerHeader-566"
|
||||||
>
|
>
|
||||||
<button
|
<button
|
||||||
class="MuiButtonBase-root MuiIconButton-root"
|
class="MuiButtonBase-root MuiIconButton-root"
|
||||||
@@ -505,10 +505,10 @@ exports[`App Route /carupdate-deploy authenticated 1`] = `
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<main
|
<main
|
||||||
class="makeStyles-content-559 makeStyles-contentShift-560"
|
class="makeStyles-content-567 makeStyles-contentShift-568"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="makeStyles-drawerHeader-558"
|
class="makeStyles-drawerHeader-566"
|
||||||
/>
|
/>
|
||||||
<main
|
<main
|
||||||
class="MuiContainer-root MuiContainer-maxWidthLg"
|
class="MuiContainer-root MuiContainer-maxWidthLg"
|
||||||
@@ -517,7 +517,7 @@ exports[`App Route /carupdate-deploy authenticated 1`] = `
|
|||||||
data-testid="mocked-updatesprovider"
|
data-testid="mocked-updatesprovider"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="makeStyles-paper-540"
|
class="makeStyles-paper-548"
|
||||||
>
|
>
|
||||||
<h1
|
<h1
|
||||||
class="MuiTypography-root MuiTypography-h5"
|
class="MuiTypography-root MuiTypography-h5"
|
||||||
@@ -527,7 +527,7 @@ exports[`App Route /carupdate-deploy authenticated 1`] = `
|
|||||||
</h1>
|
</h1>
|
||||||
<form
|
<form
|
||||||
action="{onSubmit}"
|
action="{onSubmit}"
|
||||||
class="makeStyles-form-542"
|
class="makeStyles-form-550"
|
||||||
novalidate=""
|
novalidate=""
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
@@ -631,10 +631,10 @@ exports[`App Route /carupdate-deploy authenticated 1`] = `
|
|||||||
data-testid="mocked-vehicleprovider"
|
data-testid="mocked-vehicleprovider"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="makeStyles-form-542"
|
class="makeStyles-form-550"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="MuiFormControl-root makeStyles-formControlInline-545"
|
class="MuiFormControl-root makeStyles-formControlInline-553"
|
||||||
>
|
>
|
||||||
<label
|
<label
|
||||||
class="MuiFormLabel-root MuiInputLabel-root MuiInputLabel-formControl MuiInputLabel-animated MuiInputLabel-shrink MuiInputLabel-outlined MuiFormLabel-filled"
|
class="MuiFormLabel-root MuiInputLabel-root MuiInputLabel-formControl MuiInputLabel-animated MuiInputLabel-shrink MuiInputLabel-outlined MuiFormLabel-filled"
|
||||||
@@ -676,11 +676,11 @@ exports[`App Route /carupdate-deploy authenticated 1`] = `
|
|||||||
</svg>
|
</svg>
|
||||||
<fieldset
|
<fieldset
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
class="PrivateNotchedOutline-root-563 MuiOutlinedInput-notchedOutline"
|
class="PrivateNotchedOutline-root-571 MuiOutlinedInput-notchedOutline"
|
||||||
style="padding-left: 8px;"
|
style="padding-left: 8px;"
|
||||||
>
|
>
|
||||||
<legend
|
<legend
|
||||||
class="PrivateNotchedOutline-legend-564"
|
class="PrivateNotchedOutline-legend-572"
|
||||||
style="width: 0.01px;"
|
style="width: 0.01px;"
|
||||||
>
|
>
|
||||||
<span>
|
<span>
|
||||||
@@ -691,7 +691,7 @@ exports[`App Route /carupdate-deploy authenticated 1`] = `
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="MuiFormControl-root makeStyles-formControlInline-545"
|
class="MuiFormControl-root makeStyles-formControlInline-553"
|
||||||
>
|
>
|
||||||
<label
|
<label
|
||||||
class="MuiFormLabel-root MuiInputLabel-root MuiInputLabel-formControl MuiInputLabel-animated MuiInputLabel-shrink MuiInputLabel-outlined MuiFormLabel-filled"
|
class="MuiFormLabel-root MuiInputLabel-root MuiInputLabel-formControl MuiInputLabel-animated MuiInputLabel-shrink MuiInputLabel-outlined MuiFormLabel-filled"
|
||||||
@@ -733,11 +733,11 @@ exports[`App Route /carupdate-deploy authenticated 1`] = `
|
|||||||
</svg>
|
</svg>
|
||||||
<fieldset
|
<fieldset
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
class="PrivateNotchedOutline-root-563 MuiOutlinedInput-notchedOutline"
|
class="PrivateNotchedOutline-root-571 MuiOutlinedInput-notchedOutline"
|
||||||
style="padding-left: 8px;"
|
style="padding-left: 8px;"
|
||||||
>
|
>
|
||||||
<legend
|
<legend
|
||||||
class="PrivateNotchedOutline-legend-564"
|
class="PrivateNotchedOutline-legend-572"
|
||||||
style="width: 0.01px;"
|
style="width: 0.01px;"
|
||||||
>
|
>
|
||||||
<span>
|
<span>
|
||||||
@@ -748,14 +748,14 @@ exports[`App Route /carupdate-deploy authenticated 1`] = `
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="makeStyles-labelInline-546"
|
class="makeStyles-labelInline-554"
|
||||||
>
|
>
|
||||||
No Cars Selected
|
No Cars Selected
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<button
|
<button
|
||||||
class="MuiButtonBase-root MuiButton-root MuiButton-contained makeStyles-submit-543 MuiButton-containedPrimary MuiButton-fullWidth"
|
class="MuiButtonBase-root MuiButton-root MuiButton-contained makeStyles-submit-551 MuiButton-containedPrimary MuiButton-fullWidth"
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
type="submit"
|
type="submit"
|
||||||
>
|
>
|
||||||
@@ -2132,17 +2132,17 @@ exports[`App Route /page-not-found authenticated 1`] = `
|
|||||||
data-testid="mocked-userprovider"
|
data-testid="mocked-userprovider"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="makeStyles-root-526"
|
class="makeStyles-root-534"
|
||||||
>
|
>
|
||||||
<header
|
<header
|
||||||
class="MuiPaper-root MuiAppBar-root MuiAppBar-positionFixed MuiAppBar-colorPrimary makeStyles-appBar-527 makeStyles-appBarShift-528 mui-00000fixed MuiPaper-elevation4"
|
class="MuiPaper-root MuiAppBar-root MuiAppBar-positionFixed MuiAppBar-colorPrimary makeStyles-appBar-535 makeStyles-appBarShift-536 mui-00000fixed MuiPaper-elevation4"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="MuiToolbar-root MuiToolbar-regular MuiToolbar-gutters"
|
class="MuiToolbar-root MuiToolbar-regular MuiToolbar-gutters"
|
||||||
>
|
>
|
||||||
<button
|
<button
|
||||||
aria-label="open drawer"
|
aria-label="open drawer"
|
||||||
class="MuiButtonBase-root MuiIconButton-root makeStyles-menuButton-529 MuiIconButton-colorInherit MuiIconButton-edgeStart"
|
class="MuiButtonBase-root MuiIconButton-root makeStyles-menuButton-537 MuiIconButton-colorInherit MuiIconButton-edgeStart"
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
type="button"
|
type="button"
|
||||||
>
|
>
|
||||||
@@ -2170,7 +2170,7 @@ exports[`App Route /page-not-found authenticated 1`] = `
|
|||||||
Fisker OTA Portal
|
Fisker OTA Portal
|
||||||
</h6>
|
</h6>
|
||||||
<button
|
<button
|
||||||
class="MuiButtonBase-root MuiButton-root MuiButton-text makeStyles-rightToolbar-536 MuiButton-colorInherit"
|
class="MuiButtonBase-root MuiButton-root MuiButton-text makeStyles-rightToolbar-544 MuiButton-colorInherit"
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
type="button"
|
type="button"
|
||||||
>
|
>
|
||||||
@@ -2186,13 +2186,13 @@ exports[`App Route /page-not-found authenticated 1`] = `
|
|||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
<div
|
<div
|
||||||
class="MuiDrawer-root MuiDrawer-docked makeStyles-drawer-531"
|
class="MuiDrawer-root MuiDrawer-docked makeStyles-drawer-539"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="MuiPaper-root MuiDrawer-paper makeStyles-drawerPaper-532 MuiDrawer-paperAnchorLeft MuiDrawer-paperAnchorDockedLeft MuiPaper-elevation0"
|
class="MuiPaper-root MuiDrawer-paper makeStyles-drawerPaper-540 MuiDrawer-paperAnchorLeft MuiDrawer-paperAnchorDockedLeft MuiPaper-elevation0"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="makeStyles-drawerHeader-533"
|
class="makeStyles-drawerHeader-541"
|
||||||
>
|
>
|
||||||
<button
|
<button
|
||||||
class="MuiButtonBase-root MuiIconButton-root"
|
class="MuiButtonBase-root MuiIconButton-root"
|
||||||
@@ -2338,16 +2338,16 @@ exports[`App Route /page-not-found authenticated 1`] = `
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<main
|
<main
|
||||||
class="makeStyles-content-534 makeStyles-contentShift-535"
|
class="makeStyles-content-542 makeStyles-contentShift-543"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="makeStyles-drawerHeader-533"
|
class="makeStyles-drawerHeader-541"
|
||||||
/>
|
/>
|
||||||
<main
|
<main
|
||||||
class="MuiContainer-root MuiContainer-maxWidthLg"
|
class="MuiContainer-root MuiContainer-maxWidthLg"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="makeStyles-paper-515"
|
class="makeStyles-paper-523"
|
||||||
>
|
>
|
||||||
<h1
|
<h1
|
||||||
class="MuiTypography-root MuiTypography-h2"
|
class="MuiTypography-root MuiTypography-h2"
|
||||||
@@ -2368,10 +2368,10 @@ exports[`App Route /page-not-found unauthenticated 1`] = `
|
|||||||
data-testid="mocked-userprovider"
|
data-testid="mocked-userprovider"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="makeStyles-root-501"
|
class="makeStyles-root-509"
|
||||||
>
|
>
|
||||||
<header
|
<header
|
||||||
class="MuiPaper-root MuiAppBar-root MuiAppBar-positionFixed MuiAppBar-colorPrimary makeStyles-appBar-502 mui-00000fixed MuiPaper-elevation4"
|
class="MuiPaper-root MuiAppBar-root MuiAppBar-positionFixed MuiAppBar-colorPrimary makeStyles-appBar-510 mui-00000fixed MuiPaper-elevation4"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="MuiToolbar-root MuiToolbar-regular MuiToolbar-gutters"
|
class="MuiToolbar-root MuiToolbar-regular MuiToolbar-gutters"
|
||||||
@@ -2384,16 +2384,16 @@ exports[`App Route /page-not-found unauthenticated 1`] = `
|
|||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
<main
|
<main
|
||||||
class="makeStyles-content-509"
|
class="makeStyles-content-517"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="makeStyles-drawerHeader-508"
|
class="makeStyles-drawerHeader-516"
|
||||||
/>
|
/>
|
||||||
<main
|
<main
|
||||||
class="MuiContainer-root MuiContainer-maxWidthLg"
|
class="MuiContainer-root MuiContainer-maxWidthLg"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="makeStyles-paper-490"
|
class="makeStyles-paper-498"
|
||||||
>
|
>
|
||||||
<h1
|
<h1
|
||||||
class="MuiTypography-root MuiTypography-h2"
|
class="MuiTypography-root MuiTypography-h2"
|
||||||
@@ -4102,6 +4102,9 @@ exports[`App Route /vehicle-status authenticated 1`] = `
|
|||||||
/>
|
/>
|
||||||
<main
|
<main
|
||||||
class="MuiContainer-root MuiContainer-maxWidthLg"
|
class="MuiContainer-root MuiContainer-maxWidthLg"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
data-testid="mocked-vehicleprovider"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
data-testid="mocked-updatesprovider"
|
data-testid="mocked-updatesprovider"
|
||||||
@@ -4284,6 +4287,304 @@ exports[`App Route /vehicle-status authenticated 1`] = `
|
|||||||
</tfoot>
|
</tfoot>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
<div
|
||||||
|
class="MuiGrid-root makeStyles-root-476 MuiGrid-container MuiGrid-spacing-xs-2"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="MuiGrid-root MuiGrid-item MuiGrid-grid-md-12 MuiGrid-grid-lg-6"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="makeStyles-form-467"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="MuiFormControl-root makeStyles-formControlInline-470"
|
||||||
|
>
|
||||||
|
<label
|
||||||
|
class="MuiFormLabel-root MuiInputLabel-root MuiInputLabel-formControl MuiInputLabel-animated MuiInputLabel-shrink MuiInputLabel-outlined MuiFormLabel-filled"
|
||||||
|
data-shrink="true"
|
||||||
|
for="send-command"
|
||||||
|
style="background-color: White;"
|
||||||
|
>
|
||||||
|
Command
|
||||||
|
</label>
|
||||||
|
<div
|
||||||
|
class="MuiInputBase-root MuiOutlinedInput-root MuiInputBase-formControl"
|
||||||
|
>
|
||||||
|
<select
|
||||||
|
aria-invalid="false"
|
||||||
|
class="MuiSelect-root MuiSelect-select MuiSelect-outlined MuiInputBase-input MuiOutlinedInput-input"
|
||||||
|
id="send-command"
|
||||||
|
name="send-command"
|
||||||
|
>
|
||||||
|
<option
|
||||||
|
value="LFRD"
|
||||||
|
>
|
||||||
|
Lock front right door
|
||||||
|
</option>
|
||||||
|
<option
|
||||||
|
value="UFRD"
|
||||||
|
>
|
||||||
|
Unlock front right door
|
||||||
|
</option>
|
||||||
|
<option
|
||||||
|
value="LFLD"
|
||||||
|
>
|
||||||
|
Lock front left door
|
||||||
|
</option>
|
||||||
|
<option
|
||||||
|
value="UFLD"
|
||||||
|
>
|
||||||
|
Unlock front left door
|
||||||
|
</option>
|
||||||
|
<option
|
||||||
|
value="LRRD"
|
||||||
|
>
|
||||||
|
Lock rear right door
|
||||||
|
</option>
|
||||||
|
<option
|
||||||
|
value="URRD"
|
||||||
|
>
|
||||||
|
Unlock rear right door
|
||||||
|
</option>
|
||||||
|
<option
|
||||||
|
value="LRLD"
|
||||||
|
>
|
||||||
|
Lock rear left door
|
||||||
|
</option>
|
||||||
|
<option
|
||||||
|
value="URLD"
|
||||||
|
>
|
||||||
|
Unlock rear left door
|
||||||
|
</option>
|
||||||
|
<option
|
||||||
|
value="LTRK"
|
||||||
|
>
|
||||||
|
Lock trunk
|
||||||
|
</option>
|
||||||
|
<option
|
||||||
|
value="UTRK"
|
||||||
|
>
|
||||||
|
Unlock trunk
|
||||||
|
</option>
|
||||||
|
<option
|
||||||
|
value="OWIN"
|
||||||
|
>
|
||||||
|
Open Windows
|
||||||
|
</option>
|
||||||
|
<option
|
||||||
|
value="CWIN"
|
||||||
|
>
|
||||||
|
Close Windows
|
||||||
|
</option>
|
||||||
|
<option
|
||||||
|
value="FLASH"
|
||||||
|
>
|
||||||
|
Flash headlights
|
||||||
|
</option>
|
||||||
|
</select>
|
||||||
|
<svg
|
||||||
|
aria-hidden="true"
|
||||||
|
class="MuiSvgIcon-root MuiSelect-icon MuiSelect-iconOutlined"
|
||||||
|
focusable="false"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M7 10l5 5 5-5z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
<fieldset
|
||||||
|
aria-hidden="true"
|
||||||
|
class="PrivateNotchedOutline-root-488 MuiOutlinedInput-notchedOutline"
|
||||||
|
style="padding-left: 8px;"
|
||||||
|
>
|
||||||
|
<legend
|
||||||
|
class="PrivateNotchedOutline-legend-489"
|
||||||
|
style="width: 0.01px;"
|
||||||
|
>
|
||||||
|
<span>
|
||||||
|
|
||||||
|
</span>
|
||||||
|
</legend>
|
||||||
|
</fieldset>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<span
|
||||||
|
aria-disabled="false"
|
||||||
|
aria-label="send command"
|
||||||
|
class="MuiButtonBase-root MuiIconButton-root MuiIconButton-colorPrimary"
|
||||||
|
role="button"
|
||||||
|
tabindex="0"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="MuiIconButton-label"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
aria-hidden="true"
|
||||||
|
class="MuiSvgIcon-root MuiSvgIcon-fontSizeLarge"
|
||||||
|
focusable="false"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M2.01 21L23 12 2.01 3 2 10l15 2-15 2z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</span>
|
||||||
|
<span
|
||||||
|
class="MuiTouchRipple-root"
|
||||||
|
/>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="MuiGrid-root MuiGrid-item MuiGrid-grid-md-12 MuiGrid-grid-lg-6"
|
||||||
|
style="text-align: right;"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="MuiGrid-root MuiGrid-container MuiGrid-spacing-xs-2 MuiGrid-align-items-xs-center"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="MuiGrid-root MuiGrid-item"
|
||||||
|
>
|
||||||
|
<label
|
||||||
|
class="MuiFormControlLabel-root MuiFormControlLabel-labelPlacementTop"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="MuiSwitch-root"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
aria-disabled="false"
|
||||||
|
class="MuiButtonBase-root MuiIconButton-root PrivateSwitchBase-root-492 MuiSwitch-switchBase MuiSwitch-colorPrimary PrivateSwitchBase-checked-493 Mui-checked"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="MuiIconButton-label"
|
||||||
|
>
|
||||||
|
<input
|
||||||
|
checked=""
|
||||||
|
class="PrivateSwitchBase-input-495 MuiSwitch-input"
|
||||||
|
name="logStart"
|
||||||
|
type="checkbox"
|
||||||
|
value=""
|
||||||
|
/>
|
||||||
|
<span
|
||||||
|
class="MuiSwitch-thumb"
|
||||||
|
/>
|
||||||
|
</span>
|
||||||
|
<span
|
||||||
|
class="MuiTouchRipple-root"
|
||||||
|
/>
|
||||||
|
</span>
|
||||||
|
<span
|
||||||
|
class="MuiSwitch-track"
|
||||||
|
/>
|
||||||
|
</span>
|
||||||
|
<span
|
||||||
|
class="MuiTypography-root MuiFormControlLabel-label MuiTypography-body1"
|
||||||
|
>
|
||||||
|
Logging
|
||||||
|
</span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="MuiGrid-root MuiGrid-item"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="MuiFormControl-root MuiTextField-root MuiFormControl-marginNormal"
|
||||||
|
>
|
||||||
|
<label
|
||||||
|
class="MuiFormLabel-root MuiInputLabel-root MuiInputLabel-formControl MuiInputLabel-animated MuiInputLabel-outlined"
|
||||||
|
data-shrink="false"
|
||||||
|
for="log-filter"
|
||||||
|
id="log-filter-label"
|
||||||
|
>
|
||||||
|
Filter
|
||||||
|
</label>
|
||||||
|
<div
|
||||||
|
class="MuiInputBase-root MuiOutlinedInput-root MuiInputBase-formControl"
|
||||||
|
>
|
||||||
|
<input
|
||||||
|
aria-invalid="false"
|
||||||
|
class="MuiInputBase-input MuiOutlinedInput-input"
|
||||||
|
id="log-filter"
|
||||||
|
maxlength="17"
|
||||||
|
name="log-filter"
|
||||||
|
type="text"
|
||||||
|
value=""
|
||||||
|
/>
|
||||||
|
<fieldset
|
||||||
|
aria-hidden="true"
|
||||||
|
class="PrivateNotchedOutline-root-488 MuiOutlinedInput-notchedOutline"
|
||||||
|
>
|
||||||
|
<legend
|
||||||
|
class="PrivateNotchedOutline-legendLabelled-490"
|
||||||
|
>
|
||||||
|
<span>
|
||||||
|
Filter
|
||||||
|
</span>
|
||||||
|
</legend>
|
||||||
|
</fieldset>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="MuiGrid-root MuiGrid-item"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="MuiFormControl-root MuiTextField-root"
|
||||||
|
>
|
||||||
|
<label
|
||||||
|
class="MuiFormLabel-root MuiInputLabel-root MuiInputLabel-formControl MuiInputLabel-animated MuiInputLabel-shrink MuiFormLabel-filled"
|
||||||
|
data-shrink="true"
|
||||||
|
for="log-frequency"
|
||||||
|
id="log-frequency-label"
|
||||||
|
>
|
||||||
|
Frequency
|
||||||
|
</label>
|
||||||
|
<div
|
||||||
|
class="MuiInputBase-root MuiInput-root MuiInput-underline MuiInputBase-formControl MuiInput-formControl"
|
||||||
|
>
|
||||||
|
<input
|
||||||
|
aria-invalid="false"
|
||||||
|
class="MuiInputBase-input MuiInput-input"
|
||||||
|
id="log-frequency"
|
||||||
|
type="number"
|
||||||
|
value="0"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="MuiGrid-root MuiGrid-item"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
aria-disabled="false"
|
||||||
|
aria-label="send log command"
|
||||||
|
class="MuiButtonBase-root MuiIconButton-root MuiIconButton-colorPrimary"
|
||||||
|
role="button"
|
||||||
|
tabindex="0"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="MuiIconButton-label"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
aria-hidden="true"
|
||||||
|
class="MuiSvgIcon-root MuiSvgIcon-fontSizeLarge"
|
||||||
|
focusable="false"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M2.01 21L23 12 2.01 3 2 10l15 2-15 2z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</span>
|
||||||
|
<span
|
||||||
|
class="MuiTouchRipple-root"
|
||||||
|
/>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</main>
|
</main>
|
||||||
|
|||||||
123
src/components/Cars/LogFilter/index.jsx
Normal file
123
src/components/Cars/LogFilter/index.jsx
Normal file
@@ -0,0 +1,123 @@
|
|||||||
|
import React, { useState } from "react";
|
||||||
|
import PropTypes from "prop-types";
|
||||||
|
import {
|
||||||
|
FormControlLabel,
|
||||||
|
Grid,
|
||||||
|
IconButton,
|
||||||
|
TextField,
|
||||||
|
Switch,
|
||||||
|
} from "@material-ui/core";
|
||||||
|
import SendIcon from "@material-ui/icons/Send";
|
||||||
|
|
||||||
|
import { useVehicleContext } from "../../Contexts/VehicleContext";
|
||||||
|
import { useUserContext } from "../../Contexts/UserContext";
|
||||||
|
import { useStatusContext } from "../../Contexts/StatusContext";
|
||||||
|
|
||||||
|
const LogFilter = ({ vin }) => {
|
||||||
|
const { sendLogFilter, busy } = useVehicleContext();
|
||||||
|
const {
|
||||||
|
token: {
|
||||||
|
idToken: { jwtToken: token },
|
||||||
|
},
|
||||||
|
} = useUserContext();
|
||||||
|
const { setMessage } = useStatusContext();
|
||||||
|
const [filter, setFilter] = useState("");
|
||||||
|
const [enableLog, setEnableLog] = useState(true);
|
||||||
|
const [freq, setFreq] = useState(0);
|
||||||
|
|
||||||
|
const changeFilterHandler = (e) => {
|
||||||
|
setFilter(e.target.value);
|
||||||
|
};
|
||||||
|
|
||||||
|
const changeStartHandler = (e) => {
|
||||||
|
setEnableLog(e.target.checked);
|
||||||
|
};
|
||||||
|
|
||||||
|
const changeFreqHandler = (e) => {
|
||||||
|
setFreq(e.target.value);
|
||||||
|
};
|
||||||
|
|
||||||
|
const clickHandler = async (e) => {
|
||||||
|
try {
|
||||||
|
const data = {
|
||||||
|
enable: enableLog,
|
||||||
|
frequency: freq,
|
||||||
|
filter,
|
||||||
|
};
|
||||||
|
await sendLogFilter(vin, data, token);
|
||||||
|
setMessage(`Sent log command to ${vin}`);
|
||||||
|
} catch (e) {
|
||||||
|
setMessage(e.message);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Grid
|
||||||
|
container
|
||||||
|
direction="row"
|
||||||
|
justify="flex-start"
|
||||||
|
alignItems="center"
|
||||||
|
spacing={2}
|
||||||
|
>
|
||||||
|
<Grid item>
|
||||||
|
<FormControlLabel
|
||||||
|
control={
|
||||||
|
<Switch
|
||||||
|
checked={enableLog}
|
||||||
|
onChange={changeStartHandler}
|
||||||
|
name="logStart"
|
||||||
|
color="primary"
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
labelPlacement="top"
|
||||||
|
label="Logging"
|
||||||
|
/>
|
||||||
|
</Grid>
|
||||||
|
<Grid item>
|
||||||
|
<TextField
|
||||||
|
id="log-filter"
|
||||||
|
name="log-filter"
|
||||||
|
label="Filter"
|
||||||
|
variant="outlined"
|
||||||
|
margin="normal"
|
||||||
|
inputProps={{
|
||||||
|
maxLength: "17",
|
||||||
|
}}
|
||||||
|
disabled={!enableLog}
|
||||||
|
value={filter}
|
||||||
|
onChange={changeFilterHandler}
|
||||||
|
/>
|
||||||
|
</Grid>
|
||||||
|
<Grid item>
|
||||||
|
<TextField
|
||||||
|
id="log-frequency"
|
||||||
|
label="Frequency"
|
||||||
|
type="number"
|
||||||
|
disabled={!enableLog}
|
||||||
|
InputLabelProps={{
|
||||||
|
shrink: true,
|
||||||
|
}}
|
||||||
|
value={freq}
|
||||||
|
onChange={changeFreqHandler}
|
||||||
|
/>
|
||||||
|
</Grid>
|
||||||
|
<Grid item>
|
||||||
|
<IconButton
|
||||||
|
color="primary"
|
||||||
|
aria-label="send log command"
|
||||||
|
component="span"
|
||||||
|
onClick={clickHandler}
|
||||||
|
disabled={busy}
|
||||||
|
>
|
||||||
|
<SendIcon fontSize="large" />
|
||||||
|
</IconButton>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
LogFilter.propTypes = {
|
||||||
|
vin: PropTypes.string.isRequired,
|
||||||
|
};
|
||||||
|
|
||||||
|
export default LogFilter;
|
||||||
81
src/components/Cars/SendCommand/index.jsx
Normal file
81
src/components/Cars/SendCommand/index.jsx
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
import React, { useEffect, useState } from "react";
|
||||||
|
import PropTypes from "prop-types";
|
||||||
|
import { FormControl, IconButton, InputLabel, Select } from "@material-ui/core";
|
||||||
|
import SendIcon from "@material-ui/icons/Send";
|
||||||
|
|
||||||
|
import { useVehicleContext } from "../../Contexts/VehicleContext";
|
||||||
|
import commands from "../../../services/commands";
|
||||||
|
import useStyles from "../../useStyles";
|
||||||
|
import { useUserContext } from "../../Contexts/UserContext";
|
||||||
|
import { useStatusContext } from "../../Contexts/StatusContext";
|
||||||
|
|
||||||
|
const SendCommand = ({ vin }) => {
|
||||||
|
const classes = useStyles();
|
||||||
|
const { sendCommand, busy } = useVehicleContext();
|
||||||
|
const {
|
||||||
|
token: {
|
||||||
|
idToken: { jwtToken: token },
|
||||||
|
},
|
||||||
|
} = useUserContext();
|
||||||
|
const { setMessage } = useStatusContext();
|
||||||
|
const [command, setCommand] = useState("");
|
||||||
|
|
||||||
|
const changeHandler = (e) => {
|
||||||
|
setCommand(e.target.value);
|
||||||
|
};
|
||||||
|
|
||||||
|
const clickHandler = async (e) => {
|
||||||
|
try {
|
||||||
|
await sendCommand(vin, command, token);
|
||||||
|
setMessage(`Sent command to ${vin}`);
|
||||||
|
} catch (e) {
|
||||||
|
setMessage(e.message);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!commands || commands.length === 0) return;
|
||||||
|
setCommand(commands[0].value);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={classes.form}>
|
||||||
|
<FormControl className={classes.formControlInline} variant="outlined">
|
||||||
|
<InputLabel htmlFor="send-command" style={{ backgroundColor: "White" }}>
|
||||||
|
Command
|
||||||
|
</InputLabel>
|
||||||
|
<Select
|
||||||
|
native
|
||||||
|
value={command}
|
||||||
|
variant="outlined"
|
||||||
|
inputProps={{
|
||||||
|
name: "send-command",
|
||||||
|
id: "send-command",
|
||||||
|
}}
|
||||||
|
onChange={changeHandler}
|
||||||
|
>
|
||||||
|
{commands.map((item) => (
|
||||||
|
<option key={item.value} value={item.value}>
|
||||||
|
{item.label}
|
||||||
|
</option>
|
||||||
|
))}
|
||||||
|
</Select>
|
||||||
|
</FormControl>
|
||||||
|
<IconButton
|
||||||
|
color="primary"
|
||||||
|
aria-label="send command"
|
||||||
|
component="span"
|
||||||
|
onClick={clickHandler}
|
||||||
|
disabled={busy}
|
||||||
|
>
|
||||||
|
<SendIcon fontSize="large" />
|
||||||
|
</IconButton>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
SendCommand.propTypes = {
|
||||||
|
vin: PropTypes.string.isRequired,
|
||||||
|
};
|
||||||
|
|
||||||
|
export default SendCommand;
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
import React, { useEffect, useState } from "react";
|
import React, { useEffect, useState } from "react";
|
||||||
import { useParams } from "react-router";
|
import { useParams } from "react-router";
|
||||||
import {
|
import {
|
||||||
|
Grid,
|
||||||
Table,
|
Table,
|
||||||
TableBody,
|
TableBody,
|
||||||
TableCell,
|
TableCell,
|
||||||
@@ -16,10 +17,14 @@ import {
|
|||||||
UpdatesProvider,
|
UpdatesProvider,
|
||||||
useUpdatesContext,
|
useUpdatesContext,
|
||||||
} from "../../Contexts/UpdatesContext";
|
} from "../../Contexts/UpdatesContext";
|
||||||
|
import { VehicleProvider } from "../../Contexts/VehicleContext";
|
||||||
|
|
||||||
import { useUserContext } from "../../Contexts/UserContext";
|
import { useUserContext } from "../../Contexts/UserContext";
|
||||||
import { useStatusContext } from "../../Contexts/StatusContext";
|
import { useStatusContext } from "../../Contexts/StatusContext";
|
||||||
import useStyles from "../../useStyles";
|
import useStyles from "../../useStyles";
|
||||||
import { LocalDateTimeString } from "../../../utils/dates";
|
import { LocalDateTimeString } from "../../../utils/dates";
|
||||||
|
import SendCommand from "../SendCommand";
|
||||||
|
import LogFilter from "../LogFilter";
|
||||||
|
|
||||||
const MainForm = () => {
|
const MainForm = () => {
|
||||||
const { vin } = useParams();
|
const { vin } = useParams();
|
||||||
@@ -109,14 +114,24 @@ const MainForm = () => {
|
|||||||
</TableFooter>
|
</TableFooter>
|
||||||
</Table>
|
</Table>
|
||||||
</TableContainer>
|
</TableContainer>
|
||||||
|
<Grid container className={classes.root} spacing={2}>
|
||||||
|
<Grid item lg={6} md={12}>
|
||||||
|
<SendCommand vin={vin} />
|
||||||
|
</Grid>
|
||||||
|
<Grid item lg={6} md={12} style={{ textAlign: "right" }}>
|
||||||
|
<LogFilter vin={vin} />
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const CarUpdates = () => (
|
const CarUpdates = () => (
|
||||||
|
<VehicleProvider>
|
||||||
<UpdatesProvider>
|
<UpdatesProvider>
|
||||||
<MainForm />
|
<MainForm />
|
||||||
</UpdatesProvider>
|
</UpdatesProvider>
|
||||||
|
</VehicleProvider>
|
||||||
);
|
);
|
||||||
|
|
||||||
export default CarUpdates;
|
export default CarUpdates;
|
||||||
|
|||||||
@@ -84,6 +84,30 @@ export const VehicleProvider = ({ children }) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const sendCommand = async (vin, command, token) => {
|
||||||
|
try {
|
||||||
|
setBusy(true);
|
||||||
|
const result = await api.sendCommand(vin, command, token);
|
||||||
|
if (result.error)
|
||||||
|
throw new Error(`Send command error. ${result.message}`);
|
||||||
|
return result;
|
||||||
|
} finally {
|
||||||
|
setBusy(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const sendLogFilter = async (vin, filter, token) => {
|
||||||
|
try {
|
||||||
|
setBusy(true);
|
||||||
|
const result = await api.sendLog(vin, filter, token);
|
||||||
|
if (result.error)
|
||||||
|
throw new Error(`Send log filter error. ${result.message}`);
|
||||||
|
return result;
|
||||||
|
} finally {
|
||||||
|
setBusy(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<VehicleContext.Provider
|
<VehicleContext.Provider
|
||||||
value={{
|
value={{
|
||||||
@@ -96,6 +120,8 @@ export const VehicleProvider = ({ children }) => {
|
|||||||
addVehicle,
|
addVehicle,
|
||||||
getModels,
|
getModels,
|
||||||
getYears,
|
getYears,
|
||||||
|
sendCommand,
|
||||||
|
sendLogFilter,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
|
|||||||
@@ -25,6 +25,14 @@ export const useVehicleContext = () => ({
|
|||||||
getYears: jest.fn(() => {
|
getYears: jest.fn(() => {
|
||||||
years = [2023, 2024];
|
years = [2023, 2024];
|
||||||
}),
|
}),
|
||||||
|
sendCommand: jest.fn((vin, command, token) => ({
|
||||||
|
vin,
|
||||||
|
command,
|
||||||
|
})),
|
||||||
|
sendLogFilter: jest.fn((vin, filter, token) => ({
|
||||||
|
vin,
|
||||||
|
filter,
|
||||||
|
})),
|
||||||
});
|
});
|
||||||
|
|
||||||
export const setBusy = (val) => {
|
export const setBusy = (val) => {
|
||||||
|
|||||||
@@ -25,6 +25,14 @@ const vehiclesAPI = {
|
|||||||
data: [2021, 2022],
|
data: [2021, 2022],
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
sendCommand: async (vin, command, token) => {
|
||||||
|
return {
|
||||||
|
vin, command,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
sendLog: async (vin, filter, token) => {
|
||||||
|
return Object.assign(filter, {vin});
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export default vehiclesAPI;
|
export default vehiclesAPI;
|
||||||
|
|||||||
42
src/services/commands.js
Normal file
42
src/services/commands.js
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
const Commands = [{
|
||||||
|
value: "LFRD",
|
||||||
|
label: "Lock front right door",
|
||||||
|
},{
|
||||||
|
value: "UFRD",
|
||||||
|
label: "Unlock front right door",
|
||||||
|
},{
|
||||||
|
value: "LFLD",
|
||||||
|
label: "Lock front left door",
|
||||||
|
},{
|
||||||
|
value: "UFLD",
|
||||||
|
label: "Unlock front left door",
|
||||||
|
},{
|
||||||
|
value: "LRRD",
|
||||||
|
label: "Lock rear right door",
|
||||||
|
},{
|
||||||
|
value: "URRD",
|
||||||
|
label: "Unlock rear right door",
|
||||||
|
},{
|
||||||
|
value: "LRLD",
|
||||||
|
label: "Lock rear left door",
|
||||||
|
},{
|
||||||
|
value: "URLD",
|
||||||
|
label: "Unlock rear left door",
|
||||||
|
},{
|
||||||
|
value: "LTRK",
|
||||||
|
label: "Lock trunk",
|
||||||
|
},{
|
||||||
|
value: "UTRK",
|
||||||
|
label: "Unlock trunk",
|
||||||
|
},{
|
||||||
|
value: "OWIN",
|
||||||
|
label: "Open Windows",
|
||||||
|
},{
|
||||||
|
value: "CWIN",
|
||||||
|
label: "Close Windows",
|
||||||
|
},{
|
||||||
|
value: "FLASH",
|
||||||
|
label: "Flash headlights",
|
||||||
|
}];
|
||||||
|
|
||||||
|
export default Commands;
|
||||||
@@ -30,6 +30,23 @@ const vehiclesAPI = {
|
|||||||
headers: Object.assign({ "Content-Type": "application/json" }, getAuthHeaderOptions(token)),
|
headers: Object.assign({ "Content-Type": "application/json" }, getAuthHeaderOptions(token)),
|
||||||
})
|
})
|
||||||
.then(fetchRespHandler),
|
.then(fetchRespHandler),
|
||||||
|
|
||||||
|
sendCommand: async (vin, command, token) => fetch(`${API_ENDPOINT}/vehiclecommand`, {
|
||||||
|
method: "POST",
|
||||||
|
headers: Object.assign({ "Content-Type": "application/json" }, getAuthHeaderOptions(token)),
|
||||||
|
body: JSON.stringify({
|
||||||
|
vin, command,
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
.then(fetchRespHandler),
|
||||||
|
|
||||||
|
sendLog: async (vin, filter, token) => fetch(`${API_ENDPOINT}/vehiclelog`, {
|
||||||
|
method: "POST",
|
||||||
|
headers: Object.assign({ "Content-Type": "application/json" }, getAuthHeaderOptions(token)),
|
||||||
|
body: JSON.stringify(Object.assign(filter, {vin})),
|
||||||
|
})
|
||||||
|
.then(fetchRespHandler),
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export default vehiclesAPI;
|
export default vehiclesAPI;
|
||||||
|
|||||||
Reference in New Issue
Block a user