diff --git a/interface/src/project/DashboardData.tsx b/interface/src/project/DashboardData.tsx index e3009ccc4..235fb8ece 100644 --- a/interface/src/project/DashboardData.tsx +++ b/interface/src/project/DashboardData.tsx @@ -285,11 +285,6 @@ const DashboardData: FC = () => { } ); - const paul = () => { - console.log('paul'); - sensor_sort.fns.onToggleSort({ sortKey: 'NAME' }); - }; - const device_select = useRowSelect( { nodes: coreData.devices }, { @@ -829,8 +824,7 @@ const DashboardData: FC = () => { fullWidth style={{ fontSize: '14px', justifyContent: 'flex-start' }} endIcon={getSortIcon(sensor_sort.state, 'NAME')} - // onClick={() => sensor_sort.fns.onToggleSort({ sortKey: 'NAME' })} - onClick={() => paul()} + onClick={() => sensor_sort.fns.onToggleSort({ sortKey: 'NAME' })} > NAME diff --git a/interface/src/project/SettingsCustomization.tsx b/interface/src/project/SettingsCustomization.tsx index 3eba6cbc2..88fa675e9 100644 --- a/interface/src/project/SettingsCustomization.tsx +++ b/interface/src/project/SettingsCustomization.tsx @@ -2,10 +2,6 @@ import { FC, useState, useEffect, useCallback } from 'react'; import { Button, - Table, - TableBody, - TableHead, - TableRow, Typography, Box, MenuItem, @@ -17,19 +13,22 @@ import { ToggleButtonGroup } from '@mui/material'; -import TableCell, { tableCellClasses } from '@mui/material/TableCell'; - -import { styled } from '@mui/material/styles'; +import { Table } from '@table-library/react-table-library/table'; +import { useTheme } from '@table-library/react-table-library/theme'; +import { useSort } from '@table-library/react-table-library/sort'; +import { Header, HeaderRow, HeaderCell, Body, Row, Cell } from '@table-library/react-table-library/table'; import { useSnackbar } from 'notistack'; import SaveIcon from '@mui/icons-material/Save'; import CancelIcon from '@mui/icons-material/Cancel'; import EditOffOutlinedIcon from '@mui/icons-material/EditOffOutlined'; -import FavoriteBorderOutlinedIcon from '@mui/icons-material/FavoriteBorderOutlined'; +import StarIcon from '@mui/icons-material/Star'; import VisibilityOffOutlinedIcon from '@mui/icons-material/VisibilityOffOutlined'; import CommentsDisabledOutlinedIcon from '@mui/icons-material/CommentsDisabledOutlined'; import SettingsBackupRestoreIcon from '@mui/icons-material/SettingsBackupRestore'; +import KeyboardArrowUpOutlinedIcon from '@mui/icons-material/KeyboardArrowUpOutlined'; +import KeyboardArrowDownOutlinedIcon from '@mui/icons-material/KeyboardArrowDownOutlined'; import { ButtonRow, FormLoader, ValidatedTextField, SectionContent } from '../components'; @@ -39,16 +38,10 @@ import { extractErrorMessage } from '../utils'; import { DeviceShort, Devices, DeviceEntity } from './types'; -const StyledTableCell = styled(TableCell)(({ theme }) => ({ - [`&.${tableCellClasses.head}`]: { - backgroundColor: '#607d8b' - } -})); - const SettingsCustomization: FC = () => { const { enqueueSnackbar } = useSnackbar(); - const [deviceEntities, setDeviceEntities] = useState(); + const [deviceEntities, setDeviceEntities] = useState([{ id: '', v: 0, s: '', m: 0, w: false }]); const [devices, setDevices] = useState(); const [errorMessage, setErrorMessage] = useState(); const [selectedDevice, setSelectedDevice] = useState(0); @@ -57,6 +50,86 @@ const SettingsCustomization: FC = () => { // eslint-disable-next-line const [masks, setMasks] = useState(() => ['']); + const entities_theme = useTheme({ + BaseRow: ` + font-size: 14px; + color: white; + height: 32px; + `, + HeaderRow: ` + text-transform: uppercase; + background-color: black; + border-bottom: 1px solid #e0e0e0; + color: #90CAF9; + `, + Row: ` + background-color: #1e1e1e; + border-top: 1px solid #565656; + border-bottom: 1px solid #565656; + position: relative; + z-index: 1; + &:not(:last-of-type) { + margin-bottom: -1px; + } + &:not(:first-of-type) { + margin-top: -1px; + } + &:hover { + z-index: 2; + color: white; + border-top: 1px solid #177ac9; + border-bottom: 1px solid #177ac9; + }, + &.tr.tr-body.row-select.row-select-single-selected, &.tr.tr-body.row-select.row-select-selected { + background-color: #3d4752; + color: white; + font-weight: normal; + z-index: 2; + border-top: 1px solid #177ac9; + border-bottom: 1px solid #177ac9; + } + `, + BaseCell: ` + border-top: 1px solid transparent; + border-right: 1px solid transparent; + border-bottom: 1px solid transparent; + &:nth-of-type(1) { + min-width: 128px; + width: 128px; + } + ` + }); + + const getSortIcon = (state: any, sortKey: any) => { + if (state.sortKey === sortKey && state.reverse) { + return ; + } + + if (state.sortKey === sortKey && !state.reverse) { + return ; + } + }; + + const entity_sort = useSort( + { nodes: deviceEntities }, + { + state: { + sortKey: 'NAME', + reverse: false + } + }, + { + sortIcon: { + iconDefault: null, + iconUp: , + iconDown: + }, + sortFns: { + NAME: (array) => array.sort((a, b) => a.id.localeCompare(b.id)) + } + } + ); + const fetchDevices = useCallback(async () => { try { setDevices((await EMSESP.readDevices()).data); @@ -119,7 +192,7 @@ const SettingsCustomization: FC = () => { Select a device and customize each of its entities using the options: - +  mark it as favorite to be listed at the top of the Dashboard @@ -205,7 +278,7 @@ const SettingsCustomization: FC = () => { const getMask = (de: DeviceEntity) => { var new_masks = []; - if ((de.m & 1) === 1 || de.n === '') { + if ((de.m & 1) === 1 || de.id === '') { new_masks.push('1'); } if ((de.m & 2) === 2) { @@ -222,47 +295,61 @@ const SettingsCustomization: FC = () => { }; return ( - - - - OPTIONS - ENTITY NAME (CODE) - VALUE - - - - {deviceEntities.map((de) => ( - - - { - setMask(de, mask); - }} - > - - - - - - - - - - - - - - - - {de.n} ({de.s}) - - {formatValue(de.v)} - - ))} - +
+ {(tableList: any) => ( + <> +
+ + OPTIONS + + + + VALUE + + +
+ + {tableList.map((de: DeviceEntity) => ( + + + { + setMask(de, mask); + }} + > + + + + + + + + + + + + + + + + {de.id} ({de.s}) + + {formatValue(de.v)} + + ))} + + + )}
); }; diff --git a/interface/src/project/types.ts b/interface/src/project/types.ts index bcf2815e3..c78745e55 100644 --- a/interface/src/project/types.ts +++ b/interface/src/project/types.ts @@ -129,7 +129,7 @@ export interface DeviceData { } export interface DeviceEntity { - n: string; // name + id: string; // name v: any; // value, in any format s: string; // shortname m: number; // mask diff --git a/mock-api/server.js b/mock-api/server.js index d188ecc83..972cd7ccc 100644 --- a/mock-api/server.js +++ b/mock-api/server.js @@ -576,35 +576,35 @@ const emsesp_devicedata_4 = { const emsesp_deviceentities_1 = [ { v: '(0)', - n: 'error code', + id: 'error code', s: 'errorcode', m: 0, w: false, }, { v: '14:54:39 06/06/2021', - n: 'date/time', + id: 'date/time', s: 'datetime', m: 0, w: false, }, { v: 18.2, - n: 'hc1 selected room temperature', + id: 'hc1 selected room temperature', s: 'hc1/seltemp', m: 0, w: true, }, { v: 22.6, - n: 'hc1 current room temperature', + id: 'hc1 current room temperature', s: 'hc1/curtemp', m: 0, w: false, }, { v: 'auto', - n: 'hc1 mode', + id: 'hc1 mode', s: 'hc1/mode', m: 0, w: true, @@ -612,105 +612,105 @@ const emsesp_deviceentities_1 = [ ] const emsesp_deviceentities_2 = [ - { v: false, n: 'heating active', s: 'heatingactive', m: 0 }, - { v: false, n: 'tapwater active', s: 'tapwateractive', m: 0 }, - { v: 5, n: 'selected flow temperature', s: 'selflowtemp', m: 0 }, - { v: 0, n: 'burner selected max power', s: 'selburnpow', m: 0 }, - { v: 0, n: 'heating pump modulation', s: 'heatingpumpmod', m: 0 }, - { n: 'heating pump 2 modulation', s: 'heatingpump2mod', m: 0 }, - { n: 'outside temperature', s: 'outdoortemp', m: 0 }, - { v: 53, n: 'current flow temperature', s: 'curflowtemp', m: 0 }, - { v: 51.8, n: 'return temperature', s: 'rettemp', m: 0 }, - { n: 'mixing switch temperature', s: 'switchtemp', m: 0 }, - { v: 1.3, n: 'system pressure', s: 'syspress', m: 0 }, - { v: 54.6, n: 'actual boiler temperature', s: 'boiltemp', m: 0 }, - { n: 'exhaust temperature', s: 'exhausttemp', m: 0 }, - { v: false, n: 'gas', s: 'burngas', m: 0 }, - { v: false, n: 'gas stage 2', s: 'burngas2', m: 0 }, - { v: 0, n: 'flame current', s: 'flamecurr', m: 0 }, - { v: false, n: 'heating pump', s: 'heatingpump', m: 0 }, - { v: false, n: 'fan', s: 'fanwork', m: 0 }, - { v: false, n: 'ignition', s: 'ignwork', m: 0 }, - { v: false, n: 'oil preheating', s: 'oilpreheat', m: 0 }, - { v: true, n: 'heating activated', s: 'heatingactivated', m: 0 }, - { v: 80, n: 'heating temperature', s: 'heatingtemp', m: 0 }, - { v: 70, n: 'burner pump max power', s: 'pumpmodmax', m: 0 }, - { v: 30, n: 'burner pump min power', s: 'pumpmodmin', m: 0 }, - { v: 1, n: 'pump delay', s: 'pumpdelay', m: 0 }, - { v: 10, n: 'burner min period', s: 'burnminperiod', m: 0 }, - { v: 0, n: 'burner min power', s: 'burnminpower', m: 0 }, - { v: 50, n: 'burner max power', s: 'burnmaxpower', m: 0 }, - { v: -6, n: 'hysteresis on temperature', s: 'boilhyston', m: 0 }, - { v: 6, n: 'hysteresis off temperature', s: 'boilhystoff', m: 0 }, - { v: 0, n: 'set flow temperature', s: 'setflowtemp', m: 0 }, - { v: 0, n: 'burner set power', s: 'setburnpow', m: 0 }, - { v: 0, n: 'burner current power', s: 'curburnpow', m: 0 }, - { v: 326323, n: 'burner starts', s: 'burnstarts', m: 0 }, - { v: 553437, n: 'total burner operating time', s: 'burnworkmin', m: 0 }, - { v: 451286, n: 'total heat operating time', s: 'heatworkmin', m: 0 }, - { v: 4672175, n: 'total UBA operating time', s: 'ubauptime', m: 0 }, - { v: '1C(210) 06.06.2020 12:07 (0 min)', n: 'last error code', s: 'lastcode', m: 0 }, - { v: '0H', n: 'service code', s: 'servicecode', m: 0 }, - { v: 203, n: 'service code number', s: 'servicecodenumber', m: 0 }, - { v: 'H00', n: 'maintenance message', s: 'maintenancemessage', m: 0 }, - { v: 'manual', n: 'maintenance scheduled', s: 'maintenance', m: 0 }, - { v: 6000, n: 'time to next maintenance', s: 'maintenancetime', m: 0 }, - { v: '01.01.2012', n: 'next maintenance date', s: 'maintenancedate', m: 0 }, - { v: true, n: 'dhw turn on/off', s: 'wwtapactivated', m: 0 }, - { v: 62, n: 'dhw set temperature', s: 'wwsettemp', m: 0 }, - { v: 60, n: 'dhw selected temperature', s: 'wwseltemp', m: 0 }, - { n: 'dhw selected lower temperature', s: 'wwseltemplow', m: 2 }, - { n: 'dhw selected temperature for off', s: 'wwseltempoff', m: 2 }, - { n: 'dhw single charge temperature', s: 'wwseltempsingle', m: 2 }, - { v: 'flow', n: 'dhw type', s: 'wwtype', m: 0 }, - { v: 'hot', n: 'dhw comfort', s: 'wwcomfort', m: 0 }, - { v: 40, n: 'dhw flow temperature offset', s: 'wwflowtempoffset', m: 0 }, - { v: 100, n: 'dhw max power', s: 'wwmaxpower', m: 0 }, - { v: false, n: 'dhw circulation pump available', s: 'wwcircpump', m: 0 }, - { v: '3-way valve', n: 'dhw charging type', s: 'wwchargetype', m: 0 }, - { v: -5, n: 'dhw hysteresis on temperature', s: 'wwhyston', m: 0 }, - { v: 0, n: 'dhw hysteresis off temperature', s: 'wwhystoff', m: 0 }, - { v: 70, n: 'dhw disinfection temperature', s: 'wwdisinfectiontemp', m: 0 }, - { v: 'off', n: 'dhw circulation pump mode', s: 'wwcircmode', m: 0 }, - { v: false, n: 'dhw circulation active', s: 'wwcirc', m: 0 }, - { v: 46.4, n: 'dhw current intern temperature', s: 'wwcurtemp', m: 0 }, - { n: 'dhw current extern temperature', s: 'wwcurtemp2', m: 2 }, - { v: 0, n: 'dhw current tap water flow', s: 'wwcurflow', m: 0 }, - { v: 46.3, n: 'dhw storage intern temperature', s: 'wwstoragetemp1', m: 0 }, - { n: 'dhw storage extern temperature', s: 'wwstoragetemp2', m: 2 }, - { v: true, n: 'dhw activated', s: 'wwactivated', m: 0 }, - { v: false, n: 'dhw one time charging', s: 'wwonetime', m: 0 }, - { v: false, n: 'dhw disinfecting', s: 'wwdisinfecting', m: 0 }, - { v: false, n: 'dhw charging', s: 'wwcharging', m: 0 }, - { v: false, n: 'dhw recharging', s: 'wwrecharging', m: 0 }, - { v: true, n: 'dhw temperature ok', s: 'wwtempok', m: 0 }, - { v: false, n: 'dhw active', s: 'wwactive', m: 0 }, - { v: true, n: 'dhw 3way valve active', s: 'ww3wayvalve', m: 0 }, - { v: 0, n: 'dhw set pump power', s: 'wwsetpumppower', m: 0 }, - { n: 'dhw mixer temperature', s: 'wwmixertemp', m: 2 }, - { n: 'dhw cylinder middle temperature (TS3)', s: 'wwcylmiddletemp', m: 2 }, - { v: 288768, n: 'dhw starts', s: 'wwstarts', m: 0 }, - { v: 102151, n: 'dhw active time', s: 'wwworkm', m: 0 }, + { v: false, id: 'heating active', s: 'heatingactive', m: 0 }, + { v: false, id: 'tapwater active', s: 'tapwateractive', m: 0 }, + { v: 5, id: 'selected flow temperature', s: 'selflowtemp', m: 0 }, + { v: 0, id: 'burner selected max power', s: 'selburnpow', m: 0 }, + { v: 0, id: 'heating pump modulation', s: 'heatingpumpmod', m: 0 }, + { id: 'heating pump 2 modulation', s: 'heatingpump2mod', m: 0 }, + { id: 'outside temperature', s: 'outdoortemp', m: 0 }, + { v: 53, id: 'current flow temperature', s: 'curflowtemp', m: 0 }, + { v: 51.8, id: 'return temperature', s: 'rettemp', m: 0 }, + { id: 'mixing switch temperature', s: 'switchtemp', m: 0 }, + { v: 1.3, id: 'system pressure', s: 'syspress', m: 0 }, + { v: 54.6, id: 'actual boiler temperature', s: 'boiltemp', m: 0 }, + { id: 'exhaust temperature', s: 'exhausttemp', m: 0 }, + { v: false, id: 'gas', s: 'burngas', m: 0 }, + { v: false, id: 'gas stage 2', s: 'burngas2', m: 0 }, + { v: 0, id: 'flame current', s: 'flamecurr', m: 0 }, + { v: false, id: 'heating pump', s: 'heatingpump', m: 0 }, + { v: false, id: 'fan', s: 'fanwork', m: 0 }, + { v: false, id: 'ignition', s: 'ignwork', m: 0 }, + { v: false, id: 'oil preheating', s: 'oilpreheat', m: 0 }, + { v: true, id: 'heating activated', s: 'heatingactivated', m: 0 }, + { v: 80, id: 'heating temperature', s: 'heatingtemp', m: 0 }, + { v: 70, id: 'burner pump max power', s: 'pumpmodmax', m: 0 }, + { v: 30, id: 'burner pump min power', s: 'pumpmodmin', m: 0 }, + { v: 1, id: 'pump delay', s: 'pumpdelay', m: 0 }, + { v: 10, id: 'burner min period', s: 'burnminperiod', m: 0 }, + { v: 0, id: 'burner min power', s: 'burnminpower', m: 0 }, + { v: 50, id: 'burner max power', s: 'burnmaxpower', m: 0 }, + { v: -6, id: 'hysteresis on temperature', s: 'boilhyston', m: 0 }, + { v: 6, id: 'hysteresis off temperature', s: 'boilhystoff', m: 0 }, + { v: 0, id: 'set flow temperature', s: 'setflowtemp', m: 0 }, + { v: 0, id: 'burner set power', s: 'setburnpow', m: 0 }, + { v: 0, id: 'burner current power', s: 'curburnpow', m: 0 }, + { v: 326323, id: 'burner starts', s: 'burnstarts', m: 0 }, + { v: 553437, id: 'total burner operating time', s: 'burnworkmin', m: 0 }, + { v: 451286, id: 'total heat operating time', s: 'heatworkmin', m: 0 }, + { v: 4672175, id: 'total UBA operating time', s: 'ubauptime', m: 0 }, + { v: '1C(210) 06.06.2020 12:07 (0 min)', id: 'last error code', s: 'lastcode', m: 0 }, + { v: '0H', id: 'service code', s: 'servicecode', m: 0 }, + { v: 203, id: 'service code number', s: 'servicecodenumber', m: 0 }, + { v: 'H00', id: 'maintenance message', s: 'maintenancemessage', m: 0 }, + { v: 'manual', id: 'maintenance scheduled', s: 'maintenance', m: 0 }, + { v: 6000, id: 'time to next maintenance', s: 'maintenancetime', m: 0 }, + { v: '01.01.2012', id: 'next maintenance date', s: 'maintenancedate', m: 0 }, + { v: true, id: 'dhw turn on/off', s: 'wwtapactivated', m: 0 }, + { v: 62, id: 'dhw set temperature', s: 'wwsettemp', m: 0 }, + { v: 60, id: 'dhw selected temperature', s: 'wwseltemp', m: 0 }, + { id: 'dhw selected lower temperature', s: 'wwseltemplow', m: 2 }, + { id: 'dhw selected temperature for off', s: 'wwseltempoff', m: 2 }, + { id: 'dhw single charge temperature', s: 'wwseltempsingle', m: 2 }, + { v: 'flow', id: 'dhw type', s: 'wwtype', m: 0 }, + { v: 'hot', id: 'dhw comfort', s: 'wwcomfort', m: 0 }, + { v: 40, id: 'dhw flow temperature offset', s: 'wwflowtempoffset', m: 0 }, + { v: 100, id: 'dhw max power', s: 'wwmaxpower', m: 0 }, + { v: false, id: 'dhw circulation pump available', s: 'wwcircpump', m: 0 }, + { v: '3-way valve', id: 'dhw charging type', s: 'wwchargetype', m: 0 }, + { v: -5, id: 'dhw hysteresis on temperature', s: 'wwhyston', m: 0 }, + { v: 0, id: 'dhw hysteresis off temperature', s: 'wwhystoff', m: 0 }, + { v: 70, id: 'dhw disinfection temperature', s: 'wwdisinfectiontemp', m: 0 }, + { v: 'off', id: 'dhw circulation pump mode', s: 'wwcircmode', m: 0 }, + { v: false, id: 'dhw circulation active', s: 'wwcirc', m: 0 }, + { v: 46.4, id: 'dhw current intern temperature', s: 'wwcurtemp', m: 0 }, + { id: 'dhw current extern temperature', s: 'wwcurtemp2', m: 2 }, + { v: 0, id: 'dhw current tap water flow', s: 'wwcurflow', m: 0 }, + { v: 46.3, id: 'dhw storage intern temperature', s: 'wwstoragetemp1', m: 0 }, + { id: 'dhw storage extern temperature', s: 'wwstoragetemp2', m: 2 }, + { v: true, id: 'dhw activated', s: 'wwactivated', m: 0 }, + { v: false, id: 'dhw one time charging', s: 'wwonetime', m: 0 }, + { v: false, id: 'dhw disinfecting', s: 'wwdisinfecting', m: 0 }, + { v: false, id: 'dhw charging', s: 'wwcharging', m: 0 }, + { v: false, id: 'dhw recharging', s: 'wwrecharging', m: 0 }, + { v: true, id: 'dhw temperature ok', s: 'wwtempok', m: 0 }, + { v: false, id: 'dhw active', s: 'wwactive', m: 0 }, + { v: true, id: 'dhw 3way valve active', s: 'ww3wayvalve', m: 0 }, + { v: 0, id: 'dhw set pump power', s: 'wwsetpumppower', m: 0 }, + { id: 'dhw mixer temperature', s: 'wwmixertemp', m: 2 }, + { id: 'dhw cylinder middle temperature (TS3)', s: 'wwcylmiddletemp', m: 2 }, + { v: 288768, id: 'dhw starts', s: 'wwstarts', m: 0 }, + { v: 102151, id: 'dhw active time', s: 'wwworkm', m: 0 }, ] const emsesp_deviceentities_4 = [ { v: 16, - n: 'hc2 selected room temperature', + id: 'hc2 selected room temperature', s: 'hc2/seltemp', m: 0, w: true, }, { v: 18.5, - n: 'hc2 current room temperature', + id: 'hc2 current room temperature', s: 'hc2/curtemp', m: 3, w: false, }, { v: 'off', - n: 'hc2 mode', + id: 'hc2 mode', s: 'hc2/mode', m: 3, w: true,