Update Transfer logic + Better logging (#4098)
* Add logs and better Transfer Store logic * Fix wallet transfer * Fix wrong gas in Wallet * Move log levels to Parity tab
This commit is contained in:
parent
ae7619431b
commit
cee2ac43c0
@ -152,6 +152,7 @@
|
|||||||
"isomorphic-fetch": "2.2.1",
|
"isomorphic-fetch": "2.2.1",
|
||||||
"js-sha3": "0.5.5",
|
"js-sha3": "0.5.5",
|
||||||
"lodash": "4.17.2",
|
"lodash": "4.17.2",
|
||||||
|
"loglevel": "1.4.1",
|
||||||
"marked": "0.3.6",
|
"marked": "0.3.6",
|
||||||
"material-ui": "0.16.5",
|
"material-ui": "0.16.5",
|
||||||
"material-ui-chip-input": "0.11.1",
|
"material-ui-chip-input": "0.11.1",
|
||||||
|
28
js/src/config.js
Normal file
28
js/src/config.js
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
// Copyright 2015, 2016 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/>.
|
||||||
|
|
||||||
|
import LogLevel from 'loglevel';
|
||||||
|
|
||||||
|
export const LOG_KEYS = {
|
||||||
|
TransferModalStore: {
|
||||||
|
path: 'modals/Transfer/store',
|
||||||
|
desc: 'Transfer Modal MobX Store'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getLogger = (LOG_KEY) => {
|
||||||
|
return LogLevel.getLogger(LOG_KEY.path);
|
||||||
|
};
|
@ -25,6 +25,9 @@ import ERRORS from './errors';
|
|||||||
import { ERROR_CODES } from '~/api/transport/error';
|
import { ERROR_CODES } from '~/api/transport/error';
|
||||||
import { DEFAULT_GAS, MAX_GAS_ESTIMATION } from '~/util/constants';
|
import { DEFAULT_GAS, MAX_GAS_ESTIMATION } from '~/util/constants';
|
||||||
import GasPriceStore from '~/ui/GasPriceEditor/store';
|
import GasPriceStore from '~/ui/GasPriceEditor/store';
|
||||||
|
import { getLogger, LOG_KEYS } from '~/config';
|
||||||
|
|
||||||
|
const log = getLogger(LOG_KEYS.TransferModalStore);
|
||||||
|
|
||||||
const TITLES = {
|
const TITLES = {
|
||||||
transfer: 'transfer details',
|
transfer: 'transfer details',
|
||||||
@ -332,13 +335,12 @@ export default class TransferStore {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@action recalculateGas = () => {
|
@action recalculateGas = (redo = true) => {
|
||||||
if (!this.isValid) {
|
if (!this.isValid) {
|
||||||
this.gasStore.setGas('0');
|
return this.recalculate(redo);
|
||||||
return this.recalculate();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this
|
return this
|
||||||
.estimateGas()
|
.estimateGas()
|
||||||
.then((gasEst) => {
|
.then((gasEst) => {
|
||||||
let gas = gasEst;
|
let gas = gasEst;
|
||||||
@ -351,76 +353,215 @@ export default class TransferStore {
|
|||||||
this.gasStore.setEstimated(gasEst.toFixed(0));
|
this.gasStore.setEstimated(gasEst.toFixed(0));
|
||||||
this.gasStore.setGas(gas.toFixed(0));
|
this.gasStore.setGas(gas.toFixed(0));
|
||||||
|
|
||||||
this.recalculate();
|
this.recalculate(redo);
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
console.warn('etimateGas', error);
|
console.warn('etimateGas', error);
|
||||||
this.recalculate();
|
this.recalculate(redo);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@action recalculate = () => {
|
getBalance (forceSender = false) {
|
||||||
const { account } = this;
|
if (this.isWallet && !forceSender) {
|
||||||
|
return this.balance;
|
||||||
if (!account || !this.balance) {
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const balance = this.senders
|
const balance = this.senders
|
||||||
? this.sendersBalances[this.sender]
|
? this.sendersBalances[this.sender]
|
||||||
: this.balance;
|
: this.balance;
|
||||||
|
|
||||||
|
return balance;
|
||||||
|
}
|
||||||
|
|
||||||
|
getToken (tag = this.tag, forceSender = false) {
|
||||||
|
const balance = this.getBalance(forceSender);
|
||||||
|
|
||||||
|
if (!balance) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const _tag = tag.toLowerCase();
|
||||||
|
const token = balance.tokens.find((b) => b.token.tag.toLowerCase() === _tag);
|
||||||
|
|
||||||
|
return token;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the balance of the selected token
|
||||||
|
* (in WEI for ETH, without formating for other tokens)
|
||||||
|
*/
|
||||||
|
getTokenBalance (tag = this.tag, forceSender = false) {
|
||||||
|
const token = this.getToken(tag, forceSender);
|
||||||
|
|
||||||
|
if (!token) {
|
||||||
|
return new BigNumber(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
const value = new BigNumber(token.value || 0);
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
getTokenValue (tag = this.tag, value = this.value, inverse = false) {
|
||||||
|
const token = this.getToken(tag);
|
||||||
|
|
||||||
|
if (!token) {
|
||||||
|
return new BigNumber(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
const format = token.token
|
||||||
|
? new BigNumber(token.token.format || 1)
|
||||||
|
: new BigNumber(1);
|
||||||
|
|
||||||
|
let _value;
|
||||||
|
|
||||||
|
try {
|
||||||
|
_value = new BigNumber(value || 0);
|
||||||
|
} catch (error) {
|
||||||
|
_value = new BigNumber(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (token.token && token.token.tag.toLowerCase() === 'eth') {
|
||||||
|
if (inverse) {
|
||||||
|
return this.api.util.fromWei(_value);
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.api.util.toWei(_value);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (inverse) {
|
||||||
|
return _value.div(format);
|
||||||
|
}
|
||||||
|
|
||||||
|
return _value.mul(format);
|
||||||
|
}
|
||||||
|
|
||||||
|
getValues (_gasTotal) {
|
||||||
|
const gasTotal = new BigNumber(_gasTotal || 0);
|
||||||
|
const { valueAll, isEth, isWallet } = this;
|
||||||
|
|
||||||
|
if (!valueAll) {
|
||||||
|
const value = this.getTokenValue();
|
||||||
|
|
||||||
|
// If it's a token or a wallet, eth is the estimated gas,
|
||||||
|
// and value is the user input
|
||||||
|
if (!isEth || isWallet) {
|
||||||
|
return {
|
||||||
|
eth: gasTotal,
|
||||||
|
token: value
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise, eth is the sum of the gas and the user input
|
||||||
|
const totalEthValue = gasTotal.plus(value);
|
||||||
|
|
||||||
|
return {
|
||||||
|
eth: totalEthValue,
|
||||||
|
token: value
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// If it's the total balance that needs to be sent, send the total balance
|
||||||
|
// if it's not a proper ETH transfer
|
||||||
|
if (!isEth || isWallet) {
|
||||||
|
const tokenBalance = this.getTokenBalance();
|
||||||
|
|
||||||
|
return {
|
||||||
|
eth: gasTotal,
|
||||||
|
token: tokenBalance
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise, substract the gas estimate
|
||||||
|
const availableEth = this.getTokenBalance('ETH');
|
||||||
|
const totalEthValue = availableEth.gt(gasTotal)
|
||||||
|
? availableEth.minus(gasTotal)
|
||||||
|
: new BigNumber(0);
|
||||||
|
|
||||||
|
return {
|
||||||
|
eth: totalEthValue.plus(gasTotal),
|
||||||
|
token: totalEthValue
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
getFormattedTokenValue (tokenValue) {
|
||||||
|
const token = this.getToken();
|
||||||
|
|
||||||
|
if (!token) {
|
||||||
|
return new BigNumber(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
const tag = token.token && token.token.tag || '';
|
||||||
|
|
||||||
|
return this.getTokenValue(tag, tokenValue, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@action recalculate = (redo = false) => {
|
||||||
|
const { account } = this;
|
||||||
|
|
||||||
|
if (!account || !this.balance) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const balance = this.getBalance();
|
||||||
|
|
||||||
if (!balance) {
|
if (!balance) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const { tag, valueAll, isEth, isWallet } = this;
|
|
||||||
|
|
||||||
const gasTotal = new BigNumber(this.gasStore.price || 0).mul(new BigNumber(this.gasStore.gas || 0));
|
const gasTotal = new BigNumber(this.gasStore.price || 0).mul(new BigNumber(this.gasStore.gas || 0));
|
||||||
|
|
||||||
const availableEth = new BigNumber(balance.tokens[0].value);
|
const ethBalance = this.getTokenBalance('ETH', true);
|
||||||
|
const tokenBalance = this.getTokenBalance();
|
||||||
|
const { eth, token } = this.getValues(gasTotal);
|
||||||
|
|
||||||
const senderBalance = this.balance.tokens.find((b) => tag === b.token.tag);
|
|
||||||
const format = new BigNumber(senderBalance.token.format || 1);
|
|
||||||
const available = new BigNumber(senderBalance.value).div(format);
|
|
||||||
|
|
||||||
let { value, valueError } = this;
|
|
||||||
let totalEth = gasTotal;
|
let totalEth = gasTotal;
|
||||||
let totalError = null;
|
let totalError = null;
|
||||||
|
let valueError = null;
|
||||||
|
|
||||||
if (valueAll) {
|
if (eth.gt(ethBalance)) {
|
||||||
if (isEth && !isWallet) {
|
|
||||||
const bn = this.api.util.fromWei(availableEth.minus(gasTotal));
|
|
||||||
value = (bn.lt(0) ? new BigNumber(0.0) : bn).toString();
|
|
||||||
} else if (isEth) {
|
|
||||||
value = (available.lt(0) ? new BigNumber(0.0) : available).toString();
|
|
||||||
} else {
|
|
||||||
value = available.toString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isEth && !isWallet) {
|
|
||||||
totalEth = totalEth.plus(this.api.util.toWei(value || 0));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (new BigNumber(value || 0).gt(available)) {
|
|
||||||
valueError = ERRORS.largeAmount;
|
|
||||||
} else if (valueError === ERRORS.largeAmount) {
|
|
||||||
valueError = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (totalEth.gt(availableEth)) {
|
|
||||||
totalError = ERRORS.largeAmount;
|
totalError = ERRORS.largeAmount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (token && token.gt(tokenBalance)) {
|
||||||
|
valueError = ERRORS.largeAmount;
|
||||||
|
}
|
||||||
|
|
||||||
|
log.debug('@recalculate', {
|
||||||
|
eth: eth.toFormat(),
|
||||||
|
token: token.toFormat(),
|
||||||
|
ethBalance: ethBalance.toFormat(),
|
||||||
|
tokenBalance: tokenBalance.toFormat(),
|
||||||
|
gasTotal: gasTotal.toFormat()
|
||||||
|
});
|
||||||
|
|
||||||
transaction(() => {
|
transaction(() => {
|
||||||
this.total = this.api.util.fromWei(totalEth).toFixed();
|
|
||||||
this.totalError = totalError;
|
this.totalError = totalError;
|
||||||
this.value = value;
|
|
||||||
this.valueError = valueError;
|
this.valueError = valueError;
|
||||||
this.gasStore.setErrorTotal(totalError);
|
this.gasStore.setErrorTotal(totalError);
|
||||||
this.gasStore.setEthValue(totalEth);
|
this.gasStore.setEthValue(totalEth);
|
||||||
|
|
||||||
|
this.total = this.api.util.fromWei(eth).toFixed();
|
||||||
|
|
||||||
|
const nextValue = this.getFormattedTokenValue(token);
|
||||||
|
let prevValue;
|
||||||
|
|
||||||
|
try {
|
||||||
|
prevValue = new BigNumber(this.value || 0);
|
||||||
|
} catch (error) {
|
||||||
|
prevValue = new BigNumber(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Change the input only if necessary
|
||||||
|
if (!nextValue.eq(prevValue)) {
|
||||||
|
this.value = nextValue.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Re Calculate gas once more to be sure
|
||||||
|
if (redo) {
|
||||||
|
return this.recalculateGas(false);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -485,8 +626,10 @@ export default class TransferStore {
|
|||||||
options.gas = MAX_GAS_ESTIMATION;
|
options.gas = MAX_GAS_ESTIMATION;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const { token } = this.getValues(options.gas);
|
||||||
|
|
||||||
if (isEth && !isWallet && !forceToken) {
|
if (isEth && !isWallet && !forceToken) {
|
||||||
options.value = this.api.util.toWei(this.value || 0);
|
options.value = token;
|
||||||
options.data = this._getData(gas);
|
options.data = this._getData(gas);
|
||||||
|
|
||||||
return { options, values: [] };
|
return { options, values: [] };
|
||||||
@ -494,7 +637,7 @@ export default class TransferStore {
|
|||||||
|
|
||||||
if (isWallet && !forceToken) {
|
if (isWallet && !forceToken) {
|
||||||
const to = isEth ? this.recipient : this.token.contract.address;
|
const to = isEth ? this.recipient : this.token.contract.address;
|
||||||
const value = isEth ? this.api.util.toWei(this.value || 0) : new BigNumber(0);
|
const value = isEth ? token : new BigNumber(0);
|
||||||
|
|
||||||
const values = [
|
const values = [
|
||||||
to, value,
|
to, value,
|
||||||
@ -506,7 +649,7 @@ export default class TransferStore {
|
|||||||
|
|
||||||
const values = [
|
const values = [
|
||||||
this.recipient,
|
this.recipient,
|
||||||
new BigNumber(this.value || 0).mul(this.token.format).toFixed(0)
|
token.toFixed(0)
|
||||||
];
|
];
|
||||||
|
|
||||||
return { options, values };
|
return { options, values };
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
import React, { Component, PropTypes } from 'react';
|
import React, { Component, PropTypes } from 'react';
|
||||||
import { SelectField } from 'material-ui';
|
import { MenuItem, SelectField } from 'material-ui';
|
||||||
|
|
||||||
import { nodeOrStringProptype } from '~/util/proptypes';
|
import { nodeOrStringProptype } from '~/util/proptypes';
|
||||||
|
|
||||||
@ -42,11 +42,12 @@ export default class Select extends Component {
|
|||||||
onChange: PropTypes.func,
|
onChange: PropTypes.func,
|
||||||
onKeyDown: PropTypes.func,
|
onKeyDown: PropTypes.func,
|
||||||
type: PropTypes.string,
|
type: PropTypes.string,
|
||||||
value: PropTypes.any
|
value: PropTypes.any,
|
||||||
|
values: PropTypes.array
|
||||||
}
|
}
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { children, className, disabled, error, hint, label, onBlur, onChange, onKeyDown, value } = this.props;
|
const { className, disabled, error, hint, label, onBlur, onChange, onKeyDown, value } = this.props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SelectField
|
<SelectField
|
||||||
@ -65,9 +66,36 @@ export default class Select extends Component {
|
|||||||
onKeyDown={ onKeyDown }
|
onKeyDown={ onKeyDown }
|
||||||
underlineDisabledStyle={ UNDERLINE_DISABLED }
|
underlineDisabledStyle={ UNDERLINE_DISABLED }
|
||||||
underlineStyle={ UNDERLINE_NORMAL }
|
underlineStyle={ UNDERLINE_NORMAL }
|
||||||
value={ value }>
|
value={ value }
|
||||||
{ children }
|
>
|
||||||
|
{ this.renderChildren() }
|
||||||
</SelectField>
|
</SelectField>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
renderChildren () {
|
||||||
|
const { children, values } = this.props;
|
||||||
|
|
||||||
|
if (children) {
|
||||||
|
return children;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!values) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return values.map((data, index) => {
|
||||||
|
const { name = index, value = index } = data;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<MenuItem
|
||||||
|
key={ index }
|
||||||
|
label={ name }
|
||||||
|
value={ value }
|
||||||
|
>
|
||||||
|
{ name }
|
||||||
|
</MenuItem>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,9 @@
|
|||||||
import React, { Component, PropTypes } from 'react';
|
import React, { Component, PropTypes } from 'react';
|
||||||
import { FormattedMessage } from 'react-intl';
|
import { FormattedMessage } from 'react-intl';
|
||||||
import { MenuItem } from 'material-ui';
|
import { MenuItem } from 'material-ui';
|
||||||
|
import LogLevel from 'loglevel';
|
||||||
|
|
||||||
|
import { LOG_KEYS } from '~/config';
|
||||||
import { Select, Container, LanguageSelector } from '~/ui';
|
import { Select, Container, LanguageSelector } from '~/ui';
|
||||||
|
|
||||||
import layout from '../layout.css';
|
import layout from '../layout.css';
|
||||||
@ -25,14 +27,54 @@ import layout from '../layout.css';
|
|||||||
export default class Parity extends Component {
|
export default class Parity extends Component {
|
||||||
static contextTypes = {
|
static contextTypes = {
|
||||||
api: PropTypes.object.isRequired
|
api: PropTypes.object.isRequired
|
||||||
}
|
};
|
||||||
|
|
||||||
state = {
|
state = {
|
||||||
mode: 'active'
|
loglevels: {},
|
||||||
}
|
mode: 'active',
|
||||||
|
selectValues: []
|
||||||
|
};
|
||||||
|
|
||||||
componentWillMount () {
|
componentWillMount () {
|
||||||
this.loadMode();
|
this.loadMode();
|
||||||
|
this.loadLogLevels();
|
||||||
|
this.setSelectValues();
|
||||||
|
}
|
||||||
|
|
||||||
|
loadLogLevels () {
|
||||||
|
if (process.env.NODE_ENV === 'production') {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const nextState = { ...this.state.logLevels };
|
||||||
|
|
||||||
|
Object.keys(LOG_KEYS).map((logKey) => {
|
||||||
|
const log = LOG_KEYS[logKey];
|
||||||
|
|
||||||
|
const logger = LogLevel.getLogger(log.path);
|
||||||
|
const level = logger.getLevel();
|
||||||
|
|
||||||
|
nextState[logKey] = { level, log };
|
||||||
|
});
|
||||||
|
|
||||||
|
this.setState({ logLevels: nextState });
|
||||||
|
}
|
||||||
|
|
||||||
|
setSelectValues () {
|
||||||
|
if (process.env.NODE_ENV === 'production') {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const selectValues = Object.keys(LogLevel.levels).map((levelName) => {
|
||||||
|
const value = LogLevel.levels[levelName];
|
||||||
|
|
||||||
|
return {
|
||||||
|
name: levelName,
|
||||||
|
value
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
this.setState({ selectValues });
|
||||||
}
|
}
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
@ -45,7 +87,8 @@ export default class Parity extends Component {
|
|||||||
<div>
|
<div>
|
||||||
<FormattedMessage
|
<FormattedMessage
|
||||||
id='settings.parity.overview_0'
|
id='settings.parity.overview_0'
|
||||||
defaultMessage='Control the Parity node settings and mode of operation via this interface.' />
|
defaultMessage='Control the Parity node settings and mode of operation via this interface.'
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className={ layout.details }>
|
<div className={ layout.details }>
|
||||||
@ -53,10 +96,64 @@ export default class Parity extends Component {
|
|||||||
{ this.renderModes() }
|
{ this.renderModes() }
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{ this.renderLogsConfig() }
|
||||||
</Container>
|
</Container>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
renderLogsConfig () {
|
||||||
|
if (process.env.NODE_ENV === 'production') {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={ layout.layout }>
|
||||||
|
<div className={ layout.overview }>
|
||||||
|
<div>
|
||||||
|
<FormattedMessage
|
||||||
|
id='settings.parity.loglevels'
|
||||||
|
defaultMessage='Choose the different logs level.'
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className={ layout.details }>
|
||||||
|
{ this.renderLogsLevels() }
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
renderLogsLevels () {
|
||||||
|
if (process.env.NODE_ENV === 'production') {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const { logLevels, selectValues } = this.state;
|
||||||
|
|
||||||
|
return Object.keys(logLevels).map((logKey) => {
|
||||||
|
const { level, log } = logLevels[logKey];
|
||||||
|
const { path, desc } = log;
|
||||||
|
|
||||||
|
const onChange = (_, index) => {
|
||||||
|
const nextLevel = Object.values(selectValues)[index].value;
|
||||||
|
LogLevel.getLogger(path).setLevel(nextLevel);
|
||||||
|
this.loadLogLevels();
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div key={ logKey }>
|
||||||
|
<p>{ desc }</p>
|
||||||
|
<Select
|
||||||
|
onChange={ onChange }
|
||||||
|
value={ level }
|
||||||
|
values={ selectValues }
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
renderModes () {
|
renderModes () {
|
||||||
const { mode } = this.state;
|
const { mode } = this.state;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user