diff --git a/interface/src/app/main/Dashboard.tsx b/interface/src/app/main/Dashboard.tsx
index f27a58201..061fa8165 100644
--- a/interface/src/app/main/Dashboard.tsx
+++ b/interface/src/app/main/Dashboard.tsx
@@ -3,6 +3,7 @@ import { IconContext } from 'react-icons/lib';
import { toast } from 'react-toastify';
import ChevronRightIcon from '@mui/icons-material/ChevronRight';
+import CircleIcon from '@mui/icons-material/Circle';
import EditIcon from '@mui/icons-material/Edit';
import ExpandMoreIcon from '@mui/icons-material/ExpandMore';
import UnfoldLessIcon from '@mui/icons-material/UnfoldLess';
@@ -12,8 +13,10 @@ import {
IconButton,
ToggleButton,
ToggleButtonGroup,
+ Tooltip,
Typography
} from '@mui/material';
+import Grid from '@mui/material/Grid2';
import { Body, Cell, Row, Table } from '@table-library/react-table-library/table';
import { useTheme } from '@table-library/react-table-library/theme';
@@ -24,11 +27,17 @@ import { AuthenticatedContext } from 'contexts/authentication';
import { useI18nContext } from 'i18n/i18n-react';
import { useInterval } from 'utils';
-import { readDashboard, writeDeviceValue } from '../../api/app';
+import { readDashboard, writeDeviceValue, writeSchedule } from '../../api/app';
import DeviceIcon from './DeviceIcon';
-import DashboardDevicesDialog from './DevicesDialog';
+import DevicesDialog from './DevicesDialog';
import { formatValue } from './deviceValue';
-import { type DashboardItem, DeviceEntityMask, type DeviceValue } from './types';
+import {
+ type DashboardItem,
+ DeviceEntityMask,
+ DeviceType,
+ type DeviceValue,
+ type Schedule
+} from './types';
import { deviceValueItemValidation } from './validators';
const Dashboard = () => {
@@ -54,6 +63,13 @@ const Dashboard = () => {
initialData: []
});
+ const { send: updateSchedule } = useRequest(
+ (data: Schedule) => writeSchedule(data),
+ {
+ immediate: false
+ }
+ );
+
const { loading: submitting, send: sendDeviceValue } = useRequest(
(data: { id: number; c: string; v: unknown }) => writeDeviceValue(data),
{
@@ -104,14 +120,24 @@ const Dashboard = () => {
const tree = useTree(
{ nodes: data },
{
- onChange: null // not used but needed
+ onChange: undefined // not used but needed
},
{
treeIcon: {
margin: '4px',
iconDefault: null,
- iconRight: ,
- iconDown:
+ iconRight: (
+
+ ),
+ iconDown: (
+
+ )
},
indentation: 50
}
@@ -131,27 +157,78 @@ const Dashboard = () => {
}
}, [loading]);
+ const showType = (n?: string, t?: number) => {
+ // if we have a name show it
+ if (n) {
+ return n;
+ }
+ if (t) {
+ // otherwise pick translation based on type
+ switch (t) {
+ case DeviceType.CUSTOM:
+ return LL.CUSTOM_ENTITIES(0);
+ case DeviceType.ANALOGSENSOR:
+ return LL.ANALOG_SENSOR(0);
+ case DeviceType.TEMPERATURESENSOR:
+ return LL.TEMP_SENSOR();
+ case DeviceType.SCHEDULER:
+ return LL.SCHEDULER();
+ default:
+ break;
+ }
+ }
+ return '';
+ };
+
const showName = (di: DashboardItem) => {
if (di.id < 100) {
- // if its a device and has entities
+ // if its a device (parent node) and has entities
if (di.nodes?.length) {
return (
<>
- {di.n}
+ {showType(di.n, di.t)}
({di.nodes?.length})
>
);
}
}
- return {di.dv ? di.dv.id.slice(2) : ''};
+ if (di.dv) {
+ return (
+ // ids for scheduler, and sensors are between 9600 and 9900
+
+ {di.id >= 9600 && di.id < 9900 ? di.dv.id : di.dv.id.slice(2)}
+
+ );
+ }
};
const hasMask = (id: string, mask: number) =>
(parseInt(id.slice(0, 2), 16) & mask) === mask;
+ const toggleSchedule = async (di: DashboardItem) => {
+ // create a dummy record, the id=0 picks it up
+ await updateSchedule({
+ schedule: {
+ id: 0, // special number for only changing the active flag
+ active: !di.dv?.v,
+ flags: 0, // unused
+ time: '', // unused
+ cmd: '', // unused
+ value: '', // unused
+ name: di.dv?.id ?? ''
+ }
+ })
+ .catch((error: Error) => {
+ toast.error(error.message);
+ })
+ .finally(async () => {
+ await fetchDashboard();
+ });
+ };
+
const editDashboardValue = (di: DashboardItem) => {
setSelectedDashboardItem(di);
setDeviceValueDialogOpen(true);
@@ -174,32 +251,37 @@ const Dashboard = () => {
return (
<>
-
- {LL.DASHBOARD_1()}
-
+
+
+
+ {LL.DASHBOARD_1()}
+
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
@@ -225,30 +307,65 @@ const Dashboard = () => {
{tableList.map((di: DashboardItem) => (
- {/* TODO add a comment about the number 99 */}
{di.id > 99 ? (
- {showName(di)} |
+ <>
+ {showName(di)} |
+
+
+
+ {di.dv ? formatValue(LL, di.dv.v, di.dv.u) : ''}
+
+
+ |
+
+
+ {me.admin && di.id < 9700 && di.id >= 9600 ? (
+ toggleSchedule(di)}
+ >
+ {di.dv?.v ? (
+
+ ) : (
+
+ )}
+
+ ) : (
+ me.admin &&
+ di.dv?.c &&
+ !hasMask(di.dv.id, DeviceEntityMask.DV_READONLY) && (
+ editDashboardValue(di)}
+ >
+
+
+ )
+ )}
+ |
+ >
) : (
- {showName(di)}
+ <>
+ {showName(di)}
+ |
+ |
+ >
)}
-
-
- {di.dv && formatValue(LL, di.dv.v, di.dv.u)}
-
- |
-
-
- {me.admin &&
- di.dv?.c &&
- !hasMask(di.dv.id, DeviceEntityMask.DV_READONLY) && (
- editDashboardValue(di)}
- >
-
-
- )}
- |
))}
@@ -265,7 +382,7 @@ const Dashboard = () => {
{renderContent()}
{selectedDashboardItem && selectedDashboardItem.dv && (
- setDeviceValueDialogOpen(false)}
onSave={deviceValueDialogSave}