Files
ai-agent/web/lib/tag-tree.ts
T
mlogclub 8398cd6f91 feat: implement TagSelector component for improved tag management across dashboard features
- Added TagSelector component to streamline tag selection in various components.
- Refactored existing tag handling in DashboardConversationsPage, ConversationTagPicker, EditDialog, and TicketsPage to utilize the new TagSelector.
- Removed redundant tag handling functions and optimized state management for tags.
- Updated tests to ensure proper functionality of the new tag handling logic.
2026-05-30 11:23:05 +08:00

90 lines
2.1 KiB
TypeScript

import type { TagTree } from "@/lib/api/admin"
export type FlatTagNode = TagTree & {
depth: number
path: string
searchableText: string
}
type FlattenTagTreeOptions = {
excludeIds?: number[]
}
type FlattenVisibleTagTreeOptions = FlattenTagTreeOptions & {
collapsedIds?: number[]
}
export function flattenTagTree(
nodes: TagTree[] | null | undefined,
options: FlattenTagTreeOptions = {}
): FlatTagNode[] {
const excluded = new Set(options.excludeIds ?? [])
const result: FlatTagNode[] = []
function walk(items: TagTree[] | null | undefined, depth: number, parentPath: string) {
const safeItems = Array.isArray(items) ? items : []
safeItems.forEach((item) => {
if (excluded.has(item.id)) {
return
}
const path = parentPath ? `${parentPath} / ${item.name}` : item.name
result.push({
...item,
depth,
path,
searchableText: `${path} ${item.id} ${item.remark ?? ""}`,
})
walk(item.children, depth + 1, path)
})
}
walk(nodes, 0, "")
return result
}
export function buildTagPathMap(
nodes: TagTree[] | null | undefined
): Map<number, string> {
const result = new Map<number, string>()
flattenTagTree(nodes).forEach((item) => {
result.set(item.id, item.path)
})
return result
}
export function flattenVisibleTagTree(
nodes: TagTree[] | null | undefined,
options: FlattenVisibleTagTreeOptions = {}
): FlatTagNode[] {
const excluded = new Set(options.excludeIds ?? [])
const collapsed = new Set(options.collapsedIds ?? [])
const result: FlatTagNode[] = []
function walk(items: TagTree[] | null | undefined, depth: number, parentPath: string) {
const safeItems = Array.isArray(items) ? items : []
safeItems.forEach((item) => {
if (excluded.has(item.id)) {
return
}
const path = parentPath ? `${parentPath} / ${item.name}` : item.name
result.push({
...item,
depth,
path,
searchableText: `${path} ${item.id} ${item.remark ?? ""}`,
})
if (!collapsed.has(item.id)) {
walk(item.children, depth + 1, path)
}
})
}
walk(nodes, 0, "")
return result
}