import { Button } from '@/components/ui/button'; import { Checkbox } from '@/components/ui/checkbox'; import { Input } from '@/components/ui/input'; import { ColumnDef, Row, Table } from '@tanstack/react-table'; import { ListChevronsDownUp, ListChevronsUpDown, Settings, Trash2, } from 'lucide-react'; import { useCallback, useMemo, useState } from 'react'; import { useTranslation } from 'react-i18next'; import { getMetadataValueTypeLabel, MetadataDeleteMap, MetadataType, } from './constant'; import { IMetaDataTableData } from './interface'; interface IUseMetadataColumns { isDeleteSingleValue: boolean; metadataType: MetadataType; handleDeleteSingleValue: (field: string, value: string) => void; handleDeleteSingleRow: (field: string) => void; handleEditValueRow: (data: IMetaDataTableData, index: number) => void; showTypeColumn: boolean; isShowDescription: boolean; setTableData: React.Dispatch>; setShouldSave: React.Dispatch>; } export const useMetadataColumns = ({ isDeleteSingleValue, metadataType, handleDeleteSingleValue, handleDeleteSingleRow, handleEditValueRow, isShowDescription, setTableData, setShouldSave, }: IUseMetadataColumns) => { const { t } = useTranslation(); const [deleteDialogContent, setDeleteDialogContent] = useState({ visible: false, title: '', name: '', warnText: '', onOk: () => {}, onCancel: () => {}, }); const [expanded, setExpanded] = useState(true); const [editingValue, setEditingValue] = useState<{ field: string; value: string; newValue: string; } | null>(null); const isSettingsMode = metadataType === MetadataType.Setting || metadataType === MetadataType.SingleFileSetting || metadataType === MetadataType.UpdateSingle; const showTypeColumn = isSettingsMode; const handleEditValue = (field: string, value: string) => { setEditingValue({ field, value, newValue: value }); }; const saveEditedValue = useCallback(() => { if (editingValue) { setTableData((prev) => { return prev.map((row) => { if (row.field === editingValue.field) { const updatedValues = row.values.map((v) => v === editingValue.value ? editingValue.newValue : v, ); return { ...row, values: updatedValues }; } return row; }); }); setEditingValue(null); setShouldSave(true); } }, [editingValue, setTableData]); const cancelEditValue = () => { setEditingValue(null); }; const hideDeleteModal = () => { setDeleteDialogContent({ visible: false, title: '', name: '', warnText: '', onOk: () => {}, onCancel: () => {}, }); }; const columns = useMemo(() => { const cols: ColumnDef[] = [ ...(MetadataType.Manage === metadataType || MetadataType.UpdateSingle === metadataType ? [ { id: 'select', header: ({ table }: { table: Table }) => ( table.toggleAllPageRowsSelected(!!value) } aria-label="Select all" /> ), cell: ({ row }: { row: Row }) => ( row.toggleSelected(!!value)} aria-label="Select row" /> ), enableSorting: false, enableHiding: false, }, ] : []), { accessorKey: 'field', header: () => {t('knowledgeDetails.metadata.field')}, cell: ({ row }) => (
{row.getValue('field')}
), }, // ...(showTypeColumn // ? ([ // { // accessorKey: 'valueType', // header: () => Type, // cell: ({ row }) => ( //
// {getMetadataValueTypeLabel( // row.original.valueType as IMetaDataTableData['valueType'], // )} //
// ), // }, // ] as ColumnDef[]) // : []), { accessorKey: 'description', header: () => {t('knowledgeDetails.metadata.description')}, cell: ({ row }) => (
{row.getValue('description')}
), }, { accessorKey: 'valueType', header: () => {t('knowledgeDetails.metadata.type')}, cell: ({ row }) => (
{getMetadataValueTypeLabel( row.original.valueType as IMetaDataTableData['valueType'], )}
), }, { accessorKey: 'values', header: () => (
{t('knowledgeDetails.metadata.values')}
{ setExpanded(!expanded); }} > {expanded ? ( ) : ( )} {expanded}
), cell: ({ row }) => { const values = row.getValue('values') as Array; // const supportsEnum = isMetadataValueTypeWithEnum( // row.original.valueType, // ); // if (!supportsEnum || !Array.isArray(values) || values.length === 0) { // return
; // } const displayedValues = expanded ? values : values.slice(0, 2); const hasMore = Array.isArray(values) && values.length > 2; return (
{displayedValues?.map((value: string) => { const isEditing = editingValue && editingValue.field === row.getValue('field') && editingValue.value === value; return isEditing ? (
setEditingValue({ ...editingValue, newValue: e.target.value, }) } onBlur={saveEditedValue} onKeyDown={(e) => { if (e.key === 'Enter') { saveEditedValue(); } else if (e.key === 'Escape') { cancelEditValue(); } }} autoFocus // className="text-sm min-w-20 max-w-32 outline-none bg-transparent px-1 py-0.5" />
) : ( )}
); })} {hasMore && !expanded && (
...
)}
); }, }, { accessorKey: 'action', header: () => {t('knowledgeDetails.metadata.action')}, meta: { cellClassName: 'w-12', }, cell: ({ row }) => (
), }, ]; if (!isShowDescription) { return cols.filter((col) => { if ('accessorKey' in col && col.accessorKey === 'description') { return false; } return true; }); } return cols; }, [ handleDeleteSingleRow, t, handleDeleteSingleValue, isShowDescription, isDeleteSingleValue, handleEditValueRow, metadataType, expanded, editingValue, saveEditedValue, showTypeColumn, ]); return { columns, deleteDialogContent, }; };