Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/241 refactor architecture react pour module partager components features #404

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions frontend/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
"email-validator": "^2.0.4",
"formik": "^2.4.6",
"graphql": "^16.9.0",
"jwt-decode": "^4.0.0",
"lodash": "^4.17.21",
"react": "^18.3.1",
"react-dom": "^18.3.1",
Expand Down
20 changes: 20 additions & 0 deletions frontend/src/features/auth/components/auth-guard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { Suspense } from 'react'
import { Navigate } from 'react-router-dom'
import useAuth from '../hooks/use-auth'

type AuthGuardProps = {
children: JSX.Element
}

export default function AuthGuard(props: AuthGuardProps): JSX.Element | null {
const { isAuthenticated } = useAuth()

const denied = () => {
return <Navigate to={`/login`} replace />
}

const allow = () => {
return <Suspense>{props.children}</Suspense>
}
return !isAuthenticated ? denied() : allow()
}
10 changes: 7 additions & 3 deletions frontend/src/features/auth/hooks/use-auth.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
import { useApolloClient } from '@apollo/client'
import { useEffect, useState } from 'react'
import AuthToken from '../utils/token.ts'
import { useNavigate } from 'react-router-dom'
import { useApolloClient } from '@apollo/client'
import AuthToken from '../utils/token.ts'

type AuthHook = {
isAuthenticated: boolean
logout: () => Promise<void>
}
const authToken = new AuthToken()

const useAuth = (): { isAuthenticated: boolean; logout: () => Promise<void> } => {
const useAuth = (): AuthHook => {
const [isAuthenticated, setIsAuthenticated] = useState<boolean>(!!authToken.get())
const navigate = useNavigate()
const apolloClient = useApolloClient()
Expand Down
8 changes: 4 additions & 4 deletions frontend/src/features/common/types/env-mission-types.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { ControlUnit } from './control-unit-types.ts'
import {
ControlAdministrative,
ControlGensDeMer,
ControlNavigation,
ControlSecurity,
ControlType
} from './control-types.ts'
import { ControlUnit } from './control-unit-types.ts'
import { InfractionByTarget } from './infraction-types.ts'

export enum ActionTypeEnum {
Expand Down Expand Up @@ -380,8 +380,8 @@ export type Mission<EnvAction = EnvActionControl | EnvActionSurveillance | EnvAc
export type EnvAction = EnvActionControl | EnvActionSurveillance | EnvActionNote

export type EnvActionCommonProperties = {
actionEndDateTimeUtc?: string | null
actionStartDateTimeUtc?: string | null
actionEndDateTimeUtc?: string
actionStartDateTimeUtc?: string
geom?: string
id: string
actionStatus: string
Expand All @@ -399,7 +399,7 @@ export type NewEnvActionControl = EnvActionCommonProperties & {
actionType: ActionTypeEnum.CONTROL
infractions: InfractionByTarget[]
observations: string | null
vehicleType?: string
vehicleType?: VehicleTypeEnum
formattedControlPlans: FormattedControlPlan[]
}
export type EnvActionControl = NewEnvActionControl & {
Expand Down
24 changes: 24 additions & 0 deletions frontend/src/features/common/utils/action-utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { Action } from '@common/types/action-types'
import { MissionSourceEnum } from '@common/types/env-mission-types'

export function isEnvAction(action: Action): boolean {
return action !== null && action.source === MissionSourceEnum.MONITORENV
}

export function isFishAction(action: Action): boolean {
return action !== null && action.source === MissionSourceEnum.MONITORFISH
}

export function isNavAction(action: Action): boolean {
return action !== null && action.source === MissionSourceEnum.RAPPORTNAV
}

export const vesselNameOrUnknown = (name?: string): string | undefined => {
if (!name) {
return
} else if (name === 'UNKNOWN') {
return 'Navire inconnu'
} else {
return name
}
}
5 changes: 5 additions & 0 deletions frontend/src/features/common/utils/control-utils.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
describe('control utils', () => {
it('dummy', () => {
expect(false).toBe(false)
})
})
141 changes: 141 additions & 0 deletions frontend/src/features/common/utils/control-utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
import { ControlMethod, ControlType } from '@common/types/control-types'
import { VesselSizeEnum, VesselTypeEnum } from '@common/types/mission-types'

export const controlMethodToHumanString = (controlMethod?: ControlMethod | null): string => {
switch (controlMethod) {
case ControlMethod.AIR:
return 'aérien'
case ControlMethod.LAND:
return 'à Terre'
case ControlMethod.SEA:
return 'en Mer'
default:
return ''
}
}

export const vesselTypeToHumanString = (vesselType?: VesselTypeEnum | null): string => {
switch (vesselType) {
case VesselTypeEnum.FISHING:
return 'Navire de pêche professionnelle'
case VesselTypeEnum.COMMERCIAL:
return 'Navire de commerce'
case VesselTypeEnum.MOTOR:
return 'Navire de service'
case VesselTypeEnum.SAILING:
return 'Navire de plaisance professionnelle'
case VesselTypeEnum.SAILING_LEISURE:
return 'Navire de plaisance de loisir'
default:
return ''
}
}

export const VESSEL_TYPE_OPTIONS = [
{
label: vesselTypeToHumanString(VesselTypeEnum.FISHING),
value: VesselTypeEnum.FISHING
},
{
label: vesselTypeToHumanString(VesselTypeEnum.SAILING),
value: VesselTypeEnum.SAILING
},
{
label: vesselTypeToHumanString(VesselTypeEnum.MOTOR),
value: VesselTypeEnum.MOTOR
},
{
label: vesselTypeToHumanString(VesselTypeEnum.COMMERCIAL),
value: VesselTypeEnum.COMMERCIAL
},
{
label: vesselTypeToHumanString(VesselTypeEnum.SAILING_LEISURE),
value: VesselTypeEnum.SAILING_LEISURE
}
]

export const vesselSizeToHumanString = (vesselSize?: VesselSizeEnum | null): string => {
switch (vesselSize) {
case VesselSizeEnum.LESS_THAN_12m:
return 'Moins de 12m'
case VesselSizeEnum.FROM_12_TO_24m:
return 'Entre 12m et 24m'
case VesselSizeEnum.FROM_24_TO_46m:
return 'Entre 24m et 46m'
case VesselSizeEnum.MORE_THAN_46m:
return 'Plus de 46m'
default:
return ''
}
}

export const VESSEL_SIZE_OPTIONS = [
{
label: 'Moins de 12m',
value: VesselSizeEnum.LESS_THAN_12m
},
{
label: 'Entre 12m et 24m',
value: VesselSizeEnum.FROM_12_TO_24m
},
{
label: 'Entre 24m et 46m',
value: VesselSizeEnum.FROM_24_TO_46m
},
{
label: 'Plus de 46m',
value: VesselSizeEnum.MORE_THAN_46m
}
]

export const RESCUE_TYPE_OPTIONS = [
{
label: 'Assistance de navire en difficulté',
value: true
},
{
label: 'Sauvegarde de la vie humaine',
value: false
}
]

export const controlTitle = (controlType: ControlType) => {
switch (controlType) {
case ControlType.ADMINISTRATIVE:
return 'Contrôle administratif navire'
case ControlType.GENS_DE_MER:
return 'Contrôle administratif gens de mer'
case ControlType.SECURITY:
return 'Equipements et respect des normes de sécurité'
case ControlType.NAVIGATION:
return 'Respect des règles de navigation'
}
}

export function getDisabledControlTypes(enabledControlTypes?: ControlType[]): ControlType[] {
const allControlTypes = Object.values(ControlType)
if (!enabledControlTypes) {
return allControlTypes
}
const disabledControlTypes = allControlTypes.filter(controlType => !enabledControlTypes.includes(controlType))
return disabledControlTypes
}

export const CONTROL_TYPE_OPTIONS = [
{
label: `Infraction - ${controlTitle(ControlType.ADMINISTRATIVE)}`,
value: ControlType.ADMINISTRATIVE
},
{
label: `Infraction - ${controlTitle(ControlType.SECURITY)}`,
value: ControlType.SECURITY
},
{
label: `Infraction - ${controlTitle(ControlType.NAVIGATION)}`,
value: ControlType.NAVIGATION
},
{
label: `Infraction - ${controlTitle(ControlType.GENS_DE_MER)}`,
value: ControlType.GENS_DE_MER
}
]
30 changes: 30 additions & 0 deletions frontend/src/features/common/utils/infraction-utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { ControlType } from '../../../common/types/control-types.ts'

export const infractionTitleForControlType = (controlType: ControlType): string => {
switch (controlType) {
case ControlType.ADMINISTRATIVE:
return 'Infraction administrative'
case ControlType.NAVIGATION:
return 'Infraction règles de navigation'
case ControlType.SECURITY:
return 'Infraction équipements et respect des normes de sécurité'
case ControlType.GENS_DE_MER:
return 'Infraction administrative gens de mer'
default:
return ''
}
}
export const infractionButtonTitle = (controlType: ControlType): string => {
switch (controlType) {
case ControlType.ADMINISTRATIVE:
return 'Ajouter une infraction administrative'
case ControlType.NAVIGATION:
return 'Ajouter une infraction règle de navigation'
case ControlType.SECURITY:
return 'Ajouter une infraction sécurité'
case ControlType.GENS_DE_MER:
return 'Ajouter une infraction administrative'
default:
return ''
}
}
57 changes: 57 additions & 0 deletions frontend/src/features/common/utils/status-utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import { ActionStatusReason, ActionStatusType } from '@common/types/action-types'
import { THEME } from '@mtes-mct/monitor-ui'

export const getColorForStatus = (status: ActionStatusType) => {
switch (status) {
case ActionStatusType.NAVIGATING:
return THEME.color.blueGray
case ActionStatusType.ANCHORED:
return THEME.color.blueYonder
case ActionStatusType.DOCKED:
return THEME.color.goldenPoppy
case ActionStatusType.UNAVAILABLE:
return THEME.color.maximumRed
case ActionStatusType.UNKNOWN:
default:
return 'transparent'
}
}

export const mapStatusToText = (status: ActionStatusType) => {
switch (status) {
case ActionStatusType.NAVIGATING:
return 'Navigation'
case ActionStatusType.ANCHORED:
return 'Mouillage'
case ActionStatusType.DOCKED:
return 'Présence à quai'
case ActionStatusType.UNAVAILABLE:
return 'Indisponibilité'
case ActionStatusType.UNKNOWN:
default:
return 'Inconnu'
}
}

export const statusReasonToHumanString = (reason?: ActionStatusReason): string | undefined => {
switch (reason) {
case ActionStatusReason.MAINTENANCE:
return 'Maintenance'
case ActionStatusReason.WEATHER:
return 'Météo'
case ActionStatusReason.REPRESENTATION:
return 'Représentation'
case ActionStatusReason.ADMINISTRATION:
return 'Administration'
case ActionStatusReason.HARBOUR_CONTROL:
return 'Contrôle portuaire'
case ActionStatusReason.TECHNICAL:
return 'Technique'
case ActionStatusReason.PERSONNEL:
return 'Personnel'
case ActionStatusReason.OTHER:
return 'Autre'
default:
return undefined
}
}
2 changes: 1 addition & 1 deletion frontend/src/pages/home.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ const Home: FC = () => {

useEffect(() => {
if (isAuthenticated) {
navigate('/pam/missions', { replace: true })
navigate(`/pam/missions`, { replace: true })
} else {
navigate('/login', { replace: true })
}
Expand Down
Loading
Loading