Skip to content

Commit

Permalink
Merge branch 'ui-enhancements' into PKPDX-34
Browse files Browse the repository at this point in the history
  • Loading branch information
eatyourgreens authored Dec 2, 2024
2 parents 35a09e6 + 647a1d5 commit 18209ee
Show file tree
Hide file tree
Showing 8 changed files with 456 additions and 186 deletions.
423 changes: 303 additions & 120 deletions frontend-v2/src/features/drug/Drug.tsx

Large diffs are not rendered by default.

71 changes: 44 additions & 27 deletions frontend-v2/src/features/projects/Project.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,11 @@ import {
useProjectAccessDestroyMutation,
} from "../../app/backendApi";
import UserAccess from "./UserAccess";
import { decrementDirtyCount, incrementDirtyCount, setProject } from "../main/mainSlice";
import {
decrementDirtyCount,
incrementDirtyCount,
setProject,
} from "../main/mainSlice";
import TextField from "../../components/TextField";
import ConfirmationDialog from "../../components/ConfirmationDialog";
import { selectCurrentUser, selectIsProjectShared } from "../login/loginSlice";
Expand Down Expand Up @@ -116,6 +120,8 @@ const ProjectRow: FC<Props> = ({
reset,
handleSubmit,
control,
setValue,
register,
formState: { isDirty },
} = useForm<FormData>({
defaultValues: { project, compound: defaultCompound },
Expand Down Expand Up @@ -149,27 +155,32 @@ const ProjectRow: FC<Props> = ({
handleSubmit((data: FormData) => {
if (compound && project) {
if (JSON.stringify(compound) !== JSON.stringify(data.compound)) {
dispatch(incrementDirtyCount())
updateCompound({ id: compound.id, compound: data.compound }).then(() => dispatch(decrementDirtyCount()));;
dispatch(incrementDirtyCount());
updateCompound({ id: compound.id, compound: data.compound }).then(
() => dispatch(decrementDirtyCount()),
);
}
if (JSON.stringify(project) !== JSON.stringify(data.project)) {
dispatch(incrementDirtyCount())
updateProject({ id: project.id, project: data.project }).then(() => dispatch(decrementDirtyCount()));
dispatch(incrementDirtyCount());
updateProject({ id: project.id, project: data.project }).then(() =>
dispatch(decrementDirtyCount()),
);
}
}
}),
[handleSubmit, compound, project, updateCompound, updateProject],
);

const [fieldValue, setFieldValue] = useFieldState({
name: "project.description",
control,
});

const onCancel = () => {
setFieldValue(project.description);
setValue("project.description", project.description);
};

const onShareCanel = () => {
setValue("project.user_access", project.user_access);
setUserAccessOpen(false);
setIsEditMode(false);
}

if (isLoading) {
return <div>Loading...</div>;
}
Expand Down Expand Up @@ -249,6 +260,7 @@ const ProjectRow: FC<Props> = ({
checked={isSelected}
onClick={handleSelectProject}
size="small"
id={`project-${project.id}`}
/>
</TableCell>
<TableCell>
Expand All @@ -257,12 +269,14 @@ const ProjectRow: FC<Props> = ({
name="project.name"
control={control}
textFieldProps={defaultProps}
size='small'
size="small"
rules={{ required: true, validate: validateName }}
sx={{ ...defaultSx }}
/>
) : (
<Typography>{project?.name}</Typography>
<label htmlFor={`project-${project.id}`}>
<Typography>{project?.name}</Typography>
</label>
)}
</TableCell>
<TableCell>
Expand All @@ -271,7 +285,7 @@ const ProjectRow: FC<Props> = ({
name="compound.name"
control={control}
textFieldProps={defaultProps}
size='small'
size="small"
rules={{ required: true }}
sx={defaultSx}
/>
Expand Down Expand Up @@ -332,7 +346,10 @@ const ProjectRow: FC<Props> = ({

<Tooltip title="Share Project">
<IconButton
onClick={() => setUserAccessOpen(true)}
onClick={() => {
setIsEditMode(true);
setUserAccessOpen(true);
}}
disabled={isSharedWithMe}
>
<PersonAdd />
Expand All @@ -343,15 +360,6 @@ const ProjectRow: FC<Props> = ({
<Delete />
</IconButton>
</Tooltip>
<UserAccess
open={userAccessOpen}
onClose={userAccessClose}
control={control}
userAccess={userAccess as ProjectAccess[]}
append={append}
remove={remove}
project={project}
/>
{isSharedWithMe && (
<Tooltip title="This project is shared with me as view-only">
<div>
Expand Down Expand Up @@ -393,6 +401,16 @@ const ProjectRow: FC<Props> = ({
)}
</TableCell>
</TableRow>
<UserAccess
open={userAccessOpen}
onClose={userAccessClose}
onCancel={onShareCanel}
control={control}
userAccess={userAccess as ProjectAccess[]}
append={append}
remove={remove}
project={project}
/>
{isDescriptionModalOpen && (
<DescriptionModal
isOpen={isDescriptionModalOpen}
Expand All @@ -403,8 +421,7 @@ const ProjectRow: FC<Props> = ({
project={project}
>
<MaterialTextField
onChange={(event) => setFieldValue(event.target.value)}
value={fieldValue}
{...register("project.description")}
sx={{ width: "50vw" }}
disabled={!isEditMode}
multiline
Expand All @@ -416,4 +433,4 @@ const ProjectRow: FC<Props> = ({
);
};

export default ProjectRow;
export default ProjectRow;
10 changes: 9 additions & 1 deletion frontend-v2/src/features/projects/UserAccess.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ interface Props {
userAccess: ProjectAccess[];
append: (value: ProjectAccess) => void;
remove: (index: number) => void;
onCancel: () => void;
control: Control<FormData>;
onClose: () => void;
}
Expand All @@ -41,7 +42,7 @@ const UserAccess: FC<Props> = ({
userAccess,
append,
remove,
control,
onCancel,
onClose,
}) => {
const { data: users } = useUserListQuery();
Expand Down Expand Up @@ -122,6 +123,13 @@ const UserAccess: FC<Props> = ({
margin: ".5rem",
}}
>
<Button
variant="outlined"
sx={{ marginLeft: "1rem" }}
onClick={onCancel}
>
Cancel
</Button>
<Button
variant="contained"
sx={{ marginLeft: "1rem" }}
Expand Down
3 changes: 1 addition & 2 deletions frontend-v2/src/features/results/columns.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,7 @@ export function columns({
return parameters.map((parameter) => {
return {
header: parameter.name,
value: (interval: TimeIntervalRead) =>
parameter.value(interval, simulation, variable, aucVariable),
value: parameter.value,
};
});
}
Expand Down
105 changes: 76 additions & 29 deletions frontend-v2/src/features/results/useParameters.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {
SimulateResponse,
TimeIntervalRead,
UnitListApiResponse,
VariableListApiResponse,
VariableRead,
} from "../../app/backendApi";
Expand Down Expand Up @@ -77,7 +78,7 @@ const variablePerInterval = (
variable,
simulation,
);
const intervalIndex = intervals.findIndex((i) => i.id === interval.id);
const intervalIndex = intervals.findIndex((i) => i.id === interval?.id);
const intervalValues = variableValuesPerInterval[intervalIndex];
const timePerInterval = timesPerInterval(simulation.time, intervals);
const intervalTimes = timePerInterval[intervalIndex];
Expand All @@ -93,6 +94,18 @@ const timeOverLowerThresholdPerInterval = (
return timeOverThreshold(intervalTimes, intervalValues, threshold);
};

function variableConversionFactor(
variable: VariableRead,
units: UnitListApiResponse,
) {
const modelUnit = units?.find((unit) => unit.id === variable.unit);
const displayUnit = modelUnit?.compatible_units.find(
(u) => +u.id === variable.threshold_unit,
);
const conversionFactor = parseFloat(displayUnit?.conversion_factor || "1");
return conversionFactor;
}

const timeOverUpperThresholdPerInterval = (
intervalValues: number[],
intervalTimes: number[],
Expand All @@ -102,6 +115,18 @@ const timeOverUpperThresholdPerInterval = (
return timeOverThreshold(intervalTimes, intervalValues, threshold);
};

function timeConversionFactor(
interval: TimeIntervalRead,
units: UnitListApiResponse,
) {
const modelUnit = units?.find((unit) => unit.symbol === "h");
const displayUnit = modelUnit?.compatible_units.find(
(u) => +u.id === interval.unit,
);
const conversionFactor = parseFloat(displayUnit?.conversion_factor || "1");
return conversionFactor;
}

/**
* Generate a list of secondary parameters to calculate for the current model.
* Each parameter consists of a name and a function to calculate the formatted value of the parameter
Expand All @@ -125,27 +150,45 @@ export function useParameters() {
const intervals = useNormalisedIntervals(baseIntervals);
const variables = useNormalisedVariables(baseVariables);

function variableConversionFactor(variable: VariableRead) {
const displayUnit = units?.find(
(unit) => unit.id === variable.threshold_unit,
);
const modelUnit = displayUnit?.compatible_units.find(
(u) => +u.id === variable.unit,
);
const conversionFactor = parseFloat(modelUnit?.conversion_factor || "1");
return conversionFactor;
}

function timeConversionFactor(interval: TimeIntervalRead) {
const displayUnit = units?.find((unit) => unit.id === interval.unit);
const modelUnit = displayUnit?.compatible_units.find(
(u) => u.symbol === "h",
);
const conversionFactor = parseFloat(modelUnit?.conversion_factor || "1");
return conversionFactor;
}

return [
{
name: "Start",
value(
interval: TimeIntervalRead,
simulation: SimulateResponse,
variable: VariableRead,
) {
const [intervalValues] = variablePerInterval(
intervals,
variable,
simulation,
interval,
);
const start = intervalValues ? intervalValues[0] : 0;
return formattedNumber(
start * variableConversionFactor(variable, units),
);
},
},
{
name: "End",
value(
interval: TimeIntervalRead,
simulation: SimulateResponse,
variable: VariableRead,
) {
const [intervalValues] = variablePerInterval(
intervals,
variable,
simulation,
interval,
);
const end = intervalValues
? intervalValues[intervalValues.length - 1]
: 0;
return formattedNumber(end * variableConversionFactor(variable, units));
},
},
{
name: "Min",
value(
Expand All @@ -161,7 +204,7 @@ export function useParameters() {
);

const min = intervalValues ? Math.min(...intervalValues) : 0;
return formattedNumber(min / variableConversionFactor(variable));
return formattedNumber(min * variableConversionFactor(variable, units));
},
},
{
Expand All @@ -178,7 +221,7 @@ export function useParameters() {
interval,
);
const max = intervalValues ? Math.max(...intervalValues) : 0;
return formattedNumber(max / variableConversionFactor(variable));
return formattedNumber(max * variableConversionFactor(variable, units));
},
},
{
Expand All @@ -196,9 +239,9 @@ export function useParameters() {
: [];
const difference = auc ? auc[auc.length - 1] - auc[0] : 0;
return formattedNumber(
difference /
(variableConversionFactor(variable) *
timeConversionFactor(interval)),
difference *
variableConversionFactor(variable, units) *
timeConversionFactor(interval, units),
);
},
},
Expand Down Expand Up @@ -228,7 +271,9 @@ export function useParameters() {
variable,
)
: 0;
return formattedNumber(tLower / timeConversionFactor(interval));
return formattedNumber(
tLower * timeConversionFactor(interval, units),
);
}
},
},
Expand Down Expand Up @@ -258,7 +303,9 @@ export function useParameters() {
variable,
)
: 0;
return formattedNumber(tUpper / timeConversionFactor(interval));
return formattedNumber(
tUpper * timeConversionFactor(interval, units),
);
}
},
},
Expand Down Expand Up @@ -296,7 +343,7 @@ export function useParameters() {
)
: 0;
return formattedNumber(
(tLower - tUpper) / timeConversionFactor(interval),
(tLower - tUpper) * timeConversionFactor(interval, units),
);
}
},
Expand Down
Loading

0 comments on commit 18209ee

Please sign in to comment.