fix: hide divider when OnlineUsers component is not rendered

Move the Divider into the OnlineUsers component so it conditionally
renders together with the online users content, preventing an orphaned
divider from appearing next to the preview button.
This commit is contained in:
yyh
2026-02-03 14:18:17 +08:00
parent 31177462e1
commit 19a5aee38e
2 changed files with 123 additions and 121 deletions

View File

@ -5,7 +5,6 @@ import {
} from 'react'
import { useNodes } from 'reactflow'
import { useInputFieldPanel } from '@/app/components/rag-pipeline/hooks'
import Divider from '../../base/divider'
import {
useNodesInteractions,
useNodesReadOnly,
@ -75,7 +74,6 @@ const HeaderInNormal = ({
</div>
<div className="flex items-center gap-2">
<OnlineUsers />
<Divider type="vertical" className="mx-auto h-3.5" />
<RunAndHistory {...runAndHistoryProps} />
<div className="shrink-0 cursor-pointer rounded-lg border-[0.5px] border-components-button-secondary-border bg-components-button-secondary-bg shadow-xs backdrop-blur-[10px]">
{components?.chatVariableTrigger}

View File

@ -4,6 +4,7 @@ import { ChevronDownIcon } from '@heroicons/react/20/solid'
import { useEffect, useState } from 'react'
import { useReactFlow } from 'reactflow'
import Avatar from '@/app/components/base/avatar'
import Divider from '@/app/components/base/divider'
import {
PortalToFollowElem,
PortalToFollowElemContent,
@ -107,134 +108,137 @@ const OnlineUsers = () => {
const hasCounter = remainingCount > 0
return (
<div
className={cn(
'flex h-8 items-center rounded-full border-[0.5px] border-components-panel-border',
'bg-components-panel-bg py-1 shadow-xs shadow-shadow-shadow-3 backdrop-blur-[10px]',
hasCounter ? 'min-w-[87px] gap-px pl-1 pr-1.5' : 'gap-1 px-1.5',
)}
>
<div className="flex h-6 items-center">
<div className="flex items-center">
{visibleUsers.map((user, index) => {
const isCurrentUser = user.user_id === currentUserId
const userColor = isCurrentUser ? undefined : getUserColor(user.user_id)
return (
<Tooltip
key={`${user.sid}-${index}`}
popupContent={renderDisplayName(
user,
'system-xs-medium text-text-secondary',
'text-text-quaternary',
)}
position="bottom"
triggerMethod="hover"
needsDelay={false}
asChild
popupClassName="flex h-[28px] items-center justify-center gap-1 rounded-md border-[0.5px] border-components-panel-border bg-components-tooltip-bg px-3 py-[6px] shadow-lg shadow-shadow-shadow-5 backdrop-blur-[10px]"
noDecoration
>
<div
className={cn(
'relative flex size-6 items-center justify-center',
index > 0 && '-ml-1.5',
!isCurrentUser && 'cursor-pointer transition-transform hover:scale-110',
<>
<div
className={cn(
'flex h-8 items-center rounded-full border-[0.5px] border-components-panel-border',
'bg-components-panel-bg py-1 shadow-xs shadow-shadow-shadow-3 backdrop-blur-[10px]',
hasCounter ? 'min-w-[87px] gap-px pl-1 pr-1.5' : 'gap-1 px-1.5',
)}
>
<div className="flex h-6 items-center">
<div className="flex items-center">
{visibleUsers.map((user, index) => {
const isCurrentUser = user.user_id === currentUserId
const userColor = isCurrentUser ? undefined : getUserColor(user.user_id)
return (
<Tooltip
key={`${user.sid}-${index}`}
popupContent={renderDisplayName(
user,
'system-xs-medium text-text-secondary',
'text-text-quaternary',
)}
style={{ zIndex: visibleUsers.length - index }}
onClick={() => !isCurrentUser && jumpToUserCursor(user.user_id)}
position="bottom"
triggerMethod="hover"
needsDelay={false}
asChild
popupClassName="flex h-[28px] items-center justify-center gap-1 rounded-md border-[0.5px] border-components-panel-border bg-components-tooltip-bg px-3 py-[6px] shadow-lg shadow-shadow-shadow-5 backdrop-blur-[10px]"
noDecoration
>
<Avatar
name={user.username || 'User'}
avatar={getAvatarUrl(user)}
size={24}
className="ring-1 ring-components-panel-bg"
backgroundColor={userColor}
/>
</div>
</Tooltip>
)
})}
{remainingCount > 0 && (
<PortalToFollowElem
open={dropdownOpen}
onOpenChange={setDropdownOpen}
placement="bottom-start"
offset={{
mainAxis: 8,
crossAxis: -48,
}}
>
<PortalToFollowElemTrigger
onClick={() => setDropdownOpen(prev => !prev)}
asChild
>
<div className="flex items-center gap-1">
<div
className={cn(
'flex h-6 w-6 cursor-pointer select-none items-center justify-center rounded-full bg-components-icon-bg-midnight-solid text-[10px] font-semibold uppercase leading-[12px] text-white ring-1 ring-components-panel-bg',
visibleUsers.length > 0 && '-ml-1',
'relative flex size-6 items-center justify-center',
index > 0 && '-ml-1.5',
!isCurrentUser && 'cursor-pointer transition-transform hover:scale-110',
)}
style={{ zIndex: visibleUsers.length - index }}
onClick={() => !isCurrentUser && jumpToUserCursor(user.user_id)}
>
<Avatar
name={user.username || 'User'}
avatar={getAvatarUrl(user)}
size={24}
className="ring-1 ring-components-panel-bg"
backgroundColor={userColor}
/>
</div>
</Tooltip>
)
})}
{remainingCount > 0 && (
<PortalToFollowElem
open={dropdownOpen}
onOpenChange={setDropdownOpen}
placement="bottom-start"
offset={{
mainAxis: 8,
crossAxis: -48,
}}
>
<PortalToFollowElemTrigger
onClick={() => setDropdownOpen(prev => !prev)}
asChild
>
<div className="flex items-center gap-1">
<div
className={cn(
'flex h-6 w-6 cursor-pointer select-none items-center justify-center rounded-full bg-components-icon-bg-midnight-solid text-[10px] font-semibold uppercase leading-[12px] text-white ring-1 ring-components-panel-bg',
visibleUsers.length > 0 && '-ml-1',
)}
>
+
{remainingCount}
</div>
<ChevronDownIcon className="h-3 w-3 cursor-pointer text-gray-500" />
</div>
</PortalToFollowElemTrigger>
<PortalToFollowElemContent
className="z-[9999]"
>
<div
className={cn(
'mt-1.5',
'flex flex-col',
'max-h-[200px] w-[240px] overflow-y-auto',
'rounded-xl border-[0.5px] border-components-panel-border',
'bg-components-panel-bg-blur p-1',
'shadow-lg shadow-shadow-shadow-5',
'backdrop-blur-[10px]',
)}
>
+
{remainingCount}
</div>
<ChevronDownIcon className="h-3 w-3 cursor-pointer text-gray-500" />
</div>
</PortalToFollowElemTrigger>
<PortalToFollowElemContent
className="z-[9999]"
>
<div
className={cn(
'mt-1.5',
'flex flex-col',
'max-h-[200px] w-[240px] overflow-y-auto',
'rounded-xl border-[0.5px] border-components-panel-border',
'bg-components-panel-bg-blur p-1',
'shadow-lg shadow-shadow-shadow-5',
'backdrop-blur-[10px]',
)}
>
{onlineUsers.map((user) => {
const isCurrentUser = user.user_id === currentUserId
const userColor = isCurrentUser ? undefined : getUserColor(user.user_id)
return (
<div
key={user.sid}
className={cn(
'flex items-center gap-2 rounded-lg px-3 py-1.5',
!isCurrentUser && 'cursor-pointer hover:bg-components-panel-on-panel-item-bg-hover',
)}
onClick={() => {
if (!isCurrentUser) {
jumpToUserCursor(user.user_id)
setDropdownOpen(false)
}
}}
>
<div className="relative">
<Avatar
name={user.username || 'User'}
avatar={getAvatarUrl(user)}
size={24}
backgroundColor={userColor}
/>
{onlineUsers.map((user) => {
const isCurrentUser = user.user_id === currentUserId
const userColor = isCurrentUser ? undefined : getUserColor(user.user_id)
return (
<div
key={user.sid}
className={cn(
'flex items-center gap-2 rounded-lg px-3 py-1.5',
!isCurrentUser && 'cursor-pointer hover:bg-components-panel-on-panel-item-bg-hover',
)}
onClick={() => {
if (!isCurrentUser) {
jumpToUserCursor(user.user_id)
setDropdownOpen(false)
}
}}
>
<div className="relative">
<Avatar
name={user.username || 'User'}
avatar={getAvatarUrl(user)}
size={24}
backgroundColor={userColor}
/>
</div>
{renderDisplayName(
user,
'system-xs-medium text-text-secondary',
'text-text-tertiary',
)}
</div>
{renderDisplayName(
user,
'system-xs-medium text-text-secondary',
'text-text-tertiary',
)}
</div>
)
})}
</div>
</PortalToFollowElemContent>
</PortalToFollowElem>
)}
)
})}
</div>
</PortalToFollowElemContent>
</PortalToFollowElem>
)}
</div>
</div>
</div>
</div>
<Divider type="vertical" className="mx-auto h-3.5" />
</>
)
}