diff --git a/i18n/locales/en/common.json b/i18n/locales/en/common.json index 32bc564db0..02550784a3 100644 --- a/i18n/locales/en/common.json +++ b/i18n/locales/en/common.json @@ -1,7 +1,6 @@ { " LSK": " LSK", " Make sure that you are using the latest version of Lisk Hub.": " Make sure that you are using the latest version of Lisk Hub.", - " of": " of", "% of successfully forged blocks in relation to total blocks that were available for this particular delegate to forge": "% of successfully forged blocks in relation to total blocks that were available for this particular delegate to forge", "%s Connected. Welcome %s!": "%s Connected. Welcome %s!", "%s Disconnected. See you %s!": "%s Disconnected. See you %s!", @@ -15,7 +14,6 @@ "Academy": "Academy", "Access your account by scanning the QR code below with the Lisk Mobile App:": "Access your account by scanning the QR code below with the Lisk Mobile App:", "Account": "Account", - "Account Info": "Account Info", "Account name": "Account name", "Account nickname": "Account nickname", "Action Denied by User": "Action Denied by User", @@ -26,21 +24,17 @@ "Add address to bookmarks": "Add address to bookmarks", "Add bookmark": "Add bookmark", "Add some {{activeToken}} to your Lisk Hub account now!": "Add some {{activeToken}} to your Lisk Hub account now!", - "Add to bookmarks": "Add to bookmarks", "Added Votes": "Added Votes", "Added votes": "Added votes", "Adding extensions is currently disabled in production version of Lisk Hub": "Adding extensions is currently disabled in production version of Lisk Hub", "Address": "Address", "Advanced": "Advanced", - "After logging out of your account you will be able to access the Dashboard, Settings and Search.": "After logging out of your account you will be able to access the Dashboard, Settings and Search.", - "All": "All", "All bookmarks": "All bookmarks", "All delegates": "All delegates", "All important information about delegates.": "All important information about delegates.", "All important information at a glance": "All important information at a glance", "All transactions": "All transactions", "Amount": "Amount", - "Amount (LSK)": "Amount (LSK)", "Amount of LSK earned by a delegate from forging blocks.": "Amount of LSK earned by a delegate from forging blocks.", "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.", @@ -83,7 +77,6 @@ "Choose the right words.": "Choose the right words.", "Choose your avatar": "Choose your avatar", "Clear All filters": "Clear All filters", - "Close": "Close", "Coming soon.": "Coming soon.", "Community feed": "Community feed", "Confirm": "Confirm", @@ -92,13 +85,11 @@ "Confirm transaction on {{deviceModel}}": "Confirm transaction on {{deviceModel}}", "Confirm voting": "Confirm voting", "Confirm your passphrase": "Confirm your passphrase", - "Confirmation in the next step": "Confirmation in the next step", "Confirmations": "Confirmations", "Confirmations refer to the number of blocks added to the {{token}} blockchain after a transaction has been submitted. The more confirmations registered, the more secure the transaction becomes.": "Confirmations refer to the number of blocks added to the {{token}} blockchain after a transaction has been submitted. The more confirmations registered, the more secure the transaction becomes.", "Connect": "Connect", "Connect your Hardware Wallet": "Connect your Hardware Wallet", "Connected": "Connected", - "Connected to ": "Connected to ", "Connected to:": "Connected to:", "Connection re-established": "Connection re-established", "Continue": "Continue", @@ -133,7 +124,6 @@ "Delegate registration failed": "Delegate registration failed", "Delegate registration submitted": "Delegate registration submitted", "Delegate since": "Delegate since", - "Delegate statistics": "Delegate statistics", "Delegate stats": "Delegate stats", "Delegate vote": "Delegate vote", "Delegate vote_noun": "Delegate vote", @@ -141,7 +131,6 @@ "Delegates are the most commited Lisk community members responsible for \n securing the network and processing all the transactions on Lisk’s blockchain \n network.": "Delegates are the most commited Lisk community members responsible for \n securing the network and processing all the transactions on Lisk’s blockchain \n network.", "Delete": "Delete", "Details": "Details", - "Discard": "Discard", "Does the problem still persist?": "Does the problem still persist?", "Don’t be a stranger! Connect with our worldwide community.": "Don’t be a stranger! Connect with our worldwide community.", "Don’t worry, we’re here to help": "Don’t worry, we’re here to help", @@ -158,11 +147,6 @@ "Edit voting": "Edit voting", "Enable a network switcher that lets you select testnet or custom node when logging in.": "Enable a network switcher that lets you select testnet or custom node when logging in.", "Enter URL of the *.js file with the extension": "Enter URL of the *.js file with the extension", - "Enter your 1st passphrase to confirm": "Enter your 1st passphrase to confirm", - "Enter your passphrase": "Enter your passphrase", - "Enter your second passphrase": "Enter your second passphrase", - "Enter your second passphrase to confirm": "Enter your second passphrase to confirm", - "Entered passphrase does not belong to the active account": "Entered passphrase does not belong to the active account", "Error": "Error", "Error on Ledger Connection. Be sure your device is connected properly": "Error on Ledger Connection. Be sure your device is connected properly", "Error or Device Not Connected.": "Error or Device Not Connected.", @@ -177,9 +161,6 @@ "Failed to connect to node": "Failed to connect to node", "Failed to connect: Node {{address}} is not active": "Failed to connect: Node {{address}} is not active", "Fee": "Fee", - "Fee: {{amount}} LSK": "Fee: {{amount}} LSK", - "Feedback": "Feedback", - "Filter": "Filter", "Filter Transactions": "Filter Transactions", "Filter by name": "Filter by name", "Filter by name...": "Filter by name...", @@ -202,7 +183,6 @@ "Got the Lisk Mobile App?": "Got the Lisk Mobile App?", "Guest mode": "Guest mode", "Hardware Wallet Type not recognized": "Hardware Wallet Type not recognized", - "Height": "Height", "Help": "Help", "Help Center": "Help Center", "Help improve Lisk Hub by allowing Lisk to gather anonymous usage data used for analytical purposes.": "Help improve Lisk Hub by allowing Lisk to gather anonymous usage data used for analytical purposes.", @@ -216,14 +196,11 @@ "I have read and agree to the Terms of Use": "I have read and agree to the Terms of Use", "If you see this field, you have registered a second passphrase in past and it is required to confirm transactions.": "If you see this field, you have registered a second passphrase in past and it is required to confirm transactions.", "If you’re not sure how to do this please follow the": "If you’re not sure how to do this please follow the", - "In": "In", "In order to see your recent transactions you need to sign in.": "In order to see your recent transactions you need to sign in.", "In order to use this Lisk Hub feature you need to sign in to your Lisk account.": "In order to use this Lisk Hub feature you need to sign in to your Lisk account.", "In this section of Lisk Hub you can vote for up to 101 delegates to secure Lisk’s blockchain network. By doing so you have a real impact on the Lisk ecosystem.": "In this section of Lisk Hub you can vote for up to 101 delegates to secure Lisk’s blockchain network. By doing so you have a real impact on the Lisk ecosystem.", "Include your operating system and screen resolution in your report": "Include your operating system and screen resolution in your report", - "Incoming": "Incoming", "Incoming transactions": "Incoming transactions", - "Info": "Info", "Initialize Lisk ID": "Initialize Lisk ID", "Insert label": "Insert label", "Insert public address": "Insert public address", @@ -231,7 +208,6 @@ "Insert the amount of transaction": "Insert the amount of transaction", "Install update": "Install update", "Insufficient funds (Fee: {{fee}} LSK)": "Insufficient funds (Fee: {{fee}} LSK)", - "Insufficient funds for {{amount}} LSK fee": "Insufficient funds for {{amount}} LSK fee", "Invalid Dates": "Invalid Dates", "Invalid amount": "Invalid amount", "Is Blockchain Secure?": "Is Blockchain Secure?", @@ -273,7 +249,6 @@ "Locale": "Locale", "Log out automatically after 10 minutes.": "Log out automatically after 10 minutes.", "Login Type not recognized.": "Login Type not recognized.", - "Logout": "Logout", "Look at your Ledger for confirmation": "Look at your Ledger for confirmation", "Look at your Trezor %s for completing the action": "Look at your Trezor %s for completing the action", "Looking for a device...": "Looking for a device...", @@ -287,7 +262,6 @@ "Max. 20 characters, a-z, 0-1, no special characters except !@$_.": "Max. 20 characters, a-z, 0-1, no special characters except !@$_.", "Maximum floating point is 8.": "Maximum floating point is 8.", "Maximum length exceeded": "Maximum length exceeded", - "Menu": "Menu", "Message": "Message", "Message (optional)": "Message (optional)", "Min": "Min", @@ -308,9 +282,7 @@ "No available tweets": "No available tweets", "No delegates found.": "No delegates found.", "No results": "No results", - "No results found": "No results found", "No search results in given criteria.": "No search results in given criteria.", - "No transactions yet": "No transactions yet", "No, thanks": "No, thanks", "Not enough LSK to pay for the transaction.": "Not enough LSK to pay for the transaction.", "Not voted": "Not voted", @@ -324,8 +296,6 @@ "Once activated can’t be turned off.": "Once activated can’t be turned off.", "Oops! Wrong passphrase": "Oops! Wrong passphrase", "Oops, looks like something went wrong. Please try again.": "Oops, looks like something went wrong. Please try again.", - "Out": "Out", - "Outgoing": "Outgoing", "Outgoing transactions": "Outgoing transactions", "Paper wallet": "Paper wallet", "Passphrase": "Passphrase", @@ -359,11 +329,9 @@ "Rank": "Rank", "Read More": "Read More", "Read more": "Read more", - "Recent searches": "Recent searches", "Recent {{value}} transactions": "Recent {{value}} transactions", "Recipient": "Recipient", "Redo": "Redo", - "Reference": "Reference", "Register": "Register", "Register 2nd passphrase": "Register 2nd passphrase", "Register 2nd passphrase summary": "Register 2nd passphrase summary", @@ -377,11 +345,9 @@ "Removed Votes": "Removed Votes", "Removed votes": "Removed votes", "Report the error via E-Mail": "Report the error via E-Mail", - "Request": "Request", "Request {{token}}": "Request {{token}}", "Requested amount": "Requested amount", "Required": "Required", - "Reset": "Reset", "Reset timer & continue": "Reset timer & continue", "Restart now": "Restart now", "Retry": "Retry", @@ -390,7 +356,6 @@ "Save it on a encrypted hard drive: USB key or a backup drive": "Save it on a encrypted hard drive: USB key or a backup drive", "Save your passphrase": "Save your passphrase", "Search for Lisk ID, Delegate or Transaction ID": "Search for Lisk ID, Delegate or Transaction ID", - "Search for delegate, Lisk ID, transaction ID": "Search for delegate, Lisk ID, transaction ID", "Search within the network...": "Search within the network...", "Search, view and vote for Lisk delegates on the network. Lisk Hub gives you the opportunity to request a Lisk feature and allows you to register to become a delegate.": "Search, view and vote for Lisk delegates on the network. Lisk Hub gives you the opportunity to request a Lisk feature and allows you to register to become a delegate.", "Second Passphrase": "Second Passphrase", @@ -414,7 +379,6 @@ "Send {{token}} to this wallet ": "Send {{token}} to this wallet ", "Sender": "Sender", "Session timeout": "Session timeout", - "Session timeout in": "Session timeout in", "Settings": "Settings", "Settings saved!": "Settings saved!", "Sharing link": "Sharing link", @@ -422,7 +386,6 @@ "Show passphrase": "Show passphrase", "Show the QR code": "Show the QR code", "Show this account's transactions on the dashboard.": "Show this account's transactions on the dashboard.", - "Sidechains": "Sidechains", "Sidechains will revolutionize the way decentralized apps are developed. Here you will be able to find hosts, and monitor your sidechains soon.": "Sidechains will revolutionize the way decentralized apps are developed. Here you will be able to find hosts, and monitor your sidechains soon.", "Sign In": "Sign In", "Sign a message": "Sign a message", @@ -439,9 +402,7 @@ "Standby": "Standby", "Start adding some addresses to bookmarks, to keep track of them.": "Start adding some addresses to bookmarks, to keep track of them.", "Start by Selecting the delegates you’d like to vote for.": "Start by Selecting the delegates you’d like to vote for.", - "Start here": "Start here", "Start voting": "Start voting", - "Stats": "Stats", "Status": "Status", "Step 1 / 2": "Step 1 / 2", "Step 1 / 4": "Step 1 / 4", @@ -454,21 +415,17 @@ "Success": "Success", "Sum of LSK balance of all accounts who voted for this delegate": "Sum of LSK balance of all accounts who voted for this delegate", "Sum of LSK of all accounts who voted for a delegate": "Sum of LSK of all accounts who voted for a delegate", - "Tell us what you think": "Tell us what you think", "Terms of Use": "Terms of Use", "Testnet": "Testnet", "The dashboard lets you track updates not only from Lisk, but also delegates. You can now explore delegate profile pages and follow them to get all the updates.": "The dashboard lets you track updates not only from Lisk, but also delegates. You can now explore delegate profile pages and follow them to get all the updates.", "The Lisk Academy is an entirely free, unbiased and comprehensive educational platform about blockchain technology, containing something for everyone, regardless of what level of knowledge you are at.": "The Lisk Academy is an entirely free, unbiased and comprehensive educational platform about blockchain technology, containing something for everyone, regardless of what level of knowledge you are at.", - "The Wallet will show your recent transactions.": "The Wallet will show your recent transactions.", "The download has started. Depending on your internet speed, it can take several minutes. You will be informed when it is finished and be prompted to restart the app.": "The download has started. Depending on your internet speed, it can take several minutes. You will be informed when it is finished and be prompted to restart the app.", "The easiest way to do this is to send LSK to yourself by clicking this button.": "The easiest way to do this is to send LSK to yourself by clicking this button.", - "The easiest way to do this is to send LSK to yourself. It will cost you only the usual {{fee}} LSK transaction fee.": "The easiest way to do this is to send LSK to yourself. It will cost you only the usual {{fee}} LSK transaction fee.", "The top 101 delegates are able to forge new blocks and recieve forging rewards.": "The top 101 delegates are able to forge new blocks and recieve forging rewards.", "The transaction has been canceled on your {{model}}": "The transaction has been canceled on your {{model}}", "There are no results matching this filter": "There are no results matching this filter", "There are no results matching this filter.": "There are no results matching this filter.", "There are no transactions.": "There are no transactions.", - "There are no {{filterName}} transactions.": "There are no {{filterName}} transactions.", "This account doesn’t have any votes": "This account doesn’t have any votes", "This helps to keep the network fair, open and honest.": "This helps to keep the network fair, open and honest.", "Timeout soon": "Timeout soon", @@ -490,13 +447,11 @@ "Transaction summary": "Transaction summary", "Transactions": "Transactions", "Try again": "Try again", - "Type at least 3 characters": "Type at least 3 characters", "Unable to connect to the node, no response from the server.": "Unable to connect to the node, no response from the server.", "Unable to connect to the node, please check the address and try again": "Unable to connect to the node, please check the address and try again", "Unable to detect the communication layer with your Hardware Wallet": "Unable to detect the communication layer with your Hardware Wallet", "Unable to detect the communication layer. Is ledger connected? Is Fido U2F Extension Installed?": "Unable to detect the communication layer. Is ledger connected? Is Fido U2F Extension Installed?", "Undo": "Undo", - "Unlock account": "Unlock account", "Unnamed account": "Unnamed account", "Update download finished": "Update download finished", "Updates downloaded, application has to be restarted to apply the updates.": "Updates downloaded, application has to be restarted to apply the updates.", @@ -524,7 +479,6 @@ "Wallet address:": "Wallet address:", "Wallet details": "Wallet details", "We highly recommend deleting the PDF file after printing.": "We highly recommend deleting the PDF file after printing.", - "Welcome back": "Welcome back", "Welcome to Lisk Delegates!": "Welcome to Lisk Delegates!", "Welcome to the Lisk Hub!": "Welcome to the Lisk Hub!", "What is Lisk Academy?": "What is Lisk Academy?", @@ -537,7 +491,6 @@ "Window": "Window", "Would you like to download it now?": "Would you like to download it now?", "Write message": "Write message", - "You are looking into a saved account. In order to {{nextAction}} you need to enter your passphrase.": "You are looking into a saved account. In order to {{nextAction}} you need to enter your passphrase.", "You can explore Lisk network using Hub without signing in.": "You can explore Lisk network using Hub without signing in.", "You can find out more about Lisk’s delgates, voting mechanism and benefits in a dedicated section of Lisk’s help centre.": "You can find out more about Lisk’s delgates, voting mechanism and benefits in a dedicated section of Lisk’s help centre.", "You can find the {{activeToken}} token on all of the worlds top exchanges and send them to your unique {{currency}} address:": "You can find the {{activeToken}} token on all of the worlds top exchanges and send them to your unique {{currency}} address:", @@ -573,7 +526,6 @@ "[Today], hh:mm a": "[Today], hh:mm a", "[Tomorrow], hh:mm a": "[Tomorrow], hh:mm a", "[Yesterday], hh:mm a": "[Yesterday], hh:mm a", - "for full access": "for full access", "from": "from", "ie. 192.168.0.1": "ie. 192.168.0.1", "ie. Lisker123": "ie. Lisker123", diff --git a/jest.config.js b/jest.config.js index bd9a9af637..c95b925e73 100644 --- a/jest.config.js +++ b/jest.config.js @@ -43,7 +43,6 @@ module.exports = { 'app/src/ledger.js', 'src/actions/liskService.js', 'src/actions/transactions.js', - 'src/components/account/stories.js', 'src/components/accountInitialization/index.js', 'src/components/backgroundMaker/index.js', 'src/components/dashboard/currencyGraph.js', // This should be unskipped in issue #1499 @@ -64,7 +63,6 @@ module.exports = { 'src/components/request/index.js', 'src/components/request/index.js', 'src/components/request/specifyRequest.js', - 'src/components/resultBox/index.js', 'src/components/searchBar/index.js', // Passing in mocha but not in Jest 'src/components/send/steps/form/stories.js', 'src/components/spinner/stories.js', diff --git a/src/components/account/account.css b/src/components/account/account.css deleted file mode 100644 index 638229e8b7..0000000000 --- a/src/components/account/account.css +++ /dev/null @@ -1,109 +0,0 @@ -@import './../app/variables.css'; - -.wrapper { - margin: 8px -8px 16px; -} - -.network { - margin-right: 8px; - margin-top: -3px; -} - -.value-wrapper { - position: relative; - width: 100%; - height: 70px; - text-align: center; - background: #eee; - overflow: hidden; - - & :global .inner { - font-size: 100%; - color: #5f696e; - display: inline-block; - width: 100%; - margin: 0; - box-sizing: border-box; - position: relative; - z-index: 1; - - &.primary { - font-weight: bold; - padding: 9px; - } - - &.secondary { - font-size: 100%; - } - - &.full { - line-height: 51px; - height: 70px; - } - - &.tooltip { - position: absolute; - width: 100%; - text-align: center; - left: 0; - top: 100%; - transition: all ease 200ms; - font-size: 85% !important; - z-index: 0; - } - - &.hasTip:hover { - color: #000; - } - - &.hasTip:hover + .tooltip { - top: 45px; - } - } - - & :global .status { - position: absolute; - top: 5px; - right: 5px; - z-index: 1; - } -} - -.title { - color: var(--color-grayscale-dark); - height: 56px; - display: flex; - flex-direction: column; - justify-content: center; - - & span:first-child { - font-weight: 600; - } -} - -.testnetTitle, -.devnetTitle { - color: var(--color-grayscale-dark); -} - -.current { - color: var(--color-grayscale-dark); - margin-top: 8px; - margin-left: 32px; - display: inline-block; -} - -.peer { - font-size: 16px; - display: inline-block; - text-align: left; - width: auto; - height: 56px; - margin-bottom: 20px; -} - -@media (--medium-viewport) { - .peer { - display: none; - } -} diff --git a/src/components/account/account.js b/src/components/account/account.js deleted file mode 100644 index cd2a6dff99..0000000000 --- a/src/components/account/account.js +++ /dev/null @@ -1,52 +0,0 @@ -import React from 'react'; -import Lisk from '@liskhq/lisk-client'; -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, 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) - ? - : ; - - const shouldShowNetworkIndicator = (peers.liskAPIClient - && (showNetworkIndicator || peers.options.code !== networks.mainnet.code)); - - return (shouldShowNetworkIndicator - ? ( -
-
- - {status} - {t('Connected to ')} - {translations[iconCode]} - - - {peers.liskAPIClient.currentNode} - -
-
- ) - : null - ); -}; - -export default Account; diff --git a/src/components/account/account.test.js b/src/components/account/account.test.js deleted file mode 100644 index df4278502e..0000000000 --- a/src/components/account/account.test.js +++ /dev/null @@ -1,72 +0,0 @@ -import React from 'react'; -import Lisk from '@liskhq/lisk-client'; -import { expect } from 'chai'; -import { shallow } from 'enzyme'; -import sinon from 'sinon'; -import networks from '../../constants/networks'; -import Account from './account'; - -describe('Account', () => { - let props; - - beforeEach(() => { - props = { - t: key => key, - i18n: {}, - store: {}, - onActivePeerUpdated: sinon.spy(), - showNetworkIndicator: true, - peers: { - status: { - online: false, - }, - liskAPIClient: { - currentPeer: 'localhost', - port: 4000, - }, - options: { - name: 'Custom Node', - }, - }, - account: { - isDelegate: false, - address: '16313739661670634666L', - username: 'lisk-hub', - balance: 1e8, - }, - }; - }); - - // Should be updated once we know what happens with this component - // Maybe it should be merged with the avatar or sidebar part, we don't know yet - it.skip('should Address component', () => { - const wrapper = shallow(); - expect(wrapper.find('Address')).to.have.lengthOf(1); - }); - - it('shows network indicator online', () => { - props.peers.status.online = true; - props.peers.options.code = networks.mainnet.code; - const wrapper = shallow(); - 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.liskAPIClient.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/account/index.js b/src/components/account/index.js deleted file mode 100644 index bd3ef5f807..0000000000 --- a/src/components/account/index.js +++ /dev/null @@ -1,14 +0,0 @@ -/* istanbul skip file */ -import { connect } from 'react-redux'; -import { translate } from 'react-i18next'; -import Account from './account'; - -/** - * Passing state - */ -const mapStateToProps = state => ({ - peers: state.peers, - account: state.account, -}); - -export default connect(mapStateToProps)(translate()(Account)); diff --git a/src/components/account/stories.js b/src/components/account/stories.js deleted file mode 100644 index 9cbe88bddf..0000000000 --- a/src/components/account/stories.js +++ /dev/null @@ -1,34 +0,0 @@ -import React from 'react'; -import { Provider } from 'react-redux'; - -import { storiesOf } from '@storybook/react'; -import Account from './account'; -import store from '../../store'; - -storiesOf('Account', module) - .add('delegate', () => ( - - - - )); diff --git a/src/components/accountInitialization/accountInit.css b/src/components/accountInitialization/accountInit.css deleted file mode 100644 index 7e2e7b24b6..0000000000 --- a/src/components/accountInitialization/accountInit.css +++ /dev/null @@ -1,59 +0,0 @@ -@import '../app/variables.css'; - -:root { - --font-size-L: 16px; - --font-size-XS: 14px; -} - -.wrapper { - height: 100%; - width: 100%; - display: flex; - flex-direction: column; - justify-content: space-between; - - & header { - & h2 { - font-weight: var(--font-weight-semi-bold); - text-align: left; - } - } - - & p { - line-height: 30px; - font-size: var(--font-size-L); - } - - & a { - font-weight: var(--font-weight-bold); - color: var(--color-link); - text-decoration: none; - } - - & .button { - font-weight: var(--font-weight-bold); - font-size: var(--font-size-L); - letter-spacing: 0; - line-height: 18px; - text-transform: none; - min-width: 0; - width: 100%; - } - - & > footer { - padding: 0; - margin-bottom: 20px; - } -} - -@media (--xSmall-viewport) { - .wrapper { - & p { - font-size: var(--font-size-XS); - } - - & .button { - font-size: var(--font-size-XS); - } - } -} diff --git a/src/components/accountInitialization/index.js b/src/components/accountInitialization/index.js deleted file mode 100644 index 2f10e58b83..0000000000 --- a/src/components/accountInitialization/index.js +++ /dev/null @@ -1,85 +0,0 @@ -import React from 'react'; -import { connect } from 'react-redux'; -import { translate } from 'react-i18next'; -import grid from 'flexboxgrid/dist/flexboxgrid.css'; -import { Button } from '../toolbox/buttons/button'; -import styles from './accountInit.css'; -import fees from '../../constants/fees'; -import { parseSearchParams } from '../../utils/searchParams'; -import { fromRawLsk } from '../../utils/lsk'; -import Piwik from '../../utils/piwik'; - -class AccountInitialization extends React.Component { - closeInfo() { - Piwik.trackingEvent('AccountInit', 'button', 'Close info dialog'); - this.props.nextStep(); - } - - componentDidMount() { - const { - account, nextStep, history, transactions, address, - } = this.props; - const search = Object.keys(parseSearchParams(history.location.search)); - const needsNoAccountInit = account.serverPublicKey - || account.balance === 0 - || transactions.pending.length > 0; - - if (search.includes('initializeAccount') && !needsNoAccountInit) { - history.replace({ - pathname: history.location.pathname, - search: '', - }); - nextStep({ account, accountInit: true }, 2); - } else if (needsNoAccountInit || address || search.includes('wallet')) { - nextStep(); - } - } - - onNext() { - const { account, nextStep } = this.props; - Piwik.trackingEvent('AccountInit', 'button', 'Next step'); - nextStep({ account, accountInit: true }, 2); - } - - render() { - const { t } = this.props; - - return ( -
-
-

{t('Initialize Lisk ID')}

-
-
-

{t('It is recommended that you initialize your Lisk ID.')}

-

{t('The easiest way to do this is to send LSK to yourself. It will cost you only the usual {{fee}} LSK transaction fee.', { fee: fromRawLsk(fees.send) })}

-
-
-
-
-
-
-
-
-
{t('Confirmation in the next step')}
-
-
- ); - } -} - -const mapStateToProps = state => ({ - account: state.account, - transactions: state.transactions, -}); - -export default connect(mapStateToProps)(translate()(AccountInitialization)); diff --git a/src/components/actionBar/actionBar.css b/src/components/actionBar/actionBar.css deleted file mode 100644 index 619e768ee0..0000000000 --- a/src/components/actionBar/actionBar.css +++ /dev/null @@ -1,4 +0,0 @@ -.button { - min-width: 0; - width: 100%; -} diff --git a/src/components/actionBar/actionBar.js b/src/components/actionBar/actionBar.js deleted file mode 100644 index e75bff412b..0000000000 --- a/src/components/actionBar/actionBar.js +++ /dev/null @@ -1,33 +0,0 @@ -import React from 'react'; -import grid from 'flexboxgrid/dist/flexboxgrid.css'; -import PricedButton from '../pricedButton'; -import styles from './actionBar.css'; -import { Button } from '../toolbox/buttons/button'; - -const ActionBar = ({ - secondaryButton, primaryButton, account, t, className, -}) => ( -
-
-); - -export default ActionBar; diff --git a/src/components/actionBar/index.js b/src/components/actionBar/index.js deleted file mode 100644 index 3458f2ca2d..0000000000 --- a/src/components/actionBar/index.js +++ /dev/null @@ -1,4 +0,0 @@ -import { translate } from 'react-i18next'; -import ActionBar from './actionBar'; - -export default translate()(ActionBar); diff --git a/src/components/actionBar/index.test.js b/src/components/actionBar/index.test.js deleted file mode 100644 index 8854a83e7d..0000000000 --- a/src/components/actionBar/index.test.js +++ /dev/null @@ -1,68 +0,0 @@ -import React from 'react'; -import { expect } from 'chai'; -import { mount } from 'enzyme'; -import configureStore from 'redux-mock-store'; -import PropTypes from 'prop-types'; -import sinon from 'sinon'; -import i18n from '../../i18n'; -import ActionBar from './actionBar'; -// import * as accountApi from '../../utils/api/account'; - -const fakeStore = configureStore(); - -describe('ActionBar', () => { - let wrapper; - let props; - - beforeEach(() => { - props = { - secondaryButton: { - label: 'Test cancel', - onClick: sinon.spy(), - }, - primaryButton: { - label: 'Test confirm', - disabled: false, - onClick: sinon.spy(), - }, - }; - const store = fakeStore({ - account: { - balance: 100e8, - }, - }); - wrapper = mount(, { - context: { store, i18n }, - childContextTypes: { - store: PropTypes.object.isRequired, - i18n: PropTypes.object.isRequired, - }, - }); - }); - - it('renders two Button components', () => { - expect(wrapper.find('Button')).to.have.length(2); - }); - - it('binds props.secondaryButton.label to first button label', () => { - expect(wrapper.find('Button').at(0).props().label).to.equal(props.secondaryButton.label); - }); - - it('binds props.primaryButton.label to second button label', () => { - expect(wrapper.find('Button').at(1).props().label).to.equal(props.primaryButton.label); - }); - - it('binds props.primaryButton.disabled to second button disabled', () => { - expect(wrapper.find('Button').at(1).props().disabled).to.equal(props.primaryButton.disabled); - }); - - it('binds props.secondaryButton.onClick to first button onClick', () => { - wrapper.find('Button').at(0).simulate('click'); - expect(props.secondaryButton.onClick).to.have.been.calledWith(); - }); - - it('binds props.primaryButton.onClick to second button onClick', () => { - wrapper.find('Button').at(1).simulate('click'); - expect(props.primaryButton.onClick).to.have.been.calledWith(); - }); -}); diff --git a/src/components/authInputs/authInputs.js b/src/components/authInputs/authInputs.js deleted file mode 100644 index 19fd54ab69..0000000000 --- a/src/components/authInputs/authInputs.js +++ /dev/null @@ -1,60 +0,0 @@ -import React from 'react'; -// eslint-disable-next-line import/no-named-as-default -import PassphraseInput from '../passphraseInput'; -import { extractPublicKey } from '../../utils/account'; - -class AuthInputs extends React.Component { - componentDidMount() { - if (this.props.account.secondPublicKey) { - this.props.onChange('secondPassphrase', ''); - } - } - - onChange(name, value, error) { - if (!error) { - const publicKeyMap = { - passphrase: 'publicKey', - secondPassphrase: 'secondPublicKey', - }; - const expectedPublicKey = this.props.account[publicKeyMap[name]]; - - if (expectedPublicKey && expectedPublicKey !== extractPublicKey(value)) { - error = this.props.t('Entered passphrase does not belong to the active account'); - } - } - this.props.onChange(name, value, error); - } - - render() { - return ( - - {(!this.props.account.passphrase - && ( - - ))} - {(this.props.account.secondPublicKey - && ( - - ))} - - ); - } -} - -export default AuthInputs; diff --git a/src/components/authInputs/authInputs.test.js b/src/components/authInputs/authInputs.test.js deleted file mode 100644 index 8ee41a895a..0000000000 --- a/src/components/authInputs/authInputs.test.js +++ /dev/null @@ -1,78 +0,0 @@ -import React from 'react'; -import { expect } from 'chai'; -import { mount } from 'enzyme'; -import sinon from 'sinon'; -import { I18nextProvider } from 'react-i18next'; - -import accounts from '../../../test/constants/accounts'; -import i18n from '../../i18n'; // initialized i18next instance -import AuthInputs from './authInputs'; - - -describe('AuthInputs', () => { - let wrapper; - let props; - const { passphrase } = accounts.delegate; - - beforeEach(() => { - props = { - onChange: sinon.spy(), - secondPassphrase: { value: '' }, - account: { - passphrase, - }, - passphrase: { - value: passphrase, - }, - t: key => key, - }; - }); - - it('should render Input if props.account.secondPublicKey', () => { - props.account.secondPublicKey = true; - wrapper = mount(); - expect(wrapper.find('Input')).to.have.lengthOf(1); - }); - - it('should render null if !props.account.secondPublicKey', () => { - props.account.secondPublicKey = false; - wrapper = mount(); - expect(wrapper.html()).to.equal(''); - }); - - it('should render null if !props.account.secondPublicKey', () => { - props.account.secondPublicKey = false; - wrapper = mount(); - expect(wrapper.html()).to.equal(''); - }); - - it('should call props.onChange when input value changes', () => { - props.account.secondPublicKey = true; - wrapper = mount(); - wrapper.find('.second-passphrase input').first().simulate('change', { target: { value: passphrase } }); - expect(props.onChange).to.have.been.calledWith('secondPassphrase', passphrase); - }); - - it('should call props.onChange with an error if entered secondPassphrase does not belong to secondPublicKey', () => { - const error = 'Entered passphrase does not belong to the active account'; - props.account.secondPublicKey = true; - props.account.secondPublicKey = 'fab9d261ea050b9e326d7e11587eccc343a20e64e29d8781b50fd06683cacc88'; - wrapper = mount(); - wrapper.find('.second-passphrase input').first().simulate('change', { target: { value: passphrase } }); - expect(props.onChange).to.have.been.calledWith('secondPassphrase', passphrase, error); - }); - - it('should call props.onChange(\'secondPassphrase\', \'Required\') when input value changes to \'\'', () => { - props.account.secondPublicKey = true; - wrapper = mount(); - wrapper.find('.second-passphrase input').first().simulate('change', { target: { value: '' } }); - expect(props.onChange).to.have.been.calledWith('secondPassphrase', '', 'Required'); - }); - - it('should call props.onChange(\'secondPassphrase\', \'Invalid passphrase\') when input value changes to \'test\'', () => { - props.account.secondPublicKey = true; - wrapper = mount(); - wrapper.find('.second-passphrase input').first().simulate('change', { target: { value: 'test' } }); - expect(props.onChange).to.have.been.calledWith('secondPassphrase', 'test', 'Passphrase should have 12 words, entered passphrase has 1'); - }); -}); diff --git a/src/components/authInputs/index.js b/src/components/authInputs/index.js deleted file mode 100644 index 52d15260b2..0000000000 --- a/src/components/authInputs/index.js +++ /dev/null @@ -1,11 +0,0 @@ -/* istanbul skip file */ -import { connect } from 'react-redux'; -import { translate } from 'react-i18next'; - -import AuthInputs from './authInputs'; - -const mapStateToProps = state => ({ - account: state.account, -}); - -export default connect(mapStateToProps)(translate()(AuthInputs)); diff --git a/src/components/authenticate/authenticate.js b/src/components/authenticate/authenticate.js deleted file mode 100644 index af157af8c5..0000000000 --- a/src/components/authenticate/authenticate.js +++ /dev/null @@ -1,76 +0,0 @@ -import React from 'react'; -import { handleChange, authStatePrefill, authStateIsValid } from '../../utils/form'; -import ActionBar from '../actionBar'; -import AuthInputs from '../authInputs'; -import InfoParagraph from '../infoParagraph'; -import Piwik from '../../utils/piwik'; - -class Authenticate extends React.Component { - constructor() { - super(); - this.state = { - ...authStatePrefill(), - }; - this.message = ''; - } - - componentDidMount() { - const newState = { - ...authStatePrefill(this.props.account), - }; - this.setState(newState); - } - - componentWillUpdate(props) { - const { nextAction, t } = props; - this.message = `${t('You are looking into a saved account. In order to {{nextAction}} you need to enter your passphrase.', { nextAction })}`; - } - - update() { - Piwik.trackingEvent('Authenticate', 'button', 'Update'); - const data = { - passphrase: this.state.passphrase.value, - }; - if (typeof this.props.account.secondPublicKey === 'string') { - data.secondPassphrase = this.state.secondPassphrase.value; - } - this.props.accountUpdated(data); - } - - closeDialog(e) { - e.preventDefault(); - Piwik.trackingEvent('Authenticate', 'button', 'Close dialog'); - this.props.closeDialog(); - } - - render() { - return ( -
- - {this.message} - - - - - - - ); - } -} - -export default Authenticate; diff --git a/src/components/authenticate/authenticate.test.js b/src/components/authenticate/authenticate.test.js deleted file mode 100644 index ee2ed909b3..0000000000 --- a/src/components/authenticate/authenticate.test.js +++ /dev/null @@ -1,133 +0,0 @@ -import React from 'react'; -import { expect } from 'chai'; -import { mount } from 'enzyme'; -import configureStore from 'redux-mock-store'; -import i18next from 'i18next'; -import PropTypes from 'prop-types'; -import { spy } from 'sinon'; -import accounts from '../../../test/constants/accounts'; -import ActionBar from '../actionBar'; -import i18n from '../../i18n'; -import Authenticate from './authenticate'; - - -const fakeStore = configureStore(); - -describe('Authenticate', () => { - let wrapper; - let props; - - const peers = { - status: { - online: false, - }, - data: { - currentPeer: 'localhost', - port: 4000, - options: { - name: 'Custom Node', - }, - }, - }; - - const account = { - isDelegate: false, - publicKey: accounts.genesis.publicKey, - secondPublicKey: accounts.genesis.serverPublicKey, - address: accounts.genesis.address, - }; - - const { passphrase } = accounts.genesis; - - beforeEach(() => { - props = { - account, - peers, - t: (str, opts) => i18next.t(str, opts), - nextAction: 'perform a sample action', - closeDialog: spy(), - accountUpdated: spy(), - }; - - const store = fakeStore({ - account: { - balance: 100e8, - }, - }); - wrapper = mount(, { - context: { store, i18n }, - childContextTypes: { - store: PropTypes.object.isRequired, - i18n: PropTypes.object.isRequired, - }, - }); - }); - - it('renders 3 compound React components', () => { - expect(wrapper.find('InfoParagraph')).to.have.length(1); - expect(wrapper.find(ActionBar)).to.have.length(1); - expect(wrapper.find('AuthInputs')).to.have.length(1); - }); - - it('should render InfoParagraph with appropriate message', () => { - expect(wrapper.find('InfoParagraph').text()).to.include(`You are looking into a saved account. In order to ${props.nextAction} you need to enter your passphrase`); - }); - - it('should activate primary button if correct passphrase entered', () => { - expect(wrapper.find('button.authenticate-button').props().disabled).to.equal(true); - wrapper.find('.passphrase input').first().simulate('change', { target: { value: passphrase } }); - expect(wrapper.find('button.authenticate-button').props().disabled).to.equal(false); - }); - - it('should call accountUpdated if entered passphrase and clicked submit', () => { - wrapper.find('.passphrase input').first().simulate('change', { target: { value: passphrase } }); - wrapper.update(); - wrapper.find('Button.authenticate-button').simulate('click'); - wrapper.update(); - expect(props.accountUpdated).to.have.been.calledWith({ - passphrase, - secondPassphrase: null, - }); - }); - - it('should call accountUpdated if entered passphrase and clicked submit without PublicKey', () => { - props = { - account: { - isDelegate: false, - publicKey: accounts.genesis.publicKey, - address: accounts.genesis.address, - }, - peers, - t: (str, opts) => i18next.t(str, opts), - nextAction: 'perform a sample action', - closeDialog: spy(), - accountUpdated: spy(), - }; - - const store = fakeStore({ - account: { - balance: 100e8, - }, - }); - const customWrapper = mount(, { - context: { store, i18n }, - childContextTypes: { - store: PropTypes.object.isRequired, - i18n: PropTypes.object.isRequired, - }, - }); - customWrapper.find('.passphrase input').first().simulate('change', { target: { value: passphrase } }); - customWrapper.update(); - customWrapper.find('Button.authenticate-button').simulate('click'); - customWrapper.update(); - expect(props.accountUpdated).to.have.been.calledWith({ - passphrase, - }); - }); - - it('should close dialog on click the close button', () => { - wrapper.find('button.closeDialog-button').simulate('click'); - wrapper.update(); - expect(props.closeDialog).to.have.been.calledWith(); - }); -}); diff --git a/src/components/authenticate/index.js b/src/components/authenticate/index.js deleted file mode 100644 index 69de71bac3..0000000000 --- a/src/components/authenticate/index.js +++ /dev/null @@ -1,22 +0,0 @@ -/* istanbul ignore file */ -import { connect } from 'react-redux'; -import { translate } from 'react-i18next'; -import { accountUpdated } from '../../actions/account'; -import Authenticate from './authenticate'; - -/** - * Passing state - */ -const mapStateToProps = state => ({ - peers: state.peers, - account: state.account, -}); - -const mapDispatchToProps = { - accountUpdated, -}; - -export default connect( - mapStateToProps, - mapDispatchToProps, -)(translate()(Authenticate)); diff --git a/src/components/autoSuggestV2/autoSuggest.css b/src/components/autoSuggestV2/autoSuggest.css deleted file mode 100644 index 852279e297..0000000000 --- a/src/components/autoSuggestV2/autoSuggest.css +++ /dev/null @@ -1,150 +0,0 @@ -@import './../app/variables.css'; -@import './../app/variablesV2.css'; - -:root { - --search-box-font-size: 12px; - --search-box-line-height: 56px; - --search-box-selection-background: var(--color-primary-light); -} - -.wrapper { - height: 36px; -} - -.autoSuggest { - display: none; - background-color: var(--color-white); - left: 0; - right: 0; - position: absolute; - top: 38px; - z-index: var(--autosuggest-index); - border-radius: 3px; - border-top: none; - max-height: 353px; - min-height: 41px; - box-shadow: var(--box-shadow-search); -} - -.show { - display: block; -} - -.placeholder { - background-color: transparent; - line-height: var(--search-box-line-height); - font-size: var(--search-box-font-size); - color: var(--color-grayscale-medium); - outline: none; - border: none; - position: absolute; - left: 24px; - z-index: var(--searchbar-placeholder-index); - pointer-events: none; - opacity: 0.5; - padding: 0 0 0 1px; - width: calc(100% - 44px); - text-overflow: ellipsis; - height: 33px; -} - -.noResults { - color: var(--color-primary-standard); - font-family: var(--content-font); - font-size: var(--button-font-size-s); - padding: 0 16px; -} - -.input { - padding: 1px; - z-index: var(--searchbar-input-index); - height: 36px; - background-color: var(--color-white); - border: 0.5px solid #a6adbd; - border-radius: var(--border-radius-standard); - - & input { - background-color: var(--color-white); - line-height: var(--search-box-line-height); - font-size: var(--search-box-font-size); - color: var(--color-grayscale-medium); - width: 94%; - padding: 0px; - padding-left: 24px; - border-radius: 3px; - border: none; - transition: background-color 300ms linear; - height: 31px; - - &::selection { - color: var(--color-white); - background: var(--search-box-selection-background); - } - - &::placeholder { - color: var(--color-grayscale-medium); - font-weight: 200; - letter-spacing: 0; - } - - &:focus { - outline: none; - background-color: var(--color-white); - } - } - - & span:nth-child(2) { - display: none; - position: absolute; - bottom: 0; - left: 0; - right: 0; - - &::before, - &::after { - background-color: var(--color-grayscale-light); - } - } - - & .icon { - width: 15px; - height: 15px; - position: absolute; - top: 12px; - right: 13px; - cursor: pointer; - font-size: 14px; - } - - & .iconSearch { - color: var(--color-grayscale-medium); - width: 20px; - height: 20px; - top: 9px; - font-size: 20px; - } -} - -@media (--medium-viewport) { - .wrapper { - margin-right: 0; - } - - .autoSuggest { - right: 0; - } - - .placeholder { - left: 22px; - } - - .input { - & input { - padding-left: 21px; - } - - & .icon { - padding: 0 21px 21px; - } - } -} diff --git a/src/components/autoSuggestV2/index.js b/src/components/autoSuggestV2/index.js deleted file mode 100644 index 3fa3aa2918..0000000000 --- a/src/components/autoSuggestV2/index.js +++ /dev/null @@ -1,418 +0,0 @@ -// eslint-disable-line max-lines -import React from 'react'; -import Input from 'react-toolbox/lib/input'; -import styles from './autoSuggest.css'; -import LiskAmount from '../liskAmount'; -import { FontIcon } from '../fontIcon'; -import ResultsList from './resultsList'; -import routes from '../../constants/routes'; -import keyCodes from '../../constants/keyCodes'; -import localJSONStorage from '../../utils/localJSONStorage'; -import regex from '../../utils/regex'; -import { saveSearch } from '../searchResult/keyAction'; -import { searchEntities } from '../../constants/search'; -import Piwik from '../../utils/piwik'; - -class AutoSuggest extends React.Component { - constructor(props) { - super(props); - this.submitSearch = this.submitSearch.bind(this); - this.selectedRow = null; - this.lastSearch = null; - this.state = { - show: false, - value: '', - selectedIdx: -1, - resultsLength: 0, - placeholder: '', - cleared: true, - }; - } - - componentDidMount() { - this.resetSearch(); - } - - componentDidUpdate() { - if (this.shouldSubmit && this.state.placeholder) { - this.handleSubmit(); - this.shouldSubmit = false; - } - } - - // eslint-disable-next-line max-statements - componentWillReceiveProps(nextProps) { - this.selectedRow = null; - const resultsLength = Object.keys(searchEntities).reduce((total, resultKey) => - total + nextProps.results[resultKey].length, 0); - let placeholder = ''; - let selectedIdx = -1; - if (resultsLength > 0) { - placeholder = this.getValueFromCurrentIdx(0, nextProps.results); - selectedIdx = 0; - } - this.setState({ resultsLength, selectedIdx, placeholder }); - - if (nextProps.account && nextProps.account.afterLogout === this.state.cleared) { - this.resetSearch(); - this.setState({ cleared: false }); - } - } - - // eslint-disable-next-line max-statements - onResultClick(id, type, value) { - Piwik.trackingEvent('AutoSuggest', 'button', 'Results'); - let urlSearch; - switch (type) { - case searchEntities.addresses: - case searchEntities.delegates: - urlSearch = `${routes.accounts.pathPrefix}${routes.accounts.path}/${id}`; - break; - case searchEntities.transactions: - urlSearch = `${routes.transactions.pathPrefix}${routes.transactions.path}/${id}`; - break; - /* istanbul ignore next */ - default: - break; - } - - saveSearch(value, id); - - if (!value && [searchEntities.addresses, searchEntities.transactions].filter(entity => - entity === type).length > 0) { - this.setState({ value: id }); - } else if (value) { - this.setState({ value, placeholder: '' }); - } else { - this.setState({ value: this.state.placeholder }); - } - - this.inputRef.blur(); - this.props.history.push(urlSearch); - } - - setSelectedRow(el) { - this.selectedRow = el; - } - - submitSearch() { - Piwik.trackingEvent('AutoSuggest', 'button', 'Search submit'); - this.onResultClick( - this.selectedRow.dataset.id, - this.selectedRow.dataset.type, - this.selectedRow.dataset.value, - ); - } - - /* istanbul ignore next */ - submitAnySearch() { - let searchType = null; - if (this.state.value.match(regex.address)) { - searchType = searchEntities.addresses; - } else if (this.state.value.match(regex.transactionId)) { - searchType = searchEntities.transactions; - } - - if (!searchType) { - this.props.history.push(`${routes.search.pathPrefix}${routes.search.path}/${encodeURIComponent(this.state.value)}`); - return; - } - this.onResultClick(this.state.value, searchType, this.state.value); - } - - search(searchTerm) { - this.setState({ value: searchTerm, placeholder: '' }); - if (searchTerm.length < 3) { - this.props.searchClearSuggestions(); - return; - } - - this.setState({ show: true }); - clearTimeout(this.timeout); - this.timeout = setTimeout(() => { - if (searchTerm === this.state.value) { - this.lastSearch = searchTerm; - this.props.searchSuggestions({ - searchTerm: this.state.value, - }); - } - }, 250); - } - - handleArrowDown() { - let currentIdx = this.state.selectedIdx; - let placeholder = ''; - if (this.state.resultsLength === 0) { - currentIdx = (currentIdx === this.recentSearches.length - 1) - ? this.recentSearches.length - 1 : currentIdx += 1; - placeholder = this.recentSearches[currentIdx].valueLeft; - } else { - currentIdx = (currentIdx === this.state.resultsLength) - ? this.state.resultsLength : currentIdx += 1; - placeholder = this.getValueFromCurrentIdx(currentIdx, this.props.results); - } - this.setState({ selectedIdx: currentIdx, placeholder }); - } - - handleArrowUp() { - let currentIdx = this.state.selectedIdx; - currentIdx = (currentIdx === 0) ? 0 : currentIdx -= 1; - let placeholder = ''; - /* istanbul ignore if */ - if (this.state.resultsLength === 0) { - placeholder = this.recentSearches[currentIdx].valueLeft; - } else { - placeholder = this.getValueFromCurrentIdx(currentIdx, this.props.results); - } - this.setState({ selectedIdx: currentIdx, placeholder }); - } - - // eslint-disable-next-line class-methods-use-this - getValueFromCurrentIdx(index, resultsObj) { - const targetResult = [ - { results: resultsObj.delegates, key: 'username' }, - { results: resultsObj.addresses, key: 'address' }, - { results: resultsObj.transactions, key: 'id' }, - ].filter(resultObj => index < resultObj.results.length); - return (targetResult.length && targetResult[0].results[index][targetResult[0].key]) || ''; - } - - handleSubmit() { - Piwik.trackingEvent('AutoSuggest', 'button', 'Handle submit'); - /* istanbul ignore if */ - if (this.state.value === '' && this.state.placeholder === '') { - return; - } - - const accountTransactionRegex = /^\d+?(L$|$)/; - /* istanbul ignore else */ - if (this.state.value.length > 2 && this.state.resultsLength === 0 - && !accountTransactionRegex.test(this.state.value)) { - this.shouldSubmit = true; - return; - } - - if (this.state.resultsLength > 0 || this.state.placeholder !== '') { - this.submitSearch(); - } else { - this.submitAnySearch(); - } - } - - handleKey(event) { - switch (event.keyCode) { - case keyCodes.arrowDown: - this.handleArrowDown(); - event.preventDefault(); - break; - case keyCodes.arrowUp: - this.handleArrowUp(); - event.preventDefault(); - break; - case keyCodes.escape: - this.closeDropdown(); - break; - case keyCodes.enter: - case keyCodes.tab: - this.handleSubmit(); - break; - /* istanbul ignore next */ - default: - this.shouldSubmit = false; - break; - } - return false; - } - - resetSearch() { - Piwik.trackingEvent('AutoSuggest', 'button', 'Clear suggestions'); - this.lastSearch = null; - this.setState({ value: '', placeholder: '' }); - this.props.searchClearSuggestions(); - this.closeDropdown(); - } - - closeDropdown() { - this.setState({ show: false }); - } - - // istanbul ignore next - selectInput() { - Piwik.trackingEvent('AutoSuggest', 'button', 'Select Input'); - this.inputRef.inputNode.select(); - } - - getDelegatesResults() { - return this.props.results.delegates.map((delegate, idx) => ({ - id: delegate.account.address, - valueLeft: delegate.username, - valueRight: delegate.rank, - isSelected: idx === this.state.selectedIdx, - type: searchEntities.delegates, - })); - } - - getAddressesResults() { - return this.props.results.addresses.map((account, idx) => ({ - id: account.address, - valueLeft: account.address, - valueRight: - - {' '} -LSK - , - isSelected: this.props.results.delegates.length + idx === this.state.selectedIdx, - type: searchEntities.addresses, - })); - } - - getTransactionsResults() { - return this.props.results.transactions.map((transaction, idx) => ({ - id: transaction.id, - valueLeft: transaction.id, - valueRight: transaction.height, - isSelected: this.props.results.delegates.length - + this.props.results.addresses.length + idx === this.state.selectedIdx, - type: searchEntities.transactions, - })); - } - - getRecentSearchResults() { - this.recentSearches = localJSONStorage.get('searches', []) - .filter(result => typeof result === 'object') - .map((result, idx) => { - let type = searchEntities.addresses; - if (result.id.match(regex.transactionId)) { - type = searchEntities.transactions; - } - return { - id: result.id, - valueLeft: result.searchTerm, - valueRight: '', - isSelected: idx === this.state.selectedIdx, - type, - }; - }); - return this.recentSearches; - } - - getNoResultMessage() { - let noResultMessage; - if (this.state.value.length > 0 && this.state.value.length <= 2) { - noResultMessage = this.props.t('Type at least 3 characters'); - } - if (this.state.value.length > 2 && this.state.resultsLength === 0) { - noResultMessage = this.props.t('No results found'); - } - return noResultMessage; - } - - render() { - const { t } = this.props; - - let placeholderValue = ''; - if (this.state.placeholder === '' && this.state.value === '') { - placeholderValue = t('Search for delegate, Lisk ID, transaction ID'); - } else { - placeholderValue = this.state.placeholder; - } - - return ( -
- { - }} - className={`${styles.placeholder} autosuggest-placeholder`} - type="text" - name="autosuggest-placeholder" - /> - { - this.inputRef = el; - }} - className={`${styles.input} autosuggest-input`} - theme={styles} - onClick={this.selectInput.bind(this)} - onFocus={() => this.setState({ show: true })} - onBlur={this.closeDropdown.bind(this)} - onKeyDown={this.handleKey.bind(this)} - onChange={this.search.bind(this)} - autoComplete="off" - > - { - this.state.value !== '' || this.state.placeholder !== '' - ? ( - - ) - : ( - - ) - } - -
- - - - {this.state.value === '' && this.state.resultsLength === 0 - ? ( - - ) - : null - } -

{this.getNoResultMessage()}

-
-
- ); - } -} - -export default AutoSuggest; diff --git a/src/components/autoSuggestV2/index.test.js b/src/components/autoSuggestV2/index.test.js deleted file mode 100644 index 1f71776dc8..0000000000 --- a/src/components/autoSuggestV2/index.test.js +++ /dev/null @@ -1,246 +0,0 @@ -import React from 'react'; -import { expect } from 'chai'; -import configureMockStore from 'redux-mock-store'; -import { spy, stub, useFakeTimers } from 'sinon'; -import { mountWithContext } from '../../../test/unit-test-utils/mountHelpers'; -import AutoSuggest from './index'; -import styles from './autoSuggest.css'; -import * as searchActions from '../searchResult/keyAction'; -import localJSONStorageUtil from '../../utils/localJSONStorage'; -import routes from '../../constants/routes'; -import keyCodes from '../../constants/keyCodes'; -import mockSearchResults from './searchResults.mock'; - -describe('AutoSuggest', () => { - let wrapper; - let props; - let results; - let localStorageStub; - let submitSearchSpy; - let submitSearchAnythingSpy; - let saveSearchSpy; - let clock; - - beforeEach(() => { - localStorageStub = stub(localJSONStorageUtil, 'get'); - localStorageStub.withArgs('searches', []).returns([]); - results = { ...mockSearchResults }; - props = { - account: { - address: '123L', - }, - t: key => key, - history: { - push: spy(), - }, - results, - searchSuggestions: spy(), - searchClearSuggestions: spy(), - }; - - const store = configureMockStore([])({ - search: { - suggestions: { - delegates: [], - addresses: [], - transactions: [], - }, - }, - }); - clock = useFakeTimers({ - toFake: ['setTimeout', 'clearTimeout', 'Date', 'setInterval'], - }); - - submitSearchSpy = spy(AutoSuggest.prototype, 'submitSearch'); - submitSearchAnythingSpy = spy(AutoSuggest.prototype, 'submitAnySearch'); - saveSearchSpy = spy(searchActions, 'saveSearch'); - wrapper = mountWithContext(, { storeState: store }); - wrapper.update(); - }); - - afterEach(() => { - localStorageStub.restore(); - submitSearchSpy.restore(); - submitSearchAnythingSpy.restore(); - saveSearchSpy.restore(); - clock.restore(); - }); - - it('should render a row for each entity found {addresses,delegates,transactions}', () => { - expect(wrapper).to.have.exactly(3).descendants('.addresses-result'); - expect(wrapper).to.have.exactly(3).descendants('.delegates-result'); - expect(wrapper).to.have.exactly(3).descendants('.transactions-result'); - }); - - it('should not render any row for not found entities {delegates}', () => { - const partialResults = { - ...results, - addresses: [], - transactions: [], - }; - wrapper.setProps({ results: partialResults }); - wrapper.update(); - expect(wrapper).to.have.exactly(0).descendants('.addresses-result'); - expect(wrapper).to.have.exactly(3).descendants('.delegates-result'); - expect(wrapper).to.have.exactly(0).descendants('.transactions-result'); - }); - - it('should show recent searches when focusing on input and no search value has been entered yet', () => { - localStorageStub.withArgs('searches', []).returns([ - { id: '111L', searchTerm: 'pepe' }, - { id: '111', searchTerm: '' }, - ]); - wrapper.setProps({ - results: { - delegates: [], - addresses: [], - transactions: [], - }, - }); - wrapper.update(); - const autosuggestInput = wrapper.find('.autosuggest-input').find('input').first(); - autosuggestInput.simulate('focus'); - expect(wrapper).to.have.exactly(1).descendants('.addresses-result'); - expect(wrapper).to.have.exactly(1).descendants('.transactions-result'); - expect(props.searchSuggestions).not.to.have.been.calledWith(); - }); - - it('should show autosuggest on search input change, show suggestion, and hide it on blur', () => { - let autosuggestDropdown = wrapper.find('.autosuggest-dropdown').first(); - const autosuggestInput = wrapper.find('.autosuggest-input').find('input').first(); - expect(autosuggestDropdown).not.to.have.className(styles.show); - autosuggestInput.simulate('focus'); - autosuggestInput.simulate('change', { target: { value: 'peter' } }); - clock.tick(300); - wrapper.setProps({ - results: { - delegates: [results.delegates[0]], - addresses: [], - transactions: [], - }, - }); - wrapper.update(); - expect(wrapper.find('.autosuggest-placeholder')).to.have.value('peterpan'); - - expect(props.searchSuggestions).to.have.been.calledWith(); - autosuggestDropdown = wrapper.find('.autosuggest-dropdown').first(); - expect(autosuggestDropdown).to.have.className(styles.show); - - autosuggestInput.simulate('blur'); - wrapper.update(); - autosuggestDropdown = wrapper.find('.autosuggest-dropdown').first(); - expect(autosuggestDropdown).not.to.have.className(styles.show); - }); - - it('should allow to click on {addresss} suggestion and redirect to its "explorer/accounts" page', () => { - wrapper.find('.addresses-result').first().simulate('mousedown'); - expect(props.history.push).to.have.been - .calledWith(`${routes.accounts.pathPrefix}${routes.accounts.path}/${results.addresses[0].address}`); - }); - - it('should allow to click on {delegate} suggestion and redirect to its "explorer/accounts" page', () => { - wrapper.find('.delegates-result').first().simulate('mousedown'); - expect(props.history.push).to.have.been - .calledWith(`${routes.accounts.pathPrefix}${routes.accounts.path}/${results.delegates[0].account.address}`); - }); - - it('should allow to click on {transaction} suggestion and redirect to its "explorer/transactions" page', () => { - wrapper.find('.transactions-result').first().simulate('mousedown'); - expect(props.history.push).to.have.been - .calledWith(`${routes.transactions.pathPrefix}${routes.transactions.path}/${results.transactions[0].id}`); - }); - - it('should not redirect to search result page on keyboard event {enter} if no results', () => { - const autosuggestInput = wrapper.find('.autosuggest-input').find('input').first(); - autosuggestInput.simulate('change', { target: { value: 'notExistingDelegate' } }); - autosuggestInput.simulate('keyDown', { - keyCode: keyCodes.enter, - which: keyCodes.enter, - }); - expect(saveSearchSpy).not.to.have.been.calledWith(); - expect(props.history.push).not.to.have.been.calledWith(); - }); - - it('should update placeholder on events {arrowUp/arrowDown} and redirect to entity page on keyboard event {tab}', () => { - const autosuggestInput = wrapper.find('.autosuggest-input').find('input').first(); - - wrapper.setProps({ - results: { - delegates: results.delegates, - addresses: [results.addresses[0]], - transactions: [results.transactions[0]], - }, - }); - wrapper.update(); - autosuggestInput.simulate('change', { target: { value: 'peter' } }); - autosuggestInput.simulate('keyDown', { - keyCode: keyCodes.arrowDown, - which: keyCodes.arrowDown, - }); - autosuggestInput.simulate('keyDown', { - keyCode: keyCodes.arrowDown, - which: keyCodes.arrowDown, - }); - wrapper.update(); - // first result of transactions mock data - expect(wrapper.find('.autosuggest-placeholder')).to.have.value(results.delegates[2].username); - autosuggestInput.simulate('keyDown', { - keyCode: keyCodes.arrowUp, - which: keyCodes.arrowUp, - }); - autosuggestInput.simulate('keyDown', { - keyCode: keyCodes.tab, - which: keyCodes.tab, - }); - expect(submitSearchSpy).to.have.been.calledWith(); - }); - - it('should show recent searches and close dropdown on keyboard event {escape}', () => { - const autosuggestInput = wrapper.find('.autosuggest-input').find('input').first(); - localStorageStub.withArgs('searches', []).returns([ - { searchTerm: 'genesis_11', id: '1478505779553195737L' }, - { searchTerm: '8500285156990763245', id: '8500285156990763245' }, - { searchTerm: '10881167371402274308L', id: '10881167371402274308L' }, - ]); - wrapper.setProps({ - results: { - delegates: [], - addresses: [], - transactions: [], - }, - }); - wrapper.update(); - - autosuggestInput.simulate('change'); - - autosuggestInput.simulate('keyDown', { - keyCode: keyCodes.arrowDown, - which: keyCodes.arrowDown, - }); - expect(wrapper.find('.autosuggest-placeholder')).to.have.value('genesis_11'); - - autosuggestInput.simulate('keyDown', { - keyCode: keyCodes.escape, - which: keyCodes.escape, - }); - expect(submitSearchSpy).not.to.have.been.calledWith(); - const autosuggestDropdown = wrapper.find('.autosuggest-dropdown').first(); - expect(autosuggestDropdown).not.to.have.className(styles.show); - }); - - it('should call searchClearSuggestions when resetSearch is triggered', () => { - const autosuggestInput = wrapper.find('.autosuggest-input').find('input').first(); - - wrapper.setState({ - value: 'test', - placeholder: 'test', - }); - wrapper.update(); - autosuggestInput.simulate('change', { target: { value: 'peter' } }); - wrapper.update(); - - wrapper.find('.autosuggest-btn-close').at(0).simulate('click'); - - expect(props.searchClearSuggestions).to.have.been.calledWith(); - }); -}); diff --git a/src/components/autoSuggestV2/resultsList.css b/src/components/autoSuggestV2/resultsList.css deleted file mode 100644 index 6e3acb6997..0000000000 --- a/src/components/autoSuggestV2/resultsList.css +++ /dev/null @@ -1,62 +0,0 @@ -@import './../app/variables.css'; -@import './../app/variablesV2.css'; - -.resultList { - list-style-type: none; - display: flex; - flex-direction: column; - align-content: flex-start; - margin: 0; - padding: 0; - - &:last-child { - padding-bottom: 15px; - } -} - -.row { - display: flex; - flex-direction: row; - justify-content: space-between; - margin: 0; - padding: 0; - color: var(--color-primary-standard); - font-family: var(--content-font); - font-size: var(--button-font-size-s); - - &:hover { - background-color: rgba(205, 218, 229, 0.2); - } - - & > span { - margin: 0 24px; - line-height: 36px; - } -} - -.rowResult { - cursor: pointer; -} - -.rowSelected { - background-color: rgba(204, 217, 228, 0.2); -} - -.heading { - color: var(--color-grayscale-medium); - font-family: var(--content-font); - font-size: var(--button-font-size-s); - font-weight: var(--font-weight-bold); - - &:hover { - background-color: inherit; - } -} - -@media (--medium-viewport) { - .row { - & > span { - margin: 0 21px; - } - } -} diff --git a/src/components/autoSuggestV2/resultsList.js b/src/components/autoSuggestV2/resultsList.js deleted file mode 100644 index fb18cda5c1..0000000000 --- a/src/components/autoSuggestV2/resultsList.js +++ /dev/null @@ -1,34 +0,0 @@ -import React from 'react'; -import styles from './resultsList.css'; - -class ResultsList extends React.Component { - render() { - return this.props.results.length > 0 - ? ( -
    -
  • - {this.props.header.titleLeft} - {this.props.header.titleRight} -
  • - { - this.props.results.map(result => ( -
  • this.props.onMouseDown(result.id, result.type, result.valueLeft)} - data-id={result.id} - data-type={result.type} - data-value={result.valueLeft} - className={`${styles.row} ${styles.rowResult} ${result.isSelected ? styles.rowSelected : ''} ${result.type}-result`} - ref={result.isSelected ? this.props.setSelectedRow : () => {}} - > - {result.valueLeft} - {result.valueRight} -
  • - )) - } -
- ) : null; - } -} - -export default ResultsList; diff --git a/src/components/autoSuggestV2/searchResults.mock.js b/src/components/autoSuggestV2/searchResults.mock.js deleted file mode 100644 index b34e4099ae..0000000000 --- a/src/components/autoSuggestV2/searchResults.mock.js +++ /dev/null @@ -1,52 +0,0 @@ -const mockSearchResults = { - addresses: [ - { - address: '12334L', - balance: '4932970292', - }, { - address: '1233456L', - balance: '4932970292', - }, { - address: '12334567L', - balance: '4932970292', - }, - ], - delegates: [ - { - username: 'peterpan', - rank: 73, - account: { - address: '123456L', - }, - }, { - username: 'peter2', - rank: 76, - account: { - address: '1234567L', - }, - }, { - username: '_peter4', - rank: 77, - account: { - address: '12345678L', - }, - }, - ], - transactions: [ - { - id: '1234', - height: 56, - senderId: '12345L', - }, { - id: '12345', - height: 57, - senderId: '12345L', - }, { - id: '123456', - height: 58, - senderId: '12345L', - }, - ], -}; - -export default mockSearchResults; diff --git a/src/components/backgroundMaker/backgroundMaker.css b/src/components/backgroundMaker/backgroundMaker.css deleted file mode 100644 index 27fd3c883e..0000000000 --- a/src/components/backgroundMaker/backgroundMaker.css +++ /dev/null @@ -1,10 +0,0 @@ -@import './mixin.css'; -@import '../app/variables.css'; - -@mixin backgroundMaker 1.5, var(--color-primary-semi-dark), 21deg; - -@media (--medium-viewport) { - .stageStripes { - display: none; - } -} diff --git a/src/components/backgroundMaker/index.js b/src/components/backgroundMaker/index.js deleted file mode 100644 index 653bbd235b..0000000000 --- a/src/components/backgroundMaker/index.js +++ /dev/null @@ -1,21 +0,0 @@ -import React from 'react'; -import styles from './backgroundMaker.css'; - -const BackgroundMaker = ({ className }) => ( -
- - - - - - - - - - - - -
-); - -export default BackgroundMaker; diff --git a/src/components/backgroundMaker/mixin.css b/src/components/backgroundMaker/mixin.css deleted file mode 100644 index 015284bab7..0000000000 --- a/src/components/backgroundMaker/mixin.css +++ /dev/null @@ -1,125 +0,0 @@ -@define-mixin backgroundMaker $height-factor, $background-color, $skew { - .stageStripe, - .stageStripes { - position: absolute; - } - - .stageStripes { - background-color: $background-color; - background-image: linear-gradient(109deg, #00335d 0%, #001a56 100%); - overflow: hidden; - height: 100%; - width: 100%; - pointer-events: none; - transform: skewY($skew) translate3d(0, 0, 0); - transform-origin: right top; - - & :nth-child(1) { - background-image: linear-gradient(4deg, #002759 5%, #002667 87%); - opacity: 1; - top: rem(calc($height-factor * 158)); - height: rem(calc($height-factor * 3)); - width: calc($height-factor * 41%); - right: -1.66666%; - } - - & :nth-child(2) { - background-image: linear-gradient(180deg, #003986 1%, #00305c 95%); - opacity: 0.8; - top: rem(calc($height-factor * 250)); - height: rem(calc($height-factor * 40)); - width: calc($height-factor * 101.66666%); - right: -1.66666%; - } - - & :nth-child(3) { - background-image: linear-gradient(-44deg, #0057b8 0%, #003061 98%); - opacity: 1; - top: rem(calc($height-factor * 290)); - height: rem(calc($height-factor * 3)); - width: calc($height-factor * 71%); - right: -1.66666%; - } - - & :nth-child(4) { - background-image: linear-gradient(180deg, #003986 1%, #00305c 95%); - opacity: 0.8; - top: rem(calc($height-factor * 293)); - height: rem(calc($height-factor * 40)); - width: calc($height-factor * 101.66666%); - right: -1.66666%; - } - - & :nth-child(5) { - background-image: linear-gradient(243deg, rgba(0, 28, 86, 0) 6%, rgba(0, 36, 88, 0.18) 43%, #0b3b67 73%, #005ea0 99%); - opacity: 1; - top: rem(calc($height-factor * 413)); - height: rem(calc($height-factor * 230)); - width: calc($height-factor * 71%); - left: -1.66666%; - } - - & :nth-child(6) { - background-image: linear-gradient(243deg, rgba(0, 0, 0, 0) 6%, #002e5b 64%, rgba(0, 0, 0, 0) 77%, rgba(0, 0, 0, 0) 98%); - opacity: 0.8; - top: rem(calc($height-factor * 454)); - height: rem(calc($height-factor * 190)); - width: calc($height-factor * 66%); - left: -1.66666%; - } - - & :nth-child(7) { - background-image: linear-gradient(-120deg, #003767 19%, #002e5d 30%, #00285a 45%, rgba(0, 38, 103, 0.3) 90%); - opacity: 1; - top: rem(calc($height-factor * 433)); - height: rem(calc($height-factor * 4)); - width: calc($height-factor * 31%); - right: -1.66666%; - } - - & :nth-child(8) { - background-image: linear-gradient(-120deg, #003767 19%, #002e5d 30%, #00285a 45%, rgba(0, 38, 103, 0.3) 90%); - opacity: 1; - top: rem(calc($height-factor * 533)); - height: rem(calc($height-factor * 4)); - width: calc($height-factor * 34%); - right: -1.66666%; - } - - & :nth-child(9) { - background-image: linear-gradient(180deg, rgba(0, 83, 140, 0.3) 11%, #00266f 87%); - opacity: 0.6; - top: rem(calc($height-factor * 780)); - height: rem(calc($height-factor * 220)); - width: calc($height-factor * 101.66666%); - left: -1.66666%; - } - - & :nth-child(10) { - background-image: linear-gradient(106deg, rgba(0, 96, 156, 0.3) 11%, #004880 19%, rgba(0, 0, 0, 0) 87%); - opacity: 0.8; - top: rem(calc($height-factor * 780)); - height: rem(calc($height-factor * 60)); - width: calc($height-factor * 41%); - left: -1.66666%; - } - - & :nth-child(11) { - background-image: linear-gradient(29deg, #007dbb 15%, #00417c 38%, #003372 66%, rgba(0, 0, 0, 0) 100%); - opacity: 0.8; - top: rem(calc($height-factor * 870)); - height: rem(calc($height-factor * 10)); - width: calc($height-factor * 51%); - left: -1.66666%; - } - - & :nth-child(12) { - background-image: linear-gradient(16deg, rgba(0, 0, 0, 0) 19%, #004780 29%, #00437d 39%, #003877 61%, #005c97 100%); - opacity: 0.8; - top: rem(calc($height-factor * 800)); - height: rem(calc($height-factor * 5)); - width: calc($height-factor * 51%); - right: -1.66666%; - } - } -} diff --git a/src/components/copyToClipboard/copyToClipboard.css b/src/components/copyToClipboard/copyToClipboard.css deleted file mode 100644 index cd9df37a34..0000000000 --- a/src/components/copyToClipboard/copyToClipboard.css +++ /dev/null @@ -1,3 +0,0 @@ -.clickable { - cursor: pointer; -} diff --git a/src/components/copyToClipboard/index.js b/src/components/copyToClipboard/index.js deleted file mode 100644 index 365afa2b2c..0000000000 --- a/src/components/copyToClipboard/index.js +++ /dev/null @@ -1,56 +0,0 @@ -import React from 'react'; -import { CopyToClipboard as ReactCopyToClipboard } from 'react-copy-to-clipboard'; -import { translate } from 'react-i18next'; -import { FontIcon } from '../fontIcon'; -import styles from './copyToClipboard.css'; -import Piwik from '../../utils/piwik'; - -class CopyToClipboard extends React.Component { - constructor() { - super(); - this.state = { - copied: false, - }; - } - - textIsCopied() { - Piwik.trackingEvent('CopyToClipboard', 'button', 'Copy'); - this.setState({ - copied: true, - }); - setTimeout(() => { - this.setState({ - copied: false, - }); - }, 3000); - } - - render() { - const { - value, t, className, text, copyClassName, - } = this.props; - return ( -
{ - e.stopPropagation(); - }} - > - this.textIsCopied()}> - {this.state.copied ? ( - - - {' '} - {t('Copied!')} - - ) : ( - - - {text || value} - - )} - -
- ); - } -} - -export default (translate()(CopyToClipboard)); diff --git a/src/components/copyToClipboard/index.test.js b/src/components/copyToClipboard/index.test.js deleted file mode 100644 index 66cdc1b988..0000000000 --- a/src/components/copyToClipboard/index.test.js +++ /dev/null @@ -1,52 +0,0 @@ -import React from 'react'; -import { expect } from 'chai'; -import { mount } from 'enzyme'; -import PropTypes from 'prop-types'; -import sinon from 'sinon'; -import i18n from '../../i18n'; -import CopyToClipboard from './index'; - -describe('CopyToClipboard', () => { - let wrapper; - let clock; - const props = { - text: 'test', - className: 'className', - value: 2, - t: key => key, - i18n, - }; - const options = { - context: { i18n }, - childContextTypes: { - i18n: PropTypes.object.isRequired, - }, - }; - const copiedText = ' Copied!'; - - beforeEach(() => { - wrapper = mount(, options); - clock = sinon.useFakeTimers({ - toFake: ['setTimeout', 'clearTimeout', 'Date', 'setInterval'], - }); - }); - - afterEach(() => { - clock.restore(); - }); - - it('should show "Copied!" on click', () => { - wrapper.find('.default').simulate('click'); - expect(wrapper.find('.copied')).to.have.text(copiedText); - }); - - it('should hide "Copied!" after 3000ms', () => { - wrapper.find('.default').simulate('click'); - clock.tick(2900); - expect(wrapper.find('.copied')).to.have.text(copiedText); - clock.tick(2000); - wrapper.update(); - expect(wrapper.find('.copied')).to.have.length(0); - expect(wrapper.find('.default')).to.have.text(props.text); - }); -}); diff --git a/src/components/delegatesListView/disableMenu.css b/src/components/delegatesListView/disableMenu.css deleted file mode 100644 index a7c38c9b48..0000000000 --- a/src/components/delegatesListView/disableMenu.css +++ /dev/null @@ -1,6 +0,0 @@ -.icon { - color: rgba(0, 0, 0, 0.38) !important; - cursor: default !important; - text-align: right; - width: auto; -} diff --git a/src/components/delegatesListView/voteCheckbox.css b/src/components/delegatesListView/voteCheckbox.css deleted file mode 100644 index b5d7f9f210..0000000000 --- a/src/components/delegatesListView/voteCheckbox.css +++ /dev/null @@ -1,35 +0,0 @@ -.checkbox { - display: inline-block; - width: 16px; - height: 16px; - position: relative; - - & input { - visibility: hidden; - position: absolute; - } - - & span { - position: absolute; - left: 0; - top: 0; - - &.checked { - display: none; - } - - &.unchecked { - display: block; - } - } - - & input:checked { - & ~ .checked { - display: block; - } - - & ~ .unchecked { - display: none; - } - } -} diff --git a/src/components/dialog/stories.js b/src/components/dialog/stories.js deleted file mode 100644 index 30fcbc3aaa..0000000000 --- a/src/components/dialog/stories.js +++ /dev/null @@ -1,45 +0,0 @@ -import React from 'react'; - -import { storiesOf } from '@storybook/react'; -import { action } from '@storybook/addon-actions'; -import Dialog from './dialogElement'; -import Alert from './alert'; - -const dialogContent = () => (
Hello
); - -storiesOf('Dialog', module) - .add('default', () => ( - - )) - .add('Success alert', () => ( - - )) - .add('Error alert', () => ( - - )); diff --git a/src/components/extensions/extensions.css b/src/components/extensions/extensions.css index 3c2b57a791..62bc6f3e7c 100644 --- a/src/components/extensions/extensions.css +++ b/src/components/extensions/extensions.css @@ -1,34 +1,44 @@ @import '../app/variablesV2.css'; +@import '../app/mixins.css'; -.headerWrapper { +.container { + align-items: center; + height: 100%; display: flex; - padding: 0 32px 20px; } -.feedbackWrapper { - padding: 0 32px 160px; +.wrapper { + margin: 0 auto; + width: var(--medium-box-width); } -.header { +.headerWrapper { display: flex; - justify-content: space-between; } -.container { - min-height: 670px; +.content { + box-sizing: border-box; overflow: hidden; - height: 723px; + padding: 20px; + width: 100%; & .extentionsWrapper { - padding: 0 32px; - height: 250px; + display: block; + + & > span { + @mixin contentNormal bold; + + color: var(--color-maastricht-blue); + display: block; + margin-bottom: 8px; + } } } .footer { display: flex; justify-content: center; - padding: 0 32px; + margin-top: 24px; & button { margin: 10px; @@ -36,28 +46,22 @@ } .error { - color: var(--color-error); - padding-bottom: 20px; + margin-top: 24px; } .link { + @mixin contentNormal bold; + color: var(--color-link); cursor: pointer; display: inline-block; - font-family: var(--heading-font); - font-size: var(--paragraph-font-size-l); - font-weight: var(--font-weight-bold); - line-height: 1.47; margin-bottom: 20px; text-align: center; text-decoration: underline; } .label { - color: var(--color-content-light); - font-family: var(--content-font); - font-size: var(--paragraph-font-size-l); - font-weight: var(--font-weight-semi-bold); - line-height: 1.47; + @mixin contentLargest; + margin-bottom: 8px; } diff --git a/src/components/extensions/extensions.js b/src/components/extensions/extensions.js index 27b2da60c8..18407fa3df 100644 --- a/src/components/extensions/extensions.js +++ b/src/components/extensions/extensions.js @@ -1,8 +1,9 @@ import React from 'react'; -import ToolBoxInput from '../toolbox/inputs/toolBoxInput'; -import Box from '../box'; +import { InputV2 } from '../toolbox/inputsV2'; +import Box from '../boxV2'; import { PrimaryButtonV2, SecondaryButtonV2 } from '../toolbox/buttons/button'; +import Feedback from '../toolbox/feedback/feedback'; import localJSONStorage from '../../utils/localJSONStorage'; import loadRemoteComponent from '../../utils/extensions'; import routes from '../../constants/routes'; @@ -18,9 +19,13 @@ class Extensions extends React.Component { url: localJSONStorage.get('url', ''), error: '', }; + + this.handleInput = this.handleInput.bind(this); + this.addExtension = this.addExtension.bind(this); + this.removeExtension = this.removeExtension.bind(this); } - handleInput(value, key) { + handleInput({ target: { value } }) { // const regex = /^(https:\/\/raw.githubusercontent. // com\/michaeltomasik\/extensions-lisk\/master\/)/g; const error = ''; @@ -28,7 +33,7 @@ class Extensions extends React.Component { // error = this.props.t('Use extensions from https://raw.githubusercontent.com/michaeltomasik/extensions-lisk/master/'); // } - this.setState({ [key]: value, error }); + this.setState({ url: value, error }); } removeExtension() { @@ -50,53 +55,63 @@ class Extensions extends React.Component { render() { return ( - -
+
+

{this.props.t('Add Extension')}

-
-
- {this.props.t('Beta: in order to see changes fully please reload the app when removing extension')} +
+
+
+ {this.props.t('Beta: in order to see changes fully please reload the app when removing extension')} +
+ + {this.props.t('Give feedback about this feature')} +
- - {this.props.t('Give feedback about this feature')} - -
-
- this.handleInput(val, 'url')} - /> -
-
- this.removeExtension()} - /> + + {PRODUCTION ? ( + + {this.props.t('Adding extensions is currently disabled in production version of Lisk Hub')} + + ) : ( +
+ - this.addExtension()} - /> -
-
- {(PRODUCTION) ? this.props.t('Adding extensions is currently disabled in production version of Lisk Hub') : ''} + +
+ )}
-
- + +
); } } diff --git a/src/components/formattedNumber/stories.js b/src/components/formattedNumber/stories.js deleted file mode 100644 index a9e6012a09..0000000000 --- a/src/components/formattedNumber/stories.js +++ /dev/null @@ -1,10 +0,0 @@ -import React from 'react'; - -import { storiesOf } from '@storybook/react'; - -import FormattedNumber from '.'; - -storiesOf('FormattedNumber', module) - .add('with val', () => ( - - )); diff --git a/src/components/header/countDownTemplate.js b/src/components/header/countDownTemplate.js deleted file mode 100644 index 2221592999..0000000000 --- a/src/components/header/countDownTemplate.js +++ /dev/null @@ -1,14 +0,0 @@ -import React, { Fragment } from 'react'; - -const Renderer = ({ minutes, seconds, children }) => { - const child = React.cloneElement(children, { minutes, seconds }); - return ( - - {' '} - {child} - {' '} - - ); -}; - -export default Renderer; diff --git a/src/components/header/countDownTemplate.test.js b/src/components/header/countDownTemplate.test.js deleted file mode 100644 index 3f959f4d6c..0000000000 --- a/src/components/header/countDownTemplate.test.js +++ /dev/null @@ -1,27 +0,0 @@ -import React from 'react'; -import { expect } from 'chai'; -import { mount } from 'enzyme'; -import CountDownTemplate from './countDownTemplate'; - -describe('countDownTemplate', () => { - let wrapper; - const Child = props => ( -
- {props.minutes} -: - {props.seconds} -
- ); - - beforeEach(() => { - const propsMock = { - minutes: 10, - seconds: 25, - }; - wrapper = mount(); - }); - - it('should mount Renderer', () => { - expect(wrapper).to.have.descendants('Renderer'); - }); -}); diff --git a/src/components/header/customCountDown.css b/src/components/header/customCountDown.css deleted file mode 100644 index c661716fb0..0000000000 --- a/src/components/header/customCountDown.css +++ /dev/null @@ -1,48 +0,0 @@ -@import '../app/variables.css'; -@import '../app/variablesV2.css'; - -.reset { - margin-right: 15px; - padding-left: 3px; - padding-right: 3px; - padding-bottom: 3px; - cursor: pointer; - color: var(--color-primary-standard); - display: flex; - align-items: center; - font-family: 'Open Sans', sans-serif; - font-weight: 600; - font-size: 12px; -} - -.default { - color: var(--color-grayscale-medium); -} - -.time { - color: var(--color-content-light); -} - -.timeout { - color: var(--color-error); -} - -.timerRow { - display: flex; - justify-content: flex-end; - font-weight: 600; - font-size: 12px; - font-family: 'Open Sans', sans-serif; -} - -.timerRow > p { - font-weight: 600; - font-size: 12px; - font-family: 'Open Sans', sans-serif; -} - -@media (--medium-viewport) { - .default { - color: var(--color-grayscale-medium); - } -} diff --git a/src/components/header/customCountDown.js b/src/components/header/customCountDown.js deleted file mode 100644 index f1bab1cd12..0000000000 --- a/src/components/header/customCountDown.js +++ /dev/null @@ -1,113 +0,0 @@ -import React, { Fragment } from 'react'; -import Options from '../dialog/options'; -import routes from '../../constants/routes'; -import Piwik from '../../utils/piwik'; -import styles from './customCountDown.css'; - -class CustomCountDown extends React.Component { - componentDidUpdate() { - const { - resetTimer, t, setActiveDialog, closeDialog, - } = this.props; - const minutes = parseInt(this.props.minutes, 10); - const seconds = parseInt(this.props.seconds, 10); - - if (minutes === 0 && seconds === 59) { - setActiveDialog({ - childComponent: Options, - childComponentProps: { - title: t('Timeout soon'), - text: t('You will be signed out in a minute due to no network activity. You can turn off Auto-Logout in the settings.'), - firstButton: { - text: t('Go to settings'), - onClickHandler: this.goTo.bind(this, routes.setting.path), - }, - secondButton: { - text: t('Reset timer & continue'), - onClickHandler: /* istanbul ignore next */ () => { - resetTimer(); - closeDialog(); - }, - }, - }, - }); - } - if (minutes === 0 && seconds === 1) { - setActiveDialog({ - childComponent: Options, - childComponentProps: { - title: t('Session timeout'), - text: t('Your session was timed out after 10 minutes of no network activity. You may continue to use certain sections of your Lisk Hub or sign back in to access everything.'), - firstButton: { - text: t('Sign back in'), - onClickHandler: this.goTo.bind(this, routes.loginV2.path), - }, - secondButton: { - text: t('Continue to Dashboard'), - onClickHandler: this.goTo.bind(this, routes.dashboard.path), - }, - }, - }); - } - } - - /* istanbul ignore next */ - goTo(path) { - this.props.history.replace(path); - this.props.closeDialog(); - } - - onResetTimer() { - Piwik.trackingEvent('CustomCountDown', 'button', 'Reset timer'); - this.props.resetTimer(); - } - - render() { - const { - minutes, - autoLog, - seconds, - t, - } = this.props; - const min = `0${minutes}`.slice(-2); - const sec = `0${seconds}`.slice(-2); - - const resetCondition = (minutes < 5); - const timeoutCondition = (minutes === 0 && seconds === 0); - - const resetButton = resetCondition && !timeoutCondition - ? ( -
this.onResetTimer()} - className={`${styles.reset} reset`} - > - {t('Reset')} -
- ) - :
; - - const resetStyle = resetCondition ? styles.timeout : styles.time; - const timer = !timeoutCondition - && ( -

- {t('Session timeout in')} - {' '} - - {min} -: - {sec} - -

- ); - - const renderComponent = autoLog ? ( -
- {resetButton} - {timer} -
- ) : null; - - return ({renderComponent}); - } -} -export default CustomCountDown; diff --git a/src/components/header/customCountDown.test.js b/src/components/header/customCountDown.test.js deleted file mode 100644 index 98342fe550..0000000000 --- a/src/components/header/customCountDown.test.js +++ /dev/null @@ -1,44 +0,0 @@ -import React from 'react'; -import { spy } from 'sinon'; -import { expect } from 'chai'; -import { mount } from 'enzyme'; -import CustomCountDown from './customCountDown'; - -describe('customCountDown', () => { - let wrapper; - - beforeEach(() => { - const propsMock = { - minutes: 10, - seconds: 25, - autoLog: true, - resetTimer: spy(), - setActiveDialog: () => {}, - t: key => key, - history: { - replace: () => {}, - }, - closeDialog: () => {}, - }; - wrapper = mount(); - }); - - it('should render "Session timeout in 10:25"', () => { - expect(wrapper.find('p').text()).to.be.equal('Session timeout in 10:25'); - }); - - it('should render reset button', () => { - wrapper.setProps({ minutes: 0, seconds: 59 }); - expect(wrapper.find('p').text()).to.be.equal('Session timeout in 00:59'); - expect(wrapper).to.have.descendants('.reset'); - }); - - it('should call resetTimer', () => { - wrapper.setProps({ minutes: 0, seconds: 1 }); - expect(wrapper).to.have.descendants('.reset'); - expect(wrapper.props().resetTimer).to.not.be.calledWith(); - wrapper.find('.reset').simulate('click'); - wrapper.update(); - expect(wrapper.props().resetTimer).to.be.calledWith(); - }); -}); diff --git a/src/components/header/header.css b/src/components/header/header.css deleted file mode 100644 index 03a9262a1f..0000000000 --- a/src/components/header/header.css +++ /dev/null @@ -1,419 +0,0 @@ -@import '../toolbox/buttons/css/base.css'; -@import '../app/variables.css'; - -:root { - --header-margin-right-left-M: 20px; - --header-margin-top-bottom-M: 23px; - --header-margin-right-left-S: 20px; - --header-margin-top-bottom-S: 10px; - --avatar-height: 69px; - --avatar-height-s: 33px; - --menu-icon-height-XL: 39px; - --menu-icon-height-M: 34px; - --font-size-normal: 16px; - --font-size-small: 12px; -} - -.wrapper { - display: flex; - flex-direction: row; - align-items: center; - justify-content: space-between; - height: 138px; - box-sizing: border-box; - padding-top: 15px; - - & .noPadding { - padding: 0px; - } - - & .searchBar { - display: inline-block; - float: left; - margin-bottom: 30px; - margin-right: 32px; - } -} - -.unlocked { - color: var(--color-error); - font-family: 'Open Sans', sans-serif; - font-weight: 600; - font-size: var(--font-size-small); - line-height: 1.5em; /* stylelint-disable-line */ -} - -.logoWrapper { - width: 25%; -} - -.logo { - display: none; -} - -.logoutButton { - padding: 8px; - margin: 6px 8px; - height: auto; - float: right; -} - -.lock { - font-size: 19px; - height: auto; - vertical-align: top; - line-height: 24px !important; - margin-left: 5px; -} - -.primary { - line-height: 40px; - - @mixin buttonBasics; - @mixin buttonPrimary; -} - -.secondaryBlue { - line-height: 39px; - - @mixin buttonBasics; - @mixin buttonSecondary--blue; -} - -.material-icons { - font-size: 24px !important; -} - -.login { - display: flex; - flex-direction: column; - justify-content: center; - align-items: flex-end; - - & > p { - color: var(--color-black); - font-family: var(--heading-font); - font-size: 18px; - font-weight: 800; - margin: 0; - padding: 0; - } - - & .link { - display: flex; - flex-direction: row; - align-items: center; - margin-top: 7px; - height: 23px; - font-size: 14px; - font-family: var(--content-font); - font-weight: var(--font-weight-bold); - color: var(--color-black); - text-decoration: none; - - & > span:first-child { - font-size: 21px; - } - - & > span { - font-weight: normal; - margin-left: 5px; - color: var(--color-grayscale-dark); - } - - &:hover { - color: var(--color-primary-standard); - - & > span:first-child { - color: var(--color-primary-standard); - } - } - } -} - -.loginInfo { - display: flex; - flex-direction: column; - height: 86px; - margin: 3px 4px 0 0; -} - -.rightSide { - display: inline-block; - width: 32vw; /* stylelint-disable-line */ -} - -.logout { - display: flex; - flex-direction: row; - justify-content: flex-end; - align-items: center; - cursor: pointer; - color: var(--color-black); - background-color: var(--color-white); - height: 25px; - width: 26px; - border-radius: 13.5px; - overflow: hidden; - font-family: 'Open Sans', sans-serif; - font-size: 12px; - font-weight: 600; - position: absolute; - top: 44px; - right: -5px; - transition: all ease 0.1s; - box-shadow: var(--normal-shadow); - - &:hover { - width: 75px; - color: var(--color-primary-standard); - } -} - -.logoutIcon { - font-size: 18px; - margin: 0 4px 0 5px; -} - -.logoutInfo { - display: flex; - justify-content: flex-end; -} - -.account { - position: relative; - height: 80px; - - & .avatar { - display: inline-block; - vertical-align: middle; - height: var(--avatar-height); - width: var(--avatar-height); - margin-right: 30px; - transition: transform ease-in-out 500ms; - - &:hover { - transform: scale(1.1); - transform-origin: 50%; - } - } - - & .information { - display: inline-block; - line-height: 25px; - padding-right: 20px; - height: var(--avatar-height); - font-family: 'Open Sans', sans-serif; - font-weight: 600; - vertical-align: top; - - & .balance { - font-size: 24px; - font-family: var(--heading-font); - color: var(--color-black); - line-height: 0.5em; /* stylelint-disable-line */ - padding-top: 7px; - - & small { - padding-left: 5px; - font-size: var(--font-size-small); - } - } - - & .address { - font-size: 14px; - color: var(--color-grayscale-medium); - } - - & .copy { - font-size: 24px; - padding-right: 5px; - } - - & .timer { - display: flex; - justify-content: flex-end; - font-size: var(--font-size-small); - color: var(--color-grayscale-medium); - line-height: 1.5em; /* stylelint-disable-line */ - } - } - - & .menu { - cursor: pointer; - - & .item { - padding: 0; - } - - & .link { - text-decoration: none; - width: 100%; - height: 100%; - line-height: 39px; - color: rgba(0, 0, 0, 0.87); - padding: 0; - text-align: center; - } - - & .iconCircle { - position: absolute; - bottom: -14px; - right: -24px; - background: var(--color-white); - border-radius: 100%; - height: var(--menu-icon-height-XL); - width: var(--menu-icon-height-XL); - box-shadow: 0 12px 12px 0 rgba(0, 0, 0, 0.62); - text-align: center; - - & .button { - padding: 2px; - } - } - } -} - -@media (--medium-viewport) { - .logout { - color: var(--color-grayscale-medium); - } - - .loginInfo { - width: 100%; - float: none; - margin: 0; - - & > div { - display: flex; - flex-direction: row; - justify-content: space-between; - } - } - - .wrapper { - margin: 0px; - box-shadow: 0 2px 4px 0 rgba(60, 80, 104, 0.14), 0 8px 10px 0 rgba(60, 80, 104, 0.1); - width: 100%; - position: fixed; - top: 0; - background-color: var(--color-white); - z-index: var(--headerbar-index); - height: auto; - - & .searchBar { - width: 100%; - margin-bottom: 0; - display: none; - } - } - - .logo { - display: inline-block; - height: 50px; - padding: 20px; - } - - .logoutButton { - display: none; - } - - .account { - margin: 13px 13px 0; - height: 72px; - - & .avatar { - margin-right: 0; - } - - & .information { - & .balance { - font-size: 20px; - color: var(--color-black); - font-family: var(--heading-font); - - & small { - font-size: 12px; - } - } - - & .address { - font-size: 12px; - font-weight: 400; - } - } - - & .menu { - & .iconCircle { - display: none; - } - } - } - - .login { - height: 86px; - display: flex; - flex-direction: column; - justify-content: center; - align-items: flex-end; - margin-right: 5px; - } -} - -@media (--small-viewport) { - .wrapper { - height: auto; - } - - .account { - margin: var(--header-margin-top-bottom-S) var(--header-margin-right-left-S) 0px 0px; - height: auto; - display: flex; - padding-bottom: 30px; - - & .avatar { - margin-top: 4px; - height: var(--avatar-height-s); - width: var(--avatar-height-s); - } - - & .information { - margin-top: 0; - height: var(--avatar-height-s); - line-height: 20px; - - & .balance { - font-size: 18px; - font-weight: 300; - - & small { - font-size: 10px; - } - } - } - } - - .logo { - height: 40px; - padding: 10px 10px 7px 20px; - } - - .login { - height: 86px; - - & .link { - margin: var(--header-margin-top-bottom-S) var(--header-margin-right-left-S) var(--header-margin-top-bottom-S) 0px; - line-height: 46px; - } - } -} - -@media (--xSmall-viewport) { - .logo { - padding: 10px 0 7px; - } - - .loginInfo { - margin: 0; - } -} diff --git a/src/components/header/header.js b/src/components/header/header.js deleted file mode 100644 index a9736c8563..0000000000 --- a/src/components/header/header.js +++ /dev/null @@ -1,168 +0,0 @@ -import React from 'react'; -import { Link } from 'react-router-dom'; -import Countdown from 'react-countdown-now'; -import { FontIcon } from '../fontIcon'; -import AccountVisual from '../accountVisual'; -import SearchBar from '../searchBar'; -import CountDownTemplate from './countDownTemplate'; -import CopyToClipboard from '../copyToClipboard'; -import LiskAmount from '../liskAmount'; -import Account from '../account'; -import logo from '../../assets/images/Lisk-Logo.svg'; -import PrivateWrapper from '../privateWrapper'; -import styles from './header.css'; -import CustomCountDown from './customCountDown'; -import Options from '../dialog/options'; -import routes from '../../constants/routes'; -import Piwik from '../../utils/piwik'; - -class Header extends React.Component { - /* istanbul ignore next */ - logOut() { - this.props.logOut(); - this.props.closeDialog(); - this.props.history.replace(`${routes.dashboard.path}`); - } - - shouldShowActionButton() { - const { pathname } = this.props.location; - return !this.props.isAuthenticated - && !this.props.account.loading - && pathname !== routes.loginV2.path - && ![routes.register.path, routes.addAccount.path] - .some(el => pathname.includes(el)); - } - - shouldShowSearchBar() { - const { pathname } = this.props.location; - return ![routes.register.path, routes.addAccount.path] - .some(el => pathname.includes(el)); - } - - openLogoutDialog() { - Piwik.trackingEvent('Header', 'button', 'Open logout dialog'); - - this.props.setActiveDialog({ - childComponent: Options, - childComponentProps: { - title: this.props.t('Logout'), - text: this.props.t('After logging out of your account you will be able to access the Dashboard, Settings and Search.'), - firstButton: { - text: this.props.t('Cancel'), - onClickHandler: this.props.closeDialog, - }, - secondButton: { - text: this.props.t('Logout'), - onClickHandler: this.logOut.bind(this), - }, - }, - }); - } - - render() { - const { peers, t, showNetworkIndicator } = this.props; - return ( -
-
-
- {this.shouldShowSearchBar() && } -
- {this.props.account.loading - ? null - : } -
- -
-
-
- -
-
- -
-
-
- - LSK -
- - -
- {this.props.autoLog - ? ( -
- {((this.props.account.expireTime - && this.props.account.expireTime !== 0) - && this.props.account.passphrase) - ? ( -
- { - this.props.logOut(); - this.props.history.replace(routes.loginV2.path); - }} - > - - -
- ) - : null - } -
- ) - : null - } -
-
- -
this.openLogoutDialog()} - > - {this.props.t('Logout')} - -
-
-
- { - this.shouldShowActionButton() - && ( -
-

{this.props.t('Welcome back')}

- - - {this.props.t('Sign in')} - - {this.props.t('for full access')} - - -
- ) - } -
-
-
-
- ); - } -} - - -export default Header; diff --git a/src/components/header/header.test.js b/src/components/header/header.test.js deleted file mode 100644 index 14640e31fb..0000000000 --- a/src/components/header/header.test.js +++ /dev/null @@ -1,94 +0,0 @@ -import React from 'react'; -import { expect } from 'chai'; -import { MemoryRouter as Router } from 'react-router-dom'; -import { mount } from 'enzyme'; -import configureMockStore from 'redux-mock-store'; -import PropTypes from 'prop-types'; -import sinon from 'sinon'; -import Header from './header'; -import i18n from '../../i18n'; -import routes from '../../constants/routes'; -import accounts from '../../../test/constants/accounts'; - -describe('Header', () => { - let wrapper; - const mountWithRouter = (node, options) => mount({node}, options); - const storeObject = { - peers: { liskAPIClient: {}, options: {} }, - account: { - info: {}, - }, - liskAPIClientSet: () => {}, - search: { - suggestions: { - delegates: [], - addresses: [], - transactions: [], - }, - }, - }; - const mockInputProps = { - setActiveDialog: () => { }, - resetTimer: sinon.spy(), - logOut: sinon.spy(), - history: { replace: sinon.spy() }, - account: { address: accounts.genesis.address }, - t: key => key, - location: { pathname: `${routes.search}` }, - isAuthenticated: false, - removePassphrase: sinon.spy(), - }; - - const history = { - location: { pathname: `${routes.search}` }, - replace: sinon.spy(), - createHref: sinon.spy(), - push: sinon.spy(), - }; - - const store = configureMockStore([])(storeObject); - const options = { - context: { - store, history, i18n, router: { route: history, history }, - }, - childContextTypes: { - store: PropTypes.object.isRequired, - history: PropTypes.object.isRequired, - i18n: PropTypes.object.isRequired, - router: PropTypes.object.isRequired, - }, - }; - - it('renders 1 Link component if not logged in', () => { - wrapper = mountWithRouter(
, options); - expect(wrapper.find('Link')).to.have.length(1); - }); - - it('does not show timer if account is not locked auto logout it turned off', () => { - mockInputProps.account.passphrase = accounts.genesis.passphrase; - storeObject.account = { publicKey: '123', info: {} }; - wrapper = mountWithRouter(
, options); - expect(wrapper.find('Countdown')).to.have.length(0); - }); - - it('does show timer if account is not locked auto logout it turned on', () => { - mockInputProps.account.passphrase = accounts.genesis.passphrase; - mockInputProps.account.expireTime = 1527755244818; - mockInputProps.autoLog = true; - storeObject.account = { publicKey: '123', info: {} }; - wrapper = mountWithRouter(
, options); - expect(wrapper.find('Countdown')).to.have.length(1); - }); - - it('should display logout dialog window', () => { - wrapper = mountWithRouter(
, options); - wrapper.find('.logout').first().simulate('click'); - expect(wrapper.find('Countdown')).to.have.length(1); - }); - - it('should redirect to dashboard after 10 min', () => { - wrapper = mountWithRouter(
, options); - wrapper.find('Countdown').props().onComplete(); - expect(mockInputProps.history.replace).to.have.been.calledWith(`${routes.loginV2.path}`); - }); -}); diff --git a/src/components/header/index.js b/src/components/header/index.js deleted file mode 100644 index 4f9b0c1ab4..0000000000 --- a/src/components/header/index.js +++ /dev/null @@ -1,31 +0,0 @@ -/* istanbul ignore file */ -import { connect } from 'react-redux'; -import { withRouter } from 'react-router'; -import { translate } from 'react-i18next'; -import { dialogDisplayed, dialogHidden } from '../../actions/dialog'; -import { accountLoggedOut, removePassphrase, accountUpdated } from '../../actions/account'; -import accountConfig from '../../constants/account'; -import Header from './header'; - -const { lockDuration } = accountConfig; - -const mapStateToProps = state => ({ - account: state.account, - autoLog: state.settings.autoLog, - isAuthenticated: !!state.account.publicKey, - peers: state.peers, - showNetworkIndicator: state.settings.showNetwork, -}); - -const mapDispatchToProps = { - setActiveDialog: dialogDisplayed, - closeDialog: dialogHidden, - logOut: accountLoggedOut, - removePassphrase, - resetTimer: () => accountUpdated({ expireTime: Date.now() + lockDuration }), -}; - -export default withRouter(connect( - mapStateToProps, - mapDispatchToProps, -)(translate()(Header))); diff --git a/src/components/headerV2/headerV2.js b/src/components/headerV2/headerV2.js index a06792b38e..9e889a4314 100644 --- a/src/components/headerV2/headerV2.js +++ b/src/components/headerV2/headerV2.js @@ -13,7 +13,6 @@ import Icon from '../toolbox/icon'; import UserAccount from '../topBar/accountMenu/userAccount'; import networks from '../../constants/networks'; import styles from './headerV2.css'; -import autoSuggestInputStyles from '../autoSuggestV2/autoSuggest.css'; import formStyles from '../sendV2/form/form.css'; import DropdownV2 from '../toolbox/dropdownV2/dropdownV2'; import SpinnerV2 from '../spinnerV2/spinnerV2'; @@ -191,11 +190,8 @@ class HeaderV2 extends React.Component { name="customNetwork" value={this.state.address} placeholder={this.props.t('ie. 192.168.0.1')} - className={` - custom-network - ${formStyles.input} - ${autoSuggestInputStyles.input} - ${this.state.validationError ? styles.errorInput : ''}`} + size="s" + className={`custom-network ${formStyles.input} ${this.state.validationError ? styles.errorInput : ''}`} />
diff --git a/src/components/infoParagraph/index.js b/src/components/infoParagraph/index.js deleted file mode 100644 index 72ca555f88..0000000000 --- a/src/components/infoParagraph/index.js +++ /dev/null @@ -1,19 +0,0 @@ -import React from 'react'; -import FontIcon from 'react-toolbox/lib/font_icon'; -import layout from './infoParagraph.css'; - -const InfoParagraph = props => ( -
-
- - - -
- {props.children} -
-
-
-
-); - -export default InfoParagraph; diff --git a/src/components/infoParagraph/infoParagraph.css b/src/components/infoParagraph/infoParagraph.css deleted file mode 100644 index 328265120a..0000000000 --- a/src/components/infoParagraph/infoParagraph.css +++ /dev/null @@ -1,18 +0,0 @@ -.layout-margin { - display: inline-block; - margin: 8px; -} - -.layout-padding { - display: inline-block; - padding: 8px; -} - -.layout-row { - display: flex; - flex-direction: row; -} - -.layout-align-center-center { - align-items: center; -} diff --git a/src/components/mainMenu/index.js b/src/components/mainMenu/index.js deleted file mode 100644 index 9c718ca866..0000000000 --- a/src/components/mainMenu/index.js +++ /dev/null @@ -1,17 +0,0 @@ -// istanbul ignore file -import { connect } from 'react-redux'; -import { withRouter } from 'react-router'; -import { translate } from 'react-i18next'; -import { feedbackDialogDisplayed } from '../../actions/dialog'; -import MainMenu from './mainMenu'; - -const mapStateToProps = state => ({ - account: state.account, - showDelegate: state.settings.advancedMode, -}); - -const mapDispatchToProps = { - feedbackDialogDisplayed, -}; - -export default withRouter(connect(mapStateToProps, mapDispatchToProps)(translate()(MainMenu))); diff --git a/src/components/mainMenu/mainMenu.css b/src/components/mainMenu/mainMenu.css deleted file mode 100644 index 34e8e3c638..0000000000 --- a/src/components/mainMenu/mainMenu.css +++ /dev/null @@ -1,357 +0,0 @@ -@import '../app/variables.css'; - -:root { - --menu-background-color: var(--color-white); - --menu-item-active-gradient: linear-gradient(-27deg, #004aff 4%, #57afff 61%, #93f4fe 100%); - --menu-item-active-border-width: 7px; - --menu-item-active-color: linear-gradient(90deg, #fff 0%, #eaeff7 100%); - --more-menu-color: var(--color-grayscale-medium); - --offcanvas-menu-border-color: var(--color-grayscale-light); - --more-menu-border-color: var(--color-grayscale-medium); - --read-more-font-size: 17px; - --read-more-icon-font-size: 65px; - --close-icon-font-size: 35px; -} - -.sideBarWrapper { - text-align: center; - display: flex; - flex-direction: column; - justify-content: flex-start; - height: 100%; -} - -.aside { - transform: translateX(-100%); - opacity: 0.5; - transition: all ease 300ms; - transition-delay: 200ms; - box-shadow: var(--normal-shadow); -} - -:global(.appLoaded) .aside { - opacity: 1; - transform: translateX(0); -} - -.logo { - margin: 40px 0 44px; - height: 50px; -} - -.more { - color: var(--more-menu-color); - border-top: 1px solid var(--more-menu-border-color); - background: var(--menu-background-color); - position: absolute; - width: 100%; - left: 0; - bottom: 0; - padding: 20px 0 30px; - cursor: pointer; -} - -.tab { - background: var(--menu-background-color); - text-align: center; - box-shadow: none; - width: 100% !important; - max-width: 100% !important; - border: none !important; - padding: 20px 10px !important; -} - -.navigationContainer { - overflow: hidden; - margin-left: -2px; - flex: 0 1 auto; - flex-flow: row wrap; -} - -.drawer { - width: 480px; - background: #fff; - max-width: 100%; - - &.left { - border-right: none; - left: 0; - display: flex; - flex-direction: column; - justify-content: space-between; - } -} - -.homeLink { - margin: 5px auto; -} - -@media (max-height: 920px) { - .drawer.left { - display: block; - height: 100%; - } -} - -.header { - align-items: center; - width: 100%; - display: flex; - justify-content: space-between; - padding: 0 40px 0 60px; - background: #fff; -} - -.close { - font-size: var(--close-icon-font-size); - display: flex; - width: auto; - cursor: pointer; - color: var(--more-menu-color); -} - -@media (--medium-viewport) { - .aside { - display: none; - } - - .header { - padding: 0; - } - - .close { - display: none; - } - - .logo { - margin: 20px auto; - height: 42px; - } -} - -.label { - padding: 4.5vh 10px; /* stylelint-disable-line */ - font-size: var(--main-menu-font-size); - color: var(--color-black); - font-weight: bold; - font-family: var(--heading-font); - display: flex; - flex: 0 0 auto; - width: 50%; - text-align: center; - flex-grow: 1; - text-transform: capitalize; - border-right: 1px solid var(--offcanvas-menu-border-color); - border-bottom: 1px solid var(--offcanvas-menu-border-color); - background: #fff; - max-width: 50%; - - &:nth-child(2n) { - border-right: none !important; - } - - &:nth-child(1) { - border-top: 1px solid var(--offcanvas-menu-border-color); - } - - &:nth-child(2) { - border-top: 1px solid var(--offcanvas-menu-border-color); - } - - & > div { - width: 100%; - - &:hover { - filter: brightness(1.1); - } - } - - & span { - display: block; - margin: 10px 0 0; - } - - & img { - width: 55px; - } - - & > .rippleWrapper { - display: none; - } -} - -.navigationContainer .navigation { - padding-left: 0; - box-shadow: none; - margin-left: 2px; - display: flex; - flex-flow: row wrap; -} - -.tabs nav { - overflow: hidden; -} - -.bottomIcon { - width: 22px; - height: 22px; - font-size: 22px; -} - -.topTabs { - overflow-y: auto; - height: auto; - display: block; - margin-bottom: 150px; -} - -.bottomTabs { - position: absolute; - bottom: 32px; - right: 0; - left: 0; - overflow-x: hidden; - - & .label { - color: var(--color-grayscale-medium); - font-family: var(--content-font); - font-size: 12px; - font-weight: var(--font-weight-bold); - line-height: 18px; - - &.active { - background: linear-gradient(90deg, var(--color-white) 0%, #eaeff7 100%); - color: var(--color-grayscale-medium); - - &::before { - display: none; - } - } - - & span:first-child { - margin-right: 3px; - margin-top: 3px; - } - - & span:last-child { - margin: 5px 0 0; - } - - & > div { - display: flex; - flex-direction: row; - align-items: flex-start; - transition: all ease 300ms; - margin-left: 5px; - } - - & img { - width: 25px; - height: 25px; - margin-right: 10px; - } - } - - & .bottomTab { - text-decoration: none; - font-weight: var(--font-weight-bold); - background: var(--menu-background-color); - box-shadow: none; - width: 100%; - max-width: 100%; - border: none; - padding: 5px 10px; - } -} - -.pointer { - display: none; -} - -.arrowContainer { - display: none; -} - -.label.active { - position: relative; - background: var(--menu-item-active-color); - color: var(--color-black); - opacity: 1; - - &::before { - position: absolute; - width: var(--menu-item-active-border-width); - height: 100%; - top: 0; - right: 0; - content: ''; - display: block; - opacity: 0.8; - background-image: var(--menu-item-active-gradient); - } -} - -.readMoreText { - font-size: var(--read-more-font-size); - font-weight: bold; - text-transform: capitalize; - font-family: 'gilroy', 'Open Sans', sans-serif; -} - -.readMoreIcon { - font-size: var(--read-more-icon-font-size); - width: 100%; -} - -@media (--medium-viewport) { - .sideBarWrapper { - display: none; - } - - .navigationContainer .navigation { - justify-content: center; - } - - .bottomTabs { - & .label { - & > div { - margin-left: 0; - } - - &.active { - background: none; - } - } - - & .bottomTab { - max-width: 100px; - } - } -} - -@media (--xSmall-viewport) { - .sideBarWrapper { - display: none; - } - - .label { - padding: 25px 10px; - } - - .label.active::before { - top: auto; - width: 100%; - bottom: 0; - height: 5px; - } -} - -@media (--xLarge-viewport) { - .bottomTabs { - & .label { - & > div { - margin-left: 20px; - } - } - } -} diff --git a/src/components/mainMenu/mainMenu.js b/src/components/mainMenu/mainMenu.js deleted file mode 100644 index a51d31d23a..0000000000 --- a/src/components/mainMenu/mainMenu.js +++ /dev/null @@ -1,232 +0,0 @@ -import React, { Fragment } from 'react'; -import { Link } from 'react-router-dom'; -import { Tab, Tabs as ToolboxTabs } from 'react-toolbox/lib/tabs'; -import Drawer from 'react-toolbox/lib/drawer'; - -import MenuBar from '../menuBar'; -import styles from './mainMenu.css'; -import logo from '../../assets/images/Lisk-Logo.svg'; -import * as menuLogos from '../../assets/images/main-menu-icons/*.svg'; //eslint-disable-line -import { FontIcon } from '../fontIcon'; -import routes from '../../constants/routes'; -import feedbackLinks from '../../constants/feedbackLinks'; -import Piwik from '../../utils/piwik'; - -const getIndex = (history, tabs) => { - let index = -1; - tabs.map(t => new RegExp(`${t.route}(\\/?)`)).forEach((item, i) => { - if (history.location.pathname.match(item)) { - index = i; - } - }); - return index; -}; - -const TabTemplate = ({ img, label, isFontIcon }) => ( -
- { - !isFontIcon - ? - : - } - {label} -
-); - - -class MainMenu extends React.Component { - constructor() { - super(); - this.state = { - active: false, - setting: false, - index: 0, - }; - } - - menuToggle() { - Piwik.trackingEvent('MainMenu', 'link', 'Menu toggle'); - const setting = !this.state.active ? false : this.state.setting; - this.setState({ active: !this.state.active, setting }); - } - - navigate(history, tabs, index) { - this.setState({ active: false, index }); - if (tabs[index].id === 'feedback') { - this.props.feedbackDialogDisplayed({ - childComponentProps: { - title: this.props.t('Tell us what you think'), - }, - }); - return; - } - history.push(tabs[index].route); - } - - settingToggle() { - this.setState({ - setting: !this.state.setting, - }); - } - - render() { - const { - history, t, showDelegate, account, - } = this.props; - let tabs = [ - { - label: t('Dashboard'), - route: `${routes.dashboard.path}`, - id: 'dashboard', - image: menuLogos.dashboard, - enabledWhenNotLoggedIn: true, - }, { - label: t('Wallet'), - route: `${routes.wallet.path}`, - id: 'transactions', - image: menuLogos.wallet, - }, { - label: t('Delegates'), - id: 'delegates', - route: `${routes.delegates.path}`, - image: menuLogos.delegates, - }, { - label: t('Sidechains'), - route: `${routes.sidechains.path}`, - id: 'sidechains', - image: menuLogos.sidechains, - }, - ]; - - const bottomMenuTabs = [ - { - label: t('Settings'), - route: `${routes.setting.path}`, - id: 'settings', - image: 'settings', - enabledWhenNotLoggedIn: true, - }, - { - label: t('Help'), - route: `${routes.help.path}`, - id: 'help', - image: 'logo-icon', - enabledWhenNotLoggedIn: true, - }, - ]; - - if (!showDelegate) { - tabs = tabs.filter(tab => tab.id !== 'delegates'); - } - - return ( - - - - - ); - } -} - -export default MainMenu; diff --git a/src/components/mainMenu/mainMenu.test.js b/src/components/mainMenu/mainMenu.test.js deleted file mode 100644 index 2a679c8aae..0000000000 --- a/src/components/mainMenu/mainMenu.test.js +++ /dev/null @@ -1,131 +0,0 @@ -import React from 'react'; -import { expect } from 'chai'; -import { mount } from 'enzyme'; -import { Tab, Tabs as ToolboxTabs } from 'react-toolbox'; -import { MemoryRouter } from 'react-router-dom'; -import configureMockStore from 'redux-mock-store'; -import sinon from 'sinon'; -import PropTypes from 'prop-types'; -import i18n from '../../i18n'; -import MainMenu from './mainMenu'; -import routes from '../../constants/routes'; - -describe('MainMenu', () => { - // Mocking store - const peers = { - status: { - online: false, - }, - data: { - currentPeer: 'localhost', - port: 4000, - options: { - name: 'Custom Node', - }, - }, - }; - const account = { - isDelegate: false, - address: '16313739661670634666L', - username: 'lisk-hub', - }; - const store = configureMockStore([])({ - peers, - account, - liskAPIClientSet: () => {}, - settings: { - autoLog: true, - advancedMode: true, - }, - }); - - const history = { - location: { - pathname: `${routes.delegates.path}`, - }, - push: sinon.spy(), - }; - - - const options = { - context: { store, history, i18n }, - childContextTypes: { - store: PropTypes.object.isRequired, - history: PropTypes.object.isRequired, - i18n: PropTypes.object.isRequired, - }, - lifecycleExperimental: true, - }; - let clock; - - const t = key => key; - - const props = { - showDelegate: false, - t, - account, - store, - history, - feedbackDialogDisplayed: sinon.spy(), - }; - - beforeEach(() => { - clock = sinon.useFakeTimers({ - toFake: ['setTimeout', 'clearTimeout', 'Date', 'setInterval'], - }); - }); - - afterEach(() => { - clock.restore(); - }); - - it('should render react toolbox Tabs component', () => { - const wrapper = mount( - - , options); - expect(wrapper.find(ToolboxTabs).exists()).to.equal(true); - }); - - it('should render 4 Button components if props.showDelegate', () => { - const wrapper = mount( - - , options); - expect(wrapper.find(Tab)).to.have.lengthOf(4); - }); - - it('should render 3 menu item components if !props.isDelegate', () => { - const wrapper = mount( - - , options); - expect(wrapper.find(Tab)).to.have.lengthOf(3); - }); - - it('should all Tab be disabled except Dashboard and if !props.account.address', () => { - const wrapper = mount( - - , options); - expect(wrapper.find(Tab).at(0).props().disabled).not.to.be.equal(true); - expect(wrapper.find(Tab).at(1).props().disabled).to.be.equal(true); - expect(wrapper.find(Tab).at(2).props().disabled).to.be.equal(true); - }); - - it('should allow to change active menu item', () => { - const wrapper = mount( - - , options); - - expect(wrapper).to.not.have.descendants('#feedback'); - wrapper.find(Tab).at(1).simulate('click'); - expect(history.push).to.have.been.calledWith(`${routes.wallet.path}`); - }); - - it('should click on more activate the drawer', () => { - const wrapper = mount( - - , options); - wrapper.find('.menu-button').simulate('click'); - clock.tick(100); - wrapper.update(); - expect(wrapper.find('Drawer').props().active).to.be.equal(true); - }); -}); diff --git a/src/components/menuBar/index.js b/src/components/menuBar/index.js deleted file mode 100644 index f4768b2928..0000000000 --- a/src/components/menuBar/index.js +++ /dev/null @@ -1,10 +0,0 @@ -import { connect } from 'react-redux'; -import { withRouter } from 'react-router'; -import { translate } from 'react-i18next'; -import MenuBar from './menuBar'; - -const mapStateToProps = state => ({ - isDelegate: state.account.isDelegate, -}); - -export default withRouter(connect(mapStateToProps)(translate()(MenuBar))); diff --git a/src/components/menuBar/menuBar.css b/src/components/menuBar/menuBar.css deleted file mode 100644 index 360eba9e9c..0000000000 --- a/src/components/menuBar/menuBar.css +++ /dev/null @@ -1,78 +0,0 @@ -@import '../app/variables.css'; - -:root { - --menu-bar-padding: 20px; - --menu-bar-font-size-m: 24px; - --menu-bar-font-size-s: 18px; -} - -.menuBar { - display: none; - z-index: 100 !important; -} - -.openMenu { - z-index: 1000 !important; - box-shadow: none !important; -} - -.icon { - font-size: 25px !important; - margin-top: 2px; - margin-left: 5px; - - &.goBack { - margin-left: -5px; - } -} - -@media (--medium-viewport) { - .menuBar { - position: fixed; - display: flex; - height: var(--m-menu-bar-height); - width: 100%; - bottom: 0; - left: 0; - box-shadow: 0 0 4px 0 rgba(0, 0, 0, 0.12), 0 -2px 24px 0 rgba(0, 0, 0, 0.24); - font-weight: bold; - font-size: var(--menu-bar-font-size-m); - font-family: var(--heading-font); - background-color: var(--color-white); - flex-direction: row-reverse; - justify-content: space-between; - } - - .menuButton { - display: flex; - padding: var(--menu-bar-padding); - cursor: pointer; - user-select: none; - - & > * { - font-size: inherit; - vertical-align: middle; - } - } -} - -@media (--small-viewport) { - .menuBar { - height: var(--s-menu-bar-height); - font-size: var(--menu-bar-font-size-s); - } - - .setting { - display: none; - } - - .icon { - margin-top: -2px; - } -} - -@media (--xSmall-viewport) { - .setting { - display: flex; - } -} diff --git a/src/components/menuBar/menuBar.js b/src/components/menuBar/menuBar.js deleted file mode 100644 index 297265a0c9..0000000000 --- a/src/components/menuBar/menuBar.js +++ /dev/null @@ -1,35 +0,0 @@ -import React from 'react'; -import { FontIcon } from '../fontIcon'; -import styles from './menuBar.css'; - -const MenuBar = (props) => { - const { t, menuStatus, menuToggle } = props; - const menuClass = menuStatus ? styles.openMenu : ''; - return ( -
- {!menuStatus - ? ( - menuToggle()} - > - {t('Menu')} - - - ) - : ( - menuToggle()} - > - {t('Close')} - {' '} - - - ) - } -
- ); -}; - -export default MenuBar; diff --git a/src/components/menuBar/menuBar.test.js b/src/components/menuBar/menuBar.test.js deleted file mode 100644 index e3edde0492..0000000000 --- a/src/components/menuBar/menuBar.test.js +++ /dev/null @@ -1,41 +0,0 @@ -import React from 'react'; -import { expect } from 'chai'; -import { mount } from 'enzyme'; -import MenuBar from './menuBar'; - -describe('MenuBar', () => { - let wrapper; - const props = { - t: key => key, - menuStatus: false, - settingStatus: false, - }; - - props.menuToggle = () => { props.menuStatus = !props.menuStatus; }; - - /** - * Clicks on the given element in Component - * then updates the component - * - * @param {String} selector - Valid css selector - */ - const clickAndUpdate = (selector) => { - wrapper.find(selector).simulate('click'); - wrapper = mount(); - }; - - const getClassList = selector => wrapper.find(selector).props().className; - - it('should call menuToggle when menuButton called', () => { - wrapper = mount(); - const buttonSelector = '.menu-button'; - expect(getClassList(buttonSelector)).to.include('expand'); - // clicking on menu shows the close button - clickAndUpdate(buttonSelector); - expect(getClassList(buttonSelector)).to.include('close'); - - // the second click reverts to initial state - clickAndUpdate(buttonSelector); - expect(getClassList(buttonSelector)).to.include('expand'); - }); -}); diff --git a/src/components/parallax/index.js b/src/components/parallax/index.js deleted file mode 100644 index 7cbc3d6ad8..0000000000 --- a/src/components/parallax/index.js +++ /dev/null @@ -1,35 +0,0 @@ -import React from 'react'; -import ParallaxJs from 'parallax-js'; -import options from './options'; - -class Parallax extends React.Component { - constructor() { - super(); - - this.state = {}; - } - - componentDidMount() { - const settings = {}; - Object.keys(this.props).forEach((prop) => { - if (options.includes(prop)) { - settings[prop] = this.props[prop]; - } - }); - - this.parallaxInstance = new ParallaxJs(this.wrapper, settings); - } - - render() { - return ( -
{ this.wrapper = el; }} - > - {this.props.children} -
- ); - } -} - -export default Parallax; diff --git a/src/components/parallax/index.test.js b/src/components/parallax/index.test.js deleted file mode 100644 index d74c325749..0000000000 --- a/src/components/parallax/index.test.js +++ /dev/null @@ -1,26 +0,0 @@ -import React from 'react'; -import { expect } from 'chai'; -import { mount } from 'enzyme'; -import Parallax from './index'; - -describe('Parallax', () => { - let wrapper; - - beforeEach(() => { - wrapper = mount( -
Child 1
-
Child 2
-
); - }); - - it('should mount its children', () => { - expect(wrapper.find('.child')).to.have.lengthOf(2); - }); - - it('should run Parallax on its children', () => { - const child0Html = wrapper.find('.child').at(0).html(); - const child1Html = wrapper.find('.child').at(1).html(); - expect(child0Html).to.include('transform: translate3d'); - expect(child1Html).to.include('transform: translate3d'); - }); -}); diff --git a/src/components/parallax/options.js b/src/components/parallax/options.js deleted file mode 100644 index 6cca7f176c..0000000000 --- a/src/components/parallax/options.js +++ /dev/null @@ -1,22 +0,0 @@ -export default [ - 'relativeInput', - 'clipRelativeInput', - 'hoverOnly', - 'inputElement', - 'calibrateX', - 'calibrateY', - 'invertX', - 'invertY', - 'limitX', - 'limitY', - 'scalarX', - 'scalarY', - 'frictionX', - 'frictionY', - 'originX', - 'originY', - 'precision', - 'selector', - 'pointerEvents', - 'onReady', -]; diff --git a/src/components/passphraseInput/index.js b/src/components/passphraseInput/index.js deleted file mode 100644 index a0130c1987..0000000000 --- a/src/components/passphraseInput/index.js +++ /dev/null @@ -1,162 +0,0 @@ -import { translate } from 'react-i18next'; -import React from 'react'; -import grid from 'flexboxgrid/dist/flexboxgrid.css'; -import { FontIcon } from '../fontIcon'; -import ToolBoxInput from '../toolbox/inputs/toolBoxInput'; -import { isValidPassphrase, getPassphraseValidationErrors } from '../../utils/passphrase'; -import styles from './passphraseInput.css'; -import keyCodes from '../../constants/keyCodes'; -import Piwik from '../../utils/piwik'; - -class PassphraseInput extends React.Component { - constructor(props) { - super(props); - this.state = { - inputType: 'password', - isFocused: this.props.isFocused || false, - partialPassphraseError: [], - focus: 0, - }; - } - - setFocusedField(field) { - this.setState({ focus: field }); - } - - handleValueChange(index, value) { // eslint-disable-line max-statements - let insertedValue = value.trim().replace(/\W+/g, ' '); - const insertedValueAsArray = insertedValue.split(' '); - let passphrase = this.props.value.split(' '); - - if (insertedValueAsArray.length > 1) { - for (let i = 0; i < 12; i++) { - if (insertedValueAsArray[i]) { - passphrase[i] = insertedValueAsArray[i]; - this.setState({ focus: i }); - } - } - insertedValue = insertedValueAsArray[index]; - } - - passphrase[index] = insertedValue; - passphrase = passphrase.join(' '); - - let error; - - this.setState({ partialPassphraseError: [] }); - if (!passphrase) { - error = this.props.t('Required'); - } else if (!isValidPassphrase(passphrase)) { - error = this.getPassphraseValidationError(passphrase); - } - this.props.onChange(passphrase, error); - } - - // eslint-disable-next-line class-methods-use-this - getPassphraseValidationError(passphrase) { - const { partialPassphraseError, validationError } = getPassphraseValidationErrors(passphrase); - this.setState({ partialPassphraseError }); - - return validationError; - } - - toggleInputType() { - Piwik.trackingEvent('PassphraseInput', 'button', 'Toggle input type'); - this.setState({ inputType: this.state.inputType === 'password' ? 'text' : 'password' }); - } - - keyAction({ event, value, index }) { - if (event.which === keyCodes.space || event.which === keyCodes.arrowRight) { - event.preventDefault(); - this.setState({ focus: index + 1 }); - } - - if ((event.which === keyCodes.delete && !value) || event.which === keyCodes.arrowLeft) { - this.setState({ focus: index - 1 }); - } - } - - setFocused() { - Piwik.trackingEvent('PassphraseInput', 'button', 'Set focused'); - if (this.props.onFocus) this.props.onFocus(); - this.setState({ isFocused: true }); - } - - focusAndPaste(value) { - this.setFocused(); - this.handleValueChange(0, value); - } - - render() { - const propsColumns = this.props.columns; - const xs = `col-xs-${propsColumns && propsColumns.xs ? propsColumns.xs : '6'}`; - const sm = `col-sm-${propsColumns && propsColumns.sm ? propsColumns.sm : '2'}`; - const md = `col-md-${propsColumns && propsColumns.md ? propsColumns.md : '2'}`; - - const value = this.props.value.split(' '); - return ( -
- {this.state.isFocused - ? ( -
-
- - {' '} - -
-
- {[...Array(12)].map((x, i) => ( -
- { - const val = e.target.value; - e.target.value = ''; - e.target.value = val; - - this.setFocusedField(i); - }} - onBlur={this.setFocusedField.bind(this, null)} - onChange={(val) => { - this.handleValueChange(i, val); - }} - onKeyDown={(event) => { - this.keyAction({ event, value: value[i], index: i }); - }} - index={i} - /> -
- ))} -
-
{this.props.error}
-
- ) - : ( - - ) - } -
- ); - } -} - -export { PassphraseInput }; -// eslint-disable-next-line import/no-named-as-default -export default translate()(PassphraseInput); diff --git a/src/components/passphraseInput/index.test.js b/src/components/passphraseInput/index.test.js deleted file mode 100644 index 5eba6634c6..0000000000 --- a/src/components/passphraseInput/index.test.js +++ /dev/null @@ -1,188 +0,0 @@ -import React from 'react'; -import { expect } from 'chai'; -import { spy } from 'sinon'; -import { mount } from 'enzyme'; -import PropTypes from 'prop-types'; - -import accounts from '../../../test/constants/accounts'; -import i18n from '../../i18n'; -import PassphraseInputHOC, { PassphraseInput } from './index'; -import keyCodes from '../../constants/keyCodes'; - -describe('PassphraseInput', () => { - let wrapper; - let props; - let onChangeSpy; - - describe('with HOC', () => { - beforeEach(() => { - props = { - error: '', - value: '', - onChange: key => key, - i18n, - }; - onChangeSpy = spy(props, 'onChange'); - wrapper = mount(); - }); - - afterEach(() => { - onChangeSpy.restore(); - }); - - it('should call props.onChange with error=undefined if a valid passphrase is entered', () => { - const { passphrase } = accounts.genesis; - wrapper.find('input').first().simulate('change', { target: { value: passphrase } }); - expect(wrapper.props().onChange).to.have.been.calledWith(passphrase, undefined); - }); - - it('should call props.onChange with error="Required" if an empty passphrase is entered', () => { - const passphrase = ''; - wrapper.find('input').first().simulate('change', { target: { value: passphrase } }); - expect(wrapper.props().onChange).to.have.been.calledWith(passphrase, 'Required'); - }); - - const ONLY_ONE_WORD_ERROR = 'Passphrase should have 12 words, entered passphrase has 1'; - it(`should call props.onChange with error="${ONLY_ONE_WORD_ERROR}" if an "test" passphrase is entered`, () => { - const passphrase = 'test'; - wrapper.find('input').first().simulate('change', { target: { value: passphrase } }); - wrapper.setProps({ value: passphrase }); - expect(wrapper.props().onChange).to.have.been.calledWith(passphrase, ONLY_ONE_WORD_ERROR); - }); - - const NOT_VALID_ERROR = 'Passphrase is not valid'; - it(`should call props.onChange with error="${NOT_VALID_ERROR}" if an otherwise invalid passphrase is entered`, () => { - const passphrase = 'stock wagon borrow episode laundry kitten salute link globe zero feed marble'; - wrapper.find('input').first().simulate('change', { target: { value: passphrase } }); - expect(wrapper.props().onChange).to.have.been.calledWith(passphrase, NOT_VALID_ERROR); - }); - - it('should allow to change the input field to type="text" and back', () => { - expect(wrapper.find('input').first().props().type).to.equal('password'); - wrapper.find('input').first().simulate('click'); - wrapper.find('.show-passphrase-toggle').simulate('click'); - expect(wrapper.find('input').first().props().type).to.equal('text'); - wrapper.find('.show-passphrase-toggle').simulate('click'); - expect(wrapper.find('input').first().props().type).to.equal('password'); - }); - }); - - - describe('without HOC', () => { - beforeEach(() => { - props = { - error: '', - value: '', - onChange: () => {}, - i18n, - t: key => key, - }; - - onChangeSpy = spy(props, 'onChange'); - - const options = { - context: { i18n }, - childContextTypes: { - i18n: PropTypes.object.isRequired, - }, - }; - - wrapper = mount(, options); - }); - - afterEach(() => { - onChangeSpy.restore(); - }); - - it('should highlight invalid words if a passphrase with an invalid word is entered', () => { - const errorMessage = 'Please check the highlighted words'; - let passphrase = 'wagon stock borrow episode laundry kitten salute link globe zero feed marble'; - wrapper.find('input').first().simulate('change', { target: { value: passphrase } }); - expect(wrapper.props().onChange).to.not.have.been.calledWith(passphrase, errorMessage); - passphrase = 'wagonn stock borrow episode laundry kitten salute link globe zero feed marble'; - wrapper.find('input').first().simulate('change', { target: { value: passphrase } }); - expect(wrapper.state('partialPassphraseError')[0]).to.equal(true); - expect(wrapper.props().onChange).to.have.been.calledWith(passphrase, errorMessage); - }); - - it('should focus input on click', () => { - expect(wrapper.find('input')).to.have.length(1); - expect(wrapper.state('isFocused')).to.equal(false); - wrapper.find('input').first().simulate('click'); - expect(wrapper.state('isFocused')).to.equal(true); - expect(wrapper.find('input')).to.have.length(12); - }); - - it('should handle paste a passphrase', () => { - expect(wrapper.state('isFocused')).to.equal(false); - expect(wrapper.find('input')).to.have.length(1); - const passphrase = 'stock wagon borrow episode laundry kitten salute link globe zero feed marble'; - wrapper.find('input').first().simulate('change', { target: { value: passphrase } }); - expect(wrapper.state('isFocused')).to.equal(true); - expect(wrapper.find('input')).to.have.length(12); - expect(wrapper.props().onChange).to.have.been.calledWith(passphrase); - }); - - it('should focus next element on space press', () => { - expect(wrapper.state('focus')).to.equal(0); - wrapper.find('input').first().simulate('click'); - wrapper.find('input').first().simulate('keyDown', { - keyCode: keyCodes.space, - which: keyCodes.space, - }); - expect(wrapper.state('focus')).to.equal(1); - }); - - it('should focus next element on arrow right and previous element on left press', () => { - expect(wrapper.state('focus')).to.equal(0); - wrapper.find('input').first().simulate('click'); - wrapper.find('input').first().simulate('keyDown', { - keyCode: keyCodes.arrowRight, - which: keyCodes.arrowRight, - }); - expect(wrapper.state('focus')).to.equal(1); - wrapper.find('input').at(1).simulate('keyDown', { - keyCode: keyCodes.arrowLeft, - which: keyCodes.arrowLeft, - }); - expect(wrapper.state('focus')).to.equal(0); - }); - - it('should focus previous element on backspace press', () => { - expect(wrapper.state('focus')).to.equal(0); - wrapper.find('input').first().simulate('click'); - wrapper.find('input').first().simulate('keyDown', { - keyCode: keyCodes.arrowRight, - which: keyCodes.arrowRight, - }); - expect(wrapper.state('focus')).to.equal(1); - wrapper.find('input').at(1).simulate('keyDown', { - keyCode: keyCodes.delete, - which: keyCodes.delete, - }); - expect(wrapper.state('focus')).to.equal(0); - }); - - it('should render partial input correctly on load', () => { - wrapper.find('input').first().simulate('click'); - - expect(wrapper.find('input').at(0).props().shouldfocus).to.equal(1); - expect(wrapper.find('input').at(0).props().type).to.equal('password'); - expect(wrapper.find('input').at(0).props().placeholder.toLowerCase()).to.equal('start here'); - expect(wrapper.find('input').at(0).props().value).to.equal(''); - - expect(wrapper.find('input').at(1).props().shouldfocus).to.equal(0); - expect(wrapper.find('input').at(1).props().type).to.equal('password'); - expect(wrapper.find('input').at(1).props().placeholder).to.equal(''); - expect(wrapper.find('input').at(0).props().value).to.equal(''); - }); - - it('should change focused element on focus and blur', () => { - wrapper.find('input').first().simulate('click'); - wrapper.find('input').at(1).simulate('focus'); - expect(wrapper.find('input').at(1).props().shouldfocus).to.equal(1); - wrapper.find('input').at(1).simulate('blur'); - expect(wrapper.find('input').at(1).props().shouldfocus).to.equal(0); - }); - }); -}); diff --git a/src/components/passphraseInput/passphraseInput.css b/src/components/passphraseInput/passphraseInput.css deleted file mode 100644 index 6e1c62ca37..0000000000 --- a/src/components/passphraseInput/passphraseInput.css +++ /dev/null @@ -1,85 +0,0 @@ -@import '../app/variables.css'; - -:root { - --icon-font-size: 22px; - --tab-inactive-color: --color-grayscale-dark; - --error-font-size-XL: 16px; - --error-font-size-L: 14px; -} - -.wrapper { - position: relative; -} - -.checkbox { - visibility: hidden; - position: hidden; -} - -.inputTypeToggle { - position: absolute; - right: 0; - font-size: 16px; - font-weight: var(--font-weight-semi-bold); - color: #2475b9 !important; - top: -25px; - cursor: pointer; - - & label { - text-transform: capitalize; - } - - & .eyeIcon { - font-size: var(--icon-font-size); - } -} - -.inputWrapper input { - padding-right: 35px; - border-radius: 0; -} - -.errorMessage { - color: var(--color-error); - height: 20px; - font-weight: var(--font-weight-semi-bold); - padding-top: 10px; -} - -.error input { - color: var(--color-error) !important; -} - -.partial input { - text-align: center; - border-radius: 0; -} - -@media (--small-viewport) { - .inputTypeToggle { - top: 10px; - width: 100%; - text-align: center; - } - - .errorMessage { - padding-bottom: 10px; - } - - .wrapper { - margin-top: 0; - padding-top: 40px; - } -} - -@media (--large-viewport) { - .errorMessage { - font-size: var(--error-font-size-L); - } -} - -@media (--xLarge-viewport) { - .errorMessage { - font-size: var(--error-font-size-XL); - } -} diff --git a/src/components/passphraseSteps/index.js b/src/components/passphraseSteps/index.js deleted file mode 100644 index 79623bcf22..0000000000 --- a/src/components/passphraseSteps/index.js +++ /dev/null @@ -1,206 +0,0 @@ -import React from 'react'; -import { connect } from 'react-redux'; -import { translate } from 'react-i18next'; -import grid from 'flexboxgrid/dist/flexboxgrid.css'; -import { extractPublicKey, getActiveTokenAccount } from '../../utils/account'; -import { Button } from '../toolbox/buttons/button'; -// eslint-disable-next-line import/no-named-as-default -import PassphraseInput from '../passphraseInput'; -import { passphraseIsValid, authStatePrefill } from '../../utils/form'; -import Piwik from '../../utils/piwik'; -import styles from './passphraseSteps.css'; - -class PassphraseSteps extends React.Component { - constructor(props) { - super(props); - - this.state = { - done: { - passphrase: false, - secondPassphrase: false, - }, - ...authStatePrefill(this.props.account), - }; - } - - componentDidMount() { - if (this.props.account.secondPublicKey) { - this.setState({ - secondPassphrase: { - value: '', - error: '', - }, - }); - } - - if ((this.props.account.hwInfo && this.props.account.hwInfo.deviceId) - || (this.props.account.passphrase - && !this.props.account.secondPublicKey)) { - this.props.nextStep({ - ...this.props, - ...authStatePrefill(this.props.account), - skipped: true, - }); - } - - if (typeof this.props.onMount === 'function') { - this.props.onMount(true, 'PassphraseSteps'); - } - } - - hasCorrectPassphrases() { - const firstPPAndDone = !this.props.account.passphrase && this.state.done.passphrase; - const secondPPAndDone = this.props.account.secondPublicKey && this.state.done.secondPassphrase; - const onlyFirstPPAndDone = firstPPAndDone && !this.props.account.secondPublicKey; - const onlySecondPPAndDone = secondPPAndDone && !!this.props.account.passphrase; - - return onlyFirstPPAndDone || onlySecondPPAndDone || (firstPPAndDone && secondPPAndDone); - } - - componentDidUpdate() { - if (this.hasCorrectPassphrases()) { - this.props.nextStep({ - ...this.props, - skipped: false, - passphrase: this.state.passphrase, - secondPassphrase: this.state.secondPassphrase, - }); - } - } - - onChange(name, value, error) { - if (!error) { - const publicKeyMap = { - passphrase: 'publicKey', - secondPassphrase: 'secondPublicKey', - }; - - const expectedPublicKey = this.props.account[publicKeyMap[name]]; - - if (expectedPublicKey && expectedPublicKey !== extractPublicKey(value)) { - error = this.props.t('Entered passphrase does not belong to the active account'); - } - } - - this.setState({ - [name]: { - value, - error: typeof error === 'string' ? error : undefined, - }, - }); - } - - setDone(step) { - Piwik.trackingEvent('PassphraseSteps', 'button', 'Next step'); - const done = Object.assign(this.state.done, { [step]: true }); - this.setState({ done }); - } - - onPrevStep() { - Piwik.trackingEvent('PassphraseSteps', 'button', 'Previous step'); - this.props.prevStep({ - recipient: this.props.recipient, - amount: this.props.amount, - reset: this.props.accountInit, - }); - } - - getCurrentStep() { - if (this.props.account.secondPublicKey - && (this.state.done.passphrase || this.props.account.passphrase)) { - return 'secondPassphrase'; - } - - return 'passphrase'; - } - - render() { // eslint-disable-line max-statements - const values = { - columns: { xs: 6, sm: 4, md: 6 }, - passphrase: { - key: 'passphrase', - header: this.props.t('Enter your passphrase'), - state: this.state.passphrase, - className: 'passphrase', - buttonClassName: 'first-passphrase-next', - }, - secondPassphrase: { - key: 'secondPassphrase', - header: this.props.t('Enter your second passphrase'), - state: this.state.secondPassphrase, - className: 'second-passphrase', - buttonClassName: 'second-passphrase-next', - }, - footer: { - firstGrid: grid['col-xs-4'], - secondGrid: grid['col-xs-8'], - }, - }; - - let updatedValues = { ...values }; - let updatedStyles = { ...styles }; - - if (this.props.values) { - const columns = { ...updatedValues.columns, ...this.props.values.columns }; - const footer = { ...updatedValues.footer, ...this.props.values.footer }; - const passphrase = { ...updatedValues.passphrase, ...this.props.values.passphrase }; - const secondPassphrase = { - ...updatedValues.secondPassphrase, - ...this.props.values.secondPassphrase, - }; - updatedValues = { - columns, passphrase, secondPassphrase, footer, - }; - } - - if (this.props.styles) { - updatedStyles = { ...updatedStyles, ...this.props.styles }; - } - - return ( -
-
-

{updatedValues[this.getCurrentStep()].header}

-
- -
-
-
-
-
-
-
-
-
- ); - } -} - - -const mapStateToProps = state => ({ - account: getActiveTokenAccount(state), -}); - -export default connect(mapStateToProps)(translate()(PassphraseSteps)); diff --git a/src/components/passphraseSteps/passphraseSteps.css b/src/components/passphraseSteps/passphraseSteps.css deleted file mode 100644 index fb5d1f3389..0000000000 --- a/src/components/passphraseSteps/passphraseSteps.css +++ /dev/null @@ -1,38 +0,0 @@ -@import '../app/variables.css'; - -.wrapper { - display: flex; - flex-flow: column; - justify-content: space-between; - width: 100%; - box-sizing: border-box; - height: 100%; - - & footer { - width: 100%; - } -} - -.button { - min-width: 0; - width: 100%; -} - -.headerWrapper { - padding: 20px 0px 0; - - & h2 { - font-weight: var(--font-weight-semi-bold); - margin-bottom: 0; - } -} - -.input { - padding: 5px !important; -} - -@media (--small-viewport) { - .wrapper { - max-height: 100%; - } -} diff --git a/src/components/pricedButton/index.js b/src/components/pricedButton/index.js deleted file mode 100644 index f9a53c10c6..0000000000 --- a/src/components/pricedButton/index.js +++ /dev/null @@ -1,8 +0,0 @@ -import { connect } from 'react-redux'; -import PricedButton from './pricedButton'; - -const mapStateToProps = state => ({ - balance: state.account.balance, -}); - -export default connect(mapStateToProps)(PricedButton); diff --git a/src/components/pricedButton/index.test.js b/src/components/pricedButton/index.test.js deleted file mode 100644 index 8fc38a3e62..0000000000 --- a/src/components/pricedButton/index.test.js +++ /dev/null @@ -1,55 +0,0 @@ -import React from 'react'; -import { expect } from 'chai'; -import sinon from 'sinon'; -import { shallow } from 'enzyme'; -import { PrimaryButton } from '../toolbox/buttons/button'; -import PricedButton from './pricedButton'; -import i18n from '../../i18n'; -import styles from './pricedButton.css'; - - -describe('PricedButton', () => { - let wrapper; - const props = { - fee: 5e8, - onClick: sinon.spy(), - t: (key, options) => i18n.t(key, options), - }; - const insufficientBalance = 4.9999e8; - const sufficientBalance = 6e8; - - it('renders -
- ) : null - } - {!this.props.success && this.props.account && this.props.account.hwInfo - ? ( -
- -
- ) : null - } -
- - {this.props.t('Okay')} - -
-
{this.props.subTitle}
- -
- - ); - } -} - -export default ResultBox; diff --git a/src/components/resultBox/resultBox.test.js b/src/components/resultBox/resultBox.test.js deleted file mode 100644 index 08e7a5da52..0000000000 --- a/src/components/resultBox/resultBox.test.js +++ /dev/null @@ -1,176 +0,0 @@ -import React from 'react'; -import { expect } from 'chai'; -import { mount } from 'enzyme'; -import { spy } from 'sinon'; -import PropTypes from 'prop-types'; -import { FontIcon } from '../fontIcon'; -import ResultBox from './resultBox'; -import styles from './resultBox.css'; -import i18n from '../../i18n'; - -describe('Result Box', () => { - let wrapper; - let props; - - const options = { - context: { i18n }, - childContextTypes: { - i18n: PropTypes.object.isRequired, - }, - }; - - it('renders result box with success template', () => { - const title = 'Thank you'; - const body = 'Transaction is being processed and will be confirmed. It may take up to 15 minutes to be secured in the blockchain.'; - const copy = { - title: 'Copy Transaction-ID to clipboard', - value: '1234', - }; - props = { - copy, - account: {}, - title, - body, - success: true, - reset: spy(), - copyToClipboard: () => {}, - finalCallback: () => {}, - transactionFailedClear: () => {}, - t: () => {}, - history: { location: {}, push: () => {}, replace: () => {} }, - bookmarks: { - LSK: [], - }, - }; - - wrapper = mount(, options); - - expect(wrapper.find('h2').text()).to.contain(title); - expect(wrapper.find('.result-box-message').text()).to.contain(body); - expect(wrapper.find(`.${styles.header}`).find(FontIcon)).to.be.not.present(); - expect(wrapper.find('img')).to.have.length(1); - expect(wrapper.find('.copy-title').text()).to.contain(copy.title); - - wrapper.find('.okay-button').first().simulate('click'); - expect(props.reset).to.have.been.calledWith(); - }); - - it('renders result box with failure template', () => { - const title = 'Sorry'; - const body = 'An error occurred while creating the transaction.'; - props = { - copy: null, - title, - account: {}, - body, - success: false, - reset: () => {}, - copyToClipboard: () => {}, - t: () => {}, - bookmarks: { - LSK: [], - }, - }; - - wrapper = mount(, options); - - expect(wrapper.find('h2').text()).to.contain(title); - expect(wrapper.find('.result-box-message').text()).to.contain(body); - expect(wrapper.find(`.${styles.header}`).find(FontIcon)).to.be.present(); - expect(wrapper.find('img')).to.have.length(0); - expect(wrapper.find('.copy-title')).to.have.length(0); - }); - - it('calls props.onMount if it is a function', () => { - props = { - copy: null, - title: 'Sorry', - body: 'An error occurred while creating the transaction.', - success: false, - reset: () => {}, - copyToClipboard: () => {}, - t: () => {}, - onMount: spy(), - bookmarks: { - LSK: [], - }, - account: {}, - }; - - wrapper = mount(, options); - - expect(props.onMount).to.have.been.calledWith(true, 'ResultBox'); - }); - - it('display add follwed account button', () => { - props = { - copy: null, - title: 'test', - body: 'test', - success: true, - reset: () => {}, - copyToClipboard: () => {}, - t: () => {}, - onMount: spy(), - recipientId: '123L', - bookmarks: { - LSK: [{ - address: '1L', - }], - }, - account: { - hwInfo: {}, - }, - }; - - wrapper = mount(, options); - - expect(wrapper).to.have.descendants('.add-to-bookmarks'); - }); - - it('should go to next step after clicking "Retry"', () => { - props = { - copy: null, - title: 'test', - account: { hwInfo: {} }, - body: 'test', - success: false, - recipientId: '123', - reset: () => {}, - copyToClipboard: () => {}, - t: () => {}, - bookmarks: { - LSK: [], - }, - prevStep: spy(), - transactionFailedClear: spy(), - }; - wrapper = mount(, options); - wrapper.debug(); - wrapper.find('.add-follwed-account-button').at(0).simulate('click'); - expect(props.prevStep).to.have.been.calledWith(); - expect(props.transactionFailedClear).to.have.been.calledWith(); - }); - - it('should go to next step after clicking "Add Bookmark"', () => { - props = { - copy: null, - title: 'test', - account: { hwInfo: {} }, - body: 'test', - success: true, - recipientId: 455, - reset: () => {}, - copyToClipboard: () => {}, - t: () => {}, - bookmarks: { - LSK: [], - }, - nextStep: spy(), - }; - wrapper = mount(, options); - - wrapper.find('.add-to-bookmarks').at(0).simulate('click'); - expect(props.nextStep).to.have.been.calledWith({ address: 455 }); - }); -}); diff --git a/src/components/searchBar/index.js b/src/components/searchBar/index.js deleted file mode 100644 index 9b4638e03f..0000000000 --- a/src/components/searchBar/index.js +++ /dev/null @@ -1,48 +0,0 @@ -import React from 'react'; -import { connect } from 'react-redux'; -import { withRouter } from 'react-router'; -import { translate } from 'react-i18next'; -import { searchSuggestions } from '../../actions/search'; -import actionTypes from '../../constants/actions'; -import AutoSuggest from '../autoSuggestV2'; -import styles from './searchBar.css'; - -class SearchBar extends React.Component { - shouldShowSearchBarOnMobile() { - const { pathname } = this.props.location; - return pathname.includes('explorer'); - } - - render() { - return ( -
- -
- ); - } -} - -const mapStateToProps = state => ({ - account: state.account, - suggestions: state.search.suggestions, -}); -/* istanbul ignore next */ -const mapDispatchToProps = { - searchSuggestions, - searchClearSuggestions: data => ({ - data, - type: actionTypes.searchClearSuggestions, - }), -}; - -export default withRouter(connect( - mapStateToProps, - mapDispatchToProps, -)(translate()(SearchBar))); diff --git a/src/components/searchBar/index.test.js b/src/components/searchBar/index.test.js deleted file mode 100644 index c4173e2cd2..0000000000 --- a/src/components/searchBar/index.test.js +++ /dev/null @@ -1,86 +0,0 @@ -/* eslint-disable */ -import React from 'react'; -import { expect } from 'chai'; -import { mount } from 'enzyme'; -import { stub, spy } from 'sinon'; -import { Provider } from 'react-redux'; -import { HashRouter as Router } from 'react-router-dom'; -import PropTypes from 'prop-types'; - -import i18n from '../../i18n'; -import SearchBar from './index'; - -describe('SearchBar', () => { - let wrapper; - let history; - let props; - let options; - const store = {}; - const peers = { - data: {}, - status: true, - }; - - // Mocking store - beforeEach(() => { - - history = { - location: { - pathname: 'explorer', - search: '', - }, - push: spy(), - }; - props = { - account: { - afterLogout: false, - }, - history, - t: () => {}, - searchSuggestions: () => {}, - searchClearSuggestions: () => {}, - location: { - pathname: 'explorer', - search: '', - }, - }; - options = { - context: { - store: {}, history, i18n, router: { route: history, history }, - }, - childContextTypes: { - store: PropTypes.object.isRequired, - history: PropTypes.object.isRequired, - i18n: PropTypes.object.isRequired, - router: PropTypes.object.isRequired, - }, - lifecycleExperimental: true, - }; - store.getState = () => ({ - peers, - search: { - suggestions: { - delegates: [], - addresses: [], - transactions: [], - } - } - }); - store.subscribe = () => {}; - store.dispatch = () => {}; - wrapper = mount( - - - - - , options, - ); - }); - - it('should render Autosuggest', () => { - expect(wrapper).to.have.descendants('.search-bar-input'); - expect(wrapper).to.have.descendants('.autosuggest-input'); - expect(wrapper).to.have.descendants('.autosuggest-dropdown'); - }); -}); - diff --git a/src/components/searchBar/searchBar.css b/src/components/searchBar/searchBar.css deleted file mode 100644 index fb19e7a6ff..0000000000 --- a/src/components/searchBar/searchBar.css +++ /dev/null @@ -1,44 +0,0 @@ -@import './../app/variables.css'; -@import './../app/variablesV2.css'; - -:root { - --search-box-width-l: 589px; /* stylelint-disable-line */ - --search-box-width-xl: 558px; - --search-box-font-size: 16px; - --search-box-line-height: 56px; - --sub-title-line-height: 26px; - --search-box-selection-background: var(--color-primary-light); -} - -.searchBar { - width: 100%; - max-width: var(--search-box-width-l); - height: 36px; - box-sizing: border-box; - border-radius: var(--border-radius-standard); - position: relative; - background-color: var(--color-white); - margin-left: 9px; - - &:focus { - border: 1.5px inset #4e80f7; - } -} - -@media (--large-viewport) { - .searchBar { - margin: 0 64px; - } -} - -@media (--medium-viewport) { - .searchBar { - margin: 0 35px; - } -} - -@media (--small-viewport) { - .searchBar { - margin: 0 25px; - } -} diff --git a/src/components/searchResult/keyAction.js b/src/components/searchResult/keyAction.js deleted file mode 100644 index 41ec8fb9a7..0000000000 --- a/src/components/searchResult/keyAction.js +++ /dev/null @@ -1,15 +0,0 @@ -import localJSONStorage from '../../utils/localJSONStorage'; -/* eslint-disable import/prefer-default-export */ -export const saveSearch = (searchTerm, id) => { - if (searchTerm.length === 0) return; - const validSearch = searchTerm.trim(); - - const recent = localJSONStorage.get('searches', []); - - const searchObj = { - searchTerm: validSearch, - id, - }; - const updated = [searchObj].concat(recent.filter(term => typeof term === 'object' && term.searchTerm !== validSearch)).slice(0, 3); - localJSONStorage.set('searches', updated); -}; diff --git a/src/components/searchResult/keyAction.test.js b/src/components/searchResult/keyAction.test.js deleted file mode 100644 index 5c8b3108dd..0000000000 --- a/src/components/searchResult/keyAction.test.js +++ /dev/null @@ -1,33 +0,0 @@ -import { expect } from 'chai'; -import { saveSearch } from './keyAction'; -import localJSONStorage from '../../utils/localJSONStorage'; - -describe('Search KeyAction', () => { - const storage = {}; - - beforeEach(() => { - window.localStorage.getItem = key => (storage[key]); - window.localStorage.setItem = (key, item) => { storage[key] = item; }; - }); - - it('saves the last 3 searches without duplicates', () => { - const testValues = [ - { id: '811299173602533L', searchTerm: '811299173602533L' }, - { id: '947273526752682L', searchTerm: '947273526752682L' }, - { id: '', searchTerm: '' }, - { id: '382923358293526L ', searchTerm: '382923358293526L ' }, - { id: '947273526752682L ', searchTerm: '947273526752682L' }, - ]; - - const expectedOutcome = [ - { id: '947273526752682L ', searchTerm: '947273526752682L' }, - { id: '382923358293526L ', searchTerm: '382923358293526L' }, - { id: '811299173602533L', searchTerm: '811299173602533L' }, - ]; - - testValues.forEach((searchObj) => { - saveSearch(searchObj.searchTerm, searchObj.id); - }); - expect(localJSONStorage.get('searches')).to.eql(expectedOutcome); - }); -}); diff --git a/src/components/showMore/index.js b/src/components/showMore/index.js deleted file mode 100644 index ca77232062..0000000000 --- a/src/components/showMore/index.js +++ /dev/null @@ -1,13 +0,0 @@ -import React from 'react'; -import styles from './showMore.css'; - -const ShowMore = props => ( -
- {props.text} -
-); - -export default ShowMore; diff --git a/src/components/showMore/showMore.css b/src/components/showMore/showMore.css deleted file mode 100644 index 0da51f9710..0000000000 --- a/src/components/showMore/showMore.css +++ /dev/null @@ -1,20 +0,0 @@ -@import '../app/variablesV2.css'; -@import '../app/mixins.css'; - -.wrapper { - width: 100%; - min-height: 36px; - height: 36px; - display: flex; - justify-content: center; - align-items: center; - cursor: pointer; - background-color: var(--color-white-smoke); - border-top: 1px solid var(--color-platinum); - - & > span { - @mixin contentSmall bold; - - color: var(--color-maastricht-blue); - } -} diff --git a/src/components/showMore/showMore.test.js b/src/components/showMore/showMore.test.js deleted file mode 100644 index 9af419d531..0000000000 --- a/src/components/showMore/showMore.test.js +++ /dev/null @@ -1,30 +0,0 @@ -import React from 'react'; -import { expect } from 'chai'; -import { spy } from 'sinon'; -import { mount } from 'enzyme'; -import ShowMore from './index'; - -describe('notFound', () => { - const props = { - text: 'Show More', - onClick: spy(), - className: null, - }; - - it('should render a ShowMore', () => { - const wrapper = mount(); - expect(wrapper.find('.wrapper')).to.have.lengthOf(1); - }); - - it('should render a text Show More', () => { - const wrapper = mount(); - expect(wrapper.find('span').text()).to.equal('Show More'); - }); - - it('should call onClick function', () => { - const wrapper = mount(); - wrapper.find('.wrapper').simulate('click'); - wrapper.update(); - expect(props.onClick).to.have.been.calledWith(); - }); -}); diff --git a/src/components/spinner/index.js b/src/components/spinner/index.js deleted file mode 100644 index 312e515bf0..0000000000 --- a/src/components/spinner/index.js +++ /dev/null @@ -1,12 +0,0 @@ -import React from 'react'; -import styles from './spinner.css'; - -const Spinner = () => ( - -
-
-
- -); - -export default Spinner; diff --git a/src/components/spinner/index.test.js b/src/components/spinner/index.test.js deleted file mode 100644 index 2d49db8952..0000000000 --- a/src/components/spinner/index.test.js +++ /dev/null @@ -1,12 +0,0 @@ -import React from 'react'; -import { expect } from 'chai'; -import { mount } from 'enzyme'; -import Spinner from './index'; - -describe('Spinner', () => { - it('should render 1 span and 3 div tags', () => { - const wrapper = mount(); - expect(wrapper.find('span')).to.have.lengthOf(1); - expect(wrapper.find('div')).to.have.lengthOf(3); - }); -}); diff --git a/src/components/spinner/spinner.css b/src/components/spinner/spinner.css deleted file mode 100644 index 1017fce58b..0000000000 --- a/src/components/spinner/spinner.css +++ /dev/null @@ -1,36 +0,0 @@ -.spinner { - width: 24px; - text-align: center; - display: inline-block; -} - -.bounce1, -.bounce2, -.bounce3 { - width: 3px; - height: 3px; - margin: 1px; - border-radius: 100%; - display: inline-block; - animation: changeColor 1400ms infinite ease-in-out both; -} - -.bounce1 { - animation-delay: -6400ms; -} - -.bounce2 { - animation-delay: -320ms; -} - -@keyframes changeColor { - 0%, - 80%, - 100% { - background-color: #37516a; - } - - 40% { - background-color: #c9dae5; - } -} diff --git a/src/components/spinner/stories.js b/src/components/spinner/stories.js deleted file mode 100644 index 86d8786ed8..0000000000 --- a/src/components/spinner/stories.js +++ /dev/null @@ -1,9 +0,0 @@ -import React from 'react'; -import { storiesOf } from '@storybook/react'; - -import Spinner from '.'; - -storiesOf('Spinner', module) - .add('default', () => ( - - )); diff --git a/src/components/toaster/stories.js b/src/components/toaster/stories.js deleted file mode 100644 index e8b47f6ce8..0000000000 --- a/src/components/toaster/stories.js +++ /dev/null @@ -1,37 +0,0 @@ -import React from 'react'; - -import { storiesOf } from '@storybook/react'; -import { action } from '@storybook/addon-actions'; -import Toaster from './toaster'; - - -storiesOf('Toaster', module) - .add('default', () => ( - - )) - .add('success', () => ( - - )) - .add('error', () => ( - - )); diff --git a/src/components/toolbox/buttons/button.js b/src/components/toolbox/buttons/button.js index 0f07cef945..2c05c6f06f 100644 --- a/src/components/toolbox/buttons/button.js +++ b/src/components/toolbox/buttons/button.js @@ -2,57 +2,25 @@ import React from 'react'; import { themr } from 'react-css-themr'; import { Button as ToolBoxButton } from 'react-toolbox/lib/button'; import secondaryBlueButtonTheme from './css/secondaryBlueButton.css'; -import secondaryLightButtonTheme from './css/secondaryLightButton.css'; -import primaryButtonTheme from './css/primaryButton.css'; import primaryButtonV2Theme from './css/primaryButtonV2.css'; import secondaryButtonV2Theme from './css/secondaryButtonV2.css'; -import tertiaryButtonTheme from './css/tertiaryButton.css'; import tertiaryButtonV2Theme from './css/tertiaryButtonV2.css'; -import actionButtonTheme from './css/actionButton.css'; -class TBSecondaryBlueButton extends React.Component { +class TBButton extends React.Component { render() { return ; } } -class TBPrimaryButton extends React.Component { - render() { - return ; - } -} - -class TBSecondaryLightButton extends React.Component { - render() { - return ; - } -} - -class TBTertiaryButton extends React.Component { - render() { - return ; - } -} - -class TBActionButton extends React.Component { - render() { - return ; - } -} - -const PrimaryButton = themr('importantButton', primaryButtonTheme)(TBPrimaryButton); -const PrimaryButtonV2 = themr('dangerButton', primaryButtonV2Theme)(TBPrimaryButton); -const SecondaryLightButton = themr('lightButton', secondaryLightButtonTheme)(TBSecondaryLightButton); -const SecondaryButtonV2 = themr('lightButton', secondaryButtonV2Theme)(TBSecondaryLightButton); -const TertiaryButton = themr('tertiaryButton', tertiaryButtonTheme)(TBTertiaryButton); -const TertiaryButtonV2 = themr('tertiaryButton', tertiaryButtonV2Theme)(TBTertiaryButton); -const ActionButton = themr('actionButton', actionButtonTheme)(TBActionButton); -const Button = themr('button', secondaryBlueButtonTheme)(TBSecondaryBlueButton); +const PrimaryButtonV2 = themr('primaryButton', primaryButtonV2Theme)(TBButton); +const SecondaryButtonV2 = themr('secondarytButton', secondaryButtonV2Theme)(TBButton); +const TertiaryButtonV2 = themr('tertiaryButton', tertiaryButtonV2Theme)(TBButton); +const Button = themr('button', secondaryBlueButtonTheme)(TBButton); export { - Button, PrimaryButton, SecondaryLightButton, - TertiaryButton, ActionButton, - PrimaryButtonV2, SecondaryButtonV2, + Button, + PrimaryButtonV2, + SecondaryButtonV2, TertiaryButtonV2, }; export default Button; diff --git a/src/components/toolbox/buttons/button.test.js b/src/components/toolbox/buttons/button.test.js index 17ab1735a3..d7cbc5e83b 100644 --- a/src/components/toolbox/buttons/button.test.js +++ b/src/components/toolbox/buttons/button.test.js @@ -1,21 +1,11 @@ import React from 'react'; import { expect } from 'chai'; import { mount } from 'enzyme'; -import { Button, SecondaryLightButton, ActionButton } from './button'; +import { Button } from './button'; describe('Button wrapper', () => { it('Creates only one instance of the button', () => { const wrappedButton = mount(