[WIP] add Users tab to Groups

This commit is contained in:
Sina Blattmann 2023-03-23 08:28:56 +01:00
parent 9cb29ef099
commit 5d801ab36b
7 changed files with 161 additions and 15 deletions

View File

@ -50,7 +50,6 @@ const GroupContextProvider = ({ children }: { children: ReactNode }) => {
value={{
currentType,
setCurrentType,
data,
setData,
fetchData,

View File

@ -1,9 +1,10 @@
import { Button, CircularProgress, Grid, InputLabel } from "@mui/material";
import { useFormik } from "formik";
import { useState } from "react";
import { useContext, useState } from "react";
import { FormattedMessage, useIntl } from "react-intl";
import axiosConfig from "../../config/axiosConfig";
import { I_Folder } from "../../util/types";
import { GroupContext } from "../Context/GroupContextProvider";
import InnovenergySnackbar from "../InnovenergySnackbar";
import InnovenergyTextfield from "../Layout/InnovenergyTextfield";
import MoveTree from "./Tree/MoveTree";
@ -20,11 +21,14 @@ const updateFolder = (data: I_Folder) => {
const FolderForm = (props: I_CustomerFormProps) => {
const { values, id } = props;
const intl = useIntl();
const { fetchData } = useContext(GroupContext);
const [snackbarOpen, setSnackbarOpen] = useState(false);
const [error, setError] = useState();
const [loading, setLoading] = useState(false);
const [selectedParentId, setSelectedParentId] = useState<number>();
const [selectedParentId, setSelectedParentId] = useState<number>(
values.parentId
);
const formik = useFormik({
initialValues: {
@ -41,6 +45,8 @@ const FolderForm = (props: I_CustomerFormProps) => {
id: idAsNumber,
})
.then((res) => {
// TODO figure out why this isnt refreshing tree
fetchData();
setSnackbarOpen(true);
setLoading(false);
})
@ -81,7 +87,10 @@ const FolderForm = (props: I_CustomerFormProps) => {
</InputLabel>
</Grid>
<Grid item xs={9} display="inline">
<MoveTree setSelectedParentId={setSelectedParentId} />
<MoveTree
setSelectedParentId={setSelectedParentId}
parentId={selectedParentId}
/>
</Grid>
</Grid>
<Grid container justifyContent="flex-end" sx={{ pt: 1 }}>

View File

@ -8,6 +8,7 @@ import GroupTabs from "./GroupTabs";
import GroupContextProvider from "../Context/GroupContextProvider";
import GroupTree from "./Tree/GroupTree";
import NavigationButtons from "../Layout/NavigationButtons";
import Users from "./Users/Users";
const Groups = () => {
return (
@ -22,7 +23,7 @@ const Groups = () => {
<GroupTabs />
<Routes>
<Route path={routes.folder + ":id"} element={<Folder />} index />
<Route path={routes.users + ":id"} element={<div>Users</div>} />
<Route path={routes.users + ":id"} element={<Users />} />
<Route
path={routes.installation + ":id"}
element={<Installation />}

View File

@ -1,21 +1,32 @@
import TreeView from "@mui/lab/TreeView";
import ExpandMoreIcon from "@mui/icons-material/ExpandMore";
import ChevronRightIcon from "@mui/icons-material/ChevronRight";
import { ReactNode, useContext, useEffect } from "react";
import { ReactNode, useContext, useEffect, useState } from "react";
import { TreeItem } from "@mui/lab";
import { I_Folder, I_Installation } from "../../../util/types";
import { Link } from "react-router-dom";
import routes from "../../../routes.json";
import { GroupContext } from "../../Context/GroupContextProvider";
import { instanceOfFolder } from "../../../util/group.util";
import { Grid, CircularProgress } from "@mui/material";
const GroupTree = () => {
const { setCurrentType, fetchData, data } = useContext(GroupContext);
const { setCurrentType, fetchData, data, loading } = useContext(GroupContext);
const [openNodes, setOpenNodes] = useState<string[]>([]);
const [selected, setSelected] = useState<string>("");
useEffect(() => {
fetchData();
}, [fetchData]);
/* useEffect(() => {
if (id) {
setSelected(
currentType === "Folder" ? "Folder" + id : "Installation" + id
);
}
}, [id, currentType]); */
const getNodes = (element: I_Folder | I_Installation): null | ReactNode => {
if (instanceOfFolder(element)) {
return element.children ? renderTree(element.children) : null;
@ -40,8 +51,8 @@ const GroupTree = () => {
draggable={false}
>
<TreeItem
key={element.id}
nodeId={element.id.toString()}
key={element.type + element.id}
nodeId={element.type + element.id}
label={element.name}
onClick={() => setCurrentType(element.type)}
>
@ -51,6 +62,13 @@ const GroupTree = () => {
);
});
};
if (loading) {
return (
<Grid container justifyContent="center" width="100%">
<CircularProgress />
</Grid>
);
}
if (data) {
return (
<TreeView
@ -58,6 +76,12 @@ const GroupTree = () => {
defaultCollapseIcon={<ExpandMoreIcon />}
defaultExpandIcon={<ChevronRightIcon />}
sx={{ height: 300, flexGrow: 1, maxWidth: 400 }}
expanded={openNodes}
onNodeToggle={(e, ids) => {
setOpenNodes(ids);
}}
onNodeSelect={(e: any, nodeId: string) => setSelected(nodeId)}
selected={selected}
>
{renderTree(data)}
</TreeView>

View File

@ -7,11 +7,12 @@ import { I_Folder, I_Installation } from "../../../util/types";
import { GroupContext } from "../../Context/GroupContextProvider";
import { instanceOfFolder } from "../../../util/group.util";
interface GroupTreeProps {
interface MoveTreeProps {
setSelectedParentId: (value: number) => void;
parentId: number;
}
const GroupTree = (props: GroupTreeProps) => {
const MoveTree = (props: MoveTreeProps) => {
const { data } = useContext(GroupContext);
const getNodes = (element: I_Folder | I_Installation): null | ReactNode => {
@ -50,9 +51,10 @@ const GroupTree = (props: GroupTreeProps) => {
overflow: "auto",
overflowX: "hidden",
}}
onNodeSelect={(e: any, id: string) =>
props.setSelectedParentId(parseInt(id))
}
onNodeSelect={(e: any, id: string) => {
props.setSelectedParentId(parseInt(id));
}}
selected={props.parentId.toString()}
>
{renderTree(data)}
</TreeView>
@ -61,4 +63,4 @@ const GroupTree = (props: GroupTreeProps) => {
return null;
};
export default GroupTree;
export default MoveTree;

View File

@ -0,0 +1,99 @@
import List from "@mui/material/List";
import ListItemText from "@mui/material/ListItemText";
import { CircularProgress, Divider, Grid, ListItemIcon } from "@mui/material";
import { Fragment, useContext, useEffect, useState } from "react";
import axiosConfig from "../../../config/axiosConfig";
import { useParams } from "react-router-dom";
import ListItem from "@mui/material/ListItem";
import GroupRemoveIcon from "@mui/icons-material/GroupRemove";
import { User } from "../../../util/user.util";
import { GroupContext } from "../../Context/GroupContextProvider";
import { Link } from "react-router-dom";
import routes from "../../../routes.json";
const InstallationList = () => {
const [data, setData] = useState<any>();
const [loading, setLoading] = useState(false);
const { id } = useParams();
const { currentType } = useContext(GroupContext);
useEffect(() => {
setLoading(true);
axiosConfig
.get(
currentType === "Folder"
? "/GetUsersWithAccessToFolder"
: "/GetUsersWithAccessToInstallation",
{ params: { id } }
)
.then((res) => {
// TODO temp solution
const mappedData = res.data
.filter((element: any) => element.user)
.map((element: any) => element.user);
console.log(mappedData);
setData(mappedData);
setLoading(false);
});
}, [currentType, id]);
const filterDuplicateUsers = (data: any[]) => {
return data.reduce((prev: User[], curr: User) => {
const foundUser = prev.find((el) => el.id === curr.id);
if (foundUser) {
const prevIds = foundUser.folderIds ? foundUser.folderIds : [];
foundUser.folderIds = [...prevIds, curr.parentId];
return prev;
}
curr.folderIds = [curr.parentId];
prev.push(curr);
return prev;
}, []);
};
if (loading) {
return (
<Grid container justifyContent="center" width="100%">
<CircularProgress sx={{ m: 6 }} />
</Grid>
);
}
if (data) {
return (
<List
sx={{
bgcolor: "background.paper",
position: "relative",
width: 500,
}}
component="nav"
aria-labelledby="nested-list-subheader"
>
{filterDuplicateUsers(data).map((user: User) => {
return (
<Fragment key={user.id}>
<ListItem>
<ListItemText
primary={user.name}
secondary={
<>
Inherited access from{" "}
<Link to={routes.groups + routes.users + user.parentId}>
this folder
</Link>
</>
}
/>
</ListItem>
<Divider />
</Fragment>
);
})}
</List>
);
}
return null;
};
export default InstallationList;

View File

@ -0,0 +1,12 @@
export interface User {
email: string;
hasWriteAccess: boolean;
id: number;
information: string;
language: string;
name: string;
parentId: number;
password: number;
type: string;
folderIds?: number[];
}