Compare commits
787 Commits
Author | SHA1 | Date |
---|---|---|
Matthias Kretschmann | de77f693d9 | |
Trent McConaghy | ad08e3bb53 | |
Matthias Kretschmann | 97b3e55bc1 | |
dependabot[bot] | 0948e18c41 | |
Matthias Kretschmann | 15dcc2e31a | |
Matthias Kretschmann | 2e34c0df81 | |
Matthias Kretschmann | cf1038a7fd | |
dependabot[bot] | 3b0a366217 | |
dependabot[bot] | b63a693ed6 | |
Matthias Kretschmann | 468c0204d4 | |
dependabot[bot] | 31185f9c64 | |
Matthias Kretschmann | a4cd995669 | |
Matthias Kretschmann | c3cd566efd | |
dependabot[bot] | ca1e84e3e0 | |
dependabot[bot] | 23a11e39ca | |
dependabot[bot] | f4e0a38520 | |
Matthias Kretschmann | 8699cd7ce9 | |
Matthias Kretschmann | 1bae3ae85a | |
Matthias Kretschmann | 932f6ee1e4 | |
Matthias Kretschmann | d3b35c302f | |
Matthias Kretschmann | b0acdb3473 | |
Matthias Kretschmann | 87dc14f6d9 | |
Matthias Kretschmann | d1d4ab72c6 | |
dependabot[bot] | 626432c6c9 | |
dependabot[bot] | 5b95d0253c | |
dependabot[bot] | 8850b76cf8 | |
dependabot[bot] | 72c513c338 | |
dependabot[bot] | 06f8b88140 | |
dependabot[bot] | 3ce14e8e7b | |
dependabot[bot] | 04598e296e | |
Matthias Kretschmann | 473b0b6e9d | |
Matthias Kretschmann | cb8c7fdaab | |
Matthias Kretschmann | 624ee063b0 | |
Matthias Kretschmann | 6a94339ab6 | |
Matthias Kretschmann | 08803802fa | |
Matthias Kretschmann | b771931e74 | |
Matthias Kretschmann | f5622b92f6 | |
dependabot[bot] | 4696012f06 | |
dependabot[bot] | d8f6c976bf | |
dependabot[bot] | 54ad4798fc | |
dependabot[bot] | 0eee025656 | |
dependabot[bot] | 5a4e272c95 | |
dependabot[bot] | c0ac535814 | |
dependabot[bot] | ba31f967f2 | |
Matthias Kretschmann | 61d0c7328c | |
dependabot[bot] | 8be3572945 | |
Matthias Kretschmann | 19e3b55193 | |
Matthias Kretschmann | c4d71aab53 | |
Matthias Kretschmann | fbe61b006b | |
Matthias Kretschmann | 34e20186c3 | |
dependabot[bot] | f553fcd7e0 | |
dependabot[bot] | 9ade7d25db | |
dependabot[bot] | c8706698ed | |
dependabot[bot] | ea99c045bd | |
Matthias Kretschmann | 75039762e7 | |
dependabot-preview[bot] | bca6d3d0df | |
dependabot-preview[bot] | 016086c727 | |
dependabot-preview[bot] | 735e2c5882 | |
dependabot-preview[bot] | d1a1d5430d | |
dependabot-preview[bot] | 546483b8d0 | |
dependabot-preview[bot] | b4da9f3ebc | |
dependabot-preview[bot] | 75586154d8 | |
dependabot-preview[bot] | 49f76033db | |
dependabot-preview[bot] | 957f9836c4 | |
dependabot-preview[bot] | 1684bf844f | |
dependabot-preview[bot] | 6518b01622 | |
dependabot-preview[bot] | 413ed7e13f | |
dependabot-preview[bot] | be5a32797c | |
dependabot-preview[bot] | d285b1106f | |
dependabot-preview[bot] | d5582e14ce | |
dependabot-preview[bot] | ab7a519c78 | |
dependabot-preview[bot] | cc392edf04 | |
dependabot-preview[bot] | 744bfd67fc | |
dependabot-preview[bot] | cf24217330 | |
dependabot-preview[bot] | fed35cf79b | |
dependabot-preview[bot] | 062a030fb5 | |
dependabot-preview[bot] | bdfe3854d6 | |
dependabot-preview[bot] | 7f8e363840 | |
dependabot-preview[bot] | 772df475cd | |
dependabot-preview[bot] | 12a81c8001 | |
dependabot-preview[bot] | 3f5a4aa4f6 | |
dependabot-preview[bot] | 1aa2afb005 | |
dependabot-preview[bot] | f88d9d556d | |
dependabot-preview[bot] | ee20f6541c | |
dependabot-preview[bot] | e35c3015d5 | |
dependabot-preview[bot] | 99097d91cc | |
dependabot-preview[bot] | 3af9ee9efa | |
dependabot-preview[bot] | 7ba39430c9 | |
dependabot-preview[bot] | 809deeb3a8 | |
dependabot-preview[bot] | 119a1ee672 | |
dependabot-preview[bot] | bacf948f53 | |
dependabot-preview[bot] | 4660175c50 | |
Matthias Kretschmann | 380b57388c | |
Alex Coseru | 197d3a950d | |
alexcos20 | bbeef61afd | |
alexcos20 | 8831c46e39 | |
Matthias Kretschmann | c0effd449f | |
Matthias Kretschmann | 91821e88d4 | |
dependabot-preview[bot] | 6f05baff3a | |
dependabot-preview[bot] | 0abc740ed8 | |
dependabot-preview[bot] | 5eb2b3fde0 | |
dependabot-preview[bot] | a38ecc255d | |
dependabot-preview[bot] | 7e59a1807c | |
dependabot-preview[bot] | 1f9a358451 | |
dependabot-preview[bot] | 006948360f | |
dependabot-preview[bot] | bdab45c565 | |
dependabot-preview[bot] | 62a64f8539 | |
dependabot-preview[bot] | b3fa56c2b2 | |
Matthias Kretschmann | 55d9592565 | |
mihaisc | 5015d26cea | |
mihaisc | a6b0ca4be6 | |
dependabot-preview[bot] | 3c8cbcc22b | |
dependabot-preview[bot] | 3aa79cd7dc | |
dependabot-preview[bot] | 0f55b73dc5 | |
dependabot-preview[bot] | daf39e8ed2 | |
dependabot-preview[bot] | ef013c0d10 | |
dependabot-preview[bot] | 7184a7bb66 | |
mihaisc | 28b213d2fc | |
mihaisc | 55bf9f314f | |
dependabot-preview[bot] | 51b1dd228f | |
dependabot-preview[bot] | 3511bafdf3 | |
Matthias Kretschmann | b93f005154 | |
dependabot-preview[bot] | 7cba1cd148 | |
dependabot-preview[bot] | 876d7c22d3 | |
dependabot-preview[bot] | 87bcba5af7 | |
Matthias Kretschmann | d058fc815d | |
Matthias Kretschmann | d916f0df1e | |
Matthias Kretschmann | 2884015678 | |
Matthias Kretschmann | 7d09350967 | |
Matthias Kretschmann | fe37382833 | |
dependabot-preview[bot] | 0d3bdc7a2c | |
Matthias Kretschmann | 00e2d8acb5 | |
Matthias Kretschmann | b7408a3c9b | |
Matthias Kretschmann | 4ddd607499 | |
Matthias Kretschmann | 5d9fee0e69 | |
dependabot-preview[bot] | 780d9db16e | |
Matthias Kretschmann | 7905a1f8a9 | |
Alex Coseru | 17cdb87b8d | |
dependabot-preview[bot] | 4b3130e0e9 | |
dependabot-preview[bot] | 1014ab02cf | |
dependabot-preview[bot] | cb68e7ef3d | |
dependabot-preview[bot] | cc3bc599b4 | |
dependabot-preview[bot] | 3ce29a59b9 | |
dependabot-preview[bot] | 73ba7d4cdd | |
dependabot-preview[bot] | f431b66a41 | |
dependabot-preview[bot] | 5d1377fa24 | |
dependabot-preview[bot] | cd81fa3d9a | |
dependabot-preview[bot] | c69797cb02 | |
dependabot-preview[bot] | 6d834fb6a6 | |
dependabot-preview[bot] | 0dda840f92 | |
dependabot-preview[bot] | 41600c2f30 | |
alexcos20 | 54f437a6e6 | |
dependabot-preview[bot] | 456e9a6607 | |
dependabot-preview[bot] | 8a48afb535 | |
dependabot-preview[bot] | 0dfaf4c069 | |
dependabot-preview[bot] | 23f956092a | |
dependabot-preview[bot] | 8bed302e9e | |
alexcos20 | f6be84e76f | |
dependabot-preview[bot] | 8284a407f8 | |
dependabot-preview[bot] | 074250e544 | |
dependabot-preview[bot] | 445c86f60d | |
dependabot-preview[bot] | 97fda45977 | |
dependabot-preview[bot] | b97205a0c2 | |
dependabot-preview[bot] | c0e15d5695 | |
dependabot-preview[bot] | 401d8349e6 | |
dependabot-preview[bot] | 9c93c92e10 | |
dependabot-preview[bot] | 8505c1efd0 | |
Matthias Kretschmann | 7b02cbe52f | |
dependabot-preview[bot] | a34c37f212 | |
dependabot-preview[bot] | 98c459241f | |
dependabot-preview[bot] | 6a6688b2e0 | |
dependabot-preview[bot] | d4cb1f78bd | |
Matthias Kretschmann | 13780d6a82 | |
dependabot-preview[bot] | dba1f8f878 | |
dependabot-preview[bot] | 6e12b3f1be | |
dependabot-preview[bot] | 04f5db99f0 | |
dependabot-preview[bot] | ca6ee70da8 | |
dependabot-preview[bot] | 274a9507e3 | |
dependabot-preview[bot] | 2dafe64a00 | |
dependabot-preview[bot] | e8bab5749b | |
Matthias Kretschmann | 3f5def552e | |
dependabot-preview[bot] | 7df95c69ab | |
dependabot-preview[bot] | 024b873614 | |
dependabot-preview[bot] | 9c16ad30e1 | |
dependabot-preview[bot] | 8fb906b168 | |
dependabot-preview[bot] | 20cc62b2fa | |
alexcos20 | 99fa2e965b | |
dependabot-preview[bot] | c82f31dc2d | |
dependabot-preview[bot] | d11dc641cf | |
dependabot-preview[bot] | 8e547f9b9d | |
dependabot-preview[bot] | 112f2ba00c | |
dependabot-preview[bot] | d5ff3c1df2 | |
dependabot-preview[bot] | f7d4a5a994 | |
dependabot-preview[bot] | abab1b1ffb | |
dependabot-preview[bot] | c1296ed172 | |
dependabot-preview[bot] | c00911c886 | |
dependabot-preview[bot] | c539db7141 | |
dependabot-preview[bot] | af5dd6339a | |
dependabot-preview[bot] | f70612300d | |
dependabot-preview[bot] | cd9364167d | |
dependabot-preview[bot] | 24316aa19d | |
dependabot-preview[bot] | dd6f1537c9 | |
Matthias Kretschmann | c642fa0ee7 | |
dependabot-preview[bot] | 8e06fc63e3 | |
dependabot-preview[bot] | c64adf2400 | |
dependabot-preview[bot] | 32a8086753 | |
dependabot-preview[bot] | d2e250149d | |
dependabot-preview[bot] | d5c26544ef | |
dependabot-preview[bot] | 93db50886e | |
dependabot-preview[bot] | 5e6b56112f | |
dependabot-preview[bot] | 812812d413 | |
dependabot-preview[bot] | 0d69433ad2 | |
dependabot-preview[bot] | 874ae1d058 | |
dependabot-preview[bot] | 1193b62607 | |
dependabot-preview[bot] | 1d5a17142e | |
dependabot-preview[bot] | 78f3358672 | |
Matthias Kretschmann | c34797e9d8 | |
Matthias Kretschmann | aef84642af | |
dependabot-preview[bot] | dbc8baf5ca | |
Matthias Kretschmann | 366c49537e | |
Matthias Kretschmann | 59aa6e3cc8 | |
dependabot-preview[bot] | 881c924afd | |
dependabot-preview[bot] | 41968bf4b6 | |
dependabot-preview[bot] | 906a141504 | |
alexcos20 | 38691369d4 | |
alexcos20 | 23aced5f9c | |
alexcos20 | 3f7e8f9f18 | |
alexcos20 | e7cd6105bf | |
mihaisc | aff63caf9a | |
mihaisc | b5eb2e2ddf | |
mihaisc | 553535c578 | |
mihaisc | 1b20b12cce | |
mihaisc | d234717a6a | |
Matthias Kretschmann | f63077181e | |
Matthias Kretschmann | 5f8b3d7b69 | |
Matthias Kretschmann | 192c54134a | |
Matthias Kretschmann | b7c6543fbe | |
Matthias Kretschmann | 94fa7701eb | |
Matthias Kretschmann | 5ced0c4dc8 | |
dependabot[bot] | f5728e732b | |
Matthias Kretschmann | 6bacf8936d | |
Matthias Kretschmann | 1e0f549e8f | |
dependabot[bot] | 70ba8ded20 | |
dependabot[bot] | a0df037d37 | |
Matthias Kretschmann | f143a59b0b | |
Matthias Kretschmann | 456ad15ddf | |
Matthias Kretschmann | c669089d3b | |
Matthias Kretschmann | e81c196d40 | |
Matthias Kretschmann | 57f2022f37 | |
Matthias Kretschmann | ba2de2e69c | |
Matthias Kretschmann | 3e814b98a7 | |
Matthias Kretschmann | a54bcc1afb | |
Matthias Kretschmann | 65b72e597d | |
Matthias Kretschmann | 004f946d99 | |
Matthias Kretschmann | 8089a7aa3e | |
Matthias Kretschmann | 9cbedb8f87 | |
Matthias Kretschmann | b9f83021c7 | |
Matthias Kretschmann | 44d0c25e0b | |
Matthias Kretschmann | ebdbb04bd9 | |
Matthias Kretschmann | 37296c502e | |
Matthias Kretschmann | d80530c315 | |
Matthias Kretschmann | c5ea3b7c8a | |
Matthias Kretschmann | 77e2dd49c5 | |
Matthias Kretschmann | 5ba5cd9e20 | |
Matthias Kretschmann | e9e5dd9049 | |
Matthias Kretschmann | c98fc44d35 | |
Matthias Kretschmann | 1355be96c8 | |
Matthias Kretschmann | 3d9ed9d1c3 | |
Matthias Kretschmann | f8dfaa438c | |
Matthias Kretschmann | 70a3339f8b | |
Matthias Kretschmann | 1b07944e02 | |
Matthias Kretschmann | 7f9daa0d82 | |
Matthias Kretschmann | 3df046bbea | |
Matthias Kretschmann | a8c695e16f | |
Matthias Kretschmann | ed2812d6f4 | |
Matthias Kretschmann | 2868076da2 | |
Matthias Kretschmann | b652d243d4 | |
Matthias Kretschmann | c0a79b3188 | |
Matthias Kretschmann | 670f717b37 | |
Matthias Kretschmann | dcc5642aa2 | |
Matthias Kretschmann | 50d077a887 | |
Matthias Kretschmann | 5800027cbf | |
Matthias Kretschmann | f7a5de7b5c | |
Matthias Kretschmann | 954c6d2d46 | |
Matthias Kretschmann | 8c3262c1d9 | |
Matthias Kretschmann | b4248b7693 | |
Matthias Kretschmann | 831e3d1aa1 | |
Matthias Kretschmann | 7eea449a5d | |
Matthias Kretschmann | 417abf8988 | |
Matthias Kretschmann | ed33f690f9 | |
Matthias Kretschmann | 6282dbb5fc | |
Matthias Kretschmann | ac5c66f0e9 | |
Matthias Kretschmann | 985803d43e | |
Matthias Kretschmann | c3c8ca5368 | |
Matthias Kretschmann | a81838c8e7 | |
Matthias Kretschmann | b02cda043c | |
Matthias Kretschmann | 8ca727fffc | |
Matthias Kretschmann | c8a46a5316 | |
Matthias Kretschmann | 345bbb0dfb | |
Matthias Kretschmann | afd4ec991f | |
Matthias Kretschmann | 826cb07953 | |
Matthias Kretschmann | ccdef8143e | |
Matthias Kretschmann | 4741e1260d | |
Matthias Kretschmann | 7d60a85885 | |
Matthias Kretschmann | 7c88cb4fea | |
Matthias Kretschmann | da9237ea46 | |
Matthias Kretschmann | 532dee9845 | |
Matthias Kretschmann | ced3f716da | |
Matthias Kretschmann | 9daa49a085 | |
Matthias Kretschmann | e417c8299a | |
Matthias Kretschmann | aec1f78257 | |
Matthias Kretschmann | fe4f2233f0 | |
Matthias Kretschmann | 3fb7358b77 | |
Matthias Kretschmann | f14413e34f | |
Matthias Kretschmann | 1bf47ce128 | |
Matthias Kretschmann | ae34031e9f | |
Alex Coseru | a8cde6499b | |
Matthias Kretschmann | 4319115e00 | |
Matthias Kretschmann | 77deaf063e | |
Matthias Kretschmann | 28c1d2e331 | |
Matthias Kretschmann | 70b3f8c8bd | |
Matthias Kretschmann | 9226bf2799 | |
Matthias Kretschmann | 78d4c8b874 | |
Matthias Kretschmann | 8aadcb9d97 | |
Matthias Kretschmann | e06c337ba1 | |
Matthias Kretschmann | 54a4ba5c68 | |
Matthias Kretschmann | 4fb47c063b | |
Matthias Kretschmann | 59ede97931 | |
Matthias Kretschmann | 74cb19f5ef | |
Matthias Kretschmann | 4ead855731 | |
Matthias Kretschmann | af8df224cb | |
Matthias Kretschmann | dc0f5c803d | |
Matthias Kretschmann | aef52f61c0 | |
Matthias Kretschmann | 4920bae0fa | |
Matthias Kretschmann | 8b31257837 | |
Matthias Kretschmann | e3be76fb95 | |
Matthias Kretschmann | c63325bdf2 | |
Matthias Kretschmann | 60a570892b | |
Matthias Kretschmann | 483cc35de3 | |
Matthias Kretschmann | 1813207772 | |
Matthias Kretschmann | 752498d6b3 | |
Matthias Kretschmann | c6f5f8561c | |
Matthias Kretschmann | ba3704dcce | |
Matthias Kretschmann | 6d4b6b77c2 | |
Matthias Kretschmann | 302986d63b | |
Matthias Kretschmann | 84eff3f3b4 | |
Matthias Kretschmann | 8b612ea4a2 | |
Matthias Kretschmann | 725215b6ee | |
Matthias Kretschmann | 3d1d81ffe9 | |
Matthias Kretschmann | be7020bceb | |
Matthias Kretschmann | e512ed4471 | |
Matthias Kretschmann | da357b82c2 | |
Matthias Kretschmann | 2f741d300e | |
Matthias Kretschmann | 839140d906 | |
Matthias Kretschmann | a2a6720fd8 | |
Matthias Kretschmann | a258f6b94b | |
Matthias Kretschmann | 955608202d | |
Matthias Kretschmann | a2f075171c | |
Matthias Kretschmann | 8127174fbd | |
Matthias Kretschmann | 6db965b79a | |
Matthias Kretschmann | 5002effbfe | |
Matthias Kretschmann | b6d255bbad | |
Matthias Kretschmann | 9c38c82496 | |
Matthias Kretschmann | 3b889725f1 | |
Matthias Kretschmann | 1c59d49d5d | |
Matthias Kretschmann | 414dcd455a | |
Matthias Kretschmann | 85ffae37d1 | |
Matthias Kretschmann | 475cade27f | |
Matthias Kretschmann | 10b662343f | |
Alex Coseru | 2c99d6f9e6 | |
Alex Coseru | 5d880778ba | |
Matthias Kretschmann | e007ab2090 | |
Matthias Kretschmann | 5b0c3486dd | |
Matthias Kretschmann | cf783e66b8 | |
Matthias Kretschmann | a7209f690d | |
Matthias Kretschmann | 8f0988e1b0 | |
Matthias Kretschmann | 60327973de | |
Matthias Kretschmann | 9e773fa791 | |
Sebastian Gerske | c1f9b96b04 | |
Sebastian Gerske | e965fe1ff6 | |
Sebastian Gerske | d7e93d116c | |
Matthias Kretschmann | 5b52505ee8 | |
Sebastian Gerske | aeb24aadda | |
Sebastian Gerske | 3235dc1d5e | |
Sebastian Gerske | 6b237e7348 | |
Sebastian Gerske | 9ec7b0af66 | |
Matthias Kretschmann | 29e6e8b5af | |
Matthias Kretschmann | 1e592497ae | |
Matthias Kretschmann | 97a5f39b5e | |
Matthias Kretschmann | 33b14bc8e3 | |
Matthias Kretschmann | 5f37adc420 | |
Matthias Kretschmann | b77e38c3ab | |
Matthias Kretschmann | e32f3bbb62 | |
Matthias Kretschmann | 12f6cfcb80 | |
Matthias Kretschmann | 821f80da0f | |
Matthias Kretschmann | c4e71173ba | |
Matthias Kretschmann | c4029b147c | |
Matthias Kretschmann | 8e8c145d18 | |
Matthias Kretschmann | 199df0e23d | |
Matthias Kretschmann | 8058325697 | |
Matthias Kretschmann | 9ef8fc9fba | |
Matthias Kretschmann | cb3f9c11d2 | |
Matthias Kretschmann | 09caa5461e | |
Matthias Kretschmann | 3a32a72de2 | |
Matthias Kretschmann | 8b155b375f | |
Matthias Kretschmann | dd9b1b5122 | |
Matthias Kretschmann | 7d911bf763 | |
Matthias Kretschmann | 3f730f295e | |
Matthias Kretschmann | 60d98340d9 | |
Matthias Kretschmann | c62b69b17f | |
Matthias Kretschmann | 1f7845aa22 | |
Matthias Kretschmann | 73c7624873 | |
Matthias Kretschmann | e009733c7e | |
Matthias Kretschmann | 4ae344a861 | |
Matthias Kretschmann | 276688ffee | |
Matthias Kretschmann | 20c0d9b3ae | |
Matthias Kretschmann | 33301e22c1 | |
Matthias Kretschmann | 348af32b65 | |
Matthias Kretschmann | 509a69b53d | |
Jernej Pregelj | db6b53257f | |
Jernej Pregelj | 459019f5ee | |
Jernej Pregelj | 483c333732 | |
Jernej Pregelj | e1b685bb5d | |
Jernej Pregelj | 52ec23628f | |
Matthias Kretschmann | a2b8bd6400 | |
Jernej Pregelj | 09797aed78 | |
Jernej Pregelj | 7c59faf4a4 | |
Jernej Pregelj | 552d9a90f8 | |
Jernej Pregelj | 74075fab08 | |
Matthias Kretschmann | 105dcbc8cf | |
Matthias Kretschmann | 73ac3d0875 | |
Matthias Kretschmann | b112f3aa60 | |
Matthias Kretschmann | c3270ce36c | |
Matthias Kretschmann | 7c4c7a0956 | |
Matthias Kretschmann | e76ffd8954 | |
Matthias Kretschmann | ba4717bbd3 | |
Matthias Kretschmann | e2aef49256 | |
Matthias Kretschmann | 30917f890f | |
Matthias Kretschmann | 036305c315 | |
Matthias Kretschmann | c2e2606133 | |
Matthias Kretschmann | abe3f9630f | |
Matthias Kretschmann | 68250f5ae5 | |
Matthias Kretschmann | 9012eea1dc | |
Matthias Kretschmann | 1f75f38849 | |
Matthias Kretschmann | da70e4d43c | |
Matthias Kretschmann | 15db426080 | |
Matthias Kretschmann | 1405a6931d | |
Matthias Kretschmann | 16783bc7da | |
Matthias Kretschmann | 6fe55e7a81 | |
Matthias Kretschmann | 62cc0b407d | |
Matthias Kretschmann | 0a196f462a | |
Matthias Kretschmann | f6c67781ed | |
Matthias Kretschmann | 64008abc26 | |
Matthias Kretschmann | b3ee23e728 | |
Jernej Pregelj | ba1ba78849 | |
Jernej Pregelj | 3c5ff6da1d | |
Matthias Kretschmann | 3cafd60b07 | |
Matthias Kretschmann | 17112bef00 | |
Matthias Kretschmann | 8d06a67e7f | |
Matthias Kretschmann | 31a0d3cfb1 | |
Jernej Pregelj | 599e1834cc | |
Matthias Kretschmann | e0ca17883f | |
Matthias Kretschmann | a31b041c05 | |
Javier Cortejoso | 6f40ba1735 | |
Matthias Kretschmann | c1ff41b711 | |
Jernej Pregelj | 69d8c28858 | |
Jernej Pregelj | b09c15ff1b | |
Matthias Kretschmann | 9e3f56e622 | |
Matthias Kretschmann | ba33fc52a4 | |
Matthias Kretschmann | 8d2dee6554 | |
Jernej Pregelj | 3a72470208 | |
Jernej Pregelj | 57dcdb7c21 | |
Matthias Kretschmann | 892c07b783 | |
Matthias Kretschmann | c386aa5518 | |
Matthias Kretschmann | a5919ff69d | |
Matthias Kretschmann | 9190dd6f2b | |
Matthias Kretschmann | 288c630aa8 | |
Matthias Kretschmann | 61aef37e8e | |
Jernej Pregelj | 9c47ed2183 | |
Jernej Pregelj | 3518abab26 | |
Jernej Pregelj | a1fdfa8a90 | |
Jernej Pregelj | 645f79f733 | |
Matthias Kretschmann | 69d7295f57 | |
Matthias Kretschmann | 1ab87dea30 | |
Matthias Kretschmann | ca58d7d0b1 | |
Matthias Kretschmann | 93e6ba0af7 | |
Matthias Kretschmann | c72ebd6749 | |
Matthias Kretschmann | e488b9f001 | |
Matthias Kretschmann | 4f051deefa | |
Jernej Pregelj | b4db8a6556 | |
Matthias Kretschmann | 55af9ad5ab | |
Matthias Kretschmann | 25ab6e0c42 | |
Matthias Kretschmann | 725b5884bb | |
Matthias Kretschmann | 0d6875f065 | |
Matthias Kretschmann | 57db99049f | |
Matthias Kretschmann | 0befc3a597 | |
Matthias Kretschmann | 87c54d2cb8 | |
Matthias Kretschmann | 01fb305612 | |
Matthias Kretschmann | 4ee5f19a9a | |
Matthias Kretschmann | 8bb8111aca | |
Matthias Kretschmann | 7b334b9104 | |
Matthias Kretschmann | ac2cd2eb70 | |
Jernej Pregelj | 84c0877c43 | |
Jernej Pregelj | 7cc2de7d8b | |
Matthias Kretschmann | 8d23868a9d | |
Matthias Kretschmann | ad454b9f8a | |
Jernej Pregelj | 9e7df28b89 | |
Jernej Pregelj | 85304c2d09 | |
Jernej Pregelj | cce2a7fad3 | |
Jernej Pregelj | adf52ceb77 | |
Matthias Kretschmann | d545bcaa30 | |
Matthias Kretschmann | 62c356d9e8 | |
Matthias Kretschmann | c97876336a | |
Matthias Kretschmann | edbc3276d7 | |
Matthias Kretschmann | 362a266518 | |
Matthias Kretschmann | 2a9d7476c8 | |
Matthias Kretschmann | 4ed72f382c | |
Matthias Kretschmann | 24d26e4b8b | |
Matthias Kretschmann | b6770e68de | |
Matthias Kretschmann | 64d58173c0 | |
Matthias Kretschmann | ca77e1ed94 | |
Matthias Kretschmann | 050936a0c1 | |
Matthias Kretschmann | fa078c6c4c | |
Matthias Kretschmann | 21b44fb425 | |
Matthias Kretschmann | cee49978c4 | |
Matthias Kretschmann | acb7ae4d35 | |
Matthias Kretschmann | 5adba86e5e | |
Matthias Kretschmann | 4b489811ac | |
Matthias Kretschmann | cb1e0ca624 | |
Matthias Kretschmann | 812854c19d | |
Matthias Kretschmann | 0dcbf05a9a | |
Matthias Kretschmann | a3838ba7c3 | |
Matthias Kretschmann | be847f4909 | |
Matthias Kretschmann | f5c01a8e30 | |
Jernej Pregelj | d7f40a631b | |
Jernej Pregelj | 2ad9e4f2d8 | |
Jernej Pregelj | 4c744d1ea9 | |
Jernej Pregelj | 6c8d22f56c | |
Jernej Pregelj | 4e8680a073 | |
Jernej Pregelj | 29aba3197d | |
Jernej Pregelj | eb21932604 | |
Jernej Pregelj | c367dd9e57 | |
Jernej Pregelj | 3c5f0ce401 | |
Jernej Pregelj | 28b4ce80ae | |
Jernej Pregelj | d343f58f8e | |
Jernej Pregelj | d169e76f8d | |
Jernej Pregelj | 40dab70331 | |
Jernej Pregelj | d4e361aa90 | |
Matthias Kretschmann | 22275bc9dd | |
Jernej Pregelj | fcff8c72cd | |
Matthias Kretschmann | 3d129b5415 | |
Matthias Kretschmann | 599e712181 | |
Matthias Kretschmann | 557cfcc8b5 | |
Matthias Kretschmann | c3673015db | |
Matthias Kretschmann | e33be03155 | |
Matthias Kretschmann | c6e791dabd | |
Matthias Kretschmann | a8a81226da | |
Matthias Kretschmann | 96e5363859 | |
Matthias Kretschmann | e60a46f72e | |
Matthias Kretschmann | cc53823279 | |
Matthias Kretschmann | c1cf01b834 | |
Matthias Kretschmann | af6da53c58 | |
Matthias Kretschmann | 2dfa8a0962 | |
Matthias Kretschmann | 9b9db4b655 | |
Matthias Kretschmann | 1c0f009d3e | |
Matthias Kretschmann | b320e31858 | |
Matthias Kretschmann | 87176212ef | |
Matthias Kretschmann | 0bc38610ee | |
Matthias Kretschmann | d240ee8eab | |
Jernej Pregelj | 3898dc307f | |
Jernej Pregelj | cb2fc05caa | |
Jernej Pregelj | 9a024b6004 | |
Matthias Kretschmann | 96990309e0 | |
Matthias Kretschmann | 57e9cd69ff | |
Jernej Pregelj | 49666eb420 | |
Jernej Pregelj | 5caa62ea57 | |
Jernej Pregelj | 643d5a3c84 | |
Matthias Kretschmann | 9a5ebd0a91 | |
Jernej Pregelj | 59ffac93a6 | |
Matthias Kretschmann | 0b51754954 | |
Matthias Kretschmann | dfb26d89b8 | |
Matthias Kretschmann | aaf3cff9ce | |
Jernej Pregelj | 91a611f834 | |
Jernej Pregelj | f38111073e | |
Jernej Pregelj | d7dadfb291 | |
Jernej Pregelj | 0ef8a88d30 | |
Jernej Pregelj | 67f736809b | |
Jernej Pregelj | eae754e6d7 | |
Jernej Pregelj | 08d50c0ce1 | |
Jernej Pregelj | 3cfb9755b4 | |
Jernej Pregelj | 9681d3848c | |
Jernej Pregelj | 406e039ad8 | |
Jernej Pregelj | e60ca7b941 | |
Jernej Pregelj | 3b3c08f549 | |
Jernej Pregelj | 24b68baa24 | |
Jernej Pregelj | 932b7b858b | |
Jernej Pregelj | 0cba776f02 | |
Matthias Kretschmann | 75a262f5d6 | |
Matthias Kretschmann | 1bda116c14 | |
Matthias Kretschmann | 7043266254 | |
Matthias Kretschmann | fd1482e6f5 | |
Matthias Kretschmann | 27dd656270 | |
Matthias Kretschmann | 18f7ab7ddc | |
Jernej Pregelj | e5960d3fd6 | |
Matthias Kretschmann | f55fc09495 | |
Matthias Kretschmann | d43afddc39 | |
Matthias Kretschmann | 74b8bc3f13 | |
Matthias Kretschmann | a4178854bb | |
Matthias Kretschmann | 996d986570 | |
Matthias Kretschmann | 3e912f9203 | |
Matthias Kretschmann | 512f06f7d4 | |
Matthias Kretschmann | 8e9a4c1fd2 | |
Matthias Kretschmann | 059ae62f96 | |
Matthias Kretschmann | 838757f5e8 | |
Matthias Kretschmann | 15ebb34931 | |
Matthias Kretschmann | d92c3e92f4 | |
Matthias Kretschmann | c4f862baa5 | |
Matthias Kretschmann | b8113798b6 | |
Matthias Kretschmann | 30249447ce | |
Jernej Pregelj | 667c46303c | |
Jernej Pregelj | d364a7beef | |
Matthias Kretschmann | c063ad82cb | |
Matthias Kretschmann | f699fa8db6 | |
Matthias Kretschmann | 6f7edfa30f | |
Matthias Kretschmann | 46e6d89057 | |
Matthias Kretschmann | 97d6c2756e | |
Matthias Kretschmann | 01d5bf703d | |
Matthias Kretschmann | 305e050391 | |
Matthias Kretschmann | d8f4ebe7b4 | |
Matthias Kretschmann | 81cb06e19b | |
Matthias Kretschmann | 8f73c08fdd | |
Matthias Kretschmann | 5eee8b61d2 | |
Matthias Kretschmann | 1ea527f2d1 | |
Matthias Kretschmann | 039f5da189 | |
Matthias Kretschmann | ac16107f6b | |
Matthias Kretschmann | c1b32830f7 | |
Matthias Kretschmann | 217eb80d0f | |
Matthias Kretschmann | d3bf27fddc | |
Matthias Kretschmann | dd6f6966ce | |
Matthias Kretschmann | 7dbe383269 | |
Matthias Kretschmann | e5ef417025 | |
Matthias Kretschmann | 7d727bcdf9 | |
Matthias Kretschmann | 4150e56ba3 | |
Matthias Kretschmann | 0c10eb5665 | |
Matthias Kretschmann | 04e6bb0c72 | |
Matthias Kretschmann | f230e3071c | |
Matthias Kretschmann | 4b919f2ee8 | |
Matthias Kretschmann | 97618c2ef2 | |
Matthias Kretschmann | c9f4871ffb | |
Matthias Kretschmann | 097cf8bd63 | |
Matthias Kretschmann | 264a066874 | |
Matthias Kretschmann | 1b336e2e80 | |
Matthias Kretschmann | 89b04e93fd | |
Matthias Kretschmann | eb59b9dfda | |
Matthias Kretschmann | ee4d1820ab | |
Matthias Kretschmann | e4994308ad | |
Javier Cortejoso | bf3f6e1517 | |
Matthias Kretschmann | 0820cb0bd7 | |
Matthias Kretschmann | 5f19fbe420 | |
Matthias Kretschmann | e4d2dbf772 | |
Matthias Kretschmann | 56f7dec9f6 | |
Matthias Kretschmann | f9b5ae6355 | |
Matthias Kretschmann | 273761944e | |
Matthias Kretschmann | 303a7bf12c | |
Matthias Kretschmann | 5a0689703d | |
Matthias Kretschmann | b27c458fb2 | |
Matthias Kretschmann | 56604b972c | |
Matthias Kretschmann | 1d1399248f | |
Matthias Kretschmann | 7b60127899 | |
Matthias Kretschmann | 3386a49bdb | |
Matthias Kretschmann | 9888d78f99 | |
Matthias Kretschmann | 4fd623f28e | |
Matthias Kretschmann | a1eb68b45a | |
Matthias Kretschmann | a5489a2e6c | |
Matthias Kretschmann | b90974938c | |
Matthias Kretschmann | 2d512f341e | |
Matthias Kretschmann | 340d608141 | |
Matthias Kretschmann | 1e6b334cdc | |
Matthias Kretschmann | da63ab1c37 | |
Matthias Kretschmann | b3657352aa | |
Matthias Kretschmann | ec887bebd7 | |
Jernej Pregelj | 6e0ffe4367 | |
Jernej Pregelj | 15b1bf846e | |
Matthias Kretschmann | f9a1da6a37 | |
Matthias Kretschmann | 5a8d1884d3 | |
Matthias Kretschmann | d3fc187d89 | |
Matthias Kretschmann | 1af720ffeb | |
Matthias Kretschmann | 043d9429ac | |
Matthias Kretschmann | 2395c3ff21 | |
Matthias Kretschmann | c742426b1a | |
Matthias Kretschmann | 321ae3742c | |
Matthias Kretschmann | a65be11c07 | |
Matthias Kretschmann | 41d6726bed | |
Jernej Pregelj | 8dadf21726 | |
Jernej Pregelj | dc32c71bba | |
Matthias Kretschmann | 2506939f62 | |
Matthias Kretschmann | d74a4c0cbc | |
Matthias Kretschmann | f8cb601eb7 | |
Matthias Kretschmann | be6c478ca7 | |
Matthias Kretschmann | 5e94d73197 | |
Matthias Kretschmann | 48d9b26cb6 | |
Matthias Kretschmann | 80b77461d3 | |
Matthias Kretschmann | fee5f1cf7a | |
Matthias Kretschmann | 5efd3bfaa0 | |
Matthias Kretschmann | 63b87cfb82 | |
Matthias Kretschmann | fe0506827f | |
Jernej Pregelj | 2687c78474 | |
Matthias Kretschmann | f0c3fd6865 | |
Matthias Kretschmann | 9abde21d3d | |
Matthias Kretschmann | 2247e2d980 | |
Matthias Kretschmann | c41e9790bb | |
Matthias Kretschmann | 144fce56a3 | |
Matthias Kretschmann | 64304644f4 | |
Matthias Kretschmann | 6a3efe9d16 | |
Matthias Kretschmann | f73fe0ab5e | |
Matthias Kretschmann | 8e3c0a62d2 | |
Matthias Kretschmann | 65f04b9f62 | |
Matthias Kretschmann | 9c352e740b | |
Matthias Kretschmann | 70ac182fd9 | |
Matthias Kretschmann | 66655adbf5 | |
Matthias Kretschmann | f8cff63c79 | |
Matthias Kretschmann | 9e15845995 | |
Matthias Kretschmann | c11fceaf17 | |
Matthias Kretschmann | 1b7d343984 | |
Matthias Kretschmann | 1000185841 | |
Matthias Kretschmann | 90c4590a8b | |
Matthias Kretschmann | 9f782adafc | |
Matthias Kretschmann | 3199d89d8d | |
Matthias Kretschmann | aaf425477f | |
Matthias Kretschmann | 90b163b2aa | |
Matthias Kretschmann | feebf7fc0c | |
Matthias Kretschmann | 54e4dc7e5d | |
Matthias Kretschmann | f9e367bfbc | |
Matthias Kretschmann | a283cd162b | |
Jernej Pregelj | 87b2fde0af | |
Jernej Pregelj | 4a7ddca9e8 | |
Jernej Pregelj | 988e03bcca | |
Matthias Kretschmann | 9540236ef0 | |
Jernej Pregelj | a94d7e1b6c | |
Matthias Kretschmann | 8497f6f9a2 | |
Matthias Kretschmann | 92721702a0 | |
Matthias Kretschmann | 7fc99699c7 | |
Matthias Kretschmann | 1b1ac5c9ef | |
Jernej Pregelj | 13c2c9b68a | |
Jernej Pregelj | 9795e6e642 | |
Jernej Pregelj | 36d61b3fc1 | |
Matthias Kretschmann | 7669545d13 | |
Matthias Kretschmann | 54f3f170c3 | |
Matthias Kretschmann | 1eaf6a1bf4 | |
Matthias Kretschmann | 2c280d79c5 | |
Matthias Kretschmann | 88872cc020 | |
Matthias Kretschmann | f2d69447bc | |
Matthias Kretschmann | f432ce4b2d | |
Matthias Kretschmann | 056ec23925 | |
Matthias Kretschmann | d6a7800cc4 | |
Matthias Kretschmann | 743fe533dc | |
Matthias Kretschmann | 01e68b6632 | |
Matthias Kretschmann | cda3c54f79 | |
Matthias Kretschmann | bf3378bc48 | |
Matthias Kretschmann | dfac82b3e0 | |
Matthias Kretschmann | d87d8daae7 | |
Matthias Kretschmann | 081772ce37 | |
Matthias Kretschmann | 7a2608f4f3 | |
Matthias Kretschmann | 879f51170e | |
Matthias Kretschmann | 0e12204a5a | |
Matthias Kretschmann | b2ae8fcce5 | |
Matthias Kretschmann | 7dca7f8e82 | |
Matthias Kretschmann | 10a86d389c | |
Matthias Kretschmann | d713ef11e4 | |
Matthias Kretschmann | 8856dca647 | |
Matthias Kretschmann | cbfc1bd1c7 | |
Matthias Kretschmann | fe39dec214 | |
Matthias Kretschmann | 7e2d7ac6ad | |
Matthias Kretschmann | 7a6075b553 | |
Matthias Kretschmann | c859ac098e | |
Matthias Kretschmann | cbb6fc6032 | |
sjvallon | eaf13b38a0 | |
Matthias Kretschmann | 21786a7d16 | |
Matthias Kretschmann | 7df6958123 | |
Matthias Kretschmann | 8c4fefcee1 | |
Matthias Kretschmann | f93da4576e | |
Matthias Kretschmann | 16df88aca3 | |
Matthias Kretschmann | d3e44be4e0 | |
Javier Cortejoso | 0eb35b2fa1 | |
Matthias Kretschmann | e6fc7a9085 | |
Matthias Kretschmann | 22440827ca | |
Matthias Kretschmann | a83184851c |
|
@ -1 +0,0 @@
|
|||
node_modules
|
|
@ -1,12 +0,0 @@
|
|||
root = true
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
indent_size = 4
|
||||
end_of_line = lf
|
||||
indent_style = space
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
[*.{json,yml,yaml,md}]
|
||||
indent_size = 2
|
29
.eslintrc
29
.eslintrc
|
@ -1,28 +1,43 @@
|
|||
{
|
||||
"parser": "@typescript-eslint/parser",
|
||||
"parserOptions": {
|
||||
"project": "./tsconfig.json"
|
||||
"project": [
|
||||
"./tsconfig.json",
|
||||
"./client/tsconfig.json",
|
||||
"./server/tsconfig.json",
|
||||
"./cypress/tsconfig.json"
|
||||
]
|
||||
},
|
||||
"extends": [
|
||||
"oceanprotocol",
|
||||
"oceanprotocol/react",
|
||||
"plugin:@typescript-eslint/eslint-recommended",
|
||||
"plugin:@typescript-eslint/recommended",
|
||||
"plugin:prettier/recommended",
|
||||
"prettier/react",
|
||||
"prettier/standard",
|
||||
"plugin:prettier/recommended",
|
||||
"plugin:@typescript-eslint/recommended",
|
||||
"prettier/@typescript-eslint"
|
||||
"prettier/@typescript-eslint",
|
||||
"plugin:cypress/recommended"
|
||||
],
|
||||
"plugins": ["@typescript-eslint", "prettier"],
|
||||
"plugins": ["@typescript-eslint", "prettier", "cypress"],
|
||||
"rules": {
|
||||
"@typescript-eslint/explicit-function-return-type": 0,
|
||||
"@typescript-eslint/member-delimiter-style": [
|
||||
"error",
|
||||
{ "multiline": { "delimiter": "none" } }
|
||||
]
|
||||
],
|
||||
"@typescript-eslint/no-explicit-any": "off"
|
||||
},
|
||||
"env": {
|
||||
"es6": true,
|
||||
"browser": true,
|
||||
"jest": true
|
||||
"node": true,
|
||||
"jest": true,
|
||||
"cypress/globals": true
|
||||
},
|
||||
"settings": {
|
||||
"react": {
|
||||
"version": "16.10"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: npm
|
||||
directory: "/server"
|
||||
schedule:
|
||||
interval: weekly
|
||||
time: '03:00'
|
||||
timezone: Europe/Berlin
|
||||
- package-ecosystem: npm
|
||||
directory: "/client"
|
||||
schedule:
|
||||
interval: weekly
|
||||
time: '03:00'
|
||||
timezone: Europe/Berlin
|
||||
- package-ecosystem: npm
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: weekly
|
||||
time: '03:00'
|
||||
timezone: Europe/Berlin
|
|
@ -12,6 +12,7 @@ dist
|
|||
|
||||
# misc
|
||||
.DS_Store
|
||||
.env
|
||||
.env.local
|
||||
.env.development.local
|
||||
.env.test.local
|
||||
|
@ -20,3 +21,10 @@ dist
|
|||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
|
||||
# cypress
|
||||
cypress/screenshots
|
||||
cypress/videos
|
||||
cypress/fixtures/did.txt
|
||||
cypress/fixtures/did-ipfs.txt
|
||||
artifacts
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
node_modules
|
||||
build
|
||||
dist
|
||||
coverage
|
||||
|
|
14
.prettierrc
14
.prettierrc
|
@ -1,5 +1,15 @@
|
|||
{
|
||||
"semi": false,
|
||||
"singleQuote": true,
|
||||
"trailingComma": "none"
|
||||
}
|
||||
"trailingComma": "none",
|
||||
"tabWidth": 4,
|
||||
"endOfLine": "lf",
|
||||
"overrides": [
|
||||
{
|
||||
"files": ["*.{json,yml,yaml,md}"],
|
||||
"options": {
|
||||
"tabWidth": 2
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
11
.stylelintrc
11
.stylelintrc
|
@ -1,11 +0,0 @@
|
|||
{
|
||||
"extends": [
|
||||
"stylelint-config-bigchaindb",
|
||||
"stylelint-config-css-modules",
|
||||
"./node_modules/prettier-stylelint/config.js"
|
||||
],
|
||||
"syntax": "scss",
|
||||
"rules": {
|
||||
"no-descending-specificity": null
|
||||
}
|
||||
}
|
81
.travis.yml
81
.travis.yml
|
@ -1,29 +1,86 @@
|
|||
dist: xenial
|
||||
sudo: required
|
||||
language: node_js
|
||||
node_js:
|
||||
- '11'
|
||||
- '12'
|
||||
|
||||
services:
|
||||
- docker
|
||||
|
||||
addons:
|
||||
# required for internal Aquarius-Brizo communication
|
||||
# https://docs.travis-ci.com/user/hosts/
|
||||
hosts:
|
||||
- aquarius
|
||||
apt:
|
||||
packages:
|
||||
# for Cypress
|
||||
- libgconf-2-4
|
||||
|
||||
env:
|
||||
global:
|
||||
# run E2E tests against local Spree
|
||||
- REACT_APP_NODE_URI="http://localhost:8545"
|
||||
- REACT_APP_AQUARIUS_URI="http://aquarius:5000"
|
||||
- REACT_APP_BRIZO_URI="http://localhost:8030"
|
||||
- REACT_APP_SECRET_STORE_URI="http://localhost:12001"
|
||||
- REACT_APP_FAUCET_URI="http://localhost:3001"
|
||||
- REACT_APP_BRIZO_ADDRESS="0x068ed00cf0441e4829d9784fcbe7b9e26d4bd8d0"
|
||||
|
||||
# IPFS client & server config
|
||||
- REACT_APP_IPFS_GATEWAY_URI="https://ipfs.oceanprotocol.com"
|
||||
- REACT_APP_IPFS_NODE_URI="https://ipfs.oceanprotocol.com:443"
|
||||
- IPFS_GATEWAY_URI="https://ipfs.oceanprotocol.com"
|
||||
|
||||
# start Barge with these versions
|
||||
- BRIZO_VERSION=v0.9.3
|
||||
- AQUARIUS_VERSION=v1.0.7
|
||||
- KEEPER_VERSION=v0.13.2
|
||||
- EVENTS_HANDLER_VERSION=v0.4.5
|
||||
- KEEPER_OWNER_ROLE_ADDRESS="0xe2DD09d719Da89e5a3D0F2549c7E24566e947260"
|
||||
- FAUCET_TIMESPAN=0
|
||||
|
||||
before_install:
|
||||
- npm install -g npm
|
||||
- npm install -g codacy-coverage
|
||||
# Fixes an issue where the max file watch count is exceeded, triggering ENOSPC
|
||||
# https://stackoverflow.com/questions/22475849/node-js-error-enospc#32600959
|
||||
- echo fs.inotify.max_user_watches=524288 | sudo tee -a /etc/sysctl.conf && sudo sysctl -p
|
||||
|
||||
before_script:
|
||||
- curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
|
||||
- chmod +x ./cc-test-reporter
|
||||
- ./cc-test-reporter before-build
|
||||
- git clone https://github.com/oceanprotocol/barge
|
||||
- cd barge
|
||||
- bash -x start_ocean.sh --no-commons 2>&1 > start_ocean.log &
|
||||
- cd ..
|
||||
|
||||
script:
|
||||
# - ./scripts/install.sh # runs automatically with npm ci
|
||||
# executing `npm test` scripts individually here, so first one failing will exit the build
|
||||
- npm run lint || travis_terminate 1
|
||||
- ./scripts/keeper.sh
|
||||
- ./scripts/test.sh
|
||||
- ./scripts/coverage.sh
|
||||
# Pipe the coverage data to Code Climate
|
||||
- ./cc-test-reporter format-coverage -t lcov -o coverage/codeclimate.client.json client/coverage/lcov.info
|
||||
- ./cc-test-reporter format-coverage -t lcov -o coverage/codeclimate.server.json server/coverage/lcov.info
|
||||
- ./cc-test-reporter sum-coverage coverage/codeclimate.*.json -p 2
|
||||
- if [[ "$TRAVIS_TEST_RESULT" == 0 ]]; then ./cc-test-reporter upload-coverage; fi
|
||||
- npm run test:e2e || travis_terminate 1
|
||||
- ./scripts/build.sh
|
||||
|
||||
notifications:
|
||||
email: false
|
||||
|
||||
cache:
|
||||
npm: true
|
||||
directories:
|
||||
- node_modules
|
||||
|
||||
deploy:
|
||||
- provider: script
|
||||
skip_cleanup: true
|
||||
script: bash -ex ./scripts/deploy_on_k8s.sh
|
||||
on:
|
||||
tags: true
|
||||
all_branches: true
|
||||
# cache folder with Cypress binary
|
||||
- ~/.cache
|
||||
# deploy:
|
||||
# - provider: script
|
||||
# skip_cleanup: true
|
||||
# script: bash -ex ./scripts/deploy_on_k8s.sh
|
||||
# on:
|
||||
# tags: true
|
||||
# all_branches: true
|
||||
|
|
464
CHANGELOG.md
464
CHANGELOG.md
|
@ -4,6 +4,463 @@ All notable changes to this project will be documented in this file. Dates are d
|
|||
|
||||
Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
||||
|
||||
#### [v2.4.1](https://github.com/oceanprotocol/commons/compare/v2.4.0...v2.4.1)
|
||||
|
||||
> 19 May 2020
|
||||
|
||||
- fix history [`#282`](https://github.com/oceanprotocol/commons/pull/282)
|
||||
|
||||
#### [v2.4.0](https://github.com/oceanprotocol/commons/compare/v2.3.1...v2.4.0)
|
||||
|
||||
> 19 May 2020
|
||||
|
||||
- Feature/compute [`#225`](https://github.com/oceanprotocol/commons/pull/225)
|
||||
- remove stylelint & codacy [`#270`](https://github.com/oceanprotocol/commons/pull/270)
|
||||
- Bump typescript from 3.8.3 to 3.9.2 in /client [`#256`](https://github.com/oceanprotocol/commons/pull/256)
|
||||
- Bump @sindresorhus/slugify from 0.11.0 to 1.0.0 in /client [`#255`](https://github.com/oceanprotocol/commons/pull/255)
|
||||
- Bump cypress from 4.2.0 to 4.5.0 [`#250`](https://github.com/oceanprotocol/commons/pull/250)
|
||||
- Bump @types/jest from 25.1.4 to 25.2.2 in /client [`#240`](https://github.com/oceanprotocol/commons/pull/240)
|
||||
- Bump @typescript-eslint/eslint-plugin from 2.24.0 to 2.33.0 [`#231`](https://github.com/oceanprotocol/commons/pull/231)
|
||||
- Bump start-server-and-test from 1.10.10 to 1.11.0 [`#228`](https://github.com/oceanprotocol/commons/pull/228)
|
||||
- [Security] Bump handlebars from 4.5.3 to 4.7.6 [`#227`](https://github.com/oceanprotocol/commons/pull/227)
|
||||
- Bump release-it from 13.1.1 to 13.6.0 [`#226`](https://github.com/oceanprotocol/commons/pull/226)
|
||||
- bump to squid-js v2.2.0 [`91821e8`](https://github.com/oceanprotocol/commons/commit/91821e88d4e4ff1bb6814338b3d9fee4746fd9a8)
|
||||
- Release 2.4.0 [`c0effd4`](https://github.com/oceanprotocol/commons/commit/c0effd449f7cc01cf043ab924bb8040d0db55b9b)
|
||||
- Merge pull request #281 from oceanprotocol/dependabot/npm_and_yarn/client/react-router-dom-5.2.0 [`6f05baf`](https://github.com/oceanprotocol/commons/commit/6f05baff3af9fa7490100b79b2978ed56ece02f4)
|
||||
|
||||
#### [v2.3.1](https://github.com/oceanprotocol/commons/compare/v2.3.0...v2.3.1)
|
||||
|
||||
> 20 March 2020
|
||||
|
||||
- package updates [`#223`](https://github.com/oceanprotocol/commons/pull/223)
|
||||
- Bump acorn from 5.7.3 to 5.7.4 in /server [`#222`](https://github.com/oceanprotocol/commons/pull/222)
|
||||
- Bump acorn from 5.7.3 to 5.7.4 in /client [`#221`](https://github.com/oceanprotocol/commons/pull/221)
|
||||
- Bump acorn from 7.1.0 to 7.1.1 [`#220`](https://github.com/oceanprotocol/commons/pull/220)
|
||||
- more package updates [`192c541`](https://github.com/oceanprotocol/commons/commit/192c54134ab7e26b85ee09ad94de01cfa8efc514)
|
||||
- Release 2.3.1 [`f630771`](https://github.com/oceanprotocol/commons/commit/f63077181e8094546d68ee66dc8f6d3bd33c5df6)
|
||||
- lint fixes [`b7c6543`](https://github.com/oceanprotocol/commons/commit/b7c6543fbefb6b5b701d3e879bcbd79e09255a7b)
|
||||
|
||||
#### [v2.3.0](https://github.com/oceanprotocol/commons/compare/v2.2.0...v2.3.0)
|
||||
|
||||
> 20 February 2020
|
||||
|
||||
- bump to squid.js v2 beta [`#218`](https://github.com/oceanprotocol/commons/pull/218)
|
||||
- Release 2.3.0 [`f143a59`](https://github.com/oceanprotocol/commons/commit/f143a59b0b3f911bffdc9535ad4fe9cfd345864d)
|
||||
- update ocean.assets methods [`c669089`](https://github.com/oceanprotocol/commons/commit/c669089d3b2be3d304e1ef8ed1b6827c0cb75ec8)
|
||||
|
||||
#### [v2.2.0](https://github.com/oceanprotocol/commons/compare/v2.1.0...v2.2.0)
|
||||
|
||||
> 1 February 2020
|
||||
|
||||
- bump to react-scripts v3.3 [`#209`](https://github.com/oceanprotocol/commons/pull/209)
|
||||
- package updates [`65b72e5`](https://github.com/oceanprotocol/commons/commit/65b72e597d16f8660f74b0b3a491aba723488a56)
|
||||
- fix Travis [`3e814b9`](https://github.com/oceanprotocol/commons/commit/3e814b98a7f990cfee6b910f57eb02cdd1a767f1)
|
||||
- package updates [`8089a7a`](https://github.com/oceanprotocol/commons/commit/8089a7aa3e4504e1defb3a6809e4d8b4c2a823fb)
|
||||
|
||||
#### [v2.1.0](https://github.com/oceanprotocol/commons/compare/v2.1.0-beta.0...v2.1.0)
|
||||
|
||||
> 23 January 2020
|
||||
|
||||
- Fix search code duplication [`#216`](https://github.com/oceanprotocol/commons/pull/216)
|
||||
- bump to keeper-contracts v0.13 [`#210`](https://github.com/oceanprotocol/commons/pull/210)
|
||||
- more additionalInformation checks [`#213`](https://github.com/oceanprotocol/commons/pull/213)
|
||||
- remove editorconfig [`#211`](https://github.com/oceanprotocol/commons/pull/211)
|
||||
- bump to keeper-contracts v0.13.0 [`5ba5cd9`](https://github.com/oceanprotocol/commons/commit/5ba5cd9e20f7bc7ad7aebeb4b9c54f0aea549786)
|
||||
- fix code duplication [`c5ea3b7`](https://github.com/oceanprotocol/commons/commit/c5ea3b7c8a989b7c9239cc4292de53680b36c06b)
|
||||
- bump all components [`37296c5`](https://github.com/oceanprotocol/commons/commit/37296c502e24a1e0aedc021bfa666dd33dce323d)
|
||||
|
||||
#### [v2.1.0-beta.0](https://github.com/oceanprotocol/commons/compare/v2.0.1...v2.1.0-beta.0)
|
||||
|
||||
> 17 December 2019
|
||||
|
||||
- bump to keeper-contracts v0.13.0 [`c4219bf`](https://github.com/oceanprotocol/commons/commit/c4219bf1a839e88024c3b7a87f95833b40769d58)
|
||||
- Release 2.1.0-beta.0 [`64eb7ab`](https://github.com/oceanprotocol/commons/commit/64eb7ab3f2dbd3f5b9736cab67bad4f960c914ff)
|
||||
|
||||
#### [v2.0.1](https://github.com/oceanprotocol/commons/compare/v2.0.0...v2.0.1)
|
||||
|
||||
> 7 January 2020
|
||||
|
||||
- more additionalInformation checks [`#213`](https://github.com/oceanprotocol/commons/pull/213)
|
||||
- remove editorconfig [`#211`](https://github.com/oceanprotocol/commons/pull/211)
|
||||
- remove editorconfig, define all styling in prettierrc [`f8dfaa4`](https://github.com/oceanprotocol/commons/commit/f8dfaa438c42e9d6c25ae9ac096129da95e431c3)
|
||||
- Release 2.0.1 [`e9e5dd9`](https://github.com/oceanprotocol/commons/commit/e9e5dd9049bd60041d1483f102fdd6749b5a9b70)
|
||||
|
||||
#### [v2.0.0](https://github.com/oceanprotocol/commons/compare/v2.0.0-beta.3...v2.0.0)
|
||||
|
||||
> 9 December 2019
|
||||
|
||||
- Migrate to new v2 DDO structure [`#207`](https://github.com/oceanprotocol/commons/pull/207)
|
||||
- bump dependencies [`a8c695e`](https://github.com/oceanprotocol/commons/commit/a8c695e16f07b603250aa0eae5aa64d6275072b6)
|
||||
- test and package fixes [`3df046b`](https://github.com/oceanprotocol/commons/commit/3df046bbea14c0d0b4817976b8496c5af365bc0d)
|
||||
- Release 2.0.0 [`70a3339`](https://github.com/oceanprotocol/commons/commit/70a3339f8b0fdbabad1475659639f145ec68ed6c)
|
||||
|
||||
#### [v2.0.0-beta.3](https://github.com/oceanprotocol/commons/compare/v2.0.0-beta.2...v2.0.0-beta.3)
|
||||
|
||||
> 22 November 2019
|
||||
|
||||
- bump web3 packages [`8c3262c`](https://github.com/oceanprotocol/commons/commit/8c3262c1d91727dcb514ff049d8db5f48e812fed)
|
||||
- bump packages [`5800027`](https://github.com/oceanprotocol/commons/commit/5800027cbf4461cb274ce182e3350e3a1c4b708c)
|
||||
- update to new DDO structure [`985803d`](https://github.com/oceanprotocol/commons/commit/985803d43e4a3d729d90196f260b128bf2e37f63)
|
||||
|
||||
#### [v2.0.0-beta.2](https://github.com/oceanprotocol/commons/compare/v2.0.0-beta.1...v2.0.0-beta.2)
|
||||
|
||||
> 15 November 2019
|
||||
|
||||
- bump packages [`428532e`](https://github.com/oceanprotocol/commons/commit/428532e2c624fed19bae342b40fdb0f5d9a403d3)
|
||||
- Release 2.0.0-beta.2 [`9f55d0a`](https://github.com/oceanprotocol/commons/commit/9f55d0a69577ee64fe8fd6ce9889e31f90fd1562)
|
||||
- bump squid-js [`b75af1b`](https://github.com/oceanprotocol/commons/commit/b75af1bae3f05006ea557c6de05dfe3ddea555eb)
|
||||
|
||||
#### [v2.0.0-beta.1](https://github.com/oceanprotocol/commons/compare/v2.0.0-beta.0...v2.0.0-beta.1)
|
||||
|
||||
> 14 November 2019
|
||||
|
||||
- bump web3 packages [`13a8bf8`](https://github.com/oceanprotocol/commons/commit/13a8bf86a56d3bddca44aa505a27e95507069238)
|
||||
- Release 2.0.0-beta.1 [`cf9d65d`](https://github.com/oceanprotocol/commons/commit/cf9d65da3f353db60da331f8d553e3e19f849d15)
|
||||
|
||||
#### [v2.0.0-beta.0](https://github.com/oceanprotocol/commons/compare/v1.3.2...v2.0.0-beta.0)
|
||||
|
||||
> 14 November 2019
|
||||
|
||||
- update to new DDO structure [`e34dde1`](https://github.com/oceanprotocol/commons/commit/e34dde1a111d00943dc68d32c04b8fa230996d6d)
|
||||
- Release 2.0.0-beta.0 [`0136695`](https://github.com/oceanprotocol/commons/commit/0136695051fe9f753946f1b7de4a55264e3cb174)
|
||||
- contentLength as string [`3d9935b`](https://github.com/oceanprotocol/commons/commit/3d9935b46553143ed1fad6ee6e6b80c23ca6e59e)
|
||||
|
||||
#### [v1.3.2](https://github.com/oceanprotocol/commons/compare/v1.3.1...v1.3.2)
|
||||
|
||||
> 22 November 2019
|
||||
|
||||
- Release 1.3.2 [`b02cda0`](https://github.com/oceanprotocol/commons/commit/b02cda043c33c00174e4e4f3ec56e7d0aa5386da)
|
||||
- bump to squid-js v0.8.3 [`8ca727f`](https://github.com/oceanprotocol/commons/commit/8ca727fffc2cc137b978b7d65ed586da405b015b)
|
||||
|
||||
#### [v1.3.1](https://github.com/oceanprotocol/commons/compare/v1.3.0...v1.3.1)
|
||||
|
||||
> 7 November 2019
|
||||
|
||||
- Bump squid [`#206`](https://github.com/oceanprotocol/commons/pull/206)
|
||||
- bump squid [`ccdef81`](https://github.com/oceanprotocol/commons/commit/ccdef8143ea2f6062c4ffbe65451fdce7c5c40e3)
|
||||
- downgrade @typescript-eslint packages [`afd4ec9`](https://github.com/oceanprotocol/commons/commit/afd4ec991f384596d26e63f2dcb710eda648457e)
|
||||
- Release 1.3.1 [`c8a46a5`](https://github.com/oceanprotocol/commons/commit/c8a46a5316c811766907a0b5866989e750b2ff0a)
|
||||
|
||||
#### [v1.3.0](https://github.com/oceanprotocol/commons/compare/v1.2.2...v1.3.0)
|
||||
|
||||
> 1 November 2019
|
||||
|
||||
- bump packages [`#204`](https://github.com/oceanprotocol/commons/pull/204)
|
||||
- lock to react-scripts 3.0.1 [`da9237e`](https://github.com/oceanprotocol/commons/commit/da9237ea46fd8bc5af26b168bc9a1cd1708fe122)
|
||||
- web3 1.2.2 & truffle-hd-wallet updates, simplify types [`aec1f78`](https://github.com/oceanprotocol/commons/commit/aec1f782574077510fcad323e87e6c72b3cf039a)
|
||||
- more test fixes [`fe4f223`](https://github.com/oceanprotocol/commons/commit/fe4f2233f09240c63351f03209d1588fcb7b0dcb)
|
||||
|
||||
#### [v1.2.2](https://github.com/oceanprotocol/commons/compare/v1.2.1...v1.2.2)
|
||||
|
||||
> 24 October 2019
|
||||
|
||||
- IPFS fixes [`#203`](https://github.com/oceanprotocol/commons/pull/203)
|
||||
- stream files when adding [`77deaf0`](https://github.com/oceanprotocol/commons/commit/77deaf063e2ef3c6650fe7238acae3749bea2a1b)
|
||||
- Release 1.2.2 [`ae34031`](https://github.com/oceanprotocol/commons/commit/ae34031e9f2cd1a6aea801d50149156baeb41609)
|
||||
- lazy load IPFS component [`4319115`](https://github.com/oceanprotocol/commons/commit/4319115e0015e888587f2d6538e1301936385137)
|
||||
|
||||
#### [v1.2.1](https://github.com/oceanprotocol/commons/compare/v1.2.0...v1.2.1)
|
||||
|
||||
> 15 October 2019
|
||||
|
||||
- package fixes [`78d4c8b`](https://github.com/oceanprotocol/commons/commit/78d4c8b874ac1764c219a80231c6d06d02539ff7)
|
||||
- hotfix for Docker build [`8aadcb9`](https://github.com/oceanprotocol/commons/commit/8aadcb9d97f3f6b4b8344718d4f5bd604de0ae39)
|
||||
- Docker tweaks [`9226bf2`](https://github.com/oceanprotocol/commons/commit/9226bf2799b7c85a0c85e42c537cc53de9eabead)
|
||||
|
||||
#### [v1.2.0](https://github.com/oceanprotocol/commons/compare/v1.1.4...v1.2.0)
|
||||
|
||||
> 14 October 2019
|
||||
|
||||
- Add files to IPFS during publish flow [`#191`](https://github.com/oceanprotocol/commons/pull/191)
|
||||
- working prototype of adding files to IPFS during publish flow [`1c59d49`](https://github.com/oceanprotocol/commons/commit/1c59d49d5dddcf28ed015ede4a132e6498e91711)
|
||||
- new client package-lock [`725215b`](https://github.com/oceanprotocol/commons/commit/725215b6ee0b065855f55b7124340abf63a0b357)
|
||||
- bump IPFS packages [`af8df22`](https://github.com/oceanprotocol/commons/commit/af8df224cb08e052605090f96c9a730f672a6a47)
|
||||
|
||||
#### [v1.1.4](https://github.com/oceanprotocol/commons/compare/v1.1.3...v1.1.4)
|
||||
|
||||
> 14 October 2019
|
||||
|
||||
- Faucet route refactor [`#202`](https://github.com/oceanprotocol/commons/pull/202)
|
||||
- Put Channels behind feature switch [`#201`](https://github.com/oceanprotocol/commons/pull/201)
|
||||
- put channels behind feature switch [`a7209f6`](https://github.com/oceanprotocol/commons/commit/a7209f690d925d74c57b8c61498d3cea522d8f70)
|
||||
- more dynamic intro text [`e007ab2`](https://github.com/oceanprotocol/commons/commit/e007ab20901e2155bd891fd77e2d1aa98daee5f9)
|
||||
- Release 1.1.4 [`10b6623`](https://github.com/oceanprotocol/commons/commit/10b662343faa4a27bc8259f1406cf622c2c8ac67)
|
||||
|
||||
#### [v1.1.3](https://github.com/oceanprotocol/commons/compare/v1.1.2...v1.1.3)
|
||||
|
||||
> 8 October 2019
|
||||
|
||||
- switch Barge to --no-commons flag [`#200`](https://github.com/oceanprotocol/commons/pull/200)
|
||||
- added token faucet functionality [`#199`](https://github.com/oceanprotocol/commons/pull/199)
|
||||
- prettier [`3235dc1`](https://github.com/oceanprotocol/commons/commit/3235dc1d5e24f314e6d9b2886d709eadc25913df)
|
||||
- - increased token amount given [`aeb24aa`](https://github.com/oceanprotocol/commons/commit/aeb24aadda30934785436a0501d57e71a69f2708)
|
||||
- Release 1.1.3 [`8f0988e`](https://github.com/oceanprotocol/commons/commit/8f0988e1b0978dc58a235edbd70bf742cb41e511)
|
||||
|
||||
#### [v1.1.2](https://github.com/oceanprotocol/commons/compare/v1.1.1...v1.1.2)
|
||||
|
||||
> 24 September 2019
|
||||
|
||||
- show web3 message on asset loading failure [`#198`](https://github.com/oceanprotocol/commons/pull/198)
|
||||
- Release 1.1.2 [`29e6e8b`](https://github.com/oceanprotocol/commons/commit/29e6e8b5afdc2d085b45aa51049b9b59e501e293)
|
||||
|
||||
#### [v1.1.1](https://github.com/oceanprotocol/commons/compare/v1.1.0...v1.1.1)
|
||||
|
||||
> 13 September 2019
|
||||
|
||||
- fix error output on asset details loading [`#196`](https://github.com/oceanprotocol/commons/pull/196)
|
||||
- fix event bubbling on wallet selector button [`#197`](https://github.com/oceanprotocol/commons/issues/197)
|
||||
- asset details refactor [`821f80d`](https://github.com/oceanprotocol/commons/commit/821f80da0f6c9bda862472f2a2b094a92a73ce6e)
|
||||
- Release 1.1.1 [`33b14bc`](https://github.com/oceanprotocol/commons/commit/33b14bc8e346c18e853585cd79770776d24b20ed)
|
||||
- test fixes [`12f6cfc`](https://github.com/oceanprotocol/commons/commit/12f6cfcb8049fb035bcbeabe099af51329334667)
|
||||
|
||||
#### [v1.1.0](https://github.com/oceanprotocol/commons/compare/v1.0.2...v1.1.0)
|
||||
|
||||
> 11 September 2019
|
||||
|
||||
- bump to squid-js v0.7.2 [`#189`](https://github.com/oceanprotocol/commons/pull/189)
|
||||
- get faucet network from response [`#195`](https://github.com/oceanprotocol/commons/pull/195)
|
||||
- add code climate [`#194`](https://github.com/oceanprotocol/commons/pull/194)
|
||||
- Disable auto-deployments for now [`#193`](https://github.com/oceanprotocol/commons/pull/193)
|
||||
- code fixes [`1f7845a`](https://github.com/oceanprotocol/commons/commit/1f7845aa221b486abb0f51bdc156d2bed5c0e16a)
|
||||
- Release 1.1.0 [`c4029b1`](https://github.com/oceanprotocol/commons/commit/c4029b147c2bda0a846a2365f1d96555eabb454b)
|
||||
- disable auto-deployments for now [`4ae344a`](https://github.com/oceanprotocol/commons/commit/4ae344a861c76527bce8eacb55d86e83cc7c6ae9)
|
||||
|
||||
#### [v1.0.2](https://github.com/oceanprotocol/commons/compare/v1.0.1...v1.0.2)
|
||||
|
||||
> 2 September 2019
|
||||
|
||||
- Fix vulnerabilities [`#190`](https://github.com/oceanprotocol/commons/pull/190)
|
||||
- Fix faucet on consume, publish category warning [`#185`](https://github.com/oceanprotocol/commons/pull/185)
|
||||
- Consume hang fix [`#184`](https://github.com/oceanprotocol/commons/pull/184)
|
||||
- Optional pricing [`#182`](https://github.com/oceanprotocol/commons/pull/182)
|
||||
- package updates and test fixes [`#179`](https://github.com/oceanprotocol/commons/pull/179)
|
||||
- Stop wallet event propagation [`#181`](https://github.com/oceanprotocol/commons/pull/181)
|
||||
- bump packages, fresh package-lock [`e2aef49`](https://github.com/oceanprotocol/commons/commit/e2aef49256047834cee004e4c5ca2a03a6d7bf2a)
|
||||
- bump packages [`b3ee23e`](https://github.com/oceanprotocol/commons/commit/b3ee23e728ab3654ad054eb166cb5e6a73ba9c4e)
|
||||
- bump packages [`509a69b`](https://github.com/oceanprotocol/commons/commit/509a69b53d773a4db77e788ffc0673ed2a846633)
|
||||
|
||||
#### [v1.0.1](https://github.com/oceanprotocol/commons/compare/v1.0.0...v1.0.1)
|
||||
|
||||
> 18 July 2019
|
||||
|
||||
- Update About page [`#180`](https://github.com/oceanprotocol/commons/pull/180)
|
||||
- update about text [`8d06a67`](https://github.com/oceanprotocol/commons/commit/8d06a67e7fe24a4e420666e78d173b40feb7818b)
|
||||
- Release 1.0.1 [`3cafd60`](https://github.com/oceanprotocol/commons/commit/3cafd60b07cbe73983e898d1cd89afd1a8e7e051)
|
||||
|
||||
### [v1.0.0](https://github.com/oceanprotocol/commons/compare/v0.6.3...v1.0.0)
|
||||
|
||||
> 17 July 2019
|
||||
|
||||
- Wallet selection [`#176`](https://github.com/oceanprotocol/commons/pull/176)
|
||||
- Updated the script to deploy on pacific-ocean [`#178`](https://github.com/oceanprotocol/commons/pull/178)
|
||||
- run tests against Aquarius & Brizo pacific test instances [`#173`](https://github.com/oceanprotocol/commons/pull/173)
|
||||
- Modal fixes [`#177`](https://github.com/oceanprotocol/commons/pull/177)
|
||||
- remove wallet setup from Cypress [`01fb305`](https://github.com/oceanprotocol/commons/commit/01fb305612a4c85190f569870cc1ef37a2c4593d)
|
||||
- allow login to wallets [`adf52ce`](https://github.com/oceanprotocol/commons/commit/adf52ceb77302d5a7ebe4e866766cc540f51a778)
|
||||
- fix re-renders caused by withTracker HOC [`ca58d7d`](https://github.com/oceanprotocol/commons/commit/ca58d7d0b170913352936a47cb33661f06123abb)
|
||||
|
||||
#### [v0.6.3](https://github.com/oceanprotocol/commons/compare/v0.6.2...v0.6.3)
|
||||
|
||||
> 9 July 2019
|
||||
|
||||
- Release 0.6.3 [`edbc327`](https://github.com/oceanprotocol/commons/commit/edbc3276d75b5858278be050d65d5fefcf48aaae)
|
||||
- server: adapt to new tsc output [`362a266`](https://github.com/oceanprotocol/commons/commit/362a26651822f450d4b9a528c7fa46d4b9bbbfba)
|
||||
|
||||
#### [v0.6.2](https://github.com/oceanprotocol/commons/compare/v0.6.1...v0.6.2)
|
||||
|
||||
> 9 July 2019
|
||||
|
||||
- Release 0.6.2 [`2a9d747`](https://github.com/oceanprotocol/commons/commit/2a9d7476c8a3038e2edcadc36df8861921512f2a)
|
||||
- server build fix [`4ed72f3`](https://github.com/oceanprotocol/commons/commit/4ed72f382c2c0ea0ee5fedc0bdb6050555b88361)
|
||||
|
||||
#### [v0.6.1](https://github.com/oceanprotocol/commons/compare/v0.6.0...v0.6.1)
|
||||
|
||||
> 9 July 2019
|
||||
|
||||
- Reporting data sets [`#172`](https://github.com/oceanprotocol/commons/pull/172)
|
||||
- email sending via sendgrid [`cee4997`](https://github.com/oceanprotocol/commons/commit/cee49978c495a64b20e3a5f3a3ae296dbef140dd)
|
||||
- send Slack message [`fa078c6`](https://github.com/oceanprotocol/commons/commit/fa078c6c4c5677a3f7bc98751c5c726f377a1e00)
|
||||
- add Modal component [`cb1e0ca`](https://github.com/oceanprotocol/commons/commit/cb1e0ca624a6a0aa72b87cf913f581efbe81d320)
|
||||
|
||||
#### [v0.6.0](https://github.com/oceanprotocol/commons/compare/v0.5.4...v0.6.0)
|
||||
|
||||
> 4 July 2019
|
||||
|
||||
- default all connections to Pacific [`#164`](https://github.com/oceanprotocol/commons/pull/164)
|
||||
- fix version tags, fixed squid-js [`#166`](https://github.com/oceanprotocol/commons/pull/166)
|
||||
- Connect to pacific [`#167`](https://github.com/oceanprotocol/commons/pull/167)
|
||||
- Cypress cleanup & fixes [`#165`](https://github.com/oceanprotocol/commons/pull/165)
|
||||
- End-to-end testing setup with Cypress [`#134`](https://github.com/oceanprotocol/commons/pull/134)
|
||||
- fix web3 version + use truffle-hdwallet [`d364a7b`](https://github.com/oceanprotocol/commons/commit/d364a7beef5dd547b2d41f2907736481734b1c8b)
|
||||
- add tests [`e5960d3`](https://github.com/oceanprotocol/commons/commit/e5960d3fd621ebe3d7af267d98cfcce1262e93fb)
|
||||
- fresh package-lock [`9b9db4b`](https://github.com/oceanprotocol/commons/commit/9b9db4b655b10d2255201a2abc37b234be2e9c68)
|
||||
|
||||
#### [v0.5.4](https://github.com/oceanprotocol/commons/compare/v0.5.3...v0.5.4)
|
||||
|
||||
> 25 June 2019
|
||||
|
||||
- bump to squid-js v0.6.0 [`#163`](https://github.com/oceanprotocol/commons/pull/163)
|
||||
- switch to axios for file url check [`#162`](https://github.com/oceanprotocol/commons/pull/162)
|
||||
- switch to axios for file publish [`7043266`](https://github.com/oceanprotocol/commons/commit/70432662542a4de24133bfdd8906e569adfeb606)
|
||||
- Release 0.5.4 [`9699030`](https://github.com/oceanprotocol/commons/commit/96990309e044bc2355951b9c72e0f7cefdf82feb)
|
||||
- bump to squid-js v0.6.2 [`57e9cd6`](https://github.com/oceanprotocol/commons/commit/57e9cd69ffcbdb341f39349d44ea3aa785f51f65)
|
||||
|
||||
#### [v0.5.3](https://github.com/oceanprotocol/commons/compare/v0.5.2...v0.5.3)
|
||||
|
||||
> 19 June 2019
|
||||
|
||||
- SEO component [`#159`](https://github.com/oceanprotocol/commons/pull/159)
|
||||
- Release 0.5.3 [`75a262f`](https://github.com/oceanprotocol/commons/commit/75a262f5d633bd0f053ead0b5fd44d4ad56bd029)
|
||||
- add robots.txt [`3024944`](https://github.com/oceanprotocol/commons/commit/30249447ceb7ccbc2b9347d7a757a93cd690fcbd)
|
||||
|
||||
#### [v0.5.2](https://github.com/oceanprotocol/commons/compare/v0.5.1...v0.5.2)
|
||||
|
||||
> 19 June 2019
|
||||
|
||||
- add config values for Pacific connection [`#161`](https://github.com/oceanprotocol/commons/pull/161)
|
||||
- Refactor VersionNumbers to be sourced from squid-js [`#160`](https://github.com/oceanprotocol/commons/pull/160)
|
||||
- output overall status [`059ae62`](https://github.com/oceanprotocol/commons/commit/059ae62f967f40d9635cc729d31ab84fa913df8b)
|
||||
- switch to using squid-js for version numbers [`c4f862b`](https://github.com/oceanprotocol/commons/commit/c4f862baa5fa835ec3ff3aafeefa60f524d011b2)
|
||||
- collapse contracts by default [`838757f`](https://github.com/oceanprotocol/commons/commit/838757f5e832973f54540b0bd78fd7b6ec3fcafe)
|
||||
|
||||
#### [v0.5.1](https://github.com/oceanprotocol/commons/compare/v0.5.0...v0.5.1)
|
||||
|
||||
> 14 June 2019
|
||||
|
||||
- Submarine links and Pacific support [`#158`](https://github.com/oceanprotocol/commons/pull/158)
|
||||
- link up transaction IDs with submarine, support pacific too [`97d6c27`](https://github.com/oceanprotocol/commons/commit/97d6c2756ed31f90f960dae21b8889d61232cd09)
|
||||
- link version numbers to release pages [`6f7edfa`](https://github.com/oceanprotocol/commons/commit/6f7edfa30f3b188e87cbce3c2404db313920e305)
|
||||
- Release 0.5.1 [`c063ad8`](https://github.com/oceanprotocol/commons/commit/c063ad82cb5e3a51b5083427fc50afc5b161533a)
|
||||
|
||||
#### [v0.5.0](https://github.com/oceanprotocol/commons/compare/v0.4.5...v0.5.0)
|
||||
|
||||
> 12 June 2019
|
||||
|
||||
- make price a string, Aquarius 0.2.7 validation updates [`#142`](https://github.com/oceanprotocol/commons/pull/142)
|
||||
- simplify Ocean URIs and env variables, document .env usage [`#157`](https://github.com/oceanprotocol/commons/pull/157)
|
||||
- version number fixes [`#156`](https://github.com/oceanprotocol/commons/pull/156)
|
||||
- additions to Ocean versions output [`#155`](https://github.com/oceanprotocol/commons/pull/155)
|
||||
- highly simplify Ocean URIs and env variables [`4b919f2`](https://github.com/oceanprotocol/commons/commit/4b919f2ee86b5e507d293fbe6684d296c2574d28)
|
||||
- update tests [`264a066`](https://github.com/oceanprotocol/commons/commit/264a066874dbe55950f54754924e2a5c4d2b69ec)
|
||||
- mock file fetch request [`7d727bc`](https://github.com/oceanprotocol/commons/commit/7d727bcdf95ada24304cc03a2a63c35a644d2a08)
|
||||
|
||||
#### [v0.4.5](https://github.com/oceanprotocol/commons/compare/v0.4.4...v0.4.5)
|
||||
|
||||
> 6 June 2019
|
||||
|
||||
- hotfix for failing server run on Docker [`#154`](https://github.com/oceanprotocol/commons/pull/154)
|
||||
- Release 0.4.5 [`e499430`](https://github.com/oceanprotocol/commons/commit/e4994308ad369595d88e1d7b524d986d80c58cd7)
|
||||
|
||||
#### [v0.4.4](https://github.com/oceanprotocol/commons/compare/v0.4.3...v0.4.4)
|
||||
|
||||
> 6 June 2019
|
||||
|
||||
- switch to new Travis caching strategy [`#153`](https://github.com/oceanprotocol/commons/pull/153)
|
||||
- fix account address display in Firefox [`#152`](https://github.com/oceanprotocol/commons/pull/152)
|
||||
- Release 0.4.4 [`5f19fbe`](https://github.com/oceanprotocol/commons/commit/5f19fbe4206045a6ba086173403f1594d0806be1)
|
||||
|
||||
#### [v0.4.3](https://github.com/oceanprotocol/commons/compare/v0.4.2...v0.4.3)
|
||||
|
||||
> 3 June 2019
|
||||
|
||||
- output event messages during publishing flow [`#151`](https://github.com/oceanprotocol/commons/pull/151)
|
||||
- squid-js v0.5.14 [`b27c458`](https://github.com/oceanprotocol/commons/commit/b27c458fb20af086063556831f8bc695c5f1c89b)
|
||||
- Release 0.4.3 [`303a7bf`](https://github.com/oceanprotocol/commons/commit/303a7bf12ca26a716de38ad9a14ef274c60b661b)
|
||||
- update tests [`56604b9`](https://github.com/oceanprotocol/commons/commit/56604b972c6dc99953e31cc4a4e24cd7c0e0a34e)
|
||||
|
||||
#### [v0.4.2](https://github.com/oceanprotocol/commons/compare/v0.4.1...v0.4.2)
|
||||
|
||||
> 31 May 2019
|
||||
|
||||
- test fixes [`#150`](https://github.com/oceanprotocol/commons/pull/150)
|
||||
- Reuse agreements on consume flow [`#148`](https://github.com/oceanprotocol/commons/pull/148)
|
||||
- show faucet version number, small refactor [`#147`](https://github.com/oceanprotocol/commons/pull/147)
|
||||
- change brizo fallback address [`#146`](https://github.com/oceanprotocol/commons/pull/146)
|
||||
- prevent test runner conflicts, kick out jasmine, lock TypeScript [`9888d78`](https://github.com/oceanprotocol/commons/commit/9888d78f99cebc84e8f10aa0402c2ef0bd15df49)
|
||||
- formatting and test tweaks [`1e6b334`](https://github.com/oceanprotocol/commons/commit/1e6b334cdca79e93a585d8c23f6551142d7bf1c0)
|
||||
- prevent text runner conflicts, kick out jasmine, TypeScript update [`4fd623f`](https://github.com/oceanprotocol/commons/commit/4fd623f28e3d1b1d3799ce59c6563cfee81646d2)
|
||||
|
||||
#### [v0.4.1](https://github.com/oceanprotocol/commons/compare/v0.4.0...v0.4.1)
|
||||
|
||||
> 28 May 2019
|
||||
|
||||
- output version numbers, simplify release tasks, make automatic changelog work [`#145`](https://github.com/oceanprotocol/commons/pull/145)
|
||||
- version numbers as component, fetch Brizo & Aquarius [`043d942`](https://github.com/oceanprotocol/commons/commit/043d9429ac76fe4af8099f46d73986e0e488a055)
|
||||
- simplify release tasks, automatic changelog [`41d6726`](https://github.com/oceanprotocol/commons/commit/41d6726beda89a50a3d2c1232451226cabf174e3)
|
||||
- package-locks [`c742426`](https://github.com/oceanprotocol/commons/commit/c742426b1a00a1f5776458dda133742256f4bdd9)
|
||||
|
||||
#### [v0.4.0](https://github.com/oceanprotocol/commons/compare/v0.3.2...v0.4.0)
|
||||
|
||||
> 28 May 2019
|
||||
|
||||
- AI For Good: channels, new front-page & categories list [`#125`](https://github.com/oceanprotocol/commons/pull/125)
|
||||
- rebase fix [`90b163b`](https://github.com/oceanprotocol/commons/commit/90b163b2aa1703fd4e450e4e83076ed4522b0aad)
|
||||
- category search, make multiple layouts on one page possible [`1b1ac5c`](https://github.com/oceanprotocol/commons/commit/1b1ac5c9ef75e3a67d949a07e8177245e7912fe7)
|
||||
- channel teaser component, use on channels page [`1b7d343`](https://github.com/oceanprotocol/commons/commit/1b7d34398490a14a0fd62db7b28e54dab14acc30)
|
||||
|
||||
#### [v0.3.2](https://github.com/oceanprotocol/commons/compare/v0.3.1...v0.3.2)
|
||||
|
||||
> 27 May 2019
|
||||
|
||||
- Add range error handling [`#144`](https://github.com/oceanprotocol/commons/pull/144)
|
||||
- update changelog [`7669545`](https://github.com/oceanprotocol/commons/commit/7669545d1391b764fd42419c41162182b93d9118)
|
||||
- Release 0.3.2 [`63b87cf`](https://github.com/oceanprotocol/commons/commit/63b87cfb82b410886baefe8a20da0b7f1d3ac34e)
|
||||
- add range error handling [`2687c78`](https://github.com/oceanprotocol/commons/commit/2687c7847425c549927993ee396d8e12072ad9da)
|
||||
|
||||
#### [v0.3.1](https://github.com/oceanprotocol/commons/compare/v0.3.0...v0.3.1)
|
||||
|
||||
> 27 May 2019
|
||||
|
||||
- remove AI For Good as category [`#143`](https://github.com/oceanprotocol/commons/pull/143)
|
||||
- update changelog [`88872cc`](https://github.com/oceanprotocol/commons/commit/88872cc020f0c10efcd282169c491b5e05cef916)
|
||||
- Release 0.3.1 [`54f3f17`](https://github.com/oceanprotocol/commons/commit/54f3f170c3fa2be750963afa19103d1c2e202586)
|
||||
|
||||
#### [v0.3.0](https://github.com/oceanprotocol/commons/compare/v0.2.14...v0.3.0)
|
||||
|
||||
> 21 May 2019
|
||||
|
||||
- Consume feedback mesages [`#110`](https://github.com/oceanprotocol/commons/pull/110)
|
||||
- fresh package-lock [`743fe53`](https://github.com/oceanprotocol/commons/commit/743fe533dc848dd1f120e6086e3ef311a23395a0)
|
||||
- message tweaks [`0e12204`](https://github.com/oceanprotocol/commons/commit/0e12204a5a0b72b070f5b7a8cc9d14c351cff3c2)
|
||||
- message output refactor, testing [`879f511`](https://github.com/oceanprotocol/commons/commit/879f51170ea0dfdf97d72a3594ac73b920d52162)
|
||||
|
||||
#### [v0.2.14](https://github.com/oceanprotocol/commons/compare/v0.2.13...v0.2.14)
|
||||
|
||||
> 20 May 2019
|
||||
|
||||
- AI Commons link [`#137`](https://github.com/oceanprotocol/commons/pull/137)
|
||||
- add AI Commons logo [`081772c`](https://github.com/oceanprotocol/commons/commit/081772ce3764b95d67cf685c5d71c335c7f68d47)
|
||||
- clarify changelog updating [`bf3378b`](https://github.com/oceanprotocol/commons/commit/bf3378bc489b197cc2fc0d4f955e376b39dee1ca)
|
||||
- update changelog [`7e2d7ac`](https://github.com/oceanprotocol/commons/commit/7e2d7ac6ad06c7acd26851d95ba3ab673f7a45b9)
|
||||
|
||||
#### [v0.2.13](https://github.com/oceanprotocol/commons/compare/v0.2.12...v0.2.13)
|
||||
|
||||
> 20 May 2019
|
||||
|
||||
- Output total assets [`#128`](https://github.com/oceanprotocol/commons/pull/128)
|
||||
- Updated Telegram link [`#138`](https://github.com/oceanprotocol/commons/pull/138)
|
||||
- output total assets in the marketplace, use new Market Provider for it [`2244082`](https://github.com/oceanprotocol/commons/commit/22440827cafb8ccc4621e49df12b96b1192dd5f0)
|
||||
- styling, AI Commons link [`e6fc7a9`](https://github.com/oceanprotocol/commons/commit/e6fc7a9085805a18a1779de4b9628dcc96403f4f)
|
||||
- update changelog [`7df6958`](https://github.com/oceanprotocol/commons/commit/7df695812325f6470cabd036f744cf2e5281ae6f)
|
||||
|
||||
#### [v0.2.12](https://github.com/oceanprotocol/commons/compare/v0.2.11...v0.2.12)
|
||||
|
||||
> 17 May 2019
|
||||
|
||||
- Fix versions vwv.y.z [`#135`](https://github.com/oceanprotocol/commons/pull/135)
|
||||
- consistent AI For Good category naming [`#136`](https://github.com/oceanprotocol/commons/pull/136)
|
||||
- update changelog [`a831848`](https://github.com/oceanprotocol/commons/commit/a83184851ca1293a684463b32bd2dbc0c59d5583)
|
||||
- Release 0.2.12 [`8c4fefc`](https://github.com/oceanprotocol/commons/commit/8c4fefcee1e4c7c9e02eeb97fe90911e2bc54ef6)
|
||||
|
||||
#### [v0.2.11](https://github.com/oceanprotocol/commons/compare/v0.2.10...v0.2.11)
|
||||
|
||||
> 16 May 2019
|
||||
|
||||
- url encode & decode search term [`#130`](https://github.com/oceanprotocol/commons/pull/130)
|
||||
- fix react-ga initialization [`#129`](https://github.com/oceanprotocol/commons/pull/129)
|
||||
- update changelog [`d49cace`](https://github.com/oceanprotocol/commons/commit/d49cace56a0aa551e26ad4eac2ecd196dcc499af)
|
||||
- Release 0.2.11 [`e8b150a`](https://github.com/oceanprotocol/commons/commit/e8b150a8cb5d5fc3bae8c4684cfa73494752fb6d)
|
||||
|
||||
#### [v0.2.10](https://github.com/oceanprotocol/commons/compare/v0.2.9...v0.2.10)
|
||||
|
||||
> 15 May 2019
|
||||
|
@ -11,7 +468,7 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
|||
- AI for Good category [`#126`](https://github.com/oceanprotocol/commons/pull/126)
|
||||
- Network detection tweaks [`#122`](https://github.com/oceanprotocol/commons/pull/122)
|
||||
- bump squid-js [`97b20b4`](https://github.com/oceanprotocol/commons/commit/97b20b4e9b09f3ade7d55636fb6ef169bacf4222)
|
||||
- isCorrectNetwork -> isOceanNetwork [`807723b`](https://github.com/oceanprotocol/commons/commit/807723be350a60da97f25c53eed102bafcbf1c3c)
|
||||
- isCorrectNetwork -> isOceanNetwork [`807723b`](https://github.com/oceanprotocol/commons/commit/807723be350a60da97f25c53eed102bafcbf1c3c)
|
||||
- less verbose error logging [`f49fa14`](https://github.com/oceanprotocol/commons/commit/f49fa14b2aa7d35a91f8003ddd297b4f2df8ca78)
|
||||
|
||||
#### [v0.2.9](https://github.com/oceanprotocol/commons/compare/v0.2.8...v0.2.9)
|
||||
|
@ -66,7 +523,6 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
|||
|
||||
- fix search titles [`#112`](https://github.com/oceanprotocol/commons/pull/112)
|
||||
- Release 0.2.4 [`8f832b6`](https://github.com/oceanprotocol/commons/commit/8f832b63220a46a8de0061ffc2498186e2099315)
|
||||
- update telegram link [`e6806f4`](https://github.com/oceanprotocol/commons/commit/e6806f467d6e2299bc0886eba53d0646dfa4df31)
|
||||
|
||||
#### [v0.2.3](https://github.com/oceanprotocol/commons/compare/v0.2.2...v0.2.3)
|
||||
|
||||
|
@ -223,7 +679,7 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
|||
- add changelog [`#33`](https://github.com/oceanprotocol/commons/pull/33)
|
||||
- Front-page tweaks & user asset list [`#19`](https://github.com/oceanprotocol/commons/pull/19)
|
||||
- add invoice view [`#29`](https://github.com/oceanprotocol/commons/pull/29)
|
||||
- root app->/client, microservice in /server [`#28`](https://github.com/oceanprotocol/commons/pull/28)
|
||||
- root app->/client, microservice in /server [`#28`](https://github.com/oceanprotocol/commons/pull/28)
|
||||
- Account & Faucet UI [`#25`](https://github.com/oceanprotocol/commons/pull/25)
|
||||
- New publish flow [`#23`](https://github.com/oceanprotocol/commons/pull/23)
|
||||
- package updates [`#27`](https://github.com/oceanprotocol/commons/pull/27)
|
||||
|
@ -248,4 +704,4 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
|||
- kick out prototyping stuff [`#58`](https://github.com/oceanprotocol/commons/issues/58)
|
||||
- one dev interface for client & server [`7e42991`](https://github.com/oceanprotocol/commons/commit/7e42991706f139a34e425dd7c20b28b4f55d77aa)
|
||||
- npm install [`07f6d22`](https://github.com/oceanprotocol/commons/commit/07f6d22a36f0f253f9a6619912489679f62218da)
|
||||
- display published [`43d0847`](https://github.com/oceanprotocol/commons/commit/43d0847d48ccf3f5796f27aae6cd179770c8a8d5)
|
||||
- start command [`c49fc85`](https://github.com/oceanprotocol/commons/commit/c49fc85017b0560cf96c7ed8e7d6e2c2ace1bff9)
|
||||
|
|
151
README.md
151
README.md
|
@ -1,3 +1,7 @@
|
|||
**This repo is obsolete as of Ocean V3 (Oct 2020). Superseded by [oceanprotocol/market](https://github.com/oceanprotocol/market).**
|
||||
|
||||
----
|
||||
|
||||
[![banner](https://raw.githubusercontent.com/oceanprotocol/art/master/github/repo-banner%402x.png)](https://oceanprotocol.com)
|
||||
|
||||
<h1 align="center">Commons</h1>
|
||||
|
@ -6,11 +10,10 @@
|
|||
> https://commons.oceanprotocol.com
|
||||
|
||||
[![Build Status](https://travis-ci.com/oceanprotocol/commons.svg?branch=master)](https://travis-ci.com/oceanprotocol/commons)
|
||||
[![Codacy Badge](https://api.codacy.com/project/badge/Grade/6a19987e62344b1c9c1d5bc9f315c733)](https://www.codacy.com/app/ocean-protocol/commons)
|
||||
[![Codacy Badge](https://api.codacy.com/project/badge/Coverage/6a19987e62344b1c9c1d5bc9f315c733)](https://www.codacy.com/app/ocean-protocol/commons)
|
||||
[![Maintainability](https://api.codeclimate.com/v1/badges/ed6e8212a8d294b6aa88/maintainability)](https://codeclimate.com/github/oceanprotocol/commons/maintainability)
|
||||
[![Test Coverage](https://api.codeclimate.com/v1/badges/ed6e8212a8d294b6aa88/test_coverage)](https://codeclimate.com/github/oceanprotocol/commons/test_coverage)
|
||||
[![code style: prettier](https://img.shields.io/badge/code_style-prettier-7b1173.svg?style=flat-square)](https://github.com/prettier/prettier)
|
||||
[![js oceanprotocol](https://img.shields.io/badge/js-oceanprotocol-7b1173.svg)](https://github.com/oceanprotocol/eslint-config-oceanprotocol)
|
||||
[![css bigchaindb](https://img.shields.io/badge/css-bigchaindb-39BA91.svg)](https://github.com/bigchaindb/stylelint-config-bigchaindb)
|
||||
|
||||
<img width="1218" alt="Commons UI" src="https://user-images.githubusercontent.com/90316/55874266-296ef080-5b92-11e9-8ac6-2423cb2a80fb.png">
|
||||
|
||||
|
@ -23,12 +26,20 @@
|
|||
If you're a developer and want to contribute to, or want to utilize this marketplace's code in your projects, then keep on reading.
|
||||
|
||||
- [🏄 Get Started](#-get-started)
|
||||
- [🏖 Remote Ocean: Nile](#-remote-ocean-nile)
|
||||
- [🏖 Remote Ocean: Pacific](#-remote-ocean-pacific)
|
||||
- [🐳 Use with Barge](#-use-with-barge)
|
||||
- [⛵️ Environment Variables](#️-environment-variables)
|
||||
- [Client](#client)
|
||||
- [Server](#server)
|
||||
- [Feature Switches](#feature-switches)
|
||||
- [More Settings](#more-settings)
|
||||
- [👩🔬 Testing](#-testing)
|
||||
- [Unit Tests](#unit-tests)
|
||||
- [End-to-End Integration Tests](#end-to-end-integration-tests)
|
||||
- [✨ Code Style](#-code-style)
|
||||
- [🛳 Production](#-production)
|
||||
- [⬆️ Releases](#️-releases)
|
||||
- [📜 Changelog](#-changelog)
|
||||
- [🎁 Contributing](#-contributing)
|
||||
- [🏛 License](#-license)
|
||||
|
||||
|
@ -37,7 +48,7 @@ If you're a developer and want to contribute to, or want to utilize this marketp
|
|||
This repo contains a client and a server, both written in TypeScript:
|
||||
|
||||
- **client**: React app setup with [squid-js](https://github.com/oceanprotocol/squid-js), bootstrapped with [Create React App](https://github.com/facebook/create-react-app)
|
||||
- **server**: Node.js app, utilizing [Express](https://expressjs.com). The server provides various microservices, like remote file checking.
|
||||
- **server**: Node.js app, utilizing [Express](https://expressjs.com). The server provides various microservices, like remote file checking. The endpoints are documented in [server Readme](server/).
|
||||
|
||||
To spin up both, the client and the server in a watch mode for local development, execute:
|
||||
|
||||
|
@ -48,39 +59,115 @@ npm start
|
|||
|
||||
Open [http://localhost:3000](http://localhost:3000) to view the client in the browser. The page will reload if you make edits to files in either `./client` or `./server`.
|
||||
|
||||
### 🏖 Remote Ocean: Nile
|
||||
### 🏖 Remote Ocean: Pacific
|
||||
|
||||
To make use of all the functionality, you need to connect to the Ocean network. By default, the client will connect to Ocean components running within [Ocean's Nile test network](https://docs.oceanprotocol.com/concepts/testnets/#the-nile-testnet) remotely.
|
||||
To make use of all the functionality, you need to connect to an Ocean network.
|
||||
|
||||
This means you need to connect with your MetaMask to the Nile network too. To do this:
|
||||
By default, the client will connect to Ocean components running within [Ocean's Pacific network](https://docs.oceanprotocol.com/concepts/pacific-network/) remotely.
|
||||
|
||||
By default, the client uses a burner wallet connected to the correct network automatically. If you choose to use MetaMask, you need to connect to the Pacific network. To do this:
|
||||
|
||||
1. select Custom RPC in the network dropdown in MetaMask
|
||||
2. under New Network, enter `https://nile.dev-ocean.com` as the custom RPC URL
|
||||
3. Hit _Save_, and you’re now connected to Nile
|
||||
2. under New Network, enter `https://pacific.oceanprotocol.com` as the custom RPC URL
|
||||
3. Hit _Save_, and you’re now connected to Pacific
|
||||
|
||||
### 🐳 Use with Barge
|
||||
|
||||
If you prefer to connect to locally running components instead of remote connections to Ocean's Nile network, you can spin up [`barge`](https://github.com/oceanprotocol/barge) and use a local network:
|
||||
If you prefer to connect to locally running components instead of remote connections to Ocean's Nile network, you can spin up [`barge`](https://github.com/oceanprotocol/barge) and use a local Spree network:
|
||||
|
||||
```bash
|
||||
git clone git@github.com:oceanprotocol/barge.git
|
||||
cd barge
|
||||
|
||||
./start_ocean.sh --latest --no-pleuston --local-spree-node
|
||||
# startup with local Spree node
|
||||
./start_ocean.sh --no-commons
|
||||
```
|
||||
|
||||
Modify `./client/src/config.ts` to use those local connections.
|
||||
Then set [environment variables](#️-environment-variables) to use those local connections.
|
||||
|
||||
Finally, you need to copy the generated contract artifacts out of the Docker container. To do this, execute this script in another terminal:
|
||||
|
||||
```bash
|
||||
./scripts/keeper.sh
|
||||
```
|
||||
|
||||
The script will wait for all contracts to be generated in the `keeper-contracts` Docker container, then will copy the artifacts in place.
|
||||
|
||||
If you are on macOS, you need to additionally tweak your `/etc/hosts` file so Brizo can connect to Aquarius. This is only required on macOS and is a [known limitation of Docker for Mac](https://docs.docker.com/docker-for-mac/networking/#known-limitations-use-cases-and-workarounds):
|
||||
|
||||
```bash
|
||||
sudo vi /etc/hosts
|
||||
|
||||
# add this line, and save
|
||||
127.0.0.1 aquarius
|
||||
```
|
||||
|
||||
Then use this host for the local Aquarius url in the client config:
|
||||
|
||||
```bash
|
||||
REACT_APP_AQUARIUS_URI="http://aquarius:5000"
|
||||
```
|
||||
|
||||
### ⛵️ Environment Variables
|
||||
|
||||
#### Client
|
||||
|
||||
The `./client/src/config.ts` file is setup to prioritize environment variables for setting each Ocean component endpoint.
|
||||
|
||||
By setting environment variables, you can easily switch between Ocean networks the commons client connects to, without directly modifying `./client/src/config.ts`. This is helpful e.g. for local development so you don't accidentially commit changes to the config file.
|
||||
|
||||
For local development, you can use a `.env.local` file. There's an example file with the most common network configurations preconfigured:
|
||||
|
||||
```bash
|
||||
cp client/.env.local.example client/.env.local
|
||||
|
||||
# uncomment the config you need
|
||||
vi client/.env.local
|
||||
```
|
||||
|
||||
#### Server
|
||||
|
||||
The server uses its own environment variables too:
|
||||
|
||||
```bash
|
||||
cp server/.env.example server/.env
|
||||
|
||||
# edit variables
|
||||
vi server/.env
|
||||
```
|
||||
|
||||
#### Feature Switches
|
||||
|
||||
Beside configuring the network endpopints, the client allows to activate some features with environment variables in `client/.env.local`:
|
||||
|
||||
| Env Variable | Feature Description |
|
||||
| -------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
||||
| `REACT_APP_SHOW_CHANNELS` | Show the channels feature which shows assets based on a certain tag in a prominent view. This is deeactivated by default and only activated in live Commons deployments. |
|
||||
| `REACT_APP_SHOW_REQUEST_TOKENS_BUTTON` | Shows a second button on the `/faucet` route to request Ocean Tokens in addition to Ether. Will only work in Ocean testnets. |
|
||||
| `REACT_APP_ALLOW_PRICING` | Activate pricing feature. Will show a price input during publish flow, and output prices for each data asset. |
|
||||
|
||||
#### More Settings
|
||||
|
||||
| Env Variable | Example | Feature Description |
|
||||
| --------------------------------------------------------------------- | -------------------------------------- | ------------------------------------------------- |
|
||||
| client: `REACT_APP_IPFS_GATEWAY_URI`<br /> server: `IPFS_GATEWAY_URI` | `"https://ipfs.oceanprotocol.com"` | The IPFS gateway URI. |
|
||||
| `REACT_APP_IPFS_NODE_URI` | `"https://ipfs.oceanprotocol.com:443"` | The IPFS node URI used to add files to IPFS. |
|
||||
| `REACT_APP_REPORT_EMAIL` | `"jelly@mcjellyfish.com"` | The email used for the _report an asset_ feature. |
|
||||
|
||||
## 👩🔬 Testing
|
||||
|
||||
Test suite is setup with [Jest](https://jestjs.io) and [react-testing-library](https://github.com/kentcdodds/react-testing-library).
|
||||
Test suite is setup with [Jest](https://jestjs.io) and [react-testing-library](https://github.com/kentcdodds/react-testing-library) for unit testing, and [Cypress](https://www.cypress.io) for integration testing.
|
||||
|
||||
To run all tests, including all linting tests:
|
||||
To run all linting, unit and integration tests in one go, run:
|
||||
|
||||
```bash
|
||||
npm test
|
||||
```
|
||||
|
||||
The endpoints the integration tests run against are defined by your [Environment Variables](#️-Environment-Variables), and Cypress-specific variables in `cypress.json`.
|
||||
|
||||
### Unit Tests
|
||||
|
||||
For local development, you can start the test runners for client & server in a watch mode.
|
||||
|
||||
```bash
|
||||
|
@ -97,12 +184,28 @@ cd server/
|
|||
npm run test:watch
|
||||
```
|
||||
|
||||
### End-to-End Integration Tests
|
||||
|
||||
To run all integration tests in headless mode, run:
|
||||
|
||||
```bash
|
||||
npm run test:e2e
|
||||
```
|
||||
|
||||
This will automatically spin up all required resources to run the integrations tests, and then run them.
|
||||
|
||||
You can also use the UI of Cypress to run and inspect the integration tests locally:
|
||||
|
||||
```bash
|
||||
npm run cypress:open
|
||||
```
|
||||
|
||||
## ✨ Code Style
|
||||
|
||||
For linting and auto-formatting you can use from the root of the project:
|
||||
|
||||
```bash
|
||||
# auto format all ts & css with eslint & stylelint
|
||||
# auto format all ts & css with eslint
|
||||
npm run lint
|
||||
|
||||
# auto format all ts & css with prettier, taking all configs into account
|
||||
|
@ -121,24 +224,28 @@ Builds the client for production to the `./client/build` folder, and the server
|
|||
|
||||
## ⬆️ Releases
|
||||
|
||||
Running any release task does the following:
|
||||
From a clean `master` branch you can run any release task doing the following:
|
||||
|
||||
- bumps the project version
|
||||
- bumps the project version in `package.json`, `client/package.json`, `server/package.json`
|
||||
- auto-generates and updates the CHANGELOG.md file from commit messages
|
||||
- creates a Git tag
|
||||
- updates CHANGELOG.md file with commit messages
|
||||
- commits and pushes everything
|
||||
- creates a GitHub release with commit messages as description
|
||||
|
||||
You can execute the script using {major|minor|patch} as first argument to bump the version accordingly:
|
||||
|
||||
- To bump a patch version: `npm run release`
|
||||
- To bump a minor version: `npm run release-minor`
|
||||
- To bump a major version: `npm run release-major`
|
||||
- To bump a minor version: `npm run release minor`
|
||||
- To bump a major version: `npm run release major`
|
||||
|
||||
By creating the Git tag with these tasks, Travis will trigger a new Kubernetes deployment automatically aftr a successful tag build.
|
||||
By creating the Git tag with these tasks, Travis will trigger a new Kubernetes live deployment automatically, after a successful tag build.
|
||||
|
||||
For the GitHub releases steps a GitHub personal access token, exported as `GITHUB_TOKEN` is required. [Setup](https://github.com/release-it/release-it#github-releases)
|
||||
|
||||
## 📜 Changelog
|
||||
|
||||
See the [CHANGELOG.md](./CHANGELOG.md) file. This file is auto-generated during the above mentioned release process.
|
||||
|
||||
## 🎁 Contributing
|
||||
|
||||
See the page titled "[Ways to Contribute](https://docs.oceanprotocol.com/concepts/contributing/)" in the Ocean Protocol documentation.
|
||||
|
|
|
@ -1 +1,6 @@
|
|||
node_modules
|
||||
.env.local
|
||||
.env
|
||||
build
|
||||
coverage
|
||||
__mocks__
|
||||
|
|
|
@ -0,0 +1,63 @@
|
|||
#
|
||||
# When none of the following variables are set,
|
||||
# Commons will default connecting to Pacific
|
||||
#
|
||||
|
||||
#
|
||||
# Connect to Pacific
|
||||
#
|
||||
REACT_APP_NODE_URI="https://pacific.oceanprotocol.com"
|
||||
REACT_APP_SECRET_STORE_URI="https://secret-store.oceanprotocol.com"
|
||||
REACT_APP_FAUCET_URI="https://faucet.oceanprotocol.com"
|
||||
# Pacific Test instances
|
||||
REACT_APP_AQUARIUS_URI="https://aquarius.test.oceanprotocol.com"
|
||||
REACT_APP_BRIZO_URI="https://brizo.test.oceanprotocol.com"
|
||||
REACT_APP_BRIZO_ADDRESS="0x0474ed05ba757dde575dfaaaa267d9e7f3643abc"
|
||||
# Pacific Commons instances
|
||||
# REACT_APP_AQUARIUS_URI="https://aquarius.commons.oceanprotocol.com"
|
||||
# REACT_APP_BRIZO_URI="https://brizo.commons.oceanprotocol.com"
|
||||
# REACT_APP_BRIZO_ADDRESS="0x008c25ed3594e094db4592f4115d5fa74c4f41ea"
|
||||
|
||||
#
|
||||
# Connect to Nile
|
||||
#
|
||||
# REACT_APP_NODE_URI="https://nile.dev-ocean.com"
|
||||
# REACT_APP_SECRET_STORE_URI="https://secret-store.nile.dev-ocean.com"
|
||||
# REACT_APP_FAUCET_URI="https://faucet.nile.dev-ocean.com"
|
||||
# REACT_APP_BRIZO_ADDRESS="0x4aaab179035dc57b35e2ce066919048686f82972"
|
||||
# Nile Test instances
|
||||
# REACT_APP_AQUARIUS_URI="https://aquarius.nile.dev-ocean.com"
|
||||
# REACT_APP_BRIZO_URI="https://brizo.nile.dev-ocean.com"
|
||||
# Nile Commons instances
|
||||
# REACT_APP_AQUARIUS_URI="https://aquarius.marketplace.dev-ocean.com"
|
||||
# REACT_APP_BRIZO_URI="https://brizo.marketplace.dev-ocean.com"
|
||||
|
||||
#
|
||||
# Connect to Duero
|
||||
#
|
||||
# REACT_APP_NODE_URI="https://duero.dev-ocean.com"
|
||||
# REACT_APP_AQUARIUS_URI="https://aquarius.duero.dev-ocean.com"
|
||||
# REACT_APP_BRIZO_URI="https://brizo.duero.dev-ocean.com"
|
||||
# REACT_APP_SECRET_STORE_URI="https://secret-store.duero.dev-ocean.com"
|
||||
# REACT_APP_FAUCET_URI="https://faucet.duero.dev-ocean.com"
|
||||
# REACT_APP_BRIZO_ADDRESS="0x9d4ed58293f71122ad6a733c1603927a150735d0"
|
||||
|
||||
#
|
||||
# Connect to Spree (local with Barge)
|
||||
#
|
||||
# REACT_APP_NODE_URI="http://localhost:8545"
|
||||
# REACT_APP_AQUARIUS_URI="http://aquarius:5000"
|
||||
# REACT_APP_BRIZO_URI="http://localhost:8030"
|
||||
# REACT_APP_SECRET_STORE_URI="http://localhost:12001"
|
||||
# REACT_APP_FAUCET_URI="http://localhost:3001"
|
||||
# REACT_APP_BRIZO_ADDRESS="0x068ed00cf0441e4829d9784fcbe7b9e26d4bd8d0"
|
||||
|
||||
#
|
||||
# APP CONFIG
|
||||
#
|
||||
REACT_APP_REPORT_EMAIL="test@example.com"
|
||||
# REACT_APP_SHOW_CHANNELS=true
|
||||
# REACT_APP_ALLOW_PRICING=true
|
||||
# REACT_APP_SHOW_REQUEST_TOKENS_BUTTON=true
|
||||
REACT_APP_IPFS_GATEWAY_URI="https://ipfs.oceanprotocol.com"
|
||||
REACT_APP_IPFS_NODE_URI="https://ipfs.oceanprotocol.com:443"
|
|
@ -1,20 +1,23 @@
|
|||
FROM node:11-alpine
|
||||
LABEL maintainer="Ocean Protocol <devops@oceanprotocol.com>"
|
||||
|
||||
RUN apk add --no-cache --update\
|
||||
bash\
|
||||
g++\
|
||||
gcc\
|
||||
git\
|
||||
gettext\
|
||||
make\
|
||||
python
|
||||
RUN apk add --no-cache --update \
|
||||
bash \
|
||||
g++ \
|
||||
gcc \
|
||||
git \
|
||||
gettext \
|
||||
make \
|
||||
python \
|
||||
&& rm -rf /var/cache/apk/*
|
||||
|
||||
COPY package*.json /app/frontend/
|
||||
WORKDIR /app/frontend
|
||||
RUN npm install -g npm serve \
|
||||
&& npm install \
|
||||
&& npm cache clean --force
|
||||
|
||||
COPY . /app/frontend
|
||||
WORKDIR /app/frontend
|
||||
|
||||
RUN npm install -g npm serve
|
||||
RUN npm install
|
||||
RUN npm run build
|
||||
|
||||
# Default ENV values
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,62 +1,72 @@
|
|||
{
|
||||
"name": "commons-client",
|
||||
"description": "Ocean Protocol marketplace frontend to explore, download, and publish open data sets.",
|
||||
"version": "0.1.0",
|
||||
"version": "2.4.1",
|
||||
"license": "Apache-2.0",
|
||||
"scripts": {
|
||||
"start": "react-scripts start",
|
||||
"build": "react-scripts --max_old_space_size=4096 build",
|
||||
"test": "react-scripts test --coverage --watchAll=false",
|
||||
"build": "CI=false react-scripts --max_old_space_size=4096 build",
|
||||
"test": "react-scripts test --coverage --watchAll=false --silent",
|
||||
"test:watch": "react-scripts test --coverage",
|
||||
"eject": "react-scripts eject",
|
||||
"coverage": "cat coverage/lcov.info | codacy-coverage --token 8801f827fe1144ffa85cd7da94f2bbf7"
|
||||
"analyze": "source-map-explorer 'build/static/js/*.js'"
|
||||
},
|
||||
"dependencies": {
|
||||
"@oceanprotocol/art": "^2.2.0",
|
||||
"@oceanprotocol/squid": "^0.5.10",
|
||||
"@oceanprotocol/squid": "^2.2.0",
|
||||
"@oceanprotocol/typographies": "^0.1.0",
|
||||
"@sindresorhus/slugify": "^1.0.0",
|
||||
"@truffle/hdwallet-provider": "^1.0.35",
|
||||
"axios": "^0.19.2",
|
||||
"bip39": "^3.0.2",
|
||||
"classnames": "^2.2.6",
|
||||
"ethereum-blockies": "MyEtherWallet/blockies",
|
||||
"filesize": "^4.1.2",
|
||||
"history": "^4.9.0",
|
||||
"is-url": "^1.2.4",
|
||||
"moment": "^2.24.0",
|
||||
"query-string": "^6.5.0",
|
||||
"react": "^16.8.6",
|
||||
"react-datepicker": "^2.5.0",
|
||||
"react-dom": "^16.8.6",
|
||||
"react-dotdotdot": "^1.3.0",
|
||||
"react-ga": "^2.5.7",
|
||||
"react-helmet": "^5.2.1",
|
||||
"react-markdown": "^4.0.8",
|
||||
"react-moment": "^0.9.2",
|
||||
"react-paginate": "^6.3.0",
|
||||
"react-popper": "^1.3.3",
|
||||
"react-router-dom": "^5.0.0",
|
||||
"react-transition-group": "^4.0.0",
|
||||
"slugify": "^1.3.4",
|
||||
"web3": "1.0.0-beta.37"
|
||||
"ethereum-blockies": "github:MyEtherWallet/blockies",
|
||||
"filesize": "^6.1.0",
|
||||
"history": "^4.10.1",
|
||||
"ipfs-http-client": "44.2.0",
|
||||
"is-url-superb": "^4.0.0",
|
||||
"moment": "^2.26.0",
|
||||
"node-sass": "^4.14.1",
|
||||
"query-string": "^6.13.1",
|
||||
"react": "^16.13.1",
|
||||
"react-collapsed": "^3.0.0",
|
||||
"react-datepicker": "^3.0.0",
|
||||
"react-dom": "^16.13.1",
|
||||
"react-dotdotdot": "^1.3.1",
|
||||
"react-dropzone": "^11.0.1",
|
||||
"react-ga": "^3.0.0",
|
||||
"react-helmet": "^6.0.0",
|
||||
"react-markdown": "^4.3.1",
|
||||
"react-modal": "^3.11.2",
|
||||
"react-moment": "^0.9.7",
|
||||
"react-paginate": "^6.3.2",
|
||||
"react-popper": "^1.3.7",
|
||||
"react-router-dom": "^5.2.0",
|
||||
"react-transition-group": "^4.4.1",
|
||||
"shortid": "^2.2.15",
|
||||
"web3": "^1.2.8"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@react-mock/state": "^0.1.8",
|
||||
"@types/classnames": "^2.2.7",
|
||||
"@types/filesize": "^4.1.0",
|
||||
"@sheerun/mutationobserver-shim": "^0.3.3",
|
||||
"@testing-library/jest-dom": "^5.9.0",
|
||||
"@testing-library/react": "^10.2.1",
|
||||
"@types/classnames": "^2.2.10",
|
||||
"@types/is-url": "^1.2.28",
|
||||
"@types/jest": "^24.0.12",
|
||||
"@types/react": "^16.8.15",
|
||||
"@types/react-datepicker": "^2.3.0",
|
||||
"@types/react-dom": "^16.8.4",
|
||||
"@types/react-dotdotdot": "^1.2.0",
|
||||
"@types/react-helmet": "^5.0.8",
|
||||
"@types/jest": "^26.0.0",
|
||||
"@types/react": "^16.9.35",
|
||||
"@types/react-datepicker": "^2.11.0",
|
||||
"@types/react-dom": "^16.9.8",
|
||||
"@types/react-helmet": "^6.0.0",
|
||||
"@types/react-modal": "^3.10.5",
|
||||
"@types/react-paginate": "^6.2.1",
|
||||
"@types/react-router-dom": "^4.3.2",
|
||||
"@types/react-transition-group": "^2.9.1",
|
||||
"@types/web3": "^1.0.18",
|
||||
"jest-dom": "^3.1.4",
|
||||
"node-sass": "^4.12.0",
|
||||
"react-scripts": "^3.0.0",
|
||||
"react-testing-library": "^7.0.0",
|
||||
"typescript": "^3.4.5"
|
||||
"@types/react-router-dom": "^5.1.5",
|
||||
"@types/react-transition-group": "^4.4.0",
|
||||
"@types/shortid": "^0.0.29",
|
||||
"jest-mock-axios": "^4.2.0",
|
||||
"react-scripts": "^3.4.1",
|
||||
"source-map-explorer": "^2.4.2",
|
||||
"typescript": "^3.9.3"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
@ -71,7 +81,8 @@
|
|||
"jest": {
|
||||
"collectCoverageFrom": [
|
||||
"src/**/*.{ts,tsx}",
|
||||
"!src/serviceWorker.ts"
|
||||
"!src/serviceWorker.ts",
|
||||
"!src/**/*.d.ts"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,39 +12,6 @@
|
|||
|
||||
<title>Commons</title>
|
||||
|
||||
<meta
|
||||
content="A marketplace to find and publish open data sets in the Ocean Network."
|
||||
name="description"
|
||||
/>
|
||||
<meta
|
||||
content="https://commons.oceanprotocol.com/share.png"
|
||||
name="image"
|
||||
/>
|
||||
<link href="https://commons.oceanprotocol.com" rel="canonical" />
|
||||
|
||||
<meta content="https://commons.oceanprotocol.com" property="og:url" />
|
||||
<meta content="Commons" property="og:title" />
|
||||
<meta
|
||||
content="A marketplace to find and publish open data sets in the Ocean Network."
|
||||
property="og:description"
|
||||
/>
|
||||
<meta
|
||||
content="https://commons.oceanprotocol.com/share.png"
|
||||
property="og:image"
|
||||
/>
|
||||
|
||||
<meta content="summary_large_image" name="twitter:card" />
|
||||
<meta content="@oceanprotocol" name="twitter:creator" />
|
||||
<meta content="Commons" name="twitter:title" />
|
||||
<meta
|
||||
content="A marketplace to find and publish open data sets in the Ocean Network."
|
||||
name="twitter:description"
|
||||
/>
|
||||
<meta
|
||||
content="https://commons.oceanprotocol.com/share.png"
|
||||
name="twitter:image"
|
||||
/>
|
||||
|
||||
<style>
|
||||
.loader {
|
||||
display: block;
|
||||
|
|
|
@ -21,5 +21,5 @@
|
|||
"start_url": ".",
|
||||
"display": "standalone",
|
||||
"theme_color": "#141414",
|
||||
"background_color": "#141414"
|
||||
"background_color": "#ffffff"
|
||||
}
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
User-agent: *
|
||||
Disallow: /search
|
|
@ -0,0 +1,9 @@
|
|||
import Web3 from 'web3'
|
||||
import { Eth } from 'web3/eth'
|
||||
|
||||
declare global {
|
||||
interface Window {
|
||||
web3: Web3
|
||||
ethereum: Eth
|
||||
}
|
||||
}
|
|
@ -3,3 +3,8 @@
|
|||
declare module 'ethereum-blockies' {
|
||||
export function toDataUrl(address: string): string
|
||||
}
|
||||
|
||||
declare module 'ipfs'
|
||||
declare module 'ipfs-http-client'
|
||||
declare module 'react-collapsed'
|
||||
declare module 'filesize'
|
|
@ -1,8 +1,8 @@
|
|||
import React from 'react'
|
||||
import { render } from 'react-testing-library'
|
||||
import { render } from '@testing-library/react'
|
||||
import App from './App'
|
||||
import { User } from './context'
|
||||
import { userMock } from '../__mocks__/user-mock'
|
||||
import { userMock, userMockConnected } from './__mocks__/user-mock'
|
||||
|
||||
describe('App', () => {
|
||||
it('should be able to run tests', () => {
|
||||
|
@ -10,7 +10,11 @@ describe('App', () => {
|
|||
})
|
||||
|
||||
it('renders without crashing', () => {
|
||||
const { container } = render(<App />)
|
||||
const { container } = render(
|
||||
<User.Provider value={userMockConnected}>
|
||||
<App />
|
||||
</User.Provider>
|
||||
)
|
||||
expect(container.firstChild).toBeInTheDocument()
|
||||
})
|
||||
|
||||
|
|
|
@ -1,14 +1,18 @@
|
|||
import React from 'react'
|
||||
import { BrowserRouter as Router } from 'react-router-dom'
|
||||
import { render } from 'react-testing-library'
|
||||
import { render } from '@testing-library/react'
|
||||
import Routes from './Routes'
|
||||
import { User } from './context'
|
||||
import { userMockConnected } from './__mocks__/user-mock'
|
||||
|
||||
describe('Routes', () => {
|
||||
it('renders without crashing', () => {
|
||||
const { container } = render(
|
||||
<Router>
|
||||
<Routes />
|
||||
</Router>
|
||||
<User.Provider value={userMockConnected}>
|
||||
<Router>
|
||||
<Routes />
|
||||
</Router>
|
||||
</User.Provider>
|
||||
)
|
||||
expect(container.firstChild).toBeInTheDocument()
|
||||
})
|
||||
|
|
|
@ -1,28 +1,37 @@
|
|||
import React from 'react'
|
||||
import { Route, Switch } from 'react-router-dom'
|
||||
import withTracker from './hoc/withTracker'
|
||||
import { showChannels } from './config'
|
||||
|
||||
import About from './routes/About'
|
||||
import Details from './routes/Details/'
|
||||
import Home from './routes/Home'
|
||||
import NotFound from './routes/NotFound'
|
||||
import Publish from './routes/Publish/'
|
||||
import Search from './routes/Search'
|
||||
import Faucet from './routes/Faucet'
|
||||
import History from './routes/History'
|
||||
import Channels from './routes/Channels'
|
||||
import Styleguide from './routes/Styleguide'
|
||||
|
||||
import Asset from './components/templates/Asset'
|
||||
import Channel from './components/templates/Channel'
|
||||
|
||||
const Routes = () => (
|
||||
<Switch>
|
||||
<Route exact component={withTracker(Home)} path="/" />
|
||||
<Route component={withTracker(Styleguide)} path="/styleguide" />
|
||||
<Route component={withTracker(About)} path="/about" />
|
||||
<Route component={withTracker(Publish)} path="/publish" />
|
||||
<Route component={withTracker(Search)} path="/search" />
|
||||
<Route component={withTracker(Details)} path="/asset/:did" />
|
||||
<Route component={withTracker(Faucet)} path="/faucet" />
|
||||
<Route component={withTracker(History)} path="/history" />
|
||||
<Route component={withTracker(NotFound)} />
|
||||
<Route component={Home} exact path="/" />
|
||||
<Route component={Styleguide} path="/styleguide" />
|
||||
<Route component={About} path="/about" />
|
||||
<Route component={Publish} path="/publish" />
|
||||
<Route component={Search} path="/search" />
|
||||
<Route component={Asset} path="/asset/:did" />
|
||||
<Route component={Faucet} path="/faucet" />
|
||||
<Route component={History} path="/history" />
|
||||
{showChannels && (
|
||||
<>
|
||||
<Route component={Channels} exact path="/channels" />
|
||||
<Route component={Channel} path="/channels/:channel" />
|
||||
</>
|
||||
)}
|
||||
<Route component={NotFound} />
|
||||
</Switch>
|
||||
)
|
||||
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
import mockAxios from 'jest-mock-axios'
|
||||
export default mockAxios
|
|
@ -0,0 +1,10 @@
|
|||
import { DDO } from '@oceanprotocol/squid'
|
||||
|
||||
const ddoMock = ({
|
||||
id: 'xxx',
|
||||
findServiceByType: () => {
|
||||
return { index: 'xxx' }
|
||||
}
|
||||
} as any) as DDO
|
||||
|
||||
export default ddoMock
|
|
@ -0,0 +1,8 @@
|
|||
const marketMock = {
|
||||
totalAssets: 1000,
|
||||
categories: ['category'],
|
||||
network: 'Pacific',
|
||||
networkMatch: true
|
||||
}
|
||||
|
||||
export { marketMock }
|
|
@ -0,0 +1,76 @@
|
|||
const oceanMock = {
|
||||
ocean: {
|
||||
accounts: {
|
||||
list: () => ['xxx', 'xxx']
|
||||
},
|
||||
aquarius: {
|
||||
queryMetadata: () => {
|
||||
return {
|
||||
results: [],
|
||||
totalResults: 1,
|
||||
totalPages: 1
|
||||
}
|
||||
}
|
||||
},
|
||||
assets: {
|
||||
query: () => {
|
||||
return {
|
||||
results: [],
|
||||
page: 1,
|
||||
/* eslint-disable @typescript-eslint/camelcase */
|
||||
total_pages: 1611,
|
||||
total_results: 1611
|
||||
/* eslint-enable @typescript-eslint/camelcase */
|
||||
}
|
||||
},
|
||||
resolve: jest.fn(),
|
||||
order: () => {
|
||||
return {
|
||||
next: jest.fn()
|
||||
}
|
||||
},
|
||||
consume: jest.fn()
|
||||
},
|
||||
keeper: {
|
||||
conditions: {
|
||||
accessSecretStoreCondition: {
|
||||
getGrantedDidByConsumer: () => {
|
||||
return {
|
||||
find: jest.fn()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
versions: {
|
||||
get: jest.fn(() =>
|
||||
Promise.resolve({
|
||||
squid: {
|
||||
name: 'Squid-js',
|
||||
status: 'Working'
|
||||
},
|
||||
aquarius: {
|
||||
name: 'Aquarius',
|
||||
status: 'Working'
|
||||
},
|
||||
brizo: {
|
||||
name: 'Brizo',
|
||||
network: 'Nile',
|
||||
status: 'Working',
|
||||
contracts: {
|
||||
hello: 'hello',
|
||||
hello2: 'hello2'
|
||||
}
|
||||
},
|
||||
status: {
|
||||
ok: true,
|
||||
network: true,
|
||||
contracts: true
|
||||
}
|
||||
})
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default oceanMock
|
|
@ -1,30 +1,34 @@
|
|||
import oceanMock from './ocean-mock'
|
||||
|
||||
const userMock = {
|
||||
isLogged: false,
|
||||
isLoading: false,
|
||||
isWeb3: false,
|
||||
isOceanNetwork: false,
|
||||
isBurner: false,
|
||||
isWeb3Capable: false,
|
||||
account: '',
|
||||
web3: {},
|
||||
ocean: {},
|
||||
...oceanMock,
|
||||
balance: { eth: 0, ocn: 0 },
|
||||
network: '',
|
||||
requestFromFaucet: jest.fn(),
|
||||
unlockAccounts: jest.fn(),
|
||||
loginMetamask: jest.fn(),
|
||||
loginBurnerWallet: jest.fn(),
|
||||
message: ''
|
||||
}
|
||||
|
||||
const userMockConnected = {
|
||||
isLogged: true,
|
||||
isLoading: false,
|
||||
isWeb3: true,
|
||||
isOceanNetwork: true,
|
||||
isBurner: false,
|
||||
isWeb3Capable: true,
|
||||
account: '0xxxxxx',
|
||||
web3: {},
|
||||
ocean: {},
|
||||
...oceanMock,
|
||||
balance: { eth: 0, ocn: 0 },
|
||||
network: '',
|
||||
requestFromFaucet: jest.fn(),
|
||||
unlockAccounts: jest.fn(),
|
||||
loginMetamask: jest.fn(),
|
||||
loginBurnerWallet: jest.fn(),
|
||||
message: ''
|
||||
}
|
||||
|
|
@ -2,18 +2,82 @@
|
|||
|
||||
.account {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
text-align: left;
|
||||
|
||||
> div {
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
font-family: $font-family-monospace;
|
||||
font-size: $font-size-small;
|
||||
> div:first-of-type {
|
||||
flex: 0 0 80%;
|
||||
}
|
||||
}
|
||||
|
||||
.accountId {
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
font-family: $font-family-monospace;
|
||||
font-size: $font-size-small;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.unlock {
|
||||
font-size: $font-size-small !important;
|
||||
margin-left: $spacer / 2;
|
||||
}
|
||||
|
||||
.accountType {
|
||||
width: 100%;
|
||||
margin-left: calc(1.5rem + #{$spacer / 3});
|
||||
font-size: $font-size-small;
|
||||
font-weight: $font-weight-bold;
|
||||
color: $brand-grey-light;
|
||||
}
|
||||
|
||||
.toggle {
|
||||
background: none;
|
||||
font-family: inherit;
|
||||
font-size: inherit;
|
||||
font-weight: inherit;
|
||||
color: inherit;
|
||||
border: none;
|
||||
padding: 0;
|
||||
cursor: pointer;
|
||||
|
||||
svg {
|
||||
display: inline-block;
|
||||
fill: currentColor;
|
||||
margin-right: $spacer / 8;
|
||||
transition: 0.2s ease-out;
|
||||
}
|
||||
}
|
||||
|
||||
.open {
|
||||
transform: rotate(90deg);
|
||||
}
|
||||
|
||||
.seedphrase {
|
||||
margin-top: $spacer / 2;
|
||||
margin-left: calc(1.5rem + #{$spacer / 4});
|
||||
margin-right: calc(1.5rem + #{$spacer / 4});
|
||||
|
||||
code {
|
||||
display: block;
|
||||
text-align: center;
|
||||
padding: $spacer / 2 $spacer;
|
||||
border-radius: $border-radius;
|
||||
background: $body-background;
|
||||
border: 1px solid $brand-grey-lighter;
|
||||
margin-bottom: $spacer / 4;
|
||||
word-break: normal;
|
||||
}
|
||||
}
|
||||
|
||||
.seedphraseHelp {
|
||||
color: $brand-grey-light;
|
||||
font-size: $font-size-small;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.blockies {
|
||||
width: 1.5rem;
|
||||
height: 1.5rem;
|
||||
|
@ -21,4 +85,5 @@
|
|||
display: inline-block;
|
||||
margin-right: $spacer / 3;
|
||||
margin-left: 0;
|
||||
border: 1px solid $brand-grey-lighter;
|
||||
}
|
||||
|
|
|
@ -1,28 +1,61 @@
|
|||
import React from 'react'
|
||||
import { render } from 'react-testing-library'
|
||||
import { render, fireEvent } from '@testing-library/react'
|
||||
import { toDataUrl } from 'ethereum-blockies'
|
||||
import Account from './Account'
|
||||
import { User } from '../../context'
|
||||
import { userMockConnected } from '../../__mocks__/user-mock'
|
||||
|
||||
describe('Account', () => {
|
||||
it('renders without crashing', () => {
|
||||
const { container } = render(<Account account={'0xxxxxxxxxxxxxxx'} />)
|
||||
const { container } = render(
|
||||
<User.Provider
|
||||
value={{ ...userMockConnected, account: '0xxxxxxxxxxxxxxx' }}
|
||||
>
|
||||
<Account />
|
||||
</User.Provider>
|
||||
)
|
||||
expect(container.firstChild).toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('outputs empty state without account', () => {
|
||||
const { container } = render(<Account account={''} />)
|
||||
const { container, getByText } = render(
|
||||
<User.Provider value={{ ...userMockConnected, account: '' }}>
|
||||
<Account />
|
||||
</User.Provider>
|
||||
)
|
||||
expect(container.firstChild).toHaveTextContent('No account selected')
|
||||
fireEvent.click(getByText('Unlock Account'))
|
||||
})
|
||||
|
||||
it('outputs blockie img', () => {
|
||||
const account = '0xxxxxxxxxxxxxxx'
|
||||
const blockies = toDataUrl(account)
|
||||
|
||||
const { container } = render(<Account account={account} />)
|
||||
const { container } = render(
|
||||
<User.Provider value={{ ...userMockConnected, account }}>
|
||||
<Account />
|
||||
</User.Provider>
|
||||
)
|
||||
expect(container.querySelector('.blockies')).toBeInTheDocument()
|
||||
expect(container.querySelector('.blockies')).toHaveAttribute(
|
||||
'src',
|
||||
blockies
|
||||
)
|
||||
})
|
||||
|
||||
it('Account info can be toggled', () => {
|
||||
const { container, getByText } = render(
|
||||
<User.Provider
|
||||
value={{
|
||||
...userMockConnected,
|
||||
isBurner: true,
|
||||
account: '0xxxxxxxxxxxxxxx'
|
||||
}}
|
||||
>
|
||||
<Account />
|
||||
</User.Provider>
|
||||
)
|
||||
expect(container.firstChild).toBeInTheDocument()
|
||||
fireEvent.click(getByText('Burner Wallet'))
|
||||
})
|
||||
})
|
||||
|
|
|
@ -1,19 +1,90 @@
|
|||
import React from 'react'
|
||||
import React, { PureComponent, MouseEvent } from 'react'
|
||||
import Dotdotdot from 'react-dotdotdot'
|
||||
import { toDataUrl } from 'ethereum-blockies'
|
||||
import styles from './Account.module.scss'
|
||||
import WalletSelector from '../organisms/WalletSelector'
|
||||
import content from '../../data/web3message.json'
|
||||
import { ReactComponent as Caret } from '../../img/caret.svg'
|
||||
import { User } from '../../context'
|
||||
import Button from './Button'
|
||||
|
||||
const Account = ({ account }: { account: string }) => {
|
||||
const blockies = account && toDataUrl(account)
|
||||
export default class Account extends PureComponent<
|
||||
{},
|
||||
{ isAccountInfoOpen: boolean }
|
||||
> {
|
||||
public static contextType = User
|
||||
|
||||
return account && blockies ? (
|
||||
<div className={styles.account}>
|
||||
<img className={styles.blockies} src={blockies} alt="Blockies" />
|
||||
<Dotdotdot clamp={1}>{account}</Dotdotdot>
|
||||
</div>
|
||||
) : (
|
||||
<em>No account selected</em>
|
||||
)
|
||||
public state = {
|
||||
isAccountInfoOpen: false
|
||||
}
|
||||
|
||||
private toggleAccountInfo(event: MouseEvent) {
|
||||
event.preventDefault()
|
||||
this.setState({ isAccountInfoOpen: !this.state.isAccountInfoOpen })
|
||||
}
|
||||
|
||||
public render() {
|
||||
const { account, isBurner, loginMetamask, isWeb3Capable } = this.context
|
||||
const { isAccountInfoOpen } = this.state
|
||||
const seedphrase = localStorage.getItem('seedphrase') as string
|
||||
const blockies = account && toDataUrl(account)
|
||||
|
||||
return (
|
||||
<div className={styles.account}>
|
||||
{account ? (
|
||||
<>
|
||||
<img
|
||||
className={styles.blockies}
|
||||
src={blockies}
|
||||
alt="Blockies"
|
||||
/>
|
||||
<Dotdotdot className={styles.accountId} clamp={2}>
|
||||
{account}
|
||||
</Dotdotdot>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<span className={styles.blockies} />
|
||||
<em className={styles.noAccount}>
|
||||
No account selected
|
||||
</em>
|
||||
<Button
|
||||
link
|
||||
className={styles.unlock}
|
||||
onClick={() => loginMetamask()}
|
||||
>
|
||||
Unlock Account
|
||||
</Button>
|
||||
</>
|
||||
)}
|
||||
|
||||
<div className={styles.accountType}>
|
||||
{isBurner ? (
|
||||
<button
|
||||
className={styles.toggle}
|
||||
onClick={(event) => this.toggleAccountInfo(event)}
|
||||
title="Show More Account Info"
|
||||
>
|
||||
<Caret
|
||||
className={isAccountInfoOpen ? styles.open : ''}
|
||||
/>{' '}
|
||||
Burner Wallet
|
||||
</button>
|
||||
) : (
|
||||
'MetaMask'
|
||||
)}
|
||||
{isWeb3Capable && <WalletSelector />}
|
||||
</div>
|
||||
|
||||
{isBurner && isAccountInfoOpen && (
|
||||
<div className={styles.seedphrase}>
|
||||
<code>{seedphrase}</code>
|
||||
<p className={styles.seedphraseHelp}>
|
||||
{content.seedphrase}
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default Account
|
||||
|
|
|
@ -13,10 +13,10 @@
|
|||
font-weight: $font-weight-bold;
|
||||
text-transform: uppercase;
|
||||
border-radius: 2px;
|
||||
transition: .2s ease-out;
|
||||
transition: 0.2s ease-out;
|
||||
color: $brand-white;
|
||||
background: $brand-grey-light;
|
||||
box-shadow: 0 9px 18px 0 rgba(0, 0, 0, .1);
|
||||
box-shadow: 0 9px 18px 0 rgba(0, 0, 0, 0.1);
|
||||
min-height: 45px;
|
||||
user-select: none;
|
||||
|
||||
|
@ -25,21 +25,21 @@
|
|||
color: $brand-white;
|
||||
background: $brand-grey-light;
|
||||
text-decoration: none;
|
||||
transform: translate3d(0, -.05rem, 0);
|
||||
box-shadow: 0 12px 30px 0 rgba(0, 0, 0, .1);
|
||||
transform: translate3d(0, -0.05rem, 0);
|
||||
box-shadow: 0 12px 30px 0 rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
&:active {
|
||||
background: $brand-grey-light;
|
||||
transition: none;
|
||||
transform: none;
|
||||
box-shadow: 0 5px 18px 0 rgba(0, 0, 0, .1);
|
||||
box-shadow: 0 5px 18px 0 rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
&:disabled {
|
||||
cursor: not-allowed;
|
||||
pointer-events: none;
|
||||
opacity: .5;
|
||||
opacity: 0.5;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import React from 'react'
|
||||
import { render } from 'react-testing-library'
|
||||
import { render } from '@testing-library/react'
|
||||
import { BrowserRouter as Router } from 'react-router-dom'
|
||||
import Button from './Button'
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import React, { PureComponent } from 'react'
|
||||
import React from 'react'
|
||||
import { Link } from 'react-router-dom'
|
||||
import cx from 'classnames'
|
||||
import styles from './Button.module.scss'
|
||||
|
@ -12,49 +12,37 @@ interface ButtonProps {
|
|||
onClick?: any
|
||||
disabled?: boolean
|
||||
to?: string
|
||||
name?: string
|
||||
}
|
||||
|
||||
export default class Button extends PureComponent<ButtonProps, any> {
|
||||
public render() {
|
||||
let classes
|
||||
const {
|
||||
primary,
|
||||
link,
|
||||
href,
|
||||
children,
|
||||
className,
|
||||
to,
|
||||
...props
|
||||
} = this.props
|
||||
|
||||
if (primary) {
|
||||
classes = styles.buttonPrimary
|
||||
} else if (link) {
|
||||
classes = styles.link
|
||||
} else {
|
||||
classes = styles.button
|
||||
}
|
||||
|
||||
if (to) {
|
||||
return (
|
||||
<Link to={to} className={cx(classes, className)} {...props}>
|
||||
{children}
|
||||
</Link>
|
||||
)
|
||||
}
|
||||
|
||||
if (href) {
|
||||
return (
|
||||
<a href={href} className={cx(classes, className)} {...props}>
|
||||
{children}
|
||||
</a>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<button className={cx(classes, className)} {...props}>
|
||||
{children}
|
||||
</button>
|
||||
)
|
||||
}
|
||||
function getClasses(primary: boolean | undefined, link: boolean | undefined) {
|
||||
return primary ? styles.buttonPrimary : link ? styles.link : styles.button
|
||||
}
|
||||
|
||||
const Button = ({
|
||||
primary,
|
||||
link,
|
||||
href,
|
||||
children,
|
||||
className,
|
||||
to,
|
||||
...props
|
||||
}: ButtonProps) => {
|
||||
const classes = getClasses(primary, link)
|
||||
|
||||
return to ? (
|
||||
<Link to={to} className={cx(classes, className)} {...props}>
|
||||
{children}
|
||||
</Link>
|
||||
) : href ? (
|
||||
<a href={href} className={cx(classes, className)} {...props}>
|
||||
{children}
|
||||
</a>
|
||||
) : (
|
||||
<button className={cx(classes, className)} {...props}>
|
||||
{children}
|
||||
</button>
|
||||
)
|
||||
}
|
||||
|
||||
export default Button
|
||||
|
|
|
@ -2,8 +2,24 @@
|
|||
|
||||
.categoryImage {
|
||||
height: 4rem;
|
||||
background-size: cover;
|
||||
background-size: 100%;
|
||||
background-position: center;
|
||||
margin-bottom: $spacer / $line-height;
|
||||
background-color: $body-background;
|
||||
border-radius: $border-radius;
|
||||
overflow: hidden;
|
||||
opacity: 0.85;
|
||||
transition: 0.2s ease-out;
|
||||
border: 1px solid $brand-grey-lighter;
|
||||
}
|
||||
|
||||
.header {
|
||||
composes: categoryImage;
|
||||
height: 8rem;
|
||||
margin-top: $spacer / $line-height;
|
||||
}
|
||||
|
||||
.dimmed {
|
||||
composes: categoryImage;
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
import React from 'react'
|
||||
import { render } from 'react-testing-library'
|
||||
import { render } from '@testing-library/react'
|
||||
import CategoryImage from './CategoryImage'
|
||||
import formPublish from '../../data/form-publish.json'
|
||||
|
||||
describe('CategoryImage', () => {
|
||||
it('renders fallback image', () => {
|
||||
const { container } = render(<CategoryImage category={''} />)
|
||||
const { container } = render(<CategoryImage category="" />)
|
||||
expect(container.firstChild).toBeInTheDocument()
|
||||
expect(container.firstChild.style.backgroundImage).toMatch(
|
||||
/jellyfish-back/
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import React, { PureComponent } from 'react'
|
||||
import cx from 'classnames'
|
||||
import styles from './CategoryImage.module.scss'
|
||||
|
||||
import agriculture from '../../img/categories/agriculture.jpg'
|
||||
|
@ -33,6 +34,7 @@ import theology from '../../img/categories/theology.jpg'
|
|||
import transport from '../../img/categories/transport.jpg'
|
||||
import urbanplanning from '../../img/categories/urbanplanning.jpg'
|
||||
import visualart from '../../img/categories/visualart.jpg'
|
||||
import aiforgood from '../../img/aiforgood.jpg'
|
||||
import fallback from '@oceanprotocol/art/jellyfish/jellyfish-back.svg'
|
||||
|
||||
const categoryImageFile = (category: string) => {
|
||||
|
@ -95,6 +97,8 @@ const categoryImageFile = (category: string) => {
|
|||
case 'mathematics':
|
||||
return mathematics
|
||||
case 'Medicine':
|
||||
case 'Health & Medicine':
|
||||
case 'Health':
|
||||
case 'medicine':
|
||||
return medicine
|
||||
case 'Other':
|
||||
|
@ -133,23 +137,31 @@ const categoryImageFile = (category: string) => {
|
|||
case 'Visual Arts & Design':
|
||||
case 'visualart':
|
||||
return visualart
|
||||
case 'AI for Good':
|
||||
return dataofdata
|
||||
// technically no category
|
||||
// but corresponding to title of a channel
|
||||
case 'AI For Good':
|
||||
return aiforgood
|
||||
default:
|
||||
return fallback
|
||||
}
|
||||
}
|
||||
|
||||
export default class CategoryImage extends PureComponent<{ category: string }> {
|
||||
export default class CategoryImage extends PureComponent<{
|
||||
category: string
|
||||
header?: boolean
|
||||
dimmed?: boolean
|
||||
}> {
|
||||
public render() {
|
||||
const image = categoryImageFile(this.props.category)
|
||||
const classNames = cx(styles.categoryImage, {
|
||||
[styles.header]: this.props.header,
|
||||
[styles.dimmed]: this.props.dimmed
|
||||
})
|
||||
|
||||
return (
|
||||
<div
|
||||
className={styles.categoryImage}
|
||||
style={{
|
||||
backgroundImage: `url(${image})`
|
||||
}}
|
||||
className={classNames}
|
||||
style={{ backgroundImage: `url(${image})` }}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
import React from 'react'
|
||||
import { Link } from 'react-router-dom'
|
||||
|
||||
const CategoryLink = ({
|
||||
category,
|
||||
children,
|
||||
className,
|
||||
...props
|
||||
}: {
|
||||
category: string
|
||||
children?: any
|
||||
className?: string
|
||||
}) => (
|
||||
<Link
|
||||
to={`/search?categories=${encodeURIComponent(category)}`}
|
||||
className={className}
|
||||
{...props}
|
||||
>
|
||||
{children || category}
|
||||
</Link>
|
||||
)
|
||||
|
||||
export default CategoryLink
|
|
@ -1,5 +1,5 @@
|
|||
import React from 'react'
|
||||
import { render } from 'react-testing-library'
|
||||
import { render } from '@testing-library/react'
|
||||
import Form from './Form'
|
||||
|
||||
describe('Form', () => {
|
||||
|
|
|
@ -31,8 +31,8 @@
|
|||
width: 1.25rem;
|
||||
height: 1.25rem;
|
||||
top: 50%;
|
||||
margin-top: -.6rem;
|
||||
fill: rgba($brand-grey-light, .7);
|
||||
margin-top: -0.6rem;
|
||||
fill: rgba($brand-grey-light, 0.7);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -48,7 +48,7 @@
|
|||
padding: $spacer / 3;
|
||||
margin: 0;
|
||||
border-radius: $border-radius;
|
||||
transition: .2s ease-out;
|
||||
transition: 0.2s ease-out;
|
||||
min-height: 43px;
|
||||
appearance: none;
|
||||
|
||||
|
@ -63,8 +63,8 @@
|
|||
font-size: $font-size-base;
|
||||
color: $brand-grey-light;
|
||||
font-weight: $font-weight-base;
|
||||
transition: .2s ease-out;
|
||||
opacity: .7;
|
||||
transition: 0.2s ease-out;
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
&[readonly],
|
||||
|
@ -95,7 +95,6 @@
|
|||
border: 0;
|
||||
|
||||
// custom arrow
|
||||
// stylelint-disable
|
||||
background-image: linear-gradient(45deg, transparent 50%, $brand-purple 50%),
|
||||
linear-gradient(135deg, $brand-purple 50%, transparent 50%),
|
||||
linear-gradient(
|
||||
|
@ -107,7 +106,6 @@
|
|||
background-position: calc(100% - 18px) calc(1rem + 5px),
|
||||
calc(100% - 13px) calc(1rem + 5px), 100% 0;
|
||||
background-size: 5px 5px, 5px 5px, 2.5rem 3rem;
|
||||
// stylelint-enable
|
||||
background-repeat: no-repeat;
|
||||
|
||||
&:focus {
|
||||
|
@ -153,7 +151,7 @@
|
|||
font-size: $font-size-small;
|
||||
line-height: 1.2;
|
||||
border: 2px solid $brand-grey-lighter;
|
||||
border-radius: .2rem;
|
||||
border-radius: 0.2rem;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import React from 'react'
|
||||
import { render } from 'react-testing-library'
|
||||
import { render, fireEvent } from '@testing-library/react'
|
||||
import Input from './Input'
|
||||
|
||||
describe('Input', () => {
|
||||
|
@ -7,10 +7,10 @@ describe('Input', () => {
|
|||
const { container } = render(<Input name="my-input" label="My Input" />)
|
||||
expect(container.firstChild).toBeInTheDocument()
|
||||
expect(container.querySelector('.label')).toHaveTextContent('My Input')
|
||||
expect(container.querySelector('.input')).toHaveAttribute(
|
||||
'id',
|
||||
'my-input'
|
||||
)
|
||||
|
||||
const input = container.querySelector('.input')
|
||||
expect(input).toHaveAttribute('id', 'my-input')
|
||||
input && fireEvent.focus(input)
|
||||
})
|
||||
|
||||
it('renders as text input by default', () => {
|
||||
|
@ -25,13 +25,13 @@ describe('Input', () => {
|
|||
const { container } = render(
|
||||
<Input name="my-input" label="My Input" type="search" />
|
||||
)
|
||||
expect(container.querySelector('.input')).toHaveAttribute(
|
||||
'type',
|
||||
'search'
|
||||
)
|
||||
const input = container.querySelector('.input')
|
||||
expect(input).toHaveAttribute('type', 'search')
|
||||
expect(container.querySelector('label + div')).toHaveClass(
|
||||
'inputWrapSearch'
|
||||
)
|
||||
|
||||
input && fireEvent.focus(input)
|
||||
})
|
||||
|
||||
it('renders select', () => {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import cx from 'classnames'
|
||||
import React, { PureComponent, FormEvent, ChangeEvent } from 'react'
|
||||
import slugify from 'slugify'
|
||||
import slugify from '@sindresorhus/slugify'
|
||||
import DatePicker from 'react-datepicker'
|
||||
import { ReactComponent as SearchIcon } from '../../../img/search.svg'
|
||||
import Help from './Help'
|
||||
|
@ -30,6 +30,7 @@ interface InputProps {
|
|||
rows?: number
|
||||
group?: any
|
||||
multiple?: boolean
|
||||
pattern?: string
|
||||
}
|
||||
|
||||
interface InputState {
|
||||
|
@ -55,7 +56,7 @@ export default class Input extends PureComponent<InputProps, InputState> {
|
|||
}
|
||||
}
|
||||
|
||||
public toggleFocus = () => {
|
||||
public handleFocus = () => {
|
||||
this.setState({ isFocused: !this.state.isFocused })
|
||||
}
|
||||
|
||||
|
@ -93,8 +94,8 @@ export default class Input extends PureComponent<InputProps, InputState> {
|
|||
className={styles.select}
|
||||
name={name}
|
||||
required={required}
|
||||
onFocus={this.toggleFocus}
|
||||
onBlur={this.toggleFocus}
|
||||
onFocus={this.handleFocus}
|
||||
onBlur={this.handleFocus}
|
||||
onChange={onChange}
|
||||
value={value}
|
||||
>
|
||||
|
@ -116,8 +117,8 @@ export default class Input extends PureComponent<InputProps, InputState> {
|
|||
<textarea
|
||||
id={name}
|
||||
className={styles.input}
|
||||
onFocus={this.toggleFocus}
|
||||
onBlur={this.toggleFocus}
|
||||
onFocus={this.handleFocus}
|
||||
onBlur={this.handleFocus}
|
||||
{...this.props}
|
||||
/>
|
||||
</div>
|
||||
|
@ -131,20 +132,14 @@ export default class Input extends PureComponent<InputProps, InputState> {
|
|||
<div className={styles.radioWrap} key={index}>
|
||||
<input
|
||||
className={styles.radio}
|
||||
id={slugify(option, {
|
||||
lower: true
|
||||
})}
|
||||
id={slugify(option)}
|
||||
type={type}
|
||||
name={name}
|
||||
value={slugify(option, {
|
||||
lower: true
|
||||
})}
|
||||
value={slugify(option)}
|
||||
/>
|
||||
<label
|
||||
className={styles.radioLabel}
|
||||
htmlFor={slugify(option, {
|
||||
lower: true
|
||||
})}
|
||||
htmlFor={slugify(option)}
|
||||
>
|
||||
{option}
|
||||
</label>
|
||||
|
@ -159,8 +154,8 @@ export default class Input extends PureComponent<InputProps, InputState> {
|
|||
selected={this.state.dateCreated}
|
||||
onChange={this.handleDateChange}
|
||||
className={styles.input}
|
||||
onFocus={this.toggleFocus}
|
||||
onBlur={this.toggleFocus}
|
||||
onFocus={this.handleFocus}
|
||||
onBlur={this.handleFocus}
|
||||
id={name}
|
||||
name={name}
|
||||
/>
|
||||
|
@ -175,8 +170,8 @@ export default class Input extends PureComponent<InputProps, InputState> {
|
|||
id={name}
|
||||
type={type || 'text'}
|
||||
className={styles.input}
|
||||
onFocus={this.toggleFocus}
|
||||
onBlur={this.toggleFocus}
|
||||
onFocus={this.handleFocus}
|
||||
onBlur={this.handleFocus}
|
||||
{...this.props}
|
||||
/>
|
||||
{group}
|
||||
|
@ -186,8 +181,8 @@ export default class Input extends PureComponent<InputProps, InputState> {
|
|||
id={name}
|
||||
type={type || 'text'}
|
||||
className={styles.input}
|
||||
onFocus={this.toggleFocus}
|
||||
onBlur={this.toggleFocus}
|
||||
onFocus={this.handleFocus}
|
||||
onBlur={this.handleFocus}
|
||||
{...this.props}
|
||||
/>
|
||||
)}
|
||||
|
|
|
@ -39,7 +39,9 @@
|
|||
max-width: 16rem;
|
||||
}
|
||||
|
||||
:global .react-datepicker-popper[data-placement^='top'] .react-datepicker__triangle:before,
|
||||
:global
|
||||
.react-datepicker-popper[data-placement^='top']
|
||||
.react-datepicker__triangle:before,
|
||||
:global .react-datepicker__year-read-view--down-arrow:before,
|
||||
:global .react-datepicker__month-read-view--down-arrow:before,
|
||||
:global .react-datepicker__month-year-read-view--down-arrow:before {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import React from 'react'
|
||||
import { render } from 'react-testing-library'
|
||||
import { render } from '@testing-library/react'
|
||||
import InputGroup from './InputGroup'
|
||||
|
||||
describe('InputGroup', () => {
|
||||
|
|
|
@ -17,6 +17,6 @@
|
|||
font-size: $font-size-base;
|
||||
color: $brand-grey-light;
|
||||
display: inline-block;
|
||||
margin-left: .1rem;
|
||||
margin-left: 0.1rem;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import React from 'react'
|
||||
import { render } from 'react-testing-library'
|
||||
import { render } from '@testing-library/react'
|
||||
import Label from './Label'
|
||||
|
||||
describe('Label', () => {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import React from 'react'
|
||||
import { render } from 'react-testing-library'
|
||||
import { render } from '@testing-library/react'
|
||||
import Row from './Row'
|
||||
|
||||
describe('Row', () => {
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
import React from 'react'
|
||||
import { render } from 'react-testing-library'
|
||||
import { render } from '@testing-library/react'
|
||||
import Markdown from './Markdown'
|
||||
|
||||
describe('Markdown', () => {
|
||||
it('renders without crashing', () => {
|
||||
const { container } = render(<Markdown text={'#hello'} />)
|
||||
const { container } = render(<Markdown text="#hello" />)
|
||||
expect(container.firstChild).toBeInTheDocument()
|
||||
})
|
||||
})
|
||||
|
|
|
@ -0,0 +1,93 @@
|
|||
@import '../../styles/variables';
|
||||
|
||||
// prevent background scrolling
|
||||
:global(.ReactModal__Body--open) {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.modalOverlay {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background: rgba($brand-black, 0.7);
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
animation: fadeIn 0.2s ease-out backwards;
|
||||
}
|
||||
|
||||
.modal {
|
||||
padding: $spacer;
|
||||
border-radius: $border-radius;
|
||||
background: $body-background;
|
||||
margin: $spacer auto;
|
||||
max-width: $break-point--small;
|
||||
position: relative;
|
||||
animation: moveUp 0.2s ease-out backwards;
|
||||
|
||||
@media (min-width: $break-point--small) {
|
||||
padding: $spacer * 2 $spacer * 1.5;
|
||||
}
|
||||
|
||||
&:focus {
|
||||
outline: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.header {
|
||||
margin-bottom: $spacer;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: $font-size-h3;
|
||||
margin: 0;
|
||||
|
||||
@media (min-width: $break-point--small) {
|
||||
font-size: $font-size-h2;
|
||||
}
|
||||
}
|
||||
|
||||
.description {
|
||||
margin: 0;
|
||||
margin-top: $spacer / 2;
|
||||
}
|
||||
|
||||
.close {
|
||||
position: absolute;
|
||||
cursor: pointer;
|
||||
background: none;
|
||||
border: 0;
|
||||
box-shadow: none;
|
||||
outline: 0;
|
||||
top: $spacer / 4;
|
||||
right: $spacer / 2;
|
||||
font-size: $font-size-h2;
|
||||
color: $brand-grey;
|
||||
|
||||
&:hover,
|
||||
&:focus {
|
||||
opacity: 0.7;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes fadeIn {
|
||||
from {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
to {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes moveUp {
|
||||
from {
|
||||
transform: translate3d(0, 1rem, 0);
|
||||
}
|
||||
|
||||
to {
|
||||
transform: translate3d(0, 0, 0);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
import React from 'react'
|
||||
import { render } from '@testing-library/react'
|
||||
import Modal from './Modal'
|
||||
import ReactModal from 'react-modal'
|
||||
|
||||
describe('Modal', () => {
|
||||
it('renders without crashing', () => {
|
||||
ReactModal.setAppElement(document.createElement('div'))
|
||||
|
||||
render(
|
||||
<Modal title="Hello" isOpen toggleModal={() => null}>
|
||||
Hello
|
||||
</Modal>
|
||||
)
|
||||
expect(document.querySelector('.ReactModalPortal')).toBeInTheDocument()
|
||||
})
|
||||
})
|
|
@ -0,0 +1,55 @@
|
|||
import React from 'react'
|
||||
import ReactModal from 'react-modal'
|
||||
import styles from './Modal.module.scss'
|
||||
|
||||
if (process.env.NODE_ENV !== 'test') ReactModal.setAppElement('#root')
|
||||
|
||||
const Modal = ({
|
||||
title,
|
||||
description,
|
||||
isOpen,
|
||||
onToggleModal,
|
||||
children,
|
||||
onAfterOpen,
|
||||
onRequestClose,
|
||||
...props
|
||||
}: {
|
||||
title: string
|
||||
description?: string
|
||||
isOpen: boolean
|
||||
onToggleModal: () => void
|
||||
children: any
|
||||
onAfterOpen?: () => void
|
||||
onRequestClose?: () => void
|
||||
}) => {
|
||||
return (
|
||||
<ReactModal
|
||||
isOpen={isOpen}
|
||||
onAfterOpen={onAfterOpen}
|
||||
onRequestClose={onRequestClose}
|
||||
contentLabel={title}
|
||||
className={styles.modal}
|
||||
overlayClassName={styles.modalOverlay}
|
||||
{...props}
|
||||
>
|
||||
<button
|
||||
className={styles.close}
|
||||
onClick={onToggleModal}
|
||||
data-testid="closeModal"
|
||||
>
|
||||
×
|
||||
</button>
|
||||
|
||||
<header className={styles.header}>
|
||||
<h2 className={styles.title}>{title}</h2>
|
||||
{description && (
|
||||
<p className={styles.description}>{description}</p>
|
||||
)}
|
||||
</header>
|
||||
|
||||
{children}
|
||||
</ReactModal>
|
||||
)
|
||||
}
|
||||
|
||||
export default Modal
|
|
@ -0,0 +1,71 @@
|
|||
import React from 'react'
|
||||
import { Helmet } from 'react-helmet'
|
||||
import { withRouter, RouteComponentProps } from 'react-router-dom'
|
||||
import meta from '../../data/meta.json'
|
||||
import imageDefault from '../../img/share.png'
|
||||
|
||||
const MetaTags = ({
|
||||
title,
|
||||
description,
|
||||
url,
|
||||
image
|
||||
}: {
|
||||
title: string
|
||||
description: string
|
||||
url: string
|
||||
image: string
|
||||
}) => (
|
||||
<Helmet defaultTitle={meta.title} titleTemplate={`%s - ${meta.title}`}>
|
||||
<html lang="en" />
|
||||
|
||||
{title && <title>{title}</title>}
|
||||
|
||||
{/* General tags */}
|
||||
<meta name="description" content={description} />
|
||||
<meta name="image" content={image} />
|
||||
<link rel="canonical" href={url} />
|
||||
|
||||
{/* OpenGraph tags */}
|
||||
<meta property="og:url" content={url} />
|
||||
<meta property="og:title" content={title} />
|
||||
<meta property="og:description" content={description} />
|
||||
<meta property="og:image" content={image} />
|
||||
|
||||
{/* Twitter Card tags */}
|
||||
<meta name="twitter:card" content="summary_large_image" />
|
||||
<meta name="twitter:creator" content="@oceanprotocol" />
|
||||
<meta name="twitter:title" content={title} />
|
||||
<meta name="twitter:description" content={description} />
|
||||
<meta name="twitter:image" content={image} />
|
||||
|
||||
{/* Prevent search engine indexing except for live */}
|
||||
{window.location.hostname !== 'commons.oceanprotocol.com' && (
|
||||
<meta name="robots" content="noindex,nofollow" />
|
||||
)}
|
||||
</Helmet>
|
||||
)
|
||||
|
||||
interface SeoProps extends RouteComponentProps {
|
||||
title?: string
|
||||
description?: string
|
||||
shareImage?: string
|
||||
}
|
||||
|
||||
const Seo = ({ title, description, shareImage, location }: SeoProps) => {
|
||||
title = title || meta.title
|
||||
description = description || meta.description
|
||||
shareImage = shareImage || meta.url + imageDefault
|
||||
|
||||
const url = meta.url + location.pathname + location.search
|
||||
|
||||
return (
|
||||
<MetaTags
|
||||
title={title}
|
||||
description={description}
|
||||
url={url}
|
||||
image={shareImage}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
export default withRouter(Seo)
|
|
@ -5,6 +5,7 @@
|
|||
text-align: center;
|
||||
margin-top: $spacer * $line-height;
|
||||
margin-bottom: $spacer / 2;
|
||||
line-height: 1.3;
|
||||
|
||||
&:before {
|
||||
content: '';
|
||||
|
@ -19,12 +20,27 @@
|
|||
border-radius: 50%;
|
||||
border: 2px solid $brand-purple;
|
||||
border-top-color: $brand-violet;
|
||||
animation: spinner .6s linear infinite;
|
||||
animation: spinner 0.6s linear infinite;
|
||||
}
|
||||
}
|
||||
|
||||
.spinnerMessage {
|
||||
color: $brand-grey-light;
|
||||
padding-top: $spacer / 4;
|
||||
}
|
||||
|
||||
.small {
|
||||
composes: spinner;
|
||||
margin: 0;
|
||||
display: inline-block;
|
||||
|
||||
&:before {
|
||||
width: $font-size-small;
|
||||
height: $font-size-small;
|
||||
margin-top: -($font-size-small);
|
||||
margin-left: -($font-size-small / 2);
|
||||
border-width: 0.1rem;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes spinner {
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
import React from 'react'
|
||||
import { render } from '@testing-library/react'
|
||||
import Spinner from './Spinner'
|
||||
|
||||
describe('Spinner', () => {
|
||||
it('renders without crashing', () => {
|
||||
const { container } = render(<Spinner />)
|
||||
expect(container.firstChild).toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('renders small variant', () => {
|
||||
const { container } = render(<Spinner small />)
|
||||
expect(container.firstChild).toBeInTheDocument()
|
||||
})
|
||||
})
|
|
@ -1,10 +1,27 @@
|
|||
import React from 'react'
|
||||
import styles from './Spinner.module.scss'
|
||||
|
||||
const Spinner = ({ message }: { message?: string }) => (
|
||||
<div className={styles.spinner}>
|
||||
{message && <div className={styles.spinnerMessage}>{message}</div>}
|
||||
</div>
|
||||
)
|
||||
const Spinner = ({
|
||||
message,
|
||||
small,
|
||||
className
|
||||
}: {
|
||||
message?: string
|
||||
small?: boolean
|
||||
className?: string
|
||||
}) => {
|
||||
const classes = className || (small ? styles.small : styles.spinner)
|
||||
|
||||
return (
|
||||
<div className={classes}>
|
||||
{message && (
|
||||
<div
|
||||
className={styles.spinnerMessage}
|
||||
dangerouslySetInnerHTML={{ __html: message }}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default Spinner
|
||||
|
|
|
@ -4,10 +4,10 @@
|
|||
display: inline-block;
|
||||
position: relative;
|
||||
cursor: help;
|
||||
padding: .5rem;
|
||||
padding: 0.5rem;
|
||||
}
|
||||
|
||||
// default: red square
|
||||
/* default: red square */
|
||||
.statusIndicator {
|
||||
width: $font-size-small;
|
||||
height: $font-size-small;
|
||||
|
@ -15,7 +15,7 @@
|
|||
background: $red;
|
||||
}
|
||||
|
||||
// yellow triangle
|
||||
/* yellow triangle */
|
||||
.statusIndicatorCloseEnough {
|
||||
composes: statusIndicator;
|
||||
background: none;
|
||||
|
@ -26,7 +26,7 @@
|
|||
border-bottom: $font-size-small solid $yellow;
|
||||
}
|
||||
|
||||
// green circle
|
||||
/* green circle */
|
||||
.statusIndicatorActive {
|
||||
composes: statusIndicator;
|
||||
border-radius: 50%;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import React from 'react'
|
||||
import cx from 'classnames'
|
||||
import { User } from '../../../context'
|
||||
import { User, Market } from '../../../context'
|
||||
import styles from './Indicator.module.scss'
|
||||
|
||||
const Indicator = ({
|
||||
|
@ -19,15 +19,19 @@ const Indicator = ({
|
|||
ref={forwardedRef}
|
||||
>
|
||||
<User.Consumer>
|
||||
{states =>
|
||||
!states.isWeb3 ? (
|
||||
<span className={styles.statusIndicator} />
|
||||
) : !states.isLogged || !states.isOceanNetwork ? (
|
||||
<span className={styles.statusIndicatorCloseEnough} />
|
||||
) : states.isLogged ? (
|
||||
<span className={styles.statusIndicatorActive} />
|
||||
) : null
|
||||
}
|
||||
{(user) => (
|
||||
<Market.Consumer>
|
||||
{(market) =>
|
||||
!user.isLogged || !market.networkMatch ? (
|
||||
<span
|
||||
className={styles.statusIndicatorCloseEnough}
|
||||
/>
|
||||
) : user.isLogged ? (
|
||||
<span className={styles.statusIndicatorActive} />
|
||||
) : null
|
||||
}
|
||||
</Market.Consumer>
|
||||
)}
|
||||
</User.Consumer>
|
||||
</div>
|
||||
)
|
||||
|
|
|
@ -7,12 +7,12 @@ $popoverWidth: 18rem;
|
|||
width: $popoverWidth;
|
||||
padding: $spacer / 2;
|
||||
background: $brand-black;
|
||||
border-radius: .1rem;
|
||||
border: .1rem solid $brand-grey-light;
|
||||
box-shadow: 0 6px 16px 0 rgba($brand-black, .3);
|
||||
border-radius: 0.1rem;
|
||||
border: 0.1rem solid $brand-grey-light;
|
||||
box-shadow: 0 6px 16px 0 rgba($brand-black, 0.3);
|
||||
color: $brand-grey-light;
|
||||
font-size: $font-size-small;
|
||||
animation: showPopup .2s ease-in forwards;
|
||||
animation: showPopup 0.2s ease-in forwards;
|
||||
white-space: initial;
|
||||
text-align: left;
|
||||
}
|
||||
|
@ -28,7 +28,7 @@ $popoverWidth: 18rem;
|
|||
}
|
||||
|
||||
.popoverInfoline {
|
||||
border-bottom: .05rem solid $brand-grey;
|
||||
border-bottom: 0.05rem solid $brand-grey;
|
||||
padding: $spacer / 3 0;
|
||||
|
||||
&:first-child {
|
||||
|
@ -41,7 +41,10 @@ $popoverWidth: 18rem;
|
|||
}
|
||||
|
||||
button {
|
||||
font-size: $font-size-small;
|
||||
svg,
|
||||
&[data-action] {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -50,6 +53,10 @@ $popoverWidth: 18rem;
|
|||
margin-left: $spacer / 2;
|
||||
white-space: nowrap;
|
||||
|
||||
strong {
|
||||
color: $brand-grey-lighter;
|
||||
}
|
||||
|
||||
&:first-child {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
import React from 'react'
|
||||
import { render } from 'react-testing-library'
|
||||
import { render } from '@testing-library/react'
|
||||
import Popover from './Popover'
|
||||
import { userMock, userMockConnected } from '../../../../__mocks__/user-mock'
|
||||
import { User } from '../../../context'
|
||||
import { userMock, userMockConnected } from '../../../__mocks__/user-mock'
|
||||
import { marketMock } from '../../../__mocks__/market-mock'
|
||||
import { User, Market } from '../../../context'
|
||||
|
||||
describe('Popover', () => {
|
||||
it('renders without crashing', () => {
|
||||
|
@ -25,12 +26,14 @@ describe('Popover', () => {
|
|||
|
||||
it('renders correct network', () => {
|
||||
const { container } = render(
|
||||
<User.Provider value={{ ...userMockConnected, network: 'Nile' }}>
|
||||
<Popover forwardedRef={() => null} style={{}} />
|
||||
<User.Provider value={{ ...userMockConnected, network: 'Pacific' }}>
|
||||
<Market.Provider value={{ ...marketMock }}>
|
||||
<Popover forwardedRef={() => null} style={{}} />
|
||||
</Market.Provider>
|
||||
</User.Provider>
|
||||
)
|
||||
expect(container.firstChild).toBeInTheDocument()
|
||||
expect(container.firstChild).toHaveTextContent('Connected to Nile')
|
||||
expect(container.firstChild).toHaveTextContent('Connected to Pacific')
|
||||
})
|
||||
|
||||
it('renders with wrong network', () => {
|
||||
|
@ -38,7 +41,6 @@ describe('Popover', () => {
|
|||
<User.Provider
|
||||
value={{
|
||||
...userMockConnected,
|
||||
isOceanNetwork: false,
|
||||
network: '1'
|
||||
}}
|
||||
>
|
||||
|
|
|
@ -1,20 +1,16 @@
|
|||
import React, { PureComponent } from 'react'
|
||||
import Account from '../../atoms/Account'
|
||||
import { User } from '../../../context'
|
||||
import { User, Market } from '../../../context'
|
||||
import styles from './Popover.module.scss'
|
||||
|
||||
export default class Popover extends PureComponent<{
|
||||
forwardedRef: (ref: HTMLElement | null) => void
|
||||
style: React.CSSProperties
|
||||
forwardedRef?: (ref: HTMLElement | null) => void
|
||||
style?: React.CSSProperties
|
||||
}> {
|
||||
public static contextType = User
|
||||
|
||||
public render() {
|
||||
const {
|
||||
account,
|
||||
balance,
|
||||
network,
|
||||
isWeb3,
|
||||
isOceanNetwork
|
||||
} = this.context
|
||||
const { account, balance, network } = this.context
|
||||
|
||||
return (
|
||||
<div
|
||||
|
@ -22,46 +18,46 @@ export default class Popover extends PureComponent<{
|
|||
ref={this.props.forwardedRef}
|
||||
style={this.props.style}
|
||||
>
|
||||
{!isWeb3 ? (
|
||||
<div className={styles.popoverInfoline}>
|
||||
<Account />
|
||||
</div>
|
||||
|
||||
{account && balance && (
|
||||
<div className={styles.popoverInfoline}>
|
||||
No Web3 detected. Use a browser with MetaMask installed
|
||||
to publish assets.
|
||||
<span
|
||||
className={styles.balance}
|
||||
title={(balance.eth / 1e18).toFixed(10)}
|
||||
>
|
||||
<strong>
|
||||
{(balance.eth / 1e18).toFixed(3).slice(0, -1)}
|
||||
</strong>{' '}
|
||||
ETH
|
||||
</span>
|
||||
<span className={styles.balance}>
|
||||
<strong>{balance.ocn}</strong> OCEAN
|
||||
</span>
|
||||
</div>
|
||||
) : (
|
||||
<>
|
||||
<div className={styles.popoverInfoline}>
|
||||
<Account account={account} />
|
||||
</div>
|
||||
|
||||
{account && balance && (
|
||||
<div className={styles.popoverInfoline}>
|
||||
<span
|
||||
className={styles.balance}
|
||||
title={(balance.eth / 1e18).toFixed(10)}
|
||||
>
|
||||
<strong>
|
||||
{(balance.eth / 1e18)
|
||||
.toFixed(3)
|
||||
.slice(0, -1)}
|
||||
</strong>{' '}
|
||||
ETH
|
||||
</span>
|
||||
<span className={styles.balance}>
|
||||
<strong>{balance.ocn}</strong> OCEAN
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
)}
|
||||
|
||||
<Market.Consumer>
|
||||
{(market) => (
|
||||
<div className={styles.popoverInfoline}>
|
||||
{network && !isOceanNetwork
|
||||
? 'Please connect to Custom RPC\n https://nile.dev-ocean.com'
|
||||
{network && !market.networkMatch
|
||||
? `Please connect to Custom RPC
|
||||
${
|
||||
market.network === 'Pacific'
|
||||
? 'https://pacific.oceanprotocol.com'
|
||||
: market.network === 'Nile'
|
||||
? 'https://nile.dev-ocean.com'
|
||||
: market.network === 'Duero'
|
||||
? 'https://duero.dev-ocean.com'
|
||||
: 'http://localhost:8545'
|
||||
}`
|
||||
: network && `Connected to ${network} network`}
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
)}
|
||||
</Market.Consumer>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Popover.contextType = User
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import React from 'react'
|
||||
import { render, fireEvent } from 'react-testing-library'
|
||||
import { render, fireEvent } from '@testing-library/react'
|
||||
import AccountStatus from '.'
|
||||
|
||||
describe('AccountStatus', () => {
|
||||
|
@ -10,9 +10,7 @@ describe('AccountStatus', () => {
|
|||
|
||||
it('togglePopover fires', () => {
|
||||
const { container } = render(<AccountStatus />)
|
||||
|
||||
const indicator = container.querySelector('.statusIndicator')
|
||||
|
||||
const indicator = container.querySelector('.status')
|
||||
indicator && fireEvent.mouseOver(indicator)
|
||||
expect(container.querySelector('.popover')).toBeInTheDocument()
|
||||
indicator && fireEvent.mouseOut(indicator)
|
||||
|
|
|
@ -20,7 +20,7 @@ export default class AccountStatus extends PureComponent<
|
|||
}
|
||||
|
||||
private togglePopover() {
|
||||
this.setState(prevState => ({
|
||||
this.setState((prevState) => ({
|
||||
isPopoverOpen: !prevState.isPopoverOpen
|
||||
}))
|
||||
}
|
||||
|
@ -29,7 +29,7 @@ export default class AccountStatus extends PureComponent<
|
|||
return (
|
||||
<Manager>
|
||||
<Reference>
|
||||
{({ ref }) => (
|
||||
{({ ref }: { ref: any }) => (
|
||||
<AccountIndicator
|
||||
togglePopover={() => this.togglePopover()}
|
||||
className={this.props.className}
|
||||
|
@ -39,7 +39,15 @@ export default class AccountStatus extends PureComponent<
|
|||
</Reference>
|
||||
{this.state.isPopoverOpen && (
|
||||
<Popper placement="auto">
|
||||
{({ ref, style, placement }) => (
|
||||
{({
|
||||
ref,
|
||||
style,
|
||||
placement
|
||||
}: {
|
||||
ref: any
|
||||
style: any
|
||||
placement: any
|
||||
}) => (
|
||||
<AccountPopover
|
||||
forwardedRef={ref}
|
||||
style={style}
|
||||
|
|
|
@ -1,44 +0,0 @@
|
|||
import React from 'react'
|
||||
import { Link } from 'react-router-dom'
|
||||
import moment from 'moment'
|
||||
import Dotdotdot from 'react-dotdotdot'
|
||||
import styles from './Asset.module.scss'
|
||||
import CategoryImage from '../atoms/CategoryImage'
|
||||
|
||||
const AssetLink = ({ asset, list }: { asset: any; list?: boolean }) => {
|
||||
const { metadata } = asset.findServiceByType('Metadata')
|
||||
const { base } = metadata
|
||||
|
||||
return list ? (
|
||||
<article className={styles.assetList}>
|
||||
<Link to={`/asset/${asset.id}`}>
|
||||
<h1>{base.name}</h1>
|
||||
<div
|
||||
className={styles.date}
|
||||
title={`Published on ${base.datePublished}`}
|
||||
>
|
||||
{moment(base.datePublished, 'YYYYMMDD').fromNow()}
|
||||
</div>
|
||||
</Link>
|
||||
</article>
|
||||
) : (
|
||||
<article className={styles.asset}>
|
||||
<Link to={`/asset/${asset.id}`}>
|
||||
{base.categories && (
|
||||
<CategoryImage category={base.categories[0]} />
|
||||
)}
|
||||
<h1>{base.name}</h1>
|
||||
|
||||
<div className={styles.description}>
|
||||
<Dotdotdot clamp={3}>{base.description}</Dotdotdot>
|
||||
</div>
|
||||
|
||||
<footer className={styles.assetFooter}>
|
||||
{base.categories && <div>{base.categories[0]}</div>}
|
||||
</footer>
|
||||
</Link>
|
||||
</article>
|
||||
)
|
||||
}
|
||||
|
||||
export default AssetLink
|
|
@ -20,12 +20,25 @@
|
|||
color: inherit;
|
||||
border-color: $brand-pink;
|
||||
transform: none;
|
||||
|
||||
// category image
|
||||
> div:first-child {
|
||||
opacity: 1;
|
||||
background-size: 105%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: $font-size-large;
|
||||
margin-top: 0;
|
||||
margin-bottom: $spacer / 4;
|
||||
}
|
||||
}
|
||||
|
||||
.minimal {
|
||||
h1 {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -77,7 +90,18 @@
|
|||
}
|
||||
|
||||
.assetFooter {
|
||||
margin-top: $spacer / 2;
|
||||
margin-top: $spacer;
|
||||
font-size: $font-size-small;
|
||||
color: $brand-grey-light;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.price {
|
||||
font-size: $font-size-mini;
|
||||
|
||||
span {
|
||||
color: $brand-grey;
|
||||
font-size: $font-size-small;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,78 @@
|
|||
import React from 'react'
|
||||
import { Link } from 'react-router-dom'
|
||||
import moment from 'moment'
|
||||
import Dotdotdot from 'react-dotdotdot'
|
||||
import cx from 'classnames'
|
||||
import styles from './AssetTeaser.module.scss'
|
||||
import CategoryImage from '../atoms/CategoryImage'
|
||||
import { allowPricing } from '../../config'
|
||||
import Web3 from 'web3'
|
||||
|
||||
const AssetTeaser = ({
|
||||
asset,
|
||||
list,
|
||||
minimal
|
||||
}: {
|
||||
asset: any
|
||||
list?: boolean
|
||||
minimal?: boolean
|
||||
}) => {
|
||||
const { attributes } = asset.findServiceByType('metadata')
|
||||
const { main, additionalInformation } = attributes
|
||||
|
||||
return list ? (
|
||||
<article className={styles.assetList}>
|
||||
<Link to={`/asset/${asset.id}`}>
|
||||
<h1>{main.name}</h1>
|
||||
<div
|
||||
className={styles.date}
|
||||
title={`Published on ${main.datePublished}`}
|
||||
>
|
||||
{moment(main.datePublished, 'YYYYMMDD').fromNow()}
|
||||
</div>
|
||||
</Link>
|
||||
</article>
|
||||
) : (
|
||||
<article
|
||||
className={
|
||||
minimal ? cx(styles.asset, styles.minimal) : styles.asset
|
||||
}
|
||||
>
|
||||
<Link to={`/asset/${asset.id}`}>
|
||||
{additionalInformation &&
|
||||
additionalInformation.categories &&
|
||||
!minimal && (
|
||||
<CategoryImage
|
||||
dimmed
|
||||
category={additionalInformation.categories[0]}
|
||||
/>
|
||||
)}
|
||||
<h1>{main.name}</h1>
|
||||
|
||||
{additionalInformation && !minimal && (
|
||||
<div className={styles.description}>
|
||||
<Dotdotdot clamp={3}>
|
||||
{additionalInformation.description}
|
||||
</Dotdotdot>
|
||||
</div>
|
||||
)}
|
||||
<footer className={styles.assetFooter}>
|
||||
{additionalInformation &&
|
||||
additionalInformation.categories && (
|
||||
<div>{additionalInformation.categories[0]}</div>
|
||||
)}
|
||||
{allowPricing && (
|
||||
<div className={styles.price}>
|
||||
<span>
|
||||
{Web3.utils.fromWei(main.price.toString())}
|
||||
</span>{' '}
|
||||
OCEAN
|
||||
</div>
|
||||
)}
|
||||
</footer>
|
||||
</Link>
|
||||
</article>
|
||||
)
|
||||
}
|
||||
|
||||
export default AssetTeaser
|
|
@ -0,0 +1,45 @@
|
|||
@import '../../styles/variables';
|
||||
|
||||
.dropzone {
|
||||
margin-top: $spacer;
|
||||
margin-bottom: $spacer;
|
||||
border: 0.2rem dashed $brand-grey-lighter;
|
||||
border-radius: $border-radius * 2;
|
||||
padding: $spacer;
|
||||
background: $brand-white;
|
||||
transition: 0.2s ease-out;
|
||||
cursor: pointer;
|
||||
|
||||
p {
|
||||
text-align: center;
|
||||
margin-bottom: 0;
|
||||
font-size: $font-size-small;
|
||||
color: $brand-grey-light;
|
||||
}
|
||||
|
||||
&:hover,
|
||||
&:focus,
|
||||
&:active {
|
||||
border-color: $brand-grey-light;
|
||||
outline: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.dragover {
|
||||
composes: dropzone;
|
||||
border-color: $brand-pink;
|
||||
}
|
||||
|
||||
.disabled {
|
||||
composes: dropzone;
|
||||
opacity: 0.5;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.dropzoneFiles {
|
||||
padding: $spacer 0;
|
||||
|
||||
ul {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
import React from 'react'
|
||||
import { fireEvent, render, act } from '@testing-library/react'
|
||||
import Dropzone from './Dropzone'
|
||||
|
||||
function mockData(files: any) {
|
||||
return {
|
||||
dataTransfer: {
|
||||
files,
|
||||
items: files.map((file: any) => ({
|
||||
kind: 'file',
|
||||
type: file.type,
|
||||
getAsFile: () => file
|
||||
})),
|
||||
types: ['Files']
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function flushPromises(ui: any, container: any) {
|
||||
return new Promise((resolve) =>
|
||||
setImmediate(() => {
|
||||
render(ui, { container })
|
||||
resolve(container)
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
function dispatchEvt(node: any, type: string, data: any) {
|
||||
const event = new Event(type, { bubbles: true })
|
||||
Object.assign(event, data)
|
||||
fireEvent(node, event)
|
||||
}
|
||||
|
||||
test('invoke onDragEnter when dragenter event occurs', async () => {
|
||||
const file = new File([JSON.stringify({ ping: true })], 'ping.json', {
|
||||
type: 'application/json'
|
||||
})
|
||||
const data = mockData([file])
|
||||
const handleOnDrop = jest.fn()
|
||||
|
||||
await act(async () => {
|
||||
const ui = <Dropzone handleOnDrop={handleOnDrop} />
|
||||
const { container } = render(ui)
|
||||
|
||||
// drop a file
|
||||
const dropzone = container.querySelector('div')
|
||||
dispatchEvt(dropzone, 'dragenter', data)
|
||||
dispatchEvt(dropzone, 'dragover', data)
|
||||
dispatchEvt(dropzone, 'drop', data)
|
||||
await flushPromises(ui, container)
|
||||
})
|
||||
|
||||
expect(handleOnDrop).toHaveBeenCalled()
|
||||
})
|
|
@ -0,0 +1,62 @@
|
|||
import React, { useCallback } from 'react'
|
||||
import { useDropzone } from 'react-dropzone'
|
||||
import styles from './Dropzone.module.scss'
|
||||
import { formatBytes } from '../../utils/utils'
|
||||
|
||||
export default function Dropzone({
|
||||
handleOnDrop,
|
||||
disabled,
|
||||
multiple
|
||||
}: {
|
||||
handleOnDrop(files: File[]): void
|
||||
disabled?: boolean
|
||||
multiple?: boolean
|
||||
}) {
|
||||
const onDrop = useCallback((acceptedFiles) => handleOnDrop(acceptedFiles), [
|
||||
handleOnDrop
|
||||
])
|
||||
|
||||
const {
|
||||
acceptedFiles,
|
||||
getRootProps,
|
||||
getInputProps,
|
||||
isDragActive,
|
||||
isDragReject
|
||||
} = useDropzone({ onDrop })
|
||||
|
||||
const files = acceptedFiles.map((file: any) => (
|
||||
<li key={file.path}>
|
||||
{file.path} - {formatBytes(file.size, 0)}
|
||||
</li>
|
||||
))
|
||||
|
||||
return (
|
||||
<>
|
||||
{acceptedFiles.length > 0 ? (
|
||||
<aside className={styles.dropzoneFiles}>
|
||||
<ul>{files}</ul>
|
||||
</aside>
|
||||
) : (
|
||||
<div
|
||||
{...getRootProps({
|
||||
className: isDragActive
|
||||
? styles.dragover
|
||||
: disabled
|
||||
? styles.disabled
|
||||
: styles.dropzone
|
||||
})}
|
||||
>
|
||||
<input {...getInputProps({ multiple })} />
|
||||
<p>
|
||||
{isDragActive && !isDragReject
|
||||
? `Drop it like it's hot!`
|
||||
: multiple
|
||||
? `Drag 'n' drop some files here, or click to select files`
|
||||
: `Drag 'n' drop a file here, or click to select a file`}
|
||||
{}
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
)
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
@import '../../styles/variables';
|
||||
|
||||
.assetList {
|
||||
color: $brand-grey-dark;
|
||||
border-bottom: 1px solid $brand-grey-lighter;
|
||||
padding-top: $spacer / 2;
|
||||
padding-bottom: $spacer / 2;
|
||||
|
||||
h1 {
|
||||
font-size: $font-size-base;
|
||||
color: inherit;
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.listRow {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.date {
|
||||
font-size: $font-size-small;
|
||||
color: $brand-grey-light;
|
||||
}
|
|
@ -0,0 +1,75 @@
|
|||
import React, { useEffect, useState, useContext } from 'react'
|
||||
import { User } from '../../context'
|
||||
import moment from 'moment'
|
||||
import shortid from 'shortid'
|
||||
import styles from './JobTeaser.module.scss'
|
||||
import Dotdotdot from 'react-dotdotdot'
|
||||
|
||||
export default function JobTeaser({ job }: { job: any }) {
|
||||
const { ocean } = useContext(User)
|
||||
const [assetName, setAssetName] = useState()
|
||||
const [assetUrl, setAssetUrl] = useState()
|
||||
useEffect(() => {
|
||||
async function getAsset() {
|
||||
try {
|
||||
const {
|
||||
did
|
||||
} = await (ocean as any).keeper.agreementStoreManager.getAgreement(
|
||||
job.agreementId
|
||||
)
|
||||
const asset = await (ocean as any).assets.resolve(did)
|
||||
const { attributes } = asset.findServiceByType('metadata')
|
||||
const { main } = attributes
|
||||
const link = '/asset/did:op:' + did
|
||||
setAssetName(main.name)
|
||||
setAssetUrl(link as any)
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
}
|
||||
}
|
||||
|
||||
getAsset()
|
||||
}, [ocean, job.agreementId])
|
||||
|
||||
return (
|
||||
<article className={styles.assetList}>
|
||||
<div className={styles.listRow}>
|
||||
<h1>
|
||||
<a href={assetUrl}>{assetName}</a>
|
||||
</h1>
|
||||
<div
|
||||
className={styles.date}
|
||||
title={`Created on ${job.dateCreated}`}
|
||||
>
|
||||
{moment.unix(job.dateCreated).fromNow()}
|
||||
</div>
|
||||
</div>
|
||||
<div className={styles.listRow}>
|
||||
<div>Job status</div>
|
||||
<div>{job.statusText}</div>
|
||||
</div>
|
||||
<div>
|
||||
{job.algorithmLogUrl ? (
|
||||
<a href={job.algorithmLogUrl}> Algorithm log</a>
|
||||
) : (
|
||||
''
|
||||
)}
|
||||
</div>
|
||||
<div>
|
||||
{job.resultsUrl ? (
|
||||
<>
|
||||
<div>Output URL</div>
|
||||
{job.resultsUrl.map((result: string) => (
|
||||
<a href={result} key={shortid.generate()}>
|
||||
{' '}
|
||||
{result.substring(0, 52)}...
|
||||
</a>
|
||||
))}
|
||||
</>
|
||||
) : (
|
||||
''
|
||||
)}
|
||||
</div>
|
||||
</article>
|
||||
)
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
import React from 'react'
|
||||
import { render } from 'react-testing-library'
|
||||
import { render } from '@testing-library/react'
|
||||
import Pagination from './Pagination'
|
||||
|
||||
describe('Pagination', () => {
|
||||
|
|
|
@ -17,17 +17,18 @@ export default class Pagination extends PureComponent<
|
|||
PaginationState
|
||||
> {
|
||||
public state = { smallViewport: true }
|
||||
|
||||
private mq = window.matchMedia && window.matchMedia('(min-width: 600px)')
|
||||
|
||||
public componentDidMount() {
|
||||
if (window.matchMedia) {
|
||||
if (window && window.matchMedia) {
|
||||
this.mq.addListener(this.viewportChange)
|
||||
this.viewportChange(this.mq)
|
||||
}
|
||||
}
|
||||
|
||||
public componentWillUnmount() {
|
||||
if (window.matchMedia) {
|
||||
if (window && window.matchMedia) {
|
||||
this.mq.removeListener(this.viewportChange)
|
||||
}
|
||||
}
|
||||
|
@ -53,11 +54,11 @@ export default class Pagination extends PureComponent<
|
|||
// adapt based on media query match
|
||||
marginPagesDisplayed={smallViewport ? 0 : 1}
|
||||
pageRangeDisplayed={smallViewport ? 3 : 6}
|
||||
onPageChange={data => handlePageClick(data)}
|
||||
onPageChange={(data) => handlePageClick(data)}
|
||||
disableInitialCallback
|
||||
previousLabel={'←'}
|
||||
nextLabel={'→'}
|
||||
breakLabel={'...'}
|
||||
previousLabel="←"
|
||||
nextLabel="→"
|
||||
breakLabel="..."
|
||||
containerClassName={styles.pagination}
|
||||
pageLinkClassName={styles.number}
|
||||
activeLinkClassName={styles.current}
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
@import '../../styles/variables';
|
||||
|
||||
.results {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr;
|
||||
grid-gap: $spacer;
|
||||
max-width: calc(18rem + #{$spacer * 2});
|
||||
margin: auto;
|
||||
margin-top: $spacer * 2;
|
||||
|
||||
@media (min-width: $break-point--small) {
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
max-width: none;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
}
|
||||
|
||||
@media (min-width: $break-point--medium) {
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
}
|
||||
}
|
||||
|
||||
.simple {
|
||||
composes: results;
|
||||
margin-top: 0;
|
||||
|
||||
@media (min-width: $break-point--medium) {
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
}
|
||||
}
|
||||
|
||||
.empty {
|
||||
text-align: center;
|
||||
margin-top: $spacer * 4;
|
||||
color: $brand-grey-light;
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
import React from 'react'
|
||||
import { Link } from 'react-router-dom'
|
||||
import { DDO } from '@oceanprotocol/squid'
|
||||
import Spinner from '../atoms/Spinner'
|
||||
import AssetTeaser from './AssetTeaser'
|
||||
import styles from './SearchResults.module.scss'
|
||||
|
||||
export interface SearchResultsState {
|
||||
results: DDO[]
|
||||
totalResults: number
|
||||
offset: number
|
||||
totalPages: number
|
||||
currentPage: number
|
||||
isLoading: boolean
|
||||
}
|
||||
|
||||
export default function SearchResults({
|
||||
isLoading,
|
||||
results,
|
||||
simpleGrid
|
||||
}: {
|
||||
isLoading: boolean
|
||||
results: DDO[]
|
||||
simpleGrid?: boolean
|
||||
}) {
|
||||
return isLoading ? (
|
||||
<Spinner message="Searching..." />
|
||||
) : results && results.length ? (
|
||||
<div className={simpleGrid ? styles.simple : styles.results}>
|
||||
{results.map((asset: any) => (
|
||||
<AssetTeaser key={asset.id} asset={asset} />
|
||||
))}
|
||||
</div>
|
||||
) : (
|
||||
<div className={styles.empty}>
|
||||
<p>No Data Sets Found.</p>
|
||||
<Link to="/publish">+ Publish A Data Set</Link>
|
||||
</div>
|
||||
)
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
@import '../../../styles/variables';
|
||||
|
||||
.spinner {
|
||||
composes: spinner, small from '../../atoms/Spinner.module.scss';
|
||||
margin-right: $spacer;
|
||||
}
|
||||
|
||||
.commit {
|
||||
margin-left: $spacer / 8;
|
||||
|
||||
code {
|
||||
color: $brand-grey-light;
|
||||
font-size: $font-size-mini;
|
||||
}
|
||||
}
|
||||
|
||||
.network {
|
||||
color: $brand-grey-light;
|
||||
text-transform: capitalize;
|
||||
margin-left: $spacer / 8;
|
||||
font-size: $font-size-mini;
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
import React from 'react'
|
||||
import { render } from '@testing-library/react'
|
||||
import VersionNumber from './VersionNumber'
|
||||
|
||||
describe('VersionNumber', () => {
|
||||
it('renders without crashing', () => {
|
||||
const { container } = render(<VersionNumber name="Commons" />)
|
||||
expect(container.firstChild).toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('renders with all props set', () => {
|
||||
const { container } = render(
|
||||
<VersionNumber
|
||||
name="Commons"
|
||||
version="6.6.6"
|
||||
network="Nile"
|
||||
commit="xxxxxxxxxxx"
|
||||
/>
|
||||
)
|
||||
expect(container.firstChild).toBeInTheDocument()
|
||||
expect(container.firstChild).toHaveTextContent('6.6.6')
|
||||
})
|
||||
})
|
|
@ -0,0 +1,53 @@
|
|||
import React from 'react'
|
||||
import { OceanPlatformTechStatus } from '@oceanprotocol/squid'
|
||||
import slugify from '@sindresorhus/slugify'
|
||||
import Spinner from '../../atoms/Spinner'
|
||||
import styles from './VersionNumber.module.scss'
|
||||
|
||||
const VersionNumber = ({
|
||||
name,
|
||||
version,
|
||||
network,
|
||||
status,
|
||||
commit
|
||||
}: {
|
||||
name: string
|
||||
version?: string
|
||||
network?: string
|
||||
status?: OceanPlatformTechStatus
|
||||
commit?: string
|
||||
}) =>
|
||||
version ? (
|
||||
<>
|
||||
<a
|
||||
href={`https://github.com/oceanprotocol/${slugify(
|
||||
name
|
||||
)}/releases/tag/v${version}`}
|
||||
title="Go to release on GitHub"
|
||||
>
|
||||
<code>v{version}</code>
|
||||
</a>
|
||||
{commit && (
|
||||
<a
|
||||
href={`https://github.com/oceanprotocol/${slugify(
|
||||
name
|
||||
)}/commit/${commit}`}
|
||||
className={styles.commit}
|
||||
title={`Go to commit ${commit} on GitHub`}
|
||||
>
|
||||
<code>{commit.substring(0, 7)}</code>
|
||||
</a>
|
||||
)}
|
||||
{network && <span className={styles.network}>{` ${network}`}</span>}
|
||||
</>
|
||||
) : (
|
||||
<span>
|
||||
{status === OceanPlatformTechStatus.Loading ? (
|
||||
<Spinner className={styles.spinner} small />
|
||||
) : (
|
||||
status || 'Could not get version'
|
||||
)}
|
||||
</span>
|
||||
)
|
||||
|
||||
export default VersionNumber
|
|
@ -0,0 +1,37 @@
|
|||
@import '../../../styles/variables';
|
||||
|
||||
.status {
|
||||
text-align: center;
|
||||
padding-top: $spacer / 2;
|
||||
padding-bottom: $spacer;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.element {
|
||||
display: inline-block;
|
||||
margin-left: $spacer / 1.5;
|
||||
margin-right: $spacer / 1.5;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.indicator,
|
||||
.indicatorActive {
|
||||
display: inline-block;
|
||||
margin-right: $spacer / 4;
|
||||
margin-bottom: -0.1rem;
|
||||
}
|
||||
|
||||
.indicator {
|
||||
composes: statusindicator from '../AccountStatus/Indicator.module.scss';
|
||||
}
|
||||
|
||||
.indicatorActive {
|
||||
composes: statusindicatoractive from '../AccountStatus/Indicator.module.scss';
|
||||
}
|
||||
|
||||
.indicatorLabel {
|
||||
font-family: $font-family-title;
|
||||
color: $brand-grey;
|
||||
text-transform: capitalize;
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
import React from 'react'
|
||||
import { render } from '@testing-library/react'
|
||||
import VersionStatus from './VersionStatus'
|
||||
|
||||
describe('VersionStatus', () => {
|
||||
it('renders without crashing', () => {
|
||||
const { container } = render(
|
||||
<VersionStatus
|
||||
status={{ ok: false, contracts: false, network: false }}
|
||||
/>
|
||||
)
|
||||
expect(container.firstChild).toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('renders true states', () => {
|
||||
const { container } = render(
|
||||
<VersionStatus
|
||||
status={{ ok: true, contracts: false, network: false }}
|
||||
/>
|
||||
)
|
||||
expect(container.firstChild).toBeInTheDocument()
|
||||
})
|
||||
})
|
|
@ -0,0 +1,41 @@
|
|||
import React from 'react'
|
||||
import styles from './VersionStatus.module.scss'
|
||||
|
||||
const statusInfo: { [key: string]: string } = {
|
||||
ok: 'Shows if connection to all component endpoints can be established.',
|
||||
network: 'Shows if all components are on the same network.',
|
||||
contracts: 'Shows if contracts loaded by components are the same version.'
|
||||
}
|
||||
|
||||
const VersionStatus = ({
|
||||
status
|
||||
}: {
|
||||
status: { ok: boolean; network: boolean; contracts: boolean }
|
||||
}) => {
|
||||
return (
|
||||
<div className={styles.status}>
|
||||
{Object.entries(status).map(([key, value]) => (
|
||||
<div
|
||||
className={styles.element}
|
||||
key={key}
|
||||
title={statusInfo[key]}
|
||||
>
|
||||
<span
|
||||
className={
|
||||
value === true
|
||||
? styles.indicatorActive
|
||||
: styles.indicator
|
||||
}
|
||||
>
|
||||
{value}
|
||||
</span>
|
||||
<span className={styles.indicatorLabel}>
|
||||
{key === 'ok' ? 'components' : key}
|
||||
</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default VersionStatus
|
|
@ -0,0 +1,58 @@
|
|||
@import '../../../styles/variables';
|
||||
|
||||
.tableWrap {
|
||||
// make 'em scrollable
|
||||
overflow: auto;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
}
|
||||
|
||||
.table {
|
||||
border-top: 1px solid $brand-grey-lighter;
|
||||
|
||||
table {
|
||||
margin-left: $spacer;
|
||||
width: calc(100% - #{$spacer});
|
||||
margin-bottom: -1px;
|
||||
|
||||
td {
|
||||
padding: $spacer / 6 $spacer / 2;
|
||||
|
||||
&,
|
||||
code {
|
||||
font-size: $font-size-mini;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
td {
|
||||
padding: $spacer / 4 $spacer / 2 $spacer / 4 $spacer * 1.3;
|
||||
vertical-align: top;
|
||||
|
||||
&:last-child {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
&[colspan] {
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
|
||||
a {
|
||||
&,
|
||||
code {
|
||||
color: $brand-grey;
|
||||
}
|
||||
|
||||
&:hover,
|
||||
&:focus {
|
||||
&,
|
||||
code {
|
||||
color: $brand-pink;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.label {
|
||||
min-width: 15rem;
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
import React from 'react'
|
||||
import { render } from '@testing-library/react'
|
||||
import { VersionTableContracts } from './VersionTable'
|
||||
|
||||
describe('VersionTableContracts', () => {
|
||||
it('renders without crashing', () => {
|
||||
const { container } = render(
|
||||
<VersionTableContracts
|
||||
contracts={{ hello: 'hello', hello2: 'hello2' }}
|
||||
network="nile"
|
||||
keeperVersion="6.6.6"
|
||||
/>
|
||||
)
|
||||
expect(container.firstChild).toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('renders correct Submarine links', () => {
|
||||
const { container, rerender } = render(
|
||||
<VersionTableContracts
|
||||
contracts={{ hello: 'hello', hello2: 'hello2' }}
|
||||
network="duero"
|
||||
keeperVersion="6.6.6"
|
||||
/>
|
||||
)
|
||||
expect(container.querySelector('tr:last-child a').href).toMatch(
|
||||
/submarine.duero.dev-ocean/
|
||||
)
|
||||
|
||||
rerender(
|
||||
<VersionTableContracts
|
||||
contracts={{ hello: 'hello', hello2: 'hello2' }}
|
||||
network="nile"
|
||||
keeperVersion="6.6.6"
|
||||
/>
|
||||
)
|
||||
expect(container.querySelector('tr:last-child a').href).toMatch(
|
||||
/submarine.nile.dev-ocean/
|
||||
)
|
||||
|
||||
rerender(
|
||||
<VersionTableContracts
|
||||
contracts={{ hello: 'hello', hello2: 'hello2' }}
|
||||
network="pacific"
|
||||
keeperVersion="6.6.6"
|
||||
/>
|
||||
)
|
||||
expect(container.querySelector('tr:last-child a').href).toMatch(
|
||||
/submarine.oceanprotocol/
|
||||
)
|
||||
})
|
||||
})
|
|
@ -0,0 +1,112 @@
|
|||
import React from 'react'
|
||||
import { VersionNumbersState } from '.'
|
||||
import VersionTableRow from './VersionTableRow'
|
||||
import styles from './VersionTable.module.scss'
|
||||
import VersionNumber from './VersionNumber'
|
||||
|
||||
import {
|
||||
serviceUri,
|
||||
nodeUri,
|
||||
aquariusUri,
|
||||
brizoUri,
|
||||
brizoAddress,
|
||||
secretStoreUri,
|
||||
faucetUri
|
||||
} from '../../../config'
|
||||
|
||||
const commonsConfig = {
|
||||
serviceUri,
|
||||
nodeUri,
|
||||
aquariusUri,
|
||||
brizoUri,
|
||||
brizoAddress,
|
||||
secretStoreUri,
|
||||
faucetUri
|
||||
}
|
||||
|
||||
export const VersionTableContracts = ({
|
||||
contracts,
|
||||
network,
|
||||
keeperVersion
|
||||
}: {
|
||||
contracts: {
|
||||
[contractName: string]: string
|
||||
}
|
||||
network: string
|
||||
keeperVersion?: string
|
||||
}) => (
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<strong>Keeper Contracts</strong>
|
||||
</td>
|
||||
<td>
|
||||
<VersionNumber
|
||||
name="Keeper Contracts"
|
||||
version={keeperVersion}
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
{contracts &&
|
||||
Object.keys(contracts)
|
||||
// sort alphabetically
|
||||
.sort((a, b) => a.localeCompare(b))
|
||||
.map((key) => {
|
||||
const submarineLink = `https://submarine.${
|
||||
network === 'pacific'
|
||||
? 'oceanprotocol'
|
||||
: `${network}.dev-ocean`
|
||||
}.com/address/${contracts[key]}`
|
||||
|
||||
return (
|
||||
<tr key={key}>
|
||||
<td>
|
||||
<code className={styles.label}>{key}</code>
|
||||
</td>
|
||||
<td>
|
||||
<a href={submarineLink}>
|
||||
<code>{contracts[key]}</code>
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
)
|
||||
})}
|
||||
</tbody>
|
||||
</table>
|
||||
)
|
||||
|
||||
export const VersionTableCommons = () => (
|
||||
<table>
|
||||
<tbody>
|
||||
{Object.entries(commonsConfig).map(([key, value]) => (
|
||||
<tr key={key}>
|
||||
<td>
|
||||
<code className={styles.label}>{key}</code>
|
||||
</td>
|
||||
<td>
|
||||
<code>{value}</code>
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
)
|
||||
|
||||
const VersionTable = ({ data }: { data: VersionNumbersState }) => {
|
||||
return (
|
||||
<div className={styles.tableWrap}>
|
||||
<table className={styles.table}>
|
||||
<tbody>
|
||||
{Object.entries(data)
|
||||
.filter(([key]) => key !== 'status')
|
||||
.map(([key, value]) => (
|
||||
<VersionTableRow key={key} value={value} />
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default VersionTable
|
|
@ -0,0 +1,23 @@
|
|||
@import '../../../styles/variables';
|
||||
|
||||
.handle {
|
||||
display: inline-block;
|
||||
border: 0;
|
||||
background: none;
|
||||
box-shadow: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
margin-left: -1rem;
|
||||
margin-top: -0.1rem;
|
||||
padding-right: 0.5rem;
|
||||
cursor: pointer;
|
||||
|
||||
svg {
|
||||
fill: $brand-grey-light;
|
||||
transition: 0.2s ease-out;
|
||||
}
|
||||
}
|
||||
|
||||
.open {
|
||||
transform: rotate(90deg);
|
||||
}
|
|
@ -0,0 +1,73 @@
|
|||
import React from 'react'
|
||||
import useCollapse from 'react-collapsed'
|
||||
import slugify from '@sindresorhus/slugify'
|
||||
import styles from './VersionTableRow.module.scss'
|
||||
import { VersionTableContracts, VersionTableCommons } from './VersionTable'
|
||||
import VersionNumber from './VersionNumber'
|
||||
import { ReactComponent as Caret } from '../../../img/caret.svg'
|
||||
|
||||
const VersionTableRow = ({ value }: { value: any }) => {
|
||||
const collapseStyles = {
|
||||
transitionDuration: '0.01s'
|
||||
}
|
||||
|
||||
const expandStyles = {
|
||||
transitionDuration: '0.01s',
|
||||
transitionTimingFunction: 'ease-out'
|
||||
}
|
||||
|
||||
const { getCollapseProps, getToggleProps, isOpen } = useCollapse({
|
||||
collapseStyles,
|
||||
expandStyles
|
||||
})
|
||||
|
||||
return (
|
||||
<>
|
||||
<tr>
|
||||
<td>
|
||||
{(value.name === 'Commons' || value.contracts) && (
|
||||
<button className={styles.handle} {...getToggleProps()}>
|
||||
<Caret className={isOpen ? styles.open : ''} />
|
||||
</button>
|
||||
)}
|
||||
<a
|
||||
href={`https://github.com/oceanprotocol/${slugify(
|
||||
value.name || value.software
|
||||
)}`}
|
||||
>
|
||||
<strong>{value.name || value.software}</strong>
|
||||
</a>
|
||||
</td>
|
||||
<td>
|
||||
<VersionNumber
|
||||
name={value.name || value.software}
|
||||
version={value.version}
|
||||
status={value.status}
|
||||
network={value.network}
|
||||
commit={value.commit}
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
{value.name === 'Commons' && (
|
||||
<tr {...getCollapseProps()}>
|
||||
<td colSpan={2}>
|
||||
<VersionTableCommons />
|
||||
</td>
|
||||
</tr>
|
||||
)}
|
||||
{value.contracts && (
|
||||
<tr {...getCollapseProps()}>
|
||||
<td colSpan={2}>
|
||||
<VersionTableContracts
|
||||
contracts={value.contracts}
|
||||
network={value.network || ''}
|
||||
keeperVersion={value.keeperVersion}
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
)}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default VersionTableRow
|
|
@ -0,0 +1,13 @@
|
|||
@import '../../../styles/variables';
|
||||
|
||||
.versionsTitle {
|
||||
font-size: $font-size-large;
|
||||
margin-bottom: $spacer / 2;
|
||||
margin-top: $spacer * 2;
|
||||
}
|
||||
|
||||
.versionsMinimal {
|
||||
font-family: $font-family-monospace;
|
||||
font-size: $font-size-mini;
|
||||
margin-top: $spacer;
|
||||
}
|
|
@ -0,0 +1,95 @@
|
|||
import React from 'react'
|
||||
import { render } from '@testing-library/react'
|
||||
import mockAxios from 'jest-mock-axios'
|
||||
import { StateMock } from '@react-mock/state'
|
||||
import VersionNumbers from '.'
|
||||
|
||||
import { User } from '../../../context'
|
||||
import { userMockConnected } from '../../../__mocks__/user-mock'
|
||||
|
||||
afterEach(() => {
|
||||
mockAxios.reset()
|
||||
})
|
||||
|
||||
const stateMockIncomplete = {
|
||||
commons: {
|
||||
name: 'Commons',
|
||||
version: undefined
|
||||
},
|
||||
squid: {
|
||||
name: 'Squid-js',
|
||||
version: undefined
|
||||
},
|
||||
aquarius: {
|
||||
name: 'Aquarius',
|
||||
version: undefined
|
||||
},
|
||||
brizo: {
|
||||
name: 'Brizo',
|
||||
version: undefined,
|
||||
contracts: undefined,
|
||||
network: undefined,
|
||||
keeperVersion: undefined,
|
||||
keeperUrl: undefined
|
||||
},
|
||||
faucet: {
|
||||
name: 'Faucet',
|
||||
version: undefined,
|
||||
network: undefined
|
||||
},
|
||||
status: {
|
||||
ok: false,
|
||||
network: false,
|
||||
contracts: false
|
||||
}
|
||||
}
|
||||
|
||||
const mockResponse = {
|
||||
data: {
|
||||
software: 'Faucet',
|
||||
version: '6.6.6',
|
||||
network: 'Pacific'
|
||||
}
|
||||
}
|
||||
|
||||
const mockResponseFaulty = {
|
||||
status: 404,
|
||||
statusText: 'Not Found',
|
||||
data: {}
|
||||
}
|
||||
|
||||
describe('VersionNumbers', () => {
|
||||
it('renders without crashing', () => {
|
||||
const { container, rerender } = render(
|
||||
<User.Provider value={userMockConnected}>
|
||||
<VersionNumbers account="0x00000" />
|
||||
</User.Provider>
|
||||
)
|
||||
mockAxios.mockResponse(mockResponse)
|
||||
expect(mockAxios.get).toHaveBeenCalled()
|
||||
expect(container.firstChild).toBeInTheDocument()
|
||||
|
||||
rerender(
|
||||
<User.Provider value={userMockConnected}>
|
||||
<VersionNumbers account="0x99999" />
|
||||
</User.Provider>
|
||||
)
|
||||
mockAxios.mockResponse(mockResponse)
|
||||
expect(mockAxios.get).toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('renders without proper component response', () => {
|
||||
const { container } = render(
|
||||
<User.Provider value={userMockConnected}>
|
||||
<StateMock state={stateMockIncomplete}>
|
||||
<VersionNumbers account="0x00000" />
|
||||
</StateMock>
|
||||
</User.Provider>
|
||||
)
|
||||
mockAxios.mockResponse(mockResponseFaulty)
|
||||
expect(mockAxios.get).toHaveBeenCalled()
|
||||
expect(container.querySelector('table')).toHaveTextContent(
|
||||
'Could not get version'
|
||||
)
|
||||
})
|
||||
})
|
|
@ -0,0 +1,181 @@
|
|||
import React, { PureComponent } from 'react'
|
||||
import {
|
||||
OceanPlatformVersions,
|
||||
OceanPlatformTechStatus,
|
||||
Logger
|
||||
} from '@oceanprotocol/squid'
|
||||
import axios from 'axios'
|
||||
import { version } from '../../../../package.json'
|
||||
import styles from './index.module.scss'
|
||||
|
||||
import { nodeUri, faucetUri } from '../../../config'
|
||||
import { User, Market } from '../../../context'
|
||||
|
||||
import VersionTable from './VersionTable'
|
||||
import VersionStatus from './VersionStatus'
|
||||
|
||||
interface VersionNumbersProps {
|
||||
minimal?: boolean
|
||||
account: string
|
||||
}
|
||||
|
||||
export interface VersionNumbersState extends OceanPlatformVersions {
|
||||
commons: {
|
||||
name: string
|
||||
version: string
|
||||
network: string
|
||||
}
|
||||
faucet: {
|
||||
name: string
|
||||
version: string
|
||||
network: string
|
||||
status: OceanPlatformTechStatus
|
||||
}
|
||||
}
|
||||
|
||||
export default class VersionNumbers extends PureComponent<
|
||||
VersionNumbersProps,
|
||||
VersionNumbersState
|
||||
> {
|
||||
public static contextType = User
|
||||
|
||||
// construct values which are not part of any response
|
||||
public commonsVersion =
|
||||
process.env.NODE_ENV === 'production' ? version : `${version}-dev`
|
||||
|
||||
public commonsNetwork = faucetUri.includes('localhost')
|
||||
? 'Spree'
|
||||
: new URL(nodeUri).hostname.split('.')[0]
|
||||
|
||||
// define a minimal default state to fill UI
|
||||
public state: VersionNumbersState = {
|
||||
commons: {
|
||||
name: 'Commons',
|
||||
network: this.commonsNetwork,
|
||||
version: this.commonsVersion
|
||||
},
|
||||
squid: {
|
||||
name: 'Squid-js',
|
||||
status: OceanPlatformTechStatus.Loading
|
||||
},
|
||||
aquarius: {
|
||||
name: 'Aquarius',
|
||||
status: OceanPlatformTechStatus.Loading
|
||||
},
|
||||
brizo: {
|
||||
name: 'Brizo',
|
||||
status: OceanPlatformTechStatus.Loading
|
||||
},
|
||||
faucet: {
|
||||
name: 'Faucet',
|
||||
version: '',
|
||||
network: '',
|
||||
status: OceanPlatformTechStatus.Loading
|
||||
},
|
||||
status: {
|
||||
ok: false,
|
||||
network: false,
|
||||
contracts: false
|
||||
}
|
||||
}
|
||||
|
||||
// for canceling axios requests
|
||||
public signal = axios.CancelToken.source()
|
||||
|
||||
public componentDidMount() {
|
||||
this.getOceanVersions()
|
||||
this.getFaucetVersion()
|
||||
}
|
||||
|
||||
public async componentDidUpdate(prevProps: any) {
|
||||
// Workaround: Using account prop instead of getting it from
|
||||
// context to be able to compare. Cause there is no `prevContext`.
|
||||
if (prevProps.account !== this.props.account) {
|
||||
this.getOceanVersions()
|
||||
this.getFaucetVersion()
|
||||
}
|
||||
}
|
||||
|
||||
public componentWillUnmount() {
|
||||
this.signal.cancel()
|
||||
}
|
||||
|
||||
private async getOceanVersions() {
|
||||
const { ocean } = this.context
|
||||
// wait until ocean object is properly populated
|
||||
if (ocean.versions === undefined) return
|
||||
|
||||
const response = await ocean.versions.get()
|
||||
const { squid, brizo, aquarius, status } = response
|
||||
|
||||
this.setState({
|
||||
...this.state,
|
||||
squid,
|
||||
brizo,
|
||||
aquarius,
|
||||
status
|
||||
})
|
||||
}
|
||||
|
||||
private async getFaucetVersion() {
|
||||
try {
|
||||
const response = await axios.get(faucetUri, {
|
||||
headers: { Accept: 'application/json' },
|
||||
cancelToken: this.signal.token
|
||||
})
|
||||
|
||||
// fail silently
|
||||
if (response.status !== 200) return
|
||||
|
||||
const { version, network } = response.data
|
||||
|
||||
this.setState({
|
||||
...this.state,
|
||||
faucet: {
|
||||
...this.state.faucet,
|
||||
version,
|
||||
network,
|
||||
status: OceanPlatformTechStatus.Working
|
||||
}
|
||||
})
|
||||
} catch (error) {
|
||||
!axios.isCancel(error) && Logger.error(error.message)
|
||||
}
|
||||
}
|
||||
|
||||
private MinimalOutput = () => {
|
||||
const { commons, squid, brizo, aquarius } = this.state
|
||||
|
||||
return (
|
||||
<Market.Consumer>
|
||||
{(market) => (
|
||||
<p className={styles.versionsMinimal}>
|
||||
<a
|
||||
title={`${squid.name} v${squid.version}\n${brizo.name} v${brizo.version}\n${aquarius.name} v${aquarius.version}`}
|
||||
href="/about"
|
||||
>
|
||||
v{commons.version}{' '}
|
||||
{market.network && `(${market.network})`}
|
||||
</a>
|
||||
</p>
|
||||
)}
|
||||
</Market.Consumer>
|
||||
)
|
||||
}
|
||||
|
||||
public render() {
|
||||
const { minimal } = this.props
|
||||
|
||||
return minimal ? (
|
||||
<this.MinimalOutput />
|
||||
) : (
|
||||
<>
|
||||
<h2 className={styles.versionsTitle} id="#oceanversions">
|
||||
Ocean Components Status
|
||||
</h2>
|
||||
<VersionStatus status={this.state.status} />
|
||||
<VersionTable data={this.state} />
|
||||
</>
|
||||
)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
@import '../../styles/variables';
|
||||
|
||||
.latestAssetsWrap {
|
||||
// full width break out of container
|
||||
// margin-right: calc(-50vw + 50%);
|
||||
}
|
||||
|
||||
.latestAssets {
|
||||
width: 100%;
|
||||
overflow-x: auto;
|
||||
overflow-y: hidden;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
-ms-overflow-style: -ms-autohiding-scrollbar;
|
||||
display: grid;
|
||||
grid-gap: $spacer;
|
||||
grid-auto-flow: column;
|
||||
padding: $spacer / 2 $spacer;
|
||||
border-left: 1px solid $brand-grey-lighter;
|
||||
|
||||
&::-webkit-scrollbar,
|
||||
&::-moz-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
> article {
|
||||
min-width: calc(18rem + #{$spacer});
|
||||
}
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: $font-size-h4;
|
||||
text-align: center;
|
||||
color: $brand-grey-light;
|
||||
border-bottom: 1px solid $brand-grey-lighter;
|
||||
padding-bottom: $spacer / 3;
|
||||
margin-top: $spacer * 3;
|
||||
margin-bottom: $spacer / 2;
|
||||
|
||||
@media (min-width: $break-point--small) {
|
||||
text-align: left;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
import React from 'react'
|
||||
import { BrowserRouter } from 'react-router-dom'
|
||||
import { render } from '@testing-library/react'
|
||||
import AssetsLatest from './AssetsLatest'
|
||||
import { User } from '../../context'
|
||||
import { userMockConnected } from '../../__mocks__/user-mock'
|
||||
|
||||
describe('AssetsLatest', () => {
|
||||
it('renders without crashing', () => {
|
||||
const { container } = render(
|
||||
<User.Provider value={userMockConnected}>
|
||||
<BrowserRouter>
|
||||
<AssetsLatest />
|
||||
</BrowserRouter>
|
||||
</User.Provider>
|
||||
)
|
||||
expect(container.firstChild).toBeInTheDocument()
|
||||
})
|
||||
})
|
|
@ -0,0 +1,79 @@
|
|||
import React, { PureComponent } from 'react'
|
||||
import { Logger } from '@oceanprotocol/squid'
|
||||
import { User } from '../../context'
|
||||
import Spinner from '../atoms/Spinner'
|
||||
import AssetTeaser from '../molecules/AssetTeaser'
|
||||
import styles from './AssetsLatest.module.scss'
|
||||
|
||||
interface AssetsLatestState {
|
||||
latestAssets?: any[]
|
||||
isLoadingLatest?: boolean
|
||||
}
|
||||
|
||||
export default class AssetsLatest extends PureComponent<{}, AssetsLatestState> {
|
||||
public state = { latestAssets: [], isLoadingLatest: true }
|
||||
|
||||
public _isMounted = false
|
||||
|
||||
public componentDidMount() {
|
||||
this._isMounted = true
|
||||
this._isMounted && this.getLatestAssets()
|
||||
}
|
||||
|
||||
public componentWillUnmount() {
|
||||
this._isMounted = false
|
||||
}
|
||||
|
||||
private getLatestAssets = async () => {
|
||||
const { ocean } = this.context
|
||||
|
||||
const searchQuery = {
|
||||
offset: 15,
|
||||
page: 1,
|
||||
query: {},
|
||||
sort: {
|
||||
created: -1
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
const search = await ocean.assets.query(searchQuery)
|
||||
this.setState({
|
||||
latestAssets: search.results,
|
||||
isLoadingLatest: false
|
||||
})
|
||||
} catch (error) {
|
||||
Logger.error(error.message)
|
||||
this.setState({ isLoadingLatest: false })
|
||||
}
|
||||
}
|
||||
|
||||
public render() {
|
||||
const { latestAssets, isLoadingLatest } = this.state
|
||||
|
||||
return (
|
||||
<>
|
||||
<h2 className={styles.title}>Latest published assets</h2>
|
||||
<div className={styles.latestAssetsWrap}>
|
||||
{isLoadingLatest ? (
|
||||
<Spinner message="Loading..." />
|
||||
) : latestAssets && latestAssets.length ? (
|
||||
<div className={styles.latestAssets}>
|
||||
{latestAssets.map((asset: any) => (
|
||||
<AssetTeaser
|
||||
key={asset.id}
|
||||
asset={asset}
|
||||
minimal
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
) : (
|
||||
<div>No data sets found.</div>
|
||||
)}
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
AssetsLatest.contextType = User
|
|
@ -3,16 +3,18 @@ import { Link } from 'react-router-dom'
|
|||
import { Logger } from '@oceanprotocol/squid'
|
||||
import { User } from '../../context'
|
||||
import Spinner from '../atoms/Spinner'
|
||||
import Asset from '../molecules/Asset'
|
||||
import AssetTeaser from '../molecules/AssetTeaser'
|
||||
import styles from './AssetsUser.module.scss'
|
||||
|
||||
export default class AssetsUser extends PureComponent<
|
||||
{ list?: boolean; recent?: number },
|
||||
{ results: any[]; isLoading: boolean }
|
||||
> {
|
||||
public static contextType = User
|
||||
|
||||
public state = { results: [], isLoading: true }
|
||||
|
||||
public _isMounted: boolean = false
|
||||
public _isMounted = false
|
||||
|
||||
public componentDidMount() {
|
||||
this._isMounted = true
|
||||
|
@ -57,53 +59,47 @@ export default class AssetsUser extends PureComponent<
|
|||
}
|
||||
|
||||
public render() {
|
||||
const { account, isOceanNetwork } = this.context
|
||||
const { account } = this.context
|
||||
const { recent, list } = this.props
|
||||
const { isLoading, results } = this.state
|
||||
|
||||
if (!account) return null
|
||||
|
||||
return (
|
||||
isOceanNetwork &&
|
||||
account && (
|
||||
<div className={styles.assetsUser}>
|
||||
{this.props.recent && (
|
||||
<h2 className={styles.subTitle}>
|
||||
Your Latest Published Data Sets
|
||||
</h2>
|
||||
)}
|
||||
<div className={styles.assetsUser}>
|
||||
{this.props.recent && (
|
||||
<h2 className={styles.subTitle}>
|
||||
Your Latest Published Data Sets
|
||||
</h2>
|
||||
)}
|
||||
|
||||
{this.state.isLoading ? (
|
||||
<Spinner />
|
||||
) : this.state.results.length ? (
|
||||
<>
|
||||
{this.state.results
|
||||
.slice(
|
||||
0,
|
||||
this.props.recent
|
||||
? this.props.recent
|
||||
: undefined
|
||||
)
|
||||
.filter(asset => !!asset)
|
||||
.map((asset: any) => (
|
||||
<Asset
|
||||
list={this.props.list}
|
||||
key={asset.id}
|
||||
asset={asset}
|
||||
/>
|
||||
))}
|
||||
{this.props.recent && (
|
||||
<Link className={styles.link} to={'/history'}>
|
||||
All Data Sets
|
||||
</Link>
|
||||
)}
|
||||
</>
|
||||
) : (
|
||||
<div className={styles.empty}>
|
||||
<p>No Data Sets Yet.</p>
|
||||
<Link to="/publish">+ Publish A Data Set</Link>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
{isLoading ? (
|
||||
<Spinner />
|
||||
) : results.length ? (
|
||||
<>
|
||||
{results
|
||||
.slice(0, recent || undefined)
|
||||
.filter((asset) => !!asset)
|
||||
.map((asset: any) => (
|
||||
<AssetTeaser
|
||||
list={list}
|
||||
key={asset.id}
|
||||
asset={asset}
|
||||
/>
|
||||
))}
|
||||
{recent && (
|
||||
<Link className={styles.link} to="/history">
|
||||
All Data Sets
|
||||
</Link>
|
||||
)}
|
||||
</>
|
||||
) : (
|
||||
<div className={styles.empty}>
|
||||
<p>No Data Sets Yet.</p>
|
||||
<Link to="/publish">+ Publish A Data Set</Link>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
AssetsUser.contextType = User
|
||||
|
|
|
@ -0,0 +1,75 @@
|
|||
@import '../../styles/variables';
|
||||
|
||||
.channel {
|
||||
width: 100%;
|
||||
|
||||
@media (min-width: $break-point--medium) {
|
||||
padding-top: $spacer * 2;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
> div {
|
||||
&:first-child {
|
||||
margin-bottom: $spacer;
|
||||
|
||||
@media (min-width: $break-point--medium) {
|
||||
margin-right: $spacer;
|
||||
}
|
||||
|
||||
p:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: $break-point--medium) {
|
||||
flex: 1;
|
||||
|
||||
&:first-child {
|
||||
flex: 0 0 calc(18rem + #{$spacer * 2});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// style channel teaser following another one
|
||||
+ .channel {
|
||||
border-top: 1px solid $brand-grey-lighter;
|
||||
margin-top: $spacer * 2;
|
||||
}
|
||||
}
|
||||
|
||||
.channelTitle {
|
||||
margin-top: $spacer * 4;
|
||||
margin-bottom: $spacer / 4;
|
||||
color: $brand-black;
|
||||
|
||||
@media (min-width: $break-point--medium) {
|
||||
margin-top: -($spacer / 4);
|
||||
}
|
||||
}
|
||||
|
||||
.channelHeader {
|
||||
text-align: center;
|
||||
|
||||
@media (min-width: $break-point--small) {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
a {
|
||||
display: block;
|
||||
|
||||
&:hover,
|
||||
&:focus {
|
||||
transform: none;
|
||||
|
||||
// category image
|
||||
.channelTitle + div {
|
||||
opacity: 1;
|
||||
background-size: 105%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.channelTeaser {
|
||||
color: $brand-grey;
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
import React from 'react'
|
||||
import { render } from '@testing-library/react'
|
||||
import ChannelTeaser from './ChannelTeaser'
|
||||
import { BrowserRouter } from 'react-router-dom'
|
||||
import { User } from '../../context'
|
||||
import { userMockConnected } from '../../__mocks__/user-mock'
|
||||
|
||||
describe('ChannelTeaser', () => {
|
||||
it('renders without crashing', () => {
|
||||
const { container } = render(
|
||||
<User.Provider value={userMockConnected}>
|
||||
<BrowserRouter>
|
||||
<ChannelTeaser channel="ai-for-good" />
|
||||
</BrowserRouter>
|
||||
</User.Provider>
|
||||
)
|
||||
expect(container.firstChild).toBeInTheDocument()
|
||||
})
|
||||
})
|
|
@ -0,0 +1,92 @@
|
|||
import React, { Component } from 'react'
|
||||
import { Link } from 'react-router-dom'
|
||||
import { User } from '../../context'
|
||||
import { Logger, DDO } from '@oceanprotocol/squid'
|
||||
import CategoryImage from '../atoms/CategoryImage'
|
||||
import SearchResults from '../molecules/SearchResults'
|
||||
import styles from './ChannelTeaser.module.scss'
|
||||
import channels from '../../data/channels.json'
|
||||
|
||||
interface ChannelTeaserProps {
|
||||
channel: string
|
||||
}
|
||||
|
||||
interface ChannelTeaserState {
|
||||
channelAssets?: DDO[]
|
||||
isLoadingChannel?: boolean
|
||||
}
|
||||
|
||||
export default class ChannelTeaser extends Component<
|
||||
ChannelTeaserProps,
|
||||
ChannelTeaserState
|
||||
> {
|
||||
public static contextType = User
|
||||
|
||||
// Get channel content
|
||||
public channel = channels.items
|
||||
.filter(({ tag }) => tag === this.props.channel)
|
||||
.map((channel) => channel)[0]
|
||||
|
||||
public state = {
|
||||
channelAssets: [],
|
||||
isLoadingChannel: true
|
||||
}
|
||||
|
||||
public async componentDidMount() {
|
||||
this.getChannelAssets()
|
||||
}
|
||||
|
||||
private getChannelAssets = async () => {
|
||||
const { ocean } = this.context
|
||||
|
||||
const searchQuery = {
|
||||
offset: 2,
|
||||
page: 1,
|
||||
query: {
|
||||
tags: [this.channel.tag]
|
||||
},
|
||||
sort: {
|
||||
created: -1
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
const search = await ocean.assets.query(searchQuery)
|
||||
this.setState({
|
||||
channelAssets: search.results,
|
||||
isLoadingChannel: false
|
||||
})
|
||||
} catch (error) {
|
||||
Logger.error(error.message)
|
||||
this.setState({ isLoadingChannel: false })
|
||||
}
|
||||
}
|
||||
|
||||
public render() {
|
||||
const { channelAssets, isLoadingChannel } = this.state
|
||||
const { title, tag, teaser } = this.channel
|
||||
|
||||
return (
|
||||
<div className={styles.channel}>
|
||||
<div>
|
||||
<header className={styles.channelHeader}>
|
||||
<Link to={`/channels/${tag}`}>
|
||||
<h2 className={styles.channelTitle}>{title}</h2>
|
||||
<CategoryImage category={title} />
|
||||
|
||||
<p className={styles.channelTeaser}>{teaser}</p>
|
||||
<p>Browse the channel →</p>
|
||||
</Link>
|
||||
</header>
|
||||
</div>
|
||||
<div>
|
||||
<SearchResults
|
||||
isLoading={isLoadingChannel}
|
||||
results={channelAssets}
|
||||
simpleGrid
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
|
@ -57,3 +57,37 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
.stats {
|
||||
text-align: center;
|
||||
margin-bottom: $spacer * $line-height;
|
||||
font-size: $font-size-small;
|
||||
|
||||
p {
|
||||
margin-bottom: $spacer / 4;
|
||||
}
|
||||
|
||||
p:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.aicommons {
|
||||
svg {
|
||||
width: 100px;
|
||||
height: auto;
|
||||
vertical-align: middle;
|
||||
margin-top: -0.05rem;
|
||||
margin-left: $spacer / 6;
|
||||
fill: currentColor;
|
||||
}
|
||||
|
||||
a {
|
||||
&:hover,
|
||||
&:focus {
|
||||
svg {
|
||||
fill: $brand-pink;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,27 +1,53 @@
|
|||
import React from 'react'
|
||||
import React, { useContext } from 'react'
|
||||
import { Market, User } from '../../context'
|
||||
import Content from '../atoms/Content'
|
||||
import { ReactComponent as AiCommons } from '../../img/aicommons.svg'
|
||||
import styles from './Footer.module.scss'
|
||||
|
||||
import meta from '../../data/meta.json'
|
||||
import VersionNumbers from '../molecules/VersionNumbers'
|
||||
|
||||
const Footer = () => (
|
||||
<footer className={styles.footer}>
|
||||
<Content wide>
|
||||
<small>
|
||||
© {new Date().getFullYear()}{' '}
|
||||
<a href={meta.social[0].url}>{meta.company}</a> — All
|
||||
Rights Reserved
|
||||
</small>
|
||||
export default function Footer() {
|
||||
const market = useContext(Market)
|
||||
const user = useContext(User)
|
||||
|
||||
<nav className={styles.links}>
|
||||
{meta.social.map(site => (
|
||||
<a key={site.title} href={site.url}>
|
||||
{site.title}
|
||||
</a>
|
||||
))}
|
||||
</nav>
|
||||
</Content>
|
||||
</footer>
|
||||
)
|
||||
return (
|
||||
<footer className={styles.footer}>
|
||||
<aside className={styles.stats}>
|
||||
<Content wide>
|
||||
<p>
|
||||
Online since March 2019.
|
||||
{market.totalAssets > 0 &&
|
||||
` With a total of ${market.totalAssets} registered assets.`}
|
||||
</p>
|
||||
<p className={styles.aicommons}>
|
||||
Proud supporter of{' '}
|
||||
<a
|
||||
href="https://aicommons.com/?utm_source=commons.oceanprotocol.com"
|
||||
title="AI Commons"
|
||||
>
|
||||
<AiCommons />
|
||||
</a>
|
||||
</p>
|
||||
<VersionNumbers account={user.account} minimal />
|
||||
</Content>
|
||||
</aside>
|
||||
|
||||
export default Footer
|
||||
<Content wide>
|
||||
<small>
|
||||
© {new Date().getFullYear()}{' '}
|
||||
<a href={meta.social[0].url}>{meta.company}</a> — All
|
||||
Rights Reserved
|
||||
</small>
|
||||
|
||||
<nav className={styles.links}>
|
||||
{meta.social.map((site) => (
|
||||
<a key={site.title} href={site.url}>
|
||||
{site.title}
|
||||
</a>
|
||||
))}
|
||||
</nav>
|
||||
</Content>
|
||||
</footer>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -70,7 +70,7 @@
|
|||
&::-webkit-scrollbar {
|
||||
width: 3px;
|
||||
height: 3px;
|
||||
transition: opacity .2s ease-out;
|
||||
transition: opacity 0.2s ease-out;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -99,5 +99,5 @@
|
|||
|
||||
.accountStatus {
|
||||
margin-left: $spacer / 2;
|
||||
margin-bottom: -.5rem;
|
||||
margin-bottom: -0.5rem;
|
||||
}
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue