mirror of
https://github.com/emsesp/EMS-ESP32.git
synced 2025-12-08 08:49:52 +03:00
This commit is contained in:
@@ -20,7 +20,8 @@ import {
|
||||
ValidatedTextField,
|
||||
ButtonRow,
|
||||
MessageBox,
|
||||
BlockNavigation
|
||||
BlockNavigation,
|
||||
useLayoutTitle
|
||||
} from 'components';
|
||||
|
||||
import RestartMonitor from 'framework/system/RestartMonitor';
|
||||
@@ -36,7 +37,7 @@ export function boardProfileSelectItems() {
|
||||
));
|
||||
}
|
||||
|
||||
const SettingsApplication: FC = () => {
|
||||
const ApplicationSettings: FC = () => {
|
||||
const {
|
||||
loadData,
|
||||
saveData,
|
||||
@@ -97,6 +98,8 @@ const SettingsApplication: FC = () => {
|
||||
});
|
||||
};
|
||||
|
||||
useLayoutTitle(LL.APPLICATION_SETTINGS());
|
||||
|
||||
const content = () => {
|
||||
if (!data) {
|
||||
return <FormLoader onRetry={loadData} errorMessage={errorMessage} />;
|
||||
@@ -680,11 +683,11 @@ const SettingsApplication: FC = () => {
|
||||
};
|
||||
|
||||
return (
|
||||
<SectionContent title={LL.APPLICATION_SETTINGS()} titleGutter>
|
||||
<SectionContent>
|
||||
{blocker ? <BlockNavigation blocker={blocker} /> : null}
|
||||
{restarting ? <RestartMonitor /> : content()}
|
||||
</SectionContent>
|
||||
);
|
||||
};
|
||||
|
||||
export default SettingsApplication;
|
||||
export default ApplicationSettings;
|
||||
@@ -13,17 +13,17 @@ import { useBlocker } from 'react-router-dom';
|
||||
|
||||
import { toast } from 'react-toastify';
|
||||
|
||||
import SettingsCustomEntitiesDialog from './SettingsCustomEntitiesDialog';
|
||||
import SettingsCustomEntitiesDialog from './CustomEntitiesDialog';
|
||||
import * as EMSESP from './api';
|
||||
import { DeviceValueTypeNames, DeviceValueUOM_s } from './types';
|
||||
import { entityItemValidation } from './validators';
|
||||
import type { EntityItem } from './types';
|
||||
import type { FC } from 'react';
|
||||
import { ButtonRow, FormLoader, SectionContent, BlockNavigation } from 'components';
|
||||
import { ButtonRow, FormLoader, SectionContent, BlockNavigation, useLayoutTitle } from 'components';
|
||||
|
||||
import { useI18nContext } from 'i18n/i18n-react';
|
||||
|
||||
const SettingsCustomEntities: FC = () => {
|
||||
const CustomEntities: FC = () => {
|
||||
const { LL } = useI18nContext();
|
||||
const [numChanges, setNumChanges] = useState<number>(0);
|
||||
const blocker = useBlocker(numChanges !== 0);
|
||||
@@ -31,6 +31,8 @@ const SettingsCustomEntities: FC = () => {
|
||||
const [creating, setCreating] = useState<boolean>(false);
|
||||
const [dialogOpen, setDialogOpen] = useState<boolean>(false);
|
||||
|
||||
useLayoutTitle(LL.CUSTOM_ENTITIES(0));
|
||||
|
||||
const {
|
||||
data: entities,
|
||||
send: fetchEntities,
|
||||
@@ -246,7 +248,7 @@ const SettingsCustomEntities: FC = () => {
|
||||
};
|
||||
|
||||
return (
|
||||
<SectionContent title={LL.CUSTOM_ENTITIES(0)} titleGutter>
|
||||
<SectionContent>
|
||||
{blocker ? <BlockNavigation blocker={blocker} /> : null}
|
||||
<Box mb={2} color="warning.main">
|
||||
<Typography variant="body2">{LL.ENTITIES_HELP_1()}</Typography>
|
||||
@@ -298,4 +300,4 @@ const SettingsCustomEntities: FC = () => {
|
||||
);
|
||||
};
|
||||
|
||||
export default SettingsCustomEntities;
|
||||
export default CustomEntities;
|
||||
@@ -30,7 +30,7 @@ import { useI18nContext } from 'i18n/i18n-react';
|
||||
import { numberValue, updateValue } from 'utils';
|
||||
import { validate } from 'validators';
|
||||
|
||||
type SettingsCustomEntitiesDialogProps = {
|
||||
type CustomEntitiesDialogProps = {
|
||||
open: boolean;
|
||||
creating: boolean;
|
||||
onClose: () => void;
|
||||
@@ -39,14 +39,14 @@ type SettingsCustomEntitiesDialogProps = {
|
||||
validator: Schema;
|
||||
};
|
||||
|
||||
const SettingsCustomEntitiesDialog = ({
|
||||
const CustomEntitiesDialog = ({
|
||||
open,
|
||||
creating,
|
||||
onClose,
|
||||
onSave,
|
||||
selectedItem,
|
||||
validator
|
||||
}: SettingsCustomEntitiesDialogProps) => {
|
||||
}: CustomEntitiesDialogProps) => {
|
||||
const { LL } = useI18nContext();
|
||||
const [editItem, setEditItem] = useState<EntityItem>(selectedItem);
|
||||
const [fieldErrors, setFieldErrors] = useState<ValidateFieldsError>();
|
||||
@@ -281,4 +281,4 @@ const SettingsCustomEntitiesDialog = ({
|
||||
);
|
||||
};
|
||||
|
||||
export default SettingsCustomEntitiesDialog;
|
||||
export default CustomEntitiesDialog;
|
||||
@@ -26,9 +26,9 @@ import { useState, useEffect, useCallback } from 'react';
|
||||
import { useBlocker, useLocation } from 'react-router-dom';
|
||||
import { toast } from 'react-toastify';
|
||||
|
||||
import SettingsCustomizationDialog from './CustomizationDialog';
|
||||
import EntityMaskToggle from './EntityMaskToggle';
|
||||
import OptionIcon from './OptionIcon';
|
||||
import SettingsCustomizationDialog from './SettingsCustomizationDialog';
|
||||
|
||||
import * as EMSESP from './api';
|
||||
|
||||
@@ -37,14 +37,14 @@ import type { DeviceShort, DeviceEntity } from './types';
|
||||
import type { FC } from 'react';
|
||||
import { dialogStyle } from 'CustomTheme';
|
||||
import * as SystemApi from 'api/system';
|
||||
import { ButtonRow, SectionContent, MessageBox, BlockNavigation } from 'components';
|
||||
import { ButtonRow, SectionContent, MessageBox, BlockNavigation, useLayoutTitle } from 'components';
|
||||
|
||||
import RestartMonitor from 'framework/system/RestartMonitor';
|
||||
import { useI18nContext } from 'i18n/i18n-react';
|
||||
|
||||
export const APIURL = window.location.origin + '/api/';
|
||||
|
||||
const SettingsCustomization: FC = () => {
|
||||
const Customization: FC = () => {
|
||||
const { LL } = useI18nContext();
|
||||
const [numChanges, setNumChanges] = useState<number>(0);
|
||||
const blocker = useBlocker(numChanges !== 0);
|
||||
@@ -58,6 +58,8 @@ const SettingsCustomization: FC = () => {
|
||||
const [selectedDeviceEntity, setSelectedDeviceEntity] = useState<DeviceEntity>();
|
||||
const [dialogOpen, setDialogOpen] = useState<boolean>(false);
|
||||
|
||||
useLayoutTitle(LL.CUSTOMIZATIONS());
|
||||
|
||||
// fetch devices first
|
||||
const { data: devices } = useRequest(EMSESP.readDevices);
|
||||
|
||||
@@ -508,9 +510,6 @@ const SettingsCustomization: FC = () => {
|
||||
|
||||
const renderContent = () => (
|
||||
<>
|
||||
<Typography sx={{ pt: 2, pb: 2 }} variant="h6" color="primary">
|
||||
{LL.DEVICE_ENTITIES()}
|
||||
</Typography>
|
||||
{devices && renderDeviceList()}
|
||||
{deviceEntities && renderDeviceData()}
|
||||
{restartNeeded && (
|
||||
@@ -561,7 +560,7 @@ const SettingsCustomization: FC = () => {
|
||||
);
|
||||
|
||||
return (
|
||||
<SectionContent title={LL.CUSTOMIZATIONS()} titleGutter>
|
||||
<SectionContent>
|
||||
{blocker ? <BlockNavigation blocker={blocker} /> : null}
|
||||
{restarting ? <RestartMonitor /> : renderContent()}
|
||||
{selectedDeviceEntity && (
|
||||
@@ -576,4 +575,4 @@ const SettingsCustomization: FC = () => {
|
||||
);
|
||||
};
|
||||
|
||||
export default SettingsCustomization;
|
||||
export default Customization;
|
||||
@@ -31,7 +31,7 @@ type SettingsCustomizationDialogProps = {
|
||||
selectedItem: DeviceEntity;
|
||||
};
|
||||
|
||||
const SettingsCustomizationDialog = ({ open, onClose, onSave, selectedItem }: SettingsCustomizationDialogProps) => {
|
||||
const CustomizationDialog = ({ open, onClose, onSave, selectedItem }: SettingsCustomizationDialogProps) => {
|
||||
const { LL } = useI18nContext();
|
||||
const [editItem, setEditItem] = useState<DeviceEntity>(selectedItem);
|
||||
const [error, setError] = useState<boolean>(false);
|
||||
@@ -152,4 +152,4 @@ const SettingsCustomizationDialog = ({ open, onClose, onSave, selectedItem }: Se
|
||||
);
|
||||
};
|
||||
|
||||
export default SettingsCustomizationDialog;
|
||||
export default CustomizationDialog;
|
||||
@@ -1,37 +0,0 @@
|
||||
import { Tab } from '@mui/material';
|
||||
import { Navigate, Route, Routes } from 'react-router-dom';
|
||||
|
||||
import DashboardDevices from './DashboardDevices';
|
||||
import DashboardSensors from './DashboardSensors';
|
||||
import DashboardStatus from './DashboardStatus';
|
||||
|
||||
import type { FC } from 'react';
|
||||
|
||||
import { RouterTabs, useRouterTab, useLayoutTitle } from 'components';
|
||||
|
||||
import { useI18nContext } from 'i18n/i18n-react';
|
||||
|
||||
const Dashboard: FC = () => {
|
||||
const { routerTab } = useRouterTab();
|
||||
|
||||
const { LL } = useI18nContext();
|
||||
useLayoutTitle(LL.DASHBOARD());
|
||||
|
||||
return (
|
||||
<>
|
||||
<RouterTabs value={routerTab}>
|
||||
<Tab value="/dashboard/devices" label={LL.DEVICES()} />
|
||||
<Tab value="/dashboard/sensors" label={LL.SENSORS()} />
|
||||
<Tab value="/dashboard/status" label="Status" />
|
||||
</RouterTabs>
|
||||
<Routes>
|
||||
<Route path="devices" element={<DashboardDevices />} />
|
||||
<Route path="sensors" element={<DashboardSensors />} />
|
||||
<Route path="status" element={<DashboardStatus />} />
|
||||
<Route path="*" element={<Navigate replace to="/dashboard/devices" />} />
|
||||
</Routes>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default Dashboard;
|
||||
@@ -38,8 +38,8 @@ import { useState, useContext, useEffect, useCallback, useLayoutEffect } from 'r
|
||||
import { IconContext } from 'react-icons';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { toast } from 'react-toastify';
|
||||
import DashboardDevicesDialog from './DashboardDevicesDialog';
|
||||
import DeviceIcon from './DeviceIcon';
|
||||
import DashboardDevicesDialog from './DevicesDialog';
|
||||
|
||||
import * as EMSESP from './api';
|
||||
import { formatValue } from './deviceValue';
|
||||
@@ -49,12 +49,12 @@ import { deviceValueItemValidation } from './validators';
|
||||
import type { Device, DeviceValue } from './types';
|
||||
import type { FC } from 'react';
|
||||
import { dialogStyle } from 'CustomTheme';
|
||||
import { ButtonRow, SectionContent, MessageBox } from 'components';
|
||||
import { ButtonRow, SectionContent, MessageBox, useLayoutTitle } from 'components';
|
||||
import { AuthenticatedContext } from 'contexts/authentication';
|
||||
|
||||
import { useI18nContext } from 'i18n/i18n-react';
|
||||
|
||||
const DashboardDevices: FC = () => {
|
||||
const Devices: FC = () => {
|
||||
const { me } = useContext(AuthenticatedContext);
|
||||
const { LL } = useI18nContext();
|
||||
const [size, setSize] = useState([0, 0]);
|
||||
@@ -66,6 +66,8 @@ const DashboardDevices: FC = () => {
|
||||
|
||||
const navigate = useNavigate();
|
||||
|
||||
useLayoutTitle(LL.DEVICES());
|
||||
|
||||
const { data: coreData, send: readCoreData } = useRequest(() => EMSESP.readCoreData(), {
|
||||
initialData: {
|
||||
connected: true,
|
||||
@@ -608,7 +610,7 @@ const DashboardDevices: FC = () => {
|
||||
};
|
||||
|
||||
return (
|
||||
<SectionContent title={LL.DEVICE_DATA()} titleGutter id="devices-window">
|
||||
<SectionContent id="devices-window">
|
||||
{renderCoreData()}
|
||||
{renderDeviceData()}
|
||||
{renderDeviceDetails()}
|
||||
@@ -636,4 +638,4 @@ const DashboardDevices: FC = () => {
|
||||
);
|
||||
};
|
||||
|
||||
export default DashboardDevices;
|
||||
export default Devices;
|
||||
@@ -40,7 +40,7 @@ type DashboardDevicesDialogProps = {
|
||||
progress: boolean;
|
||||
};
|
||||
|
||||
const DashboardDevicesDialog = ({
|
||||
const DevicesDialog = ({
|
||||
open,
|
||||
onClose,
|
||||
onSave,
|
||||
@@ -204,4 +204,4 @@ const DashboardDevicesDialog = ({
|
||||
);
|
||||
};
|
||||
|
||||
export default DashboardDevicesDialog;
|
||||
export default DevicesDialog;
|
||||
@@ -64,7 +64,7 @@ const showQuality = (stat: Stat) => {
|
||||
}
|
||||
};
|
||||
|
||||
const DashboardStatus: FC = () => {
|
||||
const EMSStatus: FC = () => {
|
||||
const { data: data, send: loadData, error } = useRequest(EMSESP.readStatus);
|
||||
|
||||
const { LL } = useI18nContext();
|
||||
@@ -272,11 +272,7 @@ const DashboardStatus: FC = () => {
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<SectionContent title={LL.EMS_BUS_STATUS_TITLE()} titleGutter>
|
||||
{content()}
|
||||
</SectionContent>
|
||||
);
|
||||
return <SectionContent title={LL.EMS_BUS_STATUS_TITLE()}>{content()}</SectionContent>;
|
||||
};
|
||||
|
||||
export default DashboardStatus;
|
||||
export default EMSStatus;
|
||||
@@ -1,9 +1,19 @@
|
||||
import CommentIcon from '@mui/icons-material/CommentTwoTone';
|
||||
import EastIcon from '@mui/icons-material/East';
|
||||
import DownloadIcon from '@mui/icons-material/GetApp';
|
||||
import GitHubIcon from '@mui/icons-material/GitHub';
|
||||
import MenuBookIcon from '@mui/icons-material/MenuBookTwoTone';
|
||||
import { Box, List, ListItem, ListItemAvatar, ListItemText, Link, Typography, Button } from '@mui/material';
|
||||
import {
|
||||
Box,
|
||||
List,
|
||||
ListItem,
|
||||
ListItemAvatar,
|
||||
ListItemText,
|
||||
Link,
|
||||
Typography,
|
||||
Button,
|
||||
ListItemButton,
|
||||
Avatar
|
||||
} from '@mui/material';
|
||||
import { useRequest } from 'alova';
|
||||
import { toast } from 'react-toastify';
|
||||
import type { FC } from 'react';
|
||||
@@ -39,59 +49,56 @@ const Help: FC = () => {
|
||||
};
|
||||
|
||||
return (
|
||||
<SectionContent title={LL.SUPPORT_INFORMATION(0)} titleGutter>
|
||||
<List>
|
||||
<SectionContent>
|
||||
<List sx={{ borderRadius: 3, border: '2px solid grey' }}>
|
||||
<ListItem>
|
||||
<ListItemAvatar>
|
||||
<MenuBookIcon style={{ fontSize: 24, color: 'lightblue', verticalAlign: 'middle' }} />
|
||||
</ListItemAvatar>
|
||||
<ListItemText>
|
||||
{LL.HELP_INFORMATION_1()}
|
||||
<EastIcon style={{ fontSize: 24, color: 'lightblue', verticalAlign: 'middle' }} />
|
||||
|
||||
<Link target="_blank" href="https://emsesp.github.io/docs" color="primary">
|
||||
{LL.CLICK_HERE()}
|
||||
</Link>
|
||||
</ListItemText>
|
||||
<ListItemButton component="a" href="https://emsesp.github.io/docs">
|
||||
<ListItemAvatar>
|
||||
<Avatar sx={{ bgcolor: '#72caf9' }}>
|
||||
<MenuBookIcon />
|
||||
</Avatar>
|
||||
</ListItemAvatar>
|
||||
<ListItemText primary={LL.HELP_INFORMATION_1()} />
|
||||
</ListItemButton>
|
||||
</ListItem>
|
||||
|
||||
<ListItem>
|
||||
<ListItemAvatar>
|
||||
<CommentIcon style={{ fontSize: 24, color: 'lightblue', verticalAlign: 'middle' }} />
|
||||
</ListItemAvatar>
|
||||
<ListItemText>
|
||||
{LL.HELP_INFORMATION_2()}
|
||||
<EastIcon style={{ fontSize: 24, color: 'lightblue', verticalAlign: 'middle' }} />
|
||||
|
||||
<Link target="_blank" href="https://discord.gg/3J3GgnzpyT" color="primary">
|
||||
{LL.CLICK_HERE()}
|
||||
</Link>
|
||||
</ListItemText>
|
||||
<ListItemButton component="a" href="https://discord.gg/3J3GgnzpyT">
|
||||
<ListItemAvatar>
|
||||
<Avatar sx={{ bgcolor: '#72caf9' }}>
|
||||
<CommentIcon />
|
||||
</Avatar>
|
||||
</ListItemAvatar>
|
||||
<ListItemText primary={LL.HELP_INFORMATION_2()} />
|
||||
</ListItemButton>
|
||||
</ListItem>
|
||||
|
||||
<ListItem>
|
||||
<ListItemAvatar>
|
||||
<GitHubIcon style={{ fontSize: 24, color: 'lightblue', verticalAlign: 'middle' }} />
|
||||
</ListItemAvatar>
|
||||
<ListItemText>
|
||||
{LL.HELP_INFORMATION_3()}
|
||||
<EastIcon style={{ fontSize: 24, color: 'lightblue', verticalAlign: 'middle' }} />
|
||||
<Link target="_blank" href="https://github.com/emsesp/EMS-ESP32/issues/new/choose" color="primary">
|
||||
{LL.CLICK_HERE()}
|
||||
</Link>
|
||||
<br />
|
||||
</ListItemText>
|
||||
<ListItemButton component="a" href="https://github.com/emsesp/EMS-ESP32/issues/new/choose">
|
||||
<ListItemAvatar>
|
||||
<Avatar sx={{ bgcolor: '#72caf9' }}>
|
||||
<GitHubIcon />
|
||||
</Avatar>
|
||||
</ListItemAvatar>
|
||||
<ListItemText primary={LL.HELP_INFORMATION_3()} />
|
||||
</ListItemButton>
|
||||
</ListItem>
|
||||
</List>
|
||||
|
||||
<Box color="warning.main">
|
||||
<Box p={2} color="warning.main">
|
||||
<Typography mb={1} variant="body2">
|
||||
{LL.HELP_INFORMATION_4()}
|
||||
</Typography>
|
||||
<Button
|
||||
startIcon={<DownloadIcon />}
|
||||
variant="outlined"
|
||||
color="primary"
|
||||
onClick={() => callAPI('system', 'info')}
|
||||
>
|
||||
{LL.SUPPORT_INFORMATION(0)}
|
||||
</Button>
|
||||
</Box>
|
||||
<Button startIcon={<DownloadIcon />} variant="outlined" color="primary" onClick={() => callAPI('system', 'info')}>
|
||||
{LL.SUPPORT_INFORMATION(0)}
|
||||
</Button>
|
||||
|
||||
<Button
|
||||
sx={{ ml: 2 }}
|
||||
startIcon={<DownloadIcon />}
|
||||
@@ -102,7 +109,7 @@ const Help: FC = () => {
|
||||
All Values
|
||||
</Button>
|
||||
|
||||
<Box border={1} p={1} mt={4} color="orange">
|
||||
<Box border={1} p={1} mt={4}>
|
||||
<Typography align="center" variant="subtitle1" color="orange">
|
||||
<b>{LL.HELP_INFORMATION_5()}</b>
|
||||
</Typography>
|
||||
|
||||
@@ -11,18 +11,18 @@ import { updateState, useRequest } from 'alova';
|
||||
import { useState, useEffect, useCallback } from 'react';
|
||||
import { useBlocker } from 'react-router-dom';
|
||||
import { toast } from 'react-toastify';
|
||||
import SettingsSchedulerDialog from './SettingsSchedulerDialog';
|
||||
import SettingsSchedulerDialog from './SchedulerDialog';
|
||||
import * as EMSESP from './api';
|
||||
import { ScheduleFlag } from './types';
|
||||
import { schedulerItemValidation } from './validators';
|
||||
import type { ScheduleItem } from './types';
|
||||
import type { FC } from 'react';
|
||||
|
||||
import { ButtonRow, FormLoader, SectionContent, BlockNavigation } from 'components';
|
||||
import { ButtonRow, FormLoader, SectionContent, BlockNavigation, useLayoutTitle } from 'components';
|
||||
|
||||
import { useI18nContext } from 'i18n/i18n-react';
|
||||
|
||||
const SettingsScheduler: FC = () => {
|
||||
const Scheduler: FC = () => {
|
||||
const { LL, locale } = useI18nContext();
|
||||
const [numChanges, setNumChanges] = useState<number>(0);
|
||||
const blocker = useBlocker(numChanges !== 0);
|
||||
@@ -194,6 +194,8 @@ const SettingsScheduler: FC = () => {
|
||||
</>
|
||||
);
|
||||
|
||||
useLayoutTitle(LL.SCHEDULER());
|
||||
|
||||
return (
|
||||
<Table
|
||||
data={{ nodes: schedule.filter((si) => !si.deleted).sort((a, b) => a.time.localeCompare(b.time)) }}
|
||||
@@ -249,7 +251,7 @@ const SettingsScheduler: FC = () => {
|
||||
};
|
||||
|
||||
return (
|
||||
<SectionContent title={LL.SCHEDULER()} titleGutter>
|
||||
<SectionContent>
|
||||
{blocker ? <BlockNavigation blocker={blocker} /> : null}
|
||||
<Box mb={2} color="warning.main">
|
||||
<Typography variant="body2">{LL.SCHEDULER_HELP_1()}</Typography>
|
||||
@@ -298,4 +300,4 @@ const SettingsScheduler: FC = () => {
|
||||
);
|
||||
};
|
||||
|
||||
export default SettingsScheduler;
|
||||
export default Scheduler;
|
||||
@@ -32,7 +32,7 @@ import { useI18nContext } from 'i18n/i18n-react';
|
||||
import { updateValue } from 'utils';
|
||||
import { validate } from 'validators';
|
||||
|
||||
type SettingsSchedulerDialogProps = {
|
||||
type SchedulerDialogProps = {
|
||||
open: boolean;
|
||||
creating: boolean;
|
||||
onClose: () => void;
|
||||
@@ -42,15 +42,7 @@ type SettingsSchedulerDialogProps = {
|
||||
dow: string[];
|
||||
};
|
||||
|
||||
const SettingsSchedulerDialog = ({
|
||||
open,
|
||||
creating,
|
||||
onClose,
|
||||
onSave,
|
||||
selectedItem,
|
||||
validator,
|
||||
dow
|
||||
}: SettingsSchedulerDialogProps) => {
|
||||
const SchedulerDialog = ({ open, creating, onClose, onSave, selectedItem, validator, dow }: SchedulerDialogProps) => {
|
||||
const { LL } = useI18nContext();
|
||||
const [editItem, setEditItem] = useState<ScheduleItem>(selectedItem);
|
||||
const [fieldErrors, setFieldErrors] = useState<ValidateFieldsError>();
|
||||
@@ -246,4 +238,4 @@ const SettingsSchedulerDialog = ({
|
||||
);
|
||||
};
|
||||
|
||||
export default SettingsSchedulerDialog;
|
||||
export default SchedulerDialog;
|
||||
@@ -12,20 +12,20 @@ import { useState, useContext, useEffect } from 'react';
|
||||
|
||||
import { toast } from 'react-toastify';
|
||||
|
||||
import DashboardSensorsAnalogDialog from './DashboardSensorsAnalogDialog';
|
||||
import DashboardSensorsTemperatureDialog from './DashboardSensorsTemperatureDialog';
|
||||
import DashboardSensorsAnalogDialog from './SensorsAnalogDialog';
|
||||
import DashboardSensorsTemperatureDialog from './SensorsTemperatureDialog';
|
||||
import * as EMSESP from './api';
|
||||
|
||||
import { DeviceValueUOM, DeviceValueUOM_s, AnalogTypeNames, AnalogType } from './types';
|
||||
import { temperatureSensorItemValidation, analogSensorItemValidation } from './validators';
|
||||
import type { TemperatureSensor, AnalogSensor } from './types';
|
||||
import type { FC } from 'react';
|
||||
import { ButtonRow, SectionContent } from 'components';
|
||||
import { ButtonRow, SectionContent, useLayoutTitle } from 'components';
|
||||
|
||||
import { AuthenticatedContext } from 'contexts/authentication';
|
||||
import { useI18nContext } from 'i18n/i18n-react';
|
||||
|
||||
const DashboardSensors: FC = () => {
|
||||
const Sensors: FC = () => {
|
||||
const { LL } = useI18nContext();
|
||||
const { me } = useContext(AuthenticatedContext);
|
||||
const [selectedTemperatureSensor, setSelectedTemperatureSensor] = useState<TemperatureSensor>();
|
||||
@@ -170,6 +170,8 @@ const DashboardSensors: FC = () => {
|
||||
};
|
||||
});
|
||||
|
||||
useLayoutTitle(LL.SENSORS());
|
||||
|
||||
const formatDurationMin = (duration_min: number) => {
|
||||
const days = Math.trunc((duration_min * 60000) / 86400000);
|
||||
const hours = Math.trunc((duration_min * 60000) / 3600000) % 24;
|
||||
@@ -406,7 +408,7 @@ const DashboardSensors: FC = () => {
|
||||
);
|
||||
|
||||
return (
|
||||
<SectionContent title={LL.SENSOR_DATA()} titleGutter>
|
||||
<SectionContent>
|
||||
{sensorData.ts.length > 0 && (
|
||||
<>
|
||||
<Typography sx={{ pt: 2, pb: 1 }} variant="h6" color="secondary">
|
||||
@@ -467,4 +469,4 @@ const DashboardSensors: FC = () => {
|
||||
);
|
||||
};
|
||||
|
||||
export default DashboardSensors;
|
||||
export default Sensors;
|
||||
@@ -38,7 +38,7 @@ type DashboardSensorsAnalogDialogProps = {
|
||||
validator: Schema;
|
||||
};
|
||||
|
||||
const DashboardSensorsAnalogDialog = ({
|
||||
const SensorsAnalogDialog = ({
|
||||
open,
|
||||
onClose,
|
||||
onSave,
|
||||
@@ -296,4 +296,4 @@ const DashboardSensorsAnalogDialog = ({
|
||||
);
|
||||
};
|
||||
|
||||
export default DashboardSensorsAnalogDialog;
|
||||
export default SensorsAnalogDialog;
|
||||
@@ -26,7 +26,7 @@ import { numberValue, updateValue } from 'utils';
|
||||
|
||||
import { validate } from 'validators';
|
||||
|
||||
type DashboardSensorsTemperatureDialogProps = {
|
||||
type SensorsTemperatureDialogProps = {
|
||||
open: boolean;
|
||||
onClose: () => void;
|
||||
onSave: (ts: TemperatureSensor) => void;
|
||||
@@ -34,13 +34,13 @@ type DashboardSensorsTemperatureDialogProps = {
|
||||
validator: Schema;
|
||||
};
|
||||
|
||||
const DashboardSensorsTemperatureDialog = ({
|
||||
const SensorsTemperatureDialog = ({
|
||||
open,
|
||||
onClose,
|
||||
onSave,
|
||||
selectedItem,
|
||||
validator
|
||||
}: DashboardSensorsTemperatureDialogProps) => {
|
||||
}: SensorsTemperatureDialogProps) => {
|
||||
const { LL } = useI18nContext();
|
||||
const [fieldErrors, setFieldErrors] = useState<ValidateFieldsError>();
|
||||
const [editItem, setEditItem] = useState<TemperatureSensor>(selectedItem);
|
||||
@@ -119,4 +119,4 @@ const DashboardSensorsTemperatureDialog = ({
|
||||
);
|
||||
};
|
||||
|
||||
export default DashboardSensorsTemperatureDialog;
|
||||
export default SensorsTemperatureDialog;
|
||||
@@ -1,37 +0,0 @@
|
||||
import { Tab } from '@mui/material';
|
||||
import { Navigate, Route, Routes } from 'react-router-dom';
|
||||
|
||||
import SettingsApplication from './SettingsApplication';
|
||||
import SettingsCustomEntities from './SettingsCustomEntities';
|
||||
import SettingsCustomization from './SettingsCustomization';
|
||||
import SettingsScheduler from './SettingsScheduler';
|
||||
import type { FC } from 'react';
|
||||
import { RouterTabs, useRouterTab, useLayoutTitle } from 'components';
|
||||
import { useI18nContext } from 'i18n/i18n-react';
|
||||
|
||||
const Settings: FC = () => {
|
||||
const { LL } = useI18nContext();
|
||||
const { routerTab } = useRouterTab();
|
||||
|
||||
useLayoutTitle(LL.SETTINGS_OF(''));
|
||||
|
||||
return (
|
||||
<>
|
||||
<RouterTabs value={routerTab}>
|
||||
<Tab value="/settings/application" label={LL.APPLICATION_SETTINGS()} />
|
||||
<Tab value="/settings/customization" label={LL.CUSTOMIZATIONS()} />
|
||||
<Tab value="/settings/scheduler" label={LL.SCHEDULER()} />
|
||||
<Tab value="/settings/customentities" label={LL.CUSTOM_ENTITIES(0)} />
|
||||
</RouterTabs>
|
||||
<Routes>
|
||||
<Route path="application" element={<SettingsApplication />} />
|
||||
<Route path="customization" element={<SettingsCustomization />} />
|
||||
<Route path="scheduler" element={<SettingsScheduler />} />
|
||||
<Route path="customentities" element={<SettingsCustomEntities />} />
|
||||
<Route path="*" element={<Navigate replace to="/settings/application" />} />
|
||||
</Routes>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default Settings;
|
||||
Reference in New Issue
Block a user