chore: placement menu leftpanel, and ux create add projects

This commit is contained in:
Faisal Amir 2025-09-29 13:44:56 +07:00
parent 311b79fe13
commit b4df56e0d8
4 changed files with 64 additions and 7 deletions

View File

@ -1,4 +1,4 @@
import { Link, useRouterState } from '@tanstack/react-router' import { Link, useRouterState, useNavigate } from '@tanstack/react-router'
import { useLeftPanel } from '@/hooks/useLeftPanel' import { useLeftPanel } from '@/hooks/useLeftPanel'
import { cn } from '@/lib/utils' import { cn } from '@/lib/utils'
import { import {
@ -58,6 +58,9 @@ const mainMenus = [
route: route.project, route: route.project,
isEnabled: true, isEnabled: true,
}, },
]
const secondaryMenus = [
{ {
title: 'common:assistants', title: 'common:assistants',
icon: IconClipboardSmile, icon: IconClipboardSmile,
@ -82,6 +85,7 @@ const LeftPanel = () => {
const open = useLeftPanel((state) => state.open) const open = useLeftPanel((state) => state.open)
const setLeftPanel = useLeftPanel((state) => state.setLeftPanel) const setLeftPanel = useLeftPanel((state) => state.setLeftPanel)
const { t } = useTranslation() const { t } = useTranslation()
const navigate = useNavigate()
const [searchTerm, setSearchTerm] = useState('') const [searchTerm, setSearchTerm] = useState('')
const { isAuthenticated } = useAuth() const { isAuthenticated } = useAuth()
@ -212,7 +216,12 @@ const LeftPanel = () => {
if (editingProjectKey) { if (editingProjectKey) {
updateFolder(editingProjectKey, name) updateFolder(editingProjectKey, name)
} else { } else {
addFolder(name) const newProject = addFolder(name)
// Navigate to the newly created project
navigate({
to: '/project/$projectId',
params: { projectId: newProject.id },
})
} }
setProjectDialogOpen(false) setProjectDialogOpen(false)
setEditingProjectKey(null) setEditingProjectKey(null)
@ -487,7 +496,7 @@ const LeftPanel = () => {
)} )}
<div className="flex flex-col h-full overflow-y-scroll w-[calc(100%+6px)]"> <div className="flex flex-col h-full overflow-y-scroll w-[calc(100%+6px)]">
<div className="flex flex-col w-full h-full overflow-y-auto overflow-x-hidden"> <div className="flex flex-col w-full h-full overflow-y-auto overflow-x-hidden mb-3">
<div className="h-full w-full overflow-y-auto"> <div className="h-full w-full overflow-y-auto">
{favoritedThreads.length > 0 && ( {favoritedThreads.length > 0 && (
<> <>
@ -607,6 +616,44 @@ const LeftPanel = () => {
</div> </div>
</div> </div>
</div> </div>
{secondaryMenus.map((menu) => {
if (!menu.isEnabled) {
return null
}
// Regular menu items must have route and icon
if (!menu.route || !menu.icon) return null
const isActive = (() => {
// Settings routes
if (menu.route.includes(route.settings.index)) {
return currentPath.includes(route.settings.index)
}
// Default exact match for other routes
return currentPath === menu.route
})()
return (
<Link
key={menu.title}
to={menu.route}
onClick={() => isSmallScreen && setLeftPanel(false)}
data-test-id={`menu-${menu.title}`}
activeOptions={{ exact: true }}
className={cn(
'flex items-center gap-1.5 cursor-pointer hover:bg-left-panel-fg/10 py-1 px-1 rounded',
isActive && 'bg-left-panel-fg/10'
)}
>
<menu.icon size={18} className="text-left-panel-fg/70" />
<span className="font-medium text-left-panel-fg/90">
{t(menu.title)}
</span>
</Link>
)
})}
{PlatformFeatures[PlatformFeature.AUTHENTICATION] && ( {PlatformFeatures[PlatformFeature.AUTHENTICATION] && (
<div className="space-y-1 shrink-0 py-1"> <div className="space-y-1 shrink-0 py-1">
<div> <div>

View File

@ -185,7 +185,10 @@ const SortableItem = memo(
<DropdownMenuTrigger asChild> <DropdownMenuTrigger asChild>
<IconDots <IconDots
size={14} size={14}
className="text-left-panel-fg/60 shrink-0 cursor-pointer px-0.5 -mr-1 data-[state=open]:bg-left-panel-fg/10 rounded group-hover/thread-list:data-[state=closed]:size-5 size-5 data-[state=closed]:size-0" className={cn(
'text-left-panel-fg/60 shrink-0 cursor-pointer px-0.5 -mr-1 data-[state=open]:bg-left-panel-fg/10 rounded group-hover/thread-list:data-[state=closed]:size-5 size-5 data-[state=closed]:size-0',
variant === 'project' && 'text-main-view-fg/60'
)}
onClick={(e) => { onClick={(e) => {
e.preventDefault() e.preventDefault()
e.stopPropagation() e.stopPropagation()

View File

@ -13,7 +13,7 @@ type ThreadFolder = {
type ThreadManagementState = { type ThreadManagementState = {
folders: ThreadFolder[] folders: ThreadFolder[]
setFolders: (folders: ThreadFolder[]) => void setFolders: (folders: ThreadFolder[]) => void
addFolder: (name: string) => void addFolder: (name: string) => ThreadFolder
updateFolder: (id: string, name: string) => void updateFolder: (id: string, name: string) => void
deleteFolder: (id: string) => void deleteFolder: (id: string) => void
getFolderById: (id: string) => ThreadFolder | undefined getFolderById: (id: string) => ThreadFolder | undefined
@ -37,6 +37,7 @@ export const useThreadManagement = create<ThreadManagementState>()(
set((state) => ({ set((state) => ({
folders: [...state.folders, newFolder], folders: [...state.folders, newFolder],
})) }))
return newFolder
}, },
updateFolder: (id, name) => { updateFolder: (id, name) => {

View File

@ -1,4 +1,4 @@
import { createFileRoute } from '@tanstack/react-router' import { createFileRoute, useNavigate } from '@tanstack/react-router'
import { useState, useMemo } from 'react' import { useState, useMemo } from 'react'
import { useThreadManagement } from '@/hooks/useThreadManagement' import { useThreadManagement } from '@/hooks/useThreadManagement'
@ -31,6 +31,7 @@ function Project() {
function ProjectContent() { function ProjectContent() {
const { t } = useTranslation() const { t } = useTranslation()
const navigate = useNavigate()
const { folders, addFolder, updateFolder, deleteFolder, getFolderById } = const { folders, addFolder, updateFolder, deleteFolder, getFolderById } =
useThreadManagement() useThreadManagement()
const threads = useThreads((state) => state.threads) const threads = useThreads((state) => state.threads)
@ -59,7 +60,12 @@ function ProjectContent() {
if (editingKey) { if (editingKey) {
updateFolder(editingKey, name) updateFolder(editingKey, name)
} else { } else {
addFolder(name) const newProject = addFolder(name)
// Navigate to the newly created project
navigate({
to: '/project/$projectId',
params: { projectId: newProject.id },
})
} }
setOpen(false) setOpen(false)
setEditingKey(null) setEditingKey(null)