From 9a0a5dc833235eed4892f63fd1787bd35e5dfcaa Mon Sep 17 00:00:00 2001 From: Chen Yu Date: Tue, 14 Aug 2018 19:14:27 +0800 Subject: [PATCH] merge develop to master for release 0.1.0 (#17) * update: refact config context route app index * update: adjust loading timing * update: update def * update: update notification and server list style * update: move lngs to env config * Feature/refactor (#8) * update: refact config context route app index * update: adjust loading timing * update: update def * update: update notification and server list style * update: move lngs to env config * update: update search params display * Update README.md (#10) * update: add notice of tps in doc * update: refactor config, metadata module * Feature/refactor (#11) * update: refact config context route app index * update: adjust loading timing * update: update def * update: update notification and server list style * update: move lngs to env config * update: update search params display * update: add notice of tps in doc * update: refactor config, metadata module * update: update readme * fix: fix metadata panel style * Fix/fix metadata panel style (#14) * update: refact config context route app index * update: adjust loading timing * update: update def * update: update notification and server list style * update: move lngs to env config * update: update search params display * update: add notice of tps in doc * update: refactor config, metadata module * fix: fix metadata panel style * fix: fix metadata panel height * Fix/fix metadata style (#15) * update: refact config context route app index * update: adjust loading timing * update: update def * update: update notification and server list style * update: move lngs to env config * update: update search params display * update: add notice of tps in doc * update: refactor config, metadata module * fix: fix metadata panel style * fix: fix metadata panel height * update: add badge * update: update appchain badge link * update: update appchain badge color --- .env.example | 2 +- README.md | 42 ++++- config/webpack.config.base.js | 2 +- package.json | 4 +- src/components/ErrorNotification/index.tsx | 2 +- src/components/MetadataPanel/index.tsx | 17 +- src/components/MetadataPanel/metadata.scss | 28 ++- src/components/TableWithSelector/index.tsx | 77 ++------ src/containers/BlockTable/index.tsx | 24 ++- src/containers/ConfigPage/config.scss | 5 - src/containers/ConfigPage/index.tsx | 203 +++++++++------------ src/containers/Footer/index.tsx | 2 +- src/containers/Header/index.tsx | 63 +++++-- src/containers/TransactionTable/index.tsx | 14 +- src/contexts/config.tsx | 65 ++----- src/contexts/observables.tsx | 12 +- src/initValues.ts | 20 +- src/styles/text.scss | 4 +- src/typings/index.d.ts | 4 +- src/utils/searchTextGen.ts | 5 + yarn.lock | 16 +- 21 files changed, 303 insertions(+), 308 deletions(-) create mode 100644 src/utils/searchTextGen.ts diff --git a/.env.example b/.env.example index dfced0e..8fda421 100644 --- a/.env.example +++ b/.env.example @@ -1,4 +1,4 @@ PUBLIC=localhost:8082 -CHAIN_SERVERS=http://121.196.200.225:1337,http://47.94.105.226:1337 +CHAIN_SERVER=http://47.96.231.19:4000 APP_NAME=Microscope LNGS=zh,en,ja-JP,ko,de,it,fr diff --git a/README.md b/README.md index 508aa81..aadd7d5 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,30 @@ -# Getting Started +[![MIT](https://img.shields.io/badge/License-MIT-green.svg)](https://github.com/cryptape/microscope) +[![AppChain](https://img.shields.io/badge/made%20for-Nervos%20AppChain-blue.svg)](https://appchain.nervos.org/) + +# Overview + +Microscope provides an easy-to-use user interface to inspect every cell of every AppChain. Yes, every AppChain, due to the ability to switch target chain in Metadata Panel of the Microscope. + +# About Microscope + +Microscope is a blockchain explorer built with [React](https://reactjs.org/) for inspecting any AppChain. It supports searching block, transaction, account and invoking call method of smart contract. It also can work with [ReBirth](https://github.com/cryptape/re-birth) to display a list of blocks and transactions on specified conditions, or even analyzes AppChain working status. + +## Features + +- [x] **Open Source Development**: This project is welcome anyone to use and PR. +- [x] **Multi-Chain Switch**: This project supports switch between any AppChain. +- [x] **Smart Contract Support**: This project provides a user friendly interface to call methods of smart contracts. +- [x] **User Customized**: This project supports a config page to specify which value should be displayed. +- [x] **Progressive**: This project is under progressive development, which means it can work independently, and is able to work with [ReBirth](https://github.com/cryptape/re-birth), another project for AppChain. +- [x] **Internationalized**: This project supports i18n, default to 中文 and Englisgh. + +## Getting Started + +- [Development](#development) + +- [Usage](#usage) + +# Development 1. clone the repo @@ -21,10 +47,10 @@ yarn run dll 4. Add Config ```shell -cp ./env.example ./env +cp ./.env.example ./.env ``` -set env variables in `./env` +set env variables in `./.env` ``` PUBLIC= # public content server address @@ -46,7 +72,7 @@ yarn start yarn run build:prod ``` -# How to use +# Usage ## Set appchain @@ -62,7 +88,7 @@ Homeage includes `Latest 10 Blocks` and `Latest 10 Transactions` ### Block -> NOTICE: This page only works with [agera_one](https://github.com/Keith-CY/agera_one), the server caching appchain. +> NOTICE: This page only works with [ReBirth](https://github.com/cryptape/re-birth), the server caching appchain. **Block Page** show list of blocks, the table items can be specified in **Config Page** @@ -76,7 +102,7 @@ Block Detail can be inspected via table link. ### Transaction -> NOTICE: This page only works with [agera_one](https://github.com/Keith-CY/agera_one), the server caching appchain. +> NOTICE: This page only works with [ReBirth](https://github.com/cryptape/re-birth), the server caching appchain. **Transaction Page** show list of transaction, the table items can be specified in **Config Page** @@ -92,7 +118,7 @@ Account Detail can be inspected via `from` and `to`. ### Statisitcs -> NOTICE: Partial diagrams works with [agera_one](https://github.com/Keith-CY/agera_one), the server caching appchain. +> NOTICE: Partial diagrams works with [ReBirth](https://github.com/cryptape/ReBirth), the server caching appchain. **Statistics Page** show list of diagrams, the displaying items can be specified in **Config Page** @@ -116,6 +142,8 @@ The **Metadata Panel** is used to check metadata of active chain, or inspect and ### Statistics Panel +> NOTICE: this panel is hidden by default, corresponding code is at `src/containers/Header/index.tsx` + On click of **TPS** the **Statistics Panel** will be called out. The **Statistics Panel** is used to inspect current status of active chain. diff --git a/config/webpack.config.base.js b/config/webpack.config.base.js index 4cfabd9..c1e3a96 100644 --- a/config/webpack.config.base.js +++ b/config/webpack.config.base.js @@ -42,7 +42,7 @@ module.exports = { plugins: [ new webpack.DefinePlugin({ 'process.env': { - CHAIN_SERVERS: JSON.stringify(process.env.CHAIN_SERVERS), + CHAIN_SERVER: JSON.stringify(process.env.CHAIN_SERVER), APP_NAME: JSON.stringify(process.env.APP_NAME), LNGS: JSON.stringify(process.env.LNGS) }, diff --git a/package.json b/package.json index df4063d..dda95b5 100644 --- a/package.json +++ b/package.json @@ -1,9 +1,9 @@ { - "name": "nervos-web", + "name": "Microscope", "version": "0.1.0", "description": "NervOS Web", "main": "index.js", - "repository": "https://github.com/CITA-Toys/CITA-Toys-Wallet", + "repository": "https://github.com/cryptape/microscope", "author": "Keith ", "license": "MIT", "scripts": { diff --git a/src/components/ErrorNotification/index.tsx b/src/components/ErrorNotification/index.tsx index 2f4cede..d5904d8 100644 --- a/src/components/ErrorNotification/index.tsx +++ b/src/components/ErrorNotification/index.tsx @@ -15,7 +15,7 @@ export default ({ error, dismissError }) => ( action={ (e: any) => void - switchChain: (e) => void + switchChain: (ip?: string) => (e) => void handleKeyUp: (e: React.KeyboardEvent) => void t: (key: string) => string serverList: ServerList @@ -80,7 +80,9 @@ const MetadataPanel: React.SFC = ({ value={searchIp} onKeyUp={handleKeyUp} /> - + {searchResult.chainId !== -1 ? ( @@ -89,13 +91,20 @@ const MetadataPanel: React.SFC = ({ {serverList.map(({ serverName, serverIp }) => ( switchChain(serverIp)} + onClick={switchChain(serverIp)} classes={{ root: styles.listItem, gutters: styles.serverGutters }} > - + ))} diff --git a/src/components/MetadataPanel/metadata.scss b/src/components/MetadataPanel/metadata.scss index ed522e3..e9ba621 100644 --- a/src/components/MetadataPanel/metadata.scss +++ b/src/components/MetadataPanel/metadata.scss @@ -2,12 +2,13 @@ $sidebar-padding: 29px; .display { padding: 0 $sidebar-padding; + padding-top: 6px; color: $sidebar-text; text-transform: capitalize; .item { font-size: 1rem; - line-height: 2rem; - height: 2rem; + line-height: 2.2rem; + height: 2.2rem; span { text-transform: none; } @@ -17,6 +18,7 @@ $sidebar-padding: 29px; } .validators { .box { + margin-top: 10px; padding: 10px 17px; border: 1px solid #ccc; border-radius: 4px; @@ -41,8 +43,8 @@ $sidebar-padding: 29px; background-color: #f4f7ff; font-weight: bold; padding: 0 $sidebar-padding; - height: 42px; - line-height: 42px; + height: 36px; + line-height: 36px; font-weight: bolder; text-transform: capitalize; } @@ -65,6 +67,12 @@ $sidebar-padding: 29px; padding: 6px 24px; margin-left: 10px; text-transform: capitalize; + cursor: pointer; + &:disabled { + background: #eee; + color: #aaa; + cursor: default; + } } } @@ -76,6 +84,14 @@ $sidebar-padding: 29px; } .serverGutters { - padding-left: 28px; - padding-right: 28px; + padding-left: 28px !important; + padding-right: 28px !important; +} + +.serverPrimary { + color: $heavyText !important; +} + +.serverSecondary { + color: $plainText !important; } diff --git a/src/components/TableWithSelector/index.tsx b/src/components/TableWithSelector/index.tsx index 6351871..6d1bb05 100644 --- a/src/components/TableWithSelector/index.tsx +++ b/src/components/TableWithSelector/index.tsx @@ -3,12 +3,7 @@ import { Link } from 'react-router-dom' import { translate } from 'react-i18next' import { Paper } from '@material-ui/core' import Pager from 'react-pager' -import { - KeyboardArrowLeft, - KeyboardArrowRight, - SkipNext, - SkipPrevious, -} from '@material-ui/icons' +import { KeyboardArrowLeft, KeyboardArrowRight, SkipNext, SkipPrevious } from '@material-ui/icons' import Dialog from '../../containers/Dialog' import paramsFilter from '../../utils//paramsFilter' @@ -20,7 +15,7 @@ const styles = require('./tableWithSelector.scss') export enum SelectorType { SINGLE, MULTIPLE, - RANGE, + RANGE } export interface TableHeaderWithSelector { @@ -51,20 +46,18 @@ export interface TableWithSelectorProps { // showInOut?: boolean showInout?: boolean inset?: boolean + searchText?: string } -class TableWithSelector extends React.Component< - TableWithSelectorProps & { t: (key: string) => string }, - any - > { +class TableWithSelector extends React.Component string }, any> { state = { on: false, - selectorsValue: this.props.selectorsValue, + selectorsValue: this.props.selectorsValue } showDialog = (on: boolean = false) => (e?: any) => { this.setState(state => ({ - on, + on })) } @@ -74,11 +67,11 @@ class TableWithSelector extends React.Component< const { selectorsValue } = state const newSelectorsValue = { ...selectorsValue, - [selector]: e.target.value, + [selector]: e.target.value } return { - selectorsValue: newSelectorsValue, + selectorsValue: newSelectorsValue } }) } @@ -88,35 +81,16 @@ class TableWithSelector extends React.Component< } render () { const { on, selectorsValue } = this.state - const { - headers, - items, - selectors, - pageSize, - pageNo, - count, - t, - inset, - } = this.props + const { headers, items, selectors, pageSize, pageNo, count, t, inset, searchText } = this.props const total = Math.ceil(count / pageSize) - const activeParams = paramsFilter(this.props.selectorsValue) + // const activeParams = paramsFilter(this.props.selectorsValue) return ( - - + +
- {selectors.map(selector => ( - {t(selector.text)} - ))} + {selectors.map(selector => {t(selector.text)})}
{selectors.map( @@ -140,7 +114,7 @@ class TableWithSelector extends React.Component< onChange={this.handleSelectorInput(selector.key)} />
- ), + ) )}
@@ -149,32 +123,19 @@ class TableWithSelector extends React.Component<
- {t('current params')}:{' '} - {Object.keys(activeParams) - .map(key => `${key}: ${activeParams[key]}`) - .join(', ')} + {t('current params')}: {searchText} - +
- - {headers.map(header => ( - - ))} - + {headers.map(header => )} {items.map(item => ( {headers.map(header => ( -
{t(header.text)}
{t(header.text)}
+ {header.href === undefined ? ( item[header.key] === null ? ( '/' @@ -204,7 +165,7 @@ class TableWithSelector extends React.Component< first: , last: , prev: , - next: , + next: }} className={styles.pager} onPageChanged={this.props.handlePageChanged} diff --git a/src/containers/BlockTable/index.tsx b/src/containers/BlockTable/index.tsx index a7a98c7..6b9093c 100644 --- a/src/containers/BlockTable/index.tsx +++ b/src/containers/BlockTable/index.tsx @@ -2,7 +2,7 @@ * @Author: Keith-CY * @Date: 2018-08-02 12:05:46 * @Last Modified by: Keith-CY - * @Last Modified time: 2018-08-02 12:12:50 + * @Last Modified time: 2018-08-03 18:28:02 */ import * as React from 'react' @@ -21,6 +21,7 @@ import { fetchBlocks } from '../../utils/fetcher' import paramsFilter from '../../utils/paramsFilter' import hideLoader from '../../utils/hideLoader' import { handleError, dismissError } from '../../utils/handleError' +import { rangeSelectorText } from '../../utils/searchTextGen' import { initBlockTableState } from '../../initValues' @@ -140,9 +141,20 @@ class BlockTable extends React.Component { private handleError = handleError(this) private dismissError = dismissError(this) - render () { + public render () { const { headers, items, selectors, selectorsValue, count, pageSize, pageNo, loading, error } = this.state - const activeParams = paramsFilter(selectorsValue) + const activeParams = paramsFilter(selectorsValue) as any + const blockSearchText = rangeSelectorText('Number', activeParams.numberFrom, activeParams.numberTo) + const transactionSearchText = rangeSelectorText( + 'Transaction', + activeParams.transactionFrom, + activeParams.transactionTo + ) + const searchText = + blockSearchText && transactionSearchText + ? `${blockSearchText}, ${transactionSearchText}` + : blockSearchText || transactionSearchText + return ( {loading ? ( @@ -153,10 +165,7 @@ class BlockTable extends React.Component { /> ) : null} - Current Search:{' '} - {Object.keys(activeParams) - .map(key => `${key}: ${activeParams[key]}`) - .join(', ')} + {searchText ? `Current Search: ${searchText}` : 'Blocks'} { pageSize={pageSize} pageNo={pageNo} handlePageChanged={this.handlePageChanged} + searchText={searchText} /> diff --git a/src/containers/ConfigPage/config.scss b/src/containers/ConfigPage/config.scss index 8161bb6..db2109f 100644 --- a/src/containers/ConfigPage/config.scss +++ b/src/containers/ConfigPage/config.scss @@ -13,7 +13,6 @@ } .main { - // max-width: 680px; margin: 50px auto 0; } @@ -21,10 +20,6 @@ text-transform: capitalize; } -.switchColorPrimary { - // color: blue !important; -} - .switchChecked.switchColorSecondary { color: #fff !important; } diff --git a/src/containers/ConfigPage/index.tsx b/src/containers/ConfigPage/index.tsx index d39a16e..3580276 100644 --- a/src/containers/ConfigPage/index.tsx +++ b/src/containers/ConfigPage/index.tsx @@ -12,25 +12,22 @@ import { ExpansionPanelSummary, ExpansionPanelDetails, Divider, - Switch, + Switch } from '@material-ui/core' import { ExpandMore as ExpandMoreIcon } from '@material-ui/icons' -import CITAObservables from '@nervos/observables' - import Banner from '../../components/Banner' import { PanelConfigs } from '../../config/localstorage' -import { initPanelConfigs } from '../../initValues' -import { withObservables } from '../../contexts/observables' -import { withConfig, IConfig } from '../../contexts/config' + +import { withConfig, Config } from '../../contexts/config' import hideLoader from '../../utils/hideLoader' const layout = require('../../styles/layout.scss') const styles = require('./config.scss') /* eslint-disable no-use-before-define */ -interface ConfigItem { +interface ConfigDetail { panel: ConfigPanel type: ConfigType key: string @@ -42,7 +39,7 @@ enum ConfigType { DISPLAY, COUNT, ITEMS, - VALUE, + VALUE } enum ConfigPanel { @@ -50,49 +47,38 @@ enum ConfigPanel { HEADER = 'header', BLOCK = 'block', TRANSACTION = 'transaction', - GRAPH = 'graph', + GRAPH = 'graph' } -export interface IConfigPageProps { - config: IConfig - CITAObservables: CITAObservables +export interface ConfigPageProps { + config: Config t: (key: string) => string } -export interface IConfigPageState { +export interface ConfigPageState { configs: PanelConfigs } -const initState: IConfigPageState = { - configs: initPanelConfigs, -} - -const ConfigItem = translate('microscope')( +const ConfigDetail = translate('microscope')( ({ config, - index, value, handleSwitch, handleInput, - t, + t }: { - config: ConfigItem - index: number + config: ConfigDetail value: number | string | boolean | undefined handleSwitch: (key: string) => (e: any) => void - handleInput: ( - key: string, - ) => (e: React.ChangeEvent) => void + handleInput: (key: string) => (e: React.ChangeEvent) => void t: (key: string) => string }) => ( - {t(config.type === ConfigType.DISPLAY ? 'display' : 'set')}{' '} - {t(config.title)} + {t(config.type === ConfigType.DISPLAY ? 'display' : 'set')} {t(config.title)} - // ' ' + } /> @@ -103,34 +89,29 @@ const ConfigItem = translate('microscope')( checked: styles.switchChecked, colorPrimary: styles.switchColorPrimary, colorSecondary: styles.switchColorSecondary, - // bar: styles.iOSBar, - icon: styles.iOSIcon, + icon: styles.iOSIcon }} onChange={handleSwitch(config.key)} checked={!!value} /> ) : (
- +
)}
- ), + ) ) -const Config = translate('microscope')( +const ConfigItem = translate('microscope')( ({ title, configs, values, handleSwitch, handleInput, - t, + t }: { title: any configs: any @@ -139,11 +120,7 @@ const Config = translate('microscope')( handleInput: any t: any }) => ( - + }> {t(title)} {t('config')} @@ -153,10 +130,9 @@ const Config = translate('microscope')( {configs.map((config, idx) => ( - - ), + ) ) -class ConfigPage extends React.Component { - // state: IConfigPageState - constructor (props) { - super(props) - this.state = { - configs: this.props.config.panelConfigs, - } - } - - componentDidMount () { - hideLoader() - } - private handleSwitch = key => (e: any) => { - this.setState(state => { - const { configs } = this.state - const newConfig = { ...configs, [key]: !configs[key] } - if (this.props.config.changePanelConfig(newConfig)) { - return { configs: newConfig } - } - return state - }) - } - private handleInput = key => (e: React.ChangeEvent) => { - const { value } = e.currentTarget - this.setState(state => { - const { configs } = state - const newConfig = { ...configs, [key]: value } - if (this.props.config.changePanelConfig(newConfig)) { - return { configs: newConfig } - } - return state - }) - } - private panels = [ +class ConfigPage extends React.Component { + static panels = [ // ConfigPanel.GENERAL, - ConfigPanel.HEADER, + // ConfigPanel.HEADER, ConfigPanel.BLOCK, ConfigPanel.TRANSACTION, - ConfigPanel.GRAPH, + ConfigPanel.GRAPH ] - private configs = [ + static configs = [ { panel: ConfigPanel.GENERAL, type: ConfigType.VALUE, key: 'logo', - title: 'logo', + title: 'logo' }, { panel: ConfigPanel.HEADER, type: ConfigType.DISPLAY, key: 'TPS', - title: 'TPS', + title: 'TPS' }, { panel: ConfigPanel.BLOCK, type: ConfigType.DISPLAY, key: 'blockHeight', - title: 'height', + title: 'height' }, { panel: ConfigPanel.BLOCK, type: ConfigType.DISPLAY, key: 'blockHash', - title: 'hash', + title: 'hash' }, { panel: ConfigPanel.BLOCK, type: ConfigType.DISPLAY, key: 'blockAge', - title: 'age', + title: 'age' }, { panel: ConfigPanel.BLOCK, type: ConfigType.DISPLAY, key: 'blockTransactions', - title: 'transactions', + title: 'transactions' }, { panel: ConfigPanel.BLOCK, type: ConfigType.DISPLAY, key: 'blockGasUsed', - title: 'gas used', + title: 'gas used' }, { panel: ConfigPanel.BLOCK, type: ConfigType.VALUE, key: 'blockPageSize', - title: 'page size', + title: 'page size' }, { panel: ConfigPanel.TRANSACTION, type: ConfigType.DISPLAY, key: 'transactionHash', - title: 'hash', + title: 'hash' }, { panel: ConfigPanel.TRANSACTION, type: ConfigType.DISPLAY, key: 'transactionFrom', - title: 'from', + title: 'from' }, { panel: ConfigPanel.TRANSACTION, type: ConfigType.DISPLAY, key: 'transactionTo', - title: 'to', + title: 'to' }, { panel: ConfigPanel.TRANSACTION, type: ConfigType.DISPLAY, key: 'transactionValue', - title: 'value', + title: 'value' }, { panel: ConfigPanel.TRANSACTION, type: ConfigType.DISPLAY, key: 'transactionAge', - title: 'age', + title: 'age' }, { panel: ConfigPanel.TRANSACTION, type: ConfigType.DISPLAY, key: 'transactionBlockNumber', - title: 'block number', + title: 'block number' }, { panel: ConfigPanel.TRANSACTION, type: ConfigType.DISPLAY, key: 'transactionGasUsed', - title: 'gas used', + title: 'gas used' }, { panel: ConfigPanel.TRANSACTION, type: ConfigType.VALUE, key: 'transactionPageSize', - title: 'page size', + title: 'page size' }, { panel: ConfigPanel.GRAPH, type: ConfigType.DISPLAY, key: 'graphIPB', - title: 'Interval/Block', + title: 'Interval/Block' }, { panel: ConfigPanel.GRAPH, type: ConfigType.DISPLAY, key: 'graphTPB', - title: 'Transactions/Block', + title: 'Transactions/Block' }, { panel: ConfigPanel.GRAPH, type: ConfigType.DISPLAY, key: 'graphGasUsedBlock', - title: 'Gas Used/Block', + title: 'Gas Used/Block' }, { panel: ConfigPanel.GRAPH, type: ConfigType.DISPLAY, key: 'graphGasUsedTx', - title: 'Gas Used/Transaction', + title: 'Gas Used/Transaction' }, { panel: ConfigPanel.GRAPH, type: ConfigType.DISPLAY, key: 'graphProposals', - title: 'Proposals/Validator', + title: 'Proposals/Validator' }, { panel: ConfigPanel.GRAPH, type: ConfigType.VALUE, key: 'graphMaxCount', - title: 'MaxCount', - }, - ] as ConfigItem[] - render () { + title: 'MaxCount' + } + ] as ConfigDetail[] + public constructor (props) { + super(props) + this.state = { + configs: props.config.panelConfigs + } + } + + public componentDidMount () { + hideLoader() + } + private handleSwitch = key => (e?: any) => { + this.setState(state => { + const { configs } = this.state + const newConfig = { ...configs, [key]: !configs[key] } + if (this.props.config.changePanelConfig(newConfig)) { + return { configs: newConfig } + } + return state + }) + } + private handleInput = key => (e: React.ChangeEvent) => { + const { value } = e.currentTarget + this.setState(state => { + const { configs } = state + const newConfig = { ...configs, [key]: value } + if (this.props.config.changePanelConfig(newConfig)) { + return { configs: newConfig } + } + return state + }) + } + public render () { return ( - - Config - + Config
- {this.panels.map(panel => ( - ( + config.panel === panel)} + configs={ConfigPage.configs.filter(config => config.panel === panel)} values={this.state.configs} handleSwitch={this.handleSwitch} handleInput={this.handleInput} @@ -366,4 +339,4 @@ class ConfigPage extends React.Component { } } -export default withConfig(withObservables(ConfigPage)) +export default withConfig(ConfigPage) diff --git a/src/containers/Footer/index.tsx b/src/containers/Footer/index.tsx index 00ae944..3846e00 100644 --- a/src/containers/Footer/index.tsx +++ b/src/containers/Footer/index.tsx @@ -21,7 +21,7 @@ class Footer extends React.Component<{ t: (key: string) => string }, any> { state = { overview: { title: 'overview', - content: 'Across the Microscope, we can reach every cell in the nervos', + content: 'Across the Microscope, we can reach every cell in Nervos Network', }, products: { title: 'other product', diff --git a/src/containers/Header/index.tsx b/src/containers/Header/index.tsx index 5aa0c6c..030f6e4 100644 --- a/src/containers/Header/index.tsx +++ b/src/containers/Header/index.tsx @@ -54,26 +54,20 @@ class Header extends React.Component { state = initState componentWillMount () { this.onSearch$ = new Subject() - this.fetchStatus() + // hide TPS in header } componentDidMount () { - // console.log(this.props) - + // start search subscription this.searchSubscription = this.onSearch$.debounceTime(1000).subscribe(({ key, value }) => { if (key === 'searchIp') { this.getChainMetadata(value) } }, this.handleError) - this.props.CITAObservables.metaData({ - blockNumber: 'latest' - }).subscribe((metadata: Chain.MetaData) => { - this.setState({ - metadata: { - ...metadata, - genesisTimestamp: new Date(metadata.genesisTimestamp).toLocaleString() - } - }) - }, this.handleError) + + // fetch status of brief-statistics panel + this.fetchStatisticsPanel() + // fetch data of metadata panel + this.fetchMetaDataPanel() } componentWillReceiveProps (nextProps: HeaderProps) { if (this.props.location.pathname !== nextProps.location.pathname) { @@ -102,9 +96,9 @@ class Header extends React.Component { this.setState({ sidebarNavs: open }) } /** - * @method fetchStatus + * @method fetchStatisticsPanel */ - private fetchStatus = () => { + private fetchStatisticsPanel = () => { // fetch brief statistics fetchStatistics({ type: 'brief' }) .then(({ result: { tps, tpb, ipb } }) => { @@ -139,6 +133,35 @@ class Header extends React.Component { }) .catch(this.handleError) } + + private fetchMetaDataPanel = () => { + // fetch metadata + this.props.CITAObservables.metaData({ + blockNumber: 'latest' + }).subscribe((metadata: Chain.MetaData) => { + this.setState({ + metadata: { + ...metadata, + genesisTimestamp: new Date(metadata.genesisTimestamp).toLocaleString() + } + }) + }, this.handleError) + + // fetch server list + fetchServerList() + .then(servers => { + if (!servers) return + const serverList = [] as ServerList + Object.keys(servers).forEach(serverName => { + serverList.push({ + serverName, + serverIp: servers[serverName] + }) + }) + this.setState({ serverList }) + }) + .catch(this.handleError) + } private togglePanel = (panel: string) => (e?: any) => { this.setState({ activePanel: panel @@ -147,7 +170,7 @@ class Header extends React.Component { private handleKeyUp = (e: React.KeyboardEvent) => { if (e.keyCode === 13) { - this.switchChain() + this.switchChain('')() } } @@ -168,12 +191,12 @@ class Header extends React.Component { private changeLng = (lng = 'en') => e => { this.setState({ lngOpen: false }) - // this.props.i18n.changeLanguage(lng) window.localStorage.setItem('i18nextLng', lng) window.location.reload() } - private switchChain = (chain?: string) => { + private switchChain = (chain: string = '') => (e?: any) => { const ip = chain || this.state.searchIp + if (!ip) return this.props.CITAObservables.setServer(ip.startsWith('http') ? ip : `http://${ip}`) const chainIp = ip.startsWith('http') ? ip : `http://${ip}` window.localStorage.setItem('chainIp', chainIp) @@ -218,11 +241,11 @@ class Header extends React.Component { - {this.props.config.panelConfigs.TPS ? ( + {/* this.props.config.panelConfigs.TPS ? ( - ) : null} + ) : null */}