From cdde3253a53b94e0e875ebcc0844e359fa9e692b Mon Sep 17 00:00:00 2001 From: satellitestudiodesign Date: Tue, 26 Nov 2024 16:38:33 +0100 Subject: [PATCH 1/4] add GFWOnly vesselId field to advance search and link to profile without related ids --- .../features/dataviews/dataviews.utils.ts | 10 +++---- .../search/advanced/SearchAdvanced.tsx | 18 +++++++++++++ .../search/advanced/SearchAdvancedResults.tsx | 18 ++++++++++--- .../search/search.config.selectors.ts | 4 +++ .../features/search/search.config.ts | 1 + .../features/search/search.types.ts | 1 + .../features/vessel/Vessel.module.css | 8 ++++++ apps/fishing-map/features/vessel/Vessel.tsx | 26 ++++++++++++++++--- .../vessel/vessel.config.selectors.ts | 3 +++ .../features/vessel/vessel.config.ts | 1 + .../features/vessel/vessel.slice.ts | 22 ++++++++++++---- .../features/vessel/vessel.types.ts | 1 + libs/api-client/src/utils/search.ts | 3 +++ 13 files changed, 100 insertions(+), 16 deletions(-) diff --git a/apps/fishing-map/features/dataviews/dataviews.utils.ts b/apps/fishing-map/features/dataviews/dataviews.utils.ts index fcaf464b38..447c47d0fa 100644 --- a/apps/fishing-map/features/dataviews/dataviews.utils.ts +++ b/apps/fishing-map/features/dataviews/dataviews.utils.ts @@ -49,17 +49,17 @@ export function dataviewHasVesselGroupId(dataview: UrlDataviewInstance, vesselGr export const getVesselInfoDataviewInstanceDatasetConfig = ( vesselId: string, - { info }: VesselInstanceDatasets + { info }: VesselInstanceDatasets, + includeRelatedIdentities = true ) => { return { datasetId: info, params: [{ id: 'vesselId', value: vesselId }], query: [ { id: 'dataset', value: info }, - { - id: 'includes', - value: [INCLUDES_RELATED_SELF_REPORTED_INFO_ID], - }, + ...(includeRelatedIdentities + ? [{ id: 'includes', value: [INCLUDES_RELATED_SELF_REPORTED_INFO_ID] }] + : []), ], endpoint: EndpointId.Vessel, } as DataviewDatasetConfig diff --git a/apps/fishing-map/features/search/advanced/SearchAdvanced.tsx b/apps/fishing-map/features/search/advanced/SearchAdvanced.tsx index d7a2d32210..15f15cb3f3 100644 --- a/apps/fishing-map/features/search/advanced/SearchAdvanced.tsx +++ b/apps/fishing-map/features/search/advanced/SearchAdvanced.tsx @@ -28,6 +28,7 @@ import SearchPlaceholder, { SearchEmptyState, } from 'features/search/SearchPlaceholders' import { isAdvancedSearchAllowed } from 'features/search/search.selectors' +import { selectIsGFWUser } from 'features/user/selectors/user.selectors' import SearchError from '../basic/SearchError' const SearchAdvancedResults = dynamic( @@ -43,12 +44,14 @@ function SearchAdvanced({ const dispatch = useAppDispatch() const { searchPagination, searchSuggestion, searchSuggestionClicked } = useSearchConnect() const advancedSearchAllowed = useSelector(isAdvancedSearchAllowed) + const { searchFilters, setSearchFilters } = useSearchFiltersConnect() const searchStatus = useSelector(selectSearchStatus) const searchQuery = useSelector(selectSearchQuery) const searchStatusCode = useSelector(selectSearchStatusCode) const { dispatchQueryParams } = useLocationConnect() const { hasFilters } = useSearchFiltersConnect() const searchFilterErrors = useSearchFiltersErrors() + const isGFWUser = useSelector(selectIsGFWUser) const ref = useEventKeyListener(['Enter'], fetchResults) const resetSearchState = useCallback(() => { @@ -72,12 +75,27 @@ function SearchAdvanced({ dispatchQueryParams({ query: e.target.value }) } + const handleSearchIdChange = (e: ChangeEvent) => { + setSearchFilters({ id: e.target.value }) + } + const hasSearchFilterErrors = Object.keys(searchFilterErrors).length > 0 return (
+ {isGFWUser && ( +
+ + +
+ )} return ( { if (tableContainerRef.current) { diff --git a/apps/fishing-map/features/search/search.config.selectors.ts b/apps/fishing-map/features/search/search.config.selectors.ts index a451c32c9b..3b9538eac2 100644 --- a/apps/fishing-map/features/search/search.config.selectors.ts +++ b/apps/fishing-map/features/search/search.config.selectors.ts @@ -12,6 +12,7 @@ function selectVesselSearchStateProperty

(pr }) } +export const selectSearchId = selectVesselSearchStateProperty('id') export const selectSearchQuery = selectVesselSearchStateProperty('query') export const selectSearchOption = selectVesselSearchStateProperty('searchOption') export const selectSearchInfoSource = selectVesselSearchStateProperty('infoSource') @@ -34,6 +35,7 @@ export const selectSearchOrigin = selectVesselSearchStateProperty('origin') export const selectSearchFilters = createSelector( [ + selectSearchId, selectSearchFlag, selectSearchSources, selectSearchTransmissionDateFrom, @@ -52,6 +54,7 @@ export const selectSearchFilters = createSelector( selectSearchInfoSource, ], ( + id, flag, sources, transmissionDateFrom, @@ -70,6 +73,7 @@ export const selectSearchFilters = createSelector( infoSource ): VesselSearchState => { return { + id, flag, sources, transmissionDateFrom, diff --git a/apps/fishing-map/features/search/search.config.ts b/apps/fishing-map/features/search/search.config.ts index 54fb73e31a..4c066859f2 100644 --- a/apps/fishing-map/features/search/search.config.ts +++ b/apps/fishing-map/features/search/search.config.ts @@ -8,6 +8,7 @@ export const RESULTS_PER_PAGE = 20 export const SSVID_LENGTH = 9 export const IMO_LENGTH = 7 export const EMPTY_FILTERS = { + id: undefined, query: undefined, flag: undefined, infoSource: undefined, diff --git a/apps/fishing-map/features/search/search.types.ts b/apps/fishing-map/features/search/search.types.ts index 70197b4389..d25731aeaa 100644 --- a/apps/fishing-map/features/search/search.types.ts +++ b/apps/fishing-map/features/search/search.types.ts @@ -2,6 +2,7 @@ import { GearType, VesselIdentitySourceEnum, VesselType } from '@globalfishingwa import { SearchType } from './search.config' export type VesselSearchState = { + id?: string query?: string shipname?: string sources?: string[] diff --git a/apps/fishing-map/features/vessel/Vessel.module.css b/apps/fishing-map/features/vessel/Vessel.module.css index 53d7e43601..9520840d33 100644 --- a/apps/fishing-map/features/vessel/Vessel.module.css +++ b/apps/fishing-map/features/vessel/Vessel.module.css @@ -11,3 +11,11 @@ position: relative; z-index: 1; } + +.fullProfileMessage { + padding: var(--space-S) var(--space-S) var(--space-S) var(--space-M); + display: flex; + align-items: center; + justify-content: space-between; + border-bottom: var(--border); +} diff --git a/apps/fishing-map/features/vessel/Vessel.tsx b/apps/fishing-map/features/vessel/Vessel.tsx index 3fd676f051..32cd171689 100644 --- a/apps/fishing-map/features/vessel/Vessel.tsx +++ b/apps/fishing-map/features/vessel/Vessel.tsx @@ -1,7 +1,7 @@ import { useSelector } from 'react-redux' import { Fragment, useCallback, useEffect, useMemo } from 'react' import { useTranslation } from 'react-i18next' -import { Spinner, Tab, Tabs } from '@globalfishingwatch/ui-components' +import { Button, Spinner, Tab, Tabs } from '@globalfishingwatch/ui-components' import { isAuthError } from '@globalfishingwatch/api-client' import { Dataview, VesselIdentitySourceEnum } from '@globalfishingwatch/api-types' import { @@ -16,6 +16,7 @@ import { AsyncReducerStatus } from 'utils/async-slice' import { useFetchDataviewResources } from 'features/resources/resources.hooks' import { ErrorPlaceHolder, WorkspaceLoginError } from 'features/workspace/WorkspaceError' import { + selectIncludeRelatedIdentities, selectVesselAreaSubsection, selectVesselDatasetId, selectVesselSection, @@ -37,7 +38,7 @@ import { BASEMAP_DATAVIEW_SLUG } from 'data/workspaces' import { useVesselFitBounds } from 'features/vessel/vessel-bounds.hooks' import { getVesselIdentities } from 'features/vessel/vessel.utils' import { TrackCategory, trackEvent } from 'features/app/analytics.hooks' -import { selectIsGuestUser } from 'features/user/selectors/user.selectors' +import { selectIsGFWUser, selectIsGuestUser } from 'features/user/selectors/user.selectors' import { selectVesselInfoStatus, selectVesselInfoError, @@ -55,6 +56,8 @@ const Vessel = () => { const { dispatchQueryParams } = useLocationConnect() const { removeDataviewInstance, upsertDataviewInstance } = useDataviewInstancesConnect() const vesselId = useSelector(selectVesselId) + const isGFWUser = useSelector(selectIsGFWUser) + const includeRelatedIdentities = useSelector(selectIncludeRelatedIdentities) const vesselSection = useSelector(selectVesselSection) const vesselArea = useSelector(selectVesselAreaSubsection) const datasetId = useSelector(selectVesselDatasetId) @@ -150,7 +153,7 @@ const Vessel = () => { infoStatus === AsyncReducerStatus.Idle || (infoStatus === AsyncReducerStatus.Error && infoError?.status === 401) ) { - dispatch(fetchVesselInfoThunk({ vesselId, datasetId })) + dispatch(fetchVesselInfoThunk({ vesselId, datasetId, includeRelatedIdentities })) } // eslint-disable-next-line react-hooks/exhaustive-deps }, [datasetId, dispatch, vesselId, urlWorkspaceId]) @@ -173,6 +176,11 @@ const Vessel = () => { [dispatchQueryParams, updateAreaLayersVisibility, vesselArea] ) + const handleFullProfileClick = useCallback(() => { + dispatchQueryParams({ includeRelatedIdentities: true }) + window.location.reload() + }, [dispatchQueryParams]) + if (infoStatus === AsyncReducerStatus.Loading) { return } @@ -197,6 +205,18 @@ const Vessel = () => { {infoStatus === AsyncReducerStatus.Finished && ( + {isGFWUser && !includeRelatedIdentities && ( +

+
+ You're seeing the identity and activity of a single vesselId: +
+ {vesselId} +
+ +
+ )}
diff --git a/apps/fishing-map/features/vessel/vessel.config.selectors.ts b/apps/fishing-map/features/vessel/vessel.config.selectors.ts index 0d3922fd55..fd6ae75053 100644 --- a/apps/fishing-map/features/vessel/vessel.config.selectors.ts +++ b/apps/fishing-map/features/vessel/vessel.config.selectors.ts @@ -23,6 +23,9 @@ export const selectVesselRelatedSubsection = selectVesselProfileStateProperty('v export const selectViewOnlyVessel = selectVesselProfileStateProperty('viewOnlyVessel') export const selectVesselRegistryId = selectVesselProfileStateProperty('vesselRegistryId') export const selectVesselSelfReportedId = selectVesselProfileStateProperty('vesselSelfReportedId') +export const selectIncludeRelatedIdentities = selectVesselProfileStateProperty( + 'includeRelatedIdentities' +) export const selectVesselIdentityId = createSelector( [selectVesselIdentitySource, selectVesselRegistryId, selectVesselSelfReportedId], diff --git a/apps/fishing-map/features/vessel/vessel.config.ts b/apps/fishing-map/features/vessel/vessel.config.ts index e7610a2162..faf304ecda 100644 --- a/apps/fishing-map/features/vessel/vessel.config.ts +++ b/apps/fishing-map/features/vessel/vessel.config.ts @@ -27,6 +27,7 @@ export const DEFAULT_VESSEL_STATE: VesselProfileState = { vesselArea: 'eez', vesselRelated: 'encounters', viewOnlyVessel: true, + includeRelatedIdentities: true, } export type VesselRenderField = { diff --git a/apps/fishing-map/features/vessel/vessel.slice.ts b/apps/fishing-map/features/vessel/vessel.slice.ts index 7f254be9b6..ef8fa5da10 100644 --- a/apps/fishing-map/features/vessel/vessel.slice.ts +++ b/apps/fishing-map/features/vessel/vessel.slice.ts @@ -92,11 +92,19 @@ const initialState: VesselState = { type VesselSliceState = { vessel: VesselState } -type FetchVesselThunkParams = { vesselId: string; datasetId: string } +type FetchVesselThunkParams = { + vesselId: string + datasetId: string + includeRelatedIdentities: boolean +} export const fetchVesselInfoThunk = createAsyncThunk( 'vessel/fetchInfo', async ( - { vesselId, datasetId }: FetchVesselThunkParams = {} as FetchVesselThunkParams, + { + vesselId, + datasetId, + includeRelatedIdentities, + }: FetchVesselThunkParams = {} as FetchVesselThunkParams, { dispatch, rejectWithValue, getState } ) => { try { @@ -119,9 +127,13 @@ export const fetchVesselInfoThunk = createAsyncThunk( }) dispatch(fetchDatasetsByIdsThunk({ ids: datasetsToFetch })) - const datasetConfig = getVesselInfoDataviewInstanceDatasetConfig(vesselId, { - info: dataset.id, - }) + const datasetConfig = getVesselInfoDataviewInstanceDatasetConfig( + vesselId, + { + info: dataset.id, + }, + includeRelatedIdentities + ) if (guestUser) { // This changes the order of the query params to avoid the cache datasetConfig.query?.push(CACHE_FALSE_PARAM) diff --git a/apps/fishing-map/features/vessel/vessel.types.ts b/apps/fishing-map/features/vessel/vessel.types.ts index 317e6ed94f..f2072e1573 100644 --- a/apps/fishing-map/features/vessel/vessel.types.ts +++ b/apps/fishing-map/features/vessel/vessel.types.ts @@ -14,6 +14,7 @@ export type VesselProfileState = { vesselIdentitySource: VesselIdentitySourceEnum vesselActivityMode: VesselProfileActivityMode viewOnlyVessel: boolean + includeRelatedIdentities?: boolean } export type VesselProfileStateProperty = keyof VesselProfileState diff --git a/libs/api-client/src/utils/search.ts b/libs/api-client/src/utils/search.ts index 75dd319a7d..2322ba87b4 100644 --- a/libs/api-client/src/utils/search.ts +++ b/libs/api-client/src/utils/search.ts @@ -133,6 +133,9 @@ export const getAdvancedSearchQuery = ( const getFieldValue = (value: string) => { const operator = field?.operator || params?.operator || '=' + if (field.key === 'id') { + return `selfReportedInfo.id ${operator} '${value}'` + } if (field.key === 'owner') { return `registryOwners.name ${operator} ${value}` } From 837d30df6d44621018d630f5da9abc1f12b90b45 Mon Sep 17 00:00:00 2001 From: satellitestudiodesign Date: Tue, 26 Nov 2024 18:15:08 +0100 Subject: [PATCH 2/4] tweak message --- apps/fishing-map/features/vessel/Vessel.module.css | 1 + apps/fishing-map/features/vessel/Vessel.tsx | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/fishing-map/features/vessel/Vessel.module.css b/apps/fishing-map/features/vessel/Vessel.module.css index 9520840d33..2c7bf1af0b 100644 --- a/apps/fishing-map/features/vessel/Vessel.module.css +++ b/apps/fishing-map/features/vessel/Vessel.module.css @@ -13,6 +13,7 @@ } .fullProfileMessage { + color: var(--color-secondary-blue); padding: var(--space-S) var(--space-S) var(--space-S) var(--space-M); display: flex; align-items: center; diff --git a/apps/fishing-map/features/vessel/Vessel.tsx b/apps/fishing-map/features/vessel/Vessel.tsx index 32cd171689..ad37ab4a11 100644 --- a/apps/fishing-map/features/vessel/Vessel.tsx +++ b/apps/fishing-map/features/vessel/Vessel.tsx @@ -208,7 +208,7 @@ const Vessel = () => { {isGFWUser && !includeRelatedIdentities && (
- You're seeing the identity and activity of a single vesselId: + Identity and activity of a single vessel id (only for GFW users):
{vesselId}
From 801772fca5d865f8507207c7dc2040619efa982c Mon Sep 17 00:00:00 2001 From: satellitestudiodesign Date: Tue, 26 Nov 2024 18:31:48 +0100 Subject: [PATCH 3/4] change start and end on load full profile --- apps/fishing-map/features/vessel/Vessel.tsx | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/apps/fishing-map/features/vessel/Vessel.tsx b/apps/fishing-map/features/vessel/Vessel.tsx index ad37ab4a11..8075d18fc5 100644 --- a/apps/fishing-map/features/vessel/Vessel.tsx +++ b/apps/fishing-map/features/vessel/Vessel.tsx @@ -177,7 +177,12 @@ const Vessel = () => { ) const handleFullProfileClick = useCallback(() => { - dispatchQueryParams({ includeRelatedIdentities: true }) + dispatchQueryParams({ + includeRelatedIdentities: true, + start: undefined, + end: undefined, + vesselSelfReportedId: undefined, + }) window.location.reload() }, [dispatchQueryParams]) From d2601c48a8632fffd7dcb6720a2a61a930a06646 Mon Sep 17 00:00:00 2001 From: j8seangel Date: Fri, 29 Nov 2024 07:55:31 +0100 Subject: [PATCH 4/4] Merge branch 'develop' into fishing-map/search-by-specific-vessel-id --- .prettierrc | 12 +++ apps/api-portal/eslint.config.js | 3 + apps/data-download-portal/eslint.config.js | 3 + apps/fishing-map-e2e/eslint.config.js | 3 + apps/fishing-map/eslint.config.mjs | 3 + apps/fourwings-explorer/eslint.config.js | 3 + apps/image-labeler/eslint.config.js | 3 + apps/port-labeler/eslint.config.js | 3 + apps/real-time-prototype/eslint.config.js | 3 + apps/track-labeler/eslint.config.js | 3 + .../src/features/timebar/timebar.utils.tsx | 63 +++++++++++++++ apps/user-groups-admin/eslint.config.js | 3 + apps/vessel-history/eslint.config.js | 3 + eslint.config.js | 3 + libs/api-client/eslint.config.js | 3 + libs/api-types/eslint.config.js | 3 + libs/data-transforms/eslint.config.js | 3 + libs/datasets-client/eslint.config.js | 3 + libs/dataviews-client/eslint.config.js | 3 + libs/deck-layer-composer/eslint.config.js | 3 + libs/deck-layers/eslint.config.js | 3 + libs/deck-loaders/eslint.config.js | 3 + libs/features-aggregate/eslint.config.js | 3 + libs/fourwings-aggregate/eslint.config.js | 3 + libs/i18n-labels/eslint.config.js | 3 + libs/layer-composer/eslint.config.js | 3 + libs/ocean-areas/eslint.config.js | 3 + libs/pbf-decoders/eslint.config.js | 3 + libs/react-hooks/eslint.config.js | 3 + libs/timebar/eslint.config.js | 3 + libs/ui-components/eslint.config.js | 3 + linting/legacy.js | 80 +++++++++++++++++++ 32 files changed, 242 insertions(+) create mode 100644 .prettierrc create mode 100644 apps/api-portal/eslint.config.js create mode 100644 apps/data-download-portal/eslint.config.js create mode 100644 apps/fishing-map-e2e/eslint.config.js create mode 100644 apps/fishing-map/eslint.config.mjs create mode 100644 apps/fourwings-explorer/eslint.config.js create mode 100644 apps/image-labeler/eslint.config.js create mode 100644 apps/port-labeler/eslint.config.js create mode 100644 apps/real-time-prototype/eslint.config.js create mode 100644 apps/track-labeler/eslint.config.js create mode 100644 apps/track-labeler/src/features/timebar/timebar.utils.tsx create mode 100644 apps/user-groups-admin/eslint.config.js create mode 100644 apps/vessel-history/eslint.config.js create mode 100644 eslint.config.js create mode 100644 libs/api-client/eslint.config.js create mode 100644 libs/api-types/eslint.config.js create mode 100644 libs/data-transforms/eslint.config.js create mode 100644 libs/datasets-client/eslint.config.js create mode 100644 libs/dataviews-client/eslint.config.js create mode 100644 libs/deck-layer-composer/eslint.config.js create mode 100644 libs/deck-layers/eslint.config.js create mode 100644 libs/deck-loaders/eslint.config.js create mode 100644 libs/features-aggregate/eslint.config.js create mode 100644 libs/fourwings-aggregate/eslint.config.js create mode 100644 libs/i18n-labels/eslint.config.js create mode 100644 libs/layer-composer/eslint.config.js create mode 100644 libs/ocean-areas/eslint.config.js create mode 100644 libs/pbf-decoders/eslint.config.js create mode 100644 libs/react-hooks/eslint.config.js create mode 100644 libs/timebar/eslint.config.js create mode 100644 libs/ui-components/eslint.config.js create mode 100644 linting/legacy.js diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000000..690d66b7d2 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,12 @@ +{ + "semi": false, + "tabWidth": 2, + "useTabs": false, + "printWidth": 100, + "singleQuote": true, + "arrowParens": "always", + "bracketSpacing": true, + "jsxSingleQuote": false, + "bracketSameLine": false, + "trailingComma": "es5" +} diff --git a/apps/api-portal/eslint.config.js b/apps/api-portal/eslint.config.js new file mode 100644 index 0000000000..edeb1efe61 --- /dev/null +++ b/apps/api-portal/eslint.config.js @@ -0,0 +1,3 @@ +import gfwConfig from '@globalfishingwatch/linting' + +export default gfwConfig diff --git a/apps/data-download-portal/eslint.config.js b/apps/data-download-portal/eslint.config.js new file mode 100644 index 0000000000..edeb1efe61 --- /dev/null +++ b/apps/data-download-portal/eslint.config.js @@ -0,0 +1,3 @@ +import gfwConfig from '@globalfishingwatch/linting' + +export default gfwConfig diff --git a/apps/fishing-map-e2e/eslint.config.js b/apps/fishing-map-e2e/eslint.config.js new file mode 100644 index 0000000000..edeb1efe61 --- /dev/null +++ b/apps/fishing-map-e2e/eslint.config.js @@ -0,0 +1,3 @@ +import gfwConfig from '@globalfishingwatch/linting' + +export default gfwConfig diff --git a/apps/fishing-map/eslint.config.mjs b/apps/fishing-map/eslint.config.mjs new file mode 100644 index 0000000000..edeb1efe61 --- /dev/null +++ b/apps/fishing-map/eslint.config.mjs @@ -0,0 +1,3 @@ +import gfwConfig from '@globalfishingwatch/linting' + +export default gfwConfig diff --git a/apps/fourwings-explorer/eslint.config.js b/apps/fourwings-explorer/eslint.config.js new file mode 100644 index 0000000000..edeb1efe61 --- /dev/null +++ b/apps/fourwings-explorer/eslint.config.js @@ -0,0 +1,3 @@ +import gfwConfig from '@globalfishingwatch/linting' + +export default gfwConfig diff --git a/apps/image-labeler/eslint.config.js b/apps/image-labeler/eslint.config.js new file mode 100644 index 0000000000..edeb1efe61 --- /dev/null +++ b/apps/image-labeler/eslint.config.js @@ -0,0 +1,3 @@ +import gfwConfig from '@globalfishingwatch/linting' + +export default gfwConfig diff --git a/apps/port-labeler/eslint.config.js b/apps/port-labeler/eslint.config.js new file mode 100644 index 0000000000..edeb1efe61 --- /dev/null +++ b/apps/port-labeler/eslint.config.js @@ -0,0 +1,3 @@ +import gfwConfig from '@globalfishingwatch/linting' + +export default gfwConfig diff --git a/apps/real-time-prototype/eslint.config.js b/apps/real-time-prototype/eslint.config.js new file mode 100644 index 0000000000..edeb1efe61 --- /dev/null +++ b/apps/real-time-prototype/eslint.config.js @@ -0,0 +1,3 @@ +import gfwConfig from '@globalfishingwatch/linting' + +export default gfwConfig diff --git a/apps/track-labeler/eslint.config.js b/apps/track-labeler/eslint.config.js new file mode 100644 index 0000000000..edeb1efe61 --- /dev/null +++ b/apps/track-labeler/eslint.config.js @@ -0,0 +1,3 @@ +import gfwConfig from '@globalfishingwatch/linting' + +export default gfwConfig diff --git a/apps/track-labeler/src/features/timebar/timebar.utils.tsx b/apps/track-labeler/src/features/timebar/timebar.utils.tsx new file mode 100644 index 0000000000..f362e9f815 --- /dev/null +++ b/apps/track-labeler/src/features/timebar/timebar.utils.tsx @@ -0,0 +1,63 @@ +import type { TrackPoint } from '@globalfishingwatch/api-types' +import type { LayersData, VesselPoint, FilterModeValues } from '../../types' +import { ActionType } from '../../types' + +const getIsOutOfFilterRange = ({ + value, + filterModeValues, + filterMode, +}: { + value: number + filterModeValues: FilterModeValues + filterMode: string +}) => { + if (!filterModeValues[filterMode]) return false + const isNegativRange = filterMode === 'elevation' + return isNegativRange + ? value < Number(filterModeValues[filterMode].max) && + value > Number(filterModeValues[filterMode].min) + : !( + value < Number(filterModeValues[filterMode].min) || + value > Number(filterModeValues[filterMode].max) + ) +} + +export const getTimebarPoints = ( + vesselTrack: LayersData[], + date: { start: number; end: number }, + filterMode: string, + filterModeValues: FilterModeValues +) => { + const eventsWithRenderingInfo: VesselPoint[] = vesselTrack.flatMap((data: LayersData) => { + return data.trackPoints.map((vesselMovement: TrackPoint) => { + const outOfTimeRange = + vesselMovement?.timestamp && + (date.start >= vesselMovement?.timestamp || vesselMovement?.timestamp >= date.end) + const value: number = vesselMovement[filterMode as keyof TrackPoint] as number + const outOfFilterRange = getIsOutOfFilterRange({ value, filterModeValues, filterMode }) + const outOfRange = outOfTimeRange || outOfFilterRange + + return { + timestamp: vesselMovement.timestamp, + speed: vesselMovement.speed, + fishing: false, + course: vesselMovement.course, + elevation: vesselMovement.elevation, + action: data.action || ActionType.untracked, + position: { lat: vesselMovement.latitude, lon: vesselMovement.longitude }, + outOfRange, + } as VesselPoint + }) + }) + return eventsWithRenderingInfo +} + +export const getMaxMinVesselPointsByProperty = (vesselPoints: VesselPoint[], property: string) => { + const min = Math.min( + ...vesselPoints.map((point) => point[property as keyof VesselPoint] as number) + ) + const max = Math.max( + ...vesselPoints.map((point) => point[property as keyof VesselPoint] as number) + ) + return { min, max } +} diff --git a/apps/user-groups-admin/eslint.config.js b/apps/user-groups-admin/eslint.config.js new file mode 100644 index 0000000000..edeb1efe61 --- /dev/null +++ b/apps/user-groups-admin/eslint.config.js @@ -0,0 +1,3 @@ +import gfwConfig from '@globalfishingwatch/linting' + +export default gfwConfig diff --git a/apps/vessel-history/eslint.config.js b/apps/vessel-history/eslint.config.js new file mode 100644 index 0000000000..edeb1efe61 --- /dev/null +++ b/apps/vessel-history/eslint.config.js @@ -0,0 +1,3 @@ +import gfwConfig from '@globalfishingwatch/linting' + +export default gfwConfig diff --git a/eslint.config.js b/eslint.config.js new file mode 100644 index 0000000000..edeb1efe61 --- /dev/null +++ b/eslint.config.js @@ -0,0 +1,3 @@ +import gfwConfig from '@globalfishingwatch/linting' + +export default gfwConfig diff --git a/libs/api-client/eslint.config.js b/libs/api-client/eslint.config.js new file mode 100644 index 0000000000..edeb1efe61 --- /dev/null +++ b/libs/api-client/eslint.config.js @@ -0,0 +1,3 @@ +import gfwConfig from '@globalfishingwatch/linting' + +export default gfwConfig diff --git a/libs/api-types/eslint.config.js b/libs/api-types/eslint.config.js new file mode 100644 index 0000000000..edeb1efe61 --- /dev/null +++ b/libs/api-types/eslint.config.js @@ -0,0 +1,3 @@ +import gfwConfig from '@globalfishingwatch/linting' + +export default gfwConfig diff --git a/libs/data-transforms/eslint.config.js b/libs/data-transforms/eslint.config.js new file mode 100644 index 0000000000..edeb1efe61 --- /dev/null +++ b/libs/data-transforms/eslint.config.js @@ -0,0 +1,3 @@ +import gfwConfig from '@globalfishingwatch/linting' + +export default gfwConfig diff --git a/libs/datasets-client/eslint.config.js b/libs/datasets-client/eslint.config.js new file mode 100644 index 0000000000..edeb1efe61 --- /dev/null +++ b/libs/datasets-client/eslint.config.js @@ -0,0 +1,3 @@ +import gfwConfig from '@globalfishingwatch/linting' + +export default gfwConfig diff --git a/libs/dataviews-client/eslint.config.js b/libs/dataviews-client/eslint.config.js new file mode 100644 index 0000000000..edeb1efe61 --- /dev/null +++ b/libs/dataviews-client/eslint.config.js @@ -0,0 +1,3 @@ +import gfwConfig from '@globalfishingwatch/linting' + +export default gfwConfig diff --git a/libs/deck-layer-composer/eslint.config.js b/libs/deck-layer-composer/eslint.config.js new file mode 100644 index 0000000000..edeb1efe61 --- /dev/null +++ b/libs/deck-layer-composer/eslint.config.js @@ -0,0 +1,3 @@ +import gfwConfig from '@globalfishingwatch/linting' + +export default gfwConfig diff --git a/libs/deck-layers/eslint.config.js b/libs/deck-layers/eslint.config.js new file mode 100644 index 0000000000..edeb1efe61 --- /dev/null +++ b/libs/deck-layers/eslint.config.js @@ -0,0 +1,3 @@ +import gfwConfig from '@globalfishingwatch/linting' + +export default gfwConfig diff --git a/libs/deck-loaders/eslint.config.js b/libs/deck-loaders/eslint.config.js new file mode 100644 index 0000000000..edeb1efe61 --- /dev/null +++ b/libs/deck-loaders/eslint.config.js @@ -0,0 +1,3 @@ +import gfwConfig from '@globalfishingwatch/linting' + +export default gfwConfig diff --git a/libs/features-aggregate/eslint.config.js b/libs/features-aggregate/eslint.config.js new file mode 100644 index 0000000000..edeb1efe61 --- /dev/null +++ b/libs/features-aggregate/eslint.config.js @@ -0,0 +1,3 @@ +import gfwConfig from '@globalfishingwatch/linting' + +export default gfwConfig diff --git a/libs/fourwings-aggregate/eslint.config.js b/libs/fourwings-aggregate/eslint.config.js new file mode 100644 index 0000000000..edeb1efe61 --- /dev/null +++ b/libs/fourwings-aggregate/eslint.config.js @@ -0,0 +1,3 @@ +import gfwConfig from '@globalfishingwatch/linting' + +export default gfwConfig diff --git a/libs/i18n-labels/eslint.config.js b/libs/i18n-labels/eslint.config.js new file mode 100644 index 0000000000..edeb1efe61 --- /dev/null +++ b/libs/i18n-labels/eslint.config.js @@ -0,0 +1,3 @@ +import gfwConfig from '@globalfishingwatch/linting' + +export default gfwConfig diff --git a/libs/layer-composer/eslint.config.js b/libs/layer-composer/eslint.config.js new file mode 100644 index 0000000000..edeb1efe61 --- /dev/null +++ b/libs/layer-composer/eslint.config.js @@ -0,0 +1,3 @@ +import gfwConfig from '@globalfishingwatch/linting' + +export default gfwConfig diff --git a/libs/ocean-areas/eslint.config.js b/libs/ocean-areas/eslint.config.js new file mode 100644 index 0000000000..edeb1efe61 --- /dev/null +++ b/libs/ocean-areas/eslint.config.js @@ -0,0 +1,3 @@ +import gfwConfig from '@globalfishingwatch/linting' + +export default gfwConfig diff --git a/libs/pbf-decoders/eslint.config.js b/libs/pbf-decoders/eslint.config.js new file mode 100644 index 0000000000..edeb1efe61 --- /dev/null +++ b/libs/pbf-decoders/eslint.config.js @@ -0,0 +1,3 @@ +import gfwConfig from '@globalfishingwatch/linting' + +export default gfwConfig diff --git a/libs/react-hooks/eslint.config.js b/libs/react-hooks/eslint.config.js new file mode 100644 index 0000000000..edeb1efe61 --- /dev/null +++ b/libs/react-hooks/eslint.config.js @@ -0,0 +1,3 @@ +import gfwConfig from '@globalfishingwatch/linting' + +export default gfwConfig diff --git a/libs/timebar/eslint.config.js b/libs/timebar/eslint.config.js new file mode 100644 index 0000000000..edeb1efe61 --- /dev/null +++ b/libs/timebar/eslint.config.js @@ -0,0 +1,3 @@ +import gfwConfig from '@globalfishingwatch/linting' + +export default gfwConfig diff --git a/libs/ui-components/eslint.config.js b/libs/ui-components/eslint.config.js new file mode 100644 index 0000000000..edeb1efe61 --- /dev/null +++ b/libs/ui-components/eslint.config.js @@ -0,0 +1,3 @@ +import gfwConfig from '@globalfishingwatch/linting' + +export default gfwConfig diff --git a/linting/legacy.js b/linting/legacy.js new file mode 100644 index 0000000000..b2350916df --- /dev/null +++ b/linting/legacy.js @@ -0,0 +1,80 @@ +module.exports = { + parser: '@typescript-eslint/parser', + extends: [ + // TODO fix + // 'plugin:@typescript-eslint/recommended', + 'react-app', + // TODO fix ESLint couldn't determine the plugin "import" uniquely. + // 'plugin:import/errors', + // 'plugin:import/warnings', + 'plugin:import/typescript', + 'prettier', + ], + // plugins: ['@typescript-eslint', 'react', 'import'], + // TODO fix ESLint couldn't determine the plugin "import" uniquely. + plugins: ['react', '@nx' /*'import'*/], + settings: { + react: { + version: 'detect', + }, + 'import/resolver': { + typescript: {}, + }, + 'import/parsers': { + '@typescript-eslint/parser': ['.ts', '.tsx'], + }, + }, + rules: { + 'import/default': 0, + 'import/no-unresolved': 0, + 'import/no-named-as-default': 0, + 'import/named': 0, + 'import/namespace': 0, + 'import/order': [ + 1, + { + groups: ['builtin', 'external', 'internal', 'parent', 'sibling', 'index'], + 'newlines-between': 'never', + pathGroups: [ + { + pattern: '@globalfishingwatch/**', + group: 'external', + position: 'after', + }, + { + pattern: + '{features,store,routes,common,components,redux-modules,types,assets,pages,data,hooks,utils}', + group: 'internal', + }, + { + pattern: + '{features,store,routes,common,components,redux-modules,types,assets,pages,data,hooks,utils}/**', + group: 'internal', + }, + ], + pathGroupsExcludedImportTypes: ['builtin'], + }, + ], + 'react/jsx-fragments': ['error', 'element'], + '@typescript-eslint/explicit-function-return-type': 0, + '@typescript-eslint/no-var-requires': 0, + '@typescript-eslint/no-redeclare': 0, + // note you must disable the base rule as it can report incorrect errors + // https://github.com/typescript-eslint/typescript-eslint/blob/master/docs/getting-started/linting/FAQ.md#i-am-using-a-rule-from-eslint-core-and-it-doesnt-work-correctly-with-typescript-code + 'no-use-before-define': 'off', + '@typescript-eslint/no-use-before-define': ['error'], + '@typescript-eslint/explicit-module-boundary-types': 0, + '@typescript-eslint/no-explicit-any': 0, + '@typescript-eslint/camelcase': 0, + '@typescript-eslint/no-empty-function': 0, + '@nx/dependency-checks': [ + 'error', + { + ignoredFiles: [ + '{projectRoot}/vite.config.{js,ts,mjs,mts}', + '{projectRoot}/rollup.config.{js,ts,mjs,mts}', + ], + }, + ], + }, +}