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: Account[], |
||||
|
checkedIds?: string[], |
||||
|
editedNames: { [accountId: string]: string }, |
||||
|
setAccountName?: (Account, string) => void, |
||||
|
onToggleAccount?: Account => void, |
||||
|
onSelectAll?: (Account[]) => void, |
||||
|
onUnselectAll?: (Account[]) => void, |
||||
|
title?: string, |
||||
|
emptyText?: string, |
||||
|
autoFocusFirstInput?: boolean, |
||||
|
collapsible?: boolean, |
||||
|
t: T, |
||||
|
}, |
||||
|
{ |
||||
|
collapsed: boolean, |
||||
|
}, |
||||
|
> { |
||||
|
state = { |
||||
|
collapsed: false, |
||||
|
} |
||||
|
toggleCollapse = () => { |
||||
|
this.setState(({ collapsed }) => ({ collapsed: !collapsed })) |
||||
|
} |
||||
|
onSelectAll = () => { |
||||
|
const { accounts, onSelectAll } = this.props |
||||
|
if (onSelectAll) onSelectAll(accounts) |
||||
|
} |
||||
|
onUnselectAll = () => { |
||||
|
const { accounts, onUnselectAll } = this.props |
||||
|
if (onUnselectAll) onUnselectAll(accounts) |
||||
|
} |
||||
|
render() { |
||||
|
const { |
||||
accounts, |
accounts, |
||||
checkedIds, |
checkedIds, |
||||
onToggleAccount, |
onToggleAccount, |
||||
onUpdateAccount, |
editedNames, |
||||
|
setAccountName, |
||||
onSelectAll, |
onSelectAll, |
||||
onUnselectAll, |
onUnselectAll, |
||||
isLoading, |
|
||||
title, |
title, |
||||
emptyText, |
emptyText, |
||||
|
autoFocusFirstInput, |
||||
|
collapsible, |
||||
t, |
t, |
||||
}: { |
} = this.props |
||||
accounts: Account[], |
const { collapsed } = this.state |
||||
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 withToggleAll = !!onSelectAll && !!onUnselectAll && accounts.length > 1 |
||||
const isAllSelected = accounts.every(acc => !!checkedIds.find(id => acc.id === id)) |
const isAllSelected = |
||||
|
!checkedIds || accounts.every(acc => !!checkedIds.find(id => acc.id === id)) |
||||
return ( |
return ( |
||||
<Box flow={3}> |
<Box flow={3} mt={4}> |
||||
{(title || withToggleAll) && ( |
{(title || withToggleAll) && ( |
||||
<Box horizontal align="center"> |
<Box horizontal align="center"> |
||||
{title && ( |
{title && ( |
||||
<Box ff="Open Sans|Bold" color="dark" fontSize={2} textTransform="uppercase"> |
<Box |
||||
|
horizontal |
||||
|
ff="Open Sans|Bold" |
||||
|
color="dark" |
||||
|
fontSize={2} |
||||
|
textTransform="uppercase" |
||||
|
cursor={collapsible ? 'pointer' : undefined} |
||||
|
onClick={collapsible ? this.toggleCollapse : undefined} |
||||
|
> |
||||
|
{collapsible ? <SpoilerIcon isOpened={!collapsed} mr={1} /> : null} |
||||
{title} |
{title} |
||||
</Box> |
</Box> |
||||
)} |
)} |
||||
{withToggleAll && ( |
{withToggleAll && ( |
||||
<FakeLink |
<FakeLink |
||||
ml="auto" |
ml="auto" |
||||
onClick={isAllSelected ? onUnselectAll : onSelectAll} |
onClick={isAllSelected ? this.onUnselectAll : this.onSelectAll} |
||||
fontSize={3} |
fontSize={3} |
||||
style={{ lineHeight: '10px' }} |
style={{ lineHeight: '10px' }} |
||||
> |
> |
||||
{isAllSelected ? t('app:addAccounts.unselectAll') : t('app:addAccounts.selectAll')} |
{isAllSelected |
||||
|
? t('app:addAccounts.unselectAll', { count: accounts.length }) |
||||
|
: t('app:addAccounts.selectAll', { count: accounts.length })} |
||||
</FakeLink> |
</FakeLink> |
||||
)} |
)} |
||||
</Box> |
</Box> |
||||
)} |
)} |
||||
{accounts.length || isLoading ? ( |
{collapsed ? null : accounts.length ? ( |
||||
<Box flow={2}> |
<Box flow={2}> |
||||
{accounts.map(account => ( |
{accounts.map((account, i) => ( |
||||
<AccountRow |
<AccountRow |
||||
key={account.id} |
key={account.id} |
||||
account={account} |
account={account} |
||||
isChecked={checkedIds.find(id => id === account.id) !== undefined} |
autoFocusInput={i === 0 && autoFocusFirstInput} |
||||
onClick={onToggleAccount} |
isDisabled={!onToggleAccount || !checkedIds} |
||||
onAccountUpdate={onUpdateAccount} |
isChecked={!checkedIds || checkedIds.find(id => id === account.id) !== undefined} |
||||
t={t} |
onToggleAccount={onToggleAccount} |
||||
|
onEditName={setAccountName} |
||||
|
accountName={ |
||||
|
typeof editedNames[account.id] === 'string' |
||||
|
? editedNames[account.id] |
||||
|
: account.name |
||||
|
} |
||||
/> |
/> |
||||
))} |
))} |
||||
{isLoading && ( |
|
||||
<LoadingRow> |
|
||||
<Spinner color="grey" size={16} /> |
|
||||
</LoadingRow> |
|
||||
)} |
|
||||
</Box> |
</Box> |
||||
) : emptyText && !isLoading ? ( |
) : emptyText ? ( |
||||
<Box ff="Open Sans|Regular" fontSize={3}> |
<Box ff="Open Sans|Regular" fontSize={3}> |
||||
{emptyText} |
{emptyText} |
||||
</Box> |
</Box> |
||||
) : null} |
) : null} |
||||
</Box> |
</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