🖼️ 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:
Marco Beretta 2024-08-16 10:30:14 +02:00 committed by GitHub
parent 7f50d2f7c0
commit 96581d56df
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
62 changed files with 2627 additions and 1821 deletions

View file

@ -0,0 +1,87 @@
import React from 'react';
import { useParams, useNavigate } from 'react-router-dom';
import type { MouseEvent, FocusEvent, KeyboardEvent } from 'react';
import { TooltipProvider, Tooltip, TooltipTrigger, TooltipContent } from '~/components/ui';
import { useConversations, useLocalize, useNewConvo } from '~/hooks';
import { useArchiveConversationMutation } from '~/data-provider';
import { NotificationSeverity } from '~/common';
import { useToastContext } from '~/Providers';
type ArchiveButtonProps = {
children?: React.ReactNode;
conversationId: string;
retainView: () => void;
shouldArchive: boolean;
icon?: React.ReactNode;
className?: string;
};
export function useArchiveHandler(
conversationId: string,
shouldArchive: boolean,
retainView: () => void,
) {
const localize = useLocalize();
const navigate = useNavigate();
const { showToast } = useToastContext();
const { newConversation } = useNewConvo();
const { refreshConversations } = useConversations();
const { conversationId: currentConvoId } = useParams();
const archiveConvoMutation = useArchiveConversationMutation(conversationId);
return async (e?: MouseEvent | FocusEvent | KeyboardEvent) => {
if (e) {
e.preventDefault();
}
const label = shouldArchive ? 'archive' : 'unarchive';
archiveConvoMutation.mutate(
{ conversationId, isArchived: shouldArchive },
{
onSuccess: () => {
if (currentConvoId === conversationId || currentConvoId === 'new') {
newConversation();
navigate('/c/new', { replace: true });
}
refreshConversations();
retainView();
},
onError: () => {
showToast({
message: localize(`com_ui_${label}_error`),
severity: NotificationSeverity.ERROR,
showIcon: true,
});
},
},
);
};
}
export default function ArchiveButton({
conversationId,
retainView,
shouldArchive,
icon,
className = '',
}: ArchiveButtonProps) {
const localize = useLocalize();
const archiveHandler = useArchiveHandler(conversationId, shouldArchive, retainView);
return (
<button type="button" className={className} onClick={archiveHandler}>
<TooltipProvider delayDuration={250}>
<Tooltip>
<TooltipTrigger asChild>
<span className="h-5 w-5">{icon}</span>
</TooltipTrigger>
<TooltipContent side="top" sideOffset={0}>
{localize(`com_ui_${shouldArchive ? 'archive' : 'unarchive'}`)}
</TooltipContent>
</Tooltip>
</TooltipProvider>
</button>
);
}
export { useArchiveHandler as archiveHandler };