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

Préavis – Corrige le suivi des temps d'affichage des loading spinner et boutons de téléchargement #3641

Merged
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ export function MissionDetails({ isSelected, mission, overlayPosition }: Mission
/>
)}
<Body>
<Title isSelected={isSelected}>
<Title $isSelected={isSelected}>
{mission.controlUnits.length === 1 &&
mission.controlUnits.map((controlUnit: LegacyControlUnit.LegacyControlUnit) => (
<Fragment key={controlUnit.id}>
Expand Down Expand Up @@ -176,12 +176,12 @@ const Details = styled.div`
`

const Title = styled.div<{
isSelected: boolean
$isSelected: boolean
}>`
height: 40px;
font: normal normal bold 13px/18px Marianne;
color: ${p => p.theme.color.gunMetal};
width: ${p => (p.isSelected ? 90 : 100)}%;
width: ${p => (p.$isSelected ? 90 : 100)}%;
`

const Wrapper = styled.div`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@ export function LogbookPriorNotificationForm() {

customSentry.endMeasurement(
CustomSentryMeasurementName.LOGBOOK_PRIOR_NOTIFICATION_FORM_SPINNER,
openedPriorNotificationDetail.reportId
openedPriorNotificationDetail.reportId,
2000
)

return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,8 @@ export function ManualPriorNotificationForm() {
if (openedPriorNotificationDetail?.reportId) {
customSentry.endMeasurement(
CustomSentryMeasurementName.MANUAL_PRIOR_NOTIFICATION_FORM_SPINNER,
openedPriorNotificationDetail.reportId
openedPriorNotificationDetail.reportId,
2000
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ export function PriorNotificationCard({
/>

{isPendingVerification && <Intro>Le préavis doit être vérifié par le CNSP avant sa diffusion.</Intro>}
<Intro hasNoTopMargin={isPendingVerification}>
<Intro $hasNoTopMargin={isPendingVerification}>
Le navire doit respecter un délai d’envoi{hasDesignatedPorts && ' et débarquer dans un port désigné'}.
</Intro>

Expand Down Expand Up @@ -155,9 +155,9 @@ const Body = styled.div`
`

const Intro = styled.p<{
hasNoTopMargin?: boolean
$hasNoTopMargin?: boolean
}>`
${p => p.hasNoTopMargin && 'margin-top: 2px;'}
${p => p.$hasNoTopMargin && 'margin-top: 2px;'}
color: ${p => p.theme.color.slateGray};
font-style: italic;
`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { useListSorting } from '@hooks/useListSorting'
import { useLoadingState } from '@hooks/useLoadingState'
import { useMainAppDispatch } from '@hooks/useMainAppDispatch'
import { useMainAppSelector } from '@hooks/useMainAppSelector'
import { customSentry, CustomSentryMeasurementName } from '@libs/customSentry'
import { DisplayedErrorKey } from '@libs/DisplayedError/constants'
import { Accent, Button, Icon, Size, TableWithSelectableRows, usePrevious } from '@mtes-mct/monitor-ui'
import { skipToken } from '@reduxjs/toolkit/query'
Expand Down Expand Up @@ -144,6 +145,12 @@ export function PriorNotificationList({ isFromUrl }: PriorNotificationListProps)
}
}, [previousListFilter, listFilter, table])

if (isBodyLoaderVisible) {
customSentry.startMeasurement(CustomSentryMeasurementName.PRIOR_NOTIFICATION_LIST_BODY_SPINNER, '0')
} else {
customSentry.endMeasurement(CustomSentryMeasurementName.PRIOR_NOTIFICATION_LIST_BODY_SPINNER, '0', 2000)
}

return (
<>
<SubMenu
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ import {
useGetPriorNotificationPdfExistenceQuery
} from '@features/PriorNotification/priorNotificationApi'
import { customSentry, CustomSentryMeasurementName } from '@libs/customSentry'
import { Accent, Button, customDayjs, Dropdown, Icon, usePrevious } from '@mtes-mct/monitor-ui'
import { Accent, Button, customDayjs, Dropdown, Icon } from '@mtes-mct/monitor-ui'
import { downloadFile } from '@utils/downloadFile'
import printJS from 'print-js'
import { useEffect, useMemo } from 'react'
import { useMemo } from 'react'

import { HTML_STYLE } from './template'
import { getHasAuthorizedLandingDownload, getHtmlContent } from './utils'
Expand All @@ -34,8 +34,6 @@ export function DownloadButton({
const getGearsApiQuery = useGetGearsQuery()
const { data } = useGetPriorNotificationPdfExistenceQuery(reportId, RTK_ONE_MINUTE_POLLING_QUERY_OPTIONS)

const wasDisabled = usePrevious(isDisabled)

const isPriorNotificationDocumentAvailable = useMemo(() => data?.status === StatusBodyEnum.FOUND, [data])

const hasAuthorizedLandingDownload =
Expand Down Expand Up @@ -79,17 +77,11 @@ export function DownloadButton({
downloadFile(fileName, 'application/pdf', blob)
}

useEffect(() => {
if (isDisabled === wasDisabled) {
return
}

if (isDisabled) {
customSentry.startMeasurement(CustomSentryMeasurementName.PRIOR_NOTIFICATION_CARD_DOWNLOAD_BUTTON, reportId)
} else {
customSentry.endMeasurement(CustomSentryMeasurementName.PRIOR_NOTIFICATION_CARD_DOWNLOAD_BUTTON, reportId)
}
}, [isDisabled, reportId, wasDisabled])
if (isDisabled) {
customSentry.startMeasurement(CustomSentryMeasurementName.PRIOR_NOTIFICATION_CARD_DOWNLOAD_BUTTON, reportId)
} else {
customSentry.endMeasurement(CustomSentryMeasurementName.PRIOR_NOTIFICATION_CARD_DOWNLOAD_BUTTON, reportId, 1000)
}

return (
<>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export const openManualPriorNotificationForm =
try {
if (identifier) {
customSentry.startMeasurement(
CustomSentryMeasurementName.LOGBOOK_PRIOR_NOTIFICATION_FORM_SPINNER,
CustomSentryMeasurementName.MANUAL_PRIOR_NOTIFICATION_FORM_SPINNER,
identifier.reportId
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,14 +39,14 @@ export function AlertListAndReportingList({
return (
<Wrapper>
<Title
isSelected={selectedTab === AlertAndReportingTab.ALERT}
$isSelected={selectedTab === AlertAndReportingTab.ALERT}
onClick={() => setSelectedTab(AlertAndReportingTab.ALERT)}
>
Alertes
</Title>
<Title
$isSelected={selectedTab === AlertAndReportingTab.REPORTING}
data-cy="side-window-reporting-tab"
isSelected={selectedTab === AlertAndReportingTab.REPORTING}
onClick={() => setSelectedTab(AlertAndReportingTab.REPORTING)}
>
Signalements
Expand Down Expand Up @@ -75,9 +75,9 @@ const Wrapper = styled.div`

// TODO This should be a `<a />` or a `<button />`.
const Title = styled.h2<{
isSelected: boolean
$isSelected: boolean
}>`
border-bottom: 5px solid ${p => (p.isSelected ? p.theme.color.charcoal : p.theme.color.white)};
border-bottom: 5px solid ${p => (p.$isSelected ? p.theme.color.charcoal : p.theme.color.white)};
color: ${p => p.theme.color.gunMetal};
cursor: pointer;
display: inline-block;
Expand Down
58 changes: 46 additions & 12 deletions frontend/src/libs/customSentry.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,19 @@
/* eslint-disable no-empty */

import { metrics, setMeasurement } from '@sentry/react'
import { ONE_MINUTE } from '@constants/index'
import { captureMessage, Scope, startInactiveSpan, type Span } from '@sentry/react'

type CustomSentryMeasurementValue = {
id: string
value: number
span: Span
/** Epoch in ms */
startDate: number
}

export enum CustomSentryMeasurementName {
LOGBOOK_PRIOR_NOTIFICATION_FORM_SPINNER = 'LOGBOOK_PRIOR_NOTIFICATION_FORM_SPINNER',
MANUAL_PRIOR_NOTIFICATION_FORM_SPINNER = 'MANUAL_PRIOR_NOTIFICATION_FORM_SPINNER',
PRIOR_NOTIFICATION_CARD_DOWNLOAD_BUTTON = 'PRIOR_NOTIFICATION_CARD_DOWNLOAD_BUTTON'
PRIOR_NOTIFICATION_CARD_DOWNLOAD_BUTTON = 'PRIOR_NOTIFICATION_CARD_DOWNLOAD_BUTTON',
PRIOR_NOTIFICATION_LIST_BODY_SPINNER = 'PRIOR_NOTIFICATION_LIST_BODY_SPINNER'
}

class CustomSentry {
Expand All @@ -29,29 +32,60 @@ class CustomSentry {

startMeasurement(name: CustomSentryMeasurementName, id: string) {
try {
const startDate = Date.now()
const key = `${name}-${id}`
const value = Date.now()
if (this.mesurements.has(key)) {
return
}

this.mesurements.set(key, { id, value })
const newScope = new Scope()
newScope.setTags({
side: 'frontend',
type: 'performance'
})
const newSpan = startInactiveSpan({ name: key, scope: newScope })
if (!newSpan) {
return
}

this.mesurements.set(key, { span: newSpan, startDate })

// Delete the key after 1m in case `endMeasurement()` is never called
setTimeout(() => {
this.clearMeasurement(name, id)
}, ONE_MINUTE)
} catch (_) {}
}

endMeasurement(name: CustomSentryMeasurementName, id: string) {
endMeasurement(name: CustomSentryMeasurementName, id: string, maxExpectedDurationInMs?: number) {
try {
const key = `${name}-${id}`
const measurement = this.mesurements.get(key)
if (!measurement) {
return
}

setMeasurement(name, Date.now() - measurement.value, 'millisecond')
metrics.distribution(name, measurement.value, {
tags: { type: 'important' },
unit: 'millisecond'
})
measurement.span.end()

const durationInMs = Date.now() - measurement.startDate
if (maxExpectedDurationInMs !== undefined && durationInMs > maxExpectedDurationInMs) {
const messageScope = new Scope()
messageScope.setTags({
side: 'frontend',
type: 'performance'
})

const message = `${name} took more than ${maxExpectedDurationInMs / 1000}s.`
captureMessage(message, {
level: 'warning',
tags: {
side: 'frontend',
type: 'performance'
}
})

console.warn('[MonitorFish]', message)
}

this.mesurements.delete(key)
} catch (_) {}
Expand Down
Loading