| if (!children || children.length === 0) | if (!children || children.length === 0) | ||||
| return | return | ||||
| const hasCircle = !!children.find(c => c.message_id === removeId) | |||||
| const hasCircle = !!children.find((c) => { | |||||
| const childId = c.message_id || (c as any).id | |||||
| return childId === removeId | |||||
| }) | |||||
| if (hasCircle) { | if (hasCircle) { | ||||
| node.hasCircle = true | node.hasCircle = true | ||||
| node.children = node.children.filter(c => c.message_id !== removeId) | |||||
| node.children = node.children.filter((c) => { | |||||
| const childId = c.message_id || (c as any).id | |||||
| return childId !== removeId | |||||
| }) | |||||
| children = node.children | children = node.children | ||||
| } | } | ||||
| const result: AgentLogItemWithChildren[] = [] | const result: AgentLogItemWithChildren[] = [] | ||||
| const addedItemIds: string[] = [] | const addedItemIds: string[] = [] | ||||
| list.forEach((item) => { | list.forEach((item) => { | ||||
| if (!addedItemIds.includes(item.message_id)) { | |||||
| const itemId = item.message_id || (item as any).id | |||||
| if (itemId && !addedItemIds.includes(itemId)) { | |||||
| result.push(item) | result.push(item) | ||||
| addedItemIds.push(item.message_id) | |||||
| addedItemIds.push(itemId) | |||||
| } | } | ||||
| }) | }) | ||||
| return result | return result | ||||
| const removeCircleLogItem = (log: AgentLogItemWithChildren) => { | const removeCircleLogItem = (log: AgentLogItemWithChildren) => { | ||||
| const newLog = cloneDeep(log) | const newLog = cloneDeep(log) | ||||
| // If no children, return as is | |||||
| if (!newLog.children || newLog.children.length === 0) | |||||
| return newLog | |||||
| newLog.children = removeRepeatedSiblings(newLog.children) | newLog.children = removeRepeatedSiblings(newLog.children) | ||||
| let { message_id: id, children } = newLog | |||||
| if (!children || children.length === 0) | |||||
| return log | |||||
| const id = newLog.message_id || (newLog as any).id | |||||
| let { children } = newLog | |||||
| // check one step circle | // check one step circle | ||||
| const hasOneStepCircle = !!children.find(c => c.message_id === id) | |||||
| const hasOneStepCircle = !!children.find((c) => { | |||||
| const childId = c.message_id || (c as any).id | |||||
| return childId === id | |||||
| }) | |||||
| if (hasOneStepCircle) { | if (hasOneStepCircle) { | ||||
| newLog.hasCircle = true | newLog.hasCircle = true | ||||
| newLog.children = newLog.children.filter(c => c.message_id !== id) | |||||
| newLog.children = newLog.children.filter((c) => { | |||||
| const childId = c.message_id || (c as any).id | |||||
| return childId !== id | |||||
| }) | |||||
| children = newLog.children | children = newLog.children | ||||
| } | } | ||||
| if (!logs || logs.length === 0) | if (!logs || logs.length === 0) | ||||
| return [] | return [] | ||||
| const tree: AgentLogItemWithChildren[] = [] | |||||
| logs.forEach((log) => { | |||||
| const hasParent = !!log.parent_id | |||||
| if (hasParent) { | |||||
| const parent = logs.find(item => item.message_id === log.parent_id) as AgentLogItemWithChildren | |||||
| if (parent) { | |||||
| if (!parent.children) | |||||
| parent.children = [] | |||||
| parent.children.push(log as AgentLogItemWithChildren) | |||||
| } | |||||
| // First pass: identify all unique items and track parent-child relationships | |||||
| const itemsById = new Map<string, any>() | |||||
| const childrenById = new Map<string, any[]>() | |||||
| logs.forEach((item) => { | |||||
| const itemId = item.message_id || (item as any).id | |||||
| // Only add to itemsById if not already there (keep first occurrence) | |||||
| if (itemId && !itemsById.has(itemId)) | |||||
| itemsById.set(itemId, item) | |||||
| // Initialize children array for this ID if needed | |||||
| if (itemId && !childrenById.has(itemId)) | |||||
| childrenById.set(itemId, []) | |||||
| // If this item has a parent, add it to parent's children list | |||||
| if (item.parent_id) { | |||||
| if (!childrenById.has(item.parent_id)) | |||||
| childrenById.set(item.parent_id, []) | |||||
| childrenById.get(item.parent_id)!.push(item) | |||||
| } | } | ||||
| else { | |||||
| tree.push(log as AgentLogItemWithChildren) | |||||
| }) | |||||
| // Second pass: build tree structure | |||||
| const tree: AgentLogItemWithChildren[] = [] | |||||
| // Find root nodes (items without parents) | |||||
| itemsById.forEach((item) => { | |||||
| const hasParent = !!item.parent_id | |||||
| if (!hasParent) { | |||||
| const itemId = item.message_id || (item as any).id | |||||
| const children = childrenById.get(itemId) | |||||
| if (children && children.length > 0) | |||||
| item.children = children | |||||
| tree.push(item as AgentLogItemWithChildren) | |||||
| } | } | ||||
| }) | }) | ||||
| // Add children property to all items that have children | |||||
| itemsById.forEach((item) => { | |||||
| const itemId = item.message_id || (item as any).id | |||||
| const children = childrenById.get(itemId) | |||||
| if (children && children.length > 0) | |||||
| item.children = children | |||||
| }) | |||||
| return tree | return tree | ||||
| } | } | ||||