TreeView for ProductGroups inital implementation
This commit is contained in:
+54
-14
@@ -14,6 +14,7 @@
|
||||
"@mui/icons-material": "^9.2.0",
|
||||
"@mui/material": "^9.2.0",
|
||||
"@mui/x-data-grid": "^9.10.1",
|
||||
"@mui/x-tree-view": "^9.11.0",
|
||||
"keycloak-js": "^26.2.4",
|
||||
"ky": "^2.0.2",
|
||||
"react": "^19.2.8",
|
||||
@@ -924,12 +925,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@mui/types": {
|
||||
"version": "9.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@mui/types/-/types-9.1.1.tgz",
|
||||
"integrity": "sha512-Zjt7u8wNvDg40rPTGoL+TnfkpuSKjwubsNSFRH1KAVZLcaV4I3AFNHIFbvH7p4F3alEibSbdd90xAgn5Rnfndg==",
|
||||
"version": "9.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@mui/types/-/types-9.3.0.tgz",
|
||||
"integrity": "sha512-2JSxyfpEFWNUB2vKs/T1BvkfyNisMHWph8bLMj8T0uHwmLl/0qfAwQkfwMT6kxLXN9uIum9AEbECXU8er3amIg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.29.2"
|
||||
"@babel/runtime": "^7.29.7"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0"
|
||||
@@ -941,17 +942,17 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@mui/utils": {
|
||||
"version": "9.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@mui/utils/-/utils-9.2.0.tgz",
|
||||
"integrity": "sha512-OsUH5zhlSOM4xmLl53+agug1M1UyWb4zxFxWQCqwKTKUeQPvTENtg3JhrroBD2qpCLKsX5W/DYGERJ4mBUbc8g==",
|
||||
"version": "9.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@mui/utils/-/utils-9.3.0.tgz",
|
||||
"integrity": "sha512-2HZdHwWJ6eB+7lVGSOHsByGw8jeRulT4g0NZ608Wb8Q57DE2jbNqrWPFuJsvkQQiBiTmlpvQL3i+/62zsiPrkw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.29.2",
|
||||
"@mui/types": "^9.1.1",
|
||||
"@babel/runtime": "^7.29.7",
|
||||
"@mui/types": "^9.3.0",
|
||||
"@types/prop-types": "^15.7.15",
|
||||
"clsx": "^2.1.1",
|
||||
"prop-types": "^15.8.1",
|
||||
"react-is": "^19.2.6"
|
||||
"react-is": "^19.2.8"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
@@ -1010,14 +1011,14 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@mui/x-internals": {
|
||||
"version": "9.10.1",
|
||||
"resolved": "https://registry.npmjs.org/@mui/x-internals/-/x-internals-9.10.1.tgz",
|
||||
"integrity": "sha512-pKFVzFQHB34TuMG3gOVx+LfIR8VBsi/ZhX/erRX2WOXu+ewEYGvdeK1mW9hLe7e2v3uyUbgT8RNeN0cy10cDjg==",
|
||||
"version": "9.11.0",
|
||||
"resolved": "https://registry.npmjs.org/@mui/x-internals/-/x-internals-9.11.0.tgz",
|
||||
"integrity": "sha512-JjKe9k1+gVWNPwMTZLNSc92eVmoZqP5Xq3Ui6mJkstotUrbWIZC0o9+4AfTR1lYqWwnKmqm+VtLLVCa7MEBXWQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.29.7",
|
||||
"@base-ui/utils": "^0.3.1",
|
||||
"@mui/utils": "^9.2.0",
|
||||
"@mui/utils": "^9.3.0",
|
||||
"reselect": "^5.2.0",
|
||||
"use-sync-external-store": "^1.6.0"
|
||||
},
|
||||
@@ -1032,6 +1033,45 @@
|
||||
"react": "^17.0.0 || ^18.0.0 || ^19.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@mui/x-tree-view": {
|
||||
"version": "9.11.0",
|
||||
"resolved": "https://registry.npmjs.org/@mui/x-tree-view/-/x-tree-view-9.11.0.tgz",
|
||||
"integrity": "sha512-ZJcnlOr3LwQF9n+xa/4Xh0w8wDCY250smbLGmRzK107ClifYSDTR8/IrRQg8yKBwpDYWDQZW85t0voQcverk1g==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.29.7",
|
||||
"@base-ui/utils": "^0.3.1",
|
||||
"@mui/utils": "^9.3.0",
|
||||
"@mui/x-internals": "^9.11.0",
|
||||
"@types/react-transition-group": "^4.4.12",
|
||||
"clsx": "^2.1.1",
|
||||
"prop-types": "^15.8.1",
|
||||
"react-transition-group": "^4.4.5"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/mui-org"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@emotion/react": "^11.9.0",
|
||||
"@emotion/styled": "^11.8.1",
|
||||
"@mui/material": "^7.3.0 || ^9.0.0",
|
||||
"@mui/system": "^7.3.0 || ^9.0.0",
|
||||
"react": "^17.0.0 || ^18.0.0 || ^19.0.0",
|
||||
"react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@emotion/react": {
|
||||
"optional": true
|
||||
},
|
||||
"@emotion/styled": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@mui/x-virtualizer": {
|
||||
"version": "0.6.2",
|
||||
"resolved": "https://registry.npmjs.org/@mui/x-virtualizer/-/x-virtualizer-0.6.2.tgz",
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
"@mui/icons-material": "^9.2.0",
|
||||
"@mui/material": "^9.2.0",
|
||||
"@mui/x-data-grid": "^9.10.1",
|
||||
"@mui/x-tree-view": "^9.11.0",
|
||||
"keycloak-js": "^26.2.4",
|
||||
"ky": "^2.0.2",
|
||||
"react": "^19.2.8",
|
||||
|
||||
@@ -7,6 +7,7 @@ const Layout = lazy(() => import('./Layout.tsx'))
|
||||
const HomePage = lazy(() => import('./pages/HomePage.tsx'))
|
||||
const LanguagesPage = lazy(() => import('./pages/LanguagesPage.tsx'))
|
||||
const PropertyPage = lazy(() => import('./pages/PropertyPage.tsx'))
|
||||
const ProductPage = lazy(() => import('./pages/ProductPage.tsx'))
|
||||
const NotFoundPage = lazy(() => import('./pages/NotFoundPage.tsx'))
|
||||
|
||||
const renderLazyRoute = (Component: ComponentType) => (
|
||||
@@ -24,6 +25,7 @@ const router = createBrowserRouter([
|
||||
{ index: true, element: renderLazyRoute(HomePage) },
|
||||
{ path: 'language', element: renderLazyRoute(LanguagesPage) },
|
||||
{ path: 'propertypool', element: renderLazyRoute(PropertyPage) },
|
||||
{ path: 'product', element: renderLazyRoute(ProductPage) },
|
||||
{ path: '*', element: renderLazyRoute(NotFoundPage) },
|
||||
],
|
||||
},
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
import ky from 'ky'
|
||||
import type { ProductGroup } from '../../data/productGroup'
|
||||
|
||||
export const getProductGroups = async (): Promise<ProductGroup[]> => {
|
||||
return ky.get(`http://localhost:8088/productgroups`).json<ProductGroup[]>()
|
||||
}
|
||||
|
||||
export const getProductGroupById = async (id: number): Promise<ProductGroup> => {
|
||||
return ky.get(`http://localhost:8088/productgroup/${id}`).json<ProductGroup>()
|
||||
}
|
||||
|
||||
export const createProductGroup = async (productGroup: ProductGroup): Promise<ProductGroup> => {
|
||||
return ky.post(`http://localhost:8088/productgroup`, { json: productGroup }).json<ProductGroup>()
|
||||
}
|
||||
|
||||
export const updateProductGroup = async (productGroup: ProductGroup): Promise<void> => {
|
||||
await ky.put(`http://localhost:8088/productgroup`, { json: productGroup })
|
||||
}
|
||||
|
||||
export const deleteProductGroup = async (id: number): Promise<void> => {
|
||||
await ky.delete(`http://localhost:8088/productgroup/${id}`)
|
||||
}
|
||||
@@ -18,7 +18,7 @@ function NavBar() {
|
||||
</Typography>
|
||||
<Stack direction="row" spacing={2}>
|
||||
<Button color="inherit" onClick={() => navigate('/propertypool')}>Property Pool</Button>
|
||||
<Button color="inherit">Products</Button>
|
||||
<Button color="inherit" onClick={() => navigate('/product')}>Products</Button>
|
||||
<Button color="inherit">Conditions</Button>
|
||||
<Button color="inherit" onClick={() => navigate('/language')}>Languages</Button>
|
||||
<Button color="inherit" onClick={() => navigate('/')}>Home</Button>
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
import type { ProductGroup } from '../data/productGroup';
|
||||
import { SimpleTreeView } from '@mui/x-tree-view/SimpleTreeView';
|
||||
import { TreeItem } from '@mui/x-tree-view/TreeItem';
|
||||
|
||||
type ProductGroupTreeViewProps = {
|
||||
ProductGroups?: ProductGroup[];
|
||||
};
|
||||
|
||||
export default function ProductGroupTreeView({ ProductGroups = [] }: ProductGroupTreeViewProps) {
|
||||
|
||||
const renderTree = (node: ProductGroup) => (
|
||||
<TreeItem key={node.id} itemId={node.id.toString()} label={node.label}>
|
||||
{node.childProductGroups && node.childProductGroups.map((ProductGroup) => (
|
||||
renderTree(ProductGroup)
|
||||
))}
|
||||
</TreeItem>
|
||||
);
|
||||
|
||||
return (
|
||||
<SimpleTreeView
|
||||
aria-label="Product Group Tree View"
|
||||
sx={{ height: 240, flexGrow: 1, maxWidth: 400, overflowY: 'auto' }}
|
||||
>
|
||||
{ProductGroups.map((productGroup) => renderTree(productGroup))}
|
||||
</SimpleTreeView>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
export type Product = {
|
||||
id: number;
|
||||
label: string;
|
||||
product_identifier: string;
|
||||
properties: unknown[];
|
||||
products: Product[];
|
||||
productStructureNodes: unknown[];
|
||||
isEqualPropertiesEqualValues: boolean;
|
||||
};
|
||||
|
||||
@@ -7,7 +7,7 @@ export type ProductGroup = {
|
||||
parentGroupId: number | null;
|
||||
isVisible: boolean;
|
||||
path: string;
|
||||
SubGroups: ProductGroup[];
|
||||
childProductGroups: ProductGroup[];
|
||||
PropertyTypes: PropertyType[];
|
||||
Products: Product[];
|
||||
};
|
||||
@@ -0,0 +1,40 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import ProductGroupTreeView from '../components/ProductGroupTreeView';
|
||||
import Box from '@mui/material/Box';
|
||||
import Typography from '@mui/material/Typography';
|
||||
import type { ProductGroup } from '../data/productGroup';
|
||||
import { getProductGroupById } from '../api/language/productGroup.api';
|
||||
|
||||
const ProductPage: React.FC = () => {
|
||||
const [productGroup, setProductGroup] = useState<ProductGroup | null>(null);
|
||||
|
||||
const loadProductGroup = React.useCallback(async () => {
|
||||
const loadedProductGroup = await getProductGroupById(3); // Assuming 3 is the ID for product groups
|
||||
setProductGroup(loadedProductGroup);
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
loadProductGroup();
|
||||
}, [loadProductGroup]);
|
||||
|
||||
return (
|
||||
<Box component="section" sx={{ p: 2, border: '1px dashed grey' }}>
|
||||
<Typography variant="h3">
|
||||
Property Type Management
|
||||
</Typography>
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex", // Arrange children in a row
|
||||
flexDirection: "row",
|
||||
width: "100vw", // Full width of the parent
|
||||
p: 2, // Padding around the flex container
|
||||
bgcolor: "#f5f5f5"
|
||||
}}
|
||||
>
|
||||
<ProductGroupTreeView ProductGroups={productGroup ? [productGroup] : []} />
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
export default ProductPage;
|
||||
Reference in New Issue
Block a user