From 3246f94f34c8fb980442dfe16dbdf4197b1093a2 Mon Sep 17 00:00:00 2001 From: Marco Beretta <81851188+berry-13@users.noreply.github.com> Date: Mon, 5 Oct 2026 12:19:20 +0200 Subject: [PATCH 1/6] feat: Move Chat Actions Into a Header Options Menu The header's export/share button becomes a chat options menu with Share, Export, Rename, Pin, Change project, Remove from project, Duplicate, Archive and Delete for the open chat. The sidebar row menu keeps Pin, Mark unread, Rename, Archive and Delete. --- .../components/Chat/ExportAndShareMenu.tsx | 13 +- .../src/components/Chat/Menus/HeaderMenu.tsx | 7 +- .../Chat/Menus/__tests__/HeaderMenu.spec.tsx | 4 +- client/src/components/Chat/Rename.tsx | 111 ++++++++ .../__tests__/ExportAndShareMenu.test.tsx | 43 ++- .../components/Chat/__tests__/Rename.spec.tsx | 93 +++++++ client/src/components/Conversations/Convo.tsx | 1 - .../components/Conversations/ConvoActions.tsx | 1 - .../ConvoOptions/ConvoOptions.tsx | 177 +----------- .../ConvoOptions/ProjectButton.tsx | 15 +- .../Chat/__tests__/useChatOptions.spec.tsx | 207 ++++++++++++++ client/src/hooks/Chat/useChatOptions.tsx | 259 ++++++++++++++++++ client/src/locales/en/translation.json | 4 +- .../mock/conversation-management.spec.ts | 8 +- e2e/specs/mock/export.spec.ts | 2 +- e2e/specs/mock/mcp-apps.spec.ts | 2 +- e2e/specs/mock/private-text.spec.ts | 4 +- .../shared-undocked-artifacts.spec.ts | 2 +- e2e/specs/mock/shared-links.spec.ts | 6 +- 19 files changed, 731 insertions(+), 228 deletions(-) create mode 100644 client/src/components/Chat/Rename.tsx create mode 100644 client/src/components/Chat/__tests__/Rename.spec.tsx create mode 100644 client/src/hooks/Chat/__tests__/useChatOptions.spec.tsx create mode 100644 client/src/hooks/Chat/useChatOptions.tsx diff --git a/client/src/components/Chat/ExportAndShareMenu.tsx b/client/src/components/Chat/ExportAndShareMenu.tsx index c91d30543f0..89993f052a9 100644 --- a/client/src/components/Chat/ExportAndShareMenu.tsx +++ b/client/src/components/Chat/ExportAndShareMenu.tsx @@ -1,8 +1,8 @@ import { useState, useId } from 'react'; -import { Share2 } from 'lucide-react'; +import { Ellipsis } from 'lucide-react'; import * as Ariakit from '@ariakit/react'; import { DropdownPopup, TooltipAnchor, useMediaQuery } from '@librechat/client'; -import useExportShare from '~/hooks/Chat/useExportShare'; +import useChatOptions from '~/hooks/Chat/useChatOptions'; import { useLocalize } from '~/hooks'; export default function ExportAndShareMenu({ @@ -14,14 +14,17 @@ export default function ExportAndShareMenu({ const menuId = useId(); const [isPopoverActive, setIsPopoverActive] = useState(false); const isSmallScreen = useMediaQuery('(max-width: 768px)'); - const { show, items, hasSharedLink, dialogs } = useExportShare({ isSharedButtonEnabled }); + const { show, items, hasSharedLink, dialogs } = useChatOptions({ + isSharedButtonEnabled, + closeMenu: () => setIsPopoverActive(false), + }); if (!show) { return null; } const description = localize( - hasSharedLink ? 'com_ui_export_share_link_active' : 'com_endpoint_export_share', + hasSharedLink ? 'com_ui_chat_options_link_active' : 'com_ui_chat_options', ); return ( @@ -42,7 +45,7 @@ export default function ExportAndShareMenu({ aria-label={description} className="border-border-light bg-presentation text-text-primary hover:bg-surface-tertiary aria-expanded:bg-surface-tertiary relative inline-flex size-9 shrink-0 items-center justify-center rounded-xl border transition-all ease-in-out disabled:pointer-events-none disabled:opacity-50" > -