Skip to content

Commit

Permalink
Merge pull request #1809 from LiskHQ/1713-implement-send-submitted-view
Browse files Browse the repository at this point in the history
Implement send submitted view - closes #1713
  • Loading branch information
Osvaldo Vega Agüero committed Mar 12, 2019
2 parents 93c9b0a + 8f48fb2 commit 2d72f2e
Show file tree
Hide file tree
Showing 19 changed files with 379 additions and 31 deletions.
6 changes: 5 additions & 1 deletion i18n/locales/en/common.json
Expand Up @@ -39,7 +39,6 @@
"Amount": "Amount",
"Amount (LSK)": "Amount (LSK)",
"Amount of transaction": "Amount of transaction",
"Amount of trasaction": "Amount of trasaction",
"Amount transfered": "Amount transfered",
"An error occoured while rendering this page": "An error occoured while rendering this page",
"An error occurred while creating the transaction.": "An error occurred while creating the transaction.",
Expand All @@ -50,6 +49,7 @@
"Are you certain of your choice?": "Are you certain of your choice?",
"Auto-logout": "Auto-logout",
"Back": "Back",
"Back to wallet": "Back to wallet",
"Backup your Passphrase": "Backup your Passphrase",
"Balance": "Balance",
"Become a delegate": "Become a delegate",
Expand Down Expand Up @@ -210,6 +210,7 @@
"Invalid address": "Invalid address",
"Invalid amount": "Invalid amount",
"Is Blockchain Secure?": "Is Blockchain Secure?",
"Is the problem presisting?": "Is the problem presisting?",
"It is highly recommended to delete the PDF and remove it from your trash after printing.": "It is highly recommended to delete the PDF and remove it from your trash after printing.",
"It is recommended that you initialize your Lisk ID.": "It is recommended that you initialize your Lisk ID.",
"It will cost you only the usual {{fee}} LSK transaction fee.": "It will cost you only the usual {{fee}} LSK transaction fee.",
Expand Down Expand Up @@ -341,6 +342,7 @@
"Remove from bookmarks": "Remove from bookmarks",
"Removed Votes": "Removed Votes",
"Report the error via E-Mail": "Report the error via E-Mail",
"Report the error via email": "Report the error via email",
"Request": "Request",
"Request LSK": "Request LSK",
"Requested amount": "Requested amount",
Expand Down Expand Up @@ -573,5 +575,7 @@
"{{length}} extra characters": "{{length}} extra characters",
"{{length}} out of {{maxLength}} characters left": "{{length}} out of {{maxLength}} characters left",
"{{length}} out of {{total}} characters left": "{{length}} out of {{total}} characters left",
"{{paragraph}}": "{{paragraph}}",
"{{title}}": "{{title}}",
"{{title}} has been added to your Dashboard.": "{{title}} has been added to your Dashboard."
}
1 change: 1 addition & 0 deletions jest.config.js
Expand Up @@ -145,6 +145,7 @@ module.exports = {
globals: {
PRODUCTION: true,
TEST: true,
VERSION: '',
},
coverageReporters: [
'text',
Expand Down
14 changes: 14 additions & 0 deletions src/assets/images/icons-v2/transactionError.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
11 changes: 11 additions & 0 deletions src/assets/images/icons-v2/transactionSuccess.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions src/components/app/variablesV2.css
Expand Up @@ -46,6 +46,7 @@ or "warn/action" ineastd of "red/green"
--font-size-h5: 20px;
--font-size-h6: 16px;
--font-size-small: 10px;
--font-size-large: 24px;
--heading-font: 'gilroy', 'Open Sans', sans-serif;
--content-font: 'gilroy-regular', 'Open Sans', sans-serif;
--font-weight-normal: 400;
Expand All @@ -60,6 +61,7 @@ or "warn/action" ineastd of "red/green"
--button-font-size-s: 12px;
--footnote-font-size: 12px;
--font-size-title: 18px;
--font-size-small-secondary: 13px;

/*************************
Sizes
Expand Down
10 changes: 8 additions & 2 deletions src/components/bookmarkV2/bookmark.css
Expand Up @@ -35,10 +35,16 @@
box-shadow: var(--box-shadow-search);
flex-direction: column;
justify-content: center;
align-items: center;
align-items: flex-start;
z-index: 3;
max-height: 176px;
overflow: scroll;
overflow: hidden;

& > div:first-child {
overflow: auto;
max-height: 176px;
width: calc(100% + 20px);
}
}

.status {
Expand Down
33 changes: 27 additions & 6 deletions src/components/bookmarkV2/index.js
Expand Up @@ -8,6 +8,7 @@ import styles from './bookmark.css';

// eslint-disable-next-line complexity
class Bookmark extends React.Component {
// eslint-disable-next-line max-statements
constructor(props) {
super(props);

Expand All @@ -17,13 +18,15 @@ class Bookmark extends React.Component {
};

this.loaderTimeout = null;
this.listContainerRef = null;

this.onHandleKeyPress = this.onHandleKeyPress.bind(this);
this.getFilterList = this.getFilterList.bind(this);
this.onKeyPressDownOrUp = this.onKeyPressDownOrUp.bind(this);
this.onKeyPressEnter = this.onKeyPressEnter.bind(this);
this.onChange = this.onChange.bind(this);
this.onSelectedAccount = this.onSelectedAccount.bind(this);
this.resetListIndex = this.resetListIndex.bind(this);
}

getFilterList() {
Expand All @@ -35,21 +38,37 @@ class Bookmark extends React.Component {
account.address.toLowerCase().includes(recipient.value.toLowerCase()));
}

resetListIndex() {
this.setState({ dropdownIndex: 0 });
}

onSelectedAccount(account) {
this.setState({ isLoading: false });
this.resetListIndex();
this.props.onSelectedAccount(account);
}

onKeyPressDownOrUp(action) {
const rowHeight = 44;
const { dropdownIndex } = this.state;
const accountsLength = this.getFilterList().length;

// istanbul ignore else
if (action === 'down' && dropdownIndex < accountsLength - 1) this.setState({ dropdownIndex: dropdownIndex + 1 });

if (action === 'down' && dropdownIndex < accountsLength - 1) {
if (dropdownIndex + 1 >= 4) {
this.listContainerRef.scrollTop = this.listContainerRef.scrollTop + rowHeight;
}
this.setState({ dropdownIndex: dropdownIndex + 1 });
}

// istanbul ignore else
if (action === 'up' && dropdownIndex > 0) this.setState({ dropdownIndex: this.state.dropdownIndex - 1 });
if (action === 'up' && dropdownIndex > 0) {
this.listContainerRef.scrollTop = this.listContainerRef.scrollTop > 0
&& (dropdownIndex - 1) * rowHeight < this.listContainerRef.scrollTop
? this.listContainerRef.scrollTop - rowHeight
: this.listContainerRef.scrollTop;
this.setState({ dropdownIndex: dropdownIndex - 1 });
}
}

onKeyPressEnter() {
Expand Down Expand Up @@ -86,6 +105,8 @@ class Bookmark extends React.Component {
if (this.getFilterList().length === 0) this.setState({ isLoading: false });
this.props.validateBookmark();
}, 300);

if (e && e.target && e.target.value === '') this.resetListIndex();
this.props.onChange(e);
}

Expand All @@ -96,9 +117,7 @@ class Bookmark extends React.Component {
placeholder,
showSuggestions,
} = this.props;

const { dropdownIndex } = this.state;

const showAccountVisual = recipient.address.length && !recipient.error;
const selectedAccount = recipient.selected ? recipient.title : recipient.value;

Expand Down Expand Up @@ -131,7 +150,8 @@ class Bookmark extends React.Component {
{
showSuggestions && recipient.value !== ''
? <div className={styles.bookmarkContainer}>
<ul className={`${styles.bookmarkList} bookmark-list`}>
<div ref={(node) => { this.listContainerRef = node; }}>
<ul className={`${styles.bookmarkList} bookmark-list`}>
{
this.getFilterList()
.map((account, index) =>
Expand All @@ -145,6 +165,7 @@ class Bookmark extends React.Component {
</li>)
}
</ul>
</div>
</div>
: null
}
Expand Down
2 changes: 1 addition & 1 deletion src/components/customRoute/customRoute.js
Expand Up @@ -16,7 +16,7 @@ const CustomRoute = ({
Piwik.tracking(rest.history, settings);

return ((isPrivate && isAuthenticated) || !isPrivate ?
<main className={`${isPrivate ? offlineStyle.disableWhenOffline : ''} ${offlineStyle.setHight} offlineWrapper`}>
<main className={`${isPrivate ? offlineStyle.disableWhenOffline : ''} offlineWrapper`}>
<ErrorBoundary errorMessage={t('An error occoured while rendering this page')}>
<Route path={fullPath} component={component} exact={exact} />
</ErrorBoundary>
Expand Down
4 changes: 0 additions & 4 deletions src/components/offlineWrapper/offlineWrapper.css
Expand Up @@ -2,7 +2,3 @@
opacity: 0.5;
pointer-events: none;
}

.setHeight {
height: 100%;
}
2 changes: 1 addition & 1 deletion src/components/sendV2/form/form.js
Expand Up @@ -305,7 +305,7 @@ class Form extends React.Component {
</label>

<label className={`${styles.fieldGroup}`}>
<span className={`${styles.fieldLabel}`}>{this.props.t('Amount of trasaction')}</span>
<span className={`${styles.fieldLabel}`}>{this.props.t('Amount of transaction')}</span>
<span className={`${styles.amountField} amount`}>
<InputV2
autoComplete={'off'}
Expand Down
1 change: 0 additions & 1 deletion src/components/sendV2/index.js
Expand Up @@ -5,7 +5,6 @@ import Send from './send';

const mapStateToProps = state => ({
account: state.account,
pendingTransactions: state.transactions.pending,
});

export default connect(mapStateToProps)(translate()(Send));
4 changes: 4 additions & 0 deletions src/components/sendV2/send.css
Expand Up @@ -22,3 +22,7 @@
max-width: 670px;
height: auto;
}

:global(.offlineWrapper) {
height: 100%;
}
10 changes: 10 additions & 0 deletions src/components/sendV2/send.js
Expand Up @@ -2,7 +2,9 @@ import React from 'react';
import MultiStep from './../multiStep';
import Form from './form';
import Summary from './summary';
import TransactionStatus from './transactionStatus';
import { parseSearchParams } from './../../utils/searchParams';
import routes from '../../constants/routes';
import styles from './send.css';

class Send extends React.Component {
Expand All @@ -18,6 +20,12 @@ class Send extends React.Component {
reference: { value: reference || '' },
},
};

this.backToWallet = this.backToWallet.bind(this);
}

backToWallet() {
this.props.history.push(routes.wallet.path);
}

render() {
Expand All @@ -28,9 +36,11 @@ class Send extends React.Component {
<div className={`${styles.wrapper} send-box`}>
<MultiStep
key='send'
finalCallback={this.backToWallet}
className={styles.wrapper}>
<Form fields={fields} />
<Summary />
<TransactionStatus history={this.props.history}/>
</MultiStep>
</div>
</div>
Expand Down
38 changes: 35 additions & 3 deletions src/components/sendV2/send.test.js
Expand Up @@ -3,6 +3,7 @@ import { mount } from 'enzyme';
import PropTypes from 'prop-types';
import configureMockStore from 'redux-mock-store';
import thunk from 'redux-thunk';
import accounts from '../../../test/constants/accounts';
import i18n from '../../i18n';
import Send from './send';

Expand All @@ -27,6 +28,13 @@ describe('Form', () => {
path: '/wallet/sendV2/send',
search: '?recipient=16313739661670634666L&amount=10&reference=test',
},
push: jest.fn(),
},
transactions: {
failed: undefined,
},
account: {
balance: accounts.genesis.balance,
},
followedAccounts: {
accounts: [
Expand Down Expand Up @@ -66,6 +74,9 @@ describe('Form', () => {
USD: 1,
},
},
account: {
balance: accounts.genesis.balance,
},
t: v => v,
prevState: {
fields: {},
Expand Down Expand Up @@ -93,6 +104,7 @@ describe('Form', () => {
path: '/wallet/sendV2/send',
search: '?recipient=16313739661670634666L&amount=10&reference=test',
},
push: jest.fn(),
},
};

Expand All @@ -104,15 +116,35 @@ describe('Form', () => {
expect(wrapper).toContainMatchingElement('.send-box');
expect(wrapper).toContainMatchingElement('MultiStep');
expect(wrapper).toContainMatchingElement('Form');
expect(wrapper).not.toContainMatchingElement('Summary');
expect(wrapper).not.toContainMatchingElement('TransactionStatus');
});

it('should render properly without getting data from URL', () => {
props.history.location.path = '';
props.history.location.search = '';
wrapper = mount(<Send {...props} />, options);
const newProps = { ...props };
newProps.history.location.path = '';
newProps.history.location.search = '';
wrapper = mount(<Send {...newProps} />, options);
wrapper.update();
expect(wrapper).toContainMatchingElement('.send-box');
expect(wrapper).toContainMatchingElement('MultiStep');
expect(wrapper).toContainMatchingElement('Form');
});

it('should call finallCallback after submit a transaction', () => {
wrapper.find('input.recipient').simulate('change', { target: { name: 'recipient', value: '12345L' } });
const amountField = wrapper.find('.fieldGroup').at(1);
amountField.find('InputV2').simulate('change', { target: { name: 'amount', value: '.1' } });
jest.advanceTimersByTime(300);
wrapper.update();
wrapper.find('.btn-submit').at(0).simulate('click');
wrapper.update();
expect(wrapper).toContainMatchingElement('Summary');
wrapper.find('.on-nextStep').at(0).simulate('click');
wrapper.update();
expect(wrapper).toContainMatchingElement('TransactionStatus');
wrapper.find('.on-goToWallet').at(0).simulate('click');
wrapper.update();
expect(props.history.push).toBeCalled();
});
});
17 changes: 17 additions & 0 deletions src/components/sendV2/transactionStatus/index.js
@@ -0,0 +1,17 @@
/* istanbul ignore file */
import { connect } from 'react-redux';
import { translate } from 'react-i18next';
import TransactionStatus from './transactionStatus';
import actionTypes from '../../../constants/actions';

const mapStateToProps = state => ({
failedTransactions: state.transactions.failed,
});

const mapDispatchToProps = {
transactionFailedClear: () => ({
type: actionTypes.transactionFailedClear,
}),
};

export default connect(mapStateToProps, mapDispatchToProps)(translate()(TransactionStatus));

0 comments on commit 2d72f2e

Please sign in to comment.