"use client"; import { flexRender, getCoreRowModel, useReactTable, } from "@tanstack/react-table"; import { Check, ChevronRight, ChevronsUpDown, Plus } from "lucide-react"; import { useState } from "react"; import { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator, } from "@/components/ui/command"; import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, DialogTrigger, } from "@/components/ui/dialog"; import { Popover, PopoverContent, PopoverTrigger, } from "@/components/ui/popover"; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow, } from "@/components/ui/table"; import { cn } from "@/lib/utils"; interface InputData { firstName: string; lastName: string; email: string; mobile: string; country: string; city: string; } const SOURCE_FIELD_LABELS: Record = { firstName: "نام", lastName: "نام خانوادگی", email: "ایمیل", mobile: "موبایل", country: "کشور", city: "شهر", }; const DUMMY_INPUT_DATA: InputData[] = [ { firstName: "علی", lastName: "محمدی", email: "ali.mohammadi@acme.co", mobile: "5551234567", country: "آلمان", city: "برلین", }, { firstName: "سارا", lastName: "احمدی", email: "sara.ahmadi@acme.co", mobile: "5559876543", country: "ژاپن", city: "توکیو", }, { firstName: "رضا", lastName: "کریمی", email: "reza.karimi@acme.co", mobile: "5552468135", country: "برزیل", city: "سائوپائولو", }, { firstName: "مینا", lastName: "حسینی", email: "mina.hosseini@acme.co", mobile: "5551357924", country: "فرانسه", city: "پاریس", }, { firstName: "امیر", lastName: "رضایی", email: "amir.rezaei@acme.co", mobile: "5558642097", country: "اسپانیا", city: "بارسلونا", }, ]; interface Column { header: string; accessorKey: string; } const DEFAULT_COLUMNS: Column[] = [ { header: "نام", accessorKey: "firstName", }, { header: "نام خانوادگی", accessorKey: "lastName", }, { header: "ایمیل", accessorKey: "email", }, { header: "تلفن", accessorKey: "phone", }, { header: "کشور", accessorKey: "country", }, ]; interface FieldComboboxProps { columns: Column[]; value: string; onValueChange: (value: string) => void; onCreateField: (fieldName: string) => void; onFocus: () => void; } const FieldCombobox = ({ columns, value, onValueChange, onCreateField, onFocus, }: FieldComboboxProps) => { const [open, setOpen] = useState(false); const [search, setSearch] = useState(""); const handleCreate = () => { if ( search && !columns.find((col) => col.header.toLowerCase() === search.toLowerCase()) ) { onCreateField(search); onValueChange(search.toLowerCase().replace(/\s+/g, "")); setOpen(false); setSearch(""); } }; const selectedColumn = columns.find((col) => col.accessorKey === value); return ( {columns.map((column) => ( { onValueChange(currentValue === value ? "" : currentValue); setOpen(false); }} > {column.header} ))} {search && !columns.find( (col) => col.header.toLowerCase() === search.toLowerCase(), ) && ( <> افزودن «{search}» )} ); }; interface DataPreviewListProps { currentFocusedField: string | null; } const DataPreviewList = ({ currentFocusedField }: DataPreviewListProps) => { if (!currentFocusedField) return null; return (

نمونه مقادیر برای{" "} {SOURCE_FIELD_LABELS[currentFocusedField as keyof InputData] ?? currentFocusedField}

); }; interface FieldMapping1Props { className?: string; } const FieldMapping1 = ({ className }: FieldMapping1Props) => { const [data, setData] = useState[]>([]); const [columns, setColumns] = useState(DEFAULT_COLUMNS); const [open, setOpen] = useState(false); const [currentFocusedField, setCurrentFocusedField] = useState( null, ); const [mappings, setMappings] = useState>({}); const handleCreateField = (fieldName: string) => { const accessorKey = fieldName.toLowerCase().replace(/\s+/g, ""); if (!columns.find((col) => col.accessorKey === accessorKey)) { setColumns([...columns, { header: fieldName, accessorKey }]); } }; const handleMappingChange = (incomingField: string, destField: string) => { setMappings((prev) => ({ ...prev, [incomingField]: destField, })); }; const handleSave = () => { const transformedData = DUMMY_INPUT_DATA.map((item) => { const newRow: Record = {}; Object.entries(mappings).forEach(([incomingField, destField]) => { if (destField) { newRow[destField] = item[incomingField as keyof InputData]; } }); return newRow; }); setData(transformedData); setOpen(false); }; const table = useReactTable({ data, columns, getCoreRowModel: getCoreRowModel(), }); return (
{table.getHeaderGroups().map((headerGroup) => ( {headerGroup.headers.map((header) => { return ( {flexRender( header.column.columnDef.header, header.getContext(), )} ); })} ))} {table.getRowModel().rows.length === 0 ? Array.from({ length: 10 }).map((_, i) => ( {columns.map((column) => ( ))} )) : table.getRowModel().rows.map((row) => ( {row.getVisibleCells().map((cell) => ( {flexRender( cell.column.columnDef.cell, cell.getContext(), )} ))} ))}
{data.length === 0 && (

فایل را اینجا رها کنید یا برای شروع مرور کنید

پیکربندی نگاشت فیلد ستون‌های داده را با فیلدهای مقصد تطبیق دهید

پیکربندی نگاشت

ستون‌های مبدأ را با فیلدهای مقصد تطبیق دهید

ستون‌های مبدأ

فیلدهای مقصد

    {Object.keys(DUMMY_INPUT_DATA[0]).map((key) => { return (
  • { SOURCE_FIELD_LABELS[ key as keyof InputData ] }
    handleMappingChange(key, value) } onCreateField={handleCreateField} onFocus={() => setCurrentFocusedField(key)} />
  • ); })}
)}
); }; export { FieldMapping1 };