feat(workbench): integrate runtime data and map tooling
This commit is contained in:
@@ -1,5 +1,4 @@
|
||||
import {
|
||||
Activity,
|
||||
Camera,
|
||||
Circle,
|
||||
Copy,
|
||||
@@ -15,6 +14,7 @@ import {
|
||||
Route,
|
||||
Ruler,
|
||||
Share2,
|
||||
Square,
|
||||
Trash2,
|
||||
Undo2,
|
||||
Waypoints,
|
||||
@@ -28,7 +28,6 @@ import {
|
||||
MapDrawToolbar,
|
||||
MapLayerPanel,
|
||||
MapLegendList,
|
||||
MapMetricTile,
|
||||
MapMeasurePanel,
|
||||
MapPanelSection,
|
||||
type BaseLayerOption,
|
||||
@@ -233,7 +232,8 @@ export function ToolbarPanel({
|
||||
title="图层"
|
||||
description={`${layerItems.filter((item) => item.visible).length}/${layerItems.length} 个业务图层可见`}
|
||||
icon={Icon}
|
||||
widthClassName={panelWidthClassName}
|
||||
widthClassName={panelWidthClassName ?? "flex w-[324px] max-h-[calc(100dvh-13.25rem)] flex-col"}
|
||||
contentClassName={panelWidthClassName ? undefined : "min-h-0 overflow-y-auto overscroll-contain pr-0.5"}
|
||||
visible={panelVisible}
|
||||
>
|
||||
<MapLayerPanel
|
||||
@@ -248,8 +248,23 @@ export function ToolbarPanel({
|
||||
}
|
||||
|
||||
if (renderedToolId === "measure") {
|
||||
const measureStatus = getMeasureStatus({
|
||||
enabled: measureEnabled,
|
||||
measuring,
|
||||
hasPoints: hasMeasurePoints,
|
||||
mode: activeMeasureModeId
|
||||
});
|
||||
|
||||
return (
|
||||
<MapControlPanel key="measure" title="测量" description="距离与范围测量" icon={Icon} widthClassName={panelWidthClassName ?? "w-[312px]"} visible={panelVisible}>
|
||||
<MapControlPanel
|
||||
key="measure"
|
||||
title="测量"
|
||||
description="距离、面积与管段测量"
|
||||
icon={Icon}
|
||||
widthClassName={panelWidthClassName ?? "flex w-[324px] max-h-[calc(100dvh-13.25rem)] flex-col"}
|
||||
contentClassName={panelWidthClassName ? undefined : "min-h-0 overflow-y-auto overscroll-contain pr-0.5"}
|
||||
visible={panelVisible}
|
||||
>
|
||||
<MapMeasurePanel
|
||||
modes={MEASURE_MODES}
|
||||
activeModeId={activeMeasureModeId}
|
||||
@@ -259,20 +274,21 @@ export function ToolbarPanel({
|
||||
metrics={measureResult.metrics}
|
||||
units={MEASURE_UNITS}
|
||||
activeUnitId={activeMeasureUnitId}
|
||||
status={measureStatus}
|
||||
actions={[
|
||||
{
|
||||
id: measuring ? "stop" : "start",
|
||||
icon: Ruler,
|
||||
icon: measuring ? Square : Ruler,
|
||||
label: measuring ? "停止测量" : "开始测量",
|
||||
description:
|
||||
activeMeasureModeId === "segment"
|
||||
? measuring
|
||||
? "暂停管线选择"
|
||||
: "点击管线选择资产"
|
||||
: measuring
|
||||
? "暂停地图取点"
|
||||
: "在地图上连续点击取点",
|
||||
variant: measuring ? "default" : "primary",
|
||||
measuring
|
||||
? "暂停并保留当前读数"
|
||||
: activeMeasureModeId === "segment"
|
||||
? "在地图中选择管线"
|
||||
: activeMeasureModeId === "area"
|
||||
? "在地图中圈定范围"
|
||||
: "在地图中连续取点",
|
||||
variant: measuring ? "active" : "primary",
|
||||
disabled: !measureEnabled,
|
||||
onClick: measuring ? onStopMeasure : onStartMeasure
|
||||
},
|
||||
@@ -303,8 +319,16 @@ export function ToolbarPanel({
|
||||
|
||||
if (renderedToolId === "analysis") {
|
||||
return (
|
||||
<MapControlPanel key="analysis" title="分析" description="图例与当前覆盖" icon={Icon} widthClassName={panelWidthClassName ?? "w-[316px]"} visible={panelVisible}>
|
||||
<AnalysisPanel legendItems={legendItems} />
|
||||
<MapControlPanel
|
||||
key="analysis"
|
||||
title="图例"
|
||||
description={`${legendItems.length} 项当前地图符号`}
|
||||
icon={Icon}
|
||||
widthClassName={panelWidthClassName ?? "flex w-[324px] max-h-[calc(100dvh-13.25rem)] flex-col"}
|
||||
contentClassName={panelWidthClassName ? undefined : "min-h-0 overflow-y-auto overscroll-contain pr-0.5"}
|
||||
visible={panelVisible}
|
||||
>
|
||||
<LegendPanel legendItems={legendItems} />
|
||||
</MapControlPanel>
|
||||
);
|
||||
}
|
||||
@@ -368,21 +392,68 @@ export function ToolbarPanel({
|
||||
);
|
||||
}
|
||||
|
||||
function AnalysisPanel({ legendItems }: { legendItems: MapLegendItem[] }) {
|
||||
return (
|
||||
<div className="space-y-3">
|
||||
<MapPanelSection title="图例">
|
||||
<MapLegendList items={legendItems} showStatusDot />
|
||||
</MapPanelSection>
|
||||
function getMeasureStatus({
|
||||
enabled,
|
||||
measuring,
|
||||
hasPoints,
|
||||
mode
|
||||
}: {
|
||||
enabled: boolean;
|
||||
measuring: boolean;
|
||||
hasPoints: boolean;
|
||||
mode: WorkbenchMeasureMode;
|
||||
}) {
|
||||
if (!enabled) {
|
||||
return {
|
||||
label: "地图未就绪",
|
||||
description: "等待地图加载后再开始测量",
|
||||
tone: "disabled" as const
|
||||
};
|
||||
}
|
||||
|
||||
<MapPanelSection title="当前覆盖">
|
||||
<div className="grid grid-cols-2 gap-2">
|
||||
<MapMetricTile label="影响范围" value="未开启" />
|
||||
<MapMetricTile label="风险预览" value="待生成" />
|
||||
</div>
|
||||
<MapActionRow icon={Activity} label="模拟结果" description="影响面、事故点与标签" />
|
||||
<MapActionRow icon={MapPinned} label="选中对象" description="点击管线或节点查看详情" />
|
||||
</MapPanelSection>
|
||||
if (measuring) {
|
||||
return {
|
||||
label: "测量中",
|
||||
description:
|
||||
mode === "segment"
|
||||
? "点击地图中的管线追加资产"
|
||||
: mode === "area"
|
||||
? "连续点击范围顶点,停止后保留读数"
|
||||
: "连续点击地图取点,停止后保留读数",
|
||||
tone: "active" as const
|
||||
};
|
||||
}
|
||||
|
||||
if (hasPoints) {
|
||||
return {
|
||||
label: "读数已保留",
|
||||
description: "可继续测量、复制结果或清除",
|
||||
tone: "ready" as const
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
label: "等待开始",
|
||||
description:
|
||||
mode === "segment"
|
||||
? "开始后点击管线选择资产"
|
||||
: mode === "area"
|
||||
? "开始后连续点击范围顶点"
|
||||
: "开始后连续点击地图取点",
|
||||
tone: "idle" as const
|
||||
};
|
||||
}
|
||||
|
||||
function LegendPanel({ legendItems }: { legendItems: MapLegendItem[] }) {
|
||||
return (
|
||||
<div className="space-y-2">
|
||||
<MapLegendList items={legendItems} />
|
||||
<div role="note" className="surface-control rounded-xl border px-3 py-2.5">
|
||||
<p className="text-[11px] font-semibold text-slate-700">图例随图层显隐同步</p>
|
||||
<p className="mt-1 text-[10px] leading-relaxed text-slate-500">
|
||||
管线颜色和线宽表示口径,设施颜色表示类型,风险色仅用于分析覆盖。
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user