import { useEffect, useRef } from "react"; import { MappingModeSelector } from "./components/MappingModeSelector"; import { CustomMappingEditor } from "./components/CustomMappingEditor"; import { MappingPreviewPanel } from "./components/MappingPreviewPanel"; import { DatasetSchemaHoverCard } from "@/src/features/datasets/components/DatasetSchemaHoverCard"; import { extractSchemaFields, isObjectSchema, generateEntriesFromSchema, } from "./utils/extractSchemaFields"; import type { MappingStepProps, MappingMode, CustomMappingConfig, } from "./types"; export function MappingStep({ field, fieldLabel, defaultSourceField, config, onConfigChange, observationData, isLoading, schema, onValidationChange, }: MappingStepProps) { const hasSchema = schema !== null && schema !== undefined; const isObjectType = hasSchema && isObjectSchema(schema); const hasInitializedRef = useRef(false); // Auto-initialize to custom key-value mode with schema-derived entries when: // 1. Schema exists and is an object type // 2. Config hasn't been manually set yet (mode is "full" which is the default) // 3. We haven't already initialized useEffect(() => { if ( isObjectType && config.mode === "full" && !hasInitializedRef.current && !config.custom?.keyValueMapConfig // Don't override if already has key-value config ) { hasInitializedRef.current = true; const schemaFields = extractSchemaFields(schema); if (schemaFields.length > 0) { const entries = generateEntriesFromSchema( schemaFields, defaultSourceField, ); onConfigChange({ mode: "custom", custom: { type: "keyValueMap", keyValueMapConfig: { entries, }, }, }); } } }, [ isObjectType, schema, config.mode, config.custom, defaultSourceField, onConfigChange, ]); // Get the full label for the "Full" option const getFullLabel = () => { switch (field) { case "input": return "Full observation input"; case "expectedOutput": return "Full observation output"; case "metadata": return "Full observation metadata"; default: return `Full observation ${field}`; } }; const handleModeChange = (mode: MappingMode) => { if (mode === "custom") { // Initialize custom config if switching to custom onConfigChange({ mode: "custom", custom: config.custom ?? { type: "root", rootConfig: { sourceField: defaultSourceField, jsonPath: "$", }, }, }); } else { onConfigChange({ mode, custom: config.custom, // Preserve custom config in case they switch back }); } }; const handleCustomConfigChange = (customConfig: CustomMappingConfig) => { onConfigChange({ ...config, custom: customConfig, }); }; return (
{/* Left: Configuration */}

Dataset Item {fieldLabel}

{hasSchema && ( )}

Configure how observation data maps to the Dataset Item {fieldLabel} .

{config.mode === "custom" && config.custom && ( )}
{/* Right: Preview */}
); }