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

Show Animal Nickname in Capture/Mortality Map Popup #1475

Merged
merged 16 commits into from
Feb 6, 2025
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
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/features/surveys/view/SurveyMapPopup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export interface ISurveyMapPopupProps {
title: string;
metadata: {
label: string;
value: string | number;
value: string | number | null;
}[];
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,10 @@
}

/**
* Component for displaying animal capture points on a map and in a table.
* Retrieves and displays data related to animal captures for a specific survey.
* Container displaying map of captures and mortalities for animals in the Survey, and table of animals below the map
*
* @param {ISurveySpatialAnimalProps} props
* @returns
*/
export const SurveySpatialAnimal = (props: ISurveySpatialAnimalProps) => {
const surveyContext = useSurveyContext();
Expand Down Expand Up @@ -66,7 +68,7 @@
properties: {}
}
})) ?? [],
popup: (feature) => <SurveySpatialAnimalCapturePopup feature={feature} />,
popup: (feature) => <SurveySpatialAnimalCapturePopup captureId={`${feature.id}`} />,

Check warning on line 71 in app/src/features/surveys/view/survey-spatial/components/animal/SurveySpatialAnimal.tsx

View check run for this annotation

Codecov / codecov/patch

app/src/features/surveys/view/survey-spatial/components/animal/SurveySpatialAnimal.tsx#L71

Added line #L71 was not covered by tests
tooltip: (feature) => <SurveyMapTooltip title="Animal Capture" key={`mortality-tooltip-${feature.id}`} />
};

Expand All @@ -90,7 +92,7 @@
properties: {}
}
})) ?? [],
popup: (feature) => <SurveySpatialAnimalMortalityPopup feature={feature} />,
popup: (feature) => <SurveySpatialAnimalMortalityPopup mortalityId={`${feature.id}`} />,

Check warning on line 95 in app/src/features/surveys/view/survey-spatial/components/animal/SurveySpatialAnimal.tsx

View check run for this annotation

Codecov / codecov/patch

app/src/features/surveys/view/survey-spatial/components/animal/SurveySpatialAnimal.tsx#L95

Added line #L95 was not covered by tests
tooltip: (feature) => <SurveyMapTooltip title="Animal Mortality" key={`capture-tooltip-${feature.id}`} />
};

Expand All @@ -105,7 +107,7 @@
</Box>

{/* Display data table with animal capture details */}
<Box height={{ xs: 300, md: 500 }} display="flex">
<Box height={{ xs: 300, md: 500 }} display="flex" flexDirection="column">
<SurveySpatialAnimalTable isLoading={geometryDataLoader.isLoading} />
</Box>
</>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,37 +1,41 @@
import { IStaticLayerFeature } from 'components/map/components/StaticLayers';
import { DATE_FORMAT } from 'constants/dateTimeFormats';
import dayjs from 'dayjs';
import { SurveyMapPopup } from 'features/surveys/view/SurveyMapPopup';
import { useCritterbaseApi } from 'hooks/useCritterbaseApi';
import useDataLoader from 'hooks/useDataLoader';
import { ICaptureResponse } from 'interfaces/useCritterApi.interface';
import { Popup } from 'react-leaflet';

export interface ISurveySpatialAnimalCapturePopupProps {
feature: IStaticLayerFeature;
interface ISurveySpatialAnimalCapturePopupProps {
captureId: string;
}

/**
* Renders a popup for animal capture data on the map.
* Returns information about a critter capture record, shown when a capture point is clicked on the map
*
* @param {ISurveySpatialAnimalCapturePopupProps} props
* @return {*}
* @returns {*}
*/
export const SurveySpatialAnimalCapturePopup = (props: ISurveySpatialAnimalCapturePopupProps) => {
const { feature } = props;
const { captureId } = props;

Check warning on line 19 in app/src/features/surveys/view/survey-spatial/components/animal/SurveySpatialAnimalCapturePopup.tsx

View check run for this annotation

Codecov / codecov/patch

app/src/features/surveys/view/survey-spatial/components/animal/SurveySpatialAnimalCapturePopup.tsx#L19

Added line #L19 was not covered by tests

const critterbaseApi = useCritterbaseApi();

const captureDataLoader = useDataLoader((captureId) => critterbaseApi.capture.getCapture(captureId));
const captureDataLoader = useDataLoader(() => critterbaseApi.capture.getCapture(captureId));
const animalDataLoader = useDataLoader(critterbaseApi.critters.getCritterSimple);

Check warning on line 24 in app/src/features/surveys/view/survey-spatial/components/animal/SurveySpatialAnimalCapturePopup.tsx

View check run for this annotation

Codecov / codecov/patch

app/src/features/surveys/view/survey-spatial/components/animal/SurveySpatialAnimalCapturePopup.tsx#L23-L24

Added lines #L23 - L24 were not covered by tests

const formatPopupMetadata = () => {

Check warning on line 26 in app/src/features/surveys/view/survey-spatial/components/animal/SurveySpatialAnimalCapturePopup.tsx

View check run for this annotation

Codecov / codecov/patch

app/src/features/surveys/view/survey-spatial/components/animal/SurveySpatialAnimalCapturePopup.tsx#L26

Added line #L26 was not covered by tests
if (!captureDataLoader.data || !animalDataLoader.data) return [];

const { capture_date, capture_time, capture_location } = captureDataLoader.data;
const { animal_id } = animalDataLoader.data;

Check warning on line 30 in app/src/features/surveys/view/survey-spatial/components/animal/SurveySpatialAnimalCapturePopup.tsx

View check run for this annotation

Codecov / codecov/patch

app/src/features/surveys/view/survey-spatial/components/animal/SurveySpatialAnimalCapturePopup.tsx#L29-L30

Added lines #L29 - L30 were not covered by tests

const getCaptureMetadata = (capture: ICaptureResponse) => {
return [
{ label: 'Capture ID', value: String(capture.capture_id) },
{ label: 'Date', value: dayjs(capture.capture_date).format(DATE_FORMAT.LongDateTimeFormat) },
{ label: 'Time', value: String(capture.capture_time ?? '') },
{ label: 'Nickname', value: animal_id },
{ label: 'Date', value: dayjs(capture_date).format(DATE_FORMAT.LongDateTimeFormat) },
{ label: 'Time', value: String(capture_time ?? '') },
{
label: 'Coordinates',
value: [capture.release_location?.latitude ?? null, capture.release_location?.longitude ?? null]
value: [capture_location?.latitude, capture_location?.longitude]
.filter((coord): coord is number => coord !== null)
.map((coord) => coord.toFixed(6))
.join(', ')
Expand All @@ -45,15 +49,17 @@
closeButton={true}
autoPan={true}
eventHandlers={{
add: () => {
captureDataLoader.load(String(feature.id));
add: async () => {
const capture = await captureDataLoader.load();

Check warning on line 53 in app/src/features/surveys/view/survey-spatial/components/animal/SurveySpatialAnimalCapturePopup.tsx

View check run for this annotation

Codecov / codecov/patch

app/src/features/surveys/view/survey-spatial/components/animal/SurveySpatialAnimalCapturePopup.tsx#L53

Added line #L53 was not covered by tests
// Fetch critter information to get the animal's nickname to display, which isn't included in the capture response
if (capture) animalDataLoader.load(capture.critter_id);
}
}}>
<SurveyMapPopup
isLoading={captureDataLoader.isLoading || !captureDataLoader.isReady}
title="Capture"
metadata={captureDataLoader.data ? getCaptureMetadata(captureDataLoader.data) : []}
key={`capture-feature-popup-${feature.id}`}
isLoading={captureDataLoader.isLoading || animalDataLoader.isLoading}
title="Capture Details"
metadata={formatPopupMetadata()}
key={`capture-feature-popup-${captureId}`}
/>
</Popup>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,38 +1,46 @@
import { IStaticLayerFeature } from 'components/map/components/StaticLayers';
import { DATE_FORMAT } from 'constants/dateTimeFormats';
import dayjs from 'dayjs';
import { SurveyMapPopup } from 'features/surveys/view/SurveyMapPopup';
import { useCritterbaseApi } from 'hooks/useCritterbaseApi';
import useDataLoader from 'hooks/useDataLoader';
import { IMortalityResponse } from 'interfaces/useCritterApi.interface';
import { Popup } from 'react-leaflet';

export interface ISurveySpatialAnimalMortalityPopupProps {
feature: IStaticLayerFeature;
interface ISurveySpatialAnimalMortalityPopupProps {
mortalityId: string;
}

/**
* Renders a popup for animal mortality data on the map.
* Returns information about a critter mortality record, shown when a mortality point is clicked on the map
*
* @param {ISurveySpatialAnimalMortalityPopupProps} props
* @return {*}
* @returns {*}
*/
export const SurveySpatialAnimalMortalityPopup = (props: ISurveySpatialAnimalMortalityPopupProps) => {
const { feature } = props;
const { mortalityId } = props;

Check warning on line 19 in app/src/features/surveys/view/survey-spatial/components/animal/SurveySpatialAnimalMortalityPopup.tsx

View check run for this annotation

Codecov / codecov/patch

app/src/features/surveys/view/survey-spatial/components/animal/SurveySpatialAnimalMortalityPopup.tsx#L19

Added line #L19 was not covered by tests

const critterbaseApi = useCritterbaseApi();

const mortalityDataLoader = useDataLoader((mortalityId) => critterbaseApi.mortality.getMortality(mortalityId));
const mortalityDataLoader = useDataLoader(critterbaseApi.mortality.getMortality);
const animalDataLoader = useDataLoader(critterbaseApi.critters.getCritterSimple);

Check warning on line 24 in app/src/features/surveys/view/survey-spatial/components/animal/SurveySpatialAnimalMortalityPopup.tsx

View check run for this annotation

Codecov / codecov/patch

app/src/features/surveys/view/survey-spatial/components/animal/SurveySpatialAnimalMortalityPopup.tsx#L23-L24

Added lines #L23 - L24 were not covered by tests

const formatPopupMetadata = () => {

Check warning on line 26 in app/src/features/surveys/view/survey-spatial/components/animal/SurveySpatialAnimalMortalityPopup.tsx

View check run for this annotation

Codecov / codecov/patch

app/src/features/surveys/view/survey-spatial/components/animal/SurveySpatialAnimalMortalityPopup.tsx#L26

Added line #L26 was not covered by tests
if (!mortalityDataLoader.data || !animalDataLoader.data) return [];

const { mortality_timestamp, location } = mortalityDataLoader.data;
const { animal_id } = animalDataLoader.data;

Check warning on line 30 in app/src/features/surveys/view/survey-spatial/components/animal/SurveySpatialAnimalMortalityPopup.tsx

View check run for this annotation

Codecov / codecov/patch

app/src/features/surveys/view/survey-spatial/components/animal/SurveySpatialAnimalMortalityPopup.tsx#L29-L30

Added lines #L29 - L30 were not covered by tests

const getMortalityMetadata = (mortality: IMortalityResponse) => {
return [
{ label: 'Mortality ID', value: String(mortality.mortality_id) },
{ label: 'Date', value: dayjs(mortality.mortality_timestamp).format(DATE_FORMAT.LongDateTimeFormat) },
{ label: 'Nickname', value: animal_id },
{
label: 'Date',
// Critterbase does not provide time as its own string so mortalities without time data will erroneously show 12:00 AM in the popup
value: dayjs(mortality_timestamp).format(DATE_FORMAT.MediumDateTimeFormat)
},
{
label: 'Coordinates',
value: [mortality.location?.latitude ?? null, mortality.location?.longitude ?? null]
.filter((coord): coord is number => coord !== null)
.map((coord) => coord.toFixed(6))
value: [location?.latitude, location?.longitude]
.filter(Boolean)
.map((coord) => coord!.toFixed(6))

Check warning on line 43 in app/src/features/surveys/view/survey-spatial/components/animal/SurveySpatialAnimalMortalityPopup.tsx

View check run for this annotation

Codecov / codecov/patch

app/src/features/surveys/view/survey-spatial/components/animal/SurveySpatialAnimalMortalityPopup.tsx#L43

Added line #L43 was not covered by tests
.join(', ')
}
];
Expand All @@ -44,15 +52,16 @@
closeButton={true}
autoPan={true}
eventHandlers={{
add: () => {
mortalityDataLoader.load(String(feature.id));
add: async () => {
const mortality = await mortalityDataLoader.load(mortalityId);

Check warning on line 56 in app/src/features/surveys/view/survey-spatial/components/animal/SurveySpatialAnimalMortalityPopup.tsx

View check run for this annotation

Codecov / codecov/patch

app/src/features/surveys/view/survey-spatial/components/animal/SurveySpatialAnimalMortalityPopup.tsx#L56

Added line #L56 was not covered by tests
if (mortality) animalDataLoader.load(mortality.critter_id);
}
}}>
<SurveyMapPopup
isLoading={mortalityDataLoader.isLoading || !mortalityDataLoader.isReady}
title="Mortality"
metadata={mortalityDataLoader.data ? getMortalityMetadata(mortalityDataLoader.data) : []}
key={`mortality-feature-popup-${feature.id}`}
isLoading={mortalityDataLoader.isLoading || animalDataLoader.isLoading}
title="Mortality Details"
metadata={formatPopupMetadata()}
key={`mortality-feature-popup-${mortalityId}`}
/>
</Popup>
);
Expand Down
Loading
Loading