Skip to content

Commit 7ef0e99

Browse files
Feature: add tooltip display on icon hover in chatflows and marketplace page (#4428)
* feat: add tooltip display on icon hover in chatflows and marketplace page * update list view, remove sticky note images --------- Co-authored-by: Henry <hzj94@hotmail.com>
1 parent 82d60c7 commit 7ef0e99

File tree

6 files changed

+181
-95
lines changed

6 files changed

+181
-95
lines changed

packages/ui/src/ui-component/cards/ItemCard.jsx

Lines changed: 57 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,11 @@ import { useSelector } from 'react-redux'
33

44
// material-ui
55
import { styled } from '@mui/material/styles'
6-
import { Box, Grid, Typography, useTheme } from '@mui/material'
6+
import { Box, Grid, Tooltip, Typography, useTheme } from '@mui/material'
77

88
// project imports
99
import MainCard from '@/ui-component/cards/MainCard'
10+
import MoreItemsTooltip from '../tooltip/MoreItemsTooltip'
1011

1112
const CardWrapper = styled(MainCard)(({ theme }) => ({
1213
background: theme.palette.card.main,
@@ -116,48 +117,63 @@ const ItemCard = ({ data, images, icons, onClick }) => {
116117
}}
117118
>
118119
{[
119-
...(images || []).map((img) => ({ type: 'image', src: img })),
120-
...(icons || []).map((ic) => ({ type: 'icon', icon: ic.icon, color: ic.color }))
120+
...(images || []).map((img) => ({ type: 'image', src: img.imageSrc, label: img.label })),
121+
...(icons || []).map((ic) => ({ type: 'icon', icon: ic.icon, color: ic.color, label: ic.name }))
121122
]
122123
.slice(0, 3)
123-
.map((item, index) =>
124-
item.type === 'image' ? (
125-
<Box
126-
key={item.src}
127-
sx={{
128-
width: 30,
129-
height: 30,
130-
borderRadius: '50%',
131-
backgroundColor: customization.isDarkMode
132-
? theme.palette.common.white
133-
: theme.palette.grey[300] + 75
134-
}}
135-
>
136-
<img
137-
style={{ width: '100%', height: '100%', padding: 5, objectFit: 'contain' }}
138-
alt=''
139-
src={item.src}
140-
/>
141-
</Box>
142-
) : (
143-
<div
144-
key={index}
145-
style={{
146-
width: 30,
147-
height: 30,
148-
display: 'flex',
149-
alignItems: 'center',
150-
justifyContent: 'center'
151-
}}
152-
>
153-
<item.icon size={25} color={item.color} />
154-
</div>
155-
)
156-
)}
157-
{images?.length + (icons?.length || 0) > 3 && (
158-
<Typography sx={{ alignItems: 'center', display: 'flex', fontSize: '.9rem', fontWeight: 200 }}>
159-
+ {images?.length + (icons?.length || 0) - 3} More
160-
</Typography>
124+
.map((item, index) => (
125+
<Tooltip key={item.src || index} title={item.label} placement='top'>
126+
{item.type === 'image' ? (
127+
<Box
128+
sx={{
129+
width: 30,
130+
height: 30,
131+
borderRadius: '50%',
132+
backgroundColor: customization.isDarkMode
133+
? theme.palette.common.white
134+
: theme.palette.grey[300] + 75
135+
}}
136+
>
137+
<img
138+
style={{ width: '100%', height: '100%', padding: 5, objectFit: 'contain' }}
139+
alt=''
140+
src={item.src}
141+
/>
142+
</Box>
143+
) : (
144+
<div
145+
style={{
146+
width: 30,
147+
height: 30,
148+
display: 'flex',
149+
alignItems: 'center',
150+
justifyContent: 'center'
151+
}}
152+
>
153+
<item.icon size={25} color={item.color} />
154+
</div>
155+
)}
156+
</Tooltip>
157+
))}
158+
159+
{(images?.length || 0) + (icons?.length || 0) > 3 && (
160+
<MoreItemsTooltip
161+
images={[
162+
...(images?.slice(3) || []),
163+
...(icons?.slice(Math.max(0, 3 - (images?.length || 0))) || []).map((ic) => ({ label: ic.name }))
164+
]}
165+
>
166+
<Typography
167+
sx={{
168+
alignItems: 'center',
169+
display: 'flex',
170+
fontSize: '.9rem',
171+
fontWeight: 200
172+
}}
173+
>
174+
+ {(images?.length || 0) + (icons?.length || 0) - 3} More
175+
</Typography>
176+
</MoreItemsTooltip>
161177
)}
162178
</Box>
163179
)}

packages/ui/src/ui-component/table/FlowListTable.jsx

Lines changed: 66 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ import FlowListMenu from '../button/FlowListMenu'
2525
import { Link } from 'react-router-dom'
2626
import { useAuth } from '@/hooks/useAuth'
2727

28+
import MoreItemsTooltip from '../tooltip/MoreItemsTooltip'
29+
2830
const StyledTableCell = styled(TableCell)(({ theme }) => ({
2931
borderColor: theme.palette.grey[900] + 25,
3032

@@ -234,64 +236,80 @@ export const FlowListTable = ({
234236
}}
235237
>
236238
{[
237-
...(images[row.id] || []).map((img) => ({ type: 'image', src: img })),
239+
...(images[row.id] || []).map((img) => ({
240+
type: 'image',
241+
src: img.imageSrc,
242+
label: img.label
243+
})),
238244
...(icons[row.id] || []).map((ic) => ({
239245
type: 'icon',
240246
icon: ic.icon,
241-
color: ic.color
247+
color: ic.color,
248+
title: ic.name
242249
}))
243250
]
244251
.slice(0, 5)
245-
.map((item, index) =>
246-
item.type === 'image' ? (
247-
<Box
248-
key={item.src}
249-
sx={{
250-
width: 30,
251-
height: 30,
252-
borderRadius: '50%',
253-
backgroundColor: customization.isDarkMode
254-
? theme.palette.common.white
255-
: theme.palette.grey[300] + 75
256-
}}
257-
>
258-
<img
252+
.map((item, index) => (
253+
<Tooltip key={item.imageSrc || index} title={item.label} placement='top'>
254+
{item.type === 'image' ? (
255+
<Box
256+
sx={{
257+
width: 30,
258+
height: 30,
259+
borderRadius: '50%',
260+
backgroundColor: customization.isDarkMode
261+
? theme.palette.common.white
262+
: theme.palette.grey[300] + 75
263+
}}
264+
>
265+
<img
266+
style={{
267+
width: '100%',
268+
height: '100%',
269+
padding: 5,
270+
objectFit: 'contain'
271+
}}
272+
alt=''
273+
src={item.src}
274+
/>
275+
</Box>
276+
) : (
277+
<div
259278
style={{
260-
width: '100%',
261-
height: '100%',
262-
padding: 5,
263-
objectFit: 'contain'
279+
width: 30,
280+
height: 30,
281+
display: 'flex',
282+
alignItems: 'center',
283+
justifyContent: 'center'
264284
}}
265-
alt=''
266-
src={item.src}
267-
/>
268-
</Box>
269-
) : (
270-
<div
271-
key={index}
272-
style={{
273-
width: 30,
274-
height: 30,
275-
display: 'flex',
276-
alignItems: 'center',
277-
justifyContent: 'center'
278-
}}
279-
>
280-
<item.icon size={25} color={item.color} />
281-
</div>
282-
)
283-
)}
285+
>
286+
<item.icon size={25} color={item.color} />
287+
</div>
288+
)}
289+
</Tooltip>
290+
))}
291+
284292
{(images[row.id]?.length || 0) + (icons[row.id]?.length || 0) > 5 && (
285-
<Typography
286-
sx={{
287-
alignItems: 'center',
288-
display: 'flex',
289-
fontSize: '.9rem',
290-
fontWeight: 200
291-
}}
293+
<MoreItemsTooltip
294+
images={[
295+
...(images[row.id]?.slice(5) || []),
296+
...(
297+
icons[row.id]?.slice(Math.max(0, 5 - (images[row.id]?.length || 0))) ||
298+
[]
299+
).map((ic) => ({ label: ic.name }))
300+
]}
292301
>
293-
+ {(images[row.id]?.length || 0) + (icons[row.id]?.length || 0) - 5} More
294-
</Typography>
302+
<Typography
303+
sx={{
304+
alignItems: 'center',
305+
display: 'flex',
306+
fontSize: '.9rem',
307+
fontWeight: 200
308+
}}
309+
>
310+
+ {(images[row.id]?.length || 0) + (icons[row.id]?.length || 0) - 5} More
311+
</Typography>
312+
</MoreItemsTooltip>
295313
)}
296314
</Box>
297315
)}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import { Tooltip, Typography } from '@mui/material'
2+
import { styled } from '@mui/material/styles'
3+
import PropTypes from 'prop-types'
4+
5+
const StyledOl = styled('ol')(() => ({
6+
paddingLeft: 20,
7+
margin: 0
8+
}))
9+
10+
const StyledLi = styled('li')(() => ({
11+
paddingBottom: 4
12+
}))
13+
14+
const MoreItemsTooltip = ({ images, children }) => {
15+
if (!images || images.length === 0) return children
16+
17+
return (
18+
<Tooltip
19+
title={
20+
<StyledOl>
21+
{images.map((img) => (
22+
<StyledLi key={img.imageSrc || img.label}>
23+
<Typography>{img.label}</Typography>
24+
</StyledLi>
25+
))}
26+
</StyledOl>
27+
}
28+
placement='top'
29+
>
30+
{children}
31+
</Tooltip>
32+
)
33+
}
34+
35+
export default MoreItemsTooltip
36+
37+
MoreItemsTooltip.propTypes = {
38+
images: PropTypes.array,
39+
children: PropTypes.node
40+
}

packages/ui/src/views/agentflows/index.jsx

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -117,13 +117,17 @@ const Agentflows = () => {
117117
images[agentflows[i].id] = []
118118
icons[agentflows[i].id] = []
119119
for (let j = 0; j < nodes.length; j += 1) {
120+
if (nodes[j].data.name === 'stickyNote' || nodes[j].data.name === 'stickyNoteAgentflow') continue
120121
const foundIcon = AGENTFLOW_ICONS.find((icon) => icon.name === nodes[j].data.name)
121122
if (foundIcon) {
122123
icons[agentflows[i].id].push(foundIcon)
123124
} else {
124125
const imageSrc = `${baseURL}/api/v1/node-icon/${nodes[j].data.name}`
125-
if (!images[agentflows[i].id].includes(imageSrc)) {
126-
images[agentflows[i].id].push(imageSrc)
126+
if (!images[agentflows[i].id].some((img) => img.imageSrc === imageSrc)) {
127+
images[agentflows[i].id].push({
128+
imageSrc,
129+
label: nodes[j].data.label
130+
})
127131
}
128132
}
129133
}

0 commit comments

Comments
 (0)