Skip to content
Closed
Show file tree
Hide file tree
Changes from all 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
9 changes: 6 additions & 3 deletions ui/src/data-services/models/occurrence-details.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,8 @@ export class OccurrenceDetails extends Occurrence {
.map((i: any) => {
const taxon = new Taxon(i.taxon)
const overridden = i.withdrawn
const applied = taxon.id === this.determinationTaxon.id
const applied =
!!this.determinationTaxon && taxon.id === this.determinationTaxon.id

const identification: HumanIdentification = {
id: `${i.id}`,
Expand All @@ -82,8 +83,10 @@ export class OccurrenceDetails extends Occurrence {
.sort(sortByDate)
.map((p: any) => {
const taxon = new Taxon(p.taxon)
const overridden = taxon.id !== this.determinationTaxon.id
const applied = taxon.id === this.determinationTaxon.id
const overridden =
!this.determinationTaxon || taxon.id !== this.determinationTaxon.id
const applied =
!!this.determinationTaxon && taxon.id === this.determinationTaxon.id

const prediction: MachinePrediction = {
id: `${p.id}`,
Expand Down
27 changes: 18 additions & 9 deletions ui/src/data-services/models/occurrence.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,15 @@ export type ServerOccurrence = any // TODO: Update this type

export class Occurrence {
protected readonly _occurrence: ServerOccurrence
private readonly _determinationTaxon: Taxon
private readonly _determinationTaxon: Taxon | undefined
private readonly _images: { src: string }[] = []

public constructor(occurrence: ServerOccurrence) {
this._occurrence = occurrence

this._determinationTaxon = new Taxon(occurrence.determination_details.taxon)
this._determinationTaxon = occurrence.determination_details?.taxon
? new Taxon(occurrence.determination_details.taxon)
: undefined

this._images = occurrence.detection_images
.filter((src: string) => !!src.length)
Expand Down Expand Up @@ -49,8 +51,10 @@ export class Occurrence {
return this._occurrence.deployment?.name
}

get determinationId(): string {
return `${this._occurrence.determination.id}`
get determinationId(): string | undefined {
return this._occurrence.determination
? `${this._occurrence.determination.id}`
: undefined
}

get determinationIdentificationId(): string | undefined {
Expand All @@ -70,7 +74,7 @@ export class Occurrence {
}

get determinationScore(): number | undefined {
const score = this._occurrence.determination_details.score
const score = this._occurrence.determination_details?.score

if (score || score === 0) {
return score
Expand All @@ -89,17 +93,17 @@ export class Occurrence {
return undefined
}

get determinationTaxon(): Taxon {
get determinationTaxon(): Taxon | undefined {
return this._determinationTaxon
}

get determinationVerified(): boolean {
return !!this._occurrence.determination_details.identification
return !!this._occurrence.determination_details?.identification
}

get determinationVerifiedBy() {
const verifiedBy =
this._occurrence.determination_details.identification?.user
this._occurrence.determination_details?.identification?.user

return verifiedBy
? {
Expand All @@ -116,7 +120,8 @@ export class Occurrence {
}

get displayName(): string {
return `${this.determinationTaxon.name} #${this.id}`
const name = this.determinationTaxon?.name ?? 'Unknown'
return `${name} #${this.id}`
}

get firstAppearanceTimestamp(): string {
Expand Down Expand Up @@ -180,6 +185,10 @@ export class Occurrence {
return false
}

if (!this.determinationTaxon) {
return false
}

return (
identificationTaxonId === this.determinationTaxon.id &&
identificationUserId === userId
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,9 @@ export const MachinePrediction = ({
isLoading={isLoading}
/>
{topN?.map(({ score, taxon }) => {
const applied = taxon.id === occurrence.determinationTaxon.id
const applied =
!!occurrence.determinationTaxon &&
taxon.id === occurrence.determinationTaxon.id

return (
<MachinePredictionDetails
Expand Down
36 changes: 21 additions & 15 deletions ui/src/pages/occurrence-details/occurrence-details.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -136,20 +136,26 @@ export const OccurrenceDetails = ({
<meta name="og:image" content={occurrence.images[0]?.src} />
</Helmet>
<div className={styles.header}>
<TaxonDetails
onTaxonClick={(id) =>
navigate(
getAppRoute({
to: APP_ROUTES.TAXON_DETAILS({
projectId: projectId as string,
taxonId: id,
}),
})
)
}
size="lg"
taxon={occurrence.determinationTaxon}
/>
{occurrence.determinationTaxon ? (
<TaxonDetails
onTaxonClick={(id) =>
navigate(
getAppRoute({
to: APP_ROUTES.TAXON_DETAILS({
projectId: projectId as string,
taxonId: id,
}),
})
)
}
size="lg"
taxon={occurrence.determinationTaxon}
/>
) : (
<span className="body-lg font-medium text-muted">
{translate(STRING.UNKNOWN)}
</span>
)}
<div className={styles.taxonActions}>
{occurrence.determinationScore !== undefined ? (
<BasicTooltip
Expand All @@ -169,7 +175,7 @@ export const OccurrenceDetails = ({
/>
</BasicTooltip>
) : null}
{canUpdate && (
{canUpdate && occurrence.determinationTaxon && (
<>
<Agree
agreed={userInfo ? occurrence.userAgreed(userInfo.id) : false}
Expand Down
10 changes: 6 additions & 4 deletions ui/src/pages/occurrences/occurrence-actions.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { IdentificationFieldValues } from 'data-services/hooks/identifications/types'
import { useCreateIdentifications } from 'data-services/hooks/identifications/useCreateIdentifications'
import { Occurrence } from 'data-services/models/occurrence'
import { Taxon } from 'data-services/models/taxa'
import { BasicTooltip } from 'design-system/components/tooltip/basic-tooltip'
import { AlertCircleIcon, CheckIcon, Loader2Icon } from 'lucide-react'
import { Button } from 'nova-ui-kit'
Expand Down Expand Up @@ -40,9 +41,9 @@ export const OccurrenceActions = ({
/>
<IdQuickActions
occurrenceIds={occurrences.map((occurrence) => occurrence.id)}
occurrenceTaxa={occurrences.map(
(occurrence) => occurrence.determinationTaxon
)}
occurrenceTaxa={occurrences
.map((occurrence) => occurrence.determinationTaxon)
.filter((taxon): taxon is Taxon => !!taxon)}
/>
</div>
)
Expand All @@ -69,13 +70,14 @@ const Agree = ({

return !agreed
})
.filter((occurrence) => !!occurrence.determinationTaxon)
.map((occurrence) => ({
agreeWith: {
identificationId: occurrence.determinationIdentificationId,
predictionId: occurrence.determinationPredictionId,
},
occurrenceId: occurrence.id,
taxonId: occurrence.determinationTaxon.id,
taxonId: occurrence.determinationTaxon!.id,
})),
[occurrences]
)
Expand Down
10 changes: 8 additions & 2 deletions ui/src/pages/occurrences/occurrence-columns.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -195,9 +195,15 @@ const TaxonCell = ({
<BasicTableCell style={{ minWidth: '320px' }}>
<div className={styles.taxonCellContent}>
<Link to={detailsRoute}>
<TaxonDetails compact taxon={item.determinationTaxon} />
{item.determinationTaxon ? (
<TaxonDetails compact taxon={item.determinationTaxon} />
) : (
<span className="body-base text-muted">
{translate(STRING.UNKNOWN)}
</span>
)}
</Link>
{showQuickActions && canUpdate && (
{showQuickActions && canUpdate && item.determinationTaxon && (
<div className={styles.taxonActions}>
<Agree
agreed={agreed}
Expand Down
13 changes: 7 additions & 6 deletions ui/src/pages/occurrences/occurrence-gallery.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@ import { STRING, translate } from 'utils/language'
import { UserPermission } from 'utils/user/types'
import { useUserInfo } from 'utils/user/userInfoContext'

export const isGenusOrBelow = (taxon: Taxon) =>
taxon.rank === 'GENUS' ||
taxon.rank === 'SPECIES' ||
taxon.rank === 'SUBSPECIES'
export const isGenusOrBelow = (taxon?: Taxon) =>
taxon?.rank === 'GENUS' ||
taxon?.rank === 'SPECIES' ||
taxon?.rank === 'SUBSPECIES'

export const OccurrenceGallery = ({
error,
Expand Down Expand Up @@ -158,7 +158,8 @@ export const OccurrenceGallery = ({
}
)}
>
{item.determinationTaxon.name}
{item.determinationTaxon?.name ??
translate(STRING.UNKNOWN)}
</span>
</Link>
</div>
Expand All @@ -181,7 +182,7 @@ export const OccurrenceGallery = ({
/>
</BasicTooltip>
) : null}
{!isSelecting && canUpdate && (
{!isSelecting && canUpdate && item.determinationTaxon && (
<>
<Agree
agreed={agreed}
Expand Down
Loading