import { Crosshair, LocateFixed, MousePointer2, Trash2, ZoomIn } from "lucide-react"; import { useId, useState } from "react"; import { Button } from "@/shared/ui/button"; import { FieldSelect } from "@/shared/ui/field-select"; import { Textarea } from "@/shared/ui/textarea"; import { MAX_MAP_FEATURE_IDS, MAX_MAP_FEATURE_ID_LENGTH } from "../map/map-feature-query"; import { AVAILABLE_WATER_NETWORK_SOURCE_IDS, SUPPLY_LAYER_CATALOG, type AvailableWaterNetworkSourceId } from "../map/sources"; import type { FeatureBatchTarget, WorkbenchMapCommands, WorkbenchMapControllerState } from "../map/workbench-map-controller"; import type { DetailFeature } from "../types"; import { FEATURE_LOCATION_ERROR_LABELS } from "../map/map-feature-feedback"; type FeatureLocationDraft = { sourceId: AvailableWaterNetworkSourceId; featureId: string; }; export type FeatureLocationPanelProps = { commands: Pick; controllerState: Pick; detailFeature: DetailFeature | null; enabled?: boolean; value?: FeatureLocationDraft; onValueChange?: (value: FeatureLocationDraft) => void; onUseSelectedFeature?: () => void; showError?: boolean; contentClassName?: string; }; export function FeatureLocationPanel({ commands, controllerState, detailFeature, enabled = true, value, onValueChange, onUseSelectedFeature, showError = true, contentClassName }: FeatureLocationPanelProps) { const inputId = useId(); const helpId = useId(); const [draft, setDraft] = useState({ sourceId: "pipes", featureId: "" }); const { sourceId, featureId } = value ?? draft; function updateDraft(next: FeatureLocationDraft) { if (!value) setDraft(next); onValueChange?.(next); } const featureIds = [...new Set(featureId.split(/[\s,,;;、]+/u).filter(Boolean))]; const invalidIds = featureIds.length > MAX_MAP_FEATURE_IDS || featureIds.some((id) => id.length > MAX_MAP_FEATURE_ID_LENGTH); const canLocate = enabled && featureIds.length > 0 && !invalidIds && !controllerState.pending; const canUseSelected = Boolean(detailFeature && AVAILABLE_WATER_NETWORK_SOURCE_IDS.includes(detailFeature.layer as AvailableWaterNetworkSourceId)); const target: FeatureBatchTarget = { sourceId, featureIds }; const result = controllerState.targetResult; return (
updateDraft({ sourceId: nextSourceId as AvailableWaterNetworkSourceId, featureId: "" })} options={SUPPLY_LAYER_CATALOG.filter((layer) => layer.available).map((layer) => ({ value: layer.id, label: layer.label }))} />
{featureIds.length} / {MAX_MAP_FEATURE_IDS}