feat: move icon create new thread into top panel (#3346)
* feat: move icon create new thread into top panel * chore: update conditional chcck length
This commit is contained in:
parent
8b44613015
commit
46cb1b45b9
@ -1,4 +1,4 @@
|
|||||||
import { Fragment } from 'react'
|
import { Fragment, useCallback, useEffect } from 'react'
|
||||||
|
|
||||||
import { Button } from '@janhq/joi'
|
import { Button } from '@janhq/joi'
|
||||||
import { useAtom, useAtomValue, useSetAtom } from 'jotai'
|
import { useAtom, useAtomValue, useSetAtom } from 'jotai'
|
||||||
@ -12,22 +12,35 @@ import {
|
|||||||
SquareIcon,
|
SquareIcon,
|
||||||
PaletteIcon,
|
PaletteIcon,
|
||||||
XIcon,
|
XIcon,
|
||||||
|
PenSquareIcon,
|
||||||
} from 'lucide-react'
|
} from 'lucide-react'
|
||||||
import { twMerge } from 'tailwind-merge'
|
import { twMerge } from 'tailwind-merge'
|
||||||
|
|
||||||
import LogoMark from '@/containers/Brand/Logo/Mark'
|
import LogoMark from '@/containers/Brand/Logo/Mark'
|
||||||
|
|
||||||
|
import { toaster } from '@/containers/Toast'
|
||||||
|
|
||||||
|
import useAssistantQuery from '@/hooks/useAssistantQuery'
|
||||||
|
import useThreadCreateMutation from '@/hooks/useThreadCreateMutation'
|
||||||
|
import useThreads from '@/hooks/useThreads'
|
||||||
|
|
||||||
|
import { copyOverInstructionEnabledAtom } from '@/screens/Thread/ThreadRightPanel/AssistantSettingContainer/components/CopyOverInstruction'
|
||||||
|
|
||||||
import {
|
import {
|
||||||
MainViewState,
|
MainViewState,
|
||||||
mainViewStateAtom,
|
mainViewStateAtom,
|
||||||
showLeftPanelAtom,
|
showLeftPanelAtom,
|
||||||
showRightPanelAtom,
|
showRightPanelAtom,
|
||||||
} from '@/helpers/atoms/App.atom'
|
} from '@/helpers/atoms/App.atom'
|
||||||
import { downloadedModelsAtom } from '@/helpers/atoms/Model.atom'
|
import {
|
||||||
|
downloadedModelsAtom,
|
||||||
|
getSelectedModelAtom,
|
||||||
|
} from '@/helpers/atoms/Model.atom'
|
||||||
import {
|
import {
|
||||||
reduceTransparentAtom,
|
reduceTransparentAtom,
|
||||||
selectedSettingAtom,
|
selectedSettingAtom,
|
||||||
} from '@/helpers/atoms/Setting.atom'
|
} from '@/helpers/atoms/Setting.atom'
|
||||||
|
import { threadsAtom, activeThreadAtom } from '@/helpers/atoms/Thread.atom'
|
||||||
|
|
||||||
const TopPanel = () => {
|
const TopPanel = () => {
|
||||||
const [showLeftPanel, setShowLeftPanel] = useAtom(showLeftPanelAtom)
|
const [showLeftPanel, setShowLeftPanel] = useAtom(showLeftPanelAtom)
|
||||||
@ -37,6 +50,51 @@ const TopPanel = () => {
|
|||||||
const reduceTransparent = useAtomValue(reduceTransparentAtom)
|
const reduceTransparent = useAtomValue(reduceTransparentAtom)
|
||||||
const downloadedModels = useAtomValue(downloadedModelsAtom)
|
const downloadedModels = useAtomValue(downloadedModelsAtom)
|
||||||
|
|
||||||
|
const { setActiveThread } = useThreads()
|
||||||
|
const createThreadMutation = useThreadCreateMutation()
|
||||||
|
|
||||||
|
const selectedModel = useAtomValue(getSelectedModelAtom)
|
||||||
|
const threads = useAtomValue(threadsAtom)
|
||||||
|
|
||||||
|
const activeThread = useAtomValue(activeThreadAtom)
|
||||||
|
const { data: assistants } = useAssistantQuery()
|
||||||
|
const copyOverInstructionEnabled = useAtomValue(
|
||||||
|
copyOverInstructionEnabledAtom
|
||||||
|
)
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (activeThread?.id) return
|
||||||
|
if (threads.length === 0) return
|
||||||
|
setActiveThread(threads[0].id)
|
||||||
|
}, [activeThread?.id, setActiveThread, threads])
|
||||||
|
|
||||||
|
const onCreateThreadClicked = useCallback(async () => {
|
||||||
|
if (!assistants || assistants.length) {
|
||||||
|
toaster({
|
||||||
|
title: 'No assistant available.',
|
||||||
|
description: `Could not create a new thread. Please add an assistant.`,
|
||||||
|
type: 'error',
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (!selectedModel) return
|
||||||
|
let instructions: string | undefined = undefined
|
||||||
|
if (copyOverInstructionEnabled) {
|
||||||
|
instructions = activeThread?.assistants[0]?.instructions ?? undefined
|
||||||
|
}
|
||||||
|
await createThreadMutation.mutateAsync({
|
||||||
|
modelId: selectedModel.model,
|
||||||
|
assistant: assistants[0],
|
||||||
|
instructions,
|
||||||
|
})
|
||||||
|
}, [
|
||||||
|
createThreadMutation,
|
||||||
|
selectedModel,
|
||||||
|
assistants,
|
||||||
|
activeThread,
|
||||||
|
copyOverInstructionEnabled,
|
||||||
|
])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={twMerge(
|
className={twMerge(
|
||||||
@ -73,6 +131,18 @@ const TopPanel = () => {
|
|||||||
)}
|
)}
|
||||||
</Fragment>
|
</Fragment>
|
||||||
)}
|
)}
|
||||||
|
{mainViewState === MainViewState.Thread && (
|
||||||
|
<Button
|
||||||
|
data-testid="btn-create-thread"
|
||||||
|
onClick={onCreateThreadClicked}
|
||||||
|
theme="icon"
|
||||||
|
>
|
||||||
|
<PenSquareIcon
|
||||||
|
size={16}
|
||||||
|
className="cursor-pointer text-[hsla(var(--text-secondary))]"
|
||||||
|
/>
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div className="unset-drag flex items-center gap-x-2">
|
<div className="unset-drag flex items-center gap-x-2">
|
||||||
{mainViewState !== MainViewState.Hub &&
|
{mainViewState !== MainViewState.Hub &&
|
||||||
|
|||||||
@ -1,89 +1,21 @@
|
|||||||
import { useCallback, useEffect } from 'react'
|
|
||||||
|
|
||||||
import { Button } from '@janhq/joi'
|
|
||||||
import { AnimatePresence } from 'framer-motion'
|
import { AnimatePresence } from 'framer-motion'
|
||||||
|
|
||||||
import { useAtomValue } from 'jotai'
|
import { useAtomValue } from 'jotai'
|
||||||
import { PenSquareIcon } from 'lucide-react'
|
|
||||||
|
|
||||||
import { twMerge } from 'tailwind-merge'
|
import { twMerge } from 'tailwind-merge'
|
||||||
|
|
||||||
import LeftPanelContainer from '@/containers/LeftPanelContainer'
|
import LeftPanelContainer from '@/containers/LeftPanelContainer'
|
||||||
import { toaster } from '@/containers/Toast'
|
|
||||||
|
|
||||||
import useAssistantQuery from '@/hooks/useAssistantQuery'
|
|
||||||
|
|
||||||
import useThreadCreateMutation from '@/hooks/useThreadCreateMutation'
|
|
||||||
|
|
||||||
import useThreads from '@/hooks/useThreads'
|
|
||||||
|
|
||||||
import { copyOverInstructionEnabledAtom } from '../ThreadRightPanel/AssistantSettingContainer/components/CopyOverInstruction'
|
|
||||||
|
|
||||||
import ThreadItem from './ThreadItem'
|
import ThreadItem from './ThreadItem'
|
||||||
|
|
||||||
import { getSelectedModelAtom } from '@/helpers/atoms/Model.atom'
|
import { threadsAtom } from '@/helpers/atoms/Thread.atom'
|
||||||
import { activeThreadAtom, threadsAtom } from '@/helpers/atoms/Thread.atom'
|
|
||||||
|
|
||||||
const ThreadLeftPanel: React.FC = () => {
|
const ThreadLeftPanel: React.FC = () => {
|
||||||
const { setActiveThread } = useThreads()
|
|
||||||
const createThreadMutation = useThreadCreateMutation()
|
|
||||||
|
|
||||||
const selectedModel = useAtomValue(getSelectedModelAtom)
|
|
||||||
const threads = useAtomValue(threadsAtom)
|
const threads = useAtomValue(threadsAtom)
|
||||||
|
|
||||||
const activeThread = useAtomValue(activeThreadAtom)
|
|
||||||
const { data: assistants } = useAssistantQuery()
|
|
||||||
const copyOverInstructionEnabled = useAtomValue(
|
|
||||||
copyOverInstructionEnabledAtom
|
|
||||||
)
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (activeThread?.id) return
|
|
||||||
if (threads.length === 0) return
|
|
||||||
setActiveThread(threads[0].id)
|
|
||||||
}, [activeThread?.id, setActiveThread, threads])
|
|
||||||
|
|
||||||
const onCreateThreadClicked = useCallback(async () => {
|
|
||||||
if (!assistants || assistants.length === 0) {
|
|
||||||
toaster({
|
|
||||||
title: 'No assistant available.',
|
|
||||||
description: `Could not create a new thread. Please add an assistant.`,
|
|
||||||
type: 'error',
|
|
||||||
})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if (!selectedModel) return
|
|
||||||
let instructions: string | undefined = undefined
|
|
||||||
if (copyOverInstructionEnabled) {
|
|
||||||
instructions = activeThread?.assistants[0]?.instructions ?? undefined
|
|
||||||
}
|
|
||||||
await createThreadMutation.mutateAsync({
|
|
||||||
modelId: selectedModel.model,
|
|
||||||
assistant: assistants[0],
|
|
||||||
instructions,
|
|
||||||
})
|
|
||||||
}, [
|
|
||||||
createThreadMutation,
|
|
||||||
selectedModel,
|
|
||||||
assistants,
|
|
||||||
activeThread,
|
|
||||||
copyOverInstructionEnabled,
|
|
||||||
])
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<LeftPanelContainer>
|
<LeftPanelContainer>
|
||||||
<div className={twMerge('pl-1.5 pt-3')}>
|
<div className={twMerge('pl-1.5 pt-3')}>
|
||||||
<Button
|
|
||||||
className="mb-2"
|
|
||||||
data-testid="btn-create-thread"
|
|
||||||
onClick={onCreateThreadClicked}
|
|
||||||
theme="icon"
|
|
||||||
>
|
|
||||||
<PenSquareIcon
|
|
||||||
size={16}
|
|
||||||
className="cursor-pointer text-[hsla(var(--text-secondary))]"
|
|
||||||
/>
|
|
||||||
</Button>
|
|
||||||
<AnimatePresence>
|
<AnimatePresence>
|
||||||
{threads.map((thread) => (
|
{threads.map((thread) => (
|
||||||
<ThreadItem key={thread.id} thread={thread} />
|
<ThreadItem key={thread.id} thread={thread} />
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user