Export acc js (#4973)

* Export account RPC

* Removing GethDirectory and ParityDirectory

* js export accounts as json

* js export accounts as json

* api - then - catch

* final touches

* pass

* oops

* individual accounts

* refactoring

* refactor one

* refactor one

* refactor two

* some grumble fixes

* file name changes

* constructor

* constructor

* git recognize file name change

* spec and updates

* specs

* one tiny fix

* one tiny fix

* grumbles

* more grumbles

* sliders

* ff

* pointer default

* grumbles

* almost ready

* lots of updates

* accountList

* stupid debuglog

* bug fix

* bug fix

* some more good ol fashioned updates

* filter accounts

* clean

* update spec

* ff

* ff-f

* balances fix
This commit is contained in:
Craig O'Connor
2017-04-26 05:34:48 -04:00
committed by Jaco Greeff
parent 3be3b78c90
commit cf904b6b2f
15 changed files with 765 additions and 15 deletions

View File

@@ -19,3 +19,8 @@
width: 24px;
height: 24px;
}
.textbox {
line-height: 1.5em;
margin-bottom: 1.5em;
}

View File

@@ -20,13 +20,15 @@ import { FormattedMessage } from 'react-intl';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import { newError } from '~/redux/actions';
import shapeshiftBtn from '~/../assets/images/shapeshift-btn.png';
import HardwareStore from '~/mobx/hardwareStore';
import ExportStore from '~/modals/ExportAccount/exportStore';
import { DeleteAccount, EditMeta, Faucet, PasswordManager, Shapeshift, Transfer, Verification } from '~/modals';
import { setVisibleAccounts } from '~/redux/providers/personalActions';
import { fetchCertifiers, fetchCertifications } from '~/redux/providers/certifications/actions';
import { Actionbar, Button, Page } from '~/ui';
import { DeleteIcon, DialIcon, EditIcon, LockedIcon, SendIcon, VerifyIcon } from '~/ui/Icons';
import { Actionbar, Button, ConfirmDialog, Input, Page, Portal } from '~/ui';
import { DeleteIcon, DialIcon, EditIcon, LockedIcon, SendIcon, VerifyIcon, FileDownloadIcon } from '~/ui/Icons';
import DeleteAddress from '../Address/Delete';
@@ -42,6 +44,7 @@ class Account extends Component {
};
static propTypes = {
accounts: PropTypes.object.isRequired,
fetchCertifiers: PropTypes.func.isRequired,
fetchCertifications: PropTypes.func.isRequired,
setVisibleAccounts: PropTypes.func.isRequired,
@@ -49,12 +52,20 @@ class Account extends Component {
account: PropTypes.object,
certifications: PropTypes.object,
netVersion: PropTypes.string.isRequired,
newError: PropTypes.func,
params: PropTypes.object
}
store = new Store();
hwstore = HardwareStore.get(this.context.api);
componentWillMount () {
const { accounts, newError, params } = this.props;
const { address } = params;
this.exportStore = new ExportStore(this.context.api, accounts, newError, address);
}
componentDidMount () {
this.props.fetchCertifiers();
this.setVisibleAccounts();
@@ -63,10 +74,15 @@ class Account extends Component {
componentWillReceiveProps (nextProps) {
const prevAddress = this.props.params.address;
const nextAddress = nextProps.params.address;
const { accounts } = nextProps;
if (prevAddress !== nextAddress) {
this.setVisibleAccounts(nextProps);
}
if (!Object.keys(this.exportStore.accounts).length) {
this.exportStore.setAccounts(accounts);
}
}
componentWillUnmount () {
@@ -95,6 +111,7 @@ class Account extends Component {
<div>
{ this.renderDeleteDialog(account) }
{ this.renderEditDialog(account) }
{ this.renderExportDialog() }
{ this.renderFaucetDialog() }
{ this.renderFundDialog() }
{ this.renderPasswordDialog(account) }
@@ -212,6 +229,17 @@ class Account extends Component {
}
onClick={ this.store.toggleEditDialog }
/>,
<Button
icon={ <FileDownloadIcon /> }
key='exportmeta'
label={
<FormattedMessage
id='account.button.export'
defaultMessage='export'
/>
}
onClick={ this.store.toggleExportDialog }
/>,
!(account.external || account.hardware) && (
<Button
icon={ <LockedIcon /> }
@@ -320,6 +348,64 @@ class Account extends Component {
);
}
renderExportDialog () {
const { changePassword, accountValue } = this.exportStore;
if (!this.store.isExportVisible) {
return null;
}
return (
<Portal
open
isSmallModal
onClose={ this.exportClose }
>
<ConfirmDialog
open
disabledConfirm={ false }
labelConfirm='Export'
labelDeny='Cancel'
onConfirm={ this.onExport }
onDeny={ this.exportClose }
title={
<FormattedMessage
id='export.account.title'
defaultMessage='Export Account'
/>
}
>
<div className={ styles.textbox }>
<FormattedMessage
id='export.account.info'
defaultMessage='Export your account as a JSON file. Please enter the password linked with this account.'
/>
</div>
<Input
className={ styles.textbox }
onKeyDown={ this.onEnter }
autoFocus
type='password'
hint={
<FormattedMessage
id='export.account.password.hint'
defaultMessage='The password specified when creating this account'
/>
}
label={
<FormattedMessage
id='export.account.password.label'
defaultMessage='Account password'
/>
}
onChange={ changePassword }
value={ accountValue }
/>
</ConfirmDialog>
</Portal>
);
}
renderFaucetDialog () {
const { netVersion } = this.props;
@@ -393,6 +479,30 @@ class Account extends Component {
/>
);
}
onEnter = (event) => {
if (event.key === 'Enter') {
this.onExport();
}
}
exportClose = () => {
const { toggleExportDialog } = this.store;
const { resetAccountValue } = this.exportStore;
resetAccountValue();
toggleExportDialog();
}
onExport = () => {
const { onExport } = this.exportStore;
onExport(this.hideExport);
}
hideExport = () => {
this.store.toggleExportDialog();
}
}
function mapStateToProps (state, props) {
@@ -406,6 +516,7 @@ function mapStateToProps (state, props) {
return {
account,
accounts,
certifications,
netVersion
};
@@ -415,6 +526,7 @@ function mapDispatchToProps (dispatch) {
return bindActionCreators({
fetchCertifiers,
fetchCertifications,
newError,
setVisibleAccounts
}, dispatch);
}

View File

@@ -19,6 +19,7 @@ import { action, observable } from 'mobx';
export default class Store {
@observable isDeleteVisible = false;
@observable isEditVisible = false;
@observable isExportVisible = false;
@observable isFaucetVisible = false;
@observable isFundVisible = false;
@observable isPasswordVisible = false;
@@ -33,6 +34,10 @@ export default class Store {
this.isEditVisible = !this.isEditVisible;
}
@action toggleExportDialog = () => {
this.isExportVisible = !this.isExportVisible;
}
@action toggleFaucetDialog = () => {
this.isFaucetVisible = !this.isFaucetVisible;
}

View File

@@ -24,9 +24,9 @@ import { Link } from 'react-router';
import { bindActionCreators } from 'redux';
import HardwareStore from '~/mobx/hardwareStore';
import { CreateAccount, CreateWallet } from '~/modals';
import { Actionbar, ActionbarExport, ActionbarSearch, ActionbarSort, Button, Page, Tooltip } from '~/ui';
import { AddIcon, KeyIcon } from '~/ui/Icons';
import { CreateAccount, CreateWallet, ExportAccount } from '~/modals';
import { Actionbar, ActionbarSearch, ActionbarSort, Button, Page, Tooltip } from '~/ui';
import { AddIcon, KeyIcon, FileDownloadIcon } from '~/ui/Icons';
import { setVisibleAccounts } from '~/redux/providers/personalActions';
import List from './List';
@@ -52,6 +52,7 @@ class Accounts extends Component {
addressBook: false,
newDialog: false,
newWalletDialog: false,
newExportDialog: false,
sortOrder: '',
searchValues: [],
searchTokens: [],
@@ -96,6 +97,7 @@ class Accounts extends Component {
<div>
{ this.renderNewDialog() }
{ this.renderNewWalletDialog() }
{ this.renderNewExportDialog() }
{ this.renderActionbar() }
<Page>
@@ -244,8 +246,6 @@ class Accounts extends Component {
}
renderActionbar () {
const { accounts } = this.props;
const buttons = [
<Link
to='/vaults'
@@ -284,10 +284,16 @@ class Accounts extends Component {
}
onClick={ this.onNewWalletClick }
/>,
<ActionbarExport
key='exportAccounts'
content={ accounts }
filename='accounts'
<Button
key='newExport'
icon={ <FileDownloadIcon /> }
label={
<FormattedMessage
id='accounts.button.export'
defaultMessage='export'
/>
}
onClick={ this.onNewExportClick }
/>,
this.renderSearchButton(),
this.renderSortButton()
@@ -351,6 +357,20 @@ class Accounts extends Component {
);
}
renderNewExportDialog () {
const { newExportDialog } = this.state;
if (!newExportDialog) {
return null;
}
return (
<ExportAccount
onClose={ this.onNewExportClose }
/>
);
}
onAddSearchToken = (token) => {
const { searchTokens } = this.state;
const newSearchTokens = uniq([].concat(searchTokens, token));
@@ -370,6 +390,12 @@ class Accounts extends Component {
});
}
onNewExportClick = () => {
this.setState({
newExportDialog: true
});
}
onNewAccountClose = () => {
this.setState({
newDialog: false
@@ -382,6 +408,12 @@ class Accounts extends Component {
});
}
onNewExportClose = () => {
this.setState({
newExportDialog: false
});
}
onNewAccountUpdate = () => {
}