mirror of
https://github.com/status-im/embark-area-51.git
synced 2025-01-10 05:56:00 +00:00
Adding new reducer and selector
This commit is contained in:
parent
0beb1cb78d
commit
85ad3f3edc
@ -1,4 +1,3 @@
|
|||||||
// Accounts
|
|
||||||
export const REQUEST = 'REQUEST';
|
export const REQUEST = 'REQUEST';
|
||||||
export const SUCCESS = 'SUCCESS';
|
export const SUCCESS = 'SUCCESS';
|
||||||
export const FAILURE = 'FAILURE';
|
export const FAILURE = 'FAILURE';
|
||||||
@ -24,7 +23,7 @@ export const accounts = {
|
|||||||
export const ACCOUNT = createRequestTypes('ACCOUNT');
|
export const ACCOUNT = createRequestTypes('ACCOUNT');
|
||||||
export const account = {
|
export const account = {
|
||||||
request: (address) => action(ACCOUNT[REQUEST], {address}),
|
request: (address) => action(ACCOUNT[REQUEST], {address}),
|
||||||
success: (account) => action(ACCOUNT[SUCCESS], {account}),
|
success: (account) => action(ACCOUNT[SUCCESS], {accounts: [account]}),
|
||||||
failure: (error) => action(ACCOUNT[FAILURE], {error})
|
failure: (error) => action(ACCOUNT[FAILURE], {error})
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -38,7 +37,7 @@ export const blocks = {
|
|||||||
export const BLOCK = createRequestTypes('BLOCK');
|
export const BLOCK = createRequestTypes('BLOCK');
|
||||||
export const block = {
|
export const block = {
|
||||||
request: (blockNumber) => action(BLOCK[REQUEST], {blockNumber}),
|
request: (blockNumber) => action(BLOCK[REQUEST], {blockNumber}),
|
||||||
success: (block) => action(BLOCK[SUCCESS], {block}),
|
success: (block) => action(BLOCK[SUCCESS], {blocks: [block]}),
|
||||||
failure: (error) => action(BLOCK[FAILURE], {error})
|
failure: (error) => action(BLOCK[FAILURE], {error})
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -52,7 +51,7 @@ export const transactions = {
|
|||||||
export const TRANSACTION = createRequestTypes('TRANSACTION');
|
export const TRANSACTION = createRequestTypes('TRANSACTION');
|
||||||
export const transaction = {
|
export const transaction = {
|
||||||
request: (hash) => action(TRANSACTION[REQUEST], {hash}),
|
request: (hash) => action(TRANSACTION[REQUEST], {hash}),
|
||||||
success: (transaction) => action(TRANSACTION[SUCCESS], {transaction}),
|
success: (transaction) => action(TRANSACTION[SUCCESS], {transactions: [transaction]}),
|
||||||
failure: (error) => action(TRANSACTION[FAILURE], {error})
|
failure: (error) => action(TRANSACTION[FAILURE], {error})
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -66,37 +65,41 @@ export const processes = {
|
|||||||
export const COMMANDS = createRequestTypes('COMMANDS');
|
export const COMMANDS = createRequestTypes('COMMANDS');
|
||||||
export const commands = {
|
export const commands = {
|
||||||
post: (command) => action(COMMANDS[REQUEST], {command}),
|
post: (command) => action(COMMANDS[REQUEST], {command}),
|
||||||
success: (result) => action(COMMANDS[SUCCESS], {result}),
|
success: (command) => action(COMMANDS[SUCCESS], {commands: [command]}),
|
||||||
failure: (error) => action(COMMANDS[FAILURE], {error})
|
failure: (error) => action(COMMANDS[FAILURE], {error})
|
||||||
};
|
};
|
||||||
|
|
||||||
// Process logs
|
export const PROCESS_LOGS = createRequestTypes('PROCESS_LOGS');
|
||||||
export const FETCH_PROCESS_LOGS = 'FETCH_PROCESS_LOGS';
|
export const processLogs = {
|
||||||
export const RECEIVE_PROCESS_LOGS = 'RECEIVE_PROCESS_LOGS';
|
request: (processName) => action(PROCESS_LOGS[REQUEST], {processName}),
|
||||||
export const WATCH_NEW_PROCESS_LOGS = 'WATCH_NEW_PROCESS_LOGS';
|
success: (processLogs) => action(PROCESS_LOGS[SUCCESS], {processLogs}),
|
||||||
export const RECEIVE_NEW_PROCESS_LOG = 'RECEIVE_NEW_PROCESS_LOG';
|
failure: (error) => action(PROCESS_LOGS[FAILURE], {error})
|
||||||
export const RECEIVE_PROCESS_LOGS_ERROR = 'RECEIVE_PROCESS_LOGS_ERROR';
|
};
|
||||||
// BlockHeader
|
|
||||||
export const INIT_BLOCK_HEADER = 'INIT_BLOCK_HEADER';
|
|
||||||
// Contracts
|
|
||||||
export const FETCH_CONTRACTS = 'FETCH_CONTRACTS';
|
|
||||||
export const RECEIVE_CONTRACTS = 'RECEIVE_CONTRACTS';
|
|
||||||
export const RECEIVE_CONTRACTS_ERROR = 'RECEIVE_CONTRACTS_ERROR';
|
|
||||||
// Contract
|
|
||||||
export const FETCH_CONTRACT = 'FETCH_CONTRACT';
|
|
||||||
export const RECEIVE_CONTRACT = 'RECEIVE_CONTRACT';
|
|
||||||
export const RECEIVE_CONTRACT_ERROR = 'RECEIVE_CONTRACT_ERROR';
|
|
||||||
// Contract Profile
|
|
||||||
export const FETCH_CONTRACT_PROFILE = 'FETCH_CONTRACT_PROFILE';
|
|
||||||
export const RECEIVE_CONTRACT_PROFILE = 'RECEIVE_CONTRACT_PROFILE';
|
|
||||||
export const RECEIVE_CONTRACT_PROFILE_ERROR = 'RECEIVE_CONTRACT_PROFILE_ERROR';
|
|
||||||
|
|
||||||
export function fetchProcessLogs(processName) {
|
export const CONTRACTS = createRequestTypes('CONTRACTS');
|
||||||
return {
|
export const contracts = {
|
||||||
type: FETCH_PROCESS_LOGS,
|
request: () => action(CONTRACTS[REQUEST]),
|
||||||
processName
|
success: (contracts) => action(CONTRACTS[SUCCESS], {contracts}),
|
||||||
};
|
failure: (error) => action(CONTRACTS[FAILURE], {error})
|
||||||
}
|
};
|
||||||
|
|
||||||
|
export const CONTRACT = createRequestTypes('CONTRACT');
|
||||||
|
export const contract = {
|
||||||
|
request: (contractName) => action(CONTRACT[REQUEST], {contractName}),
|
||||||
|
success: (contract) => action(CONTRACT[SUCCESS], {contracts: [contract]}),
|
||||||
|
failure: (error) => action(CONTRACT[FAILURE], {error})
|
||||||
|
};
|
||||||
|
|
||||||
|
export const CONTRACT_PROFILE = createRequestTypes('CONTRACT_PROFILE');
|
||||||
|
export const contractProfile = {
|
||||||
|
request: (contractName) => action(CONTRACT_PROFILE[REQUEST], {contractName}),
|
||||||
|
success: (contractProfile) => action(CONTRACT_PROFILE[SUCCESS], {contractProfiles: [contractProfile]}),
|
||||||
|
failure: (error) => action(CONTRACT_PROFILE[FAILURE], {error})
|
||||||
|
};
|
||||||
|
|
||||||
|
// Web Socket
|
||||||
|
export const WATCH_NEW_PROCESS_LOGS = 'WATCH_NEW_PROCESS_LOGS';
|
||||||
|
export const INIT_BLOCK_HEADER = 'INIT_BLOCK_HEADER';
|
||||||
|
|
||||||
export function listenToProcessLogs(processName) {
|
export function listenToProcessLogs(processName) {
|
||||||
return {
|
return {
|
||||||
@ -105,84 +108,8 @@ export function listenToProcessLogs(processName) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function receiveProcessLogs(processName, logs) {
|
|
||||||
return {
|
|
||||||
type: RECEIVE_PROCESS_LOGS,
|
|
||||||
processName,
|
|
||||||
logs
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function receiveProcessLogsError(error) {
|
|
||||||
return {
|
|
||||||
type: RECEIVE_PROCESS_LOGS_ERROR,
|
|
||||||
error
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function initBlockHeader(){
|
export function initBlockHeader(){
|
||||||
return {
|
return {
|
||||||
type: INIT_BLOCK_HEADER
|
type: INIT_BLOCK_HEADER
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function fetchContractProfile(contractName) {
|
|
||||||
return {
|
|
||||||
type: FETCH_CONTRACT_PROFILE,
|
|
||||||
contractName
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function receiveContractProfile(contractProfile) {
|
|
||||||
return {
|
|
||||||
type: RECEIVE_CONTRACT_PROFILE,
|
|
||||||
contractProfile
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function receiveContractProfileError() {
|
|
||||||
return {
|
|
||||||
type: RECEIVE_CONTRACT_PROFILE_ERROR
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function fetchContract(contractName) {
|
|
||||||
return {
|
|
||||||
type: FETCH_CONTRACT,
|
|
||||||
contractName
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function receiveContract(contract) {
|
|
||||||
return {
|
|
||||||
type: RECEIVE_CONTRACT,
|
|
||||||
contract
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function receiveContractError() {
|
|
||||||
return {
|
|
||||||
type: RECEIVE_CONTRACT_ERROR
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
export function fetchContracts() {
|
|
||||||
return {
|
|
||||||
type: FETCH_CONTRACTS
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function receiveContracts(contracts) {
|
|
||||||
return {
|
|
||||||
type: RECEIVE_CONTRACTS,
|
|
||||||
contracts
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function receiveContractsError() {
|
|
||||||
return {
|
|
||||||
type: RECEIVE_CONTRACTS_ERROR
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
|
@ -53,8 +53,20 @@ export function fetchProcesses() {
|
|||||||
return get('/processes');
|
return get('/processes');
|
||||||
}
|
}
|
||||||
|
|
||||||
export function fetchProcessLogs(processName) {
|
export function fetchProcessLogs(payload) {
|
||||||
return axios.get(`${constants.httpEndpoint}/process-logs/${processName}`);
|
return get(`/process-logs/${payload.processName}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function fetchContracts() {
|
||||||
|
return get('/contracts');
|
||||||
|
}
|
||||||
|
|
||||||
|
export function fetchContract(payload) {
|
||||||
|
return get(`/contract/${payload.contractName}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function fetchContractProfile(payload) {
|
||||||
|
return get(`/profiler/${payload.contractName}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function webSocketProcess(processName) {
|
export function webSocketProcess(processName) {
|
||||||
@ -64,15 +76,3 @@ export function webSocketProcess(processName) {
|
|||||||
export function webSocketBlockHeader() {
|
export function webSocketBlockHeader() {
|
||||||
return new WebSocket(`${constants.wsEndpoint}/blockchain/blockHeader`);
|
return new WebSocket(`${constants.wsEndpoint}/blockchain/blockHeader`);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function fetchContract(contractName) {
|
|
||||||
return axios.get(`${constants.httpEndpoint}/contract/${contractName}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function fetchContracts() {
|
|
||||||
return axios.get(`${constants.httpEndpoint}/contracts`);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function fetchContractProfile(contractName) {
|
|
||||||
return axios.get(`${constants.httpEndpoint}/profiler/${contractName}`);
|
|
||||||
}
|
|
||||||
|
@ -36,8 +36,7 @@ class Console extends Component {
|
|||||||
</Card.Header>
|
</Card.Header>
|
||||||
<Card.Body>
|
<Card.Body>
|
||||||
<div>
|
<div>
|
||||||
{this.props.commandResults &&
|
{this.props.commands.map((command, index) => <CommandResult key={index} result={command.result} />)}
|
||||||
this.props.commandResults.map((result) => <CommandResult key={result} result={result} />)}
|
|
||||||
</div>
|
</div>
|
||||||
<Form onSubmit={(event) => this.handleSubmit(event)}>
|
<Form onSubmit={(event) => this.handleSubmit(event)}>
|
||||||
<Form.Input value={this.state.value}
|
<Form.Input value={this.state.value}
|
||||||
@ -55,7 +54,7 @@ class Console extends Component {
|
|||||||
|
|
||||||
Console.propTypes = {
|
Console.propTypes = {
|
||||||
postCommand: PropTypes.func,
|
postCommand: PropTypes.func,
|
||||||
commandResults: PropTypes.arrayOf(PropTypes.string)
|
commands: PropTypes.arrayOf(PropTypes.object)
|
||||||
};
|
};
|
||||||
|
|
||||||
export default Console;
|
export default Console;
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import PropTypes from "prop-types";
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import {
|
import {
|
||||||
Page,
|
Page,
|
||||||
@ -33,5 +34,9 @@ const Contract = ({contract}) => (
|
|||||||
</Page.Content>
|
</Page.Content>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
Contract.propTypes = {
|
||||||
|
contract: PropTypes.object
|
||||||
|
};
|
||||||
|
|
||||||
export default Contract;
|
export default Contract;
|
||||||
|
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import PropTypes from "prop-types";
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import {NavLink, Route, Switch, withRouter} from 'react-router-dom';
|
import {NavLink, Route, Switch, withRouter} from 'react-router-dom';
|
||||||
import {
|
import {
|
||||||
@ -59,4 +60,8 @@ const ContractLayout = (props) => (
|
|||||||
</Grid.Row>
|
</Grid.Row>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
ContractLayout.propTypes = {
|
||||||
|
match: PropTypes.object
|
||||||
|
};
|
||||||
|
|
||||||
export default withRouter(ContractLayout);
|
export default withRouter(ContractLayout);
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import PropTypes from "prop-types";
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import {
|
import {
|
||||||
Page,
|
Page,
|
||||||
@ -6,8 +7,8 @@ import {
|
|||||||
Table
|
Table
|
||||||
} from "tabler-react";
|
} from "tabler-react";
|
||||||
|
|
||||||
const ContractProfile = ({contract}) => (
|
const ContractProfile = ({contractProfile}) => (
|
||||||
<Page.Content title={contract.name}>
|
<Page.Content title={contractProfile.name}>
|
||||||
<Grid.Row>
|
<Grid.Row>
|
||||||
<Grid.Col>
|
<Grid.Col>
|
||||||
<Card>
|
<Card>
|
||||||
@ -23,7 +24,7 @@ const ContractProfile = ({contract}) => (
|
|||||||
{content: "Gas Estimates"}
|
{content: "Gas Estimates"}
|
||||||
]}
|
]}
|
||||||
bodyItems={
|
bodyItems={
|
||||||
contract.methods.map((method) => {
|
contractProfile.methods.map((method) => {
|
||||||
return ([
|
return ([
|
||||||
{content: method.name},
|
{content: method.name},
|
||||||
{content: (method.payable === true).toString()},
|
{content: (method.payable === true).toString()},
|
||||||
@ -41,5 +42,9 @@ const ContractProfile = ({contract}) => (
|
|||||||
</Page.Content>
|
</Page.Content>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
ContractProfile.propTypes = {
|
||||||
|
contractProfile: PropTypes.object
|
||||||
|
};
|
||||||
|
|
||||||
export default ContractProfile;
|
export default ContractProfile;
|
||||||
|
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import PropTypes from "prop-types";
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import {
|
import {
|
||||||
Page,
|
Page,
|
||||||
@ -25,7 +26,7 @@ const Contracts = ({contracts}) => (
|
|||||||
return ([
|
return ([
|
||||||
{content: <Link to={`contracts/${contract.name}`}>{contract.name}</Link>},
|
{content: <Link to={`contracts/${contract.name}`}>{contract.name}</Link>},
|
||||||
{content: contract.address},
|
{content: contract.address},
|
||||||
{content: contract.deploy}
|
{content: contract.deploy.toString()}
|
||||||
]);
|
]);
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -36,5 +37,9 @@ const Contracts = ({contracts}) => (
|
|||||||
</Page.Content>
|
</Page.Content>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
Contracts.propTypes = {
|
||||||
|
contracts: PropTypes.arrayOf(PropTypes.object)
|
||||||
|
};
|
||||||
|
|
||||||
export default Contracts;
|
export default Contracts;
|
||||||
|
|
||||||
|
30
embark-ui/src/components/DataWrapper.js
Normal file
30
embark-ui/src/components/DataWrapper.js
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import React from "react";
|
||||||
|
|
||||||
|
import Loading from '../components/Loading';
|
||||||
|
import Error from '../components/Error';
|
||||||
|
|
||||||
|
const DataWrapper = ({error, loading, shouldRender, render, ...rest}) => {
|
||||||
|
if (error) {
|
||||||
|
return <Error error={error} />;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (loading) {
|
||||||
|
return <Loading />;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (shouldRender) {
|
||||||
|
return render(rest);
|
||||||
|
}
|
||||||
|
|
||||||
|
return <React.Fragment />;
|
||||||
|
};
|
||||||
|
|
||||||
|
DataWrapper.propTypes = {
|
||||||
|
error: PropTypes.string,
|
||||||
|
loading: PropTypes.bool,
|
||||||
|
render: PropTypes.func,
|
||||||
|
shouldRender: PropTypes.bool
|
||||||
|
};
|
||||||
|
|
||||||
|
export default DataWrapper;
|
@ -1,30 +1,26 @@
|
|||||||
import React, {Component} from 'react';
|
import React, {Component} from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import {Page} from "tabler-react";
|
import {Page} from "tabler-react";
|
||||||
import Loading from "./Loading";
|
|
||||||
|
|
||||||
class Process extends Component {
|
class Process extends Component {
|
||||||
render() {
|
render() {
|
||||||
const logs = this.props.logs;
|
const {processLogs, process}= this.props;
|
||||||
return (
|
return (
|
||||||
<Page.Content className="text-capitalize" title={this.props.processName}>
|
<Page.Content className="text-capitalize" title={process.name}>
|
||||||
<p className="text-capitalize">State: {this.props.state}</p>
|
<p className="text-capitalize">State: {process.state}</p>
|
||||||
{!logs &&
|
|
||||||
<Loading/>}
|
|
||||||
{logs &&
|
|
||||||
<div className="logs">
|
<div className="logs">
|
||||||
{
|
{
|
||||||
logs.map((item, i) => <p key={i} className={item.logLevel}>{item.msg_clear || item.msg}</p>)
|
processLogs.map((item, i) => <p key={i} className={item.logLevel}>{item.msg_clear || item.msg}</p>)
|
||||||
}
|
}
|
||||||
</div>}
|
</div>
|
||||||
</Page.Content>);
|
</Page.Content>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Process.propTypes = {
|
Process.propTypes = {
|
||||||
processName: PropTypes.string.isRequired,
|
process: PropTypes.object,
|
||||||
state: PropTypes.string.isRequired,
|
processLogs: PropTypes.arrayOf(PropTypes.object)
|
||||||
logs: PropTypes.array
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export default Process;
|
export default Process;
|
||||||
|
@ -11,15 +11,15 @@ function stampClasses(state){
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const Process = ({name, state}) => (
|
const Process = ({process}) => (
|
||||||
<Grid.Col sm={6} lg={3}>
|
<Grid.Col sm={6} lg={3}>
|
||||||
<Card className="p-3">
|
<Card className="p-3">
|
||||||
<div className="d-flex align-items-center">
|
<div className="d-flex align-items-center">
|
||||||
<span className={stampClasses(state)}>
|
<span className={stampClasses(process.state)}>
|
||||||
<i className="fe fa-cube"></i>
|
<i className="fe fa-cube"></i>
|
||||||
</span>
|
</span>
|
||||||
<div>
|
<div>
|
||||||
<h4 className="text-capitalize m-0"><Link to={`/embark/processes/${name}`}>{name}</Link></h4>
|
<h4 className="text-capitalize m-0"><Link to={`/embark/processes/${process.name}`}>{process.name}</Link></h4>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Card>
|
</Card>
|
||||||
@ -27,18 +27,17 @@ const Process = ({name, state}) => (
|
|||||||
);
|
);
|
||||||
|
|
||||||
Process.propTypes = {
|
Process.propTypes = {
|
||||||
name: PropTypes.string,
|
process: PropTypes.object
|
||||||
state: PropTypes.string
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const Processes = ({processes}) => (
|
const Processes = ({processes}) => (
|
||||||
<Grid.Row cards>
|
<Grid.Row cards>
|
||||||
{Object.keys(processes).map((name) => <Process key={name} name={name} state={processes[name].state} />)}
|
{processes.map((process) => <Process key={process.name} process={process} />)}
|
||||||
</Grid.Row>
|
</Grid.Row>
|
||||||
);
|
);
|
||||||
|
|
||||||
Processes.propTypes = {
|
Processes.propTypes = {
|
||||||
processes: PropTypes.object
|
processes: PropTypes.arrayOf(PropTypes.object)
|
||||||
};
|
};
|
||||||
|
|
||||||
export default Processes;
|
export default Processes;
|
||||||
|
@ -1,40 +1,38 @@
|
|||||||
import PropTypes from "prop-types";
|
import PropTypes from "prop-types";
|
||||||
import React, {Component} from 'react';
|
import React, {Component} from 'react';
|
||||||
import connect from "react-redux/es/connect/connect";
|
import connect from "react-redux/es/connect/connect";
|
||||||
import {NavLink, Route, Switch, withRouter} from 'react-router-dom';
|
import {NavLink, Route, Switch, withRouter, Redirect} from 'react-router-dom';
|
||||||
import {
|
import {
|
||||||
Page,
|
Page,
|
||||||
Grid,
|
Grid,
|
||||||
List
|
List
|
||||||
} from "tabler-react";
|
} from "tabler-react";
|
||||||
|
|
||||||
import ProcessesContainer from '../containers/ProcessesContainer';
|
import ProcessContainer from '../containers/ProcessContainer';
|
||||||
|
import {getProcesses} from "../reducers/selectors";
|
||||||
import Loading from "./Loading";
|
import Loading from "./Loading";
|
||||||
|
|
||||||
const routePrefix = '/embark/processes';
|
const routePrefix = '/embark/processes';
|
||||||
|
|
||||||
class ProcessesLayout extends Component {
|
class ProcessesLayout extends Component {
|
||||||
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
if (!this.props.processes || !this.props.processes.data) {
|
if (this.props.processes.length === 0) {
|
||||||
return <Loading />;
|
return <Loading />;
|
||||||
}
|
}
|
||||||
const processNames = Object.keys(this.props.processes.data) || [];
|
|
||||||
return (<Grid.Row>
|
return (<Grid.Row>
|
||||||
<Grid.Col md={3}>
|
<Grid.Col md={3}>
|
||||||
<Page.Title className="my-5">Processes</Page.Title>
|
<Page.Title className="my-5">Processes</Page.Title>
|
||||||
<div>
|
<div>
|
||||||
<List.Group transparent={true}>
|
<List.Group transparent={true}>
|
||||||
{processNames.map((processName, index) => {
|
{this.props.processes.map((process, index) => {
|
||||||
return (<List.GroupItem
|
return (<List.GroupItem
|
||||||
className="d-flex align-items-center text-capitalize"
|
className="d-flex align-items-center text-capitalize"
|
||||||
to={`${routePrefix}/${processName}`}
|
to={`${routePrefix}/${process.name}`}
|
||||||
key={'process-' + processName}
|
key={'process-' + process.name}
|
||||||
active={index === 0 && this.props.match.isExact === true}
|
active={index === 0 && this.props.match.isExact === true}
|
||||||
RootComponent={withRouter(NavLink)}
|
RootComponent={withRouter(NavLink)}
|
||||||
>
|
>
|
||||||
{processName}
|
{process.name}
|
||||||
</List.GroupItem>);
|
</List.GroupItem>);
|
||||||
})}
|
})}
|
||||||
|
|
||||||
@ -43,10 +41,8 @@ class ProcessesLayout extends Component {
|
|||||||
</Grid.Col>
|
</Grid.Col>
|
||||||
<Grid.Col md={9}>
|
<Grid.Col md={9}>
|
||||||
<Switch>
|
<Switch>
|
||||||
<Route exact path={`${routePrefix}/`} component={ProcessesContainer} />
|
<Route exact path={`${routePrefix}/:processName`} component={() => <ProcessContainer />} />
|
||||||
{processNames.map((processName, index) => {
|
<Redirect exact from={`${routePrefix}/`} to={`${routePrefix}/${this.props.processes[0].name}`} />
|
||||||
return (<Route key={'procesRoute-' + index} exact path={`${routePrefix}/${processName}`} component={ProcessesContainer}/>);
|
|
||||||
})}
|
|
||||||
</Switch>
|
</Switch>
|
||||||
</Grid.Col>
|
</Grid.Col>
|
||||||
</Grid.Row>);
|
</Grid.Row>);
|
||||||
@ -54,12 +50,12 @@ class ProcessesLayout extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ProcessesLayout.propTypes = {
|
ProcessesLayout.propTypes = {
|
||||||
processes: PropTypes.object,
|
processes: PropTypes.arrayOf(PropTypes.object),
|
||||||
match: PropTypes.object
|
match: PropTypes.object
|
||||||
};
|
};
|
||||||
|
|
||||||
function mapStateToProps(state) {
|
function mapStateToProps(state) {
|
||||||
return {processes: state.processes};
|
return {processes: getProcesses(state)};
|
||||||
}
|
}
|
||||||
|
|
||||||
export default connect(
|
export default connect(
|
||||||
|
@ -5,9 +5,9 @@ import {withRouter} from 'react-router-dom';
|
|||||||
|
|
||||||
import {account as accountAction} from '../actions';
|
import {account as accountAction} from '../actions';
|
||||||
import Account from '../components/Account';
|
import Account from '../components/Account';
|
||||||
import NoMatch from "../components/NoMatch";
|
import DataWrapper from "../components/DataWrapper";
|
||||||
import Transactions from '../components/Transactions';
|
import Transactions from '../components/Transactions';
|
||||||
import Error from '../components/Error';
|
import {getAccount, getTransactionsByAccount} from "../reducers/selectors";
|
||||||
|
|
||||||
class AccountContainer extends Component {
|
class AccountContainer extends Component {
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
@ -15,37 +15,30 @@ class AccountContainer extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const {account, error} = this.props;
|
|
||||||
if (error) {
|
|
||||||
return <Error error={error} />;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!account) {
|
|
||||||
return <NoMatch />;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<React.Fragment>
|
<DataWrapper shouldRender={this.props.account !== undefined } {...this.props} render={({account, transactions}) => (
|
||||||
<Account account={account} />
|
<React.Fragment>
|
||||||
<Transactions transactions={account.transactions || []} />
|
<Account account={account} />
|
||||||
</React.Fragment>
|
<Transactions transactions={transactions || []} />
|
||||||
|
</React.Fragment>
|
||||||
|
)} />
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function mapStateToProps(state, props) {
|
function mapStateToProps(state, props) {
|
||||||
if(state.accounts.error) {
|
return {
|
||||||
return {error: state.accounts.error};
|
account: getAccount(state, props.match.params.address),
|
||||||
}
|
transactions: getTransactionsByAccount(state, props.match.params.address),
|
||||||
if(state.accounts.data) {
|
error: state.errorMessage,
|
||||||
return {account: state.accounts.data.find(account => account.address === props.match.params.address)};
|
loading: state.loading
|
||||||
}
|
};
|
||||||
return {};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
AccountContainer.propTypes = {
|
AccountContainer.propTypes = {
|
||||||
match: PropTypes.object,
|
match: PropTypes.object,
|
||||||
account: PropTypes.object,
|
account: PropTypes.object,
|
||||||
|
transactions: PropTypes.arrayOf(PropTypes.object),
|
||||||
fetchAccount: PropTypes.func,
|
fetchAccount: PropTypes.func,
|
||||||
error: PropTypes.string
|
error: PropTypes.string
|
||||||
};
|
};
|
||||||
|
@ -4,8 +4,8 @@ import PropTypes from 'prop-types';
|
|||||||
|
|
||||||
import {accounts as accountsAction} from '../actions';
|
import {accounts as accountsAction} from '../actions';
|
||||||
import Accounts from '../components/Accounts';
|
import Accounts from '../components/Accounts';
|
||||||
import Loading from '../components/Loading';
|
import DataWrapper from "../components/DataWrapper";
|
||||||
import Error from '../components/Error';
|
import {getAccounts} from "../reducers/selectors";
|
||||||
|
|
||||||
class AccountsContainer extends Component {
|
class AccountsContainer extends Component {
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
@ -13,28 +13,23 @@ class AccountsContainer extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const {accounts} = this.props;
|
|
||||||
if (accounts.error) {
|
|
||||||
return <Error error={accounts.error} />;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!accounts.data) {
|
|
||||||
return <Loading />;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Accounts accounts={accounts.data} />
|
<DataWrapper shouldRender={this.props.accounts.length > 0} {...this.props} render={({accounts}) => (
|
||||||
|
<Accounts accounts={accounts} />
|
||||||
|
)} />
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function mapStateToProps(state) {
|
function mapStateToProps(state) {
|
||||||
return {accounts: state.accounts};
|
return {accounts: getAccounts(state), error: state.errorMessage, loading: state.loading};
|
||||||
}
|
}
|
||||||
|
|
||||||
AccountsContainer.propTypes = {
|
AccountsContainer.propTypes = {
|
||||||
accounts: PropTypes.object,
|
accounts: PropTypes.arrayOf(PropTypes.object),
|
||||||
fetchAccounts: PropTypes.func
|
fetchAccounts: PropTypes.func,
|
||||||
|
error: PropTypes.string,
|
||||||
|
loading: PropTypes.bool
|
||||||
};
|
};
|
||||||
|
|
||||||
export default connect(
|
export default connect(
|
||||||
|
@ -5,9 +5,9 @@ import {withRouter} from 'react-router-dom';
|
|||||||
|
|
||||||
import {block as blockAction} from '../actions';
|
import {block as blockAction} from '../actions';
|
||||||
import Block from '../components/Block';
|
import Block from '../components/Block';
|
||||||
import Error from "../components/Error";
|
import DataWrapper from "../components/DataWrapper";
|
||||||
import NoMatch from "../components/NoMatch";
|
|
||||||
import Transactions from '../components/Transactions';
|
import Transactions from '../components/Transactions';
|
||||||
|
import {getBlock, getTransactionsByBlock} from "../reducers/selectors";
|
||||||
|
|
||||||
class BlockContainer extends Component {
|
class BlockContainer extends Component {
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
@ -15,36 +15,30 @@ class BlockContainer extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const {block, error} = this.props;
|
|
||||||
if (error) {
|
|
||||||
return <Error error={error} />;
|
|
||||||
}
|
|
||||||
if (!block) {
|
|
||||||
return <NoMatch />;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<React.Fragment>
|
<DataWrapper shouldRender={this.props.block !== undefined } {...this.props} render={({block, transactions}) => (
|
||||||
<Block block={block} />
|
<React.Fragment>
|
||||||
<Transactions transactions={block.transactions} />
|
<Block block={block} />
|
||||||
</React.Fragment>
|
<Transactions transactions={transactions || []} />
|
||||||
|
</React.Fragment>
|
||||||
|
)} />
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function mapStateToProps(state, props) {
|
function mapStateToProps(state, props) {
|
||||||
if(state.blocks.error) {
|
return {
|
||||||
return {error: state.blocks.error};
|
block: getBlock(state, props.match.params.blockNumber),
|
||||||
}
|
transactions: getTransactionsByBlock(state, props.match.params.blockNumber),
|
||||||
if(state.blocks.data) {
|
error: state.errorMessage,
|
||||||
return {block: state.blocks.data.find(block => block.number.toString() === props.match.params.blockNumber)};
|
loading: state.loading
|
||||||
}
|
};
|
||||||
return {};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BlockContainer.propTypes = {
|
BlockContainer.propTypes = {
|
||||||
match: PropTypes.object,
|
match: PropTypes.object,
|
||||||
block: PropTypes.object,
|
block: PropTypes.object,
|
||||||
|
transactions: PropTypes.arrayOf(PropTypes.object),
|
||||||
fetchBlock: PropTypes.func,
|
fetchBlock: PropTypes.func,
|
||||||
error: PropTypes.string
|
error: PropTypes.string
|
||||||
};
|
};
|
||||||
|
@ -4,9 +4,9 @@ import PropTypes from 'prop-types';
|
|||||||
|
|
||||||
import {blocks as blocksAction} from '../actions';
|
import {blocks as blocksAction} from '../actions';
|
||||||
import Blocks from '../components/Blocks';
|
import Blocks from '../components/Blocks';
|
||||||
import Loading from '../components/Loading';
|
import DataWrapper from "../components/DataWrapper";
|
||||||
import LoadMore from '../components/LoadMore';
|
import LoadMore from "../components/LoadMore";
|
||||||
import Error from '../components/Error';
|
import {getBlocks} from "../reducers/selectors";
|
||||||
|
|
||||||
class BlocksContainer extends Component {
|
class BlocksContainer extends Component {
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
@ -18,23 +18,19 @@ class BlocksContainer extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
loadMoreFrom() {
|
loadMoreFrom() {
|
||||||
let blocks = this.props.blocks.data;
|
let blocks = this.props.blocks;
|
||||||
|
if (blocks.length === 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
return blocks[blocks.length - 1].number - 1;
|
return blocks[blocks.length - 1].number - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const {blocks} = this.props;
|
|
||||||
if (blocks.error) {
|
|
||||||
return <Error error={blocks.error} />;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!blocks.data) {
|
|
||||||
return <Loading />;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<React.Fragment>
|
<React.Fragment>
|
||||||
<Blocks blocks={blocks.data}/>
|
<DataWrapper shouldRender={this.props.blocks.length > 0} {...this.props} render={({blocks}) => (
|
||||||
|
<Blocks blocks={blocks} />
|
||||||
|
)} />
|
||||||
{(this.loadMoreFrom() >= 0) ? <LoadMore loadMore={() => this.loadMore()} /> : <React.Fragment />}
|
{(this.loadMoreFrom() >= 0) ? <LoadMore loadMore={() => this.loadMore()} /> : <React.Fragment />}
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
);
|
);
|
||||||
@ -42,12 +38,14 @@ class BlocksContainer extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function mapStateToProps(state) {
|
function mapStateToProps(state) {
|
||||||
return {blocks: state.blocks};
|
return {blocks: getBlocks(state), error: state.errorMessage, loading: state.loading};
|
||||||
}
|
}
|
||||||
|
|
||||||
BlocksContainer.propTypes = {
|
BlocksContainer.propTypes = {
|
||||||
blocks: PropTypes.object,
|
blocks: PropTypes.arrayOf(PropTypes.object),
|
||||||
fetchBlocks: PropTypes.func
|
fetchBlocks: PropTypes.func,
|
||||||
|
error: PropTypes.string,
|
||||||
|
loading: PropTypes.bool
|
||||||
};
|
};
|
||||||
|
|
||||||
export default connect(
|
export default connect(
|
||||||
|
@ -1,48 +1,45 @@
|
|||||||
import React, { Component } from 'react';
|
import React, {Component} from 'react';
|
||||||
import { connect } from 'react-redux';
|
import {connect} from 'react-redux';
|
||||||
import { compose } from 'redux';
|
import PropTypes from 'prop-types';
|
||||||
import { fetchContract } from '../actions';
|
import {withRouter} from 'react-router-dom';
|
||||||
|
|
||||||
|
import {contract as contractAction} from '../actions';
|
||||||
import Contract from '../components/Contract';
|
import Contract from '../components/Contract';
|
||||||
import { withRouter } from 'react-router'
|
import DataWrapper from "../components/DataWrapper";
|
||||||
|
import {getContract} from "../reducers/selectors";
|
||||||
|
|
||||||
class ContractContainer extends Component {
|
class ContractContainer extends Component {
|
||||||
componentWillMount() {
|
componentDidMount() {
|
||||||
this.props.fetchContract(this.props.match.params.contractName);
|
this.props.fetchContract(this.props.match.params.contractName);
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const {contract} = this.props;
|
|
||||||
if (!contract.data) {
|
|
||||||
return (
|
|
||||||
<h1>
|
|
||||||
<i>Loading contract...</i>
|
|
||||||
</h1>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (contract.error) {
|
|
||||||
return (
|
|
||||||
<h1>
|
|
||||||
<i>Error API...</i>
|
|
||||||
</h1>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Contract contract={contract.data} />
|
<DataWrapper shouldRender={this.props.contract !== undefined } {...this.props} render={({contract}) => (
|
||||||
|
<Contract contract={contract} />
|
||||||
|
)} />
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function mapStateToProps(state, props) {
|
||||||
|
return {
|
||||||
|
contract: getContract(state, props.match.params.contractName),
|
||||||
|
error: state.errorMessage,
|
||||||
|
loading: state.loading
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
ContractContainer.propTypes = {
|
||||||
|
match: PropTypes.object,
|
||||||
|
contract: PropTypes.object,
|
||||||
|
fetchContract: PropTypes.func,
|
||||||
|
error: PropTypes.string
|
||||||
};
|
};
|
||||||
|
|
||||||
function mapStateToProps(state) {
|
export default withRouter(connect(
|
||||||
return { contract: state.contract }
|
mapStateToProps,
|
||||||
};
|
{
|
||||||
|
fetchContract: contractAction.request
|
||||||
export default compose(
|
}
|
||||||
connect(
|
)(ContractContainer));
|
||||||
mapStateToProps,
|
|
||||||
{fetchContract}
|
|
||||||
),
|
|
||||||
withRouter
|
|
||||||
)(ContractContainer);
|
|
||||||
|
|
||||||
|
@ -1,48 +1,45 @@
|
|||||||
import React, { Component } from 'react';
|
import React, {Component} from 'react';
|
||||||
import { connect } from 'react-redux';
|
import {connect} from 'react-redux';
|
||||||
import { compose } from 'redux';
|
import PropTypes from 'prop-types';
|
||||||
import { fetchContractProfile } from '../actions';
|
import {withRouter} from 'react-router-dom';
|
||||||
|
|
||||||
|
import {contractProfile as contractProfileAction} from '../actions';
|
||||||
import ContractProfile from '../components/ContractProfile';
|
import ContractProfile from '../components/ContractProfile';
|
||||||
import { withRouter } from 'react-router';
|
import DataWrapper from "../components/DataWrapper";
|
||||||
|
import {getContractProfile} from "../reducers/selectors";
|
||||||
|
|
||||||
class ContractProfileContainer extends Component {
|
class ContractProfileContainer extends Component {
|
||||||
componentWillMount() {
|
componentDidMount() {
|
||||||
this.props.fetchContractProfile(this.props.match.params.contractName);
|
this.props.fetchContractProfile(this.props.match.params.contractName);
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { contractProfile } = this.props;
|
|
||||||
if (!contractProfile.data) {
|
|
||||||
return (
|
|
||||||
<h1>
|
|
||||||
<i>Loading contract profile...</i>
|
|
||||||
</h1>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (contractProfile.data.error) {
|
|
||||||
return (
|
|
||||||
<h1>
|
|
||||||
<i>Error API...</i>
|
|
||||||
</h1>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ContractProfile contract={contractProfile.data} />
|
<DataWrapper shouldRender={this.props.contractProfile !== undefined } {...this.props} render={({contractProfile}) => (
|
||||||
|
<ContractProfile contractProfile={contractProfile} />
|
||||||
|
)} />
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function mapStateToProps(state) {
|
function mapStateToProps(state, props) {
|
||||||
return { contractProfile: state.contractProfile };
|
return {
|
||||||
|
contractProfile: getContractProfile(state, props.match.params.contractName),
|
||||||
|
error: state.errorMessage,
|
||||||
|
loading: state.loading
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export default compose(
|
ContractProfileContainer.propTypes = {
|
||||||
connect(
|
match: PropTypes.object,
|
||||||
mapStateToProps,
|
contractProfile: PropTypes.object,
|
||||||
{ fetchContractProfile }
|
fetchContractProfile: PropTypes.func,
|
||||||
),
|
error: PropTypes.string
|
||||||
withRouter
|
};
|
||||||
)(ContractProfileContainer);
|
|
||||||
|
|
||||||
|
export default withRouter(connect(
|
||||||
|
mapStateToProps,
|
||||||
|
{
|
||||||
|
fetchContractProfile: contractProfileAction.request
|
||||||
|
}
|
||||||
|
)(ContractProfileContainer));
|
||||||
|
@ -1,45 +1,38 @@
|
|||||||
import React, { Component } from 'react';
|
import React, {Component} from 'react';
|
||||||
import { connect } from 'react-redux';
|
import {connect} from 'react-redux';
|
||||||
import { fetchContracts } from '../actions';
|
import PropTypes from 'prop-types';
|
||||||
|
|
||||||
|
import {contracts as contractsAction} from '../actions';
|
||||||
import Contracts from '../components/Contracts';
|
import Contracts from '../components/Contracts';
|
||||||
|
import DataWrapper from "../components/DataWrapper";
|
||||||
|
import {getContracts} from "../reducers/selectors";
|
||||||
|
|
||||||
class ContractsContainer extends Component {
|
class ContractsContainer extends Component {
|
||||||
componentWillMount() {
|
componentDidMount() {
|
||||||
this.props.fetchContracts();
|
this.props.fetchContracts();
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { contracts } = this.props;
|
|
||||||
if (!contracts.data) {
|
|
||||||
return (
|
|
||||||
<h1>
|
|
||||||
<i>Loading contracts...</i>
|
|
||||||
</h1>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (contracts.error) {
|
|
||||||
return (
|
|
||||||
<h1>
|
|
||||||
<i>Error API...</i>
|
|
||||||
</h1>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Contracts contracts={contracts.data} />
|
<DataWrapper shouldRender={this.props.contracts.length > 0} {...this.props} render={({contracts}) => (
|
||||||
|
<Contracts contracts={contracts} />
|
||||||
|
)} />
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function mapStateToProps(state) {
|
function mapStateToProps(state) {
|
||||||
return { contracts: state.contracts };
|
return {contracts: getContracts(state), error: state.errorMessage, loading: state.loading};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ContractsContainer.propTypes = {
|
||||||
|
contracts: PropTypes.object,
|
||||||
|
fetchContracts: PropTypes.func
|
||||||
|
};
|
||||||
|
|
||||||
export default connect(
|
export default connect(
|
||||||
mapStateToProps,
|
mapStateToProps,
|
||||||
{
|
{
|
||||||
fetchContracts
|
fetchContracts: contractsAction.request
|
||||||
},
|
},
|
||||||
)(ContractsContainer);
|
)(ContractsContainer);
|
||||||
|
|
||||||
|
@ -2,31 +2,40 @@ import PropTypes from "prop-types";
|
|||||||
import React, {Component} from 'react';
|
import React, {Component} from 'react';
|
||||||
import {connect} from 'react-redux';
|
import {connect} from 'react-redux';
|
||||||
import {Page} from "tabler-react";
|
import {Page} from "tabler-react";
|
||||||
import {commands as commandsAction} from "../actions";
|
|
||||||
|
|
||||||
|
import {commands as commandsAction} from "../actions";
|
||||||
|
import DataWrapper from "../components/DataWrapper";
|
||||||
import Processes from '../components/Processes';
|
import Processes from '../components/Processes';
|
||||||
import Console from '../components/Console';
|
import Console from '../components/Console';
|
||||||
|
import {getProcesses, getCommands} from "../reducers/selectors";
|
||||||
|
|
||||||
class HomeContainer extends Component {
|
class HomeContainer extends Component {
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<React.Fragment>
|
<React.Fragment>
|
||||||
<Page.Title className="my-5">Dashboard</Page.Title>
|
<Page.Title className="my-5">Dashboard</Page.Title>
|
||||||
{this.props.processes.data && <Processes processes={this.props.processes.data} />}
|
<DataWrapper shouldRender={this.props.processes.length > 0 } {...this.props} render={({processes}) => (
|
||||||
<Console postCommand={this.props.postCommand} commandResults={this.props.commandResults} />
|
<Processes processes={processes} />
|
||||||
|
)} />
|
||||||
|
<Console postCommand={this.props.postCommand} commands={this.props.commands} />
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
HomeContainer.propTypes = {
|
HomeContainer.propTypes = {
|
||||||
processes: PropTypes.object,
|
processes: PropTypes.arrayOf(PropTypes.object),
|
||||||
postCommand: PropTypes.func,
|
postCommand: PropTypes.func,
|
||||||
commandResults: PropTypes.arrayOf(PropTypes.string)
|
commands: PropTypes.arrayOf(PropTypes.object)
|
||||||
};
|
};
|
||||||
|
|
||||||
function mapStateToProps(state) {
|
function mapStateToProps(state) {
|
||||||
return {processes: state.processes, commandResults: state.commands.results};
|
return {
|
||||||
|
processes: getProcesses(state),
|
||||||
|
commands: getCommands(state),
|
||||||
|
error: state.errorMessage,
|
||||||
|
loading: state.loading
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export default connect(
|
export default connect(
|
||||||
|
55
embark-ui/src/containers/ProcessContainer.js
Normal file
55
embark-ui/src/containers/ProcessContainer.js
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
import React, {Component} from 'react';
|
||||||
|
import {connect} from 'react-redux';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import {withRouter} from "react-router-dom";
|
||||||
|
import {processLogs as processLogsAction, listenToProcessLogs} from '../actions';
|
||||||
|
import DataWrapper from "../components/DataWrapper";
|
||||||
|
import Process from "../components/Process";
|
||||||
|
import {getProcess, getProcessLogsByProcess} from "../reducers/selectors";
|
||||||
|
|
||||||
|
class ProcessContainer extends Component {
|
||||||
|
componentDidMount() {
|
||||||
|
if (this.props.process.state === 'running' && this.props.processLogs.length === 0) {
|
||||||
|
this.props.fetchProcessLogs(this.props.match.params.processName);
|
||||||
|
this.props.listenToProcessLogs(this.props.match.params.processName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<DataWrapper shouldRender={this.props.process !== undefined } {...this.props} render={({process, processLogs}) => (
|
||||||
|
<div className="processes-container">
|
||||||
|
<Process process={process}
|
||||||
|
processLogs={processLogs}/>
|
||||||
|
</div>
|
||||||
|
)} />
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ProcessContainer.propTypes = {
|
||||||
|
fetchProcessLogs: PropTypes.func,
|
||||||
|
listenToProcessLogs: PropTypes.func,
|
||||||
|
process: PropTypes.object,
|
||||||
|
processLogs: PropTypes.arrayOf(PropTypes.object),
|
||||||
|
error: PropTypes.string,
|
||||||
|
loading: PropTypes.bool,
|
||||||
|
match: PropTypes.object
|
||||||
|
};
|
||||||
|
|
||||||
|
function mapStateToProps(state, props) {
|
||||||
|
return {
|
||||||
|
process: getProcess(state, props.match.params.processName),
|
||||||
|
processLogs: getProcessLogsByProcess(state, props.match.params.processName),
|
||||||
|
error: state.errorMessage,
|
||||||
|
loading: state.loading
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export default withRouter(connect(
|
||||||
|
mapStateToProps,
|
||||||
|
{
|
||||||
|
fetchProcessLogs: processLogsAction.request,
|
||||||
|
listenToProcessLogs
|
||||||
|
}
|
||||||
|
)(ProcessContainer));
|
@ -1,58 +0,0 @@
|
|||||||
import React, {Component} from 'react';
|
|
||||||
import {connect} from 'react-redux';
|
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
import {fetchProcessLogs, listenToProcessLogs} from '../actions';
|
|
||||||
|
|
||||||
import Process from "../components/Process";
|
|
||||||
|
|
||||||
class ProcessesContainer extends Component {
|
|
||||||
componentDidMount() {
|
|
||||||
// Get correct process name
|
|
||||||
const pathParts = this.props.match.path.split('/');
|
|
||||||
this.processName = pathParts[pathParts.length - 1];
|
|
||||||
// If we are not in a specific process page (eg: processes/ root), get first process
|
|
||||||
if (Object.keys(this.props.processes.data).indexOf(this.processName) < 0) {
|
|
||||||
this.processName = Object.keys(this.props.processes.data)[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fetch logs for the process
|
|
||||||
this.props.fetchProcessLogs(this.processName);
|
|
||||||
|
|
||||||
// Only start watching if we are not already watching
|
|
||||||
if (!this.props.processes.data[this.processName].isListening) {
|
|
||||||
this.props.listenToProcessLogs(this.processName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
if (!this.processName) {
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
return (
|
|
||||||
<div className="processes-container">
|
|
||||||
<Process processName={this.processName}
|
|
||||||
state={this.props.processes.data[this.processName].state}
|
|
||||||
logs={this.props.processes.data[this.processName].logs}/>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ProcessesContainer.propTypes = {
|
|
||||||
match: PropTypes.object,
|
|
||||||
processes: PropTypes.object,
|
|
||||||
fetchProcessLogs: PropTypes.func,
|
|
||||||
listenToProcessLogs: PropTypes.func
|
|
||||||
};
|
|
||||||
|
|
||||||
function mapStateToProps(state) {
|
|
||||||
return {processes: state.processes};
|
|
||||||
}
|
|
||||||
|
|
||||||
export default connect(
|
|
||||||
mapStateToProps,
|
|
||||||
{
|
|
||||||
fetchProcessLogs,
|
|
||||||
listenToProcessLogs
|
|
||||||
}
|
|
||||||
)(ProcessesContainer);
|
|
@ -4,9 +4,9 @@ import PropTypes from 'prop-types';
|
|||||||
import {withRouter} from 'react-router-dom';
|
import {withRouter} from 'react-router-dom';
|
||||||
|
|
||||||
import {transaction as transactionAction} from '../actions';
|
import {transaction as transactionAction} from '../actions';
|
||||||
import Error from "../components/Error";
|
|
||||||
import NoMatch from "../components/NoMatch";
|
|
||||||
import Transaction from '../components/Transaction';
|
import Transaction from '../components/Transaction';
|
||||||
|
import DataWrapper from "../components/DataWrapper";
|
||||||
|
import {getTransaction} from "../reducers/selectors";
|
||||||
|
|
||||||
class TransactionContainer extends Component {
|
class TransactionContainer extends Component {
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
@ -14,35 +14,26 @@ class TransactionContainer extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const {transaction, error} = this.props;
|
|
||||||
if (error) {
|
|
||||||
return <Error error={error} />;
|
|
||||||
}
|
|
||||||
if (!transaction) {
|
|
||||||
return <NoMatch />;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<React.Fragment>
|
<DataWrapper shouldRender={this.props.transaction !== undefined } {...this.props} render={({transaction}) => (
|
||||||
<Transaction transaction={transaction} />
|
<Transaction transaction={transaction} />
|
||||||
</React.Fragment>
|
)} />
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function mapStateToProps(state, props) {
|
function mapStateToProps(state, props) {
|
||||||
if(state.transactions.error) {
|
return {
|
||||||
return {error: state.transactions.error};
|
transaction: getTransaction(state, props.match.params.hash),
|
||||||
}
|
error: state.errorMessage,
|
||||||
if(state.transactions.data) {
|
loading: state.loading
|
||||||
return {transaction: state.transactions.data.find(transaction => transaction.hash === props.match.params.hash)};
|
};
|
||||||
}
|
|
||||||
return {};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TransactionContainer.propTypes = {
|
TransactionContainer.propTypes = {
|
||||||
match: PropTypes.object,
|
match: PropTypes.object,
|
||||||
transaction: PropTypes.object,
|
transaction: PropTypes.object,
|
||||||
|
transactions: PropTypes.arrayOf(PropTypes.object),
|
||||||
fetchTransaction: PropTypes.func,
|
fetchTransaction: PropTypes.func,
|
||||||
error: PropTypes.string
|
error: PropTypes.string
|
||||||
};
|
};
|
||||||
|
@ -3,10 +3,10 @@ import {connect} from 'react-redux';
|
|||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
|
|
||||||
import {transactions as transactionsAction} from '../actions';
|
import {transactions as transactionsAction} from '../actions';
|
||||||
|
import LoadMore from "../components/LoadMore";
|
||||||
import Transactions from '../components/Transactions';
|
import Transactions from '../components/Transactions';
|
||||||
import Loading from '../components/Loading';
|
import DataWrapper from "../components/DataWrapper";
|
||||||
import LoadMore from '../components/LoadMore';
|
import {getTransactions} from "../reducers/selectors";
|
||||||
import Error from '../components/Error';
|
|
||||||
|
|
||||||
class TransactionsContainer extends Component {
|
class TransactionsContainer extends Component {
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
@ -18,23 +18,19 @@ class TransactionsContainer extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
loadMoreFrom() {
|
loadMoreFrom() {
|
||||||
let transactions = this.props.transactions.data;
|
let transactions = this.props.transactions;
|
||||||
|
if (transactions.length === 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
return transactions[transactions.length - 1].blockNumber - 1;
|
return transactions[transactions.length - 1].blockNumber - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const {transactions} = this.props;
|
|
||||||
if (transactions.error) {
|
|
||||||
return <Error error={transactions.error} />;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!transactions.data) {
|
|
||||||
return <Loading />;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<React.Fragment>
|
<React.Fragment>
|
||||||
<Transactions transactions={transactions.data}/>
|
<DataWrapper shouldRender={this.props.transactions.length > 0} {...this.props} render={({transactions}) => (
|
||||||
|
<Transactions transactions={transactions} />
|
||||||
|
)} />
|
||||||
{(this.loadMoreFrom() > 0) ? <LoadMore loadMore={() => this.loadMore()} /> : <React.Fragment />}
|
{(this.loadMoreFrom() > 0) ? <LoadMore loadMore={() => this.loadMore()} /> : <React.Fragment />}
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
);
|
);
|
||||||
@ -42,12 +38,14 @@ class TransactionsContainer extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function mapStateToProps(state) {
|
function mapStateToProps(state) {
|
||||||
return {transactions: state.transactions};
|
return {transactions: getTransactions(state), error: state.errorMessage, loading: state.loading};
|
||||||
}
|
}
|
||||||
|
|
||||||
TransactionsContainer.propTypes = {
|
TransactionsContainer.propTypes = {
|
||||||
transactions: PropTypes.object,
|
transactions: PropTypes.object,
|
||||||
fetchTransactions: PropTypes.func
|
fetchTransactions: PropTypes.func,
|
||||||
|
error: PropTypes.string,
|
||||||
|
loading: PropTypes.bool
|
||||||
};
|
};
|
||||||
|
|
||||||
export default connect(
|
export default connect(
|
||||||
|
@ -1,26 +0,0 @@
|
|||||||
import * as actions from "../actions";
|
|
||||||
|
|
||||||
function filterAccount(account, index, self) {
|
|
||||||
return index === self.findIndex((a) => a.address === account.address);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default function accounts(state = {}, action) {
|
|
||||||
switch (action.type) {
|
|
||||||
case actions.ACCOUNTS[actions.SUCCESS]:
|
|
||||||
return {
|
|
||||||
...state, error: null, data: [...action.accounts.data, ...state.data || []]
|
|
||||||
.filter(filterAccount)
|
|
||||||
};
|
|
||||||
case actions.ACCOUNTS[actions.FAILURE]:
|
|
||||||
return Object.assign({}, state, {error: action.error});
|
|
||||||
case actions.ACCOUNT[actions.SUCCESS]:
|
|
||||||
return {
|
|
||||||
...state, error: null, data: [action.account.data, ...state.data || []]
|
|
||||||
.filter(filterAccount)
|
|
||||||
};
|
|
||||||
case actions.ACCOUNT[actions.FAILURE]:
|
|
||||||
return Object.assign({}, state, {error: action.error});
|
|
||||||
default:
|
|
||||||
return state;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,32 +0,0 @@
|
|||||||
import * as actions from "../actions";
|
|
||||||
|
|
||||||
function sortBlock(a, b) {
|
|
||||||
return b.number - a.number;
|
|
||||||
}
|
|
||||||
|
|
||||||
function filterBlock(block, index, self) {
|
|
||||||
return index === self.findIndex((t) => t.number === block.number);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default function blocks(state = {}, action) {
|
|
||||||
switch (action.type) {
|
|
||||||
case actions.BLOCKS[actions.SUCCESS]:
|
|
||||||
return {
|
|
||||||
...state, error: null, data: [...action.blocks.data, ...state.data || []]
|
|
||||||
.filter(filterBlock)
|
|
||||||
.sort(sortBlock)
|
|
||||||
};
|
|
||||||
case actions.BLOCKS[actions.FAILURE]:
|
|
||||||
return Object.assign({}, state, {error: action.error});
|
|
||||||
case actions.BLOCK[actions.SUCCESS]:
|
|
||||||
return {
|
|
||||||
...state, error: null, data: [action.block.data, ...state.data || []]
|
|
||||||
.filter(filterBlock)
|
|
||||||
.sort(sortBlock)
|
|
||||||
};
|
|
||||||
case actions.BLOCK[actions.FAILURE]:
|
|
||||||
return Object.assign({}, state, {error: action.error});
|
|
||||||
default:
|
|
||||||
return state;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,14 +0,0 @@
|
|||||||
import * as actions from "../actions";
|
|
||||||
|
|
||||||
export default function commands(state = {}, action) {
|
|
||||||
switch (action.type) {
|
|
||||||
case actions.COMMANDS[actions.SUCCESS]:
|
|
||||||
return {
|
|
||||||
...state, error: null, results: [...state.results || [], action.result.data.result]
|
|
||||||
};
|
|
||||||
case actions.COMMANDS[actions.FAILURE]:
|
|
||||||
return Object.assign({}, state, {error: action.error});
|
|
||||||
default:
|
|
||||||
return state;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,12 +0,0 @@
|
|||||||
import {RECEIVE_CONTRACT_PROFILE, RECEIVE_CONTRACT_PROFILE_ERROR} from "../actions";
|
|
||||||
|
|
||||||
export default function contractProfile(state = {}, action) {
|
|
||||||
switch (action.type) {
|
|
||||||
case RECEIVE_CONTRACT_PROFILE:
|
|
||||||
return Object.assign({}, state, {data: action.contractProfile.data});
|
|
||||||
case RECEIVE_CONTRACT_PROFILE_ERROR:
|
|
||||||
return Object.assign({}, state, {error: true});
|
|
||||||
default:
|
|
||||||
return state;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,12 +0,0 @@
|
|||||||
import {RECEIVE_CONTRACT, RECEIVE_CONTRACT_ERROR} from "../actions";
|
|
||||||
|
|
||||||
export default function contract(state = {}, action) {
|
|
||||||
switch (action.type) {
|
|
||||||
case RECEIVE_CONTRACT:
|
|
||||||
return Object.assign({}, state, {data: action.contract.data});
|
|
||||||
case RECEIVE_CONTRACT_ERROR:
|
|
||||||
return Object.assign({}, state, {error: true});
|
|
||||||
default:
|
|
||||||
return state;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,12 +0,0 @@
|
|||||||
import {RECEIVE_CONTRACTS, RECEIVE_CONTRACTS_ERROR} from "../actions";
|
|
||||||
|
|
||||||
export default function contracts(state = {}, action) {
|
|
||||||
switch (action.type) {
|
|
||||||
case RECEIVE_CONTRACTS:
|
|
||||||
return Object.assign({}, state, {data: action.contracts.data});
|
|
||||||
case RECEIVE_CONTRACTS_ERROR:
|
|
||||||
return Object.assign({}, state, {error: true});
|
|
||||||
default:
|
|
||||||
return state;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,22 +1,89 @@
|
|||||||
import {combineReducers} from 'redux';
|
import {combineReducers} from 'redux';
|
||||||
import processesReducer from './processesReducer';
|
import {REQUEST} from "../actions";
|
||||||
import accountsReducer from './accountsReducer';
|
|
||||||
import blocksReducer from './blocksReducer';
|
const BN_FACTOR = 10000;
|
||||||
import transactionsReducer from './transactionsReducer';
|
|
||||||
import commandsReducer from './commandsReducer';
|
const entitiesDefaultState = {
|
||||||
import contractsReducer from './contractsReducer';
|
accounts: [],
|
||||||
import contractReducer from './contractReducer';
|
blocks: [],
|
||||||
import contractProfileReducer from './contractProfileReducer';
|
transactions: [],
|
||||||
|
processes: [],
|
||||||
|
processLogs: [],
|
||||||
|
contracts: [],
|
||||||
|
contractProfiles: [],
|
||||||
|
commands: []
|
||||||
|
};
|
||||||
|
|
||||||
|
const sorter = {
|
||||||
|
blocks: function(a, b) {
|
||||||
|
return b.number - a.number;
|
||||||
|
},
|
||||||
|
transactions: function(a, b) {
|
||||||
|
return ((BN_FACTOR * b.blockNumber) + b.transactionIndex) - ((BN_FACTOR * a.blockNumber) + a.transactionIndex);
|
||||||
|
},
|
||||||
|
processLogs: function(a, b) {
|
||||||
|
return a.timestamp - b.timestamp;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const filtrer = {
|
||||||
|
processes: function(process, index, self) {
|
||||||
|
return index === self.findIndex((t) => t.name === process.name);
|
||||||
|
},
|
||||||
|
contracts: function(contract, index, self) {
|
||||||
|
return index === self.findIndex((t) => t.name === contract.name);
|
||||||
|
},
|
||||||
|
accounts: function(account, index, self) {
|
||||||
|
return index === self.findIndex((t) => t.address === account.address);
|
||||||
|
},
|
||||||
|
blocks: function(block, index, self) {
|
||||||
|
return index === self.findIndex((t) => t.number === block.number);
|
||||||
|
},
|
||||||
|
transactions: function(tx, index, self) {
|
||||||
|
return index === self.findIndex((t) => (
|
||||||
|
t.blockNumber === tx.blockNumber && t.transactionIndex === tx.transactionIndex
|
||||||
|
));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function entities(state = entitiesDefaultState, action) {
|
||||||
|
for (let name of Object.keys(state)) {
|
||||||
|
let filter = filtrer[name] || (() => true);
|
||||||
|
let sort = sorter[name] || (() => true);
|
||||||
|
if (action[name] && action[name].length > 1) {
|
||||||
|
return {...state, [name]: [...action[name], ...state[name]].filter(filter).sort(sort)};
|
||||||
|
}
|
||||||
|
if (action[name] && action[name].length === 1) {
|
||||||
|
let entity = action[name][0];
|
||||||
|
let nested = Object.keys(state).reduce((acc, entityName) => {
|
||||||
|
if (entity[entityName] && entity[entityName].length > 0) {
|
||||||
|
let entityFilter = filtrer[entityName] || (() => true);
|
||||||
|
let entitySort = sorter[entityName] || (() => true);
|
||||||
|
acc[entityName] = [...entity[entityName], ...state[entityName]].filter(entityFilter).sort(entitySort);
|
||||||
|
}
|
||||||
|
return acc;
|
||||||
|
}, {});
|
||||||
|
return {
|
||||||
|
...state, ...nested, [name]: [...action[name], ...state[name]].filter(filter).sort(sort)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
|
function errorMessage(state = null, action) {
|
||||||
|
return action.error || state;
|
||||||
|
}
|
||||||
|
|
||||||
|
function loading(_state = false, action) {
|
||||||
|
return action.type.endsWith(REQUEST);
|
||||||
|
}
|
||||||
|
|
||||||
const rootReducer = combineReducers({
|
const rootReducer = combineReducers({
|
||||||
accounts: accountsReducer,
|
entities,
|
||||||
processes: processesReducer,
|
loading,
|
||||||
contracts: contractsReducer,
|
errorMessage
|
||||||
contract: contractReducer,
|
|
||||||
contractProfile: contractProfileReducer,
|
|
||||||
blocks: blocksReducer,
|
|
||||||
transactions: transactionsReducer,
|
|
||||||
commands: commandsReducer
|
|
||||||
});
|
});
|
||||||
|
|
||||||
export default rootReducer;
|
export default rootReducer;
|
||||||
|
@ -1,51 +0,0 @@
|
|||||||
import * as actions from "../actions";
|
|
||||||
|
|
||||||
export default function processes(state = {}, action) {
|
|
||||||
switch (action.type) {
|
|
||||||
case actions.PROCESSES[actions.SUCCESS]:
|
|
||||||
return Object.assign({}, state, {data: action.processes.data});
|
|
||||||
case actions.PROCESSES[actions.FAILURE]:
|
|
||||||
return Object.assign({}, state, {error: action.error});
|
|
||||||
case actions.RECEIVE_PROCESS_LOGS:
|
|
||||||
return {
|
|
||||||
...state,
|
|
||||||
data: {
|
|
||||||
...state.data,
|
|
||||||
[action.processName]: {
|
|
||||||
...state.data[action.processName],
|
|
||||||
logs: action.logs.data
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
case actions.RECEIVE_NEW_PROCESS_LOG: {
|
|
||||||
const logs = state.data[action.processName].logs || [];
|
|
||||||
logs.push(action.log);
|
|
||||||
return {
|
|
||||||
...state,
|
|
||||||
data: {
|
|
||||||
...state.data,
|
|
||||||
[action.processName]: {
|
|
||||||
...state.data[action.processName],
|
|
||||||
logs: logs
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
case actions.WATCH_NEW_PROCESS_LOGS: {
|
|
||||||
return {
|
|
||||||
...state,
|
|
||||||
data: {
|
|
||||||
...state.data,
|
|
||||||
[action.processName]: {
|
|
||||||
...state.data[action.processName],
|
|
||||||
isListening: true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
case actions.RECEIVE_PROCESS_LOGS_ERROR:
|
|
||||||
return Object.assign({}, state, {error: action.error});
|
|
||||||
default:
|
|
||||||
return state;
|
|
||||||
}
|
|
||||||
}
|
|
59
embark-ui/src/reducers/selectors.js
Normal file
59
embark-ui/src/reducers/selectors.js
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
export function getAccounts(state) {
|
||||||
|
return state.entities.accounts;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getAccount(state, address) {
|
||||||
|
return state.entities.accounts.find((account) => account.address === address);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getTransactions(state) {
|
||||||
|
return state.entities.transactions;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getTransaction(state, hash) {
|
||||||
|
return state.entities.transactions.find((transaction) => transaction.hash === hash);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getTransactionsByAccount(state, address) {
|
||||||
|
return state.entities.transactions.filter((transaction) => transaction.from === address);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getTransactionsByBlock(state, blockNumber) {
|
||||||
|
return state.entities.transactions.filter((transaction) => transaction.blockNumber.toString() === blockNumber);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getBlocks(state) {
|
||||||
|
return state.entities.blocks;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getBlock(state, number) {
|
||||||
|
return state.entities.blocks.find((block) => block.number.toString() === number);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getCommands(state) {
|
||||||
|
return state.entities.commands;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getProcesses(state) {
|
||||||
|
return state.entities.processes;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getProcess(state, name) {
|
||||||
|
return state.entities.processes.find((process) => process.name === name);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getProcessLogsByProcess(state, processName) {
|
||||||
|
return state.entities.processLogs.filter((processLog => processLog.name === processName));
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getContracts(state) {
|
||||||
|
return state.entities.contracts;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getContract(state, contractName) {
|
||||||
|
return state.entities.contracts.find((contract => contract.name === contractName));
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getContractProfile(state, contractName) {
|
||||||
|
return state.entities.contractProfiles.find((contractProfile => contractProfile.name === contractName));
|
||||||
|
}
|
@ -1,36 +0,0 @@
|
|||||||
import * as actions from "../actions";
|
|
||||||
|
|
||||||
const BN_FACTOR = 10000;
|
|
||||||
|
|
||||||
function sortTransaction(a, b) {
|
|
||||||
return ((BN_FACTOR * b.blockNumber) + b.transactionIndex) - ((BN_FACTOR * a.blockNumber) + a.transactionIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
function filterTransaction(tx, index, self) {
|
|
||||||
return index === self.findIndex((t) => (
|
|
||||||
t.blockNumber === tx.blockNumber && t.transactionIndex === tx.transactionIndex
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
export default function transactions(state = {}, action) {
|
|
||||||
switch (action.type) {
|
|
||||||
case actions.TRANSACTIONS[actions.SUCCESS]:
|
|
||||||
return {
|
|
||||||
...state, error: null, data: [...action.transactions.data, ...state.data || []]
|
|
||||||
.filter(filterTransaction)
|
|
||||||
.sort(sortTransaction)
|
|
||||||
};
|
|
||||||
case actions.TRANSACTIONS[actions.FAILURE]:
|
|
||||||
return Object.assign({}, state, {error: action.error});
|
|
||||||
case actions.TRANSACTION[actions.SUCCESS]:
|
|
||||||
return {
|
|
||||||
...state, error: null, data: [action.transaction.data, ...state.data || []]
|
|
||||||
.filter(filterTransaction)
|
|
||||||
.sort(sortTransaction)
|
|
||||||
};
|
|
||||||
case actions.TRANSACTION[actions.FAILURE]:
|
|
||||||
return Object.assign({}, state, {error: action.error});
|
|
||||||
default:
|
|
||||||
return state;
|
|
||||||
}
|
|
||||||
}
|
|
@ -3,12 +3,13 @@ import * as api from '../api';
|
|||||||
import {eventChannel} from 'redux-saga';
|
import {eventChannel} from 'redux-saga';
|
||||||
import {all, call, fork, put, takeEvery, take} from 'redux-saga/effects';
|
import {all, call, fork, put, takeEvery, take} from 'redux-saga/effects';
|
||||||
|
|
||||||
const {account, accounts, block, blocks, transaction, transactions, processes, commands} = actions;
|
const {account, accounts, block, blocks, transaction, transactions, processes, commands, processLogs,
|
||||||
|
contracts, contract, contractProfile} = actions;
|
||||||
|
|
||||||
function *doRequest(entity, apiFn, payload) {
|
function *doRequest(entity, apiFn, payload) {
|
||||||
const {response, error} = yield call(apiFn, payload);
|
const {response, error} = yield call(apiFn, payload);
|
||||||
if(response) {
|
if(response) {
|
||||||
yield put(entity.success(response));
|
yield put(entity.success(response.data, payload));
|
||||||
} else if (error) {
|
} else if (error) {
|
||||||
yield put(entity.failure(error));
|
yield put(entity.failure(error));
|
||||||
}
|
}
|
||||||
@ -22,6 +23,10 @@ export const fetchBlocks = doRequest.bind(null, blocks, api.fetchBlocks);
|
|||||||
export const fetchTransactions = doRequest.bind(null, transactions, api.fetchTransactions);
|
export const fetchTransactions = doRequest.bind(null, transactions, api.fetchTransactions);
|
||||||
export const fetchProcesses = doRequest.bind(null, processes, api.fetchProcesses);
|
export const fetchProcesses = doRequest.bind(null, processes, api.fetchProcesses);
|
||||||
export const postCommand = doRequest.bind(null, commands, api.postCommand);
|
export const postCommand = doRequest.bind(null, commands, api.postCommand);
|
||||||
|
export const fetchProcessLogs = doRequest.bind(null, processLogs, api.fetchProcessLogs);
|
||||||
|
export const fetchContracts = doRequest.bind(null, contracts, api.fetchContracts);
|
||||||
|
export const fetchContract = doRequest.bind(null, contract, api.fetchContract);
|
||||||
|
export const fetchContractProfile = doRequest.bind(null, contractProfile, api.fetchContractProfile);
|
||||||
|
|
||||||
export function *watchFetchTransaction() {
|
export function *watchFetchTransaction() {
|
||||||
yield takeEvery(actions.TRANSACTION[actions.REQUEST], fetchTransaction);
|
yield takeEvery(actions.TRANSACTION[actions.REQUEST], fetchTransaction);
|
||||||
@ -55,17 +60,20 @@ export function *watchPostCommand() {
|
|||||||
yield takeEvery(actions.COMMANDS[actions.REQUEST], postCommand);
|
yield takeEvery(actions.COMMANDS[actions.REQUEST], postCommand);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function *fetchProcessLogs(action) {
|
export function *watchFetchProcessLogs() {
|
||||||
try {
|
yield takeEvery(actions.PROCESS_LOGS[actions.REQUEST], fetchProcessLogs);
|
||||||
const logs = yield call(api.fetchProcessLogs, action.processName);
|
|
||||||
yield put(actions.receiveProcessLogs(action.processName, logs));
|
|
||||||
} catch (e) {
|
|
||||||
yield put(actions.receiveProcessLogsError(e));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function *watchFetchProcessLogs() {
|
export function *watchFetchContract() {
|
||||||
yield takeEvery(actions.FETCH_PROCESS_LOGS, fetchProcessLogs);
|
yield takeEvery(actions.CONTRACT[actions.REQUEST], fetchContract);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function *watchFetchContracts() {
|
||||||
|
yield takeEvery(actions.CONTRACTS[actions.REQUEST], fetchContracts);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function *watchFetchContractProfile() {
|
||||||
|
yield takeEvery(actions.CONTRACT_PROFILE[actions.REQUEST], fetchContractProfile);
|
||||||
}
|
}
|
||||||
|
|
||||||
function createChannel(socket) {
|
function createChannel(socket) {
|
||||||
@ -97,8 +105,8 @@ export function *listenToProcessLogs(action) {
|
|||||||
const socket = api.webSocketProcess(action.processName);
|
const socket = api.webSocketProcess(action.processName);
|
||||||
const channel = yield call(createChannel, socket);
|
const channel = yield call(createChannel, socket);
|
||||||
while (true) {
|
while (true) {
|
||||||
const log = yield take(channel);
|
const processLog = yield take(channel);
|
||||||
yield put({type: actions.RECEIVE_NEW_PROCESS_LOG, processName: action.processName, log});
|
yield put(processLogs.success([processLog]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -106,45 +114,6 @@ export function *watchListenToProcessLogs() {
|
|||||||
yield takeEvery(actions.WATCH_NEW_PROCESS_LOGS, listenToProcessLogs);
|
yield takeEvery(actions.WATCH_NEW_PROCESS_LOGS, listenToProcessLogs);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function *fetchContract(action) {
|
|
||||||
try {
|
|
||||||
const contract = yield call(api.fetchContract, action.contractName);
|
|
||||||
yield put(actions.receiveContract(contract));
|
|
||||||
} catch (e) {
|
|
||||||
yield put(actions.receiveContractError());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function *watchFetchContract() {
|
|
||||||
yield takeEvery(actions.FETCH_CONTRACT, fetchContract);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function *fetchContracts() {
|
|
||||||
try {
|
|
||||||
const contracts = yield call(api.fetchContracts);
|
|
||||||
yield put(actions.receiveContracts(contracts));
|
|
||||||
} catch (e) {
|
|
||||||
yield put(actions.receiveContractsError());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function *watchFetchContracts() {
|
|
||||||
yield takeEvery(actions.FETCH_CONTRACTS, fetchContracts);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function *fetchContractProfile(action) {
|
|
||||||
try {
|
|
||||||
const profile = yield call(api.fetchContractProfile, action.contractName);
|
|
||||||
yield put(actions.receiveContractProfile(profile));
|
|
||||||
} catch (e) {
|
|
||||||
yield put(actions.receiveContractError());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function *watchFetchContractProfile() {
|
|
||||||
yield takeEvery(actions.FETCH_CONTRACT_PROFILE, fetchContractProfile);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default function *root() {
|
export default function *root() {
|
||||||
yield all([
|
yield all([
|
||||||
fork(watchInitBlockHeader),
|
fork(watchInitBlockHeader),
|
||||||
|
@ -73,8 +73,8 @@ class ProcessLauncher {
|
|||||||
'ws',
|
'ws',
|
||||||
apiRoute,
|
apiRoute,
|
||||||
(ws, _req) => {
|
(ws, _req) => {
|
||||||
self.events.on('process-log-' + self.name, function(logLevel, msg) {
|
self.events.on('process-log-' + self.name, function(logLevel, msg, name, timestamp) {
|
||||||
ws.send(JSON.stringify({msg, msg_clear: msg.stripColors, logLevel}), () => {});
|
ws.send(JSON.stringify({msg, msg_clear: msg.stripColors, logLevel, name, timestamp}), () => {});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@ -89,8 +89,9 @@ class ProcessLauncher {
|
|||||||
|
|
||||||
// Translates logs from the child process to the logger
|
// Translates logs from the child process to the logger
|
||||||
_handleLog(msg) {
|
_handleLog(msg) {
|
||||||
this.events.emit('process-log-' + this.name, msg.type, msg.message);
|
const timestamp = new Date().getTime();
|
||||||
this.logs.push({msg: msg.message, msg_clear: msg.message.stripColors, logLevel: msg.logLevel});
|
this.events.emit('process-log-' + this.name, msg.type, msg.message, this.name, timestamp);
|
||||||
|
this.logs.push({msg: msg.message, msg_clear: msg.message.stripColors, logLevel: msg.logLevel, name: this.name, timestamp});
|
||||||
if (this.silent && msg.type !== 'error') {
|
if (this.silent && msg.type !== 'error') {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -17,13 +17,11 @@ class ProcessManager {
|
|||||||
'get',
|
'get',
|
||||||
'/embark-api/processes',
|
'/embark-api/processes',
|
||||||
(req, res) => {
|
(req, res) => {
|
||||||
let parsedProcesses = {};
|
const formatter = (acc, processName) => {
|
||||||
Object.keys(self.processes).forEach(processName => {
|
acc.push({state: self.processes[processName].state, name: processName});
|
||||||
parsedProcesses[processName] = {
|
return acc;
|
||||||
state: self.processes[processName].state
|
};
|
||||||
};
|
res.send(Object.keys(self.processes).reduce(formatter, []));
|
||||||
});
|
|
||||||
res.send(parsedProcesses);
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user