From 0f6fc610b2cfdbf97a8f74a8963ae6e7742343e1 Mon Sep 17 00:00:00 2001 From: Jim O'Donnell Date: Mon, 20 Jan 2025 15:12:07 +0000 Subject: [PATCH] style(frontend): fix ESLint warnings --- frontend-v2/src/components/DynamicTabs.tsx | 10 ++++-- frontend-v2/src/components/FloatField.tsx | 2 +- frontend-v2/src/components/HelpButton.tsx | 2 +- frontend-v2/src/components/IntegerField.tsx | 12 +++---- frontend-v2/src/components/SelectField.tsx | 7 ++-- frontend-v2/src/components/TextField.tsx | 6 ++-- frontend-v2/src/contexts/SimulationContext.ts | 2 +- .../features/data/CreateDosingProtocols.tsx | 27 --------------- frontend-v2/src/features/data/LoadData.tsx | 14 +------- .../src/features/data/LoadDataStepper.tsx | 15 ++++---- frontend-v2/src/features/data/MapDosing.tsx | 7 ++-- frontend-v2/src/features/data/MapHeaders.tsx | 3 +- .../src/features/data/MapObservations.tsx | 7 ++-- frontend-v2/src/features/data/PreviewData.tsx | 2 +- frontend-v2/src/features/data/SetUnits.tsx | 1 - .../src/features/data/Stratification.tsx | 7 ++-- frontend-v2/src/features/login/loginSlice.ts | 8 ++--- .../src/features/model/ParametersTab.tsx | 9 +---- .../src/features/model/VariableRow.tsx | 12 ++----- .../features/model/resetToSpeciesDefaults.ts | 2 +- frontend-v2/src/features/projects/Project.tsx | 34 ++++++++++--------- frontend-v2/src/features/results/columns.tsx | 1 - frontend-v2/src/features/simulation/config.ts | 6 ++-- .../simulation/useExportSimulation.ts | 2 +- frontend-v2/src/hooks/useCustomToast.tsx | 1 - frontend-v2/src/hooks/usePagination.tsx | 6 ++-- frontend-v2/src/hooks/usePrevious.ts | 2 +- .../contexts/CollapsibleSidebarContext.tsx | 4 +-- .../contexts/ProjectDescriptionContext.tsx | 12 +++---- 29 files changed, 92 insertions(+), 131 deletions(-) diff --git a/frontend-v2/src/components/DynamicTabs.tsx b/frontend-v2/src/components/DynamicTabs.tsx index c8319b830..6fc230e63 100644 --- a/frontend-v2/src/components/DynamicTabs.tsx +++ b/frontend-v2/src/components/DynamicTabs.tsx @@ -66,7 +66,7 @@ export const DynamicTabs: FC> = ({ const toast = useCustomToast(); const dispatch = useDispatch(); - const errors: { [key: string]: ReactElement } = {}; + const errors: { [key: string]: ReactElement } = {}; for (const key in tabErrors) { errors[key] = ( @@ -115,7 +115,13 @@ export const DynamicTabs: FC> = ({ return ( - + = { sx?: Record; }; -function convert(value: any) { +function convert(value: string): number | null { if (typeof value === "string") { if (value !== "") { return parseFloat(value); diff --git a/frontend-v2/src/components/HelpButton.tsx b/frontend-v2/src/components/HelpButton.tsx index 125ce726e..868287212 100644 --- a/frontend-v2/src/components/HelpButton.tsx +++ b/frontend-v2/src/components/HelpButton.tsx @@ -10,7 +10,7 @@ interface HelpButtonProps { children: ReactNode; } -const HelpButton: FC = ({ title, children }) => { +const HelpButton: FC = ({ children }) => { const [open, setOpen] = useState(false); const selectedPage = useSelector( (state: RootState) => state.main.selectedPage, diff --git a/frontend-v2/src/components/IntegerField.tsx b/frontend-v2/src/components/IntegerField.tsx index cded84702..89a51e25c 100644 --- a/frontend-v2/src/components/IntegerField.tsx +++ b/frontend-v2/src/components/IntegerField.tsx @@ -7,12 +7,12 @@ type Props = { label?: string; name: FieldPath; control: Control; - size?: 'small' | 'medium', - rules?: Object; + size?: "small" | "medium"; + rules?: Record; textFieldProps?: TextFieldProps; }; -function convert(value: any) { +function convert(value: string): number | string { if (typeof value === "string" && value !== "") { return parseInt(value); } else { @@ -25,7 +25,7 @@ function IntegerField({ name, control, rules, - size = 'medium', + size = "medium", textFieldProps, }: Props): ReactElement { const [fieldValue, setFieldValue] = useFieldState({ name, control }); @@ -36,12 +36,12 @@ function IntegerField({ rules={rules} render={({ field: { onChange, onBlur, value }, - fieldState: { error, isDirty, isTouched }, + fieldState: { error }, }) => { const handleBlur = (e: FocusEvent) => { const updatedValue = convert(e.target.value); if (updatedValue !== value) { - e.target.value = updatedValue; + e.target.value = updatedValue.toString(); onChange(e); } onBlur(); diff --git a/frontend-v2/src/components/SelectField.tsx b/frontend-v2/src/components/SelectField.tsx index aab56d602..8606a0b05 100644 --- a/frontend-v2/src/components/SelectField.tsx +++ b/frontend-v2/src/components/SelectField.tsx @@ -13,7 +13,7 @@ import { import { getLabel } from "../shared/getRequiredLabel"; type Option = { - value: any; + value: string; label: string; }; @@ -25,7 +25,7 @@ type Props = { rules?: Record; selectProps?: SelectProps; formControlProps?: FormControlProps; - size?: 'small' | 'medium' + size?: "small" | "medium"; sx?: SxProps; }; @@ -37,7 +37,7 @@ function SelectField({ rules, selectProps, formControlProps, - size = 'medium', + size = "medium", sx, }: Props): ReactElement { const labelId = `${name}-label`; @@ -69,7 +69,6 @@ function SelectField({ name={name} id={name} value={value === undefined || value === null ? "" : value} - // @ts-ignore onChange={onChange} onBlur={onBlur} input={} diff --git a/frontend-v2/src/components/TextField.tsx b/frontend-v2/src/components/TextField.tsx index 13575b748..a01c84e12 100644 --- a/frontend-v2/src/components/TextField.tsx +++ b/frontend-v2/src/components/TextField.tsx @@ -16,7 +16,7 @@ type Props = { mode?: "onChange" | "onBlur"; textFieldProps?: TextFieldProps; autoShrink?: boolean; - size?: 'small' | 'medium' + size?: "small" | "medium"; sx?: SxProps; }; @@ -26,7 +26,7 @@ function TextField({ control, rules, mode, - size = 'medium', + size = "medium", textFieldProps, autoShrink, sx, @@ -44,7 +44,7 @@ function TextField({ rules={rules} render={({ field: { onChange, onBlur, value }, - fieldState: { error, isDirty, isTouched }, + fieldState: { error }, }) => { const handleBlur = (e: FocusEvent) => { if (mode === "onBlur" && e.target.value !== value) { diff --git a/frontend-v2/src/contexts/SimulationContext.ts b/frontend-v2/src/contexts/SimulationContext.ts index b889322e4..2affca110 100644 --- a/frontend-v2/src/contexts/SimulationContext.ts +++ b/frontend-v2/src/contexts/SimulationContext.ts @@ -3,5 +3,5 @@ import { SimulateResponse } from "../app/backendApi"; export const SimulationContext = createContext({ simulations: [] as SimulateResponse[], - setSimulations: (simulations: SimulateResponse[]) => {}, + setSimulations: (_simulations: SimulateResponse[]) => {}, }); diff --git a/frontend-v2/src/features/data/CreateDosingProtocols.tsx b/frontend-v2/src/features/data/CreateDosingProtocols.tsx index c4dfcb673..a4cab0f9f 100644 --- a/frontend-v2/src/features/data/CreateDosingProtocols.tsx +++ b/frontend-v2/src/features/data/CreateDosingProtocols.tsx @@ -222,34 +222,7 @@ const CreateDosingProtocols: FC = ({ administrationIdField, groupIdField, ); - const administrationIds = dosingRows.map((row) => row[administrationIdField]); - const uniqueAdministrationIds = [...new Set(administrationIds)]; - const isAmount = (variable: VariableRead) => { - const amountUnits = units?.find( - (unit) => unit.symbol === amountUnit?.symbol, - )?.compatible_units; - const variableUnit = units?.find((unit) => unit.id === variable.unit); - return ( - variableUnit?.symbol !== "" && - amountUnits?.find((unit) => parseInt(unit.id) === variable.unit) !== - undefined - ); - }; - const modelAmounts = variables?.filter(isAmount) || []; - - const handleAmountMappingChange = - (id: string) => (event: SelectChangeEvent) => { - const nextData = [...state.data]; - const { value } = event.target; - const dosingRows = nextData.filter( - (row) => row[administrationIdField] === id && row["Amount"] !== ".", - ); - dosingRows.forEach((row) => { - row["Amount Variable"] = value; - }); - state.setData(nextData); - }; type InputChangeEvent = | ChangeEvent | SelectChangeEvent; diff --git a/frontend-v2/src/features/data/LoadData.tsx b/frontend-v2/src/features/data/LoadData.tsx index 73c70a67a..9bde212ee 100644 --- a/frontend-v2/src/features/data/LoadData.tsx +++ b/frontend-v2/src/features/data/LoadData.tsx @@ -102,11 +102,7 @@ function setMinimumInfusionTime(state: StepperState) { } } -const LoadData: FC = ({ - state, - firstTime, - notificationsInfo, -}) => { +const LoadData: FC = ({ state, notificationsInfo }) => { const showData = state.data.length > 0 && state.fields.length > 0; const normalisedHeaders = state.normalisedHeaders; if (!normalisedHeaders.includes("ID")) { @@ -184,14 +180,6 @@ const LoadData: FC = ({ state.setWarnings(warnings); }; - const noTimeUnit = !state.normalisedHeaders.find( - (field) => field === "Time Unit", - ); - const invalidTimeUnits = state.errors.find((error) => - error.includes("file contains multiple time units"), - ); - const showTimeUnitSelector = noTimeUnit || invalidTimeUnits; - return ( = ({ csv = "", onCancel, onFinish }) => { const csvData = Papa.parse(csv, { header: true }); const csvFields = csvData.meta.fields || []; const [data, setData] = useState((csvData.data as Data) || []); - let [errors, setErrors] = useState([]); + const [errors, setErrors] = useState([]); + let displayedErrors = [...errors]; const [warnings, setWarnings] = useState([]); const [normalisedFields, setNormalisedFields] = useState>( new Map(csvFields.map(normaliseHeader)), @@ -145,7 +146,7 @@ const LoadDataStepper: FC = ({ csv = "", onCancel, onFinish }) => { "Invalid data file. Each subject ID can only belong to one dosing protocol."; if (!areValidProtocols && !errors.includes(protocolErrorMessage)) { - errors = [...errors, protocolErrorMessage]; + displayedErrors = [...displayedErrors, protocolErrorMessage]; } const [stepState, setStepState] = useState({ activeStep: 0, maxStep: 0 }); @@ -158,7 +159,7 @@ const LoadDataStepper: FC = ({ csv = "", onCancel, onFinish }) => { !normalisedHeaders.includes("Time Unit") && !timeUnit ) { - errors = [...errors, "Time unit is not defined."]; + displayedErrors = [...displayedErrors, "Time unit is not defined."]; } const noTimeUnit = !state.normalisedHeaders.find( @@ -172,7 +173,7 @@ const LoadDataStepper: FC = ({ csv = "", onCancel, onFinish }) => { const shouldShowTimeUnitNotification = showTimeUnitSelector || hasTimeUnitChanged; const notificationsCount = - errors?.length + + displayedErrors?.length + warnings?.length + (shouldShowTimeUnitNotification ? 2 : 1); @@ -291,7 +292,9 @@ const LoadDataStepper: FC = ({ csv = "", onCancel, onFinish }) => { 0} + disabled={ + data.length === 0 || isFinished || displayedErrors.length > 0 + } > {step} @@ -301,7 +304,7 @@ const LoadDataStepper: FC = ({ csv = "", onCancel, onFinish }) => { = ({ state, - firstTime, notificationsInfo, }: IMapDosing) => { const projectId = useSelector( @@ -35,8 +34,10 @@ const MapDosing: FC = ({ { skip: !projectId }, ); const isPreclinical = project?.species !== "H"; - const { data: projectProtocols, isLoading: isProtocolsLoading } = - useProtocolListQuery({ projectId: projectIdOrZero }, { skip: !projectId }); + const { data: projectProtocols } = useProtocolListQuery( + { projectId: projectIdOrZero }, + { skip: !projectId }, + ); const { data: models = [] } = useCombinedModelListQuery( { projectId: projectIdOrZero }, { skip: !projectId }, diff --git a/frontend-v2/src/features/data/MapHeaders.tsx b/frontend-v2/src/features/data/MapHeaders.tsx index 0b62303c7..b7effa7d6 100644 --- a/frontend-v2/src/features/data/MapHeaders.tsx +++ b/frontend-v2/src/features/data/MapHeaders.tsx @@ -13,6 +13,7 @@ import { Typography, TablePagination, TableContainer, + SelectChangeEvent, } from "@mui/material"; import { Data, Field } from "./LoadData"; import { groupedHeaders } from "./dataValidation"; @@ -47,7 +48,7 @@ const MapHeaders: FC = ({ handlePageChange, } = usePagination(); const fields = [...normalisedFields.keys()]; - const handleFieldChange = (field: string) => (event: any) => { + const handleFieldChange = (field: string) => (event: SelectChangeEvent) => { const newFields = new Map([ ...normalisedFields.entries(), [field, event.target.value], diff --git a/frontend-v2/src/features/data/MapObservations.tsx b/frontend-v2/src/features/data/MapObservations.tsx index 1525827c6..e5c2b55d2 100644 --- a/frontend-v2/src/features/data/MapObservations.tsx +++ b/frontend-v2/src/features/data/MapObservations.tsx @@ -1,4 +1,4 @@ -import { ChangeEvent, FC, useState } from "react"; +import { FC, SyntheticEvent, useState } from "react"; import { DataGrid } from "@mui/x-data-grid"; import { Box, @@ -206,7 +206,10 @@ const MapObservations: FC = ({ state.setWarnings(warnings); }; - function handleTabChange(event: ChangeEvent<{}>, newValue: number) { + function handleTabChange( + event: SyntheticEvent, + newValue: number, + ) { setTab(newValue); } diff --git a/frontend-v2/src/features/data/PreviewData.tsx b/frontend-v2/src/features/data/PreviewData.tsx index 78922432d..94960b7b0 100644 --- a/frontend-v2/src/features/data/PreviewData.tsx +++ b/frontend-v2/src/features/data/PreviewData.tsx @@ -25,7 +25,7 @@ const IGNORED_COLUMNS = ["Ignore"]; function normaliseDataColumn(state: StepperState, type: string) { const normalisedHeaders = [...state.normalisedFields.entries()]; const matchingFields = - normalisedHeaders.filter(([key, value]) => value === type) || []; + normalisedHeaders.filter(([_key, value]) => value === type) || []; if (matchingFields.length !== 1) { // only normalise a column if there is exactly one column of that type. return state.data; diff --git a/frontend-v2/src/features/data/SetUnits.tsx b/frontend-v2/src/features/data/SetUnits.tsx index 3c105551e..83c87a308 100644 --- a/frontend-v2/src/features/data/SetUnits.tsx +++ b/frontend-v2/src/features/data/SetUnits.tsx @@ -26,7 +26,6 @@ interface IMapObservations { const SetUnits: FC = ({ state, - firstTime, setHasTimeUnitChanged, }: IMapObservations) => { const [isChanged, setIsChanged] = useState(false); diff --git a/frontend-v2/src/features/data/Stratification.tsx b/frontend-v2/src/features/data/Stratification.tsx index edf94e0bf..106855ee9 100644 --- a/frontend-v2/src/features/data/Stratification.tsx +++ b/frontend-v2/src/features/data/Stratification.tsx @@ -1,4 +1,4 @@ -import { ChangeEvent, FC, useState } from "react"; +import { ChangeEvent, FC, SyntheticEvent, useState } from "react"; import { Box, Radio, @@ -126,7 +126,10 @@ const Stratification: FC = ({ ); } - const handleTabChange = (event: ChangeEvent<{}>, newValue: number) => { + const handleTabChange = ( + event: SyntheticEvent, + newValue: number, + ) => { setTab(newValue); }; diff --git a/frontend-v2/src/features/login/loginSlice.ts b/frontend-v2/src/features/login/loginSlice.ts index 691e181ac..882a84a1c 100644 --- a/frontend-v2/src/features/login/loginSlice.ts +++ b/frontend-v2/src/features/login/loginSlice.ts @@ -5,7 +5,7 @@ import { UserRead, ProjectRead, ProjectAccessRead } from "../../app/backendApi"; export const fetchCsrf = createAsyncThunk( "login/fetchCsrf", - async (_, { dispatch }) => { + async () => { const csrfResponse = await fetch("/api/csrf/", { method: "GET", credentials: "include", @@ -17,7 +17,7 @@ export const fetchCsrf = createAsyncThunk( interface Login { isAuthenticated: boolean; - user: any; + user: UserRead; } interface LoginErrorResponse { @@ -111,7 +111,7 @@ export const logout = createAsyncThunk( credentials: "include", }) .then(isResponseOk) - .then((data) => { + .then(() => { dispatch(fetchCsrf()); return { isAuthenticated: false }; }); @@ -143,7 +143,7 @@ const slice = createSlice({ }, }, extraReducers: (builder) => { - builder.addCase(fetchCsrf.rejected, (state, action) => { + builder.addCase(fetchCsrf.rejected, (state) => { state.csrf = undefined; }); builder.addCase(fetchCsrf.fulfilled, (state, action) => { diff --git a/frontend-v2/src/features/model/ParametersTab.tsx b/frontend-v2/src/features/model/ParametersTab.tsx index b05044f0a..bfa3f453a 100644 --- a/frontend-v2/src/features/model/ParametersTab.tsx +++ b/frontend-v2/src/features/model/ParametersTab.tsx @@ -43,14 +43,7 @@ interface Props { units: UnitRead[]; } -const ParametersTab: FC = ({ - model, - project, - control, - variables, - compound, - units, -}) => { +const ParametersTab: FC = ({ model, project, variables, units }) => { const [setParamsToDefault] = useCombinedModelSetParamsToDefaultsUpdateMutation(); diff --git a/frontend-v2/src/features/model/VariableRow.tsx b/frontend-v2/src/features/model/VariableRow.tsx index 8aaab0cd2..12fbf3969 100644 --- a/frontend-v2/src/features/model/VariableRow.tsx +++ b/frontend-v2/src/features/model/VariableRow.tsx @@ -8,7 +8,6 @@ import { FormControlLabel, Tooltip, Typography, - Radio, } from "@mui/material"; import { Variable, @@ -43,12 +42,9 @@ interface Props { type DerivedVariableType = "AUC" | "RO" | "FUP" | "BPR" | "TLG"; -const derivedVariableRegex = /calc_.*_(f|bl|RO)/; - const VariableRow: FC = ({ project, compound, - model, variable, control, effectVariable, @@ -59,15 +55,11 @@ const VariableRow: FC = ({ updateLinksToPd, updateLagTimes, }) => { - const { - fields: mappings - } = useFieldArray({ + const { fields: mappings } = useFieldArray({ control, name: "model.mappings", }); - const { - fields: derivedVariables - } = useFieldArray({ + const { fields: derivedVariables } = useFieldArray({ control, name: "model.derived_variables", }); diff --git a/frontend-v2/src/features/model/resetToSpeciesDefaults.ts b/frontend-v2/src/features/model/resetToSpeciesDefaults.ts index 2e380ec9c..f3270164a 100644 --- a/frontend-v2/src/features/model/resetToSpeciesDefaults.ts +++ b/frontend-v2/src/features/model/resetToSpeciesDefaults.ts @@ -63,7 +63,7 @@ type VariableMutation = MutationTrigger< string | FetchArgs, unknown, FetchBaseQueryError, - {}, + unknown, FetchBaseQueryMeta >, never, diff --git a/frontend-v2/src/features/projects/Project.tsx b/frontend-v2/src/features/projects/Project.tsx index 1fbb098e6..5ea75c830 100644 --- a/frontend-v2/src/features/projects/Project.tsx +++ b/frontend-v2/src/features/projects/Project.tsx @@ -87,7 +87,12 @@ const ProjectRow: FC = ({ const [projectCopyUpdate] = useProjectCopyUpdateMutation(); const [isEditMode, setIsEditMode] = useState(false); - const { isDescriptionModalOpen, onOpenDescriptionModal, onCloseDescriptionModal, descriptionProjectId } = useProjectDescription(); + const { + isDescriptionModalOpen, + onOpenDescriptionModal, + onCloseDescriptionModal, + descriptionProjectId, + } = useProjectDescription(); useEffect(() => { if (isEditMode) { @@ -116,16 +121,10 @@ const ProjectRow: FC = ({ molecular_mass: 100, target_molecular_mass: 100, }; - const { - reset, - handleSubmit, - control, - setValue, - register, - formState: { isDirty }, - } = useForm({ - defaultValues: { project, compound: defaultCompound }, - }); + const { reset, handleSubmit, control, setValue, register } = + useForm({ + defaultValues: { project, compound: defaultCompound }, + }); const [userAccessOpen, setUserAccessOpen] = useState(false); @@ -179,7 +178,7 @@ const ProjectRow: FC = ({ setValue("project.user_access", project.user_access); setUserAccessOpen(false); setIsEditMode(false); - } + }; if (isLoading) { return
Loading...
; @@ -249,7 +248,7 @@ const ProjectRow: FC = ({ if (window.innerHeight < 800) return Math.ceil(window.innerHeight / 100); return 15; - } + }; return ( <> @@ -277,7 +276,7 @@ const ProjectRow: FC = ({ textFieldProps={defaultProps} size="small" rules={{ required: true, validate: validateName }} - sx={{ ...defaultSx, minWidth: '10rem' }} + sx={{ ...defaultSx, minWidth: "10rem" }} /> ) : (