Skip to content

Commit

Permalink
feat(app): allow local editing of JSON protocols through embedded pro…
Browse files Browse the repository at this point in the history
…tocol designer

Include an experimental windowed local protocol designer within the desktop app.
  • Loading branch information
b-cooper committed Jun 21, 2024
1 parent a90b376 commit 5647b50
Show file tree
Hide file tree
Showing 20 changed files with 34,513 additions and 35,725 deletions.
48 changes: 24 additions & 24 deletions app-shell/src/config/migrate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -384,7 +384,7 @@ const toVersion21 = (prevConfig: ConfigV20): ConfigV21 => {
...prevConfig.onDeviceDisplaySettings,
unfinishedUnboxingFlowRoute:
prevConfig.onDeviceDisplaySettings.unfinishedUnboxingFlowRoute ===
'/dashboard'
'/dashboard'
? null
: prevConfig.onDeviceDisplaySettings.unfinishedUnboxingFlowRoute,
},
Expand Down Expand Up @@ -432,29 +432,29 @@ const MIGRATIONS: [
(prevConfig: ConfigV20) => ConfigV21,
(prevConfig: ConfigV21) => ConfigV22
] = [
toVersion1,
toVersion2,
toVersion3,
toVersion4,
toVersion5,
toVersion6,
toVersion7,
toVersion8,
toVersion9,
toVersion10,
toVersion11,
toVersion12,
toVersion13,
toVersion14,
toVersion15,
toVersion16,
toVersion17,
toVersion18,
toVersion19,
toVersion20,
toVersion21,
toVersion22,
]
toVersion1,
toVersion2,
toVersion3,
toVersion4,
toVersion5,
toVersion6,
toVersion7,
toVersion8,
toVersion9,
toVersion10,
toVersion11,
toVersion12,
toVersion13,
toVersion14,
toVersion15,
toVersion16,
toVersion17,
toVersion18,
toVersion19,
toVersion20,
toVersion21,
toVersion22,
]

export const DEFAULTS: Config = migrate(DEFAULTS_V0)

Expand Down
3 changes: 1 addition & 2 deletions app-shell/src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -177,8 +177,7 @@ export const ANALYZE_PROTOCOL_SUCCESS: ANALYZE_PROTOCOL_SUCCESS_TYPE =
export const ANALYZE_PROTOCOL_FAILURE: ANALYZE_PROTOCOL_FAILURE_TYPE =
'protocolStorage:ANALYZE_PROTOCOL_FAILURE'

export const EDIT_PROTOCOL: EDIT_PROTOCOL_TYPE =
'protocolStorage:EDIT_PROTOCOL'
export const EDIT_PROTOCOL: EDIT_PROTOCOL_TYPE = 'protocolStorage:EDIT_PROTOCOL'

export const VIEW_PROTOCOL_SOURCE_FOLDER: VIEW_PROTOCOL_SOURCE_FOLDER_TYPE =
'protocolStorage:VIEW_PROTOCOL_SOURCE_FOLDER'
Expand Down
40 changes: 21 additions & 19 deletions app-shell/src/protocol-editor-ui.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,12 @@ import path from 'path'

import { getConfig } from './config'
import { createLogger } from './log'
import { PROTOCOLS_DIRECTORY_PATH, analyzeProtocolByKey, getProtocolSourceJSON, overwriteProtocol } from './protocol-storage/file-system'
import {
PROTOCOLS_DIRECTORY_PATH,
analyzeProtocolByKey,
getProtocolSourceJSON,
overwriteProtocol,
} from './protocol-storage/file-system'

const protocolEditorUiConfig = getConfig('protocolEditorUi')
const log = createLogger('protocolEditorUi')
Expand All @@ -30,7 +35,6 @@ const WINDOW_OPTS = {
),
}


const protocolEditorPath =
protocolEditorUiConfig.url.protocol === 'file:'
? path.join(app.getAppPath(), protocolEditorUiConfig.url.path)
Expand All @@ -39,13 +43,10 @@ const protocolEditorPath =
export function createProtocolEditorUi(srcFilePath: string): BrowserWindow {
log.debug('Creating protocol editor window', { options: WINDOW_OPTS })

const subWindow = new BrowserWindow(WINDOW_OPTS).once(
'ready-to-show',
() => {
log.debug('Protocol Editor window ready to show')
subWindow.show()
}
)
const subWindow = new BrowserWindow(WINDOW_OPTS).once('ready-to-show', () => {
log.debug('Protocol Editor window ready to show')
subWindow.show()
})
const protocolEditorUrl = `${protocolEditorUiConfig.url.protocol}//${protocolEditorPath}`

log.info(`Loading ${protocolEditorUrl}`)
Expand All @@ -65,17 +66,18 @@ export function createProtocolEditorUi(srcFilePath: string): BrowserWindow {
const protocolSourceJSON = getProtocolSourceJSON(srcFilePath)
protocolSourceJSON.then(json => {
subWindow.webContents.send('open-protocol-in-designer', json)
ipcMain.once('save-protocol-file-to-filesystem', (_event, fileName, fileData) => {
overwriteProtocol(srcFilePath, fileName, fileData).then(() => {
const { protocolKey } = /.*\/(?<protocolKey>.*)\/src.*/.exec(srcFilePath)?.groups ?? {}
return analyzeProtocolByKey(
protocolKey,
PROTOCOLS_DIRECTORY_PATH
)
})
})
ipcMain.once(
'save-protocol-file-to-filesystem',
(_event, fileName, fileData) => {
overwriteProtocol(srcFilePath, fileName, fileData).then(() => {

Check failure on line 72 in app-shell/src/protocol-editor-ui.ts

View workflow job for this annotation

GitHub Actions / js checks

Unsafe argument of type `any` assigned to a parameter of type `string`

Check failure on line 72 in app-shell/src/protocol-editor-ui.ts

View workflow job for this annotation

GitHub Actions / js checks

Unsafe argument of type `any` assigned to a parameter of type `string`

Check failure on line 72 in app-shell/src/protocol-editor-ui.ts

View workflow job for this annotation

GitHub Actions / js checks

Unsafe argument of type `any` assigned to a parameter of type `string`

Check failure on line 72 in app-shell/src/protocol-editor-ui.ts

View workflow job for this annotation

GitHub Actions / js checks

Unsafe argument of type `any` assigned to a parameter of type `string`
const { protocolKey } =
/.*\/(?<protocolKey>.*)\/src.*/.exec(srcFilePath)?.groups ?? {}
return analyzeProtocolByKey(protocolKey, PROTOCOLS_DIRECTORY_PATH)
})
}
)
})
});
})

return subWindow
}
17 changes: 11 additions & 6 deletions app-shell/src/protocol-storage/file-system.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,9 @@ export function parseProtocolDirs(
return Promise.all(tasks)
}

export function getProtocolSourceJSON(protocolSrcFilePath: string): Promise<any> {
export function getProtocolSourceJSON(
protocolSrcFilePath: string
): Promise<any> {
return fs.readJSON(protocolSrcFilePath)
}

Expand Down Expand Up @@ -191,9 +193,12 @@ export function overwriteProtocol(
protocolData: string
): Promise<void> {
const newSrcFilePath = path.join(path.dirname(protocolSrcPath), newFileName)
return fs.remove(protocolSrcPath).then(() => {
return fs.writeFile(newSrcFilePath, JSON.stringify(protocolData))
}).catch(e => { console.error(e) })
return fs
.remove(protocolSrcPath)
.then(() => {
return fs.writeFile(newSrcFilePath, JSON.stringify(protocolData))
})
.catch(e => {
console.error(e)
})
}


10 changes: 7 additions & 3 deletions app-shell/src/protocol-storage/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -220,9 +220,13 @@ export function registerProtocolStorage(dispatch: Dispatch): Dispatch {
FileSystem.getProtocolSourceFiles(
action.payload.protocolKey,
FileSystem.PROTOCOLS_DIRECTORY_PATH
).then((srcFiles) => {
createProtocolEditorUi(srcFiles[0])
}).catch(e => { console.error(e) })
)
.then(srcFiles => {
createProtocolEditorUi(srcFiles[0])
})
.catch(e => {
console.error(e)
})
break
}

Expand Down
2 changes: 1 addition & 1 deletion app/src/App/DesktopApp.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ import { ProtocolTimeline } from '../pages/Protocols/ProtocolDetails/ProtocolTim
import { PortalRoot as ModalPortalRoot } from './portal'
import { DesktopAppFallback } from './DesktopAppFallback'

import type { RouteProps, DesktopRouteParams } from './types'
import type { RouteProps, DesktopRouteParams } from './types'

export const DesktopApp = (): JSX.Element => {
useSoftwareUpdatePoll()
Expand Down
2 changes: 1 addition & 1 deletion app/src/molecules/Command/LoadCommandText.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export const LoadCommandText = ({
robotType,
}: LoadCommandTextProps): JSX.Element | null => {
const { t } = useTranslation('run_details')

switch (command.commandType) {
case 'loadPipette': {
const pipetteModel = getPipetteNameOnMount(
Expand Down
5 changes: 4 additions & 1 deletion app/src/molecules/Command/utils/getCommandTextData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@ import type {
import type { CommandTextData } from '../types'

export function getCommandTextData(
protocolData: CompletedProtocolAnalysis | LegacyGoodRunData | ProtocolAnalysisOutput,
protocolData:
| CompletedProtocolAnalysis
| LegacyGoodRunData
| ProtocolAnalysisOutput,
protocolCommands?: RunTimeCommand[]
): CommandTextData {
const { pipettes, labware, modules, liquids } = protocolData
Expand Down
Loading

0 comments on commit 5647b50

Please sign in to comment.