diff --git a/typescript/frontend-marios2/src/App.tsx b/typescript/frontend-marios2/src/App.tsx index 29ee0324f..ba1934e1b 100644 --- a/typescript/frontend-marios2/src/App.tsx +++ b/typescript/frontend-marios2/src/App.tsx @@ -119,6 +119,10 @@ function App() { path={routes.forgotPassword} element={} > + } + > ); @@ -147,6 +151,10 @@ function App() { path={''} element={} > + } + > } /> - + } + > }> diff --git a/typescript/frontend-marios2/src/components/login.tsx b/typescript/frontend-marios2/src/components/login.tsx index dbcd203b3..c0148d42a 100644 --- a/typescript/frontend-marios2/src/components/login.tsx +++ b/typescript/frontend-marios2/src/components/login.tsx @@ -91,7 +91,7 @@ function Login() { }; return ( - <> +
@@ -263,7 +263,7 @@ function Login() { - +
); } diff --git a/typescript/frontend-marios2/src/content/dashboards/Installations/index.tsx b/typescript/frontend-marios2/src/content/dashboards/Installations/index.tsx index 42f8ba4ac..376a2d256 100644 --- a/typescript/frontend-marios2/src/content/dashboards/Installations/index.tsx +++ b/typescript/frontend-marios2/src/content/dashboards/Installations/index.tsx @@ -104,7 +104,10 @@ function InstallationTabs() { value: 'live', label: }, - + { + value: 'overview', + label: + }, { value: 'batteryview', label: ( @@ -148,12 +151,7 @@ function InstallationTabs() { value: 'overview', label: }, - { - value: 'batteryview', - label: ( - - ) - }, + { value: 'log', label: diff --git a/typescript/frontend-marios2/src/content/dashboards/Log/Log.tsx b/typescript/frontend-marios2/src/content/dashboards/Log/Log.tsx index cd9823a17..559c9debc 100644 --- a/typescript/frontend-marios2/src/content/dashboards/Log/Log.tsx +++ b/typescript/frontend-marios2/src/content/dashboards/Log/Log.tsx @@ -29,10 +29,17 @@ interface LogProps { function Log(props: LogProps) { const theme = useTheme(); + const searchParams = new URLSearchParams(location.search); + const openModal = searchParams.get('open'); + const [warnings, setWarnings] = useState([]); const [errors, setErrors] = useState([]); - const [errorButtonPressed, setErrorButtonPressed] = useState(false); - const [warningButtonPressed, setWarningButtonPressed] = useState(false); + const [errorButtonPressed, setErrorButtonPressed] = useState( + openModal === 'error' ? true : false + ); + const [warningButtonPressed, setWarningButtonPressed] = useState( + openModal === 'warning' ? true : false + ); const [updateCount, setUpdateCount] = useState(0); const navigate = useNavigate(); const tokencontext = useContext(TokenContext); diff --git a/typescript/frontend-marios2/src/content/dashboards/Overview/chartOptions.tsx b/typescript/frontend-marios2/src/content/dashboards/Overview/chartOptions.tsx index ccb93510b..006ce83af 100644 --- a/typescript/frontend-marios2/src/content/dashboards/Overview/chartOptions.tsx +++ b/typescript/frontend-marios2/src/content/dashboards/Overview/chartOptions.tsx @@ -260,7 +260,7 @@ export const getChartOptions = ( : chartInfo.max <= 0 ? Math.ceil(chartInfo.min / findPower(chartInfo.min).value) * findPower(chartInfo.min).value - : Math.abs(chartInfo.min) < 1 + : Math.abs(chartInfo.min) < 1 || Math.abs(chartInfo.max) < 1 ? -Math.max( Math.abs( Math.ceil(chartInfo.min / findPower(chartInfo.min).value) * @@ -278,7 +278,7 @@ export const getChartOptions = ( ).toFixed(2) : chartInfo.max <= 0 ? 0 - : Math.abs(chartInfo.min) < 1 + : Math.abs(chartInfo.min) < 1 || Math.abs(chartInfo.max) < 1 ? +Math.max( Math.abs( Math.ceil(chartInfo.min / findPower(chartInfo.min).value) * @@ -306,6 +306,17 @@ export const getChartOptions = ( } } }, + annotations: { + yaxis: [ + { + y: 0, + strokeDashArray: 0, + borderColor: '#d3d3d3', + borderWidth: 1, + yAxisIndex: 0 + } + ] + }, tooltip: { y: { formatter: function (val) { diff --git a/typescript/frontend-marios2/src/content/dashboards/Overview/overview.tsx b/typescript/frontend-marios2/src/content/dashboards/Overview/overview.tsx index 4f5061b72..723924cda 100644 --- a/typescript/frontend-marios2/src/content/dashboards/Overview/overview.tsx +++ b/typescript/frontend-marios2/src/content/dashboards/Overview/overview.tsx @@ -687,7 +687,7 @@ function Overview(props: OverviewProps) { }, { name: 'Net Energy', - color: '#666666', + color: '#ff3333', type: 'line', data: weeklybalance } @@ -917,7 +917,7 @@ function Overview(props: OverviewProps) { /> )} - {weeklyData && ( + {weeklyData && currentUser.hasWriteAccess && ( )} - {monthlyData && ( + {weeklyData && !currentUser.hasWriteAccess && ( + + )} + + {monthlyData && currentUser.hasWriteAccess && ( + )} + + {monthlyData && !currentUser.hasWriteAccess && ( + )} - {currentUser.hasWriteAccess && ( - - - + + + + + + + + + + - - - - - - - - - + > + - {dailyData && ( - - )} - - {weeklyData && ( - - )} - - {monthlyData && ( - - )} - - - - - - - - - - - - - - - {dailyData && ( - - )} - {weeklyData && ( - + )} - { - ...weeklyDataArray.chartData.gridExportPower, - color: '#ff3333' - } - ]} - type="bar" - height={400} - /> - )} + {weeklyData && ( + + )} - {monthlyData && ( - - )} - - + {monthlyData && ( + + )} + - )} + + + + + + + + + + + + + {dailyData && ( + + )} + {weeklyData && ( + + )} + + {monthlyData && ( + + )} + + + )} diff --git a/typescript/frontend-marios2/src/content/dashboards/Topology/Topology.tsx b/typescript/frontend-marios2/src/content/dashboards/Topology/Topology.tsx index 5960b6ab7..f778e7aeb 100644 --- a/typescript/frontend-marios2/src/content/dashboards/Topology/Topology.tsx +++ b/typescript/frontend-marios2/src/content/dashboards/Topology/Topology.tsx @@ -1,5 +1,5 @@ import React, { useState } from 'react'; -import { Container, Grid, Switch } from '@mui/material'; +import { Container, Grid, Switch, Typography } from '@mui/material'; import TopologyColumn from './topologyColumn'; import { getAmount, @@ -41,16 +41,33 @@ function Topology(props: TopologyProps) { justifyContent: 'right' }} > - +
+ + Display Values + + +
+ + {/**/} { return value % 1 === 0; }; -function formatPower(value) { +function formatPower(value, unit) { if (isNaN(value)) { return 'Invalid'; } @@ -47,7 +47,12 @@ function formatPower(value) { magnitude++; } - const roundedValue = value.toFixed(1); + const roundedValue = Math.round(value); + + //Filter all values less than 100 Watts + if (magnitude === 0 && value < 100 && unit === 'W') { + return 0; + } return negative === false ? `${roundedValue} ${prefixes[magnitude]}` @@ -243,8 +248,12 @@ function TopologyBox(props: TopologyBoxProps) { {props.data.values.map((boxData, index) => { return ( - {formatPower(boxData.value)} - {boxData.unit} + {formatPower(boxData.value, boxData.unit) === 0 + ? null + : formatPower(boxData.value, boxData.unit)} + {formatPower(boxData.value, boxData.unit) === 0 + ? null + : boxData.unit} ); })} diff --git a/typescript/frontend-marios2/src/content/dashboards/Topology/topologyFlow.tsx b/typescript/frontend-marios2/src/content/dashboards/Topology/topologyFlow.tsx index 650806b9d..81d17316a 100644 --- a/typescript/frontend-marios2/src/content/dashboards/Topology/topologyFlow.tsx +++ b/typescript/frontend-marios2/src/content/dashboards/Topology/topologyFlow.tsx @@ -45,7 +45,12 @@ function formatPower(value) { magnitude++; } - const roundedValue = value.toFixed(1); + const roundedValue = Math.round(value); + + //Filter all values less than 100 Watts + if (magnitude === 0 && value < 100) { + return 0; + } return negative === false ? `${roundedValue} ${prefixes[magnitude]}` @@ -113,8 +118,12 @@ function TopologyFlow(props: TopologyFlowProps) { zIndex: 1 }} > - {formatPower(props.data.values[0].value)} - {props.data.values[0].unit} + {formatPower(props.data.values[0].value) === 0 + ? null + : formatPower(props.data.values[0].value)} + {formatPower(props.data.values[0].value) === 0 + ? null + : props.data.values[0].unit} )} diff --git a/typescript/frontend-marios2/src/content/dashboards/Users/User.tsx b/typescript/frontend-marios2/src/content/dashboards/Users/User.tsx index d7c4de937..8edb90915 100644 --- a/typescript/frontend-marios2/src/content/dashboards/Users/User.tsx +++ b/typescript/frontend-marios2/src/content/dashboards/Users/User.tsx @@ -9,6 +9,7 @@ import { Grid, IconButton, Modal, + Switch, Tab, Tabs, TextField, @@ -22,6 +23,7 @@ import { InnovEnergyUser } from 'src/interfaces/UserTypes'; import { TokenContext } from 'src/contexts/tokenContext'; import { TabsContainerWrapper } from 'src/layouts/TabsContainerWrapper'; import { FormattedMessage } from 'react-intl'; +import FormControlLabel from '@mui/material/FormControlLabel'; interface singleUserProps { current_user: InnovEnergyUser; @@ -80,6 +82,14 @@ function User(props: singleUserProps) { [name]: value }); }; + + const handleAdminChange = (event) => { + setFormValues({ + ...formValues, + ['hasWriteAccess']: event.target.checked + }); + }; + const handleSubmit = async (e) => { setLoading(true); setError(false); @@ -94,8 +104,13 @@ function User(props: singleUserProps) { }); if (res) { - setUpdated(true); + props.fetchDataAgain(); setLoading(false); + setUpdated(true); + + setTimeout(() => { + setUpdated(false); + }, 3000); } }; @@ -278,6 +293,34 @@ function User(props: singleUserProps) { fullWidth /> + +
+ + } + label={ + + Admin + + } + sx={{ + marginLeft: '10px' + }} + /> +
+
@@ -19,7 +19,7 @@ function Users() {
- +
); } diff --git a/typescript/frontend-marios2/src/content/dashboards/Users/userForm.tsx b/typescript/frontend-marios2/src/content/dashboards/Users/userForm.tsx index 4803a169a..23ef0361f 100644 --- a/typescript/frontend-marios2/src/content/dashboards/Users/userForm.tsx +++ b/typescript/frontend-marios2/src/content/dashboards/Users/userForm.tsx @@ -9,7 +9,9 @@ import { MenuItem, Modal, Select, + Switch, TextField, + Typography, useTheme } from '@mui/material'; import Button from '@mui/material/Button'; @@ -17,10 +19,9 @@ import { Close as CloseIcon } from '@mui/icons-material'; import { InnovEnergyUser } from 'src/interfaces/UserTypes'; import axiosConfig from 'src/Resources/axiosConfig'; import { TokenContext } from 'src/contexts/tokenContext'; -import FormControlLabel from '@mui/material/FormControlLabel'; -import Checkbox from '@mui/material/Checkbox'; import { I_Folder, I_Installation } from 'src/interfaces/InstallationTypes'; import { FormattedMessage } from 'react-intl'; +import FormControlLabel from '@mui/material/FormControlLabel'; interface userFormProps { cancel: () => void; @@ -385,16 +386,22 @@ function userForm(props: userFormProps) {
} - label="Admin" - sx={{ marginTop: 1 }} + label={Admin} + sx={{ + marginLeft: '10px', + marginTop: '9px' + }} />
diff --git a/typescript/frontend-marios2/src/content/pages/Status/Status404/index.tsx b/typescript/frontend-marios2/src/content/pages/Status/Status404/index.tsx index d760d8703..4cd500aec 100644 --- a/typescript/frontend-marios2/src/content/pages/Status/Status404/index.tsx +++ b/typescript/frontend-marios2/src/content/pages/Status/Status404/index.tsx @@ -1,17 +1,12 @@ import { Box, - Card, - Typography, - Container, - Divider, Button, - FormControl, + Container, OutlinedInput, - InputAdornment, - styled + styled, + Typography } from '@mui/material'; import { Helmet } from 'react-helmet-async'; -import SearchTwoToneIcon from '@mui/icons-material/SearchTwoTone'; const MainContent = styled(Box)( ({ theme }) => ` @@ -50,42 +45,14 @@ function Status404() { The page you were looking for doesn't exist. - - It's on us, we moved the content to a different page. The search - below should help! - + Go to homepage + - - - - - - Search - - - } - startAdornment={ - - - - } - /> - - OR - - - diff --git a/typescript/frontend-marios2/src/interfaces/Chart.tsx b/typescript/frontend-marios2/src/interfaces/Chart.tsx index 63abacf73..1c209eb69 100644 --- a/typescript/frontend-marios2/src/interfaces/Chart.tsx +++ b/typescript/frontend-marios2/src/interfaces/Chart.tsx @@ -11,6 +11,7 @@ export interface overviewInterface { soc: chartInfoInterface; temperature: chartInfoInterface; dcPower: chartInfoInterface; + dcPowerWithoutHeating: chartInfoInterface; gridPower: chartInfoInterface; pvProduction: chartInfoInterface; dcBusVoltage: chartInfoInterface; @@ -78,6 +79,7 @@ export const transformInputToDailyData = async ( soc: { magnitude: 0, unit: '', min: 0, max: 0 }, temperature: { magnitude: 0, unit: '', min: 0, max: 0 }, dcPower: { magnitude: 0, unit: '', min: 0, max: 0 }, + dcPowerWithoutHeating: { magnitude: 0, unit: '', min: 0, max: 0 }, gridPower: { magnitude: 0, unit: '', min: 0, max: 0 }, pvProduction: { magnitude: 0, unit: '', min: 0, max: 0 }, dcBusVoltage: { magnitude: 0, unit: '', min: 0, max: 0 }, @@ -108,7 +110,7 @@ export const transformInputToDailyData = async ( while (startUnixTime < endTimestamp) { timestampPromises.push(fetchData(startUnixTime, s3Credentials)); - startUnixTime = UnixTime.fromTicks(startUnixTime.ticks + diff / 200); + startUnixTime = UnixTime.fromTicks(startUnixTime.ticks + diff / 100); if (startUnixTime.ticks % 2 !== 0) { startUnixTime = UnixTime.fromTicks(startUnixTime.ticks + 1); } @@ -280,7 +282,7 @@ export const transformInputToAggregatedData = async ( maxsoc: { name: 'max SOC', data: [] }, pvProduction: { name: 'Pv Energy', data: [] }, dcChargingPower: { name: 'Charging Battery Energy', data: [] }, - heatingPower: { name: 'Heating Power', data: [] }, + heatingPower: { name: 'Heating Energy', data: [] }, dcDischargingPower: { name: 'Discharging Battery Energy', data: [] }, gridImportPower: { name: 'Grid Import Energy', data: [] }, gridExportPower: { name: 'Grid Export Energy', data: [] } @@ -290,6 +292,7 @@ export const transformInputToAggregatedData = async ( soc: { magnitude: 0, unit: '', min: 0, max: 0 }, temperature: { magnitude: 0, unit: '', min: 0, max: 0 }, dcPower: { magnitude: 0, unit: '', min: 0, max: 0 }, + dcPowerWithoutHeating: { magnitude: 0, unit: '', min: 0, max: 0 }, gridPower: { magnitude: 0, unit: '', min: 0, max: 0 }, pvProduction: { magnitude: 0, unit: '', min: 0, max: 0 }, dcBusVoltage: { magnitude: 0, unit: '', min: 0, max: 0 }, @@ -329,6 +332,9 @@ export const transformInputToAggregatedData = async ( dateList.push(currentDay.format('DD-MM')); pathsToSearch.forEach((path) => { if (result[path]) { + if (path === '/GridExportPower') { + result[path].value = -result[path].value; + } if (result[path].value < overviewData[path].min) { overviewData[path].min = result[path].value; } @@ -336,9 +342,9 @@ export const transformInputToAggregatedData = async ( if (result[path].value > overviewData[path].max) { overviewData[path].max = result[path].value; } - if (path === '/GridExportPower' && result[path].value < 0.1) { - result[path].value = 0.3; - } + // if (path === '/GridExportPower' && Math.abs(result[path].value) < 0.1) { + // result[path].value = -0.3; + // } data[path].push(result[path].value as number); } }); @@ -395,6 +401,16 @@ export const transformInputToAggregatedData = async ( path = '/HeatingPower'; chartAggregatedData.heatingPower.data = data[path]; + chartOverview.dcPowerWithoutHeating = { + magnitude: Math.max( + overviewData['/ChargingBatteryPower'].magnitude, + overviewData['/DischargingBatteryPower'].magnitude + ), + unit: '(kWh)', + min: overviewData['/DischargingBatteryPower'].min, + max: overviewData['/ChargingBatteryPower'].max + }; + chartOverview.dcPower = { magnitude: Math.max( overviewData['/ChargingBatteryPower'].magnitude, @@ -420,12 +436,8 @@ export const transformInputToAggregatedData = async ( overviewData['/GridExportPower'].magnitude ), unit: '(kWh)', - min: - overviewData['/GridImportPower'].min + - overviewData['/GridExportPower'].min, - max: - overviewData['/GridImportPower'].max + - overviewData['/GridExportPower'].max + min: overviewData['/GridExportPower'].min, + max: overviewData['/GridImportPower'].max }; chartOverview.overview = { diff --git a/typescript/frontend-marios2/src/layouts/SidebarLayout/Header/Menu/index.tsx b/typescript/frontend-marios2/src/layouts/SidebarLayout/Header/Menu/index.tsx index 65c3784cd..743301461 100644 --- a/typescript/frontend-marios2/src/layouts/SidebarLayout/Header/Menu/index.tsx +++ b/typescript/frontend-marios2/src/layouts/SidebarLayout/Header/Menu/index.tsx @@ -11,6 +11,7 @@ import { styled } from '@mui/material/styles'; import ExpandMoreTwoToneIcon from '@mui/icons-material/ExpandMoreTwoTone'; import { ThemeContext } from '../../../../theme/ThemeProvider'; import { FormattedMessage } from 'react-intl'; +import '../../../../App.css'; interface HeaderButtonsProps { language: string; @@ -106,7 +107,7 @@ function HeaderMenu(props: HeaderButtonsProps) { const isMobile = window.innerWidth <= 1280; return ( - <> +
- - handleLanguageSelect('en')}> - English - - handleLanguageSelect('de')}> - German - - handleLanguageSelect('fr')}> - French - - - +
+ + handleLanguageSelect('en')}> + English + + handleLanguageSelect('de')}> + German + + handleLanguageSelect('fr')}> + French + + +
+
); } diff --git a/typescript/frontend-marios2/src/layouts/SidebarLayout/Header/Userbox/index.tsx b/typescript/frontend-marios2/src/layouts/SidebarLayout/Header/Userbox/index.tsx index 04eb7cd32..cdfe96b9d 100644 --- a/typescript/frontend-marios2/src/layouts/SidebarLayout/Header/Userbox/index.tsx +++ b/typescript/frontend-marios2/src/layouts/SidebarLayout/Header/Userbox/index.tsx @@ -19,6 +19,7 @@ import { TokenContext } from 'src/contexts/tokenContext'; import { useNavigate } from 'react-router-dom'; import routes from 'src/Resources/routes.json'; import { WebSocketContext } from '../../../../contexts/WebSocketContextProvider'; +import '../../../../App.css'; const UserBoxButton = styled(Button)( ({ theme }) => ` @@ -86,8 +87,13 @@ function HeaderUserbox() { }; return ( - <> - +
+ {currentUser?.name} @@ -113,14 +119,16 @@ function HeaderUserbox() { horizontal: 'right' }} > - - - {currentUser?.name} - - {currentUser?.email} - - - +
+ + + {currentUser?.name} + + {currentUser?.email} + + + +
@@ -130,7 +138,7 @@ function HeaderUserbox() { - +
); } diff --git a/typescript/frontend-marios2/src/layouts/SidebarLayout/index.tsx b/typescript/frontend-marios2/src/layouts/SidebarLayout/index.tsx index 4c9f3e7cf..bbcd07914 100644 --- a/typescript/frontend-marios2/src/layouts/SidebarLayout/index.tsx +++ b/typescript/frontend-marios2/src/layouts/SidebarLayout/index.tsx @@ -43,10 +43,12 @@ const SidebarLayout = (props: SidebarLayoutProps) => { } }} > -
+
+
+