Adding tab to contract view
This commit is contained in:
parent
df3bce145d
commit
4b2715421d
|
@ -1,94 +1,75 @@
|
||||||
import PropTypes from "prop-types";
|
import PropTypes from "prop-types";
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import {NavLink, Route, Switch, withRouter} from 'react-router-dom';
|
import { TabContent, TabPane, Nav, NavItem, NavLink, Card, Button, CardTitle, CardText, Row, Col } from 'reactstrap';
|
||||||
import {
|
import classnames from 'classnames';
|
||||||
Page,
|
|
||||||
Grid,
|
|
||||||
List
|
|
||||||
} from "tabler-react";
|
|
||||||
|
|
||||||
import ContractContainer from '../containers/ContractContainer';
|
import ContractOverview from '../components/ContractOverview';
|
||||||
import ContractLoggerContainer from '../containers/ContractLoggerContainer';
|
import ContractLoggerContainer from '../containers/ContractLoggerContainer';
|
||||||
import ContractFunctionsContainer from '../containers/ContractFunctionsContainer';
|
import ContractFunctionsContainer from '../containers/ContractFunctionsContainer';
|
||||||
import ContractDeploymentContainer from '../containers/ContractDeploymentContainer';
|
|
||||||
import ContractProfileContainer from '../containers/ContractProfileContainer';
|
|
||||||
import ContractSourceContainer from '../containers/ContractSourceContainer';
|
|
||||||
|
|
||||||
const ContractLayout = ({match, contractIsFiddle = false}) => (
|
class ContractLayout extends React.Component {
|
||||||
<Grid.Row>
|
constructor(props) {
|
||||||
<Grid.Col md={3}>
|
super(props);
|
||||||
<Page.Title className="my-5"> </Page.Title>
|
|
||||||
<div>
|
this.state = {
|
||||||
<List.Group transparent={true}>
|
activeTab: '1'
|
||||||
<List.GroupItem
|
};
|
||||||
className="d-flex align-items-center"
|
}
|
||||||
to={`/embark/contracts/${match.params.contractName}/overview`}
|
|
||||||
icon="corner-left-up"
|
toggle(tab) {
|
||||||
RootComponent={NavLink}
|
if (this.state.activeTab !== tab) {
|
||||||
>
|
this.setState({
|
||||||
Overview
|
activeTab: tab
|
||||||
</List.GroupItem>
|
});
|
||||||
{!contractIsFiddle &&
|
}
|
||||||
<List.GroupItem
|
}
|
||||||
className="d-flex align-items-center"
|
render() {
|
||||||
to={`/embark/contracts/${match.params.contractName}/deployment`}
|
return (
|
||||||
icon="users"
|
<React.Fragment>
|
||||||
RootComponent={NavLink}
|
<Nav tabs>
|
||||||
|
<NavItem>
|
||||||
|
<NavLink
|
||||||
|
className={classnames({ active: this.state.activeTab === '1' })}
|
||||||
|
onClick={() => { this.toggle('1'); }}
|
||||||
>
|
>
|
||||||
Deployment / Utils
|
Overview
|
||||||
</List.GroupItem>
|
</NavLink>
|
||||||
}
|
</NavItem>
|
||||||
<List.GroupItem
|
<NavItem>
|
||||||
className="d-flex align-items-center"
|
<NavLink
|
||||||
to={`/embark/contracts/${match.params.contractName}/functions`}
|
className={classnames({ active: this.state.activeTab === '2' })}
|
||||||
icon="book-open"
|
onClick={() => { this.toggle('2'); }}
|
||||||
RootComponent={NavLink}
|
>
|
||||||
>
|
Functions
|
||||||
Functions
|
</NavLink>
|
||||||
</List.GroupItem>
|
</NavItem>
|
||||||
<List.GroupItem
|
<NavItem>
|
||||||
className="d-flex align-items-center"
|
<NavLink
|
||||||
to={`/embark/contracts/${match.params.contractName}/source`}
|
className={classnames({ active: this.state.activeTab === '3' })}
|
||||||
icon="activity"
|
onClick={() => { this.toggle('3'); }}
|
||||||
RootComponent={NavLink}
|
>
|
||||||
>
|
Logger
|
||||||
Source Code
|
</NavLink>
|
||||||
</List.GroupItem>
|
</NavItem>
|
||||||
<List.GroupItem
|
</Nav>
|
||||||
className="d-flex align-items-center"
|
<TabContent activeTab={this.state.activeTab}>
|
||||||
to={`/embark/contracts/${match.params.contractName}/profiler`}
|
<TabPane tabId="1">
|
||||||
icon="server"
|
<ContractOverview contract={this.props.contract} />
|
||||||
RootComponent={NavLink}
|
</TabPane>
|
||||||
>
|
<TabPane tabId="2">
|
||||||
Profile
|
<ContractFunctionsContainer contract={this.props.contract} />
|
||||||
</List.GroupItem>
|
</TabPane>
|
||||||
<List.GroupItem
|
<TabPane tabId="3">
|
||||||
className="d-flex align-items-center"
|
<ContractLoggerContainer contract={this.props.contract} />
|
||||||
to={`/embark/contracts/${match.params.contractName}/logger`}
|
</TabPane>
|
||||||
icon="chevrons-right"
|
</TabContent>
|
||||||
RootComponent={NavLink}
|
</React.Fragment>
|
||||||
>
|
)
|
||||||
Logger
|
}
|
||||||
</List.GroupItem>
|
}
|
||||||
</List.Group>
|
|
||||||
</div>
|
|
||||||
</Grid.Col>
|
|
||||||
<Grid.Col md={9}>
|
|
||||||
<Switch>
|
|
||||||
<Route exact path="/embark/contracts/:contractName/overview" component={ContractContainer} />
|
|
||||||
<Route exact path="/embark/contracts/:contractName/deployment" component={ContractDeploymentContainer} />
|
|
||||||
<Route exact path="/embark/contracts/:contractName/functions" component={ContractFunctionsContainer} />
|
|
||||||
<Route exact path="/embark/contracts/:contractName/source" component={ContractSourceContainer} />
|
|
||||||
<Route exact path="/embark/contracts/:contractName/profiler" component={ContractProfileContainer} />
|
|
||||||
<Route exact path="/embark/contracts/:contractName/logger" component={ContractLoggerContainer} />
|
|
||||||
</Switch>
|
|
||||||
</Grid.Col>
|
|
||||||
</Grid.Row>
|
|
||||||
);
|
|
||||||
|
|
||||||
ContractLayout.propTypes = {
|
ContractLayout.propTypes = {
|
||||||
match: PropTypes.object,
|
contract: PropTypes.object
|
||||||
contractIsFiddle: PropTypes.bool
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export default withRouter(ContractLayout);
|
export default ContractLayout;
|
||||||
|
|
|
@ -8,12 +8,11 @@ import {
|
||||||
} from "tabler-react";
|
} from "tabler-react";
|
||||||
import JSONTree from 'react-json-tree';
|
import JSONTree from 'react-json-tree';
|
||||||
import {formatContractForDisplay} from '../utils/presentation';
|
import {formatContractForDisplay} from '../utils/presentation';
|
||||||
import {withRouter} from 'react-router-dom';
|
|
||||||
|
|
||||||
const Contract = ({contract, match}) => {
|
const Contract = ({contract, match}) => {
|
||||||
const contractDisplay = formatContractForDisplay(contract);
|
const contractDisplay = formatContractForDisplay(contract);
|
||||||
return (
|
return (
|
||||||
<Page.Content title={match.params.contractName + " Overview"}>
|
<Page.Content title={contract.className + " Overview"}>
|
||||||
<Grid.Row>
|
<Grid.Row>
|
||||||
<Grid.Col>
|
<Grid.Col>
|
||||||
<Card>
|
<Card>
|
||||||
|
@ -30,7 +29,7 @@ const Contract = ({contract, match}) => {
|
||||||
</Table.Header>
|
</Table.Header>
|
||||||
<Table.Body>
|
<Table.Body>
|
||||||
<Table.Row className={contractDisplay.stateColor}>
|
<Table.Row className={contractDisplay.stateColor}>
|
||||||
<Table.Col>{(contract.name || contract.className)}</Table.Col>
|
<Table.Col>{contract.className}</Table.Col>
|
||||||
<Table.Col>{contractDisplay.address}</Table.Col>
|
<Table.Col>{contractDisplay.address}</Table.Col>
|
||||||
<Table.Col>{contractDisplay.state}</Table.Col>
|
<Table.Col>{contractDisplay.state}</Table.Col>
|
||||||
</Table.Row>
|
</Table.Row>
|
||||||
|
@ -61,8 +60,7 @@ const Contract = ({contract, match}) => {
|
||||||
|
|
||||||
Contract.propTypes = {
|
Contract.propTypes = {
|
||||||
contract: PropTypes.object,
|
contract: PropTypes.object,
|
||||||
match: PropTypes.object
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export default withRouter(Contract);
|
export default Contract;
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
import React, {Component} from 'react';
|
import React, {Component} from 'react';
|
||||||
import {connect} from 'react-redux';
|
import {connect} from 'react-redux';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import {withRouter} from 'react-router-dom';
|
|
||||||
|
|
||||||
import {contractProfile as contractProfileAction, contractFunction as contractFunctionAction} from '../actions';
|
import {contractProfile as contractProfileAction, contractFunction as contractFunctionAction} from '../actions';
|
||||||
import ContractFunctions from '../components/ContractFunctions';
|
import ContractFunctions from '../components/ContractFunctions';
|
||||||
|
@ -11,7 +10,7 @@ import {getContractProfile, getContractFunctions} from "../reducers/selectors";
|
||||||
|
|
||||||
class ContractFunctionsContainer extends Component {
|
class ContractFunctionsContainer extends Component {
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
this.props.fetchContractProfile(this.props.match.params.contractName);
|
this.props.fetchContractProfile(this.props.contract.className);
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
@ -33,15 +32,15 @@ class ContractFunctionsContainer extends Component {
|
||||||
|
|
||||||
function mapStateToProps(state, props) {
|
function mapStateToProps(state, props) {
|
||||||
return {
|
return {
|
||||||
contractProfile: getContractProfile(state, props.match.params.contractName),
|
contractProfile: getContractProfile(state, props.contract.className),
|
||||||
contractFunctions: getContractFunctions(state, props.match.params.contractName),
|
contractFunctions: getContractFunctions(state, props.contract.className),
|
||||||
error: state.errorMessage,
|
error: state.errorMessage,
|
||||||
loading: state.loading
|
loading: state.loading
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
ContractFunctionsContainer.propTypes = {
|
ContractFunctionsContainer.propTypes = {
|
||||||
match: PropTypes.object,
|
contract: PropTypes.object,
|
||||||
contractProfile: PropTypes.object,
|
contractProfile: PropTypes.object,
|
||||||
contractFunctions: PropTypes.arrayOf(PropTypes.object),
|
contractFunctions: PropTypes.arrayOf(PropTypes.object),
|
||||||
postContractFunction: PropTypes.func,
|
postContractFunction: PropTypes.func,
|
||||||
|
@ -49,10 +48,10 @@ ContractFunctionsContainer.propTypes = {
|
||||||
error: PropTypes.string
|
error: PropTypes.string
|
||||||
};
|
};
|
||||||
|
|
||||||
export default withRouter(connect(
|
export default connect(
|
||||||
mapStateToProps,
|
mapStateToProps,
|
||||||
{
|
{
|
||||||
fetchContractProfile: contractProfileAction.request,
|
fetchContractProfile: contractProfileAction.request,
|
||||||
postContractFunction: contractFunctionAction.post
|
postContractFunction: contractFunctionAction.post
|
||||||
}
|
}
|
||||||
)(ContractFunctionsContainer));
|
)(ContractFunctionsContainer);
|
||||||
|
|
|
@ -14,7 +14,7 @@ class ContractLayoutContainer extends Component {
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
if (this.props.contract){
|
if (this.props.contract){
|
||||||
return <ContractLayout contractIsFiddle={this.props.contract.isFiddle} />;
|
return <ContractLayout contract={this.props.contract}/>;
|
||||||
} else {
|
} else {
|
||||||
return <React.Fragment />;
|
return <React.Fragment />;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
import React, {Component} from 'react';
|
import React, {Component} from 'react';
|
||||||
import {connect} from 'react-redux';
|
import {connect} from 'react-redux';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import {withRouter} from 'react-router-dom';
|
|
||||||
import {contractLogs as contractLogsAction, listenToContractLogs} from '../actions';
|
import {contractLogs as contractLogsAction, listenToContractLogs} from '../actions';
|
||||||
|
|
||||||
import ContractLogger from '../components/ContractLogger';
|
import ContractLogger from '../components/ContractLogger';
|
||||||
|
@ -12,14 +11,14 @@ class ContractLoggerContainer extends Component {
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
if (this.props.contractLogs.length === 0) {
|
if (this.props.contractLogs.length === 0) {
|
||||||
this.props.listenToContractLogs();
|
this.props.listenToContractLogs();
|
||||||
this.props.fetchContractLogs(this.props.match.params.contractName);
|
this.props.fetchContractLogs(this.props.contract.className);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<DataWrapper shouldRender={this.props.contractLogs !== undefined } {...this.props} render={() => (
|
<DataWrapper shouldRender={this.props.contractLogs !== undefined } {...this.props} render={() => (
|
||||||
<ContractLogger contractLogs={this.props.contractLogs} contractName={this.props.match.params.contractName}/>
|
<ContractLogger contractLogs={this.props.contractLogs} contractName={this.props.contract.className}/>
|
||||||
)} />
|
)} />
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -27,7 +26,7 @@ class ContractLoggerContainer extends Component {
|
||||||
|
|
||||||
function mapStateToProps(state, props) {
|
function mapStateToProps(state, props) {
|
||||||
return {
|
return {
|
||||||
contractLogs: getContractLogsByContract(state, props.match.params.contractName)
|
contractLogs: getContractLogsByContract(state, props.contract.className)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,10 +37,10 @@ ContractLoggerContainer.propTypes = {
|
||||||
match: PropTypes.object
|
match: PropTypes.object
|
||||||
};
|
};
|
||||||
|
|
||||||
export default withRouter(connect(
|
export default connect(
|
||||||
mapStateToProps,
|
mapStateToProps,
|
||||||
{
|
{
|
||||||
fetchContractLogs: contractLogsAction.request,
|
fetchContractLogs: contractLogsAction.request,
|
||||||
listenToContractLogs: listenToContractLogs
|
listenToContractLogs: listenToContractLogs
|
||||||
}
|
}
|
||||||
)(ContractLoggerContainer));
|
)(ContractLoggerContainer);
|
||||||
|
|
|
@ -2,13 +2,13 @@ import React, {Component} from 'react';
|
||||||
import {connect} from 'react-redux';
|
import {connect} from 'react-redux';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
|
|
||||||
import {contract as contractAction} from '../actions';
|
import {contracts as contractsAction} from '../actions';
|
||||||
import ContractLayout from '../components/ContractLayout';
|
import ContractLayout from '../components/ContractLayout';
|
||||||
import {getContractsByPath} from "../reducers/selectors";
|
import {getContractsByPath} from "../reducers/selectors";
|
||||||
|
|
||||||
class FileContractsContainer extends Component {
|
class FileContractsContainer extends Component {
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
this.props.fetchContract(this.props.currentFile);
|
this.props.fetchContracts();
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
@ -28,7 +28,7 @@ function mapStateToProps(state, props) {
|
||||||
|
|
||||||
FileContractsContainer.propTypes = {
|
FileContractsContainer.propTypes = {
|
||||||
contracts: PropTypes.arrayOf(PropTypes.object),
|
contracts: PropTypes.arrayOf(PropTypes.object),
|
||||||
fetchFileContracts: PropTypes.func,
|
fetchContractsByPath: PropTypes.func,
|
||||||
error: PropTypes.string,
|
error: PropTypes.string,
|
||||||
loading: PropTypes.bool
|
loading: PropTypes.bool
|
||||||
};
|
};
|
||||||
|
@ -36,6 +36,6 @@ FileContractsContainer.propTypes = {
|
||||||
export default connect(
|
export default connect(
|
||||||
mapStateToProps,
|
mapStateToProps,
|
||||||
{
|
{
|
||||||
fetchContract: contractAction.request
|
fetchContracts: contractsAction.request
|
||||||
}
|
}
|
||||||
)(FileContractsContainer);
|
)(FileContractsContainer);
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
/* eslint multiline-ternary: "off" */
|
|
||||||
/* eslint operator-linebreak: "off" */
|
|
||||||
import React, {Component} from 'react';
|
import React, {Component} from 'react';
|
||||||
import {connect} from 'react-redux';
|
import {connect} from 'react-redux';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
/* eslint multiline-ternary: "off" */
|
|
||||||
/* eslint operator-linebreak: "off" */
|
|
||||||
import React, {Component} from 'react';
|
import React, {Component} from 'react';
|
||||||
import {connect} from 'react-redux';
|
import {connect} from 'react-redux';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
|
|
|
@ -68,7 +68,7 @@ export function fetchContracts() {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function fetchContract(payload) {
|
export function fetchContract(payload) {
|
||||||
return get('/contract', ...arguments);
|
return get(`/contract/${payload.contractName}`, ...arguments);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function postContractFunction(payload) {
|
export function postContractFunction(payload) {
|
||||||
|
|
|
@ -84,16 +84,9 @@ class ContractsManager {
|
||||||
|
|
||||||
embark.registerAPICall(
|
embark.registerAPICall(
|
||||||
'get',
|
'get',
|
||||||
'/embark-api/contract',
|
'/embark-api/contract/:contractName',
|
||||||
(req, res) => {
|
(req, res) => {
|
||||||
const result = [];
|
self.events.request('contracts:contract', req.params.contractName, res.send.bind(res));
|
||||||
self.events.request('contracts:all', null, (contracts) => {
|
|
||||||
const contractByFilename = contracts.filter((contract) => contract.filename === req.query.filename);
|
|
||||||
contractByFilename.forEach((contract) => {
|
|
||||||
self.events.request('contracts:contract', contract.className, (contract) => result.push(contract));
|
|
||||||
});
|
|
||||||
});
|
|
||||||
res.send(result);
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -168,7 +161,13 @@ class ContractsManager {
|
||||||
'get',
|
'get',
|
||||||
'/embark-api/contracts',
|
'/embark-api/contracts',
|
||||||
(req, res) => {
|
(req, res) => {
|
||||||
self.events.request('contracts:all', null, res.send.bind(res));
|
const result = [];
|
||||||
|
self.events.request('contracts:all', null, (contracts) => {
|
||||||
|
contracts.forEach((contract) => {
|
||||||
|
self.events.request('contracts:contract', contract.className, (contract) => result.push(contract));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
res.send(result);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue