diff --git a/package-lock.json b/package-lock.json
index 7be7848e..b3100fc4 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -139,6 +139,11 @@
"react-is": "^16.6.3"
}
},
+ "@types/clipboard": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/@types/clipboard/-/clipboard-2.0.1.tgz",
+ "integrity": "sha512-gJJX9Jjdt3bIAePQRRjYWG20dIhAgEqonguyHxXuqALxsoDsDLimihqrSg8fXgVTJ4KZCzkfglKtwsh/8dLfbA=="
+ },
"@types/history": {
"version": "4.7.2",
"resolved": "https://registry.npmjs.org/@types/history/-/history-4.7.2.tgz",
@@ -437,6 +442,14 @@
"integrity": "sha512-d3OEjQV4ROpoflsnUA8HozoIR504TFxNivYEUi6uwz0IYhBkTDXGuWlNdMtybRt3nqVx/L6XqMt0FxkXuWKZhw==",
"dev": true
},
+ "add-dom-event-listener": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/add-dom-event-listener/-/add-dom-event-listener-1.1.0.tgz",
+ "integrity": "sha512-WCxx1ixHT0GQU9hb0KI/mhgRQhnU+U3GvwY6ZvVjYq8rsihIGoaIOUbY0yMPBxLH5MDtr0kz3fisWGNcbWW7Jw==",
+ "requires": {
+ "object-assign": "4.x"
+ }
+ },
"ajv": {
"version": "6.9.1",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.9.1.tgz",
@@ -655,9 +668,9 @@
}
},
"aws-sdk": {
- "version": "2.418.0",
- "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.418.0.tgz",
- "integrity": "sha512-15aCtqqCsiyMW+CDwo6Fq3V5jDzpgb5//aPMosL+5FQnQu65t2GiLidcIPx4fWvsYpRiE/i4enz3a0Kqtt2acQ==",
+ "version": "2.448.0",
+ "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.448.0.tgz",
+ "integrity": "sha512-RMmdxP0VgI8eq7SehOHINULL6BL84wy9jOngQwJnxCPT/3/5jUuexKjzeFpdXTS4+dVToqj8q9THAbqzuXZ9dQ==",
"requires": {
"buffer": "4.9.1",
"events": "1.1.1",
@@ -1880,6 +1893,11 @@
"integrity": "sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY=",
"dev": true
},
+ "big-integer": {
+ "version": "1.6.43",
+ "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.43.tgz",
+ "integrity": "sha512-9dULc9jsKmXl0Aeunug8wbF+58n+hQoFjqClN7WeZwGLh0XJUWyJJ9Ee+Ep+Ql/J9fRsTVaeThp8MhiCCrY0Jg=="
+ },
"big.js": {
"version": "5.2.2",
"resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz",
@@ -1900,29 +1918,22 @@
"file-uri-to-path": "1.0.0"
}
},
- "bip32": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/bip32/-/bip32-1.0.2.tgz",
- "integrity": "sha512-kedLYj8yvYzND+EfzeoMSlGiN7ImiRBF/MClJSZPkMfcU+OQO7ZpL5L/Yg+TunebBZIHhunstiQF//KLKSF5rg==",
- "requires": {
- "bs58check": "^2.1.1",
- "create-hash": "^1.2.0",
- "create-hmac": "^1.1.7",
- "tiny-secp256k1": "^1.0.0",
- "typeforce": "^1.11.5",
- "wif": "^2.0.6"
- }
- },
"bip39": {
- "version": "2.5.0",
- "resolved": "https://registry.npmjs.org/bip39/-/bip39-2.5.0.tgz",
- "integrity": "sha512-xwIx/8JKoT2+IPJpFEfXoWdYwP7UVAoUxxLNfGCfVowaJE7yg1Y5B1BVPqlUNsBq5/nGwmFkwRJ8xDW4sX8OdA==",
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/bip39/-/bip39-3.0.1.tgz",
+ "integrity": "sha512-h1mxBCpocHoZ6eUWNwh13bSXCZYy/wknSAvs1se3XDOTeerHU3jA8E4PIoPr8YMY3kdDSCpM1HypJmDS+C7U2Q==",
"requires": {
+ "@types/node": "11.11.6",
"create-hash": "^1.1.0",
"pbkdf2": "^3.0.9",
- "randombytes": "^2.0.1",
- "safe-buffer": "^5.0.1",
- "unorm": "^1.3.3"
+ "randombytes": "^2.0.1"
+ },
+ "dependencies": {
+ "@types/node": {
+ "version": "11.11.6",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-11.11.6.tgz",
+ "integrity": "sha512-Exw4yUWMBXM3X+8oqzJNRqZSwUAaS4+7NdvHqQuFi/d+synz++xmX3QIf+BFqneW8N31R8Ky+sikfZUXq07ggQ=="
+ }
}
},
"bl": {
@@ -1948,7 +1959,8 @@
"bn.js": {
"version": "4.11.8",
"resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz",
- "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA=="
+ "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==",
+ "dev": true
},
"body-parser": {
"version": "1.18.3",
@@ -2045,7 +2057,8 @@
"brorand": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz",
- "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8="
+ "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=",
+ "dev": true
},
"browserify-aes": {
"version": "1.2.0",
@@ -2375,6 +2388,16 @@
}
}
},
+ "clipboard": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/clipboard/-/clipboard-2.0.4.tgz",
+ "integrity": "sha512-Vw26VSLRpJfBofiVaFb/I8PVfdI1OxKcYShe6fm0sP/DtmiWQNCjhM/okTvdCo0G+lMMm1rMYbk4IK4x1X+kgQ==",
+ "requires": {
+ "good-listener": "^1.2.2",
+ "select": "^1.1.2",
+ "tiny-emitter": "^2.0.0"
+ }
+ },
"cliui": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz",
@@ -2461,12 +2484,25 @@
"integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=",
"dev": true
},
+ "component-classes": {
+ "version": "1.2.6",
+ "resolved": "https://registry.npmjs.org/component-classes/-/component-classes-1.2.6.tgz",
+ "integrity": "sha1-xkI5TDYYpNiwuJGe/Mu9kw5c1pE=",
+ "requires": {
+ "component-indexof": "0.0.3"
+ }
+ },
"component-emitter": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz",
"integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=",
"dev": true
},
+ "component-indexof": {
+ "version": "0.0.3",
+ "resolved": "https://registry.npmjs.org/component-indexof/-/component-indexof-0.0.3.tgz",
+ "integrity": "sha1-EdCRMSI5648yyPJa6csAL/6NPCQ="
+ },
"compressible": {
"version": "2.0.16",
"resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.16.tgz",
@@ -2515,30 +2551,31 @@
"dev": true
},
"conseiljs": {
- "version": "0.2.1",
- "resolved": "https://registry.npmjs.org/conseiljs/-/conseiljs-0.2.1.tgz",
- "integrity": "sha512-vM5OufwGPsYxtfP94MlVM2gWpf1PU2gAPVpAzopq+XYKa4XeLwmTBLREQZyFatUvQ5Qa9faY3V1QJ2p7xskaQQ==",
+ "version": "git+https://github.com/Cryptonomic/ConseilJS.git#a39441ce0fbb7a3458e4271f75557ffb94892a2d",
+ "from": "git+https://github.com/Cryptonomic/ConseilJS.git#a39441ce0fbb7a3458e4271f75557ffb94892a2d",
"requires": {
"@ledgerhq/hw-transport": "4.24.0",
"@ledgerhq/hw-transport-node-hid": "4.24.0",
- "aws-sdk": "^2.417.0",
+ "aws-sdk": "^2.447.0",
"babel-runtime": "6.26.0",
- "base-n": "git://github.com/yourcodesucks/base-n.git",
+ "base-n": "git://github.com/yourcodesucks/base-n.git#9d983f475c7396fbdc2fcbbc35b4821f0deeaa25",
"basil-tezos-ledger": "0.0.1",
- "bip32": "^1.0.0",
- "bip39": "^2.5.0",
+ "big-integer": "^1.6.43",
+ "bip39": "^3.0.1",
"blakejs": "^1.1.0",
"bs58check": "^2.1.2",
"https": "^1.0.0",
"libsodium-wrappers-sumo": "0.7.4",
- "node-fetch": "^2.3.0",
+ "moo": "^0.5.0",
+ "nearley": "^2.16.0",
+ "node-fetch": "^2.5.0",
"zxcvbn": "^4.4.2"
},
"dependencies": {
"node-fetch": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.3.0.tgz",
- "integrity": "sha512-MOd8pV3fxENbryESLgVIeaGKrdl+uaYhCSSVkjeOb/31/njTpcis5aWfdqgNlHIrKOLRbMnfPINPOML2CIFeXA=="
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.5.0.tgz",
+ "integrity": "sha512-YuZKluhWGJwCcUu4RlZstdAxr8bFfOVHakc1mplwHkk8J+tqM1Y5yraYvIUpeX8aY7+crCwiELJq7Vl0o0LWXw=="
}
}
},
@@ -2702,6 +2739,15 @@
"randomfill": "^1.0.3"
}
},
+ "css-animation": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/css-animation/-/css-animation-1.5.0.tgz",
+ "integrity": "sha512-hWYoWiOZ7Vr20etzLh3kpWgtC454tW5vn4I6rLANDgpzNSkO7UfOqyCEeaoBSG9CYWQpRkFWTWbWW8o3uZrNLw==",
+ "requires": {
+ "babel-runtime": "6.x",
+ "component-classes": "^1.2.5"
+ }
+ },
"css-color-keywords": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/css-color-keywords/-/css-color-keywords-1.0.0.tgz",
@@ -2836,6 +2882,7 @@
"version": "2.6.9",
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dev": true,
"requires": {
"ms": "2.0.0"
}
@@ -2950,6 +2997,11 @@
"rimraf": "^2.2.8"
}
},
+ "delegate": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/delegate/-/delegate-3.2.0.tgz",
+ "integrity": "sha512-IofjkYBZaZivn0V8nnsMJGBr4jVLxHDheKSW88PyxS5QC4Vo9ZbZVvhzlSxY87fVq3STR6r+4cGepyHkcWOQSw=="
+ },
"delegates": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
@@ -3014,6 +3066,11 @@
"randombytes": "^2.0.0"
}
},
+ "discontinuous-range": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/discontinuous-range/-/discontinuous-range-1.0.0.tgz",
+ "integrity": "sha1-44Mx8IRLukm5qctxx3FYWqsbxlo="
+ },
"dns-equal": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz",
@@ -3039,6 +3096,11 @@
"buffer-indexof": "^1.0.0"
}
},
+ "dom-align": {
+ "version": "1.8.2",
+ "resolved": "https://registry.npmjs.org/dom-align/-/dom-align-1.8.2.tgz",
+ "integrity": "sha512-17vInOylbB7H4qua7QRsmQT05FFTZemO8BhnOPgF9BPqjAPDyQr/9V8fmJbn05vQ31m2gu3EJSSYN2u94szUZg=="
+ },
"dom-converter": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/dom-converter/-/dom-converter-0.2.0.tgz",
@@ -3133,6 +3195,7 @@
"version": "6.4.1",
"resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.4.1.tgz",
"integrity": "sha512-BsXLz5sqX8OHcsh7CqBMztyXARmGQ3LWPtGjJi6DiJHq5C/qvi9P3OqgswKSDftbu8+IoI/QDTAm2fFnQ9SZSQ==",
+ "dev": true,
"requires": {
"bn.js": "^4.4.0",
"brorand": "^1.0.1",
@@ -3806,8 +3869,7 @@
"ansi-regex": {
"version": "2.1.1",
"bundled": true,
- "dev": true,
- "optional": true
+ "dev": true
},
"aproba": {
"version": "1.2.0",
@@ -3828,14 +3890,12 @@
"balanced-match": {
"version": "1.0.0",
"bundled": true,
- "dev": true,
- "optional": true
+ "dev": true
},
"brace-expansion": {
"version": "1.1.11",
"bundled": true,
"dev": true,
- "optional": true,
"requires": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
@@ -3850,20 +3910,17 @@
"code-point-at": {
"version": "1.1.0",
"bundled": true,
- "dev": true,
- "optional": true
+ "dev": true
},
"concat-map": {
"version": "0.0.1",
"bundled": true,
- "dev": true,
- "optional": true
+ "dev": true
},
"console-control-strings": {
"version": "1.1.0",
"bundled": true,
- "dev": true,
- "optional": true
+ "dev": true
},
"core-util-is": {
"version": "1.0.2",
@@ -3980,8 +4037,7 @@
"inherits": {
"version": "2.0.3",
"bundled": true,
- "dev": true,
- "optional": true
+ "dev": true
},
"ini": {
"version": "1.3.5",
@@ -3993,7 +4049,6 @@
"version": "1.0.0",
"bundled": true,
"dev": true,
- "optional": true,
"requires": {
"number-is-nan": "^1.0.0"
}
@@ -4008,7 +4063,6 @@
"version": "3.0.4",
"bundled": true,
"dev": true,
- "optional": true,
"requires": {
"brace-expansion": "^1.1.7"
}
@@ -4016,14 +4070,12 @@
"minimist": {
"version": "0.0.8",
"bundled": true,
- "dev": true,
- "optional": true
+ "dev": true
},
"minipass": {
"version": "2.3.5",
"bundled": true,
"dev": true,
- "optional": true,
"requires": {
"safe-buffer": "^5.1.2",
"yallist": "^3.0.0"
@@ -4042,7 +4094,6 @@
"version": "0.5.1",
"bundled": true,
"dev": true,
- "optional": true,
"requires": {
"minimist": "0.0.8"
}
@@ -4123,8 +4174,7 @@
"number-is-nan": {
"version": "1.0.1",
"bundled": true,
- "dev": true,
- "optional": true
+ "dev": true
},
"object-assign": {
"version": "4.1.1",
@@ -4136,7 +4186,6 @@
"version": "1.4.0",
"bundled": true,
"dev": true,
- "optional": true,
"requires": {
"wrappy": "1"
}
@@ -4222,8 +4271,7 @@
"safe-buffer": {
"version": "5.1.2",
"bundled": true,
- "dev": true,
- "optional": true
+ "dev": true
},
"safer-buffer": {
"version": "2.1.2",
@@ -4259,7 +4307,6 @@
"version": "1.0.2",
"bundled": true,
"dev": true,
- "optional": true,
"requires": {
"code-point-at": "^1.0.0",
"is-fullwidth-code-point": "^1.0.0",
@@ -4279,7 +4326,6 @@
"version": "3.0.1",
"bundled": true,
"dev": true,
- "optional": true,
"requires": {
"ansi-regex": "^2.0.0"
}
@@ -4323,14 +4369,12 @@
"wrappy": {
"version": "1.0.2",
"bundled": true,
- "dev": true,
- "optional": true
+ "dev": true
},
"yallist": {
"version": "3.0.3",
"bundled": true,
- "dev": true,
- "optional": true
+ "dev": true
}
}
},
@@ -4478,6 +4522,14 @@
}
}
},
+ "good-listener": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/good-listener/-/good-listener-1.2.2.tgz",
+ "integrity": "sha1-1TswzfkxPf+33JoNR3CWqm0UXFA=",
+ "requires": {
+ "delegate": "^3.1.2"
+ }
+ },
"graceful-fs": {
"version": "4.1.15",
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz",
@@ -4569,6 +4621,7 @@
"version": "1.1.7",
"resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz",
"integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==",
+ "dev": true,
"requires": {
"inherits": "^2.0.3",
"minimalistic-assert": "^1.0.1"
@@ -4606,6 +4659,7 @@
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz",
"integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=",
+ "dev": true,
"requires": {
"hash.js": "^1.0.3",
"minimalistic-assert": "^1.0.0",
@@ -5377,6 +5431,11 @@
"css-vendor": "^0.3.8"
}
},
+ "keycode": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/keycode/-/keycode-2.2.0.tgz",
+ "integrity": "sha1-PQr1bce4uOXLqNCpfxByBO7CKwQ="
+ },
"killable": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/killable/-/killable-1.0.1.tgz",
@@ -5443,6 +5502,31 @@
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz",
"integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg=="
},
+ "lodash._getnative": {
+ "version": "3.9.1",
+ "resolved": "https://registry.npmjs.org/lodash._getnative/-/lodash._getnative-3.9.1.tgz",
+ "integrity": "sha1-VwvH3t5G1hzc3mh9ZdPuy6o6r/U="
+ },
+ "lodash.isarguments": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz",
+ "integrity": "sha1-L1c9hcaiQon/AGY7SRwdM4/zRYo="
+ },
+ "lodash.isarray": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/lodash.isarray/-/lodash.isarray-3.0.4.tgz",
+ "integrity": "sha1-eeTriMNqgSKvhvhEqpvNhRtfu1U="
+ },
+ "lodash.keys": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-3.1.2.tgz",
+ "integrity": "sha1-TbwEcrFWvlCgsoaFXRvQsMZWCYo=",
+ "requires": {
+ "lodash._getnative": "^3.0.0",
+ "lodash.isarguments": "^3.0.0",
+ "lodash.isarray": "^3.0.0"
+ }
+ },
"log-symbols": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz",
@@ -5674,12 +5758,14 @@
"minimalistic-assert": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz",
- "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A=="
+ "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==",
+ "dev": true
},
"minimalistic-crypto-utils": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz",
- "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo="
+ "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=",
+ "dev": true
},
"minimatch": {
"version": "3.0.4",
@@ -5782,6 +5868,19 @@
"resolved": "https://registry.npmjs.org/moment/-/moment-2.24.0.tgz",
"integrity": "sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg=="
},
+ "moment-timezone": {
+ "version": "0.5.25",
+ "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.25.tgz",
+ "integrity": "sha512-DgEaTyN/z0HFaVcVbSyVCUU6HeFdnNC3vE4c9cgu2dgMTvjBUBdBzWfasTBmAW45u5OIMeCJtU8yNjM22DHucw==",
+ "requires": {
+ "moment": ">= 2.9.0"
+ }
+ },
+ "moo": {
+ "version": "0.5.0",
+ "resolved": "https://registry.npmjs.org/moo/-/moo-0.5.0.tgz",
+ "integrity": "sha512-AMv6iqhTEd5vT/cQlH6cammKS5ekyHhyqTRKi5zKMWl1RTyFnQ3ohPSBNSm8ySe2wlxSKwDonr9D5ZT44mdO3g=="
+ },
"move-concurrently": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz",
@@ -5799,7 +5898,8 @@
"ms": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
- "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
+ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+ "dev": true
},
"multicast-dns": {
"version": "6.2.3",
@@ -5846,14 +5946,53 @@
"resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.1.tgz",
"integrity": "sha512-boQj1WFgQH3v4clhu3mTNfP+vOBxorDlE8EKiMjUlLG3C4qAESnn9AxIOkFgTR2c9LtzNjPrjS60cT27ZKBhaA=="
},
+ "nearley": {
+ "version": "2.16.0",
+ "resolved": "https://registry.npmjs.org/nearley/-/nearley-2.16.0.tgz",
+ "integrity": "sha512-Tr9XD3Vt/EujXbZBv6UAHYoLUSMQAxSsTnm9K3koXzjzNWY195NqALeyrzLZBKzAkL3gl92BcSogqrHjD8QuUg==",
+ "requires": {
+ "commander": "^2.19.0",
+ "moo": "^0.4.3",
+ "railroad-diagrams": "^1.0.0",
+ "randexp": "0.4.6",
+ "semver": "^5.4.1"
+ },
+ "dependencies": {
+ "commander": {
+ "version": "2.20.0",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.0.tgz",
+ "integrity": "sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ=="
+ },
+ "moo": {
+ "version": "0.4.3",
+ "resolved": "https://registry.npmjs.org/moo/-/moo-0.4.3.tgz",
+ "integrity": "sha512-gFD2xGCl8YFgGHsqJ9NKRVdwlioeW3mI1iqfLNYQOv0+6JRwG58Zk9DIGQgyIaffSYaO1xsKnMaYzzNr1KyIAw=="
+ }
+ }
+ },
"needle": {
- "version": "2.2.4",
- "resolved": "https://registry.npmjs.org/needle/-/needle-2.2.4.tgz",
- "integrity": "sha512-HyoqEb4wr/rsoaIDfTH2aVL9nWtQqba2/HvMv+++m8u0dz808MaagKILxtfeSN7QU7nvbQ79zk3vYOJp9zsNEA==",
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/needle/-/needle-2.3.1.tgz",
+ "integrity": "sha512-CaLXV3W8Vnbps8ZANqDGz7j4x7Yj1LW4TWF/TQuDfj7Cfx4nAPTvw98qgTevtto1oHDrh3pQkaODbqupXlsWTg==",
"requires": {
- "debug": "^2.1.2",
+ "debug": "^4.1.0",
"iconv-lite": "^0.4.4",
"sax": "^1.2.4"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
+ "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
+ "requires": {
+ "ms": "^2.1.1"
+ }
+ },
+ "ms": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
+ "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg=="
+ }
}
},
"negotiator": {
@@ -5890,9 +6029,9 @@
}
},
"node-abi": {
- "version": "2.7.1",
- "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-2.7.1.tgz",
- "integrity": "sha512-OV8Bq1OrPh6z+Y4dqwo05HqrRL9YNF7QVMRfq1/pguwKLG+q9UB/Lk0x5qXjO23JjJg+/jqCHSTaG1P3tfKfuw==",
+ "version": "2.8.0",
+ "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-2.8.0.tgz",
+ "integrity": "sha512-1/aa2clS0pue0HjckL62CsbhWWU35HARvBDXcJtYKbYR7LnIutmpxmXbuDMV9kEviD2lP/wACOgWmmwljghHyQ==",
"requires": {
"semver": "^5.4.1"
}
@@ -5913,13 +6052,20 @@
"dev": true
},
"node-hid": {
- "version": "0.7.7",
- "resolved": "https://registry.npmjs.org/node-hid/-/node-hid-0.7.7.tgz",
- "integrity": "sha512-s6x8dU9/9+yKyeNw5xvU9FvQ1QGazVrDIG08/bixxCVQw98jfeFyz51C0T9/0KzKAYMOXMtElYvPIKmtY7eizw==",
+ "version": "0.7.8",
+ "resolved": "https://registry.npmjs.org/node-hid/-/node-hid-0.7.8.tgz",
+ "integrity": "sha512-79Z9hw/pqIDp0kxvb353ivGgslo4i0hYQTcCqfRFxIJSO2gF9VtPla5uQY/9jTcDlON5O5YaqxbdH+8bs+m+1Q==",
"requires": {
- "bindings": "^1.4.0",
- "nan": "^2.12.1",
- "prebuild-install": "^5.2.4"
+ "bindings": "^1.5.0",
+ "nan": "^2.13.2",
+ "prebuild-install": "^5.3.0"
+ },
+ "dependencies": {
+ "nan": {
+ "version": "2.13.2",
+ "resolved": "https://registry.npmjs.org/nan/-/nan-2.13.2.tgz",
+ "integrity": "sha512-TghvYc72wlMGMVMluVo9WRJc0mB8KxxF/gZ4YYFy7V2ZQX9l7rgbPg7vjS9mt6U5HXODVFVI2bOduCzwOMv/lw=="
+ }
}
},
"node-libs-browser": {
@@ -6388,6 +6534,11 @@
"sha.js": "^2.4.8"
}
},
+ "performance-now": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
+ "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns="
+ },
"pify": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
@@ -6510,9 +6661,9 @@
"integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ=="
},
"prebuild-install": {
- "version": "5.2.4",
- "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-5.2.4.tgz",
- "integrity": "sha512-CG3JnpTZXdmr92GW4zbcba4jkDha6uHraJ7hW4Fn8j0mExxwOKK20hqho8ZuBDCKYCHYIkFM1P2jhtG+KpP4fg==",
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-5.3.0.tgz",
+ "integrity": "sha512-aaLVANlj4HgZweKttFNUVNRxDukytuIuxeK2boIMHjagNJCiVKWFsKF4tCE3ql3GbrD2tExPQ7/pwtEJcHNZeg==",
"requires": {
"detect-libc": "^1.0.3",
"expand-template": "^2.0.3",
@@ -6661,6 +6812,28 @@
"integrity": "sha512-w7fLxIRCRT7U8Qu53jQnJyPkYZIaR4n5151KMfcJlO/A9397Wxb1amJvROTK6TOnp7PfoAmg/qXiNHI+08jRfA==",
"dev": true
},
+ "raf": {
+ "version": "3.4.1",
+ "resolved": "https://registry.npmjs.org/raf/-/raf-3.4.1.tgz",
+ "integrity": "sha512-Sq4CW4QhwOHE8ucn6J34MqtZCeWFP2aQSmrlroYgqAV1PjStIhJXxYuTgUIfkEk7zTLjmIjLmU5q+fbD1NnOJA==",
+ "requires": {
+ "performance-now": "^2.1.0"
+ }
+ },
+ "railroad-diagrams": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/railroad-diagrams/-/railroad-diagrams-1.0.0.tgz",
+ "integrity": "sha1-635iZ1SN3t+4mcG5Dlc3RVnN234="
+ },
+ "randexp": {
+ "version": "0.4.6",
+ "resolved": "https://registry.npmjs.org/randexp/-/randexp-0.4.6.tgz",
+ "integrity": "sha512-80WNmd9DA0tmZrw9qQa62GPPWfuXJknrmVmLcxvq4uZBdYqb1wYoKTmnlGUchvVWe0XiLupYkBoXVOxz3C8DYQ==",
+ "requires": {
+ "discontinuous-range": "1.0.0",
+ "ret": "~0.1.10"
+ }
+ },
"randombytes": {
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.0.6.tgz",
@@ -6719,6 +6892,64 @@
"strip-json-comments": "~2.0.1"
}
},
+ "rc-align": {
+ "version": "2.4.5",
+ "resolved": "https://registry.npmjs.org/rc-align/-/rc-align-2.4.5.tgz",
+ "integrity": "sha512-nv9wYUYdfyfK+qskThf4BQUSIadeI/dCsfaMZfNEoxm9HwOIioQ+LyqmMK6jWHAZQgOzMLaqawhuBXlF63vgjw==",
+ "requires": {
+ "babel-runtime": "^6.26.0",
+ "dom-align": "^1.7.0",
+ "prop-types": "^15.5.8",
+ "rc-util": "^4.0.4"
+ }
+ },
+ "rc-animate": {
+ "version": "2.8.2",
+ "resolved": "https://registry.npmjs.org/rc-animate/-/rc-animate-2.8.2.tgz",
+ "integrity": "sha512-JUKpst+OSDFQjqhhZliBcmO3Fie1SeiIxsEhS7PbZVz/UjCC8uDtp31+NRxidxy3BnfXbbfZdtG9mNWIDqIfTw==",
+ "requires": {
+ "babel-runtime": "6.x",
+ "classnames": "^2.2.6",
+ "css-animation": "^1.3.2",
+ "prop-types": "15.x",
+ "raf": "^3.4.0",
+ "react-lifecycles-compat": "^3.0.4"
+ }
+ },
+ "rc-tooltip": {
+ "version": "3.7.3",
+ "resolved": "https://registry.npmjs.org/rc-tooltip/-/rc-tooltip-3.7.3.tgz",
+ "integrity": "sha512-dE2ibukxxkrde7wH9W8ozHKUO4aQnPZ6qBHtrTH9LoO836PjDdiaWO73fgPB05VfJs9FbZdmGPVEbXCeOP99Ww==",
+ "requires": {
+ "babel-runtime": "6.x",
+ "prop-types": "^15.5.8",
+ "rc-trigger": "^2.2.2"
+ }
+ },
+ "rc-trigger": {
+ "version": "2.6.2",
+ "resolved": "https://registry.npmjs.org/rc-trigger/-/rc-trigger-2.6.2.tgz",
+ "integrity": "sha512-op4xCu95/gdHVaysyxxiYxbY+Z+UcIBSUY9nQfLqm1FlitdtnAN+owD5iMPfnnsRXntgcQ5+RdYKNUFQT5DjzA==",
+ "requires": {
+ "babel-runtime": "6.x",
+ "classnames": "^2.2.6",
+ "prop-types": "15.x",
+ "rc-align": "^2.4.0",
+ "rc-animate": "2.x",
+ "rc-util": "^4.4.0"
+ }
+ },
+ "rc-util": {
+ "version": "4.6.0",
+ "resolved": "https://registry.npmjs.org/rc-util/-/rc-util-4.6.0.tgz",
+ "integrity": "sha512-rbgrzm1/i8mgfwOI4t1CwWK7wGe+OwX+dNa7PVMgxZYPBADGh86eD4OcJO1UKGeajIMDUUKMluaZxvgraQIOmw==",
+ "requires": {
+ "add-dom-event-listener": "^1.1.0",
+ "babel-runtime": "6.x",
+ "prop-types": "^15.5.10",
+ "shallowequal": "^0.2.2"
+ }
+ },
"react": {
"version": "16.8.5",
"resolved": "https://registry.npmjs.org/react/-/react-16.8.5.tgz",
@@ -6730,6 +6961,16 @@
"scheduler": "^0.13.5"
}
},
+ "react-clipboard.js": {
+ "version": "2.0.7",
+ "resolved": "https://registry.npmjs.org/react-clipboard.js/-/react-clipboard.js-2.0.7.tgz",
+ "integrity": "sha512-KDjKTFL4Yumr6yq8/uM8+Ptk7m8YJLFRz1ie6u1hk8BC64ThTrzVqh3t6zJw11alEtwLvOgieF7YDm3JpxhZTQ==",
+ "requires": {
+ "@types/clipboard": "^2.0.1",
+ "clipboard": "^2.0.0",
+ "prop-types": "^15.5.0"
+ }
+ },
"react-dom": {
"version": "16.8.5",
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.8.5.tgz",
@@ -6761,6 +7002,11 @@
"resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz",
"integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA=="
},
+ "react-moment": {
+ "version": "0.9.2",
+ "resolved": "https://registry.npmjs.org/react-moment/-/react-moment-0.9.2.tgz",
+ "integrity": "sha512-jpKIEvcEOTSa4RXWTjDlvja7sN+ee5Gyk5ZKa704FZxE01OxmKIpq9GUliqTrAgdDYJJUQsnqQamczn0TN+DTg=="
+ },
"react-redux": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/react-redux/-/react-redux-5.1.1.tgz",
@@ -6814,6 +7060,71 @@
"resolved": "https://registry.npmjs.org/react-router-redux/-/react-router-redux-4.0.8.tgz",
"integrity": "sha1-InQDWWtRUeGCN32rg1tdRfD4BU4="
},
+ "react-swipeable-views": {
+ "version": "0.13.1",
+ "resolved": "https://registry.npmjs.org/react-swipeable-views/-/react-swipeable-views-0.13.1.tgz",
+ "integrity": "sha512-zZIRBD+HFO0P5z3TCkDMsSG/Sc3LXGGtojO+dEAGxsPvZjc3ji4Z/oOcLjZ4ozl0xIlLQJZ89o1rR82H/MDBHw==",
+ "requires": {
+ "@babel/runtime": "7.0.0",
+ "dom-helpers": "^3.2.1",
+ "prop-types": "^15.5.4",
+ "react-swipeable-views-core": "^0.13.1",
+ "react-swipeable-views-utils": "^0.13.1",
+ "warning": "^4.0.1"
+ },
+ "dependencies": {
+ "@babel/runtime": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.0.0.tgz",
+ "integrity": "sha512-7hGhzlcmg01CvH1EHdSPVXYX1aJ8KCEyz6I9xYIi/asDtzBPMyMhVibhM/K6g/5qnKBwjZtp10bNZIEFTRW1MA==",
+ "requires": {
+ "regenerator-runtime": "^0.12.0"
+ }
+ }
+ }
+ },
+ "react-swipeable-views-core": {
+ "version": "0.13.1",
+ "resolved": "https://registry.npmjs.org/react-swipeable-views-core/-/react-swipeable-views-core-0.13.1.tgz",
+ "integrity": "sha512-EP8sCvvD7VDiZLglPt9icMuMNu8qLRLk0ab/fB1HXv7lX8ClnwF3UMCM0ZrN3sguSY7CsX3LevducGGsT1VcDg==",
+ "requires": {
+ "@babel/runtime": "7.0.0",
+ "warning": "^4.0.1"
+ },
+ "dependencies": {
+ "@babel/runtime": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.0.0.tgz",
+ "integrity": "sha512-7hGhzlcmg01CvH1EHdSPVXYX1aJ8KCEyz6I9xYIi/asDtzBPMyMhVibhM/K6g/5qnKBwjZtp10bNZIEFTRW1MA==",
+ "requires": {
+ "regenerator-runtime": "^0.12.0"
+ }
+ }
+ }
+ },
+ "react-swipeable-views-utils": {
+ "version": "0.13.1",
+ "resolved": "https://registry.npmjs.org/react-swipeable-views-utils/-/react-swipeable-views-utils-0.13.1.tgz",
+ "integrity": "sha512-r5eyPIIHnlvILvFHXGnASDXa3RwC6X2YevegA2II5fhzYqwQRpJ81+lnzknNg5hiIN6ucXc5vrkqRRjabAhMpA==",
+ "requires": {
+ "@babel/runtime": "7.0.0",
+ "fbjs": "^0.8.4",
+ "keycode": "^2.1.7",
+ "prop-types": "^15.6.0",
+ "react-event-listener": "^0.6.0",
+ "react-swipeable-views-core": "^0.13.1"
+ },
+ "dependencies": {
+ "@babel/runtime": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.0.0.tgz",
+ "integrity": "sha512-7hGhzlcmg01CvH1EHdSPVXYX1aJ8KCEyz6I9xYIi/asDtzBPMyMhVibhM/K6g/5qnKBwjZtp10bNZIEFTRW1MA==",
+ "requires": {
+ "regenerator-runtime": "^0.12.0"
+ }
+ }
+ }
+ },
"react-transition-group": {
"version": "2.5.3",
"resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-2.5.3.tgz",
@@ -7063,8 +7374,7 @@
"ret": {
"version": "0.1.15",
"resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz",
- "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==",
- "dev": true
+ "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg=="
},
"rimraf": {
"version": "2.6.3",
@@ -7135,6 +7445,11 @@
"ajv-keywords": "^3.1.0"
}
},
+ "select": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/select/-/select-1.1.2.tgz",
+ "integrity": "sha1-DnNQrN7ICxEIUoeG7B1EGNEbOW0="
+ },
"select-hose": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz",
@@ -7265,6 +7580,14 @@
"safe-buffer": "^5.0.1"
}
},
+ "shallowequal": {
+ "version": "0.2.2",
+ "resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-0.2.2.tgz",
+ "integrity": "sha1-HjL9W8q2rWiKSBLLDMBO/HXHAU4=",
+ "requires": {
+ "lodash.keys": "^3.1.2"
+ }
+ },
"shebang-command": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",
@@ -7976,17 +8299,10 @@
"setimmediate": "^1.0.4"
}
},
- "tiny-secp256k1": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/tiny-secp256k1/-/tiny-secp256k1-1.0.1.tgz",
- "integrity": "sha512-Wz2kMPWtCI5XBftFeF3bUL8uz2+VlasniKwOkRPjvL7h1QVd9rbhrve/HWUu747kJKzVf1XHonzcdM4Ut8fvww==",
- "requires": {
- "bindings": "^1.3.0",
- "bn.js": "^4.11.8",
- "create-hmac": "^1.1.7",
- "elliptic": "^6.4.0",
- "nan": "^2.10.0"
- }
+ "tiny-emitter": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/tiny-emitter/-/tiny-emitter-2.1.0.tgz",
+ "integrity": "sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q=="
},
"to-arraybuffer": {
"version": "1.0.1",
@@ -8094,11 +8410,6 @@
"integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=",
"dev": true
},
- "typeforce": {
- "version": "1.18.0",
- "resolved": "https://registry.npmjs.org/typeforce/-/typeforce-1.18.0.tgz",
- "integrity": "sha512-7uc1O8h1M1g0rArakJdf0uLRSSgFcYexrVoKo+bzJd32gd4gDy2L/Z+8/FjPnU9ydY3pEnVPtr9FyscYY60K1g=="
- },
"typescript": {
"version": "3.3.4000",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-3.3.4000.tgz",
@@ -8180,11 +8491,6 @@
"imurmurhash": "^0.1.4"
}
},
- "unorm": {
- "version": "1.5.0",
- "resolved": "https://registry.npmjs.org/unorm/-/unorm-1.5.0.tgz",
- "integrity": "sha512-sMfSWoiRaXXeDZSXC+YRZ23H4xchQpwxjpw1tmfR+kgbBCaOgln4NI0LXejJIhnBuKINrB3WRn+ZI8IWssirVw=="
- },
"unpipe": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
@@ -8801,14 +9107,6 @@
"string-width": "^1.0.2 || 2"
}
},
- "wif": {
- "version": "2.0.6",
- "resolved": "https://registry.npmjs.org/wif/-/wif-2.0.6.tgz",
- "integrity": "sha1-CNP1IFbGZnkplyb63g1DKudLRwQ=",
- "requires": {
- "bs58check": "<3.0.0"
- }
- },
"worker-farm": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.6.0.tgz",
diff --git a/package.json b/package.json
index 9a400155..1f7cc727 100755
--- a/package.json
+++ b/package.json
@@ -46,13 +46,18 @@
"dependencies": {
"@material-ui/core": "^3.8.3",
"@material-ui/icons": "^3.0.1",
- "conseiljs": "^0.2.1",
+ "conseiljs": "git+https://github.com/Cryptonomic/ConseilJS.git#a39441ce0fbb7a3458e4271f75557ffb94892a2d",
"moment": "^2.23.0",
+ "moment-timezone": "^0.5.25",
+ "rc-tooltip": "^3.7.3",
"react": "^16.8.5",
+ "react-clipboard.js": "^2.0.7",
"react-dom": "^16.8.5",
+ "react-moment": "^0.9.2",
"react-redux": "^5.0.7",
"react-router-dom": "^4.2.2",
"react-router-redux": "^4.0.8",
+ "react-swipeable-views": "^0.13.1",
"redux": "^4.0.0",
"redux-devtools-extension": "^2.13.7",
"redux-thunk": "^2.3.0",
diff --git a/resources/fonts/ArronaxIcons/arronax.eot b/resources/fonts/ArronaxIcons/arronax.eot
new file mode 100755
index 00000000..32e9592f
Binary files /dev/null and b/resources/fonts/ArronaxIcons/arronax.eot differ
diff --git a/resources/fonts/ArronaxIcons/arronax.svg b/resources/fonts/ArronaxIcons/arronax.svg
new file mode 100755
index 00000000..0c28d703
--- /dev/null
+++ b/resources/fonts/ArronaxIcons/arronax.svg
@@ -0,0 +1,28 @@
+
+
+
\ No newline at end of file
diff --git a/resources/fonts/ArronaxIcons/arronax.ttf b/resources/fonts/ArronaxIcons/arronax.ttf
new file mode 100755
index 00000000..cd9824d5
Binary files /dev/null and b/resources/fonts/ArronaxIcons/arronax.ttf differ
diff --git a/resources/fonts/ArronaxIcons/arronax.woff b/resources/fonts/ArronaxIcons/arronax.woff
new file mode 100755
index 00000000..77c59a1c
Binary files /dev/null and b/resources/fonts/ArronaxIcons/arronax.woff differ
diff --git a/resources/fonts/TezosIcons/Tezos-icons.eot b/resources/fonts/TezosIcons/Tezos-icons.eot
deleted file mode 100755
index ff9a5f66..00000000
Binary files a/resources/fonts/TezosIcons/Tezos-icons.eot and /dev/null differ
diff --git a/resources/fonts/TezosIcons/Tezos-icons.svg b/resources/fonts/TezosIcons/Tezos-icons.svg
deleted file mode 100755
index 0bcab169..00000000
--- a/resources/fonts/TezosIcons/Tezos-icons.svg
+++ /dev/null
@@ -1,34 +0,0 @@
-
-
-
\ No newline at end of file
diff --git a/resources/fonts/TezosIcons/Tezos-icons.ttf b/resources/fonts/TezosIcons/Tezos-icons.ttf
deleted file mode 100755
index e469a087..00000000
Binary files a/resources/fonts/TezosIcons/Tezos-icons.ttf and /dev/null differ
diff --git a/resources/fonts/TezosIcons/Tezos-icons.woff b/resources/fonts/TezosIcons/Tezos-icons.woff
deleted file mode 100755
index 0572d00d..00000000
Binary files a/resources/fonts/TezosIcons/Tezos-icons.woff and /dev/null differ
diff --git a/src/assets/sadOctopus.svg b/src/assets/sadOctopus.svg
new file mode 100644
index 00000000..5a015da3
--- /dev/null
+++ b/src/assets/sadOctopus.svg
@@ -0,0 +1,20 @@
+
+
\ No newline at end of file
diff --git a/src/components/TezosIcon/index.tsx b/src/components/ArronaxIcon/index.tsx
similarity index 59%
rename from src/components/TezosIcon/index.tsx
rename to src/components/ArronaxIcon/index.tsx
index d17a722f..0a2f1fa3 100644
--- a/src/components/TezosIcon/index.tsx
+++ b/src/components/ArronaxIcon/index.tsx
@@ -2,7 +2,7 @@ import * as React from 'react';
import styled from 'styled-components';
const Icon = styled.span`
- font-family: 'Tezos-icons' !important;
+ font-family: 'Arronax-icons' !important;
font-size: ${({ size }) => size};
color: ${({ color}) => color};
speak: none;
@@ -28,105 +28,67 @@ const getIconByName = iconName => {
const toUnicode = unicode => String.fromCharCode(parseInt(unicode, 16));
switch (iconName) {
- case 'icon-new-window': {
- return toUnicode('e916');
- }
- case 'icon-star': {
- return toUnicode('e910');
- }
- case 'icon-broadcast': {
- return toUnicode('e911');
- }
- case 'arrow-left': {
+ case 'icon-delete': {
return toUnicode('e900');
}
- case 'arrow-right': {
+ case 'icon-octopus-logo': {
+ return toUnicode('e901');
+ }
+ case 'icon-tz': {
return toUnicode('e902');
}
-
- case 'checkmark': {
+ case 'icon-sort-ascending': {
return toUnicode('e903');
}
-
- case 'checkmark-outline': {
+ case 'icon-sort-descending': {
return toUnicode('e904');
}
-
- case 'help': {
+ case 'icon-reorder': {
return toUnicode('e905');
}
-
- case 'manager': {
+ case 'icon-close': {
return toUnicode('e906');
}
-
- case 'smart-address': {
+ case 'icon-reset': {
return toUnicode('e907');
}
-
- case 'tezos': {
+ case 'icon-add': {
return toUnicode('e908');
}
-
- case 'warning': {
+ case 'icon-next': {
return toUnicode('e909');
}
-
- case 'logout': {
+ case 'icon-previous': {
return toUnicode('e90a');
}
-
- case 'settings': {
+ case 'icon-search-left': {
return toUnicode('e90b');
- }
-
- case 'checkmark2': {
+ }
+ case 'icon-search-right': {
+ return toUnicode('e90c');
+ }
+ case 'icon-down-caret': {
+ return toUnicode('e90d');
+ }
+ case 'icon-columns': {
return toUnicode('e90e');
}
-
- case 'send': {
+ case 'icon-filter': {
return toUnicode('e90f');
}
-
- case 'star': {
+ case 'icon-question': {
return toUnicode('e910');
}
-
- case 'broadcast': {
+ case 'icon-export': {
return toUnicode('e911');
}
-
- case 'view-show': {
- return toUnicode('e912');
- }
-
- case 'view-hide': {
- return toUnicode('e913');
- }
-
- case 'change': {
- return toUnicode('e914');
- }
-
- case 'receive': {
- return toUnicode('e915');
- }
-
- case 'new-window': {
- return toUnicode('e916');
- }
-
- case 'info': {
- return toUnicode('e917');
- }
-
default: {
console.error(`${iconName} No such icon in Tezos icons font`);
}
}
};
-const TezosIcon = (props: Props) => {
+const ArronaxIcon = (props: Props) => {
const { iconName, size, color, className, onClick } = props;
return (
@@ -135,4 +97,4 @@ const TezosIcon = (props: Props) => {
);
};
-export default TezosIcon;
+export default ArronaxIcon;
diff --git a/src/components/ColumnItem/index.tsx b/src/components/ColumnItem/index.tsx
new file mode 100755
index 00000000..df049c20
--- /dev/null
+++ b/src/components/ColumnItem/index.tsx
@@ -0,0 +1,61 @@
+import * as React from 'react';
+import styled from 'styled-components';
+import { withStyles } from '@material-ui/core/styles';
+import Checkbox from '@material-ui/core/Checkbox';
+import ArronaxIcon from '../ArronaxIcon';
+
+const Container = styled.div`
+ display: flex;
+ height: 51px;
+ width: 372px;
+ align-items: center;
+ padding: 0 28px 0 10px;
+ &:hover {
+ background: rgba(101, 200, 206, 0.13);
+ }
+`;
+
+const DraggableIcon = styled(ArronaxIcon)`
+ margin-left: auto;
+ opacity: 0.4;
+`;
+
+const styles = {
+ checkbox: {
+ '&$checked': {
+ color: '#56c2d9',
+ },
+ },
+ checked: {},
+};
+
+interface Props {
+ isChecked?: boolean;
+ name: string;
+ classes: any;
+ onClick: () => void;
+}
+
+const ColumnItem: React.StatelessComponent = (props) => {
+ const { isChecked, name, classes, onClick } = props;
+ return (
+
+
+ {name}
+ {/* {isChecked && } */}
+
+ );
+};
+
+ColumnItem.defaultProps = {
+ isChecked: false
+}
+
+export default withStyles(styles)(ColumnItem);
diff --git a/src/components/ColumnsDisplay/index.tsx b/src/components/ColumnsDisplay/index.tsx
deleted file mode 100644
index df125bd4..00000000
--- a/src/components/ColumnsDisplay/index.tsx
+++ /dev/null
@@ -1,360 +0,0 @@
-import * as React from 'react';
-import styled from 'styled-components';
-import { withStyles } from '@material-ui/core/styles';
-import Checkbox from '@material-ui/core/Checkbox';
-import ListItemText from '@material-ui/core/ListItemText';
-import Button from '@material-ui/core/Button';
-import Menu from '@material-ui/core/Menu';
-import MenuItem from '@material-ui/core/MenuItem';
-import DragIcon from '@material-ui/icons/DragHandle';
-import KeyboardArrowDown from '@material-ui/icons/KeyboardArrowDown';
-
-const Container = styled.div`
- display: flex;
- border: 1px solid #d8d8d8;
- border-radius: 5px;
- margin-right: 5px;
- margin-left: 5px;
-`;
-
-const ButtonShell = styled(Button)`
- position: relative;
- width: 140px;
- height: 52px;
- border: 1px solid #d8d8d8;
- border-radius: 5px;
- display: flex;
- align-items: center;
- justify-content: center;
- font-size: 18px;
- font-weight: 400 !important;
- cursor: pointer;
-`;
-
-const NestedTitle = styled.div`
- cursor: default;
- flex-shrink: 0;
- outline: none;
- margin-top: 15px;
- margin-bottom: 12px;
- margin-left: 31px;
- color: #9b9b9b;
- font-family: Roboto-Medium;
- font-size: 16px;
- font-weight: 500;
- height: 19px;
- letter-spacing: 0;
- width: 333px;
-`;
-
-const DraggableIcon = styled(DragIcon)`
- float: right;
- margin-left: 25px;
- color: #d8d8d8;
-`;
-
-const ButtonContainer = styled.span`
- flex-shrink: 0;
- display: flex;
- float: right;
- margin: 4px 20px 15px 10px !important;
-`;
-
-const ArrowIcon = styled(KeyboardArrowDown)`
- color: #56c2d9;
- margin-left: 7px;
-`;
-
-const MenuContainer = styled.div`
- height: 100%;
- display: flex;
- flex-direction: column;
- flex-wrap: nowrap;
-`;
-
-const MenuContents = styled.div`
- height: 390px;
- flex: 1;
- outline: none;
- overflow: auto;
- min-height: 1.25em;
- padding-top: 10px;
-`;
-
-const SubmitButton = styled(Button)`
- display: flex;
- background: #56c2d9 !important;
- border-radius: 5px 5px 5px 5px;
- height: 42px;
- width: 113px;
- color: #ffffff !important;
- font-family: Roboto-Bold;
- font-size: 20px;
- font-weight: bold;
- letter-spacing: 2.43px;
- text-align: center;
- width: 113px;
-`;
-const CancelButton = styled(Button)`
- display: flex;
- color: #56c2d9 !important;
- border-radius: 5px 5px 5px 5px;
- height: 42px;
- width: 113px;
- font-family: Roboto-Bold;
- font-size: 20px;
- font-weight: bold;
- letter-spacing: 2.43px;
- text-align: center;
- width: 113px;
- margin-right: 6px !important;
-`;
-
-const HR = styled.hr`
- border-color: #d8d8d8 !important;
- border-style: solid !important;
- margin-top: 0px;
- outline: none;
-`;
-
-const FadeOut = styled.span`
- position: absolute;
- width: 100%;
- height: 20px;
-`;
-
-const FadeTop = styled(FadeOut)`
- margin-top: -20px;
- background-image: linear-gradient(
- to top,
- rgba(255, 255, 255, 0.7) 0%,
- rgba(255, 255, 255, 1) 80%
- );
- z-index: 10;
-`;
-
-const FadeBottom = styled.div`
- overflow: visible;
- pointer-events: none;
- outline: none;
- position: absolute;
- width: 100%;
- margin-top: -55px;
- padding-top: 10px;
- height: 55px;
- background-image: linear-gradient(
- to bottom,
- rgba(255, 255, 255, 0) 0%,
- rgba(255, 255, 255, 0.8) 50%
- );
- z-index: 10;
-`;
-
-const styles = {
- menuItem: {
- '&&&': {
- backgroundColor: 'transparent',
- },
- },
- removeSelector: {
- '&&&': {
- cursor: 'default',
- },
- },
- checkbox: {
- '&$checked': {
- color: '#56c2d9',
- },
- },
- checked: {},
-};
-
-interface SelectedColumnsData {
- cardinality: null | number;
- dataType: string;
- displayName: string;
- entity: string;
- keyType: string;
- name: string;
-}
-
-type Props = {
- selectedColumns: any;
- selectedEntity: string;
- attributes: any;
- classes: any;
- submitValues: () => void;
- setColumns: (columns: object[]) => void;
-};
-
-type States = {
- selected: object[];
- anchorEl: boolean;
- fadeBottom: boolean;
-};
-
-class ColumnDisplay extends React.Component {
- state = {
- selected: [],
- anchorEl: null,
- fadeBottom: true,
- };
-
- componentDidMount() {
- const { selectedColumns, selectedEntity } = this.props;
- this.setState({
- selected: [...selectedColumns[selectedEntity]],
- });
- }
-
- componentDidUpdate(prevProps: Props) {
- const { selectedColumns, selectedEntity } = this.props;
- if (
- prevProps.selectedColumns[selectedEntity] !==
- selectedColumns[selectedEntity] ||
- selectedEntity !== prevProps.selectedEntity
- ) {
- this.setState({
- selected: [...selectedColumns[selectedEntity]],
- });
- }
- }
-
- handleSubmit = async event => {
- const { selected } = this.state;
- const { setColumns, submitValues } = this.props;
- event.preventDefault();
- await this.setState({ anchorEl: null });
- await setColumns(selected);
- await submitValues();
- };
-
- handleChange = (name: SelectedColumnsData) => event => {
- const { selected } = this.state;
- const positionInArray = selected.findIndex(
- selected => selected.name === name.name
- );
- if (positionInArray === -1 && selected.length <= 5) {
- this.setState({
- selected: [...selected, name],
- });
- } else if (positionInArray > -1 && selected.length <= 6) {
- selected.splice(positionInArray, 1);
- this.setState({
- selected: [...selected],
- });
- }
- };
-
- cancelChange = () => {
- const { selectedColumns, selectedEntity } = this.props;
- this.setState({
- selected: [...selectedColumns[selectedEntity]],
- anchorEl: null,
- });
- };
-
- handleClick = event => {
- this.setState({ anchorEl: event.currentTarget });
- };
-
- handleScroll = event => {
- const bottom =
- event.target.scrollHeight - event.target.scrollTop ===
- event.target.clientHeight;
- if (bottom) {
- this.setState({ fadeBottom: false });
- } else {
- this.setState({ fadeBottom: true });
- }
- };
-
- render() {
- const { selectedEntity, classes, attributes } = this.props;
- const { anchorEl, fadeBottom, selected } = this.state;
- let tab;
- switch (selectedEntity) {
- case 'blocks':
- tab = 'blocks';
- break;
- case 'operations':
- tab = 'operations';
- break;
- case 'accounts':
- tab = 'accounts';
- break;
- }
- const selectedName = selected.map(selected => {
- return selected.name;
- });
-
- return (
-
-
-
- Columns ({selected.length})
-
-
-
-
-
-
-
- );
- }
-}
-
-export default withStyles(styles)(ColumnDisplay);
diff --git a/src/components/ColumnsPanel/index.tsx b/src/components/ColumnsPanel/index.tsx
new file mode 100644
index 00000000..8d47793a
--- /dev/null
+++ b/src/components/ColumnsPanel/index.tsx
@@ -0,0 +1,207 @@
+import * as React from 'react';
+import { connect } from 'react-redux';
+import styled from 'styled-components';
+import ArronaxIcon from '../ArronaxIcon';
+import ColumnItem from '../ColumnItem';
+
+import {
+ getColumns,
+ getAttributes,
+ getEntity
+} from '../../reducers/app/selectors';
+import {
+ setColumnsAction
+} from '../../reducers/app/actions';
+import { resetColumns } from '../../reducers/app/thunks';
+
+const Container = styled.div`
+ width: ${({ count }) => count*372 + 'px' };
+ margin: auto;
+ max-width: 100%;
+`;
+
+const MainContainer = styled.div`
+ box-shadow: 0px 0px 4px 0px rgba(0, 0, 0, 0.05);
+ background-color: white;
+ max-width: 100%;
+ overflow-x: auto;
+`;
+
+const ColumnsContainer = styled.div`
+ display: flex;
+ flex-direction: column;
+ flex-wrap: wrap;
+ max-height: 510px;
+`;
+
+const HeaderTxt = styled.div`
+ color: #4a4a4a;
+ font-size: 20px;
+ margin-bottom: 14px;
+`;
+
+const Title = styled.div`
+ font-size: 16px;
+ line-height: 19px;
+ padding: 13px 25px;
+ color: rgb(155, 155, 155);
+ font-weight: 400;
+`;
+
+const RefreshIcon = styled(ArronaxIcon)`
+ margin-right: 12px;
+`;
+
+const ButtonContainer = styled.div`
+ display: flex;
+ padding: 25px;
+ justify-content: flex-end;
+`;
+
+const RunButton = styled.div`
+ cursor: pointer;
+ margin-left: 40px;
+ color: white;
+ background: #56c2d9;
+ border-radius: 9px;
+ font-size: 20px;
+ font-weight: 700;
+ height: 60px;
+ width: 158px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+`;
+
+const ResetButton = styled.div`
+ color: #56c2d9;
+ font-size: 20px;
+ font-weight: 700;
+ cursor: pointer;
+ display: flex;
+ align-items: center;
+`;
+
+type Props = {
+ selectedColumns: any[];
+ selectedEntity: string;
+ attributes: any;
+ onSubmit: () => void;
+ setColumns: (entity: string, columns: object[]) => void;
+ onResetColumns: () => void;
+};
+
+type States = {
+ selected: object[];
+};
+
+class ColumnsPanel extends React.Component {
+ state = {
+ selected: [],
+ prevPropsSelected: []
+ };
+
+ static getDerivedStateFromProps(props, state) {
+ if (props.selectedColumns !== state.prevPropsSelected) {
+ return {
+ prevPropsSelected: props.selectedColumns,
+ selected: props.selectedColumns
+ };
+ }
+ return null;
+ }
+
+ handleSubmit = async () => {
+ const { selected } = this.state;
+ const { selectedEntity, setColumns, onSubmit } = this.props;
+ await setColumns(selectedEntity, selected);
+ await onSubmit();
+ };
+
+ handleChange = (attribute) => {
+ const { selected } = this.state;
+ const positionInArray = selected.findIndex(
+ column => column.name === attribute.name
+ );
+ if (positionInArray === -1) {
+ this.setState({
+ selected: [...selected, attribute],
+ });
+ } else {
+ selected.splice(positionInArray, 1);
+ this.setState({
+ selected: [...selected],
+ });
+ }
+ };
+
+ cancelChange = () => {
+ const { onResetColumns } = this.props;
+ onResetColumns();
+ };
+
+ render() {
+ const { attributes } = this.props;
+ const { selected } = this.state;
+ const columnsCount = Math.ceil(attributes.length / 10);
+ return (
+
+ Columns
+
+ Select Columns to Display
+
+ {selected.map((attribute, index) => (
+ this.handleChange(attribute)}
+ />
+ ))}
+ {attributes.sort((a, b) => (a.displayName.toLowerCase() < b.displayName.toLowerCase()) ? -1 : 1).map((attribute, index) => {
+ const pos = selected.findIndex(item => item.name === attribute.name);
+ if (pos !== -1) {
+ return null;
+ }
+ return (
+ this.handleChange(attribute)}
+ />
+ );
+ })}
+
+
+
+
+
+ Reset
+
+
+ Apply
+
+
+
+ );
+ }
+}
+
+const mapStateToProps = state => ({
+ selectedColumns: getColumns(state),
+ attributes: getAttributes(state),
+ selectedEntity: getEntity(state),
+});
+
+const mapDispatchToProps = dispatch => ({
+ setColumns: (entity: string, columns: object[]) =>
+ dispatch(setColumnsAction(entity, columns)),
+ onResetColumns: () =>
+ dispatch(resetColumns())
+});
+
+export default connect(
+ mapStateToProps,
+ mapDispatchToProps
+)(ColumnsPanel);
+
diff --git a/src/components/CustomPaginator/index.tsx b/src/components/CustomPaginator/index.tsx
index 1e1c4310..3a0d8fa9 100755
--- a/src/components/CustomPaginator/index.tsx
+++ b/src/components/CustomPaginator/index.tsx
@@ -6,11 +6,15 @@ import MenuItem from '@material-ui/core/MenuItem';
import ArrowDropDown from '@material-ui/icons/KeyboardArrowDown';
import LeftChevronIcon from '@material-ui/icons/ChevronLeft';
import RightChevronIcon from '@material-ui/icons/ChevronRight';
+import IconButton from '@material-ui/core/IconButton';
+import Tooltip from 'rc-tooltip';
+import ArronaxIcon from '../ArronaxIcon';
+import 'rc-tooltip/assets/bootstrap_white.css';
const Container = styled.div`
position: absolute;
right: 30px;
- top: -50px;
+ top: 225px;
height: 52px;
display: flex;
align-items: center;
@@ -64,7 +68,14 @@ const MainTxtWrapper = styled.div`
color: #4a4a4a;
font-size: 16px;
letter-spacing: 1.95px;
- margin: 0 13px 0 2px;
+ margin: 0 5px 0 2px;
+`;
+
+const LimitTxt = styled.div`
+ color: #4a4a4a;
+ font-size: 16px;
+ letter-spacing: 1.95px;
+ margin: 0;
`;
const ButtonWrapper = styled.div`
@@ -79,6 +90,9 @@ const ButtonWrapper = styled.div`
cursor: ${({ isActive }) => (isActive ? 'pointer' : 'default')};
pointer-events: ${({ isActive }) => (isActive ? 'auto' : 'none')};
border-radius: ${({ isNext }) => (isNext ? '0 5px 5px 0' : '5px 0 0 5px')};
+ &:hover {
+ border-color: rgb(180, 231, 242);
+ }
`;
const LeftIconWrapper = styled(LeftChevronIcon)`
@@ -93,6 +107,26 @@ const RightIconWrapper = styled(RightChevronIcon)`
}
`;
+const TooltipButton = styled(IconButton)`
+ &&& {
+ padding: 5px;
+ margin-right: 14px;
+ }
+`;
+
+const TooltipContainer = styled.div`
+ width: 344px;
+ font-size: 16px;
+ line-height: 24px;
+ font-weight: 500;
+ color: rgb(155, 155, 155);
+ background: white;
+`;
+
+const ExportTxt = styled.span`
+ color: #56c2d9;
+`;
+
const getList = (pageCount, balance, rowsPerPage) => {
let items = [];
for (let i = 0; i < pageCount - 1; i++) {
@@ -121,15 +155,24 @@ const getList = (pageCount, balance, rowsPerPage) => {
return items;
};
+const getLimitTooltip = (onExportCsv) => {
+ return (
+
+ Queries on Arronax are limited to 5000 results. Export to CSV to get the full result set.
+
+ );
+}
+
interface Props {
rowsPerPage: number;
page: number;
totalNumber: number;
onChangePage(page: number): void;
+ onExportCsv: () => void;
}
const CustomPaginator: React.StatelessComponent = props => {
- const { page, totalNumber, onChangePage, rowsPerPage } = props;
+ const { page, totalNumber, onChangePage, rowsPerPage, onExportCsv } = props;
const pageCount = Math.ceil(totalNumber / rowsPerPage);
const balance = totalNumber % rowsPerPage;
return (
@@ -144,6 +187,23 @@ const CustomPaginator: React.StatelessComponent = props => {
of {totalNumber}
+ {totalNumber >= 5000 && (
+
+ limit
+
+
+
+
+
+
+ )}
onChangePage(page - 1)}
diff --git a/src/components/CustomTableRow/index.tsx b/src/components/CustomTableRow/index.tsx
index 2245b33c..35a33d48 100755
--- a/src/components/CustomTableRow/index.tsx
+++ b/src/components/CustomTableRow/index.tsx
@@ -1,9 +1,14 @@
import * as React from 'react';
-import * as moment from 'moment';
import styled from 'styled-components';
+import Moment from 'react-moment';
+import 'moment-timezone';
import TableCell from '@material-ui/core/TableCell';
import TableRow from '@material-ui/core/TableRow';
import Circle from '@material-ui/icons/FiberManualRecord';
+import ContentCopy from '@material-ui/icons/FileCopyOutlined';
+import Clipboard from 'react-clipboard.js';
+import { getShortColumn } from '../../utils/general';
+import { AttributeDefinition } from '../../types';
const TableRowWrapper = styled(TableRow)`
&&& {
@@ -14,11 +19,11 @@ const TableRowWrapper = styled(TableRow)`
`;
const StyledCircle1 = styled(Circle)`
- color: rgb(255, 155, 213);
+ color: ${({ newcolor }) => newcolor};
`;
const StyledCircle2 = styled(Circle)`
- color: rgb(215, 195, 113);
+ color: ${({ newcolor }) => newcolor};
margin-left: -4px;
margin-right: 7px;
`;
@@ -35,106 +40,125 @@ const StyledCell = styled(TableCell)`
const SpanContainer = styled.span`
display: flex;
+ align-items: center;
`;
-const ExplorerLink = styled.a`
- text-decoration: none;
- color: #10ade4;
+const CopyIcon = styled(ContentCopy)`
+ &&& {
+ color: #a6dfe2;
+ font-size: 20px;
+ }
+`;
+
+const ClipboardWrapper = styled(Clipboard)`
+ border: none;
+ background: transparent;
+ outline: none !important;
+ cursor: pointer;
`;
+
+const LinkDiv = styled.div`
+ color: #56c2d9;
+ cursor: pointer;
+ text-decoration: underline;
+`;
+
+const DefaultAttributeNames = [
+ 'predecessor',
+ 'hash',
+ 'block_id',
+ 'block_hash',
+ 'operation_group_hash',
+ 'delegate',
+ 'protocol',
+ 'context',
+ 'operations_hash',
+ 'signature'
+];
+
+const PrimaryKeyList = {
+ blocks: ['hash', 'level'],
+ accounts: ['account_id'],
+ operations: ['operation_group_hash']
+};
+
interface Props {
- entity: string;
item: any;
selectedColumns: any[];
network: string;
+ platform: string;
+ selectedEntity: string,
+ onClickPrimaryKey: (key, value) => void;
+}
+
+const formatValueForPrimary = (entity, name, shortValue, value, onClickPrimaryKey) => {
+ if (PrimaryKeyList[entity].includes(name)) {
+ return onClickPrimaryKey(name, value)}>{shortValue};
+ } else if (entity === 'accounts' && name === 'manager') { // TODO: resolve via metadata
+ return onClickPrimaryKey('account_id', value)}>{shortValue};
+ } else if (entity === 'blocks' && name === 'predecessor') { // TODO: resolve via metadata
+ return onClickPrimaryKey('hash', value)}>{shortValue};
+ }
+ return shortValue;
}
-export const displayType = (network, shortenedItem, item, name) => {
- if (name === 'account_id' || name === 'manager') {
+const formatValueForDisplay = (
+ platform: string,
+ network: string,
+ entity: string,
+ value: any,
+ attribute: AttributeDefinition,
+ onClickPrimaryKey: (key, value) => void
+) => {
+ const { name, dataFormat, dataType} = attribute;
+ if (dataType === 'Boolean') {
+ const svalue = value.toString();
+ return svalue.charAt(0).toUpperCase() + svalue.slice(1);
+ } else if (dataType === 'DateTime') {
+ if (!dataFormat) {
+ return value;
+ }
+ return (
+
+ {value}
+
+ )
+ } else if (name === 'account_id' || name === 'manager') {
+ let colors = Buffer.from(Buffer.from(value.substring(3, 6) + value.slice(-3), 'utf8').map(b => Math.floor((b - 48) * 255)/74)).toString('hex');
return (
-
-
-
- {shortenedItem[name]}
-
+
+
+ {formatValueForPrimary(entity, name, getShortColumn(value), value, onClickPrimaryKey)}
+
+
+
);
- } else if (
- name === 'predecessor' ||
- name === 'hash' ||
- name === 'block_id' ||
- name === 'block_hash' ||
- name === 'operation_group_hash' ||
- name === 'delegate'
- ) {
+ } else if (DefaultAttributeNames.includes(name)) {
return (
-
- {shortenedItem[name]}
-
+ {formatValueForPrimary(entity, name, getShortColumn(value), value, onClickPrimaryKey)}
+
+
+
);
- } else if (
- name === 'protocol' ||
- name === 'context' ||
- name === 'operations_hash' ||
- name === 'signature'
- ) {
- return shortenedItem[name];
} else {
- return item[name];
+ return formatValueForPrimary(entity, name, value, value, onClickPrimaryKey);
}
};
const CustomTableRow: React.StatelessComponent = props => {
- const { selectedColumns, item, network } = props;
- const shortenedItem = { ...item };
- let itemsArray = Object.keys(shortenedItem);
- itemsArray.forEach(hash => {
- if (item[hash] === null) {
- return;
- } else if (
- hash.toLowerCase().includes('hash') ||
- hash.toLowerCase().includes('predecessor') ||
- hash.toLowerCase().includes('account_id') ||
- hash.toLowerCase().includes('block_id') ||
- hash.toLowerCase() === 'manager' ||
- hash.toLowerCase().includes('protocol') ||
- hash.toLowerCase().includes('block_hash') ||
- hash.toLowerCase() === 'delegate' ||
- hash.toLowerCase().includes('operation_group_hash') ||
- hash.toLowerCase().includes('context') ||
- hash.toLowerCase().includes('signature')
- ) {
- const hashRepresentation = item[hash];
- const firstHalf = hashRepresentation.substring(0, 6);
- const secondHalf = hashRepresentation.substring(
- hashRepresentation.length - 6,
- hashRepresentation.length
- );
- const newHash = `${firstHalf}...${secondHalf}`;
- shortenedItem[hash] = newHash;
- }
- return shortenedItem[hash];
- });
+ const { selectedColumns, item, network, platform, selectedEntity, onClickPrimaryKey } = props;
return (
{selectedColumns.map((column, index) => {
return (
- {column.name === 'timestamp' ? (
- moment(item[column.name]).format('dd MM YYYY h:mm:ss a')
- ) : (
-
- {displayType(network, shortenedItem, item, column.name)}
-
- )}
+
+ {formatValueForDisplay(platform, network, selectedEntity, item[column.name], column, onClickPrimaryKey)}
+
);
})}
diff --git a/src/components/EntityModal/index.tsx b/src/components/EntityModal/index.tsx
new file mode 100755
index 00000000..be8a23ce
--- /dev/null
+++ b/src/components/EntityModal/index.tsx
@@ -0,0 +1,175 @@
+import * as React from 'react';
+import styled from 'styled-components';
+import Modal from '@material-ui/core/Modal';
+import CircularProgress from '@material-ui/core/CircularProgress';
+import Moment from 'react-moment';
+import 'moment-timezone';
+import ArronaxIcon from '../ArronaxIcon';
+
+const ModalWrapper = styled(Modal)``;
+
+const ScrollContainer = styled.div`
+ width: 100%;
+ height: 100%;
+ overflow-y: auto;
+ padding: 77px 0;
+`;
+
+const ModalContainer = styled.div`
+ background-color: #ffffff;
+ outline: none;
+ position: relative;
+ padding: 27px 30px 30px 30px;
+ margin: 0 auto;
+ width: 798px;
+ min-height: 100%;
+`;
+
+const ListContainer = styled.div`
+ width: 100%;
+`;
+
+const CloseIcon = styled(ArronaxIcon)`
+ cursor: pointer;
+ position: absolute;
+ top: 30px;
+ right: 30px;
+`;
+
+const ModalTitle = styled.div`
+ padding: 0 0 19px 0;
+ font-size: 24px;
+ line-height: 28px;
+ font-weight: 400;
+ color: #9b9b9b;
+`;
+
+const RowContainer = styled.div`
+ display: flex;
+ padding: 15px 0;
+ font-size: 16px;
+ line-height: 19px;
+ border-bottom: 1px solid #dcdcdc;
+ letter-spacing: 0.23px;
+ color: rgb(74, 74, 74);
+`;
+
+const TitleTxt = styled.div`
+ width: 198px;
+ font-weight: 400;
+`;
+
+const ContentTxt = styled.div`
+ font-weight: 300;
+ word-break: break-word;
+ flex: 1;
+`;
+
+const LoadingContainer = styled.div`
+ position: absolute;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ background-color: rgba(0, 0, 0, 0.3);
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ z-index: 100;
+`;
+
+export const ButtonContainer = styled.div`
+ display: flex;
+ padding: 15px;
+ justify-content: flex-end;
+`;
+
+export const CloseButton = styled.div`
+ color: #56c2d9;
+ font-size: 20px;
+ font-weight: 700;
+ cursor: pointer;
+ display: flex;
+ align-items: center;
+`;
+
+const TITLE = {
+ blocks: 'Block',
+ opperations: 'Operation',
+ accounts: 'Account'
+};
+
+type Props = {
+ selectedEntity: string,
+ open: boolean,
+ item: any;
+ attributes: any[];
+ isLoading: boolean,
+ onClose: () => void
+};
+
+class EntityModal extends React.Component {
+
+ onClickModal = (event) => {
+ event.stopPropagation();
+ }
+ render() {
+ const {
+ selectedEntity,
+ open,
+ item,
+ attributes,
+ isLoading,
+ onClose,
+ } = this.props;
+ return (
+
+
+ this.onClickModal(event)}>
+
+ {TITLE[selectedEntity]} Details
+ {!isLoading && (
+
+ {attributes.map((column, index) => {
+ const { displayName, dataType, dataFormat, name } = column;
+ let value = item[name];
+ if (!value) {
+ return null;
+ }
+ if (dataType === 'DateTime' && dataFormat) {
+ value = (
+
+ {value}
+
+ );
+ }
+ return (
+
+ {displayName}
+ {value}
+
+ );
+ })}
+
+
+ Close
+
+
+
+ )}
+ {isLoading && (
+
+
+
+ )}
+
+
+
+
+ );
+ }
+};
+
+export default EntityModal;
diff --git a/src/components/FilterItem/index.tsx b/src/components/FilterItem/index.tsx
deleted file mode 100755
index 12ea765e..00000000
--- a/src/components/FilterItem/index.tsx
+++ /dev/null
@@ -1,66 +0,0 @@
-import * as React from 'react';
-import styled from 'styled-components';
-import FormControl from '@material-ui/core/FormControl';
-import TextField from '@material-ui/core/TextField';
-import FormHelperText from '@material-ui/core/FormHelperText';
-
-const Container = styled(FormControl)`
- width: 100%;
-`;
-
-const TextFieldWrapper = styled(TextField)`
- &&& {
- font-size: 16px;
- font-weight: 300;
- margin: 0;
-
- input {
- padding: 10px;
- }
- }
-}`;
-const LabelWrapper = styled(FormHelperText)`
- &&& {
- color: rgba(0, 0, 0, 0.38);
- font-size: 14px;
- }
-}`;
-
-interface Props {
- label: string;
- value?: any;
- type: string;
- onChange: (value: string, type: string) => void;
-}
-
-const FilterItem: React.StatelessComponent = (props) => {
- const {value, label, type, onChange} = props;
- let realValue = '';
- if (type === 'limit') {
- realValue = value;
- } else {
- value.forEach((item, index) => {
- if (index === 0) {
- realValue = item;
- } else {
- realValue += ', ' + item;
- }
- })
- }
- return (
-
- {label}
- onChange(event.target.value, type)}
- />
-
- );
-};
-FilterItem.defaultProps = {
- value: []
-}
-
-export default FilterItem;
diff --git a/src/components/FilterPanel/index.tsx b/src/components/FilterPanel/index.tsx
index 811b207c..86534efa 100644
--- a/src/components/FilterPanel/index.tsx
+++ b/src/components/FilterPanel/index.tsx
@@ -1,91 +1,43 @@
import * as React from 'react';
import { connect } from 'react-redux';
-import styled from 'styled-components';
-import PlusIcon from '@material-ui/icons/Add';
-import DeleteIcon from '@material-ui/icons/DeleteOutline';
import IconButton from '@material-ui/core/IconButton';
+import { ConseilOperator } from 'conseiljs';
+import ArronaxIcon from 'components/ArronaxIcon';
import { fetchValues } from '../../reducers/app/thunks';
import {
getAvailableValues,
getSelectedFilters,
getOperators,
+ getAttributes,
+ getEntity
} from '../../reducers/app/selectors';
import {
- setSelectedValuesAction,
- removeValueAction,
addFilterAction,
removeFilterAction,
changeFilterAction,
+ removeAllFiltersAction
} from '../../reducers/app/actions';
import FilterSelect from '../FilterSelect';
import ValueSelect from '../ValueSelect';
import ValueInput from '../ValueInput';
+import { Filter } from '../../types';
-const Container = styled.div`
- width: 100%;
- background: #fbfbfb;
- border: 1px solid #ededed;
- border-radius: 3px;
-`;
-
-const FilterItemContainer = styled.div`
- display: flex;
- align-items: center;
- justify-content: space-between;
- padding: 18px 24px 0 30px;
-`;
-
-const FilterItemGr = styled.div`
- border-radius: 5px;
- border: 1px solid #ecedef;
- display: flex;
-`;
-
-const AddFilterFooter = styled.div`
- width: 100%;
- height: ${({ isFilters }) => (isFilters ? '67px' : '93px')};
- display: flex;
- align-items: center;
- padding-left: 24px;
- border-top: ${({ isFilters }) => (isFilters ? '1px solid #ECEDEF' : 'none')};
- margin-top: ${({ isFilters }) => (isFilters ? '18px' : '0')};
-`;
-
-const AddFilterButton = styled.div`
- color: #56c2d9;
- font-size: 18px;
- font-weight: bold;
- cursor: pointer;
- display: flex;
- align-items: center;
- opacity: ${({ isDisabled }) => (isDisabled ? 0.5 : 1)};
- pointer-events: ${({ isDisabled }) => (isDisabled ? 'none' : 'initial')};
-`;
-
-const PlusIconWrapper = styled(PlusIcon)`
- &&& {
- color: #56c2d9;
- font-size: 27px;
- }
-`;
-
-const DeleteIconWrapper = styled(DeleteIcon)`
- &&& {
- color: #d8d8d8;
- font-size: 37px;
- }
-`;
-
-const FilterExpTxt = styled.div`
- color: #9b9b9b;
- font-size: 18px;
- margin-left: 21px;
-`;
-
-const HR = styled.div`
- width: 1px;
- background-color: #ecedef;
-`;
+import {
+ Container,
+ HeaderTxt,
+ MainContainer,
+ FilterItemContainer,
+ FilterItemGr,
+ AddFilterFooter,
+ AddFilterButton,
+ PlusIconWrapper,
+ FilterExpTxt,
+ HR,
+ RefreshIcon,
+ ButtonContainer,
+ RunButton,
+ ResetButton
+} from './style';
const attrTabValue = {
blocks: 'block',
@@ -93,143 +45,102 @@ const attrTabValue = {
accounts: 'account',
};
-interface Filter {
- name: string;
- operator: string;
-}
+const CARDINALITY_NUMBER = 15;
type Props = {
- selectedValues: object[];
- availableValues: object[];
+ availableValues: object;
selectedEntity: string;
attributes: any[];
filters: Array;
operators: any;
- filterInputState: object;
- setFilterInputState: (
- value: string,
- filterName: string,
- filterOperator: string
- ) => void;
- removeValue: (value: object) => void;
- setSelectedValues: (value: object) => void;
+ swipeRef: any;
fetchValues: (value: string) => void;
addFilter: (entity: string) => void;
removeFilter: (entity: string, index: number) => void;
changeFilter: (entity: string, filter: object, index: number) => void;
+ removeAllFilters: (entity: string) => void;
+ onSubmit: () => void;
};
-type States = {
- value: string;
-};
-
-class FilterPanel extends React.Component {
- state = {
- value: '',
- };
-
- onAddFilter = () => {
- const { addFilter, selectedEntity } = this.props;
- addFilter(selectedEntity);
+class FilterPanel extends React.Component {
+ onAddFilter = async () => {
+ const { addFilter, selectedEntity, swipeRef } = this.props;
+ await addFilter(selectedEntity);
+ swipeRef.updateHeight();
};
- onRemoveFilter = (index, filter) => {
+ onRemoveFilter = (index) => {
const {
removeFilter,
selectedEntity,
- removeValue,
- selectedValues,
- filterInputState,
- setFilterInputState,
} = this.props;
- const itemToRemove = filterInputState[selectedEntity].find(
- value => Object.keys(value).toString() === filter.name
- );
- if (itemToRemove) {
- setFilterInputState(
- null,
- Object.keys(itemToRemove).toString(),
- filter.operator
- );
- }
- selectedValues.forEach(val => {
- const valueToRemove = Object.keys(val).toString();
- if (valueToRemove === filter.name) {
- removeValue(val);
- }
- });
removeFilter(selectedEntity, index);
};
- onFilterNameChange = (val, index) => {
+ onFilterNameChange = (attr, index) => {
const {
- filters,
selectedEntity,
changeFilter,
- attributes,
fetchValues,
+ availableValues,
+ operators
} = this.props;
- const cards = attributes.map(attr => {
- if (attr.cardinality < 15 && attr.cardinality !== null) {
- return attr.name;
- }
- });
- if (cards.includes(val)) {
- fetchValues(val);
+ const isLowCardinality = attr.cardinality < CARDINALITY_NUMBER && attr.cardinality !== null;
+ if (isLowCardinality && !availableValues[attr.name]) {
+ fetchValues(attr.name);
+ }
+ let operatorType = 'dateTime';
+ if (attr.dataType === 'Int' || attr.dataType === 'Decimal') {
+ operatorType = 'numeric';
+ } else if (attr.dataType === 'String') {
+ operatorType = 'string';
+ } else if (attr.dataType === 'Boolean') {
+ operatorType = 'boolean';
}
- const selectedFilter: any = filters[index];
- selectedFilter.name = val;
+ const selectedFilter = {
+ name: attr.name,
+ isLowCardinality,
+ operatorType,
+ operator: operators[operatorType][0].name,
+ values: ['']
+ };
changeFilter(selectedEntity, selectedFilter, index);
};
- onFilterOperatorChange = (val, index) => {
+ onFilterOperatorChange = (operator, index) => {
const {
filters,
selectedEntity,
changeFilter,
- filterInputState,
- setFilterInputState,
} = this.props;
- const selectedFilter: any = filters[index];
- const findInput = filterInputState[selectedEntity].find(
- filter => Object.keys(filter).toString() === selectedFilter.name
- );
- // Check to see if input value for this attribute is populated and clear if so
- if (findInput) {
- setFilterInputState(
- null,
- Object.keys(findInput).toString(),
- selectedFilter.operator
- );
- }
- selectedFilter.operator = val;
- changeFilter(selectedEntity, selectedFilter, index);
- };
- onFilterAttributeChange = (val, index) => {
- const { filters, selectedEntity, changeFilter } = this.props;
- const selectedFilter: any = filters[index];
- selectedFilter.attribute = val;
+ const selectedFilter = {
+ ...filters[index],
+ operator: operator.name,
+ values: ['']
+ };
changeFilter(selectedEntity, selectedFilter, index);
};
- onValueChange = val => {
- const { setSelectedValues } = this.props;
- setSelectedValues(val);
- };
+ onFilterValueChange = (value, index, pos) => {
+ const {
+ filters,
+ selectedEntity,
+ changeFilter
+ } = this.props;
- handleInputChange = (value, filter, filterOperator) => {
- const { setFilterInputState } = this.props;
- this.setState({ value: value });
- setFilterInputState(value, filter, filterOperator);
+ const selectedFilter: Filter = {...filters[index]};
+ selectedFilter.values[pos] = value;
+ changeFilter(selectedEntity, selectedFilter, index);
};
- handleBetweenInputChange = (value, filter, filterOperator) => {
- const { setFilterInputState } = this.props;
- this.setState({ value: value });
- const betweenValue = `-${value}`;
- setFilterInputState(betweenValue, filter, filterOperator);
+ onResetFilters = () => {
+ const {
+ removeAllFilters,
+ selectedEntity
+ } = this.props;
+ removeAllFilters(selectedEntity);
};
render() {
@@ -238,148 +149,112 @@ class FilterPanel extends React.Component {
attributes,
filters,
operators,
- selectedValues,
availableValues,
- filterInputState,
+ onSubmit
} = this.props;
- const { value } = this.state;
const entityName = attrTabValue[selectedEntity];
- const cards = [];
- attributes.forEach(attr => {
- if (attr.cardinality < 15 && attr.cardinality !== null) {
- cards.push(attr.name);
- }
- });
-
- const numericDataTypes = attributes.map(attr => {
- if (attr.dataType === 'Int' || attr.dataType === 'Decimal') {
- return attr.name;
- }
- });
- const stringDataTypes = attributes.map(attr => {
- if (attr.dataType === 'String') {
- return attr.name;
- }
- });
- const booleanDataTypes = attributes.map(attr => {
- if (attr.dataType === 'Boolean') {
- return attr.name;
- }
- });
- const disableAddFilter =
- (filters.length > 0 &&
- filters.length !==
- filterInputState[selectedEntity].length + selectedValues.length) ||
- (filters.length > 0 &&
- filters.length ===
- filterInputState[selectedEntity].length + selectedValues.length &&
- selectedValues.length !== filters.length &&
- value === '');
+ const filterLength = filters.length;
+ let disableAddFilter = true;
+ const lastFilter: any = filterLength > 0 ? filters[filterLength - 1] : {};
+ if (filterLength === 0) {
+ disableAddFilter = false;
+ } else if (lastFilter.operator === ConseilOperator.ISNULL || lastFilter.operator === 'isnotnull') {
+ disableAddFilter = false;
+ } else if(lastFilter.operator === ConseilOperator.BETWEEN || lastFilter.operator === ConseilOperator.IN) {
+ disableAddFilter = lastFilter.values.length !== 2;
+ } else if (lastFilter.values[0]) {
+ disableAddFilter = false;
+ }
return (
- {filters.map((filter: any, index) => {
- let newAttributes = [];
- attributes.forEach((attr: any) => {
- if (attr.name === filter.name) {
- newAttributes.push(attr);
- }
- const index = filters.findIndex(
- (item: any) => item.name === attr.name
- );
- if (index < 0) {
- newAttributes.push(attr);
- }
- });
- return (
-
-
- this.onFilterNameChange(val, index)}
- />
- {filter.name &&
}
- {filter.name && (
+ Filter
+
+ {filters.map((filter: Filter, index) => {
+ const newAttributes = attributes.filter((attr: any) => {
+ if (attr.name === filter.name) {
+ return true;
+ }
+ const pos = filters.findIndex(
+ (item: any) => item.name === attr.name
+ );
+ return pos === -1;
+ });
+
+ return (
+
+
- this.onFilterOperatorChange(event, index)
- }
+ value={filter.name}
+ placeholder={`Select ${entityName} Attribute`}
+ items={newAttributes}
+ onChange={attr => this.onFilterNameChange(attr, index)}
/>
- )}
- {filter.operator &&
}
- {(filter.operator && filter.operator === 'EQ') ||
- (filter.operator === 'NOTEQ' &&
- cards.includes(filter.name) && (
+ {filter.name &&
}
+ {filter.name && (
+
+ this.onFilterOperatorChange(operator, index)
+ }
+ />
+ )}
+ {filter.operator &&
}
+ {filter.operator && (filter.operator === ConseilOperator.EQ || filter.operator === 'noteq') &&
+ filter.isLowCardinality && (
this.onValueChange(value)}
+ placeholder='Select Value'
+ selectedValue={filter.values[0]}
+ values={availableValues[filter.name]}
+ onChange={value => this.onFilterValueChange(value, index, 0)}
/>
- ))}
- {filter.operator && !cards.includes(filter.name) && (
-
- this.handleInputChange(
- value,
- filter.name,
- filter.operator
- )
- }
- onBetweenInputChange={value =>
- this.handleBetweenInputChange(
- value,
- filter.name,
- filter.operator
- )
- }
- />
- )}
-
- this.onRemoveFilter(index, filter)}
- >
-
-
-
- );
- })}
+ )}
+ {filter.operator && !filter.isLowCardinality && (
+ this.onFilterValueChange(value, index, pos)}
+ />
+ )}
+
+ this.onRemoveFilter(index)}
+ >
+
+
+
+ );
+ })}
- 0}>
-
-
- Add Filter
-
- {filters.length == 0 && (
-
- You can filter by all {entityName} attributes and more.
-
- )}
-
+ 0}>
+
+
+ Add Filter
+
+ {filters.length == 0 && (
+
+ You can filter by all {entityName} attributes and more.
+
+ )}
+
+
+
+
+
+ Reset
+
+
+ Run
+
+
);
}
@@ -389,18 +264,19 @@ const mapStateToProps = state => ({
filters: getSelectedFilters(state),
availableValues: getAvailableValues(state),
operators: getOperators(state),
+ attributes: getAttributes(state),
+ selectedEntity: getEntity(state)
});
const mapDispatchToProps = dispatch => ({
fetchValues: (value: string) => dispatch(fetchValues(value)),
- removeValue: (value: object) => dispatch(removeValueAction(value)),
- setSelectedValues: (value: object) =>
- dispatch(setSelectedValuesAction(value)),
addFilter: (entity: string) => dispatch(addFilterAction(entity)),
removeFilter: (entity: string, index: number) =>
dispatch(removeFilterAction(entity, index)),
changeFilter: (entity: string, filter: object, index: number) =>
dispatch(changeFilterAction(entity, filter, index)),
+ removeAllFilters: (selectedEntity: string) =>
+ dispatch(removeAllFiltersAction(selectedEntity)),
});
export default connect(
diff --git a/src/components/FilterPanel/style.ts b/src/components/FilterPanel/style.ts
new file mode 100644
index 00000000..9ec7d7a7
--- /dev/null
+++ b/src/components/FilterPanel/style.ts
@@ -0,0 +1,107 @@
+
+import styled from 'styled-components';
+import PlusIcon from '@material-ui/icons/Add';
+import ArronaxIcon from 'components/ArronaxIcon';
+
+export const Container = styled.div`
+ width: 100%;
+`;
+
+export const HeaderTxt = styled.div`
+ color: #4a4a4a;
+ font-size: 20px;
+ margin-bottom: 14px;
+`;
+
+export const MainContainer = styled.div`
+ width: 100%;
+ background: #fbfbfb;
+ border: 1px solid #ededed;
+ border-radius: 3px;
+`;
+
+export const FilterItemContainer = styled.div`
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ padding: 18px 24px 0 30px;
+`;
+
+export const FilterItemGr = styled.div`
+ border-radius: 5px;
+ border: 1px solid #ecedef;
+ display: flex;
+`;
+
+export const AddFilterFooter = styled.div`
+ width: 100%;
+ height: ${({ isFilters }) => (isFilters ? '67px' : '93px')};
+ display: flex;
+ align-items: center;
+ padding-left: 24px;
+ border-top: ${({ isFilters }) => (isFilters ? '1px solid #ECEDEF' : 'none')};
+ margin-top: ${({ isFilters }) => (isFilters ? '18px' : '0')};
+`;
+
+export const AddFilterButton = styled.div`
+ color: #56c2d9;
+ font-size: 18px;
+ font-weight: bold;
+ cursor: pointer;
+ display: flex;
+ align-items: center;
+ opacity: ${({ isDisabled }) => (isDisabled ? 0.5 : 1)};
+ pointer-events: ${({ isDisabled }) => (isDisabled ? 'none' : 'initial')};
+`;
+
+export const PlusIconWrapper = styled(PlusIcon)`
+ &&& {
+ color: #56c2d9;
+ font-size: 27px;
+ }
+`;
+
+export const FilterExpTxt = styled.div`
+ color: #9b9b9b;
+ font-size: 18px;
+ margin-left: 21px;
+`;
+
+export const HR = styled.div`
+ width: 1px;
+ background-color: #ecedef;
+`;
+
+export const RefreshIcon = styled(ArronaxIcon)`
+ margin-right: 12px;
+`;
+
+export const ButtonContainer = styled.div`
+ display: flex;
+ padding: 25px;
+ justify-content: flex-end;
+`;
+
+export const RunButton = styled.div`
+ cursor: pointer;
+ margin-left: 40px;
+ color: white;
+ background: #56c2d9;
+ border-radius: 9px;
+ font-size: 20px;
+ font-weight: 700;
+ height: 60px;
+ width: 158px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+`;
+
+export const ResetButton = styled.div`
+ color: #56c2d9;
+ font-size: 20px;
+ font-weight: 700;
+ cursor: pointer;
+ display: flex;
+ align-items: center;
+`;
\ No newline at end of file
diff --git a/src/components/FilterSelect/index.tsx b/src/components/FilterSelect/index.tsx
index 23a75fe9..a83414c8 100755
--- a/src/components/FilterSelect/index.tsx
+++ b/src/components/FilterSelect/index.tsx
@@ -16,7 +16,7 @@ const ButtonShell = styled(Button)`
font-size: 18px;
cursor: pointer;
color: ${({ isactive }) => (isactive ? '#4A4A4A' : '#9b9b9b')};
- text-transform: capitalize;
+ text-transform: ${({ iscapital }) => (iscapital ? 'capitalize' : 'initial')};;
}
`;
@@ -107,7 +107,7 @@ interface Props {
value: string;
items: Array- ;
placeholder?: string;
- onChange: (value: string) => void;
+ onChange: (item: object) => void;
}
type States = {
@@ -132,17 +132,9 @@ class FilterSelect extends React.Component {
}
}
- componentDidUpdate(prevProps) {
- const { onChange } = this.props;
- if (prevProps.placeholder === 'Select Operator' && prevProps.value === '') {
- const equalsOperator = Object.values(prevProps.items)[0];
- onChange(equalsOperator['name']);
- }
- }
-
handleChange = item => {
const { onChange } = this.props;
- onChange(item.name);
+ onChange(item);
this.setState({ anchorEl: null });
};
@@ -181,6 +173,7 @@ class FilterSelect extends React.Component {
aria-haspopup="true"
isactive={value}
onClick={this.handleClick}
+ iscapital={placeholder !== 'Select Operator'? 1 : 0}
>
{menuTitle}
diff --git a/src/components/FilterTool/index.tsx b/src/components/FilterTool/index.tsx
deleted file mode 100755
index 9e826ee6..00000000
--- a/src/components/FilterTool/index.tsx
+++ /dev/null
@@ -1,63 +0,0 @@
-import * as React from 'react';
-import styled from 'styled-components';
-import TezosIcon from 'components/TezosIcon';
-
-const Container = styled.div`
- position: relative;
- width: 107px;
- height: 52px;
- border: 1px solid #56c2d9;
- border-radius: 5px;
- display: flex;
- align-items: center;
- justify-content: center;
- font-size: 18px;
- color: #56c2d9;
- cursor: pointer;
-`;
-
-const FilterIconWrapper = styled(TezosIcon)`
- display: inline-block;
- transform: rotate(90deg);
- margin-right: 11px;
-`;
-
-const FilterMark = styled.div`
- position: absolute;
- width: 24px;
- height: 24px;
- background: #56c2d9;
- box-shadow: 0 0 4px 0 rgba(0, 0, 0, 1);
- border-radius: 12px;
- color: #ffffff;
- font-size: 13px;
- letter-spacing: 0.2px;
- font-weight: 500;
- display: flex;
- align-items: center;
- justify-content: center;
- right: -9px;
- top: -9px;
-`;
-
-interface Props {
- value: number;
- onCollapse: () => void;
-}
-
-const FilterTool: React.StatelessComponent = props => {
- const { value, onCollapse } = props;
- return (
-
-
- Filter
- {value > 0 && {value}}
-
- );
-};
-
-FilterTool.defaultProps = {
- value: 0,
-};
-
-export default FilterTool;
diff --git a/src/components/Header/index.tsx b/src/components/Header/index.tsx
index af6c4b0f..6a699e69 100755
--- a/src/components/Header/index.tsx
+++ b/src/components/Header/index.tsx
@@ -10,7 +10,7 @@ import ArrowDropDown from '@material-ui/icons/KeyboardArrowDown';
import InputBase from '@material-ui/core/InputBase';
import IconButton from '@material-ui/core/IconButton';
import SearchIcon from '@material-ui/icons/Search';
-import TezosIcon from '../TezosIcon';
+import ArronaxIcon from '../ArronaxIcon';
import getConfigs from '../../utils/getconfig';
const configs = getConfigs();
@@ -163,7 +163,7 @@ const Header: React.StatelessComponent = props => {
ARRONAX
-
+
= props => {
))}
-
-
-
-
-
-
-
);
};
diff --git a/src/components/SettingsPanel/index.tsx b/src/components/SettingsPanel/index.tsx
index 4e11132b..19e815aa 100755
--- a/src/components/SettingsPanel/index.tsx
+++ b/src/components/SettingsPanel/index.tsx
@@ -2,70 +2,16 @@ import * as React from 'react';
import styled from 'styled-components';
import Collapse from '@material-ui/core/Collapse';
import CloseIcon from '@material-ui/icons/CloseOutlined';
-import ColumnsDisplay from '../ColumnsDisplay';
+import SwipeableViews from 'react-swipeable-views';
import FilterPanel from '../FilterPanel';
-import RefreshIcon from '@material-ui/icons/Refresh';
+import ColumnsPanel from '../ColumnsPanel';
+import { ToolType } from '../../types';
const Container = styled.div`
position: relative;
- padding: 50px 77px 50px 50px;
- background: #ecedef;
-`;
-
-const QueryContainer = styled.div`
- display: flex;
-`;
-
-const ButtonsContainer = styled.div`
- display: flex;
- width: 100%;
- align-items: center;
- justify-content: flex-end;
-`;
-
-const RunButton = styled.div`
- cursor: pointer;
- margin-left: 40px;
- color: white;
- background: #56c2d9;
- border-radius: 9px 9px 9px 9px;
- font-size: 18px;
- height: 47px;
- width: 125px;
- display: flex;
- align-items: center;
- justify-content: center;
-`;
-
-const ResetButton = styled.div`
- color: #56c2d9;
- font-size: 18px;
- font-weight: bold;
- cursor: pointer;
- display: flex;
- align-items: center;
-`;
-
-const FilterTxt = styled.div`
- color: #4a4a4a;
- font-size: 20px;
- margin-bottom: 14px;
-`;
-
-const DisplayTxt = styled(FilterTxt)`
- margin-top: 20px;
-`;
-
-const DisplayContainer = styled.div`
- align-items: center;
- padding-left: 24px;
- padding-right: 24px;
- height: 93px;
- background: white;
- border: 1px solid #ededed;
- border-radius: 3px;
- display: flex;
- flex-grow: row;
+ padding: 40px 77px 12px 50px;
+ background: rgb(236, 237, 239);
+ box-shadow: inset 0px 1px 3px 0px rgba(0, 0, 0, 0.5);
`;
const CloseIconContainer = styled.div`
@@ -83,73 +29,45 @@ const CloseIconWrapper = styled(CloseIcon)`
`;
interface Props {
- selectedColumns: any;
- isCollapse: boolean;
- filterInputState: object;
- selectedEntity: string;
- attributes: object[];
- selectedValues: object[];
- setColumns: (columns: object[]) => void;
- submitValues: () => void;
- setFilterInputState: (
- value: string,
- filterName: string,
- filterOperator: string
- ) => void;
+ isCollapsed: boolean;
+ selectedTool: string;
+ onSubmit: () => void;
onClose: () => void;
- resetValues: () => void;
}
-const SettingsPanel: React.StatelessComponent = props => {
- const {
- isCollapse,
- onClose,
- selectedColumns,
- resetValues,
- submitValues,
- filterInputState,
- setFilterInputState,
- selectedEntity,
- attributes,
- setColumns,
- selectedValues,
- } = props;
- return (
-
-
-
-
-
- Filter
-
- Display
-
-
-
-
-
-
-
- {' '}Reset
-
- Run
-
-
-
-
- );
+class SettingsPanel extends React.Component {
+ swipeableActions = null;
+ componentDidMount() {
+ this.swipeableActions.updateHeight();
+ }
+ render() {
+ const {
+ isCollapsed,
+ selectedTool,
+ onClose,
+ onSubmit
+ } = this.props;
+ const activeIndex = selectedTool === ToolType.FILTER ? 0 : 1;
+ return (
+
+
+
+
+
+ {
+ this.swipeableActions = actions;
+ }}
+ animateHeight
+ >
+
+
+
+
+
+ );
+ }
};
export default SettingsPanel;
diff --git a/src/components/Toolbar/index.tsx b/src/components/Toolbar/index.tsx
new file mode 100755
index 00000000..36b9add2
--- /dev/null
+++ b/src/components/Toolbar/index.tsx
@@ -0,0 +1,137 @@
+import * as React from 'react';
+import styled from 'styled-components';
+import ArronaxIcon from '../ArronaxIcon';
+import { ToolType } from '../../types';
+
+const Container = styled.div`
+ position: relative;
+ width: 100%;
+ height: 77px;
+ padding: 25px 30px 0 30px;
+`;
+
+const ToolItem = styled.div`
+ height: 52px;
+ border: 1px solid rgb(220, 220, 220);
+ display: flex;
+ align-items: center;
+ font-size: 18px;
+ font-weight: 500;
+ color: rgb(74, 74, 74);
+ cursor: pointer;
+ position: absolute;
+ top: 25px;
+ z-index: 1;
+ &:hover {
+ border-color: rgb(180, 231, 242);
+ color: rgb(86, 194, 217);
+ z-index: 4;
+ span {
+ color: rgb(86, 194, 217);
+ }
+ }
+ &:after {
+ content: '';
+ width: 100%;
+ height: 6px;
+ background: transparent;
+ position: absolute;
+ bottom: 0;
+ left: 0;
+ }
+`;
+
+const FilterTool = styled(ToolItem)`
+ width: 126px;
+ border-radius: 5px 0px 0px 5px;
+ padding-left: 13px;
+ left: 30px;
+ color: ${({ isactive }) => (isactive ? 'rgb(86, 194, 217)' : 'rgb(74, 74, 74)')};
+ span {
+ color: ${({ isactive }) => (isactive ? 'rgb(86, 194, 217)' : 'rgb(74, 74, 74)')};
+ }
+ &:after {
+ background: ${({ isactive }) => (isactive ? 'rgb(166, 223, 226)' : 'transparent')};
+ }
+`;
+
+const ColumnsTool = styled(ToolItem)`
+ width: 153px;
+ left: 155px;
+ padding-left: 12px;
+ color: ${({ isactive }) => (isactive ? 'rgb(86, 194, 217)' : 'rgb(74, 74, 74)')};
+ span {
+ color: ${({ isactive }) => (isactive ? 'rgb(86, 194, 217)' : 'rgb(74, 74, 74)')};
+ }
+ &:after {
+ background: ${({ isactive }) => (isactive ? 'rgb(166, 223, 226)' : 'transparent')};
+ }
+`;
+
+const ExportTool = styled(ToolItem)`
+ width: 149px;
+ border-radius: 0px 5px 5px 0px;
+ left: 307px;
+ padding-left: 18px;
+ &:after {
+ background: ${({ isactive }) => (isactive ? 'rgb(166, 223, 226)' : 'transparent')};
+ }
+`;
+
+const FilterIcon = styled(ArronaxIcon)`
+ display: inline-block;
+ margin-right: 11px;
+`;
+
+const ExportIcon = styled(ArronaxIcon)`
+ display: inline-block;
+ margin-right: 6px;
+`;
+
+const ColumnIcon = styled(ArronaxIcon)`
+ display: inline-block;
+ margin-right: 8px;
+`;
+
+
+interface Props {
+ isCollapsed: boolean;
+ selectedTool: string;
+ filterCount: number;
+ columnsCount: number;
+ onChangeTool: (tool: string) => void;
+ onExportCsv: () => void;
+}
+
+const Toolbar: React.StatelessComponent = props => {
+ const { isCollapsed, selectedTool, filterCount, columnsCount, onChangeTool, onExportCsv } = props;
+ return (
+
+ onChangeTool(ToolType.FILTER)}
+ >
+
+ Filter ({filterCount})
+
+ onChangeTool(ToolType.COLUMN)}
+ >
+ Columns ({columnsCount})
+
+
+
+ Export CSV
+
+
+ );
+};
+
+Toolbar.defaultProps = {
+ filterCount: 0,
+ columnsCount: 0,
+ isCollapsed: false
+};
+
+export default Toolbar;
diff --git a/src/components/ValueInput/index.tsx b/src/components/ValueInput/index.tsx
index 506aaa78..307b40a0 100644
--- a/src/components/ValueInput/index.tsx
+++ b/src/components/ValueInput/index.tsx
@@ -1,6 +1,7 @@
import * as React from 'react';
import styled from 'styled-components';
import TextField from '@material-ui/core/TextField';
+import { ConseilOperator } from 'conseiljs';
const Container = styled.div``;
@@ -32,63 +33,32 @@ const TextInput = styled(TextField)`
line-height: 17px;
width: 150px;
`;
-
-interface Filter {
- name: string;
- operator: string;
-}
-
interface Props {
- filter: Filter;
- inputProps?: object;
+ operator: string;
InputProps?: object;
- value: string;
- filterInputState: object;
- selectedEntity: string;
- onInputChange: (value: string) => void;
- onBetweenInputChange: (value: string) => void;
+ values: Array;
+ onChange: (value: string, index: number) => void;
}
-class ValueInput extends React.Component {
- handleInputChange = value => {
- const { onInputChange } = this.props;
- onInputChange(value);
- };
-
- handleBetweenChange = value => {
- const { onBetweenInputChange } = this.props;
- onBetweenInputChange(value);
- };
-
- render() {
+const ValueInput: React.StatelessComponent = props => {
const {
InputProps,
- inputProps,
- filter,
- filterInputState,
- selectedEntity,
- } = this.props;
+ operator,
+ values,
+ onChange
+ } = props;
let input;
- // Find state value that matches this filter
- const findStateValue = filterInputState[selectedEntity].find(
- value => Object.keys(value).toString() === filter.name
- );
- const currentStateValue = findStateValue
- ? Object.values(findStateValue).toString()
- : '';
// Render specific input type based on operators
- if (filter.operator === 'BETWEEN' || filter.operator === 'IN') {
- const splitValues = currentStateValue.split('-');
+ if (operator === ConseilOperator.BETWEEN || operator === ConseilOperator.IN) {
input = (
this.handleInputChange(event.target.value)}
+ placeholder='Insert Value'
+ onChange={event => onChange(event.target.value, 0)}
/>
@@ -96,36 +66,30 @@ class ValueInput extends React.Component {
this.handleBetweenChange(event.target.value)}
+ placeholder='Insert Value'
+ onChange={event => onChange(event.target.value, 1)}
/>
);
- } else if (
- filter.operator === 'ISNULL' ||
- filter.operator === 'ISNOTNULL'
- ) {
+ } else if (operator === ConseilOperator.ISNULL || operator === 'isnotnull') {
input = null;
} else {
input = (
this.handleInputChange(event.target.value)}
+ placeholder='Insert Value'
+ onChange={event => onChange(event.target.value, 0)}
/>
);
}
return {input};
- }
}
export default ValueInput;
diff --git a/src/components/ValueSelect/index.tsx b/src/components/ValueSelect/index.tsx
index 0f8e4046..e6779603 100644
--- a/src/components/ValueSelect/index.tsx
+++ b/src/components/ValueSelect/index.tsx
@@ -4,14 +4,10 @@ import Button from '@material-ui/core/Button';
import Menu from '@material-ui/core/Menu';
import MenuItem from '@material-ui/core/MenuItem';
import KeyboardArrowDown from '@material-ui/icons/KeyboardArrowDown';
+import { convertValue } from '../../utils/general';
const Container = styled.div``;
-const HR = styled.div`
- width: 1px;
- background-color: #ecedef;
-`;
-
const ButtonShell = styled(Button)`
&&& {
height: 52px;
@@ -75,9 +71,8 @@ const MainMenuItem = styled(MenuItem)`
`;
interface Props {
- filter: any;
- selectedValues: any;
- availableValues: Array