Skip to content

Commit

Permalink
Merge branch 'chore_release-7.3.0' into fix_RQA-2697
Browse files Browse the repository at this point in the history
  • Loading branch information
koji committed May 10, 2024
2 parents 1c83a58 + d367217 commit 89077ff
Show file tree
Hide file tree
Showing 30 changed files with 283 additions and 159 deletions.
6 changes: 4 additions & 2 deletions api/src/opentrons/hardware_control/module_control.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,11 @@
log = logging.getLogger(__name__)

MODULE_PORT_REGEX = re.compile(
# add a negative lookbehind to suppress matches on OT-2 tempfiles udev creates
r"(?<!\.#ot_module_)"
# capture all modules by name using alternation
"(" + "|".join(modules.MODULE_TYPE_BY_NAME.keys()) + ")"
# add a negative lookahead to suppress matches on tempfiles udev creates
+ "(" + "|".join(modules.MODULE_TYPE_BY_NAME.keys()) + ")"
# add a negative lookahead to suppress matches on Flex tempfiles udev creates
+ r"\d+(?!\.tmp-c\d+:\d+)",
re.I,
)
Expand Down
3 changes: 1 addition & 2 deletions app/src/assets/localization/en/device_details.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@
"about_module": "About {{name}}",
"about_pipette_name": "About {{name}} Pipette",
"about_pipette": "About pipette",
"add_fixture_description": "Add this item to your deck configuration. It will be referenced during protocol analysis.",
"add_to_slot_description": "Choose an item below to add to your deck configuration. It will be referenced during protocol analysis.",
"add_fixture_description": "Add this hardware to your deck configuration. It will be referenced during protocol analysis.",
"add_to_slot": "Add to slot {{slotName}}",
"add": "Add",
"an_error_occurred_while_updating_module": "An error occurred while updating your {{moduleName}}. Please try again.",
Expand Down
2 changes: 1 addition & 1 deletion app/src/assets/localization/en/device_settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -294,7 +294,7 @@
"update_robot_software": "Update robot software manually with a local file (.zip)",
"updating": "Updating",
"update_requires_restarting_robot": "Updating the robot software requires restarting the robot",
"upload_custom_logo_description": "Upload a logo for the robot to display during boot up. If no file is uploaded, we will display an anonymous logo.",
"upload_custom_logo_description": "Upload a logo for the robot to display during boot up.",
"upload_custom_logo_dimensions": "The logo must fit within dimensions 1024 x 600 and be a PNG file (.png).",
"upload_custom_logo": "Upload custom logo",
"usage_settings": "Usage Settings",
Expand Down
16 changes: 8 additions & 8 deletions app/src/assets/localization/en/protocol_setup.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
"action_needed": "Action needed",
"adapter_slot_location_module": "Slot {{slotName}}, {{adapterName}} on {{moduleName}}",
"adapter_slot_location": "Slot {{slotName}}, {{adapterName}}",
"add_fixture": "Add {{fixtureName}} to deck configuration",
"add_fixture": "Add {{fixtureName}} to {{locationName}}",
"additional_labware": "{{count}} additional labware",
"additional_off_deck_labware": "Additional Off-Deck Labware",
"add_this_deck_hardware": "Add this deck hardware to your deck configuration. It will be referenced during protocol analysis.",
"add_this_deck_hardware": "Add this hardware to your deck configuration. It will be referenced during protocol analysis.",
"add_to_slot": "Add to slot {{slotName}}",
"attach_gripper_failure_reason": "Attach the required gripper to continue",
"attach_gripper": "attach gripper",
Expand Down Expand Up @@ -83,7 +83,9 @@
"initial_liquids_num_plural": "{{count}} initial liquids",
"initial_liquids_num": "{{count}} initial liquid",
"initial_location": "Initial Location",
"install_modules_and_fixtures": "Install the required modules and power them on. Install the required fixtures and review the deck configuration.",
"install_modules": "Install the required module.",
"install_modules_plural": "Install the required modules.",
"install_modules_and_fixtures": "Install and calibrate the required modules. Install the required fixtures.",
"instrument_calibrations_missing_plural": "Missing {{count}} calibrations",
"instrument_calibrations_missing": "Missing {{count}} calibration",
"instruments_connected_plural": "{{count}} instruments attached",
Expand Down Expand Up @@ -132,16 +134,13 @@
"missing_pipettes": "Missing {{count}} pipette",
"missing": "Missing",
"modal_instructions_title": "{{moduleName}} Setup Instructions",
"module_and_deck_setup": "Modules & deck",
"module_connected": "Connected",
"module_disconnected": "Disconnected",
"module_instructions_link": "{{moduleName}} setup instructions",
"module_mismatch_body": "Check that the modules connected to this robot are of the right type and generation",
"module_name": "Module",
"module_not_connected": "Not connected",
"module_setup_step_description_plural": "Install the required modules and power them on.",
"module_setup_step_description": "Install the required modules and power them on.",
"module_setup_step_title": "Modules",
"module_setup_step_title": "Deck hardware",
"module_slot_location": "Slot {{slotName}}, {{moduleName}}",
"module": "Module",
"modules_connected_plural": "{{count}} modules attached",
Expand All @@ -164,6 +163,7 @@
"name": "Name",
"no_custom_values": "No custom values specified",
"no_data": "no data",
"no_deck_hardware_specified": "No deck hardware are specified for this protocol.",
"no_labware_offset_data": "no labware offset data yet",
"no_modules_or_fixtures": "No modules or fixtures are specified for this protocol.",
"no_modules_specified": "no modules are specified for this protocol.",
Expand Down Expand Up @@ -251,7 +251,7 @@
"slot_number": "Slot Number",
"status": "Status",
"step": "STEP {{index}}",
"there_are_no_unconfigured_modules": "No {{module}} is connected. Attach one and place it in {{slot}}",
"there_are_no_unconfigured_modules": "No {{module}} is connected. Attach one and place it in {{slot}}.",
"there_are_other_configured_modules": "A {{module}} is already configured in a different slot. Exit run setup and update your deck configuration to move to an already connected module. Or attach another {{module}} to continue setup.",
"tip_length_cal_description_bullet": "Perform Tip Length Calibration for each new tip type used on a pipette.",
"tip_length_cal_description": "This measures the Z distance between the bottom of the tip and the pipette’s nozzle. If you redo the tip length calibration for the tip you used to calibrate a pipette, you will also have to redo that Pipette Offset Calibration.",
Expand Down
2 changes: 1 addition & 1 deletion app/src/atoms/InputField/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ export interface InputFieldProps {
/** blur handler */
onBlur?: (event: React.FocusEvent<HTMLInputElement>) => unknown
/** makes input field read-only */
readOnly?: boolean | undefined
readOnly?: boolean
/** html tabindex property */
tabIndex?: number
/** automatically focus field on renders */
Expand Down
44 changes: 43 additions & 1 deletion app/src/atoms/MenuList/DropdownMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,47 @@ export function DropdownMenu(props: DropdownMenuProps): JSX.Element {
} = props
const [targetProps, tooltipProps] = useHoverTooltip()
const [showDropdownMenu, setShowDropdownMenu] = React.useState<boolean>(false)

const [dropdownPosition, setDropdownPosition] = React.useState<
'top' | 'bottom'
>('bottom')

React.useEffect(() => {
const handlePositionCalculation = (): void => {
const dropdownRect = dropDownMenuWrapperRef.current?.getBoundingClientRect()
if (dropdownRect != null) {
const parentElement = dropDownMenuWrapperRef?.current?.parentElement
const grandParentElement = parentElement?.parentElement?.parentElement
let availableHeight = window.innerHeight
let scrollOffset = 0

if (grandParentElement != null) {
const grandParentRect = grandParentElement.getBoundingClientRect()
availableHeight = grandParentRect.bottom - grandParentRect.top
scrollOffset = grandParentRect.top
} else if (parentElement != null) {
const parentRect = parentElement.getBoundingClientRect()
availableHeight = parentRect.bottom - parentRect.top
scrollOffset = parentRect.top
}

const dropdownBottom =
dropdownRect.bottom + (filterOptions.length + 1) * 34 - scrollOffset

setDropdownPosition(dropdownBottom > availableHeight ? 'top' : 'bottom')
}
}

window.addEventListener('resize', handlePositionCalculation)
window.addEventListener('scroll', handlePositionCalculation)
handlePositionCalculation()

return () => {
window.removeEventListener('resize', handlePositionCalculation)
window.removeEventListener('scroll', handlePositionCalculation)
}
}, [filterOptions.length, window.innerHeight])

const toggleSetShowDropdownMenu = (): void => {
setShowDropdownMenu(!showDropdownMenu)
}
Expand Down Expand Up @@ -170,7 +211,8 @@ export function DropdownMenu(props: DropdownMenuProps): JSX.Element {
backgroundColor={COLORS.white}
flexDirection={DIRECTION_COLUMN}
width={width}
top="2.5rem"
top={dropdownPosition === 'bottom' ? '2.5rem' : undefined}
bottom={dropdownPosition === 'top' ? '2.5rem' : undefined}
>
{filterOptions.map((option, index) => (
<MenuItem
Expand Down
31 changes: 31 additions & 0 deletions app/src/molecules/FileUpload/FileUpload.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import * as React from 'react'
import testFile from './__tests__/test-file.png'
import { FileUpload } from '.'

import type { StoryFn, Meta } from '@storybook/react'

const file = new File([testFile], 'a-file-to-test.png')
const handleClick = (): void => console.log('clicked the file')

export default {
title: 'App/Molecules/FileUpload',
component: FileUpload,
} as Meta

const FileUploadTemplate: StoryFn<
React.ComponentProps<typeof FileUpload>
> = args => <FileUpload {...args} />

export const FileUploadComponent = FileUploadTemplate.bind({})
FileUploadComponent.args = {
file,
fileError: null,
handleClick,
}

export const FileUploadError = FileUploadTemplate.bind({})
FileUploadError.args = {
file,
fileError: 'a terrible file',
handleClick,
}
42 changes: 42 additions & 0 deletions app/src/molecules/FileUpload/__tests__/FileUpload.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import * as React from 'react'
import { beforeEach, describe, expect, it, vi } from 'vitest'
import { screen } from '@testing-library/react'

import { renderWithProviders } from '../../../__testing-utils__'
import { i18n } from '../../../i18n'
import { FileUpload } from '..'
import testFile from './test-file.png'

const render = (props: React.ComponentProps<typeof FileUpload>) => {
return renderWithProviders(<FileUpload {...props} />, {
i18nInstance: i18n,
})[0]
}

const handleClick = vi.fn()

describe('FileUpload', () => {
let props: React.ComponentProps<typeof FileUpload>

beforeEach(() => {
const file = new File([testFile], 'a-file-to-test.png')

props = {
file,
fileError: null,
handleClick,
}
})
it('renders file upload', () => {
render(props)
screen.getByText('a-file-to-test.png')
const removeFile = screen.getByLabelText('remove_file')
removeFile.click()
expect(handleClick).toBeCalled()
})

it('renders file upload error', () => {
render({ ...props, fileError: 'oops this is a bad file' })
screen.getByText('oops this is a bad file')
})
})
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
16 changes: 14 additions & 2 deletions app/src/molecules/FileUpload/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
JUSTIFY_SPACE_BETWEEN,
SPACING,
StyledText,
truncateString,
} from '@opentrons/components'

const FILE_UPLOAD_STYLE = css`
Expand All @@ -23,6 +24,13 @@ const FILE_UPLOAD_STYLE = css`
}
`

const FILE_UPLOAD_FOCUS_VISIBLE = css`
&:focus-visible {
border-radius: ${BORDERS.borderRadius4};
box-shadow: 0 0 0 ${SPACING.spacing2} ${COLORS.blue50};
}
`

interface FileUploadProps {
file: File
fileError: string | null
Expand All @@ -36,7 +44,11 @@ export function FileUpload({
}: FileUploadProps): JSX.Element {
return (
<Flex flexDirection={DIRECTION_COLUMN} gridGap={SPACING.spacing4}>
<Btn onClick={handleClick} aria-label="remove_file">
<Btn
onClick={handleClick}
aria-label="remove_file"
css={FILE_UPLOAD_FOCUS_VISIBLE}
>
<Flex
alignItems={ALIGN_CENTER}
backgroundColor={fileError == null ? COLORS.grey20 : COLORS.red30}
Expand All @@ -46,7 +58,7 @@ export function FileUpload({
padding={SPACING.spacing8}
css={FILE_UPLOAD_STYLE}
>
<StyledText as="p">{file.name}</StyledText>
<StyledText as="p">{truncateString(file.name, 34, 19)}</StyledText>
<Icon name="close" size="1.5rem" borderRadius="50%" />
</Flex>
</Btn>
Expand Down
14 changes: 13 additions & 1 deletion app/src/molecules/ReleaseNotes/index.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import * as React from 'react'
import Markdown from 'react-markdown'

import { StyledText } from '@opentrons/components'
import { Box, COLORS, SPACING, StyledText } from '@opentrons/components'

import { useIsOEMMode } from '../../resources/robot-settings/hooks'

import styles from './styles.module.css'
Expand All @@ -28,6 +29,7 @@ export function ReleaseNotes(props: ReleaseNotesProps): JSX.Element {
li: ListItemText,
p: ParagraphText,
a: ExternalLink,
hr: HorizontalRule,
}}
>
{source}
Expand Down Expand Up @@ -58,3 +60,13 @@ function ListItemText(props: JSX.IntrinsicAttributes): JSX.Element {
function UnnumberedListText(props: JSX.IntrinsicAttributes): JSX.Element {
return <StyledText {...props} as="ul" />
}

function HorizontalRule(): JSX.Element {
return (
<Box
borderBottom={`1px solid ${String(COLORS.grey30)}`}
marginY={SPACING.spacing16}
data-testid="divider"
/>
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -347,7 +347,7 @@ export function AddFixtureModal({
}
>
<Flex flexDirection={DIRECTION_COLUMN} gridGap={SPACING.spacing32}>
<StyledText as="p">{t('add_to_slot_description')}</StyledText>
<StyledText as="p">{t('add_fixture_description')}</StyledText>
<Flex flexDirection={DIRECTION_COLUMN} gridGap={SPACING.spacing8}>
{fixtureOptions}
{nextStageOptions}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ describe('Touchscreen AddFixtureModal', () => {
render(props)
screen.getByText('Add to slot D3')
screen.getByText(
'Choose an item below to add to your deck configuration. It will be referenced during protocol analysis.'
'Add this hardware to your deck configuration. It will be referenced during protocol analysis.'
)
screen.getByText('Fixtures')
screen.getByText('Modules')
Expand All @@ -80,7 +80,7 @@ describe('Touchscreen AddFixtureModal', () => {
render(props)
screen.getByText('Add to slot D3')
screen.getByText(
'Choose an item below to add to your deck configuration. It will be referenced during protocol analysis.'
'Add this hardware to your deck configuration. It will be referenced during protocol analysis.'
)
expect(screen.queryByText('Staging area slot')).toBeNull()
screen.getByText('Trash bin')
Expand Down Expand Up @@ -111,7 +111,7 @@ describe('Desktop AddFixtureModal', () => {
render(props)
screen.getByText('Add to slot D3')
screen.getByText(
'Add this item to your deck configuration. It will be referenced during protocol analysis.'
'Add this hardware to your deck configuration. It will be referenced during protocol analysis.'
)

screen.getByText('Fixtures')
Expand All @@ -131,7 +131,7 @@ describe('Desktop AddFixtureModal', () => {
render(props)
screen.getByText('Add to slot A1')
screen.getByText(
'Add this item to your deck configuration. It will be referenced during protocol analysis.'
'Add this hardware to your deck configuration. It will be referenced during protocol analysis.'
)
screen.getByText('Fixtures')
screen.getByText('Modules')
Expand All @@ -145,7 +145,7 @@ describe('Desktop AddFixtureModal', () => {
render(props)
screen.getByText('Add to slot B3')
screen.getByText(
'Add this item to your deck configuration. It will be referenced during protocol analysis.'
'Add this hardware to your deck configuration. It will be referenced during protocol analysis.'
)
screen.getByText('Fixtures')
screen.getByText('Modules')
Expand All @@ -160,7 +160,7 @@ describe('Desktop AddFixtureModal', () => {
render(props)
screen.getByText('Add to slot B2')
screen.getByText(
'Add this item to your deck configuration. It will be referenced during protocol analysis.'
'Add this hardware to your deck configuration. It will be referenced during protocol analysis.'
)
screen.getByText('Magnetic Block GEN1')
expect(screen.getByRole('button', { name: 'Add' })).toBeInTheDocument()
Expand Down
Loading

0 comments on commit 89077ff

Please sign in to comment.