Browse Source

Change error behavior of DeviceInteractionStep

master
meriadec 7 years ago
parent
commit
56b14106b6
No known key found for this signature in database GPG Key ID: 1D2FC2305E2CB399
  1. 22
      src/components/DeviceInteraction/DeviceInteractionStep.js
  2. 5
      src/components/DeviceInteraction/components.js
  3. 103
      src/components/DeviceInteraction/index.js
  4. 3
      src/components/GenuineCheck.js
  5. 13
      src/components/ManagerPage/ManagerGenuineCheck.js
  6. 4
      src/components/ManagerPage/index.js

22
src/components/DeviceInteraction/DeviceInteractionStep.js

@ -10,7 +10,6 @@ import {
SpinnerContainer, SpinnerContainer,
IconContainer, IconContainer,
SuccessContainer, SuccessContainer,
ErrorDescContainer,
ErrorContainer, ErrorContainer,
} from './components' } from './components'
@ -20,10 +19,7 @@ export type Step = {
desc?: React$Node, desc?: React$Node,
icon: React$Node, icon: React$Node,
run?: Object => Promise<any> | { promise: Promise<any>, unsubscribe: void => any }, run?: Object => Promise<any> | { promise: Promise<any>, unsubscribe: void => any },
render?: ( render?: ({ onSuccess: Object => any, onFail: Error => void }, any) => React$Node,
{ onSuccess: Object => any, onFail: Error => void, onRetry: void => void },
any,
) => React$Node,
minMs?: number, minMs?: number,
} }
@ -38,10 +34,8 @@ type Props = {
isSuccess: boolean, isSuccess: boolean,
isPassed: boolean, isPassed: boolean,
step: Step, step: Step,
error: ?Error,
onSuccess: (any, Step) => any, onSuccess: (any, Step) => any,
onFail: (Error, Step) => any, onFail: (Error, Step) => any,
onRetry: void => any,
data: any, data: any,
} }
@ -66,13 +60,13 @@ class DeviceInteractionStep extends PureComponent<
} }
componentDidUpdate(prevProps: Props) { componentDidUpdate(prevProps: Props) {
const { isActive, error } = this.props const { isActive, isError } = this.props
const { status } = this.state const { status } = this.state
const didActivated = isActive && !prevProps.isActive const didActivated = isActive && !prevProps.isActive
const didDeactivated = !isActive && prevProps.isActive const didDeactivated = !isActive && prevProps.isActive
const stillActivated = isActive && prevProps.isActive const stillActivated = isActive && prevProps.isActive
const didResetError = !error && !!prevProps.error const didResetError = !isError && !!prevProps.isError
if (didActivated && status !== 'running') { if (didActivated && status !== 'running') {
this.run() this.run()
@ -163,8 +157,6 @@ class DeviceInteractionStep extends PureComponent<
isError, isError,
isPassed, isPassed,
step, step,
error,
onRetry,
data, data,
} = this.props } = this.props
@ -191,14 +183,8 @@ class DeviceInteractionStep extends PureComponent<
)} )}
{step.desc && step.desc} {step.desc && step.desc}
{CustomRender && ( {CustomRender && (
<CustomRender <CustomRender onSuccess={this.handleSuccess} onFail={this.handleFail} data={data} />
onSuccess={this.handleSuccess}
onFail={this.handleFail}
onRetry={onRetry}
data={data}
/>
)} )}
{isError && error && <ErrorDescContainer error={error} onRetry={onRetry} mt={2} />}
</Box> </Box>
<div style={{ width: 70, position: 'relative', overflow: 'hidden', pointerEvents: 'none' }}> <div style={{ width: 70, position: 'relative', overflow: 'hidden', pointerEvents: 'none' }}>

5
src/components/DeviceInteraction/components.js

@ -92,6 +92,8 @@ export const ErrorContainer = ({ isVisible }: { isVisible: boolean }) => (
) )
const ErrorRetryContainer = styled(Box).attrs({ const ErrorRetryContainer = styled(Box).attrs({
bg: rgba(colors.alertRed, 0.1),
borderRadius: 1,
grow: 1, grow: 1,
color: 'alertRed', color: 'alertRed',
cursor: 'pointer', cursor: 'pointer',
@ -118,6 +120,7 @@ export const ErrorDescContainer = ({
}) => ( }) => (
<Box <Box
pl={0} pl={0}
fontSize={3}
color="alertRed" color="alertRed"
align="flex-start" align="flex-start"
justify="center" justify="center"
@ -126,7 +129,7 @@ export const ErrorDescContainer = ({
}} }}
{...p} {...p}
> >
<Box horizontal bg={rgba(colors.alertRed, 0.1)} borderRadius={1}> <Box horizontal>
<Box p={1} pl={2}> <Box p={1} pl={2}>
{error.message || 'Failed'} {error.message || 'Failed'}
</Box> </Box>

103
src/components/DeviceInteraction/index.js

@ -1,40 +1,43 @@
// @flow // @flow
import React, { PureComponent } from 'react' import React, { PureComponent } from 'react'
import styled from 'styled-components'
import { delay } from 'helpers/promise' import { delay } from 'helpers/promise'
import Box from 'components/base/Box' import Box from 'components/base/Box'
import Space from 'components/base/Space'
import DeviceInteractionStep from './DeviceInteractionStep' import DeviceInteractionStep from './DeviceInteractionStep'
import type { Step } from './DeviceInteractionStep' import type { Step } from './DeviceInteractionStep'
import { ErrorDescContainer } from './components'
type Props = {
steps: Step[],
onSuccess?: any => void,
onFail?: any => void,
waitBeforeSuccess?: number,
// when true and there is an error, display the error + retry button
shouldRenderRetry?: boolean,
}
type State = {
stepIndex: number,
isSuccess: boolean,
error: ?Error,
data: Object,
}
const INITIAL_STATE = { const INITIAL_STATE = {
stepIndex: 0, stepIndex: 0,
isSuccess: false, isSuccess: false,
showSuccess: false,
error: null, error: null,
data: {}, data: {},
} }
class DeviceInteraction extends PureComponent< class DeviceInteraction extends PureComponent<Props, State> {
{
steps: Step[],
onSuccess?: any => void,
onFail?: any => void,
renderSuccess?: any => any,
waitBeforeSuccess?: number,
},
{
stepIndex: number,
isSuccess: boolean,
// used to be able to display the last check for a small amount of time
showSuccess: boolean,
error: ?Error,
data: Object,
},
> {
state = INITIAL_STATE state = INITIAL_STATE
componentWillUnmount() { componentWillUnmount() {
@ -58,12 +61,11 @@ class DeviceInteraction extends PureComponent<
if (!waitBeforeSuccess) { if (!waitBeforeSuccess) {
onSuccess && onSuccess(data) onSuccess && onSuccess(data)
} }
this.setState({ isSuccess: true, data, showSuccess: !waitBeforeSuccess }) this.setState({ isSuccess: true, data })
if (waitBeforeSuccess) { if (waitBeforeSuccess) {
await delay(waitBeforeSuccess) await delay(waitBeforeSuccess)
if (this._unmounted) return if (this._unmounted) return
onSuccess && onSuccess(data) onSuccess && onSuccess(data)
this.setState({ showSuccess: true })
} }
} else { } else {
this.setState({ stepIndex: stepIndex + 1, data }) this.setState({ stepIndex: stepIndex + 1, data })
@ -82,39 +84,40 @@ class DeviceInteraction extends PureComponent<
} }
render() { render() {
const { steps, renderSuccess, waitBeforeSuccess: _waitBeforeSuccess, ...props } = this.props const { steps, shouldRenderRetry, ...props } = this.props
const { stepIndex, error, isSuccess, data, showSuccess } = this.state const { stepIndex, error, isSuccess, data } = this.state
return ( return (
<DeviceInteractionContainer {...props}> <Box {...props}>
{isSuccess && showSuccess && renderSuccess {steps.map((step, i) => {
? renderSuccess(data) const isError = !!error && i === stepIndex
: steps.map((step, i) => { return (
const isError = !!error && i === stepIndex <DeviceInteractionStep
return ( key={step.id}
<DeviceInteractionStep step={step}
key={step.id} isError={isError}
step={step} isFirst={i === 0}
error={isError ? error : null} isLast={i === steps.length - 1}
isError={isError} isPrecedentActive={i === stepIndex - 1}
isFirst={i === 0} isActive={i === stepIndex}
isLast={i === steps.length - 1} isPassed={i < stepIndex}
isPrecedentActive={i === stepIndex - 1} isSuccess={i < stepIndex || (i === stepIndex && isSuccess)}
isActive={i === stepIndex} onSuccess={this.handleSuccess}
isPassed={i < stepIndex} onFail={this.handleFail}
isSuccess={i < stepIndex || (i === stepIndex && isSuccess)} data={data}
onSuccess={this.handleSuccess} />
onFail={this.handleFail} )
onRetry={this.reset} })}
data={data} {error &&
/> shouldRenderRetry && (
) <Box align="flex-end">
})} <Space of={0} />
</DeviceInteractionContainer> <ErrorDescContainer error={error} onRetry={this.reset} mt={2} />
</Box>
)}
</Box>
) )
} }
} }
const DeviceInteractionContainer = styled(Box).attrs({})``
export default DeviceInteraction export default DeviceInteraction

3
src/components/GenuineCheck.js

@ -101,7 +101,7 @@ class GenuineCheck extends PureComponent<Props> {
} }
render() { render() {
const { onSuccess } = this.props const { onSuccess, ...props } = this.props
const steps = [ const steps = [
{ {
id: 'device', id: 'device',
@ -146,6 +146,7 @@ class GenuineCheck extends PureComponent<Props> {
steps={steps} steps={steps}
onSuccess={onSuccess} onSuccess={onSuccess}
onFail={this.handleFail} onFail={this.handleFail}
{...props}
/> />
) )
} }

13
src/components/ManagerPage/ManagerGenuineCheck.js

@ -21,7 +21,8 @@ class ManagerGenuineCheck extends PureComponent<Props> {
render() { render() {
const { t, onSuccess } = this.props const { t, onSuccess } = this.props
return ( return (
<Box align="center" justify="center" sticky style={{ marginRight: 80 }}> <Box align="center">
<Space of={60} />
<Box align="center" style={{ maxWidth: 460 }}> <Box align="center" style={{ maxWidth: 460 }}>
<img <img
src={i('logos/connectDevice.png')} src={i('logos/connectDevice.png')}
@ -36,15 +37,7 @@ class ManagerGenuineCheck extends PureComponent<Props> {
</Text> </Text>
</Box> </Box>
<Space of={40} /> <Space of={40} />
<GenuineCheck <GenuineCheck shouldRenderRetry onSuccess={onSuccess} />
onSuccess={onSuccess}
onFail={() => {
console.log(`fail`)
}}
onUnavailable={() => {
console.log(`unavailable`)
}}
/>
</Box> </Box>
) )
} }

4
src/components/ManagerPage/index.js

@ -22,9 +22,11 @@ type State = {
class ManagerPage extends PureComponent<Props, State> { class ManagerPage extends PureComponent<Props, State> {
state = { state = {
isGenuine: null, isGenuine: null,
device: null,
deviceInfo: null,
} }
handleSuccessGenuine = ({ device, deviceInfo }) => { handleSuccessGenuine = ({ device, deviceInfo }: { device: Device, deviceInfo: DeviceInfo }) => {
this.setState({ isGenuine: true, device, deviceInfo }) this.setState({ isGenuine: true, device, deviceInfo })
} }

Loading…
Cancel
Save