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

chore: Merge chore_release-7.3.0 into edge #15117

Merged
merged 18 commits into from
May 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
1ed0740
fix(app): modify slideout restore value link layout (#15059)
koji May 2, 2024
2c5669b
fix(app): fix the arrow icon size in dropdown menu (#15042)
koji May 2, 2024
7aa5805
fix(app): remove unnecessary padding (#15067)
koji May 2, 2024
93d3180
fix(app): remove input field box-shadow on ODD (#15040)
koji May 3, 2024
8fef724
refactor(app): format <ul> in release notes (#15081)
mjhuff May 3, 2024
02a1a16
fix(app): modify the space between icon and banner outline (#15085)
koji May 3, 2024
0526f55
fix(app): disable module calibration if heating or cooling (#15054)
ncdiehl11 May 3, 2024
d6472ae
fix(app): fix input field behavior on blur (#15035)
koji May 3, 2024
dfd0f31
fix(app): fix tooltip behavior for disabled Restore default value on …
ncdiehl11 May 3, 2024
fe428d4
fix(app): fix list button styling (#15088)
koji May 3, 2024
a88f03b
fix(app): update specific analysis keys passed through CommandText wi…
ncdiehl11 May 6, 2024
ef946ef
fix(app): fix space in mini card (#15095)
koji May 6, 2024
9ae6051
fix(app, react-api-client): handle failed analysis for RTP protocol o…
ncdiehl11 May 7, 2024
59d0062
refactor(app): Update drop tip blowout copy (#15109)
mjhuff May 7, 2024
cfed247
fix(robot-server): clear ChangeNotifier's internal event immediately …
mjhuff May 7, 2024
f6bd225
fix(app): fix choose number input field behavior (#15099)
koji May 7, 2024
16b94b5
fix(app): update disabled style of ProtocolSetupStep description (#15…
ncdiehl11 May 7, 2024
e93b665
Merge branch 'chore_release-7.3.0' into mergeback
mjhuff May 7, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion api/src/opentrons/util/change_notifier.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ def notify(self) -> None:

async def wait(self) -> None:
"""Wait until the next state change notification."""
self._event.clear()
await self._event.wait()
self._event.clear()


class ChangeNotifier_ts(ChangeNotifier):
Expand Down
27 changes: 27 additions & 0 deletions api/tests/opentrons/util/test_change_notifier.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,3 +54,30 @@ async def _do_task_3() -> None:
await asyncio.gather(task_1, task_2, task_3)

assert results == [1, 2, 3]


async def test_notify_while_busy() -> None:
"""Test that waiters process a new notify() after they are done being busy."""
subject = ChangeNotifier()
results = []

async def _do_task() -> None:
results.append("TEST")
await asyncio.sleep(0.2) # Simulate being busy

async def do_task() -> None:
while True:
await subject.wait()
await _do_task()

task = asyncio.create_task(do_task())

subject.notify()
await asyncio.sleep(0.0)

subject.notify()
await asyncio.sleep(0.5)

assert results == ["TEST", "TEST"]

task.cancel()
6 changes: 3 additions & 3 deletions app/src/assets/localization/en/drop_tip_wizard.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,10 @@
"remove_the_tips_from_pipette": "You may want to remove the tips from the pipette before using it again in a protocol.",
"remove_the_tips_manually": "Remove the tips manually. Then home the gantry. Homing with tips attached could pull liquid into the pipette and damage it.",
"remove_tips": "Remove tips",
"select_blowout_slot": "<block>You can blow out liquid into a labware or dispose of it.</block><block>Select the slot where you want to blow out the liquid on the deck map to the right. Once confirmed, the gantry will move to the chosen slot.</block>",
"select_blowout_slot_odd": "<block>You can blow out liquid into a labware or dispose of it.</block><br/><block>After the gantry moves to the chosen slot, use the jog controls to move the pipette to the exact position for blowing out.</block>",
"select_blowout_slot": "<block>You can blow out liquid into a labware.</block><block>Select the slot where you want to blow out the liquid on the deck map to the right. Once confirmed, the gantry will move to the chosen slot.</block>",
"select_blowout_slot_odd": "<block>You can blow out liquid into a labware.</block><br/><block>After the gantry moves to the chosen slot, use the jog controls to move the pipette to the exact position for blowing out.</block>",
"select_drop_tip_slot": "<block>You can return tips to a tip rack or dispose of them.</block><block>Select the slot where you want to drop the tips on the deck map to the right. Once confirmed, the gantry will move to the chosen slot.</block>",
"select_drop_tip_slot_odd": "<block>You can blow out liquid into a labware or dispose of it.</block><br/><block>After the gantry moves to the chosen slot, use the jog controls to move the pipette to the exact position for dropping tips.</block>",
"select_drop_tip_slot_odd": "<block>You can return tips to a tip rack or dispose of them.</block><br/><block>After the gantry moves to the chosen slot, use the jog controls to move the pipette to the exact position for dropping tips.</block>",
"skip": "Skip",
"stand_back_blowing_out": "Stand back, robot is blowing out liquid",
"stand_back_dropping_tips": "Stand back, robot is dropping tips",
Expand Down
1 change: 1 addition & 0 deletions app/src/assets/localization/en/module_wizard_flows.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
"location_occupied": "A {{fixture}} is currently specified here on the deck configuration",
"module_calibrating": "Stand back, {{moduleName}} is calibrating",
"module_calibration": "Module calibration",
"module_heating_or_cooling": "Module calibration cannot proceed while heating or cooling",
"module_secured": "The module must be fully secured in its caddy and secured in the deck slot.",
"module_too_hot": "Module is too hot to proceed to module calibration",
"move_gantry_to_front": "Move gantry to front",
Expand Down
11 changes: 8 additions & 3 deletions app/src/atoms/InputField/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import * as React from 'react'
import { css } from 'styled-components'
import styled, { css } from 'styled-components'

import {
ALIGN_CENTER,
Expand Down Expand Up @@ -172,7 +172,6 @@ function Input(props: InputFieldProps): JSX.Element {

@media ${RESPONSIVENESS.touchscreenMediaQuerySpecs} {
height: ${size === 'small' ? '4.25rem' : '5rem'};
box-shadow: ${hasError ? BORDERS.shadowBig : 'none'};
font-size: ${TYPOGRAPHY.fontSize28};
padding: ${SPACING.spacing16} ${SPACING.spacing24};
border: 2px ${BORDERS.styleSolid}
Expand Down Expand Up @@ -277,7 +276,7 @@ function Input(props: InputFieldProps): JSX.Element {
}
}}
>
<input
<StyledInput
{...inputProps}
data-testid={props.id}
value={value}
Expand Down Expand Up @@ -315,3 +314,9 @@ function Input(props: InputFieldProps): JSX.Element {
</Flex>
)
}

const StyledInput = styled.input`
&::placeholder {
color: ${COLORS.grey40};
}
`
4 changes: 2 additions & 2 deletions app/src/atoms/MenuList/DropdownMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -156,9 +156,9 @@ export function DropdownMenu(props: DropdownMenuProps): JSX.Element {
{currentOption.name}
</StyledText>
{showDropdownMenu ? (
<Icon size="1.2rem" name="menu-down" transform="rotate(180deg)" />
<Icon size="0.75rem" name="menu-down" transform="rotate(180deg)" />
) : (
<Icon size="1.2rem" name="menu-down" />
<Icon size="0.75rem" name="menu-down" />
)}
</Flex>
{showDropdownMenu && (
Expand Down
4 changes: 4 additions & 0 deletions app/src/molecules/ReleaseNotes/styles.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,14 @@
& ol {
margin-left: 1.25rem;
margin-bottom: 0.25rem;
font-size: var(--fs-body-2);
color: var(--c-font-dark); /* from legacy --font-body-2-dark */
}

& li {
margin: 0.25rem 0;
font-size: var(--fs-body-2);
color: var(--c-font-dark); /* from legacy --font-body-2-dark */
}

& code {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,28 @@ describe('ChooseProtocolSlideout', () => {
screen.getByText('Restore default values')
})

it('shows tooltip when disabled Restore default values link is clicked', () => {
const protocolDataWithoutRunTimeParameter = {
...storedProtocolDataFixture,
}
vi.mocked(getStoredProtocols).mockReturnValue([
protocolDataWithoutRunTimeParameter,
])

render({
robot: mockConnectableRobot,
onCloseClick: vi.fn(),
showSlideout: true,
})
const proceedButton = screen.getByRole('button', {
name: 'Continue to parameters',
})
fireEvent.click(proceedButton)
const restoreValuesLink = screen.getByText('Restore default values')
fireEvent.click(restoreValuesLink)
screen.getByText('No custom values specified')
})

// ToDo (kk:04/18/2024) I will update test for RTP
/*
it('renders error state when there is a run creation error', () => {
Expand Down
53 changes: 42 additions & 11 deletions app/src/organisms/ChooseProtocolSlideout/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import {
SecondaryButton,
StyledText,
TYPOGRAPHY,
useHoverTooltip,
useTooltip,
} from '@opentrons/components'
import { ApiHostProvider } from '@opentrons/react-api-client'

Expand Down Expand Up @@ -63,6 +63,8 @@ export const CARD_OUTLINE_BORDER_STYLE = css`
}
`

const TOOLTIP_DELAY_MS = 2000

const _getFileBaseName = (filePath: string): string => {
return filePath.split('/').reverse()[0]
}
Expand All @@ -78,7 +80,11 @@ export function ChooseProtocolSlideoutComponent(
const { t } = useTranslation(['device_details', 'shared'])
const history = useHistory()
const logger = useLogger(new URL('', import.meta.url).pathname)
const [targetProps, tooltipProps] = useHoverTooltip()
const [targetProps, tooltipProps] = useTooltip()
const [
showRestoreValuesTooltip,
setShowRestoreValuesTooltip,
] = React.useState<boolean>(false)

const { robot, showSlideout, onCloseClick } = props
const { name } = robot
Expand All @@ -93,6 +99,7 @@ export function ChooseProtocolSlideoutComponent(
] = React.useState<RunTimeParameter[]>([])
const [currentPage, setCurrentPage] = React.useState<number>(1)
const [hasParamError, setHasParamError] = React.useState<boolean>(false)
const [isInputFocused, setIsInputFocused] = React.useState<boolean>(false)

React.useEffect(() => {
setRunTimeParametersOverrides(
Expand Down Expand Up @@ -229,7 +236,7 @@ export function ChooseProtocolSlideoutComponent(
const value = runtimeParam.value as number
const id = `InputField_${runtimeParam.variableName}_${index.toString()}`
const error =
Number.isNaN(value) ||
(Number.isNaN(value) && !isInputFocused) ||
value < runtimeParam.min ||
value > runtimeParam.max
? t(`protocol_details:value_out_of_range`, {
Expand Down Expand Up @@ -258,6 +265,8 @@ export function ChooseProtocolSlideoutComponent(
caption={`${runtimeParam.min}-${runtimeParam.max}`}
id={id}
error={error}
onBlur={() => setIsInputFocused(false)}
onFocus={() => setIsInputFocused(true)}
onChange={e => {
const clone = runTimeParametersOverrides.map((parameter, i) => {
if (i === index) {
Expand Down Expand Up @@ -341,24 +350,42 @@ export function ChooseProtocolSlideoutComponent(
}

const pageTwoBody = (
<Flex flexDirection={DIRECTION_COLUMN}>
<Flex flexDirection={DIRECTION_COLUMN} gridGap={SPACING.spacing10}>
<Flex justifyContent={JUSTIFY_END}>
<LinkComponent
textAlign={TYPOGRAPHY.textAlignRight}
css={
isRestoreDefaultsLinkEnabled ? ENABLED_LINK_CSS : DISABLED_LINK_CSS
}
onClick={resetRunTimeParameters}
onClick={() => {
if (isRestoreDefaultsLinkEnabled) {
resetRunTimeParameters?.()
} else {
setShowRestoreValuesTooltip(true)
setTimeout(
() => setShowRestoreValuesTooltip(false),
TOOLTIP_DELAY_MS
)
}
}}
paddingBottom={SPACING.spacing10}
{...targetProps}
>
{t('protocol_details:restore_defaults')}
</LinkComponent>
{!isRestoreDefaultsLinkEnabled && (
<Tooltip tooltipProps={tooltipProps}>
{t('protocol_details:no_custom_values')}
</Tooltip>
)}
<Tooltip
tooltipProps={{
...tooltipProps,
visible: showRestoreValuesTooltip,
}}
css={css`
&:hover {
cursor: auto;
}
`}
>
{t('protocol_details:no_custom_values')}
</Tooltip>{' '}
</Flex>
<Flex flexDirection={DIRECTION_COLUMN} gridGap={SPACING.spacing16}>
{runTimeParametersInputs}
Expand Down Expand Up @@ -525,7 +552,11 @@ function StoredProtocolList(props: StoredProtocolListProps): JSX.Element {
isWarning={missingAnalysisData}
onClick={() => handleSelectProtocol(storedProtocol)}
>
<Box display="grid" gridTemplateColumns="1fr 3fr">
<Box
display="grid"
gridTemplateColumns="1fr 3fr"
marginRight={SPACING.spacing16}
>
{!missingAnalysisData ? (
<Box
marginY={SPACING.spacingAuto}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -310,4 +310,22 @@ describe('ChooseRobotSlideout', () => {
})
expect(mockSetSelectedRobot).toBeCalledWith(null)
})

it('shows tooltip when disabled Restore default values link is clicked', () => {
render({
onCloseClick: vi.fn(),
isExpanded: true,
isSelectedRobotOnDifferentSoftwareVersion: false,
selectedRobot: null,
setSelectedRobot: mockSetSelectedRobot,
title: 'choose robot slideout title',
robotType: OT2_ROBOT_TYPE,
multiSlideout: { currentPage: 2 },
runTimeParametersOverrides: mockRunTimeParameters,
})

const restoreValuesLink = screen.getByText('Restore default values')
fireEvent.click(restoreValuesLink)
screen.getByText('No custom values specified')
})
})
47 changes: 37 additions & 10 deletions app/src/organisms/ChooseRobotSlideout/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import {
SPACING,
StyledText,
TYPOGRAPHY,
useHoverTooltip,
useTooltip,
} from '@opentrons/components'

import { FLEX_ROBOT_TYPE, OT2_ROBOT_TYPE } from '@opentrons/shared-data'
Expand Down Expand Up @@ -63,6 +63,8 @@ export const CARD_OUTLINE_BORDER_STYLE = css`
}
`

const TOOLTIP_DELAY_MS = 2000

interface RobotIsBusyAction {
type: 'robotIsBusy'
robotName: string
Expand Down Expand Up @@ -145,7 +147,12 @@ export function ChooseRobotSlideout(

const dispatch = useDispatch<Dispatch>()
const isScanning = useSelector((state: State) => getScanning(state))
const [targetProps, tooltipProps] = useHoverTooltip()
const [targetProps, tooltipProps] = useTooltip()
const [
showRestoreValuesTooltip,
setShowRestoreValuesTooltip,
] = React.useState<boolean>(false)
const [isInputFocused, setIsInputFocused] = React.useState<boolean>(false)

const unhealthyReachableRobots = useSelector((state: State) =>
getReachableRobots(state)
Expand Down Expand Up @@ -383,7 +390,7 @@ export function ChooseRobotSlideout(
const value = runtimeParam.value as number
const id = `InputField_${runtimeParam.variableName}_${index.toString()}`
const error =
Number.isNaN(value) ||
(Number.isNaN(value) && !isInputFocused) ||
value < runtimeParam.min ||
value > runtimeParam.max
? t(`value_out_of_range`, {
Expand Down Expand Up @@ -418,6 +425,8 @@ export function ChooseRobotSlideout(
}
id={id}
error={error}
onBlur={() => setIsInputFocused(false)}
onFocus={() => setIsInputFocused(true)}
onChange={e => {
const clone = runTimeParametersOverrides.map((parameter, i) => {
if (i === index) {
Expand Down Expand Up @@ -500,7 +509,7 @@ export function ChooseRobotSlideout(

const pageTwoBody =
runTimeParametersOverrides != null ? (
<Flex flexDirection={DIRECTION_COLUMN}>
<Flex flexDirection={DIRECTION_COLUMN} gridGap={SPACING.spacing10}>
<Flex justifyContent={JUSTIFY_END}>
<Link
textAlign={TYPOGRAPHY.textAlignRight}
Expand All @@ -509,17 +518,35 @@ export function ChooseRobotSlideout(
? ENABLED_LINK_CSS
: DISABLED_LINK_CSS
}
onClick={() => resetRunTimeParameters?.()}
onClick={() => {
if (isRestoreDefaultsLinkEnabled) {
resetRunTimeParameters?.()
} else {
setShowRestoreValuesTooltip(true)
setTimeout(
() => setShowRestoreValuesTooltip(false),
TOOLTIP_DELAY_MS
)
}
}}
paddingBottom={SPACING.spacing10}
{...targetProps}
>
{t('restore_defaults')}
</Link>
{!isRestoreDefaultsLinkEnabled && (
<Tooltip tooltipProps={tooltipProps}>
{t('no_custom_values')}
</Tooltip>
)}
<Tooltip
tooltipProps={{
...tooltipProps,
visible: showRestoreValuesTooltip,
}}
css={css`
&:hover {
cursor: auto;
}
`}
>
{t('no_custom_values')}
</Tooltip>
</Flex>
<Flex flexDirection={DIRECTION_COLUMN} gridGap={SPACING.spacing16}>
{runTimeParameters}
Expand Down
Loading
Loading