Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
赵月辉
/
fastgpt-migrated
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Members
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Unverified
Commit
70e837d4
authored
Jul 17, 2026
by
siigure
Committed by
GitHub
Jul 17, 2026
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
fix(chat): add MyTooltip for app name overflow handling (#7322)
parent
94134b04
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
131 additions
and
24 deletions
+131
-24
projects/app/src/pageComponents/chat/slider/ChatSliderHeader.tsx
+14
-10
projects/app/src/pageComponents/chat/slider/index.tsx
+4
-3
projects/app/src/pages/chat/share.tsx
+14
-11
projects/app/test/pageComponents/chat/appNameOverflowHover.test.ts
+99
-0
No files found.
projects/app/src/pageComponents/chat/slider/ChatSliderHeader.tsx
View file @
70e837d4
...
...
@@ -8,6 +8,7 @@ import { useTranslation } from 'react-i18next';
import
{
Box
,
Flex
,
Image
}
from
'@chakra-ui/react'
;
import
Avatar
from
'@fastgpt/web/components/common/Avatar'
;
import
MyIcon
from
'@fastgpt/web/components/common/Icon'
;
import
MyTooltip
from
'@fastgpt/web/components/common/MyTooltip'
;
import
{
useSystem
}
from
'@fastgpt/web/hooks/useSystem'
;
import
{
ChatItemContext
}
from
'@/web/core/chat/context/chatItemContext'
;
import
{
DEFAULT_LOGO_BANNER_URL
}
from
'@/pageComponents/chat/constants'
;
...
...
@@ -37,21 +38,24 @@ const ChatSliderHeader = ({ title, banner }: Props) => {
const
isHomePane
=
pane
===
ChatSidebarPaneEnum
.
HOME
&&
activeAppId
===
homeAppId
;
const
isAllAppsPane
=
pane
===
ChatSidebarPaneEnum
.
ALL_APPS
;
const
headerTitle
=
title
||
(
isCurrentAppReady
?
appName
:
''
);
return
isPc
?
(
<
Flex
py=
{
4
}
px=
{
[
2
,
2
]
}
gap=
{
2
}
alignItems=
{
'center'
}
fontSize=
{
'sm'
}
>
{
!
title
&&
<
Avatar
src=
{
isCurrentAppReady
?
appAvatar
:
undefined
}
borderRadius=
{
'md'
}
/>
}
<
Box
flex=
{
'1 0 0'
}
w=
{
0
}
fontWeight=
{
'bold'
}
fontSize=
{
title
?
'16px'
:
'inherit'
}
color=
{
title
?
'myGray.900'
:
'inherit'
}
className=
{
'textEllipsis'
}
>
{
title
||
(
isCurrentAppReady
?
appName
:
''
)
}
</
Box
>
<
MyTooltip
label=
{
headerTitle
}
showOnlyWhenOverflow
>
<
Box
flex=
{
'1 0 0'
}
w=
{
0
}
fontWeight=
{
'bold'
}
fontSize=
{
title
?
'16px'
:
'inherit'
}
color=
{
title
?
'myGray.900'
:
'inherit'
}
className=
{
'textEllipsis'
}
>
{
headerTitle
}
</
Box
>
</
MyTooltip
>
</
Flex
>
)
:
(
<>
...
...
projects/app/src/pageComponents/chat/slider/index.tsx
View file @
70e837d4
...
...
@@ -9,6 +9,7 @@ import { useUserStore } from '@/web/support/user/useUserStore';
import
UserAvatarPopover
from
'@/pageComponents/chat/UserAvatarPopover'
;
import
MyBox
from
'@fastgpt/web/components/common/MyBox'
;
import
MyIcon
from
'@fastgpt/web/components/common/Icon'
;
import
MyTooltip
from
'@fastgpt/web/components/common/MyTooltip'
;
import
{
ChatSidebarPaneEnum
,
DEFAULT_LOGO_BANNER_COLLAPSED_URL
,
...
...
@@ -545,9 +546,9 @@ const ChatSlider = ({ activeAppId }: Props) => {
})}
>
<
Avatar
src=
{
item
.
avatar
}
w=
{
'20px'
}
h=
{
'20px'
}
borderRadius=
{
'6px'
}
/>
<
Box
className=
{
'textEllipsis'
}
>
{
item
.
name
}
</
Box
>
<
MyTooltip
label=
{
item
.
name
}
showOnlyWhenOverflow
>
<
Box
className=
{
'textEllipsis'
}
>
{
item
.
name
}
</
Box
>
</
MyTooltip
>
</
Flex
>
))
}
</
MyBox
>
...
...
projects/app/src/pages/chat/share.tsx
View file @
70e837d4
...
...
@@ -51,6 +51,7 @@ import { useAppChatGenerateStatusSync } from '@/pageComponents/chat/ChatWindow/u
import
{
postMarkChatRead
}
from
'@/web/core/chat/history/api'
;
import
{
useSandboxEditor
,
useSandboxStatus
}
from
'@/pageComponents/chat/SandboxEditor/hook'
;
import
type
{
GetHistoriesBodyType
}
from
'@fastgpt/global/openapi/core/chat/history/api'
;
import
MyTooltip
from
'@fastgpt/web/components/common/MyTooltip'
;
const
logger
=
getLogger
(
LogCategories
.
MODULE
.
CHAT
.
ITEM
);
...
...
@@ -384,17 +385,19 @@ const OutLink = (props: Props) => {
flexShrink=
{
0
}
/>
)
}
<
Box
minW=
{
0
}
fontSize=
"16px"
fontWeight=
{
500
}
color=
"myGray.900"
overflow=
"hidden"
whiteSpace=
"nowrap"
textOverflow=
"clip"
>
{
mobileHeaderAppName
}
</
Box
>
<
MyTooltip
label=
{
mobileHeaderAppName
}
showOnlyWhenOverflow
>
<
Box
minW=
{
0
}
fontSize=
"16px"
fontWeight=
{
500
}
color=
"myGray.900"
overflow=
"hidden"
whiteSpace=
"nowrap"
textOverflow=
"clip"
>
{
mobileHeaderAppName
}
</
Box
>
</
MyTooltip
>
</
Flex
>
{
hideMenu
===
'1'
?
(
...
...
projects/app/test/pageComponents/chat/appNameOverflowHover.test.ts
0 → 100644
View file @
70e837d4
import
{
readFileSync
}
from
'node:fs'
;
import
{
resolve
}
from
'node:path'
;
import
{
describe
,
expect
,
it
}
from
'vitest'
;
const
longAppName
=
'qa-auto-qa-1784240694258-简单Agent鉴权'
;
const
overflowExamples
=
[
'qa-auto-qa-1784240694258-简单Agent鉴权'
,
'qa-auto-qa-1784240694258-simple-agent-auth-with-extra-long-english-name'
];
const
readProjectFile
=
(
relativePath
:
string
)
=>
readFileSync
(
resolve
(
process
.
cwd
(),
relativePath
),
'utf-8'
);
const
expectOverflowNameHasHoverFullText
=
({
nodeName
,
source
,
nameExpression
}:
{
nodeName
:
string
;
source
:
string
;
nameExpression
:
string
;
})
=>
{
const
nameIndex
=
source
.
indexOf
(
nameExpression
);
expect
(
nameIndex
,
`
${
nodeName
}
: 未找到应用名渲染表达式
${
nameExpression
}
`
).
toBeGreaterThanOrEqual
(
0
);
const
snippet
=
source
.
slice
(
Math
.
max
(
0
,
nameIndex
-
500
),
nameIndex
+
500
);
const
hasOverflowStyle
=
snippet
.
includes
(
'textEllipsis'
)
||
snippet
.
includes
(
'textOverflow'
)
||
snippet
.
includes
(
'isTruncated'
);
const
hasFullNameHoverAffordance
=
snippet
.
includes
(
'MyTooltip'
)
||
snippet
.
includes
(
'Tooltip'
)
||
snippet
.
includes
(
'showOnlyWhenOverflow'
)
||
snippet
.
includes
(
'title='
);
const
hasOverflowOnlyTooltip
=
snippet
.
includes
(
'showOnlyWhenOverflow'
);
const
hasFullNameLabel
=
snippet
.
includes
(
`label=
${
nameExpression
}
`
);
expect
(
hasOverflowStyle
,
`
${
nodeName
}
:
${
longAppName
}
这类长应用名应先被单行截断,测试才能覆盖 hover 展示全名场景`
).
toBe
(
true
);
expect
(
hasFullNameHoverAffordance
,
`
${
nodeName
}
: 长应用名被截断后 hover 不能展示完整名称,应用名节点附近缺少 MyTooltip/Tooltip/title/showOnlyWhenOverflow`
).
toBe
(
true
);
expect
(
hasOverflowOnlyTooltip
,
`
${
nodeName
}
: 短应用名不应出现多余 hover 展示,应使用 showOnlyWhenOverflow 限制只在溢出时展示`
).
toBe
(
true
);
expect
(
hasFullNameLabel
,
`
${
nodeName
}
: hover 展示内容必须使用完整应用名字段
${
nameExpression
}
,不能使用截断后的展示文本`
).
toBe
(
true
);
};
describe
(
'chat app name overflow hover disclosure'
,
()
=>
{
it
(
'门户最近使用应用:截断后的应用名 hover 应展示完整名称'
,
()
=>
{
const
source
=
readProjectFile
(
'src/pageComponents/chat/slider/index.tsx'
);
expectOverflowNameHasHoverFullText
({
nodeName
:
'门户最近使用应用'
,
source
,
nameExpression
:
'{item.name}'
});
});
it
(
'门户聊天历史侧栏顶部应用名:截断后 hover 应展示完整名称'
,
()
=>
{
const
source
=
readProjectFile
(
'src/pageComponents/chat/slider/ChatSliderHeader.tsx'
);
expectOverflowNameHasHoverFullText
({
nodeName
:
'门户聊天历史侧栏顶部应用名'
,
source
,
nameExpression
:
'{headerTitle}'
});
});
it
(
'免登链接应用:截断后的应用名 hover 应展示完整名称'
,
()
=>
{
const
source
=
readProjectFile
(
'src/pages/chat/share.tsx'
);
expectOverflowNameHasHoverFullText
({
nodeName
:
'免登链接应用'
,
source
,
nameExpression
:
'{mobileHeaderAppName}'
});
});
it
(
'短名称不应出现多余 hover 展示,中文/英文长名称溢出时才展示'
,
()
=>
{
const
tooltipSource
=
readProjectFile
(
'../../packages/web/components/common/MyTooltip/index.tsx'
);
expect
(
overflowExamples
).
toHaveLength
(
2
);
expect
(
tooltipSource
).
toContain
(
'target.scrollWidth > target.clientWidth'
);
expect
(
tooltipSource
).
toContain
(
'showOnlyWhenOverflow && !isOverflow'
);
});
});
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment