Skip to content

Commit

Permalink
Merge branch 'dev' into np_techdebt_aws_v3
Browse files Browse the repository at this point in the history
  • Loading branch information
NickPhura authored Jun 18, 2024
2 parents eeb25ef + d71f5f7 commit 3225ad3
Show file tree
Hide file tree
Showing 14 changed files with 121 additions and 90 deletions.
15 changes: 11 additions & 4 deletions api/src/openapi/schemas/critter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,10 @@ const captureSchema: OpenAPIV3.SchemaObject = {
type: 'string',
format: 'uuid'
},
capture_method_id: {
type: 'string',
format: 'uuid'
},
capture_location_id: {
type: 'string',
format: 'uuid'
Expand All @@ -82,13 +86,16 @@ const captureSchema: OpenAPIV3.SchemaObject = {
},
capture_location: locationSchema,
release_location: locationSchema,
force_create_release: {
type: 'boolean'
capture_date: {
type: 'string'
},
capture_time: {
type: 'string'
},
capture_timestamp: {
release_date: {
type: 'string'
},
release_timestamp: {
release_time: {
type: 'string'
},
capture_comment: {
Expand Down
7 changes: 5 additions & 2 deletions api/src/services/critterbase-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,13 @@ export interface ICritter {
export interface ICapture {
capture_id?: string;
critter_id: string;
capture_method_id?: string | null;
capture_location_id: string;
release_location_id: string;
capture_timestamp: string;
release_timestamp: string;
capture_date: string;
capture_time?: string | null;
release_date?: string | null;
release_time?: string | null;
capture_comment: string;
release_comment: string;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import { IErrorDialogProps } from 'components/dialog/ErrorDialog';
import PageHeader from 'components/layout/PageHeader';
import { SkeletonHorizontalStack } from 'components/loading/SkeletonLoaders';
import { CreateCaptureI18N } from 'constants/i18n';
import dayjs from 'dayjs';
import { AnimalCaptureForm } from 'features/surveys/animals/profile/captures/capture-form/components/AnimalCaptureForm';
import {
isQualitativeMeasurementCreate,
Expand All @@ -29,10 +28,9 @@ import { Link as RouterLink } from 'react-router-dom';
export const defaultAnimalCaptureFormValues: ICreateCaptureRequest = {
capture: {
capture_id: '',
capture_timestamp: '',
capture_date: '',
capture_method_id: '',
capture_time: '',
release_timestamp: '',
release_date: '',
release_time: '',
capture_comment: '',
Expand Down Expand Up @@ -132,24 +130,17 @@ export const CreateCapturePage = () => {
}
: captureLocation;

const captureTime = values.capture.capture_time ? ` ${values.capture.capture_time}-07:00` : 'T00:00:00-07:00';
const captureTimestamp = dayjs(`${values.capture.capture_date}${captureTime}`).toDate();

// if release timestamp is null, use the capture timestamp, otherwise format it for critterbase
const releaseTime = values.capture.release_time ? ` ${values.capture.release_time}-07:00` : captureTime;
const releaseTimestamp = values.capture.release_date
? dayjs(`${values.capture.release_date}${releaseTime}`).toDate()
: captureTimestamp;

// Must create capture first to avoid foreign key constraints. Can't guarantee that the capture is
// inserted before the measurements/markings.
const captureResponse = await critterbaseApi.capture.createCapture({
critter_id: critterbaseCritterId,
capture_id: undefined,
capture_timestamp: captureTimestamp,
release_timestamp: releaseTimestamp,
capture_comment: values.capture.capture_comment ?? '',
release_comment: values.capture.release_comment ?? '',
capture_date: values.capture.capture_date,
capture_time: values.capture.capture_time || undefined,
release_date: values.capture.release_date || values.capture.capture_date,
release_time: values.capture.release_time || values.capture.capture_time || undefined,
capture_comment: values.capture.capture_comment || undefined,
release_comment: values.capture.release_comment || undefined,
capture_location: captureLocation,
release_location: releaseLocation ?? captureLocation
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import Typography from '@mui/material/Typography';
import PageHeader from 'components/layout/PageHeader';
import { SkeletonHorizontalStack } from 'components/loading/SkeletonLoaders';
import { EditCaptureI18N } from 'constants/i18n';
import dayjs from 'dayjs';
import { AnimalCaptureForm } from 'features/surveys/animals/profile/captures/capture-form/components/AnimalCaptureForm';
import { FormikProps } from 'formik';
import { APIError } from 'hooks/api/useAxios';
Expand Down Expand Up @@ -103,16 +102,6 @@ export const EditCapturePage = () => {
? formatLocation(values.capture.release_location)
: values.capture.capture_location;

// Format capture timestamp
const captureTime = values.capture.capture_time ? ` ${values.capture.capture_time}-07:00` : 'T00:00:00-07:00';
const captureTimestamp = dayjs(`${values.capture.capture_date}${captureTime}`).toDate();

// If release timestamp is null, use the capture timestamp, otherwise format release location
const releaseTime = (values.capture.release_time && ` ${values.capture.release_time}-07:00`) || 'T00:00:00-07:00';
const releaseTimestamp = values.capture.release_date
? dayjs(`${values.capture.release_date}${releaseTime}`).toDate()
: captureTimestamp;

const {
qualitativeMeasurementsForDelete,
quantitativeMeasurementsForDelete,
Expand Down Expand Up @@ -143,10 +132,12 @@ export const EditCapturePage = () => {
captures: [
{
capture_id: values.capture.capture_id,
capture_timestamp: captureTimestamp,
release_timestamp: releaseTimestamp,
capture_comment: values.capture.capture_comment ?? '',
release_comment: values.capture.release_comment ?? '',
capture_date: values.capture.capture_date,
capture_time: values.capture.capture_time || undefined,
release_date: values.capture.release_date || values.capture.capture_date || undefined,
release_time: values.capture.release_time || values.capture.capture_time || undefined,
capture_comment: values.capture.capture_comment || undefined,
release_comment: values.capture.release_comment || undefined,
capture_location: captureLocation,
release_location: releaseLocation ?? captureLocation,
critter_id: critterbaseCritterId
Expand Down Expand Up @@ -196,17 +187,14 @@ export const EditCapturePage = () => {
}
};

const [captureDate, captureTime] = dayjs(capture.capture_timestamp).format('YYYY-MM-DD HH:mm:ss').split(' ');
const [releaseDate, releaseTime] = dayjs(capture.release_timestamp).format('YYYY-MM-DD HH:mm:ss').split(' ');

// Initial formik values
const initialFormikValues: IEditCaptureRequest = {
capture: {
capture_id: capture.capture_id,
capture_method_id: capture.capture_method_id ?? '',
capture_comment: capture.capture_comment ?? '',
capture_timestamp: capture.capture_timestamp,
capture_date: captureDate,
capture_time: captureTime,
capture_date: capture.capture_date,
capture_time: capture.capture_time ?? '',
capture_location: {
type: 'Feature',
geometry: {
Expand All @@ -223,9 +211,8 @@ export const EditCapturePage = () => {
},
properties: {}
},
release_timestamp: capture.release_timestamp ?? '',
release_date: releaseDate,
release_time: releaseTime,
release_date: capture.release_date ?? '',
release_time: capture.release_time ?? '',
release_comment: capture.release_comment ?? ''
},
markings:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import { ISurveyCritter } from 'contexts/animalPageContext';
import { useSurveyContext } from 'hooks/useContext';
import { useState } from 'react';
import { Link as RouterLink } from 'react-router-dom';
import { combineDateTime } from 'utils/datetime';
import { getFormattedDate } from 'utils/Utils';
import { ICaptureWithSupplementaryData } from '../AnimalCaptureContainer';
import { AnimalCaptureCardDetailsContainer } from './capture-card-details/AnimalCaptureCardDetailsContainer';
Expand Down Expand Up @@ -159,7 +160,11 @@ export const AnimalCaptureCardContainer = (props: IAnimalCaptureCardContainer) =
}}>
<Stack gap={0.5} display="flex">
<Typography fontWeight={700}>
{getFormattedDate(DATE_FORMAT.MediumDateTimeFormat, capture.capture_timestamp)}&nbsp;
{getFormattedDate(
DATE_FORMAT.MediumDateTimeFormat,
combineDateTime(capture.capture_date, capture.capture_time)
)}
&nbsp;
</Typography>
{capture.capture_location.latitude && capture.capture_location.longitude && (
<Box>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export const AnimalCapturesMap = (props: IAnimalCapturesMapProps) => {
type: 'Point',
coordinates: [capture.capture_location.longitude, capture.capture_location.latitude]
},
properties: { captureId: capture.capture_id, date: capture.capture_timestamp }
properties: { captureId: capture.capture_id, date: capture.capture_date }
})) as Feature[];

const staticLayers: IStaticLayer[] = captureMapFeatures.map((feature, index) => ({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import Stack from '@mui/material/Stack';
import Typography from '@mui/material/Typography';
import { DATE_FORMAT } from 'constants/dateTimeFormats';
import { ICaptureWithSupplementaryData } from 'features/surveys/animals/profile/captures/AnimalCaptureContainer';
import { combineDateTime } from 'utils/datetime';
import { getFormattedDate } from 'utils/Utils';

interface ICaptureDetailsProps {
Expand All @@ -18,11 +19,12 @@ interface ICaptureDetailsProps {
export const CaptureDetails = (props: ICaptureDetailsProps) => {
const { capture } = props;

const captureTimestamp = capture.capture_timestamp;
const captureDate = capture.capture_date;
const captureTime = capture.capture_time;
const captureLocation = capture.capture_location;
const captureComment = capture.capture_comment;

if (!captureTimestamp && (!captureLocation.latitude || !captureLocation.longitude) && !captureComment) {
if (!captureDate && (!captureLocation.latitude || !captureLocation.longitude) && !captureComment) {
return null;
}

Expand All @@ -35,10 +37,10 @@ export const CaptureDetails = (props: ICaptureDetailsProps) => {
fontWeight={700}
fontSize="0.75rem"
sx={{ textTransform: 'uppercase', mb: 0.5 }}>
Capture time
Capture date
</Typography>
<Typography color="textSecondary" variant="body2">
{getFormattedDate(DATE_FORMAT.MediumDateTimeFormat, captureTimestamp)}
{getFormattedDate(DATE_FORMAT.MediumDateTimeFormat, combineDateTime(captureDate, captureTime))}
</Typography>
</Box>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import Stack from '@mui/material/Stack';
import Typography from '@mui/material/Typography';
import { DATE_FORMAT } from 'constants/dateTimeFormats';
import { ICaptureWithSupplementaryData } from 'features/surveys/animals/profile/captures/AnimalCaptureContainer';
import { combineDateTime } from 'utils/datetime';
import { getFormattedDate } from 'utils/Utils';

interface IReleaseDetailsProps {
Expand All @@ -18,28 +19,29 @@ interface IReleaseDetailsProps {
export const ReleaseDetails = (props: IReleaseDetailsProps) => {
const { capture } = props;

const releaseTimestamp = capture.release_timestamp;
const releaseDate = capture.release_date;
const releaseTime = capture.release_time;
const releaseLocation = capture.release_location;
const releaseComment = capture.release_comment;

if (!releaseTimestamp && !releaseLocation && !releaseComment) {
if (!releaseDate && !releaseLocation && !releaseComment) {
return null;
}

return (
<Stack gap={2}>
<Stack direction="row" spacing={3}>
{releaseTimestamp && (
{releaseDate && (
<Box>
<Typography
color="textSecondary"
fontWeight={700}
fontSize="0.75rem"
sx={{ textTransform: 'uppercase', mb: 0.5 }}>
Release time
Release date
</Typography>
<Typography color="textSecondary" variant="body2">
{getFormattedDate(DATE_FORMAT.MediumDateTimeFormat, releaseTimestamp)}
{getFormattedDate(DATE_FORMAT.MediumDateTimeFormat, combineDateTime(releaseDate, releaseTime))}
</Typography>
</Box>
)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,19 +135,21 @@ export const EditMortalityPage = () => {

// Update existing critter information
const response = await critterbaseApi.critters.bulkUpdate({
mortality: {
critter_id: critterbaseCritterId,
mortality_id: values.mortality.mortality_id,
location: mortalityLocation,
mortality_timestamp: mortalityTimestamp,
mortality_comment: values.mortality.mortality_comment,
proximate_cause_of_death_id: values.mortality.proximate_cause_of_death_id,
proximate_cause_of_death_confidence: values.mortality.proximate_cause_of_death_confidence,
proximate_predated_by_itis_tsn: values.mortality.proximate_predated_by_itis_tsn,
ultimate_cause_of_death_id: values.mortality.ultimate_cause_of_death_id,
ultimate_cause_of_death_confidence: values.mortality.ultimate_cause_of_death_confidence,
ultimate_predated_by_itis_tsn: values.mortality.ultimate_predated_by_itis_tsn
},
mortalities: [
{
critter_id: critterbaseCritterId,
mortality_id: values.mortality.mortality_id,
location: mortalityLocation,
mortality_timestamp: mortalityTimestamp,
mortality_comment: values.mortality.mortality_comment,
proximate_cause_of_death_id: values.mortality.proximate_cause_of_death_id,
proximate_cause_of_death_confidence: values.mortality.proximate_cause_of_death_confidence,
proximate_predated_by_itis_tsn: values.mortality.proximate_predated_by_itis_tsn,
ultimate_cause_of_death_id: values.mortality.ultimate_cause_of_death_id,
ultimate_cause_of_death_confidence: values.mortality.ultimate_cause_of_death_confidence,
ultimate_predated_by_itis_tsn: values.mortality.ultimate_predated_by_itis_tsn
}
],
markings: [...markingsForUpdate, ...markingsForDelete],
qualitative_measurements: [...qualitativeMeasurementsForUpdate, ...qualitativeMeasurementsForDelete],
quantitative_measurements: [...quantitativeMeasurementsForUpdate, ...quantitativeMeasurementsForDelete]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -389,7 +389,7 @@ export const AnimalSection = (props: IAnimalSectionProps) => {
{props.critter.captures.map((capture) => (
<Collapse key={capture.capture_id}>
<EditDeleteStubCard
header={formatDate(new Date(capture.capture_timestamp))}
header={formatDate(new Date(capture.capture_date))}
subHeader={formatSubHeader({
Latitude: capture.capture_location?.latitude,
Longitude: capture.capture_location?.longitude
Expand Down
19 changes: 10 additions & 9 deletions app/src/features/surveys/view/survey-animals/animal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { DATE_LIMIT } from 'constants/dateTimeFormats';
import { default as dayjs } from 'dayjs';
import {
ICritterDetailedResponse,
ICritterSimpleResponse,
IQualitativeMeasurementCreate,
IQualitativeMeasurementUpdate,
IQuantitativeMeasurementCreate,
Expand Down Expand Up @@ -156,8 +155,10 @@ export const CreateCritterCaptureSchema = yup.object({
capture_location: LocationSchema.required(),
release_location: LocationSchema.optional().default(undefined),
capture_comment: yup.string().optional(),
capture_timestamp: dateSchema.required(req),
release_timestamp: dateSchema.optional(),
capture_date: yup.string().required(req),
capture_time: yup.string().optional().nullable(),
release_date: yup.string().optional().nullable(),
release_time: yup.string().optional().nullable(),
release_comment: yup.string().optional()
});

Expand Down Expand Up @@ -235,27 +236,27 @@ export type ICreateCritterFamily = InferType<typeof CreateCritterFamilySchema>;
export type ICreateCritterMortality = InferType<typeof CreateCritterMortalitySchema>;

/**
* Adding data to a critter in bulk
* Adding data to a critters in bulk
*/
export type IBulkCreate = {
critter?: ICritterSimpleResponse;
critters?: ICreateCritter[];
qualitative_measurements?: IQualitativeMeasurementCreate[];
quantitative_measurements?: IQuantitativeMeasurementCreate[];
capture?: ICreateCritterCapture[];
captures?: ICreateCritterCapture[];
mortality?: ICreateCritterMortality;
markings?: ICreateCritterMarking[];
collections?: ICreateCritterCollectionUnit[];
};

/**
* Editing data for a critter in bulk
* Editing data for a critters in bulk
*/
export type IBulkUpdate = {
critter?: ICritterSimpleResponse;
critters?: ICreateCritter[];
qualitative_measurements?: IQualitativeMeasurementUpdate[];
quantitative_measurements?: IQuantitativeMeasurementUpdate[];
captures?: ICreateCritterCapture[];
mortality?: ICreateCritterMortality;
mortalities?: ICreateCritterMortality[];
markings?: ICreateCritterMarking[];
collections?: ICreateCritterCollectionUnit[];
};
Original file line number Diff line number Diff line change
Expand Up @@ -103,8 +103,10 @@ export const CaptureAnimalForm = (props: AnimalFormProps<ICaptureResponse>) => {
coordinate_uncertainty_unit: props?.formObject?.release_location?.coordinate_uncertainty_unit ?? 'm'
}
: undefined,
capture_timestamp: props?.formObject?.capture_timestamp as unknown as Date,
release_timestamp: (props?.formObject?.release_timestamp as unknown as Date) ?? undefined,
capture_date: props?.formObject?.capture_date ?? '',
capture_time: props?.formObject?.capture_date ?? '',
release_date: props?.formObject?.release_date ?? '',
release_time: props?.formObject?.release_time ?? '',
capture_comment: props?.formObject?.capture_comment ?? undefined,
release_comment: props?.formObject?.release_comment ?? undefined
},
Expand Down
Loading

0 comments on commit 3225ad3

Please sign in to comment.