Skip to content

Commit

Permalink
fix vessel event interaction tooltip
Browse files Browse the repository at this point in the history
  • Loading branch information
j8seangel committed Apr 10, 2024
1 parent 3da19b4 commit c186d27
Show file tree
Hide file tree
Showing 6 changed files with 43 additions and 76 deletions.
8 changes: 6 additions & 2 deletions apps/fishing-map/features/map/popups/PopupWrapper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,11 @@ import { useSelector } from 'react-redux'
import { DataviewCategory, DataviewType } from '@globalfishingwatch/api-types'
import { IconButton, Spinner } from '@globalfishingwatch/ui-components'
import { InteractionEvent } from '@globalfishingwatch/deck-layer-composer'
import { ContextFeature, FourwingsPickingObject } from '@globalfishingwatch/deck-layers'
import {
ContextFeature,
FourwingsPickingObject,
VesselEventPickingObject,
} from '@globalfishingwatch/deck-layers'
import { TooltipEvent } from 'features/map/map.hooks'
import { POPUP_CATEGORY_ORDER } from 'data/config'
import { useTimeCompareTimeDescription } from 'features/reports/reports-timecomparison.hooks'
Expand Down Expand Up @@ -239,7 +243,7 @@ function PopupWrapper({
return (
<VesselEventsLayers
key={featureCategory}
features={features}
features={features as VesselEventPickingObject[]}
showFeaturesDetails={type === 'click'}
/>
)
Expand Down
31 changes: 6 additions & 25 deletions apps/fishing-map/features/map/popups/VesselEventsLayers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { useTranslation } from 'react-i18next'
import { groupBy } from 'lodash'
import { useSelector } from 'react-redux'
import { Icon } from '@globalfishingwatch/ui-components'
import { EventTypes, IdentityVessel, SelfReportedInfo } from '@globalfishingwatch/api-types'
import { IdentityVessel, SelfReportedInfo } from '@globalfishingwatch/api-types'
import { VesselEventPickingObject } from '@globalfishingwatch/deck-layers'
import { getEventDescriptionComponent } from 'utils/events'
import { selectVisibleResources } from 'features/resources/resources.selectors'
Expand All @@ -26,12 +26,12 @@ function VesselEventsTooltipSection({
const maxFeatures = overflows ? features.slice(0, MAX_TOOLTIP_LIST) : features
return groupBy(maxFeatures, 'properties.vesselId')
}, [overflows, features])
console.log('🚀 ~ featuresByType ~ featuresByType:', featuresByType)

const resources = useSelector(selectVisibleResources)

const vesselNamesByType = useMemo(() => {
return Object.values(featuresByType).map((features) => {
const vesselId = features[0].properties?.vesselId
const vesselId = features[0]?.vesselId
const vesselResource = Object.values(resources).find((resource) => {
return (resource.data as IdentityVessel)?.selfReportedInfo?.some(
(identity: SelfReportedInfo) => vesselId?.includes(identity.id)
Expand All @@ -57,33 +57,14 @@ function VesselEventsTooltipSection({
{vesselNamesByType[index] && showFeaturesDetails && (
<h3 className={styles.popupSectionTitle}>{vesselNamesByType[index]}</h3>
)}
{/* {featureByType.map((feature, index) => {
const {
start,
end,
type,
vesselName,
encounterVesselName,
encounterVesselId,
portName,
portFlag,
} = feature.properties
const { description, DescriptionComponent } = getEventDescriptionComponent({
start: start as any,
end: end as any,
type: type as EventTypes,
mainVesselName: vesselName,
encounterVesselName,
encounterVesselId,
portName,
portFlag,
})
{featureByType.map((feature, index) => {
const { description, DescriptionComponent } = getEventDescriptionComponent(feature)
return (
<div key={index} className={styles.row}>
{showFeaturesDetails ? DescriptionComponent : description}
</div>
)
})} */}
})}
{overflows && (
<div className={styles.vesselsMore}>
+ {features.length - MAX_TOOLTIP_LIST} {t('common.more', 'more')}
Expand Down
61 changes: 19 additions & 42 deletions apps/fishing-map/utils/events.tsx
Original file line number Diff line number Diff line change
@@ -1,27 +1,15 @@
import { Fragment } from 'react'
import { DateTime, Duration } from 'luxon'
import { Trans } from 'react-i18next'
import { EventTypes } from '@globalfishingwatch/api-types'
import { ApiEvent, EventTypes } from '@globalfishingwatch/api-types'
import { t } from 'features/i18n/i18n'
import { formatI18nDate } from 'features/i18n/i18nDate'
import { EVENTS_COLORS } from 'data/config'
import { formatInfoField } from 'utils/info'
import VesselPin from 'features/vessel/VesselPin'
import { SupportedDateType, getUTCDateTime } from './dates'

type EventProps = {
start: number
end: number
type: EventTypes
mainVesselName?: string
encounterVesselName?: string
encounterVesselId?: string
className?: string
portName?: string
portFlag?: string
}

export const getEventColors = ({ type }: { type: EventProps['type'] }) => {
export const getEventColors = ({ type }: { type: ApiEvent['type'] }) => {
const colorKey = type
// TODO not supporting authorization status yet
// if (event.type === 'encounter' && showAuthorizationStatus) {
Expand Down Expand Up @@ -80,16 +68,17 @@ export const getEventDescription = ({
start,
end,
type,
mainVesselName,
encounterVesselName,
portName,
portFlag,
}: EventProps) => {
vessel,
encounter,
port_visit,
}: ApiEvent) => {
const time = getTimeLabels({ start, end })
let description: string
let descriptionGeneric
let descriptionGeneric: string
switch (type) {
case EventTypes.Encounter: {
const mainVesselName = vessel?.name
const encounterVesselName = encounter?.vessel?.name
if (mainVesselName && encounterVesselName) {
description = t(
'event.encounterActionWithVessels',
Expand All @@ -116,7 +105,9 @@ export const getEventDescription = ({
descriptionGeneric = t('event.encounter')
break
}
case EventTypes.Port:
case EventTypes.Port: {
const portName = port_visit?.intermediateAnchorage.name
const portFlag = port_visit?.intermediateAnchorage.flag
if (portName && portFlag) {
const portLabel = [
formatInfoField(portName, 'port'),
Expand All @@ -132,6 +123,7 @@ export const getEventDescription = ({
}
descriptionGeneric = t('event.port')
break
}
case EventTypes.Loitering:
description = t(
'event.loiteringAction',
Expand All @@ -155,28 +147,13 @@ export const getEventDescription = ({
}
}

export const getEventDescriptionComponent = ({
start,
end,
type,
mainVesselName,
encounterVesselName,
encounterVesselId,
className,
portName,
portFlag,
}: EventProps) => {
let DescriptionComponent
export const getEventDescriptionComponent = (event: ApiEvent, className = '') => {
const { start, end, type, encounter } = event
const { color, colorLabels } = getEventColors({ type })
const { descriptionGeneric, description } = getEventDescription({
start,
end,
type,
mainVesselName,
encounterVesselName,
portName,
portFlag,
})
let DescriptionComponent
const encounterVesselName = encounter?.vessel?.name
const encounterVesselId = encounter?.vessel?.id
const { descriptionGeneric, description } = getEventDescription(event)
if (type === EventTypes.Encounter && encounterVesselName && encounterVesselId) {
const time = getTimeLabels({ start, end })
DescriptionComponent = (
Expand Down
5 changes: 5 additions & 0 deletions libs/deck-layer-composer/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ import {
RulerPickingObject,
RulersLayer,
UserContextPickingObject,
VesselEventPickingInfo,
VesselEventPickingObject,
VesselLayer,
} from '@globalfishingwatch/deck-layers'

export const DECK_LAYER_LIFECYCLE = {
Expand Down Expand Up @@ -63,9 +66,11 @@ export type DeckLayerInteractionFeature =
| UserContextPickingObject
| ClusterPickingObject
| RulerPickingObject
| VesselEventPickingObject

export type DeckLayerInteractionPickingInfo =
| (FourwingsPickingInfo & { layer: FourwingsLayer })
| (ContextPickingInfo & { layer: ContextLayer })
| (ClusterPickingInfo & { layer: ClusterLayer })
| (RulerPickingInfo & { layer: RulersLayer })
| (VesselEventPickingInfo & { layer: VesselLayer })
8 changes: 3 additions & 5 deletions libs/deck-layers/src/layers/vessel/VesselLayer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,13 +45,11 @@ export class VesselLayer extends CompositeLayer<VesselLayerProps & LayerProps> {
getPickingInfo = ({ info }: { info: VesselEventPickingInfo }): VesselEventPickingInfo => {
if (!info.object) {
info.object = {} as VesselEventPickingObject
info.object.properties = {} as VesselEventProperties
}
info.object.title = this.props.name
info.object.vesselId = this.props.id
info.object.category = DataviewCategory.Vessels
info.object.properties = {
...info.object.properties,
vesselId: this.props.id,
}
info.object.color = deckToHexColor(this.props.color)
// info.object.getDetail = async () => {
// return GFWAPI.fetch(`/events/${info.object?.properties.id}`)
// }
Expand Down
6 changes: 4 additions & 2 deletions libs/deck-layers/src/layers/vessel/vessel.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,10 @@ export type _VesselLayerProps = {
// export type VesselTrackPickingInfo = PickingInfo<VesselTrackPickingObject, { tile?: Tile2DHeader }>

export type VesselEventProperties = ApiEvent & {
color: string
title: string
vesselId: string
}
export type VesselEventFeature = Feature<Point, VesselEventProperties>
export type VesselEventPickingObject = VesselEventFeature & BasePickingInfo

export type VesselEventPickingObject = VesselEventProperties & BasePickingInfo
export type VesselEventPickingInfo = PickingInfo<VesselEventPickingObject, { tile?: Tile2DHeader }>

0 comments on commit c186d27

Please sign in to comment.