First iteration of Status page (WIP)

This commit is contained in:
Jaco Greeff 2017-04-21 15:20:43 +02:00
parent 2459501f4e
commit 5fc6a5627e
24 changed files with 126 additions and 89 deletions

View File

@ -1,7 +1,7 @@
[
{
"id": "viewHome",
"url": "viewHome",
"id": "home",
"url": "home",
"src": "Home",
"name": "Home",
"description": "Display a status of the node, recently accessed applications, accounts and news",
@ -9,5 +9,16 @@
"version": "2.0.0",
"visible": true,
"secure": true
},
{
"id": "status",
"url": "status",
"src": "Status",
"name": "Status",
"description": "Display an overview of the node including settings, logs and connections",
"author": "Parity Team <admin@ethcore.io>",
"version": "2.0.0",
"visible": true,
"secure": true
}
]

View File

@ -37,7 +37,6 @@ import muiTheme from '~/ui/Theme';
import MainApplication from './main';
import { patchApi } from '~/util/tx';
import { setApi } from '~/redux/providers/apiActions';
import './environment';
@ -70,9 +69,6 @@ ContractInstances.get(api);
const store = initStore(api, hashHistory);
store.dispatch({ type: 'initAll', api });
store.dispatch(setApi(api));
window.secureApi = api;
ReactDOM.render(

View File

@ -63,6 +63,8 @@ export function personalAccountsInfo (accountsInfo) {
return (dispatch, getState) => {
const { api } = getState();
console.log('_fetchOwners', api);
const _fetchOwners = Object
.values(wallets)
.map((wallet) => {

View File

@ -21,7 +21,7 @@ import subscribeToEvents from '~/util/subscribe-to-events';
import registryABI from '~/contracts/abi/registry.json';
import { setReverse, startCachingReverses } from './actions';
import { setReverse } from './actions';
const STORE_KEY = '_parity::reverses';
@ -83,12 +83,6 @@ export default (api) => (store) => {
return (next) => (action) => {
switch (action.type) {
case 'initAll':
next(action);
store.dispatch(startCachingReverses());
break;
case 'startCachingReverses':
const { registry } = Contracts.get(api);
const cached = read(store.getState().nodeStatus.netChain);
@ -120,6 +114,7 @@ export default (api) => (store) => {
});
break;
case 'stopCachingReverses':
if (subscription) {
subscription.unsubscribe();

View File

@ -36,7 +36,8 @@ export function loadTokens (options = {}) {
log.debug('loading tokens', Object.keys(options).length ? options : '');
return (dispatch, getState) => {
const { tokenReg } = Contracts.get();
const { api } = getState();
const { tokenReg } = Contracts.get(api);
tokenReg.getInstance()
.then((tokenRegInstance) => {
@ -54,7 +55,7 @@ export function fetchTokens (_tokenIndexes, options = {}) {
return (dispatch, getState) => {
const { api, images } = getState();
const { tokenReg } = Contracts.get();
const { tokenReg } = Contracts.get(api);
return tokenReg.getInstance()
.then((tokenRegInstance) => {

View File

@ -19,8 +19,10 @@ import { applyMiddleware, createStore } from 'redux';
import initMiddleware from './middleware';
import initReducers from './reducers';
import { load as loadWallet } from './providers/walletActions';
import { setApi } from './providers/apiActions';
import { startCachingReverses } from './providers/registry/actions';
import { init as initRequests } from './providers/requestsActions';
import { load as loadWallet } from './providers/walletActions';
import { setupWorker } from './providers/workerWrapper';
import {
@ -44,8 +46,12 @@ export default function (api, browserHistory, forEmbed = false) {
new PersonalProvider(store, api).start();
new SignerProvider(store, api).start();
store.dispatch(setApi(api));
store.dispatch(startCachingReverses());
store.dispatch(loadWallet(api));
store.dispatch(initRequests(api));
setupWorker(store);
return store;

View File

@ -19,7 +19,7 @@ import {
Accounts, Account, Addresses, Address, Application,
Contract, Contracts, Dapp, Dapps,
Settings, SettingsBackground, SettingsParity, SettingsProxy,
SettingsViews, Signer, Status,
SettingsViews, Signer,
Vaults, Wallet, Web, WriteContract
} from '~/views';
import builtinDapps from '~/config/dappsBuiltin.json';
@ -87,18 +87,14 @@ const settingsRoutes = [
{ path: 'parity', component: SettingsParity }
];
const statusRoutes = [
{ path: ':subpage', component: Status }
];
const routes = [
// Backward Compatible routes
{ path: '/account/:address', onEnter: handleDeprecatedRoute },
{ path: '/address/:address', onEnter: handleDeprecatedRoute },
{ path: '/contract/:address', onEnter: handleDeprecatedRoute },
{ path: '/', onEnter: redirectTo('/home') },
{ path: '/auth', onEnter: redirectTo('/home') },
{ path: '/', onEnter: redirectTo('/apps') },
{ path: '/auth', onEnter: redirectTo('/apps') },
{ path: '/settings', onEnter: redirectTo('/settings/views') }
];
@ -118,11 +114,6 @@ const childRoutes = [
indexRoute: { component: Contracts },
childRoutes: contractsRoutes
},
{
path: 'status',
indexRoute: { component: Status },
childRoutes: statusRoutes
},
{
path: 'settings',
component: Settings,

View File

@ -25,7 +25,7 @@ export default class ContextProvider extends Component {
static propTypes = {
api: PropTypes.object.isRequired,
muiTheme: PropTypes.object.isRequired,
store: PropTypes.object.isRequired,
store: PropTypes.object,
children: PropTypes.node.isRequired
}

View File

@ -278,7 +278,7 @@ export default class MethodDecodingStore {
return Promise.resolve(this._methods[signature]);
}
this._methods[signature] = Contracts.get()
this._methods[signature] = Contracts.get(this.api)
.signatureReg
.lookup(signature)
.then((method) => {

View File

@ -89,8 +89,8 @@ export function subscribeToChanges (api, dappReg, callback) {
});
}
export function fetchBuiltinApps () {
const { dappReg } = Contracts.get();
export function fetchBuiltinApps (api) {
const { dappReg } = Contracts.get(api);
return Promise
.all(builtinApps.map((app) => dappReg.getImage(app.id)))
@ -127,8 +127,8 @@ export function fetchLocalApps (api) {
});
}
export function fetchRegistryAppIds () {
const { dappReg } = Contracts.get();
export function fetchRegistryAppIds (api) {
const { dappReg } = Contracts.get(api);
return dappReg
.count()

View File

@ -137,7 +137,7 @@ export default class DappsStore extends EventEmitter {
return Promise.resolve(this._cachedApps[BUILTIN_APPS_KEY]);
}
this._cachedApps[BUILTIN_APPS_KEY] = fetchBuiltinApps()
this._cachedApps[BUILTIN_APPS_KEY] = fetchBuiltinApps(this._api)
.then((apps) => {
this._cachedApps[BUILTIN_APPS_KEY] = apps;
return apps;
@ -155,7 +155,7 @@ export default class DappsStore extends EventEmitter {
return Promise.resolve(this._registryAppsIds);
}
this._registryAppsIds = fetchRegistryAppIds()
this._registryAppsIds = fetchRegistryAppIds(this._api)
.then((appIds) => {
this._registryAppsIds = appIds;
return this._registryAppsIds;

View File

@ -15,7 +15,7 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
import { observer } from 'mobx-react';
import React, { Component } from 'react';
import React, { Component, PropTypes } from 'react';
import ReactMarkdown from 'react-markdown';
import { SectionList } from '~/ui';
@ -28,7 +28,11 @@ const VERSION_ID = '1';
@observer
export default class News extends Component {
store = Store.get();
static contextTypes = {
api: PropTypes.object.isRequired
};
store = Store.get(this.context.api);
componentWillMount () {
return this.store.retrieveNews(VERSION_ID);

View File

@ -22,12 +22,16 @@ let instance = null;
export default class Store {
@observable newsItems = null;
constructor (api) {
this._api = api;
}
@action setNewsItems = (newsItems) => {
this.newsItems = newsItems;
}
retrieveNews (versionId) {
const contracts = Contracts.get();
const contracts = Contracts.get(this._api);
return contracts.registry
.lookupMeta('paritynews', 'CONTENT')
@ -57,9 +61,9 @@ export default class Store {
});
}
static get () {
static get (api) {
if (!instance) {
instance = new Store();
instance = new Store(api);
}
return instance;

View File

@ -26,10 +26,6 @@ import styles from './urls.css';
@observer
export default class Urls extends Component {
static contextTypes = {
router: PropTypes.object.isRequired
};
static propTypes = {
extensionStore: PropTypes.object.isRequired,
store: PropTypes.object.isRequired

View File

@ -24,7 +24,6 @@ injectTapEventPlugin();
import { api } from './parity';
import { initStore } from '~/redux';
import { setApi } from '~/redux/providers/apiActions';
import ContextProvider from '~/ui/ContextProvider';
import muiTheme from '~/ui/Theme';
@ -37,9 +36,6 @@ import './home.css';
const store = initStore(api, hashHistory);
store.dispatch({ type: 'initAll', api });
store.dispatch(setApi(api));
ReactDOM.render(
<ContextProvider api={ api } muiTheme={ muiTheme } store={ store }>
<Home />

View File

@ -16,7 +16,7 @@
import React from 'react';
import { AccountsIcon, AddressesIcon, AppsIcon, ContactsIcon, FingerprintIcon, SettingsIcon, StatusIcon } from '~/ui/Icons';
import { AccountsIcon, AddressesIcon, AppsIcon, ContactsIcon, FingerprintIcon, SettingsIcon } from '~/ui/Icons';
const defaultViews = {
accounts: {
@ -48,13 +48,6 @@ const defaultViews = {
value: 'contract'
},
status: {
active: false,
icon: <StatusIcon />,
route: '/status',
value: 'status'
},
signer: {
active: true,
fixed: true,

View File

@ -112,17 +112,6 @@ class Views extends Component {
/>
)
}
{
this.renderView('status',
<FormattedMessage
id='settings.views.status.label'
/>,
<FormattedMessage
id='settings.views.status.description'
defaultMessage='See how the Parity node is performing in terms of connections to the network, logs from the actual running instance and details of mining (if enabled and configured).'
/>
)
}
{
this.renderView('signer',
<FormattedMessage

View File

@ -49,7 +49,7 @@ export default class MiningSettings extends Component {
: '';
return (
<div { ...this._testInherit() }>
<div>
<ContainerTitle
title={
<FormattedMessage

View File

@ -14,4 +14,34 @@
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
export default from './status';
import ReactDOM from 'react-dom';
import React from 'react';
import { hashHistory } from 'react-router';
import injectTapEventPlugin from 'react-tap-event-plugin';
injectTapEventPlugin();
import { api } from './parity';
import ContractInstances from '~/contracts';
import { initStore } from '~/redux';
import ContextProvider from '~/ui/ContextProvider';
import muiTheme from '~/ui/Theme';
import Status from './status';
import '~/../assets/fonts/Roboto/font.css';
import '~/../assets/fonts/RobotoMono/font.css';
import './status.css';
ContractInstances.get(api);
const store = initStore(api, hashHistory);
ReactDOM.render(
<ContextProvider api={ api } muiTheme={ muiTheme } store={ store }>
<Status />
</ContextProvider>,
document.querySelector('#container')
);

View File

@ -0,0 +1,21 @@
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
const api = window.parent.secureApi;
export {
api
};

View File

@ -25,19 +25,21 @@ import NodeStatus from './NodeStatus';
import styles from './status.css';
export default () => (
<Page
title={
<FormattedMessage
id='status.title'
defaultMessage='Status'
/>
}
>
<div className={ styles.body }>
<NodeStatus />
<Peers />
<Debug />
</div>
</Page>
);
export default function Status () {
return (
<Page
title={
<FormattedMessage
id='status.title'
defaultMessage='Status'
/>
}
>
<div className={ styles.body }>
<NodeStatus />
<Peers />
<Debug />
</div>
</Page>
);
}

View File

@ -26,7 +26,6 @@ export Dapps from './Dapps';
export ParityBar from './ParityBar';
export Settings, { SettingsBackground, SettingsParity, SettingsProxy, SettingsViews } from './Settings';
export Signer from './Signer';
export Status from './Status';
export Vaults from './Vaults';
export Wallet from './Wallet';
export Web from './Web';

View File

@ -35,6 +35,7 @@ const DAPPS_BUILTIN = require('../src/config/dappsBuiltin.json').map((dapp) => {
});
const DAPPS_VIEWS = require('../src/config/dappsViews.json').map((dapp) => {
dapp.srcPath = './views';
dapp.commons = true;
return dapp;
});
@ -167,7 +168,7 @@ module.exports = {
template: dapp.srcPath + '/index.ejs',
favicon: FAVICON,
secure: dapp.secure,
chunks: [ isProd ? null : 'commons', dapp.url ]
chunks: [ !isProd || dapp.commons ? 'commons' : null, dapp.url ]
});
});

View File

@ -16,6 +16,6 @@
module.exports = {
test: /\.js$/,
include: /node_modules\/@parity\/(abi|api|jsonrpc|wordlist)/,
include: /node_modules\/@parity\/(abi|api|jsonrpc|ui|wordlist)/,
use: 'babel-loader'
};