add layout to have the process name in the route
This commit is contained in:
parent
2e1791e0f4
commit
548b194224
|
@ -1,18 +1,23 @@
|
||||||
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 Loading from "./Loading";
|
||||||
|
|
||||||
class Process extends Component {
|
class Process extends Component {
|
||||||
render() {
|
render() {
|
||||||
const logs = this.props.logs || [];
|
const logs = this.props.logs;
|
||||||
return (
|
return (
|
||||||
<div>
|
<Page.Content title={this.props.processName.charAt(0).toUpperCase() + this.props.processName.slice(1)}>
|
||||||
State: {this.props.state}
|
<p className="capitalize">State: {this.props.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>)
|
logs.map((item, i) => <p key={i} className={item.logLevel}>{item.msg_clear || item.msg}</p>)
|
||||||
}
|
}
|
||||||
</div>
|
</div>}
|
||||||
</div>);
|
</Page.Content>);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,68 @@
|
||||||
|
import PropTypes from "prop-types";
|
||||||
|
import React, {Component} from 'react';
|
||||||
|
import connect from "react-redux/es/connect/connect";
|
||||||
|
import {NavLink, Route, Switch, withRouter} from 'react-router-dom';
|
||||||
|
import {
|
||||||
|
Page,
|
||||||
|
Grid,
|
||||||
|
List
|
||||||
|
} from "tabler-react";
|
||||||
|
|
||||||
|
import ProcessesContainer from '../containers/ProcessesContainer';
|
||||||
|
import Loading from "./Loading";
|
||||||
|
|
||||||
|
const routePrefix = '/embark/processes';
|
||||||
|
|
||||||
|
class ProcessesLayout extends Component {
|
||||||
|
|
||||||
|
|
||||||
|
render() {
|
||||||
|
if (!this.props.processes || !this.props.processes.data) {
|
||||||
|
return <Loading />;
|
||||||
|
}
|
||||||
|
const processNames = Object.keys(this.props.processes.data) || [];
|
||||||
|
return (<Grid.Row>
|
||||||
|
<Grid.Col md={3}>
|
||||||
|
<Page.Title className="my-5">Processes</Page.Title>
|
||||||
|
<div>
|
||||||
|
<List.Group transparent={true}>
|
||||||
|
{processNames.map((processName, index) => {
|
||||||
|
return (<List.GroupItem
|
||||||
|
className="d-flex align-items-center capitalize"
|
||||||
|
to={`${routePrefix}/${processName}`}
|
||||||
|
key={'process-' + processName}
|
||||||
|
active={index === 0 && this.props.match.isExact === true}
|
||||||
|
RootComponent={withRouter(NavLink)}
|
||||||
|
>
|
||||||
|
{processName}
|
||||||
|
</List.GroupItem>);
|
||||||
|
})}
|
||||||
|
|
||||||
|
</List.Group>
|
||||||
|
</div>
|
||||||
|
</Grid.Col>
|
||||||
|
<Grid.Col md={9}>
|
||||||
|
<Switch>
|
||||||
|
<Route exact path={`${routePrefix}/`} component={ProcessesContainer} />
|
||||||
|
{processNames.map((processName, index) => {
|
||||||
|
return (<Route key={'procesRoute-' + index} exact path={`${routePrefix}/${processName}`} component={ProcessesContainer}/>);
|
||||||
|
})}
|
||||||
|
</Switch>
|
||||||
|
</Grid.Col>
|
||||||
|
</Grid.Row>);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ProcessesLayout.propTypes = {
|
||||||
|
processes: PropTypes.object,
|
||||||
|
match: PropTypes.object
|
||||||
|
};
|
||||||
|
|
||||||
|
function mapStateToProps(state) {
|
||||||
|
return {processes: state.processes};
|
||||||
|
}
|
||||||
|
|
||||||
|
export default connect(
|
||||||
|
mapStateToProps
|
||||||
|
)(ProcessesLayout);
|
||||||
|
|
|
@ -6,11 +6,12 @@ import React, {Component} from 'react';
|
||||||
import history from '../history';
|
import history from '../history';
|
||||||
import Layout from '../components/Layout';
|
import Layout from '../components/Layout';
|
||||||
import routes from '../routes';
|
import routes from '../routes';
|
||||||
import {initBlockHeader} from '../actions';
|
import {initBlockHeader, fetchProcesses} from '../actions';
|
||||||
|
|
||||||
class AppContainer extends Component {
|
class AppContainer extends Component {
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
this.props.initBlockHeader();
|
this.props.initBlockHeader();
|
||||||
|
this.props.fetchProcesses();
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
@ -25,12 +26,14 @@ class AppContainer extends Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
AppContainer.propTypes = {
|
AppContainer.propTypes = {
|
||||||
initBlockHeader: PropTypes.func
|
initBlockHeader: PropTypes.func,
|
||||||
|
fetchProcesses: PropTypes.func
|
||||||
};
|
};
|
||||||
|
|
||||||
export default connect(
|
export default connect(
|
||||||
null,
|
null,
|
||||||
{
|
{
|
||||||
initBlockHeader
|
initBlockHeader,
|
||||||
|
fetchProcesses
|
||||||
},
|
},
|
||||||
)(AppContainer);
|
)(AppContainer);
|
||||||
|
|
|
@ -1,66 +1,46 @@
|
||||||
import React, {Component} from 'react';
|
import React, {Component} from 'react';
|
||||||
import {connect} from 'react-redux';
|
import {connect} from 'react-redux';
|
||||||
import {Tabs, Tab} from 'tabler-react';
|
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import {fetchProcesses, fetchProcessLogs, listenToProcessLogs} from '../actions';
|
import {fetchProcessLogs, listenToProcessLogs} from '../actions';
|
||||||
import Loading from '../components/Loading';
|
|
||||||
|
|
||||||
import "./css/processContainer.css";
|
|
||||||
import Process from "../components/Process";
|
import Process from "../components/Process";
|
||||||
|
|
||||||
class ProcessesContainer extends Component {
|
class ProcessesContainer extends Component {
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
this.props.fetchProcesses();
|
// Get correct process name
|
||||||
}
|
const pathParts = this.props.match.path.split('/');
|
||||||
|
this.processName = pathParts[pathParts.length - 1];
|
||||||
shouldComponentUpdate(nextProps, _nextState) {
|
// If we are not in a specific process page (eg: processes/ root), get first process
|
||||||
if (!this.islistening && nextProps.processes && nextProps.processes.data) {
|
if (Object.keys(this.props.processes.data).indexOf(this.processName) < 0) {
|
||||||
this.islistening = true;
|
this.processName = Object.keys(this.props.processes.data)[0];
|
||||||
Object.keys(nextProps.processes.data).forEach(processName => {
|
}
|
||||||
this.props.fetchProcessLogs(processName);
|
|
||||||
// Only start watching if we are not already watching
|
// Fetch logs for the process
|
||||||
if (!this.props.processes.data ||
|
this.props.fetchProcessLogs(this.processName);
|
||||||
!this.props.processes.data[processName] ||
|
|
||||||
!this.props.processes.data[processName].isListening
|
// Only start watching if we are not already watching
|
||||||
) {
|
if (!this.props.processes.data[this.processName].isListening) {
|
||||||
this.props.listenToProcessLogs(processName);
|
this.props.listenToProcessLogs(this.processName);
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const {processes} = this.props;
|
if (!this.processName) {
|
||||||
if (!processes.data) {
|
return '';
|
||||||
return <Loading />;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const processNames = Object.keys(processes.data);
|
|
||||||
return (
|
return (
|
||||||
<div className="processes-container">
|
<div className="processes-container">
|
||||||
{processes.error && <h1>
|
<Process processName={this.processName}
|
||||||
<i>Error: {processes.error.message || processes.error}</i>
|
state={this.props.processes.data[this.processName].state}
|
||||||
</h1>}
|
logs={this.props.processes.data[this.processName].logs}/>
|
||||||
|
|
||||||
{processNames && processNames.length && <Tabs initialTab={processNames[0]}>
|
|
||||||
{processNames.map(processName => {
|
|
||||||
return (<Tab key={processName} title={processName}>
|
|
||||||
<Process processName={processName}
|
|
||||||
state={processes.data[processName].state}
|
|
||||||
logs={processes.data[processName].logs}/>
|
|
||||||
</Tab>);
|
|
||||||
})}
|
|
||||||
</Tabs>}
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ProcessesContainer.propTypes = {
|
ProcessesContainer.propTypes = {
|
||||||
|
match: PropTypes.object,
|
||||||
processes: PropTypes.object,
|
processes: PropTypes.object,
|
||||||
fetchProcesses: PropTypes.func,
|
|
||||||
fetchProcessLogs: PropTypes.func,
|
fetchProcessLogs: PropTypes.func,
|
||||||
listenToProcessLogs: PropTypes.func
|
listenToProcessLogs: PropTypes.func
|
||||||
};
|
};
|
||||||
|
@ -72,7 +52,6 @@ function mapStateToProps(state) {
|
||||||
export default connect(
|
export default connect(
|
||||||
mapStateToProps,
|
mapStateToProps,
|
||||||
{
|
{
|
||||||
fetchProcesses,
|
|
||||||
fetchProcessLogs,
|
fetchProcessLogs,
|
||||||
listenToProcessLogs
|
listenToProcessLogs
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,4 @@
|
||||||
|
.logs {
|
||||||
.processes-container .nav-link {
|
|
||||||
text-transform: capitalize;
|
|
||||||
}
|
|
||||||
|
|
||||||
.processes-container .logs {
|
|
||||||
margin: 10px 0;
|
margin: 10px 0;
|
||||||
background-color: #333333;
|
background-color: #333333;
|
||||||
font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace;
|
font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace;
|
||||||
|
@ -13,15 +8,19 @@
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.processes-container .logs .error {
|
.logs .error {
|
||||||
color: #dc3546;
|
color: #dc3546;
|
||||||
}
|
}
|
||||||
.processes-container .logs .warn {
|
.logs .warn {
|
||||||
color: #fec107;
|
color: #fec107;
|
||||||
}
|
}
|
||||||
.processes-container .logs .debug {
|
.logs .debug {
|
||||||
color: #b7c1cc;
|
color: #b7c1cc;
|
||||||
}
|
}
|
||||||
.processes-container .logs .trace {
|
.logs .trace {
|
||||||
color: #8f98a2;
|
color: #8f98a2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.capitalize {
|
||||||
|
text-transform: capitalize;
|
||||||
|
}
|
|
@ -3,6 +3,7 @@ import ReactDOM from 'react-dom';
|
||||||
import {Provider} from 'react-redux';
|
import {Provider} from 'react-redux';
|
||||||
|
|
||||||
import "tabler-react/dist/Tabler.css";
|
import "tabler-react/dist/Tabler.css";
|
||||||
|
import "./general.css";
|
||||||
|
|
||||||
import AppContainer from './containers/AppContainer';
|
import AppContainer from './containers/AppContainer';
|
||||||
import registerServiceWorker from './registerServiceWorker';
|
import registerServiceWorker from './registerServiceWorker';
|
||||||
|
|
|
@ -4,15 +4,14 @@ import {Route, Switch} from 'react-router-dom';
|
||||||
import Home from './components/Home';
|
import Home from './components/Home';
|
||||||
import NoMatch from './components/NoMatch';
|
import NoMatch from './components/NoMatch';
|
||||||
import ExplorerLayout from './components/ExplorerLayout';
|
import ExplorerLayout from './components/ExplorerLayout';
|
||||||
|
import ProcessesLayout from './components/ProcessesLayout';
|
||||||
import ProcessesContainer from './containers/ProcessesContainer';
|
|
||||||
|
|
||||||
const routes = (
|
const routes = (
|
||||||
<React.Fragment>
|
<React.Fragment>
|
||||||
<Switch>
|
<Switch>
|
||||||
<Route exact path="/embark/" component={Home} />
|
<Route exact path="/embark/" component={Home} />
|
||||||
<Route path="/embark/explorer/" component={ExplorerLayout} />
|
<Route path="/embark/explorer/" component={ExplorerLayout} />
|
||||||
<Route path="/embark/processes/" component={ProcessesContainer} />
|
<Route path="/embark/processes/" component={ProcessesLayout} />
|
||||||
<Route component={NoMatch} />
|
<Route component={NoMatch} />
|
||||||
</Switch>
|
</Switch>
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
|
|
Loading…
Reference in New Issue