Add form component, redux devtools and fix reducers

This commit is contained in:
James Greenaway
2019-01-30 18:07:47 +00:00
parent 9e0cd0304e
commit 759fec17f3
11 changed files with 105 additions and 21 deletions

View File

@@ -1,3 +1 @@
.App { /* .App {} */
text-align: center;
}

View File

@@ -1,18 +1,25 @@
import React, { PureComponent } from 'react'; import React, { PureComponent } from 'react';
import { WorkloadListContainer } from '../WorkloadList'; import { WorkloadListContainer } from '../WorkloadList';
import { WorkloadFormContainer } from '../WorkloadForm';
import './App.css'; import './App.css';
class App extends PureComponent { class App extends PureComponent {
render() { render() {
return ( return (
<div className="App"> <div>
<div className="App-mainColumn"> <h1>CloudWork</h1>
<WorkloadListContainer /> <hr />
<div >
<WorkloadFormContainer />
</div> </div>
<div className="App-asideColumn"> <hr />
{/* <WorkloadFormContainer /> */}
<div>
<h2>Workloads</h2>
<WorkloadListContainer />
</div> </div>
</div> </div>
); );

View File

@@ -0,0 +1,71 @@
import React from 'react';
import { Dispatch } from 'redux';
import { connect } from 'react-redux';
import { submit } from '../../state/workloads/actions';
interface WorkloadFormDispatchProps {
submitWorkload: (complexity: number) => void
}
interface WorkloadFormProps extends
WorkloadFormDispatchProps {}
interface WorkloadFormState {
complexity: number;
}
class WorkloadForm extends React.PureComponent<WorkloadFormProps, WorkloadFormState> {
defaultState = {
complexity: 5,
}
state = this.defaultState;
handleSubmit = (e: React.MouseEvent) => {
this.props.submitWorkload(this.state.complexity);
this.setState(this.defaultState);
e.preventDefault();
}
render() {
return (
<form>
<h2>Create workload</h2>
<div>
<label>
Complexity: {this.state.complexity}
<br />
<input
value={this.state.complexity}
onChange={(e) => this.setState({ complexity: Number(e.target.value) })}
type="range"
min="1"
max="10"
/>
</label>
</div>
<div>
<button onClick={this.handleSubmit} type="submit">Start work</button>
</div>
</form>
);
}
}
const mapDispatchToProps = (dispatch: Dispatch): WorkloadFormDispatchProps => ({
submitWorkload: (complexity: number) => dispatch(submit({ complexity })),
});
const WorkloadFormContainer = connect(null, mapDispatchToProps)(WorkloadForm);
export {
WorkloadForm,
WorkloadFormContainer,
}
export default WorkloadForm;

View File

@@ -0,0 +1,2 @@
export { default } from './WorkloadForm';
export * from './WorkloadForm';

View File

@@ -1,3 +0,0 @@
.WorkloadItem {
border: 2px solid var(--wf-blue);
}

View File

@@ -1,21 +1,27 @@
import React from 'react'; import React from 'react';
import ReactDOM from 'react-dom'; import ReactDOM from 'react-dom';
import { createStore, applyMiddleware } from 'redux'; import { createStore, applyMiddleware, compose } from 'redux';
import { Provider } from 'react-redux'; import { Provider } from 'react-redux';
import { createEpicMiddleware } from 'redux-observable'; import { createEpicMiddleware } from 'redux-observable';
import moment from 'moment';
import { reducers, epics, Action, State } from './state'; import { reducer, epics, Action, State } from './state';
import * as WorkloadActions from './state/workloads/actions'; import * as WorkloadActions from './state/workloads/actions';
import './index.css'; import './index.css';
import App from './components/App'; import App from './components/App';
const epicMiddleware = createEpicMiddleware<Action, Action, State>(); // @ts-ignore: use Redux devtools if installed in browser
const store = createStore(reducers, applyMiddleware(epicMiddleware)); const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
const epicMiddleware = createEpicMiddleware<Action, Action, State>();
const store = createStore(reducer, composeEnhancers(applyMiddleware(epicMiddleware)));
epicMiddleware.run(epics); epicMiddleware.run(epics);
store.dispatch(WorkloadActions.submit({ complexity: 100 }));
store.dispatch(WorkloadActions.created({ id: 0, complexity: 100, completeDate: new Date() })); // demo actions
store.dispatch(WorkloadActions.submit({ complexity: 10 }));
store.dispatch(WorkloadActions.created({ id: 0, complexity: 10, completeDate: moment().add(10, 'second').toDate() }));
store.dispatch(WorkloadActions.created({ id: 1, complexity: 10, completeDate: moment().add(18, 'second').toDate() }));
/* /*

View File

@@ -1,3 +1,3 @@
export * from './reducers'; export * from './reducer';
export * from './actions'; export * from './actions';
export * from './epics'; export * from './epics';

View File

@@ -12,6 +12,6 @@ export interface State {
workloads: WorkloadsState; workloads: WorkloadsState;
} }
export const reducers = combineReducers<State, Action>({ export const reducer = combineReducers<State, Action>({
workloads: workloadReducer, workloads: workloadReducer,
}); });

View File

@@ -2,7 +2,7 @@ import { combineEpics, Epic, ofType } from 'redux-observable';
import { map, tap, ignoreElements } from 'rxjs/operators'; import { map, tap, ignoreElements } from 'rxjs/operators';
import { Action } from '../actions'; import { Action } from '../actions';
import { State } from '../reducers'; import { State } from '../reducer';
type AppEpic = Epic<Action, Action, State>; type AppEpic = Epic<Action, Action, State>;

View File

@@ -1,5 +1,5 @@
export * from './types'; export * from './types';
export * from './actions'; export * from './actions';
export * from './reducers'; export * from './reducer';
export * from './epics'; export * from './epics';
export * from './services'; export * from './services';

View File

@@ -19,6 +19,7 @@ export const reducer = (state: State = initialState, action: Action): State => {
switch (action.type) { switch (action.type) {
case 'WORKLOAD_CREATED': case 'WORKLOAD_CREATED':
return { return {
...state,
[action.payload.id]: { [action.payload.id]: {
id: action.payload.id, id: action.payload.id,
complexity: action.payload.complexity, complexity: action.payload.complexity,
@@ -29,6 +30,7 @@ export const reducer = (state: State = initialState, action: Action): State => {
case 'WORKLOAD_CANCEL': case 'WORKLOAD_CANCEL':
return { return {
...state,
[action.payload.id]: { [action.payload.id]: {
...state[action.payload.id], ...state[action.payload.id],
status: 'CANCELED', status: 'CANCELED',
@@ -37,6 +39,7 @@ export const reducer = (state: State = initialState, action: Action): State => {
case 'WORKLOAD_UPDATE_STATUS': case 'WORKLOAD_UPDATE_STATUS':
return { return {
...state,
[action.payload.id]: { [action.payload.id]: {
...state[action.payload.id], ...state[action.payload.id],
status: action.payload.status, status: action.payload.status,