mirror of
https://github.com/danny-avila/LibreChat.git
synced 2026-01-19 00:36:12 +01:00
🖼️ style: Conversation Menu and Dialogs update (#3601)
* feat: new dropdown * fix: maintain popover active when open * fix: update DeleteButton and ShareButton component to use useState for managing dialog state * BREAKING: style improvement of base Button component * style: update export button * a11y: ExportAndShareButton * add border * quick style fix * fix: flick issue on convo * fix: DropDown opens when renaming * chore: update radix-ui/react-dropdown-menu to latest * small fix * style: bookmarks update * reorder export modal * feat: imporved dropdowns * style: a lot of changes; header, bookmarks, export, nav, convo, convoOptions * fix: small style issues * fix: button * fix: bookmarks header menu * fix: dropdown close glitch * feat: Improve accessibility and keyboard navigation in ModelSpec component * fix: Nav related type issues * style: ConvoOptions theming and focus ring --------- Co-authored-by: Danny Avila <danny@librechat.ai>
This commit is contained in:
parent
7f50d2f7c0
commit
96581d56df
62 changed files with 2627 additions and 1821 deletions
|
|
@ -1,8 +1,8 @@
|
|||
import { useState, type FC } from 'react';
|
||||
import { type FC } from 'react';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
import { useLocation } from 'react-router-dom';
|
||||
import { TConversation } from 'librechat-data-provider';
|
||||
import { Content, Portal, Root, Trigger } from '@radix-ui/react-popover';
|
||||
import { Menu, MenuButton, MenuItems } from '@headlessui/react';
|
||||
import { BookmarkFilledIcon, BookmarkIcon } from '@radix-ui/react-icons';
|
||||
import { BookmarkContext } from '~/Providers/BookmarkContext';
|
||||
import { useGetConversationTags } from '~/data-provider';
|
||||
|
|
@ -25,8 +25,6 @@ const BookmarkNav: FC<BookmarkNavProps> = ({ tags, setTags }: BookmarkNavProps)
|
|||
const activeConvo = useRecoilValue(store.conversationByIndex(0));
|
||||
const globalConvo = useRecoilValue(store.conversation) ?? ({} as TConversation);
|
||||
|
||||
const [open, setIsOpen] = useState(false);
|
||||
|
||||
let conversation: TConversation | null | undefined;
|
||||
if (location.state?.from?.pathname.includes('/chat')) {
|
||||
conversation = globalConvo;
|
||||
|
|
@ -35,38 +33,29 @@ const BookmarkNav: FC<BookmarkNavProps> = ({ tags, setTags }: BookmarkNavProps)
|
|||
}
|
||||
|
||||
return (
|
||||
<Root open={open} onOpenChange={setIsOpen}>
|
||||
<Trigger asChild>
|
||||
<button
|
||||
className={cn(
|
||||
'relative mt-1 flex h-10 w-full cursor-pointer items-center gap-1 rounded-lg border-border-light bg-transparent px-1 py-2 text-text-primary transition-colors duration-200 focus-within:bg-surface-hover hover:bg-surface-hover',
|
||||
open ? 'bg-surface-hover' : '',
|
||||
)}
|
||||
id="show-bookmarks"
|
||||
data-testid="show-bookmarks"
|
||||
title={localize('com_ui_bookmarks')}
|
||||
>
|
||||
<div className="relative flex h-8 w-8 items-center justify-center rounded-full p-1 text-text-primary">
|
||||
{tags.length > 0 ? (
|
||||
<BookmarkFilledIcon className="h-5 w-5" />
|
||||
) : (
|
||||
<BookmarkIcon className="h-5 w-5" />
|
||||
<Menu as="div" className="group relative">
|
||||
{({ open }) => (
|
||||
<>
|
||||
<MenuButton
|
||||
className={cn(
|
||||
'mt-text-sm flex h-10 w-full items-center gap-2 rounded-lg p-2 text-sm transition-colors duration-200 hover:bg-surface-hover',
|
||||
open ? 'bg-surface-hover' : '',
|
||||
)}
|
||||
</div>
|
||||
<div className="grow overflow-hidden whitespace-nowrap text-left text-sm text-text-primary">
|
||||
{tags.length > 0 ? tags.join(', ') : localize('com_ui_bookmarks')}
|
||||
</div>
|
||||
</button>
|
||||
</Trigger>
|
||||
<Portal>
|
||||
<div className="fixed left-0 top-0 z-auto translate-x-[268px] translate-y-[50px]">
|
||||
<Content
|
||||
side="bottom"
|
||||
align="start"
|
||||
className="mt-2 max-h-96 min-w-[240px] overflow-y-auto rounded-lg border border-border-medium bg-surface-primary-alt text-text-primary shadow-lg lg:max-h-96"
|
||||
data-testid="bookmark-menu"
|
||||
>
|
||||
<div className="relative flex h-8 w-8 items-center justify-center rounded-full p-1 text-text-primary">
|
||||
{tags.length > 0 ? (
|
||||
<BookmarkFilledIcon className="h-5 w-5" />
|
||||
) : (
|
||||
<BookmarkIcon className="h-5 w-5" />
|
||||
)}
|
||||
</div>
|
||||
<div className="grow overflow-hidden whitespace-nowrap text-left text-sm text-text-primary">
|
||||
{tags.length > 0 ? tags.join(', ') : localize('com_ui_bookmarks')}
|
||||
</div>
|
||||
</MenuButton>
|
||||
<MenuItems className="absolute left-0 top-full z-[100] mt-1 w-full translate-y-0 overflow-hidden rounded-lg bg-header-primary p-1.5 shadow-lg outline-none">
|
||||
{data && conversation && (
|
||||
// Display bookmarks and highlight the selected tag
|
||||
<BookmarkContext.Provider value={{ bookmarks: data.filter((tag) => tag.count > 0) }}>
|
||||
<BookmarkNavItems
|
||||
// Currently selected conversation
|
||||
|
|
@ -78,10 +67,10 @@ const BookmarkNav: FC<BookmarkNavProps> = ({ tags, setTags }: BookmarkNavProps)
|
|||
/>
|
||||
</BookmarkContext.Provider>
|
||||
)}
|
||||
</Content>
|
||||
</div>
|
||||
</Portal>
|
||||
</Root>
|
||||
</MenuItems>
|
||||
</>
|
||||
)}
|
||||
</Menu>
|
||||
);
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -43,9 +43,8 @@ const BookmarkNavItems: FC<{
|
|||
return (
|
||||
<div className="flex flex-col">
|
||||
<BookmarkItem
|
||||
ctx="nav"
|
||||
tag={localize('com_ui_no_bookmarks')}
|
||||
data-testid="bookmark-item-clear"
|
||||
data-testid="bookmark-item-no-bookmarks"
|
||||
handleSubmit={() => Promise.resolve()}
|
||||
selected={false}
|
||||
icon={'🤔'}
|
||||
|
|
@ -57,18 +56,15 @@ const BookmarkNavItems: FC<{
|
|||
return (
|
||||
<div className="flex flex-col">
|
||||
<BookmarkItems
|
||||
ctx="nav"
|
||||
tags={tags}
|
||||
handleSubmit={handleSubmit}
|
||||
highlightSelected={true}
|
||||
header={
|
||||
<BookmarkItem
|
||||
ctx="nav"
|
||||
tag="Clear all"
|
||||
tag={localize('com_ui_clear_all')}
|
||||
data-testid="bookmark-item-clear"
|
||||
handleSubmit={clear}
|
||||
selected={false}
|
||||
icon={<CrossCircledIcon className="h-4 w-4" />}
|
||||
icon={<CrossCircledIcon className="size-4" />}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
import filenamify from 'filenamify';
|
||||
import { useEffect, useState } from 'react';
|
||||
import type { TConversation } from 'librechat-data-provider';
|
||||
import { Dialog, DialogButton, Input, Label, Checkbox, Dropdown } from '~/components/ui';
|
||||
import { OGDialog, Button, Input, Label, Checkbox, Dropdown } from '~/components/ui';
|
||||
import OGDialogTemplate from '~/components/ui/OGDialogTemplate';
|
||||
import { useLocalize, useExportConversation } from '~/hooks';
|
||||
import DialogTemplate from '~/components/ui/DialogTemplate';
|
||||
import { cn, defaultTextProps } from '~/utils';
|
||||
|
||||
export default function ExportModal({
|
||||
|
|
@ -62,8 +62,8 @@ export default function ExportModal({
|
|||
});
|
||||
|
||||
return (
|
||||
<Dialog open={open} onOpenChange={onOpenChange}>
|
||||
<DialogTemplate
|
||||
<OGDialog open={open} onOpenChange={onOpenChange}>
|
||||
<OGDialogTemplate
|
||||
title={localize('com_nav_export_conversation')}
|
||||
className="max-w-full sm:max-w-2xl"
|
||||
main={
|
||||
|
|
@ -164,16 +164,13 @@ export default function ExportModal({
|
|||
}
|
||||
buttons={
|
||||
<>
|
||||
<DialogButton
|
||||
onClick={exportConversation}
|
||||
className="dark:hover:gray-400 border-gray-700 bg-green-500 text-white hover:bg-green-600 dark:hover:bg-green-600"
|
||||
>
|
||||
<Button onClick={exportConversation} variant="success">
|
||||
{localize('com_endpoint_export')}
|
||||
</DialogButton>
|
||||
</Button>
|
||||
</>
|
||||
}
|
||||
selection={undefined}
|
||||
/>
|
||||
</Dialog>
|
||||
</OGDialog>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,7 +24,13 @@ import NewChat from './NewChat';
|
|||
import { cn } from '~/utils';
|
||||
import store from '~/store';
|
||||
|
||||
const Nav = ({ navVisible, setNavVisible }) => {
|
||||
const Nav = ({
|
||||
navVisible,
|
||||
setNavVisible,
|
||||
}: {
|
||||
navVisible: boolean;
|
||||
setNavVisible: React.Dispatch<React.SetStateAction<boolean>>;
|
||||
}) => {
|
||||
const localize = useLocalize();
|
||||
const { conversationId } = useParams();
|
||||
const { isAuthenticated } = useAuthContext();
|
||||
|
|
@ -80,7 +86,9 @@ const Nav = ({ navVisible, setNavVisible }) => {
|
|||
setShowLoading,
|
||||
hasNextPage: searchQuery ? searchQueryRes?.hasNextPage : hasNextPage,
|
||||
fetchNextPage: searchQuery ? searchQueryRes?.fetchNextPage : fetchNextPage,
|
||||
isFetchingNextPage: searchQuery ? searchQueryRes?.isFetchingNextPage : isFetchingNextPage,
|
||||
isFetchingNextPage: searchQuery
|
||||
? searchQueryRes?.isFetchingNextPage ?? false
|
||||
: isFetchingNextPage,
|
||||
});
|
||||
|
||||
const conversations = useMemo(
|
||||
|
|
@ -155,24 +163,37 @@ const Nav = ({ navVisible, setNavVisible }) => {
|
|||
onMouseLeave={handleMouseLeave}
|
||||
ref={containerRef}
|
||||
>
|
||||
<NewChat
|
||||
toggleNav={itemToggleNav}
|
||||
subHeaders={
|
||||
<>
|
||||
{isSearchEnabled && <SearchBar clearSearch={clearSearch} />}
|
||||
<BookmarkNav tags={tags} setTags={setTags} />
|
||||
</>
|
||||
}
|
||||
/>
|
||||
{isSmallScreen == true ? (
|
||||
<div className="pt-3.5">
|
||||
{isSearchEnabled === true && (
|
||||
<SearchBar clearSearch={clearSearch} isSmallScreen={isSmallScreen} />
|
||||
)}
|
||||
<BookmarkNav tags={tags} setTags={setTags} />
|
||||
</div>
|
||||
) : (
|
||||
<NewChat
|
||||
toggleNav={itemToggleNav}
|
||||
subHeaders={
|
||||
<>
|
||||
{isSearchEnabled === true && (
|
||||
<SearchBar
|
||||
clearSearch={clearSearch}
|
||||
isSmallScreen={isSmallScreen}
|
||||
/>
|
||||
)}
|
||||
<BookmarkNav tags={tags} setTags={setTags} />
|
||||
</>
|
||||
}
|
||||
/>
|
||||
)}
|
||||
|
||||
<Conversations
|
||||
conversations={conversations}
|
||||
moveToTop={moveToTop}
|
||||
toggleNav={itemToggleNav}
|
||||
/>
|
||||
{(isFetchingNextPage || showLoading) && (
|
||||
<Spinner
|
||||
className={cn('m-1 mx-auto mb-4 h-4 w-4 text-black dark:text-white')}
|
||||
/>
|
||||
<Spinner className={cn('m-1 mx-auto mb-4 h-4 w-4 text-text-primary')} />
|
||||
)}
|
||||
</div>
|
||||
<NavLinks />
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ function NavLinks() {
|
|||
<UserIcon />
|
||||
</div>
|
||||
) : (
|
||||
<img className="rounded-full" src={user?.avatar || avatarSrc} alt="avatar" />
|
||||
<img className="rounded-full" src={user.avatar || avatarSrc} alt="avatar" />
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -68,7 +68,7 @@ function NavLinks() {
|
|||
|
||||
<Transition
|
||||
as={Fragment}
|
||||
enter="transition ease-out duration-110 transform"
|
||||
enter="transition ease-out duration-100 transform"
|
||||
enterFrom="translate-y-2 opacity-0"
|
||||
enterTo="translate-y-0 opacity-100"
|
||||
leave="transition ease-in duration-100 transform"
|
||||
|
|
|
|||
|
|
@ -82,14 +82,14 @@ export default function NewChat({
|
|||
return (
|
||||
<TooltipProvider delayDuration={250}>
|
||||
<Tooltip>
|
||||
<div className="sticky left-0 right-0 top-0 z-20 bg-gray-50 pt-3.5 dark:bg-gray-850">
|
||||
<div className="sticky left-0 right-0 top-0 z-20 bg-surface-primary-alt pt-3.5">
|
||||
<div className="pb-0.5 last:pb-0" style={{ transform: 'none' }}>
|
||||
<a
|
||||
href="/"
|
||||
tabIndex={0}
|
||||
data-testid="nav-new-chat"
|
||||
onClick={clickHandler}
|
||||
className="group flex h-10 items-center gap-2 rounded-lg px-2 font-medium hover:bg-gray-200 dark:hover:bg-gray-700"
|
||||
className="group flex h-10 items-center gap-2 rounded-lg px-2 font-medium transition-colors duration-200 hover:bg-surface-hover"
|
||||
aria-label={localize('com_ui_new_chat')}
|
||||
>
|
||||
<NewChatButtonIcon conversation={conversation} />
|
||||
|
|
@ -104,7 +104,7 @@ export default function NewChat({
|
|||
aria-label="nav-new-chat-btn"
|
||||
className="text-token-text-primary"
|
||||
>
|
||||
<NewChatIcon className="h-[18px] w-[18px]" />
|
||||
<NewChatIcon className="size-5" />
|
||||
</button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent side="right" sideOffset={20}>
|
||||
|
|
|
|||
|
|
@ -10,10 +10,11 @@ import store from '~/store';
|
|||
|
||||
type SearchBarProps = {
|
||||
clearSearch: () => void;
|
||||
isSmallScreen?: boolean;
|
||||
};
|
||||
|
||||
const SearchBar = forwardRef((props: SearchBarProps, ref: Ref<HTMLDivElement>) => {
|
||||
const { clearSearch } = props;
|
||||
const { clearSearch, isSmallScreen } = props;
|
||||
const queryClient = useQueryClient();
|
||||
const clearConvoState = store.useClearConvoState();
|
||||
const setSearchQuery = useSetRecoilState(store.searchQuery);
|
||||
|
|
@ -58,7 +59,10 @@ const SearchBar = forwardRef((props: SearchBarProps, ref: Ref<HTMLDivElement>) =
|
|||
return (
|
||||
<div
|
||||
ref={ref}
|
||||
className="relative mt-1 flex h-10 cursor-pointer items-center gap-3 rounded-lg border-border-medium px-3 py-2 text-text-primary transition-colors duration-200 focus-within:bg-surface-hover hover:bg-surface-hover dark:focus-within:bg-surface-hover"
|
||||
className={cn(
|
||||
'relative mt-1 flex h-10 cursor-pointer items-center gap-3 rounded-lg border-border-medium px-3 py-2 text-text-primary transition-colors duration-200 focus-within:bg-surface-hover hover:bg-surface-hover dark:focus-within:bg-surface-hover',
|
||||
isSmallScreen === true ? 'h-16 rounded-2xl' : '',
|
||||
)}
|
||||
>
|
||||
{<Search className="absolute left-3 h-4 w-4" />}
|
||||
<input
|
||||
|
|
@ -77,8 +81,9 @@ const SearchBar = forwardRef((props: SearchBarProps, ref: Ref<HTMLDivElement>) =
|
|||
/>
|
||||
<X
|
||||
className={cn(
|
||||
'absolute right-[7px] h-5 w-5 cursor-pointer transition-opacity duration-1000',
|
||||
'absolute right-[7px] h-5 w-5 cursor-pointer transition-opacity duration-200',
|
||||
showClearIcon ? 'opacity-100' : 'opacity-0',
|
||||
isSmallScreen === true ? 'right-[16px]' : '',
|
||||
)}
|
||||
onClick={clearText}
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -94,7 +94,7 @@ export default function Settings({ open, onOpenChange }: TDialogProps) {
|
|||
<Tabs.Trigger
|
||||
tabIndex={0}
|
||||
className={cn(
|
||||
'group m-1 flex items-center justify-start gap-2 rounded-md px-2 py-1.5 text-sm text-text-primary transition-all duration-200 ease-in-out radix-state-active:bg-surface-tertiary radix-state-active:text-text-primary dark:radix-state-active:bg-surface-primary',
|
||||
'group m-1 flex items-center justify-start gap-2 rounded-md px-2 py-1.5 text-sm text-text-primary transition-all duration-200 ease-in-out radix-state-active:bg-surface-tertiary radix-state-active:text-text-primary dark:radix-state-active:bg-surface-active',
|
||||
isSmallScreen
|
||||
? 'flex-1 items-center justify-center text-nowrap p-1 px-3 text-sm text-text-secondary'
|
||||
: 'bg-surface-tertiary-alt',
|
||||
|
|
@ -108,7 +108,7 @@ export default function Settings({ open, onOpenChange }: TDialogProps) {
|
|||
<Tabs.Trigger
|
||||
tabIndex={0}
|
||||
className={cn(
|
||||
'group m-1 flex items-center justify-start gap-2 rounded-md px-2 py-1.5 text-sm text-text-primary transition-all duration-200 ease-in-out radix-state-active:bg-surface-tertiary radix-state-active:text-text-primary dark:radix-state-active:bg-surface-primary',
|
||||
'group m-1 flex items-center justify-start gap-2 rounded-md px-2 py-1.5 text-sm text-text-primary transition-all duration-200 ease-in-out radix-state-active:bg-surface-tertiary radix-state-active:text-text-primary dark:radix-state-active:bg-surface-active',
|
||||
isSmallScreen
|
||||
? 'flex-1 items-center justify-center text-nowrap p-1 px-3 text-sm text-text-secondary'
|
||||
: 'bg-surface-tertiary-alt',
|
||||
|
|
@ -122,7 +122,7 @@ export default function Settings({ open, onOpenChange }: TDialogProps) {
|
|||
<Tabs.Trigger
|
||||
tabIndex={0}
|
||||
className={cn(
|
||||
'group m-1 flex items-center justify-start gap-2 rounded-md px-2 py-1.5 text-sm text-text-primary transition-all duration-200 ease-in-out radix-state-active:bg-surface-tertiary radix-state-active:text-text-primary dark:radix-state-active:bg-surface-primary',
|
||||
'group m-1 flex items-center justify-start gap-2 rounded-md px-2 py-1.5 text-sm text-text-primary transition-all duration-200 ease-in-out radix-state-active:bg-surface-tertiary radix-state-active:text-text-primary dark:radix-state-active:bg-surface-active',
|
||||
isSmallScreen
|
||||
? 'flex-1 items-center justify-center text-nowrap p-1 px-3 text-sm text-text-secondary'
|
||||
: 'bg-surface-tertiary-alt',
|
||||
|
|
@ -136,7 +136,7 @@ export default function Settings({ open, onOpenChange }: TDialogProps) {
|
|||
<Tabs.Trigger
|
||||
tabIndex={0}
|
||||
className={cn(
|
||||
'group m-1 flex items-center justify-start gap-2 rounded-md px-2 py-1.5 text-sm text-text-primary transition-all duration-200 ease-in-out radix-state-active:bg-surface-tertiary radix-state-active:text-text-primary dark:radix-state-active:bg-surface-primary',
|
||||
'group m-1 flex items-center justify-start gap-2 rounded-md px-2 py-1.5 text-sm text-text-primary transition-all duration-200 ease-in-out radix-state-active:bg-surface-tertiary radix-state-active:text-text-primary dark:radix-state-active:bg-surface-active',
|
||||
isSmallScreen
|
||||
? 'flex-1 items-center justify-center text-nowrap text-sm text-text-secondary'
|
||||
: 'bg-surface-tertiary-alt',
|
||||
|
|
@ -150,7 +150,7 @@ export default function Settings({ open, onOpenChange }: TDialogProps) {
|
|||
<Tabs.Trigger
|
||||
tabIndex={0}
|
||||
className={cn(
|
||||
'group m-1 flex items-center justify-start gap-2 rounded-md px-2 py-1.5 text-sm text-text-primary transition-all duration-200 ease-in-out radix-state-active:bg-surface-tertiary radix-state-active:text-text-primary dark:radix-state-active:bg-surface-primary',
|
||||
'group m-1 flex items-center justify-start gap-2 rounded-md px-2 py-1.5 text-sm text-text-primary transition-all duration-200 ease-in-out radix-state-active:bg-surface-tertiary radix-state-active:text-text-primary dark:radix-state-active:bg-surface-active',
|
||||
isSmallScreen
|
||||
? 'flex-1 items-center justify-center text-nowrap p-1 px-3 text-sm text-text-secondary'
|
||||
: 'bg-surface-tertiary-alt',
|
||||
|
|
@ -164,7 +164,7 @@ export default function Settings({ open, onOpenChange }: TDialogProps) {
|
|||
<Tabs.Trigger
|
||||
tabIndex={0}
|
||||
className={cn(
|
||||
'group m-1 flex items-center justify-start gap-2 rounded-md px-2 py-1.5 text-sm text-text-primary transition-all duration-200 ease-in-out radix-state-active:bg-surface-tertiary radix-state-active:text-text-primary dark:radix-state-active:bg-surface-primary',
|
||||
'group m-1 flex items-center justify-start gap-2 rounded-md px-2 py-1.5 text-sm text-text-primary transition-all duration-200 ease-in-out radix-state-active:bg-surface-tertiary radix-state-active:text-text-primary dark:radix-state-active:bg-surface-active',
|
||||
isSmallScreen
|
||||
? 'flex-1 items-center justify-center text-nowrap p-1 px-3 text-sm text-text-secondary'
|
||||
: 'bg-surface-tertiary-alt',
|
||||
|
|
@ -178,7 +178,7 @@ export default function Settings({ open, onOpenChange }: TDialogProps) {
|
|||
<Tabs.Trigger
|
||||
tabIndex={0}
|
||||
className={cn(
|
||||
'group m-1 flex items-center justify-start gap-2 rounded-md px-2 py-1.5 text-sm text-text-primary transition-all duration-200 ease-in-out radix-state-active:bg-surface-tertiary radix-state-active:text-text-primary dark:radix-state-active:bg-surface-primary',
|
||||
'group m-1 flex items-center justify-start gap-2 rounded-md px-2 py-1.5 text-sm text-text-primary transition-all duration-200 ease-in-out radix-state-active:bg-surface-tertiary radix-state-active:text-text-primary dark:radix-state-active:bg-surface-active',
|
||||
isSmallScreen
|
||||
? 'flex-1 items-center justify-center text-nowrap p-1 px-3 text-sm text-text-secondary'
|
||||
: 'bg-surface-tertiary-alt',
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { useLocalize } from '~/hooks';
|
||||
import DialogTemplate from '~/components/ui/DialogTemplate';
|
||||
import { Dialog, DialogTrigger } from '~/components/ui';
|
||||
import OGDialogTemplate from '~/components/ui/OGDialogTemplate';
|
||||
import { OGDialog, OGDialogTrigger } from '~/components/ui';
|
||||
|
||||
import ArchivedChatsTable from './ArchivedChatsTable';
|
||||
|
||||
|
|
@ -10,19 +10,19 @@ export default function ArchivedChats() {
|
|||
return (
|
||||
<div className="flex items-center justify-between">
|
||||
<div>{localize('com_nav_archived_chats')}</div>
|
||||
<Dialog>
|
||||
<DialogTrigger asChild>
|
||||
<OGDialog>
|
||||
<OGDialogTrigger asChild>
|
||||
<button className="btn btn-neutral relative ">
|
||||
{localize('com_nav_archived_chats_manage')}
|
||||
</button>
|
||||
</DialogTrigger>
|
||||
<DialogTemplate
|
||||
</OGDialogTrigger>
|
||||
<OGDialogTemplate
|
||||
title={localize('com_nav_archived_chats')}
|
||||
className="max-w-[1000px]"
|
||||
showCancelButton={false}
|
||||
main={<ArchivedChatsTable />}
|
||||
/>
|
||||
</Dialog>
|
||||
</OGDialog>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,8 +2,8 @@ import { useMemo, useState } from 'react';
|
|||
import { MessageCircle, ArchiveRestore } from 'lucide-react';
|
||||
import { useConversationsInfiniteQuery } from '~/data-provider';
|
||||
import { useAuthContext, useLocalize, useNavScrolling } from '~/hooks';
|
||||
import ArchiveButton from '~/components/Conversations/ArchiveButton';
|
||||
import DeleteButton from '~/components/Conversations/DeleteButton';
|
||||
import ArchiveButton from '~/components/Conversations/ConvoOptions/ArchiveButton';
|
||||
import DeleteButton from '~/components/Conversations/ConvoOptions/DeleteButton';
|
||||
import { Spinner } from '~/components/svg';
|
||||
import { cn } from '~/utils';
|
||||
import { ConversationListResponse } from 'librechat-data-provider';
|
||||
|
|
@ -90,10 +90,7 @@ export default function ArchivedChatsTable({ className }: { className?: string }
|
|||
<DeleteButton
|
||||
conversationId={conversation.conversationId}
|
||||
retainView={moveToTop}
|
||||
renaming={false}
|
||||
title={conversation.title}
|
||||
appendLabel={false}
|
||||
className="group ml-4 flex w-full cursor-pointer items-center items-center gap-2 rounded text-sm hover:bg-gray-200 focus-visible:bg-gray-200 focus-visible:outline-0 radix-disabled:pointer-events-none radix-disabled:opacity-50 dark:hover:bg-gray-600 dark:focus-visible:bg-gray-600"
|
||||
title={conversation.title ?? ''}
|
||||
/>
|
||||
</div>
|
||||
</>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue