diff --git a/frontend/src/features/PriorNotification/components/LogbookPriorNotificationForm/index.tsx b/frontend/src/features/PriorNotification/components/LogbookPriorNotificationForm/index.tsx
index f37214d585..02d976c8e7 100644
--- a/frontend/src/features/PriorNotification/components/LogbookPriorNotificationForm/index.tsx
+++ b/frontend/src/features/PriorNotification/components/LogbookPriorNotificationForm/index.tsx
@@ -2,6 +2,7 @@ import { verifyAndSendPriorNotification } from '@features/PriorNotification/useC
import { getPriorNotificationIdentifier } from '@features/PriorNotification/utils'
import { useMainAppDispatch } from '@hooks/useMainAppDispatch'
import { useMainAppSelector } from '@hooks/useMainAppSelector'
+import { customSentry, CustomSentryMeasurementName } from '@libs/customSentry'
import { DisplayedErrorKey } from '@libs/DisplayedError/constants'
import { assertNotNullish } from '@utils/assertNotNullish'
@@ -41,6 +42,11 @@ export function LogbookPriorNotificationForm() {
return
}
+ customSentry.endMeasurement(
+ CustomSentryMeasurementName.LOGBOOK_PRIOR_NOTIFICATION_FORM_SPINNER,
+ openedPriorNotificationDetail.reportId
+ )
+
return (
data?.status === StatusBodyEnum.FOUND, [data])
const hasAuthorizedLandingDownload =
@@ -76,6 +79,18 @@ export function DownloadButton({
downloadAsPdf(fileName, 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])
+
return (
<>
{hasAuthorizedLandingDownload && (
diff --git a/frontend/src/features/PriorNotification/useCases/openLogbookPriorNotificationForm.ts b/frontend/src/features/PriorNotification/useCases/openLogbookPriorNotificationForm.ts
index 8f43670397..8e36de8eef 100644
--- a/frontend/src/features/PriorNotification/useCases/openLogbookPriorNotificationForm.ts
+++ b/frontend/src/features/PriorNotification/useCases/openLogbookPriorNotificationForm.ts
@@ -1,5 +1,6 @@
import { RtkCacheTagType } from '@api/constants'
import { addMainWindowBanner } from '@features/SideWindow/useCases/addMainWindowBanner'
+import { customSentry, CustomSentryMeasurementName } from '@libs/customSentry'
import { DisplayedErrorKey } from '@libs/DisplayedError/constants'
import { FrontendApiError } from '@libs/FrontendApiError'
import { FrontendError } from '@libs/FrontendError'
@@ -19,6 +20,11 @@ export const openLogbookPriorNotificationForm =
(identifier: PriorNotification.Identifier, fingerprint?: string): MainAppThunk> =>
async dispatch => {
try {
+ customSentry.startMeasurement(
+ CustomSentryMeasurementName.LOGBOOK_PRIOR_NOTIFICATION_FORM_SPINNER,
+ identifier.reportId
+ )
+
dispatch(displayedErrorActions.unset(DisplayedErrorKey.SIDE_WINDOW_PRIOR_NOTIFICATION_FORM_ERROR))
dispatch(priorNotificationActions.closePriorNotificationCardAndForm())
dispatch(priorNotificationActions.openPriorNotification(OpenedPriorNotificationType.LogbookForm))
diff --git a/frontend/src/features/PriorNotification/useCases/openManualPriorNotificationForm.ts b/frontend/src/features/PriorNotification/useCases/openManualPriorNotificationForm.ts
index 53145c6715..69d812fff5 100644
--- a/frontend/src/features/PriorNotification/useCases/openManualPriorNotificationForm.ts
+++ b/frontend/src/features/PriorNotification/useCases/openManualPriorNotificationForm.ts
@@ -1,4 +1,5 @@
import { RtkCacheTagType } from '@api/constants'
+import { customSentry, CustomSentryMeasurementName } from '@libs/customSentry'
import { DisplayedErrorKey } from '@libs/DisplayedError/constants'
import { FrontendApiError } from '@libs/FrontendApiError'
import { FrontendError } from '@libs/FrontendError'
@@ -24,6 +25,13 @@ export const openManualPriorNotificationForm =
): MainAppThunk> =>
async dispatch => {
try {
+ if (identifier) {
+ customSentry.startMeasurement(
+ CustomSentryMeasurementName.LOGBOOK_PRIOR_NOTIFICATION_FORM_SPINNER,
+ identifier.reportId
+ )
+ }
+
dispatch(displayedErrorActions.unset(DisplayedErrorKey.SIDE_WINDOW_PRIOR_NOTIFICATION_FORM_ERROR))
dispatch(priorNotificationActions.closePriorNotificationCardAndForm())
dispatch(priorNotificationActions.openPriorNotification(OpenedPriorNotificationType.ManualForm))
diff --git a/frontend/src/libs/customSentry.ts b/frontend/src/libs/customSentry.ts
new file mode 100644
index 0000000000..93a42196b6
--- /dev/null
+++ b/frontend/src/libs/customSentry.ts
@@ -0,0 +1,61 @@
+/* eslint-disable no-empty */
+
+import { metrics, setMeasurement } from '@sentry/react'
+
+type CustomSentryMeasurementValue = {
+ id: string
+ value: 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'
+}
+
+class CustomSentry {
+ mesurements: Map = new Map()
+
+ clearMeasurement(name: CustomSentryMeasurementName, id: string) {
+ try {
+ const key = `${name}-${id}`
+ if (!this.mesurements.has(key)) {
+ return
+ }
+
+ this.mesurements.delete(key)
+ } catch (_) {}
+ }
+
+ startMeasurement(name: CustomSentryMeasurementName, id: string) {
+ try {
+ const key = `${name}-${id}`
+ const value = Date.now()
+ if (this.mesurements.has(key)) {
+ return
+ }
+
+ this.mesurements.set(key, { id, value })
+ } catch (_) {}
+ }
+
+ endMeasurement(name: CustomSentryMeasurementName, id: string) {
+ 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'
+ })
+
+ this.mesurements.delete(key)
+ } catch (_) {}
+ }
+}
+
+export const customSentry = new CustomSentry()