Choose accounts refactor (#13039)
* added wrapper around account list to prevent storybook from collapsing the list * updated translation files * added snap-connect page * refactored account list out of the choose account component * fixed width * removed unnecessary scss from choose-account component, fixed props in choose account story * removed snaps-connect page, added comments to ChooseAccount * updated choose account subtitle text, updated styling for title & subtitle, removed redundant account list story * updated component name, updated paths * fixed linter errors * added comments * removed unused message * removed selectAccounts key from all locales * updated class name for account list header, updated allAreSelected function to use length checks * Revert "removed unused message" This reverts commit 32771bc83c08f120825ef75f0741f3034e7dbecb. * Revert "removed selectAccounts key from all locales" This reverts commit ccfa4a860f9a75693d893d7c404384e719de297e. * updated locale messages to use selectAccounts key * removed stray import * updated scss * updated translation key * removed chooseAccounts key from en locale * removed optional chaining * changes * updated subjectMetadata * updated subject types * update useOriginMetadata function to include unknown subject type * updated permission connect header props, removed host and added subjectType to targetSubjectMetadata * added subjectType to targetSubjectMetadata * removed console.log * changed prop name to iconUrlfeature/default_network_editable
parent
8cc185a8b1
commit
f946c030b5
@ -0,0 +1,175 @@ |
||||
import React from 'react'; |
||||
import PropTypes from 'prop-types'; |
||||
import classnames from 'classnames'; |
||||
import { useI18nContext } from '../../../hooks/useI18nContext'; |
||||
import CheckBox, { CHECKED, INDETERMINATE, UNCHECKED } from '../check-box'; |
||||
import Identicon from '../identicon'; |
||||
import UserPreferencedCurrencyDisplay from '../../app/user-preferenced-currency-display'; |
||||
import { PRIMARY } from '../../../helpers/constants/common'; |
||||
import Tooltip from '../tooltip'; |
||||
|
||||
const AccountList = ({ |
||||
selectNewAccountViaModal, |
||||
accounts, |
||||
addressLastConnectedMap, |
||||
selectedAccounts, |
||||
nativeCurrency, |
||||
allAreSelected, |
||||
deselectAll, |
||||
selectAll, |
||||
handleAccountClick, |
||||
}) => { |
||||
const t = useI18nContext(); |
||||
|
||||
const Header = () => { |
||||
let checked; |
||||
if (allAreSelected()) { |
||||
checked = CHECKED; |
||||
} else if (selectedAccounts.size === 0) { |
||||
checked = UNCHECKED; |
||||
} else { |
||||
checked = INDETERMINATE; |
||||
} |
||||
|
||||
return ( |
||||
<div |
||||
className={classnames({ |
||||
'choose-account-list__header--one-item': accounts.length === 1, |
||||
'choose-account-list__header--multiple-items': accounts.length > 1, |
||||
})} |
||||
> |
||||
{accounts.length > 1 ? ( |
||||
<div className="choose-account-list__select-all"> |
||||
<CheckBox |
||||
className="choose-account-list__header-check-box" |
||||
checked={checked} |
||||
onClick={() => (allAreSelected() ? deselectAll() : selectAll())} |
||||
/> |
||||
<div className="choose-account-list__text-grey"> |
||||
{t('selectAll')} |
||||
</div> |
||||
<Tooltip |
||||
position="bottom" |
||||
html={ |
||||
<div style={{ width: 200, padding: 4 }}> |
||||
{t('selectingAllWillAllow')} |
||||
</div> |
||||
} |
||||
> |
||||
<i className="fa fa-info-circle" /> |
||||
</Tooltip> |
||||
</div> |
||||
) : null} |
||||
<div |
||||
className="choose-account-list__text-blue" |
||||
onClick={() => selectNewAccountViaModal(handleAccountClick)} |
||||
> |
||||
{t('newAccount')} |
||||
</div> |
||||
</div> |
||||
); |
||||
}; |
||||
|
||||
const List = () => { |
||||
return ( |
||||
<div className="choose-account-list__wrapper"> |
||||
<div className="choose-account-list__list"> |
||||
{accounts.map((account, index) => { |
||||
const { address, addressLabel, balance } = account; |
||||
return ( |
||||
<div |
||||
key={`choose-account-list-${index}`} |
||||
onClick={() => handleAccountClick(address)} |
||||
className="choose-account-list__account" |
||||
> |
||||
<div className="choose-account-list__account-info-wrapper"> |
||||
<CheckBox |
||||
className="choose-account-list__list-check-box" |
||||
checked={selectedAccounts.has(address)} |
||||
/> |
||||
<Identicon diameter={34} address={address} /> |
||||
<div className="choose-account-list__account__info"> |
||||
<div className="choose-account-list__account__label"> |
||||
{addressLabel} |
||||
</div> |
||||
<UserPreferencedCurrencyDisplay |
||||
className="choose-account-list__account__balance" |
||||
type={PRIMARY} |
||||
value={balance} |
||||
style={{ color: '#6A737D' }} |
||||
suffix={nativeCurrency} |
||||
/> |
||||
</div> |
||||
</div> |
||||
{addressLastConnectedMap[address] ? ( |
||||
<Tooltip |
||||
title={`${t('lastConnected')} ${ |
||||
addressLastConnectedMap[address] |
||||
}`}
|
||||
> |
||||
<i className="fa fa-info-circle" /> |
||||
</Tooltip> |
||||
) : null} |
||||
</div> |
||||
); |
||||
})} |
||||
</div> |
||||
</div> |
||||
); |
||||
}; |
||||
|
||||
return ( |
||||
<div className="choose-account-list"> |
||||
<Header /> |
||||
<List /> |
||||
</div> |
||||
); |
||||
}; |
||||
|
||||
AccountList.propTypes = { |
||||
/** |
||||
* Array of user account objects |
||||
*/ |
||||
accounts: PropTypes.arrayOf( |
||||
PropTypes.shape({ |
||||
address: PropTypes.string, |
||||
addressLabel: PropTypes.string, |
||||
lastConnectedDate: PropTypes.string, |
||||
balance: PropTypes.string, |
||||
}), |
||||
).isRequired, |
||||
/** |
||||
* Function to select a new account via modal |
||||
*/ |
||||
selectNewAccountViaModal: PropTypes.func.isRequired, |
||||
/** |
||||
* A map of the last connected addresses |
||||
*/ |
||||
addressLastConnectedMap: PropTypes.object, |
||||
/** |
||||
* Native currency of current chain |
||||
*/ |
||||
nativeCurrency: PropTypes.string.isRequired, |
||||
/** |
||||
* Currently selected accounts |
||||
*/ |
||||
selectedAccounts: PropTypes.object.isRequired, |
||||
/** |
||||
* Function to check if all accounts are selected |
||||
*/ |
||||
allAreSelected: PropTypes.func.isRequired, |
||||
/** |
||||
* Function to deselect all accounts |
||||
*/ |
||||
deselectAll: PropTypes.func.isRequired, |
||||
/** |
||||
* Function to select all accounts |
||||
*/ |
||||
selectAll: PropTypes.func.isRequired, |
||||
/** |
||||
* Function to handle account click |
||||
*/ |
||||
handleAccountClick: PropTypes.func.isRequired, |
||||
}; |
||||
|
||||
export default AccountList; |
@ -0,0 +1 @@ |
||||
export { default } from './account-list'; |
@ -0,0 +1,140 @@ |
||||
.choose-account-list { |
||||
display: flex; |
||||
flex-direction: column; |
||||
width: 100%; |
||||
height: 100%; |
||||
align-items: center; |
||||
|
||||
&__header--one-item, |
||||
&__header--multiple-items { |
||||
display: flex; |
||||
flex: 0; |
||||
margin-top: 36px; |
||||
width: 100%; |
||||
padding-inline-start: 15px; |
||||
padding-inline-end: 17px; |
||||
} |
||||
|
||||
&__header--one-item { |
||||
justify-content: flex-end; |
||||
} |
||||
|
||||
&__header--multiple-items { |
||||
justify-content: space-between; |
||||
} |
||||
|
||||
&__select-all { |
||||
display: flex; |
||||
margin-inline-start: 16px; |
||||
align-items: center; |
||||
} |
||||
|
||||
&__header-check-box { |
||||
margin-right: 16px; |
||||
} |
||||
|
||||
&__wrapper { |
||||
width: 92%; |
||||
display: flex; |
||||
} |
||||
|
||||
&__list { |
||||
flex: 2 1 0; |
||||
width: 92%; |
||||
max-height: max-content; |
||||
border: 1px solid #d0d5da; |
||||
box-sizing: border-box; |
||||
border-radius: 8px; |
||||
margin-top: 8px; |
||||
overflow-y: auto; |
||||
} |
||||
|
||||
&__account { |
||||
display: flex; |
||||
align-items: center; |
||||
padding: 16px; |
||||
border-bottom: 1px solid #d2d8dd; |
||||
justify-content: space-between; |
||||
|
||||
&:last-of-type { |
||||
border-bottom: none; |
||||
} |
||||
|
||||
&:hover { |
||||
background: $Grey-000; |
||||
cursor: pointer; |
||||
} |
||||
|
||||
&__info { |
||||
display: flex; |
||||
flex-direction: column; |
||||
margin-inline-start: 16px; |
||||
min-width: 0; |
||||
} |
||||
|
||||
&__label { |
||||
@include H6; |
||||
|
||||
color: $Black-100; |
||||
text-overflow: ellipsis; |
||||
overflow: hidden; |
||||
white-space: nowrap; |
||||
} |
||||
|
||||
&__balance { |
||||
@include H7; |
||||
|
||||
color: $Grey-500; |
||||
} |
||||
|
||||
&__last-connected { |
||||
@include H8; |
||||
|
||||
display: flex; |
||||
flex-direction: column; |
||||
align-items: flex-end; |
||||
color: $primary-blue; |
||||
} |
||||
} |
||||
|
||||
&__account-info-wrapper { |
||||
display: flex; |
||||
justify-content: flex-start; |
||||
align-items: center; |
||||
min-width: 0; |
||||
} |
||||
|
||||
&__list-check-box { |
||||
margin-inline-end: 16px; |
||||
|
||||
i { |
||||
font-size: 0.8rem; |
||||
} |
||||
} |
||||
|
||||
.fa-info-circle { |
||||
color: $Grey-200; |
||||
cursor: pointer; |
||||
margin-inline-start: 8px; |
||||
font-size: 0.9rem; |
||||
} |
||||
|
||||
.fa-info-circle:hover { |
||||
color: $Grey-300; |
||||
} |
||||
|
||||
&__text, |
||||
&__text-blue, |
||||
&__text-grey { |
||||
@include H6; |
||||
} |
||||
|
||||
&__text-blue { |
||||
color: $primary-blue; |
||||
cursor: pointer; |
||||
} |
||||
|
||||
&__text-grey { |
||||
color: $Grey-500; |
||||
} |
||||
} |
@ -1,242 +0,0 @@ |
||||
import PropTypes from 'prop-types'; |
||||
import React, { Component } from 'react'; |
||||
import classnames from 'classnames'; |
||||
import Identicon from '../../../components/ui/identicon'; |
||||
import Button from '../../../components/ui/button'; |
||||
import CheckBox, { |
||||
CHECKED, |
||||
INDETERMINATE, |
||||
UNCHECKED, |
||||
} from '../../../components/ui/check-box'; |
||||
import Tooltip from '../../../components/ui/tooltip'; |
||||
import { PRIMARY } from '../../../helpers/constants/common'; |
||||
import UserPreferencedCurrencyDisplay from '../../../components/app/user-preferenced-currency-display'; |
||||
import PermissionsConnectHeader from '../../../components/app/permissions-connect-header'; |
||||
import PermissionsConnectFooter from '../../../components/app/permissions-connect-footer'; |
||||
|
||||
export default class ChooseAccount extends Component { |
||||
static propTypes = { |
||||
accounts: PropTypes.arrayOf( |
||||
PropTypes.shape({ |
||||
address: PropTypes.string, |
||||
addressLabel: PropTypes.string, |
||||
lastConnectedDate: PropTypes.string, |
||||
balance: PropTypes.string, |
||||
}), |
||||
).isRequired, |
||||
selectAccounts: PropTypes.func.isRequired, |
||||
selectNewAccountViaModal: PropTypes.func.isRequired, |
||||
nativeCurrency: PropTypes.string.isRequired, |
||||
addressLastConnectedMap: PropTypes.object, |
||||
cancelPermissionsRequest: PropTypes.func.isRequired, |
||||
permissionsRequestId: PropTypes.string.isRequired, |
||||
selectedAccountAddresses: PropTypes.object.isRequired, |
||||
targetSubjectMetadata: PropTypes.shape({ |
||||
extensionId: PropTypes.string, |
||||
iconUrl: PropTypes.string, |
||||
name: PropTypes.string.isRequired, |
||||
origin: PropTypes.string.isRequired, |
||||
}), |
||||
}; |
||||
|
||||
state = { |
||||
selectedAccounts: this.props.selectedAccountAddresses, |
||||
}; |
||||
|
||||
static defaultProps = { |
||||
addressLastConnectedMap: {}, |
||||
}; |
||||
|
||||
static contextTypes = { |
||||
t: PropTypes.func, |
||||
}; |
||||
|
||||
handleAccountClick(address) { |
||||
const { selectedAccounts } = this.state; |
||||
|
||||
const newSelectedAccounts = new Set(selectedAccounts); |
||||
|
||||
if (newSelectedAccounts.has(address)) { |
||||
newSelectedAccounts.delete(address); |
||||
} else { |
||||
newSelectedAccounts.add(address); |
||||
} |
||||
|
||||
this.setState({ selectedAccounts: newSelectedAccounts }); |
||||
} |
||||
|
||||
selectAll() { |
||||
const { accounts } = this.props; |
||||
|
||||
const newSelectedAccounts = new Set( |
||||
accounts.map((account) => account.address), |
||||
); |
||||
|
||||
this.setState({ selectedAccounts: newSelectedAccounts }); |
||||
} |
||||
|
||||
deselectAll() { |
||||
this.setState({ selectedAccounts: new Set() }); |
||||
} |
||||
|
||||
allAreSelected() { |
||||
const { accounts } = this.props; |
||||
const { selectedAccounts } = this.state; |
||||
|
||||
return accounts.every(({ address }) => selectedAccounts.has(address)); |
||||
} |
||||
|
||||
renderAccountsList = () => { |
||||
const { accounts, nativeCurrency, addressLastConnectedMap } = this.props; |
||||
const { selectedAccounts } = this.state; |
||||
return ( |
||||
<div className="permissions-connect-choose-account__accounts-list"> |
||||
{accounts.map((account, index) => { |
||||
const { address, addressLabel, balance } = account; |
||||
return ( |
||||
<div |
||||
key={`permissions-connect-choose-account-${index}`} |
||||
onClick={() => this.handleAccountClick(address)} |
||||
className="permissions-connect-choose-account__account" |
||||
> |
||||
<div className="permissions-connect-choose-account__account-info-wrapper"> |
||||
<CheckBox |
||||
className="permissions-connect-choose-account__list-check-box" |
||||
checked={selectedAccounts.has(address)} |
||||
/> |
||||
<Identicon diameter={34} address={address} /> |
||||
<div className="permissions-connect-choose-account__account__info"> |
||||
<div className="permissions-connect-choose-account__account__label"> |
||||
{addressLabel} |
||||
</div> |
||||
<UserPreferencedCurrencyDisplay |
||||
className="permissions-connect-choose-account__account__balance" |
||||
type={PRIMARY} |
||||
value={balance} |
||||
style={{ color: '#6A737D' }} |
||||
suffix={nativeCurrency} |
||||
/> |
||||
</div> |
||||
</div> |
||||
{addressLastConnectedMap[address] ? ( |
||||
<Tooltip |
||||
title={`${this.context.t('lastConnected')} ${ |
||||
addressLastConnectedMap[address] |
||||
}`}
|
||||
> |
||||
<i className="fa fa-info-circle" /> |
||||
</Tooltip> |
||||
) : null} |
||||
</div> |
||||
); |
||||
})} |
||||
</div> |
||||
); |
||||
}; |
||||
|
||||
renderAccountsListHeader() { |
||||
const { t } = this.context; |
||||
const { selectNewAccountViaModal, accounts } = this.props; |
||||
const { selectedAccounts } = this.state; |
||||
|
||||
let checked; |
||||
if (this.allAreSelected()) { |
||||
checked = CHECKED; |
||||
} else if (selectedAccounts.size === 0) { |
||||
checked = UNCHECKED; |
||||
} else { |
||||
checked = INDETERMINATE; |
||||
} |
||||
|
||||
return ( |
||||
<div |
||||
className={classnames({ |
||||
'permissions-connect-choose-account__accounts-list-header--one-item': |
||||
accounts.length === 1, |
||||
'permissions-connect-choose-account__accounts-list-header--two-items': |
||||
accounts.length > 1, |
||||
})} |
||||
> |
||||
{accounts.length > 1 ? ( |
||||
<div className="permissions-connect-choose-account__select-all"> |
||||
<CheckBox |
||||
className="permissions-connect-choose-account__header-check-box" |
||||
checked={checked} |
||||
onClick={() => |
||||
this.allAreSelected() ? this.deselectAll() : this.selectAll() |
||||
} |
||||
/> |
||||
<div className="permissions-connect-choose-account__text-grey"> |
||||
{this.context.t('selectAll')} |
||||
</div> |
||||
<Tooltip |
||||
position="bottom" |
||||
html={ |
||||
<div style={{ width: 200, padding: 4 }}> |
||||
{t('selectingAllWillAllow')} |
||||
</div> |
||||
} |
||||
> |
||||
<i className="fa fa-info-circle" /> |
||||
</Tooltip> |
||||
</div> |
||||
) : null} |
||||
<div |
||||
className="permissions-connect-choose-account__text-blue" |
||||
onClick={() => |
||||
selectNewAccountViaModal(this.handleAccountClick.bind(this)) |
||||
} |
||||
> |
||||
{this.context.t('newAccount')} |
||||
</div> |
||||
</div> |
||||
); |
||||
} |
||||
|
||||
render() { |
||||
const { |
||||
selectAccounts, |
||||
permissionsRequestId, |
||||
cancelPermissionsRequest, |
||||
targetSubjectMetadata, |
||||
accounts, |
||||
} = this.props; |
||||
const { selectedAccounts } = this.state; |
||||
const { t } = this.context; |
||||
return ( |
||||
<div className="permissions-connect-choose-account"> |
||||
<PermissionsConnectHeader |
||||
icon={targetSubjectMetadata.iconUrl} |
||||
iconName={targetSubjectMetadata.name} |
||||
headerTitle={t('connectWithMetaMask')} |
||||
headerText={ |
||||
accounts.length > 0 |
||||
? t('selectAccounts') |
||||
: t('connectAccountOrCreate') |
||||
} |
||||
siteOrigin={targetSubjectMetadata.origin} |
||||
/> |
||||
{this.renderAccountsListHeader()} |
||||
{this.renderAccountsList()} |
||||
<div className="permissions-connect-choose-account__footer-container"> |
||||
<PermissionsConnectFooter /> |
||||
<div className="permissions-connect-choose-account__bottom-buttons"> |
||||
<Button |
||||
onClick={() => cancelPermissionsRequest(permissionsRequestId)} |
||||
type="secondary" |
||||
> |
||||
{t('cancel')} |
||||
</Button> |
||||
<Button |
||||
onClick={() => selectAccounts(selectedAccounts)} |
||||
type="primary" |
||||
disabled={selectedAccounts.size === 0} |
||||
> |
||||
{t('next')} |
||||
</Button> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
); |
||||
} |
||||
} |
@ -0,0 +1,148 @@ |
||||
import PropTypes from 'prop-types'; |
||||
import React, { useState } from 'react'; |
||||
import { useI18nContext } from '../../../hooks/useI18nContext'; |
||||
import Button from '../../../components/ui/button'; |
||||
import PermissionsConnectHeader from '../../../components/app/permissions-connect-header'; |
||||
import PermissionsConnectFooter from '../../../components/app/permissions-connect-footer'; |
||||
import AccountList from '../../../components/ui/account-list'; |
||||
|
||||
const ChooseAccount = ({ |
||||
selectedAccountAddresses, |
||||
addressLastConnectedMap = {}, |
||||
accounts, |
||||
selectAccounts, |
||||
selectNewAccountViaModal, |
||||
cancelPermissionsRequest, |
||||
permissionsRequestId, |
||||
targetSubjectMetadata, |
||||
nativeCurrency, |
||||
}) => { |
||||
const [selectedAccounts, setSelectedAccounts] = useState( |
||||
selectedAccountAddresses, |
||||
); |
||||
const t = useI18nContext(); |
||||
|
||||
const handleAccountClick = (address) => { |
||||
const newSelectedAccounts = new Set(selectedAccounts); |
||||
if (newSelectedAccounts.has(address)) { |
||||
newSelectedAccounts.delete(address); |
||||
} else { |
||||
newSelectedAccounts.add(address); |
||||
} |
||||
setSelectedAccounts(newSelectedAccounts); |
||||
}; |
||||
|
||||
const selectAll = () => { |
||||
const newSelectedAccounts = new Set( |
||||
accounts.map((account) => account.address), |
||||
); |
||||
setSelectedAccounts(newSelectedAccounts); |
||||
}; |
||||
|
||||
const deselectAll = () => { |
||||
setSelectedAccounts(new Set()); |
||||
}; |
||||
|
||||
const allAreSelected = () => { |
||||
return accounts.length === selectedAccounts.size; |
||||
}; |
||||
|
||||
return ( |
||||
<div className="permissions-connect-choose-account"> |
||||
<PermissionsConnectHeader |
||||
iconUrl={targetSubjectMetadata?.iconUrl} |
||||
iconName={targetSubjectMetadata?.name} |
||||
headerTitle={t('connectWithMetaMask')} |
||||
headerText={ |
||||
accounts.length > 0 |
||||
? t('selectAccounts') |
||||
: t('connectAccountOrCreate') |
||||
} |
||||
siteOrigin={targetSubjectMetadata?.origin} |
||||
/> |
||||
<AccountList |
||||
accounts={accounts} |
||||
selectNewAccountViaModal={selectNewAccountViaModal} |
||||
addressLastConnectedMap={addressLastConnectedMap} |
||||
nativeCurrency={nativeCurrency} |
||||
selectedAccounts={selectedAccounts} |
||||
allAreSelected={allAreSelected} |
||||
deselectAll={deselectAll} |
||||
selectAll={selectAll} |
||||
handleAccountClick={handleAccountClick} |
||||
/> |
||||
<div className="permissions-connect-choose-account__footer-container"> |
||||
<PermissionsConnectFooter /> |
||||
<div className="permissions-connect-choose-account__bottom-buttons"> |
||||
<Button |
||||
onClick={() => cancelPermissionsRequest(permissionsRequestId)} |
||||
type="secondary" |
||||
> |
||||
{t('cancel')} |
||||
</Button> |
||||
<Button |
||||
onClick={() => selectAccounts(selectedAccounts)} |
||||
type="primary" |
||||
disabled={selectedAccounts.size === 0} |
||||
> |
||||
{t('next')} |
||||
</Button> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
); |
||||
}; |
||||
|
||||
ChooseAccount.propTypes = { |
||||
/** |
||||
* Array of user account objects |
||||
*/ |
||||
accounts: PropTypes.arrayOf( |
||||
PropTypes.shape({ |
||||
address: PropTypes.string, |
||||
addressLabel: PropTypes.string, |
||||
lastConnectedDate: PropTypes.string, |
||||
balance: PropTypes.string, |
||||
}), |
||||
).isRequired, |
||||
/** |
||||
* Function to select an account |
||||
*/ |
||||
selectAccounts: PropTypes.func.isRequired, |
||||
/** |
||||
* Function to select a new account via modal |
||||
*/ |
||||
selectNewAccountViaModal: PropTypes.func.isRequired, |
||||
/** |
||||
* Native currency of current chain |
||||
*/ |
||||
nativeCurrency: PropTypes.string.isRequired, |
||||
/** |
||||
* A map of the last connected addresses |
||||
*/ |
||||
addressLastConnectedMap: PropTypes.object, |
||||
/** |
||||
* Function to cancel permission request |
||||
*/ |
||||
cancelPermissionsRequest: PropTypes.func.isRequired, |
||||
/** |
||||
* Permission request Id |
||||
*/ |
||||
permissionsRequestId: PropTypes.string.isRequired, |
||||
/** |
||||
* Currently selected account addresses |
||||
*/ |
||||
selectedAccountAddresses: PropTypes.object.isRequired, |
||||
/** |
||||
* Domain data used to display site-origin pill |
||||
*/ |
||||
targetSubjectMetadata: PropTypes.shape({ |
||||
extensionId: PropTypes.string, |
||||
iconUrl: PropTypes.string, |
||||
name: PropTypes.string.isRequired, |
||||
origin: PropTypes.string.isRequired, |
||||
subjectType: PropTypes.string, |
||||
}), |
||||
}; |
||||
|
||||
export default ChooseAccount; |
@ -1 +1 @@ |
||||
export { default } from './choose-account.component'; |
||||
export { default } from './choose-account'; |
||||
|
Loading…
Reference in new issue