修改面板样式

This commit is contained in:
JIANG
2025-11-06 17:45:00 +08:00
parent 2a48e1f6df
commit 7702ba9edf
3 changed files with 124 additions and 28 deletions

View File

@@ -1,10 +1,18 @@
"use client"; "use client";
import React, { useState } from "react"; import React, { useState } from "react";
import { Box, Drawer, Tabs, Tab, Typography, IconButton } from "@mui/material";
import { import {
ChevronRight as ChevronRightIcon, Box,
ChevronLeft as ChevronLeftIcon, Drawer,
Tabs,
Tab,
Typography,
IconButton,
Tooltip,
} from "@mui/material";
import {
ChevronRight,
ChevronLeft,
Analytics as AnalyticsIcon, Analytics as AnalyticsIcon,
Search as SearchIcon, Search as SearchIcon,
MyLocation as MyLocationIcon, MyLocation as MyLocationIcon,
@@ -89,6 +97,7 @@ const BurstPipeAnalysisPanel: React.FC<BurstPipeAnalysisPanelProps> = ({
<Box <Box
className="absolute top-4 right-4 bg-white shadow-2xl rounded-lg cursor-pointer hover:shadow-xl transition-all duration-300 opacity-95 hover:opacity-100" className="absolute top-4 right-4 bg-white shadow-2xl rounded-lg cursor-pointer hover:shadow-xl transition-all duration-300 opacity-95 hover:opacity-100"
onClick={handleToggle} onClick={handleToggle}
sx={{ zIndex: 1300 }}
> >
<Box className="flex flex-col items-center py-3 px-3 gap-1"> <Box className="flex flex-col items-center py-3 px-3 gap-1">
<AnalyticsIcon className="text-[#257DD4] w-5 h-5" /> <AnalyticsIcon className="text-[#257DD4] w-5 h-5" />
@@ -99,7 +108,7 @@ const BurstPipeAnalysisPanel: React.FC<BurstPipeAnalysisPanelProps> = ({
> >
</Typography> </Typography>
<ChevronLeftIcon className="text-gray-600 w-4 h-4" /> <ChevronLeft className="text-gray-600 w-4 h-4" />
</Box> </Box>
</Box> </Box>
)} )}
@@ -111,7 +120,8 @@ const BurstPipeAnalysisPanel: React.FC<BurstPipeAnalysisPanelProps> = ({
variant="persistent" variant="persistent"
hideBackdrop hideBackdrop
sx={{ sx={{
width: isOpen ? drawerWidth : 0, // 关键:容器自身不占用布局宽度
width: 0,
flexShrink: 0, flexShrink: 0,
"& .MuiDrawer-paper": { "& .MuiDrawer-paper": {
width: drawerWidth, width: drawerWidth,
@@ -126,7 +136,7 @@ const BurstPipeAnalysisPanel: React.FC<BurstPipeAnalysisPanelProps> = ({
"0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04)", "0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04)",
backdropFilter: "blur(8px)", backdropFilter: "blur(8px)",
opacity: 0.95, opacity: 0.95,
transition: "all 0.3s ease-in-out", transition: "transform 0.3s ease-in-out, opacity 0.3s ease-in-out",
border: "none", border: "none",
"&:hover": { "&:hover": {
opacity: 1, opacity: 1,
@@ -143,14 +153,15 @@ const BurstPipeAnalysisPanel: React.FC<BurstPipeAnalysisPanelProps> = ({
</Typography> </Typography>
</Box> </Box>
<IconButton <Tooltip title="收起">
onClick={handleToggle} <IconButton
size="small" size="small"
className="text-white hover:bg-white hover:bg-opacity-20 rounded-full p-1 transition-all duration-200" onClick={handleToggle}
aria-label="关闭" sx={{ color: "primary.contrastText" }}
> >
<ChevronRightIcon className="w-5 h-5" /> <ChevronRight fontSize="small" />
</IconButton> </IconButton>
</Tooltip>
</Box> </Box>
{/* Tabs 导航 */} {/* Tabs 导航 */}

View File

@@ -1,10 +1,18 @@
"use client"; "use client";
import React, { useState } from "react"; import React, { useState } from "react";
import { Box, Drawer, Tabs, Tab, Typography, IconButton } from "@mui/material";
import { import {
ChevronRight as ChevronRightIcon, Box,
ChevronLeft as ChevronLeftIcon, Drawer,
Tabs,
Tab,
Typography,
IconButton,
Tooltip,
} from "@mui/material";
import {
ChevronRight,
ChevronLeft,
Sensors as SensorsIcon, Sensors as SensorsIcon,
Analytics as AnalyticsIcon, Analytics as AnalyticsIcon,
Search as SearchIcon, Search as SearchIcon,
@@ -79,6 +87,7 @@ const MonitoringPlaceOptimizationPanel: React.FC<
<Box <Box
className="absolute top-4 right-4 bg-white shadow-2xl rounded-lg cursor-pointer hover:shadow-xl transition-all duration-300 opacity-95 hover:opacity-100" className="absolute top-4 right-4 bg-white shadow-2xl rounded-lg cursor-pointer hover:shadow-xl transition-all duration-300 opacity-95 hover:opacity-100"
onClick={handleToggle} onClick={handleToggle}
sx={{ zIndex: 1300 }}
> >
<Box className="flex flex-col items-center py-3 px-3 gap-1"> <Box className="flex flex-col items-center py-3 px-3 gap-1">
<SensorsIcon className="text-[#257DD4] w-5 h-5" /> <SensorsIcon className="text-[#257DD4] w-5 h-5" />
@@ -89,7 +98,7 @@ const MonitoringPlaceOptimizationPanel: React.FC<
> >
</Typography> </Typography>
<ChevronLeftIcon className="text-gray-600 w-4 h-4" /> <ChevronLeft className="text-gray-600 w-4 h-4" />
</Box> </Box>
</Box> </Box>
)} )}
@@ -101,7 +110,8 @@ const MonitoringPlaceOptimizationPanel: React.FC<
variant="persistent" variant="persistent"
hideBackdrop hideBackdrop
sx={{ sx={{
width: isOpen ? drawerWidth : 0, // 关键:根容器不占据布局空间,避免页面布局受影响
width: 0,
flexShrink: 0, flexShrink: 0,
"& .MuiDrawer-paper": { "& .MuiDrawer-paper": {
width: drawerWidth, width: drawerWidth,
@@ -116,7 +126,7 @@ const MonitoringPlaceOptimizationPanel: React.FC<
"0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04)", "0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04)",
backdropFilter: "blur(8px)", backdropFilter: "blur(8px)",
opacity: 0.95, opacity: 0.95,
transition: "all 0.3s ease-in-out", transition: "transform 0.3s ease-in-out, opacity 0.3s ease-in-out",
border: "none", border: "none",
"&:hover": { "&:hover": {
opacity: 1, opacity: 1,
@@ -133,14 +143,15 @@ const MonitoringPlaceOptimizationPanel: React.FC<
</Typography> </Typography>
</Box> </Box>
<IconButton <Tooltip title="收起">
onClick={handleToggle} <IconButton
size="small" size="small"
className="text-white hover:bg-white hover:bg-opacity-20 rounded-full p-1 transition-all duration-200" onClick={handleToggle}
aria-label="关闭" sx={{ color: "primary.contrastText" }}
> >
<ChevronRightIcon className="w-5 h-5" /> <ChevronRight fontSize="small" />
</IconButton> </IconButton>
</Tooltip>
</Box> </Box>
{/* Tabs 导航 */} {/* Tabs 导航 */}

View File

@@ -0,0 +1,74 @@
"use client";
import React, { useCallback, useMemo, useState } from "react";
import { Box, Stack } from "@mui/material";
import SCADADeviceList from "./SCADADeviceList";
import SCADADataPanel from "./SCADADataPanel";
/**
* 集成面板:左侧为 SCADA 设备列表(支持从地图选择),右侧为历史数据面板(曲线/表格)。
* - 使用 SCADADeviceList 内置的地图点击选择功能
* - 使用 SCADADataPanel 的时间段查询与图表展示
* - 两者通过选中设备 ID 进行联动
*/
export interface SCADAIntegratedPanelProps {
/** 初始选中设备 ID 列表 */
initialSelection?: string[];
/** 是否展示数据清洗相关功能(传递给两个子面板) */
showCleaning?: boolean;
/** 是否显示右侧数据面板 */
showDataPanel?: boolean;
/** 数据面板默认选项卡 */
dataPanelDefaultTab?: "chart" | "table";
/** 数据面板小数位数 */
fractionDigits?: number;
}
const SCADAIntegratedPanel: React.FC<SCADAIntegratedPanelProps> = ({
initialSelection = [],
showCleaning = false,
showDataPanel = true,
dataPanelDefaultTab = "chart",
fractionDigits = 2,
}) => {
const [selectedIds, setSelectedIds] = useState<string[]>(initialSelection);
// 通过变更 key 强制重新挂载 DataPanel从而在“清洗全部”后自动刷新
const [dataPanelKey, setDataPanelKey] = useState<number>(0);
const handleSelectionChange = useCallback((ids: string[]) => {
setSelectedIds(ids);
}, []);
// 清洗全部数据后,强制刷新右侧数据面板(重新挂载触发首轮查询)
const handleCleanAllData = useCallback((_from: Date, _to: Date) => {
setDataPanelKey((k) => k + 1);
}, []);
const hasSelection = useMemo(() => selectedIds.length > 0, [selectedIds]);
return (
<Box sx={{ position: "relative", width: "100%", height: "100%" }}>
{/* 左侧:设备列表(内置抽屉布局) */}
<SCADADeviceList
selectedDeviceIds={selectedIds}
onSelectionChange={handleSelectionChange}
showCleaning={showCleaning}
onCleanAllData={handleCleanAllData}
/>
{/* 右侧:历史数据面板(内置抽屉布局) */}
{showDataPanel && (
<SCADADataPanel
key={`data-panel-${dataPanelKey}`}
deviceIds={selectedIds}
visible={true}
defaultTab={dataPanelDefaultTab}
fractionDigits={fractionDigits}
showCleaning={showCleaning}
/>
)}
</Box>
);
};
export default SCADAIntegratedPanel;