From ed831d7e79fc1b207a701990290deab3464bfd76 Mon Sep 17 00:00:00 2001 From: meriadec Date: Wed, 13 Jun 2018 21:00:02 +0200 Subject: [PATCH] Factorize AddAccount code and create AccountsList --- .../AccountsList}/AccountRow.js | 2 +- src/components/base/AccountsList/index.js | 98 ++++++++++ src/components/base/AccountsList/stories.js | 30 +++ src/components/base/Box/Box.js | 2 + src/components/base/Box/Tabbable.js | 2 +- src/components/modals/AddAccounts/index.js | 3 +- .../AddAccounts/steps/03-step-import.js | 180 ++++++------------ src/config/global-tab.js | 7 + src/styles/theme.js | 3 - 9 files changed, 204 insertions(+), 123 deletions(-) rename src/components/{modals/AddAccounts => base/AccountsList}/AccountRow.js (98%) create mode 100644 src/components/base/AccountsList/index.js create mode 100644 src/components/base/AccountsList/stories.js create mode 100644 src/config/global-tab.js diff --git a/src/components/modals/AddAccounts/AccountRow.js b/src/components/base/AccountsList/AccountRow.js similarity index 98% rename from src/components/modals/AddAccounts/AccountRow.js rename to src/components/base/AccountsList/AccountRow.js index 32303cd9..26e607f8 100644 --- a/src/components/modals/AddAccounts/AccountRow.js +++ b/src/components/base/AccountsList/AccountRow.js @@ -110,7 +110,7 @@ export default class AccountRow extends PureComponent { fontSize={4} color="grey" /> - + ) } diff --git a/src/components/base/AccountsList/index.js b/src/components/base/AccountsList/index.js new file mode 100644 index 00000000..81714ab9 --- /dev/null +++ b/src/components/base/AccountsList/index.js @@ -0,0 +1,98 @@ +// @flow + +import React from 'react' +import styled from 'styled-components' +import { translate } from 'react-i18next' +import type { Account } from '@ledgerhq/live-common/lib/types' + +import Box from 'components/base/Box' +import FakeLink from 'components/base/FakeLink' +import Spinner from 'components/base/Spinner' +import type { T } from 'types/common' + +import AccountRow from './AccountRow' + +const AccountsList = ({ + accounts, + checkedIds, + onToggleAccount, + onUpdateAccount, + onSelectAll, + onUnselectAll, + isLoading, + title, + emptyText, + t, +}: { + accounts: Account[], + checkedIds: string[], + onToggleAccount: Account => void, + onUpdateAccount: Account => void, + onSelectAll: () => void, + onUnselectAll: () => void, + isLoading?: boolean, + title?: string, + emptyText?: string, + t: T, +}) => { + const withToggleAll = !!onSelectAll && !!onUnselectAll && accounts.length > 1 + const isAllSelected = accounts.every(acc => !!checkedIds.find(id => acc.id === id)) + return ( + + {(title || withToggleAll) && ( + + {title && ( + + {title} + + )} + {withToggleAll && ( + + {isAllSelected ? t('app:addAccounts.unselectAll') : t('app:addAccounts.selectAll')} + + )} + + )} + {accounts.length || isLoading ? ( + + {accounts.map(account => ( + id === account.id) !== undefined} + onClick={onToggleAccount} + onAccountUpdate={onUpdateAccount} + /> + ))} + {isLoading && ( + + + + )} + + ) : emptyText && !isLoading ? ( + + {emptyText} + + ) : null} + + ) +} + +const LoadingRow = styled(Box).attrs({ + horizontal: true, + borderRadius: 1, + px: 3, + align: 'center', + justify: 'center', +})` + height: 48px; + border: 1px dashed ${p => p.theme.colors.grey}; +` + +export default translate()(AccountsList) diff --git a/src/components/base/AccountsList/stories.js b/src/components/base/AccountsList/stories.js new file mode 100644 index 00000000..ba82c2d4 --- /dev/null +++ b/src/components/base/AccountsList/stories.js @@ -0,0 +1,30 @@ +// @flow + +import React from 'react' +import { genAccount } from '@ledgerhq/live-common/lib/mock/account' +import { storiesOf } from '@storybook/react' +import { action } from '@storybook/addon-actions' +import { boolean, text } from '@storybook/addon-knobs' + +import AccountsList from 'components/base/AccountsList' + +const stories = storiesOf('Components/base', module) + +const ACCOUNTS = [genAccount('a'), genAccount('b'), genAccount('c')] + +const CHECKED_IDS = [] + +stories.add('AccountsList', () => ( +
+ +
+)) diff --git a/src/components/base/Box/Box.js b/src/components/base/Box/Box.js index 8141f7f9..48f6246e 100644 --- a/src/components/base/Box/Box.js +++ b/src/components/base/Box/Box.js @@ -18,6 +18,7 @@ import fontFamily from 'styles/styled/fontFamily' export const styledTextAlign = style({ prop: 'textAlign', cssProperty: 'textAlign' }) export const styledCursor = style({ prop: 'cursor', cssProperty: 'cursor' }) +export const styledTextTransform = style({ prop: 'textTransform', cssProperty: 'textTransform' }) export default styled.div` ${alignItems}; @@ -32,6 +33,7 @@ export default styled.div` ${space}; ${styledTextAlign}; ${styledCursor}; + ${styledTextTransform}; display: flex; flex-shrink: ${p => (p.noShrink === true ? '0' : p.shrink === true ? '1' : '')}; diff --git a/src/components/base/Box/Tabbable.js b/src/components/base/Box/Tabbable.js index 7ce573c7..7a54d3ab 100644 --- a/src/components/base/Box/Tabbable.js +++ b/src/components/base/Box/Tabbable.js @@ -3,7 +3,7 @@ import React, { Component } from 'react' import styled from 'styled-components' -import { isGlobalTabEnabled } from 'renderer/init' +import { isGlobalTabEnabled } from 'config/global-tab' import { rgba } from 'styles/helpers' import Box from './Box' diff --git a/src/components/modals/AddAccounts/index.js b/src/components/modals/AddAccounts/index.js index ca712357..9e9a0858 100644 --- a/src/components/modals/AddAccounts/index.js +++ b/src/components/modals/AddAccounts/index.js @@ -130,9 +130,10 @@ class AddAccounts extends PureComponent { }) transitionTo = stepId => { + const { currency } = this.state let nextState = { stepId } if (stepId === 'chooseCurrency') { - nextState = { ...INITIAL_STATE } + nextState = { ...INITIAL_STATE, currency } } this.setState(nextState) } diff --git a/src/components/modals/AddAccounts/steps/03-step-import.js b/src/components/modals/AddAccounts/steps/03-step-import.js index 528d1d7c..0472d33e 100644 --- a/src/components/modals/AddAccounts/steps/03-step-import.js +++ b/src/components/modals/AddAccounts/steps/03-step-import.js @@ -1,7 +1,6 @@ // @flow -import React, { PureComponent } from 'react' -import styled from 'styled-components' +import React, { PureComponent, Fragment } from 'react' import type { Account } from '@ledgerhq/live-common/lib/types' import uniq from 'lodash/uniq' @@ -9,12 +8,9 @@ import { getBridgeForCurrency } from 'bridge' import Box from 'components/base/Box' import Button from 'components/base/Button' -import Spinner from 'components/base/Spinner' -import FakeLink from 'components/base/FakeLink' +import AccountsList from 'components/base/AccountsList' import IconExchange from 'icons/Exchange' -import AccountRow from '../AccountRow' - import type { StepProps } from '../index' class StepImport extends PureComponent { @@ -101,7 +97,7 @@ class StepImport extends PureComponent { } } - handleAccountUpdate = (updatedAccount: Account) => { + handleUpdateAccount = (updatedAccount: Account) => { const { scannedAccounts, setState } = this.props setState({ scannedAccounts: scannedAccounts.map(account => { @@ -123,7 +119,15 @@ class StepImport extends PureComponent { handleUnselectAll = () => this.props.setState({ checkedAccountsIds: [] }) render() { - const { scanStatus, err, scannedAccounts, checkedAccountsIds, existingAccounts, t } = this.props + const { + scanStatus, + currency, + err, + scannedAccounts, + checkedAccountsIds, + existingAccounts, + t, + } = this.props const importableAccounts = scannedAccounts.filter(acc => { if (acc.operations.length <= 0) { @@ -139,124 +143,63 @@ class StepImport extends PureComponent { return existingAccounts.find(a => a.id === acc.id) === undefined }) - const isAllSelected = scannedAccounts.filter(acc => acc.operations.length > 0).every(acc => { - const isChecked = !!checkedAccountsIds.find(id => acc.id === id) - const isImported = !!existingAccounts.find(a => acc.id === a.id) - return isChecked || isImported + const importableAccountsListTitle = t('app:addAccounts.accountToImportSubtitle', { + count: importableAccounts.length, }) - return ( - - {err && {err.message}} + const importableAccountsEmpty = `We didnt find any ${ + currency ? ` ${currency.name}}` : '' + } account to import.` + return ( + - {(!!importableAccounts.length || scanStatus === 'scanning') && ( - - {!!importableAccounts.length && ( - - - {t('app:addAccounts.accountToImportSubtitle', { - count: importableAccounts.length, - })} - - - {isAllSelected - ? t('app:addAccounts.unselectAll') - : t('app:addAccounts.selectAll')} - - - )} - - - {importableAccounts.map(account => { - const isChecked = checkedAccountsIds.find(id => id === account.id) !== undefined - const existingAccount = existingAccounts.find(a => a.id === account.id) - const isDisabled = existingAccount !== undefined - return ( - - ) - })} - - {scanStatus === 'scanning' && ( - - - - )} - - - )} - - {creatableAccounts.length > 0 && ( - - - - {t('app:addAccounts.createNewAccount')} - - - id === creatableAccounts[0].id) !== undefined - } - onClick={this.handleToggleAccount} - onAccountUpdate={this.handleAccountUpdate} - /> - - )} + + - - {['error'].includes(scanStatus) && ( + {err && ( + + {err.message} - )} - - + + )} + ) } } export default StepImport -export const LoadingRow = styled(Box).attrs({ - horizontal: true, - borderRadius: 1, - px: 3, - align: 'center', - justify: 'center', -})` - height: 48px; - border: 1px dashed ${p => p.theme.colors.fog}; -` - export const StepImportFooter = ({ scanStatus, onClickAdd, + onCloseModal, checkedAccountsIds, scannedAccounts, t, @@ -277,20 +220,23 @@ export const StepImportFooter = ({ }).length const ctaWording = - willCreateAccount && willAddAccounts - ? `${t('app:addAccounts.cta.create')} / ${t('app:addAccounts.cta.import', { - count: addedAccountsCount, - })}` - : willCreateAccount - ? t('app:addAccounts.cta.create') - : t('app:addAccounts.cta.import', { count: addedAccountsCount }) + scanStatus === 'scanning' + ? t('app:common.sync.syncing') + : willCreateAccount && willAddAccounts + ? `${t('app:addAccounts.cta.create')} / ${t('app:addAccounts.cta.import', { + count: addedAccountsCount, + })}` + : willCreateAccount + ? t('app:addAccounts.cta.create') + : willAddAccounts + ? t('app:addAccounts.cta.import', { count: addedAccountsCount }) + : t('app:common.close') + + const willClose = !willCreateAccount && !willAddAccounts + const onClick = willClose ? onCloseModal : onClickAdd return ( - ) diff --git a/src/config/global-tab.js b/src/config/global-tab.js new file mode 100644 index 00000000..ef64345f --- /dev/null +++ b/src/config/global-tab.js @@ -0,0 +1,7 @@ +// Github like focus style: +// - focus states are not visible by default +// - first time user hit tab, enable global tab to see focus states +let IS_GLOBAL_TAB_ENABLED = false + +export const isGlobalTabEnabled = () => IS_GLOBAL_TAB_ENABLED +export const enableGlobalTab = () => (IS_GLOBAL_TAB_ENABLED = true) diff --git a/src/styles/theme.js b/src/styles/theme.js index 15dd9de7..4914185f 100644 --- a/src/styles/theme.js +++ b/src/styles/theme.js @@ -1,7 +1,5 @@ // @flow -import { rgba } from 'styles/helpers' - export const space = [0, 5, 10, 15, 20, 30, 40, 50, 70] export const fontSizes = [8, 9, 10, 12, 13, 16, 18, 22, 32] export const radii = [0, 4] @@ -95,7 +93,6 @@ export default { topBarHeight: 58, sideBarWidth: 230, }, - focusBoxShadow: `${rgba(colors.wallet, 0.2)} 0 2px 5px`, radii, fontFamilies, fontSizes,