🏷️ fix: Address Statefulness Issues for Bookmarks (#3590)

* refactor: optimize tag methods, remove rebuild

* refactor(tags): add lean db operations, fix updateTagsForConversation, remove rebuild button, only send convoId once

* refactor: Update BookmarkMenu to use Constants.NEW_CONVO constant for comparison

* style: Update BookmarkMenu styles and constants, use theming

* refactor: move tags query from package to client workspace

* refactor: optimize ConversationTag document creation and update logic

* style: Update BookmarkMenuItems to use theming

* refactor: JSDocs + try/catch for conversation tags API routes

* refactor: Update BookmarkNav theming classes and new data provider location

* fix: statefulness of conversation bookmarks
- move non-mutation hook to hooks/Conversation
- remove use of deprecated global convo
- update convo infinite data as well as current convo state upon successful tag add

* refactor: Update BookmarkMenu styles and constants, use theming

* refactor: Add lean option to ConversationTag deletion query

* fix(BookmarkTable): position order rendering esp. when new tag is created

* refactor: Update useBookmarkSucess to useBookmarkSuccess for consistency

* refactor: Update ConversationTag creation logic to increment count only if addToConversation is true

* style: theming
This commit is contained in:
Danny Avila 2024-08-08 21:25:10 -04:00 committed by GitHub
parent 6ea2628b56
commit 016ed866a3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
28 changed files with 622 additions and 536 deletions

View file

@ -7,6 +7,7 @@ import { cn } from '~/utils';
type MenuItemProps = {
tag: string | React.ReactNode;
selected: boolean;
ctx: 'header' | 'nav';
count?: number;
handleSubmit: (tag: string) => Promise<void>;
icon?: React.ReactNode;
@ -15,6 +16,7 @@ type MenuItemProps = {
const BookmarkItem: FC<MenuItemProps> = ({
tag,
ctx,
selected,
count,
handleSubmit,
@ -34,13 +36,30 @@ const BookmarkItem: FC<MenuItemProps> = ({
overflowWrap: 'anywhere',
};
const renderIcon = () => {
if (icon) {
return icon;
}
if (isLoading) {
return <Spinner className="size-4" />;
}
if (selected) {
return <BookmarkFilledIcon className="size-4" />;
}
return <BookmarkIcon className="size-4" />;
};
const ariaLabel =
ctx === 'header' ? `${selected ? 'Remove' : 'Add'} bookmark for ${tag}` : (tag as string);
return (
<div
<button
aria-label={ariaLabel}
role="menuitem"
className={cn(
'group m-1.5 flex w-[225px] cursor-pointer gap-2 rounded px-2 py-2.5 !pr-3 text-sm !opacity-100 focus:ring-0 radix-disabled:pointer-events-none radix-disabled:opacity-50',
'hover:bg-black/5 dark:hover:bg-white/5',
highlightSelected && selected && 'bg-black/5 dark:bg-white/5',
'group m-1.5 flex w-[225px] cursor-pointer gap-2 rounded bg-transparent px-2 py-2.5 !pr-3 text-sm !opacity-100 focus:ring-0 radix-disabled:pointer-events-none radix-disabled:opacity-50',
highlightSelected && selected ? 'bg-surface-secondary' : '',
ctx === 'header' ? 'hover:bg-header-hover' : 'hover:bg-surface-hover',
)}
tabIndex={-1}
{...rest}
@ -48,25 +67,14 @@ const BookmarkItem: FC<MenuItemProps> = ({
>
<div className="flex grow items-center justify-between gap-2">
<div className="flex items-center gap-2">
{icon ? (
icon
) : isLoading ? (
<Spinner className="size-4" />
) : selected ? (
<BookmarkFilledIcon className="size-4" />
) : (
<BookmarkIcon className="size-4" />
)}
{renderIcon()}
<div style={breakWordStyle}>{tag}</div>
</div>
{count !== undefined && (
<div className="flex items-center justify-end">
<span
className={cn(
'ml-auto w-7 min-w-max whitespace-nowrap rounded-md bg-white px-2.5 py-0.5 text-center text-xs font-medium leading-5 text-gray-600',
'dark:bg-gray-800 dark:text-white',
)}
className="ml-auto w-7 min-w-max whitespace-nowrap rounded-md bg-surface-secondary px-2.5 py-0.5 text-center text-xs font-medium leading-5 text-text-secondary"
aria-hidden="true"
>
{count}
@ -74,7 +82,8 @@ const BookmarkItem: FC<MenuItemProps> = ({
</div>
)}
</div>
</div>
</button>
);
};
export default BookmarkItem;