feat(workbench): refine operational interface
This commit is contained in:
@@ -21,7 +21,7 @@ type TickerTransitionDirection = -1 | 1;
|
||||
const tickerEase = [0.22, 1, 0.36, 1] as const;
|
||||
const tickerSwitchAnimationMs = 380;
|
||||
const tickerCardSurfaceClassName =
|
||||
"border border-white/75 bg-white/[0.92] ring-1 ring-slate-900/5 backdrop-blur-xl";
|
||||
"glass-control border";
|
||||
|
||||
const tickerCardVariants: Variants = {
|
||||
initial: (direction: TickerTransitionDirection) => ({
|
||||
@@ -261,7 +261,7 @@ export function AgentTaskTicker({
|
||||
{isHovered && hasMultipleRunningTasks ? (
|
||||
<motion.div
|
||||
key="task-indicator"
|
||||
className="agent-task-ticker-indicator flex flex-col gap-1 rounded-full bg-white/80 px-1 py-1 shadow-sm shadow-blue-950/10 backdrop-blur"
|
||||
className="agent-task-ticker-indicator flex flex-col gap-1 rounded-full bg-[var(--glass-menu)] px-1 py-1 shadow-sm shadow-blue-950/10"
|
||||
variants={tickerIndicatorVariants}
|
||||
initial="initial"
|
||||
animate="animate"
|
||||
|
||||
@@ -77,7 +77,7 @@ export function FeatureInsightPanel({ feature, onClose }: FeatureInsightPanelPro
|
||||
}, [feature]);
|
||||
|
||||
return (
|
||||
<aside className="pointer-events-auto flex h-full min-h-0 flex-col rounded border border-white/60 bg-white/88 shadow-glass backdrop-blur">
|
||||
<aside className="glass-readable pointer-events-auto flex h-full min-h-0 flex-col rounded border">
|
||||
<div className="border-b border-slate-200/80 p-4">
|
||||
<div className="flex items-start justify-between gap-3">
|
||||
<div>
|
||||
@@ -122,11 +122,11 @@ export function FeatureInsightPanel({ feature, onClose }: FeatureInsightPanelPro
|
||||
<p className="mt-0.5 truncate text-xs text-slate-500 tabular-nums">{formatFeaturePropertyValue("device_external_id", feature.properties.device_external_id)}</p>
|
||||
</div>
|
||||
</div>
|
||||
<p className="mt-2 text-sm leading-6 text-slate-700">当前点位由管网密度聚类生成,仅用于空间展示。图层暂未提供实时测值或历史曲线。</p>
|
||||
<p className="mt-2 text-sm leading-6 text-slate-700">当前点位由管网节点空间均匀采样生成,仅用于空间展示,不代表设备真实安装坐标。图层暂未提供实时测值或历史曲线。</p>
|
||||
</section>
|
||||
) : null}
|
||||
|
||||
<section className="mt-4 rounded border border-orange-100 bg-orange-50/70 p-3">
|
||||
<section className="glass-warning mt-4 rounded border border-orange-100 p-3">
|
||||
<div className="flex items-center gap-2 text-sm font-semibold text-orange-900">
|
||||
<TriangleAlert size={16} aria-hidden="true" />
|
||||
Agent 解释
|
||||
@@ -166,8 +166,8 @@ export function FeatureInsightPanel({ feature, onClose }: FeatureInsightPanelPro
|
||||
|
||||
function getScadaPresentation(rawTypeId: unknown) {
|
||||
const typeId = Number(rawTypeId);
|
||||
if (typeId === 72) return { iconPath: SCADA_ICON_PATHS.waterQuality, sectionClassName: "border-teal-200 bg-teal-50/70", labelClassName: "text-teal-800" };
|
||||
if (typeId === 58) return { iconPath: SCADA_ICON_PATHS.radarLevel, sectionClassName: "border-blue-200 bg-blue-50/70", labelClassName: "text-blue-800" };
|
||||
if (typeId === 45) return { iconPath: SCADA_ICON_PATHS.ultrasonicFlow, sectionClassName: "border-orange-200 bg-orange-50/70", labelClassName: "text-orange-800" };
|
||||
if (typeId === 72) return { iconPath: SCADA_ICON_PATHS.waterQuality, sectionClassName: "glass-normal border-teal-200", labelClassName: "text-teal-800" };
|
||||
if (typeId === 58) return { iconPath: SCADA_ICON_PATHS.radarLevel, sectionClassName: "glass-info border-blue-200", labelClassName: "text-blue-800" };
|
||||
if (typeId === 45) return { iconPath: SCADA_ICON_PATHS.ultrasonicFlow, sectionClassName: "glass-warning border-orange-200", labelClassName: "text-orange-800" };
|
||||
return { iconPath: SCADA_ICON_PATHS.unknown, sectionClassName: "border-slate-200 bg-slate-50", labelClassName: "text-slate-800" };
|
||||
}
|
||||
|
||||
@@ -46,12 +46,12 @@ const FEATURE_LAYER_META: Record<
|
||||
iconClassName: string;
|
||||
}
|
||||
> = {
|
||||
conduits: { icon: ConduitFeatureIcon, label: "管渠", headerClassName: "bg-teal-50", labelClassName: "text-teal-700", iconClassName: "bg-teal-700 text-white ring-teal-900/10" },
|
||||
junctions: { icon: JunctionFeatureIcon, label: "检查井", headerClassName: "bg-sky-50", labelClassName: "text-sky-700", iconClassName: "bg-sky-700 text-white ring-sky-900/10" },
|
||||
orifices: { icon: OrificeFeatureIcon, label: "孔口", headerClassName: "bg-slate-100", labelClassName: "text-slate-700", iconClassName: "bg-slate-600 text-white ring-slate-900/10" },
|
||||
outfalls: { icon: OutfallFeatureIcon, label: "排放口", headerClassName: "bg-blue-50", labelClassName: "text-blue-800", iconClassName: "bg-slate-700 text-white ring-slate-900/10" },
|
||||
pumps: { icon: PumpFeatureIcon, label: "泵", headerClassName: "bg-cyan-50", labelClassName: "text-cyan-800", iconClassName: "bg-cyan-800 text-white ring-cyan-950/10" },
|
||||
scada: { icon: JunctionFeatureIcon, label: "SCADA 测点", headerClassName: "bg-blue-50", labelClassName: "text-blue-700", iconClassName: "bg-blue-700 text-white ring-blue-900/10" }
|
||||
conduits: { icon: ConduitFeatureIcon, label: "管渠", headerClassName: "glass-normal", labelClassName: "text-teal-800", iconClassName: "bg-teal-700 text-white ring-teal-900/10" },
|
||||
junctions: { icon: JunctionFeatureIcon, label: "检查井", headerClassName: "glass-info", labelClassName: "text-blue-800", iconClassName: "bg-sky-700 text-white ring-sky-900/10" },
|
||||
orifices: { icon: OrificeFeatureIcon, label: "孔口", headerClassName: "bg-[var(--glass-readable)]", labelClassName: "text-slate-700", iconClassName: "bg-slate-600 text-white ring-slate-900/10" },
|
||||
outfalls: { icon: OutfallFeatureIcon, label: "排放口", headerClassName: "glass-info", labelClassName: "text-blue-800", iconClassName: "bg-slate-700 text-white ring-slate-900/10" },
|
||||
pumps: { icon: PumpFeatureIcon, label: "泵", headerClassName: "glass-normal", labelClassName: "text-teal-800", iconClassName: "bg-cyan-800 text-white ring-cyan-950/10" },
|
||||
scada: { icon: JunctionFeatureIcon, label: "SCADA 测点", headerClassName: "glass-info", labelClassName: "text-blue-800", iconClassName: "bg-blue-700 text-white ring-blue-900/10" }
|
||||
};
|
||||
|
||||
const BADGE_CLASS_NAMES: Record<FeaturePanelBadgeTone, string> = {
|
||||
@@ -128,7 +128,7 @@ export function FeaturePopover({ feature, onClose }: FeaturePopoverProps) {
|
||||
return (
|
||||
<aside
|
||||
className={cn(
|
||||
"pointer-events-auto absolute left-1/2 top-[92px] z-20 w-[min(380px,calc(100vw-24px))] -translate-x-1/2 overflow-hidden bg-white/94 shadow-2xl shadow-blue-950/20 ring-1 ring-white/80 backdrop-blur-xl",
|
||||
"glass-focus pointer-events-auto absolute left-1/2 top-[92px] z-20 w-[min(380px,calc(100vw-24px))] -translate-x-1/2 overflow-hidden border",
|
||||
MAP_MAJOR_PANEL_RADIUS_CLASS_NAME
|
||||
)}
|
||||
>
|
||||
@@ -155,8 +155,8 @@ export function FeaturePopover({ feature, onClose }: FeaturePopoverProps) {
|
||||
<div className="flex items-center gap-0.5">
|
||||
{canCopy ? (
|
||||
<button type="button" aria-label={copied ? "编号已复制" : "复制编号"} title={copied ? "编号已复制" : "复制编号"} onClick={() => void handleCopyId()} className="relative grid h-10 w-10 shrink-0 place-items-center rounded-xl text-slate-500 transition-[background-color,color,transform] duration-150 [@media(hover:hover)]:hover:bg-white/70 [@media(hover:hover)]:hover:text-slate-950 active:scale-95 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-blue-600/25">
|
||||
<Copy size={15} aria-hidden="true" className={cn("absolute transition-[opacity,transform] duration-[120ms]", copied ? "scale-90 opacity-0" : "scale-100 opacity-100")} />
|
||||
<Check size={16} aria-hidden="true" className={cn("absolute text-emerald-600 transition-[opacity,transform] duration-[120ms]", copied ? "scale-100 opacity-100" : "scale-90 opacity-0")} />
|
||||
<Copy size={15} aria-hidden="true" className={cn("absolute transition-[opacity,transform] duration-150", copied ? "scale-90 opacity-0" : "scale-100 opacity-100")} />
|
||||
<Check size={16} aria-hidden="true" className={cn("absolute text-emerald-600 transition-[opacity,transform] duration-150", copied ? "scale-100 opacity-100" : "scale-90 opacity-0")} />
|
||||
</button>
|
||||
) : null}
|
||||
<button type="button" aria-label="关闭要素信息" title="关闭要素信息" onClick={onClose} className="grid h-10 w-10 shrink-0 place-items-center rounded-xl text-slate-500 transition-[background-color,color,transform] duration-150 [@media(hover:hover)]:hover:bg-white/70 [@media(hover:hover)]:hover:text-slate-950 active:scale-95 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-blue-600/25">
|
||||
@@ -218,7 +218,7 @@ function ScadaFeaturePopover({ feature, copied, canCopy, onCopy, onClose }: Scad
|
||||
return (
|
||||
<aside
|
||||
className={cn(
|
||||
"pointer-events-auto absolute left-1/2 top-[92px] z-20 w-[min(380px,calc(100vw-24px))] bg-white/94 shadow-2xl shadow-blue-950/20 ring-1 ring-white/80 backdrop-blur-xl",
|
||||
"glass-focus pointer-events-auto absolute left-1/2 top-[92px] z-20 w-[min(380px,calc(100vw-24px))] border",
|
||||
"-translate-x-1/2 overflow-hidden",
|
||||
MAP_MAJOR_PANEL_RADIUS_CLASS_NAME
|
||||
)}
|
||||
@@ -232,7 +232,7 @@ function ScadaFeaturePopover({ feature, copied, canCopy, onCopy, onClose }: Scad
|
||||
{formatFeaturePropertyValue("device_type_name", properties.device_type_name)}
|
||||
</span>
|
||||
<span className={cn(
|
||||
"inline-flex shrink-0 items-center gap-1.5 rounded-full bg-white/80 px-2 py-0.5 text-xs font-semibold ring-1 ring-inset",
|
||||
"inline-flex shrink-0 items-center gap-1.5 rounded-full bg-[var(--glass-menu)] px-2 py-0.5 text-xs font-semibold ring-1 ring-inset",
|
||||
active ? "text-emerald-700 ring-emerald-600/20" : "text-slate-600 ring-slate-500/20"
|
||||
)}>
|
||||
<span className={cn("h-1.5 w-1.5 rounded-full", active ? "bg-emerald-500" : "bg-slate-400")} />
|
||||
@@ -247,8 +247,8 @@ function ScadaFeaturePopover({ feature, copied, canCopy, onCopy, onClose }: Scad
|
||||
<div className="flex items-center gap-0.5">
|
||||
{canCopy ? (
|
||||
<button type="button" aria-label={copied ? "测点编号已复制" : "复制测点编号"} title={copied ? "测点编号已复制" : "复制测点编号"} onClick={onCopy} className="relative grid h-10 w-10 place-items-center rounded-xl text-slate-500 transition-[background-color,color,transform] duration-150 [@media(hover:hover)]:hover:bg-white/70 [@media(hover:hover)]:hover:text-slate-950 active:scale-95 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-blue-600/25">
|
||||
<Copy size={15} aria-hidden="true" className={cn("absolute transition-[opacity,transform] duration-[120ms]", copied ? "scale-90 opacity-0" : "scale-100 opacity-100")} />
|
||||
<Check size={16} aria-hidden="true" className={cn("absolute text-emerald-600 transition-[opacity,transform] duration-[120ms]", copied ? "scale-100 opacity-100" : "scale-90 opacity-0")} />
|
||||
<Copy size={15} aria-hidden="true" className={cn("absolute transition-[opacity,transform] duration-150", copied ? "scale-90 opacity-0" : "scale-100 opacity-100")} />
|
||||
<Check size={16} aria-hidden="true" className={cn("absolute text-emerald-600 transition-[opacity,transform] duration-150", copied ? "scale-100 opacity-100" : "scale-90 opacity-0")} />
|
||||
</button>
|
||||
) : null}
|
||||
<button type="button" aria-label="关闭 SCADA 测点信息" title="关闭 SCADA 测点信息" onClick={onClose} className="grid h-10 w-10 place-items-center rounded-xl text-slate-500 transition-[background-color,color,transform] duration-150 [@media(hover:hover)]:hover:bg-white/70 [@media(hover:hover)]:hover:text-slate-950 active:scale-95 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-blue-600/25">
|
||||
@@ -274,7 +274,7 @@ function ScadaFeaturePopover({ feature, copied, canCopy, onCopy, onClose }: Scad
|
||||
|
||||
<div className="mt-3 grid grid-cols-[18px_1fr] gap-2 rounded-xl bg-slate-50 px-3 py-2.5 text-xs leading-5 text-slate-600 ring-1 ring-inset ring-slate-200/70">
|
||||
<MapPin size={15} className="mt-0.5 text-slate-500" aria-hidden="true" />
|
||||
<p>当前点位由管网密度聚类生成,用于空间展示,不代表设备真实安装坐标。</p>
|
||||
<p>当前点位由管网节点空间均匀采样生成,用于空间展示,不代表设备真实安装坐标。</p>
|
||||
</div>
|
||||
<div className="mt-2 flex items-center gap-2 px-1 text-xs text-slate-400">
|
||||
<Database size={13} aria-hidden="true" />
|
||||
@@ -288,8 +288,8 @@ function ScadaFeaturePopover({ feature, copied, canCopy, onCopy, onClose }: Scad
|
||||
|
||||
function getScadaPresentation(rawTypeId: unknown) {
|
||||
const typeId = Number(rawTypeId);
|
||||
if (typeId === 72) return { iconPath: SCADA_ICON_PATHS.waterQuality, headerClassName: "bg-teal-50", labelClassName: "text-teal-700" };
|
||||
if (typeId === 58) return { iconPath: SCADA_ICON_PATHS.radarLevel, headerClassName: "bg-blue-50", labelClassName: "text-blue-700" };
|
||||
if (typeId === 45) return { iconPath: SCADA_ICON_PATHS.ultrasonicFlow, headerClassName: "bg-orange-50", labelClassName: "text-orange-700" };
|
||||
return { iconPath: SCADA_ICON_PATHS.unknown, headerClassName: "bg-slate-100", labelClassName: "text-slate-700" };
|
||||
if (typeId === 72) return { iconPath: SCADA_ICON_PATHS.waterQuality, headerClassName: "glass-normal", labelClassName: "text-teal-800" };
|
||||
if (typeId === 58) return { iconPath: SCADA_ICON_PATHS.radarLevel, headerClassName: "glass-info", labelClassName: "text-blue-800" };
|
||||
if (typeId === 45) return { iconPath: SCADA_ICON_PATHS.ultrasonicFlow, headerClassName: "glass-warning", labelClassName: "text-orange-800" };
|
||||
return { iconPath: SCADA_ICON_PATHS.unknown, headerClassName: "bg-[var(--glass-readable)]", labelClassName: "text-slate-700" };
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ export function IconButton({ label, children, onClick, active = false }: IconBut
|
||||
className={`grid h-10 w-10 place-items-center rounded border transition ${
|
||||
active
|
||||
? "border-slate-800 bg-slate-900 text-white"
|
||||
: "border-white/60 bg-white/80 text-slate-700 shadow-sm hover:bg-white"
|
||||
: "border-transparent bg-[var(--glass-readable)] text-slate-700 shadow-sm hover:bg-white"
|
||||
}`}
|
||||
>
|
||||
{children}
|
||||
|
||||
@@ -49,9 +49,9 @@ import { getConditionReportRiskLevel } from "./condition-report-risk";
|
||||
|
||||
const RUNNING_WORKFLOW_TICK_MS = 1_000;
|
||||
const STATUS_PILL_CLASS_NAME = "rounded-full border px-2 py-0.5 text-xs font-semibold leading-4";
|
||||
const NEUTRAL_SURFACE_CLASS_NAME = "rounded-xl border border-slate-200/80 bg-white/95";
|
||||
const INSET_SURFACE_CLASS_NAME = "rounded-xl border border-slate-200/70 bg-slate-50/80";
|
||||
const REPORT_META_TILE_CLASS_NAME = "rounded-lg border border-slate-200/70 bg-slate-50/80 px-2 py-1.5";
|
||||
const NEUTRAL_SURFACE_CLASS_NAME = "rounded-xl border border-transparent bg-[var(--glass-readable)]";
|
||||
const INSET_SURFACE_CLASS_NAME = "rounded-xl border border-slate-200/70 bg-[var(--glass-menu)]";
|
||||
const REPORT_META_TILE_CLASS_NAME = "rounded-lg border border-slate-200/70 bg-[var(--glass-menu)] px-2 py-1.5";
|
||||
|
||||
const riskIndicatorClassNames: Record<ScheduledConditionRiskLevel, string> = {
|
||||
normal: "border-slate-200 bg-slate-50 text-slate-600",
|
||||
@@ -365,7 +365,7 @@ function DetailHeader({
|
||||
iconSpin = false
|
||||
}: DetailHeaderProps) {
|
||||
return (
|
||||
<div className="bg-white/95 px-3 py-3">
|
||||
<div className="px-3 py-3">
|
||||
<div className="grid gap-3 2xl:grid-cols-[minmax(0,1fr)_220px]">
|
||||
<div className="flex min-w-0 items-start gap-2.5">
|
||||
<span
|
||||
@@ -739,11 +739,11 @@ function KpiTile({ kpi }: { kpi: ScheduledConditionKpi }) {
|
||||
|
||||
function getKpiSurfaceClassName(riskLevel: ScheduledConditionRiskLevel) {
|
||||
if (riskLevel === "critical") {
|
||||
return "border-red-200/80 bg-red-50/80";
|
||||
return "glass-danger border-red-200/80";
|
||||
}
|
||||
|
||||
if (riskLevel === "attention") {
|
||||
return "border-orange-200/80 bg-orange-50/80";
|
||||
return "glass-warning border-orange-200/80";
|
||||
}
|
||||
|
||||
return "border-slate-200/70 bg-slate-50/80";
|
||||
@@ -842,11 +842,11 @@ function getTaskExecutionStepIconClassName(status: ExecutionStepStatus) {
|
||||
|
||||
function getTaskExecutionStepSurfaceClassName(status: ExecutionStepStatus) {
|
||||
if (status === "current") {
|
||||
return "border-blue-100 bg-blue-50/70";
|
||||
return "glass-info border-blue-100";
|
||||
}
|
||||
|
||||
if (status === "confirmation") {
|
||||
return "border-orange-100 bg-orange-50/70";
|
||||
return "glass-warning border-orange-100";
|
||||
}
|
||||
|
||||
return "border-slate-200/70 bg-slate-50/80";
|
||||
|
||||
@@ -12,7 +12,6 @@ import { AnimatePresence, motion } from "motion/react";
|
||||
import { useCallback, useEffect, useMemo, useState } from "react";
|
||||
import { cn } from "@/lib/utils";
|
||||
import {
|
||||
MAP_CONTROL_SURFACE_CLASS_NAME,
|
||||
MAP_READABLE_SURFACE_STRONG_CLASS_NAME
|
||||
} from "@/features/map/core/components/map-control-styles";
|
||||
import { showMapNotice } from "@/features/map/core/components/notice";
|
||||
@@ -242,8 +241,8 @@ export function ScheduledConditionFeed({
|
||||
className={cn(
|
||||
"scheduled-feed-panel-shell pointer-events-auto max-w-[calc(100vw-6rem)] overflow-hidden p-3 motion-reduce:transition-none",
|
||||
expanded ? "flex max-h-[calc(100dvh-8rem)] w-[880px] flex-col 2xl:w-[960px]" : "w-[432px]",
|
||||
"rounded-2xl",
|
||||
MAP_CONTROL_SURFACE_CLASS_NAME
|
||||
"rounded-2xl border",
|
||||
"glass-control"
|
||||
)}
|
||||
>
|
||||
<header className={cn("flex items-center gap-2.5 px-2.5 py-2", "rounded-xl", MAP_READABLE_SURFACE_STRONG_CLASS_NAME)}>
|
||||
@@ -368,7 +367,9 @@ function ConditionTimelinePanel({
|
||||
"flex min-h-0 flex-col overflow-hidden p-2.5",
|
||||
expanded ? "h-[calc(100dvh-14rem)] max-h-[calc(100dvh-14rem)]" : "h-[420px] max-h-[420px]",
|
||||
"rounded-xl",
|
||||
MAP_READABLE_SURFACE_STRONG_CLASS_NAME
|
||||
expanded
|
||||
? "border border-white/30 bg-white/10"
|
||||
: MAP_READABLE_SURFACE_STRONG_CLASS_NAME
|
||||
)}
|
||||
>
|
||||
{expanded && !loading ? (
|
||||
@@ -534,7 +535,7 @@ function ConditionFilterDropdown<TValue extends string>({
|
||||
<DropdownMenuContent
|
||||
align="start"
|
||||
sideOffset={6}
|
||||
className="scheduled-feed-scroll z-50 max-h-[280px] w-[var(--radix-dropdown-menu-trigger-width)] overflow-y-auto rounded-xl border border-white/80 bg-white p-1.5 text-slate-700 shadow-xl shadow-slate-900/15 backdrop-blur-xl"
|
||||
className="glass-menu scheduled-feed-scroll z-50 max-h-[280px] w-[var(--radix-dropdown-menu-trigger-width)] overflow-y-auto rounded-xl border p-1.5 text-slate-700"
|
||||
>
|
||||
<DropdownMenuRadioGroup value={value} onValueChange={(nextValue) => onValueChange(nextValue as TValue)}>
|
||||
{options.map((option) => (
|
||||
@@ -561,7 +562,7 @@ function ConditionFilterDropdown<TValue extends string>({
|
||||
|
||||
function ConditionEmptyState({ title, description }: { title: string; description: string }) {
|
||||
return (
|
||||
<div className="flex min-h-full flex-col items-center justify-center rounded-xl border border-dashed border-slate-200 bg-white/65 px-4 py-5 text-center">
|
||||
<div className="flex min-h-full flex-col items-center justify-center rounded-xl border border-dashed border-slate-200 bg-[var(--glass-readable)] px-4 py-5 text-center">
|
||||
<span className="grid h-8 w-8 place-items-center rounded-lg bg-slate-100 text-slate-400">
|
||||
<ChevronRight size={15} aria-hidden="true" />
|
||||
</span>
|
||||
@@ -586,7 +587,7 @@ function ConditionTimelineSkeleton({ rows }: { rows: number }) {
|
||||
) : null}
|
||||
<span className="relative z-10 h-6 w-6 animate-pulse rounded-full bg-slate-200 ring-4 ring-white" />
|
||||
</span>
|
||||
<span className="min-w-0 rounded-xl border border-white/80 bg-white/95 px-2 py-1.5">
|
||||
<span className="min-w-0 rounded-xl border border-transparent bg-[var(--glass-menu)] px-2 py-1.5">
|
||||
<span className="flex min-w-0 items-center gap-2">
|
||||
<span className="min-w-0 flex-1 space-y-1.5">
|
||||
<span className="block h-3.5 w-24 animate-pulse rounded-full bg-slate-200/90" />
|
||||
@@ -606,7 +607,7 @@ function ConditionDetailSkeleton() {
|
||||
<DetailScroll>
|
||||
<div
|
||||
className={cn(
|
||||
"relative min-h-[420px] overflow-hidden border border-slate-200/80 bg-white/95 px-4 py-3",
|
||||
"relative min-h-[420px] overflow-hidden border border-slate-200/80 bg-[var(--glass-menu)] px-4 py-3",
|
||||
"rounded-xl"
|
||||
)}
|
||||
role="status"
|
||||
@@ -737,7 +738,7 @@ function ConditionTimelineRow({ condition, selected, isLast, onSelect }: Conditi
|
||||
"min-w-0 rounded-xl border px-2 py-1.5 transition-colors group-focus-visible:border-blue-300 group-focus-visible:bg-white",
|
||||
selected
|
||||
? "border-blue-300 bg-white text-blue-900 shadow-sm shadow-blue-600/10 ring-1 ring-blue-300/40"
|
||||
: "border-white/80 bg-white/95 text-slate-700 group-hover:border-blue-100 group-hover:bg-white"
|
||||
: "border-transparent bg-[var(--glass-menu)] text-slate-700 group-hover:border-blue-100 group-hover:bg-white"
|
||||
)}
|
||||
>
|
||||
<span className="flex min-w-0 items-center gap-2">
|
||||
|
||||
@@ -46,10 +46,10 @@ const scenarioStatusLabels: Record<WorkbenchScenario["status"], string> = {
|
||||
|
||||
const menuSurfaceClassName = cn(
|
||||
MAP_MAJOR_PANEL_RADIUS_CLASS_NAME,
|
||||
"border border-white/80 bg-white/95 p-2 text-slate-900 shadow-xl shadow-slate-900/10 ring-1 ring-slate-900/5 backdrop-blur-xl"
|
||||
"glass-menu border p-2 text-slate-900"
|
||||
);
|
||||
const menuReadableRowClassName =
|
||||
"bg-white/80 focus:bg-blue-50/95 focus:text-slate-950";
|
||||
"bg-[var(--glass-readable)] focus:bg-blue-50/95 focus:text-slate-950";
|
||||
const headerControlButtonClassName =
|
||||
"inline-flex h-8 items-center gap-2 rounded-full border border-transparent bg-transparent text-sm font-semibold text-slate-700 transition-colors hover:bg-white/70 hover:text-blue-700 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-blue-600/20 focus-visible:ring-offset-2 data-[state=open]:bg-white/90 data-[state=open]:text-blue-700";
|
||||
const headerControlIconClassName =
|
||||
@@ -220,7 +220,7 @@ export function AlertMenu({
|
||||
</span>
|
||||
</DropdownMenuItem>
|
||||
)) : (
|
||||
<div className={cn("my-1 grid min-h-[76px] place-items-center border border-dashed border-slate-200 bg-white/70 px-3 py-3 text-center", MAP_COMPACT_RADIUS_CLASS_NAME)}>
|
||||
<div className={cn("my-1 grid min-h-[76px] place-items-center border border-dashed border-slate-200 bg-[var(--glass-readable)] px-3 py-3 text-center", MAP_COMPACT_RADIUS_CLASS_NAME)}>
|
||||
<div className="min-w-0">
|
||||
<CheckCircle2 size={18} className="mx-auto text-emerald-600" aria-hidden="true" />
|
||||
<p className="mt-1 text-xs font-semibold text-slate-700">当前无待复核工况</p>
|
||||
@@ -315,7 +315,7 @@ function AlertQueueSummary({
|
||||
const hasAlerts = count > 0;
|
||||
|
||||
return (
|
||||
<div className={cn("overflow-hidden bg-white/90 px-3 py-3 ring-1 ring-white/80", MAP_READABLE_RADIUS_CLASS_NAME)}>
|
||||
<div className={cn("overflow-hidden bg-[var(--glass-menu)] px-3 py-3 ring-1 ring-white/80", MAP_READABLE_RADIUS_CLASS_NAME)}>
|
||||
<div className="flex items-start justify-between gap-3">
|
||||
<div className="flex min-w-0 items-start gap-2.5">
|
||||
<span
|
||||
@@ -423,7 +423,7 @@ function MenuHeader({
|
||||
icon?: LucideIcon;
|
||||
}) {
|
||||
return (
|
||||
<div className={cn("flex items-center justify-between gap-3 border border-white/70 bg-white/90 px-2 py-2", MAP_READABLE_RADIUS_CLASS_NAME)}>
|
||||
<div className={cn("flex items-center justify-between gap-3 border border-transparent bg-[var(--glass-menu)] px-2 py-2", MAP_READABLE_RADIUS_CLASS_NAME)}>
|
||||
<div className="min-w-0">
|
||||
<div className="flex min-w-0 items-center gap-1.5">
|
||||
{Icon ? <Icon size={13} className="shrink-0 text-slate-500" aria-hidden="true" /> : null}
|
||||
|
||||
@@ -78,7 +78,7 @@ export function WorkbenchTopBar({
|
||||
};
|
||||
|
||||
return (
|
||||
<header className="pointer-events-auto absolute left-0 right-0 top-0 z-30 flex h-14 select-none items-center justify-between border-b border-white/65 bg-white/80 px-3 shadow-lg shadow-slate-900/5 backdrop-blur-2xl sm:px-4 md:px-5">
|
||||
<header className="glass-navigation pointer-events-auto absolute left-0 right-0 top-0 z-30 flex h-14 select-none items-center justify-between border-b px-3 sm:px-4 md:px-5">
|
||||
<div className="flex min-w-0 items-center gap-2.5">
|
||||
<div className={cn("grid h-8 w-8 shrink-0 place-items-center bg-blue-600 text-white shadow-lg shadow-blue-600/20", MAP_ICON_CELL_RADIUS_CLASS_NAME)}>
|
||||
<Droplets size={18} aria-hidden="true" />
|
||||
|
||||
Reference in New Issue
Block a user