mirror of
https://github.com/langgenius/dify.git
synced 2026-09-19 02:07:44 +08:00
refactor(web): read plugin profile from query cache (#40471)
This commit is contained in:
@@ -3,6 +3,7 @@ import type { Credential, PluginPayload } from '../types'
|
||||
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
|
||||
import { fireEvent, screen } from '@testing-library/react'
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
import { seedAccountProfileQuery } from '@/test/console/account-profile'
|
||||
import { render } from '@/test/console/render'
|
||||
import { AuthCategory, CredentialTypeEnum } from '../types'
|
||||
|
||||
@@ -44,14 +45,6 @@ const mockUserProfile = {
|
||||
avatar_url: '',
|
||||
}
|
||||
|
||||
vi.mock('@/context/account-state', async () => {
|
||||
const { createAccountStateModuleMock } = await import('@/test/console/state-fixture')
|
||||
return createAccountStateModuleMock(() => ({
|
||||
userProfile: mockUserProfile,
|
||||
isCurrentWorkspaceManager: mockIsCurrentWorkspaceManager(),
|
||||
workspacePermissionKeys: ['credential.use', 'credential.create', 'credential.manage'],
|
||||
}))
|
||||
})
|
||||
vi.mock('@/context/workspace-state', async () => {
|
||||
const { createWorkspaceStateModuleMock } = await import('@/test/console/state-fixture')
|
||||
return createWorkspaceStateModuleMock(() => ({
|
||||
@@ -90,6 +83,7 @@ const createConsoleQueryClient = () =>
|
||||
|
||||
const createWrapper = () => {
|
||||
const testQueryClient = createConsoleQueryClient()
|
||||
seedAccountProfileQuery(testQueryClient, mockUserProfile)
|
||||
return ({ children }: { children: ReactNode }) => (
|
||||
<QueryClientProvider client={testQueryClient}>{children}</QueryClientProvider>
|
||||
)
|
||||
|
||||
@@ -6,7 +6,7 @@ import { fireEvent, screen, waitFor, within } from '@testing-library/react'
|
||||
import userEvent from '@testing-library/user-event'
|
||||
import * as React from 'react'
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
import { render } from '@/test/console/render'
|
||||
import { renderWithAccountProfile as render } from '@/test/console/account-profile'
|
||||
import { AuthCategory } from '../../types'
|
||||
|
||||
const { mockToast } = vi.hoisted(() => {
|
||||
@@ -32,10 +32,6 @@ vi.mock('@langgenius/dify-ui/toast', () => ({
|
||||
toast: mockToast,
|
||||
}))
|
||||
|
||||
vi.mock('@/context/account-state', async () => {
|
||||
const { createAccountStateModuleMock } = await import('@/test/console/state-fixture')
|
||||
return createAccountStateModuleMock(() => ({ userProfile: {} }))
|
||||
})
|
||||
const mockAddPluginCredential = vi.fn().mockResolvedValue({})
|
||||
const mockUpdatePluginCredential = vi.fn().mockResolvedValue({})
|
||||
const defaultCredentialSchemas = [
|
||||
|
||||
+2
-16
@@ -1,22 +1,12 @@
|
||||
import type { PluginPayload } from '../../types'
|
||||
import type { FormSchema } from '@/app/components/base/form/types'
|
||||
import { QueryClient } from '@tanstack/react-query'
|
||||
import { act, fireEvent, render, screen, waitFor } from '@testing-library/react'
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
import { createAccountProfileQueryClient } from '@/test/console/account-profile'
|
||||
import { createQueryClientWrapper } from '@/test/console/query-client'
|
||||
import { AuthCategory } from '../../types'
|
||||
|
||||
const createWrapper = () =>
|
||||
createQueryClientWrapper(
|
||||
new QueryClient({
|
||||
defaultOptions: {
|
||||
queries: {
|
||||
retry: false,
|
||||
gcTime: 0,
|
||||
},
|
||||
},
|
||||
}),
|
||||
)
|
||||
const createWrapper = () => createQueryClientWrapper(createAccountProfileQueryClient())
|
||||
|
||||
// Mock API hooks - these make network requests so must be mocked
|
||||
const mockGetPluginOAuthUrl = vi.fn()
|
||||
@@ -111,10 +101,6 @@ vi.mock('@langgenius/dify-ui/toast', () => ({
|
||||
toast: mockToast,
|
||||
}))
|
||||
|
||||
vi.mock('@/context/account-state', async () => {
|
||||
const { createAccountStateModuleMock } = await import('@/test/console/state-fixture')
|
||||
return createAccountStateModuleMock(() => ({ userProfile: {} }))
|
||||
})
|
||||
// Factory function for creating test PluginPayload
|
||||
const createPluginPayload = (overrides: Partial<PluginPayload> = {}): PluginPayload => ({
|
||||
category: AuthCategory.tool,
|
||||
|
||||
@@ -8,9 +8,9 @@ import {
|
||||
PopoverTrigger,
|
||||
} from '@langgenius/dify-ui/popover'
|
||||
import { RadioGroup, RadioItem } from '@langgenius/dify-ui/radio'
|
||||
import { useAtomValue } from 'jotai'
|
||||
import { useSuspenseQuery } from '@tanstack/react-query'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { userProfileAtom } from '@/context/account-state'
|
||||
import { userProfileQueryOptions } from '@/features/account-profile/client'
|
||||
import { PermissionLevel } from '@/models/permission'
|
||||
|
||||
export type CredentialPermission =
|
||||
@@ -28,7 +28,10 @@ const optionClassName =
|
||||
|
||||
const PermissionSelector = ({ disabled, permission, onChange }: PermissionSelectorProps) => {
|
||||
const { t } = useTranslation()
|
||||
const userProfile = useAtomValue(userProfileAtom)
|
||||
const { data: userProfile } = useSuspenseQuery({
|
||||
...userProfileQueryOptions(),
|
||||
select: (data) => data.profile,
|
||||
})
|
||||
const isOnlyMe = permission === PermissionLevel.onlyMe
|
||||
const isAllTeamMembers = permission === PermissionLevel.allTeamMembers
|
||||
const permissionLabel = t(($) => $['auth.whoCanUse'], { ns: 'plugin' })
|
||||
|
||||
@@ -3,6 +3,7 @@ import type { Credential, PluginPayload } from '../../types'
|
||||
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
|
||||
import { act, fireEvent, screen, waitFor } from '@testing-library/react'
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
import { seedAccountProfileQuery } from '@/test/console/account-profile'
|
||||
import { render } from '@/test/console/render'
|
||||
import { AuthCategory, CredentialTypeEnum } from '../../types'
|
||||
import Authorized from '../index'
|
||||
@@ -87,13 +88,6 @@ const mockConsoleState = vi.hoisted(() => ({
|
||||
workspacePermissionKeys: ['credential.use', 'credential.create', 'credential.manage'] as string[],
|
||||
}))
|
||||
|
||||
vi.mock('@/context/account-state', async () => {
|
||||
const { createAccountStateModuleMock } = await import('@/test/console/state-fixture')
|
||||
return createAccountStateModuleMock(() => ({
|
||||
userProfile: mockConsoleState.userProfile,
|
||||
workspacePermissionKeys: mockConsoleState.workspacePermissionKeys,
|
||||
}))
|
||||
})
|
||||
vi.mock('@/context/permission-state', async () => {
|
||||
const { createPermissionStateModuleMock } = await import('@/test/console/state-fixture')
|
||||
return createPermissionStateModuleMock(() => ({
|
||||
@@ -137,6 +131,7 @@ const createConsoleQueryClient = () =>
|
||||
|
||||
const createWrapper = () => {
|
||||
const testQueryClient = createConsoleQueryClient()
|
||||
seedAccountProfileQuery(testQueryClient, mockConsoleState.userProfile)
|
||||
return ({ children }: { children: ReactNode }) => (
|
||||
<QueryClientProvider client={testQueryClient}>{children}</QueryClientProvider>
|
||||
)
|
||||
|
||||
@@ -1,17 +1,10 @@
|
||||
import type { Credential } from '../../types'
|
||||
import { cleanup, fireEvent, screen } from '@testing-library/react'
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
import { render } from '@/test/console/render'
|
||||
import { renderWithAccountProfile as render } from '@/test/console/account-profile'
|
||||
import { CredentialTypeEnum } from '../../types'
|
||||
import Item from '../item'
|
||||
|
||||
vi.mock('@/context/account-state', async () => {
|
||||
const { createAccountStateModuleMock } = await import('@/test/console/state-fixture')
|
||||
return createAccountStateModuleMock(() => ({
|
||||
userProfile: { id: 'test-user' },
|
||||
workspacePermissionKeys: ['credential.use', 'credential.create', 'credential.manage'],
|
||||
}))
|
||||
})
|
||||
vi.mock('@/context/permission-state', async () => {
|
||||
const { createPermissionStateModuleMock } = await import('@/test/console/state-fixture')
|
||||
return createPermissionStateModuleMock(() => ({
|
||||
|
||||
@@ -4,13 +4,13 @@ import { cn } from '@langgenius/dify-ui/cn'
|
||||
import { StatusDot } from '@langgenius/dify-ui/status-dot'
|
||||
import { Tooltip, TooltipContent, TooltipTrigger } from '@langgenius/dify-ui/tooltip'
|
||||
import { RiInformationLine } from '@remixicon/react'
|
||||
import { useAtomValue } from 'jotai'
|
||||
import { useSuspenseQuery } from '@tanstack/react-query'
|
||||
import { memo, useMemo, useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import ActionButton from '@/app/components/base/action-button'
|
||||
import Badge from '@/app/components/base/badge'
|
||||
import Input from '@/app/components/base/input'
|
||||
import { userProfileIdAtom } from '@/context/account-state'
|
||||
import { userProfileQueryOptions } from '@/features/account-profile/client'
|
||||
import { useCredentialPermissions } from '@/hooks/use-credential-permissions'
|
||||
import { CredentialTypeEnum } from '../types'
|
||||
|
||||
@@ -50,7 +50,10 @@ const Item = ({
|
||||
const { canUseCredential, canManageCredential } = useCredentialPermissions()
|
||||
const isOAuth = credential.credential_type === CredentialTypeEnum.OAUTH2
|
||||
const isPersonal = credential.visibility === 'only_me'
|
||||
const currentUserId = useAtomValue(userProfileIdAtom)
|
||||
const { data: currentUserId } = useSuspenseQuery({
|
||||
...userProfileQueryOptions(),
|
||||
select: (data) => data.profile.id,
|
||||
})
|
||||
// Borrowed-from-teammate: the backend explicitly flagged this row as another member's
|
||||
// only_me credential, returned only because the current node still references it.
|
||||
// Fallback heuristic (created_by mismatch on a selected row) is kept for backends
|
||||
|
||||
+6
-4
@@ -15,8 +15,8 @@ import {
|
||||
} from '@langgenius/dify-ui/select'
|
||||
import { Switch } from '@langgenius/dify-ui/switch'
|
||||
import { Tooltip, TooltipContent, TooltipTrigger } from '@langgenius/dify-ui/tooltip'
|
||||
import { useSuspenseQuery } from '@tanstack/react-query'
|
||||
import { useBoolean } from 'ahooks'
|
||||
import { useAtomValue } from 'jotai'
|
||||
import { useCallback, useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { Infotip } from '@/app/components/base/infotip'
|
||||
@@ -33,7 +33,7 @@ import MixedVariableTextInput from '@/app/components/workflow/nodes/tool/compone
|
||||
import ToolDatePicker from '@/app/components/workflow/nodes/tool/components/tool-date-picker'
|
||||
import ToolDateRangePicker from '@/app/components/workflow/nodes/tool/components/tool-date-range-picker'
|
||||
import { VarType as VarKindType } from '@/app/components/workflow/nodes/tool/types'
|
||||
import { userProfileAtom } from '@/context/account-state'
|
||||
import { userProfileQueryOptions } from '@/features/account-profile/client'
|
||||
import {
|
||||
createPickerProps,
|
||||
getFieldFlags,
|
||||
@@ -68,8 +68,10 @@ const ReasoningConfigForm: React.FC<Props> = ({
|
||||
}) => {
|
||||
const { t } = useTranslation()
|
||||
const language = useLanguage()
|
||||
const userProfile = useAtomValue(userProfileAtom)
|
||||
const timezone = userProfile.timezone ?? 'UTC'
|
||||
const { data: timezone } = useSuspenseQuery({
|
||||
...userProfileQueryOptions(),
|
||||
select: (data) => data.profile.timezone ?? 'UTC',
|
||||
})
|
||||
|
||||
const handleAutomatic = (key: string, val: boolean, type: string) => {
|
||||
onChange(updateInputAutoState(value, key, val, type))
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
'use client'
|
||||
import type { AppDetailResponse } from '@/models/app'
|
||||
import type { AppSSO } from '@/types/app'
|
||||
import { useQuery, useQueryClient } from '@tanstack/react-query'
|
||||
import { useQuery, useQueryClient, useSuspenseQuery } from '@tanstack/react-query'
|
||||
import { useAtomValue } from 'jotai'
|
||||
import { useCallback, useMemo, useState } from 'react'
|
||||
import { BlockEnum } from '@/app/components/workflow/types'
|
||||
import { userProfileIdAtom } from '@/context/account-state'
|
||||
import { workspacePermissionKeysAtom } from '@/context/permission-state'
|
||||
import { userProfileQueryOptions } from '@/features/account-profile/client'
|
||||
import { fetchAppDetail } from '@/service/apps'
|
||||
import {
|
||||
useInvalidateMCPServerDetail,
|
||||
@@ -35,7 +35,10 @@ export const useMCPServiceCardState = (appInfo: AppInfo, triggerModeDisabled: bo
|
||||
const { mutateAsync: updateMCPServer } = useUpdateMCPServer()
|
||||
const { mutateAsync: refreshMCPServerCode, isPending: genLoading } = useRefreshMCPServerCode()
|
||||
const invalidateMCPServerDetail = useInvalidateMCPServerDetail()
|
||||
const currentUserId = useAtomValue(userProfileIdAtom)
|
||||
const { data: currentUserId } = useSuspenseQuery({
|
||||
...userProfileQueryOptions(),
|
||||
select: (data) => data.profile.id,
|
||||
})
|
||||
const workspacePermissionKeys = useAtomValue(workspacePermissionKeysAtom)
|
||||
|
||||
const canManageMCP = useMemo(
|
||||
|
||||
@@ -10,10 +10,6 @@ export const userProfileAtom = atom((get) => {
|
||||
return get(accountProfileQueryAtom).data.profile
|
||||
})
|
||||
|
||||
export const userProfileIdAtom = atom((get) => {
|
||||
return get(userProfileAtom).id
|
||||
})
|
||||
|
||||
export const accountProfileMetaAtom = atom((get) => {
|
||||
return get(accountProfileQueryAtom).data.meta
|
||||
})
|
||||
|
||||
+9
-15
@@ -3,6 +3,7 @@ import type React from 'react'
|
||||
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
|
||||
import { screen, waitFor, within } from '@testing-library/react'
|
||||
import userEvent from '@testing-library/user-event'
|
||||
import { seedAccountProfileQuery } from '@/test/console/account-profile'
|
||||
import { seedSystemFeatures } from '@/test/console/query-data'
|
||||
import { render } from '@/test/console/render'
|
||||
import { ServiceApiAccessCard } from '../service-api-access-card'
|
||||
@@ -44,21 +45,6 @@ vi.mock('@/hooks/use-timestamp', () => ({
|
||||
}),
|
||||
}))
|
||||
|
||||
vi.mock('@/context/account-state', async () => {
|
||||
const { createAccountStateModuleMock } = await import('@/test/console/state-fixture')
|
||||
return createAccountStateModuleMock(() => ({
|
||||
userProfile: { id: 'user-1' },
|
||||
currentWorkspace: { id: 'workspace-1' },
|
||||
workspacePermissionKeys: ['app.acl.edit'],
|
||||
langGeniusVersionInfo: {
|
||||
current_env: 'PRODUCTION',
|
||||
current_version: '',
|
||||
latest_version: '',
|
||||
version: '',
|
||||
release_notes: '',
|
||||
},
|
||||
}))
|
||||
})
|
||||
vi.mock('@/context/workspace-state', async () => {
|
||||
const { createWorkspaceStateModuleMock } = await import('@/test/console/state-fixture')
|
||||
return createWorkspaceStateModuleMock(() => ({
|
||||
@@ -107,6 +93,13 @@ vi.mock('@/context/version-state', async () => {
|
||||
|
||||
vi.mock('@/service/client', () => ({
|
||||
consoleQuery: {
|
||||
account: {
|
||||
profile: {
|
||||
get: {
|
||||
queryKey: () => [['console', 'account', 'profile', 'get'], { type: 'query' }],
|
||||
},
|
||||
},
|
||||
},
|
||||
systemFeatures: {
|
||||
get: {
|
||||
queryKey: () => ['system-features'],
|
||||
@@ -256,6 +249,7 @@ function createConsoleQueryClient(webAppAuthEnabled = true) {
|
||||
enabled: webAppAuthEnabled,
|
||||
},
|
||||
})
|
||||
seedAccountProfileQuery(queryClient, { id: 'user-1' })
|
||||
return queryClient
|
||||
}
|
||||
|
||||
|
||||
+5
-2
@@ -6,8 +6,8 @@ import { useSuspenseQuery } from '@tanstack/react-query'
|
||||
import { useAtomValue } from 'jotai'
|
||||
import { useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { userProfileIdAtom } from '@/context/account-state'
|
||||
import { workspacePermissionKeysAtom } from '@/context/permission-state'
|
||||
import { userProfileQueryOptions } from '@/features/account-profile/client'
|
||||
import { systemFeaturesQueryOptions } from '@/features/system-features/client'
|
||||
import { isAccessMode } from '@/models/access-control'
|
||||
import dynamic from '@/next/dynamic'
|
||||
@@ -27,7 +27,10 @@ export function WebAppAccessControlButton({ agent }: { agent?: AgentAppDetailWit
|
||||
...systemFeaturesQueryOptions(),
|
||||
select: (systemFeatures) => systemFeatures.webapp_auth.enabled,
|
||||
})
|
||||
const currentUserId = useAtomValue(userProfileIdAtom)
|
||||
const { data: currentUserId } = useSuspenseQuery({
|
||||
...userProfileQueryOptions(),
|
||||
select: (data) => data.profile.id,
|
||||
})
|
||||
const workspacePermissionKeys = useAtomValue(workspacePermissionKeysAtom)
|
||||
const { canReleaseAndVersion: canManageWebAppAccessControl } = getAppACLCapabilities(
|
||||
agent?.permission_keys,
|
||||
|
||||
+4
-7
@@ -15,6 +15,7 @@ import {
|
||||
agentComposerSavedDraftAtom,
|
||||
isAgentComposerDirtyAtom,
|
||||
} from '@/features/agent-v2/agent-composer/store'
|
||||
import { seedAccountProfileQuery } from '@/test/console/account-profile'
|
||||
import { AgentOrchestrateReadOnlyContext } from '../../read-only-context'
|
||||
import { AgentTools } from '../index'
|
||||
|
||||
@@ -48,13 +49,6 @@ vi.mock('@/app/components/workflow/block-selector/tool-picker', () => ({
|
||||
ToolPickerContent: () => <div>Mock tool picker</div>,
|
||||
}))
|
||||
|
||||
vi.mock('@/context/account-state', async () => {
|
||||
const { atom } = await vi.importActual<typeof import('jotai')>('jotai')
|
||||
return {
|
||||
userProfileIdAtom: atom('user-1'),
|
||||
}
|
||||
})
|
||||
|
||||
vi.mock('@/app/components/workflow/block-icon', () => ({
|
||||
default: ({ toolIcon }: { toolIcon?: string | { content: string; background: string } }) => (
|
||||
<span aria-hidden data-testid="tool-icon">
|
||||
@@ -392,6 +386,7 @@ function renderAgentTools(initialDraft: AgentSoulConfigFormState = agentToolsDra
|
||||
},
|
||||
},
|
||||
})
|
||||
seedAccountProfileQuery(queryClient, { id: 'user-1' })
|
||||
|
||||
return render(
|
||||
<QueryClientProvider client={queryClient}>
|
||||
@@ -410,6 +405,7 @@ function renderAgentToolsWithStore(initialDraft: AgentSoulConfigFormState = agen
|
||||
},
|
||||
},
|
||||
})
|
||||
seedAccountProfileQuery(queryClient, { id: 'user-1' })
|
||||
const store = createStore()
|
||||
store.set(agentComposerDraftAtom, initialDraft)
|
||||
store.set(agentComposerSavedDraftAtom, initialDraft)
|
||||
@@ -436,6 +432,7 @@ function renderReadonlyAgentTools(initialDraft: AgentSoulConfigFormState = agent
|
||||
},
|
||||
},
|
||||
})
|
||||
seedAccountProfileQuery(queryClient, { id: 'user-1' })
|
||||
|
||||
return render(
|
||||
<QueryClientProvider client={queryClient}>
|
||||
|
||||
+11
-10
@@ -14,6 +14,7 @@ import { agentComposerDraftAtom } from '@/features/agent-v2/agent-composer/store
|
||||
import { agentComposerModelAtom } from '@/features/agent-v2/agent-composer/store-modules/model'
|
||||
import { agentComposerPromptAtom } from '@/features/agent-v2/agent-composer/store-modules/prompt'
|
||||
import { consoleQuery } from '@/service/client'
|
||||
import { seedAccountProfileQuery } from '@/test/console/account-profile'
|
||||
import { render } from '@/test/console/render'
|
||||
import { seedRegisteredConsoleStateFixture } from '@/test/console/state-fixture'
|
||||
import { TransferMethod } from '@/types/app'
|
||||
@@ -188,16 +189,6 @@ vi.mock('@/app/components/base/chat/chat/hooks', () => ({
|
||||
),
|
||||
}))
|
||||
|
||||
vi.mock('@/context/account-state', async () => {
|
||||
const { createAccountStateModuleMock } = await import('@/test/console/state-fixture')
|
||||
return createAccountStateModuleMock(() => ({
|
||||
userProfile: {
|
||||
avatar_url: '',
|
||||
name: 'User',
|
||||
},
|
||||
}))
|
||||
})
|
||||
|
||||
vi.mock('@/app/components/header/account-setting/model-provider-page/hooks', () => ({
|
||||
useTextGenerationCurrentProviderAndModelAndModelList: () => ({
|
||||
textGenerationModelList: [
|
||||
@@ -239,6 +230,13 @@ vi.mock('@/service/client', async () => {
|
||||
},
|
||||
},
|
||||
consoleQuery: {
|
||||
account: {
|
||||
profile: {
|
||||
get: {
|
||||
queryKey: () => [['console', 'account', 'profile', 'get'], { type: 'query' }],
|
||||
},
|
||||
},
|
||||
},
|
||||
agent: {
|
||||
byAgentId: {
|
||||
chatMessages: {
|
||||
@@ -275,6 +273,7 @@ function renderPreviewChat(
|
||||
},
|
||||
},
|
||||
})
|
||||
seedAccountProfileQuery(queryClient, { avatar_url: '', name: 'User' })
|
||||
store.set(agentComposerModelAtom, {
|
||||
provider: 'openai',
|
||||
model: 'gpt-4',
|
||||
@@ -349,6 +348,7 @@ function renderPreviewChatWithConversationHarness() {
|
||||
},
|
||||
},
|
||||
})
|
||||
seedAccountProfileQuery(queryClient, { avatar_url: '', name: 'User' })
|
||||
store.set(agentComposerModelAtom, {
|
||||
provider: 'openai',
|
||||
model: 'gpt-4',
|
||||
@@ -374,6 +374,7 @@ function renderPreviewChatWithClearCommandHarness() {
|
||||
},
|
||||
},
|
||||
})
|
||||
seedAccountProfileQuery(queryClient, { avatar_url: '', name: 'User' })
|
||||
store.set(agentComposerModelAtom, {
|
||||
provider: 'openai',
|
||||
model: 'gpt-4',
|
||||
|
||||
+12
-12
@@ -1,6 +1,6 @@
|
||||
import type { AgentConfigSnapshotSummaryResponse } from '@dify/contracts/api/console/agent/types.gen'
|
||||
import { fireEvent, screen } from '@testing-library/react'
|
||||
import { render } from '@/test/console/render'
|
||||
import { renderWithAccountProfile as render } from '@/test/console/account-profile'
|
||||
import { AgentPreviewVersionsPanel } from '../versions-panel'
|
||||
|
||||
const versions: AgentConfigSnapshotSummaryResponse[] = [
|
||||
@@ -47,6 +47,13 @@ vi.mock('@/hooks/use-timestamp', () => ({
|
||||
|
||||
vi.mock('@/service/client', () => ({
|
||||
consoleQuery: {
|
||||
account: {
|
||||
profile: {
|
||||
get: {
|
||||
queryKey: () => [['console', 'account', 'profile', 'get'], { type: 'query' }],
|
||||
},
|
||||
},
|
||||
},
|
||||
agent: {
|
||||
byAgentId: {
|
||||
versions: {
|
||||
@@ -59,17 +66,6 @@ vi.mock('@/service/client', () => ({
|
||||
},
|
||||
}))
|
||||
|
||||
vi.mock('@/context/account-state', async () => {
|
||||
const { createAccountStateModuleMock } = await import('@/test/console/state-fixture')
|
||||
return createAccountStateModuleMock(() => ({
|
||||
userProfile: {
|
||||
id: 'user-1',
|
||||
name: 'Alice',
|
||||
email: 'alice@example.com',
|
||||
},
|
||||
}))
|
||||
})
|
||||
|
||||
describe('AgentPreviewVersionsPanel', () => {
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks()
|
||||
@@ -86,6 +82,7 @@ describe('AgentPreviewVersionsPanel', () => {
|
||||
onSelectVersion={handleSelectVersion}
|
||||
onClose={vi.fn()}
|
||||
/>,
|
||||
{ accountProfile: { id: 'user-1', name: 'Alice', email: 'alice@example.com' } },
|
||||
)
|
||||
|
||||
fireEvent.click(screen.getByRole('button', { name: /Initial release/i }))
|
||||
@@ -103,6 +100,7 @@ describe('AgentPreviewVersionsPanel', () => {
|
||||
onSelectVersion={handleSelectVersion}
|
||||
onClose={vi.fn()}
|
||||
/>,
|
||||
{ accountProfile: { id: 'user-1', name: 'Alice', email: 'alice@example.com' } },
|
||||
)
|
||||
|
||||
fireEvent.click(screen.getByRole('button', { name: /currentDraft/i }))
|
||||
@@ -120,6 +118,7 @@ describe('AgentPreviewVersionsPanel', () => {
|
||||
onSelectVersion={vi.fn()}
|
||||
onClose={vi.fn()}
|
||||
/>,
|
||||
{ accountProfile: { id: 'user-1', name: 'Alice', email: 'alice@example.com' } },
|
||||
)
|
||||
|
||||
fireEvent.click(screen.getByRole('button', { name: /filter/i }))
|
||||
@@ -137,6 +136,7 @@ describe('AgentPreviewVersionsPanel', () => {
|
||||
onSelectVersion={vi.fn()}
|
||||
onClose={vi.fn()}
|
||||
/>,
|
||||
{ accountProfile: { id: 'user-1', name: 'Alice', email: 'alice@example.com' } },
|
||||
)
|
||||
|
||||
fireEvent.click(screen.getByRole('button', { name: /filter/i }))
|
||||
|
||||
+6
-4
@@ -13,8 +13,7 @@ import type { Inputs } from '@/models/debug'
|
||||
import { Avatar } from '@langgenius/dify-ui/avatar'
|
||||
import { cn } from '@langgenius/dify-ui/cn'
|
||||
import { toast } from '@langgenius/dify-ui/toast'
|
||||
import { useQueryClient } from '@tanstack/react-query'
|
||||
import { useAtomValue } from 'jotai'
|
||||
import { useQueryClient, useSuspenseQuery } from '@tanstack/react-query'
|
||||
import { useCallback, useImperativeHandle, useLayoutEffect, useRef, useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { AgentRosterResponseContent } from '@/app/components/base/chat/chat/answer/agent-roster-response-content'
|
||||
@@ -22,8 +21,8 @@ import { useChat } from '@/app/components/base/chat/chat/hooks'
|
||||
import { getLastAnswer, isValidGeneratedAnswer } from '@/app/components/base/chat/utils'
|
||||
import { ModelFeatureEnum } from '@/app/components/header/account-setting/model-provider-page/declarations'
|
||||
import { useTextGenerationCurrentProviderAndModelAndModelList } from '@/app/components/header/account-setting/model-provider-page/hooks'
|
||||
import { userProfileAtom } from '@/context/account-state'
|
||||
import { useDocLink } from '@/context/i18n'
|
||||
import { userProfileQueryOptions } from '@/features/account-profile/client'
|
||||
import dynamic from '@/next/dynamic'
|
||||
import { consoleClient, consoleQuery } from '@/service/client'
|
||||
import { buildChatConfig, getAgentSoulInputs, getAgentSoulInputsForm } from './chat-config'
|
||||
@@ -124,7 +123,10 @@ export function AgentPreviewChatConversation({
|
||||
const { t } = useTranslation('agentV2')
|
||||
const docLink = useDocLink()
|
||||
const queryClient = useQueryClient()
|
||||
const userProfile = useAtomValue(userProfileAtom)
|
||||
const { data: userProfile } = useSuspenseQuery({
|
||||
...userProfileQueryOptions(),
|
||||
select: (data) => data.profile,
|
||||
})
|
||||
const sendInterruptedRef = useRef(false)
|
||||
const [isSendPending, setIsSendPending] = useState(false)
|
||||
const notifySendInterrupted = useCallback(() => {
|
||||
|
||||
+6
-4
@@ -1,11 +1,10 @@
|
||||
'use client'
|
||||
|
||||
import type { AgentVersionFilter } from './filter'
|
||||
import { useQuery } from '@tanstack/react-query'
|
||||
import { useAtomValue } from 'jotai'
|
||||
import { useQuery, useSuspenseQuery } from '@tanstack/react-query'
|
||||
import { useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { userProfileAtom } from '@/context/account-state'
|
||||
import { userProfileQueryOptions } from '@/features/account-profile/client'
|
||||
import { consoleQuery } from '@/service/client'
|
||||
import { CurrentDraftItem } from './current-draft-item'
|
||||
import { VersionFilter } from './filter'
|
||||
@@ -28,7 +27,10 @@ export function AgentPreviewVersionsPanel({
|
||||
const { t } = useTranslation('agentV2')
|
||||
const { t: tCommon } = useTranslation('common')
|
||||
const { t: tWorkflow } = useTranslation('workflow')
|
||||
const userProfile = useAtomValue(userProfileAtom)
|
||||
const { data: userProfile } = useSuspenseQuery({
|
||||
...userProfileQueryOptions(),
|
||||
select: (data) => data.profile,
|
||||
})
|
||||
const [filterValue, setFilterValue] = useState<AgentVersionFilter>('all')
|
||||
const versionsQuery = useQuery(
|
||||
consoleQuery.agent.byAgentId.versions.get.queryOptions({
|
||||
|
||||
Reference in New Issue
Block a user