diff --git a/dashboard/src/App.css b/dashboard/src/App.css index 67272f0ec3986d02318370cb259d8e1ac607be79..44d23ae287ce1759554e67179d79bb4a22afdabe 100644 --- a/dashboard/src/App.css +++ b/dashboard/src/App.css @@ -26,7 +26,10 @@ } .CurrentAst { + height: 50vh; width: 100vw; + object-fit: cover; + object-position: right; } .AstInTimeline { diff --git a/dashboard/src/App.js b/dashboard/src/App.js index 91ddd6d898cfa1e03b8bf130d943d03f6d1e4714..3e87ab085f82cd97d177b65b5fdf60c6f80f1452 100644 --- a/dashboard/src/App.js +++ b/dashboard/src/App.js @@ -1,17 +1,16 @@ import './App.css'; import React, { useEffect, useRef } from 'react'; import './index.css'; -import { VerticalTimeline, VerticalTimelineElement } from 'react-vertical-timeline-component'; import 'react-vertical-timeline-component/style.min.css'; -import { GiFamilyTree } from "react-icons/gi"; import { useSelector, useDispatch } from 'react-redux' -import { addAst, setAstList } from './mgSlice' +import { setAst, setContext } from './mgSlice' function App() { const ws = useRef(null); const dispatch = useDispatch(); - const asts = useSelector(state => state.mg.asts); + const ast = useSelector(state => state.mg.ast); + const context = useSelector(state => state.mg.context); useEffect(() => { ws.current = new WebSocket("ws://localhost:7070/ast-events"); @@ -20,8 +19,10 @@ function App() { ws.current.onmessage = (event) => { const json = JSON.parse(event.data); try { - if ((json.event = "data")) { - dispatch(addAst(json)); + if (json.type === "ast") { + dispatch(setAst(json)); + } else if (json.type === "context") { + dispatch(setContext(json)); } } catch (err) { console.log(err); @@ -36,51 +37,47 @@ function App() { }, [dispatch]); useEffect(() => { - if (asts.length === 0) { - fetch('http://localhost:7070/asts/') + if (ast.diagram == null) { + console.log("setting ast from WS 1"); + fetch('http://localhost:7070/ast/') .then(res => res.json()) - .then((asts) => { - dispatch(setAstList(asts)) + .then((ast) => { + console.log("setting ast from WS"); + console.log(ast); + dispatch(setAst(ast)) }) .catch(console.log) } - }, [dispatch, asts.length]) + if (context.diagram == null) { + console.log("setting ctx from WS"); + fetch('http://localhost:7070/context/') + .then(res => res.json()) + .then((context) => { + dispatch(setContext(context)) + }) + .catch(console.log) + } else { + console.log(context) + } + }, [dispatch, ast, context]) return ( <div className="App"> <header className="App-header"> - <ControlPanel /> + <ControlPanel + ws={ws} + /> </header> <main> <CurrentState - diagram={asts[0] ? asts[0].diagram : ''} - label={asts[0] ? asts[0].parseRule : ''} + diagram={context ? context.diagram : ''} + label='' + /> + <CurrentState + diagram={ast ? ast.diagram : ''} + label={ast ? ast.parseRule : ''} /> - <VerticalTimeline - className='MG-Timeline'> - {asts.map(v => { - console.log(v.parseRule) - return ( - <VerticalTimelineElement - className="ast-timeline-event" - contentStyle={{ background: 'rgb(33, 150, 243)', color: '#fff' }} - contentArrowStyle={{ borderRight: '7px solid rgb(33, 150, 243)' }} - date={new Date(v.timestamp).toLocaleTimeString('en-us', { hour12: false })} - iconStyle={{ background: 'rgb(33, 150, 243)', color: '#fff', rotate: '180deg' }} - icon={<GiFamilyTree />} - key={v.timestamp} - position={'right'} - > - <h3 className="vertical-timeline-element-title">{v.parseRule}()</h3> - <p> - <img className="AstInTimeline" src={`data:image/svg+xml;utf8,${encodeURIComponent(v.diagram)}`} alt={v.parseRule} /> - </p> - </VerticalTimelineElement> - - ) - })} - </VerticalTimeline> </main> </div> ); @@ -94,14 +91,13 @@ function CurrentState(props) { ) } -class ControlPanel extends React.Component { - render() { - return ( - <div className='ControlPanel'> - <button onClick={() => { alert('You clicked me!'); }}>connect</button> - </div> - ); - } +function ControlPanel(props) { + return ( + <div className='ControlPanel'> + <button onClick={() => { props.ws.current.send("parse") }}>start parsing</button> + <button onClick={() => { props.ws.current.send("reset") }}>reset selections</button> + </div> + ) } export default App; diff --git a/dashboard/src/mgSlice.js b/dashboard/src/mgSlice.js index fbbef70f4c436f8f90d0ecf4d63b996cd69c4d6f..a820fc6fb724af10f2ae71ba2473331b28c6e272 100644 --- a/dashboard/src/mgSlice.js +++ b/dashboard/src/mgSlice.js @@ -1,23 +1,23 @@ -import { createSlice } from '@reduxjs/toolkit' +import {createSlice} from '@reduxjs/toolkit' export const mgSlice = createSlice({ - name: 'mg', - initialState: { - asts: [], - contexts: {}, - }, - reducers: { - addAst: (state, action) => { - state.asts = [action.payload, ...state.asts]; - console.log("added ast, size is " + state.asts.length); + name: 'mg', + initialState: { + ast: {}, + context: {}, }, - setAstList: (state, action) => { - state.asts = action.payload.reverse(); - console.log("set AST list, size is " + state.asts.length); + reducers: { + setAst: (state, action) => { + state.ast = action.payload; + console.log("set AST"); + }, + setContext: (state, action) => { + state.context = action.payload; + console.log("set context"); + } } - } }) -export const { addAst, setAstList } = mgSlice.actions +export const {setAst, setContext} = mgSlice.actions export default mgSlice.reducer \ No newline at end of file