mirror of
https://github.com/danny-avila/LibreChat.git
synced 2025-12-18 01:10:14 +01:00
Add Popup Menu to Save Space in Sidebar (#260)
--------- Co-authored-by: Danny Avila <110412045+danny-avila@users.noreply.github.com>
This commit is contained in:
parent
542a46dc7c
commit
93dd1eb036
7 changed files with 106 additions and 17 deletions
|
|
@ -26,8 +26,7 @@ export default function ClearConvos() {
|
||||||
<Dialog>
|
<Dialog>
|
||||||
<DialogTrigger asChild>
|
<DialogTrigger asChild>
|
||||||
<button
|
<button
|
||||||
className="flex cursor-pointer items-center gap-3 rounded-md py-3 px-3 text-sm text-white transition-colors duration-200 hover:bg-gray-500/10"
|
className="flex w-full cursor-pointer items-center gap-3 px-3 py-3 text-sm text-white transition-colors duration-200 hover:bg-gray-700"
|
||||||
// onClick={clickHandler}
|
|
||||||
>
|
>
|
||||||
<TrashIcon />
|
<TrashIcon />
|
||||||
Clear conversations
|
Clear conversations
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ export default function DarkMode() {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<button
|
<button
|
||||||
className="flex cursor-pointer items-center gap-3 rounded-md py-3 px-3 text-sm text-white transition-colors duration-200 hover:bg-gray-500/10"
|
className="flex w-full cursor-pointer items-center gap-3 px-3 py-3 text-sm text-white transition-colors duration-200 hover:bg-gray-700"
|
||||||
onClick={clickHandler}
|
onClick={clickHandler}
|
||||||
>
|
>
|
||||||
{theme === 'dark' ? <LightModeIcon /> : <DarkModeIcon />}
|
{theme === 'dark' ? <LightModeIcon /> : <DarkModeIcon />}
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@ export default function ExportConversation() {
|
||||||
<>
|
<>
|
||||||
<button
|
<button
|
||||||
className={cn(
|
className={cn(
|
||||||
'flex items-center gap-3 rounded-md py-3 px-3 text-sm transition-colors duration-200 hover:bg-gray-500/10',
|
'flex py-3 px-3 items-center gap-3 transition-colors duration-200 text-white cursor-pointer text-sm hover:bg-gray-700 w-full',
|
||||||
exportable ? 'cursor-pointer text-white' : 'cursor-not-allowed text-gray-400'
|
exportable ? 'cursor-pointer text-white' : 'cursor-not-allowed text-gray-400'
|
||||||
)}
|
)}
|
||||||
onClick={clickHandler}
|
onClick={clickHandler}
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ export default function Logout() {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<button
|
<button
|
||||||
className="flex cursor-pointer items-center gap-3 rounded-md py-3 px-3 text-sm text-white transition-colors duration-200 hover:bg-gray-500/10"
|
className="flex py-3 px-3 items-center gap-3 transition-colors duration-200 text-white cursor-pointer text-sm hover:bg-gray-700 w-full"
|
||||||
onClick={handleLogout}
|
onClick={handleLogout}
|
||||||
>
|
>
|
||||||
<LogOutIcon />
|
<LogOutIcon />
|
||||||
|
|
|
||||||
|
|
@ -1,21 +1,77 @@
|
||||||
|
import { Menu, Transition } from '@headlessui/react';
|
||||||
|
import { Fragment, useEffect, useRef, useState } from 'react';
|
||||||
import SearchBar from './SearchBar';
|
import SearchBar from './SearchBar';
|
||||||
import ClearConvos from './ClearConvos';
|
import ClearConvos from './ClearConvos';
|
||||||
import DarkMode from './DarkMode';
|
import DarkMode from './DarkMode';
|
||||||
import Logout from './Logout';
|
import Logout from './Logout';
|
||||||
import ExportConversation from './ExportConversation';
|
import ExportConversation from './ExportConversation';
|
||||||
|
import { useAuthContext } from '~/hooks/AuthContext';
|
||||||
|
import { cn } from '~/utils/';
|
||||||
|
import DotsIcon from '../svg/DotsIcon';
|
||||||
|
|
||||||
export default function NavLinks({ clearSearch, isSearchEnabled }) {
|
export default function NavLinks({ clearSearch, isSearchEnabled }) {
|
||||||
|
const { user, logout } = useAuthContext();
|
||||||
return (
|
return (
|
||||||
<>
|
<Menu
|
||||||
{!!isSearchEnabled && (
|
as="div"
|
||||||
<SearchBar
|
className="group relative"
|
||||||
clearSearch={clearSearch}
|
>
|
||||||
/>
|
{({ open }) => (
|
||||||
|
<>
|
||||||
|
<Menu.Button
|
||||||
|
className={cn(
|
||||||
|
'group-ui-open:bg-gray-800 flex w-full items-center gap-2.5 rounded-md px-3 py-3 text-sm transition-colors duration-200 hover:bg-gray-800',
|
||||||
|
open ? 'bg-gray-800' : ''
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
<div class="-ml-0.5 h-5 w-5 flex-shrink-0">
|
||||||
|
<div class="relative flex">
|
||||||
|
<img
|
||||||
|
class="rounded-sm"
|
||||||
|
src={user?.avatar || `https://avatars.dicebear.com/api/initials/${user?.name}.svg`}
|
||||||
|
alt=""
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="grow overflow-hidden text-ellipsis whitespace-nowrap text-left text-white">
|
||||||
|
{user?.name || 'USER'}
|
||||||
|
</div>
|
||||||
|
<DotsIcon />
|
||||||
|
</Menu.Button>
|
||||||
|
|
||||||
|
<Transition
|
||||||
|
as={Fragment}
|
||||||
|
enter="transition ease-out duration-100"
|
||||||
|
enterFrom="transform opacity-0 scale-95"
|
||||||
|
enterTo="transform opacity-100 scale-100"
|
||||||
|
leave="transition ease-in duration-75"
|
||||||
|
leaveFrom="transform opacity-100 scale-100"
|
||||||
|
leaveTo="transform opacity-0 scale-95"
|
||||||
|
>
|
||||||
|
<Menu.Items className="absolute bottom-full left-0 z-20 mb-2 w-full translate-y-0 overflow-hidden rounded-md bg-[#050509] py-1.5 opacity-100 outline-none">
|
||||||
|
<Menu.Item>
|
||||||
|
{({}) => <>{!!isSearchEnabled && <SearchBar clearSearch={clearSearch} />}</>}
|
||||||
|
</Menu.Item>
|
||||||
|
<Menu.Item>{({}) => <ExportConversation />}</Menu.Item>
|
||||||
|
|
||||||
|
<div
|
||||||
|
class="my-1.5 h-px bg-white/20"
|
||||||
|
role="none"
|
||||||
|
></div>
|
||||||
|
<Menu.Item>{({}) => <DarkMode />}</Menu.Item>
|
||||||
|
<Menu.Item>{({}) => <ClearConvos />}</Menu.Item>
|
||||||
|
|
||||||
|
<div
|
||||||
|
class="my-1.5 h-px bg-white/20"
|
||||||
|
role="none"
|
||||||
|
></div>
|
||||||
|
<Menu.Item>
|
||||||
|
<Logout />
|
||||||
|
</Menu.Item>
|
||||||
|
</Menu.Items>
|
||||||
|
</Transition>
|
||||||
|
</>
|
||||||
)}
|
)}
|
||||||
<ExportConversation />
|
</Menu>
|
||||||
<DarkMode />
|
|
||||||
<ClearConvos />
|
|
||||||
<Logout />
|
|
||||||
</>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -142,8 +142,8 @@ export default function Nav({ navVisible, setNavVisible }) {
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<div className="flex h-full min-h-0 flex-col ">
|
<div className="flex h-full min-h-0 flex-col ">
|
||||||
<div className="scrollbar-trigger flex h-full w-full flex-1 items-start border-white/20">
|
<div className="scrollbar-trigger flex h-full w-full flex-1 items-start border-white/20 relative">
|
||||||
<nav className="flex h-full flex-1 flex-col space-y-1 p-2">
|
<nav className="flex h-full flex-1 flex-col space-y-1 p-2 relative">
|
||||||
<NewChat />
|
<NewChat />
|
||||||
<div
|
<div
|
||||||
className={`flex-1 flex-col overflow-y-auto ${
|
className={`flex-1 flex-col overflow-y-auto ${
|
||||||
|
|
|
||||||
34
client/src/components/svg/DotsIcon.jsx
Normal file
34
client/src/components/svg/DotsIcon.jsx
Normal file
|
|
@ -0,0 +1,34 @@
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
export default function DotsIcon() {
|
||||||
|
return (
|
||||||
|
<svg
|
||||||
|
stroke="currentColor"
|
||||||
|
fill="none"
|
||||||
|
stroke-width="2"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
className="h-4 w-4 flex-shrink-0 text-gray-500"
|
||||||
|
height="1em"
|
||||||
|
width="1em"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
>
|
||||||
|
<circle
|
||||||
|
cx="12"
|
||||||
|
cy="12"
|
||||||
|
r="1"
|
||||||
|
></circle>
|
||||||
|
<circle
|
||||||
|
cx="19"
|
||||||
|
cy="12"
|
||||||
|
r="1"
|
||||||
|
></circle>
|
||||||
|
<circle
|
||||||
|
cx="5"
|
||||||
|
cy="12"
|
||||||
|
r="1"
|
||||||
|
></circle>
|
||||||
|
</svg>
|
||||||
|
);
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue