split out react UI

This commit is contained in:
Michael Mainguy 2024-02-06 15:11:29 -06:00
parent 74603cba65
commit 618c0013ee
9 changed files with 246 additions and 368 deletions

View File

@ -3,165 +3,11 @@
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta content="width=device-width, initial-scale=1" name="viewport"/> <meta content="width=device-width, initial-scale=1" name="viewport"/>
<link href="/styles.css" rel="stylesheet">
<link href="/assets/favicon-32x32.png" rel="icon" sizes="32x32" type="image/png"> <link href="/assets/favicon-32x32.png" rel="icon" sizes="32x32" type="image/png">
<link href="/assets/favicon-16x16.png" rel="icon" sizes="16x16" type="image/png"> <link href="/assets/favicon-16x16.png" rel="icon" sizes="16x16" type="image/png">
<link href="/assets/favicon-96x96.png" rel="icon" sizes="96x96" type="image/png"> <link href="/assets/favicon-96x96.png" rel="icon" sizes="96x96" type="image/png">
<title>Deep Diagram</title> <title>Deep Diagram</title>
<style>
body {
width: 100vw;
height: 100vh;
margin: 0px;
padding: 0px;
aspect-ratio: auto;
font-family: Roboto, sans-serif;
font-size: large;
color: #4444ee;
}
.scene {
width: 100vw;
height: 100vh;
overflow: hidden;
}
#gameCanvas {
width: 100%;
height: 100%;
margin: 0px;
padding: 0px;
background: transparent;
}
div.overlay {
position: absolute;
background: #000;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
z-index: 12;
width: 320px;
height: 300px;
}
div.overlay div {
background-color: #000000;
color: #FFD700;
padding: 15px 25px;
text-align: center;
text-decoration: none;
cursor: pointer;
border: none;
}
div.overlay div a {
display: inline-block;
text-decoration: none;
border-color: #FFD700;
border-style: solid;
border-width: 1px;
padding: 10px;
width: 200px;
}
div.overlay div a:visited, div.overlay div a:link {
color: white;
}
div.overlay div a:hover {
background-color: #FFD700;
color: #000000;
}
div.overlay div a {
}
div.overlay input {
display: inline-block;
margin: 10px auto;
text-decoration: none;
border-color: #FFD700;
border-style: solid;
border-width: 1px;
padding: 10px;
width: 200px;
}
div#create {
left: 50%;
top: 60%;
transform: translate(-50%, -50%);
z-index: 12;
width: 320px;
height: 344px;
border: 3px inset #FFD700;
display: none;
}
div.overlay div a.cancel {
font-size: small;
font-weight: lighter;
font-style: italic;
background-color: #222211;
color: #EEC755;
}
div.overlay div a.cancel:hover {
background-color: #EEC700;
color: #000000;
}
#download {
display: none;
}
#main.mini {
left: 100px;
top: 200px;
width: 160px;
}
#main.mini img, #tutorial img {
width: 160px;
height: 60px;
}
#main.mini div a, #tutorial div a {
width: 80px;
}
#tutorial h1 {
font-size: x-large;
font-weight: bolder;
text-align: center;
color: #F9F9E9;
}
#tutorial {
z-index: 15;
left: 100px;
top: 560px;
width: 160px;
height: 210px;
}
#closekey, #closekey a:active, #closekey a:visited, #closekey a:link {
position: relative;
color: #ffffff;
}
#loadingGrid {
z-index: -1;
width: 100%;
height: 100%;
}
</style>
<link as="script" href="/newRelic.js" rel="preload"> <link as="script" href="/newRelic.js" rel="preload">
<script src="/newRelic.js"></script> <script src="/newRelic.js"></script>
<meta content="width=device-width, initial-scale=1, height=device-height" name="viewport"> <meta content="width=device-width, initial-scale=1, height=device-height" name="viewport">

188
public/styles.css Normal file
View File

@ -0,0 +1,188 @@
body {
width: 100vw;
height: 100vh;
margin: 0px;
padding: 0px;
aspect-ratio: auto;
font-family: Roboto, sans-serif;
font-size: large;
color: #4444ee;
}
.scene {
width: 100vw;
height: 100vh;
overflow: hidden;
}
#gameCanvas {
width: 100%;
height: 100%;
margin: 0px;
padding: 0px;
background: transparent;
}
div.overlay {
position: absolute;
background: #000;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
z-index: 12;
width: 320px;
height: 120px;
}
div.overlay div {
background-color: #000000;
color: #FFD700;
padding: 15px 25px;
text-align: center;
text-decoration: none;
cursor: pointer;
border: none;
}
div.overlay div a {
display: inline-block;
text-decoration: none;
border-color: #FFD700;
border-style: solid;
border-width: 1px;
padding: 10px;
width: 200px;
}
div.overlay div a:visited, div.overlay div a:link {
color: white;
}
div.overlay div a:hover {
background-color: #FFD700;
color: #000000;
}
div.overlay div a {
}
div.overlay input {
display: inline-block;
margin: 10px auto;
text-decoration: none;
border-color: #FFD700;
border-style: solid;
border-width: 1px;
padding: 10px;
width: 200px;
}
div#create {
left: 600px;
top: 400px;
transform: translate(-50%, -50%);
z-index: 14;
width: 320px;
height: 344px;
border: 3px inset #FFD700;
display: none;
}
div.overlay div a.cancel {
font-size: small;
font-weight: lighter;
font-style: italic;
background-color: #222211;
color: #EEC755;
}
#diagramListContent ul {
list-style-type: none;
text-align: left;
padding: 0;
padding-inline-start: 0;
}
#diagramList {
overflow: scroll;
}
#diagramList > h1 {
width: 100%;
text-align: center;
}
#diagramListContent li {
margin: 12px;
}
#diagramListContent li a {
width: 90%;
}
div.overlay div a.cancel:hover {
background-color: #EEC700;
color: #000000;
}
#main.mini {
left: 100px;
top: 200px;
width: 160px;
}
#main.mini img, #tutorial img {
width: 160px;
height: 60px;
}
#main.mini div a, #tutorial div a {
width: 80px;
}
h1 {
font-size: x-large;
font-weight: bolder;
text-align: center;
color: #F9F9E9;
}
#tutorial {
z-index: 15;
left: 100px;
top: 560px;
width: 160px;
height: 210px;
}
#diagramList {
left: 340px;
top: 240px;
height: 300px;
}
#create {
left: 500px;
top: 340px;
}
#closekey, #closekey a:active, #closekey a:visited, #closekey a:link {
position: relative;
color: #ffffff;
}
#enterXR {
display: none;
}
#loadingGrid {
z-index: -1;
width: 100%;
height: 100%;
}

View File

@ -11,11 +11,9 @@ import {
import {ControllerEventType, Controllers} from "./controllers"; import {ControllerEventType, Controllers} from "./controllers";
import log from "loglevel"; import log from "loglevel";
import {DiagramManager} from "../diagram/diagramManager"; import {DiagramManager} from "../diagram/diagramManager";
import {DiagramListingMenu} from "../menus/diagramListingMenu";
import {RoundButton} from "../objects/roundButton"; import {RoundButton} from "../objects/roundButton";
export class Right extends Base { export class Right extends Base {
private listingMenu: DiagramListingMenu;
private startPosition: Vector3 = null; private startPosition: Vector3 = null;
@ -42,7 +40,6 @@ export class Right extends Base {
controllers: Controllers, controllers: Controllers,
) { ) {
super(controller, scene, xr, controllers, diagramManager); super(controller, scene, xr, controllers, diagramManager);
this.listingMenu = new DiagramListingMenu(this.scene, xr, this.controllers, diagramManager);
this.controller.onMotionControllerInitObservable.add((init) => { this.controller.onMotionControllerInitObservable.add((init) => {
this.initTrigger(init.components['xr-standard-trigger']); this.initTrigger(init.components['xr-standard-trigger']);
if (init.components['a-button']) { if (init.components['a-button']) {

View File

@ -14,12 +14,11 @@ import {toDiagramEntity} from "./functions/toDiagramEntity";
import {v4 as uuidv4} from 'uuid'; import {v4 as uuidv4} from 'uuid';
import {buildEntityActionManager} from "./functions/buildEntityActionManager"; import {buildEntityActionManager} from "./functions/buildEntityActionManager";
import {isDiagramEntity} from "./functions/isDiagramEntity"; import {isDiagramEntity} from "./functions/isDiagramEntity";
import {DiagramListingEvent} from "./types/diagramListing";
export class DiagramManager { export class DiagramManager {
public readonly onDiagramEventObservable: Observable<DiagramEvent> = new Observable(); public readonly onDiagramEventObservable: Observable<DiagramEvent> = new Observable();
public readonly onDiagramEventListingObservable: Observable<DiagramListingEvent> = new Observable();
private readonly logger = log.getLogger('DiagramManager'); private readonly logger = log.getLogger('DiagramManager');
private readonly toolbox: Toolbox; private readonly toolbox: Toolbox;
private readonly scene: Scene; private readonly scene: Scene;
@ -68,12 +67,6 @@ export class DiagramManager {
}); });
} }
//@TODO Refactor
/*public setPersistenceManager(persistenceManager: IPersistenceManager) {
this.persistenceManager = persistenceManager;
this._config = new AppConfig(persistenceManager);
this.persistenceManager.updateObserver.add(this.onRemoteEvent, -1, true, this);
}*/
public createCopy(mesh: AbstractMesh, copy: boolean = false): AbstractMesh { public createCopy(mesh: AbstractMesh, copy: boolean = false): AbstractMesh {
let newMesh; let newMesh;
if (!mesh.isAnInstance) { if (!mesh.isAnInstance) {
@ -97,13 +90,6 @@ export class DiagramManager {
if (this.config.current?.physicsEnabled) { if (this.config.current?.physicsEnabled) {
applyPhysics(this.sounds, newMesh, this.scene); applyPhysics(this.sounds, newMesh, this.scene);
} }
//@TODO Refactor
/*this.onDiagramEventObservable.notifyObservers({
type: DiagramEventType.ADD,
entity: toDiagramEntity(newMesh)
}, 2);*/
//this.persistenceManager.add(toDiagramEntity(newMesh));
return newMesh; return newMesh;
} }

View File

@ -1,18 +0,0 @@
export enum DiagramListingEventType {
GET,
ADD,
REMOVE,
MODIFY,
GETALL,
}
export type DiagramListingEvent = {
type: DiagramListingEventType;
listing?: DiagramListing;
}
export type DiagramListing = {
id: string;
name: string;
description?: string;
sharekey?: string;
}

View File

@ -6,8 +6,6 @@ import {v4 as uuidv4} from 'uuid';
import axios from "axios"; import axios from "axios";
import {DiagramManager} from "../diagram/diagramManager"; import {DiagramManager} from "../diagram/diagramManager";
import log, {Logger} from "loglevel"; import log, {Logger} from "loglevel";
import {DiagramListing, DiagramListingEventType} from "../diagram/types/diagramListing";
export class PouchdbPersistenceManager { export class PouchdbPersistenceManager {
configObserver: Observable<AppConfigType> = new Observable<AppConfigType>(); configObserver: Observable<AppConfigType> = new Observable<AppConfigType>();
@ -16,30 +14,14 @@ export class PouchdbPersistenceManager {
//implement IPersistenceManager interface with pouchdb apis //implement IPersistenceManager interface with pouchdb apis
private db: PouchDB; private db: PouchDB;
private remote: PouchDB; private remote: PouchDB;
private config: PouchDB;
private diagramListings: PouchDB; private diagramListings: PouchDB;
private readonly logger: Logger = log.getLogger('PouchdbPersistenceManager'); private readonly logger: Logger = log.getLogger('PouchdbPersistenceManager');
constructor() { constructor() {
this.config = new PouchDB("config");
this.diagramListings = new PouchDB("diagramListings"); this.diagramListings = new PouchDB("diagramListings");
} }
public async getDiagramListings() {
return this.diagramListings.allDocs({include_docs: true});
}
public setDiagramManager(diagramManager: DiagramManager) { public setDiagramManager(diagramManager: DiagramManager) {
diagramManager.onDiagramEventListingObservable.add((evt) => {
if (evt.type == DiagramListingEventType.GETALL) {
this.diagramListings.allDocs({include_docs: true}).then((all) => {
for (const entity of all.rows) {
diagramManager.onDiagramEventListingObservable.notifyObservers({
type: DiagramListingEventType.ADD,
listing: {id: entity.doc._id, name: entity.doc.name}
}, -1, false, this);
}
});
}
}, -1, false, this);
diagramManager.onDiagramEventObservable.add((evt) => { diagramManager.onDiagramEventObservable.add((evt) => {
switch (evt.type) { switch (evt.type) {
case DiagramEventType.CHANGECOLOR: case DiagramEventType.CHANGECOLOR:
@ -125,34 +107,6 @@ export class PouchdbPersistenceManager {
this.logger.error(err); this.logger.error(err);
} }
} }
public async addDiagram(diagram: DiagramListing) {
try {
const doc = await this.diagramListings.get(diagram.id);
} catch (err) {
this.diagramListings.put({...diagram, _id: diagram.id});
}
}
public async removeDiagram(diagram: DiagramListing) {
try {
this.diagramListings.delete(diagram.id);
} catch (err) {
this.logger.error(err);
}
}
public async modifyDiagram(diagram: DiagramListing) {
try {
const doc = await this.db.get(diagram.id);
this.db.put({...doc, ...diagram});
} catch (err) {
this.logger.error(err);
}
}
public async getNewRelicData(): Promise<any[]> { public async getNewRelicData(): Promise<any[]> {
return []; return [];
} }
@ -161,25 +115,23 @@ export class PouchdbPersistenceManager {
return data; return data;
} }
public async setConfig(config: any, initial: boolean = false): Promise<any> { public async setConfig(config: AppConfigType, initial: boolean = false) {
if (!initial) { if (!initial) {
const doc = await this.config.get('1'); localStorage.setItem('config', JSON.stringify(config));
const newConf = {...config, _id: '1', _rev: doc._rev};
return this.config.put(newConf);
} else { } else {
const newConf = {...config, _id: '1'}; localStorage.setItem('config', JSON.stringify(config));
return this.config.put(newConf);
} }
} }
public async getConfig(): Promise<any> { public getConfig(): AppConfigType {
return this.config.get('1'); return JSON.parse(localStorage.getItem('config')) as AppConfigType;
} }
public async initialize() { public async initialize() {
try { try {
let current = this.getPath(); let current = this.getPath();
const config = await this.config.get('1'); const configString = localStorage.getItem('config');
const config = JSON.parse(configString) as AppConfigType;
if (!current && config.currentDiagramId) { if (!current && config.currentDiagramId) {
this.db = new PouchDB(config.currentDiagramId); this.db = new PouchDB(config.currentDiagramId);
@ -192,7 +144,7 @@ export class PouchdbPersistenceManager {
} }
this.db = new PouchDB(config.currentDiagramId); this.db = new PouchDB(config.currentDiagramId);
await this.beginSync(config.currentDiagramId); await this.beginSync(config.currentDiagramId);
await this.config.put(config); localStorage.setItem('config', JSON.stringify(config));
} }
this.configObserver.notifyObservers(config); this.configObserver.notifyObservers(config);
} catch (err) { } catch (err) {
@ -264,10 +216,6 @@ export class PouchdbPersistenceManager {
} }
} }
setCurrentDiagram(diagram: DiagramListing) {
this.currentDiagramId = diagram.id;
}
sync() { sync() {
} }

View File

@ -1,94 +0,0 @@
import {AbstractMesh, MeshBuilder, Scene, Vector3, WebXRDefaultExperience} from "@babylonjs/core";
import {AbstractMenu} from "./abstractMenu";
import {ControllerEventType, Controllers} from "../controllers/controllers";
import {AdvancedDynamicTexture, Button, Control, ScrollViewer, StackPanel, TextBlock} from "@babylonjs/gui";
import {setMenuPosition} from "../util/functions/setMenuPosition";
import {DiagramManager} from "../diagram/diagramManager";
import {DiagramListingEvent, DiagramListingEventType} from "../diagram/types/diagramListing";
import {DiagramEventType} from "../diagram/types/diagramEntity";
export class DiagramListingMenu extends AbstractMenu {
private mesh: AbstractMesh;
private panel: StackPanel;
private readonly diagramManager: DiagramManager;
constructor(scene: Scene, xr: WebXRDefaultExperience, controllers: Controllers, diagramManager: DiagramManager) {
super(scene, xr, controllers);
this.diagramManager = diagramManager;
this.buildMenu();
this.controllers.controllerObserver.add((event) => {
if (event.type == ControllerEventType.B_BUTTON) {
this.toggle();
}
});
}
public toggle() {
setMenuPosition(this.handle.mesh, this.scene, new Vector3(0, .4, 0));
this.mesh.isVisible = !this.mesh.isVisible;
this.populateData();
(this.mesh.parent as AbstractMesh).isVisible = this.mesh.isVisible;
}
public populateData() {
this.panel.clearControls();
this.diagramManager.onDiagramEventListingObservable.notifyObservers({type: DiagramListingEventType.GETALL}, -1);
}
private buildMenu() {
const configPlane = MeshBuilder
.CreatePlane("gridSizePlane",
{
width: 1,
height: .5
}, this.scene);
this.mesh = configPlane;
this.createHandle(this.mesh);
this.mesh.position = new Vector3(0, .32, 0);
const configTexture = AdvancedDynamicTexture.CreateForMesh(configPlane, 2048, 1024);
configTexture.background = "white";
const scrollViewer = new ScrollViewer('diagramListingScroll');
configTexture.addControl(scrollViewer);
this.panel = new StackPanel('diagramListingStack');
scrollViewer.addControl(this.panel);
//configPlane.position.y = .5;
setMenuPosition(this.handle.mesh, this.scene, new Vector3(0, .4, 0));
this.mesh.isVisible = false;
(this.mesh.parent as AbstractMesh).isVisible = false;
this.diagramManager.onDiagramEventListingObservable.add((event: DiagramListingEvent) => {
if (event.type == DiagramListingEventType.ADD) {
this.addRow(event.listing.id, event.listing.name);
}
}, -1, false, this);
}
private addRow(id: string, name: string) {
const row = new StackPanel('diagramListingRow ' + id);
row.isVertical = false;
row.height = "68px";
row.width = 1;
this.panel.addControl(row);
const selectButton = Button.CreateSimpleButton('diagramListingText ' + id, id);
selectButton.height = "64px";
selectButton.horizontalAlignment = Control.HORIZONTAL_ALIGNMENT_LEFT;
selectButton.width = "220px";
selectButton.color = "white";
selectButton.fontSize = "48px";
selectButton.background = "#333333";
selectButton.onPointerClickObservable.add(() => {
this.diagramManager.onDiagramEventObservable.notifyObservers({type: DiagramEventType.RESET});
console.log(id);
}, -1, false, this);
const textBlock = new TextBlock('diagramListingText ' + name, 'Diagram ' + name);
textBlock.width = "1000px";
textBlock.horizontalAlignment = Control.HORIZONTAL_ALIGNMENT_LEFT;
textBlock.textHorizontalAlignment = Control.HORIZONTAL_ALIGNMENT_LEFT;
textBlock.fontSize = "48px";
row.addControl(selectButton);
row.addControl(textBlock);
}
}

View File

@ -1,26 +1,34 @@
import {useState} from "react"; import {useEffect, useState} from "react";
function MainMenu({onClick}) { function MainMenu({onClick}) {
return ( return (
<div className="overlay mini" id="main" onClick={onClick}> <div className="overlay mini" id="main">
<img height="120" src="/assets/ddd.svg" width="320"/> <img height="120" src="/assets/ddd.svg" width="320"/>
<div id="startCreate"><a href="#" id="startCreateLink">Start</a></div> <div id="diagrams"><a href="#" id="diagramsLink" onClick={onClick}>Diagrams</a></div>
<div id="enterXR"><a href="#" id="enterVRLink">Enter VR</a></div>
<div id="download"><a href="#" id="downloadLink">Download Model</a></div> <div id="download"><a href="#" id="downloadLink">Download Model</a></div>
</div> </div>
) )
} }
function CreateMenu({display}) { function CreateMenu({display, toggleCreateMenu}) {
const onCreateClick = (evt) => {
evt.preventDefault();
const name = (document.querySelector('#createName') as HTMLInputElement).value;
if (name && name.length > 4) {
document.location.href = '/db/' + name;
} else {
window.alert('Name must be longer than 4 characters');
}
}
return ( return (
<div className="overlay" id="create" style={{'display': display}}> <div className="overlay" id="create" style={{'display': display}}>
<div> <div>
<div><input id="createName" placeholder="Enter a name for your diagram" type="text"/></div> <div><input id="createName" placeholder="Enter a name for your diagram" type="text"/></div>
<div><input id="createPassword" placeholder="Enter a password (optional)" type="text"/></div> <div><input id="createPassword" placeholder="Enter a password (optional)" type="text"/></div>
<div><a href="#" id="createActionLink">Create</a></div> <div><a href="#" id="createActionLink" onClick={onCreateClick}>Create</a></div>
<div><a className="cancel" href="#" id="cancelCreateLink">Cancel</a></div> <div><a className="cancel" onClick={toggleCreateMenu} href="#" id="cancelCreateLink">Cancel</a></div>
</div> </div>
</div> </div>
) )
} }
@ -30,7 +38,6 @@ function TutorialMenu({onClick}) {
<div className="overlay" id="tutorial"> <div className="overlay" id="tutorial">
<h1>Help</h1> <h1>Help</h1>
<div id="desktopTutorial"><a href="#" id="desktopLink" onClick={onClick}>Desktop</a></div> <div id="desktopTutorial"><a href="#" id="desktopLink" onClick={onClick}>Desktop</a></div>
<div id="questTutorial"><a href="#" id="questLink">Quest</a></div>
</div> </div>
) )
} }
@ -45,15 +52,26 @@ function KeyboardHelp({display, onClick}) {
) )
} }
function DiagramList() { function DiagramList({display, onClick}) {
const [dbList, setDbList] = useState([]);
useEffect(() => {
const listDb = async () => {
const data = await indexedDB.databases();
setDbList(data.filter((item) => item.name.indexOf('_pouch_') > -1).map((item) => {
return {name: item.name.replace('_pouch_', '')}
}));
};
listDb();
}, []);
return ( return (
<div className="overlay" id="diagramList" style={{'left': '500px'}}> <div className="overlay" id="diagramList" style={{'display': display}}>
<h1>Existing Diagrams</h1> <h1>Diagrams</h1>
<div id="startCreate"><a href="#" id="startCreateLink" onClick={onClick}>New</a></div>
<div id="diagramListContent"> <div id="diagramListContent">
<ul> <ul>
<li><a href="/db/ddd">ddd</a></li> {dbList.map((item) => <li><a href={`/db/${item.name}`}>{item.name}</a></li>)}
<li><a href="/db/ddd2">ddd2</a></li>
<li><a href="/db/ddd3">ddd3</a></li>
</ul> </ul>
</div> </div>
</div> </div>
@ -64,21 +82,30 @@ function Menu() {
const [createState, setCreateState] = useState('none'); const [createState, setCreateState] = useState('none');
const [desktopTutorialState, setDesktopTutorialState] = useState('none'); const [desktopTutorialState, setDesktopTutorialState] = useState('none');
const [diagramListState, setDiagramListState] = useState('none');
function handleCreateClick() { function handleCreateClick(evt: React.MouseEvent<HTMLAnchorElement>) {
evt.preventDefault();
setCreateState(createState == 'none' ? 'block' : 'none'); setCreateState(createState == 'none' ? 'block' : 'none');
} }
function handleDesktopTutorialClick() { function handleDesktopTutorialClick(evt: React.MouseEvent<HTMLAnchorElement>) {
evt.preventDefault();
setDesktopTutorialState(desktopTutorialState == 'none' ? 'block' : 'none'); setDesktopTutorialState(desktopTutorialState == 'none' ? 'block' : 'none');
} }
function handleDiagramListClick(evt: React.MouseEvent<HTMLAnchorElement>) {
evt.preventDefault();
setDiagramListState(diagramListState == 'none' ? 'block' : 'none');
}
return ( return (
<div> <div>
<MainMenu onClick={handleCreateClick}/> <MainMenu onClick={handleDiagramListClick}/>
<TutorialMenu onClick={handleDesktopTutorialClick}/> <TutorialMenu onClick={handleDesktopTutorialClick}/>
<CreateMenu display={createState}/> <CreateMenu display={createState} toggleCreateMenu={handleCreateClick}/>
<KeyboardHelp display={desktopTutorialState} onClick={handleDesktopTutorialClick}/> <KeyboardHelp display={desktopTutorialState} onClick={handleDesktopTutorialClick}/>
<DiagramList onClick={handleCreateClick} display={diagramListState}/>
</div> </div>
) )
} }
@ -89,8 +116,6 @@ export default function WebApp() {
<Menu/> <Menu/>
</div> </div>
) )
} }
/* /*
const create = document.querySelector('#startCreateLink'); const create = document.querySelector('#startCreateLink');

View File

@ -2,4 +2,4 @@ import {createRoot} from "react-dom/client";
import WebApp from "./react/webApp"; import WebApp from "./react/webApp";
const root = createRoot(document.getElementById('webApp')); const root = createRoot(document.getElementById('webApp'));
root.render(WebApp()); root.render(WebApp());