Skip to content

Commit

Permalink
Resolved conflicts, fixed simulations animation bug
Browse files Browse the repository at this point in the history
  • Loading branch information
wniestroj committed Nov 20, 2024
2 parents 7be26bf + 4c330b4 commit 8e0e05c
Show file tree
Hide file tree
Showing 16 changed files with 218 additions and 170 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,5 @@ pkpdapp/static
frontend/node_modules

logfile.log*

.vscode
5 changes: 3 additions & 2 deletions frontend-v2/src/components/DropdownButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ type Props = {
disabled?: boolean;
data_cy?: string;
useIcon?: boolean;
sx?: SxProps
sx?: SxProps;
variant?: "text" | "outlined" | "contained";
};

const DropdownButton: FC<Props> = ({
Expand All @@ -32,7 +33,7 @@ const DropdownButton: FC<Props> = ({
disabled,
useIcon,
sx,
variant = 'contained'
variant = "contained",
}) => {
const [anchorEl, setAnchorEl] = useState<HTMLButtonElement | null>(null);

Expand Down
12 changes: 10 additions & 2 deletions frontend-v2/src/features/main/Sidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,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 } = {};
Expand Down Expand Up @@ -151,7 +154,7 @@ export default function Sidebar() {
setMobileOpen(!mobileOpen);
};

const { onCollapse, onExpand, isExpanded, animationClasses } = useCollapsibleSidebar();
const { onCollapse, onExpand, setHasSimulationsExpandedChanged, isExpanded, animationClasses } = useCollapsibleSidebar();

const pageKeys = Object.keys(PageName);
const pageValues = Object.values(PageName);
Expand All @@ -165,6 +168,9 @@ export default function Sidebar() {

const handlePageClick = (key: string) => () => {
const chosenPage = PageName[key as keyof typeof PageName];
if (key !== PageName.SIMULATIONS) {
setHasSimulationsExpandedChanged(false);
}
dispatch(setPage(chosenPage));

switch (chosenPage) {
Expand All @@ -188,6 +194,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;
}
Expand Down Expand Up @@ -294,7 +303,6 @@ export default function Sidebar() {
<ArrowForwardIcon />
</IconButton>
)}

<List>
<ListItem key={projectsPage?.key} disablePadding>
<ListItemButton
Expand Down
5 changes: 4 additions & 1 deletion frontend-v2/src/features/model/VariableRow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,10 @@ const VariableRow: FC<Props> = ({
if (type === "AUC") {
setThresholds({
...thresholds,
[variable.name]: 0,
[variable.name]: {
lower: 0,
upper: Infinity,
},
});
}
};
Expand Down
10 changes: 4 additions & 6 deletions frontend-v2/src/features/results/Results.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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));

Expand Down Expand Up @@ -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 : (
<IconButton
onClick={(e) => {
e.stopPropagation();
Expand Down
28 changes: 20 additions & 8 deletions frontend-v2/src/features/results/ResultsTab.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -155,23 +167,23 @@ const ResultsTab: FC = () => {
<div>
All Secondary PK parameters of all selected {var1} of{" "}
{rowFilter1?.label?.toLowerCase()} &apos;
{rowFilter1?.items?.[rowFilter1?.value.toString()]?.name}&apos; and{" "}
{rowFilter1?.items?.[rowFilter1?.value]?.name}&apos; and{" "}
{rowFilter2?.label.toLowerCase()} &apos;
{rowFilter2?.items?.[rowFilter2?.value.toString()]?.name}&apos;
{rowFilter2?.items?.[rowFilter2?.value]?.name}&apos;
</div>
);
}

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";
Expand Down
32 changes: 21 additions & 11 deletions frontend-v2/src/features/results/ResultsTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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",
},
];
Expand All @@ -55,9 +55,11 @@ const IntervalRow: FC<{
}> = ({ header, values }) => {
return (
<TableRow>
<TableCell sx={{ textWrap: 'nowrap'}} scope="row">{header}</TableCell>
<TableCell sx={{ textWrap: "nowrap" }} scope="row">
{header}
</TableCell>
{values.map((value, i) => (
<TableCell key={i}>{value}</TableCell>
<TableCell key={i}>{value}</TableCell>
))}
</TableRow>
);
Expand Down Expand Up @@ -127,13 +129,21 @@ export const ResultsTable: FC<ResultsTableProps> = ({
: [];

return (
<TableContainer sx={{ width: 'fit-content', maxWidth: '100%', maxHeight: getTableHeight({ steps: RESULTS_TABLE_HEIGHTS })}}>
<TableContainer
sx={{
width: "fit-content",
maxWidth: "100%",
maxHeight: getTableHeight({ steps: RESULTS_TABLE_HEIGHTS }),
}}
>
<Table stickyHeader size="small">
<TableHead>
<TableRow>
<TableCell>{rowColumn}</TableCell>
{columnHeadings.map((column, i) => (
<TableCell sx={{ textWrap: 'nowrap' }} key={i}>{column}</TableCell>
<TableCell sx={{ textWrap: "nowrap" }} key={i}>
{column}
</TableCell>
))}
</TableRow>
</TableHead>
Expand Down
35 changes: 19 additions & 16 deletions frontend-v2/src/features/results/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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];
}
Expand Down
28 changes: 17 additions & 11 deletions frontend-v2/src/features/simulation/SimulationSliderView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,13 @@ const SimulationSliderView: FC<SimulationSliderProps> = ({
const [value, setValue] = useState<number>(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<Element, Event>,
Expand All @@ -78,8 +82,10 @@ const SimulationSliderView: FC<SimulationSliderProps> = ({
};

const handleReset = () => {
setValue(defaultValue);
onChange(slider.variable, defaultValue);
if (variable) {
setValue(defaultValue);
onChange(slider.variable, defaultValue);
}
};

const handleSave = () => {
Expand Down Expand Up @@ -145,9 +151,9 @@ const SimulationSliderView: FC<SimulationSliderProps> = ({
</Typography>
</Tooltip>
</Stack>
<Box sx={{ display: 'flex', justifyContent: 'flex-end'}}>
<Box sx={{ display: 'flex', justifyContent: 'flex-end' }}>
<Tooltip title={"Reset to saved default value"} placement="top">
<IconButton aria-label="reset" onClick={handleReset} sx={{ padding: '2px'}}>
<IconButton aria-label="reset" onClick={handleReset} sx={{ padding: '2px' }}>
<Replay fontSize="small" />
</IconButton>
</Tooltip>
Expand All @@ -156,18 +162,18 @@ const SimulationSliderView: FC<SimulationSliderProps> = ({
aria-label="save"
onClick={handleSave}
disabled={isSharedWithMe}
sx={{ padding: '2px'}}
sx={{ padding: '2px' }}
>
<Save fontSize="small" />
</IconButton>
</Tooltip>
<Tooltip title={"Widen range"} placement="top">
<IconButton aria-label="widen" onClick={handleWider} sx={{ padding: '2px'}}>
<IconButton aria-label="widen" onClick={handleWider} sx={{ padding: '2px' }}>
<OpenInFull fontSize="small" />
</IconButton>
</Tooltip>
<Tooltip title={"Narrow range"} placement="top">
<IconButton aria-label="restrict" onClick={handleNarrow} sx={{ padding: '2px'}}>
<IconButton aria-label="restrict" onClick={handleNarrow} sx={{ padding: '2px' }}>
<CloseFullscreen fontSize="small" />
</IconButton>
</Tooltip>
Expand All @@ -176,7 +182,7 @@ const SimulationSliderView: FC<SimulationSliderProps> = ({
aria-label="delete"
onClick={handleDelete}
disabled={isSharedWithMe}
sx={{ padding: '2px'}}
sx={{ padding: '2px' }}
>
<Delete fontSize="small" />
</IconButton>
Expand Down
Loading

0 comments on commit 8e0e05c

Please sign in to comment.