diff --git a/app/src/components/RobotSettings/ConnectionCard.js b/app/src/components/RobotSettings/ConnectionCard.js index 0e50c5e9b0b..f6bb032d289 100644 --- a/app/src/components/RobotSettings/ConnectionCard.js +++ b/app/src/components/RobotSettings/ConnectionCard.js @@ -6,30 +6,19 @@ import {getIn} from '@thi.ng/paths' import find from 'lodash/find' import {getConfig} from '../../config' -import { - makeGetRobotNetworkingStatus, - makeGetRobotWifiList, -} from '../../http-api-client' -import {RefreshCard} from '@opentrons/components' -import { - ConnectionStatusMessage, - ConnectionInfo, - AvailableNetworks, -} from './connection' +import {makeGetRobotNetworkingStatus} from '../../http-api-client' +import {Card} from '@opentrons/components' +import SelectNetwork from './SelectNetwork' +import {ConnectionStatusMessage, ConnectionInfo} from './connection' import type {State} from '../../types' import type {ViewableRobot} from '../../discovery' -import type { - WifiNetworkList, - InternetStatus, - NetworkInterface, -} from '../../http-api-client' +import type {InternetStatus, NetworkInterface} from '../../http-api-client' type OP = {robot: ViewableRobot} type SP = {| __featureEnabled: boolean, - wifiList: ?WifiNetworkList, internetStatus: ?InternetStatus, wifiNetwork: ?NetworkInterface, ethernetNetwork: ?NetworkInterface, @@ -39,46 +28,40 @@ type Props = {...$Exact, ...SP} const __FEATURE_FLAG = 'devInternal.manageRobotConnection.newCard' -export default connect( - makeMapStateToProps - /* mapDispatchToProps */ -)(ConnectionCard) +export default connect(makeMapStateToProps)(ConnectionCard) const TITLE = 'Connectivity' function ConnectionCard (props: Props) { // TODO(mc, 2018-10-15): remove feature flag if (!props.__featureEnabled) return null - const {robot, wifiList, internetStatus, wifiNetwork, ethernetNetwork} = props + const {robot, internetStatus, wifiNetwork, ethernetNetwork} = props return ( - console.log('placeholder')}> + - + - + ) } function makeMapStateToProps (): (State, OP) => SP { const getNetworkingStatusCall = makeGetRobotNetworkingStatus() - const getWifiListCall = makeGetRobotWifiList() return (state, ownProps) => { const {robot} = ownProps const {response: statusResponse} = getNetworkingStatusCall(state, robot) - const {response: listResponse} = getWifiListCall(state, robot) const internetStatus = statusResponse && statusResponse.status const interfaces = statusResponse && statusResponse.interfaces return { internetStatus, - wifiList: listResponse && listResponse.list, wifiNetwork: find(interfaces, {type: 'wifi'}), ethernetNetwork: find(interfaces, {type: 'ethernet'}), __featureEnabled: !!getIn(getConfig(state), __FEATURE_FLAG), diff --git a/app/src/components/RobotSettings/SelectNetwork.js b/app/src/components/RobotSettings/SelectNetwork.js new file mode 100644 index 00000000000..2574c11e2b3 --- /dev/null +++ b/app/src/components/RobotSettings/SelectNetwork.js @@ -0,0 +1,122 @@ +// @flow +import * as React from 'react' +import {connect} from 'react-redux' +import find from 'lodash/find' + +import { + NO_SECURITY, + fetchWifiList, + configureWifi, + makeGetRobotWifiList, + makeGetRobotWifiConfigure, +} from '../../http-api-client' +import {NetworkDropdown} from './connection' +import {Portal} from '../portal' +import {IntervalWrapper, SpinnerModal} from '@opentrons/components' + +import type {State, Dispatch} from '../../types' +import type {ViewableRobot} from '../../discovery' +import type {WifiNetwork, WifiNetworkList} from '../../http-api-client' + +type OP = {robot: ViewableRobot} + +type SP = {|list: ?WifiNetworkList, connectingTo: ?string|} + +type DP = {| + getList: () => mixed, + configure: (network: WifiNetwork) => mixed, +|} + +type Props = {...$Exact, ...SP, ...DP} + +type SelectNetworkState = {value: ?string} + +const LIST_REFRESH_MS = 15000 + +class SelectNetwork extends React.Component { + constructor (props) { + super(props) + // prepopulate selected SSID with currently connected network, if any + this.state = {value: this.getActiveSsid()} + } + + onChange = (network: WifiNetwork) => { + this.setState({value: network.ssid}) + this.props.configure(network) + } + + getActiveSsid (): ?string { + const activeNetwork = find(this.props.list, 'active') + return activeNetwork && activeNetwork.ssid + } + + componentDidUpdate (prevProps) { + // if we don't have a selected network in component state and the list has + // updated, seed component state with active ssid from props + if (!this.state.value && this.props.list !== prevProps.list) { + this.setState({value: this.getActiveSsid()}) + } + } + + render () { + const {list, connectingTo, getList} = this.props + const {value} = this.state + + return ( + + + {connectingTo && ( + + + + )} + + ) + } +} + +function makeMapStateToProps (): (State, OP) => SP { + const getWifiListCall = makeGetRobotWifiList() + const getWifiConfigureCall = makeGetRobotWifiConfigure() + + return (state, ownProps) => { + const {robot} = ownProps + const {response: listResponse} = getWifiListCall(state, robot) + const { + request: cfgRequest, + inProgress: cfgInProgress, + error: cfgError, + } = getWifiConfigureCall(state, robot) + + return { + list: listResponse && listResponse.list, + connectingTo: + !cfgError && cfgInProgress && cfgRequest ? cfgRequest.ssid : null, + } + } +} + +function mapDispatchToProps (dispatch: Dispatch, ownProps: OP): DP { + const {robot} = ownProps + + return { + getList: () => dispatch(fetchWifiList(robot)), + configure: network => { + if (network.securityType === NO_SECURITY) { + return dispatch(configureWifi(robot, {ssid: network.ssid})) + } + }, + } +} + +export default connect( + makeMapStateToProps, + mapDispatchToProps +)(SelectNetwork) diff --git a/app/src/components/RobotSettings/connection.js b/app/src/components/RobotSettings/connection.js index 4a9c6dda70a..bcf5596bba6 100644 --- a/app/src/components/RobotSettings/connection.js +++ b/app/src/components/RobotSettings/connection.js @@ -2,6 +2,7 @@ // UI components for displaying connection info import * as React from 'react' import Select from 'react-select' +import find from 'lodash/find' import {Icon} from '@opentrons/components' import {CardContentHalf} from '../layout' import styles from './styles.css' @@ -68,22 +69,37 @@ export function ConnectionInfo (props: ConnectionInfoProps) { ) } -type AvailableNetworksProps = {list: ?WifiNetworkList} +type SelectNetworkOption = { + ...$Exact, + value: string, + label: React.Node, +} + +type NetworkDropdownProps = { + list: ?WifiNetworkList, + value: ?string, + disabled: boolean, + onChange: SelectNetworkOption => mixed, +} -export function AvailableNetworks (props: AvailableNetworksProps) { +export function NetworkDropdown (props: NetworkDropdownProps) { + const {value, disabled, onChange} = props const list = props.list || [] const options = list.map(NetworkOption) + const selectedOption = find(options, {value}) + return (