@@ -40,7 +40,7 @@ export const NullDeckState = (): JSX.Element => {
fontWeight={FONT_WEIGHT_BOLD}
fontSize={FONT_SIZE_BODY_1}
>
- {i18n.t('deck.inactive_deck')}
+ {t('inactive_deck')}
)}
diff --git a/protocol-designer/src/components/DeckSetup/SlotWarning.tsx b/protocol-designer/src/components/DeckSetup/SlotWarning.tsx
index d5f33242a6f..dac3928bbc1 100644
--- a/protocol-designer/src/components/DeckSetup/SlotWarning.tsx
+++ b/protocol-designer/src/components/DeckSetup/SlotWarning.tsx
@@ -1,6 +1,6 @@
import * as React from 'react'
+import { useTranslation } from 'react-i18next'
import styled from 'styled-components'
-import { i18n } from '../../localization'
import { RobotCoordsForeignDiv, TYPOGRAPHY } from '@opentrons/components'
import type { ModuleOrientation } from '@opentrons/shared-data'
@@ -27,7 +27,7 @@ export const SlotWarning = (props: Props): JSX.Element => {
const { x, y, xDimension, yDimension, orientation, warningType } = props
const rectXOffset = orientation === 'left' ? -OVERHANG : 0
const textXOffset = orientation === 'left' ? -1 * OVERHANG : xDimension
-
+ const { t } = useTranslation('deck')
return (
{
width={OVERHANG}
height={yDimension}
>
- {i18n.t(`deck.warning.${warningType}`)}
+ {t(`warning.${warningType}`)}
)
diff --git a/protocol-designer/src/components/FileSidebar/FileSidebar.tsx b/protocol-designer/src/components/FileSidebar/FileSidebar.tsx
index 60962e682e0..2f7076896f1 100644
--- a/protocol-designer/src/components/FileSidebar/FileSidebar.tsx
+++ b/protocol-designer/src/components/FileSidebar/FileSidebar.tsx
@@ -7,7 +7,6 @@ import {
OutlineButton,
SidePanel,
} from '@opentrons/components'
-import { i18n } from '../../localization'
import { resetScrollElements } from '../../ui/steps/utils'
import { Portal } from '../portals/MainPageModalPortal'
import { useBlockingHint } from '../Hints/useBlockingHint'
@@ -86,18 +85,20 @@ function getWarningContent({
gripperWithoutStep,
fixtureWithoutStep,
}: MissingContent): WarningContent | null {
+ const { t } = useTranslation(['alert', 'modules'])
+
if (noCommands) {
return {
content: (
<>
-
{i18n.t('alert.export_warnings.no_commands.body1')}
+
{t('export_warnings.no_commands.body1')}
- {i18n.t('alert.export_warnings.no_commands.body2')}
+ {t('export_warnings.no_commands.body2')}
here .
>
),
- heading: i18n.t('alert.export_warnings.no_commands.heading'),
+ heading: t('export_warnings.no_commands.heading'),
}
}
@@ -105,11 +106,11 @@ function getWarningContent({
return {
content: (
<>
-
{i18n.t('alert.export_warnings.unused_gripper.body1')}
-
{i18n.t('alert.export_warnings.unused_gripper.body2')}
+
{t('export_warnings.unused_gripper.body1')}
+
{t('export_warnings.unused_gripper.body2')}
>
),
- heading: i18n.t('alert.export_warnings.unused_gripper.heading'),
+ heading: t('export_warnings.unused_gripper.heading'),
}
}
@@ -117,9 +118,7 @@ function getWarningContent({
.map(pipette => `${pipette.mount} ${pipette.spec.displayName}`)
.join(' and ')
const modulesDetails = modulesWithoutStep
- .map(moduleOnDeck =>
- i18n.t(`modules.module_long_names.${moduleOnDeck.type}`)
- )
+ .map(moduleOnDeck => t(`modules:module_long_names.${moduleOnDeck.type}`))
.join(' and ')
if (pipettesWithoutStep.length && modulesWithoutStep.length) {
@@ -127,19 +126,15 @@ function getWarningContent({
content: (
<>
- {i18n.t('alert.export_warnings.unused_pipette_and_module.body1', {
+ {t('export_warnings.unused_pipette_and_module.body1', {
modulesDetails,
pipettesDetails,
})}
-
- {i18n.t('alert.export_warnings.unused_pipette_and_module.body2')}
-
+
{t('export_warnings.unused_pipette_and_module.body2')}
>
),
- heading: i18n.t(
- 'alert.export_warnings.unused_pipette_and_module.heading'
- ),
+ heading: t('export_warnings.unused_pipette_and_module.heading'),
}
}
@@ -148,14 +143,14 @@ function getWarningContent({
content: (
<>
- {i18n.t('alert.export_warnings.unused_pipette.body1', {
+ {t('export_warnings.unused_pipette.body1', {
pipettesDetails,
})}
-
{i18n.t('alert.export_warnings.unused_pipette.body2')}
+
{t('export_warnings.unused_pipette.body2')}
>
),
- heading: i18n.t('alert.export_warnings.unused_pipette.heading'),
+ heading: t('export_warnings.unused_pipette.heading'),
}
}
@@ -166,14 +161,14 @@ function getWarningContent({
content: (
<>
- {i18n.t(`alert.export_warnings.${moduleCase}.body1`, {
+ {t(`export_warnings.${moduleCase}.body1`, {
modulesDetails,
})}
-
{i18n.t(`alert.export_warnings.${moduleCase}.body2`)}
+
{t(`export_warnings.${moduleCase}.body2`)}
>
),
- heading: i18n.t(`alert.export_warnings.${moduleCase}.heading`),
+ heading: t(`export_warnings.${moduleCase}.heading`),
}
}
@@ -183,19 +178,19 @@ function getWarningContent({
(fixtureWithoutStep.trashBin && !fixtureWithoutStep.wasteChute) ||
(!fixtureWithoutStep.trashBin && fixtureWithoutStep.wasteChute) ? (
- {i18n.t('alert.export_warnings.unused_trash.body', {
+ {t('export_warnings.unused_trash.body', {
name: fixtureWithoutStep.trashBin ? 'trash bin' : 'waste chute',
})}
) : (
- {i18n.t('alert.export_warnings.unused_trash.body_both', {
+ {t('export_warnings.unused_trash.body_both', {
trashName: 'trash bin',
wasteName: 'waste chute',
})}
),
- heading: i18n.t('alert.export_warnings.unused_trash.heading'),
+ heading: t('export_warnings.unused_trash.heading'),
}
}
@@ -204,19 +199,19 @@ function getWarningContent({
content: (
<>
- {i18n.t('alert.export_warnings.unused_staging_area.body1', {
+ {t('export_warnings.unused_staging_area.body1', {
count: fixtureWithoutStep.stagingAreaSlots.length,
slot: fixtureWithoutStep.stagingAreaSlots,
})}
- {i18n.t('alert.export_warnings.unused_staging_area.body2', {
+ {t('export_warnings.unused_staging_area.body2', {
count: fixtureWithoutStep.stagingAreaSlots.length,
})}
>
),
- heading: i18n.t('alert.export_warnings.unused_staging_area.heading'),
+ heading: t('export_warnings.unused_staging_area.heading'),
}
}
diff --git a/protocol-designer/src/components/FileSidebar/index.ts b/protocol-designer/src/components/FileSidebar/index.ts
index c640b4a78c9..c27fc8a2fb8 100644
--- a/protocol-designer/src/components/FileSidebar/index.ts
+++ b/protocol-designer/src/components/FileSidebar/index.ts
@@ -1,5 +1,5 @@
import { connect } from 'react-redux'
-import { i18n } from '../../localization'
+import { useTranslation } from 'react-i18next'
import { actions, selectors } from '../../navigation'
import { selectors as fileDataSelectors } from '../../file-data'
import { selectors as stepFormSelectors } from '../../step-forms'
@@ -41,6 +41,7 @@ function mapStateToProps(state: BaseState): SP {
const initialDeckSetup = stepFormSelectors.getInitialDeckSetup(state)
const robotType = getRobotType(state)
const additionalEquipment = getAdditionalEquipment(state)
+ const { t } = useTranslation('alert')
return {
canDownload,
@@ -76,10 +77,7 @@ function mergeProps(
const { dispatch } = dispatchProps
return {
loadFile: fileChangeEvent => {
- if (
- !_hasUnsavedChanges ||
- window.confirm(i18n.t('alert.window.confirm_import'))
- ) {
+ if (!_hasUnsavedChanges || window.confirm(t('window.confirm_import'))) {
dispatch(loadFileActions.loadProtocolFile(fileChangeEvent))
}
},
diff --git a/protocol-designer/src/components/Hints/index.tsx b/protocol-designer/src/components/Hints/index.tsx
index ff93427d71f..cbf100d3358 100644
--- a/protocol-designer/src/components/Hints/index.tsx
+++ b/protocol-designer/src/components/Hints/index.tsx
@@ -7,7 +7,6 @@ import {
OutlineButton,
Text,
} from '@opentrons/components'
-import { i18n } from '../../localization'
import { actions as stepsActions } from '../../ui/steps'
import { TerminalItemId } from '../../steplist'
import { actions, selectors, HintKey } from '../../tutorial'
@@ -17,8 +16,10 @@ import EXAMPLE_ADD_LIQUIDS_IMAGE from '../../images/example_add_liquids.png'
import EXAMPLE_WATCH_LIQUIDS_MOVE_IMAGE from '../../images/example_watch_liquids_move.png'
import EXAMPLE_BATCH_EDIT_IMAGE from '../../images/announcements/multi_select.gif'
import { BaseState, ThunkDispatch } from '../../types'
+import { useTranslation } from 'react-i18next'
interface SP {
+ t: any
hintKey?: HintKey | null
}
interface DP {
@@ -58,8 +59,10 @@ class HintsComponent extends React.Component
{
return (
<>
- {i18n.t('alert.hint.add_liquids_and_labware.summary', {
- deck_setup_step: i18n.t('nav.terminal_item.__initial_setup__'),
+ {this.props.t('hint.add_liquids_and_labware.summary', {
+ deck_setup_step: this.props.t(
+ 'nav:terminal_item.__initial_setup__'
+ ),
})}
@@ -67,7 +70,7 @@ class HintsComponent extends React.Component {
Step 1:
- {i18n.t('alert.hint.add_liquids_and_labware.step1')}
+ {this.props.t('hint.add_liquids_and_labware.step1')}
@@ -77,7 +80,7 @@ class HintsComponent extends React.Component {
Step 2:
- {i18n.t('alert.hint.add_liquids_and_labware.step2')}
+ {this.props.t('hint.add_liquids_and_labware.step2')}
@@ -87,31 +90,33 @@ class HintsComponent extends React.Component {
case 'deck_setup_explanation':
return (
<>
- {i18n.t(`alert.hint.${hintKey}.body1`)}
- {i18n.t(`alert.hint.${hintKey}.body2`)}
- {i18n.t(`alert.hint.${hintKey}.body3`)}
+ {this.props.t(`hint.${hintKey}.body1`)}
+ {this.props.t(`hint.${hintKey}.body2`)}
+ {this.props.t(`hint.${hintKey}.body3`)}
>
)
case 'module_without_labware':
return (
<>
- {i18n.t(`alert.hint.${hintKey}.body`)}
+ {this.props.t(`alert:hint.${hintKey}.body`)}
>
)
case 'thermocycler_lid_passive_cooling':
return (
<>
- {i18n.t(`alert.hint.${hintKey}.body1a`)}
- {i18n.t(`alert.hint.${hintKey}.strong_body1`)}
- {i18n.t(`alert.hint.${hintKey}.body1b`)}
+ {this.props.t(`alert:hint.${hintKey}.body1a`)}
+
+ {this.props.t(`alert:hint.${hintKey}.strong_body1`)}
+
+ {this.props.t(`alert:hint.${hintKey}.body1b`)}
- {i18n.t(`alert.hint.${hintKey}.li1`)}
+ {this.props.t(`alert:hint.${hintKey}.li1`)}
- {i18n.t(`alert.hint.${hintKey}.li2`)}
+ {this.props.t(`alert:hint.${hintKey}.li2`)}
>
@@ -123,33 +128,33 @@ class HintsComponent extends React.Component {
- {i18n.t(`alert.hint.${hintKey}.body1`)}
+ {this.props.t(`alert:hint.${hintKey}.body1`)}
- {i18n.t(`alert.hint.${hintKey}.body2`)}
+ {this.props.t(`alert:hint.${hintKey}.body2`)}
- {i18n.t(`alert.hint.${hintKey}.li1a`)}
+ {this.props.t(`alert:hint.${hintKey}.li1a`)}
- {i18n.t(`alert.hint.${hintKey}.strong_li1`)}
+ {this.props.t(`alert:hint.${hintKey}.strong_li1`)}
- {i18n.t(`alert.hint.${hintKey}.li1b`)}
+ {this.props.t(`alert:hint.${hintKey}.li1b`)}
- {i18n.t(`alert.hint.${hintKey}.li2a`)}
+ {this.props.t(`alert:hint.${hintKey}.li2a`)}
- {i18n.t(`alert.hint.${hintKey}.strong_li2`)}
+ {this.props.t(`alert:hint.${hintKey}.strong_li2`)}
- {i18n.t(`alert.hint.${hintKey}.li2b`)}
+ {this.props.t(`alert:hint.${hintKey}.li2b`)}
- {i18n.t(`alert.hint.${hintKey}.body3a`)}
- {i18n.t(`alert.hint.${hintKey}.body3b`)}
+ {this.props.t(`alert:hint.${hintKey}.body3a`)}
+ {this.props.t(`alert:hint.${hintKey}.body3b`)}
- {i18n.t(`alert.hint.${hintKey}.body4a`)}
- {i18n.t(`alert.hint.${hintKey}.body4b`)}
+ {this.props.t(`alert:hint.${hintKey}.body4a`)}
+ {this.props.t(`alert:hint.${hintKey}.body4b`)}
>
@@ -157,7 +162,7 @@ class HintsComponent extends React.Component {
case 'waste_chute_warning':
return (
- {i18n.t(`alert.hint.${hintKey}.body1`)}
+ {this.props.t(`hint.${hintKey}.body1`)}
)
default:
@@ -169,7 +174,7 @@ class HintsComponent extends React.Component {
const { hintKey } = this.props
if (!hintKey) return null
- const headingText = i18n.t(`alert.hint.${hintKey}.title`)
+ const headingText = this.props.t(`hint.${hintKey}.title`)
const hintIsAlert = HINT_IS_ALERT.includes(hintKey)
return (
@@ -183,7 +188,7 @@ class HintsComponent extends React.Component {
@@ -191,7 +196,7 @@ class HintsComponent extends React.Component
{
className={styles.ok_button}
onClick={this.makeHandleCloseClick(hintKey)}
>
- {i18n.t('button.ok')}
+ {this.props.t('button:ok')}
@@ -200,9 +205,13 @@ class HintsComponent extends React.Component {
}
}
-const mapStateToProps = (state: BaseState): SP => ({
- hintKey: selectors.getHint(state),
-})
+const mapStateToProps = (state: BaseState): SP => {
+ const { t } = useTranslation(['alert', 'nav', 'button'])
+ return {
+ hintKey: selectors.getHint(state),
+ t: t,
+ }
+}
const mapDispatchToProps = (dispatch: ThunkDispatch): DP => ({
removeHint: (hintKey, rememberDismissal) =>
dispatch(actions.removeHint(hintKey, rememberDismissal)),
diff --git a/protocol-designer/src/components/Hints/useBlockingHint.tsx b/protocol-designer/src/components/Hints/useBlockingHint.tsx
index 036328914e2..5301f27f92c 100644
--- a/protocol-designer/src/components/Hints/useBlockingHint.tsx
+++ b/protocol-designer/src/components/Hints/useBlockingHint.tsx
@@ -2,11 +2,11 @@
// Instances of BlockingHint need to be individually placed by whatever component
// is controlling the flow that this modal will block, via useBlockingHint.
import * as React from 'react'
+import { useTranslation } from 'react-i18next'
import { useDispatch, useSelector } from 'react-redux'
import { actions, selectors, HintKey } from '../../tutorial'
import { ContinueModal, DeprecatedCheckboxField } from '@opentrons/components'
import { Portal } from '../portals/MainPageModalPortal'
-import { i18n } from '../../localization'
import styles from './hints.css'
export interface HintProps {
@@ -18,6 +18,7 @@ export interface HintProps {
// This component handles the checkbox and dispatching `removeHint` action on continue/cancel
export const BlockingHint = (props: HintProps): JSX.Element => {
+ const { t } = useTranslation('alert')
const { hintKey, handleCancel, handleContinue } = props
const dispatch = useDispatch()
@@ -43,7 +44,7 @@ export const BlockingHint = (props: HintProps): JSX.Element => {
@@ -51,7 +52,7 @@ export const BlockingHint = (props: HintProps): JSX.Element => {
diff --git a/protocol-designer/src/components/IngredientsList/LabwareDetailsCard/LabwareDetailsCard.tsx b/protocol-designer/src/components/IngredientsList/LabwareDetailsCard/LabwareDetailsCard.tsx
index e6a473db3c4..f71634702c8 100644
--- a/protocol-designer/src/components/IngredientsList/LabwareDetailsCard/LabwareDetailsCard.tsx
+++ b/protocol-designer/src/components/IngredientsList/LabwareDetailsCard/LabwareDetailsCard.tsx
@@ -1,6 +1,6 @@
import * as React from 'react'
+import { useTranslation } from 'react-i18next'
import cx from 'classnames'
-import { i18n } from '../../../localization'
import { PDTitledList, PDListItem } from '../../lists'
import { EditableTextField } from '../../EditableTextField'
import styles from './labwareDetailsCard.css'
@@ -12,12 +12,13 @@ export interface Props {
}
export function LabwareDetailsCard(props: Props): JSX.Element {
+ const { t } = useTranslation('form')
return (
- {i18n.t('form.generic.labware_type')}
+ {t('generic.labware_type')}
{props.labwareDefDisplayName}
@@ -27,7 +28,7 @@ export function LabwareDetailsCard(props: Props): JSX.Element {
- {i18n.t('form.generic.nickname')}
+ {t('generic.nickname')}
{
groupId,
labwareWellContents,
} = props
-
+ const { t } = useTranslation(['card', 'application'])
const showName = ingredGroup.serialize
const [expanded, setExpanded] = React.useState(true)
@@ -58,7 +58,7 @@ const LiquidGroupCard = (props: LiquidGroupCardProps): JSX.Element | null => {
ingredGroup.name != null ? truncateString(ingredGroup.name, 25) : null
return (
{
description={ }
>
- {i18n.t('card.well')}
- {i18n.t('application.units.microliter')}
- {showName && {i18n.t('card.name')} }
+ {t('well')}
+ {t('application:units.microliter')}
+ {showName && {t('name')} }
@@ -125,13 +125,11 @@ function IngredIndividual(props: IndividProps): JSX.Element {
groupId,
removeWellsContents,
} = props
-
+ const { t } = useTranslation('application')
return (
{wellName}
-
- {volume ? volume + ` ${i18n.t('application.units.microliter')}` : '-'}
-
+ {volume ? volume + ` ${t('units.microliter')}` : '-'}
{name && {name} }
{canDelete && (
+
{Object.keys(liquidGroupsById).map(groupIdForCard => (
diff --git a/protocol-designer/src/components/LabwareSelectionModal/LabwareItem.tsx b/protocol-designer/src/components/LabwareSelectionModal/LabwareItem.tsx
index 593502bc209..47a3a4b82ac 100644
--- a/protocol-designer/src/components/LabwareSelectionModal/LabwareItem.tsx
+++ b/protocol-designer/src/components/LabwareSelectionModal/LabwareItem.tsx
@@ -1,6 +1,6 @@
import * as React from 'react'
+import { useTranslation } from 'react-i18next'
import cx from 'classnames'
-import { i18n } from '../../localization'
import { Icon, IconName } from '@opentrons/components'
import { PDListItem } from '../lists'
import styles from './styles.css'
@@ -31,7 +31,7 @@ export function LabwareItem(props: Props): JSX.Element {
onMouseEnter,
selectLabware,
} = props
-
+ const { t } = useTranslation('modal')
const displayName = getLabwareDisplayName(labwareDef)
const labwareURI = getLabwareDefURI(labwareDef)
const labwareLoadName = labwareDef.parameters.loadName
@@ -61,7 +61,7 @@ export function LabwareItem(props: Props): JSX.Element {
href={`${LABWARE_LIBRARY_PAGE_PATH}/${labwareLoadName}`}
onClick={e => e.stopPropagation()}
>
- {i18n.t('modal.labware_selection.view_measurements')}
+ {t('labware_selection.view_measurements')}
) : null}
diff --git a/protocol-designer/src/components/LabwareSelectionModal/LabwarePreview.tsx b/protocol-designer/src/components/LabwareSelectionModal/LabwarePreview.tsx
index d215fd807c8..2f89d6efde1 100644
--- a/protocol-designer/src/components/LabwareSelectionModal/LabwarePreview.tsx
+++ b/protocol-designer/src/components/LabwareSelectionModal/LabwarePreview.tsx
@@ -1,5 +1,6 @@
import * as React from 'react'
import reduce from 'lodash/reduce'
+import { useTranslation } from 'react-i18next'
import {
Icon,
LabwareRender,
@@ -11,7 +12,6 @@ import {
getLabwareDefIsStandard,
LabwareDefinition2,
} from '@opentrons/shared-data'
-import { i18n } from '../../localization'
import styles from './styles.css'
interface Props {
@@ -25,6 +25,7 @@ interface Props {
export const LabwarePreview = (props: Props): JSX.Element | null => {
const { labwareDef, moduleCompatibility } = props
+ const { t } = useTranslation(['modal', 'application'])
if (!labwareDef) return null
const maxVolumes = reduce(
labwareDef.wells,
@@ -32,7 +33,7 @@ export const LabwarePreview = (props: Props): JSX.Element | null => {
new Set()
)
const formattedVolumes = Array.from(maxVolumes)
- .map(vol => `${vol}${i18n.t('application.units.microliter')}`)
+ .map(vol => `${vol}${t('application:units.microliter')}`)
.join(', ')
// NOTE: this is a temporary magic value that positions the preview component
@@ -51,9 +52,7 @@ export const LabwarePreview = (props: Props): JSX.Element | null => {
{moduleCompatibility === 'recommended' ? (
) : null}
- {i18n.t(
- `modal.labware_selection.module_compatibility.${moduleCompatibility}`
- )}
+ {t(`labware_selection.module_compatibility.${moduleCompatibility}`)}
) : null}
@@ -67,17 +66,17 @@ export const LabwarePreview = (props: Props): JSX.Element | null => {
{getLabwareDefIsStandard(labwareDef) && (
)}
diff --git a/protocol-designer/src/components/LabwareSelectionModal/LabwareSelectionModal.tsx b/protocol-designer/src/components/LabwareSelectionModal/LabwareSelectionModal.tsx
index f886399a9f7..2491108d6e5 100644
--- a/protocol-designer/src/components/LabwareSelectionModal/LabwareSelectionModal.tsx
+++ b/protocol-designer/src/components/LabwareSelectionModal/LabwareSelectionModal.tsx
@@ -1,4 +1,5 @@
import * as React from 'react'
+import { useTranslation } from 'react-i18next'
import startCase from 'lodash/startCase'
import reduce from 'lodash/reduce'
import {
@@ -23,7 +24,6 @@ import {
getModuleType,
THERMOCYCLER_MODULE_V2,
} from '@opentrons/shared-data'
-import { i18n } from '../../localization'
import { SPAN7_8_10_11_SLOT } from '../../constants'
import {
getLabwareIsCompatible as _getLabwareIsCompatible,
@@ -141,6 +141,7 @@ export const LabwareSelectionModal = (props: Props): JSX.Element | null => {
adapterLoadName,
has96Channel,
} = props
+ const { t } = useTranslation(['modules', 'modal', 'button', 'alert'])
const defs = getOnlyLatestDefs()
const moduleType = moduleModel != null ? getModuleType(moduleModel) : null
const URIs = Object.keys(defs)
@@ -160,7 +161,7 @@ export const LabwareSelectionModal = (props: Props): JSX.Element | null => {
const blockingCustomLabwareHint = useBlockingHint({
enabled: enqueuedLabwareType !== null,
hintKey: 'custom_labware_with_modules',
- content:
{i18n.t(`alert.hint.custom_labware_with_modules.body`)}
,
+ content:
{t(`alert:hint.custom_labware_with_modules.body`)}
,
handleCancel: () => setEnqueuedLabwareType(null),
handleContinue: () => {
setEnqueuedLabwareType(null)
@@ -237,8 +238,8 @@ export const LabwareSelectionModal = (props: Props): JSX.Element | null => {
)
const getTitleText = (): string => {
if (isNextToHeaterShaker) {
- return `Slot ${slot}, Labware to the side of ${i18n.t(
- `modules.module_long_names.heaterShakerModuleType`
+ return `Slot ${slot}, Labware to the side of ${t(
+ `module_long_names.heaterShakerModuleType`
)}`
}
if (adapterLoadName != null) {
@@ -249,9 +250,9 @@ export const LabwareSelectionModal = (props: Props): JSX.Element | null => {
return `Labware on top of the ${adapterDisplayName}`
}
if (parentSlot != null && moduleType != null) {
- return `Slot ${
- parentSlot === SPAN7_8_10_11_SLOT ? '7' : parentSlot
- }, ${i18n.t(`modules.module_long_names.${moduleType}`)} Labware`
+ return `Slot ${parentSlot === SPAN7_8_10_11_SLOT ? '7' : parentSlot}, ${t(
+ `module_long_names.${moduleType}`
+ )} Labware`
}
return `Slot ${slot} Labware`
}
@@ -356,10 +357,10 @@ export const LabwareSelectionModal = (props: Props): JSX.Element | null => {
)}
- {i18n.t(
+ {t(
isNextToHeaterShaker
- ? 'modal.labware_selection.heater_shaker_labware_filter'
- : 'modal.labware_selection.recommended_labware_filter'
+ ? 'modal:labware_selection.heater_shaker_labware_filter'
+ : 'modal:labware_selection.recommended_labware_filter'
)}{' '}
{
- {i18n.t('button.upload_custom_labware')}
+ {t('button:upload_custom_labware')}
{
@@ -504,7 +505,7 @@ export const LabwareSelectionModal = (props: Props): JSX.Element | null => {
/>
- {i18n.t('modal.labware_selection.creating_labware_defs')}{' '}
+ {t('modal:labware_selection.creating_labware_defs')}{' '}
{/* TODO: Ian 2019-10-15 use LinkOut component once it's in components library, see Opentrons/opentrons#4229 */}
{
.
-
- {i18n.t('button.close')}
-
+ {t('button:close')}
>
)
diff --git a/protocol-designer/src/components/LiquidPlacementForm/LiquidPlacementForm.tsx b/protocol-designer/src/components/LiquidPlacementForm/LiquidPlacementForm.tsx
index bed3d18a7ec..cb8185efe24 100644
--- a/protocol-designer/src/components/LiquidPlacementForm/LiquidPlacementForm.tsx
+++ b/protocol-designer/src/components/LiquidPlacementForm/LiquidPlacementForm.tsx
@@ -11,7 +11,6 @@ import {
DeprecatedPrimaryButton,
Options,
} from '@opentrons/components'
-import { i18n } from '../../localization'
import styles from './LiquidPlacementForm.css'
import formStyles from '../forms/forms.css'
import stepEditFormStyles from '../StepEditForm/StepEditForm.css'
@@ -32,7 +31,7 @@ export interface Props {
liquidSelectionOptions: Options
selectedWellsMaxVolume: number
showForm: boolean
-
+ t: any
cancelForm: () => unknown
clearWells: (() => unknown | null) | null
saveForm: (liquidPlacementFormValues: LiquidPlacementFormValues) => unknown
@@ -58,21 +57,21 @@ export class LiquidPlacementForm extends React.Component
{
const { selectedWellsMaxVolume } = this.props
return Yup.object().shape({
selectedLiquidId: Yup.string().required(
- i18n.t('form.generic.error.required', {
- name: i18n.t('form.liquid_placement.liquid'),
+ this.props.t('generic.error.required', {
+ name: this.props.t('liquid_placement.liquid'),
})
),
volume: Yup.number()
.nullable()
.required(
- i18n.t('form.generic.error.required', {
- name: i18n.t('form.liquid_placement.volume'),
+ this.props.t('generic.error.required', {
+ name: this.props.t('liquid_placement.volume'),
})
)
- .moreThan(0, i18n.t('form.generic.error.more_than_zero'))
+ .moreThan(0, this.props.t('generic.error.more_than_zero'))
.max(
selectedWellsMaxVolume,
- i18n.t('form.liquid_placement.volume_exceeded', {
+ this.props.t('liquid_placement.volume_exceeded', {
volume: selectedWellsMaxVolume,
})
),
@@ -126,7 +125,7 @@ export class LiquidPlacementForm extends React.Component {
diff --git a/protocol-designer/src/components/LiquidPlacementForm/index.ts b/protocol-designer/src/components/LiquidPlacementForm/index.ts
index a80df26a151..e3d4541510e 100644
--- a/protocol-designer/src/components/LiquidPlacementForm/index.ts
+++ b/protocol-designer/src/components/LiquidPlacementForm/index.ts
@@ -16,6 +16,7 @@ import {
} from './LiquidPlacementForm'
import { Dispatch } from 'redux'
import { BaseState } from '../../types'
+import { useTranslation } from 'react-i18next'
type SP = Omit<
LiquidPlacementFormProps & {
_labwareId?: string | null
@@ -27,7 +28,7 @@ type SP = Omit<
function mapStateToProps(state: BaseState): SP {
const selectedWells = getSelectedWells(state)
-
+ const { t } = useTranslation(['form', 'button', 'application'])
const _labwareId = labwareIngredSelectors.getSelectedLabwareId(state)
const liquidLocations = labwareIngredSelectors.getLiquidsByLabwareId(state)
@@ -55,6 +56,7 @@ function mapStateToProps(state: BaseState): SP {
_labwareId,
_selectedWells: Object.keys(selectedWells),
_selectionHasLiquids,
+ t: t,
}
}
diff --git a/protocol-designer/src/components/LiquidsPage/LiquidEditForm.tsx b/protocol-designer/src/components/LiquidsPage/LiquidEditForm.tsx
index 64318438729..edbb0425f4b 100644
--- a/protocol-designer/src/components/LiquidsPage/LiquidEditForm.tsx
+++ b/protocol-designer/src/components/LiquidsPage/LiquidEditForm.tsx
@@ -1,8 +1,8 @@
import * as React from 'react'
+import { useTranslation } from 'react-i18next'
import { useSelector } from 'react-redux'
import { Field, Formik, FormikProps } from 'formik'
import * as Yup from 'yup'
-import { i18n } from '../../localization'
import { swatchColors } from '../swatchColors'
import {
Card,
@@ -81,7 +81,7 @@ export function LiquidEditForm(props: Props): JSX.Element {
const selectedLiquid = useSelector(selectors.getSelectedLiquidGroupState)
const nextGroupId = useSelector(selectors.getNextLiquidGroupId)
const liquidId = selectedLiquid.liquidGroupId ?? nextGroupId
-
+ const { t } = useTranslation(['form', 'button'])
const initialValues: LiquidEditFormValues = {
name: props.name || '',
displayColor: props.displayColor ?? swatchColors(liquidId),
@@ -118,11 +118,11 @@ export function LiquidEditForm(props: Props): JSX.Element {
diff --git a/protocol-designer/src/components/LiquidsSidebar/index.tsx b/protocol-designer/src/components/LiquidsSidebar/index.tsx
index 83578c4022e..e36022ba3ba 100644
--- a/protocol-designer/src/components/LiquidsSidebar/index.tsx
+++ b/protocol-designer/src/components/LiquidsSidebar/index.tsx
@@ -1,6 +1,6 @@
import * as React from 'react'
+import { useTranslation } from 'react-i18next'
import { connect } from 'react-redux'
-import { i18n } from '../../localization'
import {
DeprecatedPrimaryButton,
SidePanel,
@@ -16,7 +16,6 @@ import * as labwareIngredActions from '../../labware-ingred/actions'
import { BaseState, ThunkDispatch } from '../../types'
import styles from './styles.css'
-
interface SP {
liquids: OrderedLiquids
selectedLiquid?: string | null
@@ -31,6 +30,7 @@ type Props = SP & DP
function LiquidsSidebarComponent(props: Props): JSX.Element {
const { liquids, selectedLiquid, createNewLiquid, selectLiquid } = props
+ const { t } = useTranslation('button')
return (
{liquids.map(({ ingredientId, name, displayColor }) => (
@@ -55,7 +55,7 @@ function LiquidsSidebarComponent(props: Props): JSX.Element {
))}
- {i18n.t('button.new_liquid')}
+ {t('new_liquid')}
diff --git a/protocol-designer/src/components/SettingsPage/FeatureFlagCard/FeatureFlagCard.tsx b/protocol-designer/src/components/SettingsPage/FeatureFlagCard/FeatureFlagCard.tsx
index fab5720c11e..755027ee57e 100644
--- a/protocol-designer/src/components/SettingsPage/FeatureFlagCard/FeatureFlagCard.tsx
+++ b/protocol-designer/src/components/SettingsPage/FeatureFlagCard/FeatureFlagCard.tsx
@@ -1,7 +1,7 @@
-import sortBy from 'lodash/sortBy'
import * as React from 'react'
+import { useTranslation } from 'react-i18next'
+import sortBy from 'lodash/sortBy'
import { ContinueModal, Card, ToggleButton } from '@opentrons/components'
-import { i18n } from '../../../localization'
import { resetScrollElements } from '../../../ui/steps/utils'
import { Portal } from '../../portals/MainPageModalPortal'
import styles from '../SettingsPage.css'
@@ -17,6 +17,7 @@ export const FeatureFlagCard = (props: Props): JSX.Element => {
const [modalFlagName, setModalFlagName] = React.useState(
null
)
+ const { t } = useTranslation(['modal', 'card', 'feature_flags'])
const prereleaseModeEnabled = props.flags.PRERELEASE_MODE === true
@@ -35,20 +36,18 @@ export const FeatureFlagCard = (props: Props): JSX.Element => {
const RICH_DESCRIPTIONS: Partial> = {
OT_PD_ALLOW_ALL_TIPRACKS: (
<>
- {i18n.t(`feature_flags.${flag}.description`)}
+ {t(`feature_flags:${flag}.description`)}
>
),
OT_PD_DISABLE_MODULE_RESTRICTIONS: (
<>
- {i18n.t(`feature_flags.${flag}.description_1`)}
- {i18n.t(`feature_flags.${flag}.description_2`)}
+ {t(`feature_flags:${flag}.description_1`)}
+ {t(`feature_flags:${flag}.description_2`)}
>
),
}
return (
- RICH_DESCRIPTIONS[flag] || (
- {i18n.t(`feature_flags.${flag}.description`)}
- )
+ RICH_DESCRIPTIONS[flag] || {t(`feature_flags:${flag}.description`)}
)
}
@@ -56,7 +55,7 @@ export const FeatureFlagCard = (props: Props): JSX.Element => {
- {i18n.t(`feature_flags.${flagName}.title`)}
+ {t(`feature_flags:${flagName}.title`)}
{
setModalFlagName(null)}
onContinueClick={() => {
@@ -108,25 +107,21 @@ export const FeatureFlagCard = (props: Props): JSX.Element => {
}}
>
- {i18n.t(
- `modal.experimental_feature_warning.${flagSwitchDirection}.body1`
- )}
+ {t(`experimental_feature_warning.${flagSwitchDirection}.body1`)}
- {i18n.t(
- `modal.experimental_feature_warning.${flagSwitchDirection}.body2`
- )}
+ {t(`experimental_feature_warning.${flagSwitchDirection}.body2`)}
)}
-
+
{userFacingFlagRows.length > 0 ? userFacingFlagRows : noFlagsFallback}
{prereleaseModeEnabled && (
-
+
{prereleaseFlagRows}
)}
diff --git a/protocol-designer/src/components/SettingsPage/SettingsApp.tsx b/protocol-designer/src/components/SettingsPage/SettingsApp.tsx
index 0816a5b0832..9f6f03c3253 100644
--- a/protocol-designer/src/components/SettingsPage/SettingsApp.tsx
+++ b/protocol-designer/src/components/SettingsPage/SettingsApp.tsx
@@ -1,6 +1,6 @@
import * as React from 'react'
import { connect } from 'react-redux'
-import { i18n } from '../../localization'
+import { useTranslation } from 'react-i18next'
import {
Card,
OutlineButton,
@@ -39,15 +39,16 @@ function SettingsAppComponent(props: Props): JSX.Element {
restoreHints,
toggleOptedIn,
} = props
+ const { t } = useTranslation(['card', 'application', 'button'])
return (
<>
-
+
{/* TODO: BC 2019-02-26 add release notes link here, when there are release notes */}
@@ -56,30 +57,28 @@ function SettingsAppComponent(props: Props): JSX.Element {
-
+
- {i18n.t('card.body.restore_hints')}
+ {t('body.restore_hints')}
{canClearHintDismissals
- ? i18n.t('button.restore')
- : i18n.t('button.restored')}
+ ? t('button:restore')
+ : t('button:restored')}
-
+
-
- {i18n.t('card.toggle.share_session')}
-
+
{t('toggle.share_session')}
- {i18n.t('card.body.reason_for_collecting_data')}{' '}
- {i18n.t('card.body.data_collected_is_internal')}.
+ {t('body.reason_for_collecting_data')}{' '}
+ {t('body.data_collected_is_internal')}.
diff --git a/protocol-designer/src/components/SettingsPage/SettingsSidebar.tsx b/protocol-designer/src/components/SettingsPage/SettingsSidebar.tsx
index ccfc06cc34e..e1546e78dd4 100644
--- a/protocol-designer/src/components/SettingsPage/SettingsSidebar.tsx
+++ b/protocol-designer/src/components/SettingsPage/SettingsSidebar.tsx
@@ -1,43 +1,21 @@
import * as React from 'react'
+import { useSelector } from 'react-redux'
+import { useTranslation } from 'react-i18next'
import { SidePanel } from '@opentrons/components'
-import { connect } from 'react-redux'
-
-import { BaseState, ThunkDispatch } from '../../types'
-import { actions, selectors, Page } from '../../navigation'
-import { i18n } from '../../localization'
+import { selectors } from '../../navigation'
import { PDTitledList } from '../lists'
import styles from './SettingsPage.css'
-interface SP {
- currentPage: Page
-}
-interface DP {
- makeNavigateToPage: (page: Page) => () => unknown
+export const SettingsSidebar = (): JSX.Element => {
+ const currentPage = useSelector(selectors.getCurrentPage)
+ const { t } = useTranslation('nav')
+ return (
+
+
+
+ )
}
-type Props = SP & DP
-
-const SettingsSidebarComponent = (props: Props): JSX.Element => (
-
-
- {/* */}
-
-)
-
-const STP = (state: BaseState): SP => ({
- currentPage: selectors.getCurrentPage(state),
-})
-
-const DTP = (dispatch: ThunkDispatch
): DP => ({
- makeNavigateToPage: (pageName: Page) => () =>
- dispatch(actions.navigateToPage(pageName)),
-})
-
-export const SettingsSidebar = connect(STP, DTP)(SettingsSidebarComponent)
diff --git a/protocol-designer/src/components/StepEditForm/ButtonRow/index.tsx b/protocol-designer/src/components/StepEditForm/ButtonRow/index.tsx
index 6ea1d67b7ac..bcf1187bcba 100644
--- a/protocol-designer/src/components/StepEditForm/ButtonRow/index.tsx
+++ b/protocol-designer/src/components/StepEditForm/ButtonRow/index.tsx
@@ -1,7 +1,7 @@
import * as React from 'react'
+import { useTranslation } from 'react-i18next'
import cx from 'classnames'
import { OutlineButton, DeprecatedPrimaryButton } from '@opentrons/components'
-import { i18n } from '../../../localization'
import modalStyles from '../../modals/modal.css'
import styles from './styles.css'
@@ -22,18 +22,18 @@ export const ButtonRow = (props: ButtonRowProps): JSX.Element => {
handleSave,
canSave,
} = props
-
+ const { t } = useTranslation('button')
return (
- {i18n.t('button.delete')}
+ {t('delete')}
- {i18n.t('button.notes')}
+ {t('notes')}
@@ -41,14 +41,14 @@ export const ButtonRow = (props: ButtonRowProps): JSX.Element => {
className={styles.form_button}
onClick={handleClose}
>
- {i18n.t('button.close')}
+ {t('close')}
- {i18n.t('button.save')}
+ {t('save')}
diff --git a/protocol-designer/src/components/StepEditForm/fields/ChangeTipField/index.tsx b/protocol-designer/src/components/StepEditForm/fields/ChangeTipField/index.tsx
index 758f6838a4d..44dfa8d625b 100644
--- a/protocol-designer/src/components/StepEditForm/fields/ChangeTipField/index.tsx
+++ b/protocol-designer/src/components/StepEditForm/fields/ChangeTipField/index.tsx
@@ -1,4 +1,5 @@
import * as React from 'react'
+import { useTranslation } from 'react-i18next'
import {
FormGroup,
SelectField,
@@ -6,7 +7,6 @@ import {
useHoverTooltip,
TOOLTIP_FIXED,
} from '@opentrons/components'
-import { i18n } from '../../../../localization'
import {
getDisabledChangeTipOptions,
DisabledChangeTipArgs,
@@ -34,7 +34,7 @@ export const ChangeTipField = (props: Props): JSX.Element => {
updateValue,
value,
} = props
-
+ const { t } = useTranslation('form')
const disabledOptions = getDisabledChangeTipOptions({
aspirateWells,
dispenseWells,
@@ -49,7 +49,7 @@ export const ChangeTipField = (props: Props): JSX.Element => {
return (
{
const { value } = props
+ const { t } = useTranslation('form')
const [targetProps, tooltipProps] = useHoverTooltip({
placement: 'bottom-start',
strategy: TOOLTIP_FIXED,
@@ -78,12 +79,10 @@ const ChangeTipOptionLabel = (props: LabelProps): JSX.Element => {
return (
<>
- {i18n.t(`form.step_edit_form.field.change_tip.option.${value}`)}
+ {t(`step_edit_form.field.change_tip.option.${value}`)}
- {i18n.t(
- `form.step_edit_form.field.change_tip.option_tooltip.${value}`
- )}
+ {t(`step_edit_form.field.change_tip.option_tooltip.${value}`)}
diff --git a/protocol-designer/src/components/StepEditForm/fields/DropTipField/index.tsx b/protocol-designer/src/components/StepEditForm/fields/DropTipField/index.tsx
index 15cdd7e887d..0448d348430 100644
--- a/protocol-designer/src/components/StepEditForm/fields/DropTipField/index.tsx
+++ b/protocol-designer/src/components/StepEditForm/fields/DropTipField/index.tsx
@@ -1,7 +1,7 @@
import * as React from 'react'
+import { useTranslation } from 'react-i18next'
import { useSelector } from 'react-redux'
import { DropdownField, DropdownOption, FormGroup } from '@opentrons/components'
-import { i18n } from '../../../../localization'
import { getAdditionalEquipmentEntities } from '../../../../step-forms/selectors'
import { StepFormDropdown } from '../StepFormDropdownField'
import styles from '../../StepEditForm.css'
@@ -16,6 +16,7 @@ export function DropTipField(
onFieldFocus,
updateValue,
} = props
+ const { t } = useTranslation('form')
const additionalEquipment = useSelector(getAdditionalEquipmentEntities)
const wasteChute = Object.values(additionalEquipment).find(
aE => aE.name === 'wasteChute'
@@ -43,7 +44,7 @@ export function DropTipField(
}, [dropdownItem])
return (
{
name,
pipetteDisplayName,
} = props
- const { t } = useTranslation('form')
+ const { t } = useTranslation(['form', 'application'])
const DEFAULT_LABEL = t('step_edit_form.field.flow_rate.label')
const initialState: State = {
@@ -142,7 +141,7 @@ export const FlowRateInput = (props: FlowRateInputProps): JSX.Element => {
isIndeterminate={isIndeterminate && modalFlowRate === null}
name={`${name}_customFlowRate`}
onChange={handleChangeNumber}
- units={i18n.t('application.units.microliterPerSec')}
+ units={t('application:units.microliterPerSec')}
value={`${modalFlowRate || ''}`}
/>
)
@@ -181,8 +180,8 @@ export const FlowRateInput = (props: FlowRateInputProps): JSX.Element => {
onChange={handleChangeRadio}
options={[
{
- name: `${defaultFlowRate || '?'} ${i18n.t(
- 'application.units.microliterPerSec'
+ name: `${defaultFlowRate || '?'} ${t(
+ 'application:units.microliterPerSec'
)} (default)`,
value: 'default',
},
@@ -207,7 +206,7 @@ export const FlowRateInput = (props: FlowRateInputProps): JSX.Element => {
name={name}
onClick={openModal}
readOnly
- units={i18n.t('application.units.microliterPerSec')}
+ units={t('application:units.microliterPerSec')}
value={props.value ? String(props.value) : 'default'}
/>
diff --git a/protocol-designer/src/components/StepEditForm/fields/LabwareLocationField/index.tsx b/protocol-designer/src/components/StepEditForm/fields/LabwareLocationField/index.tsx
index 8dedd756389..072f7fa5e02 100644
--- a/protocol-designer/src/components/StepEditForm/fields/LabwareLocationField/index.tsx
+++ b/protocol-designer/src/components/StepEditForm/fields/LabwareLocationField/index.tsx
@@ -1,10 +1,10 @@
import * as React from 'react'
import { useSelector } from 'react-redux'
+import { useTranslation } from 'react-i18next'
import {
getModuleDisplayName,
WASTE_CHUTE_CUTOUT,
} from '@opentrons/shared-data'
-import { i18n } from '../../../../localization'
import {
getAdditionalEquipmentEntities,
getLabwareEntities,
@@ -22,6 +22,7 @@ export function LabwareLocationField(
useGripper: boolean
} & { canSave: boolean } & { labware: string }
): JSX.Element {
+ const { t } = useTranslation('form')
const { labware, useGripper, value } = props
const labwareEntities = useSelector(getLabwareEntities)
const robotState = useSelector(getRobotStateAtActiveItem)
@@ -79,10 +80,10 @@ export function LabwareLocationField(
{...props}
errorToShow={
!props.canSave && bothFieldsSelected
- ? i18n.t(
- 'form.step_edit_form.labwareLabel.errors.labwareSlotIncompatible',
- { labwareName: labwareDisplayName, slot: locationString }
- )
+ ? t('step_edit_form.labwareLabel.errors.labwareSlotIncompatible', {
+ labwareName: labwareDisplayName,
+ slot: locationString,
+ })
: undefined
}
options={unoccupiedLabwareLocationsOptions}
diff --git a/protocol-designer/src/components/StepEditForm/fields/PathField/Path.tsx b/protocol-designer/src/components/StepEditForm/fields/PathField/Path.tsx
index d8108997074..6990ffc44f3 100644
--- a/protocol-designer/src/components/StepEditForm/fields/PathField/Path.tsx
+++ b/protocol-designer/src/components/StepEditForm/fields/PathField/Path.tsx
@@ -1,7 +1,7 @@
import * as React from 'react'
+import { useTranslation } from 'react-i18next'
import cx from 'classnames'
import { FormGroup, Tooltip, useHoverTooltip } from '@opentrons/components'
-import { i18n } from '../../../../localization'
import SINGLE_IMAGE from '../../../../images/path_single_transfers.svg'
import MULTI_DISPENSE_IMAGE from '../../../../images/path_multi_dispense.svg'
import MULTI_ASPIRATE_IMAGE from '../../../../images/path_multi_aspirate.svg'
@@ -57,11 +57,11 @@ const PathButton = (buttonProps: ButtonProps): JSX.Element => {
subtitle,
} = buttonProps
const [targetProps, tooltipProps] = useHoverTooltip()
-
+ const { t } = useTranslation('form')
const tooltip = (
- {i18n.t(`form.step_edit_form.field.path.title.${path}`)}
+ {t(`step_edit_form.field.path.title.${path}`)}
@@ -111,13 +111,14 @@ interface WrapperProps {
targetProps: UseHoverTooltipTargetProps
}
-const Wrapper = (props: WrapperProps): JSX.Element =>
- props.isTouchTipField || props.isDelayPositionField ? (
+const Wrapper = (props: WrapperProps): JSX.Element => {
+ const { t } = useTranslation('form')
+ return props.isTouchTipField || props.isDelayPositionField ? (
{props.children}
) : (
@@ -125,7 +126,7 @@ const Wrapper = (props: WrapperProps): JSX.Element =>
)
-
+}
const mapSTP = (state: BaseState, ownProps: OP): SP => {
const { labwareId, value } = ownProps
diff --git a/protocol-designer/src/components/labware/BrowseLabwareModal.tsx b/protocol-designer/src/components/labware/BrowseLabwareModal.tsx
index 20422d8728c..d76f4c90a03 100644
--- a/protocol-designer/src/components/labware/BrowseLabwareModal.tsx
+++ b/protocol-designer/src/components/labware/BrowseLabwareModal.tsx
@@ -1,5 +1,4 @@
import assert from 'assert'
-import { i18n } from '../../localization'
import * as React from 'react'
import cx from 'classnames'
import { connect } from 'react-redux'
@@ -19,6 +18,7 @@ import { LabwareDefinition2 } from '@opentrons/shared-data'
import modalStyles from '../modals/modal.css'
import styles from './labware.css'
+import { useTranslation } from 'react-i18next'
interface SP {
definition?: LabwareDefinition2 | null
@@ -34,6 +34,7 @@ type Props = SP & DP
const BrowseLabwareModalComponent = (props: Props): JSX.Element | null => {
const { drillUp, definition, ingredNames, wellContents } = props
+ const { t } = useTranslation('modal')
if (!definition) {
assert(definition, 'BrowseLabwareModal expected definition')
return null
@@ -54,7 +55,7 @@ const BrowseLabwareModalComponent = (props: Props): JSX.Element | null => {
wellContents={wellContents}
/>
- {i18n.t('modal.browse_labware.instructions')}
+ {t('browse_labware.instructions')}
)
diff --git a/protocol-designer/src/components/modules/AdditionalItemsRow.tsx b/protocol-designer/src/components/modules/AdditionalItemsRow.tsx
index dc5b0510000..aa13214afef 100644
--- a/protocol-designer/src/components/modules/AdditionalItemsRow.tsx
+++ b/protocol-designer/src/components/modules/AdditionalItemsRow.tsx
@@ -1,4 +1,5 @@
import * as React from 'react'
+import { useTranslation } from 'react-i18next'
import styled from 'styled-components'
import {
getCutoutDisplayName,
@@ -17,7 +18,6 @@ import {
TYPOGRAPHY,
DIRECTION_ROW,
} from '@opentrons/components'
-import { i18n } from '../../localization'
import gripperImage from '../../images/flex_gripper.png'
import wasteChuteImage from '../../images/waste_chute.png'
import trashBinImage from '../../images/flex_trash_bin.png'
@@ -49,6 +49,7 @@ export function AdditionalItemsRow(
trashBinId,
hasWasteChute,
} = props
+ const { t } = useTranslation(['modules', 'shared', 'tooltip'])
const [targetProps, tooltipProps] = useHoverTooltip()
const [trashModal, openTrashModal] = React.useState(false)
const addTrash = name !== 'gripper' && !isEquipmentAdded
@@ -76,13 +77,13 @@ export function AdditionalItemsRow(
) : null}
- {i18n.t(`modules.additional_equipment_display_names.${name}`)}
+ {t(`additional_equipment_display_names.${name}`)}
) : null}
@@ -131,7 +132,7 @@ export function AdditionalItemsRow(
onClick={() => openTrashModal(true)}
className={styles.module_button}
>
- {i18n.t('shared.edit')}
+ {t('shared:edit')}
) : null}
openTrashModal(true) : handleAttachment
}
>
- {isEquipmentAdded
- ? i18n.t('shared.remove')
- : i18n.t('shared.add')}
+ {isEquipmentAdded ? t('shared:remove') : t('shared:add')}
{disabledRemoveButton ? (
@@ -158,7 +157,7 @@ export function AdditionalItemsRow(
width="10rem"
textAlign={TYPOGRAPHY.textAlignCenter}
>
- {i18n.t(`tooltip.disabled_cannot_delete_trash`)}
+ {t(`tooltip:disabled_cannot_delete_trash`)}
) : null}
diff --git a/protocol-designer/src/components/modules/CrashInfoBox.tsx b/protocol-designer/src/components/modules/CrashInfoBox.tsx
index 11663cb9225..ec4e61ceac4 100644
--- a/protocol-designer/src/components/modules/CrashInfoBox.tsx
+++ b/protocol-designer/src/components/modules/CrashInfoBox.tsx
@@ -1,6 +1,6 @@
import * as React from 'react'
+import { useTranslation } from 'react-i18next'
import { Icon, SPACING_3 } from '@opentrons/components'
-import { i18n } from '../../localization'
import collisionImage from '../../images/modules/module_pipette_collision_warning.png'
import { KnowledgeBaseLink } from '../KnowledgeBaseLink'
import styles from './styles.css'
@@ -20,31 +20,30 @@ type TempMagCollisonProps = Pick<
>
const HeaterShakerPipetteCollisions = (): JSX.Element | null => {
+ const { t } = useTranslation('alert')
return (
<>
- 8-Channel {i18n.t(`alert.crash.pipettes_east_west`)}{' '}
+ 8-Channel {t(`crash.pipettes_east_west`)}{' '}
Heater-Shaker Module GEN1.
- 8-Channel {' '}
- {i18n.t(`alert.crash.pipettes_can_access_north_south`)}{' '}
- Heater-Shaker Module GEN1 {' '}
- {i18n.t(`alert.crash.slot_has_tiprack`)}
+ 8-Channel {t(`crash.pipettes_can_access_north_south`)}{' '}
+ Heater-Shaker Module GEN1 {t(`crash.slot_has_tiprack`)}
>
)
}
const TempMagCollisions = (props: TempMagCollisonProps): JSX.Element => {
+ const { t } = useTranslation('alert')
const moduleMessage = getCrashableModulesCopy(props) || ''
return (
8-Channel GEN1 {' '}
- {i18n.t(`alert.crash.pipettes_cannot_access_north_south`)} {moduleMessage}
- .{' '}
+ {t(`crash.pipettes_cannot_access_north_south`)} {moduleMessage}.{' '}
- {i18n.t(`alert.crash.read_more_here`)}
+ {t(`crash.read_more_here`)}
)
@@ -79,14 +78,14 @@ const PipetteModuleCollisions = (props: Props): JSX.Element | null => {
const ModuleLabwareCollisions = (
props: Pick
): JSX.Element | null => {
+ const { t } = useTranslation('alert')
if (!props.showHeaterShakerLabwareCollisions) return null
const title = 'Potential module-labware collisions'
const body = (
- {i18n.t(`alert.crash.no_labware_over`)} 53 mm {' '}
- {i18n.t(`alert.crash.labware_east_west`)}{' '}
- Heater-Shaker Module GEN1 {' '}
- {i18n.t(`alert.crash.latch_collision`)}{' '}
+ {t(`crash.no_labware_over`)} 53 mm {' '}
+ {t(`crash.labware_east_west`)} Heater-Shaker Module GEN1 {' '}
+ {t(`crash.latch_collision`)}{' '}
)
return
@@ -94,11 +93,13 @@ const ModuleLabwareCollisions = (
const ModuleModuleCollisions = (
props: Pick
): JSX.Element | null => {
+ const { t } = useTranslation('alert')
+
if (!props.showHeaterShakerModuleCollisions) return null
const title = 'Potential module-module collisions'
const body = (
- {i18n.t(`alert.crash.modules_north_south`)}{' '}
+ {t(`crash.modules_north_south`)}{' '}
Heater-Shaker Module GEN1.
)
diff --git a/protocol-designer/src/components/modules/ModuleRow.tsx b/protocol-designer/src/components/modules/ModuleRow.tsx
index 073082878b3..068edeebcff 100644
--- a/protocol-designer/src/components/modules/ModuleRow.tsx
+++ b/protocol-designer/src/components/modules/ModuleRow.tsx
@@ -1,4 +1,5 @@
import * as React from 'react'
+import { useTranslation } from 'react-i18next'
import { useDispatch } from 'react-redux'
import upperFirst from 'lodash/upperFirst'
import {
@@ -16,7 +17,6 @@ import {
FLEX_ROBOT_TYPE,
THERMOCYCLER_MODULE_TYPE,
} from '@opentrons/shared-data'
-import { i18n } from '../../localization'
import { actions as stepFormActions, ModuleOnDeck } from '../../step-forms'
import {
SPAN7_8_10_11_SLOT,
@@ -44,6 +44,7 @@ export function ModuleRow(props: Props): JSX.Element {
showCollisionWarnings,
robotType,
} = props
+ const { t } = useTranslation(['modules', 'tooltip'])
const type: ModuleType = moduleOnDeck?.type || props.type
const isFlex = robotType === FLEX_ROBOT_TYPE
const model = moduleOnDeck?.model
@@ -86,12 +87,12 @@ export function ModuleRow(props: Props): JSX.Element {
// default module slot placement magnet = Slot1 temperature = Slot3
let collisionTooltipText = null
if (collisionSlots && collisionSlots.includes('4')) {
- collisionTooltipText = i18n.t(
- `tooltip.edit_module_card.magnetic_module_collision`
+ collisionTooltipText = t(
+ `tooltip:edit_module_card.magnetic_module_collision`
)
} else if (collisionSlots && collisionSlots.includes('6')) {
- collisionTooltipText = i18n.t(
- `tooltip.edit_module_card.temperature_module_collision`
+ collisionTooltipText = t(
+ `tooltip:edit_module_card.temperature_module_collision`
)
}
@@ -126,7 +127,7 @@ export function ModuleRow(props: Props): JSX.Element {
color={C_DARK_GRAY}
marginRight={SPACING.spacing4}
/>
- {i18n.t(`modules.module_display_names.${type}`)}
+ {t(`module_display_names.${type}`)}
@@ -139,7 +140,7 @@ export function ModuleRow(props: Props): JSX.Element {
{model && (
)}
diff --git a/protocol-designer/src/components/modules/StagingAreasModal.tsx b/protocol-designer/src/components/modules/StagingAreasModal.tsx
index c9991bcf3b3..7c9928d5444 100644
--- a/protocol-designer/src/components/modules/StagingAreasModal.tsx
+++ b/protocol-designer/src/components/modules/StagingAreasModal.tsx
@@ -1,4 +1,5 @@
import * as React from 'react'
+import { useTranslation } from 'react-i18next'
import { useSelector, useDispatch } from 'react-redux'
import { Form, Formik, useFormikContext } from 'formik'
import {
@@ -24,7 +25,6 @@ import {
STAGING_AREA_RIGHT_SLOT_FIXTURE,
} from '@opentrons/shared-data'
import { getStagingAreaSlots } from '../../utils'
-import { i18n } from '../../localization'
import {
createDeckFixture,
deleteDeckFixture,
@@ -41,6 +41,7 @@ export interface StagingAreasValues {
const StagingAreasModalComponent = (
props: StagingAreasModalProps
): JSX.Element => {
+ const { t } = useTranslation(['button', 'alert'])
const { onCloseClick, stagingAreas } = props
const { values, setFieldValue } = useFormikContext
()
const initialDeckSetup = useSelector(getInitialDeckSetup)
@@ -133,8 +134,8 @@ const StagingAreasModalComponent = (
{hasConflictedSlot ? (
@@ -155,11 +156,9 @@ const StagingAreasModalComponent = (
paddingBottom={SPACING.spacing32}
gridGap={SPACING.spacing8}
>
-
- {i18n.t('button.cancel')}
-
+ {t('cancel')}
- {i18n.t('button.save')}
+ {t('save')}
@@ -175,6 +174,7 @@ export const StagingAreasModal = (
props: StagingAreasModalProps
): JSX.Element => {
const { onCloseClick, stagingAreas } = props
+ const { t } = useTranslation('modules')
const dispatch = useDispatch()
const stagingAreaLocations = getStagingAreaSlots(stagingAreas)
@@ -203,7 +203,7 @@ export const StagingAreasModal = (
- {i18n.t(`modules.additional_equipment_display_names.stagingAreas`)}
+ {t(`additional_equipment_display_names.stagingAreas`)}
0
const [stagingAreaModal, openStagingAreaModal] = React.useState(
false
@@ -48,15 +49,13 @@ export function StagingAreasRow(props: StagingAreasRowProps): JSX.Element {
) : null}
- {i18n.t(`modules.additional_equipment_display_names.stagingAreas`)}
+ {t(`additional_equipment_display_names.stagingAreas`)}
openStagingAreaModal(true)}
className={styles.module_button}
>
- {i18n.t('shared.edit')}
+ {t('shared:edit')}
) : null}
openStagingAreaModal(true)
}
>
- {hasStagingAreas
- ? i18n.t('shared.remove')
- : i18n.t('shared.add')}
+ {hasStagingAreas ? t('shared:remove') : t('shared:add')}
diff --git a/protocol-designer/src/components/modules/TrashModal.tsx b/protocol-designer/src/components/modules/TrashModal.tsx
index 23c3d91ad2e..c919f224bb3 100644
--- a/protocol-designer/src/components/modules/TrashModal.tsx
+++ b/protocol-designer/src/components/modules/TrashModal.tsx
@@ -1,4 +1,5 @@
import * as React from 'react'
+import { useTranslation } from 'react-i18next'
import { useSelector, useDispatch } from 'react-redux'
import { Form, Formik, useField, useFormikContext } from 'formik'
import {
@@ -24,7 +25,6 @@ import {
getDeckDefFromRobotType,
WASTE_CHUTE_CUTOUT,
} from '@opentrons/shared-data'
-import { i18n } from '../../localization'
import {
createDeckFixture,
deleteDeckFixture,
@@ -75,6 +75,7 @@ export const MOVABLE_TRASH_CUTOUTS: DropdownOption[] = [
const TrashModalComponent = (props: TrashModalProps): JSX.Element => {
const { onCloseClick, trashName } = props
+ const { t } = useTranslation(['alert', 'button'])
const { values } = useFormikContext
()
const initialDeckSetup = useSelector(getInitialDeckSetup)
const isSlotEmpty = getSlotIsEmpty(
@@ -115,9 +116,7 @@ const TrashModalComponent = (props: TrashModalProps): JSX.Element => {
{!isSlotEmpty ? (
) : null}
@@ -140,10 +139,10 @@ const TrashModalComponent = (props: TrashModalProps): JSX.Element => {
gridGap={SPACING.spacing8}
>
- {i18n.t('button.cancel')}
+ {t('button:cancel')}
- {i18n.t('button.save')}
+ {t('button:save')}
@@ -159,6 +158,7 @@ export interface TrashModalProps {
export const TrashModal = (props: TrashModalProps): JSX.Element => {
const { onCloseClick, trashName, trashBinId } = props
const dispatch = useDispatch()
+ const { t } = useTranslation('modules')
const onSaveClick = (values: TrashValues): void => {
if (trashName === 'trashBin' && trashBinId == null) {
@@ -184,7 +184,7 @@ export const TrashModal = (props: TrashModalProps): JSX.Element => {
- {i18n.t(`modules.additional_equipment_display_names.${trashName}`)}
+ {t(`additional_equipment_display_names.${trashName}`)}