add loading indicators, clean up code, add user tree prototype
This commit is contained in:
parent
633c3de5bc
commit
cc31922ba4
|
@ -11,6 +11,7 @@
|
||||||
"@emotion/react": "^11.10.5",
|
"@emotion/react": "^11.10.5",
|
||||||
"@emotion/styled": "^11.10.5",
|
"@emotion/styled": "^11.10.5",
|
||||||
"@mui/icons-material": "^5.11.0",
|
"@mui/icons-material": "^5.11.0",
|
||||||
|
"@mui/lab": "^5.0.0-alpha.120",
|
||||||
"@mui/material": "^5.11.7",
|
"@mui/material": "^5.11.7",
|
||||||
"@testing-library/jest-dom": "^5.16.5",
|
"@testing-library/jest-dom": "^5.16.5",
|
||||||
"@testing-library/react": "^13.4.0",
|
"@testing-library/react": "^13.4.0",
|
||||||
|
@ -3256,6 +3257,79 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@mui/lab": {
|
||||||
|
"version": "5.0.0-alpha.120",
|
||||||
|
"resolved": "https://registry.npmjs.org/@mui/lab/-/lab-5.0.0-alpha.120.tgz",
|
||||||
|
"integrity": "sha512-vjlF2jTKSZnNxtUO0xxHEDfpL5cG0LLNRsfKv8TYOiPs0Q1bbqO3YfqJsqxv8yh+wx7EFZc8lwJ4NSAQdenW3A==",
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/runtime": "^7.20.13",
|
||||||
|
"@mui/base": "5.0.0-alpha.118",
|
||||||
|
"@mui/system": "^5.11.9",
|
||||||
|
"@mui/types": "^7.2.3",
|
||||||
|
"@mui/utils": "^5.11.9",
|
||||||
|
"clsx": "^1.2.1",
|
||||||
|
"prop-types": "^15.8.1",
|
||||||
|
"react-is": "^18.2.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12.0.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/mui"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@emotion/react": "^11.5.0",
|
||||||
|
"@emotion/styled": "^11.3.0",
|
||||||
|
"@mui/material": "^5.0.0",
|
||||||
|
"@types/react": "^17.0.0 || ^18.0.0",
|
||||||
|
"react": "^17.0.0 || ^18.0.0",
|
||||||
|
"react-dom": "^17.0.0 || ^18.0.0"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"@emotion/react": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"@emotion/styled": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"@types/react": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@mui/lab/node_modules/@mui/base": {
|
||||||
|
"version": "5.0.0-alpha.118",
|
||||||
|
"resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-alpha.118.tgz",
|
||||||
|
"integrity": "sha512-GAEpqhnuHjRaAZLdxFNuOf2GDTp9sUawM46oHZV4VnYPFjXJDkIYFWfIQLONb0nga92OiqS5DD/scGzVKCL0Mw==",
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/runtime": "^7.20.13",
|
||||||
|
"@emotion/is-prop-valid": "^1.2.0",
|
||||||
|
"@mui/types": "^7.2.3",
|
||||||
|
"@mui/utils": "^5.11.9",
|
||||||
|
"@popperjs/core": "^2.11.6",
|
||||||
|
"clsx": "^1.2.1",
|
||||||
|
"prop-types": "^15.8.1",
|
||||||
|
"react-is": "^18.2.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12.0.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/mui"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@types/react": "^17.0.0 || ^18.0.0",
|
||||||
|
"react": "^17.0.0 || ^18.0.0",
|
||||||
|
"react-dom": "^17.0.0 || ^18.0.0"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"@types/react": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@mui/material": {
|
"node_modules/@mui/material": {
|
||||||
"version": "5.11.8",
|
"version": "5.11.8",
|
||||||
"resolved": "https://registry.npmjs.org/@mui/material/-/material-5.11.8.tgz",
|
"resolved": "https://registry.npmjs.org/@mui/material/-/material-5.11.8.tgz",
|
||||||
|
@ -3301,12 +3375,12 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@mui/private-theming": {
|
"node_modules/@mui/private-theming": {
|
||||||
"version": "5.11.7",
|
"version": "5.11.9",
|
||||||
"resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.11.7.tgz",
|
"resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.11.9.tgz",
|
||||||
"integrity": "sha512-XzRTSZdc8bhuUdjablTNv3kFkZ/XIMlKkOqqJCU0G8W3tWGXpau2DXkafPd1ddjPhF9zF3qLKNGgKCChYItjgA==",
|
"integrity": "sha512-XMyVIFGomVCmCm92EvYlgq3zrC9K+J6r7IKl/rBJT2/xVYoRY6uM7jeB+Wxh7kXxnW9Dbqsr2yL3cx6wSD1sAg==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/runtime": "^7.20.7",
|
"@babel/runtime": "^7.20.13",
|
||||||
"@mui/utils": "^5.11.7",
|
"@mui/utils": "^5.11.9",
|
||||||
"prop-types": "^15.8.1"
|
"prop-types": "^15.8.1"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
|
@ -3327,11 +3401,11 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@mui/styled-engine": {
|
"node_modules/@mui/styled-engine": {
|
||||||
"version": "5.11.8",
|
"version": "5.11.9",
|
||||||
"resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.11.8.tgz",
|
"resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.11.9.tgz",
|
||||||
"integrity": "sha512-iSpZp9AoeictsDi5xAQ4PGXu7mKtQyzMl7ZaWpHIGMFpsNnfY3NQNg+wkj/gpsAZ+Zg+IIyD+t+ig71Kr9fa0w==",
|
"integrity": "sha512-bkh2CjHKOMy98HyOc8wQXEZvhOmDa/bhxMUekFX5IG0/w4f5HJ8R6+K6nakUUYNEgjOWPYzNPrvGB8EcGbhahQ==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/runtime": "^7.20.7",
|
"@babel/runtime": "^7.20.13",
|
||||||
"@emotion/cache": "^11.10.5",
|
"@emotion/cache": "^11.10.5",
|
||||||
"csstype": "^3.1.1",
|
"csstype": "^3.1.1",
|
||||||
"prop-types": "^15.8.1"
|
"prop-types": "^15.8.1"
|
||||||
|
@ -3358,15 +3432,15 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@mui/system": {
|
"node_modules/@mui/system": {
|
||||||
"version": "5.11.8",
|
"version": "5.11.9",
|
||||||
"resolved": "https://registry.npmjs.org/@mui/system/-/system-5.11.8.tgz",
|
"resolved": "https://registry.npmjs.org/@mui/system/-/system-5.11.9.tgz",
|
||||||
"integrity": "sha512-zhroUcxAw2x/dISBJKhGbD70DOYCwMFRo7o/LUYTiUfQkfmLhRfEf1bopWgY9nYstn7QOxOq9fA3aR3pHrUTbw==",
|
"integrity": "sha512-h6uarf+l3FO6l75Nf7yO+qDGrIoa1DM9nAMCUFZQsNCDKOInRzcptnm8M1w/Z3gVetfeeGoIGAYuYKbft6KZZA==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/runtime": "^7.20.7",
|
"@babel/runtime": "^7.20.13",
|
||||||
"@mui/private-theming": "^5.11.7",
|
"@mui/private-theming": "^5.11.9",
|
||||||
"@mui/styled-engine": "^5.11.8",
|
"@mui/styled-engine": "^5.11.9",
|
||||||
"@mui/types": "^7.2.3",
|
"@mui/types": "^7.2.3",
|
||||||
"@mui/utils": "^5.11.7",
|
"@mui/utils": "^5.11.9",
|
||||||
"clsx": "^1.2.1",
|
"clsx": "^1.2.1",
|
||||||
"csstype": "^3.1.1",
|
"csstype": "^3.1.1",
|
||||||
"prop-types": "^15.8.1"
|
"prop-types": "^15.8.1"
|
||||||
|
@ -3410,11 +3484,11 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@mui/utils": {
|
"node_modules/@mui/utils": {
|
||||||
"version": "5.11.7",
|
"version": "5.11.9",
|
||||||
"resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.11.7.tgz",
|
"resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.11.9.tgz",
|
||||||
"integrity": "sha512-8uyNDeVHZA804Ego20Erv8TpxlbqTe/EbhTI2H1UYr4/RiIbBprat8W4Qqr2UQIsC/b3DLz+0RQ6R/E5BxEcLA==",
|
"integrity": "sha512-eOJaqzcEs4qEwolcvFAmXGpln+uvouvOS9FUX6Wkrte+4I8rZbjODOBDVNlK+V6/ziTfD4iNKC0G+KfOTApbqg==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/runtime": "^7.20.7",
|
"@babel/runtime": "^7.20.13",
|
||||||
"@types/prop-types": "^15.7.5",
|
"@types/prop-types": "^15.7.5",
|
||||||
"@types/react-is": "^16.7.1 || ^17.0.0",
|
"@types/react-is": "^16.7.1 || ^17.0.0",
|
||||||
"prop-types": "^15.8.1",
|
"prop-types": "^15.8.1",
|
||||||
|
@ -20422,6 +20496,38 @@
|
||||||
"@babel/runtime": "^7.20.6"
|
"@babel/runtime": "^7.20.6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"@mui/lab": {
|
||||||
|
"version": "5.0.0-alpha.120",
|
||||||
|
"resolved": "https://registry.npmjs.org/@mui/lab/-/lab-5.0.0-alpha.120.tgz",
|
||||||
|
"integrity": "sha512-vjlF2jTKSZnNxtUO0xxHEDfpL5cG0LLNRsfKv8TYOiPs0Q1bbqO3YfqJsqxv8yh+wx7EFZc8lwJ4NSAQdenW3A==",
|
||||||
|
"requires": {
|
||||||
|
"@babel/runtime": "^7.20.13",
|
||||||
|
"@mui/base": "5.0.0-alpha.118",
|
||||||
|
"@mui/system": "^5.11.9",
|
||||||
|
"@mui/types": "^7.2.3",
|
||||||
|
"@mui/utils": "^5.11.9",
|
||||||
|
"clsx": "^1.2.1",
|
||||||
|
"prop-types": "^15.8.1",
|
||||||
|
"react-is": "^18.2.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@mui/base": {
|
||||||
|
"version": "5.0.0-alpha.118",
|
||||||
|
"resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-alpha.118.tgz",
|
||||||
|
"integrity": "sha512-GAEpqhnuHjRaAZLdxFNuOf2GDTp9sUawM46oHZV4VnYPFjXJDkIYFWfIQLONb0nga92OiqS5DD/scGzVKCL0Mw==",
|
||||||
|
"requires": {
|
||||||
|
"@babel/runtime": "^7.20.13",
|
||||||
|
"@emotion/is-prop-valid": "^1.2.0",
|
||||||
|
"@mui/types": "^7.2.3",
|
||||||
|
"@mui/utils": "^5.11.9",
|
||||||
|
"@popperjs/core": "^2.11.6",
|
||||||
|
"clsx": "^1.2.1",
|
||||||
|
"prop-types": "^15.8.1",
|
||||||
|
"react-is": "^18.2.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"@mui/material": {
|
"@mui/material": {
|
||||||
"version": "5.11.8",
|
"version": "5.11.8",
|
||||||
"resolved": "https://registry.npmjs.org/@mui/material/-/material-5.11.8.tgz",
|
"resolved": "https://registry.npmjs.org/@mui/material/-/material-5.11.8.tgz",
|
||||||
|
@ -20442,36 +20548,36 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@mui/private-theming": {
|
"@mui/private-theming": {
|
||||||
"version": "5.11.7",
|
"version": "5.11.9",
|
||||||
"resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.11.7.tgz",
|
"resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.11.9.tgz",
|
||||||
"integrity": "sha512-XzRTSZdc8bhuUdjablTNv3kFkZ/XIMlKkOqqJCU0G8W3tWGXpau2DXkafPd1ddjPhF9zF3qLKNGgKCChYItjgA==",
|
"integrity": "sha512-XMyVIFGomVCmCm92EvYlgq3zrC9K+J6r7IKl/rBJT2/xVYoRY6uM7jeB+Wxh7kXxnW9Dbqsr2yL3cx6wSD1sAg==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@babel/runtime": "^7.20.7",
|
"@babel/runtime": "^7.20.13",
|
||||||
"@mui/utils": "^5.11.7",
|
"@mui/utils": "^5.11.9",
|
||||||
"prop-types": "^15.8.1"
|
"prop-types": "^15.8.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@mui/styled-engine": {
|
"@mui/styled-engine": {
|
||||||
"version": "5.11.8",
|
"version": "5.11.9",
|
||||||
"resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.11.8.tgz",
|
"resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.11.9.tgz",
|
||||||
"integrity": "sha512-iSpZp9AoeictsDi5xAQ4PGXu7mKtQyzMl7ZaWpHIGMFpsNnfY3NQNg+wkj/gpsAZ+Zg+IIyD+t+ig71Kr9fa0w==",
|
"integrity": "sha512-bkh2CjHKOMy98HyOc8wQXEZvhOmDa/bhxMUekFX5IG0/w4f5HJ8R6+K6nakUUYNEgjOWPYzNPrvGB8EcGbhahQ==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@babel/runtime": "^7.20.7",
|
"@babel/runtime": "^7.20.13",
|
||||||
"@emotion/cache": "^11.10.5",
|
"@emotion/cache": "^11.10.5",
|
||||||
"csstype": "^3.1.1",
|
"csstype": "^3.1.1",
|
||||||
"prop-types": "^15.8.1"
|
"prop-types": "^15.8.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@mui/system": {
|
"@mui/system": {
|
||||||
"version": "5.11.8",
|
"version": "5.11.9",
|
||||||
"resolved": "https://registry.npmjs.org/@mui/system/-/system-5.11.8.tgz",
|
"resolved": "https://registry.npmjs.org/@mui/system/-/system-5.11.9.tgz",
|
||||||
"integrity": "sha512-zhroUcxAw2x/dISBJKhGbD70DOYCwMFRo7o/LUYTiUfQkfmLhRfEf1bopWgY9nYstn7QOxOq9fA3aR3pHrUTbw==",
|
"integrity": "sha512-h6uarf+l3FO6l75Nf7yO+qDGrIoa1DM9nAMCUFZQsNCDKOInRzcptnm8M1w/Z3gVetfeeGoIGAYuYKbft6KZZA==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@babel/runtime": "^7.20.7",
|
"@babel/runtime": "^7.20.13",
|
||||||
"@mui/private-theming": "^5.11.7",
|
"@mui/private-theming": "^5.11.9",
|
||||||
"@mui/styled-engine": "^5.11.8",
|
"@mui/styled-engine": "^5.11.9",
|
||||||
"@mui/types": "^7.2.3",
|
"@mui/types": "^7.2.3",
|
||||||
"@mui/utils": "^5.11.7",
|
"@mui/utils": "^5.11.9",
|
||||||
"clsx": "^1.2.1",
|
"clsx": "^1.2.1",
|
||||||
"csstype": "^3.1.1",
|
"csstype": "^3.1.1",
|
||||||
"prop-types": "^15.8.1"
|
"prop-types": "^15.8.1"
|
||||||
|
@ -20484,11 +20590,11 @@
|
||||||
"requires": {}
|
"requires": {}
|
||||||
},
|
},
|
||||||
"@mui/utils": {
|
"@mui/utils": {
|
||||||
"version": "5.11.7",
|
"version": "5.11.9",
|
||||||
"resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.11.7.tgz",
|
"resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.11.9.tgz",
|
||||||
"integrity": "sha512-8uyNDeVHZA804Ego20Erv8TpxlbqTe/EbhTI2H1UYr4/RiIbBprat8W4Qqr2UQIsC/b3DLz+0RQ6R/E5BxEcLA==",
|
"integrity": "sha512-eOJaqzcEs4qEwolcvFAmXGpln+uvouvOS9FUX6Wkrte+4I8rZbjODOBDVNlK+V6/ziTfD4iNKC0G+KfOTApbqg==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@babel/runtime": "^7.20.7",
|
"@babel/runtime": "^7.20.13",
|
||||||
"@types/prop-types": "^15.7.5",
|
"@types/prop-types": "^15.7.5",
|
||||||
"@types/react-is": "^16.7.1 || ^17.0.0",
|
"@types/react-is": "^16.7.1 || ^17.0.0",
|
||||||
"prop-types": "^15.8.1",
|
"prop-types": "^15.8.1",
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
"@emotion/react": "^11.10.5",
|
"@emotion/react": "^11.10.5",
|
||||||
"@emotion/styled": "^11.10.5",
|
"@emotion/styled": "^11.10.5",
|
||||||
"@mui/icons-material": "^5.11.0",
|
"@mui/icons-material": "^5.11.0",
|
||||||
|
"@mui/lab": "^5.0.0-alpha.120",
|
||||||
"@mui/material": "^5.11.7",
|
"@mui/material": "^5.11.7",
|
||||||
"@testing-library/jest-dom": "^5.16.5",
|
"@testing-library/jest-dom": "^5.16.5",
|
||||||
"@testing-library/react": "^13.4.0",
|
"@testing-library/react": "^13.4.0",
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
import useToken from "./hooks/useToken";
|
import useToken from "./hooks/useToken";
|
||||||
import Login from "./Login";
|
import Login from "./Login";
|
||||||
import { BrowserRouter, Route, Routes } from "react-router-dom";
|
import { BrowserRouter, Route, Routes } from "react-router-dom";
|
||||||
import { Box, Grid, Divider, createTheme, ThemeProvider } from "@mui/material";
|
import { Box, Grid, Divider } from "@mui/material";
|
||||||
import InstallationList from "./components/InstallationList";
|
|
||||||
import BasicTable from "./components/Table";
|
import BasicTable from "./components/Table";
|
||||||
import InstallationTabs from "./components/InstallationTabs";
|
import InstallationTabs from "./components/InstallationTabs";
|
||||||
import Alarms from "./routes/Alarms";
|
import Alarms from "./routes/Alarms";
|
||||||
|
@ -17,20 +16,13 @@ import LanguageSelect from "./components/LanguageSelect";
|
||||||
import LogoutButton from "./components/LogoutButton";
|
import LogoutButton from "./components/LogoutButton";
|
||||||
import NavigationButtons from "./components/NavigationButtons";
|
import NavigationButtons from "./components/NavigationButtons";
|
||||||
import UserList from "./components/UserTree";
|
import UserList from "./components/UserTree";
|
||||||
|
import Sidebar from "./components/Sidebar";
|
||||||
|
|
||||||
const App = () => {
|
const App = () => {
|
||||||
const { token, setToken, removeToken } = useToken();
|
const { token, setToken, removeToken } = useToken();
|
||||||
const [language, setLanguage] = useState("en");
|
const [language, setLanguage] = useState("en");
|
||||||
const [currentView, setCurrentView] = useState("installations");
|
const [currentView, setCurrentView] = useState("installations");
|
||||||
|
|
||||||
const theme = createTheme({
|
|
||||||
palette: {
|
|
||||||
primary: {
|
|
||||||
main: "#F59100",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const getTranslations = () => {
|
const getTranslations = () => {
|
||||||
if (language === "de") {
|
if (language === "de") {
|
||||||
return de;
|
return de;
|
||||||
|
@ -44,62 +36,53 @@ const App = () => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<BrowserRouter>
|
<BrowserRouter>
|
||||||
<ThemeProvider theme={theme}>
|
<IntlProvider
|
||||||
<IntlProvider
|
messages={getTranslations()}
|
||||||
messages={getTranslations()}
|
locale={language}
|
||||||
locale={language}
|
defaultLocale="en"
|
||||||
defaultLocale="en"
|
>
|
||||||
>
|
<Grid container justifyContent="flex-end" sx={{ px: 1, pt: 1 }}>
|
||||||
<Grid container justifyContent="flex-end" sx={{ px: 1, pt: 1 }}>
|
<LanguageSelect language={language} setLanguage={setLanguage} />
|
||||||
<LanguageSelect language={language} setLanguage={setLanguage} />
|
<LogoutButton removeToken={removeToken} />
|
||||||
<LogoutButton removeToken={removeToken} />
|
</Grid>
|
||||||
</Grid>
|
<Box sx={{ p: 1 }}>
|
||||||
<Box sx={{ p: 1 }}>
|
<Grid container spacing={2}>
|
||||||
<Grid container spacing={2}>
|
<Grid item xs={3}>
|
||||||
<Grid item xs={3}>
|
<NavigationButtons
|
||||||
<NavigationButtons
|
currentView={currentView}
|
||||||
currentView={currentView}
|
setCurrentView={setCurrentView}
|
||||||
setCurrentView={setCurrentView}
|
/>
|
||||||
/>
|
{currentView === "installations" ? <Sidebar /> : <UserList />}
|
||||||
{currentView === "installations" ? (
|
|
||||||
<InstallationList />
|
|
||||||
) : (
|
|
||||||
<UserList />
|
|
||||||
)}
|
|
||||||
</Grid>
|
|
||||||
<Grid
|
|
||||||
item
|
|
||||||
xs={1}
|
|
||||||
container
|
|
||||||
direction="row"
|
|
||||||
justifyContent="center"
|
|
||||||
alignItems="center"
|
|
||||||
>
|
|
||||||
<Divider orientation="vertical" variant="middle" />
|
|
||||||
</Grid>
|
|
||||||
<Grid item xs={8}>
|
|
||||||
{currentView === "installations" && (
|
|
||||||
<>
|
|
||||||
<InstallationTabs />
|
|
||||||
<Routes>
|
|
||||||
<Route
|
|
||||||
path={routes.installationWithId}
|
|
||||||
element={<InstallationDetail />}
|
|
||||||
/>
|
|
||||||
<Route path={routes.alarmsWithId} element={<Alarms />} />
|
|
||||||
<Route
|
|
||||||
path={routes.usersWithId}
|
|
||||||
element={<BasicTable />}
|
|
||||||
/>
|
|
||||||
<Route path={routes.logWithId} element={<Log />} />
|
|
||||||
</Routes>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
</Grid>
|
|
||||||
</Grid>
|
</Grid>
|
||||||
</Box>
|
<Grid
|
||||||
</IntlProvider>
|
item
|
||||||
</ThemeProvider>
|
xs={1}
|
||||||
|
container
|
||||||
|
direction="row"
|
||||||
|
justifyContent="center"
|
||||||
|
alignItems="center"
|
||||||
|
>
|
||||||
|
<Divider orientation="vertical" variant="middle" />
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={8}>
|
||||||
|
{currentView === "installations" && (
|
||||||
|
<>
|
||||||
|
<InstallationTabs />
|
||||||
|
<Routes>
|
||||||
|
<Route
|
||||||
|
path={routes.installationWithId}
|
||||||
|
element={<InstallationDetail />}
|
||||||
|
/>
|
||||||
|
<Route path={routes.alarmsWithId} element={<Alarms />} />
|
||||||
|
<Route path={routes.usersWithId} element={<BasicTable />} />
|
||||||
|
<Route path={routes.logWithId} element={<Log />} />
|
||||||
|
</Routes>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
</Box>
|
||||||
|
</IntlProvider>
|
||||||
</BrowserRouter>
|
</BrowserRouter>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
import { Alert, Button, Grid, InputLabel, Snackbar } from "@mui/material";
|
import { Alert, Button, Grid, Snackbar } from "@mui/material";
|
||||||
import { useFormik } from "formik";
|
import { useFormik } from "formik";
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import { FormattedMessage, useIntl } from "react-intl";
|
import { FormattedMessage, useIntl } from "react-intl";
|
||||||
import axiosConfig from "../config/axiosConfig";
|
import axiosConfig from "../config/axiosConfig";
|
||||||
import { I_Installation } from "../util/installation.util";
|
import { I_Installation } from "../util/types";
|
||||||
import InnovenergyTextfield from "./InnovenergyTextfield";
|
import InnovenergyTextfield from "./InnovenergyTextfield";
|
||||||
|
|
||||||
interface I_CustomerFormProps {
|
interface I_CustomerFormProps {
|
||||||
|
|
|
@ -1,14 +1,17 @@
|
||||||
import List from "@mui/material/List";
|
import List from "@mui/material/List";
|
||||||
import ListItemButton from "@mui/material/ListItemButton";
|
import ListItemButton from "@mui/material/ListItemButton";
|
||||||
import ListItemText from "@mui/material/ListItemText";
|
import ListItemText from "@mui/material/ListItemText";
|
||||||
import { Divider, TextField } from "@mui/material";
|
import { CircularProgress, Divider, Grid } from "@mui/material";
|
||||||
import { Link } from "react-router-dom";
|
import { Link } from "react-router-dom";
|
||||||
import useRouteMatch from "../hooks/useRouteMatch";
|
import useRouteMatch from "../hooks/useRouteMatch";
|
||||||
import routes from "../routes.json";
|
import routes from "../routes.json";
|
||||||
import { Fragment, useEffect, useState } from "react";
|
import { Fragment, useEffect, useState } from "react";
|
||||||
import { I_Installation } from "../util/installation.util";
|
import { I_Installation } from "../util/types";
|
||||||
import axiosConfig from "../config/axiosConfig";
|
import axiosConfig from "../config/axiosConfig";
|
||||||
import { useIntl } from "react-intl";
|
|
||||||
|
interface InstallationListProps {
|
||||||
|
searchQuery: string;
|
||||||
|
}
|
||||||
|
|
||||||
const getPathWithoutId = (path?: string) => {
|
const getPathWithoutId = (path?: string) => {
|
||||||
if (path) {
|
if (path) {
|
||||||
|
@ -32,11 +35,10 @@ const filterData = (
|
||||||
return data;
|
return data;
|
||||||
};
|
};
|
||||||
|
|
||||||
const InstallationList = () => {
|
const InstallationList = (props: InstallationListProps) => {
|
||||||
const [data, setData] = useState<I_Installation[]>();
|
const [data, setData] = useState<I_Installation[]>();
|
||||||
const [searchQuery, setSearchQuery] = useState("");
|
const [loading, setLoading] = useState(false);
|
||||||
const intl = useIntl();
|
const filteredData = filterData(props.searchQuery, data);
|
||||||
const filteredData = filterData(searchQuery, data);
|
|
||||||
|
|
||||||
const routeMatch = useRouteMatch([
|
const routeMatch = useRouteMatch([
|
||||||
routes.installationWithId,
|
routes.installationWithId,
|
||||||
|
@ -46,55 +48,55 @@ const InstallationList = () => {
|
||||||
]);
|
]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
setLoading(true);
|
||||||
axiosConfig.get("/GetAllInstallations", {}).then((res) => {
|
axiosConfig.get("/GetAllInstallations", {}).then((res) => {
|
||||||
setData(res.data);
|
setData(res.data);
|
||||||
|
setLoading(false);
|
||||||
});
|
});
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<TextField
|
{loading && (
|
||||||
id="outlined-search"
|
<Grid container justifyContent="center" width="100%">
|
||||||
label={intl.formatMessage({
|
<CircularProgress sx={{ m: 6 }} />
|
||||||
id: "search",
|
</Grid>
|
||||||
defaultMessage: "Search",
|
)}
|
||||||
})}
|
{data && (
|
||||||
type="search"
|
<List
|
||||||
fullWidth
|
sx={{
|
||||||
value={searchQuery}
|
width: "100%",
|
||||||
onChange={(e) => setSearchQuery(e.target.value)}
|
bgcolor: "background.paper",
|
||||||
/>
|
position: "relative",
|
||||||
<List
|
overflow: "auto",
|
||||||
sx={{
|
maxHeight: 400,
|
||||||
width: "100%",
|
py: 0,
|
||||||
bgcolor: "background.paper",
|
mt: 1,
|
||||||
position: "relative",
|
}}
|
||||||
overflow: "auto",
|
component="nav"
|
||||||
maxHeight: 400,
|
aria-labelledby="nested-list-subheader"
|
||||||
py: 0,
|
>
|
||||||
mt: 1,
|
{filteredData?.map((installation) => (
|
||||||
}}
|
<Fragment key={installation.id}>
|
||||||
component="nav"
|
<Link
|
||||||
aria-labelledby="nested-list-subheader"
|
to={
|
||||||
>
|
getPathWithoutId(routeMatch?.pattern?.path) + installation.id
|
||||||
{filteredData?.map((installation) => (
|
}
|
||||||
<Fragment key={installation.id}>
|
style={{ textDecoration: "none", color: "black" }}
|
||||||
<Link
|
|
||||||
to={getPathWithoutId(routeMatch?.pattern?.path) + installation.id}
|
|
||||||
style={{ textDecoration: "none", color: "black" }}
|
|
||||||
>
|
|
||||||
<ListItemButton
|
|
||||||
selected={installation.id === Number(routeMatch?.params.id)}
|
|
||||||
>
|
>
|
||||||
<ListItemText
|
<ListItemButton
|
||||||
primary={installation.location + " | " + installation.name}
|
selected={installation.id === Number(routeMatch?.params.id)}
|
||||||
/>
|
>
|
||||||
</ListItemButton>
|
<ListItemText
|
||||||
</Link>
|
primary={installation.location + " | " + installation.name}
|
||||||
<Divider />
|
/>
|
||||||
</Fragment>
|
</ListItemButton>
|
||||||
))}
|
</Link>
|
||||||
</List>
|
<Divider />
|
||||||
|
</Fragment>
|
||||||
|
))}
|
||||||
|
</List>
|
||||||
|
)}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
import { TextField } from "@mui/material";
|
||||||
|
import { useState } from "react";
|
||||||
|
import { useIntl } from "react-intl";
|
||||||
|
import InstallationList from "./InstallationList";
|
||||||
|
|
||||||
|
const Sidebar = () => {
|
||||||
|
const [searchQuery, setSearchQuery] = useState("");
|
||||||
|
const intl = useIntl();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<TextField
|
||||||
|
id="outlined-search"
|
||||||
|
label={intl.formatMessage({
|
||||||
|
id: "search",
|
||||||
|
defaultMessage: "Search",
|
||||||
|
})}
|
||||||
|
type="search"
|
||||||
|
fullWidth
|
||||||
|
value={searchQuery}
|
||||||
|
onChange={(e) => setSearchQuery(e.target.value)}
|
||||||
|
/>
|
||||||
|
<InstallationList searchQuery={searchQuery} />
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Sidebar;
|
|
@ -1,5 +1,137 @@
|
||||||
|
import TreeView from "@mui/lab/TreeView";
|
||||||
|
import ExpandMoreIcon from "@mui/icons-material/ExpandMore";
|
||||||
|
import ChevronRightIcon from "@mui/icons-material/ChevronRight";
|
||||||
|
import { ReactNode } from "react";
|
||||||
|
import { TreeItem } from "@mui/lab";
|
||||||
|
import { I_Folder, I_Installation } from "../util/types";
|
||||||
const UserList = () => {
|
const UserList = () => {
|
||||||
return <div>Userlist</div>;
|
const data: I_Folder[] = [
|
||||||
|
{
|
||||||
|
id: 107,
|
||||||
|
name: "Bruen-Tromp",
|
||||||
|
information: "05 Burrows Terrace",
|
||||||
|
parentId: 75,
|
||||||
|
type: "Folder",
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
id: 100,
|
||||||
|
name: "Sporer and Sons",
|
||||||
|
information: "820 Helena Terrace",
|
||||||
|
parentId: 107,
|
||||||
|
type: "Folder",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 101,
|
||||||
|
name: "Hahn-Heaney",
|
||||||
|
information: "144 Di Loreto Center",
|
||||||
|
parentId: 107,
|
||||||
|
type: "Folder",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 125,
|
||||||
|
name: "Sporer and Sons",
|
||||||
|
information: "820 Helena Terrace",
|
||||||
|
parentId: 107,
|
||||||
|
type: "Folder",
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
location: "Säffle",
|
||||||
|
region: "SG",
|
||||||
|
country: "SE",
|
||||||
|
orderNumbers: "1LWDGmdXCLmCRFJHTKwcmpoP7bcNeaWJuj",
|
||||||
|
lat: 0,
|
||||||
|
long: 0,
|
||||||
|
s3Bucket: "",
|
||||||
|
id: 632,
|
||||||
|
name: "Nikolas Scholz",
|
||||||
|
information: "",
|
||||||
|
parentId: 125,
|
||||||
|
type: "Installation",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
location: "Krasnoye",
|
||||||
|
region: "ZH",
|
||||||
|
country: "RU",
|
||||||
|
orderNumbers: "1M4Rw8toMSJn3d8ULouDd1gYKzANFXeMWh",
|
||||||
|
lat: 0,
|
||||||
|
long: 0,
|
||||||
|
s3Bucket: "",
|
||||||
|
id: 248,
|
||||||
|
name: "Judye Goldson",
|
||||||
|
information: "",
|
||||||
|
parentId: 125,
|
||||||
|
type: "Installation",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 103,
|
||||||
|
name: "Bruen-Tromp",
|
||||||
|
information: "05 Burrows Terrace",
|
||||||
|
parentId: 75,
|
||||||
|
type: "Folder",
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
id: 100,
|
||||||
|
name: "Sporer and Sons",
|
||||||
|
information: "820 Helena Terrace",
|
||||||
|
parentId: 107,
|
||||||
|
type: "Folder",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 101,
|
||||||
|
name: "Hahn-Heaney",
|
||||||
|
information: "144 Di Loreto Center",
|
||||||
|
parentId: 107,
|
||||||
|
type: "Folder",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 135,
|
||||||
|
name: "Hahn-Heaney",
|
||||||
|
information: "144 Di Loreto Center",
|
||||||
|
parentId: 107,
|
||||||
|
type: "Folder",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const instanceOfFolder = (object: any): object is I_Folder => {
|
||||||
|
return "children" in object;
|
||||||
|
};
|
||||||
|
|
||||||
|
const getNodes = (element: I_Folder | I_Installation): null | ReactNode => {
|
||||||
|
if (instanceOfFolder(element)) {
|
||||||
|
return element.children ? renderTree(element.children) : null;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
|
||||||
|
const renderTree = (data: (I_Folder | I_Installation)[]): ReactNode => {
|
||||||
|
return data.map((element) => {
|
||||||
|
return (
|
||||||
|
<TreeItem
|
||||||
|
key={element.id}
|
||||||
|
nodeId={element.id.toString()}
|
||||||
|
label={element.name}
|
||||||
|
>
|
||||||
|
{getNodes(element)}
|
||||||
|
</TreeItem>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
return (
|
||||||
|
<TreeView
|
||||||
|
aria-label="rich object"
|
||||||
|
defaultCollapseIcon={<ExpandMoreIcon />}
|
||||||
|
defaultExpandIcon={<ChevronRightIcon />}
|
||||||
|
sx={{ height: 300, flexGrow: 1, maxWidth: 400 }}
|
||||||
|
>
|
||||||
|
{renderTree(data)}
|
||||||
|
</TreeView>
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default UserList;
|
export default UserList;
|
||||||
|
|
|
@ -1,16 +1,28 @@
|
||||||
import React from 'react';
|
import React from "react";
|
||||||
import ReactDOM from 'react-dom/client';
|
import ReactDOM from "react-dom/client";
|
||||||
import './index.css';
|
import "./index.css";
|
||||||
import App from './App';
|
import App from "./App";
|
||||||
import reportWebVitals from './reportWebVitals';
|
import reportWebVitals from "./reportWebVitals";
|
||||||
|
import { createTheme, ThemeProvider } from "@mui/material";
|
||||||
|
|
||||||
const root = ReactDOM.createRoot(
|
const root = ReactDOM.createRoot(
|
||||||
document.getElementById('root') as HTMLElement
|
document.getElementById("root") as HTMLElement
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const theme = createTheme({
|
||||||
|
palette: {
|
||||||
|
primary: {
|
||||||
|
main: "#F59100",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
root.render(
|
root.render(
|
||||||
<React.StrictMode>
|
<React.StrictMode>
|
||||||
|
<ThemeProvider theme={theme}>
|
||||||
<App />
|
<App />
|
||||||
</React.StrictMode>,
|
</ThemeProvider>
|
||||||
|
</React.StrictMode>
|
||||||
);
|
);
|
||||||
|
|
||||||
// If you want to start measuring performance in your app, pass a function
|
// If you want to start measuring performance in your app, pass a function
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
{
|
{
|
||||||
"installationWithId": "/installation/:id",
|
"installationWithId": "/installation/:id",
|
||||||
"installation": "/installation/",
|
"installation": "/installation/",
|
||||||
"alarmsWithId": "/alarms/:id",
|
"alarmsWithId": "/alarms/:id",
|
||||||
"alarms": "/alarms/",
|
"alarms": "/alarms/",
|
||||||
"usersWithId":"/users/:id",
|
"usersWithId": "/users/:id",
|
||||||
"users":"/users/",
|
"users": "/users/",
|
||||||
"logWithId": "/log/:id",
|
"logWithId": "/log/:id",
|
||||||
"log": "/log/"
|
"log": "/log/",
|
||||||
}
|
"installations": "/installations"
|
||||||
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@ import { useEffect, useState } from "react";
|
||||||
import { useParams } from "react-router-dom";
|
import { useParams } from "react-router-dom";
|
||||||
import CustomerForm from "../components/CustomerForm";
|
import CustomerForm from "../components/CustomerForm";
|
||||||
import axiosConfig from "../config/axiosConfig";
|
import axiosConfig from "../config/axiosConfig";
|
||||||
import { I_Installation } from "../util/installation.util";
|
import { I_Installation } from "../util/types";
|
||||||
|
|
||||||
const InstallationDetail = () => {
|
const InstallationDetail = () => {
|
||||||
const { id } = useParams();
|
const { id } = useParams();
|
||||||
|
@ -13,20 +13,17 @@ const InstallationDetail = () => {
|
||||||
const [error, setError] = useState<AxiosError>();
|
const [error, setError] = useState<AxiosError>();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (id !== "undefined") {
|
setLoading(true);
|
||||||
console.log(id);
|
axiosConfig
|
||||||
setLoading(true);
|
.get("/GetInstallationById?id=" + id)
|
||||||
axiosConfig
|
.then((res) => {
|
||||||
.get("/GetInstallationById?id=" + id)
|
setValues(res.data);
|
||||||
.then((res) => {
|
setLoading(false);
|
||||||
setValues(res.data);
|
})
|
||||||
setLoading(false);
|
.catch((err: AxiosError) => {
|
||||||
})
|
setError(err);
|
||||||
.catch((err: AxiosError) => {
|
setLoading(false);
|
||||||
setError(err);
|
});
|
||||||
setLoading(false);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}, [id]);
|
}, [id]);
|
||||||
|
|
||||||
if (values && values.id && values.id.toString() === id) {
|
if (values && values.id && values.id.toString() === id) {
|
||||||
|
@ -36,7 +33,13 @@ const InstallationDetail = () => {
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
} else if (loading) {
|
} else if (loading) {
|
||||||
return <CircularProgress sx={{ m: 2 }} />;
|
return (
|
||||||
|
<Box
|
||||||
|
sx={{ width: 1 / 2, justifyContent: "center", display: "flex", mt: 10 }}
|
||||||
|
>
|
||||||
|
<CircularProgress sx={{ m: 2 }} />
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
} else if (error) {
|
} else if (error) {
|
||||||
return (
|
return (
|
||||||
<Alert severity="error" sx={{ mt: 1 }}>
|
<Alert severity="error" sx={{ mt: 1 }}>
|
||||||
|
|
|
@ -1,19 +1,28 @@
|
||||||
// TODO add if required or not
|
// TODO add if required or not
|
||||||
export interface I_Installation {
|
export interface I_Installation {
|
||||||
type: string;
|
type: string;
|
||||||
title: string;
|
title: string;
|
||||||
status: number;
|
status: number;
|
||||||
detail: string;
|
detail: string;
|
||||||
instance: string;
|
instance: string;
|
||||||
location: string;
|
location: string;
|
||||||
region: string;
|
region: string;
|
||||||
country: string;
|
country: string;
|
||||||
orderNumbers: string;
|
orderNumbers: string;
|
||||||
lat: number;
|
lat: number;
|
||||||
long: number;
|
long: number;
|
||||||
s3Bucket: string;
|
s3Bucket: string;
|
||||||
id: number;
|
id: number;
|
||||||
name: string;
|
name: string;
|
||||||
information: string;
|
information: string;
|
||||||
parentId: number;
|
parentId: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface I_Folder {
|
||||||
|
id: number;
|
||||||
|
name: string;
|
||||||
|
information: string;
|
||||||
|
parentId: number;
|
||||||
|
type: string;
|
||||||
|
children?: (I_Installation | I_Folder)[];
|
||||||
|
}
|
Loading…
Reference in New Issue