diff --git a/react/change.log b/react/change.log index 5ee34f5..ca49259 100644 --- a/react/change.log +++ b/react/change.log @@ -20,6 +20,7 @@ UI: - jumblr - zcashparams folder check - claim interest modal +- renewed transactions history look v0.2.0.21a-beta -------------- diff --git a/react/package.json b/react/package.json index 656d1fd..f50b05e 100644 --- a/react/package.json +++ b/react/package.json @@ -47,6 +47,7 @@ "react-redux": "^5.0.3", "react-router": "^3.0.2", "react-router-redux": "^4.0.4", + "react-table": "~6.5.1", "react-transform-catch-errors": "^1.0.2", "react-transform-hmr": "^1.0.4", "redux": "^3.6.0", diff --git a/react/src/actions/actions/addressBalance.js b/react/src/actions/actions/addressBalance.js index a420575..9ec636b 100644 --- a/react/src/actions/actions/addressBalance.js +++ b/react/src/actions/actions/addressBalance.js @@ -222,7 +222,7 @@ export function getKMDAddressesNative(coin, mode, currentAddress) { let isNewAddr = true; for (let x = 0; x < result.length && isNewAddr; x++) { - for (let y=0; y < result[x].length && isNewAddr; y++) { + for (let y = 0; y < result[x].length && isNewAddr; y++) { if (allAddrArray[a] === result[x][y]) { isNewAddr = false; } diff --git a/react/src/actions/actions/walletAuth.js b/react/src/actions/actions/walletAuth.js index 31f2332..80798ac 100644 --- a/react/src/actions/actions/walletAuth.js +++ b/react/src/actions/actions/walletAuth.js @@ -255,6 +255,12 @@ export function iguanaActiveHandle(getMainAddress) { 'response': json, })); } + if (!Config.iguanaLessMode && + sessionStorage.getItem('IguanaActiveAccount') && + JSON.parse(sessionStorage.getItem('IguanaActiveAccount')).pubkey === json.pubkey && + json.status === 'unlocked') { + sessionStorage.setItem('IguanaActiveAccount', JSON.stringify(json)); + } dispatch(getMainAddress ? getMainAddressState(json) : iguanaActiveHandleState(json)); }); } diff --git a/react/src/components/addcoin/payload.js b/react/src/components/addcoin/payload.js index 7e727f6..e167e1d 100644 --- a/react/src/components/addcoin/payload.js +++ b/react/src/components/addcoin/payload.js @@ -182,6 +182,11 @@ export function startCurrencyAssetChain(confpath, coin, mode) { let AddCoinDataPayload = {}; let tmpPendValue = 1; let tmpIguanaRPCAuth = `tmpIgRPCUser@${sessionStorage.getItem('IguanaRPCAuth')}`; + let assetChainPorts; + + try { + assetChainPorts = window.require('electron').remote.getCurrentWindow().assetChainPorts; + } catch (e) {} if (coin !== 'BTC' && coin !== 'LTC' && @@ -424,218 +429,218 @@ export function startCurrencyAssetChain(confpath, coin, mode) { } else { const USDDiff = { 'netmagic': '2d8e7803', - 'p2p': 13966, - 'rpc': 13967 + 'p2p': assetChainPorts.USD, + 'rpc': assetChainPorts.USD - 1 }; AddCoinDataPayload.USDVar = Object.assign({}, _payloadVar, USDDiff); const CHFDiff = { 'netmagic': '59fbeb5c', - 'p2p': 15311, - 'rpc': 15312 + 'p2p': assetChainPorts.CHF, + 'rpc': assetChainPorts.CHF - 1 }; AddCoinDataPayload.CHFVar = Object.assign({}, _payloadVar, CHFDiff); const CADDiff = { 'netmagic': '3c212763', - 'p2p': 8719, - 'rpc': 8720 + 'p2p': assetChainPorts.CAD, + 'rpc': assetChainPorts.CAD - 1 }; AddCoinDataPayload.CADVar = Object.assign({}, _payloadVar, CADDiff); const BRLDiff = { 'netmagic': 'ab82d10d', - 'p2p': 9913, - 'rpc': 9914 + 'p2p': assetChainPorts.BRL, + 'rpc': assetChainPorts.BRL - 1 }; AddCoinDataPayload.BRLVar = Object.assign({}, _payloadVar, BRLDiff); const BGNDiff = { 'netmagic': '93056ad4', - 'p2p': 9109, - 'rpc': 9110 + 'p2p': assetChainPorts.BGN, + 'rpc': assetChainPorts.BGN - 1 }; AddCoinDataPayload.BGNVar = Object.assign({}, _payloadVar, BGNDiff); const AUDDiff = { 'netmagic': '07220d4e', - 'p2p': 8044, - 'rpc': 8045 + 'p2p': assetChainPorts.AUD, + 'rpc': assetChainPorts.AUD - 1 }; AddCoinDataPayload.AUDVar = Object.assign({}, _payloadVar, AUDDiff); const PLNDiff = { 'netmagic': '46ab3c28', - 'p2p': 13492, - 'rpc': 13493 + 'p2p': assetChainPorts.PLN, + 'rpc': assetChainPorts.PLN - 1 }; AddCoinDataPayload.PLNVar = Object.assign({}, _payloadVar, PLNDiff); const PHPDiff = { 'netmagic': '21535fb6', - 'p2p': 11180, - 'rpc': 11181 + 'p2p': assetChainPorts.PHP, + 'rpc': assetChainPorts.PHP - 1 }; AddCoinDataPayload.PHPVar = Object.assign({}, _payloadVar, PHPDiff); const NZDDiff = { 'netmagic': 'f579c9c2', - 'p2p': 10914, - 'rpc': 10915 + 'p2p': assetChainPorts.NZD, + 'rpc': assetChainPorts.NZD - 1 }; AddCoinDataPayload.NZDVar = Object.assign({}, _payloadVar, NZDDiff); const NOKDiff = { 'netmagic': '7082c365', - 'p2p': 11587, - 'rpc': 11588 + 'p2p': assetChainPorts.NOK, + 'rpc': assetChainPorts.NOK - 1 }; AddCoinDataPayload.NOKVar = Object.assign({}, _payloadVar, NOKDiff); const MYRDiff = { 'netmagic': '3e21761f', - 'p2p': 10687, - 'rpc': 10688 + 'p2p': assetChainPorts.MYR, + 'rpc': assetChainPorts.MYR - 1 }; AddCoinDataPayload.MYRVar = Object.assign({}, _payloadVar, MYRDiff); const MXNDiff = { 'netmagic': '304c6c12', - 'p2p': 13969, - 'rpc': 13970 + 'p2p': assetChainPorts.MXN, + 'rpc': assetChainPorts.MXN - 1 }; AddCoinDataPayload.MXNVar = Object.assign({}, _payloadVar, MXNDiff); const KRWDiff = { 'netmagic': 'c8706588', - 'p2p': 14019, - 'rpc': 14020 + 'p2p': assetChainPorts.KRW, + 'rpc': assetChainPorts.KRW - 1 }; AddCoinDataPayload.KRWVar = Object.assign({}, _payloadVar, KRWDiff); const JPYDiff = { 'netmagic': '7a55295c', - 'p2p': 13144, - 'rpc': 13145 + 'p2p': assetChainPorts.JPY, + 'rpc': assetChainPorts.JPY - 1 }; AddCoinDataPayload.JPYVar = Object.assign({}, _payloadVar, JPYDiff); const INRDiff = { 'netmagic': '740dfc1d', - 'p2p': 10535, - 'rpc': 10536 + 'p2p': assetChainPorts.INR, + 'rpc': assetChainPorts.INR - 1 }; AddCoinDataPayload.INRVar = Object.assign({}, _payloadVar, INRDiff); const ILSDiff = { 'netmagic': '605fcd58', - 'p2p': 14637, - 'rpc': 14638 + 'p2p': assetChainPorts.ILS, + 'rpc': assetChainPorts.ILS - 1 }; AddCoinDataPayload.ILSVar = Object.assign({}, _payloadVar, ILSDiff); const IDRDiff = { 'netmagic': 'fee513e7', - 'p2p': 14458, - 'rpc': 14459 + 'p2p': assetChainPorts.IDR, + 'rpc': assetChainPorts.IDR - 1 }; AddCoinDataPayload.IDRVar = Object.assign({}, _payloadVar, IDRDiff); const HKDDiff = { 'netmagic': '57269d95', - 'p2p': 15408, - 'rpc': 15409 + 'p2p': assetChainPorts.HKD, + 'rpc': assetChainPorts.HKD - 1 }; AddCoinDataPayload.HKDVar = Object.assign({}, _payloadVar, HKDDiff); const HUFDiff = { 'netmagic': 'a478d2af', - 'p2p': 13698, - 'rpc': 13699 + 'p2p': assetChainPorts.HUF, + 'rpc': assetChainPorts.HUF - 1 }; AddCoinDataPayload.HUFVar = Object.assign({}, _payloadVar, HUFDiff); const GBPDiff = { 'netmagic': '5e0ed955', - 'p2p': 11504, - 'rpc': 11505 + 'p2p': assetChainPorts.GBP, + 'rpc': assetChainPorts.GBP - 1 }; AddCoinDataPayload.GBPVar = Object.assign({}, _payloadVar, GBPDiff); const EURDiff = { 'netmagic': '8a3fd0bd', - 'p2p': 8064, - 'rpc': 8065 + 'p2p': assetChainPorts.EUR, + 'rpc': assetChainPorts.EUR - 1 }; AddCoinDataPayload.EURVar = Object.assign({}, _payloadVar, EURDiff); const DKKDiff = { 'netmagic': 'a2c2380c', - 'p2p': 13829, - 'rpc': 13830 + 'p2p': assetChainPorts.DKK, + 'rpc': assetChainPorts.DKK - 1 }; AddCoinDataPayload.DKKVar = Object.assign({}, _payloadVar, DKKDiff); const CNYDiff = { 'netmagic': '2a51b987', - 'p2p': 10383, - 'rpc': 10384 + 'p2p': assetChainPorts.CNY, + 'rpc': assetChainPorts.CNY - 1 }; AddCoinDataPayload.CNYVar = Object.assign({}, _payloadVar, CNYDiff); const ZARDiff = { 'netmagic': '920c0484', - 'p2p': 15159, - 'rpc': 15160 + 'p2p': assetChainPorts.ZAR, + 'rpc': assetChainPorts.ZAR - 1 }; AddCoinDataPayload.ZARVar = Object.assign({}, _payloadVar, ZARDiff); const TRYDiff = { 'netmagic': '82b9a778', - 'p2p': 13923, - 'rpc': 13924 + 'p2p': assetChainPorts.TRY, + 'rpc': assetChainPorts.TRY - 1 }; AddCoinDataPayload.TRYVar = Object.assign({}, _payloadVar, TRYDiff); const THBDiff = { 'netmagic': 'b58aef42', - 'p2p': 11846, - 'rpc': 11847 + 'p2p': assetChainPorts.THB, + 'rpc': assetChainPorts.THB - 1 }; AddCoinDataPayload.THBVar = Object.assign({}, _payloadVar, THBDiff); const SGDDiff = { 'netmagic': 'ca255b29', - 'p2p': 14474, - 'rpc': 14475 + 'p2p': assetChainPorts.SGD, + 'rpc': assetChainPorts.SGD - 1 }; AddCoinDataPayload.SGDVar = Object.assign({}, _payloadVar, SGDDiff); const SEKDiff = { 'netmagic': 'd95ad28b', - 'p2p': 11446, - 'rpc': 11447 + 'p2p': assetChainPorts.SEK, + 'rpc': assetChainPorts.SEK - 1 }; AddCoinDataPayload.SEKVar = Object.assign({}, _payloadVar, SEKDiff); const RONDiff = { 'netmagic': 'eb2c9500', - 'p2p': 8674, - 'rpc': 8675 + 'p2p': assetChainPorts.RON, + 'rpc': assetChainPorts.RON - 1 }; AddCoinDataPayload.RONVar = Object.assign({}, _payloadVar, RONDiff); const RUBDiff = { 'netmagic': '1b9a0eb9', - 'p2p': 8198, - 'rpc': 8199 + 'p2p': assetChainPorts.RUB, + 'rpc': assetChainPorts.RUB - 1 }; AddCoinDataPayload.RUBVar = Object.assign({}, _payloadVar, RUBDiff); const CZKDiff = { 'netmagic': '37f7ae5a', - 'p2p': 9481, - 'rpc': 9482 + 'p2p': assetChainPorts.CZK, + 'rpc': assetChainPorts.CZK - 1 }; AddCoinDataPayload.CZKVar = Object.assign({}, _payloadVar, CZKDiff); @@ -646,6 +651,11 @@ export function startCurrencyAssetChain(confpath, coin, mode) { export function startAssetChain(confpath, coin, mode, getSuppyOnly) { let tmpIguanaRPCAuth = `tmpIgRPCUser@${sessionStorage.getItem('IguanaRPCAuth')}`; let tmpPendValue; + let assetChainPorts; + + try { + assetChainPorts = window.require('electron').remote.getCurrentWindow().assetChainPorts; + } catch (e) {} if (coin !== 'BTC' && coin !== 'LTC' && @@ -682,74 +692,74 @@ export function startAssetChain(confpath, coin, mode, getSuppyOnly) { 'SUPERNET': { 'name': 'SUPERNET', 'supply': 816061, - 'AddCoinData': confpath ? Object.assign({}, _acPayloadOrigin, {"coin":"SUPERNET","conf":"SUPERNET.conf","path":confpath,"RELAY":-1,"VALIDATE":0,"startpend":4,"endpend":4,"maxpeers":32,"newcoin":"SUPERNET","name":"SUPERNET","netmagic":"cc55d9d4","p2p":11340,"rpc":11341}) : {}, - 'AddCoinDataVar': Object.assign({}, _acPayloadOrigin, {'userpass':tmpIguanaRPCAuth,"RELAY":mode,"VALIDATE":mode,"startpend":tmpPendValue,"endpend":tmpPendValue,"maxpeers":32,"newcoin":"SUPERNET","name":"SUPERNET","netmagic":"cc55d9d4","p2p":11340,"rpc":11341}) + 'AddCoinData': confpath ? Object.assign({}, _acPayloadOrigin, {"coin":"SUPERNET","conf":"SUPERNET.conf","path":confpath,"RELAY":-1,"VALIDATE":0,"startpend":4,"endpend":4,"maxpeers":32,"newcoin":"SUPERNET","name":"SUPERNET","netmagic":"cc55d9d4","p2p":assetChainPorts.SUPERNET - 1,"rpc":assetChainPorts.SUPERNET}) : {}, + 'AddCoinDataVar': Object.assign({}, _acPayloadOrigin, {'userpass':tmpIguanaRPCAuth,"RELAY":mode,"VALIDATE":mode,"startpend":tmpPendValue,"endpend":tmpPendValue,"maxpeers":32,"newcoin":"SUPERNET","name":"SUPERNET","netmagic":"cc55d9d4","p2p":assetChainPorts.SUPERNET - 1,"rpc":assetChainPorts.SUPERNET}) }, 'REVS': { 'name': 'REVS', 'supply': 1300000, - 'AddCoinData': confpath ? Object.assign({}, _acPayloadOrigin, {"coin":"REVS","conf":"REVS.conf","path":confpath,"RELAY":-1,"VALIDATE":0,"startpend":4,"endpend":4,"maxpeers":8,"newcoin":"REVS","name":"REVS","netmagic":"905c3498","p2p":10195,"rpc":10196}) : {}, - 'AddCoinDataVar': Object.assign({}, _acPayloadOrigin, {'userpass':tmpIguanaRPCAuth,"RELAY":mode,"VALIDATE":mode,"startpend":tmpPendValue,"endpend":tmpPendValue,"maxpeers":8,"newcoin":"REVS","name":"REVS","netmagic":"905c3498","p2p":10195,"rpc":10196}) + 'AddCoinData': confpath ? Object.assign({}, _acPayloadOrigin, {"coin":"REVS","conf":"REVS.conf","path":confpath,"RELAY":-1,"VALIDATE":0,"startpend":4,"endpend":4,"maxpeers":8,"newcoin":"REVS","name":"REVS","netmagic":"905c3498","p2p":assetChainPorts.REVS - 1,"rpc":assetChainPorts.REVS}) : {}, + 'AddCoinDataVar': Object.assign({}, _acPayloadOrigin, {'userpass':tmpIguanaRPCAuth,"RELAY":mode,"VALIDATE":mode,"startpend":tmpPendValue,"endpend":tmpPendValue,"maxpeers":8,"newcoin":"REVS","name":"REVS","netmagic":"905c3498","p2p":assetChainPorts.REVS - 1,"rpc":assetChainPorts.REVS}) }, 'WLC': { 'name': 'WIRELESS', 'supply': 210000000, - 'AddCoinData': confpath ? Object.assign({}, _acPayloadOrigin, {"coin":"WLC","conf":"WLC.conf","path":confpath,"RELAY":-1,"VALIDATE":0,"startpend":4,"endpend":4,"maxpeers":8,"newcoin":"WLC","name":"WIRELESS","netmagic":"62071ed3","p2p":11666,"rpc":11667}) : {}, - 'AddCoinDataVar': Object.assign({}, _acPayloadOrigin, {'userpass':tmpIguanaRPCAuth,"RELAY":mode,"VALIDATE":mode,"startpend":tmpPendValue,"endpend":tmpPendValue,"maxpeers":8,"newcoin":"WLC","name":"WIRELESS","netmagic":"62071ed3","p2p":11666,"rpc":11667}) + 'AddCoinData': confpath ? Object.assign({}, _acPayloadOrigin, {"coin":"WLC","conf":"WLC.conf","path":confpath,"RELAY":-1,"VALIDATE":0,"startpend":4,"endpend":4,"maxpeers":8,"newcoin":"WLC","name":"WIRELESS","netmagic":"62071ed3","p2p":assetChainPorts.WIRELESS - 1,"rpc":assetChainPorts.WIRELESS}) : {}, + 'AddCoinDataVar': Object.assign({}, _acPayloadOrigin, {'userpass':tmpIguanaRPCAuth,"RELAY":mode,"VALIDATE":mode,"startpend":tmpPendValue,"endpend":tmpPendValue,"maxpeers":8,"newcoin":"WLC","name":"WIRELESS","netmagic":"62071ed3","p2p":assetChainPorts.WIRELESS - 1,"rpc":assetChainPorts.WIRELESS}) }, 'PANGEA': { 'name': 'PANGEA', 'supply': 999999, - 'AddCoinData': confpath ? Object.assign({}, _acPayloadOrigin, {"coin":"PANGEA","conf":"PANGEA.conf","path":confpath,"RELAY":-1,"VALIDATE":1,"startpend":4,"endpend":4,"maxpeers":8,"newcoin":"PANGEA","name":"PANGEA","netmagic":"5fa45ae8","p2p":10073,"rpc":10074}) : {}, - 'AddCoinDataVar': Object.assign({}, _acPayloadOrigin, {'userpass':tmpIguanaRPCAuth,"RELAY":mode,"VALIDATE":mode,"startpend":tmpPendValue,"endpend":tmpPendValue,"maxpeers":8,"newcoin":"PANGEA","name":"PANGEA","netmagic":"5fa45ae8","p2p":10073,"rpc":10074}) + 'AddCoinData': confpath ? Object.assign({}, _acPayloadOrigin, {"coin":"PANGEA","conf":"PANGEA.conf","path":confpath,"RELAY":-1,"VALIDATE":1,"startpend":4,"endpend":4,"maxpeers":8,"newcoin":"PANGEA","name":"PANGEA","netmagic":"5fa45ae8","p2p":assetChainPorts.PANGEA - 1,"rpc":assetChainPorts.PANGEA}) : {}, + 'AddCoinDataVar': Object.assign({}, _acPayloadOrigin, {'userpass':tmpIguanaRPCAuth,"RELAY":mode,"VALIDATE":mode,"startpend":tmpPendValue,"endpend":tmpPendValue,"maxpeers":8,"newcoin":"PANGEA","name":"PANGEA","netmagic":"5fa45ae8","p2p":assetChainPorts.PANGEA - 1,"rpc":assetChainPorts.PANGEA}) }, 'DEX': { 'name': 'DEX', 'supply': 999999, - 'AddCoinData': confpath ? Object.assign({}, _acPayloadOrigin, {"coin":"DEX","conf":"DEX.conf","path":confpath,"RELAY":-1,"VALIDATE":1,"startpend":4,"endpend":4,"maxpeers":8,"newcoin":"DEX","name":"DEX","netmagic":"f2ae0516","p2p":9502,"rpc":9503}) : {}, - 'AddCoinDataVar': Object.assign({}, _acPayloadOrigin, {'userpass':tmpIguanaRPCAuth,"RELAY":mode,"VALIDATE":mode,"startpend":tmpPendValue,"endpend":tmpPendValue,"maxpeers":8,"newcoin":"DEX","name":"DEX","netmagic":"f2ae0516","p2p":9502,"rpc":9503}) + 'AddCoinData': confpath ? Object.assign({}, _acPayloadOrigin, {"coin":"DEX","conf":"DEX.conf","path":confpath,"RELAY":-1,"VALIDATE":1,"startpend":4,"endpend":4,"maxpeers":8,"newcoin":"DEX","name":"DEX","netmagic":"f2ae0516","p2p":assetChainPorts.DEX - 1,"rpc":assetChainPorts.DEX}) : {}, + 'AddCoinDataVar': Object.assign({}, _acPayloadOrigin, {'userpass':tmpIguanaRPCAuth,"RELAY":mode,"VALIDATE":mode,"startpend":tmpPendValue,"endpend":tmpPendValue,"maxpeers":8,"newcoin":"DEX","name":"DEX","netmagic":"f2ae0516","p2p":assetChainPorts.DEX - 1,"rpc":assetChainPorts.DEX}) }, 'JUMBLR': { 'name': 'JUMBLR', 'supply': 999999, - 'AddCoinData': confpath ? Object.assign({}, _acPayloadOrigin, {"coin":"JUMBLR","conf":"JUMBLR.conf","path":confpath,"RELAY":-1,"VALIDATE":1,"startpend":4,"endpend":4,"maxpeers":8,"newcoin":"JUMBLR","name":"JUMBLR","netmagic":"7223759e","p2p":10788,"rpc":10789}) : {}, - 'AddCoinDataVar': Object.assign({}, _acPayloadOrigin, {'userpass':tmpIguanaRPCAuth,"RELAY":mode,"VALIDATE":mode,"startpend":tmpPendValue,"endpend":tmpPendValue,"maxpeers":8,"newcoin":"JUMBLR","name":"JUMBLR","netmagic":"7223759e","p2p":10788,"rpc":10789}) + 'AddCoinData': confpath ? Object.assign({}, _acPayloadOrigin, {"coin":"JUMBLR","conf":"JUMBLR.conf","path":confpath,"RELAY":-1,"VALIDATE":1,"startpend":4,"endpend":4,"maxpeers":8,"newcoin":"JUMBLR","name":"JUMBLR","netmagic":"7223759e","p2p":assetChainPorts.JUMBLR - 1,"rpc":assetChainPorts.JUMBLR}) : {}, + 'AddCoinDataVar': Object.assign({}, _acPayloadOrigin, {'userpass':tmpIguanaRPCAuth,"RELAY":mode,"VALIDATE":mode,"startpend":tmpPendValue,"endpend":tmpPendValue,"maxpeers":8,"newcoin":"JUMBLR","name":"JUMBLR","netmagic":"7223759e","p2p":assetChainPorts.JUMBLR - 1,"rpc":assetChainPorts.JUMBLR}) }, 'BET': { 'name': 'BET', 'supply': 999999, - 'AddCoinData': confpath ? Object.assign({}, _acPayloadOrigin, {"coin":"BET","conf":"BET.conf","path":confpath,"RELAY":-1,"VALIDATE":1,"startpend":4,"endpend":4,"maxpeers":8,"newcoin":"BET","name":"BET","netmagic":"6b9e3e1b","p2p":11221,"rpc":11222}) : {}, - 'AddCoinDataVar': Object.assign({}, _acPayloadOrigin, {'userpass':tmpIguanaRPCAuth,"RELAY":mode,"VALIDATE":mode,"startpend":tmpPendValue,"endpend":tmpPendValue,"maxpeers":8,"newcoin":"BET","name":"BET","netmagic":"6b9e3e1b","p2p":11221,"rpc":11222}) + 'AddCoinData': confpath ? Object.assign({}, _acPayloadOrigin, {"coin":"BET","conf":"BET.conf","path":confpath,"RELAY":-1,"VALIDATE":1,"startpend":4,"endpend":4,"maxpeers":8,"newcoin":"BET","name":"BET","netmagic":"6b9e3e1b","p2p":assetChainPorts.BET - 1,"rpc":assetChainPorts.BET}) : {}, + 'AddCoinDataVar': Object.assign({}, _acPayloadOrigin, {'userpass':tmpIguanaRPCAuth,"RELAY":mode,"VALIDATE":mode,"startpend":tmpPendValue,"endpend":tmpPendValue,"maxpeers":8,"newcoin":"BET","name":"BET","netmagic":"6b9e3e1b","p2p":assetChainPorts.BET - 1,"rpc":assetChainPorts.BET}) }, 'CRYPTO': { 'name': 'CRYPTO', 'supply': 999999, - 'AddCoinData': confpath ? Object.assign({}, _acPayloadOrigin, {"coin":"CRYPTO","conf":"CRYPTO.conf","path":confpath,"RELAY":-1,"VALIDATE":1,"startpend":4,"endpend":4,"maxpeers":8,"newcoin":"CRYPTO","name":"CRYPTO","netmagic":"fced9e2a","p2p":10419,"rpc":10420}) : {}, - 'AddCoinDataVar': Object.assign({}, _acPayloadOrigin, {'userpass':tmpIguanaRPCAuth,"RELAY":mode,"VALIDATE":mode,"startpend":tmpPendValue,"endpend":tmpPendValue,"maxpeers":8,"newcoin":"CRYPTO","name":"CRYPTO","netmagic":"fced9e2a","p2p":10419,"rpc":10420}) + 'AddCoinData': confpath ? Object.assign({}, _acPayloadOrigin, {"coin":"CRYPTO","conf":"CRYPTO.conf","path":confpath,"RELAY":-1,"VALIDATE":1,"startpend":4,"endpend":4,"maxpeers":8,"newcoin":"CRYPTO","name":"CRYPTO","netmagic":"fced9e2a","p2p":assetChainPorts.CRYPTO - 1,"rpc":assetChainPorts.CRYPTO}) : {}, + 'AddCoinDataVar': Object.assign({}, _acPayloadOrigin, {'userpass':tmpIguanaRPCAuth,"RELAY":mode,"VALIDATE":mode,"startpend":tmpPendValue,"endpend":tmpPendValue,"maxpeers":8,"newcoin":"CRYPTO","name":"CRYPTO","netmagic":"fced9e2a","p2p":assetChainPorts.CRYPTO - 1,"rpc":assetChainPorts.CRYPTO}) }, 'HODL': { 'name': 'HODL', 'supply': 9999999, - 'AddCoinData': confpath ? Object.assign({}, _acPayloadOrigin, {"coin":"HODL","conf":"HODL.conf","path":confpath,"RELAY":-1,"VALIDATE":1,"startpend":4,"endpend":4,"maxpeers":8,"newcoin":"HODL","name":"HODL","netmagic":"9b13fb5f","p2p":8009,"rpc":8010}) : {}, - 'AddCoinDataVar': Object.assign({}, _acPayloadOrigin, {'userpass':tmpIguanaRPCAuth,"RELAY":mode,"VALIDATE":mode,"startpend":tmpPendValue,"endpend":tmpPendValue,"maxpeers":8,"newcoin":"HODL","name":"HODL","netmagic":"9b13fb5f","p2p":8009,"rpc":8010}) + 'AddCoinData': confpath ? Object.assign({}, _acPayloadOrigin, {"coin":"HODL","conf":"HODL.conf","path":confpath,"RELAY":-1,"VALIDATE":1,"startpend":4,"endpend":4,"maxpeers":8,"newcoin":"HODL","name":"HODL","netmagic":"9b13fb5f","p2p":assetChainPorts.HODL - 1,"rpc":assetChainPorts.HODL}) : {}, + 'AddCoinDataVar': Object.assign({}, _acPayloadOrigin, {'userpass':tmpIguanaRPCAuth,"RELAY":mode,"VALIDATE":mode,"startpend":tmpPendValue,"endpend":tmpPendValue,"maxpeers":8,"newcoin":"HODL","name":"HODL","netmagic":"9b13fb5f","p2p":assetChainPorts.HODL - 1,"rpc":assetChainPorts.HODL}) }, 'SHARK': { 'name': 'SHARK', 'supply': 1401, - 'AddCoinData': confpath ? Object.assign({}, _acPayloadOrigin, {"coin":"SHARK","conf":"SHARK.conf","path":confpath,"RELAY":-1,"VALIDATE":1,"startpend":4,"endpend":4,"maxpeers":8,"newcoin":"SHARK","name":"SHARK","netmagic":"54a5e30c","p2p":14103,"rpc":14104}) : {}, - 'AddCoinDataVar': Object.assign({}, _acPayloadOrigin, {'userpass':tmpIguanaRPCAuth,"RELAY":mode,"VALIDATE":mode,"startpend":tmpPendValue,"endpend":tmpPendValue,"maxpeers":8,"newcoin":"SHARK","name":"SHARK","netmagic":"54a5e30c","p2p":14103,"rpc":14104}) + 'AddCoinData': confpath ? Object.assign({}, _acPayloadOrigin, {"coin":"SHARK","conf":"SHARK.conf","path":confpath,"RELAY":-1,"VALIDATE":1,"startpend":4,"endpend":4,"maxpeers":8,"newcoin":"SHARK","name":"SHARK","netmagic":"54a5e30c","p2p":assetChainPorts.SHARK - 1,"rpc":assetChainPorts.SHARK}) : {}, + 'AddCoinDataVar': Object.assign({}, _acPayloadOrigin, {'userpass':tmpIguanaRPCAuth,"RELAY":mode,"VALIDATE":mode,"startpend":tmpPendValue,"endpend":tmpPendValue,"maxpeers":8,"newcoin":"SHARK","name":"SHARK","netmagic":"54a5e30c","p2p":assetChainPorts.SHARK - 1,"rpc":assetChainPorts.SHARK}) }, 'BOTS': { 'name': 'BOTS', 'supply': 999999, - 'AddCoinData': confpath ? Object.assign({}, _acPayloadOrigin, {"coin":"BOTS","conf":"BOTS.conf","path":confpath,"RELAY":-1,"VALIDATE":1,"startpend":4,"endpend":4,"maxpeers":8,"newcoin":"BOTS","name":"BOTS","netmagic":"5bec8cf7","p2p":10150,"rpc":10151}) : {}, - 'AddCoinDataVar': Object.assign({}, _acPayloadOrigin, {'userpass':tmpIguanaRPCAuth,"RELAY":mode,"VALIDATE":mode,"startpend":tmpPendValue,"endpend":tmpPendValue,"maxpeers":8,"newcoin":"BOTS","name":"BOTS","netmagic":"5bec8cf7","p2p":10150,"rpc":10151}) + 'AddCoinData': confpath ? Object.assign({}, _acPayloadOrigin, {"coin":"BOTS","conf":"BOTS.conf","path":confpath,"RELAY":-1,"VALIDATE":1,"startpend":4,"endpend":4,"maxpeers":8,"newcoin":"BOTS","name":"BOTS","netmagic":"5bec8cf7","p2p":assetChainPorts.BOTS - 1,"rpc":assetChainPorts.BOTS}) : {}, + 'AddCoinDataVar': Object.assign({}, _acPayloadOrigin, {'userpass':tmpIguanaRPCAuth,"RELAY":mode,"VALIDATE":mode,"startpend":tmpPendValue,"endpend":tmpPendValue,"maxpeers":8,"newcoin":"BOTS","name":"BOTS","netmagic":"5bec8cf7","p2p":assetChainPorts.BOTS - 1,"rpc":assetChainPorts.BOTS}) }, 'MGW': { 'name': 'MGW', 'supply': 999999, - 'AddCoinData': confpath ? Object.assign({}, _acPayloadOrigin, {"coin":"MGW","conf":"MGW.conf","path":confpath,"unitval":"20","zcash":1,"RELAY":-1,"VALIDATE":1,"startpend":4,"endpend":4,"maxpeers":8,"newcoin":"MGW","name":"MGW","netmagic":"6eea5dbb","p2p":15523,"rpc":15524}) : {}, - 'AddCoinDataVar': Object.assign({}, _acPayloadOrigin, {'userpass':tmpIguanaRPCAuth,"unitval":"20","zcash":1,"RELAY":mode,"VALIDATE":mode,"startpend":tmpPendValue,"endpend":tmpPendValue,"maxpeers":8,"newcoin":"MGW","name":"MGW","netmagic":"6eea5dbb","p2p":15523,"rpc":15524}) + 'AddCoinData': confpath ? Object.assign({}, _acPayloadOrigin, {"coin":"MGW","conf":"MGW.conf","path":confpath,"unitval":"20","zcash":1,"RELAY":-1,"VALIDATE":1,"startpend":4,"endpend":4,"maxpeers":8,"newcoin":"MGW","name":"MGW","netmagic":"6eea5dbb","p2p":assetChainPorts.MGW - 1,"rpc":assetChainPorts.MGW}) : {}, + 'AddCoinDataVar': Object.assign({}, _acPayloadOrigin, {'userpass':tmpIguanaRPCAuth,"unitval":"20","zcash":1,"RELAY":mode,"VALIDATE":mode,"startpend":tmpPendValue,"endpend":tmpPendValue,"maxpeers":8,"newcoin":"MGW","name":"MGW","netmagic":"6eea5dbb","p2p":assetChainPorts.MGW - 1,"rpc":assetChainPorts.MGW}) }, 'MVP': { 'name': 'MVP', @@ -760,26 +770,26 @@ export function startAssetChain(confpath, coin, mode, getSuppyOnly) { 'KV': { 'name': 'KV', 'supply': 1000000, - 'AddCoinData': confpath ? Object.assign({}, _acPayloadOrigin, {"coin":"KV","conf":"KV.conf","path":confpath,"RELAY":-1,"VALIDATE":1,"startpend":4,"endpend":4,"maxpeers":8,"newcoin":"KV","name":"KV","netmagic":"b09a2d65","p2p":9746,"rpc":9747}) : {}, - 'AddCoinDataVar': Object.assign(_acPayloadOrigin, {'userpass':tmpIguanaRPCAuth,"RELAY":mode,"VALIDATE":mode,"startpend":tmpPendValue,"endpend":tmpPendValue,"maxpeers":8,"newcoin":"KV","name":"KV","netmagic":"b09a2d65","p2p":9746,"rpc":9747}) + 'AddCoinData': confpath ? Object.assign({}, _acPayloadOrigin, {"coin":"KV","conf":"KV.conf","path":confpath,"RELAY":-1,"VALIDATE":1,"startpend":4,"endpend":4,"maxpeers":8,"newcoin":"KV","name":"KV","netmagic":"b09a2d65","p2p":assetChainPorts.KV - 1,"rpc":assetChainPorts.KV}) : {}, + 'AddCoinDataVar': Object.assign(_acPayloadOrigin, {'userpass':tmpIguanaRPCAuth,"RELAY":mode,"VALIDATE":mode,"startpend":tmpPendValue,"endpend":tmpPendValue,"maxpeers":8,"newcoin":"KV","name":"KV","netmagic":"b09a2d65","p2p":assetChainPorts.KV - 1,"rpc":assetChainPorts.KV}) }, 'CEAL': { 'name': 'CEAL', 'supply': 366666666, - 'AddCoinData': confpath ? Object.assign({}, _acPayloadOrigin, {"coin":"CEAL","conf":"CEAL.conf","path":confpath,"RELAY":-1,"VALIDATE":1,"startpend":4,"endpend":4,"maxpeers":8,"newcoin":"CEAL","name":"CEAL","netmagic":"09e51af8","p2p":13096,"rpc":13097}) : {}, - 'AddCoinDataVar': Object.assign({}, _acPayloadOrigin, {'userpass':tmpIguanaRPCAuth,"RELAY":mode,"VALIDATE":mode,"startpend":tmpPendValue,"endpend":tmpPendValue,"maxpeers":8,"newcoin":"CEAL","name":"CEAL","netmagic":"09e51af8","p2p":13096,"rpc":13097}) + 'AddCoinData': confpath ? Object.assign({}, _acPayloadOrigin, {"coin":"CEAL","conf":"CEAL.conf","path":confpath,"RELAY":-1,"VALIDATE":1,"startpend":4,"endpend":4,"maxpeers":8,"newcoin":"CEAL","name":"CEAL","netmagic":"09e51af8","p2p":assetChainPorts.CEAL - 1,"rpc":assetChainPorts.CEAL}) : {}, + 'AddCoinDataVar': Object.assign({}, _acPayloadOrigin, {'userpass':tmpIguanaRPCAuth,"RELAY":mode,"VALIDATE":mode,"startpend":tmpPendValue,"endpend":tmpPendValue,"maxpeers":8,"newcoin":"CEAL","name":"CEAL","netmagic":"09e51af8","p2p":assetChainPorts.CEAL - 1,"rpc":assetChainPorts.CEAL}) }, 'MESH': { 'name': 'MESH', 'supply': 1000007, - 'AddCoinData': confpath ? Object.assign({}, _acPayloadOrigin, {"coin":"MESH","conf":"MESH.conf","path":confpath,"RELAY":-1,"VALIDATE":1,"startpend":4,"endpend":4,"maxpeers":8,"newcoin":"MESH","name":"MESH","netmagic":"f0265c67","p2p":8399,"rpc":8400}) : {}, - 'AddCoinDataVar': Object.assign({}, _acPayloadOrigin, {'userpass':tmpIguanaRPCAuth,"RELAY":mode,"VALIDATE":mode,"startpend":tmpPendValue,"endpend":tmpPendValue,"maxpeers":8,"newcoin":"MESH","name":"MESH","netmagic":"f0265c67","p2p":8399,"rpc":8400}) + 'AddCoinData': confpath ? Object.assign({}, _acPayloadOrigin, {"coin":"MESH","conf":"MESH.conf","path":confpath,"RELAY":-1,"VALIDATE":1,"startpend":4,"endpend":4,"maxpeers":8,"newcoin":"MESH","name":"MESH","netmagic":"f0265c67","p2p":assetChainPorts.MESH - 1,"rpc":assetChainPorts.MESH}) : {}, + 'AddCoinDataVar': Object.assign({}, _acPayloadOrigin, {'userpass':tmpIguanaRPCAuth,"RELAY":mode,"VALIDATE":mode,"startpend":tmpPendValue,"endpend":tmpPendValue,"maxpeers":8,"newcoin":"MESH","name":"MESH","netmagic":"f0265c67","p2p":assetChainPorts.MESH - 1,"rpc":assetChainPorts.MESH}) }, 'COQUI': { 'name': 'COQUI', 'supply': 72000000, - 'AddCoinData': confpath ? Object.assign({}, _acPayloadOrigin, {"coin":"COQUI","conf":"COQUI.conf","path":confpath,"RELAY":-1,"VALIDATE":1,"startpend":4,"endpend":4,"maxpeers":8,"newcoin":"COQUI","name":"COQUI","netmagic":"4cbd5ef4","p2p":14275,"rpc":14276}) : {}, - 'AddCoinDataVar': Object.assign({}, _acPayloadOrigin, {'userpass':tmpIguanaRPCAuth,"RELAY":mode,"VALIDATE":mode,"startpend":tmpPendValue,"endpend":tmpPendValue,"maxpeers":8,"newcoin":"COQUI","name":"COQUI","netmagic":"4cbd5ef4","p2p":14275,"rpc":14276}) + 'AddCoinData': confpath ? Object.assign({}, _acPayloadOrigin, {"coin":"COQUI","conf":"COQUI.conf","path":confpath,"RELAY":-1,"VALIDATE":1,"startpend":4,"endpend":4,"maxpeers":8,"newcoin":"COQUI","name":"COQUI","netmagic":"4cbd5ef4","p2p":assetChainPorts.COQUI - 1,"rpc":assetChainPorts.COQUI}) : {}, + 'AddCoinDataVar': Object.assign({}, _acPayloadOrigin, {'userpass':tmpIguanaRPCAuth,"RELAY":mode,"VALIDATE":mode,"startpend":tmpPendValue,"endpend":tmpPendValue,"maxpeers":8,"newcoin":"COQUI","name":"COQUI","netmagic":"4cbd5ef4","p2p":assetChainPorts.COQUI - 1,"rpc":assetChainPorts.COQUI}) } }; diff --git a/react/src/components/dashboard/main/dashboard.scss b/react/src/components/dashboard/main/dashboard.scss index 8dfc52c..3309f01 100755 --- a/react/src/components/dashboard/main/dashboard.scss +++ b/react/src/components/dashboard/main/dashboard.scss @@ -133,4 +133,46 @@ // walletsNativeTxInfo.js .height-170 { height: 170px; +} + +.rt-tr.-odd div, +.rt-tr.-even div { + padding-top: 2px; + padding-bottom: 2px; +} + +.rt-tr-group.-odd .-padRow { + display: none; +} + +.ReactTable .rt-tfoot .rt-td { + text-align: center; +} + +.ReactTable .rt-thead .rt-th.-sort-asc, +.ReactTable .rt-thead .rt-td.-sort-asc, +.ReactTable .rt-thead .rt-th.-sort-desc, +.ReactTable .rt-thead .rt-td.-sort-desc{ + box-shadow: none; +} + +.ReactTable .rt-thead .rt-th.-sort-asc div:nth-child(1):after { + font-family: FontAwesome; + padding-left: 5px; + content: "\f106"; +} +.ReactTable .rt-thead .rt-th.-sort-desc div:nth-child(1):after { + font-family: FontAwesome; + padding-left: 5px; + content: "\f107"; +} + +.rt-tr.-padRow { + display: none; +} + +.ReactTable .-pagination, +.ReactTable .rt-thead.-header, +.ReactTable .rt-tfoot{ + box-shadow: none; } \ No newline at end of file diff --git a/react/src/components/dashboard/walletsData/pagination.js b/react/src/components/dashboard/walletsData/pagination.js new file mode 100644 index 0000000..dba569d --- /dev/null +++ b/react/src/components/dashboard/walletsData/pagination.js @@ -0,0 +1,46 @@ +import React, { Component } from 'react'; +import PaginationRender from './pagination.render'; + +export default class TablePaginationRenderer extends Component { + constructor (props) { + super(); + this.state = { + page: props.page + } + this.getSafePage = this.getSafePage.bind(this); + this.changePage = this.changePage.bind(this); + this.applyPage = this.applyPage.bind(this); + } + + componentWillReceiveProps(nextProps) { + this.setState({ page: nextProps.page }); + } + + getSafePage(page) { + if (isNaN(page)) { + page = this.props.page; + } + + return Math.min(Math.max(page, 0), this.props.pages - 1); + } + + changePage(page) { + page = this.getSafePage(page); + this.setState({ page }); + + if (this.props.page !== page) { + this.props.onPageChange(page); + } + } + + applyPage(e) { + const page = this.state.page; + + e && e.preventDefault(); + this.changePage(page === '' ? this.props.page : page); + } + + render() { + return PaginationRender.call(this); + } +} \ No newline at end of file diff --git a/react/src/components/dashboard/walletsData/pagination.render.js b/react/src/components/dashboard/walletsData/pagination.render.js new file mode 100644 index 0000000..c4d1de6 --- /dev/null +++ b/react/src/components/dashboard/walletsData/pagination.render.js @@ -0,0 +1,103 @@ +import React from 'react'; +import classnames from 'classnames'; + +const defaultButton = props => + <button + type="button" + className="-btn" + {...props}> + {props.children} + </button> + +const PaginationRender = function() { + const { + // Computed + pages, + // Props + page, + showPageSizeOptions, + pageSizeOptions, + pageSize, + showPageJump, + canPrevious, + canNext, + onPageSizeChange, + className, + PreviousComponent = defaultButton, + NextComponent = defaultButton, + } = this.props; + + return ( + <div + className={classnames(className, '-pagination')} + style={this.props.paginationStyle}> + <div className="-previous"> + <PreviousComponent + onClick={e => { + if (!canPrevious) return; + this.changePage(page - 1) + }} + disabled={!canPrevious}> + {this.props.previousText} + </PreviousComponent> + </div> + <div className="-center"> + <span className="-pageInfo"> + {this.props.pageText}{' '} + {showPageJump + ? + <div className="-pageJump"> + <input + type={this.state.page === '' ? 'text' : 'number'} + onChange={e => { + const val = e.target.value; + this.changePage(val - 1); + }} + value={this.state.page === '' ? '' : this.state.page + 1} + onBlur={this.applyPage} + onKeyPress={e => { + if (e.which === 13 || e.keyCode === 13) { + this.applyPage(); + } + }} /> + </div> + : + <span className="-currentPage"> + {page + 1} + </span>}{' '} + {this.props.ofText}{' '} + <span className="-totalPages">{pages || 1}</span> + </span> + { showPageSizeOptions && + <span className="select-wrap -pageSizeOptions"> + <select + onChange={e => onPageSizeChange(Number(e.target.value))} + value={pageSize}> + { pageSizeOptions.map((option, i) => { + return ( + <option + key={i} + value={option}> + {option} {this.props.rowsText} + </option> + ); + })} + </select> + </span> + } + </div> + <div className="-next"> + <NextComponent + onClick={e => { + if (!canNext) return; + this.changePage(page + 1); + }} + disabled={!canNext}> + {this.props.nextText} + </NextComponent> + </div> + </div> + ) +}; + +export default PaginationRender; \ No newline at end of file diff --git a/react/src/components/dashboard/walletsData/walletsData.js b/react/src/components/dashboard/walletsData/walletsData.js index 841857d..43c0e1d 100644 --- a/react/src/components/dashboard/walletsData/walletsData.js +++ b/react/src/components/dashboard/walletsData/walletsData.js @@ -23,13 +23,17 @@ import { } from '../../../actions/actionCreators'; import Store from '../../../store'; import { - PaginationItemRender, - PaginationItemsPerPageSelectorRender, - PaginationRender, + AddressTypeRender, + TransactionDetailRender, + AddressRender, + AddressItemRender, + TxTypeRender, + TxAmountRender, TxHistoryListRender, AddressListRender, WalletsDataRender } from './walletsData.render'; +import { secondsToString } from '../../../util/time'; import { SocketProvider } from 'socket.io-react'; import io from 'socket.io-client'; @@ -41,18 +45,22 @@ class WalletsData extends React.Component { super(props); this.state = { basiliskActionsMenu: false, - itemsPerPage: 10, - activePage: 1, - itemsList: null, + itemsList: [], + filteredItemsList: [], currentAddress: null, addressSelectorOpen: false, currentStackLength: 0, totalStackLength: 0, useCache: true, + itemsListColumns: this.generateItemsListColumns(), + defaultPageSize: 10, + pageSize: 10, + showPagination: true, + searchTerm: null, coin: null, - txhistory: null, + txhistory: null }; - this.updateInput = this.updateInput.bind(this); + this.toggleBasiliskActionsMenu = this.toggleBasiliskActionsMenu.bind(this); this.basiliskRefreshAction = this.basiliskRefreshAction.bind(this); this.basiliskConnectionAction = this.basiliskConnectionAction.bind(this); @@ -94,6 +102,84 @@ class WalletsData extends React.Component { socket.removeAllListeners('messages'); } + generateItemsListColumns() { + let columns = []; + + if (this.isNativeMode()) { + columns.push({ + Header: translate('INDEX.TYPE'), + Footer: translate('INDEX.TYPE'), + className: 'colum--type', + headerClassName: 'colum--type', + footerClassName: 'colum--type', + Cell: AddressTypeRender() + }); + } + + columns.push(...[ + { + id: 'direction', + Header: translate('INDEX.DIRECTION'), + Footer: translate('INDEX.DIRECTION'), + className: 'colum--direction', + headerClassName: 'colum--direction', + footerClassName: 'colum--direction', + accessor: (tx) => TxTypeRender.call(this, tx.category || tx.type) + }, + { + Header: translate('INDEX.CONFIRMATIONS'), + Footer: translate('INDEX.CONFIRMATIONS'), + headerClassName: 'hidden-xs hidden-sm', + footerClassName: 'hidden-xs hidden-sm', + className: 'hidden-xs hidden-sm', + accessor: 'confirmations' + }, + { + id: 'amount', + Header: translate('INDEX.AMOUNT'), + Footer: translate('INDEX.AMOUNT'), + accessor: (tx) => TxAmountRender.call(this, tx) + }, + { + id: 'timestamp', + Header: translate('INDEX.TIME'), + Footer: translate('INDEX.TIME'), + accessor: (tx) => secondsToString(tx.blocktime || tx.timestamp || tx.time) + } + ]); + + if (this.isFullMode()) { + columns.push({ + Header: translate('INDEX.DEST_ADDRESS'), + Footer: translate('INDEX.DEST_ADDRESS'), + accessor: 'address' + }); + } + + if (this.isNativeMode()) { + columns.push({ + id: 'destination-address', + Header: translate('INDEX.DEST_ADDRESS'), + Footer: translate('INDEX.DEST_ADDRESS'), + accessor: (tx) => AddressRender.call(this, tx) + }); + } + + // const txDetailColumnCssClasses = this.isBasiliskMode() ? 'hidden-xs hidden-sm' : 'hidden-xs hidden-sm'; + + columns.push({ + id: 'tx-detail', + Header: translate('INDEX.TX_DETAIL'), + Footer: translate('INDEX.TX_DETAIL'), + className: 'colum--txinfo', + headerClassName: 'colum--txinfo', + footerClassName: 'colum--txinfo', + Cell: props => TransactionDetailRender.call(this, props.index) + }); + + return columns; + } + handleClickOutside(e) { if (e.srcElement.className !== 'btn dropdown-toggle btn-info' && (e.srcElement.offsetParent && e.srcElement.offsetParent.className !== 'btn dropdown-toggle btn-info') && @@ -240,17 +326,6 @@ class WalletsData extends React.Component { Store.dispatch(displayNotariesModal(true)); } - updateInput(e) { - let historyToSplit = sortByDate(this.props.ActiveCoin.txhistory, this.props.ActiveCoin.mode); - historyToSplit = historyToSplit.slice(0, e.target.value); - - this.setState({ - [e.target.name]: e.target.value, - activePage: 1, - itemsList: historyToSplit, - }); - } - toggleTxInfoModal(display, txIndex) { Store.dispatch(toggleDashboardTxInfoModal(display, txIndex)); } @@ -258,7 +333,7 @@ class WalletsData extends React.Component { indexTxHistory(txhistoryArr) { if (txhistoryArr.length > 1) { for (let i = 0; i < txhistoryArr.length; i++) { - this.props.ActiveCoin.txhistory[i]['index'] = i + 1; + this.props.ActiveCoin.txhistory[i].index = i + 1; } } @@ -266,151 +341,46 @@ class WalletsData extends React.Component { } componentWillReceiveProps(props) { - let historyToSplit; - let stateObj = {}; - - if (this.props && - this.props.ActiveCoin && - this.props.ActiveCoin.coin) { - if ((!this.state.currentAddress && this.props.ActiveCoin.activeAddress) || - (this.state.currentAddress !== this.props.ActiveCoin.activeAddress)) { - stateObj = Object.assign(stateObj, { - currentAddress: this.props.ActiveCoin.activeAddress, - }); - } - - if (this.props.ActiveCoin.txhistory && - this.props.ActiveCoin.txhistory !== 'loading' && - this.props.ActiveCoin.txhistory !== 'no data' && - this.props.ActiveCoin.txhistory.length) { - - historyToSplit = sortByDate(this.indexTxHistory(this.props.ActiveCoin.txhistory), this.props.ActiveCoin.mode === 'basilisk' ? 'index' : 'confirmations'); - historyToSplit = historyToSplit.slice( - (this.state.activePage - 1) * this.state.itemsPerPage, - this.state.activePage * this.state.itemsPerPage - ); - - if (!this.state.itemsList || (this.state.coin && this.state.coin !== this.props.ActiveCoin.coin) || ( - JSON.stringify(this.props.ActiveCoin.txhistory) !== JSON.stringify(this.state.txhistory))) { - - stateObj = Object.assign(stateObj, { - itemsList: historyToSplit, - txhistory: this.props.ActiveCoin.txhistory, - }); - } - } - - if (!historyToSplit && - this.props.ActiveCoin.txhistory && - this.props.ActiveCoin.txhistory === 'no data') { - stateObj = Object.assign(stateObj, { - itemsList: 'no data', - }); - } else if (!historyToSplit && this.props.ActiveCoin.txhistory && this.props.ActiveCoin.txhistory === 'loading') { - stateObj = Object.assign(stateObj, { - itemsList: 'loading', - }); - } - - stateObj = Object.assign(stateObj, { - coin: this.props.ActiveCoin.coin, - }); - if (Object.keys(stateObj).length) { - this.setState(Object.assign({}, this.state, stateObj)); - } - } - } - - updateCurrentPage(page) { - let historyToSplit = sortByDate(this.props.ActiveCoin.txhistory, this.props.ActiveCoin.mode); - historyToSplit = historyToSplit.slice( - (page - 1) * this.state.itemsPerPage, - page * this.state.itemsPerPage - ); - - this.setState(Object.assign({}, this.state, { - activePage: page, - itemsList: historyToSplit, - })); - } - - renderPaginationItems() { - let items = []; - - for (let i = 0; i < Math.ceil(this.props.ActiveCoin.txhistory.length / this.state.itemsPerPage); i++) { - items.push( - PaginationItemRender.call(this, i) - ); + if (!this.state.currentAddress && + this.props.ActiveCoin.activeAddress && + this.props.ActiveCoin.mode === 'basilisk') { + this.setState(Object.assign({}, this.state, { + currentAddress: this.props.ActiveCoin.activeAddress, + })); } - return items; - } - - renderPaginationItemsPerPageSelector() { if (this.props.ActiveCoin.txhistory && - this.state.itemsList !== 'loading' && - this.props.ActiveCoin.txhistory.length > 10) { - return PaginationItemsPerPageSelectorRender.call(this); - } else { - return null; + this.props.ActiveCoin.txhistory !== 'loading' && + this.props.ActiveCoin.txhistory !== 'no data' && + this.props.ActiveCoin.txhistory.length) { + if (!this.state.itemsList || + (this.state.coin && this.state.coin !== this.props.ActiveCoin.coin) || + (JSON.stringify(this.props.ActiveCoin.txhistory) !== JSON.stringify(this.state.txhistory))) { + const sortedItemsList = this.indexTxHistory(sortByDate(this.props.ActiveCoin.txhistory, this.props.ActiveCoin.mode === 'basilisk' ? 'index' : 'confirmations')); + + this.setState(Object.assign({}, this.state, { + itemsList: sortedItemsList, + filteredItemsList: this.filterTransactions(sortedItemsList, this.state.searchTerm), + txhistory: this.props.ActiveCoin.txhistory, + showPagination: this.props.ActiveCoin.txhistory && this.props.ActiveCoin.txhistory.length >= this.state.defaultPageSize + })); + } } - } - renderPagination() { if (this.props.ActiveCoin.txhistory && - this.state.itemsList !== 'loading' && - this.props.ActiveCoin.txhistory.length > 10) { - const _paginationFrom = ((this.state.activePage - 1) * this.state.itemsPerPage) + 1; - const _paginationTo = this.state.activePage * this.state.itemsPerPage; - - return PaginationRender.call( - this, - _paginationFrom, - _paginationTo - ); - } else { - return null; + this.props.ActiveCoin.txhistory === 'no data') { + this.setState(Object.assign({}, this.state, { + itemsList: 'no data', + })); + } else if (this.props.ActiveCoin.txhistory && this.props.ActiveCoin.txhistory === 'loading') { + this.setState(Object.assign({}, this.state, { + itemsList: 'loading', + })); } - } - renderTxType(category) { - if (category === 'send' || - category === 'sent') { - return ( - <span className="label label-danger"> - <i className="icon fa-arrow-circle-left"></i> <span>{ translate('DASHBOARD.OUT') }</span> - </span> - ); - } - if (category === 'receive' || - category === 'received') { - return ( - <span className="label label-success"> - <i className="icon fa-arrow-circle-right"></i> <span>{ translate('DASHBOARD.IN') }</span> - </span> - ); - } - if (category === 'generate') { - return ( - <span> - <i className="icon fa-cogs"></i> <span>{ translate('DASHBOARD.MINED') }</span> - </span> - ); - } - if (category === 'immature') { - return ( - <span> - <i className="icon fa-clock-o"></i> <span>{ translate('DASHBOARD.IMMATURE') }</span> - </span> - ); - } - if (category === 'unknown') { - return ( - <span> - <i className="icon fa-meh-o"></i> <span>{ translate('DASHBOARD.UNKNOWN') }</span> - </span> - ); - } + this.setState({ + itemsListColumns: this.generateItemsListColumns() + }); } isFullySynced() { @@ -427,40 +397,47 @@ class WalletsData extends React.Component { // TODO: add basilisk first run check, display no data if second run renderTxHistoryList() { - if (this.state.itemsList === 'loading') { - return ( - <tr className="hover--none"> - <td colSpan="7">{ translate('INDEX.LOADING_HISTORY') }...</td> - </tr> - ); + if (this.state.itemsList === 'loading' || + this.state.itemsList.length == 0) { + if (this.isFullySynced()) { + return ( + <tr className="hover--none"> + <td colSpan="7">{ translate('INDEX.LOADING_HISTORY') }...</td> + </tr> + ); + } else { + return ( + <tr className="hover--none"> + <td colSpan="7">Synchronization is in progress...</td> + </tr> + ); + } } else if (this.state.itemsList === 'no data') { return ( <tr className="hover--none"> <td colSpan="7">{ translate('INDEX.NO_DATA') }</td> </tr> ); - } else { - if (this.state.itemsList && - this.state.itemsList.length && - this.state.itemsList !== 'no data') { - return this.state.itemsList.map((tx, index) => - TxHistoryListRender.call( - this, - tx, - index - ) - ); - } + } else if (this.state.itemsList) { + return TxHistoryListRender.call(this); } + + return null; } - updateAddressSelection(address, type, amount) { + onPageSizeChange(pageSize, pageIndex) { + this.setState(Object.assign({}, this.state, { + pageSize: pageSize, + showPagination: this.state.itemsList && this.state.itemsList.length >= defaultPageSize, + })) + } + + updateAddressSelection(address) { Store.dispatch(changeActiveAddress(address)); this.setState(Object.assign({}, this.state, { currentAddress: address, addressSelectorOpen: false, - activePage: 1, })); if (this.props.ActiveCoin.mode === 'basilisk') { @@ -490,31 +467,19 @@ class WalletsData extends React.Component { })); } - renderAddress(tx) { - if (!tx.address) { - return ( - <span> - <i className="icon fa-bullseye"></i> <span className="label label-dark">{ translate('DASHBOARD.ZADDR_NOT_LISTED') }</span> - </span> - ); - } - - return tx.address; - } - renderAddressByType(type) { const _addresses = this.props.ActiveCoin.addresses; + const _coin = this.props.ActiveCoin.coin; if (_addresses && _addresses[type] && _addresses[type].length) { let items = []; const _cache = this.props.ActiveCoin.cache; - const _coin = this.props.ActiveCoin.coin; for (let i = 0; i < _addresses[type].length; i++) { const address = _addresses[type][i].address; - let _amount = address.amount; + let _amount = _addresses[type][i].amount; if (this.props.ActiveCoin.mode === 'basilisk') { _amount = _cache && _cache[_coin] && _cache[_coin][address] && _cache[_coin][address].getbalance && _cache[_coin][address].getbalance.data && _cache[_coin][address].getbalance.data.balance ? _cache[_coin][address].getbalance.data.balance : 'N/A'; @@ -525,32 +490,28 @@ class WalletsData extends React.Component { } items.push( - <li - key={address} - className={ address === this.state.currentAddress ? 'selected' : '' }> - <a onClick={ () => this.updateAddressSelection(address, type, _amount) }> - <i className={ 'icon fa-eye' + (type === 'public' ? '' : '-slash') }></i> - <span className="text">[ { _amount } { _coin } ] { address }</span> - <span className="glyphicon glyphicon-ok check-mark"></span> - </a> - </li> + AddressItemRender.call(this, address, type, _amount, _coin) ); } return items; - } else { - return null; + } else if (this.props.Dashboard.activeHandle[this.props.ActiveCoin.coin] && this.props.ActiveCoin.mode === 'basilisk') { + const address = this.props.Dashboard.activeHandle[this.props.ActiveCoin.coin]; + + return AddressItemRender.call(this, address, type, null, _coin); } + + return null; } - hasPublicAdresses() { + hasPublicAddresses() { return this.props.ActiveCoin.addresses && this.props.ActiveCoin.addresses.public && this.props.ActiveCoin.addresses.public.length; } renderAddressAmount() { - if (this.hasPublicAdresses()) { + if (this.hasPublicAddresses()) { const _addresses = this.props.ActiveCoin.addresses; const _cache = this.props.ActiveCoin.cache; const _coin = this.props.ActiveCoin.coin; @@ -568,7 +529,13 @@ class WalletsData extends React.Component { return _amount; } else { const address = _addresses.public[i].address; - let _amount = _cache && _cache[_coin] && _cache[_coin][address] && _cache[_coin][address].getbalance.data && _cache[_coin][address].getbalance.data.balance ? _cache[_coin][address].getbalance.data.balance : 'N/A'; + let _amount; + + if (this.props.ActiveCoin.mode === 'basilisk') { + _amount = _cache && _cache[_coin] && _cache[_coin][address] && _cache[_coin][address].getbalance.data && _cache[_coin][address].getbalance.data.balance ? _cache[_coin][address].getbalance.data.balance : 'N/A'; + } else { + _amount = _addresses.public[i].amount; + } if (_amount !== 'N/A') { _amount = formatValue('round', _amount, -6); @@ -596,22 +563,54 @@ class WalletsData extends React.Component { ); } else { return ( - <span>- { translate('KMD_NATIVE.SELECT_ADDRESS') } -</span> + <span>Filter by address</span> ); } } - renderAddressList() { - if (this.props.Dashboard && + shouldDisplayAddressList() { + if (this.props.ActiveCoin.mode === 'basilisk') { + return this.props.Dashboard && this.props.Dashboard.activeHandle && - this.props.Dashboard.activeHandle[this.props.ActiveCoin.coin] && - this.props.ActiveCoin.mode === 'basilisk') { + this.props.Dashboard.activeHandle[this.props.ActiveCoin.coin]; + } + } + + renderAddressList() { + if (this.shouldDisplayAddressList()) { return AddressListRender.call(this); } else { return null; } } + onSearchTermChange(newSearchTerm) { + this.setState(Object.assign({}, this.state, { + searchTerm: newSearchTerm, + filteredItemsList: this.filterTransactions(this.state.itemsList, newSearchTerm) + })); + } + + filterTransactions(txList, searchTerm) { + return txList.filter(tx => this.filterTransaction(tx, searchTerm)); + } + + filterTransaction(tx, term) { + if (!term) { + return true; + } + + return this.contains(tx.address, term) + || this.contains(tx.confirmations, term) + || this.contains(tx.amount, term) + || this.contains(tx.type, term) + || this.contains(secondsToString(tx.blocktime || tx.timestamp || tx.time), term); + } + + contains(value, property) { + return (value + '').indexOf(property) !== -1; + } + isActiveCoinMode(coinMode) { return this.props.ActiveCoin.mode === coinMode; } diff --git a/react/src/components/dashboard/walletsData/walletsData.render.js b/react/src/components/dashboard/walletsData/walletsData.render.js index 97167ec..51f0f8a 100644 --- a/react/src/components/dashboard/walletsData/walletsData.render.js +++ b/react/src/components/dashboard/walletsData/walletsData.render.js @@ -4,109 +4,58 @@ import WalletsBasiliskRefresh from '../walletsBasiliskRefresh/walletsBasiliskRef import WalletsBasiliskConnection from '../walletsBasiliskConnection/walletsBasiliskConnection'; import WalletsNotariesList from '../walletsNotariesList/walletsNotariesList'; import WalletsCacheData from '../walletsCacheData/walletsCacheData'; -import { secondsToString } from '../../../util/time'; +import ReactTable from 'react-table'; +import TablePaginationRenderer from './pagination'; import { formatValue } from '../../../util/formatValue'; import Config from '../../../config'; -// TODO: clean basilisk dropdown menu - -export const PaginationItemRender = function(i) { +export const AddressTypeRender = function() { return ( - <li - key={ `${i}-pagination-link` } - className={ 'paginate_button' + (this.state.activePage === i + 1 ? ' active' : '') }> - <a - key={ `${i}-pagination` } - onClick={ this.state.activePage !== (i + 1) ? () => this.updateCurrentPage(i + 1) : null }>{ i + 1 }</a> - </li> + <span> + <span className="label label-default"> + <i className="icon fa-eye"></i> { translate('IAPI.PUBLIC_SM') } + </span> + </span> ); }; -export const PaginationItemsPerPageSelectorRender = function() { +export const TransactionDetailRender = function(transactionIndex) { return ( - <div className="dataTables_length"> - <label> - { translate('INDEX.SHOW') } - <select - name="itemsPerPage" - className="form-control input-sm" - onChange={ this.updateInput }> - <option value="10">10</option> - <option value="25">25</option> - <option value="50">50</option> - <option value="100">100</option> - </select> - { translate('INDEX.ENTRIES_SM') } - </label> - </div> + <button + type="button" + className="btn btn-xs white btn-info waves-effect waves-light btn-kmdtxid" + onClick={ () => this.toggleTxInfoModal(!this.props.ActiveCoin.showTransactionInfo, transactionIndex) }> + <i className="icon fa-search"></i> + </button> ); }; -export const PaginationRender = function(paginationFrom, paginationTo) { - const disableNextBtn = this.state.activePage >= Math.floor(this.props.ActiveCoin.txhistory.length / this.state.itemsPerPage); +export const AddressRender = function(tx) { + if (!tx.address) { + return ( + <span> + <i className="icon fa-bullseye"></i> + <span className="label label-dark"> + { translate('DASHBOARD.ZADDR_NOT_LISTED') } + </span> + </span> + ); + } - return ( - <div className="row unselectable padding-top-20"> - <div className="col-sm-5"> - <div className="dataTables_info"> - { translate('INDEX.SHOWING') } - { paginationFrom } - { translate('INDEX.TO_ALT') } - { paginationTo } - { translate('INDEX.OF') } - { this.props.ActiveCoin.txhistory.length } - { translate('INDEX.ENTRIES_SM') } - </div> - </div> - <div className="col-sm-7"> - <div className="dataTables_paginate paging_simple_numbers"> - <ul className="pagination"> - <li className={ 'paginate_button previous' + (this.state.activePage === 1 ? ' disabled' : '') }> - <a onClick={ () => this.updateCurrentPage(this.state.activePage - 1) }>{ translate('INDEX.PREVIOUS') }</a> - </li> - { this.renderPaginationItems() } - <li className={ 'paginate_button next' + (disableNextBtn ? ' disabled' : '') }> - <a onClick={ () => this.updateCurrentPage(this.state.activePage + 1) }>{ translate('INDEX.NEXT') }</a> - </li> - </ul> - </div> - </div> - </div> - ); + return tx.address; }; -export const TxHistoryListRender = function(tx, index) { +export const AddressItemRender = function(address, type, amount, coin) { return ( - <tr key={ tx.txid + tx.amount }> - { this.isNativeMode() ? - <td> - <span className="label label-default"> - <i className="icon fa-eye"></i> { translate('IAPI.PUBLIC_SM') } - </span> - </td> - : - null - } - <td>{ this.renderTxType(tx.category || tx.type) }</td> - <td>{ tx.confirmations }</td> - { Config.roundValues && - <td title={ tx.amount }>{ formatValue('round', tx.amount, -6) || translate('DASHBOARD.UNKNOWN') }</td> - } - { !Config.roundValues && - <td>{ tx.amount || translate('DASHBOARD.UNKNOWN') }</td> - } - <td>{ secondsToString(tx.blocktime || tx.timestamp || tx.time) }</td> - <td className={ this.isFullMode() ? '' : 'hide' }>{ tx.address }</td> - <td className={ this.isNativeMode() ? '' : 'hide' }>{ this.renderAddress(tx) }</td> - <td className={ this.isBasiliskMode() ? 'text-center' : '' }> - <button - type="button" - className="btn btn-xs white btn-info waves-effect waves-light btn-kmdtxid" - onClick={ () => this.toggleTxInfoModal(!this.props.ActiveCoin.showTransactionInfo, ((this.state.activePage - 1) * this.state.itemsPerPage) + index) }> - <i className="icon fa-search"></i> - </button> - </td> - </tr> + <li + key={address} + className={ address === this.state.currentAddress ? 'selected' : '' }> + <a onClick={ () => this.updateAddressSelection(address) }> + <i className={ 'icon fa-eye' + (type === 'public' ? '' : '-slash') }></i> + <span className="text">[ { amount } { coin } ] { address }</span> + <span className="glyphicon glyphicon-ok check-mark"></span> + </a> + </li> ); }; @@ -121,7 +70,7 @@ export const AddressListRender = function() { <button type="button" className="btn dropdown-toggle btn-info" - title={ `-${translate('KMD_NATIVE.SELECT_ADDRESS')}-` } + title={ `${translate('KMD_NATIVE.SELECT_ADDRESS')}` } onClick={ this.openDropMenu }> <span className="filter-option pull-left">{ this.renderSelectorCurrentLabel() } </span> <span className="bs-caret"> @@ -130,9 +79,17 @@ export const AddressListRender = function() { </button> <div className="dropdown-menu open"> <ul className="dropdown-menu inner"> - <li className="selected"> - <a><span className="text"> - { translate('KMD_NATIVE.SELECT_ADDRESS') } - </span></a> + <li className="no--hover"> + <a><span className="text">{ this.props.ActiveCoin.mode === 'basilisk' ? 'Filter by address' : translate('KMD_NATIVE.SELECT_ADDRESS') }</span></a> </li> + { this.props.ActiveCoin.mode === 'native' && + <li className={ !this.state.currentAddress ? 'selected' : '' }> + <a onClick={ () => this.updateAddressSelection('') }> + <span className="text">All</span> + <span className="glyphicon glyphicon-ok check-mark"></span> + </a> + </li> + } { this.renderAddressByType('public') } </ul> </div> @@ -143,6 +100,86 @@ export const AddressListRender = function() { } }; +export const TxTypeRender = function(category) { + if (category === 'send' || + category === 'sent') { + return ( + <span className="label label-danger"> + <i className="icon fa-arrow-circle-left"></i> <span>{ translate('DASHBOARD.OUT') }</span> + </span> + ); + } + if (category === 'receive' || + category === 'received') { + return ( + <span className="label label-success"> + <i className="icon fa-arrow-circle-right"></i> <span>{ translate('DASHBOARD.IN') } </span> + </span> + ); + } + if (category === 'generate') { + return ( + <span> + <i className="icon fa-cogs"></i> <span>{ translate('DASHBOARD.MINED') }</span> + </span> + ); + } + if (category === 'immature') { + return ( + <span> + <i className="icon fa-clock-o"></i> <span>{ translate('DASHBOARD.IMMATURE') }</span> + </span> + ); + } + if (category === 'unknown') { + return ( + <span> + <i className="icon fa-meh-o"></i> <span>{ translate('DASHBOARD.UNKNOWN') }</span> + </span> + ); + } +}; + +export const TxAmountRender = function(tx) { + let _amountNegative; + + if ((tx.category === 'send' || + tx.category === 'sent') || + (tx.type === 'send' || + tx.type === 'sent')) { + _amountNegative = -1; + } else { + _amountNegative = 1; + } + + if (Config.roundValues) { + return ( + <span title={ tx.amount * _amountNegative }>{ formatValue('round', tx.amount, -6) * _amountNegative || translate('DASHBOARD.UNKNOWN') }</span> + ); + } + + return ( + <span>{ tx.amount * _amountNegative || translate('DASHBOARD.UNKNOWN') }</span> + ); +}; + +export const TxHistoryListRender = function() { + return ( + <ReactTable + data={ this.state.filteredItemsList } + columns={ this.state.itemsListColumns } + minRows="0" + sortable={ true } + className="-striped -highlight" + PaginationComponent={ TablePaginationRenderer } + nextText={ translate('INDEX.NEXT_PAGE') } + previousText={ translate('INDEX.PREVIOUS_PAGE') } + showPaginationBottom={ this.state.showPagination } + pageSize={ this.pageSize } + onPageSizeChange={ (pageSize, pageIndex) => this.onPageSizeChange(pageSize, pageIndex) } /> + ); +}; + export const WalletsDataRender = function() { return ( <span> @@ -156,18 +193,20 @@ export const WalletsDataRender = function() { <div> <div className="col-xlg-12 col-lg-12 col-sm-12 col-xs-12"> <div className="panel"> + { this.props.ActiveCoin.mode === 'basilisk' && + <div className={ 'margin-bottom-3 basilisk-progress-bar ' + (this.state.currentStackLength === 1 || (this.state.currentStackLength === 0 && this.state.totalStackLength === 0) ? 'hide' : 'progress progress-sm') }> + <div + className="progress-bar progress-bar-striped active progress-bar-indicating progress-bar-success font-size-80-percent" + style={{ width: 100 - (this.state.currentStackLength * 100 / this.state.totalStackLength) + '%' }}> + { translate('SEND.PROCESSING_REQ') }: { this.state.currentStackLength } / { this.state.totalStackLength } + </div> + </div> + } <header className="panel-heading z-index-10"> - <i - className="icon fa-refresh manual-txhistory-refresh pointer" - onClick={ this.refreshTxHistory }></i> + <i + className={ 'icon fa-refresh manual-txhistory-refresh pointer' + (this.state.currentStackLength === 1 || (this.state.currentStackLength === 0 && this.state.totalStackLength === 0) ? '' : ' hide') } + onClick={ this.refreshTxHistory }></i> <div className={ 'panel-actions' + (this.props.ActiveCoin.mode === 'basilisk' ? '' : ' hide') }> - <div className={ 'margin-bottom-3 ' + (this.state.currentStackLength === 1 || (this.state.currentStackLength === 0 && this.state.totalStackLength === 0) ? 'hide' : 'progress progress-sm') }> - <div - className="progress-bar progress-bar-striped active progress-bar-indicating progress-bar-success font-size-80-percent" - style={{ width: 100 - (this.state.currentStackLength * 100 / this.state.totalStackLength) + '%' }}> - { translate('SEND.PROCESSING_REQ') }: { this.state.currentStackLength } / { this.state.totalStackLength } - </div> - </div> { !this.isNativeMode() ? <div className={ 'dropdown basilisk-actions' + (this.state.basiliskActionsMenu ? ' open' : '') } @@ -223,63 +262,22 @@ export const WalletsDataRender = function() { <h4 className="panel-title">{ translate('INDEX.TRANSACTION_HISTORY') }</h4> </header> <div className="panel-body"> - <div className="row"> - <div className="col-sm-8"> - { this.renderAddressList() } - </div> - </div> - <div className="row pagination-container"> - <div className="col-sm-6"> - { this.renderPaginationItemsPerPageSelector() } - </div> - <div className="col-sm-6"> - <div className="dataTables_filter"> - <label> - { translate('INDEX.SEARCH') }: <input type="search" className="form-control input-sm" disabled="true" /> - </label> + <div className="row padding-bottom-30 padding-top-10"> + { this.shouldDisplayAddressList() && + <div className="col-sm-8 no-padding-left"> + { this.renderAddressList() } </div> + } + <div className="col-sm-4 search-box"> + <input + className="form-control" + onChange={ e => this.onSearchTermChange(e.target.value) } + placeholder="Search" /> </div> </div> <div className="row"> - <table - className="table table-hover dataTable table-striped" - width="100%"> - <thead> - <tr> - { this.isNativeMode() ? - <th>{ translate('INDEX.TYPE') }</th> - : - null - } - <th>{ translate('INDEX.DIRECTION') }</th> - <th className="hidden-xs hidden-sm">{ translate('INDEX.CONFIRMATIONS') }</th> - <th>{ translate('INDEX.AMOUNT') }</th> - <th>{ translate('INDEX.TIME') }</th> - <th className={ this.isBasiliskMode() ? 'hide' : '' }>{ translate('INDEX.DEST_ADDRESS') }</th> - <th className={ this.isBasiliskMode() ? 'hidden-xs hidden-sm text-center' : 'hidden-xs hidden-sm' }>{ translate('INDEX.TX_DETAIL') }</th> - </tr> - </thead> - <tbody> - { this.renderTxHistoryList() } - </tbody> - <tfoot> - <tr> - { this.isNativeMode() ? - <th>{ translate('INDEX.TYPE') }</th> - : - null - } - <th>{ translate('INDEX.DIRECTION') }</th> - <th>{ translate('INDEX.CONFIRMATIONS') }</th> - <th>{ translate('INDEX.AMOUNT') }</th> - <th>{ translate('INDEX.TIME') }</th> - <th className={ this.isBasiliskMode() ? 'hide' : '' }>{ translate('INDEX.DEST_ADDRESS') }</th> - <th className={ this.isBasiliskMode() ? 'hidden-xs hidden-sm text-center' : '' }>{ translate('INDEX.TX_DETAIL') }</th> - </tr> - </tfoot> - </table> + { this.renderTxHistoryList() } </div> - { this.renderPagination() } </div> </div> </div> diff --git a/react/src/components/dashboard/walletsNative/walletsNative.render.js b/react/src/components/dashboard/walletsNative/walletsNative.render.js index e9202c2..deacd2f 100644 --- a/react/src/components/dashboard/walletsNative/walletsNative.render.js +++ b/react/src/components/dashboard/walletsNative/walletsNative.render.js @@ -14,7 +14,7 @@ const WalletsNativeRender = function() { id="easydex-header-div" className="background-color-white" style={ this.getCoinStyle('transparent') }> - <ol className={ (!this.state.nativeOnly ? 'breadcrumb breadcrumb--normal' : 'breadcrumb') + (this.props.ActiveCoin.coin === 'KMD' || this.props.ActiveCoin.coin === 'JUMBLR' || this.props.ActiveCoin.coin === 'MESH' || this.props.ActiveCoin.coin === 'MVP' ? ' coin-logo-wide' : '') + (this.state.nativeOnly ? ' native-coin-logo' : '') }> + <ol className={ 'coin-logo ' + (!this.state.nativeOnly ? 'breadcrumb breadcrumb--normal' : 'breadcrumb') + (this.props.ActiveCoin.coin === 'KMD' || this.props.ActiveCoin.coin === 'JUMBLR' || this.props.ActiveCoin.coin === 'MESH' || this.props.ActiveCoin.coin === 'MVP' ? ' coin-logo-wide' : '') + (this.state.nativeOnly ? ' native-coin-logo' : '') }> <li className="header-easydex-section"> { this.getCoinStyle('title') && <img src={ this.getCoinStyle('title') } /> diff --git a/react/src/components/dashboard/walletsNav/walletsNav.render.js b/react/src/components/dashboard/walletsNav/walletsNav.render.js index b17f82d..58e7cf1 100644 --- a/react/src/components/dashboard/walletsNav/walletsNav.render.js +++ b/react/src/components/dashboard/walletsNav/walletsNav.render.js @@ -27,7 +27,7 @@ export const WalletsNavWithWalletRender = function() { className={ 'page-header page-header-bordered header-easydex padding-bottom-' + (this.state.nativeOnly ? '40 page-header--native' : '20') } id="header-dashboard" style={{ marginBottom: this.props.ActiveCoin.mode === 'basilisk' ? '30px' : (this.state.nativeOnly ? '30px' : '0') }}> - <ol className={ this.state.nativeOnly ? 'hide' : 'breadcrumb' }> + <ol className={ this.state.nativeOnly ? 'hide' : 'breadcrumb' + (this.props.ActiveCoin.mode === 'basilisk' ? ' breadcrumb--basilisk' : ' breadcrumb--native') }> <strong>{ translate('INDEX.MY') } { this.props && this.props.ActiveCoin ? this.props.ActiveCoin.coin : '-' } { translate('INDEX.ADDRESS') }: </strong> { this.props && this.props.Dashboard && this.props.Dashboard.activeHandle ? this.props.Dashboard.activeHandle[this.props.ActiveCoin.coin] : '-' } <button diff --git a/react/src/components/overrides.scss b/react/src/components/overrides.scss index 6d1ea2f..11c0ee8 100644 --- a/react/src/components/overrides.scss +++ b/react/src/components/overrides.scss @@ -373,6 +373,9 @@ input:checked + .slider:before { text-align: center; } +.coin-logo.breadcrumb { + z-index: 100; +} .breadcrumb > li + li:before { display: none; } @@ -754,6 +757,10 @@ select{ } } +.toggle-filters:hover { + background-color: #f3f1f1; +} + /* jumblr */ .jumblr { p { @@ -892,4 +899,101 @@ select{ z-index: 100; } } +} + +.search-box { + float: right; + padding-right: 0; +} + +.no-padding-left { + padding-left: 0; +} + +.basilisk-progress-bar { + position: absolute; + width: 100%; +} + +.breadcrumb--basilisk, +.breadcrumb--native { + top: 0; +} + +.dropdown-menu { + .no--hover { + pointer-events: none; + } +} + +.ReactTable { + border: none; + + .pagination-bottom { + margin-top: 35px; + } + .rt-td { + text-align: center; + } + .rt-table { + border: 1px solid rgba(0, 0, 0, 0.1); + } + .rt-thead .rt-th, + .rt-thead .rt-td { + padding: 10px 5px; + } + .rt-tr.-odd div, + .rt-tr.-even div { + padding-top: 10px; + padding-bottom: 10px; + } + .-pagination, + .rt-thead, + .rt-tfoot { + border: none; + } + .rt-tfoot { + border-top: 1px solid rgba(0, 0, 0, 0.1); + } + .rt-thead { + border-bottom: 1px solid rgba(0, 0, 0, 0.1); + } + .colum--direction { + width: 40px !important; + flex: 40 0 auto !important; + padding-right: 10px; + } + .colum--txinfo { + width: 40px !important; + flex: 40 0 auto !important; + } + .colum--type { + width: 40px !important; + flex: 40 0 auto !important; + } + .-pagination { + .-pageJump { + margin-right: 5px; + margin-left: 5px; + } + .-btn { + color: #757575; + background-color: #efefef; + border: 1px solid #e0e0e0; + } + .-btn:hover { + color: #fff; + } + .-btn[disabled]:hover { + color: #757575; + } + } + .rt-noData { + top: 46px; + width: 100%; + text-align: center; + height: 98px; + padding: 38px; + background: rgba(255, 255, 255, 0.85); + } } \ No newline at end of file diff --git a/react/src/styles/index.scss b/react/src/styles/index.scss index 84c0948..b8589ce 100644 --- a/react/src/styles/index.scss +++ b/react/src/styles/index.scss @@ -33,4 +33,5 @@ @import '../components/addcoin/addcoin.scss'; @import '../components/dashboard/main/dashboard.scss'; @import '../components/login/login.scss'; -@import '../components/overrides.scss'; \ No newline at end of file +@import '../components/overrides.scss'; +@import '~react-table/react-table.css'; diff --git a/react/src/translate/en.js b/react/src/translate/en.js index 95af166..c3032d6 100644 --- a/react/src/translate/en.js +++ b/react/src/translate/en.js @@ -255,7 +255,9 @@ export const _lang = { 'QRCODE': 'Show QR code', 'SCAN_QR_CODE': 'Scan QR Code', 'SCAN_QRCODE_WEBCAM': 'Scan QR Code with webcam', - 'TOGGLE_ZERO_ADDRESSES': 'Toggle empty addresses' + 'TOGGLE_ZERO_ADDRESSES': 'Toggle empty addresses', + 'NEXT_PAGE': 'Next Page', + 'PREVIOUS_PAGE': 'Previous Page' }, 'ATOMIC': { 'RAW_OUTPUT': 'Raw Output',