Docker für Keykloak Test
This commit is contained in:
@@ -0,0 +1,22 @@
|
|||||||
|
import ky from 'ky'
|
||||||
|
import type { propertyGroup } from '../../data/propertyGroup'
|
||||||
|
|
||||||
|
export const getPropertyGroups = async (): Promise<propertyGroup[]> => {
|
||||||
|
return ky.get(`http://localhost:8088/propertygroups`).json<propertyGroup[]>()
|
||||||
|
}
|
||||||
|
|
||||||
|
export const getPropertyGroupById = async (id: number): Promise<propertyGroup> => {
|
||||||
|
return ky.get(`http://localhost:8088/propertygroup/${id}`).json<propertyGroup>()
|
||||||
|
}
|
||||||
|
|
||||||
|
export const createPropertyGroup = async (propertyGroup: propertyGroup): Promise<propertyGroup> => {
|
||||||
|
return ky.post(`http://localhost:8088/propertygroup`, { json: propertyGroup }).json<propertyGroup>()
|
||||||
|
}
|
||||||
|
|
||||||
|
export const updatePropertyGroup = async (propertyGroup: propertyGroup): Promise<propertyGroup> => {
|
||||||
|
return ky.put(`http://localhost:8088/propertygroup`, { json: propertyGroup }).json<propertyGroup>()
|
||||||
|
}
|
||||||
|
|
||||||
|
export const deletePropertyGroup = async (id: number): Promise<void> => {
|
||||||
|
return ky.delete(`http://localhost:8088/propertygroup/${id}`).json<void>()
|
||||||
|
}
|
||||||
@@ -0,0 +1,87 @@
|
|||||||
|
import Tooltip from '@mui/material/Tooltip';
|
||||||
|
import { ExportCsv } from '@mui/x-data-grid';
|
||||||
|
import type {propertyGroup} from '../data/propertyGroup';
|
||||||
|
|
||||||
|
import { DataGrid, Toolbar, ToolbarButton} from '@mui/x-data-grid';
|
||||||
|
import Paper from '@mui/material/Paper';
|
||||||
|
import DeleteIcon from '@mui/icons-material/Delete';
|
||||||
|
import AddIcon from '@mui/icons-material/Add';
|
||||||
|
import FileDownloadIcon from '@mui/icons-material/FileDownload';
|
||||||
|
import { updatePropertyGroup } from '../api/language/propertyGroup.api';
|
||||||
|
import Typography from '@mui/material/Typography';
|
||||||
|
|
||||||
|
const PropertyGroupsTableView = ({ propertyGroups, setSelectedRow }: { propertyGroups: propertyGroup[]; setSelectedRow: (id: number) => void }) => {
|
||||||
|
// const [languages, setLanguages] = useState<Language[]>([]);
|
||||||
|
|
||||||
|
function CustomToolbar() {
|
||||||
|
return (
|
||||||
|
<Toolbar>
|
||||||
|
<Typography variant="body1" component="div" sx={{ flexGrow: 1 }}>
|
||||||
|
Available PropertyGroups.
|
||||||
|
</Typography>
|
||||||
|
<Tooltip title="Download as CSV">
|
||||||
|
<ExportCsv render={<ToolbarButton />}>
|
||||||
|
<FileDownloadIcon fontSize="small" />
|
||||||
|
</ExportCsv>
|
||||||
|
</Tooltip>
|
||||||
|
<ToolbarButton onClick={() => console.log('Delete Row clicked')}>
|
||||||
|
<DeleteIcon fontSize="small" sx={{ ml: 'auto' }} />
|
||||||
|
</ToolbarButton>
|
||||||
|
<ToolbarButton onClick={() => console.log('Add Row clicked')}>
|
||||||
|
<AddIcon fontSize="small" sx={{ ml: 'auto' }} />
|
||||||
|
</ToolbarButton>
|
||||||
|
</Toolbar>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<Paper sx={{ height: 600, width: '30vw', marginRight: 2 }}>
|
||||||
|
<DataGrid
|
||||||
|
sx={{ border: 1, borderRadius: 2,
|
||||||
|
boxShadow: 2,
|
||||||
|
borderColor: 'primary.main',
|
||||||
|
'& .MuiDataGrid-cell:hover': { color: 'primary.main' },
|
||||||
|
'& .even-row': { backgroundColor: 'rgba(0, 0, 1, 0.02)' },
|
||||||
|
'& .odd-row': { backgroundColor: 'rgba(0, 0, 20, 0.04)' },
|
||||||
|
}}
|
||||||
|
|
||||||
|
columnHeaderHeight={36}
|
||||||
|
rowHeight={25}
|
||||||
|
rowSpacingType="margin"
|
||||||
|
initialState={{
|
||||||
|
sorting: {
|
||||||
|
sortModel: [{ field: 'label', sort: 'asc' }],
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
rows={propertyGroups}
|
||||||
|
columns={[
|
||||||
|
{ field: 'id', headerName: 'ID', width: 100 ,align: 'right', headerAlign: 'right', editable: false},
|
||||||
|
{ field: 'label', headerName: 'Label', width: 200, editable: true },
|
||||||
|
{ field: 'description', headerName: 'Description', width: 200 , editable: true},
|
||||||
|
]}
|
||||||
|
slots={{
|
||||||
|
toolbar: CustomToolbar,
|
||||||
|
}}
|
||||||
|
processRowUpdate={(updatedRow, originalRow) => {
|
||||||
|
updatePropertyGroup({id: updatedRow.id, label: updatedRow.label, description: updatedRow.description});
|
||||||
|
return updatedRow;
|
||||||
|
}}
|
||||||
|
getRowClassName={(params) =>
|
||||||
|
params.indexRelativeToCurrentPage % 2 === 0 ? 'even-row' : 'odd-row'
|
||||||
|
}
|
||||||
|
onCellClick={(params) => {
|
||||||
|
const selectedRowId = params.id as number;
|
||||||
|
const selectedRow = propertyGroups.find((row) => row.id === selectedRowId);
|
||||||
|
setSelectedRow(selectedRow ? selectedRow.id : 0);
|
||||||
|
}}
|
||||||
|
|
||||||
|
showToolbar
|
||||||
|
/>
|
||||||
|
</Paper>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default PropertyGroupsTableView;
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
export type propertyGroup = {
|
||||||
|
id: number;
|
||||||
|
label: string;
|
||||||
|
description: string;
|
||||||
|
};
|
||||||
|
|
||||||
@@ -1,7 +1,8 @@
|
|||||||
import Keycloak from 'keycloak-js';
|
import Keycloak from 'keycloak-js';
|
||||||
|
|
||||||
const keycloak = new Keycloak({
|
const keycloak = new Keycloak({
|
||||||
url: 'https://barefacedlean.ddnss.de:9099',
|
url: 'http://localhost:8080',
|
||||||
realm: 'simplycpq',
|
realm: 'simplycpq',
|
||||||
clientId: 'simplycpq',
|
clientId: 'scpq',
|
||||||
});
|
});
|
||||||
export default keycloak;
|
export default keycloak;
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ keycloak.init({ onLoad: 'login-required' }).then(() => {
|
|||||||
createRoot(document.getElementById('root')!).render(
|
createRoot(document.getElementById('root')!).render(
|
||||||
<StrictMode>
|
<StrictMode>
|
||||||
<App />
|
<App />
|
||||||
</StrictMode>,
|
</StrictMode>
|
||||||
)
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -1,15 +1,37 @@
|
|||||||
import React from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
|
import PropertyGroupsTableView from '../components/PropertyGroupsTableView';
|
||||||
|
import TranslationsTableView from '../components/TranslationsTableView';
|
||||||
import Box from '@mui/material/Box';
|
import Box from '@mui/material/Box';
|
||||||
import Typography from '@mui/material/Typography';
|
import Typography from '@mui/material/Typography';
|
||||||
|
import type { propertyGroup } from '../data/propertyGroup';
|
||||||
|
import { getPropertyGroups } from '../api/language/propertyGroup.api';
|
||||||
|
|
||||||
const PropertyPage: React.FC = () => {
|
const PropertyPage: React.FC = () => {
|
||||||
|
const [propertyGroups, setPropertyGroups] = useState<propertyGroup[]>([]);
|
||||||
|
const [selectedRow, setSelectedRow] = useState(0);
|
||||||
|
useEffect(() => {
|
||||||
|
getPropertyGroups().then(setPropertyGroups);
|
||||||
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box component="section" sx={{ p: 2, border: '1px dashed grey' }}>
|
<Box component="section" sx={{ p: 2, border: '1px dashed grey' }}>
|
||||||
<Typography variant="h3">
|
<Typography variant="h3">
|
||||||
Property Management
|
Property Type Management
|
||||||
</Typography>
|
</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"
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<PropertyGroupsTableView propertyGroups={propertyGroups} setSelectedRow={setSelectedRow} />
|
||||||
|
<TranslationsTableView selectedRow={selectedRow} />
|
||||||
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default PropertyPage;
|
export default PropertyPage;
|
||||||
|
|||||||
@@ -0,0 +1,13 @@
|
|||||||
|
services:
|
||||||
|
keycloak:
|
||||||
|
image: quay.io/keycloak/keycloak:26.0
|
||||||
|
command: start-dev --import-realm
|
||||||
|
environment:
|
||||||
|
KC_BOOTSTRAP_ADMIN_USERNAME: admin
|
||||||
|
KC_BOOTSTRAP_ADMIN_PASSWORD: admin
|
||||||
|
ports:
|
||||||
|
- '8080:8080'
|
||||||
|
volumes:
|
||||||
|
- ./realms.json:/opt/keycloak/data/import/realms.json
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
[{
|
||||||
|
"realm": "simplycpq",
|
||||||
|
"enabled": true,
|
||||||
|
"users": [{
|
||||||
|
"username": "tsindt",
|
||||||
|
"enabled": true,
|
||||||
|
"emailVerified": true,
|
||||||
|
"firstName": "Thomas",
|
||||||
|
"lastName": "Sindt",
|
||||||
|
"email": "thomas.sindt@example.com",
|
||||||
|
"credentials": [{
|
||||||
|
"type": "password",
|
||||||
|
"value": "XD14ko8d",
|
||||||
|
"temporary": false
|
||||||
|
}],
|
||||||
|
"realmRoles": ["admin"]
|
||||||
|
}],
|
||||||
|
"roles": {
|
||||||
|
"realm": [{
|
||||||
|
"name": "admin",
|
||||||
|
"description": "Administrator role"
|
||||||
|
}]},
|
||||||
|
"clients": [{
|
||||||
|
"clientId": "scpq-backend",
|
||||||
|
"name": "Simply CPQ Backend",
|
||||||
|
"protocol": "openid-connect",
|
||||||
|
"publicClient": false,
|
||||||
|
"secret": "express-secret",
|
||||||
|
"serviceAccountsEnabled": true,
|
||||||
|
"standardFlowEnabled": false,
|
||||||
|
"directAccessGrantsEnabled": true,
|
||||||
|
"redirectUris": [],
|
||||||
|
"webOrigins": []
|
||||||
|
},{
|
||||||
|
"clientId": "scpq",
|
||||||
|
"name": "Simply CPQ",
|
||||||
|
"protocol": "openid-connect",
|
||||||
|
"publicClient": true,
|
||||||
|
"redirectUris": ["http://localhost:5173/*"],
|
||||||
|
"webOrigins": ["http://localhost:5173"],
|
||||||
|
"standardFlowEnabled": true
|
||||||
|
}]
|
||||||
|
}]
|
||||||
Reference in New Issue
Block a user