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

fix(protocol-designer): format export modal mesasge for repeat modules and 96-channel #15249

Merged
merged 4 commits into from
May 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
49 changes: 45 additions & 4 deletions protocol-designer/src/components/FileSidebar/FileSidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -127,12 +127,53 @@ function getWarningContent({
}

const pipettesDetails = pipettesWithoutStep
.map(pipette => `${pipette.mount} ${pipette.spec.displayName}`)
.map(pipette =>
pipette.spec.channels === 96
? `${pipette.spec.displayName} pipette`
: `${pipette.mount} ${pipette.spec.displayName} pipette`
)
.join(' and ')

const modulesDetails = modulesWithoutStep
.map(moduleOnDeck => t(`modules:module_long_names.${moduleOnDeck.type}`))
.join(' and ')
const unusedModuleCounts = modulesWithoutStep.reduce<{
ncdiehl11 marked this conversation as resolved.
Show resolved Hide resolved
[key: string]: number
}>((acc, mod) => {
if (!(mod.type in acc)) {
return { ...acc, [mod.type]: 1 }
} else {
return { ...acc, [mod.type]: acc[mod.type] + 1 }
}
}, {})

const modulesDetails = Object.keys(unusedModuleCounts)
// sorting by module count
.sort((k1, k2) => {
if (unusedModuleCounts[k1] < unusedModuleCounts[k2]) {
return 1
} else if (unusedModuleCounts[k1] > unusedModuleCounts[k2]) {
return -1
} else {
return 0
}
})
.map(modType =>
unusedModuleCounts[modType] === 1
? t(`modules:module_long_names.${modType}`)
: `${t(`modules:module_long_names.${modType}`)}s`
)
// transform list of modules with counts to string
.reduce((acc, modName, index, arr) => {
if (arr.length > 2) {
if (index === arr.length - 1) {
return `${acc} and ${modName}`
} else {
return `${acc}${modName}, `
}
} else if (arr.length === 2) {
return index === 0 ? `${modName} and ` : `${acc}${modName}`
} else {
return modName
}
}, '')

if (pipettesWithoutStep.length && modulesWithoutStep.length) {
return {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -230,4 +230,58 @@ describe('FileSidebar', () => {
'One or more modules specified in your protocol in Slot(s) A1,B1 are not currently used in any step. In order to run this protocol you will need to power up and connect the modules to your robot.'
)
})
it('renders the formatted unused pipettes and modules warning sorted by count', () => {
vi.mocked(getInitialDeckSetup).mockReturnValue({
modules: {
moduleId1: {
slot: 'A1',
moduleState: {} as any,
id: 'moduleId',
type: 'thermocyclerModuleType',
model: 'thermocyclerModuleV2',
},
moduleId2: {
slot: 'C3',
moduleState: {} as any,
id: 'moduleId1',
type: 'temperatureModuleType',
model: 'temperatureModuleV2',
},
moduleId3: {
slot: 'D3',
moduleState: {} as any,
id: 'moduleId2',
type: 'temperatureModuleType',
model: 'temperatureModuleV2',
},
moduleId4: {
slot: 'C1',
moduleState: {} as any,
id: 'moduleId3',
type: 'heaterShakerModuleType',
model: 'heaterShakerModuleV1',
},
},
pipettes: {
pipetteId: {
mount: 'left',
name: 'p1000_96',
id: 'pipetteId',
tiprackLabwareDef: [fixtureTiprack300ul as LabwareDefinition2],
tiprackDefURI: ['mockDefUri'],
spec: {
displayName: 'mock display name',
channels: 96,
} as any,
},
},
additionalEquipmentOnDeck: {},
labware: {},
})
render()
fireEvent.click(screen.getByRole('button', { name: 'Export' }))
screen.getByText(
'The mock display name pipette and Temperature modules, Thermocycler module, and Heater-Shaker module in your protocol are not currently used in any step. In order to run this protocol you will need to attach this pipette as well as power up and connect the module to your robot.'
)
})
})
Loading