🔖 feat: Conversation Bookmarks (#3344)

* feat: add tags property in Conversation model

* feat: add ConversationTag model

* feat: add the tags parameter to getConvosByPage

* feat: add API route to ConversationTag

* feat: add types of ConversationTag

* feat: add data access functions for conversation tags

* feat: add Bookmark table component

* feat: Add an action to bookmark

* feat: add Bookmark nav component

* fix: failed test

* refactor: made 'Saved' tag a constant

* feat: add new bookmark to current conversation

* chore: Add comment

* fix: delete tag from conversations when it's deleted

* fix: Update the query cache when the tag title is changed.

* chore: fix typo

* refactor: add description of rebuilding bookmarks

* chore: remove unused variables

* fix: position when adding a new bookmark

* refactor: add comment, rename a function

* refactor: add a unique constraint in ConversationTag

* chore: add localizations
This commit is contained in:
Yuichi Oneda 2024-07-29 07:45:59 -07:00 committed by GitHub
parent d4d56281e3
commit e565e0faab
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
65 changed files with 3751 additions and 36 deletions

View file

@ -12,6 +12,7 @@ import { ResizableHandleAlt, ResizablePanel, ResizablePanelGroup } from '~/compo
import { TooltipProvider, Tooltip } from '~/components/ui/Tooltip';
import useSideNavLinks from '~/hooks/Nav/useSideNavLinks';
import { useMediaQuery, useLocalStorage } from '~/hooks';
import BookmarkPanel from './Bookmarks/BookmarkPanel';
import NavToggle from '~/components/Nav/NavToggle';
import { useChatContext } from '~/Providers';
import Switcher from './Switcher';
@ -79,8 +80,20 @@ const SidePanel = ({
localStorage.setItem('fullPanelCollapse', 'true');
panelRef.current?.collapse();
}, []);
const [showBookmarks, setShowBookmarks] = useState(false);
const manageBookmarks = useCallback((e) => {
e.preventDefault();
setShowBookmarks((prev) => !prev);
}, []);
const Links = useSideNavLinks({ hidePanel, assistants, keyProvided, endpoint, interfaceConfig });
const Links = useSideNavLinks({
hidePanel,
assistants,
keyProvided,
endpoint,
interfaceConfig,
manageBookmarks,
});
// eslint-disable-next-line react-hooks/exhaustive-deps
const throttledSaveLayout = useCallback(
@ -128,6 +141,7 @@ const SidePanel = ({
return (
<>
{showBookmarks && <BookmarkPanel open={showBookmarks} onOpenChange={setShowBookmarks} />}
<TooltipProvider delayDuration={0}>
<ResizablePanelGroup
direction="horizontal"
@ -216,7 +230,7 @@ const SidePanel = ({
</ResizablePanelGroup>
</TooltipProvider>
<div
className={`nav-mask${!isCollapsed ? ' active' : ''}`}
className={`nav-mask${!isCollapsed ? 'active' : ''}`}
onClick={() => {
setIsCollapsed(() => {
localStorage.setItem('fullPanelCollapse', 'true');