Skip to content

Commit

Permalink
Feature/login panel (#225)
Browse files Browse the repository at this point in the history
* build(deps): bump @types/node from 16.11.4 to 16.11.6

Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 16.11.4 to 16.11.6.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

---
updated-dependencies:
- dependency-name: "@types/node"
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

* Fix RemoveZoneCommand

* build(deps): bump @mui/material from 5.0.5 to 5.0.6

Bumps [@mui/material](https://github.com/mui-org/material-ui/tree/HEAD/packages/mui-material) from 5.0.5 to 5.0.6.
- [Release notes](https://github.com/mui-org/material-ui/releases)
- [Changelog](https://github.com/mui-org/material-ui/blob/master/CHANGELOG.md)
- [Commits](https://github.com/mui-org/material-ui/commits/v5.0.6/packages/mui-material)

---
updated-dependencies:
- dependency-name: "@mui/material"
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

* build(deps-dev): bump @types/react from 17.0.32 to 17.0.33

Bumps [@types/react](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/react) from 17.0.32 to 17.0.33.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/react)

---
updated-dependencies:
- dependency-name: "@types/react"
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

* Add simple login panel

* Add start simulation ui in SimulationPanel

* add mocked api request (#204)

* update post req (#204)

* update comment

* update url

* update urls and cors (#204)

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: ostatni5 <26521377+ostatni5@users.noreply.github.com>
  • Loading branch information
3 people authored Nov 1, 2021
1 parent 9fe3b18 commit 057f4c4
Show file tree
Hide file tree
Showing 14 changed files with 238 additions and 29 deletions.
5 changes: 5 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
"@types/signals": "^1.0.1",
"@types/throttle-debounce": "^2.1.0",
"comlink": "^4.3.1",
"ky": "^0.28.6",
"react": "^17.0.2",
"react-async-script": "^1.2.0",
"react-dom": "^17.0.2",
Expand Down
5 changes: 4 additions & 1 deletion src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
import { createTheme } from '@mui/material';
import { ThemeProvider, StyledEngineProvider } from '@mui/material/styles';
import './App.css';
import { Store } from './services/StoreService';
import WrapperApp from './WrapperApp/WrapperApp';

function App() {
const theme = createTheme();
return (
<StyledEngineProvider injectFirst>
<ThemeProvider theme={theme}>
<WrapperApp></WrapperApp>
<Store>
<WrapperApp></WrapperApp>
</Store>
</ThemeProvider>
</StyledEngineProvider>
);
Expand Down
18 changes: 10 additions & 8 deletions src/ThreeEditor/ThreeEditor.tsx
Original file line number Diff line number Diff line change
@@ -1,26 +1,28 @@
import React, { useEffect, useRef, useState } from 'react';
import React, { useEffect, useRef } from 'react';
import './css/main.css';
import { Editor } from './js/Editor';
import { initEditor } from './main';

interface ThreeEditorProps {
onEditorInitialized?: (editor: Editor) => void
}

function ThreeEditor() {
// React.memo(component, ()=>true) to prevent re-rendering and re-initializing editor
const ThreeEditor = React.memo(function ThreeEditorComponent(props: ThreeEditorProps) {
const containerEl = useRef(null);


const [, setEditor] = useState<Editor>();

useEffect(() => {
if (containerEl.current) {

const { editor } = initEditor(containerEl.current);
setEditor(editor);

props.onEditorInitialized?.call(null, editor);

}
return () => {

}
}, [containerEl]);
}, [containerEl, props.onEditorInitialized]);


return (
Expand All @@ -30,6 +32,6 @@ function ThreeEditor() {
flexGrow: 1
}} />
);
}
}, () => true)

export default ThreeEditor;
4 changes: 2 additions & 2 deletions src/ThreeEditor/js/commands/RemoveZoneCommand.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,14 @@ class RemoveZoneCommand extends Command {

execute() {

this.editor.zonesManager.remove( this.zone );
this.editor.zonesManager.removeZone( this.zone );
this.editor.deselect();

}

undo() {

this.editor.zonesManager.add( this.zone );
this.editor.zonesManager.addZone( this.zone );
this.editor.select( this.zone );

}
Expand Down
4 changes: 3 additions & 1 deletion src/ThreeEditor/util/CSG/CSGManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@ interface CSGManagerJSON {
boundingZone: BoundingZoneJSON
}

export class CSGZonesContainer extends THREE.Group{
export class CSGZonesContainer extends THREE.Group implements ISimulationObject {
notRemovable = true;
notMoveable = true;
children: CSGZone[];
readonly isCSGZonesContainer: true = true;
constructor(){
Expand Down
2 changes: 1 addition & 1 deletion src/ThreeEditor/util/CSG/CSGZone.ts
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@ export class CSGZone extends THREE.Mesh {
union.map((operation) => CSGOperation.fromJSON(editor, operation))
);

let subscribedObjectsUuid = undefined;
let subscribedObjectsUuid;

if(Array.isArray(data.subscribedObjectsUuid))
subscribedObjectsUuid = new Set(data.subscribedObjectsUuid)
Expand Down
47 changes: 31 additions & 16 deletions src/WrapperApp/WrapperApp.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
import * as React from 'react';
import Tabs from '@mui/material/Tabs';
import Tab from '@mui/material/Tab';
import React, { SyntheticEvent, useState } from 'react';
import { css } from '@emotion/css';
import Box from '@mui/material/Box';
import { SyntheticEvent, useState } from 'react';
import LoginPanel from './components/LoginPanel';
import Tab from '@mui/material/Tab';
import Tabs from '@mui/material/Tabs';
import ThreeEditor from '../ThreeEditor/ThreeEditor';
import UserData from '../util/user/UserData';
import SimulationPanel from './components/SimulationPanel';
import { useStore } from '../services/StoreService';
import { DEMO_MODE } from '../util/Config';

import { css } from '@emotion/css';

interface TabPanelProps {
children?: React.ReactNode;
Expand Down Expand Up @@ -34,34 +38,45 @@ function TabPanel(props: TabPanelProps) {


function WrapperApp() {
const [value, setValue] = useState(0);
const { editorRef } = useStore();

const [tabsValue, setTabsValue] = useState(0);
const [currentUser, setCurrentUser] = useState<UserData | null>(null);

const handleChange = (event: SyntheticEvent, newValue: number) => {
setValue(newValue);
newValue === 5 && setCurrentUser(null);
setTabsValue(newValue);
};

const demoMode = process.env.REACT_APP_TARGET === 'demo';

return (
<Box sx={{ width: '100%', height: '100vh', display: 'flex', flexDirection: 'column' }}>
<Box sx={{ borderBottom: 1, borderColor: 'divider' }}>
<Tabs value={value} onChange={handleChange} >
<Tabs value={tabsValue} onChange={handleChange} >
<Tab label="Editor" />
<Tab label="Run" disabled={demoMode} />
<Tab label="Run" disabled={DEMO_MODE} />
<Tab label="Results" disabled />
<Tab label="Projects" disabled />
<Tab label="Logout" disabled />
<Tab label="About" />
<Tab sx={{ marginLeft: 'auto' }} label={currentUser ? "Logout" : "Login"} />
</Tabs>
</Box>
<TabPanel value={value} index={0} >
<ThreeEditor></ThreeEditor>
<TabPanel value={tabsValue} index={0} >
<ThreeEditor onEditorInitialized={(editor) => editorRef.current = editor} />
</TabPanel>
{demoMode &&
<TabPanel value={value} index={1}>
Run Simulation
{DEMO_MODE ||
<TabPanel value={tabsValue} index={1}>
<SimulationPanel />
</TabPanel>
}
<TabPanel value={tabsValue} index={5} >
<LoginPanel
handleLogin={(data) => {
setCurrentUser({ uuid: "", login: data.email })
setTabsValue(0);
}}
/>
</TabPanel>
</Box>
);
}
Expand Down
60 changes: 60 additions & 0 deletions src/WrapperApp/components/LoginPanel.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import { Box, Button, TextField } from "@mui/material";
import React from "react";

interface LoginPanelProps {
handleLogin: (data:{email:string,password:string}) => void;
}

export default function LoginPanel(props: LoginPanelProps) {
const [email, setEmail] = React.useState('');
const handleEmailChange = (event: React.ChangeEvent<HTMLInputElement>) => {
setEmail(event.target.value);
};
const [password, setPassword] = React.useState('');
const handlePasswordChange = (event: React.ChangeEvent<HTMLInputElement>) => {
setPassword(event.target.value);
};
return (
<Box sx={{
margin: "0 auto",
display: "flex",
alignItems: "center",
padding: "5rem"
}}>
<Box component="form"
sx={{
margin: "0 auto",
backgroundColor: "rgba(255,255,255,.6)",
display: "flex",
flexDirection: "column",
gap: "1.5rem",
padding: "5rem"
}}
>
<TextField
id="loginField"
label="Email adress"
variant="outlined"
value={email}
onChange={handleEmailChange}
/>
<TextField
id="passwordField"
label="Password"
variant="outlined"
type="password"
value={password}
onChange={handlePasswordChange}
/>
<Button
variant="outlined"
onClick={()=>{
setPassword('')
setEmail('')
props.handleLogin({email,password})
}}
>Login</Button>
</Box>
</Box>
)
}
63 changes: 63 additions & 0 deletions src/WrapperApp/components/SimulationPanel.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import { Box, Button, LinearProgress } from '@mui/material';
import ky from 'ky';

import React, { useState } from "react";
import { useStore } from '../../services/StoreService';
import { BACKEND_URL, CORS } from '../../util/Config';

interface SimulationPanelProps {
onError?: (error: unknown) => void;
onSuccess?: (result: unknown) => void;
}

export default function SimulationPanel(props: SimulationPanelProps) {
const { editorRef } = useStore();
const [isInProgress, setInProgress] = useState<boolean>(false);

const sendRequest = () => {
setInProgress(true);
ky.post(`${BACKEND_URL}/sh/demo`, {
mode: CORS ? 'cors' : 'no-cors',
json: editorRef.current?.toJSON()
})
.json()
.then((response) => {
alert(response);
props.onSuccess?.call(null, response);
})
.catch((error) => {
alert(error);
props.onError?.call(null, error);
}).finally(() => {
setInProgress(false);
});
};

return (
<Box sx={{
margin: "0 auto",
width: "min(960px, 100%)",
padding: "5rem",
display: "flex",
flexDirection: "column",
gap: "1.5rem",
}}>
<LinearProgress
variant={
isInProgress ? 'indeterminate' : 'determinate'
}
value={0}
/>
<Button
sx={{
width: "min(300px, 100%)",
margin: "0 auto",
}}
onClick={sendRequest}

>
{isInProgress ? 'Stop' : 'Start'}
</Button>
</Box>
);
}
34 changes: 34 additions & 0 deletions src/services/StoreService.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { ReactNode, useRef } from "react";
import { Editor } from "../ThreeEditor/js/Editor";
import { createGenericContext } from "../util/GenericContext";



export interface StoreProps {
children: ReactNode
}

export interface IStore {
editorRef: React.MutableRefObject<Editor | undefined>
}

const [useStore, StoreContextProvider] = createGenericContext<IStore>();

const Store = (props: StoreProps) => {
const editorRef = useRef<Editor>();

const value: IStore = {
editorRef
}

return (
<StoreContextProvider value={value}>
{props.children}
</StoreContextProvider>
)
};

export {
useStore,
Store
}
3 changes: 3 additions & 0 deletions src/util/Config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export const BACKEND_URL = process.env.REACT_APP_BACKEND_URL ?? 'http://localhost:5000';
export const CORS = false;
export const DEMO_MODE = process.env.REACT_APP_TARGET === 'demo';
17 changes: 17 additions & 0 deletions src/util/GenericContext.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import React from "react";

export const createGenericContext = <T extends unknown>() => {
// Create a context with a generic parameter or undefined
const genericContext = React.createContext<T | undefined>(undefined);

// Check if the value provided to the context is defined or throw an error
const useGenericContext = () => {
const contextIsDefined = React.useContext(genericContext);
if (!contextIsDefined) {
throw new Error("useGenericContext must be used within a Provider");
}
return contextIsDefined;
};

return [useGenericContext, genericContext.Provider] as const;
};
4 changes: 4 additions & 0 deletions src/util/user/UserData.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export default interface UserData{
uuid: string,
login: string,
}

0 comments on commit 057f4c4

Please sign in to comment.