2024-08-08 21:25:10 -04:00
|
|
|
import React, { useState, useRef } 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-08-08 21:25:10 -04:00
|
|
|
import { useConversationTagMutation } from '~/data-provider';
|
2024-07-29 19:25:36 -04:00
|
|
|
import { TableRow, TableCell } from '~/components/ui';
|
2024-08-08 21:25:10 -04:00
|
|
|
import { NotificationSeverity } from '~/common';
|
|
|
|
|
import { useToastContext } from '~/Providers';
|
|
|
|
|
import { useLocalize } from '~/hooks';
|
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-08-08 21:25:10 -04:00
|
|
|
interface DragItem {
|
|
|
|
|
index: number;
|
|
|
|
|
id: string;
|
|
|
|
|
type: string;
|
|
|
|
|
}
|
|
|
|
|
|
2024-07-29 19:25:36 -04:00
|
|
|
const BookmarkTableRow: React.FC<BookmarkTableRowProps> = ({ row, moveRow, position }) => {
|
|
|
|
|
const [isHovered, setIsHovered] = useState(false);
|
2024-08-08 21:25:10 -04:00
|
|
|
const ref = useRef<HTMLTableRowElement>(null);
|
|
|
|
|
|
2024-08-22 17:09:05 -04:00
|
|
|
const mutation = useConversationTagMutation({ context: 'BookmarkTableRow', tag: row.tag });
|
2024-08-08 21:25:10 -04:00
|
|
|
const localize = useLocalize();
|
|
|
|
|
const { showToast } = useToastContext();
|
|
|
|
|
|
|
|
|
|
const handleDrop = (item: DragItem) => {
|
|
|
|
|
const data = {
|
|
|
|
|
...row,
|
|
|
|
|
position: item.index,
|
|
|
|
|
};
|
|
|
|
|
mutation.mutate(data, {
|
|
|
|
|
onError: () => {
|
|
|
|
|
showToast({
|
|
|
|
|
message: localize('com_ui_bookmarks_update_error'),
|
|
|
|
|
severity: NotificationSeverity.ERROR,
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
};
|
2024-07-29 07:45:59 -07:00
|
|
|
|
2024-07-29 19:25:36 -04:00
|
|
|
const [, drop] = useDrop({
|
|
|
|
|
accept: 'bookmark',
|
2024-08-08 21:25:10 -04:00
|
|
|
drop: (item: DragItem) => handleDrop(item),
|
|
|
|
|
hover(item: DragItem) {
|
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-08-22 17:09:05 -04:00
|
|
|
className="cursor-move hover:bg-surface-tertiary"
|
2024-07-29 19:25:36 -04:00
|
|
|
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;
|