diff --git a/interface/package.json b/interface/package.json index 802a1d620..22f227f34 100644 --- a/interface/package.json +++ b/interface/package.json @@ -35,7 +35,7 @@ "react": "^18.3.1", "react-dom": "^18.3.1", "react-icons": "^5.3.0", - "react-router-dom": "^6.26.2", + "react-router-dom": "^6.27.0", "react-toastify": "^10.0.5", "typesafe-i18n": "^5.26.2", "typescript": "^5.6.3" @@ -49,7 +49,7 @@ "@types/formidable": "^3", "@types/node": "^22.7.5", "@types/react": "^18.3.11", - "@types/react-dom": "^18.3.0", + "@types/react-dom": "^18.3.1", "@types/react-router-dom": "^5.3.3", "concurrently": "^9.0.1", "eslint": "^9.12.0", diff --git a/interface/src/App.tsx b/interface/src/App.tsx index f6c9d49be..f9f3a9a91 100644 --- a/interface/src/App.tsx +++ b/interface/src/App.tsx @@ -25,7 +25,7 @@ const App = () => { { const dashboard_theme = useTheme({ Table: ` - --data-table-library_grid-template-columns: minmax(80px, auto) 120px 40px; + --data-table-library_grid-template-columns: minmax(80px, auto) 120px 32px; `, BaseRow: ` font-size: 14px; .td { - height: 32px; + height: 28px; } `, Row: ` + cursor: pointer; background-color: #1e1e1e; .td { - height: 22px; + // border-top: 1px solid #0000; + // border-bottom: 1px solid #0000; } + &.tr.tr-body.row-select.row-select-single-selected { + background-color: #177ac9; + font-weight: normal; + } &:hover .td { - border-top: 1px solid #177ac9; - border-bottom: 1px solid #177ac9; + background-color: #177ac9; + // border-top: 1px solid #177ac9; + // border-bottom: 1px solid #177ac9; } `, BaseCell: ` &:nth-of-type(2) { text-align: right; } + &:nth-of-type(3) { + text-align: right; + } ` }); @@ -164,9 +174,9 @@ const Dashboard = () => { case DeviceType.CUSTOM: return LL.CUSTOM_ENTITIES(0); case DeviceType.ANALOGSENSOR: - return LL.ANALOG_SENSOR(0); + return LL.ANALOG_SENSORS(); case DeviceType.TEMPERATURESENSOR: - return LL.TEMP_SENSOR(); + return LL.TEMP_SENSORS(); case DeviceType.SCHEDULER: return LL.SCHEDULER(); default: @@ -200,8 +210,10 @@ const Dashboard = () => { (parseInt(id.slice(0, 2), 16) & mask) === mask; const editDashboardValue = (di: DashboardItem) => { - setSelectedDashboardItem(di); - setDeviceValueDialogOpen(true); + if (me.admin && di.dv?.c) { + setSelectedDashboardItem(di); + setDeviceValueDialogOpen(true); + } }; const handleShowAll = ( @@ -276,7 +288,11 @@ const Dashboard = () => { {(tableList: DashboardItem[]) => ( {tableList.map((di: DashboardItem) => ( - + editDashboardValue(di)} + > {di.id > 99 ? ( <> {showName(di)} @@ -294,7 +310,7 @@ const Dashboard = () => { - + {me.admin && di.dv?.c && !hasMask(di.dv.id, DeviceEntityMask.DV_READONLY) && ( diff --git a/interface/src/app/main/Devices.tsx b/interface/src/app/main/Devices.tsx index 462e4326b..5e0146a56 100644 --- a/interface/src/app/main/Devices.tsx +++ b/interface/src/app/main/Devices.tsx @@ -148,22 +148,23 @@ const Devices = () => { } `, Row: ` - background-color: #1E1E1E; - position: relative; cursor: pointer; + background-color: #1E1E1E; + // position: relative; .td { padding: 8px; - border-top: 1px solid #565656; - border-bottom: 1px solid #565656; + // border-top: 1px solid #565656; + // border-bottom: 1px solid #565656; } &.tr.tr-body.row-select.row-select-single-selected { - background-color: #3d4752; + background-color: #177ac9; font-weight: normal; } - &:hover .td { - border-top: 1px solid #177ac9; - border-bottom: 1px solid #177ac9; - } + // &:hover .td { + // background-color: #177ac9; + // border-top: 1px solid #177ac9; + // border-bottom: 1px solid #177ac9; + // } ` }); @@ -174,14 +175,18 @@ const Devices = () => { --data-table-library_grid-template-columns: repeat(1, minmax(0, 1fr)) 130px; `, BaseRow: ` - .td { - height: 42px; - } + // .td { + // height: 42px; + // } `, HeaderRow: ` .th { padding: 8px; height: 36px; + `, + Row: ` + &:hover .td { + background-color: #177ac9; ` } ]); @@ -222,7 +227,12 @@ const Devices = () => { Row: ` &:nth-of-type(odd) .td { background-color: #303030; - } + }, + &:hover .td { + background-color: #177ac9; + // border-top: 1px solid #177ac9; + // border-bottom: 1px solid #177ac9; + } ` } ]); diff --git a/interface/yarn.lock b/interface/yarn.lock index bf670a2eb..b1ac8d749 100644 --- a/interface/yarn.lock +++ b/interface/yarn.lock @@ -1360,10 +1360,10 @@ __metadata: languageName: node linkType: hard -"@remix-run/router@npm:1.19.2": - version: 1.19.2 - resolution: "@remix-run/router@npm:1.19.2" - checksum: 10c0/ac7fc813350686705f2c29219e70e1e299d9a8e3b301e9e81f7e84f578c40c6462b590cf0d78863bac40dbc325b68c71ae070f4a1465793d1d1971b619618295 +"@remix-run/router@npm:1.20.0": + version: 1.20.0 + resolution: "@remix-run/router@npm:1.20.0" + checksum: 10c0/2e017dea530717a6e93a16d478714c4c9165313a1c48e39172ec609bc20324ca6362e8ee2243602df6343644c9268d82a3f50f154d3bb8a17dddde6c37be6e83 languageName: node linkType: hard @@ -1699,12 +1699,12 @@ __metadata: languageName: node linkType: hard -"@types/react-dom@npm:^18.3.0": - version: 18.3.0 - resolution: "@types/react-dom@npm:18.3.0" +"@types/react-dom@npm:^18.3.1": + version: 18.3.1 + resolution: "@types/react-dom@npm:18.3.1" dependencies: "@types/react": "npm:*" - checksum: 10c0/6c90d2ed72c5a0e440d2c75d99287e4b5df3e7b011838cdc03ae5cd518ab52164d86990e73246b9d812eaf02ec351d74e3b4f5bd325bf341e13bf980392fd53b + checksum: 10c0/8b416551c60bb6bd8ec10e198c957910cfb271bc3922463040b0d57cf4739cdcd24b13224f8d68f10318926e1ec3cd69af0af79f0291b599a992f8c80d47f1eb languageName: node linkType: hard @@ -1910,7 +1910,7 @@ __metadata: "@types/formidable": "npm:^3" "@types/node": "npm:^22.7.5" "@types/react": "npm:^18.3.11" - "@types/react-dom": "npm:^18.3.0" + "@types/react-dom": "npm:^18.3.1" "@types/react-router-dom": "npm:^5.3.3" alova: "npm:3.0.20" async-validator: "npm:^4.2.5" @@ -1925,7 +1925,7 @@ __metadata: react: "npm:^18.3.1" react-dom: "npm:^18.3.1" react-icons: "npm:^5.3.0" - react-router-dom: "npm:^6.26.2" + react-router-dom: "npm:^6.27.0" react-toastify: "npm:^10.0.5" rollup-plugin-visualizer: "npm:^5.12.0" terser: "npm:^5.34.1" @@ -6003,27 +6003,27 @@ __metadata: languageName: node linkType: hard -"react-router-dom@npm:^6.26.2": - version: 6.26.2 - resolution: "react-router-dom@npm:6.26.2" +"react-router-dom@npm:^6.27.0": + version: 6.27.0 + resolution: "react-router-dom@npm:6.27.0" dependencies: - "@remix-run/router": "npm:1.19.2" - react-router: "npm:6.26.2" + "@remix-run/router": "npm:1.20.0" + react-router: "npm:6.27.0" peerDependencies: react: ">=16.8" react-dom: ">=16.8" - checksum: 10c0/7515128a98eef0a6b2bf354ef9dfefad03556a06be00fa9220eda6526aaada8a42f294911083473d7ced6d7128c3088bd193218bbb3d62593f9f4f7053781c23 + checksum: 10c0/7db48ffd0b387af0eed060ceaf42075d074e63fbd30f4cf60993526b3610883a9ff82615965001165ed69d2bf2f1bce05c594a21c8d0d845e7b9bf203201116e languageName: node linkType: hard -"react-router@npm:6.26.2": - version: 6.26.2 - resolution: "react-router@npm:6.26.2" +"react-router@npm:6.27.0": + version: 6.27.0 + resolution: "react-router@npm:6.27.0" dependencies: - "@remix-run/router": "npm:1.19.2" + "@remix-run/router": "npm:1.20.0" peerDependencies: react: ">=16.8" - checksum: 10c0/0d15a39b419c99fb5ccad76388bfc4ee2b01323b3b1b694595a9f9ea28e1fbeea25486b5398f5d3d93922f5c6a9aa751b6bb27419488d85279f6ca5ff9e0a6bb + checksum: 10c0/440d6ee00890cec92a0c2183164149fbb96363efccf52bb132a964f44e51aec2f4b5a0520c67f6f17faddaa4097090fd76f7efe58263947532fceeb11dd4cdf3 languageName: node linkType: hard diff --git a/mock-api/rest_server.ts b/mock-api/rest_server.ts index ea9ff6694..2c6e2dd31 100644 --- a/mock-api/rest_server.ts +++ b/mock-api/rest_server.ts @@ -4351,7 +4351,6 @@ router t: element.t, nodes: getDashboardEntityData(id) }; - // only add to dashboard if we have values if ((dashboard_object.nodes ?? []).length > 0) { dashboard_data.push(dashboard_object); @@ -4374,7 +4373,7 @@ router sensor_data = emsesp_sensordata.ts.map((item, index) => ({ id: DeviceTypeUniqueID.TEMPERATURESENSOR_UID * 100 + index, dv: { - id: item.n, + id: '00' + item.n, v: item.t, // value is called t in ts (temperature) u: item.u } @@ -4395,12 +4394,11 @@ router sensor_data = sensor_data.map((item, index) => ({ id: DeviceTypeUniqueID.ANALOGSENSOR_UID * 100 + index, dv: { - id: item.n, + id: '00' + item.n, v: item.v, u: item.u } })); - dashboard_object = { id: DeviceTypeUniqueID.ANALOGSENSOR_UID, t: DeviceType.ANALOGSENSOR, @@ -4417,9 +4415,10 @@ router let scheduler_data2 = scheduler_data.map((item, index) => ({ id: DeviceTypeUniqueID.SCHEDULER_UID * 100 + index, dv: { - id: item.name, - v: item.active - // u: item.u // don't need uom + id: '00' + item.name, + v: item.active ? 'on' : 'off', + c: item.name, + l: ['off', 'on'] } })); dashboard_object = { @@ -4431,22 +4430,39 @@ router if ((dashboard_object.nodes ?? []).length > 0) { dashboard_data.push(dashboard_object); } - // } else { - // for testing - // single object - const element = emsesp_coredata.devices[3]; // pick the 4th device - const id = element.id; + // for testing only + + // add the custom entity data dashboard_object = { - id: id, - n: element.n, - t: element.t, - nodes: getDashboardEntityData(id) + id: DeviceTypeUniqueID.CUSTOM_UID, // unique ID for custom entities + t: DeviceType.CUSTOM, + nodes: getDashboardEntityData(99) }; + // only add to dashboard if we have values + if ((dashboard_object.nodes ?? []).length > 0) { + dashboard_data.push(dashboard_object); + } + + let scheduler_data = emsesp_schedule.schedule.filter((item) => item.name); + let scheduler_data2 = scheduler_data.map((item, index) => ({ + id: DeviceTypeUniqueID.SCHEDULER_UID * 100 + index, + dv: { + id: '00' + item.name, + v: item.active ? 'on' : 'off', + c: item.name, + l: ['off', 'on'] + } + })); + dashboard_object = { + id: DeviceTypeUniqueID.SCHEDULER_UID, + t: DeviceType.SCHEDULER, + nodes: scheduler_data2 + }; + // only add to dashboard if we have values if ((dashboard_object.nodes ?? []).length > 0) { dashboard_data.push(dashboard_object); } - console.log('dashboard_data: ', dashboard_data); } // console.log('dashboard_data: ', dashboard_data); @@ -4498,24 +4514,6 @@ router // Scheduler .post(EMSESP_SCHEDULE_ENDPOINT, async (request: any) => { const content = await request.json(); - // check if we're changing active from the Dashboard - if (content.schedule.id === 0) { - console.log( - "Toggle schedule '" + - content.schedule.name + - "' to " + - content.schedule.active - ); - // find the schedule in emsesp_schedule via the name and toggle the active - const objIndex = emsesp_schedule.schedule.findIndex( - (obj) => obj.name === content.schedule.name - ); - if (objIndex !== -1) { - emsesp_schedule.schedule[objIndex].active = content.schedule.active; - } - - return status(200); - } emsesp_schedule = content; console.log('schedule saved', emsesp_schedule); return status(200); @@ -4557,6 +4555,10 @@ router const value = content.v; const id = content.id; + console.log( + 'write device value, id: ' + id + ' command: ' + command + ' value: ' + value + ); + var objIndex; if (id === 1) { objIndex = emsesp_devicedata_1.nodes.findIndex((obj) => obj.c == command); @@ -4598,16 +4600,27 @@ router objIndex = emsesp_devicedata_10.nodes.findIndex((obj) => obj.c == command); emsesp_devicedata_10.nodes[objIndex].v = value; } - if (id === 99) { + if (id === DeviceTypeUniqueID.CUSTOM_UID) { // custom entities objIndex = emsesp_devicedata_99.nodes.findIndex((obj) => obj.c == command); emsesp_devicedata_99.nodes[objIndex].v = value; } + if (id === DeviceTypeUniqueID.SCHEDULER_UID) { + // toggle scheduler + // find the schedule in emsesp_schedule via the name and toggle the active + const objIndex = emsesp_schedule.schedule.findIndex( + (obj) => obj.name === command + ); + if (objIndex !== -1) { + emsesp_schedule.schedule[objIndex].active = value; + console.log("Toggle schedule '" + command + "' to " + value); + } + } // await delay(1000); // wait to show spinner - console.log( - 'Device Value updated. command:' + command + ' value:' + value + ' id:' + id - ); + // console.log( + // 'Device Value updated. command:' + command + ' value:' + value + ' id:' + id + // ); return status(200); })