add check for hasWriteaccess

This commit is contained in:
Sina Blattmann 2023-04-06 14:31:31 +02:00
parent 85d982e62f
commit 7a74e5e5dc
14 changed files with 3514 additions and 51 deletions

File diff suppressed because it is too large Load Diff

View File

@ -35,6 +35,7 @@
"sass": "^1.58.3",
"sass-loader": "^13.2.0",
"style-loader": "^3.3.1",
"testcafe": "^2.4.0",
"typescript": "^4.9.5",
"web-vitals": "^2.1.4"
},

View File

@ -48,7 +48,9 @@ const App = () => {
<Routes>
<Route
path="*"
element={<Navigate to={routes.installations} replace />}
element={
<Navigate to={routes.installations + routes.list} replace />
}
/>
<Route
path={routes.installations + "*"}

View File

@ -1,9 +1,10 @@
import React, { useState } from "react";
import React, { useContext, useState } from "react";
import { Alert, CircularProgress, Grid } from "@mui/material";
import Container from "@mui/material/Container";
import { axiosConfigWithoutToken } from "./config/axiosConfig";
import InnovenergyTextfield from "./components/Layout/InnovenergyTextfield";
import InnovenergyButton from "./components/Layout/InnovenergyButton";
import { UserContext } from "./components/Context/UserContextProvider";
const loginUser = async (username: string, password: string) => {
return axiosConfigWithoutToken.post("/Login", null, {
@ -21,6 +22,7 @@ const Login = ({ setToken, setLanguage }: I_LoginProps) => {
const [password, setPassword] = useState("");
const [loading, setLoading] = useState(false);
const [error, setError] = useState();
const { setCurrentUser } = useContext(UserContext);
const verifyToken = async (token: string) => {
axiosConfigWithoutToken.get("/GetAllInstallations", {
@ -36,6 +38,7 @@ const Login = ({ setToken, setLanguage }: I_LoginProps) => {
verifyToken(data.token)
.then(() => {
setToken(data.token);
setCurrentUser(data.user);
setLoading(false);
setLanguage(data.user.language);
})

View File

@ -4,13 +4,17 @@ import AvailableUserDialog from "./AvailableUserDialog";
import InnovenergyList from "./InnovenergyList";
import UsersWithDirectAccess from "./UsersWithDirectAccess";
import UsersWithInheritedAccess from "./UsersWithInheritedAccess";
import { useContext } from "react";
import { UserContext } from "../../Context/UserContextProvider";
const AccessManagement = () => {
const { currentUser } = useContext(UserContext);
return (
<UsersContextProvider>
<Grid container sx={{ mt: 1 }}>
<Grid item xs={6}>
<AvailableUserDialog />
{currentUser?.hasWriteAccess && <AvailableUserDialog />}
<InnovenergyList id="access-management-list">
<UsersWithDirectAccess />
<UsersWithInheritedAccess />

View File

@ -13,12 +13,14 @@ import PersonIcon from "@mui/icons-material/Person";
import { UsersContext } from "../../Context/UsersContextProvider";
import { useParams } from "react-router-dom";
import { GroupContext } from "../../Context/GroupContextProvider";
import { UserContext } from "../../Context/UserContextProvider";
const UsersWithDirectAccess = () => {
const { fetchUsersWithDirectAccessForResource, directAccessUsers } =
useContext(UsersContext);
const { currentType } = useContext(GroupContext);
const { id } = useParams();
const { currentUser } = useContext(UserContext);
useEffect(() => {
fetchUsersWithDirectAccessForResource();
@ -45,6 +47,7 @@ const UsersWithDirectAccess = () => {
<ListItem
id={"direct-access-user-" + user.id}
secondaryAction={
currentUser?.hasWriteAccess && (
<IconButton
id={"direct-access-user-icon-button" + user.id}
onClick={() => handleIconClick(user.id)}
@ -54,6 +57,7 @@ const UsersWithDirectAccess = () => {
id={"direct-access-user-icon" + user.id}
/>
</IconButton>
)
}
>
<ListItemAvatar id={"direct-access-user-item-avatar" + user.id}>

View File

@ -8,6 +8,7 @@ import { GroupContext } from "../Context/GroupContextProvider";
import InnovenergySnackbar from "../InnovenergySnackbar";
import InnovenergyButton from "../Layout/InnovenergyButton";
import InnovenergyTextfield from "../Layout/InnovenergyTextfield";
import { UserContext } from "../Context/UserContextProvider";
interface I_CustomerFormProps {
values: I_Folder;
@ -22,11 +23,14 @@ const FolderForm = (props: I_CustomerFormProps) => {
const { values, additionalButtons, handleSubmit } = props;
const intl = useIntl();
const { fetchData } = useContext(GroupContext);
const { currentUser } = useContext(UserContext);
const [snackbarOpen, setSnackbarOpen] = useState(false);
const [error, setError] = useState();
const [loading, setLoading] = useState(false);
const readOnly = !currentUser?.hasWriteAccess;
const formik = useFormik({
initialValues: {
name: additionalButtons && additionalButtons.length ? values.name : "",
@ -54,6 +58,7 @@ const FolderForm = (props: I_CustomerFormProps) => {
<form onSubmit={formik.handleSubmit}>
<InnovenergyTextfield
id="folder-name-textfield"
disabled={readOnly}
label={intl.formatMessage({
id: "name",
defaultMessage: "Name",
@ -64,6 +69,7 @@ const FolderForm = (props: I_CustomerFormProps) => {
/>
<InnovenergyTextfield
id="folder-information-textfield"
disabled={readOnly}
label={intl.formatMessage({
id: "information",
defaultMessage: "Information",
@ -74,7 +80,10 @@ const FolderForm = (props: I_CustomerFormProps) => {
/>
<Grid container justifyContent="flex-end" sx={{ pt: 1 }}>
{loading && <CircularProgress />}
{additionalButtons && additionalButtons.map((button) => button)}
{!readOnly &&
additionalButtons &&
additionalButtons.map((button) => button)}
{!readOnly && (
<InnovenergyButton
id="folder-form-submit-button"
type="submit"
@ -82,6 +91,7 @@ const FolderForm = (props: I_CustomerFormProps) => {
>
<FormattedMessage id="submit" defaultMessage="Submit" />
</InnovenergyButton>
)}
</Grid>
<InnovenergySnackbar
error={error}

View File

@ -18,8 +18,6 @@ const GroupTabs = () => {
const intl = useIntl();
const { currentType } = useContext(GroupContext);
console.log(routeMatch);
if (id) {
return (
<Box sx={{ width: "100%" }}>

View File

@ -76,7 +76,7 @@ const GroupTree = () => {
height: 480,
flexGrow: 1,
overflow: "auto",
".MuiTreeView-root": { overflowX: "hidden" },
overflowX: "hidden",
}}
expanded={openNodes}
onNodeToggle={(e, ids) => {

View File

@ -8,6 +8,7 @@ import { InstallationContext } from "../Context/InstallationContextProvider";
import MoveDialog from "../Groups/Tree/MoveDialog";
import InnovenergyButton from "../Layout/InnovenergyButton";
import InnovenergyTextfield from "../Layout/InnovenergyTextfield";
import { UserContext } from "../Context/UserContextProvider";
interface I_InstallationFormProps {
values: I_Installation;
@ -20,6 +21,9 @@ const InstallationForm = (props: I_InstallationFormProps) => {
const intl = useIntl();
const { fetchData } = useContext(InstallationContext);
const { currentUser } = useContext(UserContext);
const readOnly = !currentUser?.hasWriteAccess;
const formik = useFormik({
initialValues: {
@ -49,6 +53,7 @@ const InstallationForm = (props: I_InstallationFormProps) => {
return (
<form onSubmit={formik.handleSubmit}>
<InnovenergyTextfield
disabled={readOnly}
id="installation-name-textfield"
label={intl.formatMessage({
id: "customerName",
@ -59,6 +64,7 @@ const InstallationForm = (props: I_InstallationFormProps) => {
handleChange={formik.handleChange}
/>
<InnovenergyTextfield
disabled={readOnly}
id="installation-region-textfield"
label={intl.formatMessage({
id: "region",
@ -69,6 +75,7 @@ const InstallationForm = (props: I_InstallationFormProps) => {
handleChange={formik.handleChange}
/>
<InnovenergyTextfield
disabled={readOnly}
id="installation-location-textfield"
label={intl.formatMessage({
id: "location",
@ -79,6 +86,7 @@ const InstallationForm = (props: I_InstallationFormProps) => {
handleChange={formik.handleChange}
/>
<InnovenergyTextfield
disabled={readOnly}
id="installation-country-textfield"
label={intl.formatMessage({
id: "country",
@ -89,6 +97,7 @@ const InstallationForm = (props: I_InstallationFormProps) => {
handleChange={formik.handleChange}
/>
<InnovenergyTextfield
disabled={readOnly}
id="installation-orderNumbers-textfield"
label={intl.formatMessage({
id: "orderNumbers",
@ -99,10 +108,15 @@ const InstallationForm = (props: I_InstallationFormProps) => {
handleChange={formik.handleChange}
/>
<Grid container justifyContent="flex-end" sx={{ pt: 1 }}>
{hasMoveButton && <MoveDialog values={values} />}
{hasMoveButton && !readOnly && <MoveDialog values={values} />}
{!readOnly && (
<InnovenergyButton id="installation-form-submit-button" type="submit">
<FormattedMessage id="applyChanges" defaultMessage="Apply changes" />
<FormattedMessage
id="applyChanges"
defaultMessage="Apply changes"
/>
</InnovenergyButton>
)}
</Grid>
<Snackbar
open={open}

View File

@ -8,6 +8,7 @@ interface I_InnovenergyTextfieldProps {
handleChange: (e: React.ChangeEvent<HTMLInputElement>) => void;
type?: string;
readOnly?: boolean;
disabled?: boolean;
}
const InnovenergyTextfield = (props: I_InnovenergyTextfieldProps) => {
@ -23,12 +24,19 @@ const InnovenergyTextfield = (props: I_InnovenergyTextfieldProps) => {
name={props.name}
type={props.type}
fullWidth
sx={{ my: 0.5 }}
sx={{
my: 0.5,
".Mui-disabled": {
"-webkit-text-fill-color": "black",
color: "black",
},
}}
value={props.value || ""}
onChange={props.handleChange}
InputProps={{
readOnly: props.readOnly,
}}
disabled={props.disabled}
/>
</Grid>
</Grid>

View File

@ -22,12 +22,10 @@ const Detail = <T extends { id: number }>(props: I_DetailProps<T>) => {
axiosConfig
.get("/GetUserById?id=" + id)
.then((res) => {
console.log("noterr");
setValues(res.data);
setLoading(false);
})
.catch((err: AxiosError) => {
console.log("err");
setError(err);
setLoading(false);
});
@ -43,7 +41,11 @@ const Detail = <T extends { id: number }>(props: I_DetailProps<T>) => {
};
if (values && values.id && values.id.toString() === id) {
return <UserForm values={values} handleSubmit={handleUpdate} />;
return (
<Box sx={{ py: 3 }}>
<UserForm values={values} handleSubmit={handleUpdate} />
</Box>
);
} else if (loading) {
return (
<Box

View File

@ -1,11 +1,12 @@
import { Alert, CircularProgress, Grid, Snackbar } from "@mui/material";
import { AxiosError, AxiosResponse } from "axios";
import { useFormik } from "formik";
import { useState } from "react";
import { useContext, useState } from "react";
import { FormattedMessage, useIntl } from "react-intl";
import { I_User } from "../../util/user.util";
import InnovenergyButton from "../Layout/InnovenergyButton";
import InnovenergyTextfield from "../Layout/InnovenergyTextfield";
import { UserContext } from "../Context/UserContextProvider";
interface I_UserFormProps {
handleSubmit: (formikValues: Partial<I_User>) => Promise<AxiosResponse>;
@ -18,6 +19,9 @@ const UserForm = (props: I_UserFormProps) => {
const [error, setError] = useState<AxiosError>();
const intl = useIntl();
const { currentUser } = useContext(UserContext);
const readOnly = !currentUser?.hasWriteAccess;
const formik = useFormik({
initialValues: {
@ -55,6 +59,7 @@ const UserForm = (props: I_UserFormProps) => {
name="name"
value={formik.values.name}
handleChange={formik.handleChange}
disabled={readOnly}
/>
<InnovenergyTextfield
id="email-textfield"
@ -65,6 +70,7 @@ const UserForm = (props: I_UserFormProps) => {
name="email"
value={formik.values.email}
handleChange={formik.handleChange}
disabled={readOnly}
/>
<InnovenergyTextfield
id="information-textfield"
@ -75,12 +81,15 @@ const UserForm = (props: I_UserFormProps) => {
name="information"
value={formik.values.information}
handleChange={formik.handleChange}
disabled={readOnly}
/>
<Grid container justifyContent="flex-end" sx={{ pt: 1 }}>
{loading && <CircularProgress />}
{currentUser?.hasWriteAccess && (
<InnovenergyButton type="submit">
<FormattedMessage id="submit" defaultMessage="Submit" />
</InnovenergyButton>
)}
</Grid>
<Snackbar
open={open}

View File

@ -7,13 +7,17 @@ import AddUser from "./AddUser";
import User from "./User";
import UserList from "./UserList";
import UserTabs from "./UserTabs";
import { useContext } from "react";
import { UserContext } from "../Context/UserContextProvider";
const Users = () => {
const { currentUser } = useContext(UserContext);
return (
<UsersContextProvider>
<Grid container>
<Grid container spacing={2}>
<Grid item xs={3}>
<AddUser />
{currentUser?.hasWriteAccess && <AddUser />}
<SearchSidebar id="users-search-sidebar" listComponent={UserList} />
</Grid>
<Grid item xs={9}>