Skip to content

Commit

Permalink
Merge branch 'chore_release-8.0.0' of https://github.com/Opentrons/op…
Browse files Browse the repository at this point in the history
…entrons into csv_param_improvements
  • Loading branch information
jbleon95 committed Aug 6, 2024
2 parents 322ac26 + cfaffe4 commit 7621b9e
Show file tree
Hide file tree
Showing 40 changed files with 1,078 additions and 411 deletions.
11 changes: 10 additions & 1 deletion api/src/opentrons/protocol_engine/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,15 @@
CommandType,
CommandIntent,
)
from .state import State, StateView, StateSummary, CommandSlice, CommandPointer, Config
from .state import (
State,
StateView,
StateSummary,
CommandSlice,
CommandPointer,
Config,
CommandErrorSlice,
)
from .plugins import AbstractPlugin

from .types import (
Expand Down Expand Up @@ -81,6 +89,7 @@
"State",
"StateView",
"CommandSlice",
"CommandErrorSlice",
"CommandPointer",
# public value interfaces and models
"LabwareOffset",
Expand Down
2 changes: 2 additions & 0 deletions api/src/opentrons/protocol_engine/state/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
CommandState,
CommandView,
CommandSlice,
CommandErrorSlice,
CommandPointer,
)
from .command_history import CommandEntry
Expand Down Expand Up @@ -39,6 +40,7 @@
"CommandState",
"CommandView",
"CommandSlice",
"CommandErrorSlice",
"CommandPointer",
"CommandEntry",
# labware state and values
Expand Down
29 changes: 29 additions & 0 deletions api/src/opentrons/protocol_engine/state/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,15 @@ class CommandSlice:
total_length: int


@dataclass(frozen=True)
class CommandErrorSlice:
"""A subset of all commands errors in state."""

commands_errors: List[ErrorOccurrence]
cursor: int
total_length: int


@dataclass(frozen=True)
class CommandPointer:
"""Brief info about a command and where to find it."""
Expand Down Expand Up @@ -619,6 +628,26 @@ def get_slice(
total_length=total_length,
)

def get_errors_slice(
self,
cursor: int,
length: int,
) -> CommandErrorSlice:
"""Get a subset of commands error around a given cursor."""
# start is inclusive, stop is exclusive
all_errors = self.get_all_errors()
total_length = len(all_errors)
actual_cursor = max(0, min(cursor, total_length - 1))
stop = min(total_length, actual_cursor + length)

sliced_errors = all_errors[actual_cursor:stop]

return CommandErrorSlice(
commands_errors=sliced_errors,
cursor=actual_cursor,
total_length=total_length,
)

def get_error(self) -> Optional[ErrorOccurrence]:
"""Get the run's fatal error, if there was one."""
run_error = self._state.run_error
Expand Down
23 changes: 23 additions & 0 deletions api/src/opentrons/protocol_runner/run_orchestrator.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@
StateSummary,
CommandPointer,
CommandSlice,
CommandErrorSlice,
DeckType,
ErrorOccurrence,
)
from ..protocol_engine.errors import RunStoppedError
from ..protocol_engine.types import (
Expand Down Expand Up @@ -269,6 +271,23 @@ def get_command_slice(
cursor=cursor, length=length
)

def get_command_error_slice(
self,
cursor: int,
length: int,
) -> CommandErrorSlice:
"""Get a slice of run commands errors.
Args:
cursor: Requested index of first error in the returned slice.
If the cursor is omitted, a cursor will be selected automatically
based on the last error occurence.
length: Length of slice to return.
"""
return self._protocol_engine.state_view.commands.get_errors_slice(
cursor=cursor, length=length
)

def get_command_recovery_target(self) -> Optional[CommandPointer]:
"""Get the current error recovery target."""
return self._protocol_engine.state_view.commands.get_recovery_target()
Expand All @@ -281,6 +300,10 @@ def get_all_commands(self) -> List[Command]:
"""Get all run commands."""
return self._protocol_engine.state_view.commands.get_all()

def get_command_errors(self) -> List[ErrorOccurrence]:
"""Get all run command errors."""
return self._protocol_engine.state_view.commands.get_all_errors()

def get_run_status(self) -> EngineStatus:
"""Get the current execution status of the engine."""
return self._protocol_engine.state_view.commands.get_status()
Expand Down
46 changes: 30 additions & 16 deletions api/tests/opentrons/protocol_engine/state/test_command_view_old.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
CommandState,
CommandView,
CommandSlice,
CommandErrorSlice,
CommandPointer,
RunResult,
QueueStatus,
Expand Down Expand Up @@ -903,7 +904,7 @@ def test_get_current() -> None:
def test_get_slice_empty() -> None:
"""It should return a slice from the tail if no current command."""
subject = get_command_view(commands=[])
result = subject.get_slice(cursor=None, length=2)
result = subject.get_slice(cursor=0, length=2)

assert result == CommandSlice(commands=[], cursor=0, total_length=0)

Expand Down Expand Up @@ -1005,24 +1006,37 @@ def test_get_slice_default_cursor_running() -> None:
)


def test_get_slice_default_cursor_queued() -> None:
"""It should select a cursor automatically."""
command_1 = create_succeeded_command(command_id="command-id-1")
command_2 = create_succeeded_command(command_id="command-id-2")
command_3 = create_succeeded_command(command_id="command-id-3")
command_4 = create_queued_command(command_id="command-id-4")
command_5 = create_queued_command(command_id="command-id-5")
def test_get_errors_slice_empty() -> None:
"""It should return a slice from the tail if no current command."""
subject = get_command_view(failed_command_errors=[])
result = subject.get_errors_slice(cursor=0, length=2)

assert result == CommandErrorSlice(commands_errors=[], cursor=0, total_length=0)


def test_get_errors_slice() -> None:
"""It should return a slice of all command errors."""
error_1 = ErrorOccurrence.construct(id="error-id-1") # type: ignore[call-arg]
error_2 = ErrorOccurrence.construct(id="error-id-2") # type: ignore[call-arg]
error_3 = ErrorOccurrence.construct(id="error-id-3") # type: ignore[call-arg]
error_4 = ErrorOccurrence.construct(id="error-id-4") # type: ignore[call-arg]

subject = get_command_view(
commands=[command_1, command_2, command_3, command_4, command_5],
running_command_id=None,
queued_command_ids=[command_4.id, command_5.id],
failed_command_errors=[error_1, error_2, error_3, error_4]
)

result = subject.get_slice(cursor=None, length=2)
result = subject.get_errors_slice(cursor=1, length=3)

assert result == CommandSlice(
commands=[command_3, command_4],
cursor=2,
total_length=5,
assert result == CommandErrorSlice(
commands_errors=[error_2, error_3, error_4],
cursor=1,
total_length=4,
)

result = subject.get_errors_slice(cursor=-3, length=10)

assert result == CommandErrorSlice(
commands_errors=[error_1, error_2, error_3, error_4],
cursor=0,
total_length=4,
)
4 changes: 2 additions & 2 deletions app/src/assets/localization/en/drop_tip_wizard.json
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
{
"before_you_begin_do_you_want_to_blowout": "Before you begin, do you need to preserve aspirated liquid?",
"begin_removal": "Begin removal",
"blowout_complete": "blowout complete",
"blowout_complete": "Blowout complete",
"blowout_liquid": "Blow out liquid",
"cant_safely_drop_tips": "Can't safely drop tips",
"choose_blowout_location": "choose blowout location",
"choose_drop_tip_location": "choose tip-drop location",
"confirm_blowout_location": "Is the pipette positioned where the liquids should be blown out?",
"confirm_drop_tip_location": "Is the pipette positioned where the tips should be dropped?",
"confirm_removal_and_home": "Confirm removal and home",
"drop_tip_complete": "tip drop complete",
"drop_tip_complete": "Tip drop complete",
"drop_tip_failed": "The drop tip could not be completed. Contact customer support for assistance.",
"drop_tips": "drop tips",
"error_dropping_tips": "Error dropping tips",
Expand Down
38 changes: 14 additions & 24 deletions app/src/atoms/buttons/FloatingActionButton.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import * as React from 'react'
import { useTranslation } from 'react-i18next'
import { css } from 'styled-components'

import {
Expand All @@ -12,29 +11,21 @@ import {
Icon,
POSITION_FIXED,
SPACING,
LegacyStyledText,
TYPOGRAPHY,
StyledText,
} from '@opentrons/components'

import type { IconName, StyleProps } from '@opentrons/components'
import type { IconName } from '@opentrons/components'

interface FloatingActionButtonProps extends StyleProps {
buttonText?: React.ReactNode
interface FloatingActionButtonProps extends React.ComponentProps<typeof Btn> {
buttonText: string
disabled?: boolean
iconName?: IconName
onClick: React.MouseEventHandler
}

export function FloatingActionButton(
props: FloatingActionButtonProps
): JSX.Element {
const { t } = useTranslation('protocol_setup')
const {
buttonText = t('map_view'),
disabled = false,
iconName = 'deck-map',
...buttonProps
} = props
const { buttonText, disabled = false, iconName, ...buttonProps } = props

const contentColor = disabled ? COLORS.grey50 : COLORS.white
const FLOATING_ACTION_BUTTON_STYLE = css`
Expand Down Expand Up @@ -65,9 +56,6 @@ export function FloatingActionButton(
bottom={SPACING.spacing24}
css={FLOATING_ACTION_BUTTON_STYLE}
disabled={disabled}
fontSize={TYPOGRAPHY.fontSize28}
fontWeight={TYPOGRAPHY.fontWeightSemiBold}
lineHeight={TYPOGRAPHY.lineHeight36}
padding={`${SPACING.spacing12} ${SPACING.spacing24}`}
position={POSITION_FIXED}
right={SPACING.spacing24}
Expand All @@ -78,13 +66,15 @@ export function FloatingActionButton(
flexDirection={DIRECTION_ROW}
gridGap={SPACING.spacing8}
>
<Icon
color={contentColor}
height="3rem"
name={iconName}
width="3.75rem"
/>
<LegacyStyledText>{buttonText}</LegacyStyledText>
{iconName != null ? (
<Icon
color={contentColor}
height="3rem"
name={iconName}
width="3.75rem"
/>
) : null}
<StyledText oddStyle="level4HeaderSemiBold">{buttonText}</StyledText>
</Flex>
</Btn>
)
Expand Down
2 changes: 1 addition & 1 deletion app/src/atoms/buttons/RadioButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ export function RadioButton(props: RadioButtonProps): JSX.Element {
/>
<SettingButtonLabel role="label" htmlFor={id}>
<StyledText
oddStyle={isLarge ? 'level4HeaderRegular' : 'bodyTextRegular'}
oddStyle={isLarge ? 'level4HeaderSemiBold' : 'bodyTextRegular'}
desktopStyle="bodyDefaultRegular"
>
{buttonLabel}
Expand Down
3 changes: 0 additions & 3 deletions app/src/atoms/buttons/__tests__/FloatingActionButton.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,6 @@ describe('FloatingActionButton', () => {
`padding: ${SPACING.spacing12} ${SPACING.spacing24}`
)
expect(button).toHaveStyle(`background-color: ${COLORS.purple50}`)
expect(button).toHaveStyle(`font-size: ${TYPOGRAPHY.fontSize28}`)
expect(button).toHaveStyle(`font-weight: ${TYPOGRAPHY.fontWeightSemiBold}`)
expect(button).toHaveStyle(`line-height: ${TYPOGRAPHY.lineHeight36}`)
expect(button).toHaveStyle(`border-radius: ${BORDERS.borderRadius40}`)
expect(button).toHaveStyle(
`text-transform: ${TYPOGRAPHY.textTransformNone}`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -141,8 +141,8 @@ export function SimpleWizardBodyContent(props: Props): JSX.Element {
<>
{isSuccess ? (
<img
width={robotType === FLEX_ROBOT_TYPE ? '170px' : '160px'}
height={robotType === FLEX_ROBOT_TYPE ? '141px' : '120px'}
width={robotType === FLEX_ROBOT_TYPE ? '250px' : '160px'}
height={robotType === FLEX_ROBOT_TYPE ? '208px' : '120px'}
src={SuccessIcon}
alt="Success Icon"
/>
Expand Down
Loading

0 comments on commit 7621b9e

Please sign in to comment.