1 Commits

Author SHA1 Message Date
dependabot[bot]
e3c5fd92d2 Bump elliptic from 6.4.1 to 6.5.4
Bumps [elliptic](https://github.com/indutny/elliptic) from 6.4.1 to 6.5.4.
- [Release notes](https://github.com/indutny/elliptic/releases)
- [Commits](https://github.com/indutny/elliptic/compare/v6.4.1...v6.5.4)

Signed-off-by: dependabot[bot] <support@github.com>
2021-03-09 10:17:57 +00:00
13 changed files with 8782 additions and 40388 deletions

31445
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -4,7 +4,6 @@
"private": true, "private": true,
"dependencies": { "dependencies": {
"babel-loader": "8.0.4", "babel-loader": "8.0.4",
"bootstrap": "^5.1.0",
"moment": "^2.24.0", "moment": "^2.24.0",
"react": "^16.7.0", "react": "^16.7.0",
"react-dom": "^16.7.0", "react-dom": "^16.7.0",
@@ -12,7 +11,7 @@
"react-scripts": "2.1.3", "react-scripts": "2.1.3",
"react-timeago": "^4.3.0", "react-timeago": "^4.3.0",
"redux": "^4.0.1", "redux": "^4.0.1",
"redux-observable": "^1.2.0", "redux-observable": "^1.0.0",
"rxjs": "^6.4.0", "rxjs": "^6.4.0",
"typesafe-actions": "^3.0.0", "typesafe-actions": "^3.0.0",
"typescript": "3.2.4" "typescript": "3.2.4"

View File

@@ -1,71 +1 @@
/* .App {} */ /* .App {} */
.app-root {
color: rgb(82, 1, 245);
}
.header {
padding-bottom: 2rem;
border-bottom: 3px solid rgb(82, 1, 245)
}
.border {
border: 3px solid rgb(82, 1, 245) !important;
}
button {
background-color: rgb(82, 1, 245);
color: white;
border: none;
padding: 0.5rem 1rem;
margin-top: 3rem;
}
.form-container {
margin-top: 3.375rem;
max-height: 21rem;
}
.list-container {
margin-right: 5rem;
}
input[type=range]{
-webkit-appearance: none;
}
input[type=range]::-webkit-slider-runnable-track {
width: 300px;
height: 5px;
background: rgb(82, 1, 245);
border: none;
border-radius: 3px;
}
input[type=range]::-webkit-slider-thumb {
-webkit-appearance: none;
border: none;
height: 16px;
width: 16px;
/* border-radius: 50%; */
background: rgb(82, 1, 245);
margin-top: -4px;
}
input[type=range]:focus {
outline: none;
}
input[type=range]:focus::-webkit-slider-runnable-track {
background: rgb(82, 1, 245);
}
.primary-details {
margin-right: auto;
}
.WorkloadItem-secondaryButton {
margin-left: 1.5rem;
background: rgb(82, 1, 245, 0.4);
color: rgb(82, 1, 245);
}

View File

@@ -6,22 +6,21 @@ import './App.css';
class App extends PureComponent { class App extends PureComponent {
nowHandler () : number {
return Date.now();
}
render() { render() {
return ( return (
<div className="app-root container mt-5 pt-5 d-flex flex-column"> <div>
<h1 className="header">CloudWork</h1> <h1>CloudWork</h1>
<div className="d-flex flex-row-reverse mt-5"> <hr />
<div className="form-container border p-5" style={{flex: 2}}><WorkloadFormContainer /></div>
<div className="list-container" style={{flex: 5}}> <div >
<h2 className="mb-3">Workloads</h2> <WorkloadFormContainer />
<WorkloadListContainer nowHandler={this.nowHandler}/> </div>
</div> <hr />
</div>
<div>
<h2>Workloads</h2>
<WorkloadListContainer />
</div>
</div> </div>
); );
} }

View File

@@ -31,13 +31,13 @@ class WorkloadForm extends React.PureComponent<WorkloadFormProps, WorkloadFormSt
render() { render() {
return ( return (
<form> <form>
<h2 className="form-header mb-5">Create workload</h2> <h2>Create workload</h2>
<div> <div>
<label className="d-block w-100"> <label>
<span className="mb-2 d-block">Complexity: {this.state.complexity}</span> Complexity: {this.state.complexity}
<br />
<input <input
className="w-100"
value={this.state.complexity} value={this.state.complexity}
onChange={(e) => this.setState({ complexity: Number(e.target.value) })} onChange={(e) => this.setState({ complexity: Number(e.target.value) })}
type="range" type="range"

View File

@@ -1,12 +1,8 @@
import React, { useEffect } from 'react'; import React from 'react';
import TimeAgo from 'react-timeago'; import TimeAgo from 'react-timeago';
import { Status } from '../../state/workloads' import { Status } from '../../state/workloads'
import { Dispatch } from 'redux';
import { connect } from 'react-redux';
import { RootAction } from '../../state';
import { updateStatus } from '../../state/workloads/actions';
const statusMap = {CANCELED: "Cancelled", SUCCESS: "Successful", FAILURE: "Failed"};
export interface WorkloadItemStateProps { export interface WorkloadItemStateProps {
id: number; id: number;
complexity: number; complexity: number;
@@ -16,7 +12,6 @@ export interface WorkloadItemStateProps {
export interface WorkloadItemMethodProps { export interface WorkloadItemMethodProps {
onCancel: () => void; onCancel: () => void;
nowHandler: () => number;
} }
export interface WorkloadItemProps extends export interface WorkloadItemProps extends
@@ -24,21 +19,19 @@ export interface WorkloadItemProps extends
WorkloadItemMethodProps {} WorkloadItemMethodProps {}
const WorkloadItem: React.SFC<WorkloadItemProps> = (props) => { const WorkloadItem: React.SFC<WorkloadItemProps> = (props) => (
// console.log(props.completeDate) <div className="WorkloadItem">
<div>
return <div className="WorkloadItem border p-4 mb-4 d-flex">
<div className="primary-details">
<h3 className="WorkloadItem-heading">Workload #{props.id}</h3> <h3 className="WorkloadItem-heading">Workload #{props.id}</h3>
<span className="WorkloadItem-subHeading">Complexity {props.complexity}</span> <span className="WorkloadItem-subHeading">Complexity: {props.complexity}</span>
</div> </div>
<div className="d-flex"> <div>
{props.status === 'WORKING' {props.status === 'WORKING'
? ( ? (
<> <>
<span className="my-auto"><TimeAgo date={props.completeDate} now={props.nowHandler} /></span> <span><TimeAgo date={props.completeDate} /></span>
<button <button
className="WorkloadItem-secondaryButton ml-3 my-auto" className="WorkloadItem-secondaryButton"
onClick={props.onCancel} onClick={props.onCancel}
> >
Cancel Cancel
@@ -46,23 +39,16 @@ const WorkloadItem: React.SFC<WorkloadItemProps> = (props) => {
</> </>
) )
: ( : (
<span className="WorkloadItem-statusText my-auto">{statusMap[props.status]}</span> <span className="WorkloadItem-statusText">{props.status.toLowerCase()}</span>
) )
} }
</div> </div>
</div> </div>
}; );
const mapDispatchToProps = (dispatch: Dispatch<RootAction>) => ({
udpateWorkloadStatus: (id: number, status: Status) => dispatch(updateStatus({ id, status })),
})
const WorkloadItemContainer = connect(null, mapDispatchToProps)(WorkloadItem);
export { export {
WorkloadItem, WorkloadItem,
WorkloadItemContainer
}; };
export default WorkloadItem; export default WorkloadItem;

View File

@@ -12,7 +12,6 @@ export interface WorkloadListStateProps {
export interface WorkloadListDispatchProps { export interface WorkloadListDispatchProps {
cancelWorkload: (id: number) => void; cancelWorkload: (id: number) => void;
nowHandler: () => number;
} }
export interface WorkloadListProps extends export interface WorkloadListProps extends
@@ -20,19 +19,19 @@ export interface WorkloadListProps extends
WorkloadListDispatchProps {} WorkloadListDispatchProps {}
const WorkloadList: React.SFC<WorkloadListProps> = ({ workloads, cancelWorkload, nowHandler }) => ( const WorkloadList: React.SFC<WorkloadListProps> = ({ workloads, cancelWorkload }) => (
!workloads.length !workloads.length
? ( ? (
<span>No workloads to display</span> <span>No workloads to display</span>
) )
: ( : (
<ul className="list-unstyled"> <ol>
{workloads.map((workload) => ( {workloads.map((workload) => (
<li key={workload.id}> <li key={workload.id}>
<WorkloadItem {...workload} onCancel={() => cancelWorkload(workload.id)} nowHandler={nowHandler} /> <WorkloadItem {...workload} onCancel={() => cancelWorkload(workload.id)} />
</li> </li>
))} ))}
</ul> </ol>
) )
); );
@@ -41,7 +40,7 @@ const mapStateToProps = (state: RootState): WorkloadListStateProps => ({
workloads: Object.values(state.workloads), workloads: Object.values(state.workloads),
}); });
const mapDispatchToProps = (dispatch: Dispatch<RootAction>) => ({ const mapDispatchToProps = (dispatch: Dispatch<RootAction>): WorkloadListDispatchProps => ({
cancelWorkload: (id: number) => dispatch(cancel({ id })), cancelWorkload: (id: number) => dispatch(cancel({ id })),
}) })

View File

@@ -3,11 +3,10 @@ import ReactDOM from 'react-dom';
import { createStore, applyMiddleware, compose } 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 moment from 'moment';
import { reducer, epics, RootAction, RootState } from './state'; import { reducer, epics, RootAction, RootState } from './state';
import * as WorkloadActions from './state/workloads/actions'; import * as WorkloadActions from './state/workloads/actions';
import "bootstrap/dist/css/bootstrap.min.css"
import './index.css'; import './index.css';
import App from './components/App'; import App from './components/App';
@@ -21,7 +20,7 @@ epicMiddleware.run(epics);
// demo actions // demo actions
store.dispatch(WorkloadActions.submit({ complexity: 10 })); store.dispatch(WorkloadActions.submit({ complexity: 10 }));
// store.dispatch(WorkloadActions.created({ id: 999, complexity: 10, completeDate: moment().add(10, 'second').toDate(), status: 'WORKING' })); store.dispatch(WorkloadActions.created({ id: 999, complexity: 10, completeDate: moment().add(10, 'second').toDate(), status: 'WORKING' }));
ReactDOM.render( ReactDOM.render(

View File

@@ -1,22 +1,18 @@
import { createAction } from 'typesafe-actions'; import { createAction } from 'typesafe-actions';
import { Status } from './types'; import { Status } from './types';
import { SUBMIT, CREATED, CANCEL, FAILED, UPDATE_STATUS } from './constants'; import { SUBMIT, CREATED, CANCEL, UPDATE_STATUS } from './constants';
export const submit = createAction(SUBMIT, resolve => (params: { complexity: number }) => resolve({ complexity: params.complexity })); export const submit = createAction(SUBMIT, resolve => (params: { complexity: number }) => resolve({ complexity: params.complexity }));
export const created = createAction(CREATED, resolve => { export const created = createAction(CREATED, resolve =>
return (params: { id: number, status: Status, complexity: number, completeDate: Date }) => { (params: { id: number, status: Status, complexity: number, completeDate: Date }) => resolve({
return resolve({ id: params.id,
id: params.id, status: params.status,
status: params.status, completeDate: params.completeDate,
completeDate: params.completeDate, complexity: params.complexity,
complexity: params.complexity, }));
})
}
});
export const failed = createAction(FAILED, resolve => (params: { message: string }) => resolve({ message: params.message }));
export const cancel = createAction(CANCEL, resolve => (params: { id: number }) => resolve({ id: params.id })); export const cancel = createAction(CANCEL, resolve => (params: { id: number }) => resolve({ id: params.id }));

View File

@@ -2,4 +2,3 @@ export const SUBMIT = 'workload/SUBMIT';
export const CREATED = 'workload/CREATED'; export const CREATED = 'workload/CREATED';
export const CANCEL = 'workload/CANCEL'; export const CANCEL = 'workload/CANCEL';
export const UPDATE_STATUS = 'workload/UPDATE_STATUS'; export const UPDATE_STATUS = 'workload/UPDATE_STATUS';
export const FAILED = 'workload/FAILED';

View File

@@ -1,44 +1,25 @@
import { from, timer } from 'rxjs';
import { combineEpics, Epic } from 'redux-observable'; import { combineEpics, Epic } from 'redux-observable';
import { filter, map, switchMap, delayWhen } from 'rxjs/operators'; import { filter, map, tap, ignoreElements } from 'rxjs/operators';
import { isActionOf } from 'typesafe-actions'; import { isActionOf } from 'typesafe-actions';
import { RootAction, RootState } from '../reducer'; import { RootAction, RootState } from '../reducer';
import * as workloadsActions from './actions'; import * as workloadsActions from './actions';
import {service} from "../workloads/services";
type AppEpic = Epic<RootAction, RootAction, RootState>; type AppEpic = Epic<RootAction, RootAction, RootState>;
const createWorkload: AppEpic = (action$, state$) => ( const logWorkloadSubmissions: AppEpic = (action$, state$) => (
action$.pipe( action$.pipe(
filter(isActionOf(workloadsActions.submit)), filter(isActionOf(workloadsActions.submit)),
switchMap(action => from(service.create(action.payload))), map(action => action.payload),
map(res => workloadsActions.created(res)), tap((payload) => console.log('Workload submitted', payload)),
ignoreElements(),
) )
); );
const cancelWorkload: AppEpic = (action$, state$) => (
action$.pipe(
filter(isActionOf(workloadsActions.cancel)),
switchMap(action => from(service.cancel(action.payload))),
map(res => workloadsActions.updateStatus(res))
)
);
const updateWorkload: AppEpic = action$ => (
action$.pipe(
filter(isActionOf(workloadsActions.created)),
delayWhen(action => timer(action.payload.complexity * 1000)),
switchMap(action => from(service.checkStatus(action.payload))),
map(res => workloadsActions.updateStatus(res))
)
);
export const epics = combineEpics( export const epics = combineEpics(
createWorkload, logWorkloadSubmissions,
cancelWorkload,
updateWorkload
); );
export default epics; export default epics;

View File

@@ -2,7 +2,8 @@ import moment from 'moment';
import { Status } from './types'; import { Status } from './types';
class WorkloadService {
export class WorkloadService {
private workLoads: { [key in number]: Work } = {}; private workLoads: { [key in number]: Work } = {};
private counter = 0; private counter = 0;
@@ -64,6 +65,3 @@ interface Work {
status: Status; status: Status;
timer: NodeJS.Timeout; timer: NodeJS.Timeout;
} }
const service = new WorkloadService();
export {WorkloadService, service}

17505
yarn.lock Executable file → Normal file

File diff suppressed because it is too large Load Diff