Add connected but unstyled workload list
This commit is contained in:
@@ -8,6 +8,8 @@
|
||||
"react-dom": "^16.7.0",
|
||||
"react-redux": "^6.0.0",
|
||||
"react-scripts": "2.1.3",
|
||||
"react-timeago": "^4.3.0",
|
||||
"redux": "^4.0.1",
|
||||
"redux-observable": "^1.0.0",
|
||||
"rxjs": "^6.4.0",
|
||||
"typescript": "3.2.4"
|
||||
@@ -32,6 +34,7 @@
|
||||
"@types/node": "10.12.18",
|
||||
"@types/react": "16.7.22",
|
||||
"@types/react-dom": "16.0.11",
|
||||
"@types/react-redux": "^7.0.1"
|
||||
"@types/react-redux": "^7.0.1",
|
||||
"@types/react-timeago": "^4.1.0"
|
||||
}
|
||||
}
|
||||
|
||||
14
src/App.tsx
14
src/App.tsx
@@ -1,14 +0,0 @@
|
||||
import React, { PureComponent } from 'react';
|
||||
import './App.css';
|
||||
|
||||
class App extends PureComponent {
|
||||
render() {
|
||||
return (
|
||||
<div className="App">
|
||||
App goes here…
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default App;
|
||||
22
src/components/App/App.tsx
Executable file
22
src/components/App/App.tsx
Executable file
@@ -0,0 +1,22 @@
|
||||
import React, { PureComponent } from 'react';
|
||||
|
||||
import { WorkloadListContainer } from '../WorkloadList';
|
||||
import './App.css';
|
||||
|
||||
|
||||
class App extends PureComponent {
|
||||
render() {
|
||||
return (
|
||||
<div className="App">
|
||||
<div className="App-mainColumn">
|
||||
<WorkloadListContainer />
|
||||
</div>
|
||||
<div className="App-asideColumn">
|
||||
{/* <WorkloadFormContainer /> */}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default App;
|
||||
2
src/components/App/index.ts
Normal file
2
src/components/App/index.ts
Normal file
@@ -0,0 +1,2 @@
|
||||
export { default } from './App';
|
||||
export * from './App';
|
||||
3
src/components/WorkloadItem/WorkloadItem.css
Normal file
3
src/components/WorkloadItem/WorkloadItem.css
Normal file
@@ -0,0 +1,3 @@
|
||||
.WorkloadItem {
|
||||
border: 2px solid var(--wf-blue);
|
||||
}
|
||||
54
src/components/WorkloadItem/WorkloadItem.tsx
Normal file
54
src/components/WorkloadItem/WorkloadItem.tsx
Normal file
@@ -0,0 +1,54 @@
|
||||
import React from 'react';
|
||||
import TimeAgo from 'react-timeago';
|
||||
import { Status } from '../../state/workloads'
|
||||
|
||||
|
||||
export interface WorkloadItemStateProps {
|
||||
id: number;
|
||||
complexity: number;
|
||||
status: Status;
|
||||
completeDate: Date;
|
||||
}
|
||||
|
||||
export interface WorkloadItemMethodProps {
|
||||
onCancel: () => void;
|
||||
}
|
||||
|
||||
export interface WorkloadItemProps extends
|
||||
WorkloadItemStateProps,
|
||||
WorkloadItemMethodProps {}
|
||||
|
||||
|
||||
const WorkloadItem: React.SFC<WorkloadItemProps> = (props) => (
|
||||
<div className="WorkloadItem">
|
||||
<div>
|
||||
<h3 className="WorkloadItem-heading">Workload #{props.id}</h3>
|
||||
<span className="WorkloadItem-subHeading">Complexity: {props.complexity}</span>
|
||||
</div>
|
||||
<div>
|
||||
{props.status === 'WORKING'
|
||||
? (
|
||||
<>
|
||||
<span><TimeAgo date={props.completeDate} /></span>
|
||||
<button
|
||||
className="WorkloadItem-secondaryButton"
|
||||
onClick={props.onCancel}
|
||||
>
|
||||
Cancel
|
||||
</button>
|
||||
</>
|
||||
)
|
||||
: (
|
||||
<span className="WorkloadItem-statusText">{props.status.toLowerCase()}</span>
|
||||
)
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
|
||||
export {
|
||||
WorkloadItem,
|
||||
};
|
||||
|
||||
export default WorkloadItem;
|
||||
2
src/components/WorkloadItem/index.ts
Normal file
2
src/components/WorkloadItem/index.ts
Normal file
@@ -0,0 +1,2 @@
|
||||
export { default } from './WorkloadItem';
|
||||
export * from './WorkloadItem';
|
||||
55
src/components/WorkloadList/WorkloadList.tsx
Normal file
55
src/components/WorkloadList/WorkloadList.tsx
Normal file
@@ -0,0 +1,55 @@
|
||||
import React from 'react';
|
||||
import { Dispatch } from 'redux';
|
||||
import { connect } from 'react-redux';
|
||||
import { Action, State } from '../../state';
|
||||
import { cancel } from '../../state/workloads/actions';
|
||||
import { WorkloadItem, WorkloadItemStateProps } from '../WorkloadItem';
|
||||
|
||||
|
||||
export interface WorkloadListStateProps {
|
||||
workloads: WorkloadItemStateProps[];
|
||||
}
|
||||
|
||||
export interface WorkloadListDispatchProps {
|
||||
cancelWorkload: (id: number) => void;
|
||||
}
|
||||
|
||||
export interface WorkloadListProps extends
|
||||
WorkloadListStateProps,
|
||||
WorkloadListDispatchProps {}
|
||||
|
||||
|
||||
const WorkloadList: React.SFC<WorkloadListProps> = ({ workloads, cancelWorkload }) => (
|
||||
!workloads.length
|
||||
? (
|
||||
<span>No workloads to display</span>
|
||||
)
|
||||
: (
|
||||
<ol>
|
||||
{workloads.map((workload) => (
|
||||
<li key={workload.id}>
|
||||
<WorkloadItem {...workload} onCancel={() => cancelWorkload(workload.id)} />
|
||||
</li>
|
||||
))}
|
||||
</ol>
|
||||
)
|
||||
);
|
||||
|
||||
|
||||
const mapStateToProps = (state: State): WorkloadListStateProps => ({
|
||||
workloads: Object.values(state.workloads),
|
||||
});
|
||||
|
||||
const mapDispatchToProps = (dispatch: Dispatch<Action>): WorkloadListDispatchProps => ({
|
||||
cancelWorkload: (id: number) => dispatch(cancel({ id })),
|
||||
})
|
||||
|
||||
const WorkloadListContainer = connect(mapStateToProps, mapDispatchToProps)(WorkloadList);
|
||||
|
||||
|
||||
export {
|
||||
WorkloadList,
|
||||
WorkloadListContainer,
|
||||
};
|
||||
|
||||
export default WorkloadList;
|
||||
1
src/components/WorkloadList/index.ts
Normal file
1
src/components/WorkloadList/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from './WorkloadList';
|
||||
@@ -7,7 +7,7 @@ import { createEpicMiddleware } from 'redux-observable';
|
||||
import { reducers, epics, Action, State } from './state';
|
||||
import * as WorkloadActions from './state/workloads/actions';
|
||||
import './index.css';
|
||||
import App from './App';
|
||||
import App from './components/App';
|
||||
|
||||
|
||||
const epicMiddleware = createEpicMiddleware<Action, Action, State>();
|
||||
@@ -15,6 +15,7 @@ const store = createStore(reducers, applyMiddleware(epicMiddleware));
|
||||
|
||||
epicMiddleware.run(epics);
|
||||
store.dispatch(WorkloadActions.submit({ complexity: 100 }));
|
||||
store.dispatch(WorkloadActions.created({ id: 0, complexity: 100, completeDate: new Date() }));
|
||||
|
||||
|
||||
/*
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
export * from './types';
|
||||
export * from './actions';
|
||||
export * from './reducers';
|
||||
export * from './epics';
|
||||
|
||||
@@ -3,6 +3,7 @@ import { Status } from './types';
|
||||
|
||||
interface Entry<Id extends number> {
|
||||
id: Id;
|
||||
complexity: number;
|
||||
completeDate: Date;
|
||||
status: Status;
|
||||
}
|
||||
@@ -20,6 +21,7 @@ export const reducer = (state: State = initialState, action: Action): State => {
|
||||
return {
|
||||
[action.payload.id]: {
|
||||
id: action.payload.id,
|
||||
complexity: action.payload.complexity,
|
||||
completeDate: action.payload.completeDate,
|
||||
status: 'WORKING',
|
||||
},
|
||||
|
||||
14
yarn.lock
14
yarn.lock
@@ -943,6 +943,13 @@
|
||||
"@types/react" "*"
|
||||
redux "^4.0.0"
|
||||
|
||||
"@types/react-timeago@^4.1.0":
|
||||
version "4.1.0"
|
||||
resolved "https://npm.nutterlogic.com/@types%2freact-timeago/-/react-timeago-4.1.0.tgz#e8ebc0add9de6d768fda610922879382bdc2f327"
|
||||
integrity sha512-rQihM3unIJ2i3gxJhoM9hktqrMsrqv2OVyz4zWG7T6hUdmt4V5IGs6B65EJgo+4Rt9Z5pscc0H9YcZX4hPuLkA==
|
||||
dependencies:
|
||||
"@types/react" "*"
|
||||
|
||||
"@types/react@*", "@types/react@16.7.22":
|
||||
version "16.7.22"
|
||||
resolved "https://npm.nutterlogic.com/@types%2freact/-/react-16.7.22.tgz#5bc6d166d5ac34b835756f0b736c7b1af0043e81"
|
||||
@@ -8050,6 +8057,11 @@ react-scripts@2.1.3:
|
||||
optionalDependencies:
|
||||
fsevents "1.2.4"
|
||||
|
||||
react-timeago@^4.3.0:
|
||||
version "4.3.0"
|
||||
resolved "https://npm.nutterlogic.com/react-timeago/-/react-timeago-4.3.0.tgz#ff47bb12c3c2a40bc31e6b3e457f5ac4a690a3ec"
|
||||
integrity sha512-q89RXb4K16xyDdy2GR/mIRYrDw8ll/RlohSIgjCr1J85eHKeL/XEl4XPKICMdJnJpaXwRzOjlsdnEuxWsi61RQ==
|
||||
|
||||
react@^16.7.0:
|
||||
version "16.7.0"
|
||||
resolved "https://npm.nutterlogic.com/react/-/react-16.7.0.tgz#b674ec396b0a5715873b350446f7ea0802ab6381"
|
||||
@@ -8154,7 +8166,7 @@ redux-observable@^1.0.0:
|
||||
resolved "https://npm.nutterlogic.com/redux-observable/-/redux-observable-1.0.0.tgz#780ff2455493eedcef806616fe286b454fd15d91"
|
||||
integrity sha512-6bXnpqWTBeLaLQjXHyN1giXq4nLxCmv+SUkdmiwBgvmVxvDbdmydvL1Z7DGo0WItyzI/kqXQKiucUuTxnrPRkA==
|
||||
|
||||
redux@^4.0.0:
|
||||
redux@^4.0.0, redux@^4.0.1:
|
||||
version "4.0.1"
|
||||
resolved "https://npm.nutterlogic.com/redux/-/redux-4.0.1.tgz#436cae6cc40fbe4727689d7c8fae44808f1bfef5"
|
||||
integrity sha512-R7bAtSkk7nY6O/OYMVR9RiBI+XghjF9rlbl5806HJbQph0LJVHZrU5oaO4q70eUKiqMRqm4y07KLTlMZ2BlVmg==
|
||||
|
||||
Reference in New Issue
Block a user