feat(ui): 统一面板空状态引导

This commit is contained in:
2026-07-30 14:34:43 +08:00
parent 8836549697
commit 04557b9363
21 changed files with 400 additions and 435 deletions
@@ -11,11 +11,15 @@ import {
TableHead,
TableRow,
} from "@mui/material";
import { FormatListBulleted } from "@mui/icons-material";
import {
FormatListBulleted,
TroubleshootOutlined,
} from "@mui/icons-material";
import dayjs from "dayjs";
import { getAreaColor } from "./utils";
import { FLOW_DISPLAY_UNIT, toM3h } from "@utils/units";
import { LeakageResultDetail } from "./types";
import PanelEmptyState from "@components/olmap/common/PanelEmptyState";
interface Props {
result: LeakageResultDetail | null;
@@ -31,39 +35,11 @@ const RecognitionResults: React.FC<Props> = ({ result }) => {
if (!result || !sortedRows.length) {
return (
<Box className="flex flex-col items-center justify-center h-full text-gray-400 p-4">
<Box className="mb-4">
<svg
width="80"
height="80"
viewBox="0 0 80 80"
fill="none"
className="opacity-40"
>
<rect
x="10"
y="20"
width="60"
height="45"
rx="2"
stroke="currentColor"
strokeWidth="2"
/>
<line
x1="10"
y1="30"
x2="70"
y2="30"
stroke="currentColor"
strokeWidth="2"
/>
</svg>
</Box>
<Typography variant="body2"></Typography>
<Typography variant="body2" className="mt-1">
</Typography>
</Box>
<PanelEmptyState
icon={<TroubleshootOutlined />}
title="尚未生成识别结果"
description="请在“识别参数”中运行分析,或在“方案查询”中打开历史结果。"
/>
);
}
@@ -27,6 +27,7 @@ import { useControllableObjectState } from "@components/olmap/core/useControllab
import { LeakageResultDetail, LeakageSchemeRecord } from "./types";
import { FLOW_DISPLAY_UNIT, toM3h } from "@utils/units";
import { useSchemeCreatorName } from "@components/olmap/core/useSchemeCreatorName";
import { SchemeQueryEmptyState } from "@components/olmap/common/PanelEmptyState";
interface Props {
onViewResult: (result: LeakageResultDetail) => void;
@@ -40,12 +41,14 @@ export interface DMALeakSchemeQueryState {
queryAll: boolean;
queryDate: Dayjs | null;
expandedId: number | null;
hasQueried: boolean;
}
export const createDMALeakSchemeQueryState = (): DMALeakSchemeQueryState => ({
queryAll: true,
queryDate: dayjs(),
expandedId: null,
hasQueried: false,
});
const SchemeQuery: React.FC<Props> = ({
@@ -61,7 +64,7 @@ const SchemeQuery: React.FC<Props> = ({
onStateChange,
createDMALeakSchemeQueryState(),
);
const { queryAll, queryDate, expandedId } = queryState;
const { queryAll, queryDate, expandedId, hasQueried } = queryState;
const [internalSchemes, setInternalSchemes] = useState<LeakageSchemeRecord[]>([]);
const [loading, setLoading] = useState(false);
const creatorName = useSchemeCreatorName();
@@ -93,6 +96,7 @@ const SchemeQuery: React.FC<Props> = ({
});
const nextSchemes = response.data as LeakageSchemeRecord[];
setSchemes(nextSchemes);
setQueryField("hasQueried", true);
if (nextSchemes.length === 0) {
open?.({
type: "success",
@@ -150,7 +154,10 @@ const SchemeQuery: React.FC<Props> = ({
<Checkbox
size="small"
checked={queryAll}
onChange={(e) => setQueryField("queryAll", e.target.checked)}
onChange={(e) => {
setQueryField("queryAll", e.target.checked);
setQueryField("hasQueried", false);
}}
/>
}
label={<Typography variant="body2"></Typography>}
@@ -159,7 +166,10 @@ const SchemeQuery: React.FC<Props> = ({
<LocalizationProvider dateAdapter={AdapterDayjs} adapterLocale="zh-cn">
<DatePicker
value={queryDate}
onChange={(value) => setQueryField("queryDate", value)}
onChange={(value) => {
setQueryField("queryDate", value);
setQueryField("hasQueried", false);
}}
disabled={queryAll}
format="YYYY-MM-DD"
slotProps={{ textField: { size: "small", sx: { width: 200 } } }}
@@ -180,39 +190,7 @@ const SchemeQuery: React.FC<Props> = ({
</Box>
<Box className="flex-1 overflow-auto">
{sortedSchemes.length === 0 ? (
<Box className="flex flex-col items-center justify-center h-full text-gray-400">
<Box className="mb-4">
<svg
width="80"
height="80"
viewBox="0 0 80 80"
fill="none"
className="opacity-40"
>
<rect
x="10"
y="20"
width="60"
height="45"
rx="2"
stroke="currentColor"
strokeWidth="2"
/>
<line
x1="10"
y1="30"
x2="70"
y2="30"
stroke="currentColor"
strokeWidth="2"
/>
</svg>
</Box>
<Typography variant="body2"> 0 </Typography>
<Typography variant="body2" className="mt-1">
No data
</Typography>
</Box>
<SchemeQueryEmptyState hasQueried={hasQueried} />
) : (
<Box className="space-y-2 p-2">
<Typography variant="caption" className="text-gray-500 px-2">