import { actions as asset } from 'features/assets'
import { actions as balance } from 'features/balances'
import { actions as configuration } from 'features/configuration'
-import { actions as console } from 'features/console'
import { actions as core } from 'features/core'
import { actions as mockhsm } from 'features/mockhsm'
import { actions as testnet } from 'features/testnet'
asset,
balance,
configuration,
- console,
core,
key: mockhsm,
testnet,
import { push } from 'react-router-redux'
+import { chainClient } from 'utility/environment'
const actions = {
dismissFlash: (param) => ({type: 'DISMISS_FLASH', param}),
dispatch(push('/configuration'))
}
}
+ },
+ cmd: (data) => () => {
+ return chainClient().bytomCli.request(data)
}
}
}
const cancel = cancelAction ? () => dispatch(cancelAction) : null
const backdropAction = cancel || accept
+ const boxStyle = this.props.options.box
return(
<div className={styles.main}>
<div className={styles.backdrop} onClick={backdropAction}></div>
- <div className={`${this.props.options.wide && styles.wide} ${styles.content}`}>
+ <div className={`${this.props.options.wide && styles.wide} ${boxStyle? styles.box: styles.content}`}>
+ {
+ boxStyle &&
+ <div className={styles.title}>
+ <p>Console</p>
+ <button className={`btn ${styles.close}`} onClick={accept}>X</button>
+ </div>
+ }
{body}
-
- <button className={`btn btn-${this.props.options.danger ? 'danger' : 'primary'} ${styles.accept}`} onClick={accept}>
- { lang === 'zh' ? '关闭' : 'OK' }</button>
- {cancel && <button className={`btn btn-link ${styles.cancel}`} onClick={cancel}>Cancel</button>}
+ {!boxStyle && <button className={`btn btn-${this.props.options.danger ? 'danger' : 'primary'} ${styles.accept}`} onClick={accept}>
+ { lang === 'zh' ? '关闭' : 'OK' }</button>}
+ {!boxStyle && cancel && <button className={`btn btn-link ${styles.cancel}`} onClick={cancel}>Cancel</button>}
</div>
</div>
)
.cancel {
color: $text-color;
}
+
+.box {
+ background: $background-color;
+ position: absolute;
+ top: 10%;
+ height: 80%;
+}
+
+.title {
+ height: 50px;
+ padding: 10px 30px;
+ border-bottom: 1px solid $border-color;
+ font-size: $font-size-page-title;
+ color: $text-strong-color;
+}
+
+.close {
+ position: absolute;
+ right: 10px;
+ top: 10px;
+}
{ lang === 'zh' ? '备份与恢复' : 'Backup and Restore'}
</Link>
</li>
-
- <li>
- <Link to='/console' activeClassName={styles.active}>
- {navIcon('client', styles)}
- Console
- </Link>
- </li>
</ul>
</div>
)
+++ /dev/null
-import { chainClient } from 'utility/environment'
-
-let actions = {
- request: (data) => () => {
- return chainClient().bytomCli.request(data)
- }
-}
-
-export default actions
+++ /dev/null
-import React from 'react'
-import componentClassNames from 'utility/componentClassNames'
-import {PageContent, PageTitle, ConsoleSection} from 'features/shared/components'
-import styles from './ConsolePage.scss'
-import {connect} from 'react-redux'
-import actions from 'actions'
-
-class ConsolePage extends React.Component {
- constructor(props) {
- super(props)
- }
-
- render() {
- const lang = this.props.core.lang
-
- return (
- <div className={componentClassNames(this, 'flex-container', styles.mainContainer)}>
- <PageTitle title={'Console'}/>
- <PageContent>
- <ConsoleSection
- cmd={this.props.cmd}
- />
- </PageContent>
- </div>
- )
- }
-}
-
-const mapStateToProps = (state) => ({
- core: state.core
-})
-
-const mapDispatchToProps = (dispatch) => ({
- cmd: (data) => dispatch(actions.console.request(data)),
-})
-
-export default connect(
- mapStateToProps,
- mapDispatchToProps
-)(ConsolePage)
+++ /dev/null
-.page_header h1 {
- margin-bottom: 0;
-}
-
-.table {
- margin-bottom: $grid-gutter-width;
-
- td {
- vertical-align: top;
- }
-}
-
-.row_label {
- padding-right: $grid-gutter-width;
- text-transform: capitalize;
- font-weight: 500;
- white-space: pre;
-}
-
-.row_value {
- white-space: pre;
- text-align: right;
-}
-
-.block_hash {
- display: block;
- word-wrap: break-word;
- word-break: break-all;
-}
-
-.flex {
- display: flex;
- //overflow:hidden;
-}
-
-.col {
- display: flex;
- width: 50%;
- padding: $grid-gutter-width;
- h4 {
- margin-top: 0;
- }
-}
-
-.sub-row {
- padding: $grid-gutter-width $grid-gutter-width 0;
-}
-
-.top {
- border-bottom: 1px solid $border-color;
-}
-
-.left {
- padding-left: 0;
- width: 67%;
-}
-
-.right {
- border-left: 1px solid $border-color;
- width: 33%;
-}
-
-.replication_lag {
- display: inline-block;
- float: right;
- border-radius: $border-radius-base;
- color: white;
- padding: 0 8px;
- line-height: 1.5;
- margin-top: 2px;
- margin-left: -8px;
-}
-
-.green {
- background: $highlight-secondary;
-}
-
-.yellow {
- background: $brand-warning;
-}
-
-.red {
- background: darken($highlight-danger-background, 20%);
-}
-
-.mainContainer {
- background-color: $background-color;
-}
-
-code {
- padding-left: 0;
- font-size: $font-size-code;
-}
-
-.switch {
- position: relative;
- display: inline-block;
- width: 44px;
- height: 22px;
-
- /* Hide default HTML checkbox */
- input {display:none;}
-
- input:checked + .slider {
- background-color: $highlight-default;
- }
-
- input:focus + .slider {
- box-shadow: 0 0 1px $highlight-default;
- }
-
- input:checked + .slider:before {
- -webkit-transform: translateX(22px);
- -ms-transform: translateX(22px);
- transform: translateX(22px);
- }
-}
-
-/* The slider */
-.slider {
- position: absolute;
- cursor: pointer;
- top: 0;
- left: 0;
- right: 0;
- bottom: 0;
- background-color: #ccc;
- -webkit-transition: .4s;
- transition: .4s;
- border-radius: 34px;
-}
-
-.slider:before {
- position: absolute;
- content: "";
- height: 18px;
- width: 18px;
- left: 2px;
- bottom: 2px;
- background-color: white;
- -webkit-transition: .4s;
- transition: .4s;
- border-radius: 50%;
-}
\ No newline at end of file
+++ /dev/null
-import ConsolePage from './ConsolePage'
-
-export {
- ConsolePage
-}
+++ /dev/null
-import actions from './actions'
-import routes from './routes'
-
-export {
- actions,
- routes,
-}
+++ /dev/null
-import { RoutingContainer } from 'features/shared/components'
-import { ConsolePage } from './components'
-
-export default {
- path: 'console',
- component: RoutingContainer,
- indexRoute: { component: ConsolePage }
-}
import { connect } from 'react-redux'
import {DropdownButton, MenuItem} from 'react-bootstrap'
import componentClassNames from 'utility/componentClassNames'
-import { PageContent, PageTitle } from 'features/shared/components'
+import { PageContent, PageTitle, ConsoleSection } from 'features/shared/components'
import React from 'react'
import styles from './CoreIndex.scss'
import actions from 'actions'
this.handleMiningState = this.handleMiningState.bind(this)
this.handleAdvancedOptionChange = this.handleAdvancedOptionChange.bind(this)
this.changeBTMamount = this.changeBTMamount.bind(this)
+ this.consolePopup = this.consolePopup.bind(this)
}
componentDidMount() {
}
}
+ consolePopup(e) {
+ e.preventDefault()
+ this.props.showModal(
+ <ConsoleSection
+ cmd={this.props.cmd}
+ />
+ )
+ }
+
render() {
let navState = this.props.navAdvancedState === 'advance'
let miningState = this.props.core.mingStatus
return (
<div className={componentClassNames(this, 'flex-container', styles.mainContainer)}>
- <PageTitle title={lang === 'zh' ? '核心状态' :'Core Status'} />
+ <PageTitle
+ title={lang === 'zh' ? '核心状态' :'Core Status'}
+ actions={[
+ <button className='btn btn-link' onClick={this.consolePopup}>
+ <img src={require('images/console-window.svg')}/>
+ </button>
+ ]}
+ />
<PageContent>
<div className={`${styles.flex}`}>
showNavAdvanced: () => dispatch(actions.app.showNavAdvanced),
hideNavAdvanced: () => dispatch(actions.app.hideNavAdvanced),
uptdateBtmAmountUnit: (param) => dispatch(actions.core.updateBTMAmountUnit(param)),
- updateMiningState: (param) => dispatch(actions.core.updateMiningState(param))
+ updateMiningState: (param) => dispatch(actions.core.updateMiningState(param)),
+ showModal: (body) => dispatch(actions.app.showModal(
+ body,
+ actions.app.hideModal,
+ null,
+ {
+ box: true,
+ wide: true
+ }
+ )),
+ cmd: (data) => dispatch(actions.app.cmd(data))
})
export default connect(
}
echo (text) {
- if(text.startsWith('help')){
- this.terminal.log(command['help'])
+ if(text.trim() === 'help'){
+ command['help'].forEach( (descriptionLine) => {
+ this.terminal.log(descriptionLine)
+ })
+ }else if(text.trim() === 'clear'){
+ this.terminal.setState({
+ acceptInput: true,
+ log: []
+ })
}else{
this.props.cmd(text)
.then(data=>
{
- this.terminal.log(JSON.stringify(data, null, 2))
+ if(data.status === 'success'){
+ let output = data.data
+ if(output){
+ const keys = Object.keys(output)
+ if(keys.length === 1){
+ this.terminal.log(output[keys[0]])
+ }else{
+ this.terminal.log(JSON.stringify(output, null, 2))
+ }
+ }
+ }else if(data.status === 'fail'){
+ this.terminal.logX('Error', data.msg.replace(/"/g,''))
+ }else{
+ this.terminal.log(JSON.stringify(data.data, null, 2))
+ }
}).catch(() =>
{
- this.terminal.log('command not found')
+ this.terminal.logX('Error','command not found')
})
}
this.terminal.return()
render() {
return(
- <div className='form-group'>
- <div
- className={styles.reactConsoleContainer}
- >
- <p>
- Welcome to the Bytom Core API console.<br/>
- Type <code>help</code> for an overview of available commands.
- </p>
- <p className='text-danger'>
- <strong>WARNING:</strong> Scammers have been active, telling users to type commands here, stealing their wallet contents. Do not use this console without fully understanding the ramification of a command.
- </p>
+ <div
+ className={styles.reactConsoleContainer}
+ >
+ <p>
+ Welcome to the Bytom Core API console.<br/>
+ Type <code>help</code> for an overview of available commands.
+ </p>
+ <p className='text-danger'>
+ <strong>WARNING:</strong> Scammers have been active, telling users to type commands here, stealing their wallet contents. Do not use this console without fully understanding the ramification of a command.
+ </p>
- <Console
- ref={ref => this.terminal = ref}
- handler={this.echo}
- autofocus={true}
- />
- </div>
+ <Console
+ ref={ref => this.terminal = ref}
+ handler={this.echo}
+ autofocus={true}
+ />
</div>
)
}
font-size: 0.85em;
font-family: "Menlo", "Consolas", "DejaVu Sans Mono", monospace;
box-sizing: border-box;
- padding: 0.5em;
+ height: calc( 100% - 50px );
+ padding: 30px;
+ overflow: scroll;
}
{
- "help": "create-key <alias> <password>\nlist-keys"
+ "help": [
+ "validate-address <address>",
+ "sign-message <address> <message> <password>",
+ "get-transaction <transaction id>",
+ "list-transactions",
+ "build-transaction <base_transaction> [{\"account_id\":id,\"amount\":amount,\"asset_id\": id,\"type\":type of transaction}…] <ttl> <time_range>",
+ "sign-transaction <password> <transaction>",
+ "estimate-transaction-gas <transaction>",
+ "get-unconfirmed-transaction <tx_id>",
+ "list-unconfirmed-transactions",
+ "decode-raw-transaction <raw_transaction>",
+ "get-block-count",
+ "get-block-hash",
+ "get-block ( <block_height> | <block_hash> )",
+ "get-block-header ( <block_height> | <block_hash> )",
+ "get-difficulty ( <block_height> | <block_hash> )",
+ "get-hash-rate ( <block_height> | <block_hash> )",
+ "net-info",
+ "is-mining",
+ "set-mining <true|false>",
+ "gas-rate",
+ "verify-message <address> <derived_xpub> <message> <signature>",
+ "decode-program <program>"
+ ]
}
\ No newline at end of file
import { routes as unspents } from 'features/unspents'
import { routes as mockhsm } from 'features/mockhsm'
import { routes as backup } from 'features/backup'
-import { routes as console } from 'features/console'
const makeRoutes = (store) => ({
path: '/',
unspents(store),
mockhsm(store),
backup,
- console,
{
path: '*',
component: NotFound
font-weight: normal;
}
+.text-danger{
+ color: $text-danger;
+}
+
div.react-console-prompt-box {
padding-top: 1em;
color: #444;
background: none;
color: #444; } }
-div.react-console-message {
+div.react-console-message,
+span.react-console-prompt {
white-space: pre-wrap; /* CSS3 */
white-space: -moz-pre-wrap; /* Firefox */
white-space: -pre-wrap; /* Opera <7 */
white-space: -o-pre-wrap; /* Opera 7 */
word-wrap: break-word; /* IE */
- padding: 0.1em; }
+ padding: 0.1em;
+}
+
+div.react-console-message-Error{
+ color: $text-danger;
+}