diff --git a/CHANGELOG.md b/CHANGELOG.md index 51ad02fa5..57a0e916e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -212,7 +212,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Added pool data to telegrams 0x494 & 0x495 [#102](https://github.com/emsesp/EMS-ESP32/issues/102) - Add RC300 second summermode telegram [#108](https://github.com/emsesp/EMS-ESP32/issues/108) - Add support for the RC25 thermostat [#106](https://github.com/emsesp/EMS-ESP32/issues/106) -- Add new command 'entities' for a device, e.g. http://ems-esp/api/boiler/entities to show the shortname, description and HA Entity name (if HA enabled) [#116](https://github.com/emsesp/EMS-ESP32/issues/116) +- Add new command 'entities' for a device, e.g. to show the shortname, description and HA Entity name (if HA enabled) [#116](https://github.com/emsesp/EMS-ESP32/issues/116) - Support for Junkers program and remote (fb10/fb110) temperature - Home Assistant `state_class` attribute for Wh, kWh, W and KW [#129](https://github.com/emsesp/EMS-ESP32/issues/129) - Add current room influence for RC300 [#136](https://github.com/emsesp/EMS-ESP32/issues/136) @@ -434,4 +434,4 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - some names of mqtt-tags like in v2.2.1 - new ESP32 partition side to allow for smoother OTA and fallback - Network Gateway IP is optional (#682)emsesp/EMS-ESP -- moved to a new GitHub repo https://github.com/emsesp/EMS-ESP32 +- moved to a new GitHub repo diff --git a/CHANGELOG_LATEST.md b/CHANGELOG_LATEST.md index a45fe6e6e..780d0a2da 100644 --- a/CHANGELOG_LATEST.md +++ b/CHANGELOG_LATEST.md @@ -4,6 +4,8 @@ ## **IMPORTANT! BREAKING CHANGES** +- dallassensor has been renamed to temperaturesensor in MQTT payloads + ## Added - Workaround for better Domoticz MQTT intergration? [#904](https://github.com/emsesp/EMS-ESP32/issues/904) @@ -29,3 +31,5 @@ - Improved HA Discovery so previous configs no longer need to be removed when starting [#1077](https://github.com/emsesp/EMS-ESP32/pull/1077) (thanks @pswid!) - Enlarge UART-Stack to 2,5k - Retry timeout for Mqtt-QOS1/2 10seconds +- Optimize WebUI rendering when using Dialog Boxes [#1116](https://github.com/emsesp/EMS-ESP32/issues/1116) +- Optimize Web libraries to reduce bundle size (3.6.x) [#1112](https://github.com/emsesp/EMS-ESP32/issues/1112) diff --git a/interface/.eslintrc.json b/interface/.eslintrc.json index 32758fa78..4fc97f6f7 100644 --- a/interface/.eslintrc.json +++ b/interface/.eslintrc.json @@ -52,7 +52,7 @@ "@typescript-eslint/no-implied-eval": "off", "@typescript-eslint/no-misused-promises": "off", "arrow-body-style": ["error", "as-needed"], - "react-hooks/exhaustive-deps": "error", + "react-hooks/exhaustive-deps": "warn", "@typescript-eslint/consistent-type-imports": [ "error", { diff --git a/interface/package.json b/interface/package.json index 1a2472c86..517e0bb70 100644 --- a/interface/package.json +++ b/interface/package.json @@ -20,20 +20,20 @@ "lint-fixall": "eslint . --cache --fix" }, "dependencies": { - "@emotion/react": "^11.10.6", - "@emotion/styled": "^11.10.6", + "@emotion/react": "^11.10.8", + "@emotion/styled": "^11.10.8", "@msgpack/msgpack": "^3.0.0-beta2", "@mui/icons-material": "^5.11.16", - "@mui/material": "^5.12.1", + "@mui/material": "^5.12.2", "@remix-run/router": "^1.5.0", - "@table-library/react-table-library": "4.1.0", + "@table-library/react-table-library": "4.1.2", "@types/lodash-es": "^4.17.7", - "@types/node": "^18.16.0", - "@types/react": "^18.0.38", - "@types/react-dom": "^18.0.11", + "@types/node": "^18.16.2", + "@types/react": "^18.2.0", + "@types/react-dom": "^18.2.1", "@types/react-router-dom": "^5.3.3", "async-validator": "^4.2.5", - "axios": "^1.3.6", + "axios": "^1.4.0", "history": "^5.3.0", "jwt-decode": "^3.1.2", "lodash-es": "^4.17.21", @@ -67,7 +67,7 @@ "prettier": "^2.8.8", "rollup-plugin-visualizer": "^5.9.0", "terser": "^5.17.1", - "vite": "^4.3.1", + "vite": "^4.3.3", "vite-plugin-svgr": "^2.4.0", "vite-tsconfig-paths": "^4.2.0" }, diff --git a/interface/src/framework/mqtt/MqttSettingsForm.tsx b/interface/src/framework/mqtt/MqttSettingsForm.tsx index b2deb9d25..189610cf4 100644 --- a/interface/src/framework/mqtt/MqttSettingsForm.tsx +++ b/interface/src/framework/mqtt/MqttSettingsForm.tsx @@ -1,6 +1,6 @@ import CancelIcon from '@mui/icons-material/Cancel'; import WarningIcon from '@mui/icons-material/Warning'; -import { Button, Checkbox, MenuItem, Grid, Typography, InputAdornment } from '@mui/material'; +import { Button, Checkbox, MenuItem, Grid, Typography, InputAdornment, TextField } from '@mui/material'; import { useState } from 'react'; import type { ValidateFieldsError } from 'async-validator'; import type { FC } from 'react'; @@ -94,7 +94,7 @@ const MqttSettingsForm: FC = () => { /> - { /> - { /> - { 0 1 2 - + { {LL.FORMATTING()} - { > {LL.MQTT_NEST_1()} {LL.MQTT_NEST_2()} - + } label={LL.MQTT_RESPONSE()} @@ -233,7 +233,7 @@ const MqttSettingsForm: FC = () => { alignItems="flex-start" > - { > Home Assistant Domoticz - + - { /> - { {LL.MQTT_ENTITY_FORMAT_0()} {LL.MQTT_ENTITY_FORMAT_1()} {LL.MQTT_ENTITY_FORMAT_2()} - + )} @@ -299,8 +299,7 @@ const MqttSettingsForm: FC = () => { /> - { /> - { /> - { /> - { /> - { /> - {LL.SECONDS()} diff --git a/interface/src/framework/network/NetworkSettingsForm.tsx b/interface/src/framework/network/NetworkSettingsForm.tsx index 308121075..bc2a768bc 100644 --- a/interface/src/framework/network/NetworkSettingsForm.tsx +++ b/interface/src/framework/network/NetworkSettingsForm.tsx @@ -15,7 +15,8 @@ import { ListItemSecondaryAction, ListItemText, Typography, - InputAdornment + InputAdornment, + TextField } from '@mui/material'; import { useContext, useEffect, useState } from 'react'; import { toast } from 'react-toastify'; @@ -165,7 +166,6 @@ const WiFiSettingsForm: FC = () => { margin="normal" /> )} - { type="number" margin="normal" /> - } label={LL.NETWORK_DISABLE_SLEEP()} /> - } label={LL.NETWORK_LOW_BAND()} /> - {LL.GENERAL_OPTIONS()} - { onChange={updateFormValue} margin="normal" /> - } label={LL.NETWORK_USE_DNS()} /> - } label={LL.NETWORK_ENABLE_CORS()} /> {data.enableCORS && ( - { margin="normal" /> )} - } label={LL.NETWORK_ENABLE_IPV6()} /> - } label={LL.NETWORK_FIXED_IP()} diff --git a/interface/src/framework/system/SystemLog.tsx b/interface/src/framework/system/SystemLog.tsx index 5019738fc..ca2251d3a 100644 --- a/interface/src/framework/system/SystemLog.tsx +++ b/interface/src/framework/system/SystemLog.tsx @@ -1,6 +1,6 @@ import DownloadIcon from '@mui/icons-material/GetApp'; import WarningIcon from '@mui/icons-material/Warning'; -import { Box, styled, Button, Checkbox, MenuItem, Grid } from '@mui/material'; +import { Box, styled, Button, Checkbox, MenuItem, Grid, TextField } from '@mui/material'; import { useState, useEffect, useCallback, useLayoutEffect } from 'react'; import type { FC } from 'react'; @@ -138,7 +138,6 @@ const SystemLog: FC = () => { return () => { es.close(); }; - // eslint-disable-next-line }, []); const content = () => { @@ -150,7 +149,7 @@ const SystemLog: FC = () => { <> - { INFO DEBUG ALL - + - { 50 75 100 - + { return ( <> - + + - } /> + } /> + } /> } /> - } /> + } /> ); diff --git a/interface/src/project/DashboardData.tsx b/interface/src/project/DashboardDevices.tsx similarity index 50% rename from interface/src/project/DashboardData.tsx rename to interface/src/project/DashboardDevices.tsx index 4af8b8673..e35dcef99 100644 --- a/interface/src/project/DashboardData.tsx +++ b/interface/src/project/DashboardDevices.tsx @@ -45,8 +45,8 @@ import DeviceIcon from './DeviceIcon'; import * as EMSESP from './api'; -import { DeviceValueUOM, DeviceValueUOM_s, AnalogType, AnalogTypeNames, DeviceEntityMask } from './types'; -import type { SensorData, Device, CoreData, DeviceData, DeviceValue, Sensor, Analog } from './types'; +import { DeviceValueUOM, DeviceValueUOM_s, DeviceEntityMask } from './types'; +import type { SensorData, Device, CoreData, DeviceData, DeviceValue, TemperatureSensor, AnalogSensor } from './types'; import type { FC } from 'react'; import { ButtonRow, ValidatedTextField, SectionContent, MessageBox } from 'components'; import { AuthenticatedContext } from 'contexts/authentication'; @@ -54,26 +54,22 @@ import { AuthenticatedContext } from 'contexts/authentication'; import { useI18nContext } from 'i18n/i18n-react'; import { numberValue, updateValue, extractErrorMessage } from 'utils'; -const DashboardData: FC = () => { +const DashboardDevices: FC = () => { const { me } = useContext(AuthenticatedContext); - const { LL } = useI18nContext(); - - const [coreData, setCoreData] = useState({ - connected: true, - devices: [], - s_n: '', - active_sensors: 0, - analog_enabled: false - }); - const [deviceData, setDeviceData] = useState({ label: '', data: [] }); - const [sensorData, setSensorData] = useState({ sensors: [], analogs: [] }); const [deviceValue, setDeviceValue] = useState(); - const [sensor, setSensor] = useState(); - const [analog, setAnalog] = useState(); const [deviceDialog, setDeviceDialog] = useState(-1); const [onlyFav, setOnlyFav] = useState(false); + const [coreData, setCoreData] = useState({ + connected: true, + devices: [] + }); + const [selectedDevice, setSelectedDevice] = useState(); + + const [sensorData, setSensorData] = useState({ ts: [], as: [] }); + const [analog, setAnalog] = useState(); + const [sensor, setSensor] = useState(); const common_theme = useTheme({ BaseRow: ` @@ -168,25 +164,6 @@ const DashboardData: FC = () => { } ]); - const temperature_theme = useTheme([data_theme]); - - const analog_theme = useTheme([ - data_theme, - { - Table: ` - --data-table-library_grid-template-columns: 80px repeat(1, minmax(0, 1fr)) 120px 100px 40px; - `, - BaseCell: ` - &:nth-of-type(2) { - text-align: left; - }, - &:nth-of-type(4) { - text-align: right; - } - ` - } - ]); - const getSortIcon = (state: any, sortKey: any) => { if (state.sortKey === sortKey && state.reverse) { return ; @@ -197,41 +174,6 @@ const DashboardData: FC = () => { return ; }; - const analog_sort = useSort( - { nodes: sensorData.analogs }, - {}, - { - sortIcon: { - iconDefault: , - iconUp: , - iconDown: - }, - sortToggleType: SortToggleType.AlternateWithReset, - sortFns: { - GPIO: (array) => array.sort((a, b) => a.g - b.g), - NAME: (array) => array.sort((a, b) => a.n.localeCompare(b.n)), - TYPE: (array) => array.sort((a, b) => a.t - b.t) - } - } - ); - - const sensor_sort = useSort( - { nodes: sensorData.sensors }, - {}, - { - sortIcon: { - iconDefault: , - iconUp: , - iconDown: - }, - sortToggleType: SortToggleType.AlternateWithReset, - sortFns: { - NAME: (array) => array.sort((a, b) => a.n.localeCompare(b.n)), - TEMPERATURE: (array) => array.sort((a, b) => a.t - b.t) - } - } - ); - const dv_sort = useSort( { nodes: deviceData.data }, {}, @@ -256,18 +198,17 @@ const DashboardData: FC = () => { } ); - const fetchSensorData = async () => { - try { - setSensorData((await EMSESP.readSensorData()).data); - } catch (error) { - toast.error(extractErrorMessage(error, LL.PROBLEM_LOADING())); - } - }; + // const fetchSensorData = async () => { + // try { + // setSensorData((await EMSESP.readSensorData()).data); + // } catch (error) { + // toast.error(extractErrorMessage(error, LL.PROBLEM_LOADING())); + // } + // }; - const fetchDeviceData = async (id: string) => { - const unique_id = parseInt(id); + const fetchDeviceData = async (id: number) => { try { - setDeviceData((await EMSESP.readDeviceData({ id: unique_id })).data); + setDeviceData((await EMSESP.readDeviceData({ id })).data); } catch (error) { toast.error(extractErrorMessage(error, LL.PROBLEM_LOADING())); } @@ -285,29 +226,43 @@ const DashboardData: FC = () => { void fetchCoreData(); }, [fetchCoreData]); - const refreshDataIndex = (selectedDevice: string) => { - if (selectedDevice === 'sensor') { - void fetchSensorData(); - return; - } + // const refreshDataIndex = (selectedDevice: string) => { + // // if (selectedDevice === 'sensor') { + // // void fetchSensorData(); + // // return; + // // } - setSensorData({ sensors: [], analogs: [] }); + // // setSensorData({ sensors: [], analogs: [] }); + // if (selectedDevice) { + // void fetchDeviceData(selectedDevice); + // } else { + // void fetchCoreData(); + // } + // }; + + const refreshData = () => { + // const selectedDevice = device_select.state.id; + // if (selectedDevice === 'sensor') { + // // void fetchSensorData(); + // return; + // } + + // setSensorData({ sensors: [], analogs: [] }); if (selectedDevice) { void fetchDeviceData(selectedDevice); } else { void fetchCoreData(); } - }; - const refreshData = () => { - refreshDataIndex(device_select.state.id); + // refreshDataIndex(device_select.state.id); }; function onSelectChange(action: any, state: any) { + setSelectedDevice(device_select.state.id); if (action.type === 'ADD_BY_ID_EXCLUSIVELY') { refreshData(); } else { - setSensorData({ sensors: [], analogs: [] }); + // setSensorData({ sensors: [], analogs: [] }); } } @@ -437,7 +392,7 @@ const DashboardData: FC = () => { const sendDeviceValue = async () => { if (deviceValue) { try { - const response = await EMSESP.writeValue({ + const response = await EMSESP.writeDeviceValue({ id: Number(device_select.state.id), devicevalue: deviceValue }); @@ -523,100 +478,6 @@ const DashboardData: FC = () => { } }; - const addAnalogSensor = () => { - setAnalog({ id: '0', g: 0, n: '', u: 0, v: 0, o: 0, t: 0, f: 1 }); - }; - - const sendSensor = async () => { - if (sensor) { - try { - const response = await EMSESP.writeSensor({ - id: sensor.id, - name: sensor.n, - offset: sensor.o - }); - if (response.status === 204) { - toast.error(LL.UPLOAD_OF(LL.SENSOR()) + ' ' + LL.FAILED()); - } else if (response.status === 403) { - toast.error(LL.ACCESS_DENIED()); - } else { - toast.success(LL.UPDATED_OF(LL.SENSOR())); - } - setSensor(undefined); - } catch (error) { - toast.error(extractErrorMessage(error, LL.PROBLEM_UPDATING())); - } finally { - setSensor(undefined); - await fetchSensorData(); - } - } - }; - - const renderSensorDialog = () => { - if (sensor) { - return ( - setSensor(undefined)}> - - {LL.EDIT()} {LL.TEMP_SENSOR()} - - - - - {LL.ID_OF(LL.SENSOR())}: {sensor.id} - - - - - - - - °C - }} - /> - - - - - - - - - ); - } - }; - const renderDeviceDialog = () => { if (coreData && coreData.devices.length > 0 && deviceDialog !== -1) { return ( @@ -692,21 +553,6 @@ const DashboardData: FC = () => { ))} - {(coreData.active_sensors > 0 || coreData.analog_enabled) && ( - - - - - {coreData.s_n} - {LL.ATTACHED_SENSORS()} - {coreData.active_sensors} - - addAnalogSensor()}> - - - - - )} )} @@ -813,421 +659,13 @@ const DashboardData: FC = () => { ); }; - const updateSensor = (s: Sensor) => { - if (s && me.admin) { - setSensor(s); - } - }; - - const updateAnalog = (a: Analog) => { - if (me.admin) { - setAnalog(a); - } - }; - - const renderDallasData = () => ( - <> - - {LL.TEMP_SENSORS()} - - - {(tableList: any) => ( - <> -
- - - - - - - - - -
- - {tableList.map((s: Sensor) => ( - updateSensor(s)}> - {s.n} - {formatValue(s.t, s.u)} - - {me.admin && ( - updateSensor(s)}> - - - )} - - - ))} - - - )} -
- - ); - - const renderAnalogData = () => ( - <> - - {LL.ANALOG_SENSORS()} - - - - {(tableList: any) => ( - <> -
- - - - - - - - - - - {LL.VALUE(0)} - - -
- - {tableList.map((a: Analog) => ( - updateAnalog(a)}> - {a.g} - {a.n} - {AnalogTypeNames[a.t]} - {a.t ? formatValue(a.v, a.u) : ''} - - {me.admin && ( - updateAnalog(a)}> - - - )} - - - ))} - - - )} -
- - ); - - const sendRemoveAnalog = async () => { - if (analog) { - try { - const response = await EMSESP.writeAnalog({ - gpio: analog.g, - name: analog.n, - offset: analog.o, - factor: analog.f, - uom: analog.u, - type: -1 - }); - - if (response.status === 204) { - toast.error(LL.DELETION_OF(LL.ANALOG_SENSOR()) + ' ' + LL.FAILED()); - } else if (response.status === 403) { - toast.error(LL.ACCESS_DENIED()); - } else { - toast.success(LL.REMOVED_OF(LL.ANALOG_SENSOR())); - } - } catch (error) { - toast.error(extractErrorMessage(error, LL.PROBLEM_UPDATING())); - } finally { - setAnalog(undefined); - await fetchSensorData(); - } - } - }; - - const sendAnalog = async () => { - if (analog) { - try { - const response = await EMSESP.writeAnalog({ - gpio: analog.g, - name: analog.n, - offset: analog.o, - factor: analog.f, - uom: analog.u, - type: analog.t - }); - - if (response.status === 204) { - toast.error(LL.UPDATE_OF(LL.ANALOG_SENSOR()) + ' ' + LL.FAILED()); - } else if (response.status === 403) { - toast.error(LL.ACCESS_DENIED()); - } else { - toast.success(LL.UPDATED_OF(LL.ANALOG_SENSOR())); - } - } catch (error) { - toast.error(extractErrorMessage(error, LL.PROBLEM_UPDATING())); - } finally { - setAnalog(undefined); - await fetchSensorData(); - } - } - }; - - const renderAnalogDialog = () => { - if (analog) { - return ( - setAnalog(undefined)}> - - {LL.EDIT()} {LL.ANALOG_SENSOR()} - - - - - - - - - - - - {AnalogTypeNames.map((val, i) => ( - - {val} - - ))} - - - {analog.t >= AnalogType.COUNTER && analog.t <= AnalogType.RATE && ( - <> - - - {DeviceValueUOM_s.map((val, i) => ( - - {val} - - ))} - - - {analog.t === AnalogType.ADC && ( - - mV - }} - /> - - )} - {analog.t === AnalogType.COUNTER && ( - - - - )} - - - - - )} - {analog.t === AnalogType.DIGITAL_OUT && (analog.g === 25 || analog.g === 26) && ( - <> - - - - - )} - {analog.t === AnalogType.DIGITAL_OUT && analog.g !== 25 && analog.g !== 26 && ( - <> - - - - - )} - {analog.t >= AnalogType.PWM_0 && ( - <> - - Hz - }} - /> - - - % - }} - /> - - - )} - - - {LL.WARN_GPIO()} - - - - - - - - - - - ); - } - }; - return ( - + {renderCoreData()} {renderDeviceData()} {renderDeviceDialog()} - {sensorData.sensors.length !== 0 && renderDallasData()} - {sensorData.analogs.length !== 0 && renderAnalogData()} {renderDeviceValueDialog()} - {renderSensorDialog()} - {renderAnalogDialog()} + + + + + + + ); +}; + +export default DashboardSensors; diff --git a/interface/src/project/DashboardSensorsAnalogDialog.tsx b/interface/src/project/DashboardSensorsAnalogDialog.tsx new file mode 100644 index 000000000..b34489b1e --- /dev/null +++ b/interface/src/project/DashboardSensorsAnalogDialog.tsx @@ -0,0 +1,261 @@ +import CancelIcon from '@mui/icons-material/Cancel'; +import RemoveIcon from '@mui/icons-material/RemoveCircleOutline'; +import WarningIcon from '@mui/icons-material/Warning'; + +import { + Button, + Typography, + Box, + Dialog, + DialogTitle, + DialogContent, + DialogActions, + InputAdornment, + Grid, + MenuItem, + TextField +} from '@mui/material'; +import { useState, useEffect } from 'react'; + +import { AnalogType, AnalogTypeNames, DeviceValueUOM_s } from './types'; +import type { AnalogSensor } from './types'; +import type Schema from 'async-validator'; +import type { ValidateFieldsError } from 'async-validator'; +import { ValidatedTextField } from 'components'; + +import { useI18nContext } from 'i18n/i18n-react'; +import { numberValue, updateValue } from 'utils'; + +import { validate } from 'validators'; + +type DashboardSensorsAnalogDialogProps = { + open: boolean; + onClose: () => void; + onSave: (as: AnalogSensor) => void; + creating: boolean; + selectedItem: AnalogSensor; + validator: Schema; +}; + +const DashboardSensorsAnalogDialog = ({ + open, + onClose, + onSave, + creating, + selectedItem, + validator +}: DashboardSensorsAnalogDialogProps) => { + const { LL } = useI18nContext(); + const [fieldErrors, setFieldErrors] = useState(); + const [editItem, setEditItem] = useState(selectedItem); + const updateFormValue = updateValue(setEditItem); + + useEffect(() => { + if (open) { + setFieldErrors(undefined); + setEditItem(selectedItem); + } + }, [open, selectedItem]); + + const close = () => { + onClose(); + }; + + const save = async () => { + try { + setFieldErrors(undefined); + await validate(validator, editItem); + onSave(editItem); + } catch (errors: any) { + setFieldErrors(errors); + } + }; + + const remove = () => { + editItem.d = true; + onSave(editItem); + }; + + return ( + + + {creating ? LL.ADD(1) + ' ' + LL.NEW(1) : LL.EDIT()} {LL.ANALOG_SENSOR()} + + + + + + + + + + + + {AnalogTypeNames.map((val, i) => ( + + {val} + + ))} + + + {editItem.t >= AnalogType.COUNTER && editItem.t <= AnalogType.RATE && ( + <> + + + {DeviceValueUOM_s.map((val, i) => ( + + {val} + + ))} + + + {editItem.t === AnalogType.ADC && ( + + mV + }} + /> + + )} + {editItem.t === AnalogType.COUNTER && ( + + + + )} + + + + + )} + {editItem.t === AnalogType.DIGITAL_OUT && (editItem.g === 25 || editItem.g === 26) && ( + + + + )} + {editItem.t === AnalogType.DIGITAL_OUT && editItem.g !== 25 && editItem.g !== 26 && ( + + + + )} + {editItem.t >= AnalogType.PWM_0 && ( + <> + + Hz + }} + /> + + + % + }} + /> + + + )} + + + {LL.WARN_GPIO()} + + + + {!creating && ( + + + + )} + + + + + ); +}; + +export default DashboardSensorsAnalogDialog; diff --git a/interface/src/project/DashboardSensorsTemperatureDialog.tsx b/interface/src/project/DashboardSensorsTemperatureDialog.tsx new file mode 100644 index 000000000..ddda88a3c --- /dev/null +++ b/interface/src/project/DashboardSensorsTemperatureDialog.tsx @@ -0,0 +1,121 @@ +import CancelIcon from '@mui/icons-material/Cancel'; +import WarningIcon from '@mui/icons-material/Warning'; + +import { + Button, + Typography, + Box, + Dialog, + DialogTitle, + DialogContent, + DialogActions, + InputAdornment, + Grid, + TextField +} from '@mui/material'; +import { useState, useEffect } from 'react'; + +import type { TemperatureSensor } from './types'; +import type Schema from 'async-validator'; +import type { ValidateFieldsError } from 'async-validator'; +import { ValidatedTextField } from 'components'; + +import { useI18nContext } from 'i18n/i18n-react'; +import { numberValue, updateValue } from 'utils'; + +import { validate } from 'validators'; + +type DashboardSensorsTemperatureDialogProps = { + open: boolean; + onClose: () => void; + onSave: (ts: TemperatureSensor) => void; + selectedItem: TemperatureSensor; + validator: Schema; +}; + +const DashboardSensorsTemperatureDialog = ({ + open, + onClose, + onSave, + selectedItem, + validator +}: DashboardSensorsTemperatureDialogProps) => { + const { LL } = useI18nContext(); + const [fieldErrors, setFieldErrors] = useState(); + const [editItem, setEditItem] = useState(selectedItem); + const updateFormValue = updateValue(setEditItem); + + useEffect(() => { + if (open) { + setFieldErrors(undefined); + setEditItem(selectedItem); + } + }, [open, selectedItem]); + + const close = () => { + onClose(); + }; + + const save = async () => { + try { + setFieldErrors(undefined); + await validate(validator, editItem); + onSave(editItem); + } catch (errors: any) { + setFieldErrors(errors); + } + }; + + return ( + + + {LL.EDIT()} {LL.TEMP_SENSOR()} + + + + + {LL.ID_OF(LL.SENSOR())}: {editItem.id} + + + + + + + + °C + }} + /> + + + + + + + + + ); +}; + +export default DashboardSensorsTemperatureDialog; diff --git a/interface/src/project/DeviceIcon.tsx b/interface/src/project/DeviceIcon.tsx index 190a659a8..9db5dbacd 100644 --- a/interface/src/project/DeviceIcon.tsx +++ b/interface/src/project/DeviceIcon.tsx @@ -15,7 +15,7 @@ interface DeviceIconProps { // matches emsdevice.h DeviceType const enum DeviceType { SYSTEM = 0, - DALLASSENSOR, + TEMPERATURESENSOR, ANALOGSENSOR, SCHEDULER, BOILER, @@ -37,7 +37,7 @@ const enum DeviceType { const DeviceIcon: FC = ({ type_id }) => { switch (type_id) { - case DeviceType.DALLASSENSOR: + case DeviceType.TEMPERATURESENSOR: case DeviceType.ANALOGSENSOR: return ; case DeviceType.BOILER: diff --git a/interface/src/project/SettingsApplication.tsx b/interface/src/project/SettingsApplication.tsx index 933167329..a2a67c02b 100644 --- a/interface/src/project/SettingsApplication.tsx +++ b/interface/src/project/SettingsApplication.tsx @@ -1,7 +1,7 @@ import CancelIcon from '@mui/icons-material/Cancel'; import PowerSettingsNewIcon from '@mui/icons-material/PowerSettingsNew'; import WarningIcon from '@mui/icons-material/Warning'; -import { Box, Button, Checkbox, MenuItem, Grid, Typography, Divider, InputAdornment } from '@mui/material'; +import { Box, Button, Checkbox, MenuItem, Grid, Typography, Divider, InputAdornment, TextField } from '@mui/material'; import { useState } from 'react'; import { toast } from 'react-toastify'; @@ -132,7 +132,7 @@ const SettingsApplication: FC = () => { {LL.BOARD_PROFILE_TEXT()} - { {LL.CUSTOM()}… - + {data.board_profile === 'CUSTOM' && ( <> { /> - { {LL.DISABLED(1)} LAN8720 TLK110 - +
{data.phy_type !== 0 && ( @@ -257,7 +257,7 @@ const SettingsApplication: FC = () => { alignItems="flex-start" > - { /> - { /> - { GPIO0_OUT GPIO16_OUT GPIO17_OUT - +
)} @@ -309,7 +309,7 @@ const SettingsApplication: FC = () => { - { EMS+ HT3 {LL.HARDWARE()} - + - { Gateway 4 (0x4B) Gateway 5 (0x4C) Gateway 7 (0x4D) - + {LL.GENERAL_OPTIONS()} - { Polski (PL) Svenska (SV) Türk (TR) - + {data.led_gpio !== 0 && ( { - { {LL.ONOFF_CAP()} true/false 1/0 - + - { true/false "1"/"0" 1/0 - + - { > {LL.VALUE(1)} {LL.INDEX()} - + {data.dallas_gpio !== 0 && ( @@ -590,7 +590,7 @@ const SettingsApplication: FC = () => { />
- { INFO DEBUG ALL - + { )} - {!restartNeeded && dirtyFlags && dirtyFlags.length !== 0 && (