2024-07-29 19:25:36 -04:00
|
|
|
import React, { useState } from 'react';
|
2024-07-29 07:45:59 -07:00
|
|
|
import { useDrag, useDrop } from 'react-dnd';
|
|
|
|
|
import type { TConversationTag } from 'librechat-data-provider';
|
|
|
|
|
import { DeleteBookmarkButton, EditBookmarkButton } from '~/components/Bookmarks';
|
2024-07-29 19:25:36 -04:00
|
|
|
import { TableRow, TableCell } from '~/components/ui';
|
2024-07-29 07:45:59 -07:00
|
|
|
|
2024-07-29 19:25:36 -04:00
|
|
|
interface BookmarkTableRowProps {
|
2024-07-29 07:45:59 -07:00
|
|
|
row: TConversationTag;
|
2024-07-29 19:25:36 -04:00
|
|
|
moveRow: (dragIndex: number, hoverIndex: number) => void;
|
|
|
|
|
position: number;
|
2024-07-29 07:45:59 -07:00
|
|
|
}
|
|
|
|
|
|
2024-07-29 19:25:36 -04:00
|
|
|
const BookmarkTableRow: React.FC<BookmarkTableRowProps> = ({ row, moveRow, position }) => {
|
|
|
|
|
const [isHovered, setIsHovered] = useState(false);
|
|
|
|
|
const ref = React.useRef<HTMLTableRowElement>(null);
|
2024-07-29 07:45:59 -07:00
|
|
|
|
2024-07-29 19:25:36 -04:00
|
|
|
const [, drop] = useDrop({
|
|
|
|
|
accept: 'bookmark',
|
|
|
|
|
hover(item: { index: number }) {
|
2024-07-29 07:45:59 -07:00
|
|
|
if (!ref.current) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
const dragIndex = item.index;
|
|
|
|
|
const hoverIndex = position;
|
|
|
|
|
if (dragIndex === hoverIndex) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
moveRow(dragIndex, hoverIndex);
|
|
|
|
|
item.index = hoverIndex;
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const [{ isDragging }, drag] = useDrag({
|
2024-07-29 19:25:36 -04:00
|
|
|
type: 'bookmark',
|
|
|
|
|
item: { index: position },
|
2024-07-29 07:45:59 -07:00
|
|
|
collect: (monitor) => ({
|
|
|
|
|
isDragging: monitor.isDragging(),
|
|
|
|
|
}),
|
|
|
|
|
});
|
|
|
|
|
|
2024-07-29 19:25:36 -04:00
|
|
|
drag(drop(ref));
|
2024-07-29 07:45:59 -07:00
|
|
|
|
|
|
|
|
return (
|
2024-07-29 19:25:36 -04:00
|
|
|
<TableRow
|
2024-07-29 07:45:59 -07:00
|
|
|
ref={ref}
|
2024-07-29 19:25:36 -04:00
|
|
|
className="cursor-move hover:bg-gray-100 dark:hover:bg-gray-800"
|
|
|
|
|
style={{ opacity: isDragging ? 0.5 : 1 }}
|
|
|
|
|
onMouseEnter={() => setIsHovered(true)}
|
|
|
|
|
onMouseLeave={() => setIsHovered(false)}
|
2024-07-29 07:45:59 -07:00
|
|
|
>
|
2024-07-29 19:25:36 -04:00
|
|
|
<TableCell className="w-full px-3 py-3.5 pl-6">
|
|
|
|
|
<div className="truncate">{row.tag}</div>
|
|
|
|
|
</TableCell>
|
|
|
|
|
<TableCell className="w-full px-3 py-3.5 sm:pl-6">
|
|
|
|
|
<div className="flex items-center justify-between py-1">
|
|
|
|
|
<div>{row.count}</div>
|
|
|
|
|
<div
|
|
|
|
|
className="flex items-center gap-2"
|
|
|
|
|
style={{
|
|
|
|
|
opacity: isHovered ? 1 : 0,
|
|
|
|
|
transition: 'opacity 0.1s ease-in-out',
|
|
|
|
|
}}
|
|
|
|
|
onFocus={() => setIsHovered(true)}
|
|
|
|
|
onBlur={() => setIsHovered(false)}
|
|
|
|
|
>
|
|
|
|
|
<EditBookmarkButton
|
|
|
|
|
bookmark={row}
|
|
|
|
|
tabIndex={0}
|
|
|
|
|
onFocus={() => setIsHovered(true)}
|
|
|
|
|
onBlur={() => setIsHovered(false)}
|
|
|
|
|
/>
|
|
|
|
|
<DeleteBookmarkButton
|
|
|
|
|
bookmark={row.tag}
|
|
|
|
|
tabIndex={0}
|
|
|
|
|
onFocus={() => setIsHovered(true)}
|
|
|
|
|
onBlur={() => setIsHovered(false)}
|
|
|
|
|
/>
|
2024-07-29 07:45:59 -07:00
|
|
|
</div>
|
2024-07-29 19:25:36 -04:00
|
|
|
</div>
|
|
|
|
|
</TableCell>
|
|
|
|
|
</TableRow>
|
2024-07-29 07:45:59 -07:00
|
|
|
);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export default BookmarkTableRow;
|