More picklists

This commit is contained in:
padamsen_fisker
2024-03-05 16:31:08 -05:00
parent f3b56c0e55
commit 8f011d11f2
7 changed files with 406 additions and 130 deletions

View File

@@ -291,11 +291,11 @@ export const VehicleProvider = ({ children }) => {
} }
}; };
const getAllFlashpacks = async (options, token) => { const getAllFlashpacks = async (model, trim, year, options, token) => {
try { try {
setBusy(true); setBusy(true);
const result = await api.getAllFlashpacks(options, token); const result = await api.getAllFlashpacks(model, trim, year, options, token);
if (result.error) { if (result.error) {
throw new Error(`Get all flashpacks error. ${result.message}`); throw new Error(`Get all flashpacks error. ${result.message}`);
} }

View File

@@ -24,138 +24,175 @@ exports[`FlashpackAdd Render 1`] = `
> >
<div> <div>
<div <div
class="MuiFormControl-root MuiTextField-root MuiFormControl-marginNormal MuiFormControl-fullWidth" class="MuiFormControl-root MuiFormControl-marginNormal MuiFormControl-fullWidth"
> >
<label <label
class="MuiFormLabel-root MuiInputLabel-root MuiInputLabel-formControl MuiInputLabel-animated MuiInputLabel-outlined Mui-required Mui-required" class="MuiFormLabel-root MuiInputLabel-root makeStyles-whiteBackground-0 MuiInputLabel-formControl MuiInputLabel-animated MuiInputLabel-shrink MuiInputLabel-outlined MuiFormLabel-filled"
data-shrink="false" data-shrink="true"
for="carModel"
id="carModel-label"
> >
Model Model
<span
aria-hidden="true"
class="MuiFormLabel-asterisk MuiInputLabel-asterisk"
>
*
</span>
</label> </label>
<div <div
class="MuiInputBase-root MuiOutlinedInput-root MuiInputBase-fullWidth MuiInputBase-formControl" class="MuiInputBase-root MuiOutlinedInput-root MuiInputBase-formControl"
required=""
> >
<input <select
aria-invalid="false" aria-invalid="false"
class="MuiInputBase-input MuiOutlinedInput-input" class="MuiSelect-root MuiSelect-select MuiSelect-outlined MuiInputBase-input MuiOutlinedInput-input"
id="carModel"
maxlength="255"
name="carModel"
required="" required=""
type="text" >
value="" <option
/> value="Ocean"
>
Ocean
</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 <fieldset
aria-hidden="true" aria-hidden="true"
class="PrivateNotchedOutline-root-0 MuiOutlinedInput-notchedOutline" class="PrivateNotchedOutline-root-0 MuiOutlinedInput-notchedOutline"
style="padding-left: 8px;"
> >
<legend <legend
class="PrivateNotchedOutline-legendLabelled-0" class="PrivateNotchedOutline-legend-0"
style="width: 0.01px;"
> >
<span> <span>
Model
 *
</span> </span>
</legend> </legend>
</fieldset> </fieldset>
</div> </div>
</div> </div>
<div <div
class="MuiFormControl-root MuiTextField-root MuiFormControl-marginNormal MuiFormControl-fullWidth" class="MuiFormControl-root MuiFormControl-marginNormal MuiFormControl-fullWidth"
> >
<label <label
class="MuiFormLabel-root MuiInputLabel-root MuiInputLabel-formControl MuiInputLabel-animated MuiInputLabel-outlined Mui-required Mui-required" class="MuiFormLabel-root MuiInputLabel-root makeStyles-whiteBackground-0 MuiInputLabel-formControl MuiInputLabel-animated MuiInputLabel-shrink MuiInputLabel-outlined MuiFormLabel-filled"
data-shrink="false" data-shrink="true"
for="carTrim"
id="carTrim-label"
> >
Trim Trim
<span
aria-hidden="true"
class="MuiFormLabel-asterisk MuiInputLabel-asterisk"
>
*
</span>
</label> </label>
<div <div
class="MuiInputBase-root MuiOutlinedInput-root MuiInputBase-fullWidth MuiInputBase-formControl" class="MuiInputBase-root MuiOutlinedInput-root MuiInputBase-formControl"
required=""
> >
<input <select
aria-invalid="false" aria-invalid="false"
class="MuiInputBase-input MuiOutlinedInput-input" class="MuiSelect-root MuiSelect-select MuiSelect-outlined MuiInputBase-input MuiOutlinedInput-input"
id="carTrim"
maxlength="255"
name="carTrim"
required="" required=""
type="text" >
value="" <option
/> value="Base"
>
Base
</option>
<option
value="Sport"
>
Sport
</option>
<option
value="Ocean One"
>
Ocean One
</option>
<option
value="Ultra"
>
Ultra
</option>
<option
value="Extreme"
>
Extreme
</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 <fieldset
aria-hidden="true" aria-hidden="true"
class="PrivateNotchedOutline-root-0 MuiOutlinedInput-notchedOutline" class="PrivateNotchedOutline-root-0 MuiOutlinedInput-notchedOutline"
style="padding-left: 8px;"
> >
<legend <legend
class="PrivateNotchedOutline-legendLabelled-0" class="PrivateNotchedOutline-legend-0"
style="width: 0.01px;"
> >
<span> <span>
Trim
 *
</span> </span>
</legend> </legend>
</fieldset> </fieldset>
</div> </div>
</div> </div>
<div <div
class="MuiFormControl-root MuiTextField-root MuiFormControl-marginNormal MuiFormControl-fullWidth" class="MuiFormControl-root MuiFormControl-marginNormal MuiFormControl-fullWidth"
> >
<label <label
class="MuiFormLabel-root MuiInputLabel-root MuiInputLabel-formControl MuiInputLabel-animated MuiInputLabel-outlined Mui-required Mui-required" class="MuiFormLabel-root MuiInputLabel-root makeStyles-whiteBackground-0 MuiInputLabel-formControl MuiInputLabel-animated MuiInputLabel-shrink MuiInputLabel-outlined MuiFormLabel-filled"
data-shrink="false" data-shrink="true"
for="carYear"
id="carYear-label"
> >
Year Year
<span
aria-hidden="true"
class="MuiFormLabel-asterisk MuiInputLabel-asterisk"
>
*
</span>
</label> </label>
<div <div
class="MuiInputBase-root MuiOutlinedInput-root MuiInputBase-fullWidth MuiInputBase-formControl" class="MuiInputBase-root MuiOutlinedInput-root MuiInputBase-formControl"
required=""
> >
<input <select
aria-invalid="false" aria-invalid="false"
class="MuiInputBase-input MuiOutlinedInput-input" class="MuiSelect-root MuiSelect-select MuiSelect-outlined MuiInputBase-input MuiOutlinedInput-input"
id="carYear"
maxlength="255"
name="carYear"
required="" required=""
type="number" >
value="" <option
/> value="2023"
>
2023
</option>
<option
value="2024"
>
2024
</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 <fieldset
aria-hidden="true" aria-hidden="true"
class="PrivateNotchedOutline-root-0 MuiOutlinedInput-notchedOutline" class="PrivateNotchedOutline-root-0 MuiOutlinedInput-notchedOutline"
style="padding-left: 8px;"
> >
<legend <legend
class="PrivateNotchedOutline-legendLabelled-0" class="PrivateNotchedOutline-legend-0"
style="width: 0.01px;"
> >
<span> <span>
Year
 *
</span> </span>
</legend> </legend>
</fieldset> </fieldset>

View File

@@ -12,7 +12,10 @@ import { logger } from "../../../services/monitoring";
import { useStatusContext } from "../../Contexts/StatusContext"; import { useStatusContext } from "../../Contexts/StatusContext";
import { useVehicleContext, VehicleProvider } from "../../Contexts/VehicleContext"; import { useVehicleContext, VehicleProvider } from "../../Contexts/VehicleContext";
import { useUserContext } from "../../Contexts/UserContext"; import { useUserContext } from "../../Contexts/UserContext";
import { useLocalStorage } from "../../useLocalStorage";
import useStyles from "../../useStyles"; import useStyles from "../../useStyles";
import { DropDownList } from "../../Controls/DropDownList";
import modelsTrimsYears from '.././modelsTrimsYears.json';
const MainForm = () => { const MainForm = () => {
const { const {
@@ -23,9 +26,11 @@ const MainForm = () => {
const classes = useStyles(); const classes = useStyles();
const [redirect, setRedirect] = useState(null); const [redirect, setRedirect] = useState(null);
const { setMessage, setTitle, setSitePath } = useStatusContext(); const { setMessage, setTitle, setSitePath } = useStatusContext();
const [carModel, setCarModel] = useState(""); const [carModel, setCarModel] = useLocalStorage("FLASHPACK_ADD_MODEL", "Ocean");
const [carTrim, setCarTrim] = useState(""); const [carTrim, setCarTrim] = useLocalStorage("FLASHPACK_ADD_TRIM", "Base");
const [carYear, setCarYear] = useState(); const [carYear, setCarYear] = useLocalStorage("FLASHPACK_ADD_YEAR", 2024);
const [trims, setTrims] = useLocalStorage("FLASHPACK_ADD_TRIMS", modelsTrimsYears.oceanTrims);
const [years, setYears] = useLocalStorage("FLASHPACK_ADD_YEARS", modelsTrimsYears.oceanYears);
const [flashpack, setFlashpack] = useState(); const [flashpack, setFlashpack] = useState();
const [mappingInputs, setMappingInputs] = useState([{ ecuName: "", ecuVersion: "" }]); const [mappingInputs, setMappingInputs] = useState([{ ecuName: "", ecuVersion: "" }]);
const { const {
@@ -52,15 +57,30 @@ const MainForm = () => {
}, []); }, []);
const onCarModelChange = (event) => { const onCarModelChange = (event) => {
setCarModel(event.target.value); let newModel = event.target.value
setCarModel(newModel)
switch (newModel) {
case "Ocean":
setTrims(modelsTrimsYears.oceanTrims);
setYears(modelsTrimsYears.oceanYears);
break;
default:
break;
}
} }
const onCarTrimChange = (event) => { const onCarTrimChange = (event) => {
setCarTrim(event.target.value); let newTrim = event.target.value
setCarTrim(newTrim)
} }
const onCarYearChange = (event) => { const onCarYearChange = (event) => {
setCarYear(event.target.value); let newYear = event.target.value
setCarYear(newYear)
} }
const onFlashpackChange = (event) => { const onFlashpackChange = (event) => {
@@ -119,51 +139,9 @@ const MainForm = () => {
<div className={classes.paper}> <div className={classes.paper}>
<form className={classes.form} noValidate action="{onSubmit}"> <form className={classes.form} noValidate action="{onSubmit}">
<div> <div>
<TextField <DropDownList fullWidth required label="Model" data={modelsTrimsYears.models} classes={classes} onChange={onCarModelChange} value={carModel} />
id="carModel" <DropDownList fullWidth required label="Trim" data={trims} disabled={!carModel || !trims} classes={classes} onChange={onCarTrimChange} value={carTrim} />
name="carModel" <DropDownList fullWidth required label="Year" data={years} disabled={!carModel || !years} classes={classes} onChange={onCarYearChange} value={carYear} />
label="Model"
variant="outlined"
margin="normal"
inputProps={{
maxLength: "255",
}}
required
fullWidth
value={carModel}
onChange={onCarModelChange}
type="text"
/>
<TextField
id="carTrim"
name="carTrim"
label="Trim"
variant="outlined"
margin="normal"
inputProps={{
maxLength: "255",
}}
required
fullWidth
value={carTrim}
onChange={onCarTrimChange}
type="text"
/>
<TextField
id="carYear"
name="carYear"
label="Year"
variant="outlined"
margin="normal"
inputProps={{
maxLength: "255",
}}
required
fullWidth
value={carYear}
onChange={onCarYearChange}
type="number"
/>
<TextField <TextField
id="flashpack" id="flashpack"
name="flashpack" name="flashpack"

View File

@@ -15,6 +15,175 @@ exports[`Flashpack Render 1`] = `
data-testid="mocked-vehicleprovider" data-testid="mocked-vehicleprovider"
> >
<div> <div>
<div
class="MuiFormControl-root MuiFormControl-marginNormal"
>
<label
class="MuiFormLabel-root MuiInputLabel-root makeStyles-whiteBackground-0 MuiInputLabel-formControl MuiInputLabel-animated MuiInputLabel-shrink MuiInputLabel-outlined MuiFormLabel-filled"
data-shrink="true"
>
Model
</label>
<div
class="MuiInputBase-root MuiOutlinedInput-root MuiInputBase-formControl"
>
<select
aria-invalid="false"
class="MuiSelect-root MuiSelect-select MuiSelect-outlined MuiInputBase-input MuiOutlinedInput-input"
>
<option
value="Ocean"
>
Ocean
</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 MuiFormControl-marginNormal"
>
<label
class="MuiFormLabel-root MuiInputLabel-root makeStyles-whiteBackground-0 MuiInputLabel-formControl MuiInputLabel-animated MuiInputLabel-shrink MuiInputLabel-outlined MuiFormLabel-filled"
data-shrink="true"
>
Trim
</label>
<div
class="MuiInputBase-root MuiOutlinedInput-root MuiInputBase-formControl"
>
<select
aria-invalid="false"
class="MuiSelect-root MuiSelect-select MuiSelect-outlined MuiInputBase-input MuiOutlinedInput-input"
>
<option
value="Base"
>
Base
</option>
<option
value="Sport"
>
Sport
</option>
<option
value="Ocean One"
>
Ocean One
</option>
<option
value="Ultra"
>
Ultra
</option>
<option
value="Extreme"
>
Extreme
</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 MuiFormControl-marginNormal"
>
<label
class="MuiFormLabel-root MuiInputLabel-root makeStyles-whiteBackground-0 MuiInputLabel-formControl MuiInputLabel-animated MuiInputLabel-shrink MuiInputLabel-outlined MuiFormLabel-filled"
data-shrink="true"
>
Year
</label>
<div
class="MuiInputBase-root MuiOutlinedInput-root MuiInputBase-formControl"
>
<select
aria-invalid="false"
class="MuiSelect-root MuiSelect-select MuiSelect-outlined MuiInputBase-input MuiOutlinedInput-input"
>
<option
value="2023"
>
2023
</option>
<option
value="2024"
>
2024
</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 <div
class="MuiGrid-root makeStyles-root-0 MuiGrid-container MuiGrid-spacing-xs-2" class="MuiGrid-root makeStyles-root-0 MuiGrid-container MuiGrid-spacing-xs-2"
> >

View File

@@ -21,7 +21,9 @@ import TableHeaderSortable from "../Table/HeaderSortable";
import { useLocalStorage } from "../useLocalStorage"; import { useLocalStorage } from "../useLocalStorage";
import DeleteConfirmation from "../DeleteConfirmation"; import DeleteConfirmation from "../DeleteConfirmation";
import { RoleWrap } from "../Controls/RoleWrap"; import { RoleWrap } from "../Controls/RoleWrap";
import { DropDownList } from "../Controls/DropDownList";
import useStyles from "../useStyles"; import useStyles from "../useStyles";
import modelsTrimsYears from './modelsTrimsYears.json';
const tableColumns = [ const tableColumns = [
{ {
@@ -55,6 +57,11 @@ const MainForm = () => {
const [pageIndex, setPageIndex] = useState(0); const [pageIndex, setPageIndex] = useState(0);
const [showDeleteModal, setShowDeleteModal] = useState(false); const [showDeleteModal, setShowDeleteModal] = useState(false);
const [rowToDelete, setRowToDelete] = useState({}); const [rowToDelete, setRowToDelete] = useState({});
const [model, setModel] = useLocalStorage("FLASHPACKS_MODEL", "Ocean");
const [trim, setTrim] = useLocalStorage("FLASHPACKS_TRIM", "Base");
const [year, setYear] = useLocalStorage("FLASHPACKS_YEAR", 2024);
const [trims, setTrims] = useLocalStorage("FLASHPACKS_TRIMS", modelsTrimsYears.oceanTrims);
const [years, setYears] = useLocalStorage("FLASHPACKS_YEARS", modelsTrimsYears.oceanYears);
const { const {
getAllFlashpacks, getAllFlashpacks,
flashpacks, flashpacks,
@@ -84,14 +91,17 @@ const MainForm = () => {
}, []); }, []);
useEffect(() => { useEffect(() => {
loadFlashpacks(); loadFlashpacks(model, trim, year);
// eslint-disable-next-line react-hooks/exhaustive-deps // eslint-disable-next-line react-hooks/exhaustive-deps
}, [token, pageIndex, pageSize]); }, [token, pageIndex, pageSize]);
const loadFlashpacks = async () => { const loadFlashpacks = async (model, trim, year) => {
try { try {
if (!token) return; if (!token) return;
await getAllFlashpacks( await getAllFlashpacks(
model,
trim,
year,
{ {
limit: pageSize, limit: pageSize,
offset: pageSize * pageIndex, offset: pageSize * pageIndex,
@@ -104,6 +114,45 @@ const MainForm = () => {
} }
}; };
const onModelChange = (event) => {
let newModel = event.target.value
setModel(newModel)
switch (newModel) {
case "Ocean":
setTrims(modelsTrimsYears.oceanTrims);
setYears(modelsTrimsYears.oceanYears);
break;
default:
break;
}
if (trim && year) {
loadFlashpacks(newModel, trim, year)
}
};
const onTrimChange = (event) => {
let newTrim = event.target.value
setTrim(newTrim)
if (model && year) {
loadFlashpacks(model, newTrim, year)
}
};
const onYearChange = (event) => {
let newYear = event.target.value
setYear(newYear)
if (model && trim) {
loadFlashpacks(model, trim, newYear)
}
};
const handleChangePageIndex = (event, newIndex) => { const handleChangePageIndex = (event, newIndex) => {
setPageIndex(newIndex); setPageIndex(newIndex);
}; };
@@ -125,7 +174,7 @@ const MainForm = () => {
if (!result || result.error) return; if (!result || result.error) return;
setMessage(`Deleted ${rowToDelete.car_year} ${rowToDelete.car_model} ${rowToDelete.car_trim} ${rowToDelete.flashpack}`); setMessage(`Deleted ${rowToDelete.car_year} ${rowToDelete.car_model} ${rowToDelete.car_trim} ${rowToDelete.flashpack}`);
loadFlashpacks(); loadFlashpacks(model, trim, year);
} catch (e) { } catch (e) {
setMessage(e.message); setMessage(e.message);
logger.warn(e.stack); logger.warn(e.stack);
@@ -135,6 +184,9 @@ const MainForm = () => {
return ( return (
<div> <div>
<DropDownList label="Model" data={modelsTrimsYears.models} classes={classes} onChange={onModelChange} value={model} />
<DropDownList label="Trim" data={trims} disabled={!model || !trims} classes={classes} onChange={onTrimChange} value={trim} />
<DropDownList label="Year" data={years} disabled={!model || !years} classes={classes} onChange={onYearChange} value={year} />
<Grid container className={classes.root} spacing={2}> <Grid container className={classes.root} spacing={2}>
<Grid item md={4} className={clsx(classes.textJustifyAlign, classes.actionsBar)}> <Grid item md={4} className={clsx(classes.textJustifyAlign, classes.actionsBar)}>
<Link to={`/tools/flashpack/add`} className={classes.labelInline}> <Link to={`/tools/flashpack/add`} className={classes.labelInline}>

View File

@@ -0,0 +1,40 @@
{
"models": [
{
"value": "Ocean",
"label": "Ocean"
}
],
"oceanTrims": [
{
"value": "Base",
"label": "Base"
},
{
"value": "Sport",
"label": "Sport"
},
{
"value": "Ocean One",
"label": "Ocean One"
},
{
"value": "Ultra",
"label": "Ultra"
},
{
"value": "Extreme",
"label": "Extreme"
}
],
"oceanYears": [
{
"value": 2023,
"label": "2023"
},
{
"value": 2024,
"label": "2024"
}
]
}

View File

@@ -261,8 +261,8 @@ const vehiclesAPI = {
.catch(errorHandler) .catch(errorHandler)
}, },
getAllFlashpacks: async (options, token) => { getAllFlashpacks: async (model, trim, year, options, token) => {
return fetch(addQueryParams(`${API_ENDPOINT}/flashpack_versions`, options), { return fetch(addQueryParams(`${API_ENDPOINT}/flashpack_versions/${model}/${trim}/${year}`, options), {
method: "GET", method: "GET",
headers: Object.assign( headers: Object.assign(
{ "Content-Type": "application/json" }, { "Content-Type": "application/json" },