| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354 |
- "use client";
- import { AlertTriangle, Ban, Calculator, CheckCircle2, CircleHelp, Eye, History, PackageCheck } from "lucide-react";
- import type { SourceBinding } from "@/lib/types";
- interface Props {
- binding: SourceBinding;
- marker: string;
- active: boolean;
- onActivate: (bindingId: string, toggle?: boolean) => void;
- compact?: boolean;
- }
- export function BindingBadge({ binding, marker, active, onActivate, compact = false }: Props) {
- const evidence = evidencePresentation(binding);
- const Icon = evidence.icon;
- return <button
- type="button"
- className={`bindingBadge is-${evidence.tone} ${active ? "is-active" : ""} ${compact ? "is-compact" : ""}`}
- data-binding-id={binding.id}
- aria-pressed={active}
- title={selectorDescription(binding)}
- onClick={() => onActivate(binding.id, false)}
- onFocus={() => onActivate(binding.id, false)}
- >
- <span className="bindingMarker">{marker}</span>
- <Icon aria-hidden="true" size={13} />
- {!compact ? <span>{evidence.label}</span> : null}
- </button>;
- }
- export function evidencePresentation(binding: SourceBinding) {
- if (binding.resolution === "unsafe") return { label: "无法安全关联", tone: "unsafe", icon: CircleHelp };
- if (binding.resolution === "partial" || (binding.selector.kind === "unresolved" && binding.resolution !== "missing")) return { label: "部分可定位", tone: "partial", icon: AlertTriangle };
- if (binding.resolution === "missing") return { label: "记录缺失", tone: "missing", icon: AlertTriangle };
- if (binding.transform.kind === "fallback") return { label: "历史回退", tone: "fallback", icon: History };
- if (binding.evidence.adoption === "explicitly-adopted") return { label: "明确采用", tone: "adopted", icon: CheckCircle2 };
- if (binding.evidence.adoption === "explicitly-rejected") return { label: "明确未采用", tone: "rejected", icon: Ban };
- if (binding.evidence.availability === "direct-read") return { label: "已读取,是否采用未记录", tone: "read", icon: Eye };
- if (binding.evidence.availability === "returned-to-agent") return { label: "已返回给 Agent,是否采用未记录", tone: "read", icon: PackageCheck };
- if (binding.evidence.availability === "available-upstream") return { label: "当时可获得,是否读取和采用未记录", tone: "available", icon: CircleHelp };
- if (binding.evidence.availability === "produced-by-run") return { label: "运行产出", tone: "produced", icon: PackageCheck };
- if (binding.evidence.availability === "visualization-derived") return { label: "可视化计算", tone: "calculated", icon: Calculator };
- return { label: "是否采用未记录", tone: "unknown", icon: CircleHelp };
- }
- export function selectorDescription(binding: SourceBinding) {
- const selector = binding.selector;
- if (selector.kind === "json-pointer") return selector.path;
- if (selector.kind === "text-span") return `${selector.path} · 字符 ${selector.startCodePoint}–${selector.endCodePoint}`;
- if (selector.kind === "members") return `${selector.members.length} 项聚合 · ${selector.reducer}`;
- if (selector.kind === "whole-record") return "完整记录";
- return selector.reason;
- }
|