[WIP] add page tab and corresponding routes

This commit is contained in:
Sina Blattmann 2023-03-06 08:47:19 +01:00
parent d2e4f93fd1
commit 8369daec24
14 changed files with 168 additions and 74 deletions

View File

@ -1,6 +1,6 @@
import useToken from "./hooks/useToken";
import Login from "./Login";
import { BrowserRouter, Route, Routes } from "react-router-dom";
import { BrowserRouter, Navigate, Route, Routes } from "react-router-dom";
import { Grid } from "@mui/material";
import routes from "./routes.json";
import { IntlProvider } from "react-intl";
@ -11,7 +11,7 @@ import LanguageSelect from "./components/LanguageSelect";
import LogoutButton from "./components/LogoutButton";
import Installations from "./routes/Installations";
import Users from "./routes/Users";
import Groups from "./routes/Groups";
const App = () => {
const { token, setToken, removeToken } = useToken();
@ -40,11 +40,15 @@ const App = () => {
<LogoutButton removeToken={removeToken} />
</Grid>
<Routes>
<Route
path="*"
element={<Navigate to={routes.installations} replace />}
/>
<Route
path={routes.installations + "*"}
element={<Installations />}
/>
<Route path={routes.tree} element={<Users />} />
<Route path={routes.groups + "*"} element={<Groups />} />
</Routes>
</IntlProvider>
</BrowserRouter>

View File

@ -1,5 +1,5 @@
import React, { useState } from "react";
import { Alert, Button, CircularProgress } from "@mui/material";
import { Alert, Button, CircularProgress, Grid } from "@mui/material";
import Container from "@mui/material/Container";
import InnovenergyTextfield from "./components/InnovenergyTextfield";
import { axiosConfigWithoutToken } from "./config/axiosConfig";
@ -47,11 +47,11 @@ const Login = ({ setToken }: { setToken: any }) => {
handleChange={(e) => setPassword(e.target.value)}
/>
{error && <Alert severity="error">Incorrect username or password</Alert>}
<div>
<Grid container justifyContent="flex-end" sx={{ pt: 1 }}>
<Button variant="outlined" onClick={handleSubmit} sx={{ my: 1 }}>
Login
</Button>
</div>
</Grid>
{loading && <CircularProgress />}
</Container>
);

View File

@ -0,0 +1,50 @@
import * as React from "react";
import Tabs from "@mui/material/Tabs";
import Tab from "@mui/material/Tab";
import Box from "@mui/material/Box";
import { Link } from "react-router-dom";
import routes from "../routes.json";
import useRouteMatch from "../hooks/useRouteMatch";
import { useIntl } from "react-intl";
const GroupTabs = () => {
const routeMatch = useRouteMatch([
routes.groups + routes.group + ":id",
routes.groups + routes.users + ":id",
]);
const id = routeMatch?.params?.id;
const intl = useIntl();
return (
<Box sx={{ width: "100%" }}>
<Box sx={{ borderBottom: 1, borderColor: "divider" }}>
<Tabs
value={routeMatch?.pattern?.path ?? routes.group + ":id"}
aria-label="basic tabs example"
>
<Tab
label={intl.formatMessage({
id: "group",
defaultMessage: "Group",
})}
value={routes.groups + routes.group + ":id"}
component={Link}
to={routes.group + id}
/>
<Tab
label={intl.formatMessage({
id: "users",
defaultMessage: "Users",
})}
value={routes.groups + routes.users + ":id"}
component={Link}
to={routes.users + id}
/>
</Tabs>
</Box>
</Box>
);
};
export default GroupTabs;

View File

@ -5,8 +5,9 @@ import { ReactNode, useEffect, useState } from "react";
import { TreeItem } from "@mui/lab";
import { I_Folder, I_Installation } from "../util/types";
import axiosConfig from "../config/axiosConfig";
const UserList = () => {
const [data, setData] = useState<I_Folder[]>();
import { Link } from "react-router-dom";
const GroupTree = () => {
const [data, setData] = useState<(I_Folder | I_Installation)[]>();
useEffect(() => {
axiosConfig.get("/GetTree").then((res) => {
@ -14,11 +15,6 @@ const UserList = () => {
});
}, []);
const handleClick = (e: any, nodes: any) => {
console.log(e);
console.log(nodes);
};
const instanceOfFolder = (object: any): object is I_Folder => {
return "children" in object;
};
@ -33,13 +29,18 @@ const UserList = () => {
const renderTree = (data: (I_Folder | I_Installation)[]): ReactNode => {
return data.map((element) => {
return (
<TreeItem
key={element.id}
nodeId={element.id.toString()}
label={element.name}
<Link
to={"/groups/group/" + element.id}
style={{ textDecoration: "none", color: "black" }}
>
{getNodes(element)}
</TreeItem>
<TreeItem
key={element.id}
nodeId={element.id.toString()}
label={element.name}
>
{getNodes(element)}
</TreeItem>
</Link>
);
});
};
@ -49,11 +50,10 @@ const UserList = () => {
defaultCollapseIcon={<ExpandMoreIcon />}
defaultExpandIcon={<ChevronRightIcon />}
sx={{ height: 300, flexGrow: 1, maxWidth: 400 }}
onNodeToggle={handleClick}
>
{data && renderTree(data)}
</TreeView>
);
};
export default UserList;
export default GroupTree;

View File

@ -77,7 +77,6 @@ const InstallationList = (props: InstallationListProps) => {
aria-labelledby="nested-list-subheader"
>
{filteredData?.map((installation) => {
console.log(routeMatch);
return (
<Fragment key={installation.id}>
<Link

View File

@ -31,9 +31,7 @@ const InstallationTabs = () => {
id: "installation",
defaultMessage: "Installation",
})}
value={
routes.installations + routes.installation + ":id"
}
value={routes.installations + routes.installation + ":id"}
component={Link}
to={routes.installation + id}
/>

View File

@ -7,7 +7,7 @@ import routes from "../routes.json";
const NavigationButtons = () => {
const routeMatch = useRouteMatch([
routes.installations + "*",
routes.tree + "*",
routes.groups + "*",
]);
return (
@ -27,8 +27,8 @@ const NavigationButtons = () => {
defaultMessage="All installations"
/>
</ToggleButton>
<ToggleButton value={routes.tree + "*"} component={Link} to={routes.tree}>
<FormattedMessage id="users" defaultMessage="Users" />
<ToggleButton value={routes.groups + "*"} component={Link} to={routes.groups}>
<FormattedMessage id="groups" defaultMessage="Groups" />
</ToggleButton>
</ToggleButtonGroup>
);

View File

@ -14,5 +14,7 @@
"search": "Suche",
"users": "Benutzer",
"logout": "Logout",
"updatedSuccessfully": "Erfolgreich aktualisiert"
"updatedSuccessfully": "Erfolgreich aktualisiert",
"groups": "Gruppen",
"group": "Gruppe"
}

View File

@ -14,5 +14,7 @@
"search": "Search",
"users": "Users",
"logout": "Logout",
"updatedSuccessfully": "Updated successfully"
"updatedSuccessfully": "Updated successfully",
"groups": "Groups",
"group": "Group"
}

View File

@ -4,5 +4,6 @@
"users": "users/",
"log": "log/",
"installations": "/installations/",
"tree": "/users/*"
"groups": "/groups/",
"group": "group/"
}

View File

@ -0,0 +1,48 @@
import { Box, CircularProgress, Alert } from "@mui/material";
import { AxiosError } from "axios";
import { useState, useEffect } from "react";
import { useParams } from "react-router-dom";
import axiosConfig from "../config/axiosConfig";
import { I_Installation } from "../util/types";
const Group = () => {
const { id } = useParams();
const [values, setValues] = useState<I_Installation>();
const [loading, setLoading] = useState(false);
const [error, setError] = useState<AxiosError>();
useEffect(() => {
setLoading(true);
axiosConfig
.get("/GetFolderById?id=" + id)
.then((res) => {
setValues(res.data);
setLoading(false);
})
.catch((err: AxiosError) => {
setError(err);
setLoading(false);
});
}, [id]);
if (values && values.id && values.id.toString() === id) {
return <Box sx={{ py: 3 }}>{id}</Box>;
} else if (loading) {
return (
<Box
sx={{ width: 1 / 2, justifyContent: "center", display: "flex", mt: 10 }}
>
<CircularProgress sx={{ m: 2 }} />
</Box>
);
} else if (error) {
return (
<Alert severity="error" sx={{ mt: 1 }}>
{error.message}
</Alert>
);
}
return null;
};
export default Group;

View File

@ -0,0 +1,30 @@
import { Grid } from "@mui/material";
import { Container } from "@mui/system";
import { Routes, Route } from "react-router";
import GroupTabs from "../components/GroupTabs";
import NavigationButtons from "../components/NavigationButtons";
import UserTree from "../components/GroupTree";
import routes from "../routes.json";
import Group from "./Group";
const Groups = () => {
return (
<Container maxWidth="xl">
<Grid container spacing={2}>
<Grid item xs={3}>
<NavigationButtons />
<UserTree />
</Grid>
<Grid item xs={9}>
<GroupTabs />
<Routes>
<Route path={routes.group + ":id"} element={<Group />} index />
<Route path={routes.users + ":id"} element={<div>Users</div>} />
</Routes>
</Grid>
</Grid>
</Container>
);
};
export default Groups;

View File

@ -1,4 +1,4 @@
import { Grid, Divider } from "@mui/material";
import { Grid } from "@mui/material";
import { Container } from "@mui/system";
import { Routes, Route } from "react-router";
import InstallationTabs from "../components/InstallationTabs";
@ -13,22 +13,12 @@ import Sidebar from "../components/Sidebar";
const Installations = () => {
return (
<Container maxWidth="xl">
<Grid container spacing={2}>
<Grid container spacing={4}>
<Grid item xs={3}>
<NavigationButtons />
<Sidebar />
</Grid>
<Grid
item
xs={1}
container
direction="row"
justifyContent="center"
alignItems="center"
>
<Divider orientation="vertical" variant="middle" />
</Grid>
<Grid item xs={8}>
<Grid item xs={9}>
<InstallationTabs />
<Routes>
<Route

View File

@ -1,30 +0,0 @@
import { Grid, Divider } from "@mui/material";
import { Container } from "@mui/system";
import NavigationButtons from "../components/NavigationButtons";
import UserTree from "../components/UserTree";
const Users = () => {
return (
<Container maxWidth="xl">
<Grid container spacing={2}>
<Grid item xs={3}>
<NavigationButtons />
<UserTree />
</Grid>
<Grid
item
xs={1}
container
direction="row"
justifyContent="center"
alignItems="center"
>
<Divider orientation="vertical" variant="middle" />
</Grid>
<Grid item xs={8}></Grid>
</Grid>
</Container>
);
};
export default Users;