From a5607ac90e51d3a8ce75f59eb2dc0f035d065ac2 Mon Sep 17 00:00:00 2001 From: Jaco Greeff Date: Fri, 4 May 2018 15:07:44 +0200 Subject: [PATCH] App for realtime storage queries (#11) * Create app-storage structure * Split shared components into ui-react-app * Cleanup @flow issues * Rename apps classes * Split with ui-react-app operational * Import es semantic-ui * Selection section/key split into 2 * Basic storage queries (no-params) in-place * Upgrades * No-param queries operational * Default values operational (dropdown) * Additional cleanups, constrolled value * @flow updates * @flow fixes * Move Params to ui-react-app (future-use in app-storage) * Fix final @flow issues * Query removal * Cleanups * Update README * Upgrades * Fixup cached components * Bump @polkadot/rx-react * Simple explorer animations * Additional (final) cleanups --- .flowconfig | 3 +- README.md | 13 ++ flow-typed/react-dropzone.js | 3 +- flow-typed/semantic-ui-react.js | 14 +- package.json | 2 +- packages/app-explorer/package.json | 18 +- .../app-explorer/src/{App/index.js => App.js} | 16 +- packages/app-explorer/src/App/App.css | 27 --- packages/app-explorer/src/BestHash.js | 35 +--- .../src/BlockHeader/BlockHeader.css | 6 + .../app-explorer/src/BlockHeader/index.js | 4 +- .../app-explorer/src/BlockHeaders/index.js | 53 ++---- .../src/BlockHeaders/transform.js | 10 +- packages/app-explorer/src/index.css | 33 ++++ packages/app-explorer/src/translate.js | 2 +- packages/app-extrinsics/package.json | 19 +- packages/app-extrinsics/src/Account.js | 68 ++++--- packages/app-extrinsics/src/App.js | 5 +- .../app-extrinsics/src/Extrinsic/index.js | 104 ++++++++--- .../app-extrinsics/src/Extrinsic/subjects.js | 36 +--- .../app-extrinsics/src/Extrinsic/types.js | 12 ++ .../src/InputExtrinsic/index.js | 63 ------- .../src/InputExtrinsic/options.js | 60 ------- packages/app-extrinsics/src/Params/Account.js | 51 ++++++ .../src/Params/Param/Account.js | 30 ---- .../src/Params/Param/Proposal.js | 32 ---- .../app-extrinsics/src/Params/Proposal.js | 70 ++++++++ .../src/Params/findComponent.js | 43 ----- packages/app-extrinsics/src/Params/index.js | 52 +----- packages/app-extrinsics/src/Signer/Decoded.js | 7 +- packages/app-extrinsics/src/Signer/index.js | 5 +- packages/app-extrinsics/src/Signer/submit.js | 5 +- .../app-extrinsics/src/Submission/Nonce.js | 45 +++-- .../src/Submission/Submission.css | 2 +- .../app-extrinsics/src/Submission/Submit.js | 5 +- .../app-extrinsics/src/Submission/index.js | 101 +++++++---- .../app-extrinsics/src/Submission/subjects.js | 33 +--- .../app-extrinsics/src/Submission/types.js | 14 ++ packages/app-extrinsics/src/index.css | 47 ----- packages/app-extrinsics/src/translate.js | 2 +- packages/app-extrinsics/src/types.js | 18 -- .../{extrinsics-codec => app-storage}/LICENSE | 0 packages/app-storage/README.md | 1 + .../{extrinsics => app-storage}/package.json | 9 +- packages/app-storage/src/App.js | 28 +++ packages/app-storage/src/Queries/Query.js | 61 +++++++ packages/app-storage/src/Queries/Remove.js | 46 +++++ .../src/Queries/cache.js} | 10 +- packages/app-storage/src/Queries/index.js | 42 +++++ packages/app-storage/src/Queries/transform.js | 33 ++++ packages/app-storage/src/Selection/Add.js | 56 ++++++ packages/app-storage/src/Selection/index.js | 44 +++++ packages/app-storage/src/index.css | 25 +++ .../{extrinsics => app-storage/src}/index.js | 6 +- packages/app-storage/src/subjects.js | 29 +++ packages/app-storage/src/translate.js | 8 + packages/app-storage/src/types.js | 12 ++ packages/apps/package.json | 17 +- packages/apps/src/App/App.css | 4 +- packages/apps/src/App/index.js | 12 +- packages/apps/src/Connecting/Connecting.css | 11 +- packages/apps/src/Connecting/index.js | 15 +- packages/apps/src/Content/Content.css | 4 +- packages/apps/src/Content/index.js | 8 +- packages/apps/src/NotFound/NotFound.css | 2 +- packages/apps/src/NotFound/index.js | 8 +- packages/apps/src/SideBar/Item.css | 6 +- packages/apps/src/SideBar/Item.js | 18 +- packages/apps/src/SideBar/SideBar.css | 2 +- packages/apps/src/SideBar/index.js | 13 +- packages/apps/src/index.js | 32 +--- packages/apps/src/routing/index.js | 3 +- packages/apps/src/routing/storage.js | 21 +++ packages/apps/src/translate.js | 2 +- packages/apps/src/types.js | 20 --- packages/extrinsics-codec/README.md | 1 - packages/extrinsics-codec/package.json | 21 --- packages/extrinsics-codec/src/encode/call.js | 17 -- .../extrinsics-codec/src/encode/extrinsic.js | 21 --- packages/extrinsics-codec/src/encode/index.js | 18 -- packages/extrinsics-codec/src/encode/param.js | 32 ---- .../extrinsics-codec/src/encode/params.js | 16 -- packages/extrinsics-codec/src/encode/type.js | 47 ----- packages/extrinsics-polkadot/README.md | 1 - packages/extrinsics-polkadot/package.json | 17 -- packages/extrinsics-polkadot/src/consensus.js | 30 ---- packages/extrinsics-polkadot/src/council.js | 85 --------- .../extrinsics-polkadot/src/councilVoting.js | 52 ------ packages/extrinsics-polkadot/src/democracy.js | 54 ------ packages/extrinsics-polkadot/src/index.js | 26 --- packages/extrinsics-polkadot/src/session.js | 35 ---- packages/extrinsics-polkadot/src/staking.js | 60 ------- packages/extrinsics/LICENSE | 15 -- packages/extrinsics/README.md | 1 - packages/extrinsics/src/index.js | 46 ----- packages/extrinsics/src/methods.js | 35 ---- packages/extrinsics/src/params.js | 19 -- packages/extrinsics/src/section.js | 23 --- packages/extrinsics/src/types.js | 84 --------- .../LICENSE | 0 packages/ui-react-app/README.md | 1 + packages/ui-react-app/package.json | 29 +++ .../src/InputAddress/InputAddress.css | 0 .../src/InputAddress/PairDisplay.css | 0 .../src/InputAddress/PairDisplay.js | 0 .../src/InputAddress/index.js | 46 ++--- .../src/InputExtrinsic/InputExtrinsic.css | 12 +- .../src/InputExtrinsic/SelectMethod.js | 52 ++++++ .../src/InputExtrinsic/SelectSection.js | 40 +++++ .../ui-react-app/src/InputExtrinsic/index.js | 100 +++++++++++ .../src/InputExtrinsic/options/method.js | 41 +++++ .../src/InputExtrinsic/options/section.js | 21 +++ .../src/InputStorage/InputStorage.css | 40 +++++ .../src/InputStorage/SelectKey.js | 51 ++++++ .../src/InputStorage/SelectSection.js | 39 ++++ .../ui-react-app/src/InputStorage/index.js | 95 ++++++++++ .../src/InputStorage/options/key.js | 46 +++++ .../src/InputStorage/options/section.js | 28 +++ .../ui-react-app/src/Params/Param/Account.js | 36 ++++ .../src/Params/Param/Amount.js | 3 +- .../src/Params/Param/Base.js | 11 +- .../src/Params/Param/Bool.js | 0 .../src/Params/Param/Bytes.js | 0 .../src/Params/Param/File.js | 10 +- .../src/Params/Param/Hash.js | 0 .../src/Params/Param/Unknown.js | 2 +- .../src/Params/Param/VoteThreshold.js | 2 +- .../src/Params/Param/Wasm.js | 0 .../src/Params/Param/findComponent.js | 42 +++++ .../ui-react-app/src/Params/Param/index.js | 59 ++++++ .../src/Params/Params.css | 14 +- packages/ui-react-app/src/Params/index.js | 123 +++++++++++++ .../src/Params/initValue.js | 23 ++- .../src/Params/subjects.js | 29 ++- .../src/Params/typeToText.js | 8 +- .../src/Params/types.js | 17 +- packages/ui-react-app/src/RxDropdown.js | 57 ++++++ packages/{apps => ui-react-app}/src/i18n.js | 26 ++- packages/ui-react-app/src/index.js | 46 +++++ .../src/keyring.js | 0 packages/ui-react-app/src/styles.js | 12 ++ .../src/styles/app.css} | 0 packages/ui-react-app/src/styles/form.css | 48 +++++ packages/ui-react-app/src/styles/rx.css | 8 + .../src/styles}/semantic.css | 4 + packages/ui-react-app/src/translate.js | 8 + packages/ui-react-app/src/types.js | 27 +++ yarn.lock | 170 +++++++++++------- 148 files changed, 2250 insertions(+), 1708 deletions(-) rename packages/app-explorer/src/{App/index.js => App.js} (65%) delete mode 100644 packages/app-explorer/src/App/App.css create mode 100644 packages/app-extrinsics/src/Extrinsic/types.js delete mode 100644 packages/app-extrinsics/src/InputExtrinsic/index.js delete mode 100644 packages/app-extrinsics/src/InputExtrinsic/options.js create mode 100644 packages/app-extrinsics/src/Params/Account.js delete mode 100644 packages/app-extrinsics/src/Params/Param/Account.js delete mode 100644 packages/app-extrinsics/src/Params/Param/Proposal.js create mode 100644 packages/app-extrinsics/src/Params/Proposal.js delete mode 100644 packages/app-extrinsics/src/Params/findComponent.js create mode 100644 packages/app-extrinsics/src/Submission/types.js rename packages/{extrinsics-codec => app-storage}/LICENSE (100%) create mode 100644 packages/app-storage/README.md rename packages/{extrinsics => app-storage}/package.json (60%) create mode 100644 packages/app-storage/src/App.js create mode 100644 packages/app-storage/src/Queries/Query.js create mode 100644 packages/app-storage/src/Queries/Remove.js rename packages/{app-explorer/src/types.js => app-storage/src/Queries/cache.js} (59%) create mode 100644 packages/app-storage/src/Queries/index.js create mode 100644 packages/app-storage/src/Queries/transform.js create mode 100644 packages/app-storage/src/Selection/Add.js create mode 100644 packages/app-storage/src/Selection/index.js create mode 100644 packages/app-storage/src/index.css rename packages/{extrinsics => app-storage/src}/index.js (60%) create mode 100644 packages/app-storage/src/subjects.js create mode 100644 packages/app-storage/src/translate.js create mode 100644 packages/app-storage/src/types.js create mode 100644 packages/apps/src/routing/storage.js delete mode 100644 packages/extrinsics-codec/README.md delete mode 100644 packages/extrinsics-codec/package.json delete mode 100644 packages/extrinsics-codec/src/encode/call.js delete mode 100644 packages/extrinsics-codec/src/encode/extrinsic.js delete mode 100644 packages/extrinsics-codec/src/encode/index.js delete mode 100644 packages/extrinsics-codec/src/encode/param.js delete mode 100644 packages/extrinsics-codec/src/encode/params.js delete mode 100644 packages/extrinsics-codec/src/encode/type.js delete mode 100644 packages/extrinsics-polkadot/README.md delete mode 100644 packages/extrinsics-polkadot/package.json delete mode 100644 packages/extrinsics-polkadot/src/consensus.js delete mode 100644 packages/extrinsics-polkadot/src/council.js delete mode 100644 packages/extrinsics-polkadot/src/councilVoting.js delete mode 100644 packages/extrinsics-polkadot/src/democracy.js delete mode 100644 packages/extrinsics-polkadot/src/index.js delete mode 100644 packages/extrinsics-polkadot/src/session.js delete mode 100644 packages/extrinsics-polkadot/src/staking.js delete mode 100644 packages/extrinsics/LICENSE delete mode 100644 packages/extrinsics/README.md delete mode 100644 packages/extrinsics/src/index.js delete mode 100644 packages/extrinsics/src/methods.js delete mode 100644 packages/extrinsics/src/params.js delete mode 100644 packages/extrinsics/src/section.js delete mode 100644 packages/extrinsics/src/types.js rename packages/{extrinsics-polkadot => ui-react-app}/LICENSE (100%) create mode 100644 packages/ui-react-app/README.md create mode 100644 packages/ui-react-app/package.json rename packages/{app-extrinsics => ui-react-app}/src/InputAddress/InputAddress.css (100%) rename packages/{app-extrinsics => ui-react-app}/src/InputAddress/PairDisplay.css (100%) rename packages/{app-extrinsics => ui-react-app}/src/InputAddress/PairDisplay.js (100%) rename packages/{app-extrinsics => ui-react-app}/src/InputAddress/index.js (51%) rename packages/{app-extrinsics => ui-react-app}/src/InputExtrinsic/InputExtrinsic.css (67%) create mode 100644 packages/ui-react-app/src/InputExtrinsic/SelectMethod.js create mode 100644 packages/ui-react-app/src/InputExtrinsic/SelectSection.js create mode 100644 packages/ui-react-app/src/InputExtrinsic/index.js create mode 100644 packages/ui-react-app/src/InputExtrinsic/options/method.js create mode 100644 packages/ui-react-app/src/InputExtrinsic/options/section.js create mode 100644 packages/ui-react-app/src/InputStorage/InputStorage.css create mode 100644 packages/ui-react-app/src/InputStorage/SelectKey.js create mode 100644 packages/ui-react-app/src/InputStorage/SelectSection.js create mode 100644 packages/ui-react-app/src/InputStorage/index.js create mode 100644 packages/ui-react-app/src/InputStorage/options/key.js create mode 100644 packages/ui-react-app/src/InputStorage/options/section.js create mode 100644 packages/ui-react-app/src/Params/Param/Account.js rename packages/{app-extrinsics => ui-react-app}/src/Params/Param/Amount.js (87%) rename packages/{app-extrinsics => ui-react-app}/src/Params/Param/Base.js (80%) rename packages/{app-extrinsics => ui-react-app}/src/Params/Param/Bool.js (100%) rename packages/{app-extrinsics => ui-react-app}/src/Params/Param/Bytes.js (100%) rename packages/{app-extrinsics => ui-react-app}/src/Params/Param/File.js (84%) rename packages/{app-extrinsics => ui-react-app}/src/Params/Param/Hash.js (100%) rename packages/{app-extrinsics => ui-react-app}/src/Params/Param/Unknown.js (92%) rename packages/{app-extrinsics => ui-react-app}/src/Params/Param/VoteThreshold.js (95%) rename packages/{app-extrinsics => ui-react-app}/src/Params/Param/Wasm.js (100%) create mode 100644 packages/ui-react-app/src/Params/Param/findComponent.js create mode 100644 packages/ui-react-app/src/Params/Param/index.js rename packages/{app-extrinsics => ui-react-app}/src/Params/Params.css (74%) create mode 100644 packages/ui-react-app/src/Params/index.js rename packages/{app-extrinsics => ui-react-app}/src/Params/initValue.js (52%) rename packages/{app-extrinsics => ui-react-app}/src/Params/subjects.js (54%) rename packages/{app-extrinsics => ui-react-app}/src/Params/typeToText.js (50%) rename packages/{app-extrinsics => ui-react-app}/src/Params/types.js (54%) create mode 100644 packages/ui-react-app/src/RxDropdown.js rename packages/{apps => ui-react-app}/src/i18n.js (70%) create mode 100644 packages/ui-react-app/src/index.js rename packages/{app-extrinsics => ui-react-app}/src/keyring.js (100%) create mode 100644 packages/ui-react-app/src/styles.js rename packages/{apps/src/index.css => ui-react-app/src/styles/app.css} (100%) create mode 100644 packages/ui-react-app/src/styles/form.css create mode 100644 packages/ui-react-app/src/styles/rx.css rename packages/{apps/src => ui-react-app/src/styles}/semantic.css (94%) create mode 100644 packages/ui-react-app/src/translate.js create mode 100644 packages/ui-react-app/src/types.js diff --git a/.flowconfig b/.flowconfig index e6ffabb22e..e291c6545f 100644 --- a/.flowconfig +++ b/.flowconfig @@ -14,5 +14,4 @@ all=warn include_warnings=true module.name_mapper='^@polkadot/app-\(accounts\|explorer\|extrinsics\|home\|rpc\|settings\|storage\)\(.*\)$' -> '/packages/app-\1/src\2' module.name_mapper='^@polkadot/apps\(.*\)$' -> '/packages/apps/src\1' -module.name_mapper='^@polkadot/extrinsics-\(codec\|polkadot\|substrate\)\(.*\)$' -> '/packages/extrinsics-\1/src\2' -module.name_mapper='^@polkadot/extrinsics\(.*\)$' -> '/packages/extrinsics/src\1' +module.name_mapper='^@polkadot/ui-react-app\(.*\)$' -> '/packages/ui-react-app/src\1' diff --git a/README.md b/README.md index 6e0b45c84f..05839b61d3 100644 --- a/README.md +++ b/README.md @@ -12,3 +12,16 @@ A Portal into the Polkadot network. Provides a view and interaction layer from a browser. This can be accessed as a hosted application via [https://polkadot.js.org/apps/](https://polkadot.js.org/apps/). + +## overview + +The repo is split into a number of packages, each representing an application. These are - + +- [apps](packages/apps/) This is the main entry point. It handles the selection sidebar and routing to the specific application being displayed. +- [app-explorer](packages/app-explorer/) A simple block explorer. It only shows the most recent blocks, updating as they become available. +- [app-extrinsics](packages/app-extrinsics/) Submission of extrinsics to a node. +- [app-storage](packages/app-storage/) A simple node storage query application. Multiple queries can be queued and updates as new values become available. + +In addition the following libraries are also included in the repo - + +- [ui-react-app](packages/ui-react-app/) A reactive (using RxJS) application framework with a number of useful shared components. This will be moved to the [@polkadot/ui](https://github.com/polkadot-js/ui/) repository once it reaches a base level of stability and usability. (At this point with the framework being tested on the apps above, it makes development easier having it close) diff --git a/flow-typed/react-dropzone.js b/flow-typed/react-dropzone.js index 68f23e44f7..f5978dc04f 100644 --- a/flow-typed/react-dropzone.js +++ b/flow-typed/react-dropzone.js @@ -1,5 +1,6 @@ // @flow declare module 'react-dropzone' { - declare module.exports: React$StatelessFunctionalComponent<*> + declare type Dropzone = React$StatelessFunctionalComponent<*>; + declare module.exports: Dropzone; } diff --git a/flow-typed/semantic-ui-react.js b/flow-typed/semantic-ui-react.js index 3e1ddefb7b..cdb52c30f7 100644 --- a/flow-typed/semantic-ui-react.js +++ b/flow-typed/semantic-ui-react.js @@ -3,23 +3,23 @@ declare module 'semantic-ui-react/dist/es/collections/Menu' { declare module.exports: React$StatelessFunctionalComponent<*> & { Item: React$StatelessFunctionalComponent<*> - } + }; } declare module 'semantic-ui-react/dist/es/elements/Button' { - declare module.exports: React$StatelessFunctionalComponent<*> + declare module.exports: React$StatelessFunctionalComponent<*>; } declare module 'semantic-ui-react/dist/es/elements/Icon' { - declare module.exports: React$StatelessFunctionalComponent<*> + declare module.exports: React$StatelessFunctionalComponent<*>; } declare module 'semantic-ui-react/dist/es/elements/Input' { - declare module.exports: React$StatelessFunctionalComponent<*> + declare module.exports: React$StatelessFunctionalComponent<*>; } declare module 'semantic-ui-react/dist/es/elements/Label' { - declare module.exports: React$StatelessFunctionalComponent<*> + declare module.exports: React$StatelessFunctionalComponent<*>; } declare module 'semantic-ui-react/dist/es/modules/Dropdown' { @@ -27,7 +27,7 @@ declare module 'semantic-ui-react/dist/es/modules/Dropdown' { Divider: React$StatelessFunctionalComponent<*>, Header: React$StatelessFunctionalComponent<*>, Item: React$StatelessFunctionalComponent<*> - } + }; } declare module 'semantic-ui-react/dist/es/modules/Modal' { @@ -35,5 +35,5 @@ declare module 'semantic-ui-react/dist/es/modules/Modal' { Actions: React$StatelessFunctionalComponent<*>, Content: React$StatelessFunctionalComponent<*>, Header: React$StatelessFunctionalComponent<*> - } + }; } diff --git a/package.json b/package.json index 11b4093c72..98a63cff37 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,7 @@ "test": "echo 'no tests executed'" }, "devDependencies": { - "@polkadot/dev": "^0.17.12", + "@polkadot/dev": "^0.17.13", "babel-preset-react": "^6.24.1", "gh-pages": "^1.1.0", "lerna": "^2.5.1", diff --git a/packages/app-explorer/package.json b/packages/app-explorer/package.json index b7e76f05b1..9b023c7904 100644 --- a/packages/app-explorer/package.json +++ b/packages/app-explorer/package.json @@ -2,7 +2,7 @@ "name": "@polkadot/app-explorer", "version": "0.1.6", "main": "index.js", - "repository": "https://github.com/polkadot-js/portal.git", + "repository": "https://github.com/polkadot-js/apps.git", "author": "Jaco Greeff ", "license": "ISC", "scripts": { @@ -11,16 +11,10 @@ "test": "jest --coverage" }, "devDependencies": { - "@polkadot/primitives": "^0.10.4", - "@polkadot/primitives-codec": "^0.10.4", - "@polkadot/primitives-json": "^0.10.4", - "@polkadot/rx-react": "^0.4.7", - "@polkadot/util": "^0.19.4", - "@polkadot/util-crypto": "^0.19.4", - "react": "^16.3.1", - "react-dom": "^16.3.1", - "react-i18next": "^7.5.1", - "semantic-ui-css": "^2.3.1", - "semantic-ui-react": "^0.79.1" + "@polkadot/primitives": "^0.12.4", + "@polkadot/primitives-codec": "^0.12.4", + "@polkadot/primitives-json": "^0.12.4", + "@polkadot/ui-react-app": "^0.1.6", + "@polkadot/util-crypto": "^0.19.4" } } diff --git a/packages/app-explorer/src/App/index.js b/packages/app-explorer/src/App.js similarity index 65% rename from packages/app-explorer/src/App/index.js rename to packages/app-explorer/src/App.js index f48c0c35c0..4bf878987f 100644 --- a/packages/app-explorer/src/App/index.js +++ b/packages/app-explorer/src/App.js @@ -3,18 +3,16 @@ // of the ISC license. See the LICENSE file for details. // @flow -import type { BaseProps } from '../types'; - -import './App.css'; +import type { I18nProps } from '@polkadot/ui-react-app/types'; import React from 'react'; import BestNumber from '@polkadot/rx-react/BestNumber'; -import translate from '../translate'; -import BestHash from '../BestHash'; -import BlockHeaders from '../BlockHeaders'; +import BestHash from './BestHash'; +import BlockHeaders from './BlockHeaders'; +import translate from './translate'; -type Props = BaseProps & {}; +type Props = I18nProps & {}; function App ({ className, style, t }: Props): React$Node { return ( @@ -23,12 +21,12 @@ function App ({ className, style, t }: Props): React$Node { style={style} > - + ); diff --git a/packages/app-explorer/src/App/App.css b/packages/app-explorer/src/App/App.css deleted file mode 100644 index d5848637cc..0000000000 --- a/packages/app-explorer/src/App/App.css +++ /dev/null @@ -1,27 +0,0 @@ -/* Copyright 2017-2018 Jaco Greeff -/* This software may be modified and distributed under the terms -/* of the ISC license. See the LICENSE file for details. */ - -.explorer--App { - padding: 1em; -} - -.explorer--App-BestNumber { - font-size: 3rem; - font-weight: 100; - line-height: 3rem; - opacity: 0.5; - text-align: right; -} - -.explorer--App-BestHash { - font-size: 1.5em; - font-weight: 100; - line-height: 1.5em; - margin-bottom: 1em; - opacity: 0.5; - text-align: right; -} - -.explorer--App-BlockHeaders { -} diff --git a/packages/app-explorer/src/BestHash.js b/packages/app-explorer/src/BestHash.js index 2bd7e3084a..5bc6381216 100644 --- a/packages/app-explorer/src/BestHash.js +++ b/packages/app-explorer/src/BestHash.js @@ -4,37 +4,18 @@ // @flow import type { Header } from '@polkadot/primitives/header'; -import type { BaseProps } from './types'; -import React from 'react'; import headerHash from '@polkadot/primitives-codec/header/hash'; +import Div from '@polkadot/rx-react/Div'; import withApiCall from '@polkadot/rx-react/with/apiCall'; import u8aToHexShort from '@polkadot/util/u8a/toHexShort'; -import translate from './translate'; - -type Props = BaseProps & { - value?: Header -}; - -function BestHash ({ className, style, value }: Props): React$Node { - if (!value) { - return null; +export default withApiCall({ method: 'newHead', section: 'chain' })( + Div, { + className: 'explorer--BestHash', + format: (value?: Header): ?string => + value + ? u8aToHexShort(headerHash(value)) + : value } - - return ( -
- {u8aToHexShort(headerHash(value))} -
- ); -} - -export default translate( - withApiCall({ - method: 'newHead', - section: 'chain' - })(BestHash) ); diff --git a/packages/app-explorer/src/BlockHeader/BlockHeader.css b/packages/app-explorer/src/BlockHeader/BlockHeader.css index ba84ddf578..0cbe2ed6d6 100644 --- a/packages/app-explorer/src/BlockHeader/BlockHeader.css +++ b/packages/app-explorer/src/BlockHeader/BlockHeader.css @@ -3,9 +3,15 @@ /* of the ISC license. See the LICENSE file for details. */ .explorer--BlockHeader { + animation: fadein 1.5s; display: flex; } +@keyframes fadein { + from { opacity: 0; } + to { opacity: 1; } +} + .explorer--BlockHeader:nth-child(even) { background: #f9f9f9; } diff --git a/packages/app-explorer/src/BlockHeader/index.js b/packages/app-explorer/src/BlockHeader/index.js index 34dde9351e..dc8fd000f4 100644 --- a/packages/app-explorer/src/BlockHeader/index.js +++ b/packages/app-explorer/src/BlockHeader/index.js @@ -4,7 +4,7 @@ // @flow import type { Header } from '@polkadot/primitives/header'; -import type { BaseProps } from '../types'; +import type { I18nProps } from '@polkadot/ui-react-app/types'; import './BlockHeader.css'; @@ -14,7 +14,7 @@ import u8aToHex from '@polkadot/util/u8a/toHex'; import translate from '../translate'; -type Props = BaseProps & { +type Props = I18nProps & { label?: string, value?: Header }; diff --git a/packages/app-explorer/src/BlockHeaders/index.js b/packages/app-explorer/src/BlockHeaders/index.js index be4d6ee83a..74c63b8a62 100644 --- a/packages/app-explorer/src/BlockHeaders/index.js +++ b/packages/app-explorer/src/BlockHeaders/index.js @@ -4,47 +4,32 @@ // @flow import type { Header } from '@polkadot/primitives/header'; -import type { BaseProps } from '../types'; import React from 'react'; +import Div from '@polkadot/rx-react/Div'; import withApiCall from '@polkadot/rx-react/with/apiCall'; -import translate from '../translate'; import BlockHeader from '../BlockHeader'; -import { blockHeaders } from '../subjects'; +import { blockHeaders as subject } from '../subjects'; import transform from './transform'; -type Props = BaseProps & { - value: Array
+const apiMethod = { + method: 'newHead', + section: 'chain' }; -function BlockHeaders ({ className, style, value }: Props): React$Node { - return ( -
- { - (value || []).map((header) => ( - - )) - } -
- ); -} +const apiOptions = { + subject, + transform +}; -export default translate( - withApiCall( - { - method: 'newHead', - section: 'chain' - }, - { - subject: blockHeaders, - transform - } - )(BlockHeaders) -); +export default withApiCall(apiMethod, apiOptions)(Div, { + className: 'explorer--BlockHeaders', + format: (value?: Array
= []): React$Node => + value.map((value) => ( + + )) +}); diff --git a/packages/app-explorer/src/BlockHeaders/transform.js b/packages/app-explorer/src/BlockHeaders/transform.js index 3a2ac75f2f..7e08eee9fe 100644 --- a/packages/app-explorer/src/BlockHeaders/transform.js +++ b/packages/app-explorer/src/BlockHeaders/transform.js @@ -14,11 +14,11 @@ export default function transform (header: Header): Array
{ return prev; } - return prev.reduce((next, value, index) => { - if (index < 9) { + return prev + .filter((value, index) => index < 9) + .reduce((next, value, index) => { next.push(value); - } - return next; - }, [header]); + return next; + }, [header]); } diff --git a/packages/app-explorer/src/index.css b/packages/app-explorer/src/index.css index 4a7a50b8f0..6625e738fa 100644 --- a/packages/app-explorer/src/index.css +++ b/packages/app-explorer/src/index.css @@ -1,3 +1,36 @@ /* Copyright 2017-2018 Jaco Greeff /* This software may be modified and distributed under the terms /* of the ISC license. See the LICENSE file for details. */ + +.explorer--App { + padding: 1em; +} + +.explorer--App .rx--updated { + background: transparent !important; +} + +.explorer--BestHash, +.explorer--BestNumber { + font-weight: 100; + text-align: right; + opacity: 0.5; +} + +.explorer--BestHash.rx--updated, +.explorer--BestNumber.rx--updated { + opacity: 1; +} + +.explorer--BestHash { + font-size: 1.5em; + line-height: 1.5em; + margin-bottom: 1em; +} + +.explorer--BestNumber { + font-size: 3rem; + line-height: 3rem; +} + +.explorer--BlockHeaders {} diff --git a/packages/app-explorer/src/translate.js b/packages/app-explorer/src/translate.js index ea4ad5ab8e..446d376bf7 100644 --- a/packages/app-explorer/src/translate.js +++ b/packages/app-explorer/src/translate.js @@ -5,4 +5,4 @@ import { translate } from 'react-i18next'; -export default translate(['explorer']); +export default translate(['explorer', 'ui']); diff --git a/packages/app-extrinsics/package.json b/packages/app-extrinsics/package.json index 7cd851bf67..1a247f88bd 100644 --- a/packages/app-extrinsics/package.json +++ b/packages/app-extrinsics/package.json @@ -2,7 +2,7 @@ "name": "@polkadot/app-extrinsics", "version": "0.1.6", "main": "index.js", - "repository": "https://github.com/polkadot-js/portal.git", + "repository": "https://github.com/polkadot-js/apps.git", "author": "Jaco Greeff ", "license": "ISC", "scripts": { @@ -11,18 +11,9 @@ "test": "jest --coverage" }, "devDependencies": { - "@polkadot/extrinsics": "^0.1.6", - "@polkadot/extrinsics-codec": "^0.1.6", - "@polkadot/extrinsics-polkadot": "^0.1.6", - "@polkadot/rx-react": "^0.4.7", - "@polkadot/ui-react": "^0.9.12", - "@polkadot/util": "^0.19.4", - "@polkadot/util-keyring": "^0.19.4", - "react": "^16.3.1", - "react-dom": "^16.3.1", - "react-dropzone": "^4.2.9", - "react-i18next": "^7.5.1", - "semantic-ui-css": "^2.3.1", - "semantic-ui-react": "^0.79.1" + "@polkadot/extrinsics": "^0.12.4", + "@polkadot/extrinsics-codec": "^0.12.4", + "@polkadot/ui-react-app": "^0.1.6", + "react-dropzone": "^4.2.9" } } diff --git a/packages/app-extrinsics/src/Account.js b/packages/app-extrinsics/src/Account.js index 18e0e63a32..21dd19140f 100644 --- a/packages/app-extrinsics/src/Account.js +++ b/packages/app-extrinsics/src/Account.js @@ -3,50 +3,60 @@ // of the ISC license. See the LICENSE file for details. // @flow -import type { BaseProps } from './types'; +import type { I18nProps } from '@polkadot/ui-react-app/types'; import React from 'react'; import Label from 'semantic-ui-react/dist/es/elements/Label'; import Balance from '@polkadot/rx-react/Balance'; import withObservableParams from '@polkadot/rx-react/with/observableParams'; +import InputAddress from '@polkadot/ui-react-app/src/InputAddress'; import translate from './translate'; -import InputAddress from './InputAddress'; -type Props = BaseProps & { +type Props = I18nProps & { isError?: boolean, label: string, subject: rxjs$BehaviorSubject }; -function Account ({ className, isError, label, subject, style, t }: Props): React$Node { - const AccountBalance = withObservableParams(subject)(Balance); +class Account extends React.PureComponent { + Balance: React$ComponentType<*>; - return ( -
-
- - + constructor (props: Props) { + super(props); + + this.Balance = withObservableParams(props.subject)(Balance, { + className: 'ui disabled dropdown selection' + }); + } + + render (): React$Node { + const { className, label, subject, style, t } = this.props; + const Balance = this.Balance; + + return ( +
+
+ +
+
+ + +
-
- - -
-
- ); + ); + } } export default translate(Account); diff --git a/packages/app-extrinsics/src/App.js b/packages/app-extrinsics/src/App.js index 0eb5586af7..5de9c0af24 100644 --- a/packages/app-extrinsics/src/App.js +++ b/packages/app-extrinsics/src/App.js @@ -3,7 +3,8 @@ // of the ISC license. See the LICENSE file for details. // @flow -import type { BaseProps, QueueTx } from './types'; +import type { I18nProps } from '@polkadot/ui-react-app/types'; +import type { QueueTx } from './types'; import React from 'react'; import { BehaviorSubject } from 'rxjs/BehaviorSubject'; @@ -13,7 +14,7 @@ import Submission from './Submission'; import Signer from './Signer'; import translate from './translate'; -type Props = BaseProps & {}; +type Props = I18nProps & {}; const queue: rxjs$BehaviorSubject = new BehaviorSubject(({ isValid: false, diff --git a/packages/app-extrinsics/src/Extrinsic/index.js b/packages/app-extrinsics/src/Extrinsic/index.js index df3fb4b9c4..ca9116499f 100644 --- a/packages/app-extrinsics/src/Extrinsic/index.js +++ b/packages/app-extrinsics/src/Extrinsic/index.js @@ -3,43 +3,99 @@ // of the ISC license. See the LICENSE file for details. // @flow -import type { BareProps, EncodedParams } from '../types'; +import type { BareProps } from '@polkadot/ui-react-app/types'; +import type { EncodedParams } from '../types'; +import type { Subjects } from './types'; import React from 'react'; -import Label from 'semantic-ui-react/dist/es/elements/Label'; +import encodeExtrinsic from '@polkadot/extrinsics-codec/encode/extrinsic'; import withObservable from '@polkadot/rx-react/with/observable'; +import InputExtrinsic from '@polkadot/ui-react-app/src/InputExtrinsic'; +import Params from '@polkadot/ui-react-app/src/Params'; +import isUndefined from '@polkadot/util/is/undefined'; -import InputExtrinsic from '../InputExtrinsic'; -import Params from '../Params'; +import paramComponents from '../Params'; import createSubjects from './subjects'; type Props = BareProps & { isError?: boolean, isPrivate?: boolean, - label: string, + labelMethod?: string, + labelSection?: string, subject: rxjs$BehaviorSubject }; -export default function Extrinsic ({ className, isError, isPrivate, label, style, subject }: Props): React$Node { - const subjects = createSubjects(subject); - const MethodParams = withObservable(subjects.method)(Params); +export default class Extrinsic extends React.PureComponent { + subjects: Subjects; + subscriptions: Array; + Params: React$ComponentType<*>; - return ( -
-
- - + s.unsubscribe() + ); + } + + onChange = (): void => { + const extrinsic = this.subjects.method.getValue(); + const values = this.subjects.params.getValue(); + const isValid = !!extrinsic.params && + Object + .values(extrinsic.params) + .reduce((isValid, param, index) => { + return isValid && + !isUndefined(values[index]) && + !isUndefined(values[index].value) && + values[index].isValid; + }, !!values); + const raw = values.map((param) => param && param.value); + const data = extrinsic.params && encodeExtrinsic(extrinsic, raw); + + this.props.subject.next({ + data, + extrinsic, + isValid + }); + }; + + render (): React$Node { + const { className, isError, isPrivate, labelMethod, labelSection, style } = this.props; + const { Params, subjects } = this; + + return ( +
+
+ +
+
- -
- ); + ); + } } diff --git a/packages/app-extrinsics/src/Extrinsic/subjects.js b/packages/app-extrinsics/src/Extrinsic/subjects.js index c25b358206..6895c627a4 100644 --- a/packages/app-extrinsics/src/Extrinsic/subjects.js +++ b/packages/app-extrinsics/src/Extrinsic/subjects.js @@ -4,40 +4,16 @@ // @flow import type { Extrinsic } from '@polkadot/extrinsics/types'; -import type { EncodedParams, RawParam } from '../types'; +import type { EncodedParams } from '../types'; +import type { Subjects } from './types'; import { BehaviorSubject } from 'rxjs/BehaviorSubject'; -import encodeExtrinsic from '@polkadot/extrinsics-codec/src/encode/extrinsic'; -import isUndefined from '@polkadot/util/is/undefined'; - -type Subjects = { - method: rxjs$BehaviorSubject, - params: rxjs$BehaviorSubject> -}; export default function subjects (subject: rxjs$BehaviorSubject): Subjects { - const subjects = { - method: new BehaviorSubject(({}: $Shape)), + const extrinsic = subject.getValue().extrinsic || ({}: $Shape); + + return { + method: new BehaviorSubject(extrinsic), params: new BehaviorSubject([]) }; - - const onChange = (): void => { - const extrinsic = subjects.method.getValue(); - const values = subjects.params.getValue(); - const isValid = !!extrinsic.params && extrinsic.params.reduce((isValid, param, index) => { - return isValid && !isUndefined(values[index]) && !isUndefined(values[index].value) && values[index].isValid; - }, !!values); - const raw = values.map((param) => param && param.value); - const data = extrinsic.params && encodeExtrinsic(extrinsic, raw); - - subject.next({ - data, - extrinsic, - isValid - }); - }; - - subjects.params.subscribe(onChange); - - return subjects; } diff --git a/packages/app-extrinsics/src/Extrinsic/types.js b/packages/app-extrinsics/src/Extrinsic/types.js new file mode 100644 index 0000000000..8334330323 --- /dev/null +++ b/packages/app-extrinsics/src/Extrinsic/types.js @@ -0,0 +1,12 @@ +// Copyright 2017-2018 Jaco Greeff +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. +// @flow + +import type { Extrinsic } from '@polkadot/extrinsics/types'; +import type { RawParam } from '@polkadot/ui-react-app/Params/types'; + +export type Subjects = { + method: rxjs$BehaviorSubject, + params: rxjs$BehaviorSubject> +}; diff --git a/packages/app-extrinsics/src/InputExtrinsic/index.js b/packages/app-extrinsics/src/InputExtrinsic/index.js deleted file mode 100644 index 05b6d3ef87..0000000000 --- a/packages/app-extrinsics/src/InputExtrinsic/index.js +++ /dev/null @@ -1,63 +0,0 @@ -// Copyright 2017-2018 Jaco Greeff -// This software may be modified and distributed under the terms -// of the ISC license. See the LICENSE file for details. -// @flow - -// TODO: This is a useful, shared component, move out - -import type { Extrinsic } from '@polkadot/extrinsics/types'; - -import './InputExtrinsic.css'; - -import React from 'react'; -import Dropdown from 'semantic-ui-react/dist/es/modules/Dropdown'; -import extrinsics from '@polkadot/extrinsics-polkadot/src'; - -import options from './options'; - -type Props = { - className?: string, - isError?: boolean, - isPrivate?: boolean, - onChange?: (event: SyntheticEvent<*>, value: Extrinsic) => void, - style?: { - [string]: string - }, - subject?: rxjs$Subject -}; - -export default function InputExtrinsic (props: Props): React$Node { - // eslint-disable-next-line no-unused-vars - const onChange = (event: SyntheticEvent<*>, { value }): void => { - const extrinsic = extrinsics.get(value); - - if (props.subject) { - props.subject.next(extrinsic); - } - - if (props.onChange) { - props.onChange(event, extrinsic); - } - }; - - const _props = Object.assign({}, props); - - delete _props.isError; - delete _props.isPrivate; - - return ( - - ); -} diff --git a/packages/app-extrinsics/src/InputExtrinsic/options.js b/packages/app-extrinsics/src/InputExtrinsic/options.js deleted file mode 100644 index 94e0c1355b..0000000000 --- a/packages/app-extrinsics/src/InputExtrinsic/options.js +++ /dev/null @@ -1,60 +0,0 @@ -// Copyright 2017-2018 Jaco Greeff -// This software may be modified and distributed under the terms -// of the ISC license. See the LICENSE file for details. -// @flow - -import React from 'react'; -import Dropdown from 'semantic-ui-react/dist/es/modules/Dropdown'; -import extrinsics from '@polkadot/extrinsics-polkadot/src'; - -const options = { - private: [], - public: [] -}; - -const sortByName = (a, b) => - a.name.localeCompare(b.name); - -const addHeader = (shouldAdd, to, name, description) => { - if (shouldAdd) { - if (to.length) { - to.push(); - } - - to.push( - - {description} - - ); - } -}; - -extrinsics.sections.sort(sortByName).forEach(({ description, hasPrivate, hasPublic, methods, name }) => { - addHeader(hasPublic, options.public, name, description); - addHeader(hasPrivate, options.private, name, description); - - methods.sort(sortByName).forEach(({ description, name, params, isPrivate }) => { - const inputs = params.map(({ name }) => name).join(', '); - - options[isPrivate ? 'private' : 'public'].push({ - className: 'ui--InputExtrinsic-Item', - text: [ -
- {description || name} -
, -
- {name}({inputs}) -
- ], - value: name - }); - }); -}); - -export default options; diff --git a/packages/app-extrinsics/src/Params/Account.js b/packages/app-extrinsics/src/Params/Account.js new file mode 100644 index 0000000000..13c5a19fb3 --- /dev/null +++ b/packages/app-extrinsics/src/Params/Account.js @@ -0,0 +1,51 @@ +// Copyright 2017-2018 Jaco Greeff +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. +// @flow + +import type { Props } from '@polkadot/ui-react-app/Params/types'; + +import React from 'react'; +import { BehaviorSubject } from 'rxjs/BehaviorSubject'; + +import BaseAccount from '../Account'; + +export default class Account extends React.PureComponent { + account: rxjs$BehaviorSubject; + subscriptions: Array + + constructor (props: Props) { + super(props); + + this.account = new BehaviorSubject(new Uint8Array([])); + } + + componentWillMount () { + this.subscriptions = [ + this.account.subscribe((value: Uint8Array) => + this.props.subject.next({ + isValid: !!value && value.length === 32, + value + }) + ) + ]; + } + + componentWillUnmount () { + this.subscriptions.forEach((s) => + s.unsubscribe() + ); + } + + render (): React$Node { + const { isError, label } = this.props; + + return ( + + ); + } +} diff --git a/packages/app-extrinsics/src/Params/Param/Account.js b/packages/app-extrinsics/src/Params/Param/Account.js deleted file mode 100644 index 5a4baca3ee..0000000000 --- a/packages/app-extrinsics/src/Params/Param/Account.js +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright 2017-2018 Jaco Greeff -// This software may be modified and distributed under the terms -// of the ISC license. See the LICENSE file for details. -// @flow - -import type { Props } from '../types'; - -import React from 'react'; -import { BehaviorSubject } from 'rxjs/BehaviorSubject'; - -import BaseAccount from '../../Account'; - -export default function Account ({ isError, label, subject }: Props): React$Node { - const account: rxjs$BehaviorSubject = new BehaviorSubject(new Uint8Array([])); - - account.subscribe((value: Uint8Array) => - subject.next({ - isValid: !!(value && value.length), - value - }) - ); - - return ( - - ); -} diff --git a/packages/app-extrinsics/src/Params/Param/Proposal.js b/packages/app-extrinsics/src/Params/Param/Proposal.js deleted file mode 100644 index 4005129f47..0000000000 --- a/packages/app-extrinsics/src/Params/Param/Proposal.js +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright 2017-2018 Jaco Greeff -// This software may be modified and distributed under the terms -// of the ISC license. See the LICENSE file for details. -// @flow - -import type { EncodedParams } from '../../types'; -import type { Props } from '../types'; - -import React from 'react'; -import { BehaviorSubject } from 'rxjs/BehaviorSubject'; - -import Extrinsic from '../../Extrinsic'; - -export default function Proposal ({ isError, label, subject }: Props): React$Node { - const extrinsic: rxjs$BehaviorSubject = new BehaviorSubject(({ isValid: false }: $Shape)); - - extrinsic.subscribe(({ data, isValid }: EncodedParams) => - subject.next({ - isValid, - value: data - }) - ); - - return ( - - ); -} diff --git a/packages/app-extrinsics/src/Params/Proposal.js b/packages/app-extrinsics/src/Params/Proposal.js new file mode 100644 index 0000000000..9387c0fac9 --- /dev/null +++ b/packages/app-extrinsics/src/Params/Proposal.js @@ -0,0 +1,70 @@ +// Copyright 2017-2018 Jaco Greeff +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. +// @flow + +import type { Props as BaseProps } from '@polkadot/ui-react-app/Params/types'; +import type { I18nProps } from '@polkadot/ui-react-app/types'; +import type { EncodedParams } from '../types'; + +import React from 'react'; +import { BehaviorSubject } from 'rxjs/BehaviorSubject'; + +import Extrinsic from '../Extrinsic'; +import translate from '../translate'; + +type Props = BaseProps & I18nProps; + +class Proposal extends React.PureComponent { + extrinsic: rxjs$BehaviorSubject; + subscriptions: Array + + constructor (props: Props) { + super(props); + + this.extrinsic = new BehaviorSubject(({ isValid: false }: $Shape)); + } + + componentWillMount () { + this.subscriptions = [ + this.extrinsic.subscribe(({ data, isValid }: EncodedParams) => + this.props.subject.next({ + isValid, + value: data + }) + ) + ]; + } + + componentWillUnmount () { + this.subscriptions.forEach((s) => + s.unsubscribe() + ); + } + + render (): React$Node { + const { isError, label, t } = this.props; + + return ( + + ); + } +} + +export default translate(Proposal); diff --git a/packages/app-extrinsics/src/Params/findComponent.js b/packages/app-extrinsics/src/Params/findComponent.js deleted file mode 100644 index ca9fd4705e..0000000000 --- a/packages/app-extrinsics/src/Params/findComponent.js +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright 2017-2018 Jaco Greeff -// This software may be modified and distributed under the terms -// of the ISC license. See the LICENSE file for details. -// @flow - -import type { Extrinsic$Type } from '@polkadot/extrinsics/types'; - -import Account from './Param/Account'; -import Amount from './Param/Amount'; -import Bool from './Param/Bool'; -import Bytes from './Param/Bytes'; -import Hash from './Param/Hash'; -import Proposal from './Param/Proposal'; -import Unknown from './Param/Unknown'; -import VoteThreshold from './Param/VoteThreshold'; -import Wasm from './Param/Wasm'; - -const Components = { - 'AccountId': Account, - 'Balance': Amount, - 'BlockNumber': Amount, - 'bool': Bool, - 'Bytes': Bytes, - 'Hash': Hash, - 'MisbehaviorReport': Unknown, - 'Proposal': Proposal, - 'SessionKey': Unknown, - 'u32': Amount, - 'u64': Amount, - 'VoteThreshold': VoteThreshold, - 'Wasm': Wasm -}; - -export default function findComponent (type: Extrinsic$Type): React$ComponentType<*> { - if (Array.isArray(type)) { - // eslint-disable-next-line no-unused-vars - const [outer, inner] = type; - - return findComponent(inner); - } - - return Components[type]; -} diff --git a/packages/app-extrinsics/src/Params/index.js b/packages/app-extrinsics/src/Params/index.js index 7ac79a56ca..dcef1fc1b8 100644 --- a/packages/app-extrinsics/src/Params/index.js +++ b/packages/app-extrinsics/src/Params/index.js @@ -3,52 +3,14 @@ // of the ISC license. See the LICENSE file for details. // @flow -import type { Extrinsic } from '@polkadot/extrinsics/types'; -import type { BaseProps, RawParam } from '../types'; +import type { ComponentMap } from '@polkadot/ui-react-app/Params/types'; -import './Params.css'; +import Account from './Account'; +import Proposal from './Proposal'; -import React from 'react'; - -import translate from '../translate'; -import findComponent from './findComponent'; -import createSubjects from './subjects'; -import typeToText from './typeToText'; - -type Props = BaseProps & { - subject: rxjs$BehaviorSubject>, - value: Extrinsic; +const components: ComponentMap = { + 'AccountId': Account, + 'Proposal': Proposal }; -function Params ({ className, style, subject, value: { name, params } }: Props): React$Node { - if (!params || !params.length) { - return null; - } - - const subjects = createSubjects(params, subject); - - return ( -
-
- {params.map((value, index) => { - const Component = findComponent(value.type); - - return ( - - ); - })} -
-
- ); -} - -export default translate(Params); +export default components; diff --git a/packages/app-extrinsics/src/Signer/Decoded.js b/packages/app-extrinsics/src/Signer/Decoded.js index c14566def2..4cfb6007bb 100644 --- a/packages/app-extrinsics/src/Signer/Decoded.js +++ b/packages/app-extrinsics/src/Signer/Decoded.js @@ -3,7 +3,8 @@ // of the ISC license. See the LICENSE file for details. // @flow -import type { BaseProps, QueueTx } from '../types'; +import type { I18nProps } from '@polkadot/ui-react-app/types'; +import type { QueueTx } from '../types'; import React from 'react'; import { Trans } from 'react-i18next'; @@ -13,7 +14,7 @@ import u8aToHexShort from '@polkadot/util/u8a/toHexShort'; import translate from '../translate'; -type Props = BaseProps & { +type Props = I18nProps & { value: QueueTx }; @@ -33,7 +34,7 @@ function Decoded ({ className, style, t, value: { data, extrinsic, index, public

- You are about to sign a message from {from} calling {extrinsic.name} with an index of {index.toString()} + You are about to sign a message from {from} calling {extrinsic.section}_{extrinsic.name} with an index of {index.toString()}

diff --git a/packages/app-extrinsics/src/Signer/index.js b/packages/app-extrinsics/src/Signer/index.js index 9e298dc15e..a21e91bd83 100644 --- a/packages/app-extrinsics/src/Signer/index.js +++ b/packages/app-extrinsics/src/Signer/index.js @@ -4,7 +4,8 @@ // @flow import type { ApiProps } from '@polkadot/rx-react/types'; -import type { BaseProps, QueueTx } from '../types'; +import type { I18nProps } from '@polkadot/ui-react-app/types'; +import type { QueueTx } from '../types'; import './Signer.css'; @@ -17,7 +18,7 @@ import translate from '../translate'; import Decoded from './Decoded'; import submitExtrinsic from './submit'; -type Props = BaseProps & ApiProps & { +type Props = I18nProps & ApiProps & { subject: rxjs$BehaviorSubject, value: QueueTx }; diff --git a/packages/app-extrinsics/src/Signer/submit.js b/packages/app-extrinsics/src/Signer/submit.js index ee7ef59cb9..2d6a1fc04e 100644 --- a/packages/app-extrinsics/src/Signer/submit.js +++ b/packages/app-extrinsics/src/Signer/submit.js @@ -6,12 +6,11 @@ import type { RxApiInterface } from '@polkadot/rx-api/types'; import type { QueueTx } from '../types'; -import encodeCall from '@polkadot/extrinsics-codec/src/encode/call'; +import encodeCall from '@polkadot/extrinsics-codec/encode/call'; +import keyring from '@polkadot/ui-react-app/src/keyring'; import u8aConcat from '@polkadot/util/u8a/concat'; import u8aToHex from '@polkadot/util/u8a/toHex'; -import keyring from '../keyring'; - export default function submit (api: RxApiInterface, tx: QueueTx, subject: rxjs$BehaviorSubject): Promise { const message = encodeCall(tx.publicKey, tx.index, tx.data); const signature = keyring.getPair(tx.publicKey).sign(message); diff --git a/packages/app-extrinsics/src/Submission/Nonce.js b/packages/app-extrinsics/src/Submission/Nonce.js index b947288fa0..c2df7dd420 100644 --- a/packages/app-extrinsics/src/Submission/Nonce.js +++ b/packages/app-extrinsics/src/Submission/Nonce.js @@ -4,7 +4,7 @@ // @flow import type BN from 'bn.js'; -import type { BareProps } from '../types'; +import type { BareProps } from '@polkadot/ui-react-app/types'; import React from 'react'; import Label from 'semantic-ui-react/dist/es/elements/Label'; @@ -17,22 +17,33 @@ type Props = BareProps & { value: rxjs$BehaviorSubject }; -export default function Nonce ({ className, label, style, subject, t, value }: Props): React$Node { - const SenderNonce = withObservableParams(value)(RxNonce); +export default class Nonce extends React.PureComponent { + Nonce: React$ComponentType<*>; - return ( -

-
- - + constructor (props: Props) { + super(props); + + // NOTE we basically get away with not checking updates since the parent is only created once + this.Nonce = withObservableParams(props.value)(RxNonce); + } + + render (): React$Node { + const { className, label, style, subject } = this.props; + const Nonce = this.Nonce; + + return ( +
+
+ + +
-
- ); + ); + } } diff --git a/packages/app-extrinsics/src/Submission/Submission.css b/packages/app-extrinsics/src/Submission/Submission.css index e9c9a7bf50..2c63e1165c 100644 --- a/packages/app-extrinsics/src/Submission/Submission.css +++ b/packages/app-extrinsics/src/Submission/Submission.css @@ -10,6 +10,6 @@ } .extrinsics--Submission-ButtonRow .button { - margin-right: 0.5rem; + margin-left: 0.5rem; text-align: left; } diff --git a/packages/app-extrinsics/src/Submission/Submit.js b/packages/app-extrinsics/src/Submission/Submit.js index 60f251cc4c..9bc5207396 100644 --- a/packages/app-extrinsics/src/Submission/Submit.js +++ b/packages/app-extrinsics/src/Submission/Submit.js @@ -3,14 +3,15 @@ // of the ISC license. See the LICENSE file for details. // @flow -import type { BaseProps, QueueTx } from '../types'; +import type { I18nProps } from '@polkadot/ui-react-app/types'; +import type { QueueTx } from '../types'; import React from 'react'; import Button from 'semantic-ui-react/dist/es/elements/Button'; import translate from '../translate'; -type Props = BaseProps & { +type Props = I18nProps & { subject: rxjs$BehaviorSubject, value: QueueTx; }; diff --git a/packages/app-extrinsics/src/Submission/index.js b/packages/app-extrinsics/src/Submission/index.js index d787f89b56..d5ae9d91bf 100644 --- a/packages/app-extrinsics/src/Submission/index.js +++ b/packages/app-extrinsics/src/Submission/index.js @@ -3,7 +3,9 @@ // of the ISC license. See the LICENSE file for details. // @flow -import type { BaseProps, QueueTx } from '../types'; +import type { I18nProps } from '@polkadot/ui-react-app/types'; +import type { QueueTx } from '../types'; +import type { Subjects } from './types'; import './Submission.css'; @@ -17,43 +19,76 @@ import Nonce from './Nonce'; import Submit from './Submit'; import createSubjects from './subjects'; -type Props = BaseProps & { +type Props = I18nProps & { subject: rxjs$BehaviorSubject }; -function Submission ({ className, subject, style, t }: Props): React$Node { - const subjects = createSubjects(); - const Button = withObservable(subjects.call)(Submit); +class Submission extends React.PureComponent { + Submit: React$ComponentType<*>; + subjects: Subjects; - return ( -
- - - -
-
- ); + ); + } } export default translate(Submission); diff --git a/packages/app-extrinsics/src/Submission/subjects.js b/packages/app-extrinsics/src/Submission/subjects.js index 2bd207ee35..4a8995dd04 100644 --- a/packages/app-extrinsics/src/Submission/subjects.js +++ b/packages/app-extrinsics/src/Submission/subjects.js @@ -4,47 +4,22 @@ // @flow import type { EncodedParams, QueueTx } from '../types'; +import type { Subjects } from './types'; import BN from 'bn.js'; import { BehaviorSubject } from 'rxjs/BehaviorSubject'; - -type Subjects = { - call: rxjs$BehaviorSubject, - index: rxjs$BehaviorSubject, - method: rxjs$BehaviorSubject, - sender: rxjs$BehaviorSubject -}; +import map from '@polkadot/extrinsics-substrate'; export default function createSubjects (): Subjects { - const subjects = { + return { index: new BehaviorSubject(new BN(0)), call: new BehaviorSubject(({ isValid: false }: $Shape)), method: new BehaviorSubject(({ + extrinsic: map.staking.methods.public.transfer, isValid: false }: $Shape)), sender: new BehaviorSubject(new Uint8Array([])) }; - - const onChange = (): void => { - const publicKey = subjects.sender.getValue(); - const message = subjects.method.getValue(); - const index = subjects.index.getValue(); - const isValid = !!(publicKey && publicKey.length && message && message.isValid); - - subjects.call.next({ - data: message.data, - extrinsic: message.extrinsic, - isValid, - index, - publicKey, - status: 'incomplete' - }); - }; - - subjects.method.subscribe(onChange); - subjects.sender.subscribe(onChange); - - return subjects; } diff --git a/packages/app-extrinsics/src/Submission/types.js b/packages/app-extrinsics/src/Submission/types.js new file mode 100644 index 0000000000..fb2b6f289f --- /dev/null +++ b/packages/app-extrinsics/src/Submission/types.js @@ -0,0 +1,14 @@ +// Copyright 2017-2018 Jaco Greeff +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. +// @flow + +import type BN from 'bn.js'; +import type { EncodedParams, QueueTx } from '../types'; + +export type Subjects = { + call: rxjs$BehaviorSubject, + index: rxjs$BehaviorSubject, + method: rxjs$BehaviorSubject, + sender: rxjs$BehaviorSubject +}; diff --git a/packages/app-extrinsics/src/index.css b/packages/app-extrinsics/src/index.css index 7554ffb4f2..cbfaf0204b 100644 --- a/packages/app-extrinsics/src/index.css +++ b/packages/app-extrinsics/src/index.css @@ -5,50 +5,3 @@ .extrinsics--App { padding: 1em; } - -.extrinsics--full, -.extrinsics--split { - width: 100%; -} - -.extrinsics--split { - display: flex; - flex-wrap: wrap; - flex-direction: row; - justify-content: flex-start; - align-items: stretch; -} - -.extrinsics--split > div { - box-sizing: border-box; - min-width: 0; - width: 100%; -} - -.extrinsics--split > div.full, -.extrinsics--split > div.large, -.extrinsics--split > div.medium, -.extrinsics--split > div.small { - padding-right: 0.5rem; -} - -.extrinsics--split > div.full { - flex: 0 100%; -} - -.extrinsics--split > div.large { - flex: 0 75%; -} - -.extrinsics--split > div.medium { - flex: 0 50%; -} - -.extrinsics--split > div.small { - flex: 0 25%; -} - -.hasUpdated { - background: #ffffe0 !important; - transition: all 0.7s ease-in-out; -} diff --git a/packages/app-extrinsics/src/translate.js b/packages/app-extrinsics/src/translate.js index cdf6a90371..627acf2456 100644 --- a/packages/app-extrinsics/src/translate.js +++ b/packages/app-extrinsics/src/translate.js @@ -5,4 +5,4 @@ import { translate } from 'react-i18next'; -export default translate(['extrinsics']); +export default translate(['extrinsics', 'ui']); diff --git a/packages/app-extrinsics/src/types.js b/packages/app-extrinsics/src/types.js index 56301ac26b..c1abc594ac 100644 --- a/packages/app-extrinsics/src/types.js +++ b/packages/app-extrinsics/src/types.js @@ -6,24 +6,6 @@ import type BN from 'bn.js'; import type { Extrinsic } from '@polkadot/extrinsics/types'; -export type BareProps = { - className?: string, - style?: { - [string]: string - } -}; - -export type BaseProps = BareProps & { - t: I18Next$Translate -}; - -export type RawParam = { - // flowlint-next-line unclear-type:off - data?: any, - isValid: boolean, - value: mixed, -} - export type EncodedParams = { data: Uint8Array, extrinsic: Extrinsic, diff --git a/packages/extrinsics-codec/LICENSE b/packages/app-storage/LICENSE similarity index 100% rename from packages/extrinsics-codec/LICENSE rename to packages/app-storage/LICENSE diff --git a/packages/app-storage/README.md b/packages/app-storage/README.md new file mode 100644 index 0000000000..3b61e3c40d --- /dev/null +++ b/packages/app-storage/README.md @@ -0,0 +1 @@ +# @polkadot/app-storage diff --git a/packages/extrinsics/package.json b/packages/app-storage/package.json similarity index 60% rename from packages/extrinsics/package.json rename to packages/app-storage/package.json index d92b61cb69..954ceb99b7 100644 --- a/packages/extrinsics/package.json +++ b/packages/app-storage/package.json @@ -1,8 +1,8 @@ { - "name": "@polkadot/extrinsics", + "name": "@polkadot/app-storage", "version": "0.1.6", "main": "index.js", - "repository": "https://github.com/polkadot-js/portal.git", + "repository": "https://github.com/polkadot-js/apps.git", "author": "Jaco Greeff ", "license": "ISC", "scripts": { @@ -10,8 +10,7 @@ "check": "stylelint 'src/**/*.css' && eslint src && flow check", "test": "jest --coverage" }, - "dependencies": { - "@polkadot/util": "^0.19.4", - "babel-runtime": "^6.26.0" + "devDependencies": { + "@polkadot/ui-react-app": "^0.1.6" } } diff --git a/packages/app-storage/src/App.js b/packages/app-storage/src/App.js new file mode 100644 index 0000000000..1b55aa30b0 --- /dev/null +++ b/packages/app-storage/src/App.js @@ -0,0 +1,28 @@ +// Copyright 2017-2018 Jaco Greeff +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. +// @flow + +import type { I18nProps } from '@polkadot/ui-react-app/types'; + +import React from 'react'; + +import Queries from './Queries'; +import Selection from './Selection'; +import translate from './translate'; + +type Props = I18nProps & {}; + +function App ({ className, style, t }: Props): React$Node { + return ( +
+ + +
+ ); +} + +export default translate(App); diff --git a/packages/app-storage/src/Queries/Query.js b/packages/app-storage/src/Queries/Query.js new file mode 100644 index 0000000000..fcb90df26c --- /dev/null +++ b/packages/app-storage/src/Queries/Query.js @@ -0,0 +1,61 @@ +// Copyright 2017-2018 Jaco Greeff +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. +// @flow + +import type { I18nProps } from '@polkadot/ui-react-app/types'; +import type { StorageQuery } from '../types'; + +import React from 'react'; +import Label from 'semantic-ui-react/dist/es/elements/Label'; +import Div from '@polkadot/rx-react/Div'; +import withStorage from '@polkadot/rx-react/with/storage'; + +import translate from '../translate'; +import Remove from './Remove'; +import cache from './cache'; +import createTransform from './transform'; + +type Props = I18nProps & { + value: StorageQuery +}; + +function Query ({ className, style, value: { id, key, params } }: Props): React$Node { + const CachedQuery = (() => { + if (!cache[id]) { + const transform = createTransform(key); + + cache[id] = withStorage(key, { params, transform })( + Div, { className: 'ui disabled dropdown selection' } + ); + } + + return cache[id]; + })(); + + const inputs = Object + .keys(key.params || {}) + // $FlowFixMe key.params exists + .map((name) => `${name}: ${key.params[name].type}`) + .join(', '); + + return ( +
+
+ + +
+
+ + +
+
+ ); +} + +export default translate(Query); diff --git a/packages/app-storage/src/Queries/Remove.js b/packages/app-storage/src/Queries/Remove.js new file mode 100644 index 0000000000..85457b862c --- /dev/null +++ b/packages/app-storage/src/Queries/Remove.js @@ -0,0 +1,46 @@ +// Copyright 2017-2018 Jaco Greeff +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. +// @flow + +import type { I18nProps } from '@polkadot/ui-react-app/types'; + +import React from 'react'; +import Button from 'semantic-ui-react/dist/es/elements/Button'; + +import subjects from '../subjects'; +import translate from '../translate'; +import cache from './cache'; + +type Props = I18nProps & { + value: number; +}; + +function Remove ({ className, style, value }: Props): React$Node { + const onRemove = (): void => { + const current = subjects.queries.getValue(); + + delete cache[value]; + + subjects.queries.next( + current + .filter(({ id }) => id !== value) + .reduce((next, item) => { + next.push(item); + + return next; + }, []) + ); + }; + + return ( +