diff --git a/package-lock.json b/package-lock.json index 717e3a3..88dac76 100644 --- a/package-lock.json +++ b/package-lock.json @@ -37,7 +37,7 @@ "react": "^19.1.0", "react-dom": "^19.1.0", "react-icons": "^5.5.0", - "react-window": "^2.2.2", + "react-window": "^1.8.10", "tailwindcss": "^4.1.13" }, "devDependencies": { @@ -46,6 +46,7 @@ "@types/node": "^20", "@types/react": "^19.1.0", "@types/react-dom": "^19.1.0", + "@types/react-window": "^1.8.8", "cross-env": "^7.0.3", "eslint": "^8", "eslint-config-next": "^15.0.3", @@ -7992,6 +7993,16 @@ "@types/react": "*" } }, + "node_modules/@types/react-window": { + "version": "1.8.8", + "resolved": "https://registry.npmjs.org/@types/react-window/-/react-window-1.8.8.tgz", + "integrity": "sha512-8Ls660bHR1AUA2kuRvVG9D/4XpRC6wjAaPT9dil7Ckc76eP9TKWZwwmgfq8Q1LANX3QNDnoU4Zp48A3w+zK69Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/react": "*" + } + }, "node_modules/@types/unist": { "version": "2.0.11", "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz", @@ -14590,6 +14601,12 @@ "node": ">= 0.6" } }, + "node_modules/memoize-one": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-5.2.1.tgz", + "integrity": "sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q==", + "license": "MIT" + }, "node_modules/merge-descriptors": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", @@ -16462,13 +16479,20 @@ } }, "node_modules/react-window": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/react-window/-/react-window-2.2.2.tgz", - "integrity": "sha512-kvHKwFImKBWNbx2S87NZOhQhAVkBthjmnOfHlhQI45p3A+D+V53E+CqQMsyHrxNe3ke+YtWXuKDa1eoHAaIWJg==", + "version": "1.8.10", + "resolved": "https://registry.npmjs.org/react-window/-/react-window-1.8.10.tgz", + "integrity": "sha512-Y0Cx+dnU6NLa5/EvoHukUD0BklJ8qITCtVEPY1C/nL8wwoZ0b5aEw8Ff1dOVHw7fCzMt55XfJDd8S8W8LCaUCg==", "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.0.0", + "memoize-one": ">=3.1.1 <6" + }, + "engines": { + "node": ">8.0.0" + }, "peerDependencies": { - "react": "^18.0.0 || ^19.0.0", - "react-dom": "^18.0.0 || ^19.0.0" + "react": "^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0" } }, "node_modules/readable-stream": { diff --git a/package.json b/package.json index 7cc74e7..18bade5 100644 --- a/package.json +++ b/package.json @@ -42,7 +42,7 @@ "react": "^19.1.0", "react-dom": "^19.1.0", "react-icons": "^5.5.0", - "react-window": "^2.2.2", + "react-window": "^1.8.10", "tailwindcss": "^4.1.13" }, "devDependencies": { @@ -51,6 +51,7 @@ "@types/node": "^20", "@types/react": "^19.1.0", "@types/react-dom": "^19.1.0", + "@types/react-window": "^1.8.8", "cross-env": "^7.0.3", "eslint": "^8", "eslint-config-next": "^15.0.3", diff --git a/src/components/olmap/SCADADeviceList.tsx b/src/components/olmap/SCADADeviceList.tsx index a18b681..4afaee0 100644 --- a/src/components/olmap/SCADADeviceList.tsx +++ b/src/components/olmap/SCADADeviceList.tsx @@ -12,7 +12,6 @@ import { Box, Paper, Typography, - List, ListItem, ListItemButton, ListItemText, @@ -39,6 +38,7 @@ import { Clear, DeviceHub, } from "@mui/icons-material"; +import { FixedSizeList } from "react-window"; import { useMap } from "@app/OlMap/MapComponent"; import { GeoJSON } from "ol/format"; @@ -452,108 +452,122 @@ const SCADADeviceList: React.FC = ({ ) : ( - - {filteredDevices.map((device, index) => ( - - - handleDeviceClick(device, event)} - sx={{ - "&.Mui-selected": { - backgroundColor: "primary.50", - borderLeft: 3, - borderColor: "primary.main", - }, - "&:hover": { - backgroundColor: "grey.50", - }, - }} - > - - - {getStatusIcon(device.status)} - - - - - - {device.name} - - - - } - secondary={ - - - ID: {device.id} - - - 坐标: {device.coordinates[0].toFixed(6)},{" "} - {device.coordinates[1].toFixed(6)} - - - } - slotProps={{ - secondary: { - component: "div", // 使其支持多行 + + {({ + index, + style, + }: { + index: number; + style: React.CSSProperties; + }) => { + const device = filteredDevices[index]; + return ( +
+ + handleDeviceClick(device, event)} + sx={{ + "&.Mui-selected": { + backgroundColor: "primary.50", + borderLeft: 3, + borderColor: "primary.main", + }, + "&:hover": { + backgroundColor: "grey.50", }, }} - /> + > + + + {getStatusIcon(device.status)} + + - - { - event.stopPropagation(); - handleZoomToDevice(device); - }} - sx={{ - ml: 1, - color: "primary.main", - "&:hover": { - backgroundColor: "primary.50", + + + {device.name} + + + + } + secondary={ + + + ID: {device.id} + + + 坐标: {device.coordinates[0].toFixed(6)},{" "} + {device.coordinates[1].toFixed(6)} + + + } + slotProps={{ + secondary: { + component: "div", // 使其支持多行 }, }} - > - - - - - - {index < filteredDevices.length - 1 && ( - - )} - - ))} - + /> + + + { + event.stopPropagation(); + handleZoomToDevice(device); + }} + sx={{ + ml: 1, + color: "primary.main", + "&:hover": { + backgroundColor: "primary.50", + }, + }} + > + + + + + + {index < filteredDevices.length - 1 && ( + + )} +
+ ); + }} +
)}