Skip to content

Commit

Permalink
feat(app): Enable download robot logs in advanced settings (#2014)
Browse files Browse the repository at this point in the history
closes #1727
  • Loading branch information
Kadee80 authored Aug 7, 2018
1 parent 3da58d7 commit 6e51ba0
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 14 deletions.
4 changes: 3 additions & 1 deletion app-shell/src/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import initializeMenu from './menu'
import {initialize as initializeApiUpdate} from './api-update'
import createLogger from './log'
import {getConfig, getStore, getOverrides, registerConfig} from './config'
import {registerRobotLogs} from './robot-logs'

const config = getConfig()
const log = createLogger(__filename)
Expand Down Expand Up @@ -43,10 +44,11 @@ function startUp () {
}

const configHandler = registerConfig(dispatch)

const downloadHandler = registerRobotLogs(dispatch, mainWindow)
ipcMain.on('dispatch', (_, action) => {
log.debug('Received action via IPC from renderer', {action})
configHandler(action)
downloadHandler(action)
})

if (config.devtools) {
Expand Down
12 changes: 12 additions & 0 deletions app-shell/src/robot-logs.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// download robot logs manager

export function registerRobotLogs (dispatch, mainWindow) {
return function handleIncomingAction (action) {
const {type, payload: {logUrls}} = action
if (type === 'shell:DOWNLOAD_LOGS') {
logUrls.forEach((url) => {
mainWindow.webContents.downloadURL(url)
})
}
}
}
35 changes: 25 additions & 10 deletions app/src/components/RobotSettings/AdvancedSettingsCard.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,24 @@ import {connect} from 'react-redux'

import type {State, Dispatch} from '../../types'
import type {Robot} from '../../robot'
import type {Setting} from '../../http-api-client'
import {fetchSettings, setSettings, makeGetRobotSettings} from '../../http-api-client'
import type {Setting, RobotHealth} from '../../http-api-client'
import {fetchSettings, setSettings, makeGetRobotSettings, makeGetRobotHealth} from '../../http-api-client'
import {downloadLogs} from '../../shell'

import {RefreshCard} from '@opentrons/components'
import {LabeledButton, LabeledToggle} from '../controls'

type OP = Robot

type SP = {settings: Array<Setting>}
type SP = {
health: ?RobotHealth,
settings: Array<Setting>,
}

type DP = {
fetch: () => mixed,
set: (id: string, value: boolean) => mixed,
download: () => mixed,
}

type Props = OP & SP & DP
Expand Down Expand Up @@ -54,8 +59,8 @@ class BooleanSettingToggle extends React.Component<BooleanSettingProps> {
}

function AdvancedSettingsCard (props: Props) {
const {name, settings, set, fetch} = props

const {name, settings, set, fetch, download, health} = props
const logsAvailable = health && health.response && health.response.logs
return (
<RefreshCard watch={name} refresh={fetch} title={TITLE} column>
{settings.map(s => (
Expand All @@ -64,7 +69,8 @@ function AdvancedSettingsCard (props: Props) {
<LabeledButton
label='Download Logs'
buttonProps={{
disabled: true,
disabled: !logsAvailable,
onClick: download,
children: 'Download'
}}
>
Expand All @@ -76,14 +82,23 @@ function AdvancedSettingsCard (props: Props) {

function makeMapStateToProps (): (state: State, ownProps: OP) => SP {
const getRobotSettings = makeGetRobotSettings()

return (state, ownProps) =>
getRobotSettings(state, ownProps).response || {settings: []}
const getRobotHealth = makeGetRobotHealth()

return (state, ownProps) => {
const settingsRequest = getRobotSettings(state, ownProps)
const settings = settingsRequest && settingsRequest.response && settingsRequest.response.settings
const health = getRobotHealth(state, ownProps)
return {
health,
settings: settings || []
}
}
}

function mapDispatchToProps (dispatch: Dispatch, ownProps: OP): DP {
return {
fetch: () => dispatch(fetchSettings(ownProps)),
set: (id, value) => dispatch(setSettings(ownProps, id, value))
set: (id, value) => dispatch(setSettings(ownProps, id, value)),
download: () => dispatch(downloadLogs(ownProps))
}
}
1 change: 1 addition & 0 deletions app/src/http-api-client/health.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ type HealthResponse = {
name: string,
api_version: string,
fw_version: string,
logs: ?Array<string>,
}

export type HealthAction =
Expand Down
17 changes: 14 additions & 3 deletions app/src/shell/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
// desktop shell module
import {remote, ipcRenderer} from 'electron'
import {createSelector, type Selector} from 'reselect'

import createLogger from '../logger'

import type {State, Action, Middleware, ThunkPromiseAction, Error} from '../types'
import type {RobotService} from '../robot'
import {makeGetRobotHealth} from '../http-api-client'
import type {State, Action, Middleware, ThunkPromiseAction, ThunkAction, Error} from '../types'

const {
CURRENT_VERSION,
Expand Down Expand Up @@ -183,3 +183,14 @@ export function getShellConfig () {
function selectShellUpdateState (state: State) {
return state.shell.update
}

export function downloadLogs (robot: RobotService): ThunkAction {
return (dispatch, getState) => {
const health = makeGetRobotHealth()(getState(), robot)
const logPaths = health && health.response && health.response.logs
if (logPaths) {
const logUrls = logPaths.map((p) => `http://${robot.ip}:${robot.port}${p}`)
dispatch({type: 'shell:DOWNLOAD_LOGS', payload: {logUrls}, meta: {shell: true}})
}
}
}

0 comments on commit 6e51ba0

Please sign in to comment.