Skip to content
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

SIMSBIOHUB-286: Upload Telemetry Files on Device Creation #1102

Merged
merged 62 commits into from
Sep 29, 2023
Merged
Show file tree
Hide file tree
Changes from 52 commits
Commits
Show all changes
62 commits
Select commit Hold shift + click to select a range
78d0095
Added method to BctwService for keyX file uploads
JeremyQuartech Sep 12, 2023
063af6e
Merge branch 'dev' into SIMSBIOHUB-263
JeremyQuartech Sep 13, 2023
ce9c9c0
WIP: Attachment service and repo functions for keyx files
JeremyQuartech Sep 14, 2023
e46e75b
Added survey_attachment_keyx table
JeremyQuartech Sep 14, 2023
22b4323
Added attachment-repo methods to insert and update keyx references
JeremyQuartech Sep 14, 2023
be69edf
Added attachment-keyx-service and modified file object type in BctwSe…
JeremyQuartech Sep 14, 2023
daafac9
Updated api routes for file processing
JeremyQuartech Sep 14, 2023
cc7b09e
Various bug fixes, implemented ui changes for uploads
JeremyQuartech Sep 15, 2023
9f1320a
Added notes where improvements can likely be made still.
JeremyQuartech Sep 15, 2023
79b0b12
Merge branch 'dev' into SIMSBIOHUB-263
JeremyQuartech Sep 15, 2023
b524858
Renamed process endpoint and added stub schema
JeremyQuartech Sep 18, 2023
57e56d5
renamed process endpoint to /processKeyx
JeremyQuartech Sep 18, 2023
02f37dd
revert name changes
JeremyQuartech Sep 19, 2023
e451dac
Addressed various PR comments
JeremyQuartech Sep 19, 2023
9fb59f9
Extracted keyx detection to file-utils to reduce complexity of upload()
JeremyQuartech Sep 19, 2023
fdd8b45
Add unit tests for /survey/process
JeremyQuartech Sep 19, 2023
b40fe5c
Added basic keyx specific upload dialog to survey documents
JeremyQuartech Sep 19, 2023
ef710d1
updated Bctw Service unit tests
JeremyQuartech Sep 19, 2023
c2bd027
Removed /process endpoint
JeremyQuartech Sep 19, 2023
573312e
Added keyx specific upload endpoint
JeremyQuartech Sep 19, 2023
0a9f0e0
Added keyx response schema and error handling to bcwt service
JeremyQuartech Sep 19, 2023
72e531c
Removed keyx attachment table migration
JeremyQuartech Sep 19, 2023
9946b6a
Added zip file validation
JeremyQuartech Sep 19, 2023
5397ee6
WIP: displaying errors in keyx uploader
JeremyQuartech Sep 20, 2023
4a73169
Added error handling for BCTW api connection refusal
JeremyQuartech Sep 20, 2023
f663c77
Disabled error details by default
JeremyQuartech Sep 20, 2023
98323d7
Reverted attachment-repo changes
JeremyQuartech Sep 20, 2023
57cb457
Removed dead cod
JeremyQuartech Sep 20, 2023
645660d
Merge branch 'dev' into SIMSBIOHUB-263
JeremyQuartech Sep 20, 2023
fa75116
Updated BctwService tests
JeremyQuartech Sep 21, 2023
8dd0643
Removed console log and added keyxResults to upload response
JeremyQuartech Sep 21, 2023
a29f3a1
Added request timeout to BCTW service
JeremyQuartech Sep 21, 2023
0d75a74
Added keyx results to openapi schema
JeremyQuartech Sep 21, 2023
9027969
Removed console logs
JeremyQuartech Sep 21, 2023
4d3266a
Fixed code smells and addressed PR comments
JeremyQuartech Sep 21, 2023
4f4b571
fixed code smells
JeremyQuartech Sep 21, 2023
171d01c
Moved keyx detection to media-utils and updated unit tests
JeremyQuartech Sep 21, 2023
3887a50
Code duplication fixes
JeremyQuartech Sep 21, 2023
6e964f8
Code duplication fix
JeremyQuartech Sep 21, 2023
e2da28c
Merge branch 'dev' into SIMSBIOHUB-263
GrahamS-Quartech Sep 21, 2023
9d5f0c4
WIP: Attachment section inside add device form
JeremyQuartech Sep 21, 2023
7c2fe68
Added basic file upload component to Telemetry device form
JeremyQuartech Sep 22, 2023
d0d7764
Changed file uploads on device add to use staged mode instead of dire…
JeremyQuartech Sep 25, 2023
6416d4d
Merge branch 'dev' into SIMSBIOHUB-286
JeremyQuartech Sep 25, 2023
7c5583f
Made uploadHandler prop optional
JeremyQuartech Sep 25, 2023
3a7f330
Refactored TelemetryFileUpload to reduce complexity
JeremyQuartech Sep 25, 2023
5444d0d
Separated handleSaveTelemetry in a function for both edit and add tel…
JeremyQuartech Sep 26, 2023
942497a
Fixed logic bug on upload rendering
JeremyQuartech Sep 26, 2023
5fcf548
Removed 'any' casting on error catch
JeremyQuartech Sep 26, 2023
1239b30
Refactored handleEditTelemetry to split up device and deployment spec…
JeremyQuartech Sep 26, 2023
19d5dc1
WIP: Telemetry upload tests
JeremyQuartech Sep 27, 2023
19a64f0
Merge branch 'dev' into SIMSBIOHUB-286
JeremyQuartech Sep 27, 2023
6a40c87
Added KeyX file registration status detection to deviceId endpoint
JeremyQuartech Sep 27, 2023
7215e62
Updated logic in add telemetry form to only allow uploads if keyx doe…
JeremyQuartech Sep 27, 2023
5a2c026
Added support to upload keyx and cfg files during telemetry device edit
JeremyQuartech Sep 27, 2023
8426bba
Minor tweaks to AttchmentFormSection of TelemetryDeviceForm
JeremyQuartech Sep 27, 2023
428a5b4
Fixed broken device detail tests.
JeremyQuartech Sep 28, 2023
769ea35
Added test coverage for getKeyXDetails
JeremyQuartech Sep 28, 2023
14e5bd5
updated useDeviceApi tests
JeremyQuartech Sep 28, 2023
39f42da
added uploadSurveyKeyx test
JeremyQuartech Sep 28, 2023
d35402a
Adds test of telemetry device add
JeremyQuartech Sep 28, 2023
9afedbc
Added basic test to TelemetryFileUpload component
JeremyQuartech Sep 28, 2023
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
2 changes: 1 addition & 1 deletion app/src/components/file-upload/FileUpload.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export interface IFileUploadProps {
* @type {IUploadHandler}
* @memberof IFileUploadProps
*/
uploadHandler: IUploadHandler;
uploadHandler?: IUploadHandler;
/**
* Callback fired for each accepted file in the list (that do not have any `DropZone` errors (size, count, extension).
*
Expand Down
26 changes: 14 additions & 12 deletions app/src/components/file-upload/FileUploadItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,12 @@

export interface IFileUploadItemProps {
/**
* A file upload callback fired for each file.
* An optional file upload callback fired for each file.
*
* @type {IUploadHandler}
* @memberof IFileUploadItemProps
*/
uploadHandler: IUploadHandler;
uploadHandler?: IUploadHandler;
/**
* An optional callback fired if the file upload is successful.
*
Expand Down Expand Up @@ -223,16 +223,18 @@
onSuccess?.(response);
};

uploadHandler(file, cancelToken, handleFileUploadProgress)
.then(handleFileUploadSuccess, (error: APIError) => {
setError(error?.message);
setErrorDetails(
error.errors?.map((error) => {
return { _id: v4(), message: String(error) };
})
);
})
.catch();
if (uploadHandler) {
uploadHandler(file, cancelToken, handleFileUploadProgress)
.then(handleFileUploadSuccess, (error: APIError) => {
setError(error?.message);
setErrorDetails(
error?.errors?.map((e) => {
return { _id: v4(), message: e?.toString() };

Check warning on line 232 in app/src/components/file-upload/FileUploadItem.tsx

View check run for this annotation

Codecov / codecov/patch

app/src/components/file-upload/FileUploadItem.tsx#L232

Added line #L232 was not covered by tests
})
);
})
.catch();
}

setStatus(UploadFileStatus.UPLOADING);
}, [
Expand Down
1 change: 1 addition & 0 deletions app/src/constants/attachments.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ export enum ProjectSurveyAttachmentValidExtensions {
DATA = '.txt, .xls, .xlsx, .xlsm, .xlsb, .accdb, .mdb, .ods, .csv',
IMAGE = '.gif, .png, .jpg, .jpeg, .svg, .tiff, .bmp, .tif',
KEYX = '.keyx, .zip',
CONFIG = '.cfg',
REPORT = '.doc, .docx, .pdf',
SPATIAL = '.kml, .gpx, .zip',
VIDEO = '.mp4, .mov, .wmv, .ave',
Expand Down
110 changes: 75 additions & 35 deletions app/src/features/surveys/view/SurveyAnimals.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import HelpButtonTooltip from 'components/buttons/HelpButtonTooltip';
import EditDialog from 'components/dialog/EditDialog';
import { H2ButtonToolbar } from 'components/toolbar/ActionToolbars';
import { AttachmentType } from 'constants/attachments';
import { SurveyAnimalsI18N } from 'constants/i18n';
import { DialogContext } from 'contexts/dialogContext';
import { SurveyContext } from 'contexts/surveyContext';
Expand All @@ -16,10 +17,18 @@
import yup from 'utils/YupSchema';
import NoSurveySectionData from '../components/NoSurveySectionData';
import { AnimalSchema, AnimalSex, Critter, IAnimal } from './survey-animals/animal';
import { AnimalTelemetryDeviceSchema, Device, IAnimalTelemetryDevice } from './survey-animals/device';
import {
AnimalTelemetryDeviceSchema,
Device,
IAnimalTelemetryDevice,
IDeploymentTimespan
} from './survey-animals/device';
import IndividualAnimalForm from './survey-animals/IndividualAnimalForm';
import { SurveyAnimalsTable } from './survey-animals/SurveyAnimalsTable';
import TelemetryDeviceForm, { TELEMETRY_DEVICE_FORM_MODE } from './survey-animals/TelemetryDeviceForm';
import TelemetryDeviceForm, {
IAnimalTelemetryDeviceFile,
TELEMETRY_DEVICE_FORM_MODE
} from './survey-animals/TelemetryDeviceForm';

const SurveyAnimals: React.FC = () => {
const bhApi = useBiohubApi();
Expand Down Expand Up @@ -151,44 +160,75 @@
}
};

const handleTelemetrySave = async (survey_critter_id: number, data: IAnimalTelemetryDevice[]) => {
const handleAddTelemetry = async (survey_critter_id: number, data: IAnimalTelemetryDeviceFile[]) => {
const critter = critterData?.find((a) => a.survey_critter_id === survey_critter_id);
const critterTelemetryDevice = { ...data[0], critter_id: critter?.critter_id ?? '' };
if (telemetryFormMode === TELEMETRY_DEVICE_FORM_MODE.ADD) {
try {
await bhApi.survey.addDeployment(projectId, surveyId, survey_critter_id, critterTelemetryDevice);
setPopup('Successfully added deployment.');
} catch (e) {
const { attachmentFile, attachmentType, ...critterTelemetryDevice } = {

Check warning on line 165 in app/src/features/surveys/view/SurveyAnimals.tsx

View check run for this annotation

Codecov / codecov/patch

app/src/features/surveys/view/SurveyAnimals.tsx#L165

Added line #L165 was not covered by tests
...data[0],
critter_id: critter?.critter_id ?? ''
};
try {

Check warning on line 169 in app/src/features/surveys/view/SurveyAnimals.tsx

View check run for this annotation

Codecov / codecov/patch

app/src/features/surveys/view/SurveyAnimals.tsx#L169

Added line #L169 was not covered by tests
// Upload attachment if there is one
if (attachmentFile && attachmentType === AttachmentType.KEYX) {
await bhApi.survey.uploadSurveyKeyx(projectId, surveyId, attachmentFile);

Check warning on line 172 in app/src/features/surveys/view/SurveyAnimals.tsx

View check run for this annotation

Codecov / codecov/patch

app/src/features/surveys/view/SurveyAnimals.tsx#L172

Added line #L172 was not covered by tests
} else if (attachmentFile && attachmentType === AttachmentType.OTHER) {
await bhApi.survey.uploadSurveyAttachments(projectId, surveyId, attachmentFile);

Check warning on line 174 in app/src/features/surveys/view/SurveyAnimals.tsx

View check run for this annotation

Codecov / codecov/patch

app/src/features/surveys/view/SurveyAnimals.tsx#L174

Added line #L174 was not covered by tests
}
// create new deployment record
await bhApi.survey.addDeployment(projectId, surveyId, survey_critter_id, critterTelemetryDevice);
setPopup('Successfully added deployment.');
surveyContext.artifactDataLoader.refresh(projectId, surveyId);

Check warning on line 179 in app/src/features/surveys/view/SurveyAnimals.tsx

View check run for this annotation

Codecov / codecov/patch

app/src/features/surveys/view/SurveyAnimals.tsx#L177-L179

Added lines #L177 - L179 were not covered by tests
} catch (error: unknown) {
if (error instanceof Error) {
setPopup('Failed to add deployment' + (error?.message ? `: ${error.message}` : '.'));
} else {
setPopup('Failed to add deployment.');
}
} else if (telemetryFormMode === TELEMETRY_DEVICE_FORM_MODE.EDIT) {
for (const formValues of data) {
const existingDevice = deploymentData?.find((a) => a.device_id === formValues.device_id);
const formDevice = new Device({ collar_id: existingDevice?.collar_id, ...formValues });
if (existingDevice && !_deepEquals(new Device(existingDevice), formDevice)) {
//Verify whether the data entered in the form changed from the device metadata we already have.
try {
await telemetryApi.devices.upsertCollar(formDevice); //If it's different, upsert. Note that this alone does not touch a deployment.
} catch (e) {
setPopup(`Failed to update device ${formDevice.device_id}`);
}
}
for (const formDeployment of formValues.deployments ?? []) {
//Iterate over the deployments under this device.
const existingDeployment = deploymentData?.find((a) => a.deployment_id === formDeployment.deployment_id); //Find the deployment info we already have.
if (
!datesSameNullable(formDeployment?.attachment_start, existingDeployment?.attachment_start) ||
!datesSameNullable(formDeployment?.attachment_end, existingDeployment?.attachment_end) //Helper function necessary for this date comparison since moment(null) !== moment(null) normally.
) {
try {
await bhApi.survey.updateDeployment(projectId, surveyId, survey_critter_id, formDeployment);
} catch (e) {
setPopup(`Failed to update deployment ${formDeployment.deployment_id}`);
}
}
}
};

const updateDevice = async (formValues: IAnimalTelemetryDevice) => {
const existingDevice = deploymentData?.find((deployment) => deployment.device_id === formValues.device_id);
const formDevice = new Device({ collar_id: existingDevice?.collar_id, ...formValues });

Check warning on line 191 in app/src/features/surveys/view/SurveyAnimals.tsx

View check run for this annotation

Codecov / codecov/patch

app/src/features/surveys/view/SurveyAnimals.tsx#L190-L191

Added lines #L190 - L191 were not covered by tests
if (existingDevice && !_deepEquals(new Device(existingDevice), formDevice)) {
try {
await telemetryApi.devices.upsertCollar(formDevice);

Check warning on line 194 in app/src/features/surveys/view/SurveyAnimals.tsx

View check run for this annotation

Codecov / codecov/patch

app/src/features/surveys/view/SurveyAnimals.tsx#L193-L194

Added lines #L193 - L194 were not covered by tests
} catch (error) {
setPopup(`Failed to update device ${formDevice.device_id}`);

Check warning on line 196 in app/src/features/surveys/view/SurveyAnimals.tsx

View check run for this annotation

Codecov / codecov/patch

app/src/features/surveys/view/SurveyAnimals.tsx#L196

Added line #L196 was not covered by tests
}
}
};

const updateDeployments = async (formDeployments: IDeploymentTimespan[], survey_critter_id: number) => {
for (const formDeployment of formDeployments ?? []) {
const existingDeployment = deploymentData?.find(
(animalDeployment) => animalDeployment.deployment_id === formDeployment.deployment_id

Check warning on line 204 in app/src/features/surveys/view/SurveyAnimals.tsx

View check run for this annotation

Codecov / codecov/patch

app/src/features/surveys/view/SurveyAnimals.tsx#L203-L204

Added lines #L203 - L204 were not covered by tests
);
if (
!datesSameNullable(formDeployment?.attachment_start, existingDeployment?.attachment_start) ||
!datesSameNullable(formDeployment?.attachment_end, existingDeployment?.attachment_end)
) {
try {
await bhApi.survey.updateDeployment(projectId, surveyId, survey_critter_id, formDeployment);

Check warning on line 211 in app/src/features/surveys/view/SurveyAnimals.tsx

View check run for this annotation

Codecov / codecov/patch

app/src/features/surveys/view/SurveyAnimals.tsx#L210-L211

Added lines #L210 - L211 were not covered by tests
} catch (error) {
setPopup(`Failed to update deployment ${formDeployment.deployment_id}`);

Check warning on line 213 in app/src/features/surveys/view/SurveyAnimals.tsx

View check run for this annotation

Codecov / codecov/patch

app/src/features/surveys/view/SurveyAnimals.tsx#L213

Added line #L213 was not covered by tests
}
}
setPopup('Updated deployment and device data successfully.');
}
};

const handleEditTelemetry = async (survey_critter_id: number, data: IAnimalTelemetryDeviceFile[]) => {
for (const { attachmentFile, attachmentType, ...formValues } of data) {
await updateDevice(formValues);

Check warning on line 221 in app/src/features/surveys/view/SurveyAnimals.tsx

View check run for this annotation

Codecov / codecov/patch

app/src/features/surveys/view/SurveyAnimals.tsx#L220-L221

Added lines #L220 - L221 were not covered by tests
await updateDeployments(formValues.deployments ?? [], survey_critter_id);
}
setPopup('Updated deployment and device data successfully.');

Check warning on line 224 in app/src/features/surveys/view/SurveyAnimals.tsx

View check run for this annotation

Codecov / codecov/patch

app/src/features/surveys/view/SurveyAnimals.tsx#L224

Added line #L224 was not covered by tests
};

const handleTelemetrySave = async (survey_critter_id: number, data: IAnimalTelemetryDeviceFile[]) => {
if (telemetryFormMode === TELEMETRY_DEVICE_FORM_MODE.ADD) {
await handleAddTelemetry(survey_critter_id, data);

Check warning on line 229 in app/src/features/surveys/view/SurveyAnimals.tsx

View check run for this annotation

Codecov / codecov/patch

app/src/features/surveys/view/SurveyAnimals.tsx#L229

Added line #L229 was not covered by tests
} else if (telemetryFormMode === TELEMETRY_DEVICE_FORM_MODE.EDIT) {
await handleEditTelemetry(survey_critter_id, data);

Check warning on line 231 in app/src/features/surveys/view/SurveyAnimals.tsx

View check run for this annotation

Codecov / codecov/patch

app/src/features/surveys/view/SurveyAnimals.tsx#L231

Added line #L231 was not covered by tests
}

setOpenDeviceDialog(false);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,44 @@
import CustomTextField from 'components/fields/CustomTextField';
import SingleDateField from 'components/fields/SingleDateField';
import TelemetrySelectField from 'components/fields/TelemetrySelectField';
import { AttachmentType } from 'constants/attachments';
import { Form, useFormikContext } from 'formik';
import useDataLoader from 'hooks/useDataLoader';
import { useTelemetryApi } from 'hooks/useTelemetryApi';
import moment from 'moment';
import { Fragment, useEffect, useState } from 'react';
import { IAnimalTelemetryDevice, IDeploymentTimespan } from './device';
import { TelemetryFileUpload } from './TelemetryFileUpload';

export enum TELEMETRY_DEVICE_FORM_MODE {
ADD = 'add',
EDIT = 'edit'
}

export interface IAnimalTelemetryDeviceFile extends IAnimalTelemetryDevice {
attachmentFile?: File;
attachmentType?: AttachmentType;
}

const AttchmentFormSection = ({ index, deviceMake }: { index: number; deviceMake: string }): JSX.Element => {
JeremyQuartech marked this conversation as resolved.
Show resolved Hide resolved
return (

Check warning on line 26 in app/src/features/surveys/view/survey-animals/TelemetryDeviceForm.tsx

View check run for this annotation

Codecov / codecov/patch

app/src/features/surveys/view/survey-animals/TelemetryDeviceForm.tsx#L26

Added line #L26 was not covered by tests
<Paper sx={{ padding: 3 }}>
{deviceMake === 'Vectronic' && (
<>
<Typography sx={{ ml: 1, mb: 3 }}>{`Upload Vectronic KeyX File`}</Typography>
<TelemetryFileUpload attachmentType={AttachmentType.KEYX} index={index} />
</>
)}
{deviceMake === 'Lotek' && (
<>
<Typography sx={{ ml: 1, mb: 3 }}>{`Upload Lotek Config File`}</Typography>
<TelemetryFileUpload attachmentType={AttachmentType.OTHER} index={index} />
</>
)}
</Paper>
);
};

const DeploymentFormSection = ({
index,
deployments
Expand Down Expand Up @@ -48,12 +74,12 @@

interface IDeviceFormSectionProps {
mode: TELEMETRY_DEVICE_FORM_MODE;
values: IAnimalTelemetryDevice[];
values: IAnimalTelemetryDeviceFile[];
index: number;
}

const DeviceFormSection = ({ values, index, mode }: IDeviceFormSectionProps): JSX.Element => {
const { setStatus } = useFormikContext<{ formValues: IAnimalTelemetryDevice[] }>();
const { setStatus } = useFormikContext<{ formValues: IAnimalTelemetryDeviceFile[] }>();
const [bctwErrors, setBctwErrors] = useState<Record<string, string | undefined>>({});
const api = useTelemetryApi();

Expand Down Expand Up @@ -123,6 +149,12 @@
<CustomTextField label="Device Model" name={`${index}.device_model`} />
</Grid>
</Grid>
{mode === TELEMETRY_DEVICE_FORM_MODE.ADD &&
(values[index].device_make === 'Vectronic' || values[index].device_make === 'Lotek') && (
<Box sx={{ mt: 3 }}>
<AttchmentFormSection index={index} deviceMake={values[index].device_make} />
</Box>
)}
<Box sx={{ mt: 3 }}>
<Paper sx={{ padding: 3 }}>
<Typography sx={{ ml: 1, mb: 3 }}>Deployments</Typography>
Expand All @@ -147,7 +179,7 @@
}

const TelemetryDeviceForm = ({ mode }: ITelemetryDeviceFormProps) => {
const { values } = useFormikContext<IAnimalTelemetryDevice[]>();
const { values } = useFormikContext<IAnimalTelemetryDeviceFile[]>();

return (
<Form>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import FileUpload, { IReplaceHandler } from 'components/file-upload/FileUpload';
import { IFileHandler, UploadFileStatus } from 'components/file-upload/FileUploadItem';
import { AttachmentType, ProjectSurveyAttachmentValidExtensions } from 'constants/attachments';
import { useFormikContext } from 'formik';
import React from 'react';
import { IAnimalTelemetryDeviceFile } from './TelemetryDeviceForm';

export const TelemetryFileUpload: React.FC<{ attachmentType: AttachmentType; index: number }> = (props) => {
const { setFieldValue } = useFormikContext<{ formValues: IAnimalTelemetryDeviceFile[] }>();
const fileHandler: IFileHandler = (file) => {
setFieldValue(`${props.index}.attachmentFile`, file);
setFieldValue(`${props.index}.attachmentType`, props.attachmentType);

Check warning on line 12 in app/src/features/surveys/view/survey-animals/TelemetryFileUpload.tsx

View check run for this annotation

Codecov / codecov/patch

app/src/features/surveys/view/survey-animals/TelemetryFileUpload.tsx#L9-L12

Added lines #L9 - L12 were not covered by tests
};

const replaceHandler: IReplaceHandler = () => {
setFieldValue(`${props.index}.attachmentFile`, null);
setFieldValue(`${props.index}.attachmentType`, props.attachmentType);

Check warning on line 17 in app/src/features/surveys/view/survey-animals/TelemetryFileUpload.tsx

View check run for this annotation

Codecov / codecov/patch

app/src/features/surveys/view/survey-animals/TelemetryFileUpload.tsx#L15-L17

Added lines #L15 - L17 were not covered by tests
};

return (

Check warning on line 20 in app/src/features/surveys/view/survey-animals/TelemetryFileUpload.tsx

View check run for this annotation

Codecov / codecov/patch

app/src/features/surveys/view/survey-animals/TelemetryFileUpload.tsx#L20

Added line #L20 was not covered by tests
<FileUpload
fileHandler={fileHandler}
onReplace={replaceHandler}
dropZoneProps={{
maxNumFiles: 1,
multiple: false,
acceptedFileExtensions:
props.attachmentType === AttachmentType.KEYX
? ProjectSurveyAttachmentValidExtensions.KEYX
: ProjectSurveyAttachmentValidExtensions.CONFIG
}}
replace={true}
status={UploadFileStatus.STAGED}
/>
);
};

export default TelemetryFileUpload;