LibreChat/client/src/components/SidePanel/Bookmarks/BookmarkTableRow.tsx

116 lines
3.3 KiB
TypeScript
Raw Normal View History

import React, { useState, useRef } from 'react';
import { useDrag, useDrop } from 'react-dnd';
import type { TConversationTag } from 'librechat-data-provider';
import { DeleteBookmarkButton, EditBookmarkButton } from '~/components/Bookmarks';
import { useConversationTagMutation } from '~/data-provider';
import { TableRow, TableCell } from '~/components/ui';
import { NotificationSeverity } from '~/common';
import { useToastContext } from '~/Providers';
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 [isHovered, setIsHovered] = useState(false);
const ref = useRef<HTMLTableRowElement>(null);
🔖 feat: Enhance Bookmarks UX, add RBAC, toggle via `librechat.yaml` (#3747) * chore: update package version to 0.7.416 * chore: Update Role.js imports order * refactor: move updateTagsInConvo to tags route, add RBAC for tags * refactor: add updateTagsInConvoOptions * fix: loading state for bookmark form * refactor: update primaryText class in TitleButton component * refactor: remove duplicate bookmarks and theming * refactor: update EditIcon component to use React.forwardRef * refactor: add _id field to tConversationTagSchema * refactor: remove promises * refactor: move mutation logic from BookmarkForm -> BookmarkEditDialog * refactor: update button class in BookmarkForm component * fix: conversation mutations and add better logging to useConversationTagMutation * refactor: update logger message in BookmarkEditDialog component * refactor: improve UI consistency in BookmarkNav and NewChat components * refactor: update logger message in BookmarkEditDialog component * refactor: Add tags prop to BookmarkForm component * refactor: Update BookmarkForm to avoid tag mutation if the tag already exists; also close dialog on submission programmatically * refactor: general role helper function to support updating access permissions for different permission types * refactor: Update getLatestText function to handle undefined values in message.content * refactor: Update useHasAccess hook to handle null role values for authenticated users * feat: toggle bookmarks access * refactor: Update PromptsCommand to handle access permissions for prompts * feat: updateConversationSelector * refactor: rename `vars` to `tagToDelete` for clarity * fix: prevent recreation of deleted tags in BookmarkMenu on Item Click * ci: mock updateBookmarksAccess function * ci: mock updateBookmarksAccess function
2024-08-22 17:09:05 -04:00
const mutation = useConversationTagMutation({ context: 'BookmarkTableRow', tag: row.tag });
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,
});
},
});
};
const [, drop] = useDrop({
accept: 'bookmark',
drop: (item: DragItem) => handleDrop(item),
hover(item: DragItem) {
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({
type: 'bookmark',
item: { index: position },
collect: (monitor) => ({
isDragging: monitor.isDragging(),
}),
});
drag(drop(ref));
return (
<TableRow
ref={ref}
🔖 feat: Enhance Bookmarks UX, add RBAC, toggle via `librechat.yaml` (#3747) * chore: update package version to 0.7.416 * chore: Update Role.js imports order * refactor: move updateTagsInConvo to tags route, add RBAC for tags * refactor: add updateTagsInConvoOptions * fix: loading state for bookmark form * refactor: update primaryText class in TitleButton component * refactor: remove duplicate bookmarks and theming * refactor: update EditIcon component to use React.forwardRef * refactor: add _id field to tConversationTagSchema * refactor: remove promises * refactor: move mutation logic from BookmarkForm -> BookmarkEditDialog * refactor: update button class in BookmarkForm component * fix: conversation mutations and add better logging to useConversationTagMutation * refactor: update logger message in BookmarkEditDialog component * refactor: improve UI consistency in BookmarkNav and NewChat components * refactor: update logger message in BookmarkEditDialog component * refactor: Add tags prop to BookmarkForm component * refactor: Update BookmarkForm to avoid tag mutation if the tag already exists; also close dialog on submission programmatically * refactor: general role helper function to support updating access permissions for different permission types * refactor: Update getLatestText function to handle undefined values in message.content * refactor: Update useHasAccess hook to handle null role values for authenticated users * feat: toggle bookmarks access * refactor: Update PromptsCommand to handle access permissions for prompts * feat: updateConversationSelector * refactor: rename `vars` to `tagToDelete` for clarity * fix: prevent recreation of deleted tags in BookmarkMenu on Item Click * ci: mock updateBookmarksAccess function * ci: mock updateBookmarksAccess function
2024-08-22 17:09:05 -04:00
className="cursor-move hover:bg-surface-tertiary"
style={{ opacity: isDragging ? 0.5 : 1 }}
onMouseEnter={() => setIsHovered(true)}
onMouseLeave={() => setIsHovered(false)}
>
<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)}
/>
</div>
</div>
</TableCell>
</TableRow>
);
};
export default BookmarkTableRow;