Skip to content

Commit

Permalink
Préavis – Corrige le suivi des temps d'affichage des loading spinner …
Browse files Browse the repository at this point in the history
…et boutons de téléchargement (#3641)

## Linked issues

- #3579

----

- [ ] Tests E2E (Cypress)
  • Loading branch information
ivangabriele authored Sep 12, 2024
2 parents d38ce13 + 82dd985 commit 76e9b6b
Show file tree
Hide file tree
Showing 9 changed files with 75 additions and 40 deletions.
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

0 comments on commit 76e9b6b

Please sign in to comment.