update to git code before switching from fossil
This commit is contained in:
parent
9f1e1e4730
commit
dff51b0d53
|
@ -1,18 +1,114 @@
|
|||
import Home from "./routes/Home";
|
||||
import useToken from "./hooks/useToken";
|
||||
import Login from "./Login";
|
||||
import { BrowserRouter } from "react-router-dom";
|
||||
import { BrowserRouter, Route, Routes } from "react-router-dom";
|
||||
import {
|
||||
Box,
|
||||
Grid,
|
||||
ButtonGroup,
|
||||
Button,
|
||||
Divider,
|
||||
Select,
|
||||
MenuItem,
|
||||
} from "@mui/material";
|
||||
import NestedList from "./components/NestedList";
|
||||
import BasicTable from "./components/Table";
|
||||
import BasicTabs from "./components/Tabs";
|
||||
import Alarms from "./routes/Alarms";
|
||||
import InstallationDetail from "./routes/Installation";
|
||||
import Log from "./routes/Log";
|
||||
import routes from "./routes.json";
|
||||
import { FormattedMessage, IntlProvider } from "react-intl";
|
||||
import { useState } from "react";
|
||||
|
||||
const App = () => {
|
||||
const { token, setToken } = useToken();
|
||||
const [language, setLanguage] = useState("en");
|
||||
|
||||
if (!token) {
|
||||
return <Login setToken={setToken} />;
|
||||
}
|
||||
|
||||
const de = {
|
||||
allInstallations: "Alle Installationen",
|
||||
};
|
||||
|
||||
const en = {
|
||||
allInstallations: "All installations",
|
||||
};
|
||||
|
||||
const getTranslations = () => {
|
||||
if (language === "de") {
|
||||
return de;
|
||||
}
|
||||
return en;
|
||||
};
|
||||
|
||||
return (
|
||||
<BrowserRouter>
|
||||
<Home />
|
||||
<IntlProvider
|
||||
messages={getTranslations()}
|
||||
locale={language}
|
||||
defaultLocale="en"
|
||||
>
|
||||
<Box sx={{ padding: 2 }}>
|
||||
<Grid container spacing={2}>
|
||||
<Grid item xs={3}>
|
||||
<ButtonGroup
|
||||
variant="outlined"
|
||||
aria-label="outlined primary button group"
|
||||
sx={{ paddingBottom: 3 }}
|
||||
>
|
||||
<Button>
|
||||
<FormattedMessage
|
||||
id="allInstallations"
|
||||
defaultMessage="All installations"
|
||||
/>
|
||||
</Button>
|
||||
<Button>
|
||||
<FormattedMessage id="users" defaultMessage="Users" />
|
||||
</Button>
|
||||
</ButtonGroup>
|
||||
<NestedList />
|
||||
<Select
|
||||
labelId="demo-simple-select-label"
|
||||
id="demo-simple-select"
|
||||
value={language}
|
||||
label="Age"
|
||||
onChange={(e) => setLanguage(e.target.value)}
|
||||
>
|
||||
<MenuItem value="en">
|
||||
<FormattedMessage id="english" defaultMessage="English" />
|
||||
</MenuItem>
|
||||
<MenuItem value="de">
|
||||
<FormattedMessage id="german" defaultMessage="German" />
|
||||
</MenuItem>
|
||||
</Select>
|
||||
</Grid>
|
||||
<Grid
|
||||
item
|
||||
xs={1}
|
||||
container
|
||||
direction="row"
|
||||
justifyContent="center"
|
||||
alignItems="center"
|
||||
>
|
||||
<Divider orientation="vertical" variant="middle" />
|
||||
</Grid>
|
||||
<Grid item xs={8}>
|
||||
<BasicTabs />
|
||||
<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>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -1,15 +1,14 @@
|
|||
import React, { useState } from "react";
|
||||
import axios from "axios";
|
||||
import { Button, CircularProgress, TextField } from "@mui/material";
|
||||
import { Button, CircularProgress } from "@mui/material";
|
||||
import Container from "@mui/material/Container";
|
||||
import InnovenergyTextfield from "./components/InnovenergyTextfield";
|
||||
import { axiosConfigWithoutToken } from "./config/axiosConfig";
|
||||
|
||||
const loginUser = async (username: string, password: string) => {
|
||||
return axios
|
||||
.post("https://localhost:7087/api/Login", {
|
||||
return axiosConfigWithoutToken.post("/Login", {
|
||||
username,
|
||||
password,
|
||||
})
|
||||
.then((data) => data);
|
||||
});
|
||||
};
|
||||
|
||||
const Login = ({ setToken }: { setToken: any }) => {
|
||||
|
@ -26,24 +25,27 @@ const Login = ({ setToken }: { setToken: any }) => {
|
|||
};
|
||||
|
||||
return (
|
||||
<Container>
|
||||
<TextField
|
||||
id="outlined-basic"
|
||||
<Container maxWidth="xs" sx={{ p: 2, alignContent: "center" }}>
|
||||
<InnovenergyTextfield
|
||||
id="username-textfield"
|
||||
label="Username"
|
||||
variant="outlined"
|
||||
name="email"
|
||||
sx={{ my: 0.5 }}
|
||||
onChange={(e) => setUsername(e.target.value)}
|
||||
value={username}
|
||||
handleChange={(e) => setUsername(e.target.value)}
|
||||
/>
|
||||
<TextField
|
||||
id="outlined-password-input"
|
||||
<InnovenergyTextfield
|
||||
id="password-textfield"
|
||||
label="Password"
|
||||
name="password"
|
||||
type="password"
|
||||
autoComplete="current-password"
|
||||
sx={{ my: 0.5 }}
|
||||
onChange={(e) => setPassword(e.target.value)}
|
||||
value={password}
|
||||
handleChange={(e) => setPassword(e.target.value)}
|
||||
/>
|
||||
<Button onClick={handleSubmit}>Login</Button>
|
||||
<div>
|
||||
<Button variant="outlined" onClick={handleSubmit} sx={{ my: 1 }}>
|
||||
Login
|
||||
</Button>
|
||||
</div>
|
||||
{loading && <CircularProgress />}
|
||||
</Container>
|
||||
);
|
||||
|
|
|
@ -0,0 +1,95 @@
|
|||
import { Button } from "@mui/material";
|
||||
import { useFormik } from "formik";
|
||||
import { FormattedMessage, useIntl } from "react-intl";
|
||||
import axiosConfig from "../config/axiosConfig";
|
||||
import { I_Installation } from "../util/installation.util";
|
||||
import InnovenergyTextfield from "./InnovenergyTextfield";
|
||||
|
||||
interface I_CustomerFormProps {
|
||||
values: I_Installation;
|
||||
id: string | undefined;
|
||||
}
|
||||
const CustomerForm = (props: I_CustomerFormProps) => {
|
||||
const { values, id } = props;
|
||||
const intl = useIntl();
|
||||
|
||||
const formik = useFormik({
|
||||
initialValues: {
|
||||
name: values.name,
|
||||
region: values.region,
|
||||
location: values.location,
|
||||
country: values.country,
|
||||
orderNumber: values.orderNumber,
|
||||
},
|
||||
onSubmit: (formikValues) => {
|
||||
axiosConfig
|
||||
.put("https://localhost:7087/api/UpdateInstallation", {
|
||||
...formikValues,
|
||||
id,
|
||||
})
|
||||
.then((res) => {
|
||||
console.log(res);
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
return (
|
||||
<form onSubmit={formik.handleSubmit}>
|
||||
<InnovenergyTextfield
|
||||
id="name-textfield"
|
||||
label={intl.formatMessage({
|
||||
id: "customerName",
|
||||
defaultMessage: "Customer name",
|
||||
})}
|
||||
name="name"
|
||||
value={formik.values.name}
|
||||
handleChange={formik.handleChange}
|
||||
/>
|
||||
<InnovenergyTextfield
|
||||
id="region-textfield"
|
||||
label={intl.formatMessage({
|
||||
id: "region",
|
||||
defaultMessage: "Region",
|
||||
})}
|
||||
name="region"
|
||||
value={formik.values.region}
|
||||
handleChange={formik.handleChange}
|
||||
/>
|
||||
<InnovenergyTextfield
|
||||
id="location-textfield"
|
||||
label={intl.formatMessage({
|
||||
id: "location",
|
||||
defaultMessage: "Location",
|
||||
})}
|
||||
name="location"
|
||||
value={formik.values.location}
|
||||
handleChange={formik.handleChange}
|
||||
/>
|
||||
<InnovenergyTextfield
|
||||
id="country-textfield"
|
||||
label={intl.formatMessage({
|
||||
id: "country",
|
||||
defaultMessage: "Country",
|
||||
})}
|
||||
name="country"
|
||||
value={formik.values.country}
|
||||
handleChange={formik.handleChange}
|
||||
/>
|
||||
<InnovenergyTextfield
|
||||
id="orderNumber-textfield"
|
||||
label={intl.formatMessage({
|
||||
id: "orderNumber",
|
||||
defaultMessage: "Order number",
|
||||
})}
|
||||
name="orderNumber"
|
||||
value={formik.values.orderNumber}
|
||||
handleChange={formik.handleChange}
|
||||
/>
|
||||
<Button variant="outlined" type="submit">
|
||||
<FormattedMessage id="applyChanges" defaultMessage="Apply changes" />
|
||||
</Button>
|
||||
</form>
|
||||
);
|
||||
};
|
||||
|
||||
export default CustomerForm;
|
|
@ -0,0 +1,57 @@
|
|||
import { useState, useCallback } from "react";
|
||||
import ReactFlow, {
|
||||
addEdge,
|
||||
FitViewOptions,
|
||||
applyNodeChanges,
|
||||
applyEdgeChanges,
|
||||
Node,
|
||||
Edge,
|
||||
NodeChange,
|
||||
EdgeChange,
|
||||
Connection,
|
||||
} from "reactflow";
|
||||
|
||||
const initialNodes: Node[] = [
|
||||
{ id: "1", data: { label: "Node 1" }, position: { x: 5, y: 5 } },
|
||||
{ id: "2", data: { label: "Node 2" }, position: { x: 5, y: 100 } },
|
||||
];
|
||||
|
||||
const initialEdges: Edge[] = [{ id: "e1-2", source: "1", target: "2" }];
|
||||
|
||||
const fitViewOptions: FitViewOptions = {
|
||||
padding: 0.2,
|
||||
};
|
||||
|
||||
function Flow() {
|
||||
const [nodes, setNodes] = useState<Node[]>(initialNodes);
|
||||
const [edges, setEdges] = useState<Edge[]>(initialEdges);
|
||||
|
||||
const onNodesChange = useCallback(
|
||||
(changes: NodeChange[]) =>
|
||||
setNodes((nds) => applyNodeChanges(changes, nds)),
|
||||
[setNodes]
|
||||
);
|
||||
const onEdgesChange = useCallback(
|
||||
(changes: EdgeChange[]) =>
|
||||
setEdges((eds) => applyEdgeChanges(changes, eds)),
|
||||
[setEdges]
|
||||
);
|
||||
const onConnect = useCallback(
|
||||
(connection: Connection) => setEdges((eds) => addEdge(connection, eds)),
|
||||
[setEdges]
|
||||
);
|
||||
|
||||
return (
|
||||
<ReactFlow
|
||||
nodes={nodes}
|
||||
edges={edges}
|
||||
onNodesChange={onNodesChange}
|
||||
onEdgesChange={onEdgesChange}
|
||||
onConnect={onConnect}
|
||||
fitView
|
||||
fitViewOptions={fitViewOptions}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
export default Flow;
|
|
@ -0,0 +1,28 @@
|
|||
import { TextField } from "@mui/material";
|
||||
|
||||
interface I_InnovenergyTextfieldProps {
|
||||
id: string;
|
||||
label: string;
|
||||
value: string;
|
||||
name: string;
|
||||
handleChange: (e: React.ChangeEvent<HTMLInputElement>) => void;
|
||||
type?: string;
|
||||
}
|
||||
|
||||
const InnovenergyTextfield = (props: I_InnovenergyTextfieldProps) => {
|
||||
return (
|
||||
<TextField
|
||||
id={props.id}
|
||||
label={props.label}
|
||||
variant="outlined"
|
||||
name={props.name}
|
||||
type={props.type}
|
||||
fullWidth
|
||||
sx={{ my: 0.5 }}
|
||||
value={props.value || ""}
|
||||
onChange={props.handleChange}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export default InnovenergyTextfield;
|
|
@ -1,14 +1,14 @@
|
|||
import List from "@mui/material/List";
|
||||
import ListItemButton from "@mui/material/ListItemButton";
|
||||
import ListItemText from "@mui/material/ListItemText";
|
||||
import { Divider } from "@mui/material";
|
||||
import { Divider, TextField } from "@mui/material";
|
||||
import { Link } from "react-router-dom";
|
||||
import useRouteMatch from "../hooks/useRouteMatch";
|
||||
import routes from "../routes.json";
|
||||
import { useEffect, useState } from "react";
|
||||
import axios from "axios";
|
||||
import { Installation } from "../util/installation.util";
|
||||
|
||||
import { I_Installation } from "../util/installation.util";
|
||||
import axiosConfig from "../config/axiosConfig";
|
||||
import { useIntl } from "react-intl";
|
||||
|
||||
const getPathWithoutId = (path?: string) => {
|
||||
if (path) {
|
||||
|
@ -18,8 +18,26 @@ const getPathWithoutId = (path?: string) => {
|
|||
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<Installation[]>();
|
||||
const [data, setData] = useState<I_Installation[]>();
|
||||
const [searchQuery, setSearchQuery] = useState("");
|
||||
const intl = useIntl();
|
||||
const filteredData = filterData(searchQuery, data);
|
||||
|
||||
const routeMatch = useRouteMatch([
|
||||
routes.installationWithId,
|
||||
routes.alarmsWithId,
|
||||
|
@ -28,32 +46,41 @@ const NestedList = () => {
|
|||
]);
|
||||
|
||||
useEffect(() => {
|
||||
const tokenString = sessionStorage.getItem("token");
|
||||
const token = tokenString !== null ? JSON.parse(tokenString) : "";
|
||||
axios
|
||||
.get("https://localhost:7087/api/GetAllInstallations", {
|
||||
headers: {
|
||||
auth: token,
|
||||
},
|
||||
})
|
||||
axiosConfig
|
||||
.get("https://localhost:7087/api/GetAllInstallations", {})
|
||||
.then((res) => {
|
||||
setData(res.data);
|
||||
});
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<>
|
||||
<TextField
|
||||
id="outlined-search"
|
||||
label={intl.formatMessage({
|
||||
id: "search",
|
||||
defaultMessage: "Search",
|
||||
})}
|
||||
type="search"
|
||||
fullWidth
|
||||
value={searchQuery}
|
||||
onChange={(e) => setSearchQuery(e.target.value)}
|
||||
/>
|
||||
<List
|
||||
sx={{ width: "100%", bgcolor: "background.paper" }}
|
||||
component="nav"
|
||||
aria-labelledby="nested-list-subheader"
|
||||
>
|
||||
{data?.map((installation) => (
|
||||
{filteredData?.map((installation) => (
|
||||
<>
|
||||
<Link
|
||||
key={installation.id}
|
||||
to={getPathWithoutId(routeMatch?.pattern?.path) + installation.id}
|
||||
style={{ textDecoration: "none" }}
|
||||
style={{ textDecoration: "none", color: "black" }}
|
||||
>
|
||||
<ListItemButton
|
||||
selected={installation.id === Number(routeMatch?.params.id)}
|
||||
>
|
||||
<ListItemButton>
|
||||
<ListItemText
|
||||
primary={installation.location + " | " + installation.name}
|
||||
/>
|
||||
|
@ -63,6 +90,7 @@ const NestedList = () => {
|
|||
</>
|
||||
))}
|
||||
</List>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@ 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 BasicTabs = () => {
|
||||
const routeMatch = useRouteMatch([
|
||||
|
@ -15,31 +16,44 @@ const BasicTabs = () => {
|
|||
]);
|
||||
|
||||
const id = routeMatch?.params?.id;
|
||||
const intl = useIntl();
|
||||
|
||||
return (
|
||||
<Box sx={{ width: "100%" }}>
|
||||
<Box sx={{ borderBottom: 1, borderColor: "divider" }}>
|
||||
<Tabs value={routeMatch?.pattern?.path} aria-label="basic tabs example">
|
||||
<Tab
|
||||
label="Installation"
|
||||
label={intl.formatMessage({
|
||||
id: "installation",
|
||||
defaultMessage: "Installation",
|
||||
})}
|
||||
value={routes.installationWithId}
|
||||
component={Link}
|
||||
to={routes.installation + id}
|
||||
/>
|
||||
<Tab
|
||||
label="Alarms"
|
||||
label={intl.formatMessage({
|
||||
id: "alarms",
|
||||
defaultMessage: "Alarms",
|
||||
})}
|
||||
value={routes.alarmsWithId}
|
||||
component={Link}
|
||||
to={routes.alarms + id}
|
||||
/>
|
||||
<Tab
|
||||
label="Users"
|
||||
label={intl.formatMessage({
|
||||
id: "users",
|
||||
defaultMessage: "Users",
|
||||
})}
|
||||
value={routes.usersWithId}
|
||||
component={Link}
|
||||
to={routes.users + id}
|
||||
/>
|
||||
<Tab
|
||||
label="Log"
|
||||
label={intl.formatMessage({
|
||||
id: "log",
|
||||
defaultMessage: "Log",
|
||||
})}
|
||||
value={routes.logWithId}
|
||||
component={Link}
|
||||
to={routes.log + id}
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
import axios from "axios";
|
||||
|
||||
export const axiosConfigWithoutToken = axios.create({
|
||||
baseURL: "https://localhost:7087/api",
|
||||
});
|
||||
|
||||
const axiosConfig = axios.create({
|
||||
baseURL: "https://localhost:7087/api",
|
||||
});
|
||||
|
||||
axiosConfig.interceptors.request.use(
|
||||
(config) => {
|
||||
const tokenString = sessionStorage.getItem("token");
|
||||
const token = tokenString !== null ? JSON.parse(tokenString) : "";
|
||||
if (token) {
|
||||
config.headers.auth = token;
|
||||
}
|
||||
return config;
|
||||
},
|
||||
(error) => {
|
||||
return Promise.reject(error);
|
||||
}
|
||||
);
|
||||
|
||||
export default axiosConfig;
|
|
@ -1,22 +1,22 @@
|
|||
import { useState } from "react";
|
||||
|
||||
const getToken = (): string => {
|
||||
const tokenString = sessionStorage.getItem("token");
|
||||
return tokenString !== null ? JSON.parse(tokenString).token : "";
|
||||
};
|
||||
import axiosConfig from "../config/axiosConfig";
|
||||
|
||||
const useToken = () => {
|
||||
const [token, setToken] = useState(getToken());
|
||||
const getToken = () => {
|
||||
const tokenString = sessionStorage.getItem("token");
|
||||
return tokenString !== null ? JSON.parse(tokenString) : "";
|
||||
};
|
||||
|
||||
const [token, setToken] = useState(getToken());
|
||||
const saveToken = (userToken: any) => {
|
||||
setToken(userToken);
|
||||
sessionStorage.setItem("token", JSON.stringify(userToken));
|
||||
setToken(userToken);
|
||||
axiosConfig.defaults.headers.common["auth"] = userToken;
|
||||
};
|
||||
|
||||
return {
|
||||
setToken: saveToken,
|
||||
token,
|
||||
getToken: getToken,
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
const Alarms = () => {
|
||||
return <div>alarms</div>;
|
||||
};
|
||||
|
||||
export default Alarms;
|
|
@ -1,93 +1,31 @@
|
|||
import { Box, TextField } from "@mui/material";
|
||||
import axios from "axios";
|
||||
import { Box, CircularProgress } from "@mui/material";
|
||||
import { useEffect, useState } from "react";
|
||||
import { useParams } from "react-router-dom";
|
||||
import { Installation } from "../util/installation.util";
|
||||
import CustomerForm from "../components/CustomerForm";
|
||||
import axiosConfig from "../config/axiosConfig";
|
||||
import { I_Installation } from "../util/installation.util";
|
||||
|
||||
const InstallationDetail = () => {
|
||||
const { id } = useParams();
|
||||
|
||||
const [values, setValues] = useState<Installation>();
|
||||
const [values, setValues] = useState<I_Installation>();
|
||||
const [loading, setLoading] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
const tokenString = sessionStorage.getItem("token");
|
||||
const token = tokenString !== null ? JSON.parse(tokenString) : "";
|
||||
axios
|
||||
.get("https://localhost:7087/api/GetInstallationById?id=" + id, {
|
||||
headers: {
|
||||
auth: token,
|
||||
},
|
||||
})
|
||||
.then((res) => {
|
||||
setLoading(true);
|
||||
axiosConfig.get("/GetInstallationById?id=" + id).then((res) => {
|
||||
setValues(res.data);
|
||||
console.log(res.data);
|
||||
setLoading(false);
|
||||
});
|
||||
}, [id]);
|
||||
|
||||
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
const { name, value } = e.target;
|
||||
setValues({
|
||||
...values,
|
||||
[name]: value,
|
||||
} as Installation);
|
||||
};
|
||||
|
||||
if (values) {
|
||||
if (values && values.id.toString() === id) {
|
||||
return (
|
||||
<Box sx={{ py: 3, width: 1 / 2 }}>
|
||||
<TextField
|
||||
id="outlined-basic"
|
||||
label="Customer name"
|
||||
variant="outlined"
|
||||
name="name"
|
||||
type="text"
|
||||
fullWidth
|
||||
sx={{ my: 0.5 }}
|
||||
value={values.name}
|
||||
onChange={handleChange}
|
||||
/>
|
||||
<TextField
|
||||
id="outlined-basic"
|
||||
label="Region"
|
||||
variant="outlined"
|
||||
name="region"
|
||||
fullWidth
|
||||
sx={{ my: 0.5 }}
|
||||
value={values.region}
|
||||
onChange={handleChange}
|
||||
/>
|
||||
<TextField
|
||||
id="outlined-basic"
|
||||
label="Location"
|
||||
variant="outlined"
|
||||
name="location"
|
||||
fullWidth
|
||||
sx={{ my: 0.5 }}
|
||||
value={values.location}
|
||||
onChange={handleChange}
|
||||
/>
|
||||
<TextField
|
||||
id="outlined-basic"
|
||||
label="Country"
|
||||
variant="outlined"
|
||||
name="country"
|
||||
fullWidth
|
||||
sx={{ my: 0.5 }}
|
||||
value={values.country}
|
||||
onChange={handleChange}
|
||||
/>
|
||||
<TextField
|
||||
id="outlined-basic"
|
||||
label="Order number"
|
||||
variant="outlined"
|
||||
name="orderNumber"
|
||||
fullWidth
|
||||
sx={{ my: 0.5 }}
|
||||
value={values.orderNumbers}
|
||||
onChange={handleChange}
|
||||
/>
|
||||
<CustomerForm values={values} id={id} />
|
||||
</Box>
|
||||
);
|
||||
} else if (loading) {
|
||||
return <CircularProgress />;
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
|
|
@ -0,0 +1,156 @@
|
|||
const Log = () => {
|
||||
const foo = {
|
||||
TimeStamp: "1676643900",
|
||||
Devices: [
|
||||
{
|
||||
"TruConvertAc 205330741": {
|
||||
Ac: {
|
||||
L1: {
|
||||
Current: 2.49,
|
||||
Voltage: 239.4,
|
||||
Phi: 0.200334842323119592691046359,
|
||||
},
|
||||
L2: {
|
||||
Current: 2.65,
|
||||
Voltage: 239.6,
|
||||
Phi: 0.200334842323119592691046359,
|
||||
},
|
||||
L3: {
|
||||
Current: 2.63,
|
||||
Voltage: 239.8,
|
||||
Phi: 0,
|
||||
},
|
||||
Frequency: 49.98,
|
||||
},
|
||||
Dc: {
|
||||
Current: 2.249388753056234718826405868,
|
||||
Voltage: 818,
|
||||
Power: 1840.0,
|
||||
},
|
||||
Alarms: [],
|
||||
},
|
||||
},
|
||||
{
|
||||
"TruConvertDc 3214": {
|
||||
Dc: {
|
||||
Current: -2.1173594132029339853300733496,
|
||||
Voltage: 818,
|
||||
Power: -1732.0,
|
||||
},
|
||||
Dc48: {
|
||||
Current: -30,
|
||||
Voltage: 56.0,
|
||||
Power: -1680.0,
|
||||
},
|
||||
Warnings: [],
|
||||
Alarms: [],
|
||||
},
|
||||
},
|
||||
{
|
||||
"EmuMeter 123": {
|
||||
Ac: {
|
||||
L1: {
|
||||
Current: 3.212,
|
||||
Voltage: 239.4,
|
||||
Phi: 1.1483422646081408626645746948,
|
||||
},
|
||||
L2: {
|
||||
Current: -2.462,
|
||||
Voltage: 238.9,
|
||||
Phi: 1.8441893582623698418074097834,
|
||||
},
|
||||
L3: {
|
||||
Current: 2.995,
|
||||
Voltage: 238.8,
|
||||
Phi: 0.1415394733244272187457893568,
|
||||
},
|
||||
Frequency: 49.9,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
"EmuMeter 123": {
|
||||
Ac: {
|
||||
L1: {
|
||||
Current: 3.212,
|
||||
Voltage: 239.4,
|
||||
Phi: 1.1483422646081408626645746948,
|
||||
},
|
||||
L2: {
|
||||
Current: -2.462,
|
||||
Voltage: 238.9,
|
||||
Phi: 1.8441893582623698418074097834,
|
||||
},
|
||||
L3: {
|
||||
Current: 2.995,
|
||||
Voltage: 238.8,
|
||||
Phi: 0.1415394733244272187457893568,
|
||||
},
|
||||
Frequency: 49.9,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "AMPT",
|
||||
Type: "PvOnDc",
|
||||
"Current 1": 2.098,
|
||||
"Current 2": 2.575,
|
||||
"Voltage 1": 822.989,
|
||||
"Voltage 2": 823.169,
|
||||
"Power 1": 1726.630922,
|
||||
"Power 2": 2119.660175,
|
||||
},
|
||||
{
|
||||
Name: "48TL Battery",
|
||||
Type: "Battery",
|
||||
Dc48: {
|
||||
Current: 14.17,
|
||||
Voltage: 53.41,
|
||||
Power: 756.8197,
|
||||
},
|
||||
Alarms: [],
|
||||
Warnings: [],
|
||||
Soc: 77.4,
|
||||
HeaterOn: true,
|
||||
EocReached: false,
|
||||
BatteryCold: false,
|
||||
Temperature: 265.4,
|
||||
},
|
||||
{
|
||||
Name: "48TL Battery",
|
||||
Type: "Battery",
|
||||
Dc48: {
|
||||
Current: 11.3,
|
||||
Voltage: 53.4,
|
||||
Power: 603.42,
|
||||
},
|
||||
Alarms: [],
|
||||
Warnings: ["bit44:"],
|
||||
Soc: 77.6,
|
||||
HeaterOn: true,
|
||||
EocReached: false,
|
||||
BatteryCold: false,
|
||||
Temperature: 264.9,
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const flattenObject = (obj: any, prefix = "") =>
|
||||
Object.keys(obj).reduce((previous: any, current: any) => {
|
||||
const pre = prefix.length ? prefix + "/" : "";
|
||||
if (Array.isArray(obj) || typeof obj === "string") {
|
||||
return previous;
|
||||
}
|
||||
if (typeof obj[current] === "object") {
|
||||
Object.assign(previous, flattenObject(obj[current], pre + current));
|
||||
} else {
|
||||
previous[pre + current] = obj[current];
|
||||
}
|
||||
return previous;
|
||||
}, {});
|
||||
|
||||
console.log(flattenObject(foo.Devices[0]));
|
||||
return <div>log</div>;
|
||||
};
|
||||
|
||||
export default Log;
|
|
@ -1,5 +1,5 @@
|
|||
// TODO add if required or not
|
||||
export interface Installation {
|
||||
export interface I_Installation {
|
||||
type: string;
|
||||
title: string;
|
||||
status: number;
|
||||
|
@ -8,7 +8,7 @@ export interface Installation {
|
|||
location: string;
|
||||
region: string;
|
||||
country: string;
|
||||
orderNumbers: string;
|
||||
orderNumber: string;
|
||||
lat: number;
|
||||
long: number;
|
||||
s3Bucket: string;
|
||||
|
@ -17,3 +17,5 @@ export interface Installation {
|
|||
information: string;
|
||||
parentId: number;
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue