diff --git a/gates/webapp.js b/gates/webapp.js index 6d07560..d275eac 100644 --- a/gates/webapp.js +++ b/gates/webapp.js @@ -20,9 +20,9 @@ expressApp.use( expressApp.use(cors()); expressApp.options(cors()); expressApp.use(express.static(publicPath)); -expressApp.get('*',(req,res) => { - res.sendFile(path.join(publicPath, 'index.html')) -}); +// expressApp.get('*',(req,res) => { +// res.sendFile(path.join(publicPath, 'index.html')) +// }); expressApp.use(bodyParser.json()); diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..ab4ff72 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,6 @@ +{ + "compilerOptions": { + "experimentalDecorators": true, + "allowJs": true + } +} \ No newline at end of file diff --git a/ui/config-overrides.js b/ui/config-overrides.js new file mode 100644 index 0000000..35c227e --- /dev/null +++ b/ui/config-overrides.js @@ -0,0 +1,5 @@ +/** @format */ + +const {override, addDecoratorsLegacy, disableEsLint} = require('customize-cra'); + +module.exports = override(addDecoratorsLegacy(), disableEsLint()); diff --git a/ui/package-lock.json b/ui/package-lock.json index c1cd622..5516b96 100644 --- a/ui/package-lock.json +++ b/ui/package-lock.json @@ -275,6 +275,18 @@ "@babel/plugin-syntax-class-properties": "^7.0.0" } }, + "@babel/plugin-proposal-decorators": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.1.2.tgz", + "integrity": "sha512-YooynBO6PmBgHvAd0fl5e5Tq/a0pEC6RqF62ouafme8FzdIVH41Mz/u1dn8fFVm4jzEJ+g/MsOxouwybJPuP8Q==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-replace-supers": "^7.1.0", + "@babel/helper-split-export-declaration": "^7.0.0", + "@babel/plugin-syntax-decorators": "^7.1.0" + } + }, "@babel/plugin-proposal-json-strings": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.0.0.tgz", @@ -328,6 +340,15 @@ "@babel/helper-plugin-utils": "^7.0.0" } }, + "@babel/plugin-syntax-decorators": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.1.0.tgz", + "integrity": "sha512-uQvRSbgQ0nQg3jsmIixXXDCgSpkBolJ9X7NYThMKCcjvE8dN2uWJUzTUNNAeuKOjARTd+wUQV0ztXpgunZYKzQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, "@babel/plugin-syntax-dynamic-import": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.0.0.tgz", @@ -3394,6 +3415,16 @@ "cssom": "0.3.x" } }, + "customize-cra": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/customize-cra/-/customize-cra-0.1.1.tgz", + "integrity": "sha512-Te22FctWJbpkxZDkGxonvjwAO5kvE0dyHik39IrJYk3tTL9wE+y3bo0uhYhh3MS03Soap76fZ5AEs8mkn85WOg==", + "dev": true, + "requires": { + "lodash.curry": "^4.1.1", + "lodash.flow": "^3.5.0" + } + }, "cyclist": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-0.2.2.tgz", @@ -7714,11 +7745,23 @@ "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", "integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY=" }, + "lodash.curry": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.curry/-/lodash.curry-4.1.1.tgz", + "integrity": "sha1-JI42By7ekGUB11lmIAqG2riyMXA=", + "dev": true + }, "lodash.debounce": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168=" }, + "lodash.flow": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/lodash.flow/-/lodash.flow-3.5.0.tgz", + "integrity": "sha1-h79AKSuM+D5OjOGjrkIJ4gBxZ1o=", + "dev": true + }, "lodash.memoize": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", @@ -11466,6 +11509,35 @@ "whatwg-fetch": "3.0.0" } }, + "react-app-rewired": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/react-app-rewired/-/react-app-rewired-1.6.2.tgz", + "integrity": "sha512-TxbP1W9jPPTmj0YJeFNgcJc6IMg7sv845aHUIUvVQtXdA8IWzOZairk3Bth6GHbxoF2QitbvUlM7/NAH4VmmJg==", + "dev": true, + "requires": { + "cross-spawn": "^5.1.0", + "dotenv": "^4.0.0" + }, + "dependencies": { + "cross-spawn": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", + "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", + "dev": true, + "requires": { + "lru-cache": "^4.0.1", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "dotenv": { + "version": "4.0.0", + "resolved": "http://registry.npmjs.org/dotenv/-/dotenv-4.0.0.tgz", + "integrity": "sha1-hk7xN5rO1Vzm+V3r7NzhefegzR0=", + "dev": true + } + } + }, "react-bootstrap": { "version": "1.0.0-beta.1", "resolved": "https://registry.npmjs.org/react-bootstrap/-/react-bootstrap-1.0.0-beta.1.tgz", diff --git a/ui/package.json b/ui/package.json index a2bb445..437078c 100644 --- a/ui/package.json +++ b/ui/package.json @@ -1,5 +1,5 @@ { - "name": "client", + "name": "chaos_monkey", "version": "1.0.0", "private": true, "dependencies": { @@ -16,10 +16,10 @@ "socket.io-client": "^2.1.1" }, "scripts": { - "start": "react-scripts start", - "build": "react-scripts build", - "test": "react-scripts test", - "eject": "react-scripts eject" + "start": "react-app-rewired start", + "build": "react-app-rewired build", + "test": "react-app-rewired test", + "eject": "react-app-rewired eject" }, "eslintConfig": { "extends": "react-app" @@ -29,5 +29,10 @@ "not dead", "not ie <= 11", "not op_mini all" - ] + ], + "devDependencies": { + "@babel/plugin-proposal-decorators": "^7.1.2", + "customize-cra": "^0.1.1", + "react-app-rewired": "^1.6.2" + } } diff --git a/ui/src/App.css b/ui/src/App.css index eddf720..d2fb163 100644 --- a/ui/src/App.css +++ b/ui/src/App.css @@ -1,4 +1,8 @@ .app_logo { height: 30px; margin:0 8px; +} + +.button_fixed { + position: fixed; } \ No newline at end of file diff --git a/ui/src/components/CreatePrank/CreatePlankList.jsx b/ui/src/components/CreatePrank/CreatePlankList.jsx index d016b74..18dc261 100644 --- a/ui/src/components/CreatePrank/CreatePlankList.jsx +++ b/ui/src/components/CreatePrank/CreatePlankList.jsx @@ -1,53 +1,37 @@ /** @format */ -import React, {Fragment} from 'react'; +import React from 'react'; +import {observer} from 'mobx-react'; // Styles import Col from 'react-bootstrap/lib/Col'; import Row from 'react-bootstrap/lib/Row'; import ListGroup from 'react-bootstrap/lib/ListGroup'; -import Dropdown from 'react-bootstrap/lib/Dropdown'; -import DropdownButton from 'react-bootstrap/lib/DropdownButton'; -const CreatePlankList = ({items, listName, howLong}) => { +const CreatePlankList = observer(({items, listName, onClick}) => { return ( - - - -
{listName}
- - - - {items.map(item => ( - - {item} - - ))} - - More... - - - -
- {howLong && ( - - New Line - - + +
{listName}
+ + + + {items.map((item, idx) => ( + onClick(item)} > - 5 sec - 10 sec - 30 sec - 1 min -
- -
- )} -
+ {item.name} + + ))} + + More... + + + + ); -}; +}); export default CreatePlankList; diff --git a/ui/src/components/CreatePrank/CreatePrank.jsx b/ui/src/components/CreatePrank/CreatePrank.jsx index e42593b..50d7d65 100644 --- a/ui/src/components/CreatePrank/CreatePrank.jsx +++ b/ui/src/components/CreatePrank/CreatePrank.jsx @@ -1,47 +1,70 @@ /** @format */ import React, {Component} from 'react'; +import {inject, observer} from 'mobx-react'; import CreatePlankList from './CreatePlankList'; +import DurationDropdown from './DurationDropdown'; // Styles -// import Button from 'react-bootstrap/lib/Button'; import Col from 'react-bootstrap/lib/Col'; import Row from 'react-bootstrap/lib/Row'; import Button from 'react-bootstrap/lib/Button'; +@inject('store') +@observer class CreatePrank extends Component { state = { - selectedItem: '', - items: [ - 'Random with surprises', - 'Exhausted hardware', - 'Error handling benchmark', - 'Slow and comprhensive', + selectedPrank: '', + pranks: [ + {name: 'Random with surprises'}, + {name: 'Exhausted hardware'}, + {name: 'Error handling benchmark'}, + {name: 'Slow and comprhensive'}, ], }; + componentDidMount() { + this.props.store.getSinglePranksList(); + } + + createPrank = prank => { + this.props.store.addPrank(prank); + }; render() { + const {singlePranks} = this.props.store; + console.log('Selected Prank', this.state.selectedPrank.name); return ( - +

Create Plank

+ - OR - -
+ + OR + + +
- + this.setState({selectedPrank: prank})} + /> - + diff --git a/ui/src/components/CreatePrank/DurationDropdown.jsx b/ui/src/components/CreatePrank/DurationDropdown.jsx new file mode 100644 index 0000000..4a29127 --- /dev/null +++ b/ui/src/components/CreatePrank/DurationDropdown.jsx @@ -0,0 +1,31 @@ +/** @format */ + +import React from 'react'; + +// Styles +import Col from 'react-bootstrap/lib/Col'; +import Row from 'react-bootstrap/lib/Row'; +import Dropdown from 'react-bootstrap/lib/Dropdown'; +import DropdownButton from 'react-bootstrap/lib/DropdownButton'; + +const DurationDropdown = () => { + return ( + + How long + + + 5 sec + 10 sec + 30 sec + 1 min + + + + ); +}; + +export default DurationDropdown; diff --git a/ui/src/components/Dashboard.jsx b/ui/src/components/Dashboard.jsx index 2f191f2..1d3988d 100644 --- a/ui/src/components/Dashboard.jsx +++ b/ui/src/components/Dashboard.jsx @@ -9,11 +9,11 @@ import Menu from './Menu'; import Container from 'react-bootstrap/lib/Container'; import Row from 'react-bootstrap/lib/Row'; -const Dashboard = ({children, ...rest}) => { +const Dashboard = ({children, name}) => { return ( -
+
diff --git a/ui/src/components/Header.jsx b/ui/src/components/Header.jsx index 3751228..da2cda5 100644 --- a/ui/src/components/Header.jsx +++ b/ui/src/components/Header.jsx @@ -7,13 +7,14 @@ import Breadcrumb from 'react-bootstrap/lib/Breadcrumb'; import Col from 'react-bootstrap/lib/Col'; import monkeyLogo from '../assets/chaos-monkey.png'; -const Header = () => { +const Header = props => { + console.log(props); return ( - Chaos Monkey + Chaos Monkey Chaos control - Create prank + {props.name} ); diff --git a/ui/src/components/PranksLog/PranksLog.jsx b/ui/src/components/PranksLog/PranksLog.jsx index 07559c3..05eb7c3 100644 --- a/ui/src/components/PranksLog/PranksLog.jsx +++ b/ui/src/components/PranksLog/PranksLog.jsx @@ -1,7 +1,7 @@ /** @format */ import React, {Component} from 'react'; -import io from 'socket.io-client'; +import {inject, observer} from 'mobx-react'; import PranksLogList from './PranksLogList'; import PrankScore from './PrankScore'; @@ -9,37 +9,20 @@ import PrankScore from './PrankScore'; // Styles import Col from 'react-bootstrap/lib/Col'; import Row from 'react-bootstrap/lib/Row'; -import Button from 'react-bootstrap/lib/Button'; - -const socket = io('http://localhost:8081'); +@inject('store') +@observer class PranksLog extends Component { - state = { - items: [], - }; - componentDidMount() { - socket.connect(); - console.log('Socket Connected', 'Will auto DC in 30sec'); - socket.on('new-prank-activity', data => { - if (data) { - this.setState({items: [...this.state.items, data]}); - } else { - console.log(`A new prank just ran ${JSON.stringify(data)}`); - } - }); - setTimeout(() => { - socket.disconnect(); - console.log('Socket AUTO Disconnected'); - }, 30000); + this.props.store.getPranksLog(); + } + + componentWillUnmount() { + this.props.store.disconnect(); } - dc = () => { - socket.disconnect(); - console.log('Socket Disconnected !'); - }; render() { - const {items} = this.state; + const {pranksLog, crazyScore} = this.props.store; return ( @@ -47,17 +30,9 @@ class PranksLog extends Component {

Pranks log

- - - -
- - -
after loading too much items press the RED button
- + +
); diff --git a/ui/src/components/PranksLog/PranksLogList.jsx b/ui/src/components/PranksLog/PranksLogList.jsx index a39f263..2b8c7bd 100644 --- a/ui/src/components/PranksLog/PranksLogList.jsx +++ b/ui/src/components/PranksLog/PranksLogList.jsx @@ -2,6 +2,7 @@ import React, {Fragment} from 'react'; import moment from 'moment'; +import {observer} from 'mobx-react'; // Styles import Badge from 'react-bootstrap/lib/Badge'; @@ -9,7 +10,7 @@ import Card from 'react-bootstrap/lib/Card'; import Col from 'react-bootstrap/lib/Col'; import Row from 'react-bootstrap/lib/Row'; -const PranksLogList = ({items}) => { +const PranksLogList = observer(({items}) => { return ( {items && @@ -48,6 +49,6 @@ const PranksLogList = ({items}) => { )} ); -}; +}); export default PranksLogList; diff --git a/ui/src/index.js b/ui/src/index.js index 1317768..2a30a4a 100644 --- a/ui/src/index.js +++ b/ui/src/index.js @@ -2,12 +2,20 @@ import React from 'react'; import ReactDOM from 'react-dom'; +import {Provider} from 'mobx-react'; + +import store from './stores/prankStore'; import 'bootstrap/dist/css/bootstrap.min.css'; import App from './App.jsx'; import * as serviceWorker from './serviceWorker'; import './index.css'; -ReactDOM.render(, document.getElementById('root')); +ReactDOM.render( + + + , + document.getElementById('root') +); // If you want your app to work offline and load faster, you can change // unregister() to register() below. Note this comes with some pitfalls. diff --git a/ui/src/router/AppRouter.jsx b/ui/src/router/AppRouter.jsx index 7563b88..42f7233 100644 --- a/ui/src/router/AppRouter.jsx +++ b/ui/src/router/AppRouter.jsx @@ -10,11 +10,15 @@ import RouteContainer from './RouteContainer'; export const history = createHistory(); -const AppRouter = () => ( +const AppRouter = props => ( - - + + ); diff --git a/ui/src/router/RouteContainer.jsx b/ui/src/router/RouteContainer.jsx index fb796a2..d5894cc 100644 --- a/ui/src/router/RouteContainer.jsx +++ b/ui/src/router/RouteContainer.jsx @@ -9,11 +9,11 @@ const RouteContainer = ({component: Component, ...rest}) => ( ( - + )} /> ); -export default RouteContainer; \ No newline at end of file +export default RouteContainer; diff --git a/ui/src/stores/prankStore.js b/ui/src/stores/prankStore.js new file mode 100644 index 0000000..30ff392 --- /dev/null +++ b/ui/src/stores/prankStore.js @@ -0,0 +1,67 @@ +/** @format */ + +import {action, observable, computed} from 'mobx'; +import axios from 'axios'; +import io from 'socket.io-client'; + +const socket = io('http://localhost:8081'); + +class PrankStore { + @observable + singlePranks = []; + @observable + pranksLog = []; + + @computed + get crazyScore() { + let score = 0; + score = + score + + Math.floor( + this.pranksLog.length * Math.floor(Math.random() * Math.floor(10)) + ); + return score; + } + @action.bound + async getSinglePranksList() { + try { + const res = await axios.get('http://localhost:8081/chaos/pranks-pool'); + this.singlePranks = res.data; + console.log(res.data); + } catch (e) { + console.log('Error getting pranks list', e); + } + } + + @action.bound + getPranksLog() { + socket.connect(); + console.log('Socket Connected'); + socket.on('new-prank-activity', data => { + if (data) { + console.log(data); + this.pranksLog.push(data); + } else { + console.log(`A new prank just ran ${JSON.stringify(data)}`); + } + }); + } + + @action.bound + disconnect() { + socket.disconnect(); + console.log('Socket Disconnected'); + } + @action.bound + async addPrank(prank) { + try { + await axios.post('http://localhost:8081/chaos/pranks-activity', prank); + console.log('Prank Added Successfully'); + } catch (e) { + console.log('Error Adding Prank', e); + } + } +} + +const store = new PrankStore(); +export default store; diff --git a/ui/src/stores/pranksStore.jsx b/ui/src/stores/pranksStore.jsx deleted file mode 100644 index e69de29..0000000