From 6dfbcf7dc7e079a977ecdfc633f1490960aa51eb Mon Sep 17 00:00:00 2001 From: wniestroj <152595753+wniestroj@users.noreply.github.com> Date: Wed, 13 Nov 2024 19:59:09 +0100 Subject: [PATCH 1/6] Fixing Simulations bug with plot being resized on changing layout (#566) * PKPDX-29 Add headers to results tables * Remove unnecessary quotation mark * Fix plots being constantly resized when changing layout * Fix plots being constantly resized when changing layout * Added controlling of plots width in dependence to resolution/scale --------- Co-authored-by: Jim O'Donnell --- .../simulation/SimulationPlotView.tsx | 23 +++++++++++++++++-- .../src/features/simulation/Simulations.tsx | 6 +---- .../simulation/SimulationsSidePanel.tsx | 1 - 3 files changed, 22 insertions(+), 8 deletions(-) diff --git a/frontend-v2/src/features/simulation/SimulationPlotView.tsx b/frontend-v2/src/features/simulation/SimulationPlotView.tsx index ba423606..81aec41e 100644 --- a/frontend-v2/src/features/simulation/SimulationPlotView.tsx +++ b/frontend-v2/src/features/simulation/SimulationPlotView.tsx @@ -266,6 +266,7 @@ interface SimulationPlotProps { model: CombinedModelRead; visibleGroups: string[]; shouldShowLegend: boolean; + layout: string; } const SimulationPlotView: FC = ({ @@ -281,7 +282,8 @@ const SimulationPlotView: FC = ({ compound, model, visibleGroups, - shouldShowLegend + shouldShowLegend, + layout }) => { const projectId = useSelector( (state: RootState) => state.main.selectedProject, @@ -460,7 +462,25 @@ const SimulationPlotView: FC = ({ // axis dticks // const { dticky, dticky2 } = dticks(rangey, rangey2, plot); + const getPlotWidth = () => { + if (window.innerWidth > 1900 ) { + return 650 + } + + if (window.innerWidth > 1700) { + return 550 + } + + if (window.innerWidth > 1500) { + return screen.width > 1400 ? 450 : 650 + } + + return 680; + } + const plotLayout: Partial = { + autosize: false, + width: getPlotWidth(), dragmode: "pan", showlegend: shouldShowLegend, shapes: icLines.map((icLine, i) => { @@ -638,7 +658,6 @@ const SimulationPlotView: FC = ({ layout={plotLayout} style={{ width: "100%", height: "100%" }} config={config} - useResizeHandler={true} /> { const defaultLayout = layoutOptions[0]?.value; const [layout, setLayout] = useState(defaultLayout); - const updateWindowDimensions = () => - window.innerWidth < 1000 && setLayout("horizontal"); - window.addEventListener("resize", updateWindowDimensions); - // reset form and sliders if simulation changes useEffect(() => { if (simulation && variables) { @@ -506,6 +501,7 @@ const Simulations: FC = () => { model={model} visibleGroups={visibleGroups} shouldShowLegend={shouldShowLegend} + layout={layout} /> ) : (
Loading...
diff --git a/frontend-v2/src/features/simulation/SimulationsSidePanel.tsx b/frontend-v2/src/features/simulation/SimulationsSidePanel.tsx index af5b0d2e..3b765eaf 100644 --- a/frontend-v2/src/features/simulation/SimulationsSidePanel.tsx +++ b/frontend-v2/src/features/simulation/SimulationsSidePanel.tsx @@ -213,7 +213,6 @@ export const SimulationsSidePanel = ({ checked={layout === value} onChange={() => { setLayout(value); - window.dispatchEvent(new Event("resize")); }} /> } From 6e93ea9c23fcbe2c4002a7322522b00446cc4d28 Mon Sep 17 00:00:00 2001 From: Martin Robinson Date: Mon, 18 Nov 2024 11:36:21 +0000 Subject: [PATCH 2/6] feat: disable results page if no secondary parameters (#567) --- .gitignore | 2 ++ frontend-v2/src/features/main/Sidebar.tsx | 6 ++++ frontend-v2/src/features/results/utils.ts | 35 ++++++++++++----------- 3 files changed, 27 insertions(+), 16 deletions(-) diff --git a/.gitignore b/.gitignore index ee630317..77bf3019 100644 --- a/.gitignore +++ b/.gitignore @@ -21,3 +21,5 @@ pkpdapp/static frontend/node_modules logfile.log* + +.vscode \ No newline at end of file diff --git a/frontend-v2/src/features/main/Sidebar.tsx b/frontend-v2/src/features/main/Sidebar.tsx index 6408ebd4..b7260018 100644 --- a/frontend-v2/src/features/main/Sidebar.tsx +++ b/frontend-v2/src/features/main/Sidebar.tsx @@ -103,6 +103,9 @@ export default function Sidebar() { const doses = groups?.flatMap((group) => group.protocols.map((p) => p.doses)); const groupsAreIncomplete = doses?.some((dosing) => !dosing[0]?.amount); + const noSecondaryParameters = model ? + model.derived_variables.reduce((acc, dv) => { return acc && dv.type !== "AUC"; }, true) : + false; const warnings: { [key: string]: string } = {}; const errors: { [key: string]: string } = {}; @@ -181,6 +184,9 @@ export default function Sidebar() { if (page === PageName.TRIAL_DESIGN && PageName.MODEL in errors) { return true; } + if (page === PageName.RESULTS && noSecondaryParameters) { + return true; + } if (page === PageName.DATA && PageName.MODEL in errors) { return true; } diff --git a/frontend-v2/src/features/results/utils.ts b/frontend-v2/src/features/results/utils.ts index b88568b0..090efd46 100644 --- a/frontend-v2/src/features/results/utils.ts +++ b/frontend-v2/src/features/results/utils.ts @@ -34,23 +34,26 @@ export function valuesPerInterval( const times = simulation?.time || []; const values = variable && simulation ? simulation.outputs[variable.id] : []; return timeIntervals.map((interval) => { + if (values.length === 0) { + return []; + } const startIndex = times.findIndex((t) => t >= interval.start); const endIndex = times.findIndex((t) => t >= interval.end); const start = startIndex > 0 ? interpolate( - [times[startIndex - 1], times[startIndex]], - [values[startIndex - 1], values[startIndex]], - interval.start, - ) + [times[startIndex - 1], times[startIndex]], + [values[startIndex - 1], values[startIndex]], + interval.start, + ) : values[0]; const end = endIndex > -1 ? interpolate( - [times[endIndex - 1], times[endIndex]], - [values[endIndex - 1], values[endIndex]], - interval.end, - ) + [times[endIndex - 1], times[endIndex]], + [values[endIndex - 1], values[endIndex]], + interval.end, + ) : values[values.length - 1]; const intervalValues = [ start, @@ -106,20 +109,20 @@ export function thresholdCrossingPoints( const startTime = thresholdStart > 0 ? interpolate( - [intervalValues[thresholdStart - 1], intervalValues[thresholdStart]], - [intervalTimes[thresholdStart - 1], intervalTimes[thresholdStart]], - threshold, - ) + [intervalValues[thresholdStart - 1], intervalValues[thresholdStart]], + [intervalTimes[thresholdStart - 1], intervalTimes[thresholdStart]], + threshold, + ) : intervalTimes[0]; const endTime = thresholdStart === -1 // threshold never reached ? startTime : thresholdEnd > 0 ? interpolate( - [intervalValues[thresholdEnd - 1], intervalValues[thresholdEnd]], - [intervalTimes[thresholdEnd - 1], intervalTimes[thresholdEnd]], - threshold, - ) + [intervalValues[thresholdEnd - 1], intervalValues[thresholdEnd]], + [intervalTimes[thresholdEnd - 1], intervalTimes[thresholdEnd]], + threshold, + ) : intervalTimes[intervalTimes.length - 1]; // threshold reached beyond the end of the interval return [endTime - startTime, thresholdEnd]; } From 5514893a47177e0aa4fceddcac45bcb564dc1821 Mon Sep 17 00:00:00 2001 From: Martin Robinson Date: Wed, 20 Nov 2024 14:54:14 +0000 Subject: [PATCH 3/6] feat: remove simulation requests when adding new plots or sliders (#569) * feat: request all outputs from simulation except amounts * feat: prevent re-simulating when adding sliders --- .../simulation/SimulationSliderView.tsx | 28 ++++++----- .../src/features/simulation/Simulations.tsx | 10 ++-- .../simulation/useExportSimulation.ts | 6 +-- .../simulation/useSimulatedVariables.ts | 34 -------------- .../src/features/simulation/useSimulation.ts | 4 +- .../simulation/useSimulationInputs.ts | 46 ++++++++++++++----- 6 files changed, 59 insertions(+), 69 deletions(-) delete mode 100644 frontend-v2/src/features/simulation/useSimulatedVariables.ts diff --git a/frontend-v2/src/features/simulation/SimulationSliderView.tsx b/frontend-v2/src/features/simulation/SimulationSliderView.tsx index f793de3c..f371dab4 100644 --- a/frontend-v2/src/features/simulation/SimulationSliderView.tsx +++ b/frontend-v2/src/features/simulation/SimulationSliderView.tsx @@ -64,9 +64,13 @@ const SimulationSliderView: FC = ({ const [value, setValue] = useState(defaultValue); useEffect(() => { - setValue(defaultValue); - onChange(slider.variable, defaultValue); - }, [defaultValue, onChange, slider.variable]); + // don't set the value of the slider until the variable is loaded + if (variable) { + const defaultValue = variable.default_value || 1.0; + setValue(defaultValue); + onChange(slider.variable, defaultValue); + } + }, [onChange, variable]); const handleSliderChange = ( event: Event | SyntheticEvent, @@ -78,8 +82,10 @@ const SimulationSliderView: FC = ({ }; const handleReset = () => { - setValue(defaultValue); - onChange(slider.variable, defaultValue); + if (variable) { + setValue(defaultValue); + onChange(slider.variable, defaultValue); + } }; const handleSave = () => { @@ -145,9 +151,9 @@ const SimulationSliderView: FC = ({ - + - + @@ -156,18 +162,18 @@ const SimulationSliderView: FC = ({ aria-label="save" onClick={handleSave} disabled={isSharedWithMe} - sx={{ padding: '2px'}} + sx={{ padding: '2px' }} > - + - + @@ -176,7 +182,7 @@ const SimulationSliderView: FC = ({ aria-label="delete" onClick={handleDelete} disabled={isSharedWithMe} - sx={{ padding: '2px'}} + sx={{ padding: '2px' }} > diff --git a/frontend-v2/src/features/simulation/Simulations.tsx b/frontend-v2/src/features/simulation/Simulations.tsx index 28a5bb3b..2f97cee9 100644 --- a/frontend-v2/src/features/simulation/Simulations.tsx +++ b/frontend-v2/src/features/simulation/Simulations.tsx @@ -35,7 +35,6 @@ import { import SimulationPlotView from "./SimulationPlotView"; import useSimulation from "./useSimulation"; import useSimulationInputs from "./useSimulationInputs"; -import useSimulatedVariables from "./useSimulatedVariables"; import useDirty from "../../hooks/useDirty"; import paramPriority from "../model/paramPriority"; import { selectIsProjectShared } from "../login/loginSlice"; @@ -151,7 +150,9 @@ const Simulations: FC = () => { const [sliderValues, setSliderValues] = useState( undefined, ); + console.log('sliderValues', sliderValues); const handleChangeSlider = useCallback((variable: number, value: number) => { + console.log('handleChangeSlider', variable, value); setSliderValues((prevSliderValues) => ({ ...prevSliderValues, [variable]: value, @@ -196,12 +197,11 @@ const Simulations: FC = () => { variables, timeMax, ); - const simulatedVariables = useSimulatedVariables(variables, sliderValues); const { loadingSimulate, data, error: simulateError, - } = useSimulation(simInputs, simulatedVariables, model); + } = useSimulation(simInputs, model); const refSimInputs = useSimulationInputs( model, @@ -210,10 +210,8 @@ const Simulations: FC = () => { variables, timeMax, ); - const referenceVariables = useSimulatedVariables(variables, EMPTY_OBJECT); const { data: dataReference } = useSimulation( refSimInputs, - referenceVariables, showReference ? model : undefined ); @@ -256,6 +254,7 @@ const Simulations: FC = () => { // reset form and sliders if simulation changes useEffect(() => { if (simulation && variables) { + console.log('reset form and sliders if simulation changes'); setSliderValues((s) => { const initialValues = getSliderInitialValues(simulation, s, variables); return initialValues; @@ -268,7 +267,6 @@ const Simulations: FC = () => { const [exportSimulation, { error: exportSimulateErrorBase }] = useExportSimulation({ simInputs, - simulatedVariables, model, project, }); diff --git a/frontend-v2/src/features/simulation/useExportSimulation.ts b/frontend-v2/src/features/simulation/useExportSimulation.ts index 535091a6..658a8122 100644 --- a/frontend-v2/src/features/simulation/useExportSimulation.ts +++ b/frontend-v2/src/features/simulation/useExportSimulation.ts @@ -11,7 +11,6 @@ import { interface iExportSimulation { simInputs: Simulate; - simulatedVariables: { qname: string; value: number | undefined }[]; model: CombinedModelRead | undefined; project: ProjectRead | undefined; } @@ -41,7 +40,6 @@ const parseResponse = (data: any, timeCol: number, label: string) => { export default function useExportSimulation({ simInputs, - simulatedVariables, model, project, }: iExportSimulation): [() => void, { error: any }] { @@ -70,12 +68,12 @@ export default function useExportSimulation({ project && groups ) { - console.log("Export to CSV: simulating with params", simulatedVariables); + console.log("Export to CSV: simulating with params", simInputs.variables); simulate({ id: model.id, simulate: simInputs, }).then((response) => { - let rows = simulatedVariables.map((p) => [p.qname, p.value]); + let rows = Object.keys(simInputs.variables).map((key) => [key, simInputs.variables[key]]); if (response?.data) { const cols = Object.keys(response.data[0].outputs); const vars = cols.map((vid) => diff --git a/frontend-v2/src/features/simulation/useSimulatedVariables.ts b/frontend-v2/src/features/simulation/useSimulatedVariables.ts deleted file mode 100644 index 78b1cccf..00000000 --- a/frontend-v2/src/features/simulation/useSimulatedVariables.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { useMemo } from "react"; -import { VariableRead } from "../../app/backendApi"; - -type SliderValues = { [key: number]: number }; - -const DEFAULT_VARS: { qname: string; value: number | undefined }[] = []; - -const getVariablesSimulated = ( - variables?: VariableRead[], - sliderValues?: SliderValues, -) => { - const constantVariables = variables?.filter((v) => v.constant) || []; - const merged = constantVariables.map((v: VariableRead) => { - const result = { qname: v.qname, value: v.default_value }; - if (sliderValues && sliderValues[v.id]) { - result.value = sliderValues[v.id]; - } - return result; - }); - return merged; -}; - -export default function useSimulatedVariables( - variables: VariableRead[] | undefined, - sliderValues: SliderValues | undefined, -) { - return useMemo( - () => - variables && sliderValues - ? getVariablesSimulated(variables, sliderValues) - : DEFAULT_VARS, - [variables, sliderValues], - ); -} diff --git a/frontend-v2/src/features/simulation/useSimulation.ts b/frontend-v2/src/features/simulation/useSimulation.ts index df4fc7bc..dbc2e54e 100644 --- a/frontend-v2/src/features/simulation/useSimulation.ts +++ b/frontend-v2/src/features/simulation/useSimulation.ts @@ -19,7 +19,6 @@ const SIMULATION_PAGES = [PageName.SIMULATIONS, PageName.RESULTS]; export default function useSimulation( simInputs: Simulate, - simulatedVariables: { qname: string; value: number | undefined }[], model: CombinedModelRead | undefined, ) { const { compound, protocols } = useProtocols(); @@ -46,7 +45,7 @@ export default function useSimulation( SIMULATION_PAGES.includes(page) ) { setLoadingSimulate(true); - console.log("Simulating with params", simulatedVariables); + console.log("Simulating with params", simInputs.variables); simulate({ id: model.id, simulate: simInputs, @@ -70,7 +69,6 @@ export default function useSimulation( protocols, simulate, JSON.stringify(simInputs), - JSON.stringify(simulatedVariables), page, ]); diff --git a/frontend-v2/src/features/simulation/useSimulationInputs.ts b/frontend-v2/src/features/simulation/useSimulationInputs.ts index 4bd8f9a5..f36349c9 100644 --- a/frontend-v2/src/features/simulation/useSimulationInputs.ts +++ b/frontend-v2/src/features/simulation/useSimulationInputs.ts @@ -14,31 +14,55 @@ const DEFAULT_INPUTS = { time_max: 0, }; +enum simulationInputMode { + REQUESTED_OUTPUTS = "REQUESTED", + ALL_OUTPUTS = "ALL", + ALL_OUTPUTS_NO_AMOUNTS = "ALL_NO_AMOUNTS", +} + const getSimulateInput = ( model: CombinedModelRead, simulation: SimulationRead, sliderValues: SliderValues, variables?: VariableRead[], timeMax?: number, - allOutputs: boolean = false, + mode: simulationInputMode = simulationInputMode.REQUESTED_OUTPUTS, ): Simulate => { const outputs: string[] = []; + + const constantVariables = variables?.filter((v) => v.constant) || []; const simulateVariables: { [key: string]: number } = {}; - for (const slider of simulation?.sliders || []) { - if (sliderValues[slider.variable]) { - const variable = variables?.find((v) => v.id === slider.variable); - if (variable) { - simulateVariables[variable.qname] = sliderValues[slider.variable]; - } + constantVariables.forEach((v: VariableRead) => { + const result = { qname: v.qname, value: v.default_value || 0 }; + if (sliderValues && sliderValues[v.id]) { + result.value = sliderValues[v.id]; } - } - if (allOutputs) { + simulateVariables[result.qname] = result.value; + }); + + if (mode == simulationInputMode.ALL_OUTPUTS) { for (const v of variables || []) { if (!v.constant) { outputs.push(v.qname); } } - } else { + } else if (mode == simulationInputMode.ALL_OUTPUTS_NO_AMOUNTS) { + const amountNames = ["Aa", "A1", "A2", "A3"]; + for (const v of variables || []) { + let isAmount = model.is_library_model && amountNames.includes(v.name); + if (!v.constant && !isAmount) { + outputs.push(v.qname); + } + } + for (const plot of simulation?.plots || []) { + for (const y_axis of plot.y_axes) { + const variable = variables?.find((v) => v.id === y_axis.variable); + if (variable && !outputs.includes(variable.qname)) { + outputs.push(variable.qname); + } + } + } + } else if (mode == simulationInputMode.REQUESTED_OUTPUTS) { for (const plot of simulation?.plots || []) { for (const y_axis of plot.y_axes) { const variable = variables?.find((v) => v.id === y_axis.variable); @@ -91,7 +115,7 @@ export default function useSimulationInputs( return useMemo( () => model && simulation && sliderValues - ? getSimulateInput(model, simulation, sliderValues, variables, timeMax) + ? getSimulateInput(model, simulation, sliderValues, variables, timeMax, simulationInputMode.ALL_OUTPUTS_NO_AMOUNTS) : DEFAULT_INPUTS, [simulation, sliderValues, variables, timeMax], ); From 029bc704774b814a402c4aa315c60bea85f785d3 Mon Sep 17 00:00:00 2001 From: Jim O'Donnell Date: Wed, 20 Nov 2024 15:36:28 +0000 Subject: [PATCH 4/6] fix(frontend): TypeScript errors in Results (#570) --- frontend-v2/src/features/results/Results.tsx | 10 +++--- .../src/features/results/ResultsTab.tsx | 28 +++++++++++----- .../src/features/results/ResultsTable.tsx | 32 ++++++++++++------- 3 files changed, 45 insertions(+), 25 deletions(-) diff --git a/frontend-v2/src/features/results/Results.tsx b/frontend-v2/src/features/results/Results.tsx index c79d188b..49615b87 100644 --- a/frontend-v2/src/features/results/Results.tsx +++ b/frontend-v2/src/features/results/Results.tsx @@ -32,10 +32,8 @@ const Results: FC = () => { setTab(newValue); }; - const handleTabRemove = async (table) => { - if ( - window.confirm("Are you sure you want to delete the current Table?") - ) { + const handleTabRemove = async (table: Table) => { + if (window.confirm("Are you sure you want to delete the current Table?")) { const removedIndex = tables.map(({ id }) => id).indexOf(table.id); setTables(tables.filter(({ id }) => id !== table.id)); @@ -79,9 +77,9 @@ const Results: FC = () => { key={table.id} label={table.name} {...a11yProps(index)} - sx={{ maxHeight: '48px', minHeight: 0}} + sx={{ maxHeight: "48px", minHeight: 0 }} icon={ - index === 0 ? null : ( + index === 0 ? undefined : ( { e.stopPropagation(); diff --git a/frontend-v2/src/features/results/ResultsTab.tsx b/frontend-v2/src/features/results/ResultsTab.tsx index dfcf5963..76889d6f 100644 --- a/frontend-v2/src/features/results/ResultsTab.tsx +++ b/frontend-v2/src/features/results/ResultsTab.tsx @@ -31,6 +31,18 @@ export type RowData = | TimeInterval[] | VariableRead[]; +type Item = + | { name: string } + | Parameter + | (TimeInterval & { name: string }) + | VariableRead; +type RowFilter = { + filter: (event: SelectChangeEvent) => void; + value: number; + items: Item[]; + label: string; +}; + const ResultsTab: FC = () => { const { groups = [] } = useSubjectGroups(); const { intervals } = useContext(SimulationContext); @@ -102,8 +114,8 @@ const ResultsTab: FC = () => { setParameter(newValue); } - let rowFilter1; - let rowFilter2; + let rowFilter1: RowFilter | undefined; + let rowFilter2: RowFilter | undefined; const groupSelect = { filter: handleGroupChange, @@ -155,23 +167,23 @@ const ResultsTab: FC = () => {
All Secondary PK parameters of all selected {var1} of{" "} {rowFilter1?.label?.toLowerCase()} ' - {rowFilter1?.items?.[rowFilter1?.value.toString()]?.name}' and{" "} + {rowFilter1?.items?.[rowFilter1?.value]?.name}' and{" "} {rowFilter2?.label.toLowerCase()} ' - {rowFilter2?.items?.[rowFilter2?.value.toString()]?.name}' + {rowFilter2?.items?.[rowFilter2?.value]?.name}'
); } const var1 = rowFilter1?.label === "Parameter" - ? rowFilter1?.items?.[rowFilter1?.value.toString()]?.name - : rowFilter2?.items?.[rowFilter2?.value.toString()]?.name; + ? rowFilter1?.items?.[rowFilter1?.value]?.name + : rowFilter2?.items?.[rowFilter2?.value]?.name; const var2 = rowFilter1?.label === "Parameter" ? rowFilter2?.label : rowFilter1?.label; const var3 = rowFilter1?.label === "Parameter" - ? rowFilter2?.items?.[rowFilter2?.value.toString()]?.name - : rowFilter1?.items?.[rowFilter1?.value.toString()]?.name; + ? rowFilter2?.items?.[rowFilter2?.value]?.name + : rowFilter1?.items?.[rowFilter1?.value]?.name; const desc1 = () => { if (var2 === "Interval") return "and time interval"; diff --git a/frontend-v2/src/features/results/ResultsTable.tsx b/frontend-v2/src/features/results/ResultsTable.tsx index aa1f2d34..046d9573 100644 --- a/frontend-v2/src/features/results/ResultsTable.tsx +++ b/frontend-v2/src/features/results/ResultsTable.tsx @@ -20,31 +20,31 @@ import { getTableHeight } from "../../shared/calculateTableHeights"; const RESULTS_TABLE_HEIGHTS = [ { - minHeight: "1100", + minHeight: 1100, tableHeight: "70vh", }, { - minHeight: "1000", + minHeight: 1000, tableHeight: "65vh", }, { - minHeight: "900", + minHeight: 900, tableHeight: "60vh", }, { - minHeight: "800", + minHeight: 800, tableHeight: "58vh", }, { - minHeight: "700", + minHeight: 700, tableHeight: "53vh", }, { - minHeight: "600", + minHeight: 600, tableHeight: "40vh", }, { - minHeight: "500", + minHeight: 500, tableHeight: "40vh", }, ]; @@ -55,9 +55,11 @@ const IntervalRow: FC<{ }> = ({ header, values }) => { return ( - {header} + + {header} + {values.map((value, i) => ( - {value} + {value} ))} ); @@ -127,13 +129,21 @@ export const ResultsTable: FC = ({ : []; return ( - + {rowColumn} {columnHeadings.map((column, i) => ( - {column} + + {column} + ))} From bcb653d1380529c90aa913b5a543a03210c9a8f9 Mon Sep 17 00:00:00 2001 From: Jim O'Donnell Date: Wed, 20 Nov 2024 16:06:44 +0000 Subject: [PATCH 5/6] fix(frontend): fix TS errors in Simulations (#571) --- frontend-v2/src/components/DropdownButton.tsx | 5 ++- .../src/features/simulation/Simulations.tsx | 28 +++++-------- .../simulation/SimulationsSidePanel.tsx | 39 +++++++++++-------- 3 files changed, 36 insertions(+), 36 deletions(-) diff --git a/frontend-v2/src/components/DropdownButton.tsx b/frontend-v2/src/components/DropdownButton.tsx index 2967a10d..4684fae7 100644 --- a/frontend-v2/src/components/DropdownButton.tsx +++ b/frontend-v2/src/components/DropdownButton.tsx @@ -21,7 +21,8 @@ type Props = { disabled?: boolean; data_cy?: string; useIcon?: boolean; - sx?: SxProps + sx?: SxProps; + variant?: "text" | "outlined" | "contained"; }; const DropdownButton: FC = ({ @@ -32,7 +33,7 @@ const DropdownButton: FC = ({ disabled, useIcon, sx, - variant = 'contained' + variant = "contained", }) => { const [anchorEl, setAnchorEl] = useState(null); diff --git a/frontend-v2/src/features/simulation/Simulations.tsx b/frontend-v2/src/features/simulation/Simulations.tsx index 2f97cee9..f9a4bef0 100644 --- a/frontend-v2/src/features/simulation/Simulations.tsx +++ b/frontend-v2/src/features/simulation/Simulations.tsx @@ -1,9 +1,4 @@ -import { - Alert, - Grid, - Snackbar, - Box -} from "@mui/material"; +import { Alert, Grid, Snackbar, Box } from "@mui/material"; import { useSelector } from "react-redux"; import { RootState } from "../../app/store"; import { @@ -46,31 +41,31 @@ import { getTableHeight } from "../../shared/calculateTableHeights"; const PlotsWidthSteps = [ { - minHeight: "1100", + minHeight: 1100, tableHeight: "75vw", }, { - minHeight: "1000", + minHeight: 1000, tableHeight: "72vw", }, { - minHeight: "900", + minHeight: 900, tableHeight: "70vw", }, { - minHeight: "800", + minHeight: 800, tableHeight: "65vw", }, { - minHeight: "700", + minHeight: 700, tableHeight: "60vw", }, { - minHeight: "600", + minHeight: 600, tableHeight: "55vw", }, { - minHeight: "500", + minHeight: 500, tableHeight: "53vw", }, ]; @@ -150,9 +145,7 @@ const Simulations: FC = () => { const [sliderValues, setSliderValues] = useState( undefined, ); - console.log('sliderValues', sliderValues); const handleChangeSlider = useCallback((variable: number, value: number) => { - console.log('handleChangeSlider', variable, value); setSliderValues((prevSliderValues) => ({ ...prevSliderValues, [variable]: value, @@ -212,7 +205,7 @@ const Simulations: FC = () => { ); const { data: dataReference } = useSimulation( refSimInputs, - showReference ? model : undefined + showReference ? model : undefined, ); const { @@ -254,7 +247,6 @@ const Simulations: FC = () => { // reset form and sliders if simulation changes useEffect(() => { if (simulation && variables) { - console.log('reset form and sliders if simulation changes'); setSliderValues((s) => { const initialValues = getSliderInitialValues(simulation, s, variables); return initialValues; @@ -370,7 +362,7 @@ const Simulations: FC = () => { }; const orderedSliders = sliders.map((slider, i) => { - const variable = variables.find((v) => v.id === slider.variable); + const variable = variables?.find((v) => v.id === slider.variable); return { ...slider, priority: variable ? paramPriority(variable) : 0, diff --git a/frontend-v2/src/features/simulation/SimulationsSidePanel.tsx b/frontend-v2/src/features/simulation/SimulationsSidePanel.tsx index 3b765eaf..622d484b 100644 --- a/frontend-v2/src/features/simulation/SimulationsSidePanel.tsx +++ b/frontend-v2/src/features/simulation/SimulationsSidePanel.tsx @@ -19,8 +19,15 @@ import HelpButton from "../../components/HelpButton"; import { ExpandLess, ExpandMore } from "@mui/icons-material"; import { ChangeEvent, useState } from "react"; import { getTableHeight } from "../../shared/calculateTableHeights"; -import { Simulation, SimulationPlot, SimulationRead, SimulationSlider, SubjectGroupRead, UnitRead } from "../../app/backendApi"; -import { UseFormReset } from "react-hook-form"; +import { + Simulation, + SimulationPlot, + SimulationRead, + SimulationSlider, + SubjectGroupRead, + UnitRead, +} from "../../app/backendApi"; +import { Control } from "react-hook-form"; type SimulationsSidePanelType = { portalId: string; @@ -30,11 +37,11 @@ type SimulationsSidePanelType = { }[]; handleAddPlot: (plot: number) => void; isSharedWithMe: boolean; - layoutOptions: { value: string, label: string }[]; + layoutOptions: { value: string; label: string }[]; layout: string; setLayout: (layout: string) => void; plots: SimulationPlot[]; - control: UseFormReset; + control: Control; units: UnitRead[]; simulation: SimulationRead; groups?: SubjectGroupRead[]; @@ -45,15 +52,15 @@ type SimulationsSidePanelType = { label: string; }[]; handleAddSlider: (slider: number) => void; - orderedSliders: SimulationSlider[]; + orderedSliders: (SimulationSlider & { fieldArrayIndex: number })[]; handleChangeSlider: (variable: number, value: number) => void; - handleRemoveSlider: (index: number) => void; - handleSaveSlider: (slider: SimulationSlider) => void; + handleRemoveSlider: (index: number) => () => void; + handleSaveSlider: (slider: SimulationSlider) => (value: number) => void; exportSimulation: () => void; showReference: boolean; setShowReference: (reference: boolean) => void; shouldShowLegend: boolean; - setShouldShowLegend: (value: boolean) => void + setShouldShowLegend: (value: boolean) => void; }; const ButtonSx = { @@ -73,31 +80,31 @@ const ButtonSx = { const SidePanelSteps = [ { - minHeight: "1100", + minHeight: 1100, tableHeight: "75vh", }, { - minHeight: "1000", + minHeight: 1000, tableHeight: "72vh", }, { - minHeight: "900", + minHeight: 900, tableHeight: "70vh", }, { - minHeight: "800", + minHeight: 800, tableHeight: "65vh", }, { - minHeight: "700", + minHeight: 700, tableHeight: "60vh", }, { - minHeight: "600", + minHeight: 600, tableHeight: "55vh", }, { - minHeight: "500", + minHeight: 500, tableHeight: "53vh", }, ]; @@ -127,7 +134,7 @@ export const SimulationsSidePanel = ({ showReference, setShowReference, shouldShowLegend, - setShouldShowLegend + setShouldShowLegend, }: SimulationsSidePanelType) => { const portalRoot = document.getElementById(portalId); const [collapseLayout, setCollapseLayout] = useState(true); From 04ca571532129ba4bf91c8f634dd7ee9a4d2f139 Mon Sep 17 00:00:00 2001 From: Jim O'Donnell Date: Wed, 20 Nov 2024 16:20:17 +0000 Subject: [PATCH 6/6] fix(frontend): fix TS errors in parameter thresholds (#572) --- frontend-v2/src/features/model/VariableRow.tsx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/frontend-v2/src/features/model/VariableRow.tsx b/frontend-v2/src/features/model/VariableRow.tsx index 8b441889..cc59e0e6 100644 --- a/frontend-v2/src/features/model/VariableRow.tsx +++ b/frontend-v2/src/features/model/VariableRow.tsx @@ -250,7 +250,10 @@ const VariableRow: FC = ({ if (type === "AUC") { setThresholds({ ...thresholds, - [variable.name]: 0, + [variable.name]: { + lower: 0, + upper: Infinity, + }, }); } };