From d17de8454f4b81480f2638ed78f33cdd6a48090e Mon Sep 17 00:00:00 2001 From: Loup Theron Date: Wed, 14 Aug 2024 11:35:15 +0200 Subject: [PATCH 1/4] wip: parse new naf marker --- .../domain/entities/position/NetworkType.kt | 6 ++++++ .../domain/entities/position/Position.kt | 1 + .../gouv/cnsp/monitorfish/domain/mappers/NAFCode.kt | 1 + .../monitorfish/domain/mappers/NAFMessageMapper.kt | 9 +++++++++ .../domain/mappers/NAFMessageMapperUTests.kt | 13 +++++++++++++ 5 files changed, 30 insertions(+) create mode 100644 backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/domain/entities/position/NetworkType.kt diff --git a/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/domain/entities/position/NetworkType.kt b/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/domain/entities/position/NetworkType.kt new file mode 100644 index 0000000000..ef52e26d7c --- /dev/null +++ b/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/domain/entities/position/NetworkType.kt @@ -0,0 +1,6 @@ +package fr.gouv.cnsp.monitorfish.domain.entities.position + +enum class NetworkType(val code: String) { + CELLULAR("CEL"), + SATELLITE("SAT"), +} diff --git a/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/domain/entities/position/Position.kt b/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/domain/entities/position/Position.kt index 284c3368aa..f6e6e58d08 100644 --- a/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/domain/entities/position/Position.kt +++ b/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/domain/entities/position/Position.kt @@ -19,6 +19,7 @@ data class Position( val vesselName: String? = null, val flagState: CountryCode? = null, val positionType: PositionType, + val networkType: NetworkType? = null, val isManual: Boolean? = null, val isFishing: Boolean? = null, val isAtPort: Boolean? = null, diff --git a/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/domain/mappers/NAFCode.kt b/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/domain/mappers/NAFCode.kt index b668a4b8bb..e7fa563e57 100644 --- a/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/domain/mappers/NAFCode.kt +++ b/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/domain/mappers/NAFCode.kt @@ -25,6 +25,7 @@ enum class NAFCode(val code: String) { TRIP_NUMBER("TN"), LATITUDE("LA"), LONGITUDE("LO"), + NETWORK_TYPE("MS"), ; diff --git a/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/domain/mappers/NAFMessageMapper.kt b/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/domain/mappers/NAFMessageMapper.kt index c721ae8354..03f2673d50 100644 --- a/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/domain/mappers/NAFMessageMapper.kt +++ b/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/domain/mappers/NAFMessageMapper.kt @@ -1,6 +1,7 @@ package fr.gouv.cnsp.monitorfish.domain.mappers import com.neovisionaries.i18n.CountryCode +import fr.gouv.cnsp.monitorfish.domain.entities.position.NetworkType import fr.gouv.cnsp.monitorfish.domain.entities.position.Position import fr.gouv.cnsp.monitorfish.domain.entities.position.PositionType import fr.gouv.cnsp.monitorfish.domain.exceptions.NAFMessageParsingException @@ -33,6 +34,7 @@ class NAFMessageMapper(private val naf: String) { private var speed: Double? = null private var tripNumber: String? = null private var isManual: Boolean = false + private var networkType: NetworkType? = null private val noCountry = "X" private val positionMessageType = "POS" @@ -83,6 +85,12 @@ class NAFMessageMapper(private val naf: String) { NAFCode.LONGITUDE_DECIMAL -> this.longitude = value.toDouble() NAFCode.SPEED -> this.speed = value.toDouble().div(10) NAFCode.COURSE -> this.course = value.toDouble() + NAFCode.NETWORK_TYPE -> { + when (value.isNotEmpty()) { + true -> this.networkType = NetworkType.valueOf(value) + false -> this.networkType = null + } + } else -> { logger.debug("VMS parsing: NAF code \"$it\" of value \"$value\" not handled") } @@ -152,6 +160,7 @@ class NAFMessageMapper(private val naf: String) { from = from, tripNumber = tripNumber, positionType = PositionType.VMS, + networkType = n, isManual = isManual, ) } diff --git a/backend/src/test/kotlin/fr/gouv/cnsp/monitorfish/domain/mappers/NAFMessageMapperUTests.kt b/backend/src/test/kotlin/fr/gouv/cnsp/monitorfish/domain/mappers/NAFMessageMapperUTests.kt index ea5bd0e539..81fee5be85 100644 --- a/backend/src/test/kotlin/fr/gouv/cnsp/monitorfish/domain/mappers/NAFMessageMapperUTests.kt +++ b/backend/src/test/kotlin/fr/gouv/cnsp/monitorfish/domain/mappers/NAFMessageMapperUTests.kt @@ -205,4 +205,17 @@ internal class NAFMessageMapperUTests { assertThat(position.speed).isNull() assertThat(position.course).isNull() } + + @Test + internal fun `init Should parse the position type When given`() { + // Given + val naf = "//SR//TM/POS//IR/FRA000123456//NA/MANUEL//RC/FT6951//FS/FRA//XR/TL326095//DA/20200814//TI/0911//LT/+43.0789//LG/+006.1549//SP/000//CO/0//FR/FRA//RD/20200814//RT/0912//MS/SAT//ER//" + + // When + val position = NAFMessageMapper(naf).toPosition() + + // Then + assertThat(position.speed).isNull() + assertThat(position.course).isNull() + } } From 3553b1b28dd558ed6e6eaa8d57d34c71ff92f64e Mon Sep 17 00:00:00 2001 From: Loup Theron Date: Wed, 14 Aug 2024 17:28:48 +0200 Subject: [PATCH 2/4] Add network type to positions table --- .../domain/entities/position/NetworkType.kt | 11 +++++++++++ .../monitorfish/domain/entities/position/Position.kt | 2 +- .../monitorfish/domain/mappers/NAFMessageMapper.kt | 6 +++--- .../infrastructure/api/outputs/PositionDataOutput.kt | 3 +++ .../database/entities/PositionEntity.kt | 6 ++++++ .../repositories/interfaces/DBPositionRepository.kt | 9 ++++++--- .../exceptions/BackendRequestErrorCode.kt | 1 + .../internal/V0.273__Update_positions_table.sql | 4 ++++ .../db/testdata/V666.1__Insert_dummy_positions.sql | 8 ++++++++ .../domain/mappers/NAFMessageMapperUTests.kt | 6 +++--- 10 files changed, 46 insertions(+), 10 deletions(-) create mode 100644 backend/src/main/resources/db/migration/internal/V0.273__Update_positions_table.sql diff --git a/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/domain/entities/position/NetworkType.kt b/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/domain/entities/position/NetworkType.kt index ef52e26d7c..0c1409546a 100644 --- a/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/domain/entities/position/NetworkType.kt +++ b/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/domain/entities/position/NetworkType.kt @@ -3,4 +3,15 @@ package fr.gouv.cnsp.monitorfish.domain.entities.position enum class NetworkType(val code: String) { CELLULAR("CEL"), SATELLITE("SAT"), + ; + + companion object { + infix fun from(code: String): NetworkType { + return try { + NetworkType.entries.first { it.code == code } + } catch (e: NoSuchElementException) { + throw NoSuchElementException("NetworkType $code not found.", e) + } + } + } } diff --git a/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/domain/entities/position/Position.kt b/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/domain/entities/position/Position.kt index f6e6e58d08..05214806a1 100644 --- a/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/domain/entities/position/Position.kt +++ b/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/domain/entities/position/Position.kt @@ -19,7 +19,6 @@ data class Position( val vesselName: String? = null, val flagState: CountryCode? = null, val positionType: PositionType, - val networkType: NetworkType? = null, val isManual: Boolean? = null, val isFishing: Boolean? = null, val isAtPort: Boolean? = null, @@ -32,4 +31,5 @@ data class Position( val from: CountryCode? = null, val destination: CountryCode? = null, val tripNumber: String? = null, + val networkType: NetworkType? = null, ) diff --git a/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/domain/mappers/NAFMessageMapper.kt b/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/domain/mappers/NAFMessageMapper.kt index 03f2673d50..5e9722d13f 100644 --- a/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/domain/mappers/NAFMessageMapper.kt +++ b/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/domain/mappers/NAFMessageMapper.kt @@ -87,7 +87,7 @@ class NAFMessageMapper(private val naf: String) { NAFCode.COURSE -> this.course = value.toDouble() NAFCode.NETWORK_TYPE -> { when (value.isNotEmpty()) { - true -> this.networkType = NetworkType.valueOf(value) + true -> this.networkType = NetworkType.from(value) false -> this.networkType = null } } @@ -95,7 +95,7 @@ class NAFMessageMapper(private val naf: String) { logger.debug("VMS parsing: NAF code \"$it\" of value \"$value\" not handled") } } - } catch (e: NumberFormatException) { + } catch (e: Exception) { throw NAFMessageParsingException("Incorrect value at field $it", naf, e) } }.run { @@ -160,7 +160,7 @@ class NAFMessageMapper(private val naf: String) { from = from, tripNumber = tripNumber, positionType = PositionType.VMS, - networkType = n, + networkType = networkType, isManual = isManual, ) } diff --git a/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/api/outputs/PositionDataOutput.kt b/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/api/outputs/PositionDataOutput.kt index b5af90a0cc..102911b30b 100644 --- a/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/api/outputs/PositionDataOutput.kt +++ b/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/api/outputs/PositionDataOutput.kt @@ -1,6 +1,7 @@ package fr.gouv.cnsp.monitorfish.infrastructure.api.outputs import com.neovisionaries.i18n.CountryCode +import fr.gouv.cnsp.monitorfish.domain.entities.position.NetworkType import fr.gouv.cnsp.monitorfish.domain.entities.position.Position import fr.gouv.cnsp.monitorfish.domain.entities.position.PositionType import java.time.ZonedDateTime @@ -24,6 +25,7 @@ data class PositionDataOutput( val isManual: Boolean? = null, val isFishing: Boolean? = null, val isAtPort: Boolean? = null, + val networkType: NetworkType? = null, ) { companion object { fun fromPosition(position: Position): PositionDataOutput { @@ -46,6 +48,7 @@ data class PositionDataOutput( isManual = position.isManual, isFishing = position.isFishing, isAtPort = position.isAtPort, + networkType = position.networkType, ) } } diff --git a/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/database/entities/PositionEntity.kt b/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/database/entities/PositionEntity.kt index a931e72572..2efd96a904 100644 --- a/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/database/entities/PositionEntity.kt +++ b/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/database/entities/PositionEntity.kt @@ -1,6 +1,7 @@ package fr.gouv.cnsp.monitorfish.infrastructure.database.entities import com.neovisionaries.i18n.CountryCode +import fr.gouv.cnsp.monitorfish.domain.entities.position.NetworkType import fr.gouv.cnsp.monitorfish.domain.entities.position.Position import fr.gouv.cnsp.monitorfish.domain.entities.position.PositionType import fr.gouv.cnsp.monitorfish.infrastructure.database.entities.converters.CountryCodeConverter @@ -44,6 +45,9 @@ data class PositionEntity( val isFishing: Boolean? = false, @Column(name = "is_at_port") val isAtPort: Boolean? = null, + @Column(name = "network_type") + @Enumerated(EnumType.STRING) + val networkType: NetworkType? = null, // Mandatory fields @Enumerated(EnumType.STRING) @@ -81,6 +85,7 @@ data class PositionEntity( isManual = isManual, isFishing = isFishing, isAtPort = isAtPort, + networkType = networkType, ) companion object { @@ -103,6 +108,7 @@ data class PositionEntity( positionType = position.positionType, isManual = position.isManual, isFishing = position.isFishing, + networkType = position.networkType, ) } } diff --git a/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/database/repositories/interfaces/DBPositionRepository.kt b/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/database/repositories/interfaces/DBPositionRepository.kt index e92b005086..66ac01ae5a 100644 --- a/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/database/repositories/interfaces/DBPositionRepository.kt +++ b/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/database/repositories/interfaces/DBPositionRepository.kt @@ -29,7 +29,8 @@ interface DBPositionRepository : CrudRepository { "p.position_type, " + "p.is_manual, " + "p.is_fishing, " + - "p.is_at_port " + + "p.is_at_port, " + + "p.network_type " + "from positions p " + "where p.internal_reference_number = :internalReferenceNumber " + "and p.date_time >= :from " + @@ -63,7 +64,8 @@ interface DBPositionRepository : CrudRepository { "p.position_type, " + "p.is_manual, " + "p.is_fishing, " + - "p.is_at_port " + + "p.is_at_port, " + + "p.network_type " + "from positions p " + "where p.external_reference_number = :externalReferenceNumber " + "and p.date_time >= :from " + @@ -97,7 +99,8 @@ interface DBPositionRepository : CrudRepository { "p.position_type, " + "p.is_manual, " + "p.is_fishing, " + - "p.is_at_port " + + "p.is_at_port, " + + "p.network_type " + "from positions p " + "where p.ircs = :ircs " + "and p.date_time >= :from " + diff --git a/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/exceptions/BackendRequestErrorCode.kt b/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/exceptions/BackendRequestErrorCode.kt index 4ac3cec475..37d714f7fc 100644 --- a/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/exceptions/BackendRequestErrorCode.kt +++ b/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/exceptions/BackendRequestErrorCode.kt @@ -13,4 +13,5 @@ package fr.gouv.cnsp.monitorfish.infrastructure.exceptions */ enum class BackendRequestErrorCode { WRONG_BODY_PARAMETER_TYPE, + UNAUTHORIZED, } diff --git a/backend/src/main/resources/db/migration/internal/V0.273__Update_positions_table.sql b/backend/src/main/resources/db/migration/internal/V0.273__Update_positions_table.sql new file mode 100644 index 0000000000..1906c9e29e --- /dev/null +++ b/backend/src/main/resources/db/migration/internal/V0.273__Update_positions_table.sql @@ -0,0 +1,4 @@ +ALTER TABLE + public.positions +ADD COLUMN + network_type varchar(50); diff --git a/backend/src/main/resources/db/testdata/V666.1__Insert_dummy_positions.sql b/backend/src/main/resources/db/testdata/V666.1__Insert_dummy_positions.sql index 89648c9214..c4cc8afb39 100644 --- a/backend/src/main/resources/db/testdata/V666.1__Insert_dummy_positions.sql +++ b/backend/src/main/resources/db/testdata/V666.1__Insert_dummy_positions.sql @@ -69281,3 +69281,11 @@ INSERT INTO POSITIONS (INTERNAL_REFERENCE_NUMBER, EXTERNAL_REFERENCE_NUMBER, MMS update positions set is_at_port = true where INTERNAL_REFERENCE_NUMBER = 'FAK000999999' and date_time < (now() AT TIME ZONE 'UTC')::TIMESTAMP - interval '22 hours'; + +update positions +set network_type = 'CELLULAR' +where INTERNAL_REFERENCE_NUMBER = 'FAK000999999' and date_time < (now() AT TIME ZONE 'UTC')::TIMESTAMP - interval '22 hours'; + +update positions +set network_type = 'SATELLITE' +where INTERNAL_REFERENCE_NUMBER = 'FAK000999999' and date_time > (now() AT TIME ZONE 'UTC')::TIMESTAMP - interval '22 hours'; diff --git a/backend/src/test/kotlin/fr/gouv/cnsp/monitorfish/domain/mappers/NAFMessageMapperUTests.kt b/backend/src/test/kotlin/fr/gouv/cnsp/monitorfish/domain/mappers/NAFMessageMapperUTests.kt index 81fee5be85..cd06993776 100644 --- a/backend/src/test/kotlin/fr/gouv/cnsp/monitorfish/domain/mappers/NAFMessageMapperUTests.kt +++ b/backend/src/test/kotlin/fr/gouv/cnsp/monitorfish/domain/mappers/NAFMessageMapperUTests.kt @@ -1,6 +1,7 @@ package fr.gouv.cnsp.monitorfish.domain.mappers import com.neovisionaries.i18n.CountryCode +import fr.gouv.cnsp.monitorfish.domain.entities.position.NetworkType import org.assertj.core.api.Assertions.assertThat import org.assertj.core.api.Assertions.catchThrowable import org.junit.jupiter.api.Test @@ -207,7 +208,7 @@ internal class NAFMessageMapperUTests { } @Test - internal fun `init Should parse the position type When given`() { + internal fun `init Should parse the network type When given`() { // Given val naf = "//SR//TM/POS//IR/FRA000123456//NA/MANUEL//RC/FT6951//FS/FRA//XR/TL326095//DA/20200814//TI/0911//LT/+43.0789//LG/+006.1549//SP/000//CO/0//FR/FRA//RD/20200814//RT/0912//MS/SAT//ER//" @@ -215,7 +216,6 @@ internal class NAFMessageMapperUTests { val position = NAFMessageMapper(naf).toPosition() // Then - assertThat(position.speed).isNull() - assertThat(position.course).isNull() + assertThat(position.networkType).isEqualTo(NetworkType.SATELLITE) } } From 679b37e83fa84f9eb4b7e8405da78a601e2292f3 Mon Sep 17 00:00:00 2001 From: Loup Theron Date: Thu, 15 Aug 2024 09:57:26 +0200 Subject: [PATCH 3/4] Add network type in positions list --- .../exceptions/BackendRequestErrorCode.kt | 1 - .../vessel_sidebar/control_buttons.spec.ts | 31 +++++++++++++++++++ .../track/__tests__/__mocks__/vesselTrack.ts | 25 +++++++++++++++ .../vesselTrackWithDuplicatePositions.ts | 16 ++++++++++ .../vessel/track/__tests__/index.test.ts | 2 ++ frontend/src/domain/entities/vessel/types.ts | 6 ++++ .../actions/TrackRequest/ExportTrack.tsx | 15 +++++++++ .../TrackRequest/HighlightPositionCell.tsx | 19 +++++++++++- .../actions/TrackRequest/constants.tsx | 7 +++-- 9 files changed, 117 insertions(+), 5 deletions(-) diff --git a/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/exceptions/BackendRequestErrorCode.kt b/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/exceptions/BackendRequestErrorCode.kt index 37d714f7fc..4ac3cec475 100644 --- a/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/exceptions/BackendRequestErrorCode.kt +++ b/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/exceptions/BackendRequestErrorCode.kt @@ -13,5 +13,4 @@ package fr.gouv.cnsp.monitorfish.infrastructure.exceptions */ enum class BackendRequestErrorCode { WRONG_BODY_PARAMETER_TYPE, - UNAUTHORIZED, } diff --git a/frontend/cypress/e2e/vessel_sidebar/control_buttons.spec.ts b/frontend/cypress/e2e/vessel_sidebar/control_buttons.spec.ts index 82e9e83f68..45547f6182 100644 --- a/frontend/cypress/e2e/vessel_sidebar/control_buttons.spec.ts +++ b/frontend/cypress/e2e/vessel_sidebar/control_buttons.spec.ts @@ -45,6 +45,37 @@ context('Vessel sidebar controls buttons', () => { cy.get('[data-id="0"] > td').eq(2).contains('8.7 nds') cy.get('[data-id="0"] > td').eq(1).find('[title="Position au port"]').should('exist') cy.get('[data-id="0"] > td').eq(1).find('[title="Position manuelle (4h-report)"]').should('exist') + cy.get('[data-id="0"] > td').eq(1).find('[title="Réseau CELLULAR"]').should('exist') + cy.get('[data-id="0"] > td').eq(1).contains('CEL') + }) + + it('Vessel track Should be downloaded', () => { + // Given + cy.get('*[data-cy^="vessel-search-input"]', { timeout: 10000 }).type('Pheno') + cy.get('*[data-cy^="vessel-search-item"]').eq(0).click() + cy.wait(200) + cy.get('*[data-cy^="vessel-sidebar"]').should('be.visible') + cy.get('*[data-cy^="vessel-track-depth-selection"]').click() + cy.fill('Afficher la piste VMS depuis', '3 jours') + cy.wait(500) + + // When + cy.clickButton('Exporter la piste') + + // Then + cy.wait(400) + cy.exec('cd cypress/downloads && ls').then(result => { + const downloadedCSVFilename = result.stdout + + return cy + .readFile(`cypress/downloads/${downloadedCSVFilename}`) + .should( + 'contains', + 'Nom,Marq. Ext.,C/S,MMSI,CFR,Pavillon,GDH (UTC),Latitude,Longitude,Cap,Vitesse,Au port,Type de réseau' + ) + .should('contains', '"PHENOMENE","DONTSINK","CALLME","","FAK000999999"') + .should('contains', '"45° 55′ 12″ N","008° 45′ 54″ W",13,8.7,"Oui","Cellulaire"') + }) }) it('Vessel track dates Should be changed When walking in fishing trips', () => { diff --git a/frontend/src/domain/entities/vessel/track/__tests__/__mocks__/vesselTrack.ts b/frontend/src/domain/entities/vessel/track/__tests__/__mocks__/vesselTrack.ts index 8b07d9b844..b72c807976 100644 --- a/frontend/src/domain/entities/vessel/track/__tests__/__mocks__/vesselTrack.ts +++ b/frontend/src/domain/entities/vessel/track/__tests__/__mocks__/vesselTrack.ts @@ -1,3 +1,5 @@ +import { NetworkType } from '../../../types' + export const DUMMY_VESSEL_TRACK = [ { course: 356, @@ -14,6 +16,7 @@ export const DUMMY_VESSEL_TRACK = [ latitude: 46.386, longitude: -3.328, mmsi: null, + networkType: NetworkType.SATELLITE, positionType: 'VMS', speed: 2.8, tripNumber: null, @@ -34,6 +37,7 @@ export const DUMMY_VESSEL_TRACK = [ latitude: 46.43, longitude: -3.347, mmsi: null, + networkType: NetworkType.SATELLITE, positionType: 'VMS', speed: 2.9, tripNumber: null, @@ -54,6 +58,7 @@ export const DUMMY_VESSEL_TRACK = [ latitude: 46.458, longitude: -3.411, mmsi: null, + networkType: NetworkType.SATELLITE, positionType: 'VMS', speed: 2.2, tripNumber: null, @@ -74,6 +79,7 @@ export const DUMMY_VESSEL_TRACK = [ latitude: 46.486, longitude: -3.481, mmsi: null, + networkType: NetworkType.SATELLITE, positionType: 'VMS', speed: 3.1, tripNumber: null, @@ -94,6 +100,7 @@ export const DUMMY_VESSEL_TRACK = [ latitude: 46.471, longitude: -3.552, mmsi: null, + networkType: NetworkType.SATELLITE, positionType: 'VMS', speed: 2.8, tripNumber: null, @@ -114,6 +121,7 @@ export const DUMMY_VESSEL_TRACK = [ latitude: 46.45, longitude: -3.614, mmsi: null, + networkType: NetworkType.SATELLITE, positionType: 'VMS', speed: 2.9, tripNumber: null, @@ -137,6 +145,7 @@ export const VESSEL_TRACK_ALL_SAME_COORDINATES = [ latitude: 43.2942, longitude: 3.4492, mmsi: null, + networkType: NetworkType.SATELLITE, positionType: 'VMS', speed: 0.0, tripNumber: null, @@ -157,6 +166,7 @@ export const VESSEL_TRACK_ALL_SAME_COORDINATES = [ latitude: 43.2942, longitude: 3.4492, mmsi: null, + networkType: NetworkType.SATELLITE, positionType: 'VMS', speed: 0.0, tripNumber: null, @@ -177,6 +187,7 @@ export const VESSEL_TRACK_ALL_SAME_COORDINATES = [ latitude: 43.2942, longitude: 3.4492, mmsi: null, + networkType: NetworkType.SATELLITE, positionType: 'VMS', speed: 0.0, tripNumber: null, @@ -197,6 +208,7 @@ export const VESSEL_TRACK_ALL_SAME_COORDINATES = [ latitude: 43.2942, longitude: 3.4492, mmsi: null, + networkType: NetworkType.SATELLITE, positionType: 'VMS', speed: 0.0, tripNumber: null, @@ -217,6 +229,7 @@ export const VESSEL_TRACK_ALL_SAME_COORDINATES = [ latitude: 43.2942, longitude: 3.4492, mmsi: null, + networkType: NetworkType.SATELLITE, positionType: 'VMS', speed: 0.0, tripNumber: null, @@ -237,6 +250,7 @@ export const VESSEL_TRACK_ALL_SAME_COORDINATES = [ latitude: 43.2942, longitude: 3.4492, mmsi: null, + networkType: NetworkType.SATELLITE, positionType: 'VMS', speed: 0.0, tripNumber: null, @@ -257,6 +271,7 @@ export const VESSEL_TRACK_ALL_SAME_COORDINATES = [ latitude: 43.2942, longitude: 3.4492, mmsi: null, + networkType: NetworkType.SATELLITE, positionType: 'VMS', speed: 0.0, tripNumber: null, @@ -277,6 +292,7 @@ export const VESSEL_TRACK_ALL_SAME_COORDINATES = [ latitude: 43.2942, longitude: 3.4492, mmsi: null, + networkType: NetworkType.SATELLITE, positionType: 'VMS', speed: 0.0, tripNumber: null, @@ -297,6 +313,7 @@ export const VESSEL_TRACK_ALL_SAME_COORDINATES = [ latitude: 43.2942, longitude: 3.4492, mmsi: null, + networkType: NetworkType.SATELLITE, positionType: 'VMS', speed: 0.0, tripNumber: null, @@ -317,6 +334,7 @@ export const VESSEL_TRACK_ALL_SAME_COORDINATES = [ latitude: 43.2942, longitude: 3.4492, mmsi: null, + networkType: NetworkType.SATELLITE, positionType: 'VMS', speed: 0.0, tripNumber: null, @@ -337,6 +355,7 @@ export const VESSEL_TRACK_ALL_SAME_COORDINATES = [ latitude: 43.2942, longitude: 3.4492, mmsi: null, + networkType: NetworkType.SATELLITE, positionType: 'VMS', speed: 0.0, tripNumber: null, @@ -357,6 +376,7 @@ export const VESSEL_TRACK_ALL_SAME_COORDINATES = [ latitude: 43.2942, longitude: 3.4492, mmsi: null, + networkType: NetworkType.SATELLITE, positionType: 'VMS', speed: 0.0, tripNumber: null, @@ -380,6 +400,7 @@ export const VESSEL_TRACK_FEW_SAME_COORDINATES = [ latitude: 43.2948, longitude: 3.4498, mmsi: null, + networkType: NetworkType.SATELLITE, positionType: 'VMS', speed: 0.0, tripNumber: null, @@ -400,6 +421,7 @@ export const VESSEL_TRACK_FEW_SAME_COORDINATES = [ latitude: 43.2942, longitude: 3.4492, mmsi: null, + networkType: NetworkType.SATELLITE, positionType: 'VMS', speed: 0.0, tripNumber: null, @@ -420,6 +442,7 @@ export const VESSEL_TRACK_FEW_SAME_COORDINATES = [ latitude: 43.2942, longitude: 3.4492, mmsi: null, + networkType: NetworkType.SATELLITE, positionType: 'VMS', speed: 0.0, tripNumber: null, @@ -440,6 +463,7 @@ export const VESSEL_TRACK_FEW_SAME_COORDINATES = [ latitude: 43.2942, longitude: 3.4492, mmsi: null, + networkType: NetworkType.SATELLITE, positionType: 'VMS', speed: 0.0, tripNumber: null, @@ -460,6 +484,7 @@ export const VESSEL_TRACK_FEW_SAME_COORDINATES = [ latitude: 43.2953, longitude: 3.4485, mmsi: null, + networkType: NetworkType.SATELLITE, positionType: 'VMS', speed: 0.0, tripNumber: null, diff --git a/frontend/src/domain/entities/vessel/track/__tests__/__mocks__/vesselTrackWithDuplicatePositions.ts b/frontend/src/domain/entities/vessel/track/__tests__/__mocks__/vesselTrackWithDuplicatePositions.ts index 0f623f3af2..56b254b653 100644 --- a/frontend/src/domain/entities/vessel/track/__tests__/__mocks__/vesselTrackWithDuplicatePositions.ts +++ b/frontend/src/domain/entities/vessel/track/__tests__/__mocks__/vesselTrackWithDuplicatePositions.ts @@ -1,3 +1,5 @@ +import { NetworkType } from '../../../types' + export const DUMMY_VESSEL_TRACK_WITH_DUPLICATE_POSITIONS = [ { course: 0.0, @@ -14,6 +16,7 @@ export const DUMMY_VESSEL_TRACK_WITH_DUPLICATE_POSITIONS = [ latitude: 47.7936, longitude: -4.2805, mmsi: null, + networkType: NetworkType.SATELLITE, positionType: 'VMS', speed: 0.0, tripNumber: null, @@ -34,6 +37,7 @@ export const DUMMY_VESSEL_TRACK_WITH_DUPLICATE_POSITIONS = [ latitude: 47.7936, longitude: -4.2804, mmsi: null, + networkType: NetworkType.SATELLITE, positionType: 'VMS', speed: 0.0, tripNumber: null, @@ -54,6 +58,7 @@ export const DUMMY_VESSEL_TRACK_WITH_DUPLICATE_POSITIONS = [ latitude: 47.7941, longitude: -4.2807, mmsi: null, + networkType: NetworkType.SATELLITE, positionType: 'VMS', speed: 0.5, tripNumber: null, @@ -74,6 +79,7 @@ export const DUMMY_VESSEL_TRACK_WITH_DUPLICATE_POSITIONS = [ latitude: 47.7936, longitude: -4.2805, mmsi: null, + networkType: NetworkType.SATELLITE, positionType: 'VMS', speed: 0.0, tripNumber: null, @@ -94,6 +100,7 @@ export const DUMMY_VESSEL_TRACK_WITH_DUPLICATE_POSITIONS = [ latitude: 47.7936, longitude: -4.2805, mmsi: null, + networkType: NetworkType.SATELLITE, positionType: 'VMS', speed: 0.5, tripNumber: null, @@ -114,6 +121,7 @@ export const DUMMY_VESSEL_TRACK_WITH_DUPLICATE_POSITIONS = [ latitude: 47.7936, longitude: -4.2805, mmsi: null, + networkType: NetworkType.SATELLITE, positionType: 'VMS', speed: 0.0, tripNumber: null, @@ -134,6 +142,7 @@ export const DUMMY_VESSEL_TRACK_WITH_DUPLICATE_POSITIONS = [ latitude: 47.7936, longitude: -4.2804, mmsi: null, + networkType: NetworkType.SATELLITE, positionType: 'VMS', speed: 0.0, tripNumber: null, @@ -154,6 +163,7 @@ export const DUMMY_VESSEL_TRACK_WITH_DUPLICATE_POSITIONS = [ latitude: 47.7936, longitude: -4.2805, mmsi: null, + networkType: NetworkType.SATELLITE, positionType: 'VMS', speed: 0.0, tripNumber: null, @@ -174,6 +184,7 @@ export const DUMMY_VESSEL_TRACK_WITH_DUPLICATE_POSITIONS = [ latitude: 47.7936, longitude: -4.2805, mmsi: null, + networkType: NetworkType.SATELLITE, positionType: 'VMS', speed: 0.5, tripNumber: null, @@ -194,6 +205,7 @@ export const DUMMY_VESSEL_TRACK_WITH_DUPLICATE_POSITIONS = [ latitude: 47.7936, longitude: -4.2805, mmsi: null, + networkType: NetworkType.SATELLITE, positionType: 'VMS', speed: 0.0, tripNumber: null, @@ -214,6 +226,7 @@ export const DUMMY_VESSEL_TRACK_WITH_DUPLICATE_POSITIONS = [ latitude: 47.7481, longitude: -4.2828, mmsi: null, + networkType: NetworkType.SATELLITE, positionType: 'VMS', speed: 7.5, tripNumber: null, @@ -234,6 +247,7 @@ export const DUMMY_VESSEL_TRACK_WITH_DUPLICATE_POSITIONS = [ latitude: 47.7048, longitude: -4.286, mmsi: null, + networkType: NetworkType.SATELLITE, positionType: 'VMS', speed: 6.0, tripNumber: null, @@ -254,6 +268,7 @@ export const DUMMY_VESSEL_TRACK_WITH_DUPLICATE_POSITIONS = [ latitude: 47.6723, longitude: -4.2161, mmsi: null, + networkType: NetworkType.SATELLITE, positionType: 'VMS', speed: 3.0, tripNumber: null, @@ -274,6 +289,7 @@ export const DUMMY_VESSEL_TRACK_WITH_DUPLICATE_POSITIONS = [ latitude: 47.6432, longitude: -4.1644, mmsi: null, + networkType: NetworkType.SATELLITE, positionType: 'VMS', speed: 2.5, tripNumber: null, diff --git a/frontend/src/domain/entities/vessel/track/__tests__/index.test.ts b/frontend/src/domain/entities/vessel/track/__tests__/index.test.ts index 142885e2f0..a5649108d8 100644 --- a/frontend/src/domain/entities/vessel/track/__tests__/index.test.ts +++ b/frontend/src/domain/entities/vessel/track/__tests__/index.test.ts @@ -7,6 +7,7 @@ import { VESSEL_TRACK_FEW_SAME_COORDINATES } from './__mocks__/vesselTrack' import { DUMMY_VESSEL_TRACK_WITH_DUPLICATE_POSITIONS } from './__mocks__/vesselTrackWithDuplicatePositions' +import { NetworkType } from '../../types' import { getFeaturesFromPositions, getTrackType } from '../index' import type { VesselLineFeature, VesselPointFeature, VesselPosition } from '../../types' @@ -50,6 +51,7 @@ describe('vessel/track', () => { latitude: 46.386, longitude: -3.328, mmsi: null, + networkType: NetworkType.SATELLITE, positionType: 'VMS', speed: 2.8, tripNumber: null, diff --git a/frontend/src/domain/entities/vessel/types.ts b/frontend/src/domain/entities/vessel/types.ts index 077450e0dd..2bc89e0699 100644 --- a/frontend/src/domain/entities/vessel/types.ts +++ b/frontend/src/domain/entities/vessel/types.ts @@ -47,6 +47,11 @@ export enum VesselIdentifier { IRCS = 'IRCS' } +export enum NetworkType { + CELLULAR = 'CELLULAR', + SATELLITE = 'SATELLITE' +} + export type VesselIdentity = { beaconNumber?: number | null districtCode?: string | null @@ -135,6 +140,7 @@ export type VesselPosition = { latitude: number longitude: number mmsi: string | null + networkType: NetworkType | null positionType: string speed: number tripNumber: number | null diff --git a/frontend/src/features/VesselSidebar/actions/TrackRequest/ExportTrack.tsx b/frontend/src/features/VesselSidebar/actions/TrackRequest/ExportTrack.tsx index c16df61dad..eaacf8bf62 100644 --- a/frontend/src/features/VesselSidebar/actions/TrackRequest/ExportTrack.tsx +++ b/frontend/src/features/VesselSidebar/actions/TrackRequest/ExportTrack.tsx @@ -5,6 +5,7 @@ import styled from 'styled-components' import { getCoordinates } from '../../../../coordinates' import { WSG84_PROJECTION } from '../../../../domain/entities/map/constants' +import { NetworkType } from '../../../../domain/entities/vessel/types' import { useMainAppSelector } from '../../../../hooks/useMainAppSelector' import { getDate } from '../../../../utils' import { downloadAsCsv } from '../../../../utils/downloadAsCsv' @@ -79,6 +80,20 @@ export function ExportTrack() { isAtPort: { label: 'Au port', transform: position => (position.isAtPort ? 'Oui' : 'Non') + }, + networkType: { + label: 'Type de réseau', + transform: position => { + if (position.networkType === NetworkType.CELLULAR) { + return 'Cellulaire' + } + + if (position.networkType === NetworkType.SATELLITE) { + return 'Satellite' + } + + return 'Inconnu' + } } } /* eslint-enable sort-keys-fix/sort-keys-fix */ diff --git a/frontend/src/features/VesselSidebar/actions/TrackRequest/HighlightPositionCell.tsx b/frontend/src/features/VesselSidebar/actions/TrackRequest/HighlightPositionCell.tsx index 3e469c78bf..3989260ba2 100644 --- a/frontend/src/features/VesselSidebar/actions/TrackRequest/HighlightPositionCell.tsx +++ b/frontend/src/features/VesselSidebar/actions/TrackRequest/HighlightPositionCell.tsx @@ -1,6 +1,6 @@ import { useMainAppDispatch } from '@hooks/useMainAppDispatch' import { useMainAppSelector } from '@hooks/useMainAppSelector' -import { Icon } from '@mtes-mct/monitor-ui' +import { Accent, Icon, Tag } from '@mtes-mct/monitor-ui' import { transform } from 'ol/proj' import styled from 'styled-components' @@ -15,12 +15,14 @@ import type { VesselPosition } from '../../../../domain/entities/vessel/types' type HighlightPositionCellProps = { isAtPortPositionMarkerShowed?: boolean isManualPositionMarkerShowed?: boolean + isNetworkTypeMarkerShowed?: boolean row: VesselPosition value: unknown } export function HighlightPositionCell({ isAtPortPositionMarkerShowed, isManualPositionMarkerShowed, + isNetworkTypeMarkerShowed, row, value }: HighlightPositionCellProps) { @@ -43,10 +45,25 @@ export function HighlightPositionCell({ {(value ?? '') as string} {isManualPositionMarkerShowed && row.isManual ? : ''} {isAtPortPositionMarkerShowed && row.isAtPort ? : ''} + {isNetworkTypeMarkerShowed && row.networkType ? ( + + {row.networkType.slice(0, 3)} + + ) : ( + '' + )} ) } +const StyledTag = styled(Tag)` + font-size: 10px; + height: 17px; + padding: 0px 4px; + margin-left: 3px; + vertical-align: text-top; +` + const StyledAnchor = styled(Icon.Anchor)` margin-left: 3px; ` diff --git a/frontend/src/features/VesselSidebar/actions/TrackRequest/constants.tsx b/frontend/src/features/VesselSidebar/actions/TrackRequest/constants.tsx index 59d7fb7a02..323a09bc5b 100644 --- a/frontend/src/features/VesselSidebar/actions/TrackRequest/constants.tsx +++ b/frontend/src/features/VesselSidebar/actions/TrackRequest/constants.tsx @@ -22,6 +22,7 @@ export const POSITION_TABLE_COLUMNS: Array @@ -29,7 +30,7 @@ export const POSITION_TABLE_COLUMNS: Array (isNumeric(row.speed) ? `${row.speed} nds` : '-'), @@ -37,7 +38,7 @@ export const POSITION_TABLE_COLUMNS: Array (isNumeric(row.course) ? `${row.course} °` : '-'), @@ -45,7 +46,7 @@ export const POSITION_TABLE_COLUMNS: Array Date: Mon, 19 Aug 2024 10:59:45 +0200 Subject: [PATCH 4/4] Rename V0.273__Update_positions_table.sql to V0.276__Update_positions_table.sql --- ...ate_positions_table.sql => V0.276__Update_positions_table.sql} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename backend/src/main/resources/db/migration/internal/{V0.273__Update_positions_table.sql => V0.276__Update_positions_table.sql} (100%) diff --git a/backend/src/main/resources/db/migration/internal/V0.273__Update_positions_table.sql b/backend/src/main/resources/db/migration/internal/V0.276__Update_positions_table.sql similarity index 100% rename from backend/src/main/resources/db/migration/internal/V0.273__Update_positions_table.sql rename to backend/src/main/resources/db/migration/internal/V0.276__Update_positions_table.sql