Merge pull request #1 from polkadot-js/jg-submit
submitExtrinsics from app-testing
This commit is contained in:
commit
f4deeca850
10
.babelrc
10
.babelrc
@ -1,11 +1,3 @@
|
||||
{
|
||||
"extends": "@polkadot/dev/config/babel",
|
||||
"plugins": [
|
||||
["module-resolver", {
|
||||
"alias": {
|
||||
"^@polkadot/portal-(chains|db-chain|db|p2p|rpc|runtime|state|wasm)(.*)": "./packages/portal-\\1/src\\2",
|
||||
"^@polkadot/portal": "./packages/portal/src"
|
||||
}
|
||||
}]
|
||||
]
|
||||
"extends": "@polkadot/dev/config/babel"
|
||||
}
|
||||
|
||||
27
flow-typed/semantic-ui-react.js
vendored
Normal file
27
flow-typed/semantic-ui-react.js
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
// @flow
|
||||
|
||||
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 'semantic-ui-react/dist/es/elements/Icon' {
|
||||
declare module.exports: React$StatelessFunctionalComponent<*>
|
||||
}
|
||||
|
||||
declare module 'semantic-ui-react/dist/es/elements/Input' {
|
||||
declare module.exports: React$StatelessFunctionalComponent<*>
|
||||
}
|
||||
|
||||
declare module 'semantic-ui-react/dist/es/elements/Label' {
|
||||
declare module.exports: React$StatelessFunctionalComponent<*>
|
||||
}
|
||||
|
||||
declare module 'semantic-ui-react/dist/es/modules/Dropdown' {
|
||||
declare module.exports: React$StatelessFunctionalComponent<*>
|
||||
}
|
||||
@ -8,13 +8,13 @@
|
||||
"build": "cd packages/portal && react-scripts build",
|
||||
"check": "eslint packages && flow check",
|
||||
"start": "cd packages/portal && react-scripts start",
|
||||
"test": "jest --coverage"
|
||||
"test": "echo 'to tests executed'"
|
||||
},
|
||||
"dependencies": {
|
||||
"@polkadot/portal": "^0.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@polkadot/dev": "^0.17.8",
|
||||
"@polkadot/dev": "^0.17.9",
|
||||
"lerna": "^2.5.1",
|
||||
"react-scripts": "^2.0.0-next.b2fd8db8"
|
||||
},
|
||||
|
||||
23
packages/app-home/package.json
Normal file
23
packages/app-home/package.json
Normal file
@ -0,0 +1,23 @@
|
||||
{
|
||||
"name": "@polkadot/app-home",
|
||||
"version": "0.1.0",
|
||||
"main": "src/index.js",
|
||||
"repository": "https://github.com/polkadot-js/portal.git",
|
||||
"author": "Jaco Greeff <jacogr@gmail.com>",
|
||||
"license": "ISC",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"build": "react-scripts build",
|
||||
"check": "stylelint 'src/**/*.css' && eslint src && flow check",
|
||||
"start": "react-scripts start",
|
||||
"test": "react-scripts test --env=jsdom --coverage"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@polkadot/rx-react": "^0.2.13",
|
||||
"@polkadot/util": "^0.19.1",
|
||||
"react": "^16.3.1",
|
||||
"react-dom": "^16.3.1",
|
||||
"semantic-ui-css": "^2.3.1",
|
||||
"semantic-ui-react": "^0.79.1"
|
||||
}
|
||||
}
|
||||
@ -2,11 +2,11 @@
|
||||
/* This software may be modified and distributed under the terms
|
||||
/* of the ISC license. See the LICENSE file for details. */
|
||||
|
||||
.testing--Body {
|
||||
padding: 0;
|
||||
}
|
||||
.home--App {}
|
||||
|
||||
.testing--Body-BlockNumber {
|
||||
.home--App-BestNumber {
|
||||
font-size: 3rem;
|
||||
line-height: 3rem;
|
||||
margin-bottom: 1rem;
|
||||
opacity: 0.5;
|
||||
text-align: right;
|
||||
27
packages/app-home/src/App/index.js
Normal file
27
packages/app-home/src/App/index.js
Normal file
@ -0,0 +1,27 @@
|
||||
// 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 { BaseProps } from '@polkadot/portal/types';
|
||||
|
||||
import './App.css';
|
||||
|
||||
import React from 'react';
|
||||
import BestNumber from '@polkadot/rx-react/BestNumber';
|
||||
|
||||
type Props = BaseProps & {};
|
||||
|
||||
export default function App ({ className, style }: Props) {
|
||||
return (
|
||||
<div
|
||||
className={['home--App', className].join(' ')}
|
||||
style={style}
|
||||
>
|
||||
<BestNumber
|
||||
className='home--App-BestNumber'
|
||||
label='#'
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
3
packages/app-home/src/index.css
Normal file
3
packages/app-home/src/index.css
Normal file
@ -0,0 +1,3 @@
|
||||
/* 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. */
|
||||
@ -3,8 +3,8 @@
|
||||
// of the ISC license. See the LICENSE file for details.
|
||||
// @flow
|
||||
|
||||
import addr from './addr';
|
||||
import './index.css';
|
||||
|
||||
const subject = addr();
|
||||
import App from './App';
|
||||
|
||||
export default subject;
|
||||
export default App;
|
||||
@ -1,5 +1,5 @@
|
||||
{
|
||||
"name": "@polkadot/content-testing",
|
||||
"name": "@polkadot/app-testing",
|
||||
"version": "0.1.0",
|
||||
"main": "src/index.js",
|
||||
"repository": "https://github.com/polkadot-js/portal.git",
|
||||
@ -13,10 +13,11 @@
|
||||
"test": "react-scripts test --env=jsdom --coverage"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@polkadot/rx-react": "^0.2.2",
|
||||
"@polkadot/rx-react": "^0.2.13",
|
||||
"@polkadot/ui-react": "^0.9.10",
|
||||
"@polkadot/util": "^0.18.6",
|
||||
"@polkadot/util-keyring": "^0.18.6",
|
||||
"@polkadot/util": "^0.19.1",
|
||||
"@polkadot/util-keyring": "^0.19.1",
|
||||
"prop-types": "^15.6.1",
|
||||
"react": "^16.3.1",
|
||||
"react-dom": "^16.3.1",
|
||||
"semantic-ui-css": "^2.3.1",
|
||||
44
packages/app-testing/src/Account.js
Normal file
44
packages/app-testing/src/Account.js
Normal file
@ -0,0 +1,44 @@
|
||||
// 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 { BaseProps } from './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 './InputAddress';
|
||||
|
||||
type Props = BaseProps & {
|
||||
label: string,
|
||||
subject: rxjs$BehaviorSubject<*>
|
||||
};
|
||||
|
||||
export default function Account ({ className, label, subject, style }: Props) {
|
||||
const AccountBalance = withObservableParams(Balance, subject);
|
||||
|
||||
return (
|
||||
<div
|
||||
className={['testing--Account', 'testing--split', className].join(' ')}
|
||||
style={style}
|
||||
>
|
||||
<div className='large'>
|
||||
<Label>{label}</Label>
|
||||
<InputAddress
|
||||
placeholder='0x...'
|
||||
subject={subject}
|
||||
/>
|
||||
</div>
|
||||
<div className='small'>
|
||||
<Label>with an available balance of</Label>
|
||||
<AccountBalance
|
||||
className='ui disabled dropdown selection'
|
||||
classNameUpdated='hasUpdated'
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
29
packages/app-testing/src/App.js
Normal file
29
packages/app-testing/src/App.js
Normal file
@ -0,0 +1,29 @@
|
||||
// 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 { BaseProps } from './types';
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import CallDisplay from './CallDisplay';
|
||||
import CallSelect from './CallSelect';
|
||||
import Nonce from './Nonce';
|
||||
import Sender from './Sender';
|
||||
|
||||
type Props = BaseProps & {};
|
||||
|
||||
export default function App ({ className, style }: Props) {
|
||||
return (
|
||||
<div
|
||||
className={['testing--App', className].join(' ')}
|
||||
style={style}
|
||||
>
|
||||
<Sender />
|
||||
<CallSelect />
|
||||
<Nonce />
|
||||
<CallDisplay />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
18
packages/app-testing/src/CallDisplay/CallDisplay.css
Normal file
18
packages/app-testing/src/CallDisplay/CallDisplay.css
Normal file
@ -0,0 +1,18 @@
|
||||
/* 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. */
|
||||
|
||||
.testing--CallDisplay {
|
||||
margin-top: 1.5rem;
|
||||
}
|
||||
|
||||
.testing--CallDisplay-error {
|
||||
color: red;
|
||||
opacity: 0.75;
|
||||
}
|
||||
|
||||
.testing--CallDisplay-Component {
|
||||
margin: 1.5rem 0;
|
||||
}
|
||||
|
||||
.testing--CallDisplay-Button {}
|
||||
21
packages/app-testing/src/CallDisplay/Error.js
Normal file
21
packages/app-testing/src/CallDisplay/Error.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 { BaseProps } from '../types';
|
||||
|
||||
import './CallDisplay.css';
|
||||
|
||||
import React from 'react';
|
||||
|
||||
export default function Error ({ className, style }: BaseProps): React$Node {
|
||||
return (
|
||||
<div
|
||||
className={['testing--CallDisplay-error', className].join(' ')}
|
||||
style={style}
|
||||
>
|
||||
ERROR: Invalid or unimplemented extrinsic function
|
||||
</div>
|
||||
);
|
||||
}
|
||||
69
packages/app-testing/src/CallDisplay/index.js
Normal file
69
packages/app-testing/src/CallDisplay/index.js
Normal file
@ -0,0 +1,69 @@
|
||||
// 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 { BaseProps, BaseContext } from '../types';
|
||||
|
||||
import './CallDisplay.css';
|
||||
|
||||
import PropTypes from 'prop-types';
|
||||
import React from 'react';
|
||||
import Button from 'semantic-ui-react/dist/es/elements/Button';
|
||||
import withObservable from '@polkadot/rx-react/with/observable';
|
||||
|
||||
import StakingStake from '../Staking/Stake';
|
||||
import StakingTransfer from '../Staking/Transfer';
|
||||
import StakingUnstake from '../Staking/Unstake';
|
||||
import { extrinsicName } from '../subjects';
|
||||
import ErrorComponent from './Error';
|
||||
import submitExtrinsic from './submit';
|
||||
|
||||
type ValueGetter = {
|
||||
getValues: () => Array<mixed>
|
||||
}
|
||||
|
||||
type Props = BaseProps & {
|
||||
value?: string;
|
||||
};
|
||||
|
||||
const COMPONENTS = {
|
||||
'staking_stake': StakingStake,
|
||||
'staking_transfer': StakingTransfer,
|
||||
'staking_unstake': StakingUnstake
|
||||
};
|
||||
|
||||
function CallDisplay ({ className, style, value }: Props, { api }: BaseContext) {
|
||||
// flowlint-next-line sketchy-null-string:off
|
||||
if (!value) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const Component = COMPONENTS[value] || ErrorComponent;
|
||||
const onSubmit = () => {
|
||||
// flowlint-next-line unclear-type:off
|
||||
submitExtrinsic(api, value, ((Component: any): ValueGetter).getValues());
|
||||
};
|
||||
|
||||
return (
|
||||
<div
|
||||
className={['testing--CallDisplay', className].join(' ')}
|
||||
style={style}
|
||||
>
|
||||
<Component className='testing--CallDisplay-Component' />
|
||||
<Button
|
||||
className='testing--CallDisplay-Execute'
|
||||
onClick={onSubmit}
|
||||
primary
|
||||
>
|
||||
Submit Extrinsic
|
||||
</Button>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
CallDisplay.contextTypes = {
|
||||
api: PropTypes.object
|
||||
};
|
||||
|
||||
export default withObservable(CallDisplay, extrinsicName);
|
||||
32
packages/app-testing/src/CallDisplay/submit.js
Normal file
32
packages/app-testing/src/CallDisplay/submit.js
Normal file
@ -0,0 +1,32 @@
|
||||
// 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 { RxApiInterface } from '@polkadot/rx-api/types';
|
||||
|
||||
import encode from '../encode';
|
||||
import extrinsics from '../extrinsics';
|
||||
import keyring from '../keyring';
|
||||
import { senderAddr, senderIndex } from '../subjects';
|
||||
|
||||
export default function submit (api: RxApiInterface, method: string, values: Array<mixed>): void {
|
||||
// TODO: Display some progress once we have a subscription
|
||||
api.author
|
||||
.submitExtrinsic(
|
||||
encode(
|
||||
extrinsics[method],
|
||||
// flowlint-next-line unclear-type:off
|
||||
keyring.getPair(((senderAddr.getValue(): any): Uint8Array)),
|
||||
senderIndex.getValue() || 0,
|
||||
values
|
||||
)
|
||||
)
|
||||
.toPromise()
|
||||
.then((result) => {
|
||||
console.log('submitExtrinsic: result=', result);
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('submitExtrinsic: error=', error);
|
||||
});
|
||||
}
|
||||
43
packages/app-testing/src/CallSelect.js
Normal file
43
packages/app-testing/src/CallSelect.js
Normal file
@ -0,0 +1,43 @@
|
||||
// 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 { BaseProps } from './types';
|
||||
|
||||
import React from 'react';
|
||||
import Dropdown from 'semantic-ui-react/dist/es/modules/Dropdown';
|
||||
import Label from 'semantic-ui-react/dist/es/elements/Label';
|
||||
|
||||
import { extrinsicName } from './subjects';
|
||||
import extrinsics from './extrinsics';
|
||||
|
||||
type Props = BaseProps & {};
|
||||
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
const onChange = (event: SyntheticEvent<*>, { value }): void => {
|
||||
extrinsicName.next(value);
|
||||
};
|
||||
|
||||
const options = Object.keys(extrinsics).map((value) => ({
|
||||
text: extrinsics[value].description,
|
||||
value
|
||||
}));
|
||||
|
||||
export default function CallSelect ({ className, style }: Props) {
|
||||
return (
|
||||
<div
|
||||
className={['testing--CallSelect', 'testing--split', className].join(' ')}
|
||||
style={style}
|
||||
>
|
||||
<div className='large'>
|
||||
<Label>submit the following extrinsic</Label>
|
||||
<Dropdown
|
||||
selection
|
||||
onChange={onChange}
|
||||
options={options}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@ -3,8 +3,8 @@
|
||||
// of the ISC license. See the LICENSE file for details.
|
||||
// @flow
|
||||
|
||||
import type { BaseProps } from '@polkadot/portal/types';
|
||||
import type { KeyringPair } from '@poladot/util-keyring/types';
|
||||
import type { KeyringPair } from '@polkadot/util-keyring/types';
|
||||
import type { BaseProps } from '../types';
|
||||
|
||||
import './PairDisplay.css';
|
||||
|
||||
@ -16,8 +16,9 @@ type Props = BaseProps & {
|
||||
pair: KeyringPair
|
||||
};
|
||||
|
||||
export default function PairDisplay ({ className, name, pair, style }: Props): React$Node {
|
||||
export default function PairDisplay ({ className, pair, style }: Props): React$Node {
|
||||
const publicKey = pair.publicKey();
|
||||
const { name } = pair.getMeta();
|
||||
|
||||
return (
|
||||
<div
|
||||
51
packages/app-testing/src/InputAddress/index.js
Normal file
51
packages/app-testing/src/InputAddress/index.js
Normal file
@ -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 { BaseProps } from '../types';
|
||||
|
||||
import './InputAddress.css';
|
||||
|
||||
import React from 'react';
|
||||
import Dropdown from 'semantic-ui-react/dist/es/modules/Dropdown';
|
||||
|
||||
import PairDisplay from './PairDisplay';
|
||||
import keyring from '../keyring';
|
||||
|
||||
type Props = BaseProps & {
|
||||
subject: rxjs$Subject<*>
|
||||
};
|
||||
|
||||
const testOptions = keyring.getPairs().map((pair) => {
|
||||
const publicKey = pair.publicKey();
|
||||
|
||||
return {
|
||||
text: (
|
||||
<PairDisplay
|
||||
key={publicKey.toString()}
|
||||
pair={pair}
|
||||
/>
|
||||
),
|
||||
value: publicKey
|
||||
};
|
||||
});
|
||||
|
||||
export default function InputAddress (props: Props): React$Node {
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
const onChange = (event: SyntheticEvent<*>, { value }): void => {
|
||||
if (props.subject) {
|
||||
props.subject.next(value);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Dropdown
|
||||
{...props}
|
||||
className={['ui--InputAddress', props.className].join(' ')}
|
||||
selection
|
||||
options={testOptions}
|
||||
onChange={onChange}
|
||||
/>
|
||||
);
|
||||
}
|
||||
47
packages/app-testing/src/Nonce.js
Normal file
47
packages/app-testing/src/Nonce.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 { BaseProps } from './types';
|
||||
|
||||
import React from 'react';
|
||||
import Label from 'semantic-ui-react/dist/es/elements/Label';
|
||||
import RxNonce from '@polkadot/rx-react/Nonce';
|
||||
import withObservableParams from '@polkadot/rx-react/with/observableParams';
|
||||
import u8aToBn from '@polkadot/util/u8a/toBn';
|
||||
|
||||
import { senderAddr, senderIndex } from './subjects';
|
||||
|
||||
type Props = BaseProps & {};
|
||||
|
||||
const SenderNonce = withObservableParams(RxNonce, senderAddr);
|
||||
const onNonceChange = (value): void => {
|
||||
// flowlint-next-line sketchy-null-mixed:off
|
||||
if (!value || value.length !== 8) {
|
||||
return;
|
||||
}
|
||||
|
||||
senderIndex.next(
|
||||
// flowlint-next-line unclear-type:off
|
||||
u8aToBn(((value: any): Uint8Array), true)
|
||||
);
|
||||
};
|
||||
|
||||
export default function Nonce ({ className, style }: Props) {
|
||||
return (
|
||||
<div
|
||||
className={['testing--split', className].join(' ')}
|
||||
style={style}
|
||||
>
|
||||
<div className='small'>
|
||||
<Label>with an index</Label>
|
||||
<SenderNonce
|
||||
className='ui disabled dropdown selection'
|
||||
classNameUpdated='hasUpdated'
|
||||
onChange={onNonceChange}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
24
packages/app-testing/src/Recipient.js
Normal file
24
packages/app-testing/src/Recipient.js
Normal file
@ -0,0 +1,24 @@
|
||||
// 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 { BaseProps } from './types';
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import Account from './Account';
|
||||
import { recipientAddr } from './subjects';
|
||||
|
||||
type Props = BaseProps & {};
|
||||
|
||||
export default function Recipient (props: Props) {
|
||||
return (
|
||||
<Account
|
||||
{...props}
|
||||
className={['testing--Recipient', props.className].join(' ')}
|
||||
label='to the recipient'
|
||||
subject={recipientAddr}
|
||||
/>
|
||||
);
|
||||
}
|
||||
24
packages/app-testing/src/Sender.js
Normal file
24
packages/app-testing/src/Sender.js
Normal file
@ -0,0 +1,24 @@
|
||||
// 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 { BaseProps } from './types';
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import Account from './Account';
|
||||
import { senderAddr } from './subjects';
|
||||
|
||||
type Props = BaseProps & {};
|
||||
|
||||
export default function Sender (props: Props) {
|
||||
return (
|
||||
<Account
|
||||
{...props}
|
||||
className={['testing--Sender', props.className].join(' ')}
|
||||
label='using the selected account'
|
||||
subject={senderAddr}
|
||||
/>
|
||||
);
|
||||
}
|
||||
8
packages/app-testing/src/Staking/Stake/getValues.js
Normal file
8
packages/app-testing/src/Staking/Stake/getValues.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
|
||||
|
||||
export default function getValues (): Array<mixed> {
|
||||
return [];
|
||||
}
|
||||
25
packages/app-testing/src/Staking/Stake/index.js
Normal file
25
packages/app-testing/src/Staking/Stake/index.js
Normal file
@ -0,0 +1,25 @@
|
||||
// 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 { BaseProps } from '../../types';
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import getValues from './getValues';
|
||||
|
||||
type Props = BaseProps & {};
|
||||
|
||||
function StakingStake ({ className, style }: Props) {
|
||||
return (
|
||||
<div
|
||||
className={['testing--StakingStake', className].join(' ')}
|
||||
style={style}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
StakingStake.getValues = getValues;
|
||||
|
||||
export default StakingStake;
|
||||
41
packages/app-testing/src/Staking/Transfer/Amount.js
Normal file
41
packages/app-testing/src/Staking/Transfer/Amount.js
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.
|
||||
// @flow
|
||||
|
||||
import type { BaseProps } from '../../types';
|
||||
|
||||
import BN from 'bn.js';
|
||||
import React from 'react';
|
||||
import Input from 'semantic-ui-react/dist/es/elements/Input';
|
||||
import Label from 'semantic-ui-react/dist/es/elements/Label';
|
||||
|
||||
import { amount } from './subjects';
|
||||
|
||||
type Props = BaseProps & {};
|
||||
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
const onChange = (event: SyntheticEvent<*>, { value }): void => {
|
||||
amount.next(
|
||||
new BN(value || 0)
|
||||
);
|
||||
};
|
||||
|
||||
export default function Amount ({ className, style }: Props) {
|
||||
return (
|
||||
<div
|
||||
className={['testing--split', className].join(' ')}
|
||||
style={style}
|
||||
>
|
||||
<div className='small'>
|
||||
<Label>sending an amount of</Label>
|
||||
<Input
|
||||
defaultValue={0}
|
||||
min={0}
|
||||
onChange={onChange}
|
||||
type='number'
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
14
packages/app-testing/src/Staking/Transfer/getValues.js
Normal file
14
packages/app-testing/src/Staking/Transfer/getValues.js
Normal file
@ -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 { recipientAddr } from '../../subjects';
|
||||
import { amount } from './subjects';
|
||||
|
||||
export default function getValues (): Array<mixed> {
|
||||
return [
|
||||
recipientAddr.getValue(),
|
||||
amount.getValue()
|
||||
];
|
||||
}
|
||||
30
packages/app-testing/src/Staking/Transfer/index.js
Normal file
30
packages/app-testing/src/Staking/Transfer/index.js
Normal file
@ -0,0 +1,30 @@
|
||||
// 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 { BaseProps } from '../../types';
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import Recipient from '../../Recipient';
|
||||
import Amount from './Amount';
|
||||
import getValues from './getValues';
|
||||
|
||||
type Props = BaseProps & {};
|
||||
|
||||
function StakingTransfer ({ className, style }: Props) {
|
||||
return (
|
||||
<div
|
||||
className={['testing--StakingTransfer', className].join(' ')}
|
||||
style={style}
|
||||
>
|
||||
<Amount />
|
||||
<Recipient />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
StakingTransfer.getValues = getValues;
|
||||
|
||||
export default StakingTransfer;
|
||||
@ -3,8 +3,7 @@
|
||||
// of the ISC license. See the LICENSE file for details.
|
||||
// @flow
|
||||
|
||||
import { ReplaySubject } from 'rxjs/ReplaySubject';
|
||||
import BN from 'bn.js';
|
||||
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
|
||||
|
||||
export default function addr () {
|
||||
return new ReplaySubject(1);
|
||||
}
|
||||
export const amount = new BehaviorSubject(new BN(0));
|
||||
8
packages/app-testing/src/Staking/Unstake/getValues.js
Normal file
8
packages/app-testing/src/Staking/Unstake/getValues.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
|
||||
|
||||
export default function getValues (): Array<mixed> {
|
||||
return [];
|
||||
}
|
||||
25
packages/app-testing/src/Staking/Unstake/index.js
Normal file
25
packages/app-testing/src/Staking/Unstake/index.js
Normal file
@ -0,0 +1,25 @@
|
||||
// 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 { BaseProps } from '../../types';
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import getValues from './getValues';
|
||||
|
||||
type Props = BaseProps & {};
|
||||
|
||||
function StakingUnstake ({ className, style }: Props) {
|
||||
return (
|
||||
<div
|
||||
className={['testing--StakingUnstake', className].join(' ')}
|
||||
style={style}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
StakingUnstake.getValues = getValues;
|
||||
|
||||
export default StakingUnstake;
|
||||
33
packages/app-testing/src/encode/index.js
Normal file
33
packages/app-testing/src/encode/index.js
Normal file
@ -0,0 +1,33 @@
|
||||
// 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: Move to API
|
||||
|
||||
import type BN from 'bn.js';
|
||||
import type { KeyringPair } from '@polkadot/util-keyring/types';
|
||||
import type { Extrinsic } from '../extrinsics/types';
|
||||
|
||||
const assert = require('@polkadot/util/assert');
|
||||
const bnToU8a = require('@polkadot/util/bn/toU8a');
|
||||
const u8aConcat = require('@polkadot/util/u8a/concat');
|
||||
|
||||
const encodeParams = require('./params');
|
||||
|
||||
module.exports = function encode ({ index, params }: Extrinsic, sender?: ?KeyringPair, nonce: number | BN, values: Array<mixed>): Uint8Array {
|
||||
assert(sender, 'Expected a valid sender to extrinsic encode');
|
||||
|
||||
const encodedParams = encodeParams(values, params);
|
||||
const message = u8aConcat(
|
||||
// $FlowFixMe sender checked above
|
||||
sender.publicKey(),
|
||||
bnToU8a(nonce, 64, true),
|
||||
index,
|
||||
encodedParams
|
||||
);
|
||||
// $FlowFixMe sender checked above
|
||||
const signature = sender.sign(message);
|
||||
|
||||
return u8aConcat(message, signature);
|
||||
};
|
||||
23
packages/app-testing/src/encode/param.js
Normal file
23
packages/app-testing/src/encode/param.js
Normal file
@ -0,0 +1,23 @@
|
||||
// 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 '../extrinsics/types';
|
||||
|
||||
const bnToU8a = require('@polkadot/util/bn/toU8a');
|
||||
|
||||
// flowlint-next-line unclear-type:off
|
||||
module.exports = function encodeValue (value: any, type: Extrinsic$Type): Uint8Array {
|
||||
switch (type) {
|
||||
case 'AccountId':
|
||||
return value;
|
||||
|
||||
case 'Balance':
|
||||
case 'BlockNumber':
|
||||
return bnToU8a(value, 64, true);
|
||||
|
||||
default:
|
||||
throw new Error(`Unable to encode value with type '${type}'`);
|
||||
}
|
||||
};
|
||||
16
packages/app-testing/src/encode/params.js
Normal file
16
packages/app-testing/src/encode/params.js
Normal file
@ -0,0 +1,16 @@
|
||||
// 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$Params } from '../extrinsics/types';
|
||||
|
||||
const u8aConcat = require('@polkadot/util/u8a/concat');
|
||||
|
||||
const encodeParam = require('./param');
|
||||
|
||||
module.exports = function encodeParams (values: Array<mixed>, params: Extrinsic$Params): Uint8Array {
|
||||
return u8aConcat.apply(null, values.map((value, index) => {
|
||||
return encodeParam(value, params[index]);
|
||||
}));
|
||||
};
|
||||
@ -3,8 +3,7 @@
|
||||
// of the ISC license. See the LICENSE file for details.
|
||||
// @flow
|
||||
|
||||
import 'semantic-ui-css/semantic.min.css';
|
||||
import type { ExtrinsicsBasic } from './types';
|
||||
|
||||
import Body from './Body';
|
||||
|
||||
export default Body;
|
||||
module.exports = ({
|
||||
}: ExtrinsicsBasic);
|
||||
9
packages/app-testing/src/extrinsics/council.js
Normal file
9
packages/app-testing/src/extrinsics/council.js
Normal file
@ -0,0 +1,9 @@
|
||||
// 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 { ExtrinsicsBasic } from './types';
|
||||
|
||||
module.exports = ({
|
||||
}: ExtrinsicsBasic);
|
||||
9
packages/app-testing/src/extrinsics/councilVoting.js
Normal file
9
packages/app-testing/src/extrinsics/councilVoting.js
Normal file
@ -0,0 +1,9 @@
|
||||
// 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 { ExtrinsicsBasic } from './types';
|
||||
|
||||
module.exports = ({
|
||||
}: ExtrinsicsBasic);
|
||||
9
packages/app-testing/src/extrinsics/democracy.js
Normal file
9
packages/app-testing/src/extrinsics/democracy.js
Normal file
@ -0,0 +1,9 @@
|
||||
// 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 { ExtrinsicsBasic } from './types';
|
||||
|
||||
module.exports = ({
|
||||
}: ExtrinsicsBasic);
|
||||
56
packages/app-testing/src/extrinsics/index.js
Normal file
56
packages/app-testing/src/extrinsics/index.js
Normal file
@ -0,0 +1,56 @@
|
||||
// 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: Move to API
|
||||
|
||||
import type { Extrinsics, ExtrinsicsBasic } from './types';
|
||||
|
||||
const bnToU8a = require('@polkadot/util/bn/toU8a');
|
||||
const u8aConcat = require('@polkadot/util/u8a/concat');
|
||||
const u8aToHex = require('@polkadot/util/u8a/toHex');
|
||||
|
||||
const consensus = require('./consensus');
|
||||
const council = require('./council');
|
||||
const councilVoting = require('./councilVoting');
|
||||
const democracy = require('./democracy');
|
||||
const session = require('./session');
|
||||
const staking = require('./staking');
|
||||
|
||||
const all: { [string]: ExtrinsicsBasic } = {
|
||||
consensus, // 0
|
||||
session, // 1
|
||||
staking, // 2
|
||||
democracy, // 3
|
||||
council, // 4
|
||||
councilVoting // 5
|
||||
};
|
||||
|
||||
const flattenned: Extrinsics = Object
|
||||
.keys(all)
|
||||
.reduce((flat, sectionName, _index) => {
|
||||
const section = all[sectionName];
|
||||
const sectionIndex = bnToU8a(_index, 8);
|
||||
|
||||
return Object
|
||||
.keys(section)
|
||||
.reduce((flat, method, _index) => {
|
||||
const name = `${sectionName}_${method}`;
|
||||
const methodIndex = bnToU8a(_index, 8);
|
||||
const index = u8aConcat(sectionIndex, methodIndex);
|
||||
const indexHex = u8aToHex(index);
|
||||
|
||||
flat[name] = {
|
||||
index,
|
||||
indexHex,
|
||||
name,
|
||||
// flowlint-next-line inexact-spread:off
|
||||
...section[method]
|
||||
};
|
||||
|
||||
return flat;
|
||||
}, flat);
|
||||
}, ({}: $Shape<Extrinsics>));
|
||||
|
||||
module.exports = flattenned;
|
||||
9
packages/app-testing/src/extrinsics/session.js
Normal file
9
packages/app-testing/src/extrinsics/session.js
Normal file
@ -0,0 +1,9 @@
|
||||
// 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 { ExtrinsicsBasic } from './types';
|
||||
|
||||
module.exports = ({
|
||||
}: ExtrinsicsBasic);
|
||||
21
packages/app-testing/src/extrinsics/staking.js
Normal file
21
packages/app-testing/src/extrinsics/staking.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 { ExtrinsicsBasic } from './types';
|
||||
|
||||
module.exports = ({
|
||||
transfer: {
|
||||
description: 'Staking Transfer',
|
||||
params: ['AccountId', 'Balance']
|
||||
},
|
||||
stake: {
|
||||
description: 'Stake',
|
||||
params: []
|
||||
},
|
||||
unstake: {
|
||||
description: 'Unstake',
|
||||
params: []
|
||||
}
|
||||
}: ExtrinsicsBasic);
|
||||
27
packages/app-testing/src/extrinsics/types.js
Normal file
27
packages/app-testing/src/extrinsics/types.js
Normal file
@ -0,0 +1,27 @@
|
||||
// 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
|
||||
|
||||
export type Extrinsic$Type = 'AccountId' | 'Balance' | 'BlockNumber';
|
||||
|
||||
export type Extrinsic$Params = Array<Extrinsic$Type>;
|
||||
|
||||
export type ExtrinsicBasic = {
|
||||
description: string,
|
||||
params: Extrinsic$Params
|
||||
}
|
||||
|
||||
export type Extrinsic = ExtrinsicBasic & {
|
||||
index: Uint8Array,
|
||||
indexHex: string,
|
||||
name: string
|
||||
};
|
||||
|
||||
export type Extrinsics = {
|
||||
[string]: Extrinsic
|
||||
}
|
||||
|
||||
export type ExtrinsicsBasic = {
|
||||
[string]: ExtrinsicBasic
|
||||
}
|
||||
46
packages/app-testing/src/index.css
Normal file
46
packages/app-testing/src/index.css
Normal file
@ -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. */
|
||||
|
||||
.testing--full,
|
||||
.testing--split {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.testing--split {
|
||||
display:flex;
|
||||
flex-wrap:wrap;
|
||||
flex-direction:row;
|
||||
justify-content:flex-start;
|
||||
align-items:stretch;
|
||||
}
|
||||
|
||||
.testing--split > div {
|
||||
box-sizing: border-box;
|
||||
padding-right: 0.5rem;
|
||||
}
|
||||
|
||||
.testing--split > div.full {
|
||||
flex: 0 100%;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.testing--split > div.large {
|
||||
flex: 0 75%;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.testing--split > div.medium {
|
||||
flex: 0 50%;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.testing--split > div.small {
|
||||
flex: 0 25%;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.hasUpdated {
|
||||
background: #ffffe0 !important;
|
||||
transition: all 0.7s ease-in-out;
|
||||
}
|
||||
@ -3,8 +3,8 @@
|
||||
// of the ISC license. See the LICENSE file for details.
|
||||
// @flow
|
||||
|
||||
import addr from './addr';
|
||||
import './index.css';
|
||||
|
||||
const subject = addr();
|
||||
import App from './App';
|
||||
|
||||
export default subject;
|
||||
export default App;
|
||||
13
packages/app-testing/src/subjects.js
Normal file
13
packages/app-testing/src/subjects.js
Normal file
@ -0,0 +1,13 @@
|
||||
// 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 { BehaviorSubject } from 'rxjs/BehaviorSubject';
|
||||
|
||||
import BN from 'bn.js';
|
||||
|
||||
export const extrinsicName = new BehaviorSubject();
|
||||
export const recipientAddr = new BehaviorSubject();
|
||||
export const senderAddr = new BehaviorSubject();
|
||||
export const senderIndex = new BehaviorSubject(new BN(0));
|
||||
17
packages/app-testing/src/types.js
Normal file
17
packages/app-testing/src/types.js
Normal file
@ -0,0 +1,17 @@
|
||||
// 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 { RxApiInterface } from '@polkadot/rx-api/types';
|
||||
|
||||
export type BaseProps = {
|
||||
className?: string,
|
||||
style?: {
|
||||
[string]: string
|
||||
}
|
||||
};
|
||||
|
||||
export type BaseContext = {
|
||||
api: RxApiInterface
|
||||
};
|
||||
@ -1,78 +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 { BaseProps } from '@polkadot/portal/types';
|
||||
|
||||
import './Body.css';
|
||||
|
||||
import React from 'react';
|
||||
// import { Observable } from 'rxjs/Observable';
|
||||
// import { from as fromObservable } from 'rxjs/observable/from';
|
||||
import Input from 'semantic-ui-react/dist/es/elements/Input';
|
||||
import Label from 'semantic-ui-react/dist/es/elements/Label';
|
||||
import Balance from '@polkadot/rx-react/Balance';
|
||||
import BlockNumber from '@polkadot/rx-react/BlockNumber';
|
||||
import ContextProvider from '@polkadot/rx-react/ContextProvider';
|
||||
import withObservableParams from '@polkadot/rx-react/with/observableParams';
|
||||
|
||||
import InputAddress from '../InputAddress';
|
||||
import addrRecipient from '../subject/addrRecipient';
|
||||
import addrSender from '../subject/addrSender';
|
||||
|
||||
type Props = BaseProps & {};
|
||||
|
||||
function publicMap (pair: KeyringPair): Uint8Array {
|
||||
return pair.publicKey();
|
||||
}
|
||||
|
||||
const RecipientBalance = withObservableParams(Balance, addrRecipient, publicMap);
|
||||
const SenderBalance = withObservableParams(Balance, addrSender, publicMap);
|
||||
|
||||
export default function Body ({ className, style }: Props) {
|
||||
return (
|
||||
<ContextProvider>
|
||||
<div
|
||||
className={['testing--Body', className].join(' ')}
|
||||
style={style}
|
||||
>
|
||||
<BlockNumber
|
||||
className='testing--Body-BlockNumber'
|
||||
label='best block #'
|
||||
/>
|
||||
|
||||
<div>
|
||||
<Label>using the selected account</Label>
|
||||
<InputAddress
|
||||
placeholder='0x...'
|
||||
subject={addrSender}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<Label>with an available balance of</Label>
|
||||
<SenderBalance className='ui disabled dropdown selection' />
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<Label>send an amount of</Label>
|
||||
<Input />
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<Label>to the recipient</Label>
|
||||
<InputAddress
|
||||
placeholder='0x...'
|
||||
subject={addrRecipient}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<Label>with an available balance of</Label>
|
||||
<RecipientBalance className='ui disabled dropdown selection' />
|
||||
</div>
|
||||
</div>
|
||||
</ContextProvider>
|
||||
);
|
||||
}
|
||||
@ -1,50 +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 { BaseProps } from '@polkadot/portal/types';
|
||||
|
||||
import './InputAddress.css';
|
||||
|
||||
import React from 'react';
|
||||
import Dropdown from 'semantic-ui-react/dist/es/modules/Dropdown';
|
||||
|
||||
import PairDisplay from './PairDisplay';
|
||||
import keyring from '../keyring';
|
||||
|
||||
type Props = BaseProps & {
|
||||
subject: rxjs$Subject
|
||||
};
|
||||
|
||||
const testOptions = Object.keys(keyring).map((name) => ({
|
||||
text: (
|
||||
<PairDisplay
|
||||
key={name}
|
||||
name={name}
|
||||
pair={keyring[name]}
|
||||
/>
|
||||
),
|
||||
value: name
|
||||
}));
|
||||
|
||||
export default function InputAddress (_props: Props): React$Node {
|
||||
const props = Object.assign({}, _props, {
|
||||
className: ['ui--InputAddress', _props.className].join(' ')
|
||||
});
|
||||
const onChange = (_, { value }) => {
|
||||
if (_props.subject) {
|
||||
_props.subject.next(keyring[value]);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Dropdown
|
||||
search
|
||||
selection
|
||||
options={testOptions}
|
||||
onChange={onChange}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@ -14,7 +14,9 @@
|
||||
"test": "react-scripts test --env=jsdom --coverage"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@polkadot/content-testing": "^0.1.0",
|
||||
"@polkadot/app-home": "^0.1.0",
|
||||
"@polkadot/app-testing": "^0.1.0",
|
||||
"@polkadot/rx-react": "^0.2.13",
|
||||
"@polkadot/ui-react": "^0.9.10",
|
||||
"i18next": "^11.1.1",
|
||||
"i18next-browser-languagedetector": "^2.2.0",
|
||||
|
||||
@ -23,11 +23,11 @@ export default translate(['portal'])(
|
||||
style={style}
|
||||
>
|
||||
{
|
||||
routes.map(({ component, isExact, key, path }) => (
|
||||
routes.map(({ component, isExact, name, path }) => (
|
||||
<Route
|
||||
component={component}
|
||||
exact={isExact}
|
||||
key={key}
|
||||
key={name}
|
||||
path={path}
|
||||
/>
|
||||
))
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
// of the ISC license. See the LICENSE file for details.
|
||||
// @flow
|
||||
|
||||
import type { BaseProps, Routes } from '../types';
|
||||
import type { BaseProps, Route } from '../types';
|
||||
|
||||
import './Item.css';
|
||||
|
||||
@ -12,7 +12,7 @@ import { NavLink } from 'react-router-dom';
|
||||
import Icon from 'semantic-ui-react/dist/es/elements/Icon';
|
||||
import Menu from 'semantic-ui-react/dist/es/collections/Menu';
|
||||
|
||||
type Props = BaseProps & Routes & {};
|
||||
type Props = BaseProps & Route & {};
|
||||
|
||||
export default function Item ({ className, i18n, icon, isExact, name, path, style, t }: Props) {
|
||||
return (
|
||||
|
||||
@ -30,7 +30,7 @@ export default translate(['portal'])(
|
||||
{
|
||||
routes.map((props) => (
|
||||
<Item
|
||||
name={props.key}
|
||||
key={props.name}
|
||||
t={t}
|
||||
{...props}
|
||||
/>
|
||||
|
||||
@ -11,15 +11,18 @@ import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import { I18nextProvider } from 'react-i18next';
|
||||
import { HashRouter } from 'react-router-dom';
|
||||
import ContextProvider from '@polkadot/rx-react/ContextProvider';
|
||||
|
||||
import i18n from './i18n';
|
||||
import App from './App';
|
||||
|
||||
ReactDOM.render(
|
||||
<I18nextProvider i18n={i18n}>
|
||||
<HashRouter>
|
||||
<App />
|
||||
</HashRouter>
|
||||
<ContextProvider>
|
||||
<HashRouter>
|
||||
<App />
|
||||
</HashRouter>
|
||||
</ContextProvider>
|
||||
</I18nextProvider>,
|
||||
// flowlint-next-line unclear-type:off
|
||||
((document.getElementById('root'): any): Element)
|
||||
|
||||
22
packages/portal/src/routes/home.js
Normal file
22
packages/portal/src/routes/home.js
Normal file
@ -0,0 +1,22 @@
|
||||
// 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 Home from '@polkadot/app-home';
|
||||
|
||||
export default ([
|
||||
{
|
||||
component: Home,
|
||||
i18n: {
|
||||
defaultValue: 'Home'
|
||||
},
|
||||
icon: 'home',
|
||||
isExact: true,
|
||||
isHidden: false,
|
||||
name: 'home',
|
||||
path: '/'
|
||||
}
|
||||
]: Routes);
|
||||
@ -6,11 +6,11 @@
|
||||
import type { Routes } from '../types';
|
||||
|
||||
// import accounts from './accounts';
|
||||
// import home from './home';
|
||||
import home from './home';
|
||||
// import settings from './settings';
|
||||
import testing from './testing';
|
||||
|
||||
export default (([].concat(
|
||||
testing
|
||||
// , home, accounts, settings
|
||||
home, testing
|
||||
// , accounts, settings
|
||||
)): Routes);
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
|
||||
import type { Routes } from '../types';
|
||||
|
||||
import Testing from '@polkadot/content-testing';
|
||||
import Testing from '@polkadot/app-testing';
|
||||
|
||||
export default ([
|
||||
{
|
||||
@ -14,9 +14,9 @@ export default ([
|
||||
defaultValue: 'Testing'
|
||||
},
|
||||
icon: 'braille',
|
||||
isExact: true,
|
||||
isExact: false,
|
||||
isHidden: false,
|
||||
key: 'testing',
|
||||
path: '/'
|
||||
name: 'testing',
|
||||
path: '/testing'
|
||||
}
|
||||
]: Routes);
|
||||
|
||||
@ -3,6 +3,8 @@
|
||||
// of the ISC license. See the LICENSE file for details.
|
||||
// @flow
|
||||
|
||||
import type { RxApiInterface } from '@polkadot/rx-api/types';
|
||||
|
||||
export type BaseProps = {
|
||||
className?: string,
|
||||
style?: {
|
||||
@ -11,10 +13,14 @@ export type BaseProps = {
|
||||
t: I18Next$Translate
|
||||
};
|
||||
|
||||
export type BaseContext = {
|
||||
api: RxApiInterface
|
||||
};
|
||||
|
||||
export type Route = {
|
||||
component: React$StatelessFunctionalComponent<*>,
|
||||
i18n: I18Nex$tTranslate$Config,
|
||||
icon: React$StatelessFunctionalComponent<*>,
|
||||
i18n: I18Next$Translate$Config,
|
||||
icon: React$StatelessFunctionalComponent<*> | string,
|
||||
isExact: boolean,
|
||||
isHidden: boolean,
|
||||
name: string,
|
||||
|
||||
80
yarn.lock
80
yarn.lock
@ -1212,9 +1212,9 @@
|
||||
"@polkadot/util" "^0.18.6"
|
||||
babel-runtime "^6.26.0"
|
||||
|
||||
"@polkadot/dev@^0.17.8":
|
||||
version "0.17.8"
|
||||
resolved "https://registry.yarnpkg.com/@polkadot/dev/-/dev-0.17.8.tgz#d22daea75e88587250c4f8d7ebdda1dd957570df"
|
||||
"@polkadot/dev@^0.17.9":
|
||||
version "0.17.9"
|
||||
resolved "https://registry.yarnpkg.com/@polkadot/dev/-/dev-0.17.9.tgz#12316416384eb3da5e926f2e875902a3c8e4e5a3"
|
||||
dependencies:
|
||||
babel-cli "^6.26.0"
|
||||
babel-core "^6.26.0"
|
||||
@ -1299,20 +1299,20 @@
|
||||
"@polkadot/util" "^0.18.4"
|
||||
babel-runtime "^6.26.0"
|
||||
|
||||
"@polkadot/rx-api@^0.2.2":
|
||||
version "0.2.2"
|
||||
resolved "https://registry.yarnpkg.com/@polkadot/rx-api/-/rx-api-0.2.2.tgz#ee4e28fd2322e4469780d6f1d0e1529a6c95c258"
|
||||
"@polkadot/rx-api@^0.2.13":
|
||||
version "0.2.13"
|
||||
resolved "https://registry.yarnpkg.com/@polkadot/rx-api/-/rx-api-0.2.13.tgz#94004e0e3a134bf75f50e0b22e5fa59c136db0e1"
|
||||
dependencies:
|
||||
"@polkadot/api" "^0.8.14"
|
||||
"@polkadot/api-provider" "^0.8.14"
|
||||
rxjs "^5.5.10"
|
||||
|
||||
"@polkadot/rx-react@^0.2.2":
|
||||
version "0.2.2"
|
||||
resolved "https://registry.yarnpkg.com/@polkadot/rx-react/-/rx-react-0.2.2.tgz#8651dbf8cf7d9f32ebdb7d8d82011e96b92b0c54"
|
||||
"@polkadot/rx-react@^0.2.13":
|
||||
version "0.2.13"
|
||||
resolved "https://registry.yarnpkg.com/@polkadot/rx-react/-/rx-react-0.2.13.tgz#291e7e18eeaeea4dc3d16e50d932ca46da9c492d"
|
||||
dependencies:
|
||||
"@polkadot/rx-api" "^0.2.2"
|
||||
"@polkadot/util" "^0.18.6"
|
||||
"@polkadot/rx-api" "^0.2.13"
|
||||
"@polkadot/util" "^0.19.1"
|
||||
|
||||
"@polkadot/ui-identicon@^0.9.10":
|
||||
version "0.9.10"
|
||||
@ -1358,6 +1358,16 @@
|
||||
tweetnacl "^1.0.0"
|
||||
xxhashjs "^0.2.2"
|
||||
|
||||
"@polkadot/util-crypto@^0.19.1":
|
||||
version "0.19.1"
|
||||
resolved "https://registry.yarnpkg.com/@polkadot/util-crypto/-/util-crypto-0.19.1.tgz#95927de2f8a4384f05b872132e00bfd34aa1ea77"
|
||||
dependencies:
|
||||
babel-runtime "^6.26.0"
|
||||
blakejs "^1.1.0"
|
||||
js-sha3 "^0.7.0"
|
||||
tweetnacl "^1.0.0"
|
||||
xxhashjs "^0.2.2"
|
||||
|
||||
"@polkadot/util-keyring@^0.18.4":
|
||||
version "0.18.4"
|
||||
resolved "https://registry.yarnpkg.com/@polkadot/util-keyring/-/util-keyring-0.18.4.tgz#0e2bdbb3700275025632f42171a3fecacde513e3"
|
||||
@ -1374,6 +1384,14 @@
|
||||
"@polkadot/util-crypto" "^0.18.6"
|
||||
babel-runtime "^6.26.0"
|
||||
|
||||
"@polkadot/util-keyring@^0.19.1":
|
||||
version "0.19.1"
|
||||
resolved "https://registry.yarnpkg.com/@polkadot/util-keyring/-/util-keyring-0.19.1.tgz#dbf6e9efbe1dd4de982367c279b3193584db414f"
|
||||
dependencies:
|
||||
"@polkadot/util" "^0.19.1"
|
||||
"@polkadot/util-crypto" "^0.19.1"
|
||||
babel-runtime "^6.26.0"
|
||||
|
||||
"@polkadot/util-rlp@^0.18.5":
|
||||
version "0.18.5"
|
||||
resolved "https://registry.yarnpkg.com/@polkadot/util-rlp/-/util-rlp-0.18.5.tgz#d06a165a1120f293056f81128f93f494ebe7b390"
|
||||
@ -1417,6 +1435,15 @@
|
||||
deasync "^0.1.12"
|
||||
ip-regex "^2.1.0"
|
||||
|
||||
"@polkadot/util@^0.19.1":
|
||||
version "0.19.1"
|
||||
resolved "https://registry.yarnpkg.com/@polkadot/util/-/util-0.19.1.tgz#e19dc51b3d998b489ed26738a3a1e0cded65c020"
|
||||
dependencies:
|
||||
babel-runtime "^6.26.0"
|
||||
bn.js "^4.11.8"
|
||||
deasync "^0.1.12"
|
||||
ip-regex "^2.1.0"
|
||||
|
||||
"@types/node@*":
|
||||
version "9.6.2"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-9.6.2.tgz#e49ac1adb458835e95ca6487bc20f916b37aff23"
|
||||
@ -2064,6 +2091,16 @@ babel-plugin-macros@2.0.0:
|
||||
dependencies:
|
||||
cosmiconfig "3.1.0"
|
||||
|
||||
babel-plugin-module-resolver@^3.1.1:
|
||||
version "3.1.1"
|
||||
resolved "https://registry.yarnpkg.com/babel-plugin-module-resolver/-/babel-plugin-module-resolver-3.1.1.tgz#881cf67e3d4b8400d5eaaefc1be44d2dc1fe404f"
|
||||
dependencies:
|
||||
find-babel-config "^1.1.0"
|
||||
glob "^7.1.2"
|
||||
pkg-up "^2.0.0"
|
||||
reselect "^3.0.1"
|
||||
resolve "^1.4.0"
|
||||
|
||||
babel-plugin-named-asset-import@1.0.0-next.b2fd8db8:
|
||||
version "1.0.0-next.b2fd8db8"
|
||||
resolved "https://registry.yarnpkg.com/babel-plugin-named-asset-import/-/babel-plugin-named-asset-import-1.0.0-next.b2fd8db8.tgz#bd32f356288cbab326196b5f75547bc0dedf540a"
|
||||
@ -4893,6 +4930,13 @@ finalhandler@1.1.1:
|
||||
statuses "~1.4.0"
|
||||
unpipe "~1.0.0"
|
||||
|
||||
find-babel-config@^1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/find-babel-config/-/find-babel-config-1.1.0.tgz#acc01043a6749fec34429be6b64f542ebb5d6355"
|
||||
dependencies:
|
||||
json5 "^0.5.1"
|
||||
path-exists "^3.0.0"
|
||||
|
||||
find-cache-dir@^0.1.1:
|
||||
version "0.1.1"
|
||||
resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-0.1.1.tgz#c8defae57c8a52a8a784f9e31c57c742e993a0b9"
|
||||
@ -8039,7 +8083,7 @@ pkg-dir@^2.0.0:
|
||||
dependencies:
|
||||
find-up "^2.1.0"
|
||||
|
||||
pkg-up@2.0.0:
|
||||
pkg-up@2.0.0, pkg-up@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/pkg-up/-/pkg-up-2.0.0.tgz#c819ac728059a461cab1c3889a2be3c49a004d7f"
|
||||
dependencies:
|
||||
@ -8476,7 +8520,7 @@ promise@^7.1.1:
|
||||
dependencies:
|
||||
asap "~2.0.3"
|
||||
|
||||
prop-types@^15.5.10, prop-types@^15.5.4, prop-types@^15.6.0:
|
||||
prop-types@^15.5.10, prop-types@^15.5.4, prop-types@^15.6.0, prop-types@^15.6.1:
|
||||
version "15.6.1"
|
||||
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.6.1.tgz#36644453564255ddda391191fb3a125cbdf654ca"
|
||||
dependencies:
|
||||
@ -9211,6 +9255,10 @@ requires-port@1.0.x, requires-port@1.x.x, requires-port@~1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff"
|
||||
|
||||
reselect@^3.0.1:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/reselect/-/reselect-3.0.1.tgz#efdaa98ea7451324d092b2b2163a6a1d7a9a2147"
|
||||
|
||||
resolve-cwd@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-2.0.0.tgz#00a9f7387556e27038eae232caa372a6a59b665a"
|
||||
@ -9254,6 +9302,12 @@ resolve@^1.3.2, resolve@^1.3.3, resolve@^1.5.0:
|
||||
dependencies:
|
||||
path-parse "^1.0.5"
|
||||
|
||||
resolve@^1.4.0:
|
||||
version "1.7.1"
|
||||
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.7.1.tgz#aadd656374fd298aee895bc026b8297418677fd3"
|
||||
dependencies:
|
||||
path-parse "^1.0.5"
|
||||
|
||||
restore-cursor@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf"
|
||||
|
||||
Loading…
Reference in New Issue
Block a user