Add utility/toolbox app (#51)
* Upgrades * Add & use Output component * Render app in content * Use update @polkadot/dev-react * Add app-toolbox * DRY className concat * Hashing in place * Verify signature operational * Entry updates * Verification operational * Final cleanups before PR * Bump version
This commit is contained in:
parent
e1f1ca5153
commit
5f884c4b65
3
.babelrc
3
.babelrc
@ -1,4 +1,3 @@
|
||||
{
|
||||
"extends": "@polkadot/dev/config/babel",
|
||||
"presets": ["react"]
|
||||
"extends": "@polkadot/dev-react/config/babel"
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
{
|
||||
"extends": [
|
||||
"./node_modules/@polkadot/dev/config/eslint.js"
|
||||
"./node_modules/@polkadot/dev-react/config/eslint.js"
|
||||
]
|
||||
}
|
||||
|
||||
@ -6,12 +6,13 @@
|
||||
|
||||
[libs]
|
||||
node_modules/@polkadot/dev/flow-typed
|
||||
node_modules/@polkadot/dev-react/flow-typed
|
||||
|
||||
[lints]
|
||||
all=warn
|
||||
|
||||
[options]
|
||||
include_warnings=true
|
||||
module.name_mapper='^@polkadot/app-\(accounts\|addresses\|explorer\|extrinsics\|home\|rpc\|settings\|storage\|vanitygen\)\(.*\)$' -> '<PROJECT_ROOT>/packages/app-\1/src\2'
|
||||
module.name_mapper='^@polkadot/app-\(accounts\|addresses\|explorer\|extrinsics\|home\|rpc\|settings\|storage\|toolbox\|vanitygen\)\(.*\)$' -> '<PROJECT_ROOT>/packages/app-\1/src\2'
|
||||
module.name_mapper='^@polkadot/apps\(.*\)$' -> '<PROJECT_ROOT>/packages/apps/src\1'
|
||||
module.name_mapper='^@polkadot/ui-\(app\|keyring\)\(.*\)$' -> '<PROJECT_ROOT>/packages/ui-\1/src\2'
|
||||
|
||||
@ -1,3 +1,3 @@
|
||||
{
|
||||
"extends": "@polkadot/dev/config/stylelint"
|
||||
"extends": "@polkadot/dev-react/config/stylelint"
|
||||
}
|
||||
|
||||
@ -1,5 +0,0 @@
|
||||
// @flow
|
||||
|
||||
declare module 'i18next-browser-languagedetector' {
|
||||
declare module.exports: {}
|
||||
}
|
||||
5
flow-typed/i18next-xhr-backend.js
vendored
5
flow-typed/i18next-xhr-backend.js
vendored
@ -1,5 +0,0 @@
|
||||
// @flow
|
||||
|
||||
declare module 'i18next-xhr-backend' {
|
||||
declare module.exports: {}
|
||||
}
|
||||
23
flow-typed/i18next.js
vendored
23
flow-typed/i18next.js
vendored
@ -1,23 +0,0 @@
|
||||
// @flow
|
||||
|
||||
declare type I18Next$Config = {
|
||||
fallbackLng?: string,
|
||||
ns?: Array<string>,
|
||||
defaultNS?: string,
|
||||
debug?: boolean,
|
||||
interpolation?: {
|
||||
escapeValue: boolean
|
||||
},
|
||||
react?: {
|
||||
wait: boolean
|
||||
}
|
||||
};
|
||||
|
||||
declare module 'i18next' {
|
||||
declare type I18Next = {
|
||||
use: (any) => I18Next,
|
||||
init: (I18Next$Config) => I18Next
|
||||
};
|
||||
|
||||
declare module.exports: I18Next
|
||||
}
|
||||
5
flow-typed/react-copy-to-clipboard.js
vendored
5
flow-typed/react-copy-to-clipboard.js
vendored
@ -1,5 +0,0 @@
|
||||
// @flow
|
||||
|
||||
declare module 'react-copy-to-clipboard' {
|
||||
declare module.exports: React$ComponentType<{ text?: string }>;
|
||||
}
|
||||
6
flow-typed/react-dropzone.js
vendored
6
flow-typed/react-dropzone.js
vendored
@ -1,6 +0,0 @@
|
||||
// @flow
|
||||
|
||||
declare module 'react-dropzone' {
|
||||
declare type Dropzone = React$StatelessFunctionalComponent<*>;
|
||||
declare module.exports: Dropzone;
|
||||
}
|
||||
19
flow-typed/react-i18next.js
vendored
19
flow-typed/react-i18next.js
vendored
@ -1,19 +0,0 @@
|
||||
// @flow
|
||||
|
||||
declare type I18Next$Translate$Config = {
|
||||
defaultValue: string,
|
||||
replace?: {
|
||||
[string]: any
|
||||
}
|
||||
};
|
||||
|
||||
declare type I18Next$Translate = (key: string, config: I18Next$Translate$Config) => string;
|
||||
|
||||
declare module 'react-i18next' {
|
||||
declare module.exports: {
|
||||
I18nextProvider: React$StatelessFunctionalComponent<*>,
|
||||
Trans: React$StatelessFunctionalComponent<*>,
|
||||
reactI18nextModule: {},
|
||||
translate: (context: string | Array<string>) => (Component: React$ComponentType<*>) => React$StatelessFunctionalComponent<*>
|
||||
}
|
||||
}
|
||||
5
flow-typed/react-remarkable.js
vendored
5
flow-typed/react-remarkable.js
vendored
@ -1,5 +0,0 @@
|
||||
// @flow
|
||||
|
||||
declare module 'react-remarkable' {
|
||||
declare module.exports: React$StatelessFunctionalComponent<*>
|
||||
}
|
||||
7
flow-typed/react-router.js
vendored
7
flow-typed/react-router.js
vendored
@ -1,7 +0,0 @@
|
||||
// @flow
|
||||
|
||||
declare module 'react-router' {
|
||||
declare module.exports: {
|
||||
withRouter: (Component: React$ComponentType<*>) => React$StatelessFunctionalComponent<*>;
|
||||
}
|
||||
}
|
||||
@ -1 +1 @@
|
||||
module.exports = require('@polkadot/dev/config/jest');
|
||||
module.exports = require('@polkadot/dev-react/config/jest');
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
{
|
||||
"lerna": "2.5.1",
|
||||
"lerna": "2.11.0",
|
||||
"npmClient": "yarn",
|
||||
"useWorkspaces": true,
|
||||
"command": {
|
||||
@ -10,5 +10,5 @@
|
||||
"packages": [
|
||||
"packages/*"
|
||||
],
|
||||
"version": "0.4.12"
|
||||
"version": "0.5.0"
|
||||
}
|
||||
|
||||
@ -9,16 +9,15 @@
|
||||
"build": "polkadot-dev-build-babel && yarn run build:apps",
|
||||
"build:apps": "cd packages/apps && react-scripts build",
|
||||
"check": "eslint packages && flow check",
|
||||
"clean": "polkadot-dev-clean-build",
|
||||
"deploy:ghpages": "gh-pages -d packages/apps/build",
|
||||
"vanitygen": "polkadot-dev-build-babel && node packages/app-vanitygen/build/generator/cli.js",
|
||||
"start": "cd packages/apps && react-scripts start",
|
||||
"test": "echo 'no tests executed'"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@polkadot/dev": "^0.17.13",
|
||||
"babel-preset-react": "^6.24.1",
|
||||
"@polkadot/dev-react": "^0.18.3",
|
||||
"gh-pages": "^1.1.0",
|
||||
"lerna": "^2.5.1",
|
||||
"react-scripts": "2.0.0-next.66cc7a90"
|
||||
},
|
||||
"browserslist": {
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@polkadot/app-accounts",
|
||||
"version": "0.4.12",
|
||||
"version": "0.5.0",
|
||||
"main": "index.js",
|
||||
"repository": "https://github.com/polkadot-js/apps.git",
|
||||
"author": "Jaco Greeff <jacogr@gmail.com>",
|
||||
@ -11,6 +11,6 @@
|
||||
"test": "jest --coverage"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@polkadot/ui-app": "^0.4.12"
|
||||
"@polkadot/ui-app": "^0.5.0"
|
||||
}
|
||||
}
|
||||
|
||||
@ -8,6 +8,7 @@ import type { BareProps } from '@polkadot/ui-app/types';
|
||||
import React from 'react';
|
||||
|
||||
import CopyButton from '@polkadot/ui-app/src/CopyButton';
|
||||
import classes from '@polkadot/ui-app/src/util/classes';
|
||||
import IdentityIcon from '@polkadot/ui-react/IdentityIcon';
|
||||
import Balance from '@polkadot/ui-react-rx/Balance';
|
||||
import Nonce from '@polkadot/ui-react-rx/Nonce';
|
||||
@ -58,7 +59,7 @@ export default class Address extends React.PureComponent<Props, State> {
|
||||
|
||||
return (
|
||||
<div
|
||||
className={['accounts--Address', isValid ? '' : 'invalid', className].join(' ')}
|
||||
className={classes('accounts--Address', isValid && 'invalid', className)}
|
||||
style={style}
|
||||
>
|
||||
<IdentityIcon
|
||||
|
||||
@ -10,6 +10,7 @@ import React from 'react';
|
||||
import Button from '@polkadot/ui-app/src/Button';
|
||||
import Input from '@polkadot/ui-app/src/Input';
|
||||
import Password from '@polkadot/ui-app/src/Password';
|
||||
import classes from '@polkadot/ui-app/src/util/classes';
|
||||
import keyring from '@polkadot/ui-keyring/src';
|
||||
import isHex from '@polkadot/util/is/hex';
|
||||
import hexToU8a from '@polkadot/util/hex/toU8a';
|
||||
@ -66,7 +67,7 @@ class Creator extends React.PureComponent<Props, State> {
|
||||
|
||||
return (
|
||||
<div
|
||||
className={['accounts--Creator', className].join(' ')}
|
||||
className={classes('accounts--Creator', className)}
|
||||
style={style}
|
||||
>
|
||||
<div className='ui--grid'>
|
||||
|
||||
@ -11,6 +11,7 @@ import React from 'react';
|
||||
import Button from '@polkadot/ui-app/src/Button';
|
||||
import Input from '@polkadot/ui-app/src/Input';
|
||||
import InputAddress from '@polkadot/ui-app/src/InputAddress';
|
||||
import classes from '@polkadot/ui-app/src/util/classes';
|
||||
import keyring from '@polkadot/ui-keyring/src';
|
||||
|
||||
import Address from './Address';
|
||||
@ -49,7 +50,7 @@ class Editor extends React.PureComponent<Props, State> {
|
||||
if (!currentPair) {
|
||||
return (
|
||||
<div
|
||||
className={['accounts--Editor', className].join(' ')}
|
||||
className={classes('accounts--Editor', className)}
|
||||
style={style}
|
||||
>
|
||||
{t('editor.none', {
|
||||
@ -63,7 +64,7 @@ class Editor extends React.PureComponent<Props, State> {
|
||||
|
||||
return (
|
||||
<div
|
||||
className={['accounts--Editor', className].join(' ')}
|
||||
className={classes('accounts--Editor', className)}
|
||||
style={style}
|
||||
>
|
||||
<div className='ui--grid'>
|
||||
@ -77,7 +78,7 @@ class Editor extends React.PureComponent<Props, State> {
|
||||
className='full'
|
||||
defaultValue={defaultPublicKey}
|
||||
hideAddress
|
||||
isSUIInput={false}
|
||||
isInput={false}
|
||||
label={t('editor.select', {
|
||||
defaultValue: 'using my account'
|
||||
})}
|
||||
|
||||
@ -12,6 +12,7 @@
|
||||
}
|
||||
|
||||
.accounts--Address {
|
||||
padding: 0 2em;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
@ -39,7 +40,7 @@
|
||||
}
|
||||
|
||||
.accounts--Address-data {
|
||||
padding: 0.5em 2em;
|
||||
padding: 0.5em 0;
|
||||
}
|
||||
|
||||
.accounts--Address-data * {
|
||||
|
||||
@ -10,6 +10,7 @@ import './index.css';
|
||||
import React from 'react';
|
||||
|
||||
import Button from '@polkadot/ui-app/src/Button';
|
||||
import classes from '@polkadot/ui-app/src/util/classes';
|
||||
|
||||
import Creator from './Creator';
|
||||
import Editor from './Editor';
|
||||
@ -24,7 +25,8 @@ type State = {
|
||||
}
|
||||
|
||||
// FIXME React-router would probably be the best route, not home-grown
|
||||
const Components: { [Actions]: React$ComponentType<*> } = {
|
||||
// flowlint-next-line unclear-type:off
|
||||
const Components: { [Actions]: React$ComponentType<any> } = {
|
||||
'create': Creator,
|
||||
'edit': Editor
|
||||
};
|
||||
@ -39,7 +41,7 @@ class App extends React.PureComponent<Props, State> {
|
||||
|
||||
return (
|
||||
<div
|
||||
className={['accounts--App', className].join(' ')}
|
||||
className={classes('accounts--App', className)}
|
||||
style={style}
|
||||
>
|
||||
<Button.Group className='accounts--App-navigation'>
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@polkadot/app-addresses",
|
||||
"version": "0.4.12",
|
||||
"version": "0.5.0",
|
||||
"main": "index.js",
|
||||
"repository": "https://github.com/polkadot-js/apps.git",
|
||||
"author": "Jaco Greeff <jacogr@gmail.com>",
|
||||
@ -11,7 +11,7 @@
|
||||
"test": "jest --coverage"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@polkadot/app-accounts": "^0.4.12",
|
||||
"@polkadot/ui-app": "^0.4.12"
|
||||
"@polkadot/app-accounts": "^0.5.0",
|
||||
"@polkadot/ui-app": "^0.5.0"
|
||||
}
|
||||
}
|
||||
|
||||
@ -9,6 +9,7 @@ import React from 'react';
|
||||
|
||||
import Button from '@polkadot/ui-app/src/Button';
|
||||
import Input from '@polkadot/ui-app/src/Input';
|
||||
import classes from '@polkadot/ui-app/src/util/classes';
|
||||
import keyring from '@polkadot/ui-keyring/src';
|
||||
import addressDecode from '@polkadot/util-keyring/address/decode';
|
||||
import addressEncode from '@polkadot/util-keyring/address/encode';
|
||||
@ -43,7 +44,7 @@ class Creator extends React.PureComponent<Props, State> {
|
||||
|
||||
return (
|
||||
<div
|
||||
className={['addresses--Creator', className].join(' ')}
|
||||
className={classes('addresses--Creator', className)}
|
||||
style={style}
|
||||
>
|
||||
<div className='ui--grid'>
|
||||
|
||||
@ -11,6 +11,7 @@ import React from 'react';
|
||||
import Button from '@polkadot/ui-app/src/Button';
|
||||
import Input from '@polkadot/ui-app/src/Input';
|
||||
import InputAddress from '@polkadot/ui-app/src/InputAddress';
|
||||
import classes from '@polkadot/ui-app/src/util/classes';
|
||||
import keyring from '@polkadot/ui-keyring/src';
|
||||
|
||||
import Address from '@polkadot/app-accounts/src/Address';
|
||||
@ -50,7 +51,7 @@ class Editor extends React.PureComponent<Props, State> {
|
||||
if (!currentAddress) {
|
||||
return (
|
||||
<div
|
||||
className={['addresses--Editor', className].join(' ')}
|
||||
className={classes('addresses--Editor', className)}
|
||||
style={style}
|
||||
>
|
||||
{t('editor.none', {
|
||||
@ -64,7 +65,7 @@ class Editor extends React.PureComponent<Props, State> {
|
||||
|
||||
return (
|
||||
<div
|
||||
className={['addresses--Editor', className].join(' ')}
|
||||
className={classes('addresses--Editor', className)}
|
||||
style={style}
|
||||
>
|
||||
<div className='ui--grid'>
|
||||
|
||||
@ -10,6 +10,7 @@ import './index.css';
|
||||
import React from 'react';
|
||||
|
||||
import Button from '@polkadot/ui-app/src/Button';
|
||||
import classes from '@polkadot/ui-app/src/util/classes';
|
||||
|
||||
import Creator from './Creator';
|
||||
import Editor from './Editor';
|
||||
@ -24,7 +25,8 @@ type State = {
|
||||
}
|
||||
|
||||
// FIXME React-router would probably be the best route, not home-grown
|
||||
const Components: { [Actions]: React$ComponentType<*> } = {
|
||||
// flowlint-next-line unclear-type:off
|
||||
const Components: { [Actions]: React$ComponentType<any> } = {
|
||||
'create': Creator,
|
||||
'edit': Editor
|
||||
};
|
||||
@ -39,7 +41,7 @@ class App extends React.PureComponent<Props, State> {
|
||||
|
||||
return (
|
||||
<div
|
||||
className={['addresses--App', className].join(' ')}
|
||||
className={classes('addresses--App', className)}
|
||||
style={style}
|
||||
>
|
||||
<Button.Group className='addresses--App-navigation'>
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@polkadot/app-explorer",
|
||||
"version": "0.4.12",
|
||||
"version": "0.5.0",
|
||||
"main": "index.js",
|
||||
"repository": "https://github.com/polkadot-js/apps.git",
|
||||
"author": "Jaco Greeff <jacogr@gmail.com>",
|
||||
@ -11,10 +11,10 @@
|
||||
"test": "jest --coverage"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@polkadot/primitives": "^0.13.8",
|
||||
"@polkadot/primitives-codec": "^0.13.8",
|
||||
"@polkadot/primitives-json": "^0.13.8",
|
||||
"@polkadot/ui-app": "^0.4.12",
|
||||
"@polkadot/util-crypto": "^0.19.6"
|
||||
"@polkadot/primitives": "^0.13.10",
|
||||
"@polkadot/primitives-codec": "^0.13.10",
|
||||
"@polkadot/primitives-json": "^0.13.10",
|
||||
"@polkadot/ui-app": "^0.5.0",
|
||||
"@polkadot/util-crypto": "^0.19.7"
|
||||
}
|
||||
}
|
||||
|
||||
@ -11,6 +11,7 @@ import './BlockHeader.css';
|
||||
import React from 'react';
|
||||
|
||||
import headerHash from '@polkadot/primitives-codec/header/hash';
|
||||
import classes from '@polkadot/ui-app/src/util/classes';
|
||||
import u8aToHex from '@polkadot/util/u8a/toHex';
|
||||
|
||||
import translate from '../translate';
|
||||
@ -30,7 +31,7 @@ function BlockHeader ({ className, label = '#', value, style }: Props): React$No
|
||||
|
||||
return (
|
||||
<div
|
||||
className={['explorer--BlockHeader', className].join(' ')}
|
||||
className={classes('explorer--BlockHeader', className)}
|
||||
style={style}
|
||||
>
|
||||
<div className='number'>
|
||||
|
||||
@ -9,6 +9,7 @@ import './index.css';
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import classes from '@polkadot/ui-app/src/util/classes';
|
||||
import BestNumber from '@polkadot/ui-react-rx/BestNumber';
|
||||
|
||||
import BestHash from './BestHash';
|
||||
@ -20,7 +21,7 @@ type Props = I18nProps & {};
|
||||
function App ({ className, style, t }: Props): React$Node {
|
||||
return (
|
||||
<div
|
||||
className={['explorer--App', className].join(' ')}
|
||||
className={classes('explorer--App', className)}
|
||||
style={style}
|
||||
>
|
||||
<BestNumber
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@polkadot/app-extrinsics",
|
||||
"version": "0.4.12",
|
||||
"version": "0.5.0",
|
||||
"main": "index.js",
|
||||
"repository": "https://github.com/polkadot-js/apps.git",
|
||||
"author": "Jaco Greeff <jacogr@gmail.com>",
|
||||
@ -11,9 +11,9 @@
|
||||
"test": "jest --coverage"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@polkadot/extrinsics": "^0.13.8",
|
||||
"@polkadot/extrinsics-codec": "^0.13.8",
|
||||
"@polkadot/ui-app": "^0.4.12",
|
||||
"@polkadot/extrinsics": "^0.13.10",
|
||||
"@polkadot/extrinsics-codec": "^0.13.10",
|
||||
"@polkadot/ui-app": "^0.5.0",
|
||||
"react-dropzone": "^4.2.9"
|
||||
}
|
||||
}
|
||||
|
||||
@ -10,6 +10,7 @@ import React from 'react';
|
||||
|
||||
import InputAddress from '@polkadot/ui-app/src/InputAddress';
|
||||
import Labelled from '@polkadot/ui-app/src/Labelled';
|
||||
import classes from '@polkadot/ui-app/src/util/classes';
|
||||
import Balance from '@polkadot/ui-react-rx/Balance';
|
||||
|
||||
import translate from './translate';
|
||||
@ -45,7 +46,7 @@ class Account extends React.PureComponent<Props, State> {
|
||||
|
||||
return (
|
||||
<div
|
||||
className={['extrinsics--Account', 'ui--row', className].join(' ')}
|
||||
className={classes('extrinsics--Account', 'ui--row', className)}
|
||||
style={style}
|
||||
>
|
||||
<div className='large'>
|
||||
|
||||
@ -13,6 +13,7 @@ import React from 'react';
|
||||
import encode from '@polkadot/extrinsics-codec/encode/extrinsic';
|
||||
import InputExtrinsic from '@polkadot/ui-app/src/InputExtrinsic';
|
||||
import Params from '@polkadot/ui-app/src/Params';
|
||||
import classes from '@polkadot/ui-app/src/util/classes';
|
||||
import isUndefined from '@polkadot/util/is/undefined';
|
||||
|
||||
import paramComponents from './Params';
|
||||
@ -48,7 +49,7 @@ export default class ExtrinsicDisplay extends React.PureComponent<Props, State>
|
||||
|
||||
return (
|
||||
<div
|
||||
className={['extrinsics--Extrinsic', className].join(' ')}
|
||||
className={classes('extrinsics--Extrinsic', className)}
|
||||
style={style}
|
||||
>
|
||||
<InputExtrinsic
|
||||
|
||||
@ -9,6 +9,7 @@ import type { BareProps } from '@polkadot/ui-app/types';
|
||||
import React from 'react';
|
||||
|
||||
import Labelled from '@polkadot/ui-app/src/Labelled';
|
||||
import classes from '@polkadot/ui-app/src/util/classes';
|
||||
import RxNonce from '@polkadot/ui-react-rx/Nonce';
|
||||
|
||||
type Props = BareProps & {
|
||||
@ -20,7 +21,7 @@ type Props = BareProps & {
|
||||
export default function Nonce ({ className, label, style, onChange, value }: Props): React$Node {
|
||||
return (
|
||||
<div
|
||||
className={['ui--row', className].join(' ')}
|
||||
className={classes('ui--row', className)}
|
||||
style={style}
|
||||
>
|
||||
<Labelled
|
||||
|
||||
@ -11,6 +11,7 @@ import React from 'react';
|
||||
|
||||
import extrinsics from '@polkadot/extrinsics-substrate';
|
||||
import Button from '@polkadot/ui-app/src/Button';
|
||||
import classes from '@polkadot/ui-app/src/util/classes';
|
||||
|
||||
import Account from './Account';
|
||||
import Extrinsic from './Extrinsic';
|
||||
@ -43,7 +44,7 @@ class Selection extends React.PureComponent<Props, State> {
|
||||
|
||||
return (
|
||||
<div
|
||||
className={['extrinsics--Selection', className].join(' ')}
|
||||
className={classes('extrinsics--Selection', className)}
|
||||
style={style}
|
||||
>
|
||||
<Account
|
||||
|
||||
@ -10,6 +10,7 @@ import BN from 'bn.js';
|
||||
import React from 'react';
|
||||
import { Trans } from 'react-i18next';
|
||||
|
||||
import classes from '@polkadot/ui-app/src/util/classes';
|
||||
import IdentityIcon from '@polkadot/ui-react/IdentityIcon';
|
||||
import u8aToHexShort from '@polkadot/util/u8a/toHexShort';
|
||||
import addressEncode from '@polkadot/util-keyring/address/encode';
|
||||
@ -25,7 +26,7 @@ function Decoded ({ className, style, t, value: { extrinsic: { name, section },
|
||||
|
||||
return (
|
||||
<div
|
||||
className={['extrinsics--Signer-Decoded', className].join(' ')}
|
||||
className={classes('extrinsics--Signer-Decoded', className)}
|
||||
style={style}
|
||||
>
|
||||
<div className='expanded'>
|
||||
|
||||
@ -9,6 +9,7 @@ import type { KeyringPair } from '@polkadot/util-keyring/types';
|
||||
import React from 'react';
|
||||
|
||||
import Password from '@polkadot/ui-app/src/Password';
|
||||
import classes from '@polkadot/ui-app/src/util/classes';
|
||||
import keyring from '@polkadot/ui-keyring/src';
|
||||
|
||||
import translate from '../translate';
|
||||
@ -51,7 +52,7 @@ class Unlock extends React.PureComponent<Props, State> {
|
||||
|
||||
return (
|
||||
<div
|
||||
className={['extrinsics--Signer-Unlock', className].join(' ')}
|
||||
className={classes('extrinsics--Signer-Unlock', className)}
|
||||
style={style}
|
||||
>
|
||||
<div className='ui--row'>
|
||||
|
||||
@ -13,6 +13,7 @@ import React from 'react';
|
||||
|
||||
import Button from '@polkadot/ui-app/src/Button';
|
||||
import Modal from '@polkadot/ui-app/src/Modal';
|
||||
import classes from '@polkadot/ui-app/src/util/classes';
|
||||
import keyring from '@polkadot/ui-keyring/src';
|
||||
import withApi from '@polkadot/ui-react-rx/with/api';
|
||||
|
||||
@ -69,7 +70,7 @@ class Signer extends React.PureComponent<Props, State> {
|
||||
|
||||
return (
|
||||
<Modal
|
||||
className={['extrinsics--Signer', className].join(' ')}
|
||||
className={classes('extrinsics--Signer', className)}
|
||||
dimmer='inverted'
|
||||
open
|
||||
style={style}
|
||||
|
||||
@ -8,6 +8,8 @@ import type { QueueTx } from './types';
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import classes from '@polkadot/ui-app/src/util/classes';
|
||||
|
||||
type Props = BareProps & {
|
||||
queue: Array<QueueTx>
|
||||
}
|
||||
@ -23,12 +25,12 @@ export default function Status ({ className, queue, style }: Props): React$Node
|
||||
|
||||
return (
|
||||
<div
|
||||
className={['extrinsics--Status', className].join(' ')}
|
||||
className={classes('extrinsics--Status', className)}
|
||||
style={style}
|
||||
>
|
||||
{available.map(({ extrinsic: { name, section }, id, status }) =>
|
||||
<div
|
||||
className={['extrinsics--Status-Item', status].join(' ')}
|
||||
className={classes('extrinsics--Status-Item', status)}
|
||||
key={id}
|
||||
>
|
||||
<div className='header'>
|
||||
|
||||
@ -10,6 +10,8 @@ import './index.css';
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import classes from '@polkadot/ui-app/src/util/classes';
|
||||
|
||||
import Selection from './Selection';
|
||||
import Signer from './Signer';
|
||||
import Status from './Status';
|
||||
@ -31,7 +33,7 @@ export default class App extends React.PureComponent<Props, State> {
|
||||
|
||||
return (
|
||||
<div
|
||||
className={['extrinsics--App', className].join(' ')}
|
||||
className={classes('extrinsics--App', className)}
|
||||
style={style}
|
||||
>
|
||||
<Selection onQueue={this.onQueue} />
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@polkadot/app-storage",
|
||||
"version": "0.4.12",
|
||||
"version": "0.5.0",
|
||||
"main": "index.js",
|
||||
"repository": "https://github.com/polkadot-js/apps.git",
|
||||
"author": "Jaco Greeff <jacogr@gmail.com>",
|
||||
@ -11,6 +11,6 @@
|
||||
"test": "jest --coverage"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@polkadot/ui-app": "^0.4.12"
|
||||
"@polkadot/ui-app": "^0.5.0"
|
||||
}
|
||||
}
|
||||
|
||||
@ -8,6 +8,8 @@ import type { StorageQuery } from './types';
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import classes from '@polkadot/ui-app/src/util/classes';
|
||||
|
||||
import translate from './translate';
|
||||
import Query from './Query';
|
||||
|
||||
@ -23,7 +25,7 @@ function Queries ({ className, onRemove, style, value }: Props): React$Node {
|
||||
|
||||
return (
|
||||
<div
|
||||
className={['storage--Queries', className].join(' ')}
|
||||
className={classes('storage--Queries', className)}
|
||||
style={style}
|
||||
>
|
||||
{value.map((query) =>
|
||||
|
||||
@ -12,6 +12,7 @@ import Button from '@polkadot/ui-app/src/Button';
|
||||
import Labelled from '@polkadot/ui-app/src/Labelled';
|
||||
import typeToText from '@polkadot/ui-app/src/Params/typeToText';
|
||||
import valueToText from '@polkadot/ui-app/src/Params/valueToText';
|
||||
import classes from '@polkadot/ui-app/src/util/classes';
|
||||
import withStorageDiv from '@polkadot/ui-react-rx/with/storageDiv';
|
||||
|
||||
import translate from './translate';
|
||||
@ -23,7 +24,8 @@ type Props = I18nProps & {
|
||||
|
||||
type State = {
|
||||
inputs: Array<React$Node>,
|
||||
Component: React$ComponentType<*>;
|
||||
// flowlint-next-line unclear-type:off
|
||||
Component: React$ComponentType<any>;
|
||||
};
|
||||
|
||||
const cache = [];
|
||||
@ -32,14 +34,15 @@ class Query extends React.PureComponent<Props, State> {
|
||||
state: State = ({}: $Shape<State>);
|
||||
|
||||
static getDerivedStateFromProps ({ value: { id, key, params } }: Props, prevState: State): State | null {
|
||||
const Component = ((): React$ComponentType<*> => {
|
||||
// flowlint-next-line unclear-type:off
|
||||
const Component = ((): React$ComponentType<any> => {
|
||||
if (!cache[id]) {
|
||||
const values = params.map(({ value }) => value);
|
||||
|
||||
cache[id] = withStorageDiv(key, { params: values })(
|
||||
(value) =>
|
||||
valueToText(key.type, value),
|
||||
{ className: 'ui disabled dropdown selection' }
|
||||
{ className: 'ui--output' }
|
||||
);
|
||||
}
|
||||
|
||||
@ -67,7 +70,7 @@ class Query extends React.PureComponent<Props, State> {
|
||||
|
||||
return (
|
||||
<div
|
||||
className={['storage--Query', 'storage--actionrow', className].join(' ')}
|
||||
className={classes('storage--Query', 'storage--actionrow', className)}
|
||||
style={style}
|
||||
>
|
||||
<Labelled
|
||||
|
||||
@ -15,6 +15,7 @@ import Button from '@polkadot/ui-app/src/Button';
|
||||
import InputStorage from '@polkadot/ui-app/src/InputStorage';
|
||||
import Labelled from '@polkadot/ui-app/src/Labelled';
|
||||
import Params from '@polkadot/ui-app/src/Params';
|
||||
import classes from '@polkadot/ui-app/src/util/classes';
|
||||
import isUndefined from '@polkadot/util/is/undefined';
|
||||
|
||||
import translate from './translate';
|
||||
@ -44,7 +45,7 @@ class Selection extends React.PureComponent<Props, State> {
|
||||
|
||||
return (
|
||||
<div
|
||||
className={['storage--Selection', 'storage--actionrow', className].join(' ')}
|
||||
className={classes('storage--Selection', 'storage--actionrow', className)}
|
||||
style={style}
|
||||
>
|
||||
<div className='storage--actionrow-value'>
|
||||
|
||||
@ -10,6 +10,8 @@ import './index.css';
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import classes from '@polkadot/ui-app/src/util/classes';
|
||||
|
||||
import Queries from './Queries';
|
||||
import Selection from './Selection';
|
||||
import translate from './translate';
|
||||
@ -31,7 +33,7 @@ class App extends React.PureComponent<Props, State> {
|
||||
|
||||
return (
|
||||
<div
|
||||
className={['storage--App', className].join(' ')}
|
||||
className={classes('storage--App', className)}
|
||||
style={style}
|
||||
>
|
||||
<Selection onAdd={this.onAdd} />
|
||||
|
||||
@ -8,5 +8,6 @@ import type { StorageDef$Key } from '@polkadot/storage/types';
|
||||
export type StorageQuery = {
|
||||
id: number,
|
||||
key: StorageDef$Key,
|
||||
params: Array<*>
|
||||
// flowlint-next-line unclear-type:off
|
||||
params: Array<any>
|
||||
}
|
||||
|
||||
15
packages/app-toolbox/LICENSE
Normal file
15
packages/app-toolbox/LICENSE
Normal file
@ -0,0 +1,15 @@
|
||||
ISC License (ISC)
|
||||
|
||||
Copyright 2017-2018 Jaco Greeff <jacogr@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
||||
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
PERFORMANCE OF THIS SOFTWARE.
|
||||
1
packages/app-toolbox/README.md
Normal file
1
packages/app-toolbox/README.md
Normal file
@ -0,0 +1 @@
|
||||
# @polkadot/app-toolbox
|
||||
17
packages/app-toolbox/package.json
Normal file
17
packages/app-toolbox/package.json
Normal file
@ -0,0 +1,17 @@
|
||||
{
|
||||
"name": "@polkadot/app-toolbox",
|
||||
"version": "0.5.0",
|
||||
"main": "index.js",
|
||||
"repository": "https://github.com/polkadot-js/apps.git",
|
||||
"author": "Jaco Greeff <jacogr@gmail.com>",
|
||||
"license": "ISC",
|
||||
"scripts": {
|
||||
"build": "polkadot-dev-build-babel",
|
||||
"check": "stylelint 'src/**/*.css' && eslint src && flow check",
|
||||
"test": "jest --coverage"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@polkadot/ui-app": "^0.5.0",
|
||||
"@polkadot/ui-keyring": "^0.5.0"
|
||||
}
|
||||
}
|
||||
95
packages/app-toolbox/src/Hash.js
Normal file
95
packages/app-toolbox/src/Hash.js
Normal file
@ -0,0 +1,95 @@
|
||||
// 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 as Props } from '@polkadot/ui-app/types';
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import Input from '@polkadot/ui-app/src/Input';
|
||||
import Output from '@polkadot/ui-app/src/Output';
|
||||
import Static from '@polkadot/ui-app/src/Static';
|
||||
import classes from '@polkadot/ui-app/src/util/classes';
|
||||
import hexToU8a from '@polkadot/util/hex/toU8a';
|
||||
import isHex from '@polkadot/util/is/hex';
|
||||
import u8aFromString from '@polkadot/util/u8a/fromString';
|
||||
import xxhashAsHex256 from '@polkadot/util-crypto/xxhash/asHex256';
|
||||
|
||||
import translate from './translate';
|
||||
|
||||
type State = {
|
||||
data: string,
|
||||
hash: string,
|
||||
isHexData: boolean
|
||||
};
|
||||
|
||||
class Hash extends React.PureComponent<Props, State> {
|
||||
state: State = {
|
||||
data: '',
|
||||
hash: xxhashAsHex256(u8aFromString('')),
|
||||
isHexData: false
|
||||
};
|
||||
|
||||
render (): React$Node {
|
||||
const { className, style, t } = this.props;
|
||||
const { data, hash, isHexData } = this.state;
|
||||
|
||||
return (
|
||||
<div
|
||||
className={classes('toolbox--Hash', className)}
|
||||
style={style}
|
||||
>
|
||||
<div className='ui--row'>
|
||||
<Input
|
||||
className='large'
|
||||
label={t('hash.data', {
|
||||
defaultValue: 'from the following data (hex or string)'
|
||||
})}
|
||||
onChange={this.onChangeData}
|
||||
value={data}
|
||||
/>
|
||||
<Static
|
||||
className='small'
|
||||
label={t('hash.isHex', {
|
||||
defaultValue: 'hex input data'
|
||||
})}
|
||||
value={
|
||||
isHexData
|
||||
? t('hash.isHex.yes', {
|
||||
defaultValue: 'Yes'
|
||||
})
|
||||
: t('hash.isHex.no', {
|
||||
defaultValue: 'No'
|
||||
})
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
<div className='ui--row'>
|
||||
<Output
|
||||
className='full toolbox--hex'
|
||||
isHidden={hash.length === 0}
|
||||
label={t('hash.output', {
|
||||
defaultValue: 'the resulting hash is'
|
||||
})}
|
||||
value={hash}
|
||||
withCopy
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
onChangeData = (data: string): void => {
|
||||
const isHexData = isHex(data);
|
||||
const hash = xxhashAsHex256(
|
||||
isHexData
|
||||
? hexToU8a(data)
|
||||
: u8aFromString(data)
|
||||
);
|
||||
|
||||
this.setState({ data, hash, isHexData });
|
||||
}
|
||||
}
|
||||
|
||||
export default translate(Hash);
|
||||
194
packages/app-toolbox/src/Sign.js
Normal file
194
packages/app-toolbox/src/Sign.js
Normal file
@ -0,0 +1,194 @@
|
||||
// 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 as Props } from '@polkadot/ui-app/types';
|
||||
import type { KeyringPair } from '@polkadot/util-keyring/types';
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import Button from '@polkadot/ui-app/src/Button';
|
||||
import Input from '@polkadot/ui-app/src/Input';
|
||||
import InputAddress from '@polkadot/ui-app/src/InputAddress';
|
||||
import Output from '@polkadot/ui-app/src/Output';
|
||||
import Static from '@polkadot/ui-app/src/Static';
|
||||
import classes from '@polkadot/ui-app/src/util/classes';
|
||||
import keyring from '@polkadot/ui-keyring/src';
|
||||
import hexToU8a from '@polkadot/util/hex/toU8a';
|
||||
import isHex from '@polkadot/util/is/hex';
|
||||
import u8aFromString from '@polkadot/util/u8a/fromString';
|
||||
import u8aToHex from '@polkadot/util/u8a/toHex';
|
||||
|
||||
import Unlock from './Unlock';
|
||||
import translate from './translate';
|
||||
|
||||
type State = {
|
||||
currentPair: KeyringPair | null,
|
||||
defaultPublicKey?: Uint8Array,
|
||||
data: string,
|
||||
isHexData: boolean,
|
||||
isLocked: boolean,
|
||||
isUnlockVisible: boolean,
|
||||
signature: string
|
||||
};
|
||||
|
||||
class Sign extends React.PureComponent<Props, State> {
|
||||
state: State;
|
||||
|
||||
constructor (props: Props) {
|
||||
super(props);
|
||||
|
||||
const pairs = keyring.getPairs();
|
||||
const currentPair = pairs[0] || null;
|
||||
|
||||
this.state = {
|
||||
currentPair,
|
||||
defaultPublicKey: currentPair
|
||||
? currentPair.publicKey()
|
||||
: void 0,
|
||||
data: '',
|
||||
isHexData: false,
|
||||
isLocked: currentPair
|
||||
? !currentPair.hasSecretKey()
|
||||
: false,
|
||||
isUnlockVisible: false,
|
||||
signature: ''
|
||||
};
|
||||
}
|
||||
|
||||
render (): React$Node {
|
||||
const { className, style, t } = this.props;
|
||||
const { currentPair, data, defaultPublicKey, isHexData, isLocked, isUnlockVisible, signature } = this.state;
|
||||
|
||||
return (
|
||||
<div
|
||||
className={classes('toolbox--Sign', className)}
|
||||
style={style}
|
||||
>
|
||||
<div className='ui--row'>
|
||||
<InputAddress
|
||||
className='full'
|
||||
defaultValue={defaultPublicKey}
|
||||
isInput={false}
|
||||
label={t('sign.account', {
|
||||
defaultValue: 'using my account'
|
||||
})}
|
||||
onChange={this.onChangeAccount}
|
||||
type='account'
|
||||
/>
|
||||
</div>
|
||||
<div className='ui--row'>
|
||||
<Input
|
||||
className='large'
|
||||
label={t('sign.data', {
|
||||
defaultValue: 'sign the following data (hex or string)'
|
||||
})}
|
||||
onChange={this.onChangeData}
|
||||
value={data}
|
||||
/>
|
||||
<Static
|
||||
className='small'
|
||||
label={t('sign.isHex', {
|
||||
defaultValue: 'hex input data'
|
||||
})}
|
||||
value={
|
||||
isHexData
|
||||
? t('sign.isHex.yes', {
|
||||
defaultValue: 'Yes'
|
||||
})
|
||||
: t('sign.isHex.no', {
|
||||
defaultValue: 'No'
|
||||
})
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
<div className='ui--row'>
|
||||
<Output
|
||||
className='full toolbox--hex'
|
||||
isHidden={signature.length === 0}
|
||||
label={t('sign.signed', {
|
||||
defaultValue: 'signature of supplied data'
|
||||
})}
|
||||
value={signature}
|
||||
withCopy
|
||||
/>
|
||||
</div>
|
||||
<Unlock
|
||||
isVisible={isUnlockVisible}
|
||||
onClose={this.toggleUnlock}
|
||||
pair={currentPair}
|
||||
/>
|
||||
{
|
||||
isLocked
|
||||
? (
|
||||
<Button.Group>
|
||||
<Button
|
||||
isPrimary
|
||||
onClick={this.toggleUnlock}
|
||||
text={t('sign.unlock', {
|
||||
defaultValue: 'Unlock account'
|
||||
})}
|
||||
/>
|
||||
</Button.Group>
|
||||
)
|
||||
: null
|
||||
}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
nextState = (newState: $Shape<State>): void => {
|
||||
this.setState(
|
||||
(prevState: State): $Shape<State> => {
|
||||
const { currentPair = prevState.currentPair, data = prevState.data, isHexData = prevState.isHexData, isUnlockVisible = prevState.isUnlockVisible } = newState;
|
||||
const isLocked = !currentPair || !currentPair.hasSecretKey();
|
||||
let signature = '';
|
||||
|
||||
if (!isLocked && currentPair) {
|
||||
signature = u8aToHex(
|
||||
currentPair.sign(
|
||||
isHexData
|
||||
? hexToU8a(data)
|
||||
: u8aFromString(data)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return {
|
||||
currentPair,
|
||||
data,
|
||||
isHexData,
|
||||
isLocked,
|
||||
isUnlockVisible,
|
||||
signature
|
||||
};
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
toggleUnlock = (): void => {
|
||||
const { isUnlockVisible } = this.state;
|
||||
|
||||
this.nextState({
|
||||
isUnlockVisible: !isUnlockVisible
|
||||
});
|
||||
}
|
||||
|
||||
onChangeAccount = (publicKey: Uint8Array): void => {
|
||||
const currentPair = keyring.getPair(publicKey);
|
||||
|
||||
this.nextState({ currentPair });
|
||||
}
|
||||
|
||||
onChangeData = (data: string): void => {
|
||||
const isHexData = isHex(data);
|
||||
|
||||
this.nextState({ data, isHexData });
|
||||
}
|
||||
|
||||
onUnlock = (): void => {
|
||||
}
|
||||
}
|
||||
|
||||
export default translate(Sign);
|
||||
182
packages/app-toolbox/src/Unlock.js
Normal file
182
packages/app-toolbox/src/Unlock.js
Normal file
@ -0,0 +1,182 @@
|
||||
// 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-app/types';
|
||||
import type { KeyringPair } from '@polkadot/util-keyring/types';
|
||||
|
||||
import React from 'react';
|
||||
import { Trans } from 'react-i18next';
|
||||
|
||||
import Button from '@polkadot/ui-app/src/Button';
|
||||
import Modal from '@polkadot/ui-app/src/Modal';
|
||||
import Password from '@polkadot/ui-app/src/Password';
|
||||
import classes from '@polkadot/ui-app/src/util/classes';
|
||||
import IdentityIcon from '@polkadot/ui-react/IdentityIcon';
|
||||
|
||||
import translate from './translate';
|
||||
|
||||
type Props = I18nProps & {
|
||||
isVisible: boolean,
|
||||
onClose: () => void,
|
||||
pair: KeyringPair
|
||||
};
|
||||
|
||||
type UnlockI18n = {
|
||||
key: string,
|
||||
value: I18Next$Translate$Config
|
||||
}
|
||||
|
||||
type State = {
|
||||
address: string,
|
||||
password: string,
|
||||
unlockError: UnlockI18n | null
|
||||
};
|
||||
|
||||
class Unlock extends React.PureComponent<Props, State> {
|
||||
state: State = {
|
||||
address: '',
|
||||
password: '',
|
||||
unlockError: null
|
||||
};
|
||||
|
||||
static getDerivedStateFromProps ({ pair }: Props, prevState: State): $Shape<State> {
|
||||
const address = pair
|
||||
? pair.address()
|
||||
: '';
|
||||
|
||||
const isSame = address !== prevState.address;
|
||||
|
||||
return {
|
||||
address,
|
||||
password: isSame
|
||||
? prevState.password
|
||||
: '',
|
||||
unlockError: isSame
|
||||
? prevState.unlockError
|
||||
: null
|
||||
};
|
||||
}
|
||||
|
||||
render (): React$Node {
|
||||
const { className, isVisible, style, t } = this.props;
|
||||
const { address, password, unlockError } = this.state;
|
||||
|
||||
if (!isVisible) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<Modal
|
||||
className={classes('toolbox--Unlock', className)}
|
||||
dimmer='inverted'
|
||||
open
|
||||
style={style}
|
||||
>
|
||||
<Modal.Header>
|
||||
{t('unlock.header', {
|
||||
defaultValue: 'Unlock account'
|
||||
})}
|
||||
</Modal.Header>
|
||||
<Modal.Content>
|
||||
<div className='toolbox--Unlock-Content'>
|
||||
<div className='expanded'>
|
||||
<p>
|
||||
<Trans i18nkey='unlock.info'>
|
||||
You are about to unlock your account <span className='code'>{address}</span> to allow for the signing of messages.
|
||||
</Trans>
|
||||
</p>
|
||||
</div>
|
||||
<IdentityIcon
|
||||
className='icon'
|
||||
value={address}
|
||||
/>
|
||||
</div>
|
||||
<div className='toolbox--Unlock-Entry'>
|
||||
<div className='ui--row'>
|
||||
<Password
|
||||
className='medium'
|
||||
isError={!!unlockError}
|
||||
label={t('unlock.password', {
|
||||
defaultValue: 'unlock account using'
|
||||
})}
|
||||
onChange={this.onChangePassword}
|
||||
value={password}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</Modal.Content>
|
||||
<Modal.Actions>
|
||||
<Button.Group>
|
||||
<Button
|
||||
isNegative
|
||||
onClick={this.onCancel}
|
||||
text={t('unlock.cancel', {
|
||||
defaultValue: 'Cancel'
|
||||
})}
|
||||
/>
|
||||
<Button.Or />
|
||||
<Button
|
||||
isPrimary
|
||||
onClick={this.onUnlock}
|
||||
text={t('unlock.doit', {
|
||||
defaultValue: 'Unlock'
|
||||
})}
|
||||
/>
|
||||
</Button.Group>
|
||||
</Modal.Actions>
|
||||
</Modal>
|
||||
);
|
||||
}
|
||||
|
||||
unlockAccount (password?: string): ?UnlockI18n {
|
||||
const { pair } = this.props;
|
||||
|
||||
if (pair.hasSecretKey()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
// $FlowFixMe typo in underlying type, fixed at base (upgrades)
|
||||
pair.decodePkcs8(void 0, password);
|
||||
} catch (error) {
|
||||
return {
|
||||
key: 'unlock.generic',
|
||||
value: {
|
||||
defaultValue: error.message
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
onChangePassword = (password: string): void => {
|
||||
this.setState({
|
||||
password,
|
||||
unlockError: null
|
||||
});
|
||||
}
|
||||
|
||||
onCancel = (): void => {
|
||||
const { onClose } = this.props;
|
||||
|
||||
onClose();
|
||||
}
|
||||
|
||||
onUnlock = (): void => {
|
||||
const { onClose } = this.props;
|
||||
const { password } = this.state;
|
||||
const unlockError = this.unlockAccount(password);
|
||||
|
||||
if (unlockError) {
|
||||
this.setState({ unlockError });
|
||||
return;
|
||||
}
|
||||
|
||||
onClose();
|
||||
};
|
||||
}
|
||||
|
||||
export default translate(Unlock);
|
||||
177
packages/app-toolbox/src/Verify.js
Normal file
177
packages/app-toolbox/src/Verify.js
Normal file
@ -0,0 +1,177 @@
|
||||
// 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 as Props } from '@polkadot/ui-app/types';
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import Icon from '@polkadot/ui-app/src/Icon';
|
||||
import Input from '@polkadot/ui-app/src/Input';
|
||||
import InputAddress from '@polkadot/ui-app/src/InputAddress';
|
||||
import Static from '@polkadot/ui-app/src/Static';
|
||||
import classes from '@polkadot/ui-app/src/util/classes';
|
||||
import keyring from '@polkadot/ui-keyring/src';
|
||||
import hexToU8a from '@polkadot/util/hex/toU8a';
|
||||
import isHex from '@polkadot/util/is/hex';
|
||||
import u8aFromString from '@polkadot/util/u8a/fromString';
|
||||
import naclVerify from '@polkadot/util-crypto/nacl/verify';
|
||||
|
||||
import translate from './translate';
|
||||
|
||||
type State = {
|
||||
currentPublicKey: Uint8Array | null,
|
||||
defaultPublicKey?: Uint8Array,
|
||||
data: string,
|
||||
isHexData: boolean,
|
||||
isValidAddress: boolean,
|
||||
isValidSignature: boolean,
|
||||
isValid: boolean,
|
||||
signature: string
|
||||
};
|
||||
|
||||
class Verify extends React.PureComponent<Props, State> {
|
||||
state: State;
|
||||
|
||||
constructor (props: Props) {
|
||||
super(props);
|
||||
|
||||
const pairs = keyring.getPairs();
|
||||
const currentPair = pairs[0];
|
||||
const currentPublicKey = currentPair
|
||||
? currentPair.publicKey()
|
||||
: null;
|
||||
|
||||
this.state = {
|
||||
currentPublicKey,
|
||||
defaultPublicKey: currentPublicKey || void 0,
|
||||
data: '',
|
||||
isHexData: false,
|
||||
isValidAddress: !!currentPair,
|
||||
isValidSignature: false,
|
||||
isValid: false,
|
||||
signature: ''
|
||||
};
|
||||
}
|
||||
|
||||
render (): React$Node {
|
||||
const { className, style, t } = this.props;
|
||||
const { defaultPublicKey, data, isHexData, isValid, isValidAddress, isValidSignature, signature } = this.state;
|
||||
|
||||
return (
|
||||
<div
|
||||
className={classes('toolbox--Verify', className)}
|
||||
style={style}
|
||||
>
|
||||
<div className='ui--row'>
|
||||
<Input
|
||||
className='large'
|
||||
label={t('verify.data', {
|
||||
defaultValue: 'using the following data (hex or string)'
|
||||
})}
|
||||
onChange={this.onChangeData}
|
||||
value={data}
|
||||
/>
|
||||
<Static
|
||||
className='small'
|
||||
label={t('verify.isHex', {
|
||||
defaultValue: 'hex input data'
|
||||
})}
|
||||
value={
|
||||
isHexData
|
||||
? t('verify.isHex.yes', {
|
||||
defaultValue: 'Yes'
|
||||
})
|
||||
: t('verify.isHex.no', {
|
||||
defaultValue: 'No'
|
||||
})
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
<div className='ui--row'>
|
||||
<InputAddress
|
||||
className='full'
|
||||
defaultValue={defaultPublicKey}
|
||||
isError={!isValidAddress}
|
||||
isInput
|
||||
label={t('verify.account', {
|
||||
defaultValue: 'verify using address'
|
||||
})}
|
||||
onChange={this.onChangeAddress}
|
||||
/>
|
||||
</div>
|
||||
<div className='ui--row'>
|
||||
<Input
|
||||
className='full'
|
||||
icon={
|
||||
<Icon
|
||||
color={isValid ? 'green' : (isValidSignature ? 'red' : void 0)}
|
||||
name={isValid ? 'check circle' : (isValidSignature ? 'exclamation circle' : 'help circle')}
|
||||
size='big'
|
||||
/>
|
||||
}
|
||||
isError={!isValidSignature}
|
||||
label={t('verify.signature', {
|
||||
defaultValue: 'checking the supplied signature'
|
||||
})}
|
||||
onChange={this.onChangeSignature}
|
||||
value={signature}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
nextState (newState: $Shape<State>): void {
|
||||
this.setState(
|
||||
(prevState: State): $Shape<State> => {
|
||||
const { isHexData = prevState.isHexData, isValidAddress = prevState.isValidAddress, isValidSignature = prevState.isValidSignature, currentPublicKey = prevState.currentPublicKey, data = prevState.data, signature = prevState.signature } = newState;
|
||||
|
||||
let isValid = isValidAddress && isValidSignature;
|
||||
|
||||
if (isValid && currentPublicKey) {
|
||||
isValid = naclVerify(
|
||||
isHexData
|
||||
? hexToU8a(data)
|
||||
: u8aFromString(data),
|
||||
hexToU8a(signature),
|
||||
currentPublicKey
|
||||
);
|
||||
}
|
||||
|
||||
return {
|
||||
isHexData,
|
||||
isValid,
|
||||
isValidAddress,
|
||||
isValidSignature,
|
||||
currentPublicKey,
|
||||
data,
|
||||
signature
|
||||
};
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
onChangeData = (data: string): void => {
|
||||
const isHexData = isHex(data);
|
||||
|
||||
this.nextState({ data, isHexData });
|
||||
}
|
||||
|
||||
onChangeSignature = (signature: string): void => {
|
||||
console.log('onChangeSig', isHex(signature), signature.length);
|
||||
|
||||
const isValidSignature = isHex(signature) && signature.length === 130;
|
||||
|
||||
this.nextState({ signature, isValidSignature });
|
||||
}
|
||||
|
||||
onChangeAddress = (currentPublicKey: Uint8Array): void => {
|
||||
const isValidAddress = currentPublicKey && currentPublicKey.length === 32;
|
||||
|
||||
this.nextState({ currentPublicKey, isValidAddress });
|
||||
}
|
||||
}
|
||||
|
||||
export default translate(Verify);
|
||||
41
packages/app-toolbox/src/index.css
Normal file
41
packages/app-toolbox/src/index.css
Normal file
@ -0,0 +1,41 @@
|
||||
/* 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. */
|
||||
|
||||
.toolbox--App {
|
||||
padding: 1em 2em;
|
||||
}
|
||||
|
||||
.toolbox--App-navigation.ui--Button-Group {
|
||||
margin-bottom: 2em;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.toolbox--hex .ui--output {
|
||||
font-family: monospace;
|
||||
}
|
||||
|
||||
.toolbox--Unlock-Content {
|
||||
align-content: center;
|
||||
display: flex;
|
||||
line-height: 1.5em;
|
||||
}
|
||||
|
||||
.toolbox--Unlock-Content .expanded {
|
||||
padding-right: 2em;
|
||||
}
|
||||
|
||||
.toolbox--Unlock-Content .expanded .code {
|
||||
background: #f5f5f5;
|
||||
font-family: monospace;
|
||||
margin: 0 0.25em;
|
||||
overflow-wrap: break-word;
|
||||
padding: 0.25em 0.5em;
|
||||
word-break: break-all;
|
||||
word-break: break-word;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
.toolbox--Unlock-Entry {
|
||||
padding-top: 1.5rem;
|
||||
}
|
||||
94
packages/app-toolbox/src/index.js
Normal file
94
packages/app-toolbox/src/index.js
Normal file
@ -0,0 +1,94 @@
|
||||
// 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-app/types';
|
||||
|
||||
import './index.css';
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import Button from '@polkadot/ui-app/src/Button';
|
||||
import classes from '@polkadot/ui-app/src/util/classes';
|
||||
|
||||
import Hash from './Hash';
|
||||
import Sign from './Sign';
|
||||
import Verify from './Verify';
|
||||
import translate from './translate';
|
||||
|
||||
type Actions = 'hash' | 'sign' | 'verify';
|
||||
|
||||
type Props = I18nProps & {};
|
||||
|
||||
type State = {
|
||||
action: Actions
|
||||
}
|
||||
|
||||
// FIXME React-router would probably be the best route, not home-grown
|
||||
// flowlint-next-line unclear-type:off
|
||||
const Components: { [Actions]: React$ComponentType<any> } = {
|
||||
'hash': Hash,
|
||||
'sign': Sign,
|
||||
'verify': Verify
|
||||
};
|
||||
|
||||
class App extends React.PureComponent<Props, State> {
|
||||
state: State = {
|
||||
action: 'hash'
|
||||
};
|
||||
|
||||
render (): React$Node {
|
||||
const { className, style, t } = this.props;
|
||||
const { action } = this.state;
|
||||
const Component = Components[action];
|
||||
|
||||
return (
|
||||
<div
|
||||
className={classes('toolbox--App', className)}
|
||||
style={style}
|
||||
>
|
||||
<Button.Group className='accounts--App-navigation'>
|
||||
<Button
|
||||
isPrimary={action === 'hash'}
|
||||
onClick={this.selectHash}
|
||||
text={t('app.hash', {
|
||||
defaultValue: 'Hash data'
|
||||
})}
|
||||
/>
|
||||
<Button.Or />
|
||||
<Button
|
||||
isPrimary={action === 'sign'}
|
||||
onClick={this.selectSign}
|
||||
text={t('app.sign', {
|
||||
defaultValue: 'Sign message'
|
||||
})}
|
||||
/>
|
||||
<Button.Or />
|
||||
<Button
|
||||
isPrimary={action === 'verify'}
|
||||
onClick={this.selectVerify}
|
||||
text={t('app.verify', {
|
||||
defaultValue: 'Verify signature'
|
||||
})}
|
||||
/>
|
||||
</Button.Group>
|
||||
<Component />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
selectHash = (): void => {
|
||||
this.setState({ action: 'hash' });
|
||||
}
|
||||
|
||||
selectSign = (): void => {
|
||||
this.setState({ action: 'sign' });
|
||||
}
|
||||
|
||||
selectVerify = (): void => {
|
||||
this.setState({ action: 'verify' });
|
||||
}
|
||||
}
|
||||
|
||||
export default translate(App);
|
||||
8
packages/app-toolbox/src/translate.js
Normal file
8
packages/app-toolbox/src/translate.js
Normal file
@ -0,0 +1,8 @@
|
||||
// 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 { translate } from 'react-i18next';
|
||||
|
||||
export default translate(['toolbox', 'ui']);
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@polkadot/app-vanitygen",
|
||||
"version": "0.4.12",
|
||||
"version": "0.5.0",
|
||||
"main": "index.js",
|
||||
"repository": "https://github.com/polkadot-js/apps.git",
|
||||
"author": "Jaco Greeff <jacogr@gmail.com>",
|
||||
@ -11,7 +11,7 @@
|
||||
"test": "jest --coverage"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@polkadot/ui-app": "^0.4.12",
|
||||
"@polkadot/ui-app": "^0.5.0",
|
||||
"chalk": "^2.4.1",
|
||||
"yargs": "10.1.2"
|
||||
},
|
||||
|
||||
@ -9,6 +9,7 @@ import React from 'react';
|
||||
|
||||
import CopyButton from '@polkadot/ui-app/src/CopyButton';
|
||||
import Button from '@polkadot/ui-app/src/Button';
|
||||
import classes from '@polkadot/ui-app/src/util/classes';
|
||||
import IdentityIcon from '@polkadot/ui-react/IdentityIcon';
|
||||
import u8aToHex from '@polkadot/util/u8a/toHex';
|
||||
|
||||
@ -39,7 +40,7 @@ export default class Match extends React.PureComponent<Props, State> {
|
||||
|
||||
return (
|
||||
<div
|
||||
className={['vanity--Match', className].join(' ')}
|
||||
className={classes('vanity--Match', className)}
|
||||
style={style}
|
||||
>
|
||||
<div className='vanity--Match-item'>
|
||||
|
||||
@ -13,7 +13,8 @@ import React from 'react';
|
||||
import Button from '@polkadot/ui-app/src/Button';
|
||||
import Dropdown from '@polkadot/ui-app/src/Dropdown';
|
||||
import Input from '@polkadot/ui-app/src/Input';
|
||||
import Labelled from '@polkadot/ui-app/src/Labelled';
|
||||
import Static from '@polkadot/ui-app/src/Static';
|
||||
import classes from '@polkadot/ui-app/src/util/classes';
|
||||
|
||||
import Match from './Match';
|
||||
import generator from './generator';
|
||||
@ -61,7 +62,7 @@ class App extends React.PureComponent<Props, State> {
|
||||
|
||||
return (
|
||||
<div
|
||||
className={['vanity--App', className].join(' ')}
|
||||
className={classes('vanity--App', className)}
|
||||
style={style}
|
||||
>
|
||||
<div className='ui--row'>
|
||||
@ -85,18 +86,15 @@ class App extends React.PureComponent<Props, State> {
|
||||
onChange={this.onChangeCase}
|
||||
value={withCase}
|
||||
/>
|
||||
<Labelled
|
||||
<Static
|
||||
className='small'
|
||||
label={t('vanity.offset', {
|
||||
defaultValue: 'exact offset'
|
||||
})}
|
||||
>
|
||||
<div className='ui dropdown selection disabled'>
|
||||
{t('vanity.offset.off', {
|
||||
defaultValue: 'No'
|
||||
})}
|
||||
</div>
|
||||
</Labelled>
|
||||
value={t('vanity.offset.off', {
|
||||
defaultValue: 'No'
|
||||
})}
|
||||
/>
|
||||
</div>
|
||||
<Button.Group>
|
||||
<Button
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@polkadot/apps",
|
||||
"version": "0.4.12",
|
||||
"version": "0.5.0",
|
||||
"description": "An Apps portal into the Polkadot network",
|
||||
"main": "index.js",
|
||||
"homepage": ".",
|
||||
@ -14,12 +14,13 @@
|
||||
"test": "react-scripts test --env=jsdom --coverage"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@polkadot/app-accounts": "^0.4.12",
|
||||
"@polkadot/app-addresses": "^0.4.12",
|
||||
"@polkadot/app-explorer": "^0.4.12",
|
||||
"@polkadot/app-extrinsics": "^0.4.12",
|
||||
"@polkadot/app-storage": "^0.4.12",
|
||||
"@polkadot/ui-app": "^0.4.12",
|
||||
"react-remarkable": "^1.1.3"
|
||||
"@polkadot/app-accounts": "^0.5.0",
|
||||
"@polkadot/app-addresses": "^0.5.0",
|
||||
"@polkadot/app-explorer": "^0.5.0",
|
||||
"@polkadot/app-extrinsics": "^0.5.0",
|
||||
"@polkadot/app-storage": "^0.5.0",
|
||||
"@polkadot/app-toolbox": "^0.5.0",
|
||||
"@polkadot/app-vanitygen": "^0.5.0",
|
||||
"@polkadot/ui-app": "^0.5.0"
|
||||
}
|
||||
}
|
||||
|
||||
@ -9,6 +9,8 @@ import './App.css';
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import classes from '@polkadot/ui-app/src/util/classes';
|
||||
|
||||
import Connecting from '../Connecting';
|
||||
import Content from '../Content';
|
||||
import SideBar from '../SideBar';
|
||||
@ -19,7 +21,7 @@ type Props = I18nProps & {};
|
||||
function App ({ className, style }: Props): React$Node {
|
||||
return (
|
||||
<div
|
||||
className={['apps--App', className].join(' ')}
|
||||
className={classes('apps--App', className)}
|
||||
style={style}
|
||||
>
|
||||
<SideBar className='apps--App-column' />
|
||||
|
||||
@ -9,6 +9,7 @@ import './Connecting.css';
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import classes from '@polkadot/ui-app/src/util/classes';
|
||||
import withApiCall from '@polkadot/ui-react-rx/with/apiCall';
|
||||
|
||||
import translate from '../translate';
|
||||
@ -25,7 +26,7 @@ function Connecting ({ className, style, value, t }: Props): React$Node {
|
||||
// 'ui inverted page modals dimmer transition visible active'
|
||||
return (
|
||||
<div
|
||||
className={['apps--Connecting', className].join(' ')}
|
||||
className={classes('apps--Connecting', className)}
|
||||
style={style}
|
||||
>
|
||||
<div className='apps--Connecting-text'>
|
||||
|
||||
@ -11,29 +11,28 @@ import './Content.css';
|
||||
import React from 'react';
|
||||
import { withRouter } from 'react-router';
|
||||
|
||||
import classes from '@polkadot/ui-app/src/util/classes';
|
||||
|
||||
import routing from '../routing';
|
||||
import translate from '../translate';
|
||||
|
||||
type Props = I18nProps & {
|
||||
location: Location
|
||||
};
|
||||
|
||||
function Content ({ className, location, style }: Props): React$Node {
|
||||
function Content ({ children, className, location, style }: Props): React$Node {
|
||||
const app = location.pathname.slice(1) || routing.default;
|
||||
const { Component } = routing.routes.find((route) =>
|
||||
route && route.name === app
|
||||
) || routing.unknown;
|
||||
|
||||
return (
|
||||
<div
|
||||
className={['apps--Content', className].join(' ')}
|
||||
className={classes('apps--Content', className)}
|
||||
style={style}
|
||||
>
|
||||
<iframe
|
||||
className='apps--Content-Frame'
|
||||
src={`index.html?app=${app}`}
|
||||
title={app}
|
||||
/>
|
||||
<Component />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
export default translate(
|
||||
withRouter(Content)
|
||||
);
|
||||
|
||||
export default withRouter(Content);
|
||||
|
||||
@ -9,6 +9,8 @@ import './NotFound.css';
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import classes from '@polkadot/ui-app/src/util/classes';
|
||||
|
||||
import translate from '../translate';
|
||||
|
||||
type Props = I18nProps & {};
|
||||
@ -16,7 +18,7 @@ type Props = I18nProps & {};
|
||||
function NotFound ({ className, style, t }: Props): React$Node {
|
||||
return (
|
||||
<div
|
||||
className={['apps--NotFound', className].join(' ')}
|
||||
className={classes('apps--NotFound', className)}
|
||||
style={style}
|
||||
>
|
||||
{t('notfound.error', {
|
||||
|
||||
@ -11,6 +11,7 @@ import React from 'react';
|
||||
|
||||
import Icon from '@polkadot/ui-app/src/Icon';
|
||||
import Menu from '@polkadot/ui-app/src/Menu';
|
||||
import classes from '@polkadot/ui-app/src/util/classes';
|
||||
|
||||
import routing from '../routing';
|
||||
import translate from '../translate';
|
||||
@ -21,7 +22,7 @@ type Props = I18nProps & {};
|
||||
function SideBar ({ className, style, t }: Props): React$Node {
|
||||
return (
|
||||
<div
|
||||
className={['apps--SideBar', className].join(' ')}
|
||||
className={classes('apps--SideBar', className)}
|
||||
style={style}
|
||||
>
|
||||
<Menu
|
||||
|
||||
@ -6,22 +6,5 @@
|
||||
import createApp from '@polkadot/ui-app/src';
|
||||
|
||||
import App from './App';
|
||||
import NotFound from './NotFound';
|
||||
import routing from './routing';
|
||||
import urlParams from './urlParams';
|
||||
|
||||
createApp((() => {
|
||||
const { app } = urlParams();
|
||||
|
||||
if (app) {
|
||||
const route = routing.routes.find((route) =>
|
||||
route && route.name === app
|
||||
);
|
||||
|
||||
return route
|
||||
? route.component
|
||||
: NotFound;
|
||||
}
|
||||
|
||||
return App;
|
||||
})());
|
||||
createApp(App);
|
||||
|
||||
@ -9,7 +9,7 @@ import Accounts from '@polkadot/app-accounts/src';
|
||||
|
||||
export default ([
|
||||
{
|
||||
component: Accounts,
|
||||
Component: Accounts,
|
||||
i18n: {
|
||||
defaultValue: 'Accounts'
|
||||
},
|
||||
|
||||
@ -9,7 +9,7 @@ import Addresses from '@polkadot/app-addresses/src';
|
||||
|
||||
export default ([
|
||||
{
|
||||
component: Addresses,
|
||||
Component: Addresses,
|
||||
i18n: {
|
||||
defaultValue: 'Addresses'
|
||||
},
|
||||
|
||||
@ -9,7 +9,7 @@ import Explorer from '@polkadot/app-explorer/src';
|
||||
|
||||
export default ([
|
||||
{
|
||||
component: Explorer,
|
||||
Component: Explorer,
|
||||
i18n: {
|
||||
defaultValue: 'Explorer'
|
||||
},
|
||||
|
||||
@ -9,7 +9,7 @@ import Extrinsics from '@polkadot/app-extrinsics/src';
|
||||
|
||||
export default ([
|
||||
{
|
||||
component: Extrinsics,
|
||||
Component: Extrinsics,
|
||||
i18n: {
|
||||
defaultValue: 'Extrinsics'
|
||||
},
|
||||
|
||||
@ -12,11 +12,14 @@ import extrinsics from './extrinsics';
|
||||
// import home from './home';
|
||||
// import settings from './settings';
|
||||
import storage from './storage';
|
||||
import toolbox from './toolbox';
|
||||
import unknown from './unknown';
|
||||
import vanitygen from './vanitygen';
|
||||
|
||||
export default ({
|
||||
default: 'explorer',
|
||||
routes: [].concat(
|
||||
explorer, extrinsics, storage, null, accounts, addresses, vanitygen
|
||||
)
|
||||
explorer, extrinsics, storage, toolbox, null, accounts, addresses, vanitygen
|
||||
),
|
||||
unknown
|
||||
}: Routing);
|
||||
|
||||
@ -9,7 +9,7 @@ import Storage from '@polkadot/app-storage/src';
|
||||
|
||||
export default ([
|
||||
{
|
||||
component: Storage,
|
||||
Component: Storage,
|
||||
i18n: {
|
||||
defaultValue: 'Storage'
|
||||
},
|
||||
|
||||
21
packages/apps/src/routing/toolbox.js
Normal file
21
packages/apps/src/routing/toolbox.js
Normal file
@ -0,0 +1,21 @@
|
||||
// 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 { Routes } from '../types';
|
||||
|
||||
import Toolbox from '@polkadot/app-toolbox/src';
|
||||
|
||||
export default ([
|
||||
{
|
||||
Component: Toolbox,
|
||||
i18n: {
|
||||
defaultValue: 'Toolbox'
|
||||
},
|
||||
icon: 'configure',
|
||||
isExact: false,
|
||||
isHidden: false,
|
||||
name: 'toolbox'
|
||||
}
|
||||
]: Routes);
|
||||
19
packages/apps/src/routing/unknown.js
Normal file
19
packages/apps/src/routing/unknown.js
Normal file
@ -0,0 +1,19 @@
|
||||
// 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 { Route } from '../types';
|
||||
|
||||
import NotFound from '../NotFound';
|
||||
|
||||
export default ({
|
||||
Component: NotFound,
|
||||
i18n: {
|
||||
defaultValue: 'Not found'
|
||||
},
|
||||
icon: 'error',
|
||||
isExact: false,
|
||||
isHidden: true,
|
||||
name: 'unknown'
|
||||
}: Route);
|
||||
@ -9,7 +9,7 @@ import Vanity from '@polkadot/app-vanitygen/src';
|
||||
|
||||
export default ([
|
||||
{
|
||||
component: Vanity,
|
||||
Component: Vanity,
|
||||
i18n: {
|
||||
defaultValue: 'Vanity'
|
||||
},
|
||||
|
||||
@ -4,9 +4,11 @@
|
||||
// @flow
|
||||
|
||||
export type Route = {
|
||||
component: React$ComponentType<*>,
|
||||
// flowlint-next-line unclear-type:off
|
||||
Component: React$ComponentType<any>,
|
||||
i18n: I18Next$Translate$Config,
|
||||
icon: React$ComponentType<*> | string,
|
||||
// flowlint-next-line unclear-type:off
|
||||
icon: React$ComponentType<any> | string,
|
||||
isExact: boolean,
|
||||
isHidden: boolean,
|
||||
name: string,
|
||||
@ -17,5 +19,6 @@ export type Routes = Array<Route | null>;
|
||||
|
||||
export type Routing = {
|
||||
default: string,
|
||||
routes: Routes
|
||||
routes: Routes,
|
||||
unknown: Route
|
||||
}
|
||||
|
||||
@ -1,24 +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
|
||||
|
||||
type Params = {
|
||||
[string]: string
|
||||
};
|
||||
|
||||
export default function urlParams (): Params {
|
||||
if (window.location.search.indexOf('?') !== 0) {
|
||||
return {};
|
||||
}
|
||||
|
||||
const parts = window.location.search.slice(1).split('&');
|
||||
|
||||
return parts.reduce((params, param) => {
|
||||
const [name, value] = param.split('=');
|
||||
|
||||
params[name] = value;
|
||||
|
||||
return params;
|
||||
}, {});
|
||||
}
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@polkadot/ui-app",
|
||||
"version": "0.4.12",
|
||||
"version": "0.5.0",
|
||||
"main": "index.js",
|
||||
"repository": "https://github.com/polkadot-js/apps.git",
|
||||
"author": "Jaco Greeff <jacogr@gmail.com>",
|
||||
@ -11,13 +11,14 @@
|
||||
"test": "jest --coverage"
|
||||
},
|
||||
"dependencies": {
|
||||
"@polkadot/extrinsics-substrate": "^0.13.8",
|
||||
"@polkadot/params": "^0.13.8",
|
||||
"@polkadot/storage-substrate": "^0.13.8",
|
||||
"@polkadot/ui-keyring": "^0.4.12",
|
||||
"@polkadot/ui-react": "^0.11.9",
|
||||
"@polkadot/ui-react-rx": "^0.11.9",
|
||||
"@polkadot/util": "^0.19.6",
|
||||
"@polkadot/extrinsics-substrate": "^0.13.10",
|
||||
"@polkadot/params": "^0.13.10",
|
||||
"@polkadot/primitives": "^0.13.10",
|
||||
"@polkadot/storage-substrate": "^0.13.10",
|
||||
"@polkadot/ui-keyring": "^0.5.0",
|
||||
"@polkadot/ui-react": "^0.11.10",
|
||||
"@polkadot/ui-react-rx": "^0.11.10",
|
||||
"@polkadot/util": "^0.19.7",
|
||||
"i18next": "^11.1.1",
|
||||
"i18next-browser-languagedetector": "^2.2.0",
|
||||
"i18next-xhr-backend": "^1.5.1",
|
||||
@ -29,8 +30,5 @@
|
||||
"semantic-ui-css": "^2.3.1",
|
||||
"semantic-ui-react": "^0.79.1",
|
||||
"store": "^2.0.12"
|
||||
},
|
||||
"devDepependencies": {
|
||||
"@polkadot/primitives": "^0.12.6"
|
||||
}
|
||||
}
|
||||
|
||||
@ -7,12 +7,14 @@ import type { BareProps } from '../types';
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import classes from '../util/classes';
|
||||
|
||||
type Props = BareProps;
|
||||
|
||||
function ButtonDivider ({ className, style }: Props): React$Node {
|
||||
return (
|
||||
<div
|
||||
className={['ui button compact mini basic', className].join(' ')}
|
||||
className={classes('ui button compact mini basic', className)}
|
||||
style={style}
|
||||
/>
|
||||
);
|
||||
|
||||
@ -8,6 +8,7 @@ import type { BareProps } from '../types';
|
||||
import React from 'react';
|
||||
import SUIButton from 'semantic-ui-react/dist/es/elements/Button';
|
||||
|
||||
import classes from '../util/classes';
|
||||
import Divider from './Divider';
|
||||
|
||||
type Props = BareProps & {
|
||||
@ -17,7 +18,7 @@ type Props = BareProps & {
|
||||
function ButtonGroup ({ children, className, style }: Props): React$Node {
|
||||
return (
|
||||
<div
|
||||
className={['ui--Button-Group', className].join(' ')}
|
||||
className={classes('ui--Button-Group', className)}
|
||||
style={style}
|
||||
>
|
||||
<SUIButton.Group>
|
||||
|
||||
@ -16,7 +16,7 @@ type Props = BareProps & {
|
||||
isCircular?: boolean,
|
||||
isPrimary?: boolean,
|
||||
size?: Button$Sizes,
|
||||
value?: string
|
||||
value?: mixed
|
||||
}
|
||||
|
||||
export default function CopyButton ({ className, icon = 'copy', isCircular = true, isPrimary = true, size = 'tiny', style, value }: Props): React$Node {
|
||||
|
||||
@ -8,6 +8,7 @@ import type { BareProps } from './types';
|
||||
import React from 'react';
|
||||
import SUIDropdown from 'semantic-ui-react/dist/es/modules/Dropdown';
|
||||
|
||||
import classes from './util/classes';
|
||||
import Labelled from './Labelled';
|
||||
|
||||
type Props = BareProps & {
|
||||
@ -17,8 +18,10 @@ type Props = BareProps & {
|
||||
label?: React$Node,
|
||||
// flowlint-next-line unclear-type:off
|
||||
onChange: (value: any) => void,
|
||||
onSearch?: (filteredOptions: Array<*>, query: string) => Array<*>,
|
||||
options: Array<*>,
|
||||
// flowlint-next-line unclear-type:off
|
||||
onSearch?: (filteredOptions: Array<any>, query: string) => Array<any>,
|
||||
// flowlint-next-line unclear-type:off
|
||||
options: Array<any>,
|
||||
// flowlint-next-line unclear-type:off
|
||||
transform?: (value: any) => any,
|
||||
value?: mixed,
|
||||
@ -36,7 +39,7 @@ export default class Dropdown extends React.PureComponent<Props> {
|
||||
|
||||
return (
|
||||
<Labelled
|
||||
className={['ui--Dropdown', className].join(' ')}
|
||||
className={classes('ui--Dropdown', className)}
|
||||
label={label}
|
||||
style={style}
|
||||
withLabel={withLabel}
|
||||
@ -55,7 +58,8 @@ export default class Dropdown extends React.PureComponent<Props> {
|
||||
);
|
||||
}
|
||||
|
||||
onChange = (event: SyntheticEvent<*>, { value }: SUIEvent): void => {
|
||||
// flowlint-next-line unclear-type:off
|
||||
onChange = (event: SyntheticEvent<any>, { value }: SUIEvent): void => {
|
||||
const { onChange, transform } = this.props;
|
||||
|
||||
onChange(
|
||||
|
||||
@ -8,6 +8,8 @@ import type { BareProps } from './types';
|
||||
import React from 'react';
|
||||
import SUIInput from 'semantic-ui-react/dist/es/elements/Input';
|
||||
|
||||
import isUndefined from '@polkadot/util/is/undefined';
|
||||
|
||||
import Labelled from './Labelled';
|
||||
|
||||
type Input$Type = 'number' | 'password' | 'text';
|
||||
@ -15,9 +17,11 @@ type Input$Type = 'number' | 'password' | 'text';
|
||||
type Props = BareProps & {
|
||||
children?: React$Node,
|
||||
defaultValue?: mixed,
|
||||
icon?: React$Node,
|
||||
isAction?: boolean,
|
||||
isDisabled?: boolean,
|
||||
isError?: boolean,
|
||||
isHidden?: boolean,
|
||||
label?: React$Node,
|
||||
max?: mixed,
|
||||
min?: mixed,
|
||||
@ -46,7 +50,7 @@ export default class Input extends React.PureComponent<Props, State> {
|
||||
};
|
||||
|
||||
render (): React$Node {
|
||||
const { children, className, defaultValue, isAction = false, isDisabled = false, isError = false, label, max, min, placeholder, style, type = 'text', value, withLabel } = this.props;
|
||||
const { children, className, defaultValue, icon, isAction = false, isDisabled = false, isError = false, isHidden = false, label, max, min, placeholder, style, type = 'text', value, withLabel } = this.props;
|
||||
const { name } = this.state;
|
||||
|
||||
return (
|
||||
@ -60,7 +64,14 @@ export default class Input extends React.PureComponent<Props, State> {
|
||||
action={isAction}
|
||||
defaultValue={defaultValue}
|
||||
disabled={isDisabled}
|
||||
id={name}
|
||||
iconPosition={
|
||||
isUndefined(icon)
|
||||
? void 0
|
||||
: 'left'
|
||||
}
|
||||
error={isError}
|
||||
hidden={isHidden}
|
||||
max={max}
|
||||
min={min}
|
||||
name={name}
|
||||
@ -69,14 +80,22 @@ export default class Input extends React.PureComponent<Props, State> {
|
||||
type={type}
|
||||
value={value}
|
||||
>
|
||||
<input />
|
||||
<input
|
||||
autoComplete={
|
||||
type === 'password'
|
||||
? 'new-password'
|
||||
: 'off'
|
||||
}
|
||||
/>
|
||||
{icon}
|
||||
{children}
|
||||
</SUIInput>
|
||||
</Labelled>
|
||||
);
|
||||
}
|
||||
|
||||
onChange = (event: SyntheticEvent<*>, { value }: SUIEvent): void => {
|
||||
// flowlint-next-line unclear-type:off
|
||||
onChange = (event: SyntheticEvent<any>, { value }: SUIEvent): void => {
|
||||
this.props.onChange(value);
|
||||
}
|
||||
}
|
||||
|
||||
@ -8,8 +8,8 @@
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.ui--InputAddress input.search {
|
||||
margin-left: 3rem;
|
||||
.ui--InputAddress .ui.search.selection.dropdown > input.search {
|
||||
padding-left: 4rem;
|
||||
}
|
||||
|
||||
.flag--hideAddress .ui--KeyPair .ui--KeyPair-address {
|
||||
|
||||
@ -15,6 +15,7 @@ import createOptionHeader from '@polkadot/ui-keyring/src/options/header';
|
||||
import addressDecode from '@polkadot/util-keyring/address/decode';
|
||||
|
||||
import Dropdown from '../Dropdown';
|
||||
import classes from '../util/classes';
|
||||
import addressToAddress from './addressToAddress';
|
||||
|
||||
type Props = BareProps & {
|
||||
@ -68,7 +69,7 @@ export default class InputAddress extends React.Component<Props, State> {
|
||||
|
||||
return (
|
||||
<Dropdown
|
||||
className={['ui--InputAddress', hideAddress ? 'flag--hideAddress' : '', className].join(' ')}
|
||||
className={classes('ui--InputAddress', hideAddress ? 'flag--hideAddress' : '', className)}
|
||||
defaultValue={defaultValue}
|
||||
isError={isError}
|
||||
label={label}
|
||||
|
||||
@ -11,6 +11,7 @@ import React from 'react';
|
||||
import extrinsics from '@polkadot/extrinsics-substrate';
|
||||
|
||||
import Dropdown from '../Dropdown';
|
||||
import classes from '../util/classes';
|
||||
import translate from '../translate';
|
||||
import createOptions from './options/method';
|
||||
|
||||
@ -36,7 +37,7 @@ function SelectMethod ({ className, isError, label = '', onChange, style, t, typ
|
||||
|
||||
return (
|
||||
<Dropdown
|
||||
className={['ui--DropdownLinked-Items', className].join(' ')}
|
||||
className={classes('ui--DropdownLinked-Items', className)}
|
||||
isError={isError}
|
||||
label={label || t('input.extrinsic.method', {
|
||||
defaultValue: 'with the extrinsic'
|
||||
|
||||
@ -9,6 +9,7 @@ import type { I18nProps } from '../types';
|
||||
import React from 'react';
|
||||
|
||||
import Dropdown from '../Dropdown';
|
||||
import classes from '../util/classes';
|
||||
import translate from '../translate';
|
||||
import createOptions from './options/section';
|
||||
|
||||
@ -27,7 +28,7 @@ function SelectSection ({ className, defaultValue, isError, label = '', onChange
|
||||
|
||||
return (
|
||||
<Dropdown
|
||||
className={['ui--DropdownLinked-Sections', className].join(' ')}
|
||||
className={classes('ui--DropdownLinked-Sections', className)}
|
||||
defaultValue={defaultValue}
|
||||
isError={isError}
|
||||
label={label || t('input.extrinsic.section', {
|
||||
|
||||
@ -13,6 +13,7 @@ import './InputExtrinsic.css';
|
||||
import React from 'react';
|
||||
import map from '@polkadot/extrinsics-substrate';
|
||||
|
||||
import classes from '../util/classes';
|
||||
import translate from '../translate';
|
||||
import SelectMethod from './SelectMethod';
|
||||
import SelectSection from './SelectSection';
|
||||
@ -50,7 +51,7 @@ class InputExtrinsic extends React.PureComponent<Props, State> {
|
||||
|
||||
return (
|
||||
<div
|
||||
className={['ui--DropdownLinked', 'ui--row', className].join(' ')}
|
||||
className={classes('ui--DropdownLinked', 'ui--row', className)}
|
||||
style={style}
|
||||
>
|
||||
<SelectSection
|
||||
|
||||
@ -10,7 +10,7 @@ import React from 'react';
|
||||
import map from '@polkadot/extrinsics-substrate';
|
||||
|
||||
// flowlint-next-line unclear-type:off
|
||||
export default function createOptions (sectionName: any, type: 'private' | 'public'): Array<*> {
|
||||
export default function createOptions (sectionName: any, type: 'private' | 'public'): Array<any> {
|
||||
const section = map[(sectionName: ExtrinsicSectionName)];
|
||||
|
||||
if (!section) {
|
||||
|
||||
@ -5,7 +5,8 @@
|
||||
|
||||
import map from '@polkadot/extrinsics-substrate';
|
||||
|
||||
export default function createOptions (type: 'private' | 'public'): Array<*> {
|
||||
// flowlint-next-line unclear-type:off
|
||||
export default function createOptions (type: 'private' | 'public'): Array<any> {
|
||||
return Object
|
||||
.keys(map)
|
||||
.sort()
|
||||
|
||||
@ -11,6 +11,7 @@ import React from 'react';
|
||||
import map from '@polkadot/storage-substrate/keys';
|
||||
|
||||
import Dropdown from '../Dropdown';
|
||||
import classes from '../util/classes';
|
||||
import translate from '../translate';
|
||||
import createOptions from './options/key';
|
||||
|
||||
@ -35,7 +36,7 @@ function SelectKey ({ className, isError, label = '', onChange, style, t, value:
|
||||
|
||||
return (
|
||||
<Dropdown
|
||||
className={['ui--DropdownLinked-Items', className].join(' ')}
|
||||
className={classes('ui--DropdownLinked-Items', className)}
|
||||
isError={isError}
|
||||
label={label || t('input.storage.key', {
|
||||
defaultValue: 'with storage key'
|
||||
|
||||
@ -9,6 +9,7 @@ import type { I18nProps } from '../types';
|
||||
import React from 'react';
|
||||
|
||||
import Dropdown from '../Dropdown';
|
||||
import classes from '../util/classes';
|
||||
import translate from '../translate';
|
||||
import createOptions from './options/section';
|
||||
|
||||
@ -26,7 +27,7 @@ const options = createOptions();
|
||||
function SelectSection ({ className, defaultValue, isError, label, onChange, style, t, value: { section }, withLabel }: Props): React$Node {
|
||||
return (
|
||||
<Dropdown
|
||||
className={['ui--DropdownLinked-Sections', className].join(' ')}
|
||||
className={classes('ui--DropdownLinked-Sections', className)}
|
||||
defaultValue={defaultValue}
|
||||
isError={isError}
|
||||
label={label || t('input.storage.section', {
|
||||
|
||||
@ -11,8 +11,10 @@ import type { I18nProps } from '../types';
|
||||
import '../InputExtrinsic/InputExtrinsic.css';
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import map from '@polkadot/storage-substrate/keys';
|
||||
|
||||
import classes from '../util/classes';
|
||||
import translate from '../translate';
|
||||
import SelectKey from './SelectKey';
|
||||
import SelectSection from './SelectSection';
|
||||
@ -48,7 +50,7 @@ class InputStorage extends React.PureComponent<Props, State> {
|
||||
|
||||
return (
|
||||
<div
|
||||
className={['ui--DropdownLinked', 'ui--row', className].join(' ')}
|
||||
className={classes('ui--DropdownLinked', 'ui--row', className)}
|
||||
style={style}
|
||||
>
|
||||
<SelectSection
|
||||
|
||||
@ -10,7 +10,7 @@ import React from 'react';
|
||||
import map from '@polkadot/storage-substrate/keys';
|
||||
|
||||
// flowlint-next-line unclear-type:off
|
||||
export default function createOptions (sectionName: any): Array<*> {
|
||||
export default function createOptions (sectionName: any): Array<any> {
|
||||
const section = map[(sectionName: StateDb$SectionNames)];
|
||||
|
||||
if (!section) {
|
||||
|
||||
@ -5,7 +5,8 @@
|
||||
|
||||
import map from '@polkadot/storage-substrate/keys';
|
||||
|
||||
export default function createOptions (): Array<*> {
|
||||
// flowlint-next-line unclear-type:off
|
||||
export default function createOptions (): Array<any> {
|
||||
return Object
|
||||
.keys(map)
|
||||
.sort()
|
||||
|
||||
@ -8,7 +8,10 @@ import type { BareProps } from './types';
|
||||
import React from 'react';
|
||||
import Label from 'semantic-ui-react/dist/es/elements/Label';
|
||||
|
||||
import classes from './util/classes';
|
||||
|
||||
type Props = BareProps & {
|
||||
isHidden?: boolean,
|
||||
// flowlint-next-line unclear-type:off
|
||||
label?: any,
|
||||
children: React$Node,
|
||||
@ -19,10 +22,14 @@ const defaultLabel: React$Node = (
|
||||
<div> </div>
|
||||
);
|
||||
|
||||
export default function Labelled ({ className, children, label = defaultLabel, style, withLabel = true }: Props): React$Node {
|
||||
export default function Labelled ({ className, children, isHidden = false, label = defaultLabel, style, withLabel = true }: Props): React$Node {
|
||||
if (isHidden) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return (
|
||||
<div
|
||||
className={className}
|
||||
className={classes('ui--Labelled', className)}
|
||||
style={style}
|
||||
>
|
||||
{
|
||||
|
||||
47
packages/ui-app/src/Output.js
Normal file
47
packages/ui-app/src/Output.js
Normal file
@ -0,0 +1,47 @@
|
||||
// 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 { BareProps } from './types';
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import CopyButton from './CopyButton';
|
||||
import Labelled from './Labelled';
|
||||
|
||||
type Props = BareProps & {
|
||||
children?: React$Node,
|
||||
isHidden?: boolean,
|
||||
label?: React$Node,
|
||||
value?: mixed,
|
||||
withCopy?: boolean,
|
||||
withLabel?: boolean
|
||||
};
|
||||
|
||||
export default function Output ({ className, children, isHidden, label, style, value, withCopy = false, withLabel }: Props): React$Node {
|
||||
return (
|
||||
<Labelled
|
||||
className={className}
|
||||
isHidden={isHidden}
|
||||
label={label}
|
||||
style={style}
|
||||
withLabel={withLabel}
|
||||
>
|
||||
<div className='ui--output'>
|
||||
{
|
||||
// flowlint-next-line unclear-type:off
|
||||
((value: any): React$Node)
|
||||
}
|
||||
{children}
|
||||
{
|
||||
withCopy
|
||||
? (
|
||||
<CopyButton className='ui--output-button' value={value} />
|
||||
)
|
||||
: null
|
||||
}
|
||||
</div>
|
||||
</Labelled>
|
||||
);
|
||||
}
|
||||
@ -7,6 +7,8 @@ import type { BareProps } from '../../types';
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import classes from '../../util/classes';
|
||||
|
||||
type Props = BareProps & {
|
||||
children: React$Node
|
||||
};
|
||||
@ -14,7 +16,7 @@ type Props = BareProps & {
|
||||
export default function Bare ({ children, className, style }: Props): React$Node {
|
||||
return (
|
||||
<div
|
||||
className={['ui--row', className].join(' ')}
|
||||
className={classes('ui--row', className)}
|
||||
style={style}
|
||||
>
|
||||
{children}
|
||||
|
||||
@ -8,6 +8,7 @@ import type { BareProps } from '@polkadot/ui-app/types';
|
||||
import React from 'react';
|
||||
import Dropzone from 'react-dropzone';
|
||||
|
||||
import classes from '../../util/classes';
|
||||
import translate from '../../translate';
|
||||
import Base from './Base';
|
||||
|
||||
@ -41,7 +42,7 @@ class BytesFile extends React.PureComponent<Props, State> {
|
||||
withLabel={withLabel}
|
||||
>
|
||||
<Dropzone
|
||||
className={['ui--Param-File', isError ? 'error' : '', className].join(' ')}
|
||||
className={classes('ui--Param-File', isError ? 'error' : '', className)}
|
||||
disabled={isDisabled}
|
||||
multiple={false}
|
||||
onDrop={this.onDrop}
|
||||
|
||||
@ -41,7 +41,8 @@ const components: ComponentMap = {
|
||||
'VoteThreshold': VoteThreshold
|
||||
};
|
||||
|
||||
export default function findComponent (type: Param$Types, overrides?: ComponentMap = {}): React$ComponentType<*> | Array<React$ComponentType<*>> {
|
||||
// flowlint-next-line unclear-type:off
|
||||
export default function findComponent (type: Param$Types, overrides?: ComponentMap = {}): React$ComponentType<any> | Array<React$ComponentType<any>> {
|
||||
if (Array.isArray(type)) {
|
||||
return type
|
||||
.map((type) =>
|
||||
|
||||
@ -9,6 +9,7 @@ import type { BaseProps, ComponentMap, RawParam } from '../types';
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import classes from '../../util/classes';
|
||||
import translate from '../../translate';
|
||||
import typeToText from '../typeToText';
|
||||
import findComponent from './findComponent';
|
||||
@ -28,7 +29,8 @@ type ComponentProps = BaseProps & {
|
||||
};
|
||||
|
||||
type State = {
|
||||
Components: React$ComponentType<*> | Array<React$ComponentType<*>>
|
||||
// flowlint-next-line unclear-type:off
|
||||
Components: React$ComponentType<any> | Array<React$ComponentType<any>>
|
||||
| null
|
||||
}
|
||||
|
||||
@ -60,7 +62,8 @@ class ParamComponent extends React.PureComponent<Props, State> {
|
||||
: this.renderComponents();
|
||||
}
|
||||
|
||||
renderComponents = (_Components: React$ComponentType<*> | Array<React$ComponentType<*>> | null = this.state.Components, startIndex: string = '0', { name, type, options = {} } = this.props.value) => {
|
||||
// flowlint-next-line unclear-type:off
|
||||
renderComponents = (_Components: React$ComponentType<any> | Array<React$ComponentType<any>> | null = this.state.Components, startIndex: string = '0', { name, type, options = {} } = this.props.value) => {
|
||||
if (!_Components) {
|
||||
return null;
|
||||
}
|
||||
@ -69,7 +72,7 @@ class ParamComponent extends React.PureComponent<Props, State> {
|
||||
|
||||
if (!Array.isArray(type)) {
|
||||
// flowlint-next-line unclear-type:off
|
||||
const Component = ((_Components: any): React$ComponentType<*>);
|
||||
const Component = ((_Components: any): React$ComponentType<any>);
|
||||
|
||||
return this.renderComponent(Component, startIndex, {
|
||||
className,
|
||||
@ -85,7 +88,7 @@ class ParamComponent extends React.PureComponent<Props, State> {
|
||||
}
|
||||
|
||||
// flowlint-next-line unclear-type:off
|
||||
const Components = ((_Components: any): Array<React$ComponentType<*>>);
|
||||
const Components = ((_Components: any): Array<React$ComponentType<any>>);
|
||||
|
||||
return Components.map((Component, index) => {
|
||||
return this.renderComponents(Component, `${startIndex}-${index}`, {
|
||||
@ -96,13 +99,14 @@ class ParamComponent extends React.PureComponent<Props, State> {
|
||||
});
|
||||
}
|
||||
|
||||
renderComponent = (Component: React$ComponentType<*>, sub: string, props: ComponentProps): React$Node => {
|
||||
// flowlint-next-line unclear-type:off
|
||||
renderComponent = (Component: React$ComponentType<any>, sub: string, props: ComponentProps): React$Node => {
|
||||
const { className, index, onChange, style, value: { name, type, options = {} } } = props;
|
||||
const text = typeToText(type);
|
||||
|
||||
return (
|
||||
<Component
|
||||
className={['ui--Param', className].join(' ')}
|
||||
className={classes('ui--Param', className)}
|
||||
index={index}
|
||||
key={`${name}:${text}:${index}}`}
|
||||
label={`${name}: ${text} (${index})`}
|
||||
|
||||
@ -11,6 +11,7 @@ import './Params.css';
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import classes from '../util/classes';
|
||||
import translate from '../translate';
|
||||
import Param from './Param';
|
||||
import createValues from './values';
|
||||
@ -62,7 +63,7 @@ class Params extends React.PureComponent<Props, State> {
|
||||
|
||||
return (
|
||||
<div
|
||||
className={['ui--Params', className].join(' ')}
|
||||
className={classes('ui--Params', className)}
|
||||
style={style}
|
||||
>
|
||||
<div className='ui--Params-Content'>
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user