MCPcopy Create free account
hub / github.com/agent-tower/core / TaskList

Function TaskList

packages/web/src/components/task/TaskList.tsx:68–399  ·  view source on GitHub ↗
({
  tasks = [],
  projects = [],
  selectedTaskId,
  onSelectTask,
  filterProjectId,
  setFilterProjectId,
  width = 320,
  onCreateTask,
  onCreateProject,
  isCreateActive,
  activeTaskIds,
  onTaskStatusChange,
  onDeleteTask,
}: TaskListProps)

Source from the content-addressed store, hash-verified

66export function TaskList({
67 tasks = [],
68 projects = [],
69 selectedTaskId,
70 onSelectTask,
71 filterProjectId,
72 setFilterProjectId,
73 width = 320,
74 onCreateTask,
75 onCreateProject,
76 isCreateActive,
77 onTaskStatusChange,
78 onDeleteTask,
79}: TaskListProps) {
80 const { t } = useI18n()
81 const { preserveDesktopSearch } = useDesktopTitlebar()
82 const isMobile = useIsMobile()
83 const [activeDragTask, setActiveDragTask] = useState<UITask | null>(null)
84 const [activeDragFromStatus, setActiveDragFromStatus] = useState<UITaskStatus | null>(null)
85 const [isSearchOpen, setIsSearchOpen] = useState(false)
86
87 const flipRegistryRef = useRef<Map<string, HTMLElement>>(new Map())
88 const activeGhostsRef = useRef<Set<HTMLDivElement>>(new Set())
89 const previousCardsRef = useRef<Map<string, { status: UITaskStatus; rect: DOMRect; html: string }>>(new Map())
90
91 const flipHandle = useMemo<FlipHandle>(() => ({
92 registry: flipRegistryRef.current,
93 }), [])
94
95 const removeGhost = useCallback((ghost: HTMLDivElement) => {
96 ghost.remove()
97 activeGhostsRef.current.delete(ghost)
98 }, [])
99
100 // 直接在 render 中计算派生状态,不使用 useEffect
101 const filteredTasks = filterProjectId
102 ? tasks.filter(t => t.projectId === filterProjectId)
103 : tasks
104
105 const getGroupFallbackRect = useCallback((status: UITaskStatus, fromRect: DOMRect): DOMRect | null => {
106 const group = document.querySelector<HTMLElement>(`[data-task-group-status="${status}"]`)
107 if (!group) return null
108
109 const header = group.querySelector<HTMLElement>('button')
110 const rect = (header ?? group).getBoundingClientRect()
111 if (rect.width === 0 || rect.height === 0) return null
112
113 return new DOMRect(rect.left + 8, rect.bottom + 4, fromRect.width, fromRect.height)
114 }, [])
115
116 const createStatusMoveGhost = useCallback((fromRect: DOMRect, toRect: DOMRect, html: string, isFallbackTarget = false) => {
117 const ghost = document.createElement('div')
118 ghost.setAttribute('aria-hidden', 'true')
119 ghost.innerHTML = html
120 const inner = ghost.firstElementChild as HTMLElement | null
121 if (inner) {
122 inner.style.cssText = ''
123 inner.className = inner.className
124 .replace(/\bopacity-\S*/g, '')
125 .replace(/\banimate-task-enter\b/g, '')

Callers

nothing calls this directly

Calls 9

useI18nFunction · 0.90
useDesktopTitlebarFunction · 0.90
useIsMobileFunction · 0.90
groupTasksByStatusFunction · 0.85
setMethod · 0.80
removeMethod · 0.45
deleteMethod · 0.45
getMethod · 0.45
hasMethod · 0.45

Tested by

no test coverage detected