Skip to content

feat: improved url and form state sync #736

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,21 +13,22 @@
"@testing-library/jest-dom": "5.16.4",
"@testing-library/react": "13.3.0",
"@testing-library/user-event": "13.5.0",
"@vercel/analytics": "^1.1.2",
"@vercel/analytics": "^1.2.2",
"@vercel/speed-insights": "^1.0.10",
"@vitejs/plugin-react": "^4.0.0",
"axios": "0.27.2",
"dotenv": "^16.0.3",
"fontsource-roboto": "4.0.0",
"jsdom": "^22.1.0",
"lodash": "^4.17.21",
"plotly.js": "2.13.2",
"react": "18.2.0",
"react-dom": "18.2.0",
"react-ga4": "^1.4.1",
"react-helmet": "^6.1.0",
"react-hook-form": "7.33.1",
"react-plotly.js": "2.5.1",
"react-router-dom": "^7.4.0",
"react-scripts": "5.0.1",
"react-top-loading-bar": "2.1.0",
"typescript": "4.7.4",
Expand Down
6 changes: 5 additions & 1 deletion frontend/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { makeStyles } from "@mui/styles";
import CssBaseline from "@mui/material/CssBaseline";
import { PlotSpectra } from "./components/PlotSpectra";
import { Header } from "./components/Header";
import { BrowserRouter } from "react-router";

export const useStyles = makeStyles({
root: {
Expand All @@ -20,7 +21,8 @@ export const useStyles = makeStyles({
export default function App(): React.ReactElement {
const classes = useStyles();
return (
<div className={classes.root}>
<BrowserRouter>
<div className={classes.root}>
<CssBaseline />
<Header />
<Container style={{ maxWidth: "none" }}>
Expand All @@ -29,5 +31,7 @@ export default function App(): React.ReactElement {
</Box>
</Container>
</div>
</BrowserRouter>

);
}
125 changes: 110 additions & 15 deletions frontend/src/components/Form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ import { Species } from "./fields/Species/Species";
import { DownloadTxtButton } from "./DownloadTxtButton";
import UseNonEquilibriumCalculationsSwitch from "./fields/UseNonEquilibriumCalculationsSwitch";
import UseSimulateSlitSwitch from "./fields/UseSimulateSlitSwitch";
import {isEqual} from 'lodash'
import useParamState from "../hooks/useParamsState";
import { DEFAULT_VALUES } from "../constants";

export interface Response<T> {
data?: T;
Expand All @@ -49,6 +52,7 @@ export const Form: React.FunctionComponent<FormProps> = ({
spectra,
setSpectra,
}) => {

const {
isNonEquilibrium,
toggleIsNonEquilibrium,
Expand All @@ -66,9 +70,8 @@ export const Form: React.FunctionComponent<FormProps> = ({
} = useFromStore();

//TODO - we need to make it global

const methods = useForm<FormValues>({
defaultValues: { species: [{ molecule: "CO", mole_fraction: 0.1 }] },
defaultValues: DEFAULT_VALUES,
resolver: yupResolver(formSchema),
});

Expand All @@ -77,9 +80,71 @@ export const Form: React.FunctionComponent<FormProps> = ({
handleSubmit,
setValue,
watch,
reset,
formState: { dirtyFields },
} = methods;

const [params, setParams] = useParamState('form',DEFAULT_VALUES);

useEffect(() => {
if (params && !isEqual(params, DEFAULT_VALUES)) {
const hasNonEquilibriumParams = params.trot !== undefined || params.tvib !== undefined;
console.log(hasNonEquilibriumParams)
if (hasNonEquilibriumParams) {
toggleIsNonEquilibrium(true);
toggleshowNonEquilibriumSwitch(true);
setTimeout(() => {
reset(params);
}, 0)
}else{
reset(params);
}
}
}, []);

const addSpecies = () => {
setParams((prev) => ({
...prev,
species: [...prev.species, { molecule: "", mole_fraction: 0.0}],
}));
};

const updateMoleFraction = (index: number, newMoleFraction: number) => {
setParams((prev) => ({
...prev,
species: prev.species.map((s, indexVal) =>
indexVal == index ? { ...s, mole_fraction: newMoleFraction } : s
),
}));
};

const updateMolecule = (index: number, molecule: string) => {
setParams((prev) => ({
...prev,
species: prev.species.map((s, indexVal) =>
indexVal == index ? { ...s, molecule: molecule } : s
),
}));
};


const removeSpecies = (index: number) => {
setParams((prev) => ({
...prev,
species: prev.species.filter((s, indexVal) => indexVal != index),
}));
};


const updateFieldValue = (key: string, value: any) => {
setParams((prev) => ({
...prev,
[key]: value,
}));
};



const databaseWatch = watch("database");
React.useEffect(() => {
if (databaseWatch === Database.GEISA) {
Expand Down Expand Up @@ -292,56 +357,78 @@ export const Form: React.FunctionComponent<FormProps> = ({
>
<Grid container spacing={3}>
<Grid xs={12} sm={8} md={5} lg={6}>
<DatabaseField />
<DatabaseField
updateFieldValue={updateFieldValue}
/>
</Grid>
<Grid xs={12} sm={8} md={5} lg={6}>
<Mode />
<Mode
updateFieldValue={updateFieldValue}
/>
</Grid>
<Grid xs={12}>
<WavenumberRangeSlider />
<WavenumberRangeSlider
updateFieldValue={updateFieldValue}
/>
</Grid>

{isNonEquilibrium ? (
<Grid sm={8} lg={4}>
<TGas />
<TGas
updateFieldValue={updateFieldValue}
/>
</Grid>
) : (
<Grid sm={8} lg={12}>
<TGas />
<TGas
updateFieldValue={updateFieldValue}
/>
</Grid>
)}

{isNonEquilibrium ? (
<>
<Grid sm={8} lg={4}>
<TRot />
<TRot
updateFieldValue={updateFieldValue}
/>
</Grid>
<Grid sm={8} lg={4}>
<TVib />
<TVib
updateFieldValue={updateFieldValue}
/>
</Grid>
</>
) : null}

{isNonEquilibrium ? (
<Grid sm={8} lg={12}>
<Pressure />
<Pressure
updateFieldValue={updateFieldValue}
/>
</Grid>
) : (
<Grid sm={8} lg={12}>
<Pressure />
<Pressure
updateFieldValue={updateFieldValue}
/>
</Grid>
)}

{isNonEquilibrium ? (
<>
<Grid sm={8} lg={12}>
<PathLength />
<PathLength
updateFieldValue={updateFieldValue}
/>
</Grid>
</>
) : (
<>
<Grid sm={8} lg={12}>
<PathLength />
<PathLength
updateFieldValue={updateFieldValue}
/>
</Grid>
</>
)}
Expand All @@ -351,19 +438,27 @@ export const Form: React.FunctionComponent<FormProps> = ({
isNonEquilibrium={isNonEquilibrium}
control={control}
databaseWatch={databaseWatch}
addSpecies={addSpecies}
updateMolecule={updateMolecule}
updateMoleFraction={updateMoleFraction}
removeSpecies={removeSpecies}
/>
</Grid>

{useSimulateSlitFunction ? (
<Grid xs={12}>
<UseSimulateSlitSwitch />
<UseSimulateSlitSwitch
updateFieldValue={updateFieldValue}
/>
</Grid>
) : null}

{useSimulateSlitFunction ? (
useSlit ? (
<Grid xs={12}>
<SimulateSlit />
<SimulateSlit
updateFieldValue={updateFieldValue}
/>
</Grid>
) : null
) : null}
Expand Down
7 changes: 6 additions & 1 deletion frontend/src/components/fields/Database.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,11 @@ import FormControl from "@mui/joy/FormControl";
import { Controller, useFormContext } from "react-hook-form";
import { Database as TDatabase } from "../types";

export const Database: React.FC = () => {
export interface DatabaseProps {
updateFieldValue: (key: string, value: any) => void;
}

export const Database: React.FC<DatabaseProps> = ({updateFieldValue}) => {
const { control } = useFormContext();
return (
<FormControl>
Expand All @@ -20,6 +24,7 @@ export const Database: React.FC = () => {
{...formState}
onChange={(_, value) => {
field.onChange(value);
updateFieldValue("database", value);
}}
value={field.value}
>
Expand Down
8 changes: 7 additions & 1 deletion frontend/src/components/fields/Mode.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,13 @@ import Option from "@mui/joy/Option";

import { Controller, useFormContext } from "react-hook-form";

export const Mode: React.FC = () => {
export interface ModeProps {
updateFieldValue: (key: string, value: any) => void;
}

export const Mode: React.FC<ModeProps> = ({updateFieldValue}) => {
const { control } = useFormContext();

return (
<FormControl>
<FormLabel>Mode</FormLabel>
Expand All @@ -20,6 +25,7 @@ export const Mode: React.FC = () => {
{...field}
onChange={(_, value) => {
field.onChange(value);
updateFieldValue("mode", value);
}}
value={field.value}
>
Expand Down
15 changes: 12 additions & 3 deletions frontend/src/components/fields/PathLength.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,11 @@ import { Controller, useFormContext } from "react-hook-form";
import { PathLengthUnit } from "./PathLengthUnits";
import Divider from "@mui/joy/Divider";

export const PathLength: React.FC = () => {
export interface PathLengthProps {
updateFieldValue: (key: string, value: any) => void;
}

export const PathLength: React.FC<PathLengthProps> = ({updateFieldValue}) => {
const { control } = useFormContext();
return (
<Controller
Expand All @@ -16,13 +20,18 @@ export const PathLength: React.FC = () => {
<Input
{...field}
type="number"
onChange={field.onChange}
onChange={(e) => {
field.onChange(Number(e.target.value));
updateFieldValue("path_length", Number(e.target.value));
}}
value={field.value}
error={!!fieldState.error}
endDecorator={
<div>
<Divider orientation="vertical" />
<PathLengthUnit />
<PathLengthUnit
updateFieldValue={updateFieldValue}
/>
</div>
}
/>
Expand Down
6 changes: 5 additions & 1 deletion frontend/src/components/fields/PathLengthUnits.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,12 @@ import Select from "@mui/joy/Select";
import FormControl from "@mui/joy/FormControl";
import { Controller, useFormContext } from "react-hook-form";

export interface PathLengthUnitProps {
updateFieldValue: (key: string, value: any) => void;
}


export const PathLengthUnit: React.FC = () => {
export const PathLengthUnit: React.FC<PathLengthUnitProps> = ({updateFieldValue}) => {
const { control } = useFormContext();
return (
<FormControl>
Expand All @@ -20,6 +23,7 @@ export const PathLengthUnit: React.FC = () => {
id="mode-select"
onChange={(_, value) => {
field.onChange(value);
updateFieldValue("path_length_units", value);
}}
value={field.value}
slotProps={{
Expand Down
Loading