diff --git a/i18n/locales/en/common.json b/i18n/locales/en/common.json index 4a3378a351..cd47447e10 100644 --- a/i18n/locales/en/common.json +++ b/i18n/locales/en/common.json @@ -63,6 +63,7 @@ "Confirmation in the next step": "Confirmation in the next step", "Confirmation in the next step.": "Confirmation in the next step.", "Confirmations": "Confirmations", + "Connected to ": "Connected to ", "Connecting to network": "Connecting to network", "Connection re-established": "Connection re-established", "Continue to Dashboard": "Continue to Dashboard", diff --git a/src/actions/transactions.js b/src/actions/transactions.js index 065f63e44a..08868df3f4 100644 --- a/src/actions/transactions.js +++ b/src/actions/transactions.js @@ -226,6 +226,9 @@ export const sent = ({ amount: toRawLsk(amount), fee: Fees.send, type: transactionTypes.send, + asset: { + data, + }, }, type: actionTypes.transactionAdded, }); diff --git a/src/actions/transactions.test.js b/src/actions/transactions.test.js index 72f093e06a..fbf68c39c3 100644 --- a/src/actions/transactions.test.js +++ b/src/actions/transactions.test.js @@ -213,6 +213,7 @@ describe('actions: transactions', () => { senderPublicKey: 'test_public-key', senderId: 'test_address', recipientId: data.recipientId, + asset: { data: undefined }, amount: toRawLsk(data.amount), fee: Fees.send, type: transactionTypes.send, diff --git a/src/components/account/account.css b/src/components/account/account.css index 531645d2d6..ed257b4c2c 100644 --- a/src/components/account/account.css +++ b/src/components/account/account.css @@ -1,20 +1,12 @@ @import './../app/variables.css'; -:root { - --online: #73cba9; - --offline: #f45d4c; -} - .wrapper { margin: 8px -8px 16px; } -:global .online { - color: var(--online); -} - -:global .offline { - color: var(--offline); +.network { + margin-right: 8px; + margin-top: -3px; } .value-wrapper { @@ -79,16 +71,30 @@ .title { color: white; + height: 56px; + display: flex; + flex-direction: column; + justify-content: center; +} + +.testnetTitle, +.devnetTitle { + color: var(--color-grayscale-medium); } .current { color: var(--color-grayscale-medium); + margin-top: 8px; + margin-left: 32px; + display: inline-block; } .peer { font-size: 16px; display: inline-block; text-align: left; + width: auto; + height: 56px; } @media (--medium-viewport) { diff --git a/src/components/account/account.js b/src/components/account/account.js index 651e15cebd..48ff8da84d 100644 --- a/src/components/account/account.js +++ b/src/components/account/account.js @@ -1,28 +1,44 @@ import React from 'react'; +import Lisk from 'lisk-elements'; import { FontIcon } from '../fontIcon'; import networks from '../../constants/networks'; import styles from './account.css'; + /** * Contains some of the important and basic information about the account * * @param {object} props - include properties of component */ -const Account = ({ peers, t }) => { +const Account = ({ peers, t, showNetworkIndicator }) => { + const iconMap = ['mainnet', 'testnet', 'devnet']; + const translations = iconMap.map(code => t(code)); + + let iconCode = peers.options.code; + if (iconCode === 2) { + iconCode = (peers.options.nethash === Lisk.constants.MAINNET_NETHASH) ? + networks.mainnet.code : iconCode; + iconCode = (peers.options.nethash === Lisk.constants.TESTNET_NETHASH) ? + networks.testnet.code : iconCode; + } + const status = (peers.status && peers.status.online) ? - : + : ; - return ((peers.data && + return ((showNetworkIndicator && peers.data && peers.options.code !== networks.mainnet.code) ?
-
{t(peers.options.name)} {status} +
+ + {status} + {t('Connected to ')}{translations[iconCode]} + + + {peers.data.currentNode} +
- - - {peers.data.currentNode} -
: null ); diff --git a/src/components/account/account.test.js b/src/components/account/account.test.js index 1fee5fc171..39e888b191 100644 --- a/src/components/account/account.test.js +++ b/src/components/account/account.test.js @@ -1,7 +1,9 @@ import React from 'react'; +import Lisk from 'lisk-elements'; import { expect } from 'chai'; import { shallow } from 'enzyme'; import sinon from 'sinon'; +import networks from '../../constants/networks'; import Account from './account'; describe('Account', () => { @@ -13,6 +15,7 @@ describe('Account', () => { i18n: {}, store: {}, onActivePeerUpdated: sinon.spy(), + showNetworkIndicator: true, peers: { status: { online: false, @@ -41,9 +44,28 @@ describe('Account', () => { expect(wrapper.find('Address')).to.have.lengthOf(1); }); - it('depicts being online when peers.status.online is true', () => { + it('shows network indicator online', () => { props.peers.status.online = true; const wrapper = shallow(); - expect(wrapper.find('.status FontIcon')).to.have.className('online'); + wrapper.update(); + expect(wrapper).to.have.exactly(1).descendants('.online'); + }); + + it('shows network indicator offline', () => { + props.peers.status.online = false; + const wrapper = shallow(); + wrapper.update(); + expect(wrapper).to.have.exactly(1).descendants('.offline'); + }); + + it('shows testnet icon when online and nethash matches', () => { + props.peers.status.online = true; + props.peers.options.nethash = Lisk.constants.TESTNET_NETHASH; + props.peers.options.code = networks.customNode.code; + props.peers.data.currentNode = 'http://localhost:4000'; + const wrapper = shallow(); + wrapper.update(); + expect(wrapper).to.have.exactly(1).descendants('.online'); + expect(wrapper).to.have.exactly(1).descendants('.testnet-title'); }); }); diff --git a/src/components/app/global.css b/src/components/app/global.css index e3550b8b2a..2ca92f62be 100644 --- a/src/components/app/global.css +++ b/src/components/app/global.css @@ -39,12 +39,6 @@ order to be available application wide padding: 0px 30px; } -:global .appLoaded { - & .searchBar { - display: inline-block; - } -} - @media (--medium-viewport) { :global body.contentFocused { margin-top: 0; diff --git a/src/components/autoSuggest/autoSuggest.css b/src/components/autoSuggest/autoSuggest.css index 1b44ea5ee6..b0a3156eab 100644 --- a/src/components/autoSuggest/autoSuggest.css +++ b/src/components/autoSuggest/autoSuggest.css @@ -45,7 +45,8 @@ pointer-events: none; opacity: 0.5; padding: 0; - width: 100%; + width: calc(30vw - 74px); /* stylelint-disable-line */ + text-overflow: ellipsis; } .input { diff --git a/src/components/header/header.css b/src/components/header/header.css index fd625f1513..31002bece9 100644 --- a/src/components/header/header.css +++ b/src/components/header/header.css @@ -15,7 +15,9 @@ } .wrapper { - text-align: right; + display: flex; + flex-direction: row; + justify-content: space-between; & .noPadding { padding: 0px; @@ -25,6 +27,7 @@ display: inline-block; float: left; margin-bottom: 30px; + margin-right: 32px; } } @@ -218,6 +221,12 @@ .loginInfo { width: 100%; float: none; + + & > div { + display: flex; + flex-direction: row; + justify-content: space-between; + } } .wrapper { @@ -233,6 +242,7 @@ & .searchBar { width: 100%; margin-bottom: 0; + display: none; } } diff --git a/src/components/header/header.js b/src/components/header/header.js index 0b317584d9..a539661b60 100644 --- a/src/components/header/header.js +++ b/src/components/header/header.js @@ -58,8 +58,18 @@ class Header extends React.Component { } render() { + const { peers, t, showNetworkIndicator } = this.props; return (
+
+
+ {this.shouldShowSearchBar() && } +
+ {this.props.account.loading + ? null + : } +
+
@@ -134,12 +144,6 @@ class Header extends React.Component {
-
- {this.shouldShowSearchBar() && } - {this.props.account.loading - ? null - : } -
); } diff --git a/src/components/header/index.js b/src/components/header/index.js index f519a1b6e4..7f7c4ce171 100644 --- a/src/components/header/index.js +++ b/src/components/header/index.js @@ -14,6 +14,7 @@ const mapStateToProps = state => ({ autoLog: state.settings.autoLog, isAuthenticated: !!state.account.publicKey, peers: state.peers, + showNetworkIndicator: state.settings.showNetwork, }); const mapDispatchToProps = dispatch => ({ diff --git a/src/components/searchBar/searchBar.css b/src/components/searchBar/searchBar.css index c04d2b4d20..0a2e5504c8 100644 --- a/src/components/searchBar/searchBar.css +++ b/src/components/searchBar/searchBar.css @@ -10,11 +10,10 @@ } .searchBar { - display: none; vertical-align: top; position: relative; width: var(--search-box-width-l); - margin-right: 50px; + margin-right: 32px; & .icon { position: absolute; diff --git a/src/components/transactions/transactionRow.css b/src/components/transactions/transactionRow.css index 22d6c80bac..d106ed1bfa 100644 --- a/src/components/transactions/transactionRow.css +++ b/src/components/transactions/transactionRow.css @@ -9,12 +9,32 @@ --result-address-font-weight: var(--font-weight-semi-bold); --grid-header-line-height: 60px; --main-row-line-height: 70px; + --box-padding-right-M: 0; + --box-padding-right-L: 0; + --box-padding-right-XL: 0; } .header { color: var(--grid-header-color); line-height: var(--grid-header-line-height); font-weight: var(--font-weight-very-bold); + + &:nth-child(2) { + text-align: left; + } +} + +.reference { + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + text-align: left; +} + +.arrowRow { + & span { + margin-right: 8px; + } } .rows { @@ -58,7 +78,7 @@ } .rows { - padding: 0px var(--box-padding-left-XL); + padding: 0 var(--box-padding-right-XL) 0 var(--box-padding-left-XL); } } @@ -68,7 +88,7 @@ } .rows { - padding: 0px var(--box-padding-left-L); + padding: 0 var(--box-padding-right-L) 0 var(--box-padding-left-L); } } @@ -78,7 +98,7 @@ } .rows { - padding: 0px var(--box-padding-left-M); + padding: 0 var(--box-padding-right-M) 0 var(--box-padding-left-M); &:nth-of-type(even) { background: var(--gradient-greyscale-mobile); @@ -88,10 +108,22 @@ background: var(--color-grayscale-mobile-background); } } + + .arrowRow { + text-align: right; + + & span { + margin-right: 8px; + } + } } @media (--small-viewport) { .hiddenXs { display: none; } + + .arrowRow { + text-align: right; + } } diff --git a/src/components/transactions/transactionRow.js b/src/components/transactions/transactionRow.js index 22e9a449ba..8d47361fb2 100644 --- a/src/components/transactions/transactionRow.js +++ b/src/components/transactions/transactionRow.js @@ -19,21 +19,28 @@ class TransactionRow extends React.Component { const onClick = !props.onClick ? (() => {}) : () => props.onClick(this.props); return (
-
+
+
+
+ {props.value.asset && props.value.asset.data ? + {props.value.asset.data} + : '-'} +
+
{props.value.confirmations ? : }
-
+
-
+
diff --git a/src/components/transactions/transactionRow.test.js b/src/components/transactions/transactionRow.test.js index a396d9a9ca..0993b96364 100644 --- a/src/components/transactions/transactionRow.test.js +++ b/src/components/transactions/transactionRow.test.js @@ -56,7 +56,7 @@ describe('TransactionRow', () => { , options); - expect(wrapper.find('.transactions-cell')).to.have.lengthOf(4); + expect(wrapper.find('.transactions-cell')).to.have.lengthOf(5); }); it('should not cause any error on click if props.onClick is not defined', () => { diff --git a/src/components/transactions/transactionsHeader.js b/src/components/transactions/transactionsHeader.js index b65d09f641..1dbbdde48a 100644 --- a/src/components/transactions/transactionsHeader.js +++ b/src/components/transactions/transactionsHeader.js @@ -5,7 +5,8 @@ import styles from './transactionRow.css'; const TransactionsHeader = ({ t }) => (
-
{t('Address')}
+
{t('Address')}
+
{t('Reference')}
{t('Date')}
{t('Amount (LSK)')}
diff --git a/src/components/transactions/transactionsHeader.test.js b/src/components/transactions/transactionsHeader.test.js index 0bb27b0286..202a1c8f75 100644 --- a/src/components/transactions/transactionsHeader.test.js +++ b/src/components/transactions/transactionsHeader.test.js @@ -18,6 +18,6 @@ describe('TransactionsHeader', () => { }, ); - expect(wrapper.find('.transactions-header')).to.have.lengthOf(3); + expect(wrapper.find('.transactions-header')).to.have.lengthOf(4); }); }); diff --git a/test/e2e/login.feature b/test/e2e/login.feature index 13a270b2a5..d8b2fd32b3 100644 --- a/test/e2e/login.feature +++ b/test/e2e/login.feature @@ -20,12 +20,14 @@ Feature: Login Scenario: should allow to login to Testnet through network options launch protocol Given I go to "/" Then I should see no "network" + When I go to "/setting" + And I click "showNetwork" When I'm on login page Then I fill in passphrase of "genesis" to "passphrase" field And I select option no. 3 from "network" select And I click "login button" Then I should be logged in as "genesis" account - And I should see text "testnet" in "peer network" element + And I should see text "Connected to testnet" in "network-status" element And I click "joyride-tooltip__button--skip" And I click "joyride-tooltip__button--skip" When I click "transactions" menu @@ -34,13 +36,15 @@ Feature: Login Scenario: should allow to login to Custom node through network options launch protocol Given I go to "/" Then I should see no "network" + When I go to "/setting" + And I click "showNetwork" When I'm on login page Then I fill in passphrase of "genesis" to "passphrase" field And I select option no. 4 from "network" select When I fill in "https://testnet.lisk.io" to "address" field And I click "login button" Then I should be logged in as "genesis" account - And I should see text "custom node" in "peer network" element + And I should see text "Connected to testnet" in "network-status" element And I click "joyride-tooltip__button--skip" And I click "joyride-tooltip__button--skip" When I click "transactions" menu