| import React, { useRef } from 'react'; |
| import { useDrag, useDrop } from 'react-dnd'; |
| import type { TConversationTag } from 'librechat-data-provider'; |
| import { TableRow, TableCell, useToastContext } from '@librechat/client'; |
| import { DeleteBookmarkButton, EditBookmarkButton } from '~/components/Bookmarks'; |
| import { useConversationTagMutation } from '~/data-provider'; |
| import { NotificationSeverity } from '~/common'; |
| import { useLocalize } from '~/hooks'; |
|
|
| interface BookmarkTableRowProps { |
| row: TConversationTag; |
| moveRow: (dragIndex: number, hoverIndex: number) => void; |
| position: number; |
| } |
|
|
| interface DragItem { |
| index: number; |
| id: string; |
| type: string; |
| } |
|
|
| const BookmarkTableRow: React.FC<BookmarkTableRowProps> = ({ row, moveRow, position }) => { |
| const ref = useRef<HTMLTableRowElement>(null); |
| const mutation = useConversationTagMutation({ context: 'BookmarkTableRow', tag: row.tag }); |
| const localize = useLocalize(); |
| const { showToast } = useToastContext(); |
|
|
| const handleDrop = (item: DragItem) => { |
| mutation.mutate( |
| { ...row, position: item.index }, |
| { |
| onSuccess: () => { |
| showToast({ |
| message: localize('com_ui_bookmarks_update_success'), |
| severity: NotificationSeverity.SUCCESS, |
| }); |
| }, |
| onError: () => { |
| showToast({ |
| message: localize('com_ui_bookmarks_update_error'), |
| severity: NotificationSeverity.ERROR, |
| }); |
| }, |
| }, |
| ); |
| }; |
|
|
| const [, drop] = useDrop({ |
| accept: 'bookmark', |
| drop: handleDrop, |
| hover(item: DragItem) { |
| if (!ref.current || item.index === position) { |
| return; |
| } |
| moveRow(item.index, position); |
| item.index = position; |
| }, |
| }); |
|
|
| const [{ isDragging }, drag] = useDrag({ |
| type: 'bookmark', |
| item: { index: position }, |
| collect: (monitor) => ({ |
| isDragging: monitor.isDragging(), |
| }), |
| }); |
|
|
| drag(drop(ref)); |
|
|
| return ( |
| <TableRow |
| ref={ref} |
| className="cursor-move hover:bg-surface-secondary" |
| style={{ opacity: isDragging ? 0.5 : 1 }} |
| > |
| <TableCell className="w-[70%] px-4 py-4"> |
| <div className="overflow-hidden text-ellipsis whitespace-nowrap">{row.tag}</div> |
| </TableCell> |
| <TableCell className="w-[10%] px-12 py-4">{row.count}</TableCell> |
| <TableCell className="w-[20%] px-4 py-4"> |
| <div className="flex gap-2"> |
| <EditBookmarkButton bookmark={row} tabIndex={0} /> |
| <DeleteBookmarkButton bookmark={row.tag} tabIndex={0} /> |
| </div> |
| </TableCell> |
| </TableRow> |
| ); |
| }; |
|
|
| export default BookmarkTableRow; |
|
|