Skip to content

Commit

Permalink
Merge branch 'fishing-map/vessel-profile-3' into fishing-map/vessel-p…
Browse files Browse the repository at this point in the history
…rofile-3-feedback-javi-1
  • Loading branch information
weberjavi committed Oct 1, 2024
2 parents 23bcea0 + 97d81bc commit 5f73774
Show file tree
Hide file tree
Showing 35 changed files with 362 additions and 196 deletions.
25 changes: 12 additions & 13 deletions apps/fishing-map/features/reports/events/VGREvents.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@ import VGREventsVesselsTable from 'features/reports/events/VGREventsVesselsTable
import ReportVesselsFilter from 'features/reports/activity/vessels/ReportVesselsFilter'
import { COLOR_PRIMARY_BLUE } from 'features/app/app.config'
import { VESSEL_GROUP_ENCOUNTER_EVENTS_ID } from 'features/reports/vessel-groups/vessel-group-report.dataviews'
import {
selectVGREventsVessels,
selectVGREventsVesselsFlags,
selectVGREventsVesselsGrouped,
} from 'features/reports/events/vgr-events.selectors'
import styles from './VGREvents.module.css'

function VGREvents() {
Expand All @@ -32,6 +37,9 @@ function VGREvents() {
const filter = useSelector(selectVGREventsVesselFilter)
const eventsDataview = useSelector(selectVGREventsSubsectionDataview)
const vesselsGroupByProperty = useSelector(selectVGREventsVesselsProperty)
const vessels = useSelector(selectVGREventsVessels)
const vesselFlags = useSelector(selectVGREventsVesselsFlags)
const vesselGroups = useSelector(selectVGREventsVesselsGrouped)

const { start, end } = useTimerangeConnect()
const startMillis = DateTime.fromISO(start).toMillis()
Expand All @@ -40,9 +48,8 @@ function VGREvents() {

const response = useGetVesselGroupEventsStatsQuery(
{
includes: ['TIME_SERIES', 'EVENTS_GROUPED'],
includes: ['TIME_SERIES'],
dataview: eventsDataview!,
groupBy: vesselsGroupByProperty.toUpperCase(),
vesselGroupId,
interval,
start,
Expand All @@ -61,14 +68,6 @@ function VGREvents() {
color = 'rgb(247 222 110)' // Needed to make the graph lines more visible
}

const filteredGroups = useMemo(() => {
if (!data) return null
if (!filter) return data.groups
const [filterProperty, filterValue] = filter.split(':')
if (vesselsGroupByProperty !== filterProperty) return data.groups
return data.groups.filter(({ name }) => name === filterValue)
}, [data, filter, vesselsGroupByProperty])

if (error || !data || isLoading) {
return (
<div className={styles.container}>
Expand All @@ -88,8 +87,8 @@ function VGREvents() {
t('vesselGroup.summaryEvents', {
defaultValue:
'<strong>{{vessels}} vessels</strong> from <strong>{{flags}} flags</strong> had <strong>{{activityQuantity}} {{activityUnit}}</strong> globally between <strong>{{start}}</strong> and <strong>{{end}}</strong>',
vessels: data.groups.reduce((acc, group) => acc + group.value, 0),
flags: data.groups.length,
vessels: vessels?.length,
flags: vesselFlags,
activityQuantity: data.timeseries.reduce((acc, group) => acc + group.value, 0),
activityUnit: `${eventsDataview?.datasets?.[0]?.subcategory?.toLowerCase()} ${t(
'common.events',
Expand Down Expand Up @@ -118,7 +117,7 @@ function VGREvents() {
<VGREventsVesselPropertySelector />
</div>
<VesselGroupReportVesselsGraph
data={filteredGroups as VesselGroupEventsStatsResponseGroups}
data={vesselGroups as VesselGroupEventsStatsResponseGroups}
color={eventsDataview?.config?.color}
property={vesselsGroupByProperty}
filterQueryParam="vGREventsVesselFilter"
Expand Down
46 changes: 45 additions & 1 deletion apps/fishing-map/features/reports/events/vgr-events.selectors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
selectVesselGroupEventsVessels,
VesselGroupEventsVesselsParams,
} from 'queries/vessel-group-events-stats-api'
import { groupBy } from 'es-toolkit'
import { selectVGRData } from 'features/reports/vessel-groups/vessel-group-report.slice'
import { getSearchIdentityResolved } from 'features/vessel/vessel.utils'
import { selectTimeRange } from 'features/app/selectors/app.timebar.selectors'
Expand All @@ -12,10 +13,13 @@ import {
selectVGREventsResultsPerPage,
selectVGREventsVesselFilter,
selectVGREventsVesselPage,
selectVGREventsVesselsProperty,
} from 'features/reports/vessel-groups/vessel-group.config.selectors'
import { getVesselsFiltered } from 'features/reports/areas/area-reports.utils'
import { REPORT_FILTER_PROPERTIES } from 'features/reports/vessel-groups/vessels/vessel-group-report-vessels.selectors'
import { selectVGREventsSubsectionDataview } from 'features/reports/vessel-groups/vessel-group-report.selectors'
import { OTHER_CATEGORY_LABEL } from 'features/reports/vessel-groups/vessel-group-report.config'
import { formatInfoField } from 'utils/info'

export const selectFetchVGREventsVesselsParams = createSelector(
[selectTimeRange, selectReportVesselGroupId, selectVGREventsSubsectionDataview],
Expand Down Expand Up @@ -54,10 +58,16 @@ export const selectVGREventsVessels = createSelector(
return []
}
const identity = getSearchIdentityResolved(vessel.identity!)

return {
...vesselWithEvents,
...identity,
geartype: identity.geartypes,
geartype:
(identity.geartypes || [])
.sort()
.map((g) => formatInfoField(g, 'geartype'))
.join(', ') || OTHER_CATEGORY_LABEL,
flagTranslated: formatInfoField(identity.flag, 'flag'),
}
})
return insightVessels.sort((a, b) => b.numEvents - a.numEvents)
Expand All @@ -80,6 +90,40 @@ export const selectVGREventsVesselsPaginated = createSelector(
}
)

export const selectVGREventsVesselsGrouped = createSelector(
[selectVGREventsVesselsFiltered, selectVGREventsVesselsProperty],
(vessels, property) => {
if (!vessels?.length) return []
const groups: { name: string; value: number }[] = Object.entries(
groupBy(vessels, (vessel) => {
return property === 'flag' ? (vessel.flagTranslated as string) : (vessel.geartype as string)
})
)
.map(([key, value]) => ({ name: key, property: key, value: value.length }))
.sort((a, b) => b.value - a.value)

if (groups.length <= 9) {
return groups
}

const firstNine = groups.slice(0, 9)
const other = groups.slice(9)

return [
...firstNine,
{
name: OTHER_CATEGORY_LABEL,
property: other.map((g) => g.name).join(', '),
value: other.reduce((acc, group) => acc + group.value, 0),
},
]
}
)
export const selectVGREventsVesselsFlags = createSelector([selectVGREventsVessels], (vessels) => {
if (!vessels?.length) return []
return Object.keys(groupBy(vessels, (v) => v.flag)).length
})

export const selectVGREventsVesselsPagination = createSelector(
[
selectVGREventsVesselsPaginated,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,15 @@
display: none;
}

.summary {
color: var(--color-secondary-blue);
}

.summary strong {
font-weight: 400;
color: var(--color-primary-blue);
}

@media print {
.actions {
display: none;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import { useCallback } from 'react'
import { useTranslation } from 'react-i18next'
import cx from 'classnames'
import { useSelector } from 'react-redux'
import { DateTime } from 'luxon'
import parse from 'html-react-parser'
import { Button, Icon, IconButton } from '@globalfishingwatch/ui-components'
import { useSmallScreen } from '@globalfishingwatch/react-hooks'
import { useAppDispatch } from 'features/app/app.hooks'
Expand All @@ -15,6 +17,12 @@ import {
import { formatInfoField } from 'utils/info'
import { useLocationConnect } from 'routes/routes.hook'
import { selectHasOtherVesselGroupDataviews } from 'features/dataviews/selectors/dataviews.selectors'
import {
selectVGRUniqVessels,
selectVGRVesselsFlags,
selectVGRVesselsTimeRange,
} from 'features/reports/vessel-groups/vessels/vessel-group-report-vessels.selectors'
import { formatI18nDate } from 'features/i18n/i18nDate'
import styles from './VesselGroupReportTitle.module.css'
import { VesselGroupReport } from './vessel-group-report.slice'
import { selectViewOnlyVesselGroup } from './vessel-group.config.selectors'
Expand All @@ -31,6 +39,9 @@ export default function VesselGroupReportTitle({ vesselGroup, loading }: ReportT
const isSmallScreen = useSmallScreen()
const viewOnlyVesselGroup = useSelector(selectViewOnlyVesselGroup)
const hasOtherLayers = useSelector(selectHasOtherVesselGroupDataviews)
const vessels = useSelector(selectVGRUniqVessels)
const timeRange = useSelector(selectVGRVesselsTimeRange)
const flags = useSelector(selectVGRVesselsFlags)

const onEditClick = useCallback(() => {
if (vesselGroup?.id || !vesselGroup?.vessels?.length) {
Expand Down Expand Up @@ -77,6 +88,24 @@ export default function VesselGroupReportTitle({ vesselGroup, loading }: ReportT
<h1 className={styles.title} data-test="report-title">
{formatInfoField(vesselGroup.name, 'name')}
</h1>
{timeRange && vessels && flags && (
<h2 className={styles.summary}>
{parse(
t('vesselGroup.summary', {
defaultValue:
'<strong>{{vessels}} vessels</strong> from <strong>{{flags}} flags</strong> active from <strong>{{start}}</strong> to <strong>{{end}}</strong>',
vessels: vessels?.length,
flags: flags?.size,
start: formatI18nDate(timeRange.start, {
format: DateTime.DATE_MED,
}),
end: formatI18nDate(timeRange.end, {
format: DateTime.DATE_MED,
}),
})
)}
</h2>
)}
</div>
<a className={styles.reportLink} href={window.location.href}>
{t('vesselGroupReport.linkToReport', 'Check the vessel group report here')}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,3 @@
.container {
padding: var(--space-M);
}

.summary {
font: var(--font-L);
color: var(--color-secondary-blue);
margin-bottom: var(--space-M);
}

.summary strong {
font-weight: 400;
color: var(--color-primary-blue);
}
Original file line number Diff line number Diff line change
@@ -1,15 +1,6 @@
import { useSelector } from 'react-redux'
import { DateTime } from 'luxon'
import { useTranslation } from 'react-i18next'
import parse from 'html-react-parser'
import ReportVesselsFilter from 'features/reports/activity/vessels/ReportVesselsFilter'
import {
selectVGRUniqVessels,
selectVGRVesselsFlags,
selectVGRVesselsGraphDataGrouped,
selectVGRVesselsTimeRange,
} from 'features/reports/vessel-groups/vessels/vessel-group-report-vessels.selectors'
import { formatI18nDate } from 'features/i18n/i18nDate'
import { selectVGRVesselsGraphDataGrouped } from 'features/reports/vessel-groups/vessels/vessel-group-report-vessels.selectors'
import {} from 'features/reports/vessel-groups/vessel-group-report.selectors'
import {
selectVGRVesselFilter,
Expand All @@ -24,34 +15,12 @@ import VesselGroupReportVesselsTable from './VesselGroupReportVesselsTable'
import styles from './VesselGroupReportVessels.module.css'

function VesselGroupReportVessels() {
const { t } = useTranslation()
const vessels = useSelector(selectVGRUniqVessels)
const subsection = useSelector(selectVGRVesselsSubsection)
const reportDataview = useSelector(selectVGRDataview)
const timeRange = useSelector(selectVGRVesselsTimeRange)
const flags = useSelector(selectVGRVesselsFlags)
const filter = useSelector(selectVGRVesselFilter)
const data = useSelector(selectVGRVesselsGraphDataGrouped)
return (
<div className={styles.container}>
{timeRange && vessels && flags && (
<h2 className={styles.summary}>
{parse(
t('vesselGroup.summary', {
defaultValue:
'This group contains <strong>{{vessels}} vessels</strong> from <strong>{{flags}} flags</strong> active from <strong>{{start}}</strong> to <strong>{{end}}</strong>',
vessels: vessels?.length,
flags: flags?.size,
start: formatI18nDate(timeRange.start, {
format: DateTime.DATE_MED,
}),
end: formatI18nDate(timeRange.end, {
format: DateTime.DATE_MED,
}),
})
)}
</h2>
)}
<VesselGroupReportVesselsGraphSelector />
<VesselGroupReportVesselsGraph
data={data}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
VGRVesselsSubsection,
} from 'features/vessel-groups/vessel-groups.types'
import { COLOR_PRIMARY_BLUE } from 'features/app/app.config'
import { OTHER_CATEGORY_LABEL } from 'features/reports/vessel-groups/vessel-group-report.config'
import styles from './VesselGroupReportVesselsGraph.module.css'

type ReportGraphTooltipProps = {
Expand Down Expand Up @@ -65,6 +66,7 @@ const ReportGraphTooltip = (props: any) => {
const CustomTick = (props: any) => {
const { x, y, payload, width, visibleTicksCount, property, filterQueryParam, pageQueryParam } =
props

const { t } = useTranslation()
const { dispatchQueryParams } = useLocationConnect()
const isOtherCategory = payload.value === OTHERS_CATEGORY_LABEL
Expand All @@ -90,10 +92,14 @@ const CustomTick = (props: any) => {
}

const onLabelClick = () => {
dispatchQueryParams({
[filterQueryParam]: `${filterProperties[property as VGRVesselsSubsection]}:${payload.value}`,
[pageQueryParam]: 0,
})
if (payload.value !== OTHER_CATEGORY_LABEL) {
dispatchQueryParams({
[filterQueryParam]: `${filterProperties[property as VGRVesselsSubsection]}:${
payload.value
}`,
[pageQueryParam]: 0,
})
}
}

const label = isOtherCategory ? t('analysis.others', 'Others') : getTickLabel(payload.value)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,8 @@ export const selectVGRVesselsFlags = createSelector([selectVGRVesselsParsed], (v
if (!vessels?.length) return null
let flags = new Set<string>()
vessels.forEach((vessel) => {
if (vessel.flag) {
flags.add(vessel.flag)
if (vessel.flagTranslated) {
flags.add(vessel.flagTranslated)
}
})
return flags
Expand Down Expand Up @@ -178,7 +178,7 @@ export const selectVGRVesselsGraphDataGrouped = createSelector(
let vesselsGrouped = {}
switch (subsection) {
case 'flag':
vesselsGrouped = groupBy(vessels, (vessel) => vessel.flag)
vesselsGrouped = groupBy(vessels, (vessel) => vessel.flagTranslatedClean)
break
case 'shiptypes':
vesselsGrouped = groupBy(vessels, (vessel) => vessel.vesselType.split(', ')[0])
Expand Down
4 changes: 3 additions & 1 deletion apps/fishing-map/features/search/search.hook.ts
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,9 @@ export const useFetchSearchResults = () => {
if (total >= 0) {
trackEvent({
category: TrackCategory.SearchVessel,
action: 'Search specific vessel',
action: searchInBasic
? 'Search specific vessel'
: 'add_filters_and_hit_search_in_advanced_search',
label: query,
value: total,
})
Expand Down
2 changes: 2 additions & 0 deletions apps/fishing-map/features/timebar/Timebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,8 @@ const TimebarWrapper = () => {
DAY_INTERVAL_BUTTON: 'Use day preset',
MONTH_INTERVAL_BUTTON: 'Use month preset',
YEAR_INTERVAL_BUTTON: 'Use year preset',
SEEK_RELEASE: 'Move timebar slider',
BOOKMARK_SELECT: 'Select bookmark period',
}
if (e.source && gaActions[e.source]) {
trackEvent({
Expand Down
Loading

0 comments on commit 5f73774

Please sign in to comment.