diff --git a/apps/fishing-map/data/config.ts b/apps/fishing-map/data/config.ts index a0f7a864cf..0e947e1e6a 100644 --- a/apps/fishing-map/data/config.ts +++ b/apps/fishing-map/data/config.ts @@ -108,12 +108,6 @@ export const DEFAULT_WORKSPACE: WorkspaceState & AppState = { visibleEvents: 'all', timebarGraph: TimebarGraphs.None, bivariateDataviews: undefined, - reportActivityGraph: REPORT_ACTIVITY_GRAPH_EVOLUTION, - reportCategory: undefined, - reportVesselFilter: '', - reportVesselGraph: REPORT_VESSELS_GRAPH_FLAG, - reportVesselPage: 0, - reportResultsPerPage: REPORT_VESSELS_PER_PAGE, userTab: UserTab.Info, } diff --git a/apps/fishing-map/features/app/App.tsx b/apps/fishing-map/features/app/App.tsx index 86810d5b59..70ed49b45c 100644 --- a/apps/fishing-map/features/app/App.tsx +++ b/apps/fishing-map/features/app/App.tsx @@ -17,6 +17,7 @@ import { selectLocationType, selectWorkspaceId, selectIsMapDrawing, + selectIsVesselGroupReportLocation, } from 'routes/routes.selectors' import menuBgImage from 'assets/images/menubg.jpg' import { useLocationConnect, useReplaceLoginUrl } from 'routes/routes.hook' @@ -54,11 +55,11 @@ import AppModals from 'features/modals/Modals' import { useMapFitBounds } from 'features/map/map-bounds.hooks' import { useSetMapCoordinates } from 'features/map/map-viewport.hooks' import { useDatasetDrag } from 'features/app/drag-dataset.hooks' -import { selectReportAreaBounds } from 'features/app/selectors/app.reports.selector' import { selectIsUserLogged } from 'features/user/selectors/user.selectors' import ErrorBoundary from 'features/app/ErrorBoundary' import { selectDebugOptions } from 'features/debug/debug.slice' import { useFitWorkspaceBounds } from 'features/workspace/workspace.hook' +import { selectReportAreaBounds } from 'features/area-report/reports.config.selectors' import { useAppDispatch } from './app.hooks' import { selectReadOnly, selectSidebarOpen } from './selectors/app.selectors' import { useAnalytics } from './analytics.hooks' @@ -76,6 +77,7 @@ declare global { const Main = () => { const isWorkspaceLocation = useSelector(selectIsWorkspaceLocation) + const isVesselGroupReportLocation = useSelector(selectIsVesselGroupReportLocation) const locationType = useSelector(selectLocationType) const reportLocation = useSelector(selectIsAnyReportLocation) const workspaceStatus = useSelector(selectWorkspaceStatus) @@ -87,6 +89,7 @@ const Main = () => { const isWorkspacesRouteWithTimebar = isWorkspaceLocation || locationType === WORKSPACE_VESSEL || + isVesselGroupReportLocation || (reportLocation && !isTimeComparisonReport) const isWorkspaceMapReady = useSelector(selectIsWorkspaceMapReady) const showTimebar = @@ -129,7 +132,7 @@ function App() { const i18n = useTranslation() const { dispatchQueryParams } = useLocationConnect() const [menuOpen, setMenuOpen] = useState(false) - const workspaceLocation = useSelector(selectIsWorkspaceLocation) + const isWorkspaceLocation = useSelector(selectIsWorkspaceLocation) const vesselLocation = useSelector(selectIsVesselLocation) const isReportLocation = useSelector(selectIsAnyReportLocation) const reportAreaBounds = useSelector(selectReportAreaBounds) @@ -241,7 +244,7 @@ function App() { asideWidth = isReportLocation ? '45%' : '34rem' } else if (isAnySearchLocation) { asideWidth = '100%' - } else if (workspaceLocation) { + } else if (isWorkspaceLocation) { asideWidth = '39rem' } @@ -261,7 +264,7 @@ function App() { } main={
} diff --git a/apps/fishing-map/features/app/selectors/app.reports.selector.ts b/apps/fishing-map/features/app/selectors/app.reports.selector.ts index 765dc71328..a15c4dfe46 100644 --- a/apps/fishing-map/features/app/selectors/app.reports.selector.ts +++ b/apps/fishing-map/features/app/selectors/app.reports.selector.ts @@ -6,7 +6,6 @@ import { selectReportActiveCategories, } from 'features/dataviews/selectors/dataviews.selectors' import { selectReportById } from 'features/area-report/reports.slice' -import { selectWorkspaceStateProperty } from 'features/workspace/workspace.selectors' import { selectLocationAreaId, selectLocationDatasetId, @@ -15,8 +14,16 @@ import { selectUrlBufferUnitQuery, selectUrlBufferValueQuery, } from 'routes/routes.selectors' -import { BufferOperation, BufferUnit, ReportCategory, ReportVesselGraph } from 'types' +import { BufferOperation, BufferUnit } from 'types' import { createDeepEqualSelector } from 'utils/selectors' +import { + selectReportBufferOperationSelector, + selectReportBufferUnitSelector, + selectReportBufferValueSelector, + selectReportCategorySelector, + selectReportVesselGraphSelector, +} from 'features/area-report/reports.config.selectors' +import { ReportCategory, ReportVesselGraph } from 'features/area-report/reports.types' export function isActivityReport(reportCategory: ReportCategory) { return reportCategory === ReportCategory.Fishing || reportCategory === ReportCategory.Presence @@ -44,7 +51,6 @@ export const selectReportAreaId = createSelector( } ) -const selectReportCategorySelector = selectWorkspaceStateProperty('reportCategory') export const selectReportCategory = createSelector( [selectReportCategorySelector, selectReportActiveCategories], (reportCategory, activeCategories): ReportCategory => { @@ -54,8 +60,6 @@ export const selectReportCategory = createSelector( } ) -export const selectReportAreaBounds = selectWorkspaceStateProperty('reportAreaBounds') - export const selectActiveReportDataviews = createDeepEqualSelector( [ selectReportCategory, @@ -79,9 +83,6 @@ export const selectActiveReportDataviews = createDeepEqualSelector( } ) -export const selectReportActivityGraph = selectWorkspaceStateProperty('reportActivityGraph') -const selectReportVesselGraphSelector = selectWorkspaceStateProperty('reportVesselGraph') - export const selectReportVesselGraph = createSelector( [selectReportVesselGraphSelector, selectReportCategory], (reportVesselGraph, reportCategory): ReportVesselGraph => { @@ -91,13 +92,6 @@ export const selectReportVesselGraph = createSelector( return reportVesselGraph } ) - -export const selectReportVesselFilter = selectWorkspaceStateProperty('reportVesselFilter') -export const selectReportVesselPage = selectWorkspaceStateProperty('reportVesselPage') -export const selectReportResultsPerPage = selectWorkspaceStateProperty('reportResultsPerPage') -export const selectReportTimeComparison = selectWorkspaceStateProperty('reportTimeComparison') - -const selectReportBufferValueSelector = selectWorkspaceStateProperty('reportBufferValue') export const selectReportBufferValue = createSelector( [selectReportBufferValueSelector, selectUrlBufferValueQuery], (workspaceBufferValue, urlBufferValue): number => { @@ -105,7 +99,6 @@ export const selectReportBufferValue = createSelector( } ) -const selectReportBufferUnitSelector = selectWorkspaceStateProperty('reportBufferUnit') export const selectReportBufferUnit = createSelector( [selectReportBufferUnitSelector, selectUrlBufferUnitQuery], (workspaceBufferUnit, urlBufferUnit): BufferUnit => { @@ -113,7 +106,6 @@ export const selectReportBufferUnit = createSelector( } ) -const selectReportBufferOperationSelector = selectWorkspaceStateProperty('reportBufferOperation') export const selectReportBufferOperation = createSelector( [selectReportBufferOperationSelector, selectUrlBufferOperationQuery], (workspaceBufferOperation, urlBufferOperation): BufferOperation => { diff --git a/apps/fishing-map/features/app/selectors/app.workspace.selectors.ts b/apps/fishing-map/features/app/selectors/app.workspace.selectors.ts index a927dcceaa..9869dec392 100644 --- a/apps/fishing-map/features/app/selectors/app.workspace.selectors.ts +++ b/apps/fishing-map/features/app/selectors/app.workspace.selectors.ts @@ -12,14 +12,8 @@ import { selectVisibleEvents, } from 'features/app/selectors/app.selectors' import { - selectReportActivityGraph, - selectReportAreaBounds, selectReportCategory, - selectReportResultsPerPage, - selectReportTimeComparison, - selectReportVesselFilter, selectReportVesselGraph, - selectReportVesselPage, selectReportBufferValue, selectReportBufferUnit, selectReportBufferOperation, @@ -36,6 +30,14 @@ import { selectViewport } from 'features/app/selectors/app.viewport.selectors' import { selectDataviewInstancesMergedOrdered } from 'features/dataviews/selectors/dataviews.instances.selectors' import { selectDaysFromLatest, selectWorkspace } from 'features/workspace/workspace.selectors' import { DEFAULT_WORKSPACE_CATEGORY } from 'data/workspaces' +import { + selectReportActivityGraph, + selectReportAreaBounds, + selectReportResultsPerPage, + selectReportTimeComparison, + selectReportVesselFilter, + selectReportVesselPage, +} from 'features/area-report/reports.config.selectors' const selectWorkspaceReportState = createSelector( [ diff --git a/apps/fishing-map/features/area-report/Report.tsx b/apps/fishing-map/features/area-report/Report.tsx index 6de0b6bf72..8325818eb9 100644 --- a/apps/fishing-map/features/area-report/Report.tsx +++ b/apps/fishing-map/features/area-report/Report.tsx @@ -30,7 +30,7 @@ import { selectReportDataviewsWithPermissions, } from 'features/area-report/reports.selectors' import ReportVesselsPlaceholder from 'features/area-report/placeholders/ReportVesselsPlaceholder' -import { ReportCategory, TimebarVisualisations } from 'types' +import { TimebarVisualisations } from 'types' import { getDownloadReportSupported } from 'features/download/download.utils' import { SUPPORT_EMAIL } from 'data/config' import { @@ -78,6 +78,7 @@ import ReportVessels from './vessels/ReportVessels' import ReportDownload from './download/ReportDownload' import ReportEnvironment from './environment/ReportEnvironment' import styles from './Report.module.css' +import { ReportCategory } from './reports.types' export type ReportActivityUnit = 'hour' | 'detection' diff --git a/apps/fishing-map/features/area-report/activity/ReportActivity.tsx b/apps/fishing-map/features/area-report/activity/ReportActivity.tsx index 697ce27137..0554ce19ee 100644 --- a/apps/fishing-map/features/area-report/activity/ReportActivity.tsx +++ b/apps/fishing-map/features/area-report/activity/ReportActivity.tsx @@ -10,12 +10,12 @@ import { useReportFilteredTimeSeries, } from 'features/area-report/reports-timeseries.hooks' import { selectTimeComparisonValues } from 'features/area-report/reports.selectors' -import { ReportActivityGraph } from 'types' -import { selectReportActivityGraph } from 'features/app/selectors/app.reports.selector' import ReportActivityPlaceholder from 'features/area-report/placeholders/ReportActivityPlaceholder' import ReportActivityPeriodComparison from 'features/area-report/activity/ReportActivityPeriodComparison' import ReportActivityPeriodComparisonGraph from 'features/area-report/activity/ReportActivityPeriodComparisonGraph' import UserGuideLink from 'features/help/UserGuideLink' +import { selectReportActivityGraph } from '../reports.config.selectors' +import { ReportActivityGraph } from '../reports.types' import ReportActivityEvolution from './ReportActivityEvolution' import ReportActivityBeforeAfter from './ReportActivityBeforeAfter' import ReportActivityBeforeAfterGraph from './ReportActivityBeforeAfterGraph' diff --git a/apps/fishing-map/features/area-report/activity/ReportActivityBeforeAfter.tsx b/apps/fishing-map/features/area-report/activity/ReportActivityBeforeAfter.tsx index 5d0373dca9..3d9f00a1a6 100644 --- a/apps/fishing-map/features/area-report/activity/ReportActivityBeforeAfter.tsx +++ b/apps/fishing-map/features/area-report/activity/ReportActivityBeforeAfter.tsx @@ -3,13 +3,13 @@ import { useTranslation } from 'react-i18next' import { useSelector } from 'react-redux' import { InputDate, InputText, Select, SelectOption } from '@globalfishingwatch/ui-components' import { useReportTimeCompareConnect } from 'features/area-report/reports-timecomparison.hooks' -import { selectReportTimeComparison } from 'features/app/selectors/app.reports.selector' import { selectActiveActivityAndDetectionsDataviews } from 'features/dataviews/selectors/dataviews.selectors' import { getSourcesSelectedInDataview } from 'features/workspace/activity/activity.utils' import { selectReportAreaIds } from 'features/area-report/reports.selectors' import { selectDatasetAreaDetail } from 'features/areas/areas.slice' import { TrackCategory, trackEvent } from 'features/app/analytics.hooks' import { MAX_MONTHS_TO_COMPARE, MAX_DAYS_TO_COMPARE } from 'features/area-report/reports.config' +import { selectReportTimeComparison } from '../reports.config.selectors' import styles from './ReportActivityBeforeAfter.module.css' export default function ReportActivityBeforeAfter() { diff --git a/apps/fishing-map/features/area-report/activity/ReportActivityBeforeAfterGraph.tsx b/apps/fishing-map/features/area-report/activity/ReportActivityBeforeAfterGraph.tsx index 199333e863..4ec9cea595 100644 --- a/apps/fishing-map/features/area-report/activity/ReportActivityBeforeAfterGraph.tsx +++ b/apps/fishing-map/features/area-report/activity/ReportActivityBeforeAfterGraph.tsx @@ -13,14 +13,14 @@ import { import { DateTime } from 'luxon' import { useSelector } from 'react-redux' import { FourwingsInterval } from '@globalfishingwatch/deck-loaders' -import { selectReportTimeComparison } from 'features/app/selectors/app.reports.selector' -import { ReportActivityTimeComparison } from 'types' import i18n from 'features/i18n/i18n' import { COLOR_PRIMARY_BLUE } from 'features/app/app.config' import { getUTCDateTime } from 'utils/dates' import { formatDate, tickFormatter } from 'features/area-report/reports.utils' import { formatI18nNumber } from 'features/i18n/i18nNumber' import { toFixed } from 'utils/shared' +import { selectReportTimeComparison } from '../reports.config.selectors' +import { ReportActivityTimeComparison } from '../reports.types' import styles from './ReportActivityEvolution.module.css' interface ComparisonGraphData { diff --git a/apps/fishing-map/features/area-report/activity/ReportActivityGraphSelector.tsx b/apps/fishing-map/features/area-report/activity/ReportActivityGraphSelector.tsx index 3677e3072e..76d2ba3aaf 100644 --- a/apps/fishing-map/features/area-report/activity/ReportActivityGraphSelector.tsx +++ b/apps/fishing-map/features/area-report/activity/ReportActivityGraphSelector.tsx @@ -8,14 +8,12 @@ import { REPORT_ACTIVITY_GRAPH_BEFORE_AFTER, REPORT_ACTIVITY_GRAPH_PERIOD_COMPARISON, } from 'data/config' -import { - selectActiveReportDataviews, - selectReportActivityGraph, -} from 'features/app/selectors/app.reports.selector' +import { selectActiveReportDataviews } from 'features/app/selectors/app.reports.selector' import { useFitAreaInViewport } from 'features/area-report/reports.hooks' -import { ReportActivityGraph } from 'types' import { useSetReportTimeComparison } from 'features/area-report/reports-timecomparison.hooks' import { TrackCategory, trackEvent } from 'features/app/analytics.hooks' +import { selectReportActivityGraph } from '../reports.config.selectors' +import { ReportActivityGraph } from '../reports.types' type ReportActivityGraphSelectorProps = { loading: boolean diff --git a/apps/fishing-map/features/area-report/activity/ReportActivityPeriodComparison.tsx b/apps/fishing-map/features/area-report/activity/ReportActivityPeriodComparison.tsx index 63dc745cc8..229a1ba78e 100644 --- a/apps/fishing-map/features/area-report/activity/ReportActivityPeriodComparison.tsx +++ b/apps/fishing-map/features/area-report/activity/ReportActivityPeriodComparison.tsx @@ -3,7 +3,6 @@ import { useTranslation } from 'react-i18next' import { useSelector } from 'react-redux' import { InputDate, InputText, Select } from '@globalfishingwatch/ui-components' import { useReportTimeCompareConnect } from 'features/area-report/reports-timecomparison.hooks' -import { selectReportTimeComparison } from 'features/app/selectors/app.reports.selector' import { selectActiveActivityAndDetectionsDataviews } from 'features/dataviews/selectors/dataviews.selectors' import { getSourcesSelectedInDataview } from 'features/workspace/activity/activity.utils' import { selectReportAreaIds } from 'features/area-report/reports.selectors' @@ -12,6 +11,7 @@ import Hint from 'features/help/Hint' import { COLOR_PRIMARY_BLUE } from 'features/app/app.config' import { TrackCategory, trackEvent } from 'features/app/analytics.hooks' import { MAX_MONTHS_TO_COMPARE, MAX_DAYS_TO_COMPARE } from 'features/area-report/reports.config' +import { selectReportTimeComparison } from '../reports.config.selectors' import styles from './ReportActivityBeforeAfter.module.css' export default function ReportActivityGraph() { diff --git a/apps/fishing-map/features/area-report/activity/ReportActivityPeriodComparisonGraph.tsx b/apps/fishing-map/features/area-report/activity/ReportActivityPeriodComparisonGraph.tsx index ef24839898..cae2d3809d 100644 --- a/apps/fishing-map/features/area-report/activity/ReportActivityPeriodComparisonGraph.tsx +++ b/apps/fishing-map/features/area-report/activity/ReportActivityPeriodComparisonGraph.tsx @@ -14,12 +14,12 @@ import { Interval as TimeInterval } from 'luxon' import { useSelector } from 'react-redux' import { FourwingsInterval } from '@globalfishingwatch/deck-loaders' import { selectLatestAvailableDataDate } from 'features/app/selectors/app.selectors' -import { selectReportTimeComparison } from 'features/app/selectors/app.reports.selector' import i18n, { t } from 'features/i18n/i18n' import { COLOR_GRADIENT, COLOR_PRIMARY_BLUE } from 'features/app/app.config' import { getUTCDateTime } from 'utils/dates' import { formatDate, formatTooltipValue, tickFormatter } from 'features/area-report/reports.utils' import { EMPTY_FIELD_PLACEHOLDER } from 'utils/info' +import { selectReportTimeComparison } from '../reports.config.selectors' import styles from './ReportActivityEvolution.module.css' const DIFFERENCE = 'difference' diff --git a/apps/fishing-map/features/area-report/reports-timecomparison.hooks.ts b/apps/fishing-map/features/area-report/reports-timecomparison.hooks.ts index e88c4f5d4c..ba72a6532d 100644 --- a/apps/fishing-map/features/area-report/reports-timecomparison.hooks.ts +++ b/apps/fishing-map/features/area-report/reports-timecomparison.hooks.ts @@ -3,18 +3,16 @@ import { useSelector } from 'react-redux' import { useTranslation } from 'react-i18next' import { DateTime } from 'luxon' import { SelectOption } from '@globalfishingwatch/ui-components' -import { ReportActivityGraph } from 'types' import { AVAILABLE_START, AVAILABLE_END } from 'data/config' -import { - selectReportActivityGraph, - selectReportTimeComparison, -} from 'features/app/selectors/app.reports.selector' +import {} from 'features/app/selectors/app.reports.selector' import { useTimerangeConnect } from 'features/timebar/timebar.hooks' import { useLocationConnect } from 'routes/routes.hook' import { getUTCDateTime } from 'utils/dates' import { formatI18nDate } from 'features/i18n/i18nDate' import { useFitAreaInViewport } from 'features/area-report/reports.hooks' import { MAX_DAYS_TO_COMPARE, MAX_MONTHS_TO_COMPARE } from 'features/area-report/reports.config' +import { selectReportActivityGraph, selectReportTimeComparison } from './reports.config.selectors' +import { ReportActivityGraph } from './reports.types' // TODO get this from start and endDate from datasets const MIN_DATE = AVAILABLE_START.slice(0, 10) diff --git a/apps/fishing-map/features/area-report/reports-timeseries.hooks.ts b/apps/fishing-map/features/area-report/reports-timeseries.hooks.ts index 7a1807f200..8e9d43bc29 100644 --- a/apps/fishing-map/features/area-report/reports-timeseries.hooks.ts +++ b/apps/fishing-map/features/area-report/reports-timeseries.hooks.ts @@ -20,9 +20,7 @@ import { } from '@globalfishingwatch/deck-loaders' import { selectActiveReportDataviews, - selectReportActivityGraph, selectReportCategory, - selectReportTimeComparison, } from 'features/app/selectors/app.reports.selector' import { FilteredPolygons } from 'features/area-report/reports-geo.utils' import { @@ -36,11 +34,12 @@ import { selectReportBufferHash, selectShowTimeComparison, } from 'features/area-report/reports.selectors' -import { ReportActivityGraph, ReportCategory } from 'types' import { selectTimeRange } from 'features/app/selectors/app.timebar.selectors' import { AreaGeometry } from 'features/areas/areas.slice' import { useFilterCellsByPolygonWorker } from 'features/area-report/reports-geo.utils.workers.hooks' import { TimeRange } from 'features/timebar/timebar.slice' +import { ReportActivityGraph, ReportCategory } from './reports.types' +import { selectReportActivityGraph, selectReportTimeComparison } from './reports.config.selectors' interface EvolutionGraphData { date: string diff --git a/apps/fishing-map/features/area-report/reports.config.selectors.ts b/apps/fishing-map/features/area-report/reports.config.selectors.ts new file mode 100644 index 0000000000..643d165f02 --- /dev/null +++ b/apps/fishing-map/features/area-report/reports.config.selectors.ts @@ -0,0 +1,25 @@ +import { createSelector } from '@reduxjs/toolkit' +import { selectQueryParam } from 'routes/routes.selectors' +import { AreaReportState, AreaReportStateProperty } from './reports.types' +import { DEFAULT_AREA_REPORT_STATE } from './reports.config' + +type AreaReportProperty

= Required[P] +function selectAreaReportStateProperty

(property: P) { + return createSelector([selectQueryParam(property)], (urlProperty): AreaReportProperty

=> { + if (urlProperty !== undefined) return urlProperty + return DEFAULT_AREA_REPORT_STATE[property] as AreaReportProperty

+ }) +} + +export const selectReportCategorySelector = selectAreaReportStateProperty('reportCategory') +export const selectReportAreaBounds = selectAreaReportStateProperty('reportAreaBounds') +export const selectReportActivityGraph = selectAreaReportStateProperty('reportActivityGraph') +export const selectReportVesselGraphSelector = selectAreaReportStateProperty('reportVesselGraph') +export const selectReportVesselFilter = selectAreaReportStateProperty('reportVesselFilter') +export const selectReportVesselPage = selectAreaReportStateProperty('reportVesselPage') +export const selectReportResultsPerPage = selectAreaReportStateProperty('reportResultsPerPage') +export const selectReportTimeComparison = selectAreaReportStateProperty('reportTimeComparison') +export const selectReportBufferValueSelector = selectAreaReportStateProperty('reportBufferValue') +export const selectReportBufferUnitSelector = selectAreaReportStateProperty('reportBufferUnit') +export const selectReportBufferOperationSelector = + selectAreaReportStateProperty('reportBufferOperation') diff --git a/apps/fishing-map/features/area-report/reports.config.ts b/apps/fishing-map/features/area-report/reports.config.ts index f3c39a24b4..8d188c3f81 100644 --- a/apps/fishing-map/features/area-report/reports.config.ts +++ b/apps/fishing-map/features/area-report/reports.config.ts @@ -1,4 +1,10 @@ +import { + REPORT_ACTIVITY_GRAPH_EVOLUTION, + REPORT_VESSELS_GRAPH_FLAG, + REPORT_VESSELS_PER_PAGE, +} from 'data/config' import { BufferUnit, BufferOperation } from 'types' +import { AreaReportState } from './reports.types' export const REPORT_BUFFER_FEATURE_ID: string = 'buffer' export const DEFAULT_BUFFER_VALUE: number = 50 @@ -20,3 +26,17 @@ export const OTHERS_CATEGORY_LABEL = 'OTHERS' export const MAX_DAYS_TO_COMPARE = 100 export const MAX_MONTHS_TO_COMPARE = 12 + +export const DEFAULT_AREA_REPORT_STATE: AreaReportState = { + reportActivityGraph: REPORT_ACTIVITY_GRAPH_EVOLUTION, + reportCategory: undefined, + reportVesselFilter: '', + reportVesselGraph: REPORT_VESSELS_GRAPH_FLAG, + reportVesselPage: 0, + reportResultsPerPage: REPORT_VESSELS_PER_PAGE, + reportAreaBounds: undefined, + reportTimeComparison: undefined, + reportBufferValue: undefined, + reportBufferUnit: undefined, + reportBufferOperation: undefined, +} diff --git a/apps/fishing-map/features/area-report/reports.selectors.ts b/apps/fishing-map/features/area-report/reports.selectors.ts index 09a1199611..495d74d476 100644 --- a/apps/fishing-map/features/area-report/reports.selectors.ts +++ b/apps/fishing-map/features/area-report/reports.selectors.ts @@ -9,16 +9,11 @@ import { selectReportAreaId, selectReportDatasetId, selectActiveReportDataviews, - selectReportActivityGraph, selectReportBufferOperation, selectReportBufferUnit, selectReportBufferValue, selectReportCategory, - selectReportResultsPerPage, - selectReportTimeComparison, - selectReportVesselFilter, selectReportVesselGraph, - selectReportVesselPage, } from 'features/app/selectors/app.reports.selector' import { selectAllDatasets } from 'features/datasets/datasets.slice' import { @@ -33,7 +28,6 @@ import { getReportCategoryFromDataview, getVesselsFiltered, } from 'features/area-report/reports.utils' -import { ReportCategory } from 'types' import { createDeepEqualSelector } from 'utils/selectors' import { EMPTY_FIELD_PLACEHOLDER, getVesselGearTypeLabel } from 'utils/info' import { sortStrings } from 'utils/shared' @@ -45,6 +39,14 @@ import { } from 'features/area-report/reports.config' import { selectDataviewInstancesResolved } from 'features/dataviews/selectors/dataviews.instances.selectors' import { selectReportVesselsData, selectReportPreviewBuffer } from './report.slice' +import { + selectReportVesselFilter, + selectReportVesselPage, + selectReportResultsPerPage, + selectReportActivityGraph, + selectReportTimeComparison, +} from './reports.config.selectors' +import { ReportCategory } from './reports.types' const EMPTY_ARRAY: [] = [] diff --git a/apps/fishing-map/features/area-report/reports.types.ts b/apps/fishing-map/features/area-report/reports.types.ts new file mode 100644 index 0000000000..1ad1481fad --- /dev/null +++ b/apps/fishing-map/features/area-report/reports.types.ts @@ -0,0 +1,50 @@ +import { DatasetSubCategory, DataviewCategory } from '@globalfishingwatch/api-types' +import { + REPORT_ACTIVITY_GRAPH_EVOLUTION, + REPORT_ACTIVITY_GRAPH_BEFORE_AFTER, + REPORT_ACTIVITY_GRAPH_PERIOD_COMPARISON, + REPORT_VESSELS_GRAPH_FLAG, + REPORT_VESSELS_GRAPH_GEARTYPE, + REPORT_VESSELS_GRAPH_VESSELTYPE, +} from 'data/config' +import { Bbox, BufferOperation, BufferUnit } from 'types' + +export type ReportActivityGraph = + | typeof REPORT_ACTIVITY_GRAPH_EVOLUTION + | typeof REPORT_ACTIVITY_GRAPH_BEFORE_AFTER + | typeof REPORT_ACTIVITY_GRAPH_PERIOD_COMPARISON + +export enum ReportCategory { + Fishing = DatasetSubCategory.Fishing, + Presence = DatasetSubCategory.Presence, + Detections = DataviewCategory.Detections, + Environment = DataviewCategory.Environment, +} + +export type ReportVesselGraph = + | typeof REPORT_VESSELS_GRAPH_GEARTYPE + | typeof REPORT_VESSELS_GRAPH_VESSELTYPE + | typeof REPORT_VESSELS_GRAPH_FLAG + +export type ReportActivityTimeComparison = { + start: string + compareStart: string + duration: number + durationType: 'days' | 'months' +} + +export type AreaReportState = { + reportActivityGraph?: ReportActivityGraph + reportAreaBounds?: Bbox + reportCategory?: ReportCategory + reportTimeComparison?: ReportActivityTimeComparison + reportVesselFilter?: string + reportVesselGraph?: ReportVesselGraph + reportVesselPage?: number + reportBufferValue?: number + reportBufferUnit?: BufferUnit + reportBufferOperation?: BufferOperation + reportResultsPerPage?: number +} + +export type AreaReportStateProperty = keyof AreaReportState diff --git a/apps/fishing-map/features/area-report/reports.utils.ts b/apps/fishing-map/features/area-report/reports.utils.ts index 1fdd2e48be..95178d1161 100644 --- a/apps/fishing-map/features/area-report/reports.utils.ts +++ b/apps/fishing-map/features/area-report/reports.utils.ts @@ -18,7 +18,7 @@ import { getSchemaFilterOperationInDataview, SupportedDatasetSchema, } from 'features/datasets/datasets.utils' -import { Bbox, BufferOperation, BufferUnit, ReportCategory } from 'types' +import { Bbox, BufferOperation, BufferUnit } from 'types' import { Area, AreaGeometry } from 'features/areas/areas.slice' import { IdentityVesselData, VesselDataIdentity } from 'features/vessel/vessel.slice' import { VesselGroupReportVesselParsed } from 'features/vessel-group-report/vessels/vessel-group-report-vessels.types' @@ -30,6 +30,7 @@ import { REPORT_BUFFER_FEATURE_ID, } from './reports.config' import { ReportVesselWithDatasets } from './reports.selectors' +import { ReportCategory } from './reports.types' const ALWAYS_SHOWN_FILTERS = ['vessel-groups'] diff --git a/apps/fishing-map/features/area-report/summary/ReportSummary.tsx b/apps/fishing-map/features/area-report/summary/ReportSummary.tsx index 511fbf5451..f8a2544001 100644 --- a/apps/fishing-map/features/area-report/summary/ReportSummary.tsx +++ b/apps/fishing-map/features/area-report/summary/ReportSummary.tsx @@ -9,7 +9,6 @@ import { formatI18nDate } from 'features/i18n/i18nDate' import { selectActiveReportDataviews, selectReportCategory, - selectReportTimeComparison, } from 'features/app/selectors/app.reports.selector' import ReportSummaryTags from 'features/area-report/summary/ReportSummaryTags' import { FIELDS, getCommonProperties } from 'features/area-report/reports.utils' @@ -26,7 +25,6 @@ import ReportSummaryPlaceholder from 'features/area-report/placeholders/ReportSu import ReportSummaryTagsPlaceholder from 'features/area-report/placeholders/ReportSummaryTagsPlaceholder' import { getSourcesSelectedInDataview } from 'features/workspace/activity/activity.utils' import { listAsSentence } from 'utils/shared' -import { ReportCategory } from 'types' import { getDateRangeHash, selectReportVesselsDateRangeHash, @@ -34,6 +32,8 @@ import { import { selectTimeRange } from 'features/app/selectors/app.timebar.selectors' import { useTimeCompareTimeDescription } from 'features/area-report/reports-timecomparison.hooks' import { selectReportVesselsHours, selectReportVesselsNumber } from '../reports.selectors' +import { selectReportTimeComparison } from '../reports.config.selectors' +import { ReportCategory } from '../reports.types' import styles from './ReportSummary.module.css' type ReportSummaryProps = { diff --git a/apps/fishing-map/features/area-report/vessels/ReportVessels.tsx b/apps/fishing-map/features/area-report/vessels/ReportVessels.tsx index b1897a1679..11ee903396 100644 --- a/apps/fishing-map/features/area-report/vessels/ReportVessels.tsx +++ b/apps/fishing-map/features/area-report/vessels/ReportVessels.tsx @@ -5,13 +5,13 @@ import ReportVesselsGraphSelector from 'features/area-report/vessels/ReportVesse import { selectActiveReportDataviews, selectReportCategory, - selectReportVesselFilter, } from 'features/app/selectors/app.reports.selector' -import { ReportCategory } from 'types' import ReportSummaryTags from 'features/area-report/summary/ReportSummaryTags' import { FIELDS, getCommonProperties } from 'features/area-report/reports.utils' import { PROPERTIES_EXCLUDED } from 'features/area-report/summary/ReportSummary' import { ReportActivityUnit } from '../Report' +import { selectReportVesselFilter } from '../reports.config.selectors' +import { ReportCategory } from '../reports.types' import ReportVesselsGraph from './ReportVesselsGraph' import ReportVesselsFilter from './ReportVesselsFilter' import ReportVesselsTable from './ReportVesselsTable' diff --git a/apps/fishing-map/features/area-report/vessels/ReportVesselsGraph.tsx b/apps/fishing-map/features/area-report/vessels/ReportVesselsGraph.tsx index a7c5685294..8b282ed486 100644 --- a/apps/fishing-map/features/area-report/vessels/ReportVesselsGraph.tsx +++ b/apps/fishing-map/features/area-report/vessels/ReportVesselsGraph.tsx @@ -5,7 +5,6 @@ import { BarChart, Bar, XAxis, Tooltip, ResponsiveContainer, LabelList } from 'r import { useTranslation } from 'react-i18next' import { Tooltip as GFWTooltip } from '@globalfishingwatch/ui-components' import { selectReportVesselGraph } from 'features/app/selectors/app.reports.selector' -import { ReportVesselGraph } from 'types' import I18nNumber, { formatI18nNumber } from 'features/i18n/i18nNumber' import { useLocationConnect } from 'routes/routes.hook' import { ReportVesselsGraphPlaceholder } from 'features/area-report/placeholders/ReportVesselsPlaceholder' @@ -22,6 +21,7 @@ import { selectReportVesselsGraphDataGrouped, selectReportVesselsGraphDataOthers, } from '../reports.selectors' +import { ReportVesselGraph } from '../reports.types' import styles from './ReportVesselsGraph.module.css' const MAX_OTHER_TOOLTIP_ITEMS = 10 diff --git a/apps/fishing-map/features/area-report/vessels/ReportVesselsGraphSelector.tsx b/apps/fishing-map/features/area-report/vessels/ReportVesselsGraphSelector.tsx index 855957b06a..4826d3a313 100644 --- a/apps/fishing-map/features/area-report/vessels/ReportVesselsGraphSelector.tsx +++ b/apps/fishing-map/features/area-report/vessels/ReportVesselsGraphSelector.tsx @@ -12,8 +12,8 @@ import { selectReportCategory, selectReportVesselGraph, } from 'features/app/selectors/app.reports.selector' -import { ReportCategory, ReportVesselGraph } from 'types' import { TrackCategory, trackEvent } from 'features/app/analytics.hooks' +import { ReportCategory, ReportVesselGraph } from '../reports.types' export default function ReportVesselsGraphSelector() { const { dispatchQueryParams } = useLocationConnect() diff --git a/apps/fishing-map/features/area-report/vessels/ReportVesselsTable.tsx b/apps/fishing-map/features/area-report/vessels/ReportVesselsTable.tsx index 6f058e0601..202654a8d6 100644 --- a/apps/fishing-map/features/area-report/vessels/ReportVesselsTable.tsx +++ b/apps/fishing-map/features/area-report/vessels/ReportVesselsTable.tsx @@ -11,7 +11,6 @@ import { selectActiveReportDataviews, selectReportCategory, } from 'features/app/selectors/app.reports.selector' -import { ReportCategory } from 'types' import { selectUserData } from 'features/user/selectors/user.selectors' import DatasetLabel from 'features/datasets/DatasetLabel' import { EMPTY_API_VALUES } from 'features/area-report/reports.config' @@ -20,6 +19,7 @@ import VesselPin from 'features/vessel/VesselPin' import { GLOBAL_VESSELS_DATASET_ID } from 'data/workspaces' import { selectReportVesselsPaginated } from '../reports.selectors' import { ReportActivityUnit } from '../Report' +import { ReportCategory } from '../reports.types' import styles from './ReportVesselsTable.module.css' type ReportVesselTableProps = { diff --git a/apps/fishing-map/features/area-report/vessels/ReportVesselsTableFooter.tsx b/apps/fishing-map/features/area-report/vessels/ReportVesselsTableFooter.tsx index ff38745b0a..f6407b075c 100644 --- a/apps/fishing-map/features/area-report/vessels/ReportVesselsTableFooter.tsx +++ b/apps/fishing-map/features/area-report/vessels/ReportVesselsTableFooter.tsx @@ -9,7 +9,6 @@ import I18nNumber from 'features/i18n/i18nNumber' import { useLocationConnect } from 'routes/routes.hook' import VesselGroupAddButton from 'features/vessel-groups/VesselGroupAddButton' import { selectTimeRange } from 'features/app/selectors/app.timebar.selectors' -import { selectReportVesselFilter } from 'features/app/selectors/app.reports.selector' import { REPORT_SHOW_MORE_VESSELS_PER_PAGE, REPORT_VESSELS_PER_PAGE } from 'data/config' import { useAppDispatch } from 'features/app/app.hooks' import { @@ -23,11 +22,11 @@ import { selectReportVesselsList, selectReportVesselsListWithAllInfo, selectReportVesselsPagination, - getVesselsFiltered, ReportVesselWithDatasets, selectReportAreaName, } from '../reports.selectors' -import { parseReportVesselsToIdentity } from '../reports.utils' +import { getVesselsFiltered, parseReportVesselsToIdentity } from '../reports.utils' +import { selectReportVesselFilter } from '../reports.config.selectors' import styles from './ReportVesselsTableFooter.module.css' type ReportVesselsTableFooterProps = { @@ -53,12 +52,13 @@ export default function ReportVesselsTableFooter({ reportName }: ReportVesselsTa const onDownloadVesselsClick = () => { if (allVesselsWithAllInfo?.length) { - const vessels = getVesselsFiltered(allVesselsWithAllInfo, reportVesselFilter)?.map( - (vessel) => { - const { dataviewId, category, sourceColor, flagTranslatedClean, ...rest } = vessel - return rest - } - ) as ReportVesselWithDatasets[] + const vessels = getVesselsFiltered( + allVesselsWithAllInfo, + reportVesselFilter + )?.map((vessel) => { + const { dataviewId, category, sourceColor, flagTranslatedClean, ...rest } = vessel + return rest + }) trackEvent({ category: TrackCategory.Analysis, action: `Click 'Download CSV'`, diff --git a/apps/fishing-map/features/dataviews/selectors/dataviews.selectors.ts b/apps/fishing-map/features/dataviews/selectors/dataviews.selectors.ts index cd19b58427..e06adbb259 100644 --- a/apps/fishing-map/features/dataviews/selectors/dataviews.selectors.ts +++ b/apps/fishing-map/features/dataviews/selectors/dataviews.selectors.ts @@ -15,13 +15,10 @@ import { getRelatedDatasetByType, isPrivateDataset, } from 'features/datasets/datasets.utils' -import { - selectWorkspaceDataviewInstances, - selectWorkspaceStateProperty, -} from 'features/workspace/workspace.selectors' +import { selectWorkspaceDataviewInstances } from 'features/workspace/workspace.selectors' import { DEFAULT_BASEMAP_DATAVIEW_INSTANCE, DEFAULT_DATAVIEW_SLUGS } from 'data/workspaces' import { selectAllDataviews } from 'features/dataviews/dataviews.slice' -import { ReportCategory, TimebarVisualisations } from 'types' +import { TimebarVisualisations } from 'types' import { createDeepEqualSelector } from 'utils/selectors' import { selectIsAnyVesselLocation, @@ -43,6 +40,8 @@ import { isBathymetryDataview } from 'features/dataviews/dataviews.utils' import { selectDownloadActiveTabId } from 'features/download/downloadActivity.slice' import { HeatmapDownloadTab } from 'features/download/downloadActivity.config' import { selectViewOnlyVesselGroup } from 'features/vessel-group-report/vessel-group.config.selectors' +import { ReportCategory } from 'features/area-report/reports.types' +import { selectReportCategorySelector } from 'features/area-report/reports.config.selectors' import { selectContextAreasDataviews, selectActivityDataviews, @@ -82,7 +81,6 @@ export const selectReportActiveCategories = createSelector( } ) -const selectReportCategorySelector = selectWorkspaceStateProperty('reportCategory') const selectReportCategory = createSelector( [selectReportCategorySelector, selectReportActiveCategories], (reportCategory, activeCategories): ReportCategory => { diff --git a/apps/fishing-map/features/search/Search.tsx b/apps/fishing-map/features/search/Search.tsx index bf6511cc18..fda64ccf87 100644 --- a/apps/fishing-map/features/search/Search.tsx +++ b/apps/fishing-map/features/search/Search.tsx @@ -41,7 +41,7 @@ import { isBasicSearchAllowed, isAdvancedSearchAllowed, } from 'features/search/search.selectors' -import { VesselSearchState } from 'types' +import { VesselSearchState } from 'features/search/search.types' import { TrackCategory, trackEvent } from 'features/app/analytics.hooks' import styles from './Search.module.css' diff --git a/apps/fishing-map/features/search/advanced/SearchAdvancedFilters.tsx b/apps/fishing-map/features/search/advanced/SearchAdvancedFilters.tsx index 7e3806f3d6..a58c73483e 100644 --- a/apps/fishing-map/features/search/advanced/SearchAdvancedFilters.tsx +++ b/apps/fishing-map/features/search/advanced/SearchAdvancedFilters.tsx @@ -24,7 +24,7 @@ import { DEFAULT_VESSEL_IDENTITY_ID, } from 'features/vessel/vessel.config' import { useSearchFiltersConnect, useSearchFiltersErrors } from 'features/search/search.hook' -import { VesselSearchState } from 'types' +import { VesselSearchState } from 'features/search/search.types' import { ADVANCED_SEARCH_FIELDS, getSearchDataview, diff --git a/apps/fishing-map/features/search/advanced/SearchAdvancedResults.tsx b/apps/fishing-map/features/search/advanced/SearchAdvancedResults.tsx index 248384835f..47d9bffcd8 100644 --- a/apps/fishing-map/features/search/advanced/SearchAdvancedResults.tsx +++ b/apps/fishing-map/features/search/advanced/SearchAdvancedResults.tsx @@ -25,7 +25,8 @@ import { AsyncReducerStatus } from 'utils/async-slice' import { SearchComponentProps } from 'features/search/basic/SearchBasic' import { useAppDispatch } from 'features/app/app.hooks' import { FIRST_YEAR_OF_DATA } from 'data/config' -import { Locale, VesselSearchState } from 'types' +import { Locale } from 'types' +import { VesselSearchState } from 'features/search/search.types' import I18nDate from 'features/i18n/i18nDate' import { VesselIdentityProperty, diff --git a/apps/fishing-map/features/search/advanced/advanced-search.utils.ts b/apps/fishing-map/features/search/advanced/advanced-search.utils.ts index 9fdf5982ba..130cea3b98 100644 --- a/apps/fishing-map/features/search/advanced/advanced-search.utils.ts +++ b/apps/fishing-map/features/search/advanced/advanced-search.utils.ts @@ -1,6 +1,6 @@ import { Dataset } from '@globalfishingwatch/api-types' import { SchemaFieldDataview, isFieldInFieldsAllowed } from 'features/datasets/datasets.utils' -import { VesselSearchState } from 'types' +import { VesselSearchState } from 'features/search/search.types' export const ADVANCED_SEARCH_FIELDS = ['ssvid', 'imo', 'callsign', 'owner'] as const diff --git a/apps/fishing-map/features/search/search.config.selectors.ts b/apps/fishing-map/features/search/search.config.selectors.ts index 10f57a7517..a451c32c9b 100644 --- a/apps/fishing-map/features/search/search.config.selectors.ts +++ b/apps/fishing-map/features/search/search.config.selectors.ts @@ -1,7 +1,7 @@ import { createSelector } from '@reduxjs/toolkit' import { selectLocationQuery } from 'routes/routes.selectors' import { DEFAULT_SEARCH_STATE } from 'features/search/search.config' -import { VesselSearchState, VesselSearchStateProperty } from 'types' +import { VesselSearchState, VesselSearchStateProperty } from 'features/search/search.types' type VesselSearchProperty

= Required[P] function selectVesselSearchStateProperty

(property: P) { diff --git a/apps/fishing-map/features/search/search.config.ts b/apps/fishing-map/features/search/search.config.ts index 1129054a5e..54fb73e31a 100644 --- a/apps/fishing-map/features/search/search.config.ts +++ b/apps/fishing-map/features/search/search.config.ts @@ -1,4 +1,4 @@ -import { VesselSearchState } from 'types' +import { VesselSearchState } from 'features/search/search.types' export const MIN_SEARCH_CHARACTERS = 3 diff --git a/apps/fishing-map/features/search/search.hook.ts b/apps/fishing-map/features/search/search.hook.ts index 0dee94cecb..0cd34e23d0 100644 --- a/apps/fishing-map/features/search/search.hook.ts +++ b/apps/fishing-map/features/search/search.hook.ts @@ -7,7 +7,7 @@ import { selectSearchOption, selectSearchQuery, } from 'features/search/search.config.selectors' -import { VesselSearchState } from 'types' +import { VesselSearchState } from 'features/search/search.types' import { useAppDispatch } from 'features/app/app.hooks' import { MIN_SEARCH_CHARACTERS, RESULTS_PER_PAGE } from 'features/search/search.config' import { selectIsGFWUser } from 'features/user/selectors/user.selectors' diff --git a/apps/fishing-map/features/search/search.slice.ts b/apps/fishing-map/features/search/search.slice.ts index b10f1b6f29..99234cdaac 100644 --- a/apps/fishing-map/features/search/search.slice.ts +++ b/apps/fishing-map/features/search/search.slice.ts @@ -19,9 +19,9 @@ import { import { AsyncError, AsyncReducerStatus } from 'utils/async-slice' import { selectDatasetById } from 'features/datasets/datasets.slice' import { getRelatedDatasetByType, isFieldInFieldsAllowed } from 'features/datasets/datasets.utils' -import { VesselSearchState } from 'types' import { IdentityVesselData, VesselDataIdentity } from 'features/vessel/vessel.slice' import { getVesselId, getVesselIdentities } from 'features/vessel/vessel.utils' +import { VesselSearchState } from 'features/search/search.types' export type VesselLastIdentity = Omit & { dataset: Dataset | string diff --git a/apps/fishing-map/features/search/search.types.ts b/apps/fishing-map/features/search/search.types.ts new file mode 100644 index 0000000000..70197b4389 --- /dev/null +++ b/apps/fishing-map/features/search/search.types.ts @@ -0,0 +1,26 @@ +import { GearType, VesselIdentitySourceEnum, VesselType } from '@globalfishingwatch/api-types' +import { SearchType } from './search.config' + +export type VesselSearchState = { + query?: string + shipname?: string + sources?: string[] + searchOption?: SearchType + infoSource?: VesselIdentitySourceEnum + ssvid?: string + imo?: string + callsign?: string + codMarinha?: string + nationalId?: string + flag?: string[] + geartypes?: GearType[] + shiptypes?: VesselType[] + targetSpecies?: string + transmissionDateFrom?: string + transmissionDateTo?: string + owner?: string + fleet?: string[] + origin?: string +} + +export type VesselSearchStateProperty = keyof VesselSearchState diff --git a/apps/fishing-map/features/vessel-group-report/VesselGroupReport.tsx b/apps/fishing-map/features/vessel-group-report/VesselGroupReport.tsx index d61566aa9e..234786c370 100644 --- a/apps/fishing-map/features/vessel-group-report/VesselGroupReport.tsx +++ b/apps/fishing-map/features/vessel-group-report/VesselGroupReport.tsx @@ -4,9 +4,9 @@ import { useCallback, useEffect, useMemo } from 'react' import { Tab, Tabs } from '@globalfishingwatch/ui-components' import { selectReportVesselGroupId } from 'routes/routes.selectors' import { AsyncReducerStatus } from 'utils/async-slice' -import { VesselGroupReportSection } from 'types' import { TrackCategory, trackEvent } from 'features/app/analytics.hooks' import { useLocationConnect } from 'routes/routes.hook' +import { VesselGroupReportSection } from 'features/vessel-groups/vessel-groups.types' import { useFetchVesselGroupReport } from './vessel-group-report.hooks' import { selectVesselGroupReportData, diff --git a/apps/fishing-map/features/vessel-group-report/vessel-group-report.config.ts b/apps/fishing-map/features/vessel-group-report/vessel-group-report.config.ts index ca16d5d123..2e2fadf24b 100644 --- a/apps/fishing-map/features/vessel-group-report/vessel-group-report.config.ts +++ b/apps/fishing-map/features/vessel-group-report/vessel-group-report.config.ts @@ -1,5 +1,5 @@ import { REPORT_VESSELS_PER_PAGE } from 'data/config' -import { VesselGroupReportState } from 'types' +import { VesselGroupReportState } from 'features/vessel-groups/vessel-groups.types' export const OTHER_CATEGORY_LABEL = 'OTHER' diff --git a/apps/fishing-map/features/vessel-group-report/vessel-group.config.selectors.ts b/apps/fishing-map/features/vessel-group-report/vessel-group.config.selectors.ts index 0fdbdc6f2c..3164a0e0e6 100644 --- a/apps/fishing-map/features/vessel-group-report/vessel-group.config.selectors.ts +++ b/apps/fishing-map/features/vessel-group-report/vessel-group.config.selectors.ts @@ -1,6 +1,9 @@ import { createSelector } from '@reduxjs/toolkit' -import { VesselGroupReportState, VesselGroupReportStateProperty } from 'types' import { selectQueryParam } from 'routes/routes.selectors' +import { + VesselGroupReportState, + VesselGroupReportStateProperty, +} from 'features/vessel-groups/vessel-groups.types' import { DEFAULT_VESSEL_GROUP_REPORT_STATE } from './vessel-group-report.config' type VesselGroupReportProperty

= diff --git a/apps/fishing-map/features/vessel-group-report/vessels/VesselGroupReportVesselsGraph.tsx b/apps/fishing-map/features/vessel-group-report/vessels/VesselGroupReportVesselsGraph.tsx index 0b24657cd4..eee11c7728 100644 --- a/apps/fishing-map/features/vessel-group-report/vessels/VesselGroupReportVesselsGraph.tsx +++ b/apps/fishing-map/features/vessel-group-report/vessels/VesselGroupReportVesselsGraph.tsx @@ -3,7 +3,6 @@ import cx from 'classnames' import { useSelector } from 'react-redux' import { BarChart, Bar, XAxis, Tooltip, ResponsiveContainer, LabelList } from 'recharts' import { useTranslation } from 'react-i18next' -import { VesselGroupReportVesselsSubsection } from 'types' import I18nNumber, { formatI18nNumber } from 'features/i18n/i18nNumber' import { EMPTY_API_VALUES, OTHERS_CATEGORY_LABEL } from 'features/area-report/reports.config' import { formatInfoField } from 'utils/info' @@ -12,6 +11,7 @@ import { selectVesselGroupReportVesselsGraphDataGrouped } from 'features/vessel- import { selectReportVesselGroupId } from 'routes/routes.selectors' import { selectActiveDataviewInstancesResolved } from 'features/dataviews/selectors/dataviews.instances.selectors' import { useLocationConnect } from 'routes/routes.hook' +import { VesselGroupReportVesselsSubsection } from 'features/vessel-groups/vessel-groups.types' import styles from './VesselGroupReportVesselsGraph.module.css' type ReportGraphTooltipProps = { diff --git a/apps/fishing-map/features/vessel-group-report/vessels/VesselGroupReportVesselsGraphSelector.tsx b/apps/fishing-map/features/vessel-group-report/vessels/VesselGroupReportVesselsGraphSelector.tsx index 70101cd4c6..953017c8c1 100644 --- a/apps/fishing-map/features/vessel-group-report/vessels/VesselGroupReportVesselsGraphSelector.tsx +++ b/apps/fishing-map/features/vessel-group-report/vessels/VesselGroupReportVesselsGraphSelector.tsx @@ -1,10 +1,10 @@ import { useSelector } from 'react-redux' import { useTranslation } from 'react-i18next' import { Choice, ChoiceOption } from '@globalfishingwatch/ui-components' -import { VesselGroupReportVesselsSubsection } from 'types' import { useLocationConnect } from 'routes/routes.hook' import { selectVesselGroupReportStatus } from 'features/vessel-group-report/vessel-group-report.slice' import { AsyncReducerStatus } from 'utils/async-slice' +import { VesselGroupReportVesselsSubsection } from 'features/vessel-groups/vessel-groups.types' import { selectVesselGroupReportVesselsSubsection } from '../vessel-group.config.selectors' type VesselGroupReportVesselsGraphSelectorProps = {} diff --git a/apps/fishing-map/features/vessel-group-report/vessels/VesselGroupReportVesselsTable.tsx b/apps/fishing-map/features/vessel-group-report/vessels/VesselGroupReportVesselsTable.tsx index 655779c4ed..c3bfb8851d 100644 --- a/apps/fishing-map/features/vessel-group-report/vessels/VesselGroupReportVesselsTable.tsx +++ b/apps/fishing-map/features/vessel-group-report/vessels/VesselGroupReportVesselsTable.tsx @@ -14,15 +14,15 @@ import VesselLink from 'features/vessel/VesselLink' import VesselPin from 'features/vessel/VesselPin' import { selectWorkspaceStatus } from 'features/workspace/workspace.selectors' import { AsyncReducerStatus } from 'utils/async-slice' -import { - VesselGroupReportVesselsOrderDirection, - VesselGroupReportVesselsOrderProperty, -} from 'types' import { selectVesselGroupReportVesselsOrderDirection, selectVesselGroupReportVesselsOrderProperty, } from 'features/vessel-group-report/vessel-group.config.selectors' import { selectVesselGroupReportVessels } from 'features/vessel-group-report/vessel-group-report.slice' +import { + VesselGroupReportVesselsOrderProperty, + VesselGroupReportVesselsOrderDirection, +} from 'features/vessel-groups/vessel-groups.types' import styles from './VesselGroupReportVesselsTable.module.css' import { selectVesselGroupReportVesselsPaginated } from './vessel-group-report-vessels.selectors' import VesselGroupReportVesselsTableFooter from './VesselGroupReportVesselsTableFooter' diff --git a/apps/fishing-map/features/vessel-groups/vessel-groups.types.ts b/apps/fishing-map/features/vessel-groups/vessel-groups.types.ts new file mode 100644 index 0000000000..bc074964b2 --- /dev/null +++ b/apps/fishing-map/features/vessel-groups/vessel-groups.types.ts @@ -0,0 +1,21 @@ +export type VesselGroupReportSection = 'vessels' | 'insights' | 'activity' | 'events' +export type VesselGroupReportVesselsSubsection = 'flag' | 'shiptypes' | 'geartypes' | 'source' +export type VesselGroupReportActivitySubsection = 'fishing-effort' | 'presence' +export type VesselGroupReportEventsSubsection = 'fishing' | 'encounters' | 'port' | 'loitering' +export type VesselGroupReportVesselsOrderProperty = 'shipname' | 'flag' | 'shiptype' +export type VesselGroupReportVesselsOrderDirection = 'asc' | 'desc' + +export type VesselGroupReportState = { + viewOnlyVesselGroup: boolean + vesselGroupReportSection: VesselGroupReportSection + vesselGroupReportVesselsSubsection?: VesselGroupReportVesselsSubsection + vesselGroupReportActivitySubsection?: VesselGroupReportActivitySubsection + vesselGroupReportEventsSubsection?: VesselGroupReportEventsSubsection + vesselGroupReportVesselPage?: number + vesselGroupReportResultsPerPage?: number + vesselGroupReportVesselFilter?: string + vesselGroupReportVesselsOrderProperty?: VesselGroupReportVesselsOrderProperty + vesselGroupReportVesselsOrderDirection?: VesselGroupReportVesselsOrderDirection +} + +export type VesselGroupReportStateProperty = keyof VesselGroupReportState diff --git a/apps/fishing-map/features/vessel/Vessel.tsx b/apps/fishing-map/features/vessel/Vessel.tsx index 53fc2ad729..d13d580671 100644 --- a/apps/fishing-map/features/vessel/Vessel.tsx +++ b/apps/fishing-map/features/vessel/Vessel.tsx @@ -29,7 +29,6 @@ import { useClickedEventConnect } from 'features/map/map-interactions.hooks' import VesselAreas from 'features/vessel/areas/VesselAreas' import RelatedVessels from 'features/vessel/related-vessels/RelatedVessels' import { useLocationConnect } from 'routes/routes.hook' -import { VesselSection } from 'types' import { selectVesselHasEventsDatasets } from 'features/vessel/selectors/vessel.resources.selectors' import { useDataviewInstancesConnect } from 'features/workspace/workspace.hook' import { VESSEL_PROFILE_DATAVIEWS_INSTANCES } from 'data/default-workspaces/context-layers' @@ -50,6 +49,7 @@ import Insights from 'features/vessel/insights/Insights' import VesselActivity from './activity/VesselActivity' import VesselIdentity from './identity/VesselIdentity' import styles from './Vessel.module.css' +import { VesselSection } from './vessel.types' const Vessel = () => { const { t } = useTranslation() diff --git a/apps/fishing-map/features/vessel/activity/VesselActivity.tsx b/apps/fishing-map/features/vessel/activity/VesselActivity.tsx index 48bbdade91..22c0f17b7f 100644 --- a/apps/fishing-map/features/vessel/activity/VesselActivity.tsx +++ b/apps/fishing-map/features/vessel/activity/VesselActivity.tsx @@ -8,12 +8,12 @@ import ActivityByVoyage from 'features/vessel/activity/activity-by-voyage/Activi import { VesselActivitySummary } from 'features/vessel/activity/VesselActivitySummary' import { useLocationConnect } from 'routes/routes.hook' import { selectVesselActivityMode } from 'features/vessel/vessel.config.selectors' -import { VesselProfileActivityMode } from 'types' import { selectVesselHasEventsDatasets } from 'features/vessel/selectors/vessel.resources.selectors' import { TrackCategory, trackEvent } from 'features/app/analytics.hooks' import { selectVesselProfileDataview } from 'features/dataviews/selectors/dataviews.instances.selectors' import { useVesselProfileEventsError, useVesselProfileEventsLoading } from '../vessel-events.hooks' import { useVesselProfileLayer } from '../vessel-bounds.hooks' +import { VesselProfileActivityMode } from '../vessel.types' import styles from './VesselActivity.module.css' const VesselActivity = () => { diff --git a/apps/fishing-map/features/vessel/areas/VesselAreas.tsx b/apps/fishing-map/features/vessel/areas/VesselAreas.tsx index c93e8db423..4d6e9215a1 100644 --- a/apps/fishing-map/features/vessel/areas/VesselAreas.tsx +++ b/apps/fishing-map/features/vessel/areas/VesselAreas.tsx @@ -11,7 +11,6 @@ import { selectEventsGroupedByArea, UNKNOWN_AREA, } from 'features/vessel/activity/vessels-activity.selectors' -import { VesselAreaSubsection } from 'types' import { selectVesselAreaSubsection } from 'features/vessel/vessel.config.selectors' import { useLocationConnect } from 'routes/routes.hook' import { useRegionNamesByType } from 'features/regions/regions.hooks' @@ -27,6 +26,7 @@ import { selectVesselProfileColor } from 'features/dataviews/selectors/dataviews import { useMapFitBounds } from 'features/map/map-bounds.hooks' import { useDebouncedDispatchHighlightedEvent } from 'features/map/map-interactions.hooks' import { useVesselProfileEventsLoading } from '../vessel-events.hooks' +import { VesselAreaSubsection } from '../vessel.types' import styles from './VesselAreas.module.css' type VesselAreasProps = { diff --git a/apps/fishing-map/features/vessel/related-vessels/RelatedVessels.tsx b/apps/fishing-map/features/vessel/related-vessels/RelatedVessels.tsx index 7e08e5c856..0a7e3a0d26 100644 --- a/apps/fishing-map/features/vessel/related-vessels/RelatedVessels.tsx +++ b/apps/fishing-map/features/vessel/related-vessels/RelatedVessels.tsx @@ -2,7 +2,6 @@ import { useTranslation } from 'react-i18next' import { useSelector } from 'react-redux' import { useCallback, useMemo } from 'react' import { Choice, ChoiceOption, Spinner } from '@globalfishingwatch/ui-components' -import { VesselRelatedSubsection } from 'types' import { selectVesselRelatedSubsection } from 'features/vessel/vessel.config.selectors' import { useLocationConnect } from 'routes/routes.hook' import RelatedEncounterVessels from 'features/vessel/related-vessels/RelatedEncounterVessels' @@ -10,6 +9,7 @@ import RelatedOwnersVessels from 'features/vessel/related-vessels/RelatedOwnersV import { VesselActivitySummary } from 'features/vessel/activity/VesselActivitySummary' import { TrackCategory, trackEvent } from 'features/app/analytics.hooks' import { useVesselProfileEventsLoading } from '../vessel-events.hooks' +import { VesselRelatedSubsection } from '../vessel.types' import styles from './RelatedVessels.module.css' const RelatedVessels = () => { diff --git a/apps/fishing-map/features/vessel/vessel.config.selectors.ts b/apps/fishing-map/features/vessel/vessel.config.selectors.ts index d6aca4f2ac..41ce8d65ad 100644 --- a/apps/fishing-map/features/vessel/vessel.config.selectors.ts +++ b/apps/fishing-map/features/vessel/vessel.config.selectors.ts @@ -1,8 +1,8 @@ import { createSelector } from '@reduxjs/toolkit' import { VesselIdentitySourceEnum } from '@globalfishingwatch/api-types' -import { VesselProfileState, VesselProfileStateProperty } from 'types' import { selectQueryParam } from 'routes/routes.selectors' import { DEFAULT_VESSEL_STATE } from 'features/vessel/vessel.config' +import { VesselProfileStateProperty, VesselProfileState } from './vessel.types' type VesselProfileProperty

= Required[P] export function selectVesselProfileStateProperty

( diff --git a/apps/fishing-map/features/vessel/vessel.config.ts b/apps/fishing-map/features/vessel/vessel.config.ts index 8871446ec5..45ce2cf80b 100644 --- a/apps/fishing-map/features/vessel/vessel.config.ts +++ b/apps/fishing-map/features/vessel/vessel.config.ts @@ -2,7 +2,7 @@ import { RegionType, SelfReportedSource } from '@globalfishingwatch/api-types' import { VesselIdentitySourceEnum } from '@globalfishingwatch/api-types' import { I18nNamespaces } from 'features/i18n/i18n.types' import { IdentityVesselData } from 'features/vessel/vessel.slice' -import { VesselProfileState } from 'types' +import { VesselProfileState } from './vessel.types' export const DEFAULT_VESSEL_IDENTITY_DATASET = 'public-global-vessel-identity' export const DEFAULT_VESSEL_IDENTITY_VERSION = 'v3.0' diff --git a/apps/fishing-map/features/vessel/vessel.types.ts b/apps/fishing-map/features/vessel/vessel.types.ts new file mode 100644 index 0000000000..317e6ed94f --- /dev/null +++ b/apps/fishing-map/features/vessel/vessel.types.ts @@ -0,0 +1,19 @@ +import { VesselIdentitySourceEnum } from '@globalfishingwatch/api-types' + +export type VesselSection = 'activity' | 'related_vessels' | 'areas' | 'insights' +export type VesselAreaSubsection = 'fao' | 'eez' | 'mpa' | 'rfmo' +export type VesselRelatedSubsection = 'encounters' | 'owners' +export type VesselProfileActivityMode = 'voyage' | 'type' +export type VesselProfileState = { + vesselDatasetId: string + vesselRegistryId?: string + vesselSelfReportedId?: string + vesselSection: VesselSection + vesselArea: VesselAreaSubsection + vesselRelated: VesselRelatedSubsection + vesselIdentitySource: VesselIdentitySourceEnum + vesselActivityMode: VesselProfileActivityMode + viewOnlyVessel: boolean +} + +export type VesselProfileStateProperty = keyof VesselProfileState diff --git a/apps/fishing-map/features/workspace/workspace.slice.ts b/apps/fishing-map/features/workspace/workspace.slice.ts index 92ac83e729..28c7fc9d46 100644 --- a/apps/fishing-map/features/workspace/workspace.slice.ts +++ b/apps/fishing-map/features/workspace/workspace.slice.ts @@ -19,7 +19,7 @@ import { UrlDataviewInstance, } from '@globalfishingwatch/dataviews-client' import { DEFAULT_TIME_RANGE, PRIVATE_SUFIX, VALID_PASSWORD } from 'data/config' -import { QueryParams, WorkspaceState } from 'types' +import { AnyWorkspaceState, QueryParams, WorkspaceState } from 'types' import { fetchDatasetsByIdsThunk } from 'features/datasets/datasets.slice' import { fetchDataviewsByIdsThunk } from 'features/dataviews/dataviews.slice' import { @@ -71,7 +71,7 @@ interface WorkspaceSliceState { // used to identify when someone saves its own version of the workspace customStatus: AsyncReducerStatus error: AsyncError - data: Workspace | null + data: Workspace | null password: string | typeof VALID_PASSWORD lastVisited: LastWorkspaceVisited | undefined } diff --git a/apps/fishing-map/routes/routes.selectors.ts b/apps/fishing-map/routes/routes.selectors.ts index eb9d317239..b78a0cb8d5 100644 --- a/apps/fishing-map/routes/routes.selectors.ts +++ b/apps/fishing-map/routes/routes.selectors.ts @@ -47,6 +47,7 @@ const selectIsReportLocation = createSelector( [selectLocationType], (locationType) => locationType === REPORT ) + const selectIsWorkspaceReportLocation = createSelector( [selectLocationType], (locationType) => locationType === WORKSPACE_REPORT diff --git a/apps/fishing-map/types/index.ts b/apps/fishing-map/types/index.ts index 00fcf31914..01a7b177f9 100644 --- a/apps/fishing-map/types/index.ts +++ b/apps/fishing-map/types/index.ts @@ -1,12 +1,5 @@ import { BaseUrlWorkspace, UrlDataviewInstance } from '@globalfishingwatch/dataviews-client' -import { - DatasetSubCategory, - DataviewCategory, - EventType, - GearType, - VesselIdentitySourceEnum, - VesselType, -} from '@globalfishingwatch/api-types' +import { EventType } from '@globalfishingwatch/api-types' import { DrawFeatureType, FourwingsVisualizationMode, @@ -14,16 +7,14 @@ import { HEATMAP_LOW_RES_ID, RulerData, } from '@globalfishingwatch/deck-layers' -import { - REPORT_VESSELS_GRAPH_GEARTYPE, - REPORT_VESSELS_GRAPH_FLAG, - REPORT_ACTIVITY_GRAPH_EVOLUTION, - REPORT_ACTIVITY_GRAPH_BEFORE_AFTER, - REPORT_ACTIVITY_GRAPH_PERIOD_COMPARISON, - REPORT_VESSELS_GRAPH_VESSELTYPE, -} from 'data/config' -import { SearchType } from 'features/search/search.config' import { MapAnnotation } from 'features/map/overlays/annotations/annotations.types' +import { AreaReportState, AreaReportStateProperty } from 'features/area-report/reports.types' +import { VesselProfileState, VesselProfileStateProperty } from 'features/vessel/vessel.types' +import { + VesselGroupReportState, + VesselGroupReportStateProperty, +} from 'features/vessel-groups/vessel-groups.types' +import { VesselSearchState, VesselSearchStateProperty } from 'features/search/search.types' export { Locale } from '@globalfishingwatch/api-types' type WorkspaceViewportParam = 'latitude' | 'longitude' | 'zoom' @@ -31,28 +22,16 @@ type WorkspaceTimeRangeParam = 'start' | 'end' export type BufferUnit = 'nauticalmiles' | 'kilometers' export type BufferOperation = 'dissolve' | 'difference' -type ReportStateProperty = - | 'reportActivityGraph' - | 'reportAreaBounds' - | 'reportCategory' - | 'reportResultsPerPage' - | 'reportTimeComparison' - | 'reportVesselFilter' - | 'reportVesselGraph' - | 'reportVesselPage' - | 'reportBufferValue' - | 'reportBufferUnit' - | 'reportBufferOperation' - export type WorkspaceStateProperty = keyof WorkspaceState type AppStateProperty = keyof AppState -type AnyStateProperty = WorkspaceStateProperty | ReportStateProperty | AppStateProperty +type AnyStateProperty = WorkspaceStateProperty | AppStateProperty export type WorkspaceParam = | WorkspaceViewportParam | WorkspaceTimeRangeParam | AnyStateProperty + | AreaReportStateProperty | VesselProfileStateProperty | VesselGroupReportStateProperty | VesselSearchStateProperty @@ -61,29 +40,6 @@ export type WorkspaceViewport = Record type WorkspaceTimeRange = Record type BivariateDataviews = [string, string] -export type ReportActivityGraph = - | typeof REPORT_ACTIVITY_GRAPH_EVOLUTION - | typeof REPORT_ACTIVITY_GRAPH_BEFORE_AFTER - | typeof REPORT_ACTIVITY_GRAPH_PERIOD_COMPARISON - -export type ReportActivityTimeComparison = { - start: string - compareStart: string - duration: number - durationType: 'days' | 'months' -} - -export enum ReportCategory { - Fishing = DatasetSubCategory.Fishing, - Presence = DatasetSubCategory.Presence, - Detections = DataviewCategory.Detections, - Environment = DataviewCategory.Environment, -} - -export type ReportVesselGraph = - | typeof REPORT_VESSELS_GRAPH_GEARTYPE - | typeof REPORT_VESSELS_GRAPH_VESSELTYPE - | typeof REPORT_VESSELS_GRAPH_FLAG export interface WorkspaceState extends BaseUrlWorkspace { activityVisualizationMode?: FourwingsVisualizationMode @@ -97,17 +53,6 @@ export interface WorkspaceState extends BaseUrlWorkspace { mapRulersVisible?: boolean daysFromLatest?: number // use latest day as endAt minus the number of days set here readOnly?: boolean - reportActivityGraph?: ReportActivityGraph - reportAreaBounds?: Bbox - reportCategory?: ReportCategory - reportTimeComparison?: ReportActivityTimeComparison - reportVesselFilter?: string - reportVesselGraph?: ReportVesselGraph - reportVesselPage?: number - reportBufferValue?: number - reportBufferUnit?: BufferUnit - reportBufferOperation?: BufferOperation - reportResultsPerPage?: number sidebarOpen?: boolean timebarGraph?: TimebarGraphs timebarSelectedEnvId?: string @@ -115,68 +60,9 @@ export interface WorkspaceState extends BaseUrlWorkspace { visibleEvents?: VisibleEvents } -export type VesselSearchState = { - query?: string - shipname?: string - sources?: string[] - searchOption?: SearchType - infoSource?: VesselIdentitySourceEnum - ssvid?: string - imo?: string - callsign?: string - codMarinha?: string - nationalId?: string - flag?: string[] - geartypes?: GearType[] - shiptypes?: VesselType[] - targetSpecies?: string - transmissionDateFrom?: string - transmissionDateTo?: string - owner?: string - fleet?: string[] - origin?: string -} - -export type VesselSearchStateProperty = keyof VesselSearchState -export type VesselSection = 'activity' | 'related_vessels' | 'areas' | 'insights' -export type VesselAreaSubsection = 'fao' | 'eez' | 'mpa' | 'rfmo' -export type VesselRelatedSubsection = 'encounters' | 'owners' -export type VesselProfileActivityMode = 'voyage' | 'type' -export type VesselProfileState = { - vesselDatasetId: string - vesselRegistryId?: string - vesselSelfReportedId?: string - vesselSection: VesselSection - vesselArea: VesselAreaSubsection - vesselRelated: VesselRelatedSubsection - vesselIdentitySource: VesselIdentitySourceEnum - vesselActivityMode: VesselProfileActivityMode - viewOnlyVessel: boolean -} - -export type VesselProfileStateProperty = keyof VesselProfileState - -export type VesselGroupReportSection = 'vessels' | 'insights' | 'activity' | 'events' -export type VesselGroupReportVesselsSubsection = 'flag' | 'shiptypes' | 'geartypes' | 'source' -export type VesselGroupReportActivitySubsection = 'fishing-effort' | 'presence' -export type VesselGroupReportEventsSubsection = 'fishing' | 'encounters' | 'port' | 'loitering' -export type VesselGroupReportVesselsOrderProperty = 'shipname' | 'flag' | 'shiptype' -export type VesselGroupReportVesselsOrderDirection = 'asc' | 'desc' - -export type VesselGroupReportState = { - viewOnlyVesselGroup: boolean - vesselGroupReportSection: VesselGroupReportSection - vesselGroupReportVesselsSubsection?: VesselGroupReportVesselsSubsection - vesselGroupReportActivitySubsection?: VesselGroupReportActivitySubsection - vesselGroupReportEventsSubsection?: VesselGroupReportEventsSubsection - vesselGroupReportVesselPage?: number - vesselGroupReportResultsPerPage?: number - vesselGroupReportVesselFilter?: string - vesselGroupReportVesselsOrderProperty?: VesselGroupReportVesselsOrderProperty - vesselGroupReportVesselsOrderDirection?: VesselGroupReportVesselsOrderDirection -} - -export type VesselGroupReportStateProperty = keyof VesselGroupReportState +export type AnyWorkspaceState = Partial< + WorkspaceState & AreaReportState & VesselProfileState & VesselGroupReportState +> type RedirectParam = { 'access-token'?: string @@ -197,9 +83,10 @@ export type AppState = { } export type QueryParams = Partial & - Partial & WorkspaceState & + Partial & Partial & + Partial & Partial & AppState & RedirectParam &