meriadec
7 years ago
15 changed files with 442 additions and 324 deletions
@ -1,99 +1,127 @@ |
|||||
// @flow
|
// @flow
|
||||
|
|
||||
import React from 'react' |
import React, { Component } from 'react' |
||||
import styled from 'styled-components' |
|
||||
import { translate } from 'react-i18next' |
import { translate } from 'react-i18next' |
||||
import type { Account } from '@ledgerhq/live-common/lib/types' |
import type { Account } from '@ledgerhq/live-common/lib/types' |
||||
|
|
||||
import Box from 'components/base/Box' |
import Box from 'components/base/Box' |
||||
import FakeLink from 'components/base/FakeLink' |
import FakeLink from 'components/base/FakeLink' |
||||
import Spinner from 'components/base/Spinner' |
|
||||
import type { T } from 'types/common' |
import type { T } from 'types/common' |
||||
|
import { SpoilerIcon } from '../Spoiler' |
||||
|
|
||||
import AccountRow from './AccountRow' |
import AccountRow from './AccountRow' |
||||
|
|
||||
const AccountsList = ({ |
class AccountsList extends Component< |
||||
accounts, |
{ |
||||
checkedIds, |
accounts: Account[], |
||||
onToggleAccount, |
checkedIds?: string[], |
||||
onUpdateAccount, |
editedNames: { [accountId: string]: string }, |
||||
onSelectAll, |
setAccountName?: (Account, string) => void, |
||||
onUnselectAll, |
onToggleAccount?: Account => void, |
||||
isLoading, |
onSelectAll?: (Account[]) => void, |
||||
title, |
onUnselectAll?: (Account[]) => void, |
||||
emptyText, |
title?: string, |
||||
t, |
emptyText?: string, |
||||
}: { |
autoFocusFirstInput?: boolean, |
||||
accounts: Account[], |
collapsible?: boolean, |
||||
checkedIds: string[], |
t: T, |
||||
onToggleAccount: Account => void, |
}, |
||||
onUpdateAccount: Account => void, |
{ |
||||
onSelectAll: () => void, |
collapsed: boolean, |
||||
onUnselectAll: () => void, |
}, |
||||
isLoading?: boolean, |
> { |
||||
title?: string, |
state = { |
||||
emptyText?: string, |
collapsed: false, |
||||
t: T, |
} |
||||
}) => { |
toggleCollapse = () => { |
||||
const withToggleAll = !!onSelectAll && !!onUnselectAll && accounts.length > 1 |
this.setState(({ collapsed }) => ({ collapsed: !collapsed })) |
||||
const isAllSelected = accounts.every(acc => !!checkedIds.find(id => acc.id === id)) |
} |
||||
return ( |
onSelectAll = () => { |
||||
<Box flow={3}> |
const { accounts, onSelectAll } = this.props |
||||
{(title || withToggleAll) && ( |
if (onSelectAll) onSelectAll(accounts) |
||||
<Box horizontal align="center"> |
} |
||||
{title && ( |
onUnselectAll = () => { |
||||
<Box ff="Open Sans|Bold" color="dark" fontSize={2} textTransform="uppercase"> |
const { accounts, onUnselectAll } = this.props |
||||
{title} |
if (onUnselectAll) onUnselectAll(accounts) |
||||
</Box> |
} |
||||
)} |
render() { |
||||
{withToggleAll && ( |
const { |
||||
<FakeLink |
accounts, |
||||
ml="auto" |
checkedIds, |
||||
onClick={isAllSelected ? onUnselectAll : onSelectAll} |
onToggleAccount, |
||||
fontSize={3} |
editedNames, |
||||
style={{ lineHeight: '10px' }} |
setAccountName, |
||||
> |
onSelectAll, |
||||
{isAllSelected ? t('app:addAccounts.unselectAll') : t('app:addAccounts.selectAll')} |
onUnselectAll, |
||||
</FakeLink> |
title, |
||||
)} |
emptyText, |
||||
</Box> |
autoFocusFirstInput, |
||||
)} |
collapsible, |
||||
{accounts.length || isLoading ? ( |
t, |
||||
<Box flow={2}> |
} = this.props |
||||
{accounts.map(account => ( |
const { collapsed } = this.state |
||||
<AccountRow |
const withToggleAll = !!onSelectAll && !!onUnselectAll && accounts.length > 1 |
||||
key={account.id} |
const isAllSelected = |
||||
account={account} |
!checkedIds || accounts.every(acc => !!checkedIds.find(id => acc.id === id)) |
||||
isChecked={checkedIds.find(id => id === account.id) !== undefined} |
return ( |
||||
onClick={onToggleAccount} |
<Box flow={3} mt={4}> |
||||
onAccountUpdate={onUpdateAccount} |
{(title || withToggleAll) && ( |
||||
t={t} |
<Box horizontal align="center"> |
||||
/> |
{title && ( |
||||
))} |
<Box |
||||
{isLoading && ( |
horizontal |
||||
<LoadingRow> |
ff="Open Sans|Bold" |
||||
<Spinner color="grey" size={16} /> |
color="dark" |
||||
</LoadingRow> |
fontSize={2} |
||||
)} |
textTransform="uppercase" |
||||
</Box> |
cursor={collapsible ? 'pointer' : undefined} |
||||
) : emptyText && !isLoading ? ( |
onClick={collapsible ? this.toggleCollapse : undefined} |
||||
<Box ff="Open Sans|Regular" fontSize={3}> |
> |
||||
{emptyText} |
{collapsible ? <SpoilerIcon isOpened={!collapsed} mr={1} /> : null} |
||||
</Box> |
{title} |
||||
) : null} |
</Box> |
||||
</Box> |
)} |
||||
) |
{withToggleAll && ( |
||||
|
<FakeLink |
||||
|
ml="auto" |
||||
|
onClick={isAllSelected ? this.onUnselectAll : this.onSelectAll} |
||||
|
fontSize={3} |
||||
|
style={{ lineHeight: '10px' }} |
||||
|
> |
||||
|
{isAllSelected |
||||
|
? t('app:addAccounts.unselectAll', { count: accounts.length }) |
||||
|
: t('app:addAccounts.selectAll', { count: accounts.length })} |
||||
|
</FakeLink> |
||||
|
)} |
||||
|
</Box> |
||||
|
)} |
||||
|
{collapsed ? null : accounts.length ? ( |
||||
|
<Box flow={2}> |
||||
|
{accounts.map((account, i) => ( |
||||
|
<AccountRow |
||||
|
key={account.id} |
||||
|
account={account} |
||||
|
autoFocusInput={i === 0 && autoFocusFirstInput} |
||||
|
isDisabled={!onToggleAccount || !checkedIds} |
||||
|
isChecked={!checkedIds || checkedIds.find(id => id === account.id) !== undefined} |
||||
|
onToggleAccount={onToggleAccount} |
||||
|
onEditName={setAccountName} |
||||
|
accountName={ |
||||
|
typeof editedNames[account.id] === 'string' |
||||
|
? editedNames[account.id] |
||||
|
: account.name |
||||
|
} |
||||
|
/> |
||||
|
))} |
||||
|
</Box> |
||||
|
) : emptyText ? ( |
||||
|
<Box ff="Open Sans|Regular" fontSize={3}> |
||||
|
{emptyText} |
||||
|
</Box> |
||||
|
) : null} |
||||
|
</Box> |
||||
|
) |
||||
|
} |
||||
} |
} |
||||
|
|
||||
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) |
export default translate()(AccountsList) |
||||
|
@ -1,10 +1,19 @@ |
|||||
// @flow
|
// @flow
|
||||
import type { CryptoCurrency } from '@ledgerhq/live-common/lib/types' |
import type { Account, CryptoCurrency } from '@ledgerhq/live-common/lib/types' |
||||
|
import { MAX_ACCOUNT_NAME_SIZE } from 'config/constants' |
||||
|
|
||||
export const getAccountPlaceholderName = ( |
export const getAccountPlaceholderName = ( |
||||
c: CryptoCurrency, |
c: CryptoCurrency, |
||||
index: number, |
index: number, |
||||
isLegacy: boolean = false, |
isLegacy: boolean = false, |
||||
) => `${c.name} ${index}${isLegacy ? ' (legacy)' : ''}` |
) => `${c.name} ${index + 1}${isLegacy ? ' (legacy)' : ''}` |
||||
|
|
||||
export const getNewAccountPlaceholderName = (_c: CryptoCurrency, _index: number) => `New Account` |
export const getNewAccountPlaceholderName = getAccountPlaceholderName // same naming
|
||||
|
// export const getNewAccountPlaceholderName = (_c: CryptoCurrency, _index: number) => `New Account`
|
||||
|
|
||||
|
export const validateNameEdition = (account: Account, name: ?string): string => |
||||
|
( |
||||
|
(name || account.name || '').replace(/\s+/g, ' ').trim() || |
||||
|
account.name || |
||||
|
getAccountPlaceholderName(account.currency, account.index) |
||||
|
).slice(0, MAX_ACCOUNT_NAME_SIZE) |
||||
|
Loading…
Reference in new issue