From 633c3de5bc8539e63f58c1ce84f26c989254828a Mon Sep 17 00:00:00 2001 From: Sina Blattmann Date: Thu, 23 Feb 2023 16:37:14 +0100 Subject: [PATCH] [WIP] style changes, work on error handling and user feedback --- typescript/Frontend/src/App.tsx | 112 ++++++---- .../Frontend/src/components/CustomerForm.tsx | 19 +- .../src/components/InnovenergyTextfield.tsx | 34 +-- .../{NestedList.tsx => InstallationList.tsx} | 197 +++++++++--------- .../src/components/InstallationTabs.tsx | 73 +++++++ .../src/components/LanguageSelect.tsx | 1 - .../src/components/NavigationButtons.tsx | 35 +++- typescript/Frontend/src/components/Tabs.tsx | 82 -------- .../Frontend/src/components/UserTree.tsx | 5 + typescript/Frontend/src/lang/en.json | 4 +- .../Frontend/src/routes/Installation.tsx | 39 ++-- 11 files changed, 331 insertions(+), 270 deletions(-) rename typescript/Frontend/src/components/{NestedList.tsx => InstallationList.tsx} (90%) create mode 100644 typescript/Frontend/src/components/InstallationTabs.tsx delete mode 100644 typescript/Frontend/src/components/Tabs.tsx create mode 100644 typescript/Frontend/src/components/UserTree.tsx diff --git a/typescript/Frontend/src/App.tsx b/typescript/Frontend/src/App.tsx index 21278ba28..59d9a6a33 100644 --- a/typescript/Frontend/src/App.tsx +++ b/typescript/Frontend/src/App.tsx @@ -1,10 +1,10 @@ import useToken from "./hooks/useToken"; import Login from "./Login"; import { BrowserRouter, Route, Routes } from "react-router-dom"; -import { Box, Grid, Divider } from "@mui/material"; -import NestedList from "./components/NestedList"; +import { Box, Grid, Divider, createTheme, ThemeProvider } from "@mui/material"; +import InstallationList from "./components/InstallationList"; import BasicTable from "./components/Table"; -import BasicTabs from "./components/Tabs"; +import InstallationTabs from "./components/InstallationTabs"; import Alarms from "./routes/Alarms"; import InstallationDetail from "./routes/Installation"; import Log from "./routes/Log"; @@ -13,11 +13,23 @@ import { IntlProvider } from "react-intl"; import { useState } from "react"; import en from "./lang/en.json"; import de from "./lang/de.json"; +import LanguageSelect from "./components/LanguageSelect"; +import LogoutButton from "./components/LogoutButton"; import NavigationButtons from "./components/NavigationButtons"; +import UserList from "./components/UserTree"; const App = () => { const { token, setToken, removeToken } = useToken(); const [language, setLanguage] = useState("en"); + const [currentView, setCurrentView] = useState("installations"); + + const theme = createTheme({ + palette: { + primary: { + main: "#F59100", + }, + }, + }); const getTranslations = () => { if (language === "de") { @@ -32,46 +44,62 @@ const App = () => { return ( - - - - - - - - - - - - - - } - /> - } /> - } /> - } /> - - + + + + + - - + + + + + {currentView === "installations" ? ( + + ) : ( + + )} + + + + + + {currentView === "installations" && ( + <> + + + } + /> + } /> + } + /> + } /> + + + )} + + + + + ); }; diff --git a/typescript/Frontend/src/components/CustomerForm.tsx b/typescript/Frontend/src/components/CustomerForm.tsx index 9c5d70897..eb0d6e3c1 100644 --- a/typescript/Frontend/src/components/CustomerForm.tsx +++ b/typescript/Frontend/src/components/CustomerForm.tsx @@ -1,4 +1,4 @@ -import { Alert, Button, Snackbar } from "@mui/material"; +import { Alert, Button, Grid, InputLabel, Snackbar } from "@mui/material"; import { useFormik } from "formik"; import { useState } from "react"; import { FormattedMessage, useIntl } from "react-intl"; @@ -92,20 +92,25 @@ const CustomerForm = (props: I_CustomerFormProps) => { value={formik.values.orderNumbers} handleChange={formik.handleChange} /> - + + + - + diff --git a/typescript/Frontend/src/components/InnovenergyTextfield.tsx b/typescript/Frontend/src/components/InnovenergyTextfield.tsx index 6f857db14..0bcd5b57e 100644 --- a/typescript/Frontend/src/components/InnovenergyTextfield.tsx +++ b/typescript/Frontend/src/components/InnovenergyTextfield.tsx @@ -1,4 +1,4 @@ -import { TextField } from "@mui/material"; +import { Grid, InputLabel, TextField } from "@mui/material"; interface I_InnovenergyTextfieldProps { id: string; @@ -7,21 +7,31 @@ interface I_InnovenergyTextfieldProps { name: string; handleChange: (e: React.ChangeEvent) => void; type?: string; + readOnly?: boolean; } const InnovenergyTextfield = (props: I_InnovenergyTextfieldProps) => { return ( - + + + {props.label} + + + + + ); }; diff --git a/typescript/Frontend/src/components/NestedList.tsx b/typescript/Frontend/src/components/InstallationList.tsx similarity index 90% rename from typescript/Frontend/src/components/NestedList.tsx rename to typescript/Frontend/src/components/InstallationList.tsx index d9d25b62c..e3170bfa6 100644 --- a/typescript/Frontend/src/components/NestedList.tsx +++ b/typescript/Frontend/src/components/InstallationList.tsx @@ -1,95 +1,102 @@ -import List from "@mui/material/List"; -import ListItemButton from "@mui/material/ListItemButton"; -import ListItemText from "@mui/material/ListItemText"; -import { Divider, TextField } from "@mui/material"; -import { Link } from "react-router-dom"; -import useRouteMatch from "../hooks/useRouteMatch"; -import routes from "../routes.json"; -import { Fragment, useEffect, useState } from "react"; -import { I_Installation } from "../util/installation.util"; -import axiosConfig from "../config/axiosConfig"; -import { useIntl } from "react-intl"; - -const getPathWithoutId = (path?: string) => { - if (path) { - const splitString = path.split(":"); - return splitString[0]; - } - return routes.installation; -}; - -const filterData = ( - searchQuery: string, - data: I_Installation[] | undefined -) => { - if (data) { - return data.filter( - (installation) => - installation.name.toLowerCase().includes(searchQuery.toLowerCase()) || - installation.location.toLowerCase().includes(searchQuery.toLowerCase()) - ); - } - return data; -}; - -const NestedList = () => { - const [data, setData] = useState(); - const [searchQuery, setSearchQuery] = useState(""); - const intl = useIntl(); - const filteredData = filterData(searchQuery, data); - - const routeMatch = useRouteMatch([ - routes.installationWithId, - routes.alarmsWithId, - routes.usersWithId, - routes.logWithId, - ]); - - useEffect(() => { - console.log("useeffect"); - axiosConfig.get("/GetAllInstallations", {}).then((res) => { - setData(res.data); - }); - }, []); - - return ( - <> - setSearchQuery(e.target.value)} - /> - - {filteredData?.map((installation) => ( - - - - - - - - - ))} - - - ); -}; - -export default NestedList; +import List from "@mui/material/List"; +import ListItemButton from "@mui/material/ListItemButton"; +import ListItemText from "@mui/material/ListItemText"; +import { Divider, TextField } from "@mui/material"; +import { Link } from "react-router-dom"; +import useRouteMatch from "../hooks/useRouteMatch"; +import routes from "../routes.json"; +import { Fragment, useEffect, useState } from "react"; +import { I_Installation } from "../util/installation.util"; +import axiosConfig from "../config/axiosConfig"; +import { useIntl } from "react-intl"; + +const getPathWithoutId = (path?: string) => { + if (path) { + const splitString = path.split(":"); + return splitString[0]; + } + return routes.installation; +}; + +const filterData = ( + searchQuery: string, + data: I_Installation[] | undefined +) => { + if (data) { + return data.filter( + (installation) => + installation.name.toLowerCase().includes(searchQuery.toLowerCase()) || + installation.location.toLowerCase().includes(searchQuery.toLowerCase()) + ); + } + return data; +}; + +const InstallationList = () => { + const [data, setData] = useState(); + const [searchQuery, setSearchQuery] = useState(""); + const intl = useIntl(); + const filteredData = filterData(searchQuery, data); + + const routeMatch = useRouteMatch([ + routes.installationWithId, + routes.alarmsWithId, + routes.usersWithId, + routes.logWithId, + ]); + + useEffect(() => { + axiosConfig.get("/GetAllInstallations", {}).then((res) => { + setData(res.data); + }); + }, []); + + return ( + <> + setSearchQuery(e.target.value)} + /> + + {filteredData?.map((installation) => ( + + + + + + + + + ))} + + + ); +}; + +export default InstallationList; diff --git a/typescript/Frontend/src/components/InstallationTabs.tsx b/typescript/Frontend/src/components/InstallationTabs.tsx new file mode 100644 index 000000000..8291357ac --- /dev/null +++ b/typescript/Frontend/src/components/InstallationTabs.tsx @@ -0,0 +1,73 @@ +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 InstallationTabs = () => { + const routeMatch = useRouteMatch([ + routes.installationWithId, + routes.alarmsWithId, + routes.usersWithId, + routes.logWithId, + ]); + + const id = routeMatch?.params?.id; + const intl = useIntl(); + + if (id) { + return ( + + + + + + + + + + + ); + } + return null; +}; + +export default InstallationTabs; diff --git a/typescript/Frontend/src/components/LanguageSelect.tsx b/typescript/Frontend/src/components/LanguageSelect.tsx index a90217bc4..6349befc0 100644 --- a/typescript/Frontend/src/components/LanguageSelect.tsx +++ b/typescript/Frontend/src/components/LanguageSelect.tsx @@ -13,7 +13,6 @@ const LanguageSelect = (props: LanguageSelectProps) => { value={props.language} label="Age" onChange={(e) => props.setLanguage(e.target.value)} - sx={{ ml: "auto" }} > diff --git a/typescript/Frontend/src/components/NavigationButtons.tsx b/typescript/Frontend/src/components/NavigationButtons.tsx index 9175a7410..21ccbde9a 100644 --- a/typescript/Frontend/src/components/NavigationButtons.tsx +++ b/typescript/Frontend/src/components/NavigationButtons.tsx @@ -1,23 +1,36 @@ -import { Button, ButtonGroup } from "@mui/material"; +import { ToggleButton, ToggleButtonGroup } from "@mui/material"; import { FormattedMessage } from "react-intl"; -const NavigationButtons = () => { +interface NavigationButtonsProps { + currentView: string; + setCurrentView: (value: string) => void; +} +const NavigationButtons = (props: NavigationButtonsProps) => { + const handleChange = ( + event: React.MouseEvent, + newAlignment: string + ) => { + props.setCurrentView(newAlignment); + }; + return ( - - - - + + ); }; diff --git a/typescript/Frontend/src/components/Tabs.tsx b/typescript/Frontend/src/components/Tabs.tsx deleted file mode 100644 index 5d3cadeb0..000000000 --- a/typescript/Frontend/src/components/Tabs.tsx +++ /dev/null @@ -1,82 +0,0 @@ -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"; -import LogoutButton from "./LogoutButton"; -import LanguageSelect from "./LanguageSelect"; - -interface BasicTabsProps { - removeToken: () => void; - language: string; - setLanguage: (language: string) => void; -} -const BasicTabs = (props: BasicTabsProps) => { - const routeMatch = useRouteMatch([ - routes.installationWithId, - routes.alarmsWithId, - routes.usersWithId, - routes.logWithId, - ]); - - const id = routeMatch?.params?.id; - const intl = useIntl(); - - return ( - - - - - - - - - - - - - ); -}; - -export default BasicTabs; diff --git a/typescript/Frontend/src/components/UserTree.tsx b/typescript/Frontend/src/components/UserTree.tsx new file mode 100644 index 000000000..57cb861c4 --- /dev/null +++ b/typescript/Frontend/src/components/UserTree.tsx @@ -0,0 +1,5 @@ +const UserList = () => { + return
Userlist
; +}; + +export default UserList; diff --git a/typescript/Frontend/src/lang/en.json b/typescript/Frontend/src/lang/en.json index 3197f95b6..8d6940a56 100644 --- a/typescript/Frontend/src/lang/en.json +++ b/typescript/Frontend/src/lang/en.json @@ -2,7 +2,7 @@ "alarms": "Alarms", "allInstallations": "All installations", "applyChanges": "Apply changes", - "country": "country", + "country": "Country", "customerName": "Customer name", "english": "English", "german": "German", @@ -15,4 +15,4 @@ "users": "Users", "logout": "Logout", "updatedSuccessfully": "Updated successfully" -} \ No newline at end of file +} diff --git a/typescript/Frontend/src/routes/Installation.tsx b/typescript/Frontend/src/routes/Installation.tsx index 9e856abf5..8bcd82fed 100644 --- a/typescript/Frontend/src/routes/Installation.tsx +++ b/typescript/Frontend/src/routes/Installation.tsx @@ -13,26 +13,23 @@ const InstallationDetail = () => { const [error, setError] = useState(); useEffect(() => { - setLoading(true); - axiosConfig - .get("/GetInstallationById?id=" + id) - .then((res) => { - setValues(res.data); - setLoading(false); - }) - .catch((err: AxiosError) => { - setError(err); - setLoading(false); - }); + if (id !== "undefined") { + console.log(id); + setLoading(true); + axiosConfig + .get("/GetInstallationById?id=" + id) + .then((res) => { + setValues(res.data); + setLoading(false); + }) + .catch((err: AxiosError) => { + setError(err); + setLoading(false); + }); + } }, [id]); - if (error) { - return ( - - {error.message} - - ); - } else if (values && values.id.toString() === id) { + if (values && values.id && values.id.toString() === id) { return ( @@ -40,6 +37,12 @@ const InstallationDetail = () => { ); } else if (loading) { return ; + } else if (error) { + return ( + + {error.message} + + ); } return null; };