refactor: organize supply frontend structure
This commit is contained in:
@@ -1,11 +1,9 @@
|
||||
"use client";
|
||||
|
||||
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
||||
import { AnimatePresence, motion, type Variants } from "motion/react";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { cn } from "@/shared/ui/cn";
|
||||
import type {
|
||||
ScheduledConditionRecord
|
||||
} from "@/features/workbench/types";
|
||||
} from "../types";
|
||||
import {
|
||||
createVisibleTickerCards,
|
||||
type TickerStackCard
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import type {
|
||||
ScheduledConditionRiskLevel,
|
||||
ScheduledConditionStatus
|
||||
} from "@/features/workbench/types";
|
||||
} from "../types";
|
||||
|
||||
export function getConditionReportRiskLevel(
|
||||
status: ScheduledConditionStatus,
|
||||
|
||||
@@ -1,113 +0,0 @@
|
||||
import type { ReactNode, SVGProps } from "react";
|
||||
|
||||
export type DrainageFeatureIconProps = SVGProps<SVGSVGElement> & {
|
||||
size?: number;
|
||||
};
|
||||
|
||||
type DrainageIconFrameProps = DrainageFeatureIconProps & {
|
||||
children: ReactNode;
|
||||
};
|
||||
|
||||
function DrainageIconFrame({ children, size = 20, ...props }: DrainageIconFrameProps) {
|
||||
return (
|
||||
<svg
|
||||
width={size}
|
||||
height={size}
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
strokeWidth="1.8"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
focusable="false"
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
export function ConduitFeatureIcon(props: DrainageFeatureIconProps) {
|
||||
return (
|
||||
<DrainageIconFrame {...props}>
|
||||
<circle cx="3.5" cy="12" r="1.75" />
|
||||
<circle cx="20.5" cy="12" r="1.75" />
|
||||
<path d="M5.25 9.5h13.5M5.25 14.5h13.5" />
|
||||
</DrainageIconFrame>
|
||||
);
|
||||
}
|
||||
|
||||
export function JunctionFeatureIcon(props: DrainageFeatureIconProps) {
|
||||
return (
|
||||
<DrainageIconFrame {...props}>
|
||||
<circle cx="12" cy="12" r="5" />
|
||||
<circle cx="12" cy="12" r="1.75" />
|
||||
<path d="M12 2.5V7M2.5 12H7M17 12h4.5M12 17v4.5" />
|
||||
</DrainageIconFrame>
|
||||
);
|
||||
}
|
||||
|
||||
export function ValveFeatureIcon(props: DrainageFeatureIconProps) {
|
||||
return (
|
||||
<DrainageIconFrame {...props}>
|
||||
<path d="M3.5 12h4.75M15.75 12h4.75" />
|
||||
<path d="m8.25 7 7.5 5-7.5 5V7Z" />
|
||||
<path d="m15.75 7-7.5 5 7.5 5V7Z" />
|
||||
<path d="M12 7V3.5M9.5 3.5h5" />
|
||||
</DrainageIconFrame>
|
||||
);
|
||||
}
|
||||
|
||||
export function ReservoirFeatureIcon(props: DrainageFeatureIconProps) {
|
||||
return (
|
||||
<DrainageIconFrame {...props}>
|
||||
<path d="M5 8.5c0-2.2 14-2.2 14 0v7c0 2.2-14 2.2-14 0v-7Z" />
|
||||
<path d="M5 8.5c0 2.2 14 2.2 14 0" />
|
||||
<path d="M5 12c0 2.2 14 2.2 14 0" />
|
||||
<path d="M8 19.5h8" />
|
||||
</DrainageIconFrame>
|
||||
);
|
||||
}
|
||||
|
||||
export function ScadaFeatureIcon(props: DrainageFeatureIconProps) {
|
||||
return (
|
||||
<DrainageIconFrame {...props}>
|
||||
<circle cx="12" cy="7.5" r="1.75" />
|
||||
<path d="M8.25 4.25a5.25 5.25 0 0 0 0 6.5M15.75 4.25a5.25 5.25 0 0 1 0 6.5" />
|
||||
<path d="M5.25 2.25a9 9 0 0 0 0 10.5M18.75 2.25a9 9 0 0 1 0 10.5" />
|
||||
<path d="M12 9.25v5.25M3.5 18h4l1.5-3 2.75 6 2.5-5 1.25 2h5" />
|
||||
</DrainageIconFrame>
|
||||
);
|
||||
}
|
||||
|
||||
export function OrificeFeatureIcon(props: DrainageFeatureIconProps) {
|
||||
return (
|
||||
<DrainageIconFrame {...props}>
|
||||
<path d="M2.5 12H9M15 12h6.5" />
|
||||
<path d="M9.5 4v5.35M9.5 14.65V20M14.5 4v5.35M14.5 14.65V20" />
|
||||
<circle cx="12" cy="12" r="3" />
|
||||
</DrainageIconFrame>
|
||||
);
|
||||
}
|
||||
|
||||
export function PumpFeatureIcon(props: DrainageFeatureIconProps) {
|
||||
return (
|
||||
<DrainageIconFrame {...props}>
|
||||
<circle cx="9.5" cy="13.5" r="6" />
|
||||
<circle cx="9.5" cy="13.5" r="1.25" />
|
||||
<path d="M9.5 12.25V8.5M10.75 13.5h3.75M8.65 14.4 6.2 16.85" />
|
||||
<path d="M9.5 7.5V3.5h10v5M3.5 13.5H1.75" />
|
||||
<path d="m17 6 2.5 2.5L22 6" />
|
||||
</DrainageIconFrame>
|
||||
);
|
||||
}
|
||||
|
||||
export function OutfallFeatureIcon(props: DrainageFeatureIconProps) {
|
||||
return (
|
||||
<DrainageIconFrame {...props}>
|
||||
<path d="M4 4.5h10v7h5" />
|
||||
<path d="m16.5 8.75 2.75 2.75-2.75 2.75" />
|
||||
<path d="M3 18c1.5-1.25 3-1.25 4.5 0s3 1.25 4.5 0 3-1.25 4.5 0 3 1.25 4.5 0M5 21c1.15-.75 2.3-.75 3.45 0s2.3.75 3.45 0 2.3-.75 3.45 0 2.3.75 3.45 0" />
|
||||
</DrainageIconFrame>
|
||||
);
|
||||
}
|
||||
@@ -1,5 +1,3 @@
|
||||
"use client";
|
||||
|
||||
import { Target, TriangleAlert, X } from "lucide-react";
|
||||
import { useMemo } from "react";
|
||||
import type { DetailFeature } from "../types";
|
||||
|
||||
@@ -1,14 +1,12 @@
|
||||
"use client";
|
||||
|
||||
import { Check, Copy, Database, X } from "lucide-react";
|
||||
import type { ComponentType } from "react";
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
import {
|
||||
MAP_FOCUS_SURFACE_CLASS_NAME,
|
||||
MAP_MAJOR_PANEL_RADIUS_CLASS_NAME
|
||||
} from "@/features/map/core/components/map-control-styles";
|
||||
import { showMapNotice } from "@/features/map/core/components/notice-actions";
|
||||
import { cn } from "@/lib/utils";
|
||||
MAP_MAJOR_PANEL_RADIUS_CLASS_NAME,
|
||||
showMapNotice
|
||||
} from "@/features/map/core";
|
||||
import { cn } from "@/shared/ui/cn";
|
||||
import type { WaterNetworkSourceId } from "../map/sources";
|
||||
import type { DetailFeature } from "../types";
|
||||
import {
|
||||
@@ -16,14 +14,14 @@ import {
|
||||
type FeaturePanelBadgeTone
|
||||
} from "../utils/feature-properties";
|
||||
import {
|
||||
ConduitFeatureIcon,
|
||||
PipeFeatureIcon,
|
||||
JunctionFeatureIcon,
|
||||
PumpFeatureIcon,
|
||||
ReservoirFeatureIcon,
|
||||
ScadaFeatureIcon,
|
||||
ValveFeatureIcon,
|
||||
type DrainageFeatureIconProps
|
||||
} from "./drainage-feature-icons";
|
||||
type SupplyFeatureIconProps
|
||||
} from "./supply-feature-icons";
|
||||
import { FeaturePropertyList } from "./feature-property-list";
|
||||
|
||||
type FeaturePopoverProps = {
|
||||
@@ -34,14 +32,14 @@ type FeaturePopoverProps = {
|
||||
const FEATURE_LAYER_META: Record<
|
||||
WaterNetworkSourceId,
|
||||
{
|
||||
icon: ComponentType<DrainageFeatureIconProps>;
|
||||
icon: ComponentType<SupplyFeatureIconProps>;
|
||||
label: string;
|
||||
headerClassName: string;
|
||||
labelClassName: string;
|
||||
iconClassName: string;
|
||||
}
|
||||
> = {
|
||||
pipes: { icon: ConduitFeatureIcon, label: "管线", headerClassName: "bg-teal-50/70", labelClassName: "text-teal-800", iconClassName: "bg-teal-700 text-white ring-teal-900/10" },
|
||||
pipes: { icon: PipeFeatureIcon, label: "管线", headerClassName: "bg-teal-50/70", labelClassName: "text-teal-800", iconClassName: "bg-teal-700 text-white ring-teal-900/10" },
|
||||
junctions: { icon: JunctionFeatureIcon, label: "节点", headerClassName: "bg-blue-50/70", labelClassName: "text-blue-800", iconClassName: "bg-sky-700 text-white ring-sky-900/10" },
|
||||
valves: { icon: ValveFeatureIcon, label: "阀门", headerClassName: "bg-violet-50/70", labelClassName: "text-violet-800", iconClassName: "bg-violet-600 text-white ring-violet-900/10" },
|
||||
reservoirs: { icon: ReservoirFeatureIcon, label: "水库", headerClassName: "bg-sky-50/70", labelClassName: "text-sky-900", iconClassName: "bg-sky-800 text-white ring-sky-900/10" },
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { cn } from "@/lib/utils";
|
||||
import { cn } from "@/shared/ui/cn";
|
||||
import type { LocalizedFeatureProperty } from "../utils/feature-properties";
|
||||
|
||||
type FeaturePropertyListProps = {
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
"use client";
|
||||
|
||||
import { useEffect, useMemo, useState } from "react";
|
||||
import { ChevronDown, Crosshair, LocateFixed, RotateCcw, X } from "lucide-react";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { cn } from "@/shared/ui/cn";
|
||||
import {
|
||||
LAYER_GROUP_GEOMETRIES,
|
||||
type LayerGroupId,
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
"use client";
|
||||
|
||||
import {
|
||||
AlertTriangle,
|
||||
Bot,
|
||||
@@ -20,13 +18,13 @@ import {
|
||||
} from "lucide-react";
|
||||
import { AnimatePresence, motion } from "motion/react";
|
||||
import { useEffect, useState } from "react";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { showMapNotice } from "@/features/map/core/components/notice-actions";
|
||||
import { cn } from "@/shared/ui/cn";
|
||||
import { showMapNotice } from "@/features/map/core";
|
||||
import {
|
||||
getRunningWorkflowDefinition,
|
||||
getRunningWorkflowState,
|
||||
getWorkflowStepStatus
|
||||
} from "@/features/workbench/data/running-workflows";
|
||||
} from "../data/running-workflows";
|
||||
import type {
|
||||
ScheduledConditionAnalysisInsight,
|
||||
ScheduledConditionItem,
|
||||
@@ -34,7 +32,7 @@ import type {
|
||||
ScheduledConditionRecord,
|
||||
ScheduledConditionRiskLevel,
|
||||
ScheduledWorkOrderItem
|
||||
} from "@/features/workbench/types";
|
||||
} from "../types";
|
||||
import {
|
||||
formatDuration,
|
||||
formatTime,
|
||||
|
||||
@@ -10,7 +10,7 @@ import type {
|
||||
ScheduledConditionStatus,
|
||||
ScheduledWorkOrderItem,
|
||||
ScheduledWorkOrderStage
|
||||
} from "@/features/workbench/types";
|
||||
} from "../types";
|
||||
|
||||
export const CONDITION_FILTER_ALL = "__all__";
|
||||
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
"use client";
|
||||
|
||||
import {
|
||||
CalendarClock,
|
||||
ChevronDown,
|
||||
@@ -10,12 +8,11 @@ import {
|
||||
} from "lucide-react";
|
||||
import { AnimatePresence, motion } from "motion/react";
|
||||
import { useCallback, useEffect, useMemo, useState } from "react";
|
||||
import { MAP_TOOL_PANEL_SURFACE_CLASS_NAME } from "@/features/map/core/components/map-control-styles";
|
||||
import { showMapNotice } from "@/features/map/core/components/notice-actions";
|
||||
import { isGeneratedScheduledConditionSessionId } from "@/features/workbench/data/scheduled-conditions";
|
||||
import type { ScheduledConditionItem } from "@/features/workbench/types";
|
||||
import { createConditionConversationPrompt } from "@/features/workbench/utils/scheduled-condition-prompts";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { MAP_TOOL_PANEL_SURFACE_CLASS_NAME, showMapNotice } from "@/features/map/core";
|
||||
import { isGeneratedScheduledConditionSessionId } from "../data/scheduled-conditions";
|
||||
import type { ScheduledConditionItem } from "../types";
|
||||
import { createConditionConversationPrompt } from "../utils/scheduled-condition-prompts";
|
||||
import { cn } from "@/shared/ui/cn";
|
||||
import {
|
||||
DropdownMenu,
|
||||
DropdownMenuContent,
|
||||
|
||||
@@ -0,0 +1,93 @@
|
||||
import type { ReactNode, SVGProps } from "react";
|
||||
|
||||
export type SupplyFeatureIconProps = SVGProps<SVGSVGElement> & {
|
||||
size?: number;
|
||||
};
|
||||
|
||||
type SupplyIconFrameProps = SupplyFeatureIconProps & {
|
||||
children: ReactNode;
|
||||
};
|
||||
|
||||
function SupplyIconFrame({ children, size = 20, ...props }: SupplyIconFrameProps) {
|
||||
return (
|
||||
<svg
|
||||
width={size}
|
||||
height={size}
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
strokeWidth="1.8"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
focusable="false"
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
export function PipeFeatureIcon(props: SupplyFeatureIconProps) {
|
||||
return (
|
||||
<SupplyIconFrame {...props}>
|
||||
<circle cx="3.5" cy="12" r="1.75" />
|
||||
<circle cx="20.5" cy="12" r="1.75" />
|
||||
<path d="M5.25 9.5h13.5M5.25 14.5h13.5" />
|
||||
</SupplyIconFrame>
|
||||
);
|
||||
}
|
||||
|
||||
export function JunctionFeatureIcon(props: SupplyFeatureIconProps) {
|
||||
return (
|
||||
<SupplyIconFrame {...props}>
|
||||
<circle cx="12" cy="12" r="5" />
|
||||
<circle cx="12" cy="12" r="1.75" />
|
||||
<path d="M12 2.5V7M2.5 12H7M17 12h4.5M12 17v4.5" />
|
||||
</SupplyIconFrame>
|
||||
);
|
||||
}
|
||||
|
||||
export function ValveFeatureIcon(props: SupplyFeatureIconProps) {
|
||||
return (
|
||||
<SupplyIconFrame {...props}>
|
||||
<path d="M3.5 12h4.75M15.75 12h4.75" />
|
||||
<path d="m8.25 7 7.5 5-7.5 5V7Z" />
|
||||
<path d="m15.75 7-7.5 5 7.5 5V7Z" />
|
||||
<path d="M12 7V3.5M9.5 3.5h5" />
|
||||
</SupplyIconFrame>
|
||||
);
|
||||
}
|
||||
|
||||
export function ReservoirFeatureIcon(props: SupplyFeatureIconProps) {
|
||||
return (
|
||||
<SupplyIconFrame {...props}>
|
||||
<path d="M5 8.5c0-2.2 14-2.2 14 0v7c0 2.2-14 2.2-14 0v-7Z" />
|
||||
<path d="M5 8.5c0 2.2 14 2.2 14 0" />
|
||||
<path d="M5 12c0 2.2 14 2.2 14 0" />
|
||||
<path d="M8 19.5h8" />
|
||||
</SupplyIconFrame>
|
||||
);
|
||||
}
|
||||
|
||||
export function ScadaFeatureIcon(props: SupplyFeatureIconProps) {
|
||||
return (
|
||||
<SupplyIconFrame {...props}>
|
||||
<circle cx="12" cy="7.5" r="1.75" />
|
||||
<path d="M8.25 4.25a5.25 5.25 0 0 0 0 6.5M15.75 4.25a5.25 5.25 0 0 1 0 6.5" />
|
||||
<path d="M5.25 2.25a9 9 0 0 0 0 10.5M18.75 2.25a9 9 0 0 1 0 10.5" />
|
||||
<path d="M12 9.25v5.25M3.5 18h4l1.5-3 2.75 6 2.5-5 1.25 2h5" />
|
||||
</SupplyIconFrame>
|
||||
);
|
||||
}
|
||||
|
||||
export function PumpFeatureIcon(props: SupplyFeatureIconProps) {
|
||||
return (
|
||||
<SupplyIconFrame {...props}>
|
||||
<circle cx="9.5" cy="13.5" r="6" />
|
||||
<circle cx="9.5" cy="13.5" r="1.25" />
|
||||
<path d="M9.5 12.25V8.5M10.75 13.5h3.75M8.65 14.4 6.2 16.85" />
|
||||
<path d="M9.5 7.5V3.5h10v5M3.5 13.5H1.75" />
|
||||
<path d="m17 6 2.5 2.5L22 6" />
|
||||
</SupplyIconFrame>
|
||||
);
|
||||
}
|
||||
@@ -23,21 +23,20 @@ import {
|
||||
import { useEffect, useMemo, useState } from "react";
|
||||
import {
|
||||
MapAnnotationPanel,
|
||||
type MapAnnotationItem,
|
||||
type MapAnnotationShareAction
|
||||
} from "@/features/map/core/components/annotation-panel";
|
||||
import type { BaseLayerOption } from "@/features/map/core/components/base-layers-control";
|
||||
import {
|
||||
MapActionRow,
|
||||
MapControlPanel,
|
||||
MapDrawToolbar,
|
||||
MapLayerPanel,
|
||||
MapLegendList,
|
||||
MapMetricTile,
|
||||
MapPanelSection
|
||||
} from "@/features/map/core/components/control-panel";
|
||||
import { MapDrawToolbar } from "@/features/map/core/components/draw-toolbar";
|
||||
import { MapLayerPanel } from "@/features/map/core/components/layer-panel";
|
||||
import type { MapLayerControlItem } from "@/features/map/core/components/layer-control";
|
||||
import { MapLegendList, type MapLegendItem } from "@/features/map/core/components/legend";
|
||||
import { MapMeasurePanel } from "@/features/map/core/components/measure-panel";
|
||||
MapMeasurePanel,
|
||||
MapPanelSection,
|
||||
type BaseLayerOption,
|
||||
type MapAnnotationItem,
|
||||
type MapAnnotationShareAction,
|
||||
type MapLayerControlItem,
|
||||
type MapLegendItem
|
||||
} from "@/features/map/core";
|
||||
import {
|
||||
type WorkbenchDrawingAnnotation,
|
||||
type WorkbenchDrawMode
|
||||
|
||||
@@ -0,0 +1,118 @@
|
||||
import { AgentCollapsedRail, AgentCommandPanel, AgentPersona } from "@/features/agent";
|
||||
import {
|
||||
MAP_CONTROL_SURFACE_CLASS_NAME,
|
||||
MAP_MAJOR_PANEL_RADIUS_CLASS_NAME
|
||||
} from "@/features/map/core";
|
||||
import { cn } from "@/shared/ui/cn";
|
||||
import type { ComponentProps } from "react";
|
||||
import { WORKBENCH_LAYOUT, getWorkbenchViewportLayout } from "../layout/workbench-layout";
|
||||
import { useAgentPanelResize } from "../hooks/use-agent-panel-resize";
|
||||
|
||||
type AgentPanelProps = Omit<ComponentProps<typeof AgentCommandPanel>, "collapsing" | "onCollapse">;
|
||||
|
||||
type WorkbenchAgentPanelsProps = {
|
||||
panelProps: AgentPanelProps;
|
||||
panelOpen: boolean;
|
||||
panelCollapsing: boolean;
|
||||
mobileOpen: boolean;
|
||||
mobilePanelCollapsing: boolean;
|
||||
personaState: ComponentProps<typeof AgentPersona>["state"];
|
||||
statusLabel: string;
|
||||
viewportWidth: number;
|
||||
onCollapsePanel: () => void;
|
||||
onCloseMobilePanel: () => void;
|
||||
onExpandPanel: () => void;
|
||||
onOpenMobilePanel: () => void;
|
||||
};
|
||||
|
||||
export function WorkbenchAgentPanels({
|
||||
panelProps,
|
||||
panelOpen,
|
||||
panelCollapsing,
|
||||
mobileOpen,
|
||||
mobilePanelCollapsing,
|
||||
personaState,
|
||||
statusLabel,
|
||||
viewportWidth,
|
||||
onCollapsePanel,
|
||||
onCloseMobilePanel,
|
||||
onExpandPanel,
|
||||
onOpenMobilePanel
|
||||
}: WorkbenchAgentPanelsProps) {
|
||||
const resize = useAgentPanelResize(viewportWidth);
|
||||
const defaultWidth = getWorkbenchViewportLayout(viewportWidth).agentWidth;
|
||||
|
||||
return (
|
||||
<>
|
||||
<div
|
||||
ref={resize.panelRef}
|
||||
className="pointer-events-none absolute bottom-4 left-3 top-24 z-20 hidden w-[var(--workbench-agent-width)] max-w-[50vw] 2xl:w-[var(--workbench-agent-width-wide)] lg:block"
|
||||
style={resize.width === null ? undefined : { width: resize.width }}
|
||||
>
|
||||
{panelOpen ? (
|
||||
<>
|
||||
<AgentCommandPanel
|
||||
{...panelProps}
|
||||
collapsing={panelCollapsing}
|
||||
onCollapse={onCollapsePanel}
|
||||
/>
|
||||
<div
|
||||
aria-label="调整 Agent 面板宽度"
|
||||
aria-orientation="vertical"
|
||||
aria-valuemax={Math.round(viewportWidth * WORKBENCH_LAYOUT.maxAgentViewportRatio)}
|
||||
aria-valuemin={defaultWidth}
|
||||
aria-valuenow={Math.round(resize.width ?? defaultWidth)}
|
||||
className={cn(
|
||||
"group pointer-events-auto absolute -right-3 top-4 bottom-4 z-10 flex w-6 cursor-ew-resize touch-none items-center justify-center outline-hidden",
|
||||
resize.resizing && "[&>span]:bg-blue-500 [&>span]:opacity-100"
|
||||
)}
|
||||
role="separator"
|
||||
tabIndex={0}
|
||||
title="拖拽调整 Agent 面板宽度"
|
||||
onKeyDown={resize.handleKeyDown}
|
||||
onPointerDown={resize.handlePointerDown}
|
||||
>
|
||||
<span className="h-14 w-1 rounded-full bg-slate-500/60 opacity-50 shadow-xs transition-[height,background-color,opacity] group-hover:h-20 group-hover:bg-blue-500 group-hover:opacity-100 group-focus-visible:h-20 group-focus-visible:bg-blue-500 group-focus-visible:opacity-100" />
|
||||
</div>
|
||||
</>
|
||||
) : (
|
||||
<AgentCollapsedRail
|
||||
personaState={personaState}
|
||||
statusLabel={statusLabel}
|
||||
onExpand={onExpandPanel}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="absolute bottom-20 left-3 right-3 z-30 lg:hidden">
|
||||
{mobileOpen ? (
|
||||
<div className="h-[calc(100dvh-8.5rem)] min-h-[420px]">
|
||||
<AgentCommandPanel
|
||||
{...panelProps}
|
||||
collapsing={mobilePanelCollapsing}
|
||||
onCollapse={onCloseMobilePanel}
|
||||
/>
|
||||
</div>
|
||||
) : null}
|
||||
</div>
|
||||
|
||||
{!mobileOpen ? (
|
||||
<div className="absolute bottom-20 left-3 z-30 lg:hidden">
|
||||
<button
|
||||
type="button"
|
||||
aria-label="打开 Agent 面板"
|
||||
title="打开 Agent 面板"
|
||||
onClick={onOpenMobilePanel}
|
||||
className={cn(
|
||||
"grid h-12 w-12 place-items-center text-violet-700",
|
||||
MAP_MAJOR_PANEL_RADIUS_CLASS_NAME,
|
||||
MAP_CONTROL_SURFACE_CLASS_NAME
|
||||
)}
|
||||
>
|
||||
<AgentPersona className="pointer-events-none h-10 w-10" state={personaState} />
|
||||
</button>
|
||||
</div>
|
||||
) : null}
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -1,5 +1,3 @@
|
||||
"use client";
|
||||
|
||||
import {
|
||||
Activity,
|
||||
Bell,
|
||||
@@ -24,8 +22,8 @@ import {
|
||||
MAP_ICON_CELL_RADIUS_CLASS_NAME,
|
||||
MAP_MAJOR_PANEL_RADIUS_CLASS_NAME,
|
||||
MAP_READABLE_RADIUS_CLASS_NAME
|
||||
} from "@/features/map/core/components/map-control-styles";
|
||||
import { cn } from "@/lib/utils";
|
||||
} from "@/features/map/core";
|
||||
import { cn } from "@/shared/ui/cn";
|
||||
import {
|
||||
DropdownMenu,
|
||||
DropdownMenuContent,
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
"use client";
|
||||
|
||||
import { useState } from "react";
|
||||
import {
|
||||
Box,
|
||||
@@ -13,8 +11,8 @@ import {
|
||||
} from "lucide-react";
|
||||
import {
|
||||
MAP_ICON_CELL_RADIUS_CLASS_NAME
|
||||
} from "@/features/map/core/components/map-control-styles";
|
||||
import { cn } from "@/lib/utils";
|
||||
} from "@/features/map/core";
|
||||
import { cn } from "@/shared/ui/cn";
|
||||
import type { WorkbenchAlert, WorkbenchScenario, WorkbenchUser } from "../types";
|
||||
import { AlertMenu, ScenarioMenu, UserMenu } from "./workbench-top-bar-menus";
|
||||
import {
|
||||
|
||||
Reference in New Issue
Block a user