React Treeviews Test

This commit is contained in:
2026-07-30 18:46:02 +02:00
parent 037afe6f72
commit c6ea67b404
10 changed files with 944 additions and 51 deletions
+49
View File
@@ -1,2 +1,51 @@
# Simply CPQ Buildtime Client # Simply CPQ Buildtime Client
Dieser Ordner enthält alle relevanten Dateien und Informationen zum Simply CPQ Buildtime Client. Dieser dient der Pflege von Produktdaten, Regeln, Konditionen und Administration der Simply CPQ Anwendung. Dieser Ordner enthält alle relevanten Dateien und Informationen zum Simply CPQ Buildtime Client. Dieser dient der Pflege von Produktdaten, Regeln, Konditionen und Administration der Simply CPQ Anwendung.
## Genutzte Techologie
Der Client ist eine Web-Applikation, die auf der React-Library aufgebaut ist.
[React](https://react.dev/)
### Zusätzliche Open Source Bibliotheken:
#### Umgebung
Für die Entwicklung wird die Software Node.JS benötigt, hier zu finden:
https://nodejs.org/
Mit
```bash
npm create vite@latest logical-editor --template react
```
kann dann die Umgebung erzeugt werden.
Mit
```bash
npm run dev
```
kann die Entwicklungsumgebung gestartet werden.
Folgende Komponenten müssen noch installiert werden:
##### React Router
```bash
npm install react-router
```
#### Tree View Komponente (react-arborist)
Diese Komponente wird zur Anzeige von Bäumen auf der Oberfläche genutzt. Hier zu finden:
[jameskerr/react-arborist: The complete tree view component for React](https://github.com/jameskerr/react-arborist)
Zur Installation im Root-Verzeichnis des Client-Quellcodes
```bash
npm install react-arborist
```
aufrufen.
#### Icon-Library:
HeroIcon Lib mit der MIT Lizenz ([tailwindlabs/heroicons: A set of free MIT-licensed high-quality SVG icons for UI development.](https://github.com/tailwindlabs/heroicons)
).
```bash
npm install @heroicons/react
```
File diff suppressed because it is too large Load Diff
+5 -1
View File
@@ -10,9 +10,13 @@
"preview": "vite preview" "preview": "vite preview"
}, },
"dependencies": { "dependencies": {
"@heroicons/react": "^2.2.0",
"@tailwindcss/vite": "^4.3.3",
"react": "^19.2.7", "react": "^19.2.7",
"react-arborist": "^3.16.0",
"react-dom": "^19.2.7", "react-dom": "^19.2.7",
"react-router": "^8.3.0" "react-router": "^8.3.0",
"tailwindcss": "^4.3.3"
}, },
"devDependencies": { "devDependencies": {
"@types/react": "^19.2.17", "@types/react": "^19.2.17",
@@ -89,6 +89,11 @@
height: 1vh; height: 1vh;
} }
.side-links {
font-size: 12px;
background: whitesmoke;
}
footer { footer {
padding: 16px; padding: 16px;
color: gray; color: gray;
@@ -4,6 +4,7 @@ import { createBrowserRouter, RouterProvider } from 'react-router'
import Layout from './Layout.jsx' import Layout from './Layout.jsx'
import HomePage from './pages/HomePage.jsx' import HomePage from './pages/HomePage.jsx'
import LanguagePage from './pages/LanguagePage.jsx' import LanguagePage from './pages/LanguagePage.jsx'
import PropertyPage from './pages/PropertyPage.jsx'
import NotFoundPage from './pages/NotFoundPage.jsx' import NotFoundPage from './pages/NotFoundPage.jsx'
import './App.css' import './App.css'
@@ -15,6 +16,7 @@ const router = createBrowserRouter([
children: [ children: [
{ index: true, element: <HomePage /> }, { index: true, element: <HomePage /> },
{ path: 'language', element: <LanguagePage /> }, { path: 'language', element: <LanguagePage /> },
{ path: 'propertypool', element: <PropertyPage /> },
{ path: '*', element: <NotFoundPage /> }, { path: '*', element: <NotFoundPage /> },
], ],
}, },
@@ -11,7 +11,7 @@ function Layout() {
<main> <main>
<Outlet /> <Outlet />
</main> </main>
<footer>My App, 2026</footer> <footer><p>(c) 2026 Dr. Thomas Sindt - Simply CPQ</p></footer>
</div> </div>
) )
} }
@@ -10,6 +10,7 @@ const NavBar = () => {
</div> </div>
<div className="nav-links"> <div className="nav-links">
<Link to="/">Home</Link> <Link to="/">Home</Link>
<Link to="/propertypool">Property Pool</Link>
<Link to="/language">Language</Link> <Link to="/language">Language</Link>
</div> </div>
<div className="logo-container"> <div className="logo-container">
@@ -0,0 +1,21 @@
import React, { Component } from 'react';
import { useState } from 'react';
import { Tree } from 'react-arborist';
import TreeView from './TreeView';
const PropertySideBar = ({ properties, setUpdate }) => {
return (
<nav className="sidebar">
<div>
<h1>Property Pool:</h1>
</div>
<div className="side-links">
<TreeView data={[properties]} setUpdate={setUpdate} />
</div>
<div className="spacer">...</div>
</nav>
);
};
export default PropertySideBar;
@@ -0,0 +1,29 @@
import {Tree} from 'react-arborist';
const TreeView = ({ data, setUpdate }) => {
return (
<Tree
initialData={data}
childrenAccessor="subPropertygroups"
width="200px"
openByDefault={true}
>
{Node}
</Tree>
);
};
const Node = ({ node, style, dragHandle, tree }) => {
console.log(node, tree);
return (
<div className="node-container" style={style} ref={dragHandle} onClick={() => {setUpdate(prev => !prev); node.toggle()}}>
{node.isLeaf ? "📄" : node.isOpen ? "📂" : "📁"}
{node.data.label}
</div>
);
};
export default TreeView;
@@ -0,0 +1,22 @@
import React from 'react';
import { useState } from 'react'
import PropertySideBar from '../components/PropertySideBar';
import UseFetch from '../components/tools/UseFetch';
const PropertyPage = () => {
const { data: properties, isLoading, error } = UseFetch(`http://localhost:8088/propertygroup/1`)
const [update, setUpdate] = useState(false)
if (isLoading) return <p>Loading profile...</p>
if (error) return <p>Error: {error}</p>
return (
<div className="content">
<div><PropertySideBar properties={properties} setUpdate={setUpdate} /></div>
<div className="main"></div>
</div>
);
};
export default PropertyPage;