CEC-5900 - Add the ability to edit Flashpack versions after they are added
This commit is contained in:
@@ -354,6 +354,26 @@ export const VehicleProvider = ({ children }) => {
|
||||
}
|
||||
}
|
||||
|
||||
const addFlashpackVersionECUMapping = async (model, trim, year, flashpack, ecuName, ecuVersion, token) => {
|
||||
try {
|
||||
setBusy(true);
|
||||
|
||||
const data = {
|
||||
"car_ecu_name": ecuName,
|
||||
"car_ecu_version": ecuVersion,
|
||||
}
|
||||
|
||||
const result = await api.addFlashpackVersionECUMapping(model, trim, year, flashpack, data, token)
|
||||
if (result.error) {
|
||||
throw new Error(`Add flashpack version ECU mapping error. ${result.message}`);
|
||||
}
|
||||
|
||||
return result;
|
||||
} finally {
|
||||
setBusy(false)
|
||||
}
|
||||
}
|
||||
|
||||
const deleteFlashpackVersion = async (model, trim, year, flashpack, token) => {
|
||||
try {
|
||||
setBusy(true);
|
||||
@@ -367,7 +387,22 @@ export const VehicleProvider = ({ children }) => {
|
||||
|
||||
const result = await api.deleteFlashpackVersion(data, token);
|
||||
if (result.error) {
|
||||
throw new Error(`Delete flashpack ecu mappings error. ${result.message}`);
|
||||
throw new Error(`Delete flashpack version error. ${result.message}`);
|
||||
}
|
||||
|
||||
return result;
|
||||
} finally {
|
||||
setBusy(false);
|
||||
}
|
||||
};
|
||||
|
||||
const deleteFlashpackVersionECUMapping = async (model, trim, year, flashpack, ecuName, ecuVersion, token) => {
|
||||
try {
|
||||
setBusy(true);
|
||||
|
||||
const result = await api.deleteFlashpackVersionECUMapping(model, trim, year, flashpack, ecuName, ecuVersion, token);
|
||||
if (result.error) {
|
||||
throw new Error(`Delete flashpack ecu mapping error. ${result.message}`);
|
||||
}
|
||||
|
||||
return result;
|
||||
@@ -427,7 +462,9 @@ export const VehicleProvider = ({ children }) => {
|
||||
flashpackECUMappings,
|
||||
getFlashpackECUMappings,
|
||||
addFlashpackVersion,
|
||||
addFlashpackVersionECUMapping,
|
||||
deleteFlashpackVersion,
|
||||
deleteFlashpackVersionECUMapping,
|
||||
getCarFlashpackVersionInfo,
|
||||
}}
|
||||
>
|
||||
|
||||
@@ -0,0 +1,612 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`FlashpackECUMappingAdd Render 1`] = `
|
||||
<div>
|
||||
<div
|
||||
data-testid="mocked-vehicleprovider"
|
||||
>
|
||||
<div
|
||||
data-testid="mocked-statusprovider"
|
||||
>
|
||||
<div
|
||||
data-testid="mocked-userprovider"
|
||||
>
|
||||
<div
|
||||
data-testid="mocked-vehicleprovider"
|
||||
>
|
||||
<div
|
||||
class="makeStyles-paper-0"
|
||||
>
|
||||
<form
|
||||
action="{onSubmit}"
|
||||
class="makeStyles-form-0"
|
||||
novalidate=""
|
||||
>
|
||||
<div>
|
||||
<div
|
||||
class="MuiFormControl-root MuiFormControl-marginNormal"
|
||||
>
|
||||
<label
|
||||
class="MuiFormLabel-root MuiInputLabel-root makeStyles-whiteBackground-0 MuiInputLabel-formControl MuiInputLabel-animated MuiInputLabel-outlined Mui-required Mui-required"
|
||||
data-shrink="false"
|
||||
>
|
||||
ECU Name
|
||||
<span
|
||||
aria-hidden="true"
|
||||
class="MuiFormLabel-asterisk MuiInputLabel-asterisk"
|
||||
>
|
||||
|
||||
*
|
||||
</span>
|
||||
</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="ecuName"
|
||||
name="ecuName"
|
||||
>
|
||||
<option />
|
||||
<option
|
||||
value="AGS"
|
||||
>
|
||||
AGS
|
||||
</option>
|
||||
<option
|
||||
value="ADB"
|
||||
>
|
||||
ADB
|
||||
</option>
|
||||
<option
|
||||
value="ADAS"
|
||||
>
|
||||
ADAS
|
||||
</option>
|
||||
<option
|
||||
value="ACU"
|
||||
>
|
||||
ACU
|
||||
</option>
|
||||
<option
|
||||
value="ACP"
|
||||
>
|
||||
ACP
|
||||
</option>
|
||||
<option
|
||||
value="AMP"
|
||||
>
|
||||
AMP
|
||||
</option>
|
||||
<option
|
||||
value="AP_FL"
|
||||
>
|
||||
AP_FL
|
||||
</option>
|
||||
<option
|
||||
value="AP_FR"
|
||||
>
|
||||
AP_FR
|
||||
</option>
|
||||
<option
|
||||
value="AP_RL"
|
||||
>
|
||||
AP_RL
|
||||
</option>
|
||||
<option
|
||||
value="AP_RR"
|
||||
>
|
||||
AP_RR
|
||||
</option>
|
||||
<option
|
||||
value="AL"
|
||||
>
|
||||
AL
|
||||
</option>
|
||||
<option
|
||||
value="BCS"
|
||||
>
|
||||
BCS
|
||||
</option>
|
||||
<option
|
||||
value="BMS"
|
||||
>
|
||||
BMS
|
||||
</option>
|
||||
<option
|
||||
value="BMU"
|
||||
>
|
||||
BMU
|
||||
</option>
|
||||
<option
|
||||
value="BCM"
|
||||
>
|
||||
BCM
|
||||
</option>
|
||||
<option
|
||||
value="CDS"
|
||||
>
|
||||
CDS
|
||||
</option>
|
||||
<option
|
||||
value="CCU"
|
||||
>
|
||||
CCU
|
||||
</option>
|
||||
<option
|
||||
value="CIM"
|
||||
>
|
||||
CIM
|
||||
</option>
|
||||
<option
|
||||
value="CVM"
|
||||
>
|
||||
CVM
|
||||
</option>
|
||||
<option
|
||||
value="CFM"
|
||||
>
|
||||
CFM
|
||||
</option>
|
||||
<option
|
||||
value="CMRR_FL"
|
||||
>
|
||||
CMRR_FL
|
||||
</option>
|
||||
<option
|
||||
value="CMRR_FR"
|
||||
>
|
||||
CMRR_FR
|
||||
</option>
|
||||
<option
|
||||
value="CMRR_RL"
|
||||
>
|
||||
CMRR_RL
|
||||
</option>
|
||||
<option
|
||||
value="CMRR_RR"
|
||||
>
|
||||
CMRR_RR
|
||||
</option>
|
||||
<option
|
||||
value="DVRC"
|
||||
>
|
||||
DVRC
|
||||
</option>
|
||||
<option
|
||||
value="DC-CHM"
|
||||
>
|
||||
DC-CHM
|
||||
</option>
|
||||
<option
|
||||
value="DMC"
|
||||
>
|
||||
DMC
|
||||
</option>
|
||||
<option
|
||||
value="DSMC"
|
||||
>
|
||||
DSMC
|
||||
</option>
|
||||
<option
|
||||
value="DWSG"
|
||||
>
|
||||
DWSG
|
||||
</option>
|
||||
<option
|
||||
value="EKS"
|
||||
>
|
||||
EKS
|
||||
</option>
|
||||
<option
|
||||
value="EPS"
|
||||
>
|
||||
EPS
|
||||
</option>
|
||||
<option
|
||||
value="EAS"
|
||||
>
|
||||
EAS
|
||||
</option>
|
||||
<option
|
||||
value="ECC"
|
||||
>
|
||||
ECC
|
||||
</option>
|
||||
<option
|
||||
value="EWP_B"
|
||||
>
|
||||
EWP_B
|
||||
</option>
|
||||
<option
|
||||
value="EWP_FD"
|
||||
>
|
||||
EWP_FD
|
||||
</option>
|
||||
<option
|
||||
value="EWP_H"
|
||||
>
|
||||
EWP_H
|
||||
</option>
|
||||
<option
|
||||
value="EWP_RD"
|
||||
>
|
||||
EWP_RD
|
||||
</option>
|
||||
<option
|
||||
value="EWM"
|
||||
>
|
||||
EWM
|
||||
</option>
|
||||
<option
|
||||
value="EXV_B"
|
||||
>
|
||||
EXV_B
|
||||
</option>
|
||||
<option
|
||||
value="EXV_HP"
|
||||
>
|
||||
EXV_HP
|
||||
</option>
|
||||
<option
|
||||
value="ESP"
|
||||
>
|
||||
ESP
|
||||
</option>
|
||||
<option
|
||||
value="FDHA_FL"
|
||||
>
|
||||
FDHA_FL
|
||||
</option>
|
||||
<option
|
||||
value="FDHA_FR"
|
||||
>
|
||||
FDHA_FR
|
||||
</option>
|
||||
<option
|
||||
value="FDHA_RL"
|
||||
>
|
||||
FDHA_RL
|
||||
</option>
|
||||
<option
|
||||
value="FDHA_RR"
|
||||
>
|
||||
FDHA_RR
|
||||
</option>
|
||||
<option
|
||||
value="Lumber"
|
||||
>
|
||||
Lumber
|
||||
</option>
|
||||
<option
|
||||
value="FBM_L"
|
||||
>
|
||||
FBM_L
|
||||
</option>
|
||||
<option
|
||||
value="FBM_R"
|
||||
>
|
||||
FBM_R
|
||||
</option>
|
||||
<option
|
||||
value="FVC"
|
||||
>
|
||||
FVC
|
||||
</option>
|
||||
<option
|
||||
value="GW"
|
||||
>
|
||||
GW
|
||||
</option>
|
||||
<option
|
||||
value="HUD"
|
||||
>
|
||||
HUD
|
||||
</option>
|
||||
<option
|
||||
value="IDS"
|
||||
>
|
||||
IDS
|
||||
</option>
|
||||
<option
|
||||
value="ICC"
|
||||
>
|
||||
ICC
|
||||
</option>
|
||||
<option
|
||||
value="IBS"
|
||||
>
|
||||
IBS
|
||||
</option>
|
||||
<option
|
||||
value="iBooster"
|
||||
>
|
||||
iBooster
|
||||
</option>
|
||||
<option
|
||||
value="KS"
|
||||
>
|
||||
KS
|
||||
</option>
|
||||
<option
|
||||
value="LSC"
|
||||
>
|
||||
LSC
|
||||
</option>
|
||||
<option
|
||||
value="MRR"
|
||||
>
|
||||
MRR
|
||||
</option>
|
||||
<option
|
||||
value="MCU_F"
|
||||
>
|
||||
MCU_F
|
||||
</option>
|
||||
<option
|
||||
value="MCU_R"
|
||||
>
|
||||
MCU_R
|
||||
</option>
|
||||
<option
|
||||
value="MDV"
|
||||
>
|
||||
MDV
|
||||
</option>
|
||||
<option
|
||||
value="MFS"
|
||||
>
|
||||
MFS
|
||||
</option>
|
||||
<option
|
||||
value="MIS"
|
||||
>
|
||||
MIS
|
||||
</option>
|
||||
<option
|
||||
value="MPC"
|
||||
>
|
||||
MPC
|
||||
</option>
|
||||
<option
|
||||
value="OMC"
|
||||
>
|
||||
OMC
|
||||
</option>
|
||||
<option
|
||||
value="OHC"
|
||||
>
|
||||
OHC
|
||||
</option>
|
||||
<option
|
||||
value="PAS"
|
||||
>
|
||||
PAS
|
||||
</option>
|
||||
<option
|
||||
value="PCU"
|
||||
>
|
||||
PCU
|
||||
</option>
|
||||
<option
|
||||
value="PMS"
|
||||
>
|
||||
PMS
|
||||
</option>
|
||||
<option
|
||||
value="PSM"
|
||||
>
|
||||
PSM
|
||||
</option>
|
||||
<option
|
||||
value="PEPS"
|
||||
>
|
||||
PEPS
|
||||
</option>
|
||||
<option
|
||||
value="PKC"
|
||||
>
|
||||
PKC
|
||||
</option>
|
||||
<option
|
||||
value="PKC_ANT_L"
|
||||
>
|
||||
PKC_ANT_L
|
||||
</option>
|
||||
<option
|
||||
value="PKC_ANT_R"
|
||||
>
|
||||
PKC_ANT_R
|
||||
</option>
|
||||
<option
|
||||
value="PWC"
|
||||
>
|
||||
PWC
|
||||
</option>
|
||||
<option
|
||||
value="PASC"
|
||||
>
|
||||
PASC
|
||||
</option>
|
||||
<option
|
||||
value="PDU"
|
||||
>
|
||||
PDU
|
||||
</option>
|
||||
<option
|
||||
value="PLGM"
|
||||
>
|
||||
PLGM
|
||||
</option>
|
||||
<option
|
||||
value="PVIU"
|
||||
>
|
||||
PVIU
|
||||
</option>
|
||||
<option
|
||||
value="RLS"
|
||||
>
|
||||
RLS
|
||||
</option>
|
||||
<option
|
||||
value="RAC"
|
||||
>
|
||||
RAC
|
||||
</option>
|
||||
<option
|
||||
value="RVC"
|
||||
>
|
||||
RVC
|
||||
</option>
|
||||
<option
|
||||
value="RSC"
|
||||
>
|
||||
RSC
|
||||
</option>
|
||||
<option
|
||||
value="RCM"
|
||||
>
|
||||
RCM
|
||||
</option>
|
||||
<option
|
||||
value="RSM"
|
||||
>
|
||||
RSM
|
||||
</option>
|
||||
<option
|
||||
value="TBOX"
|
||||
>
|
||||
TBOX
|
||||
</option>
|
||||
<option
|
||||
value="TPMS"
|
||||
>
|
||||
TPMS
|
||||
</option>
|
||||
<option
|
||||
value="TDS"
|
||||
>
|
||||
TDS
|
||||
</option>
|
||||
<option
|
||||
value="USB Box"
|
||||
>
|
||||
USB Box
|
||||
</option>
|
||||
<option
|
||||
value="VCU"
|
||||
>
|
||||
VCU
|
||||
</option>
|
||||
<option
|
||||
value="VSP"
|
||||
>
|
||||
VSP
|
||||
</option>
|
||||
<option
|
||||
value="WTC_B"
|
||||
>
|
||||
WTC_B
|
||||
</option>
|
||||
<option
|
||||
value="WTC_H"
|
||||
>
|
||||
WTC_H
|
||||
</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-0 MuiOutlinedInput-notchedOutline"
|
||||
style="padding-left: 8px;"
|
||||
>
|
||||
<legend
|
||||
class="PrivateNotchedOutline-legend-0"
|
||||
style="width: 0.01px;"
|
||||
>
|
||||
<span>
|
||||
|
||||
</span>
|
||||
</legend>
|
||||
</fieldset>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="MuiFormControl-root MuiTextField-root MuiFormControl-marginNormal"
|
||||
>
|
||||
<label
|
||||
class="MuiFormLabel-root MuiInputLabel-root MuiInputLabel-formControl MuiInputLabel-animated MuiInputLabel-outlined Mui-required Mui-required"
|
||||
data-shrink="false"
|
||||
for="ecuVersion"
|
||||
id="ecuVersion-label"
|
||||
>
|
||||
ECU Version
|
||||
<span
|
||||
aria-hidden="true"
|
||||
class="MuiFormLabel-asterisk MuiInputLabel-asterisk"
|
||||
>
|
||||
|
||||
*
|
||||
</span>
|
||||
</label>
|
||||
<div
|
||||
class="MuiInputBase-root MuiOutlinedInput-root MuiInputBase-formControl"
|
||||
>
|
||||
<input
|
||||
aria-invalid="false"
|
||||
class="MuiInputBase-input MuiOutlinedInput-input"
|
||||
id="ecuVersion"
|
||||
maxlength="255"
|
||||
name="ecuVersion"
|
||||
required=""
|
||||
type="text"
|
||||
value=""
|
||||
/>
|
||||
<fieldset
|
||||
aria-hidden="true"
|
||||
class="PrivateNotchedOutline-root-0 MuiOutlinedInput-notchedOutline"
|
||||
>
|
||||
<legend
|
||||
class="PrivateNotchedOutline-legendLabelled-0"
|
||||
>
|
||||
<span>
|
||||
ECU Version
|
||||
*
|
||||
</span>
|
||||
</legend>
|
||||
</fieldset>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
class="MuiButtonBase-root MuiButton-root MuiButton-contained makeStyles-submit-0 MuiButton-containedPrimary MuiButton-fullWidth"
|
||||
tabindex="0"
|
||||
type="submit"
|
||||
>
|
||||
<span
|
||||
class="MuiButton-label"
|
||||
>
|
||||
Submit
|
||||
</span>
|
||||
<span
|
||||
class="MuiTouchRipple-root"
|
||||
/>
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
134
src/components/Flashpack/AddMapping/index.jsx
Normal file
134
src/components/Flashpack/AddMapping/index.jsx
Normal file
@@ -0,0 +1,134 @@
|
||||
import {
|
||||
Button,
|
||||
TextField
|
||||
} from "@material-ui/core";
|
||||
import ECUDropDown from "../../Controls/ECUDropDown";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { useParams } from "react-router-dom";
|
||||
import { Redirect } from "react-router";
|
||||
import { logger } from "../../../services/monitoring";
|
||||
import { useStatusContext } from "../../Contexts/StatusContext";
|
||||
import { useVehicleContext, VehicleProvider } from "../../Contexts/VehicleContext";
|
||||
import { useUserContext } from "../../Contexts/UserContext";
|
||||
import useStyles from "../../useStyles";
|
||||
|
||||
const MainForm = () => {
|
||||
const { model, trim, year, flashpack } = useParams();
|
||||
const {
|
||||
token: {
|
||||
idToken: { jwtToken: token },
|
||||
},
|
||||
} = useUserContext();
|
||||
const classes = useStyles();
|
||||
const [redirect, setRedirect] = useState(null);
|
||||
const { setMessage, setTitle, setSitePath } = useStatusContext();
|
||||
const [ecuName, setECUName] = useState("");
|
||||
const [ecuVersion, setECUVersion] = useState("");
|
||||
const {
|
||||
addFlashpackVersionECUMapping,
|
||||
busy,
|
||||
} = useVehicleContext();
|
||||
|
||||
useEffect(() => {
|
||||
setTitle(`Add Flashpack ECU Version Mapping`);
|
||||
setSitePath([
|
||||
{
|
||||
label: "Tools",
|
||||
link: "/tools/flashpacks",
|
||||
},
|
||||
{
|
||||
label: "Flashpack Versions",
|
||||
link: "/tools/flashpacks",
|
||||
},
|
||||
{
|
||||
label: `Flashpack ${flashpack}`,
|
||||
link: `/tools/flashpack/${model}/${trim}/${year}/${flashpack}`
|
||||
},
|
||||
{
|
||||
label: `Add Flashpack ECU Version Mapping`,
|
||||
},
|
||||
]);
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, []);
|
||||
|
||||
const onCarECUNameChange = (event) => {
|
||||
let newECU = event.target.value
|
||||
|
||||
setECUName(newECU)
|
||||
}
|
||||
|
||||
const onCarECUVersionChange = (event) => {
|
||||
let newECUVersion = event.target.value
|
||||
|
||||
setECUVersion(newECUVersion)
|
||||
}
|
||||
|
||||
const onSubmit = async (event) => {
|
||||
try {
|
||||
event.preventDefault();
|
||||
|
||||
const result = await addFlashpackVersionECUMapping(model, trim, parseInt(year), flashpack, ecuName, ecuVersion, token);
|
||||
if (!result || result.error) return;
|
||||
|
||||
setMessage(`Added ${year} ${model} ${trim} ${flashpack} ${ecuName} ${ecuVersion}`);
|
||||
setRedirect(`/tools/flashpack/${model}/${trim}/${year}/${flashpack}`);
|
||||
} catch (e) {
|
||||
setMessage(e.message);
|
||||
logger.warn(e.stack);
|
||||
}
|
||||
};
|
||||
|
||||
if (redirect && redirect.length > 0) {
|
||||
return <Redirect to={redirect} />;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={classes.paper}>
|
||||
<form className={classes.form} noValidate action="{onSubmit}">
|
||||
<div>
|
||||
<ECUDropDown
|
||||
id="ecuName"
|
||||
name="ecuName"
|
||||
label="ECU Name"
|
||||
value={ecuName}
|
||||
changeHandler={(event) => onCarECUNameChange(event)}
|
||||
required
|
||||
/>
|
||||
<TextField
|
||||
id="ecuVersion"
|
||||
name="ecuVersion"
|
||||
label="ECU Version"
|
||||
variant="outlined"
|
||||
margin="normal"
|
||||
inputProps={{
|
||||
maxLength: "255",
|
||||
}}
|
||||
required
|
||||
value={ecuVersion}
|
||||
onChange={(event) => onCarECUVersionChange(event)}
|
||||
type="text"
|
||||
/>
|
||||
</div>
|
||||
<Button
|
||||
type="submit"
|
||||
disabled={busy}
|
||||
fullWidth
|
||||
variant="contained"
|
||||
color="primary"
|
||||
className={classes.submit}
|
||||
onClick={onSubmit}
|
||||
>
|
||||
{busy ? "Submitting..." : "Submit"}
|
||||
</Button>
|
||||
</form >
|
||||
</div >
|
||||
);
|
||||
};
|
||||
|
||||
const FlashpackECUMappingAdd = () => (
|
||||
<VehicleProvider>
|
||||
<MainForm />
|
||||
</VehicleProvider>
|
||||
);
|
||||
|
||||
export default FlashpackECUMappingAdd;
|
||||
46
src/components/Flashpack/AddMapping/index.test.jsx
Normal file
46
src/components/Flashpack/AddMapping/index.test.jsx
Normal file
@@ -0,0 +1,46 @@
|
||||
jest.mock("../../Contexts/VehicleContext");
|
||||
jest.mock("../../Contexts/StatusContext");
|
||||
jest.mock("../../Contexts/UserContext");
|
||||
jest.mock("@material-ui/core/utils/unstable_useId", () =>
|
||||
jest.fn().mockReturnValue("mui-test-id")
|
||||
);
|
||||
import { render, waitFor } from "@testing-library/react";
|
||||
import { MemoryRouter, Route } from "react-router-dom";
|
||||
import { VehicleProvider } from "../../Contexts/VehicleContext";
|
||||
import { StatusProvider } from "../../Contexts/StatusContext";
|
||||
import { UserProvider, setToken } from "../../Contexts/UserContext";
|
||||
import { TEST_AUTH_OBJECT_FISKER } from "../../../utils/testing";
|
||||
import MainForm from "./index";
|
||||
import addSnapshotSerializer from "../../../utils/snapshot";
|
||||
|
||||
const renderFlashpackECUMappingAdd = async () => {
|
||||
const { container } = render(
|
||||
<VehicleProvider>
|
||||
<StatusProvider>
|
||||
<UserProvider>
|
||||
<MemoryRouter initialEntries={["/tools/flashpack/Ocean/Base/2023/44.4/addECUMapping"]}>
|
||||
<Route path="/tools/flashpack/:model/:trim/:year/:flashpack/addECUMapping">
|
||||
<MainForm />
|
||||
</Route>
|
||||
</MemoryRouter>
|
||||
</UserProvider>
|
||||
</StatusProvider>
|
||||
</VehicleProvider>
|
||||
);
|
||||
await waitFor(() => {
|
||||
/* render */
|
||||
});
|
||||
return container;
|
||||
};
|
||||
|
||||
describe("FlashpackECUMappingAdd", () => {
|
||||
beforeAll(() => {
|
||||
addSnapshotSerializer(expect);
|
||||
});
|
||||
|
||||
it("Render", async () => {
|
||||
setToken(TEST_AUTH_OBJECT_FISKER);
|
||||
const container = await renderFlashpackECUMappingAdd();
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
@@ -15,6 +15,29 @@ exports[`FlashpackDetails Render 1`] = `
|
||||
data-testid="mocked-vehicleprovider"
|
||||
>
|
||||
<div>
|
||||
<div
|
||||
class="MuiGrid-root makeStyles-root-0 MuiGrid-container MuiGrid-spacing-xs-2"
|
||||
>
|
||||
<div
|
||||
class="MuiGrid-root makeStyles-textJustifyAlign-0 makeStyles-actionsBar-0 MuiGrid-item MuiGrid-grid-md-4"
|
||||
>
|
||||
<a
|
||||
class="makeStyles-labelInline-0"
|
||||
href="/tools/flashpackadd/undefined/undefined/undefined/44.4"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
class="MuiSvgIcon-root MuiSvgIcon-fontSizeLarge"
|
||||
focusable="false"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm5 11h-4v4h-2v-4H7v-2h4V7h2v4h4v2z"
|
||||
/>
|
||||
</svg>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<table
|
||||
class="MuiTable-root"
|
||||
>
|
||||
@@ -70,6 +93,29 @@ exports[`FlashpackDetails 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"
|
||||
>
|
||||
Delete
|
||||
<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>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody
|
||||
@@ -90,6 +136,7 @@ exports[`FlashpackDetails Render 1`] = `
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
<div />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { useParams } from "react-router-dom";
|
||||
import {
|
||||
Grid,
|
||||
IconButton,
|
||||
Table,
|
||||
TableBody,
|
||||
TableCell,
|
||||
@@ -8,12 +10,18 @@ import {
|
||||
TablePagination,
|
||||
TableRow,
|
||||
} from "@material-ui/core";
|
||||
import AddCircleIcon from "@material-ui/icons/AddCircle";
|
||||
import { logger } from "../../../services/monitoring";
|
||||
import DeleteIcon from "@material-ui/icons/Delete";
|
||||
import clsx from "clsx";
|
||||
import { Link } from "react-router-dom";
|
||||
import { useVehicleContext, VehicleProvider } from "../../Contexts/VehicleContext";
|
||||
import { useStatusContext } from "../../Contexts/StatusContext";
|
||||
import { useUserContext } from "../../Contexts/UserContext";
|
||||
import TableHeaderSortable from "../../Table/HeaderSortable";
|
||||
import { useLocalStorage } from "../../useLocalStorage";
|
||||
import DeleteConfirmation from "../../DeleteConfirmation";
|
||||
import { RoleWrap } from "../../Controls/RoleWrap";
|
||||
import useStyles from "../../useStyles";
|
||||
|
||||
const tableColumns = [
|
||||
@@ -25,6 +33,10 @@ const tableColumns = [
|
||||
id: "car_ecu_version",
|
||||
label: "ECU Version",
|
||||
},
|
||||
{
|
||||
id: "delete",
|
||||
label: "Delete",
|
||||
},
|
||||
];
|
||||
|
||||
const PAGE_SIZE = "FLASHPACK_MAPPINGS_TABLE_PAGE_SIZE";
|
||||
@@ -37,15 +49,20 @@ const MainForm = () => {
|
||||
const [pageIndex, setPageIndex] = useState(0);
|
||||
const [orderBy, setOrderBy] = useState("flashpack");
|
||||
const [order, setOrder] = useState("desc");
|
||||
const [showDeleteModal, setShowDeleteModal] = useState(false);
|
||||
const [rowToDelete, setRowToDelete] = useState({});
|
||||
const {
|
||||
getFlashpackECUMappings,
|
||||
flashpackECUMappings,
|
||||
totalFlashpackECUMappings,
|
||||
deleteFlashpackVersionECUMapping,
|
||||
} = useVehicleContext();
|
||||
const {
|
||||
token: {
|
||||
idToken: { jwtToken: token },
|
||||
},
|
||||
groups,
|
||||
providers,
|
||||
} = useUserContext();
|
||||
|
||||
useEffect(() => {
|
||||
@@ -118,8 +135,35 @@ const MainForm = () => {
|
||||
}
|
||||
};
|
||||
|
||||
const onDeleteClick = (row) => {
|
||||
setRowToDelete(row);
|
||||
setShowDeleteModal(true);
|
||||
}
|
||||
|
||||
const sendDelete = async () => {
|
||||
if (rowToDelete) {
|
||||
try {
|
||||
const result = await deleteFlashpackVersionECUMapping(rowToDelete.car_model, rowToDelete.car_trim, rowToDelete.car_year, rowToDelete.flashpack, rowToDelete.car_ecu_name, rowToDelete.car_ecu_version, token);
|
||||
if (!result || result.error) return;
|
||||
|
||||
setMessage(`Deleted ${rowToDelete.car_year} ${rowToDelete.car_model} ${rowToDelete.car_trim} ${rowToDelete.flashpack} ${rowToDelete.car_ecu_name} ${rowToDelete.car_ecu_version}`);
|
||||
loadFlashpackECUMappings();
|
||||
} catch (e) {
|
||||
setMessage(e.message);
|
||||
logger.warn(e.stack);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Grid container className={classes.root} spacing={2}>
|
||||
<Grid item md={4} className={clsx(classes.textJustifyAlign, classes.actionsBar)}>
|
||||
<Link to={`/tools/flashpackadd/${model}/${trim}/${year}/${flashpack}`} className={classes.labelInline}>
|
||||
<AddCircleIcon fontSize="large" />
|
||||
</Link>
|
||||
</Grid>
|
||||
</Grid>
|
||||
<Table>
|
||||
<TableHeaderSortable
|
||||
classes={classes}
|
||||
@@ -137,6 +181,22 @@ const MainForm = () => {
|
||||
<TableCell align="center">
|
||||
{row.car_ecu_version}
|
||||
</TableCell>
|
||||
<TableCell align="center">
|
||||
<RoleWrap
|
||||
groups={groups}
|
||||
providers={providers}
|
||||
rolesPerProvider={Permissions.FiskerDelete}
|
||||
>
|
||||
<IconButton
|
||||
onClick={() => onDeleteClick(row)}
|
||||
aria-label={`Send delete for ${row.car_year} ${row.car_model} ${row.car_trim} ${row.flashpack} ${row.car_ecu_name} ${row.car_ecu_version}`}
|
||||
size="small"
|
||||
color="primary"
|
||||
>
|
||||
<DeleteIcon aria-label={`Delete ${row.car_year} ${row.car_model} ${row.car_trim} ${row.flashpack} ${row.car_ecu_name} ${row.car_ecu_version}`} />
|
||||
</IconButton>
|
||||
</RoleWrap>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
))}
|
||||
</TableBody>
|
||||
@@ -147,7 +207,7 @@ const MainForm = () => {
|
||||
) : (
|
||||
<TablePagination
|
||||
rowsPerPageOptions={[5, 10, 25, 100]}
|
||||
colSpan={2}
|
||||
colSpan={3}
|
||||
count={totalFlashpackECUMappings}
|
||||
rowsPerPage={pageSize}
|
||||
page={pageIndex}
|
||||
@@ -161,6 +221,12 @@ const MainForm = () => {
|
||||
</TableRow>
|
||||
</TableFooter>
|
||||
</Table>
|
||||
<DeleteConfirmation
|
||||
message={rowToDelete && rowToDelete.car_year + " " + rowToDelete.car_model + " " + rowToDelete.car_trim + " " + rowToDelete.flashpack + " " + rowToDelete.car_ecu_name + " " + rowToDelete.car_ecu_version}
|
||||
open={showDeleteModal}
|
||||
close={() => setShowDeleteModal(false)}
|
||||
deleteFunction={sendDelete}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -18,8 +18,8 @@ const renderFlashpackDetails = async () => {
|
||||
<VehicleProvider>
|
||||
<StatusProvider>
|
||||
<UserProvider>
|
||||
<MemoryRouter initialEntries={["/tools/flashpack/Ocean/2023/44.4"]}>
|
||||
<Route path="/tools/flashpack/:carModel/:carYear/:flashpack">
|
||||
<MemoryRouter initialEntries={["/tools/flashpack/Ocean/Base/2023/44.4"]}>
|
||||
<Route path="/tools/flashpack/:carModel/:carTrim/:carYear/:flashpack">
|
||||
<MainForm carModel="Ocean" carYear="2023" flashpack="44.4" />
|
||||
</Route>
|
||||
</MemoryRouter>
|
||||
|
||||
@@ -36,6 +36,7 @@ const SuppliersList = React.lazy(() => import("../Suppliers/List"));
|
||||
const SupplierDetails = React.lazy(() => import("../Suppliers/Details"));
|
||||
const Flashpacks = React.lazy(() => import("../Flashpack"));
|
||||
const FlashpackDetails = React.lazy(() => import("../Flashpack/Details"));
|
||||
const FlashpackECUMappingAdd = React.lazy(() => import("../Flashpack/AddMapping"))
|
||||
const FlashpackAdd = React.lazy(() => import("../Flashpack/Add"))
|
||||
const Datascope = React.lazy(() => import("../Dashboard"));
|
||||
const Sums = React.lazy(() => import("../SUMS/List"))
|
||||
@@ -297,6 +298,15 @@ const SiteRoutes = () => {
|
||||
rolesPerGroup={Permissions.FiskerRead}
|
||||
providers={providers}
|
||||
/>
|
||||
<AuthRoute
|
||||
path="/tools/flashpackadd/:model/:trim/:year/:flashpack"
|
||||
render={() => <FlashpackECUMappingAdd />}
|
||||
type={TYPES.PROTECTED}
|
||||
token={token}
|
||||
groups={groups}
|
||||
rolesPerGroup={Permissions.FiskerCreate}
|
||||
providers={providers}
|
||||
/>
|
||||
<AuthRoute
|
||||
path="/tools/flashpack/add"
|
||||
render={() => <FlashpackAdd />}
|
||||
|
||||
@@ -295,6 +295,18 @@ const vehiclesAPI = {
|
||||
.catch(errorHandler)
|
||||
},
|
||||
|
||||
addFlashpackVersionECUMapping: async (model, trim, year, flashpack, data, token) => {
|
||||
return fetch(`${API_ENDPOINT}/flashpack_version_ecu_mapping/${model}/${trim}/${year}/${flashpack}`, {
|
||||
method: "POST",
|
||||
headers: Object.assign(
|
||||
{ "Content-Type": "application/json" },
|
||||
getAuthHeaderOptions(token),
|
||||
),
|
||||
body: JSON.stringify(data),
|
||||
}).then(fetchRespHandler)
|
||||
.catch(errorHandler)
|
||||
},
|
||||
|
||||
deleteFlashpackVersion: async (data, token) => {
|
||||
return fetch(`${API_ENDPOINT}/flashpack_version`, {
|
||||
method: "DELETE",
|
||||
@@ -307,6 +319,17 @@ const vehiclesAPI = {
|
||||
.catch(errorHandler)
|
||||
},
|
||||
|
||||
deleteFlashpackVersionECUMapping: async (model, trim, year, flashpack, ecuName, ecuVersion, token) => {
|
||||
return fetch(`${API_ENDPOINT}/flashpack_version_ecu_mapping/${model}/${trim}/${year}/${flashpack}/${ecuName}/${ecuVersion}`, {
|
||||
method: "DELETE",
|
||||
headers: Object.assign(
|
||||
{ "Content-Type": "application/json" },
|
||||
getAuthHeaderOptions(token)
|
||||
),
|
||||
}).then(fetchRespHandler)
|
||||
.catch(errorHandler)
|
||||
},
|
||||
|
||||
getCarFlashpackVersionInfo: async (vin, token) => {
|
||||
return fetch(`${API_ENDPOINT}/flashpack_version_info/${vin}`, {
|
||||
method: "GET",
|
||||
|
||||
Reference in New Issue
Block a user