Browse Source

Merge pull request #656 from meriadec/activity-indicator-error

Display error tooltip in ActivityIndicator
master
Gaëtan Renaudeau 7 years ago
committed by GitHub
parent
commit
d1a81fb5cf
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 29
      src/components/TopBar/ActivityIndicator.js
  2. 17
      src/components/base/Tooltip/index.js

29
src/components/TopBar/ActivityIndicator.js

@ -14,6 +14,8 @@ import { BridgeSyncConsumer } from 'bridge/BridgeSyncContext'
import CounterValues from 'helpers/countervalues' import CounterValues from 'helpers/countervalues'
import { Rotating } from 'components/base/Spinner' import { Rotating } from 'components/base/Spinner'
import Tooltip from 'components/base/Tooltip'
import TranslatedError from 'components/TranslatedError'
import Box from 'components/base/Box' import Box from 'components/base/Box'
import IconRefresh from 'icons/Refresh' import IconRefresh from 'icons/Refresh'
import IconExclamationCircle from 'icons/ExclamationCircle' import IconExclamationCircle from 'icons/ExclamationCircle'
@ -28,6 +30,7 @@ type Props = {
// FIXME: eslint should see that it is used in static method // FIXME: eslint should see that it is used in static method
isGlobalSyncStatePending: boolean, // eslint-disable-line react/no-unused-prop-types isGlobalSyncStatePending: boolean, // eslint-disable-line react/no-unused-prop-types
error: ?Error,
isPending: boolean, isPending: boolean,
isError: boolean, isError: boolean,
t: T, t: T,
@ -75,12 +78,12 @@ class ActivityIndicatorInner extends PureComponent<Props, State> {
} }
render() { render() {
const { isPending, isError, t } = this.props const { isPending, isError, error, t } = this.props
const { hasClicked, isFirstSync } = this.state const { hasClicked, isFirstSync } = this.state
const isDisabled = isError || (isPending && (isFirstSync || hasClicked)) const isDisabled = isError || (isPending && (isFirstSync || hasClicked))
const isRotating = isPending && (hasClicked || isFirstSync) const isRotating = isPending && (hasClicked || isFirstSync)
return ( const content = (
<ItemContainer disabled={isDisabled} onClick={isDisabled ? undefined : this.handleRefresh}> <ItemContainer disabled={isDisabled} onClick={isDisabled ? undefined : this.handleRefresh}>
<Rotating <Rotating
size={16} size={16}
@ -123,6 +126,23 @@ class ActivityIndicatorInner extends PureComponent<Props, State> {
</Box> </Box>
</ItemContainer> </ItemContainer>
) )
if (error) {
return (
<Tooltip
tooltipBg="alertRed"
render={() => (
<Box fontSize={4} p={2} style={{ maxWidth: 250 }}>
<TranslatedError error={error} />
</Box>
)}
>
{content}
</Tooltip>
)
}
return content
} }
} }
@ -132,13 +152,14 @@ const ActivityIndicator = ({ globalSyncState, t }: { globalSyncState: AsyncState
<CounterValues.PollingConsumer> <CounterValues.PollingConsumer>
{cvPolling => { {cvPolling => {
const isPending = cvPolling.pending || globalSyncState.pending const isPending = cvPolling.pending || globalSyncState.pending
const isError = cvPolling.error || globalSyncState.error const isError = !isPending && (cvPolling.error || globalSyncState.error)
return ( return (
<ActivityIndicatorInner <ActivityIndicatorInner
t={t} t={t}
isPending={isPending} isPending={isPending}
isGlobalSyncStatePending={globalSyncState.pending} isGlobalSyncStatePending={globalSyncState.pending}
isError={!!isError && !isPending} isError={!!isError}
error={isError ? globalSyncState.error : null}
cvPoll={cvPolling.poll} cvPoll={cvPolling.poll}
setSyncBehavior={setSyncBehavior} setSyncBehavior={setSyncBehavior}
/> />

17
src/components/base/Tooltip/index.js

@ -20,15 +20,17 @@ export const TooltipContainer = ({
children, children,
innerRef, innerRef,
style, style,
tooltipBg,
}: { }: {
children: any, children: any,
innerRef?: Function, innerRef?: Function,
style?: Object, style?: Object,
tooltipBg?: string,
}) => ( }) => (
<div <div
ref={innerRef} ref={innerRef}
style={{ style={{
background: colors.dark, background: colors[tooltipBg || 'dark'],
borderRadius: 4, borderRadius: 4,
color: 'white', color: 'white',
fontFamily: 'Open Sans', fontFamily: 'Open Sans',
@ -51,6 +53,7 @@ type Props = {
offset?: Array<number>, offset?: Array<number>,
children: any, children: any,
render: Function, render: Function,
tooltipBg?: string,
} }
class Tooltip extends PureComponent<Props> { class Tooltip extends PureComponent<Props> {
@ -59,7 +62,7 @@ class Tooltip extends PureComponent<Props> {
} }
componentDidMount() { componentDidMount() {
const { offset } = this.props const { offset, tooltipBg } = this.props
if (this._node && this._template) { if (this._node && this._template) {
tippy(this._node, { tippy(this._node, {
@ -76,7 +79,9 @@ class Tooltip extends PureComponent<Props> {
if (this._node && this._node._tippy) { if (this._node && this._node._tippy) {
this._node._tippy.popper.querySelector('.tippy-roundarrow').innerHTML = ` this._node._tippy.popper.querySelector('.tippy-roundarrow').innerHTML = `
<svg viewBox="0 0 24 8"> <svg viewBox="0 0 24 8">
<path d="M5 8l5.5-5.6c.8-.8 2-.8 2.8 0L19 8" /> <path${
tooltipBg ? ` fill="${colors[tooltipBg]}"` : ''
} d="M5 8l5.5-5.6c.8-.8 2-.8 2.8 0L19 8" />
</svg>` </svg>`
} }
} }
@ -86,12 +91,14 @@ class Tooltip extends PureComponent<Props> {
_template = undefined _template = undefined
render() { render() {
const { children, render, ...props } = this.props const { children, render, tooltipBg, ...props } = this.props
return ( return (
<Container innerRef={n => (this._node = n)} {...props}> <Container innerRef={n => (this._node = n)} {...props}>
<Template> <Template>
<TooltipContainer innerRef={n => (this._template = n)}>{render()}</TooltipContainer> <TooltipContainer tooltipBg={tooltipBg} innerRef={n => (this._template = n)}>
{render()}
</TooltipContainer>
</Template> </Template>
{children} {children}
</Container> </Container>

Loading…
Cancel
Save