mirror of
https://github.com/langgenius/dify.git
synced 2026-06-01 06:28:14 +08:00
fix: not configure default model tip not align
This commit is contained in:
@ -47,12 +47,24 @@ const mockQuotaConfig = {
|
||||
}
|
||||
|
||||
const renderModelProviderPage = (
|
||||
props: { searchText?: string, enableMarketplace?: boolean, stickyToolbar?: boolean } = {},
|
||||
props: {
|
||||
enableMarketplace?: boolean
|
||||
fixedWarningAlignment?: 'viewport' | 'content-frame'
|
||||
searchText?: string
|
||||
stickyToolbar?: boolean
|
||||
} = {},
|
||||
) => {
|
||||
const { searchText = '', enableMarketplace = true, stickyToolbar = true } = props
|
||||
return renderWithSystemFeatures(<ModelProviderPage searchText={searchText} stickyToolbar={stickyToolbar} />, {
|
||||
const { fixedWarningAlignment, searchText = '', enableMarketplace = true, stickyToolbar = true } = props
|
||||
return renderWithSystemFeatures((
|
||||
<ModelProviderPage
|
||||
fixedWarningAlignment={fixedWarningAlignment}
|
||||
searchText={searchText}
|
||||
stickyToolbar={stickyToolbar}
|
||||
/>
|
||||
), {
|
||||
systemFeatures: { enable_marketplace: enableMarketplace },
|
||||
})
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
const mockProviders = [
|
||||
@ -316,6 +328,17 @@ describe('ModelProviderPage', () => {
|
||||
expect(screen.getByText('common.modelProvider.noneConfigured')).toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('should align the fixed warning to the content frame when requested', () => {
|
||||
const { container } = renderModelProviderPage({ fixedWarningAlignment: 'content-frame' })
|
||||
const warning = screen.getByText('common.modelProvider.noneConfigured')
|
||||
const warningContainer = warning.closest('.fixed')
|
||||
|
||||
expect(warningContainer).not.toHaveClass('right-2')
|
||||
expect(warningContainer).toHaveClass('right-0', 'left-[var(--model-provider-warning-left,0px)]')
|
||||
expect(warning.closest('.mx-auto')).toHaveClass('max-w-[1600px]', 'justify-end', 'px-6')
|
||||
expect(container.firstElementChild).toHaveClass('relative')
|
||||
})
|
||||
|
||||
it('should not show warning when some default models are set', () => {
|
||||
mockDefaultModels.llm = {
|
||||
data: { model: 'gpt-4', model_type: 'llm', provider: { provider: 'openai', icon_small: { en_US: '' } } },
|
||||
|
||||
@ -32,6 +32,7 @@ import { providerToPluginId } from './utils'
|
||||
type SystemModelConfigStatus = 'no-provider' | 'none-configured' | 'partially-configured' | 'fully-configured'
|
||||
|
||||
type Props = {
|
||||
fixedWarningAlignment?: 'viewport' | 'content-frame'
|
||||
onSearchTextChange?: (value: string) => void
|
||||
searchText: string
|
||||
stickyToolbar?: boolean
|
||||
@ -40,6 +41,7 @@ type Props = {
|
||||
const FixedModelProvider = ['langgenius/openai/openai', 'langgenius/anthropic/anthropic']
|
||||
|
||||
const ModelProviderPage = ({
|
||||
fixedWarningAlignment = 'viewport',
|
||||
onSearchTextChange,
|
||||
searchText,
|
||||
stickyToolbar,
|
||||
@ -176,20 +178,28 @@ const ModelProviderPage = ({
|
||||
</div>
|
||||
</div>
|
||||
{showWarning && !warningDismissed && (
|
||||
<div className="fixed top-2 right-2 z-50 p-2">
|
||||
<div className="flex items-center gap-2 rounded-lg border-[0.5px] border-components-button-secondary-border bg-components-button-secondary-bg px-3 py-2 shadow-xs backdrop-blur-[5px]">
|
||||
<span aria-hidden className="i-ri-alert-fill size-4 shrink-0 text-text-warning-secondary" />
|
||||
<span className="shrink-0 system-xs-medium whitespace-nowrap text-text-primary" title={t(warningTextKey, { ns: 'common' })}>
|
||||
{t(warningTextKey, { ns: 'common' })}
|
||||
</span>
|
||||
<button
|
||||
type="button"
|
||||
className="flex size-4 shrink-0 items-center justify-center text-text-tertiary hover:text-text-secondary"
|
||||
aria-label={t('operation.close', { ns: 'common' })}
|
||||
onClick={() => setWarningDismissed(true)}
|
||||
>
|
||||
<span aria-hidden className="i-ri-close-line size-4" />
|
||||
</button>
|
||||
<div className={fixedWarningAlignment === 'content-frame'
|
||||
? 'pointer-events-none fixed top-2 right-0 left-[var(--model-provider-warning-left,0px)] z-50'
|
||||
: 'fixed top-2 right-2 z-50 p-2'}
|
||||
>
|
||||
<div className={fixedWarningAlignment === 'content-frame'
|
||||
? 'mx-auto box-border flex w-full max-w-[1600px] justify-end px-6 py-2'
|
||||
: undefined}
|
||||
>
|
||||
<div className="pointer-events-auto flex items-center gap-2 rounded-lg border-[0.5px] border-components-button-secondary-border bg-components-button-secondary-bg px-3 py-2 shadow-xs backdrop-blur-[5px]">
|
||||
<span aria-hidden className="i-ri-alert-fill size-4 shrink-0 text-text-warning-secondary" />
|
||||
<span className="shrink-0 system-xs-medium whitespace-nowrap text-text-primary" title={t(warningTextKey, { ns: 'common' })}>
|
||||
{t(warningTextKey, { ns: 'common' })}
|
||||
</span>
|
||||
<button
|
||||
type="button"
|
||||
className="flex size-4 shrink-0 items-center justify-center text-text-tertiary hover:text-text-secondary"
|
||||
aria-label={t('operation.close', { ns: 'common' })}
|
||||
onClick={() => setWarningDismissed(true)}
|
||||
>
|
||||
<span aria-hidden className="i-ri-close-line size-4" />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
@ -88,13 +88,15 @@ vi.mock('@/app/components/plugins/plugin-page/install-plugin-dropdown', () => ({
|
||||
vi.mock('@/app/components/header/account-setting/model-provider-page', () => ({
|
||||
__esModule: true,
|
||||
default: ({
|
||||
fixedWarningAlignment,
|
||||
onSearchTextChange,
|
||||
searchText,
|
||||
}: {
|
||||
fixedWarningAlignment?: string
|
||||
onSearchTextChange?: (value: string) => void
|
||||
searchText: string
|
||||
}) => (
|
||||
<div data-testid="model-provider-page">
|
||||
<div data-testid="model-provider-page" data-fixed-warning-alignment={fixedWarningAlignment}>
|
||||
<input
|
||||
aria-label="search"
|
||||
value={searchText}
|
||||
@ -170,6 +172,7 @@ describe('IntegrationsPage', () => {
|
||||
|
||||
expect(screen.getByTestId('model-provider-page')).toBeInTheDocument()
|
||||
expect(screen.getByTestId('model-provider-page').parentElement).toHaveClass('max-w-[1600px]', 'px-6', 'pt-2')
|
||||
expect(screen.getByTestId('model-provider-page')).toHaveAttribute('data-fixed-warning-alignment', 'content-frame')
|
||||
expect(screen.getAllByText('common.settings.provider')).toHaveLength(2)
|
||||
expect(screen.getByRole('textbox', { name: 'search' })).toBeInTheDocument()
|
||||
})
|
||||
@ -398,10 +401,17 @@ describe('IntegrationsPage', () => {
|
||||
})
|
||||
|
||||
it('collapses and expands the integrations sidebar', () => {
|
||||
renderIntegrationsPage({ section: 'provider' })
|
||||
const { container } = renderIntegrationsPage({ section: 'provider' })
|
||||
|
||||
expect(container.firstElementChild).toHaveStyle({
|
||||
'--model-provider-warning-left': 'calc(240px + 200px)',
|
||||
})
|
||||
|
||||
fireEvent.click(screen.getByRole('button', { name: 'common.settings.collapse' }))
|
||||
|
||||
expect(container.firstElementChild).toHaveStyle({
|
||||
'--model-provider-warning-left': 'calc(240px + 56px)',
|
||||
})
|
||||
expect(screen.queryByText('common.settings.integrations')).not.toBeInTheDocument()
|
||||
expect(screen.queryByText('common.settings.swaggerAPIAsTool')).not.toBeInTheDocument()
|
||||
expect(screen.getByRole('link', { name: 'MCP' })).toBeInTheDocument()
|
||||
|
||||
@ -28,6 +28,7 @@ const IntegrationSectionRenderer = ({
|
||||
return (
|
||||
<div className={`${toolsContentFrameClassNames.compact} ${toolsContentInsetClassNames.compact} pt-2`}>
|
||||
<ModelProviderPage
|
||||
fixedWarningAlignment="content-frame"
|
||||
searchText={providerSearchText}
|
||||
stickyToolbar
|
||||
onSearchTextChange={onProviderSearchTextChange}
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
'use client'
|
||||
|
||||
import type { ComponentType } from 'react'
|
||||
import type { ComponentType, CSSProperties } from 'react'
|
||||
import type { Permissions, ReferenceSetting } from '@/app/components/plugins/types'
|
||||
import type { IntegrationSection } from '@/app/components/tools/integration-routes'
|
||||
import { Button } from '@langgenius/dify-ui/button'
|
||||
@ -280,6 +280,10 @@ export default function IntegrationsPage({
|
||||
toolsContentInsetClassNames.compact,
|
||||
toolsUnifiedContentFrameClassName,
|
||||
)
|
||||
const sidebarWidthStyle = {
|
||||
'--integrations-sidebar-width': sidebarCollapsed ? '56px' : '200px',
|
||||
'--model-provider-warning-left': `calc(240px + ${sidebarCollapsed ? '56px' : '200px'})`,
|
||||
} as CSSProperties & Record<'--integrations-sidebar-width' | '--model-provider-warning-left', string>
|
||||
const integrationHeader = useMemo(() => {
|
||||
switch (section) {
|
||||
case 'builtin':
|
||||
@ -355,7 +359,7 @@ export default function IntegrationsPage({
|
||||
: undefined
|
||||
|
||||
return (
|
||||
<div className="flex h-full min-h-0 bg-components-panel-bg">
|
||||
<div className="flex h-full min-h-0 bg-components-panel-bg" style={sidebarWidthStyle}>
|
||||
<aside className={cn(
|
||||
'flex shrink-0 flex-col border-r border-divider-burn bg-components-panel-bg px-2 py-2 transition-[width]',
|
||||
sidebarCollapsed ? 'w-14 items-center' : 'w-[200px] items-end',
|
||||
|
||||
Reference in New Issue
Block a user