Make most major changes for an updated chat UI (#843)

- Updated references panel
- Use subtle coloring for chat cards
- Chat streaming with train of thought
- Side panel with limited sessions, expandable
- Manage conversation file filters easily from the side panel
- Updated nav menu, easily go to agents/automations/profile
- Upload data from the chat UI (on click attachment icon)
- Slash command pop-up menu, scrollable and selectable
- Dark mode-enabled
- Mostly mobile friendly
This commit is contained in:
sabaimran
2024-07-14 10:48:06 -07:00
committed by GitHub
parent 02658ad4fd
commit 06dce4729b
46 changed files with 5652 additions and 954 deletions

View File

@@ -11,26 +11,19 @@ menu.menu a {
gap: 4px;
}
menu.menu a.selected {
background-color: var(--primary-hover);
}
menu.menu a:hover {
background-color: var(--primary-hover);
}
menu.menu {
display: flex;
justify-content: space-around;
padding: 0;
margin: 0;
a.selected {
background-color: hsl(var(--accent));
}
div.titleBar {
display: grid;
grid-template-columns: 1fr auto;
padding: 16px 0;
margin: auto;
display: flex;
padding-left: 12px;
padding-right: 32px;
padding-top: 16px;
padding-bottom: 16px;
justify-content: space-between;
align-content: space-evenly;
align-items: start;
}
div.titleBar menu {
@@ -75,14 +68,6 @@ div.settingsMenuOptions {
border-radius: 8px;
}
div.settingsMenuOptions a {
padding: 4px;
}
div.settingsMenuUsername {
font-weight: bold;
}
@media screen and (max-width: 600px) {
menu.menu span {
display: none;
@@ -91,4 +76,8 @@ div.settingsMenuUsername {
div.settingsMenuOptions {
right: 4px;
}
div.titleBar {
padding: 8px;
}
}

View File

@@ -1,106 +1,164 @@
'use client'
import styles from './navMenu.module.css';
import Image from 'next/image';
import Link from 'next/link';
import { useAuthenticatedData, UserProfile } from '@/app/common/auth';
import { useState } from 'react';
import { useState, useEffect } from 'react';
import {
Menubar,
MenubarContent,
MenubarItem,
MenubarMenu,
MenubarSeparator,
MenubarTrigger,
} from "@/components/ui/menubar";
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuLabel,
DropdownMenuSeparator,
DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
import { Toggle } from '@/components/ui/toggle';
import { Moon } from '@phosphor-icons/react';
interface NavMenuProps {
selected: string;
showLogo?: boolean;
title?: string;
}
function SettingsMenu(props: UserProfile) {
const [showSettings, setShowSettings] = useState(false);
return (
<div className={styles.settingsMenu}>
<div className={styles.settingsMenuProfile} onClick={() => setShowSettings(!showSettings)}>
<Image
src={props.photo || "/agents.svg"}
alt={props.username}
width={50}
height={50}
/>
</div>
{showSettings && (
<div className={styles.settingsMenuOptions}>
<div className={styles.settingsMenuUsername}>{props.username}</div>
<Link href="/config">
Settings
</Link>
<Link href="https://github.com/khoj-ai/khoj">
Github
</Link>
<Link href="https://docs.khoj.dev">
Help
</Link>
<Link href="/auth/logout">
Logout
</Link>
</div>
)}
</div>
);
}
export default function NavMenu(props: NavMenuProps) {
let userData = useAuthenticatedData();
const userData = useAuthenticatedData();
const [displayTitle, setDisplayTitle] = useState<string>(props.title || props.selected.toUpperCase());
const [isMobileWidth, setIsMobileWidth] = useState(false);
const [darkMode, setDarkMode] = useState(false);
useEffect(() => {
setIsMobileWidth(window.innerWidth < 768);
setDisplayTitle(props.title || props.selected.toUpperCase());
}, [props.title]);
useEffect(() => {
window.addEventListener('resize', () => {
setIsMobileWidth(window.innerWidth < 768);
});
if (localStorage.getItem('theme') === 'dark') {
document.documentElement.classList.add('dark');
setDarkMode(true);
}
}, []);
useEffect(() => {
toggleDarkMode(darkMode);
}, [darkMode]);
function toggleDarkMode(darkMode: boolean) {
if (darkMode) {
document.documentElement.classList.add('dark');
} else {
document.documentElement.classList.remove('dark');
}
localStorage.setItem('theme', darkMode ? 'dark' : 'light');
}
return (
<div className={styles.titleBar}>
<Link href="/">
<Image
src="/khoj-logo.svg"
alt="Khoj Logo"
className={styles.logo}
width={100}
height={50}
priority
/>
</Link>
<menu className={styles.menu}>
<a className={props.selected === "Chat" ? styles.selected : ""} href = '/chat'>
<Image
src="/chat.svg"
alt="Chat Logo"
className={styles.lgoo}
width={24}
height={24}
priority
/>
<span>
Chat
</span>
</a>
<a className={props.selected === "Agents" ? styles.selected : ""} href='/agents'>
<Image
src="/agents.svg"
alt="Agent Logo"
className={styles.lgoo}
width={24}
height={24}
priority
/>
<span>
Agents
</span>
</a>
<a className={props.selected === "Automations" ? styles.selected : ""} href = '/automations'>
<Image
src="/automation.svg"
alt="Automation Logo"
className={styles.lgoo}
width={24}
height={24}
priority
/>
<span>
Automations
</span>
</a>
{userData && <SettingsMenu {...userData} />}
</menu>
<div className={`text-nowrap text-ellipsis overflow-hidden max-w-screen-md grid items-top font-bold mr-8`}>
{displayTitle && <h2 className={`text-lg text-ellipsis whitespace-nowrap overflow-x-hidden`} >{displayTitle}</h2>}
</div>
{
isMobileWidth ?
<DropdownMenu>
<DropdownMenuTrigger>=</DropdownMenuTrigger>
<DropdownMenuContent>
<DropdownMenuItem>
<Link href='/chat' className={`${props.selected.toLowerCase() === 'chat' ? styles.selected : ''} hover:bg-background`}>Chat</Link>
</DropdownMenuItem>
<DropdownMenuItem>
<Link href='/agents' className={`${props.selected.toLowerCase() === 'agent' ? styles.selected : ''} hover:bg-background`}>Agents</Link>
</DropdownMenuItem>
<DropdownMenuItem>
<Link href='/automations' className={`${props.selected.toLowerCase() === 'automations' ? styles.selected : ''} hover:bg-background`}>Automations</Link>
</DropdownMenuItem>
{userData && <>
<DropdownMenuSeparator />
<DropdownMenuLabel>Profile</DropdownMenuLabel>
<DropdownMenuItem>
<Link href="/config">Settings</Link>
</DropdownMenuItem>
<DropdownMenuItem>
<Link href="https://docs.khoj.dev">Help</Link>
</DropdownMenuItem>
<DropdownMenuItem>
<Link href="/auth/logout">Logout</Link>
</DropdownMenuItem>
</>}
</DropdownMenuContent>
</DropdownMenu>
:
<Menubar className='items-top inline-flex h-9 items-center justify-center rounded-lg bg-muted p-1 text-muted-foreground'>
<MenubarMenu>
<Link href='/chat' target="_blank" rel="noreferrer" className={`${props.selected.toLowerCase() === 'chat' ? styles.selected : ''} hover:bg-background`}>
<MenubarTrigger>Chat</MenubarTrigger>
</Link>
</MenubarMenu>
<MenubarMenu>
<Link href='/agents' target="_blank" rel="noreferrer" className={`${props.selected.toLowerCase() === 'agent' ? styles.selected : ''} hover:bg-background`}>
<MenubarTrigger>Agents</MenubarTrigger>
</Link>
</MenubarMenu>
<MenubarMenu>
<Link href='/automations' target="_blank" rel="noreferrer" className={`${props.selected.toLowerCase() === 'automations' ? styles.selected : ''} hover:bg-background`}>
<MenubarTrigger>Automations</MenubarTrigger>
</Link>
</MenubarMenu>
<MenubarMenu>
<MenubarTrigger>Profile</MenubarTrigger>
<MenubarContent>
<MenubarItem>
<Toggle
pressed={darkMode}
onClick={() => {
setDarkMode(!darkMode)
}
}>
<Moon />
</Toggle>
</MenubarItem>
{userData &&
<>
<MenubarItem>
<Link href="/config">
Settings
</Link>
</MenubarItem>
<MenubarSeparator />
<MenubarItem>
<Link href="https://docs.khoj.dev">
Help
</Link>
</MenubarItem>
<MenubarSeparator />
<MenubarItem>
<Link href="/auth/logout">
Logout
</Link>
</MenubarItem>
</>
}
</MenubarContent>
</MenubarMenu>
</Menubar>
}
</div>
)
}