From ad0b5865ecb0b007e612176c3945474c054c1992 Mon Sep 17 00:00:00 2001 From: Jamey Huffnagle Date: Thu, 19 Dec 2024 15:53:01 -0500 Subject: [PATCH] refactor(app): report `robotType` in select events (#17153) Closes EXEC-629 and RQA-2386 --- .../DeviceResetSlideout.tsx | 5 +++- .../RenameRobotSlideout.tsx | 4 ++++ .../__tests__/RenameRobotSlideout.test.tsx | 10 ++++++-- .../CalibrationDataDownload.tsx | 6 ++++- .../CalibrationDataDownload.test.tsx | 3 ++- app/src/pages/ODD/NameRobot/index.tsx | 2 ++ .../analytics/__tests__/make-event.test.ts | 10 +++++--- app/src/redux/analytics/make-event.ts | 5 ++++ app/src/redux/analytics/selectors.ts | 23 ++++++++++++++++--- app/src/redux/analytics/types.ts | 3 ++- 10 files changed, 59 insertions(+), 12 deletions(-) diff --git a/app/src/organisms/Desktop/Devices/RobotSettings/AdvancedTab/AdvancedTabSlideouts/DeviceResetSlideout.tsx b/app/src/organisms/Desktop/Devices/RobotSettings/AdvancedTab/AdvancedTabSlideouts/DeviceResetSlideout.tsx index 763ca9f0cb2..bf963b22f29 100644 --- a/app/src/organisms/Desktop/Devices/RobotSettings/AdvancedTab/AdvancedTabSlideouts/DeviceResetSlideout.tsx +++ b/app/src/organisms/Desktop/Devices/RobotSettings/AdvancedTab/AdvancedTabSlideouts/DeviceResetSlideout.tsx @@ -20,6 +20,7 @@ import { LegacyStyledText, TYPOGRAPHY, } from '@opentrons/components' +import { FLEX_ROBOT_TYPE, OT2_ROBOT_TYPE } from '@opentrons/shared-data' import { Slideout } from '/app/atoms/Slideout' import { Divider } from '/app/atoms/structure' @@ -107,7 +108,9 @@ export function DeviceResetSlideout({ e.preventDefault() doTrackEvent({ name: ANALYTICS_CALIBRATION_DATA_DOWNLOADED, - properties: {}, + properties: { + robotType: isFlex ? FLEX_ROBOT_TYPE : OT2_ROBOT_TYPE, + }, }) saveAs( new Blob([ diff --git a/app/src/organisms/Desktop/Devices/RobotSettings/AdvancedTab/AdvancedTabSlideouts/RenameRobotSlideout.tsx b/app/src/organisms/Desktop/Devices/RobotSettings/AdvancedTab/AdvancedTabSlideouts/RenameRobotSlideout.tsx index 55d9806a88f..af75fca2189 100644 --- a/app/src/organisms/Desktop/Devices/RobotSettings/AdvancedTab/AdvancedTabSlideouts/RenameRobotSlideout.tsx +++ b/app/src/organisms/Desktop/Devices/RobotSettings/AdvancedTab/AdvancedTabSlideouts/RenameRobotSlideout.tsx @@ -3,6 +3,7 @@ import { useSelector, useDispatch } from 'react-redux' import { useNavigate } from 'react-router-dom' import { useForm, Controller } from 'react-hook-form' import { useTranslation } from 'react-i18next' + import { COLORS, Banner, @@ -14,6 +15,8 @@ import { SPACING, } from '@opentrons/components' import { useUpdateRobotNameMutation } from '@opentrons/react-api-client' +import { FLEX_ROBOT_TYPE, OT2_ROBOT_TYPE } from '@opentrons/shared-data' + import { removeRobot, getConnectableRobots, @@ -152,6 +155,7 @@ export function RenameRobotSlideout({ properties: { previousRobotName, newRobotName: newRobotName, + robotType: isFlex ? FLEX_ROBOT_TYPE : OT2_ROBOT_TYPE, }, }) handleSubmit(onSubmit)() diff --git a/app/src/organisms/Desktop/Devices/RobotSettings/AdvancedTab/AdvancedTabSlideouts/__tests__/RenameRobotSlideout.test.tsx b/app/src/organisms/Desktop/Devices/RobotSettings/AdvancedTab/AdvancedTabSlideouts/__tests__/RenameRobotSlideout.test.tsx index 6f7b1b4ab28..13612c63f19 100644 --- a/app/src/organisms/Desktop/Devices/RobotSettings/AdvancedTab/AdvancedTabSlideouts/__tests__/RenameRobotSlideout.test.tsx +++ b/app/src/organisms/Desktop/Devices/RobotSettings/AdvancedTab/AdvancedTabSlideouts/__tests__/RenameRobotSlideout.test.tsx @@ -2,6 +2,9 @@ import { MemoryRouter } from 'react-router-dom' import { fireEvent, screen, waitFor } from '@testing-library/react' import { describe, it, vi, expect, beforeEach } from 'vitest' import '@testing-library/jest-dom/vitest' + +import { OT2_ROBOT_TYPE } from '@opentrons/shared-data' + import { renderWithProviders } from '/app/__testing-utils__' import { i18n } from '/app/i18n' import { useTrackEvent, ANALYTICS_RENAME_ROBOT } from '/app/redux/analytics' @@ -14,7 +17,6 @@ import { mockConnectableRobot, mockReachableRobot, } from '/app/redux/discovery/__fixtures__' - import { RenameRobotSlideout } from '../RenameRobotSlideout' import { useIsFlex } from '/app/redux-resources/robots' @@ -111,7 +113,11 @@ describe('RobotSettings RenameRobotSlideout', () => { await waitFor(() => { expect(mockTrackEvent).toHaveBeenCalledWith({ name: ANALYTICS_RENAME_ROBOT, - properties: { newRobotName: 'mockInput', previousRobotName: 'otie' }, + properties: { + newRobotName: 'mockInput', + previousRobotName: 'otie', + robotType: OT2_ROBOT_TYPE, + }, }) }) }) diff --git a/app/src/organisms/Desktop/RobotSettingsCalibration/CalibrationDataDownload.tsx b/app/src/organisms/Desktop/RobotSettingsCalibration/CalibrationDataDownload.tsx index 4731df09ae4..83aeddf3e35 100644 --- a/app/src/organisms/Desktop/RobotSettingsCalibration/CalibrationDataDownload.tsx +++ b/app/src/organisms/Desktop/RobotSettingsCalibration/CalibrationDataDownload.tsx @@ -17,6 +17,8 @@ import { useInstrumentsQuery, useModulesQuery, } from '@opentrons/react-api-client' +import { FLEX_ROBOT_TYPE, OT2_ROBOT_TYPE } from '@opentrons/shared-data' + import { TertiaryButton } from '/app/atoms/buttons' import { useDeckCalibrationData, @@ -72,7 +74,9 @@ export function CalibrationDataDownload({ e.preventDefault() doTrackEvent({ name: ANALYTICS_CALIBRATION_DATA_DOWNLOADED, - properties: {}, + properties: { + robotType: isFlex ? FLEX_ROBOT_TYPE : OT2_ROBOT_TYPE, + }, }) saveAs( new Blob([ diff --git a/app/src/organisms/Desktop/RobotSettingsCalibration/__tests__/CalibrationDataDownload.test.tsx b/app/src/organisms/Desktop/RobotSettingsCalibration/__tests__/CalibrationDataDownload.test.tsx index b84b25e2e16..b50a892ca73 100644 --- a/app/src/organisms/Desktop/RobotSettingsCalibration/__tests__/CalibrationDataDownload.test.tsx +++ b/app/src/organisms/Desktop/RobotSettingsCalibration/__tests__/CalibrationDataDownload.test.tsx @@ -16,6 +16,7 @@ import { useModulesQuery, } from '@opentrons/react-api-client' import { instrumentsResponseFixture } from '@opentrons/api-client' +import { OT2_ROBOT_TYPE } from '@opentrons/shared-data' import { i18n } from '/app/i18n' import { @@ -145,7 +146,7 @@ describe('CalibrationDataDownload', () => { fireEvent.click(downloadButton) expect(mockTrackEvent).toHaveBeenCalledWith({ name: ANALYTICS_CALIBRATION_DATA_DOWNLOADED, - properties: {}, + properties: { robotType: OT2_ROBOT_TYPE }, }) }) diff --git a/app/src/pages/ODD/NameRobot/index.tsx b/app/src/pages/ODD/NameRobot/index.tsx index b0162041963..1417adbbf37 100644 --- a/app/src/pages/ODD/NameRobot/index.tsx +++ b/app/src/pages/ODD/NameRobot/index.tsx @@ -23,6 +23,7 @@ import { TYPOGRAPHY, } from '@opentrons/components' import { useUpdateRobotNameMutation } from '@opentrons/react-api-client' +import { FLEX_ROBOT_TYPE } from '@opentrons/shared-data' import { removeRobot, @@ -166,6 +167,7 @@ export function NameRobot(): JSX.Element { properties: { previousRobotName: previousName, newRobotName: newRobotName, + robotType: FLEX_ROBOT_TYPE, }, }) handleSubmit(onSubmit)() diff --git a/app/src/redux/analytics/__tests__/make-event.test.ts b/app/src/redux/analytics/__tests__/make-event.test.ts index 70506dc162a..8cc56e18950 100644 --- a/app/src/redux/analytics/__tests__/make-event.test.ts +++ b/app/src/redux/analytics/__tests__/make-event.test.ts @@ -1,5 +1,7 @@ import { vi, describe, it, expect, beforeEach } from 'vitest' +import { OT2_ROBOT_TYPE } from '@opentrons/shared-data' + import { makeEvent } from '../make-event' import * as selectors from '../selectors' @@ -49,6 +51,7 @@ describe('analytics events map', () => { name: 'pipetteOffsetCalibrationStarted', properties: { ...action.payload, + robotType: OT2_ROBOT_TYPE, }, }) }) @@ -65,6 +68,7 @@ describe('analytics events map', () => { name: 'tipLengthCalibrationStarted', properties: { ...action.payload, + robotType: OT2_ROBOT_TYPE, }, }) }) @@ -77,6 +81,7 @@ describe('analytics events map', () => { robotName: 'my-robot', sessionId: 'seshid', command: { command: 'calibration.exitSession' }, + robotType: OT2_ROBOT_TYPE, }, } as any vi.mocked(selectors.getAnalyticsSessionExitDetails).mockReturnValue({ @@ -86,7 +91,7 @@ describe('analytics events map', () => { return expect(makeEvent(action, state)).resolves.toEqual({ name: 'my-session-typeExit', - properties: { step: 'session-step' }, + properties: { step: 'session-step', robotType: OT2_ROBOT_TYPE }, }) }) @@ -117,12 +122,11 @@ describe('analytics events map', () => { properties: { pipetteModel: 'my-pipette-model', tipRackDisplayName: 'some display name', + robotType: OT2_ROBOT_TYPE, }, }) }) - }) - describe('events with calibration data', () => { it('analytics:RESOURCE_MONITOR_REPORT -> resourceMonitorReport event', () => { const state = {} as any const action = { diff --git a/app/src/redux/analytics/make-event.ts b/app/src/redux/analytics/make-event.ts index bc5c8955104..608915c4112 100644 --- a/app/src/redux/analytics/make-event.ts +++ b/app/src/redux/analytics/make-event.ts @@ -13,6 +13,7 @@ import { getAnalyticsSessionExitDetails, getSessionInstrumentAnalyticsData, } from './selectors' +import { OT2_ROBOT_TYPE } from '@opentrons/shared-data' import type { State, Action } from '../types' import type { AnalyticsEvent } from './types' @@ -180,6 +181,7 @@ export function makeEvent( name: `${sessionDetails.sessionType}Exit`, properties: { step: sessionDetails.step, + robotType: OT2_ROBOT_TYPE, }, } : null @@ -203,6 +205,7 @@ export function makeEvent( 'tiprackDefinition' in commandData ? commandData.tiprackDefinition.metadata.displayName : null, + robotType: OT2_ROBOT_TYPE, }, } : null @@ -234,6 +237,7 @@ export function makeEvent( name: 'pipetteOffsetCalibrationStarted', properties: { ...action.payload, + robotType: OT2_ROBOT_TYPE, }, }) } @@ -243,6 +247,7 @@ export function makeEvent( name: 'tipLengthCalibrationStarted', properties: { ...action.payload, + robotType: OT2_ROBOT_TYPE, }, }) } diff --git a/app/src/redux/analytics/selectors.ts b/app/src/redux/analytics/selectors.ts index 4751a8eb99e..962f2c55832 100644 --- a/app/src/redux/analytics/selectors.ts +++ b/app/src/redux/analytics/selectors.ts @@ -1,24 +1,24 @@ import * as Sessions from '../sessions' -import { getViewableRobots, getRobotApiVersion } from '../discovery' +import { FLEX_ROBOT_TYPE, OT2_ROBOT_TYPE } from '@opentrons/shared-data' +import { getViewableRobots, getRobotApiVersion } from '../discovery' import { getRobotUpdateVersion, getRobotUpdateRobot, getRobotUpdateSession, getRobotSystemType, } from '../robot-update' - import { getRobotSessionById } from '../sessions/selectors' import type { State } from '../types' - import type { AnalyticsConfig, BuildrootAnalyticsData, AnalyticsSessionExitDetails, SessionInstrumentAnalyticsData, } from './types' +import type { RobotType } from '@opentrons/shared-data' export function getBuildrootAnalyticsData( state: State, @@ -40,12 +40,29 @@ export function getBuildrootAnalyticsData( const currentVersion = getRobotApiVersion(robot) ?? 'unknown' const currentSystem = getRobotSystemType(robot) ?? 'unknown' + const getRobotType = (): RobotType | undefined => { + switch (currentSystem) { + case 'flex': + return FLEX_ROBOT_TYPE + case 'ot2-buildroot': + case 'ot2-balena': + return OT2_ROBOT_TYPE + case 'unknown': + return undefined + default: { + console.error('Unexpected system type: ', currentSystem) + return undefined + } + } + } + return { currentVersion, currentSystem, updateVersion: updateVersion ?? 'unknown', error: session != null && 'error' in session ? session.error : null, robotSerialNumber, + robotType: getRobotType(), } } diff --git a/app/src/redux/analytics/types.ts b/app/src/redux/analytics/types.ts index d27c2955fe2..95b320e88ab 100644 --- a/app/src/redux/analytics/types.ts +++ b/app/src/redux/analytics/types.ts @@ -1,4 +1,4 @@ -import type { PipetteMount as Mount } from '@opentrons/shared-data' +import type { PipetteMount as Mount, RobotType } from '@opentrons/shared-data' import type { CalibrationCheckComparisonsPerCalibration } from '../sessions/types' import type { DeckCalibrationStatus } from '../calibration/types' import type { Config } from '../config/types' @@ -42,6 +42,7 @@ export interface BuildrootAnalyticsData { updateVersion: string error: string | null robotSerialNumber: string | null + robotType: RobotType | undefined } export interface PipetteOffsetCalibrationAnalyticsData {