diff --git a/web/app/components/workflow-app/components/workflow-main.tsx b/web/app/components/workflow-app/components/workflow-main.tsx
index f6704026b5..15ef50a3a0 100644
--- a/web/app/components/workflow-app/components/workflow-main.tsx
+++ b/web/app/components/workflow-app/components/workflow-main.tsx
@@ -11,6 +11,8 @@ import { FILE_EXTS } from '@/app/components/base/prompt-editor/constants'
import { WorkflowWithInnerContext } from '@/app/components/workflow'
import type { WorkflowProps } from '@/app/components/workflow'
import WorkflowChildren from './workflow-children'
+import UserCursors from '@/app/components/workflow/collaboration/components/user-cursors'
+
import {
useConfigsMap,
useInspectVarsCrud,
@@ -229,63 +231,7 @@ const WorkflowMain = ({
>
-
- {/* Render other users' cursors on top */}
- {Object.entries(cursors || {}).map(([userId, cursor]) => {
- if (userId === myUserId)
- return null
-
- const userInfo = onlineUsers.find(user => user.user_id === userId)
- const userName = userInfo?.username || `User ${userId.slice(-4)}`
-
- const getUserColor = (id: string) => {
- const colors = ['#3B82F6', '#EF4444', '#10B981', '#F59E0B', '#8B5CF6', '#EC4899', '#06B6D4', '#84CC16']
- const hash = id.split('').reduce((a, b) => {
- a = ((a << 5) - a) + b.charCodeAt(0)
- return a & a
- }, 0)
- return colors[Math.abs(hash) % colors.length]
- }
-
- const userColor = getUserColor(userId)
-
- return (
-
-
-
-
- {userName}
-
-
- )
- })}
+
)
}
diff --git a/web/app/components/workflow/collaboration/components/user-cursors.tsx b/web/app/components/workflow/collaboration/components/user-cursors.tsx
new file mode 100644
index 0000000000..799972b0b8
--- /dev/null
+++ b/web/app/components/workflow/collaboration/components/user-cursors.tsx
@@ -0,0 +1,75 @@
+import type { FC } from 'react'
+import type { CursorPosition, OnlineUser } from '@/app/components/workflow/collaboration/types'
+
+type UserCursorsProps = {
+ cursors: Record
+ myUserId: string | null
+ onlineUsers: OnlineUser[]
+}
+
+const getUserColor = (id: string) => {
+ const colors = ['#3B82F6', '#EF4444', '#10B981', '#F59E0B', '#8B5CF6', '#EC4899', '#06B6D4', '#84CC16']
+ const hash = id.split('').reduce((a, b) => {
+ a = ((a << 5) - a) + b.charCodeAt(0)
+ return a & a
+ }, 0)
+ return colors[Math.abs(hash) % colors.length]
+}
+
+const UserCursors: FC = ({
+ cursors,
+ myUserId,
+ onlineUsers,
+}) => {
+ return (
+ <>
+ {Object.entries(cursors || {}).map(([userId, cursor]) => {
+ if (userId === myUserId)
+ return null
+
+ const userInfo = onlineUsers.find(user => user.user_id === userId)
+ const userName = userInfo?.username || `User ${userId.slice(-4)}`
+ const userColor = getUserColor(userId)
+
+ return (
+
+
+
+
+ {userName}
+
+
+ )
+ })}
+ >
+ )
+}
+
+export default UserCursors