1 Commits

Author SHA1 Message Date
dependabot[bot]
1280129151 Bump tar from 4.4.8 to 4.4.19
Bumps [tar](https://github.com/npm/node-tar) from 4.4.8 to 4.4.19.
- [Release notes](https://github.com/npm/node-tar/releases)
- [Changelog](https://github.com/npm/node-tar/blob/main/CHANGELOG.md)
- [Commits](https://github.com/npm/node-tar/compare/v4.4.8...v4.4.19)

---
updated-dependencies:
- dependency-name: tar
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-09-01 16:07:46 +00:00
13 changed files with 8794 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,
"dependencies": {
"babel-loader": "8.0.4",
"bootstrap": "^5.1.0",
"moment": "^2.24.0",
"react": "^16.7.0",
"react-dom": "^16.7.0",
@@ -12,7 +11,7 @@
"react-scripts": "2.1.3",
"react-timeago": "^4.3.0",
"redux": "^4.0.1",
"redux-observable": "^1.2.0",
"redux-observable": "^1.0.0",
"rxjs": "^6.4.0",
"typesafe-actions": "^3.0.0",
"typescript": "3.2.4"

View File

@@ -1,71 +1 @@
/* .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 {
nowHandler () : number {
return Date.now();
}
render() {
return (
<div className="app-root container mt-5 pt-5 d-flex flex-column">
<h1 className="header">CloudWork</h1>
<div className="d-flex flex-row-reverse mt-5">
<div className="form-container border p-5" style={{flex: 2}}><WorkloadFormContainer /></div>
<div className="list-container" style={{flex: 5}}>
<h2 className="mb-3">Workloads</h2>
<WorkloadListContainer nowHandler={this.nowHandler}/>
</div>
</div>
<div>
<h1>CloudWork</h1>
<hr />
<div >
<WorkloadFormContainer />
</div>
<hr />
<div>
<h2>Workloads</h2>
<WorkloadListContainer />
</div>
</div>
);
}

View File

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

View File

@@ -1,12 +1,8 @@
import React, { useEffect } from 'react';
import React from 'react';
import TimeAgo from 'react-timeago';
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 {
id: number;
complexity: number;
@@ -16,7 +12,6 @@ export interface WorkloadItemStateProps {
export interface WorkloadItemMethodProps {
onCancel: () => void;
nowHandler: () => number;
}
export interface WorkloadItemProps extends
@@ -24,21 +19,19 @@ export interface WorkloadItemProps extends
WorkloadItemMethodProps {}
const WorkloadItem: React.SFC<WorkloadItemProps> = (props) => {
// console.log(props.completeDate)
return <div className="WorkloadItem border p-4 mb-4 d-flex">
<div className="primary-details">
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>
<span className="WorkloadItem-subHeading">Complexity: {props.complexity}</span>
</div>
<div className="d-flex">
<div>
{props.status === 'WORKING'
? (
<>
<span className="my-auto"><TimeAgo date={props.completeDate} now={props.nowHandler} /></span>
<span><TimeAgo date={props.completeDate} /></span>
<button
className="WorkloadItem-secondaryButton ml-3 my-auto"
className="WorkloadItem-secondaryButton"
onClick={props.onCancel}
>
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>
};
);
const mapDispatchToProps = (dispatch: Dispatch<RootAction>) => ({
udpateWorkloadStatus: (id: number, status: Status) => dispatch(updateStatus({ id, status })),
})
const WorkloadItemContainer = connect(null, mapDispatchToProps)(WorkloadItem);
export {
WorkloadItem,
WorkloadItemContainer
};
export default WorkloadItem;

View File

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

View File

@@ -3,11 +3,10 @@ import ReactDOM from 'react-dom';
import { createStore, applyMiddleware, compose } from 'redux';
import { Provider } from 'react-redux';
import { createEpicMiddleware } from 'redux-observable';
// import moment from 'moment';
import moment from 'moment';
import { reducer, epics, RootAction, RootState } from './state';
import * as WorkloadActions from './state/workloads/actions';
import "bootstrap/dist/css/bootstrap.min.css"
import './index.css';
import App from './components/App';
@@ -21,7 +20,7 @@ epicMiddleware.run(epics);
// demo actions
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(

View File

@@ -1,22 +1,18 @@
import { createAction } from 'typesafe-actions';
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 created = createAction(CREATED, resolve => {
return (params: { id: number, status: Status, complexity: number, completeDate: Date }) => {
return resolve({
id: params.id,
status: params.status,
completeDate: params.completeDate,
complexity: params.complexity,
})
}
});
export const failed = createAction(FAILED, resolve => (params: { message: string }) => resolve({ message: params.message }));
export const created = createAction(CREATED, resolve =>
(params: { id: number, status: Status, complexity: number, completeDate: Date }) => resolve({
id: params.id,
status: params.status,
completeDate: params.completeDate,
complexity: params.complexity,
}));
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 CANCEL = 'workload/CANCEL';
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 { filter, map, switchMap, delayWhen } from 'rxjs/operators';
import { filter, map, tap, ignoreElements } from 'rxjs/operators';
import { isActionOf } from 'typesafe-actions';
import { RootAction, RootState } from '../reducer';
import * as workloadsActions from './actions';
import {service} from "../workloads/services";
type AppEpic = Epic<RootAction, RootAction, RootState>;
const createWorkload: AppEpic = (action$, state$) => (
const logWorkloadSubmissions: AppEpic = (action$, state$) => (
action$.pipe(
filter(isActionOf(workloadsActions.submit)),
switchMap(action => from(service.create(action.payload))),
map(res => workloadsActions.created(res)),
map(action => action.payload),
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(
createWorkload,
cancelWorkload,
updateWorkload
logWorkloadSubmissions,
);
export default epics;

View File

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

17517
yarn.lock Executable file → Normal file

File diff suppressed because it is too large Load Diff