mirror of
https://github.com/langgenius/dify.git
synced 2026-04-27 11:06:46 +08:00
fix(web): use nuqs for log conversation url state (#34820)
This commit is contained in:
parent
4c05316a7b
commit
8225f98565
@ -1,14 +1,13 @@
|
|||||||
/* eslint-disable ts/no-explicit-any */
|
/* eslint-disable ts/no-explicit-any */
|
||||||
import type { ReactNode } from 'react'
|
import type { ReactNode } from 'react'
|
||||||
import { act, fireEvent, render, screen, waitFor } from '@testing-library/react'
|
import { act, fireEvent, screen, waitFor } from '@testing-library/react'
|
||||||
|
import { renderWithNuqs } from '@/test/nuqs-testing'
|
||||||
import { AppModeEnum } from '@/types/app'
|
import { AppModeEnum } from '@/types/app'
|
||||||
import ConversationList from '../list'
|
import ConversationList from '../list'
|
||||||
|
|
||||||
const mockFetchChatMessages = vi.fn()
|
const mockFetchChatMessages = vi.fn()
|
||||||
const mockUpdateLogMessageFeedbacks = vi.fn()
|
const mockUpdateLogMessageFeedbacks = vi.fn()
|
||||||
const mockUpdateLogMessageAnnotations = vi.fn()
|
const mockUpdateLogMessageAnnotations = vi.fn()
|
||||||
const mockPush = vi.fn()
|
|
||||||
const mockReplace = vi.fn()
|
|
||||||
const mockOnRefresh = vi.fn()
|
const mockOnRefresh = vi.fn()
|
||||||
const mockSetCurrentLogItem = vi.fn()
|
const mockSetCurrentLogItem = vi.fn()
|
||||||
const mockSetShowPromptLogModal = vi.fn()
|
const mockSetShowPromptLogModal = vi.fn()
|
||||||
@ -17,7 +16,6 @@ const mockSetShowMessageLogModal = vi.fn()
|
|||||||
const mockCompletionRefetch = vi.fn()
|
const mockCompletionRefetch = vi.fn()
|
||||||
const mockDelAnnotation = vi.fn()
|
const mockDelAnnotation = vi.fn()
|
||||||
|
|
||||||
let mockSearchParams = new URLSearchParams()
|
|
||||||
let mockChatConversationDetail: Record<string, unknown> | undefined
|
let mockChatConversationDetail: Record<string, unknown> | undefined
|
||||||
let mockCompletionConversationDetail: Record<string, unknown> | undefined
|
let mockCompletionConversationDetail: Record<string, unknown> | undefined
|
||||||
let mockShowMessageLogModal = false
|
let mockShowMessageLogModal = false
|
||||||
@ -53,18 +51,6 @@ vi.mock('@/hooks/use-breakpoints', () => ({
|
|||||||
},
|
},
|
||||||
}))
|
}))
|
||||||
|
|
||||||
vi.mock('@/next/navigation', () => ({
|
|
||||||
useRouter: () => ({
|
|
||||||
push: mockPush,
|
|
||||||
replace: mockReplace,
|
|
||||||
}),
|
|
||||||
usePathname: () => '/apps/app-1/logs',
|
|
||||||
useSearchParams: () => ({
|
|
||||||
get: (key: string) => mockSearchParams.get(key),
|
|
||||||
toString: () => mockSearchParams.toString(),
|
|
||||||
}),
|
|
||||||
}))
|
|
||||||
|
|
||||||
vi.mock('@/service/use-log', () => ({
|
vi.mock('@/service/use-log', () => ({
|
||||||
useChatConversationDetail: () => ({
|
useChatConversationDetail: () => ({
|
||||||
data: mockChatConversationDetail,
|
data: mockChatConversationDetail,
|
||||||
@ -256,10 +242,28 @@ const createChatMessage = (id: string, overrides: Record<string, unknown> = {})
|
|||||||
...overrides,
|
...overrides,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const renderConversationList = ({
|
||||||
|
appDetail = { id: 'app-1', mode: AppModeEnum.CHAT } as any,
|
||||||
|
logs = createLogs() as any,
|
||||||
|
searchParams = '?page=2',
|
||||||
|
}: {
|
||||||
|
appDetail?: any
|
||||||
|
logs?: any
|
||||||
|
searchParams?: string
|
||||||
|
} = {}) => {
|
||||||
|
return renderWithNuqs(
|
||||||
|
<ConversationList
|
||||||
|
appDetail={appDetail}
|
||||||
|
logs={logs}
|
||||||
|
onRefresh={mockOnRefresh}
|
||||||
|
/>,
|
||||||
|
{ searchParams },
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
describe('ConversationList', () => {
|
describe('ConversationList', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
vi.clearAllMocks()
|
vi.clearAllMocks()
|
||||||
mockSearchParams = new URLSearchParams('page=2')
|
|
||||||
mockChatConversationDetail = undefined
|
mockChatConversationDetail = undefined
|
||||||
mockCompletionConversationDetail = undefined
|
mockCompletionConversationDetail = undefined
|
||||||
mockShowMessageLogModal = false
|
mockShowMessageLogModal = false
|
||||||
@ -273,34 +277,29 @@ describe('ConversationList', () => {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should render chat rows and push the conversation id into the url when a row is clicked', () => {
|
it('should render chat rows and push the conversation id into the url when a row is clicked', async () => {
|
||||||
render(
|
const { onUrlUpdate } = renderConversationList()
|
||||||
<ConversationList
|
|
||||||
appDetail={{ id: 'app-1', mode: AppModeEnum.CHAT } as any}
|
|
||||||
logs={createLogs() as any}
|
|
||||||
onRefresh={mockOnRefresh}
|
|
||||||
/>,
|
|
||||||
)
|
|
||||||
|
|
||||||
expect(screen.getByText('hello world')).toBeInTheDocument()
|
expect(screen.getByText('hello world')).toBeInTheDocument()
|
||||||
expect(screen.getAllByText('formatted-1710000000')).toHaveLength(2)
|
expect(screen.getAllByText('formatted-1710000000')).toHaveLength(2)
|
||||||
|
|
||||||
fireEvent.click(screen.getByText('hello world'))
|
fireEvent.click(screen.getByText('hello world'))
|
||||||
|
|
||||||
expect(mockPush).toHaveBeenCalledWith('/apps/app-1/logs?page=2&conversation_id=conversation-1', { scroll: false })
|
await waitFor(() => {
|
||||||
expect(screen.getByTestId('drawer')).toBeInTheDocument()
|
expect(onUrlUpdate).toHaveBeenCalled()
|
||||||
|
expect(screen.getByTestId('drawer')).toBeInTheDocument()
|
||||||
|
})
|
||||||
|
|
||||||
|
const update = onUrlUpdate.mock.calls.at(-1)![0]
|
||||||
|
expect(update.searchParams.get('page')).toBe('2')
|
||||||
|
expect(update.searchParams.get('conversation_id')).toBe('conversation-1')
|
||||||
|
expect(update.options.history).toBe('push')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should close the drawer, refresh, and clear modal flags', () => {
|
it('should close the drawer, refresh, and clear modal flags', async () => {
|
||||||
mockSearchParams = new URLSearchParams('page=2&conversation_id=conversation-1')
|
const { onUrlUpdate } = renderConversationList({
|
||||||
|
searchParams: '?page=2&conversation_id=conversation-1',
|
||||||
render(
|
})
|
||||||
<ConversationList
|
|
||||||
appDetail={{ id: 'app-1', mode: AppModeEnum.CHAT } as any}
|
|
||||||
logs={createLogs() as any}
|
|
||||||
onRefresh={mockOnRefresh}
|
|
||||||
/>,
|
|
||||||
)
|
|
||||||
|
|
||||||
fireEvent.click(screen.getByText('close-drawer'))
|
fireEvent.click(screen.getByText('close-drawer'))
|
||||||
|
|
||||||
@ -308,11 +307,18 @@ describe('ConversationList', () => {
|
|||||||
expect(mockSetShowPromptLogModal).toHaveBeenCalledWith(false)
|
expect(mockSetShowPromptLogModal).toHaveBeenCalledWith(false)
|
||||||
expect(mockSetShowAgentLogModal).toHaveBeenCalledWith(false)
|
expect(mockSetShowAgentLogModal).toHaveBeenCalledWith(false)
|
||||||
expect(mockSetShowMessageLogModal).toHaveBeenCalledWith(false)
|
expect(mockSetShowMessageLogModal).toHaveBeenCalledWith(false)
|
||||||
expect(mockReplace).toHaveBeenCalledWith('/apps/app-1/logs?page=2', { scroll: false })
|
|
||||||
|
await waitFor(() => {
|
||||||
|
expect(onUrlUpdate).toHaveBeenCalled()
|
||||||
|
})
|
||||||
|
|
||||||
|
const update = onUrlUpdate.mock.calls.at(-1)![0]
|
||||||
|
expect(update.searchParams.get('page')).toBe('2')
|
||||||
|
expect(update.searchParams.has('conversation_id')).toBe(false)
|
||||||
|
expect(update.options.history).toBe('replace')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should render chat conversation details and submit feedback from the chat panel', async () => {
|
it('should render chat conversation details and submit feedback from the chat panel', async () => {
|
||||||
mockSearchParams = new URLSearchParams('page=2&conversation_id=conversation-1')
|
|
||||||
mockChatConversationDetail = {
|
mockChatConversationDetail = {
|
||||||
id: 'conversation-1',
|
id: 'conversation-1',
|
||||||
created_at: 1710000000,
|
created_at: 1710000000,
|
||||||
@ -355,13 +361,9 @@ describe('ConversationList', () => {
|
|||||||
mockShowMessageLogModal = true
|
mockShowMessageLogModal = true
|
||||||
mockCurrentLogItem = { id: 'log-1' }
|
mockCurrentLogItem = { id: 'log-1' }
|
||||||
|
|
||||||
render(
|
renderConversationList({
|
||||||
<ConversationList
|
searchParams: '?page=2&conversation_id=conversation-1',
|
||||||
appDetail={{ id: 'app-1', mode: AppModeEnum.CHAT } as any}
|
})
|
||||||
logs={createLogs() as any}
|
|
||||||
onRefresh={mockOnRefresh}
|
|
||||||
/>,
|
|
||||||
)
|
|
||||||
|
|
||||||
await waitFor(() => {
|
await waitFor(() => {
|
||||||
expect(mockFetchChatMessages).toHaveBeenCalledWith({
|
expect(mockFetchChatMessages).toHaveBeenCalledWith({
|
||||||
@ -396,7 +398,6 @@ describe('ConversationList', () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
it('should render completion details and refetch after feedback updates', async () => {
|
it('should render completion details and refetch after feedback updates', async () => {
|
||||||
mockSearchParams = new URLSearchParams('page=2&conversation_id=conversation-1')
|
|
||||||
mockCompletionConversationDetail = {
|
mockCompletionConversationDetail = {
|
||||||
id: 'conversation-1',
|
id: 'conversation-1',
|
||||||
created_at: 1710000000,
|
created_at: 1710000000,
|
||||||
@ -423,13 +424,11 @@ describe('ConversationList', () => {
|
|||||||
mockShowPromptLogModal = true
|
mockShowPromptLogModal = true
|
||||||
mockCurrentLogItem = { id: 'log-2' }
|
mockCurrentLogItem = { id: 'log-2' }
|
||||||
|
|
||||||
render(
|
renderConversationList({
|
||||||
<ConversationList
|
appDetail: { id: 'app-1', mode: AppModeEnum.COMPLETION } as any,
|
||||||
appDetail={{ id: 'app-1', mode: AppModeEnum.COMPLETION } as any}
|
logs: createCompletionLogs() as any,
|
||||||
logs={createCompletionLogs() as any}
|
searchParams: '?page=2&conversation_id=conversation-1',
|
||||||
onRefresh={mockOnRefresh}
|
})
|
||||||
/>,
|
|
||||||
)
|
|
||||||
|
|
||||||
await waitFor(() => {
|
await waitFor(() => {
|
||||||
expect(screen.getByTestId('text-generation')).toBeInTheDocument()
|
expect(screen.getByTestId('text-generation')).toBeInTheDocument()
|
||||||
@ -454,64 +453,61 @@ describe('ConversationList', () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
it('should render chatflow status cells and feedback counters for advanced chat logs', () => {
|
it('should render chatflow status cells and feedback counters for advanced chat logs', () => {
|
||||||
render(
|
renderConversationList({
|
||||||
<ConversationList
|
appDetail: { id: 'app-1', mode: AppModeEnum.ADVANCED_CHAT } as any,
|
||||||
appDetail={{ id: 'app-1', mode: AppModeEnum.ADVANCED_CHAT } as any}
|
logs: {
|
||||||
logs={{
|
data: [
|
||||||
data: [
|
{
|
||||||
{
|
id: 'conversation-pending',
|
||||||
id: 'conversation-pending',
|
name: 'Pending row',
|
||||||
name: 'Pending row',
|
from_account_name: 'user-a',
|
||||||
from_account_name: 'user-a',
|
read_at: 1710000001,
|
||||||
read_at: 1710000001,
|
message_count: 3,
|
||||||
message_count: 3,
|
status_count: { paused: 1, success: 0, failed: 0, partial_success: 0 },
|
||||||
status_count: { paused: 1, success: 0, failed: 0, partial_success: 0 },
|
user_feedback_stats: { like: 2, dislike: 0 },
|
||||||
user_feedback_stats: { like: 2, dislike: 0 },
|
admin_feedback_stats: { like: 0, dislike: 1 },
|
||||||
admin_feedback_stats: { like: 0, dislike: 1 },
|
updated_at: 1710000000,
|
||||||
updated_at: 1710000000,
|
created_at: 1710000000,
|
||||||
created_at: 1710000000,
|
},
|
||||||
},
|
{
|
||||||
{
|
id: 'conversation-success',
|
||||||
id: 'conversation-success',
|
name: 'Success row',
|
||||||
name: 'Success row',
|
from_account_name: 'user-b',
|
||||||
from_account_name: 'user-b',
|
read_at: 1710000001,
|
||||||
read_at: 1710000001,
|
message_count: 4,
|
||||||
message_count: 4,
|
status_count: { paused: 0, success: 4, failed: 0, partial_success: 0 },
|
||||||
status_count: { paused: 0, success: 4, failed: 0, partial_success: 0 },
|
user_feedback_stats: { like: 0, dislike: 0 },
|
||||||
user_feedback_stats: { like: 0, dislike: 0 },
|
admin_feedback_stats: { like: 0, dislike: 0 },
|
||||||
admin_feedback_stats: { like: 0, dislike: 0 },
|
updated_at: 1710000000,
|
||||||
updated_at: 1710000000,
|
created_at: 1710000000,
|
||||||
created_at: 1710000000,
|
},
|
||||||
},
|
{
|
||||||
{
|
id: 'conversation-partial',
|
||||||
id: 'conversation-partial',
|
name: 'Partial row',
|
||||||
name: 'Partial row',
|
from_account_name: 'user-c',
|
||||||
from_account_name: 'user-c',
|
read_at: 1710000001,
|
||||||
read_at: 1710000001,
|
message_count: 5,
|
||||||
message_count: 5,
|
status_count: { paused: 0, success: 3, failed: 0, partial_success: 1 },
|
||||||
status_count: { paused: 0, success: 3, failed: 0, partial_success: 1 },
|
user_feedback_stats: { like: 0, dislike: 0 },
|
||||||
user_feedback_stats: { like: 0, dislike: 0 },
|
admin_feedback_stats: { like: 0, dislike: 0 },
|
||||||
admin_feedback_stats: { like: 0, dislike: 0 },
|
updated_at: 1710000000,
|
||||||
updated_at: 1710000000,
|
created_at: 1710000000,
|
||||||
created_at: 1710000000,
|
},
|
||||||
},
|
{
|
||||||
{
|
id: 'conversation-failure',
|
||||||
id: 'conversation-failure',
|
name: 'Failure row',
|
||||||
name: 'Failure row',
|
from_account_name: 'user-d',
|
||||||
from_account_name: 'user-d',
|
read_at: 1710000001,
|
||||||
read_at: 1710000001,
|
message_count: 1,
|
||||||
message_count: 1,
|
status_count: { paused: 0, success: 0, failed: 2, partial_success: 0 },
|
||||||
status_count: { paused: 0, success: 0, failed: 2, partial_success: 0 },
|
user_feedback_stats: { like: 0, dislike: 0 },
|
||||||
user_feedback_stats: { like: 0, dislike: 0 },
|
admin_feedback_stats: { like: 0, dislike: 0 },
|
||||||
admin_feedback_stats: { like: 0, dislike: 0 },
|
updated_at: 1710000000,
|
||||||
updated_at: 1710000000,
|
created_at: 1710000000,
|
||||||
created_at: 1710000000,
|
},
|
||||||
},
|
],
|
||||||
],
|
} as any,
|
||||||
} as any}
|
})
|
||||||
onRefresh={mockOnRefresh}
|
|
||||||
/>,
|
|
||||||
)
|
|
||||||
|
|
||||||
expect(screen.getByText('Pending')).toBeInTheDocument()
|
expect(screen.getByText('Pending')).toBeInTheDocument()
|
||||||
expect(screen.getByText('Success')).toBeInTheDocument()
|
expect(screen.getByText('Success')).toBeInTheDocument()
|
||||||
@ -522,7 +518,6 @@ describe('ConversationList', () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
it('should support annotation changes, modal closing, and paginated scroll loading in the detail drawer', async () => {
|
it('should support annotation changes, modal closing, and paginated scroll loading in the detail drawer', async () => {
|
||||||
mockSearchParams = new URLSearchParams('page=2&conversation_id=conversation-1')
|
|
||||||
mockChatConversationDetail = {
|
mockChatConversationDetail = {
|
||||||
id: 'conversation-1',
|
id: 'conversation-1',
|
||||||
created_at: 1710000000,
|
created_at: 1710000000,
|
||||||
@ -568,13 +563,9 @@ describe('ConversationList', () => {
|
|||||||
has_more: false,
|
has_more: false,
|
||||||
})
|
})
|
||||||
|
|
||||||
render(
|
renderConversationList({
|
||||||
<ConversationList
|
searchParams: '?page=2&conversation_id=conversation-1',
|
||||||
appDetail={{ id: 'app-1', mode: AppModeEnum.CHAT } as any}
|
})
|
||||||
logs={createLogs() as any}
|
|
||||||
onRefresh={mockOnRefresh}
|
|
||||||
/>,
|
|
||||||
)
|
|
||||||
|
|
||||||
await waitFor(() => {
|
await waitFor(() => {
|
||||||
expect(screen.getByTestId('chat-panel')).toBeInTheDocument()
|
expect(screen.getByTestId('chat-panel')).toBeInTheDocument()
|
||||||
@ -609,7 +600,6 @@ describe('ConversationList', () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
it('should close the prompt log modal from completion detail drawers', async () => {
|
it('should close the prompt log modal from completion detail drawers', async () => {
|
||||||
mockSearchParams = new URLSearchParams('page=2&conversation_id=conversation-1')
|
|
||||||
mockCompletionConversationDetail = {
|
mockCompletionConversationDetail = {
|
||||||
id: 'conversation-1',
|
id: 'conversation-1',
|
||||||
created_at: 1710000000,
|
created_at: 1710000000,
|
||||||
@ -636,13 +626,11 @@ describe('ConversationList', () => {
|
|||||||
mockShowPromptLogModal = true
|
mockShowPromptLogModal = true
|
||||||
mockCurrentLogItem = { id: 'log-2' }
|
mockCurrentLogItem = { id: 'log-2' }
|
||||||
|
|
||||||
render(
|
renderConversationList({
|
||||||
<ConversationList
|
appDetail: { id: 'app-1', mode: AppModeEnum.COMPLETION } as any,
|
||||||
appDetail={{ id: 'app-1', mode: AppModeEnum.COMPLETION } as any}
|
logs: createCompletionLogs() as any,
|
||||||
logs={createCompletionLogs() as any}
|
searchParams: '?page=2&conversation_id=conversation-1',
|
||||||
onRefresh={mockOnRefresh}
|
})
|
||||||
/>,
|
|
||||||
)
|
|
||||||
|
|
||||||
expect(await screen.findByTestId('prompt-log-modal')).toBeInTheDocument()
|
expect(await screen.findByTestId('prompt-log-modal')).toBeInTheDocument()
|
||||||
|
|
||||||
|
|||||||
@ -13,6 +13,7 @@ import dayjs from 'dayjs'
|
|||||||
import timezone from 'dayjs/plugin/timezone'
|
import timezone from 'dayjs/plugin/timezone'
|
||||||
import utc from 'dayjs/plugin/utc'
|
import utc from 'dayjs/plugin/utc'
|
||||||
import { noop } from 'es-toolkit/function'
|
import { noop } from 'es-toolkit/function'
|
||||||
|
import { parseAsString, useQueryState } from 'nuqs'
|
||||||
import * as React from 'react'
|
import * as React from 'react'
|
||||||
import { useCallback, useEffect, useRef, useState } from 'react'
|
import { useCallback, useEffect, useRef, useState } from 'react'
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
@ -33,7 +34,6 @@ import { WorkflowContextProvider } from '@/app/components/workflow/context'
|
|||||||
import { useAppContext } from '@/context/app-context'
|
import { useAppContext } from '@/context/app-context'
|
||||||
import useBreakpoints, { MediaType } from '@/hooks/use-breakpoints'
|
import useBreakpoints, { MediaType } from '@/hooks/use-breakpoints'
|
||||||
import useTimestamp from '@/hooks/use-timestamp'
|
import useTimestamp from '@/hooks/use-timestamp'
|
||||||
import { usePathname, useRouter, useSearchParams } from '@/next/navigation'
|
|
||||||
import { fetchChatMessages, updateLogMessageAnnotations, updateLogMessageFeedbacks } from '@/service/log'
|
import { fetchChatMessages, updateLogMessageAnnotations, updateLogMessageFeedbacks } from '@/service/log'
|
||||||
import { AppSourceType } from '@/service/share'
|
import { AppSourceType } from '@/service/share'
|
||||||
import { useChatConversationDetail, useCompletionConversationDetail } from '@/service/use-log'
|
import { useChatConversationDetail, useCompletionConversationDetail } from '@/service/use-log'
|
||||||
@ -46,7 +46,6 @@ import {
|
|||||||
applyAnnotationEdited,
|
applyAnnotationEdited,
|
||||||
applyAnnotationRemoved,
|
applyAnnotationRemoved,
|
||||||
buildChatThreadState,
|
buildChatThreadState,
|
||||||
buildConversationUrl,
|
|
||||||
getCompletionMessageFiles,
|
getCompletionMessageFiles,
|
||||||
getConversationRowValues,
|
getConversationRowValues,
|
||||||
getDetailVarList,
|
getDetailVarList,
|
||||||
@ -674,10 +673,7 @@ const ChatConversationDetailComp: FC<{ appId?: string, conversationId?: string }
|
|||||||
const ConversationList: FC<IConversationList> = ({ logs, appDetail, onRefresh }) => {
|
const ConversationList: FC<IConversationList> = ({ logs, appDetail, onRefresh }) => {
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
const { formatTime } = useTimestamp()
|
const { formatTime } = useTimestamp()
|
||||||
const router = useRouter()
|
const [conversationIdInUrl, setConversationIdInUrl] = useQueryState('conversation_id', parseAsString)
|
||||||
const pathname = usePathname()
|
|
||||||
const searchParams = useSearchParams()
|
|
||||||
const conversationIdInUrl = searchParams.get('conversation_id') ?? undefined
|
|
||||||
|
|
||||||
const media = useBreakpoints()
|
const media = useBreakpoints()
|
||||||
const isMobile = media === MediaType.mobile
|
const isMobile = media === MediaType.mobile
|
||||||
@ -697,8 +693,6 @@ const ConversationList: FC<IConversationList> = ({ logs, appDetail, onRefresh })
|
|||||||
|
|
||||||
const activeConversationId = conversationIdInUrl ?? pendingConversationIdRef.current ?? currentConversation?.id
|
const activeConversationId = conversationIdInUrl ?? pendingConversationIdRef.current ?? currentConversation?.id
|
||||||
|
|
||||||
const buildUrlWithConversation = useCallback((conversationId?: string) => buildConversationUrl(pathname, searchParams.toString(), conversationId), [pathname, searchParams])
|
|
||||||
|
|
||||||
const handleRowClick = useCallback((log: ConversationListItem) => {
|
const handleRowClick = useCallback((log: ConversationListItem) => {
|
||||||
if (conversationIdInUrl === log.id) {
|
if (conversationIdInUrl === log.id) {
|
||||||
if (!showDrawer)
|
if (!showDrawer)
|
||||||
@ -717,8 +711,8 @@ const ConversationList: FC<IConversationList> = ({ logs, appDetail, onRefresh })
|
|||||||
if (currentConversation?.id !== log.id)
|
if (currentConversation?.id !== log.id)
|
||||||
setCurrentConversation(undefined)
|
setCurrentConversation(undefined)
|
||||||
|
|
||||||
router.push(buildUrlWithConversation(log.id), { scroll: false })
|
void setConversationIdInUrl(log.id, { history: 'push' })
|
||||||
}, [buildUrlWithConversation, conversationIdInUrl, currentConversation, router, showDrawer])
|
}, [conversationIdInUrl, currentConversation, setConversationIdInUrl, showDrawer])
|
||||||
|
|
||||||
const currentConversationId = currentConversation?.id
|
const currentConversationId = currentConversation?.id
|
||||||
|
|
||||||
@ -755,7 +749,7 @@ const ConversationList: FC<IConversationList> = ({ logs, appDetail, onRefresh })
|
|||||||
|
|
||||||
if (pendingConversationCacheRef.current?.id === conversationIdInUrl || matchedConversation)
|
if (pendingConversationCacheRef.current?.id === conversationIdInUrl || matchedConversation)
|
||||||
pendingConversationCacheRef.current = undefined
|
pendingConversationCacheRef.current = undefined
|
||||||
}, [conversationIdInUrl, currentConversation, isChatMode, logs?.data, showDrawer])
|
}, [conversationIdInUrl, currentConversation, currentConversationId, logs?.data, showDrawer])
|
||||||
|
|
||||||
const onCloseDrawer = useCallback(() => {
|
const onCloseDrawer = useCallback(() => {
|
||||||
onRefresh()
|
onRefresh()
|
||||||
@ -769,8 +763,8 @@ const ConversationList: FC<IConversationList> = ({ logs, appDetail, onRefresh })
|
|||||||
closingConversationIdRef.current = conversationIdInUrl ?? null
|
closingConversationIdRef.current = conversationIdInUrl ?? null
|
||||||
|
|
||||||
if (conversationIdInUrl)
|
if (conversationIdInUrl)
|
||||||
router.replace(buildUrlWithConversation(), { scroll: false })
|
void setConversationIdInUrl(null, { history: 'replace' })
|
||||||
}, [buildUrlWithConversation, conversationIdInUrl, onRefresh, router, setShowAgentLogModal, setShowMessageLogModal, setShowPromptLogModal])
|
}, [conversationIdInUrl, onRefresh, setConversationIdInUrl, setShowAgentLogModal, setShowMessageLogModal, setShowPromptLogModal])
|
||||||
|
|
||||||
// Annotated data needs to be highlighted
|
// Annotated data needs to be highlighted
|
||||||
const renderTdValue = (value: string | number | null, isEmptyStyle: boolean, isHighlight = false, annotation?: LogAnnotation) => {
|
const renderTdValue = (value: string | number | null, isEmptyStyle: boolean, isHighlight = false, annotation?: LogAnnotation) => {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user