Add tree organization system with categories, tags, and folders

Features:
- Categories: Global and team-specific tree categorization (admin-managed)
- Tags: Flexible tree tagging with autocomplete (author + admin)
- User folders: Personal tree collections with subfolder support
  - Hierarchical structure (max 3 levels deep)
  - Right-click context menu for folder management
  - Cascade delete for subfolders
- Filter trees by category, tags, and folder in library view

Backend:
- New models: Category, Tag, UserFolder with relationships
- New API endpoints for categories, tags, and folders
- Tree organization migrations (005, 006)

Frontend:
- FolderSidebar with hierarchical folder tree
- FolderEditModal for create/edit with color picker
- AddToFolderMenu for quick tree organization
- TagInput with autocomplete and TagBadges display
- Updated TreeMetadataForm and TreeLibraryPage

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
chihlasm
2026-02-02 01:31:13 -05:00
parent 2d99c52025
commit fafdaa50a5
41 changed files with 5006 additions and 221 deletions

View File

@@ -0,0 +1,45 @@
// Category types for tree organization
export interface Category {
id: string
name: string
slug: string
description: string | null
team_id: string | null
display_order: number
is_active: boolean
created_at: string
updated_at: string
tree_count: number
}
export interface CategoryListItem {
id: string
name: string
slug: string
description: string | null
team_id: string | null
display_order: number
is_active: boolean
tree_count: number
}
export interface CategoryCreate {
name: string
description?: string | null
team_id?: string | null
}
export interface CategoryUpdate {
name?: string
description?: string | null
display_order?: number
is_active?: boolean
}
// Embedded category info for tree responses
export interface CategoryInfo {
id: string
name: string
slug: string
}

View File

@@ -0,0 +1,52 @@
// Folder types for user tree organization
export interface Folder {
id: string
name: string
color: string
icon: string
parent_id: string | null
display_order: number
tree_count: number
created_at: string
updated_at: string
}
export interface FolderListItem {
id: string
name: string
color: string
icon: string
parent_id: string | null
display_order: number
tree_count: number
}
export interface FolderCreate {
name: string
color?: string
icon?: string
parent_id?: string | null
}
export interface FolderUpdate {
name?: string
color?: string
icon?: string
display_order?: number
parent_id?: string | null
}
export interface FolderReorderRequest {
folder_ids: string[]
}
export interface FolderTreeRequest {
tree_id: string
}
// For hierarchical display of folders
export interface FolderTreeItem extends FolderListItem {
children: FolderTreeItem[]
isExpanded?: boolean
}

View File

@@ -3,6 +3,9 @@ export * from './auth'
export * from './tree'
export * from './session'
export * from './invite'
export * from './tag'
export * from './category'
export * from './folder'
// API response wrapper types
export interface PaginatedResponse<T> {

27
frontend/src/types/tag.ts Normal file
View File

@@ -0,0 +1,27 @@
// Tag types for tree organization
export interface Tag {
id: string
name: string
slug: string
team_id: string | null
usage_count: number
created_at: string
}
export interface TagListItem {
id: string
name: string
slug: string
team_id: string | null
usage_count: number
}
export interface TagCreate {
name: string
team_id?: string | null
}
export interface TagAssignment {
tags: string[]
}

View File

@@ -1,3 +1,5 @@
import type { CategoryInfo } from './category'
// Tree node types
export type NodeType = 'decision' | 'action' | 'solution'
@@ -60,10 +62,15 @@ export interface Tree {
name: string
description: string | null
category: string | null
category_id: string | null
category_info: CategoryInfo | null
tags: string[]
tree_structure: TreeStructure
author_id: string | null
team_id: string | null
is_active: boolean
is_public: boolean
is_default: boolean
version: number
created_at: string
updated_at: string
@@ -75,7 +82,13 @@ export interface TreeListItem {
name: string
description: string | null
category: string | null
category_id: string | null
category_info: CategoryInfo | null
tags: string[]
author_id: string | null
is_active: boolean
is_public: boolean
is_default: boolean
version: number
usage_count: number
created_at: string
@@ -86,13 +99,33 @@ export interface TreeCreate {
name: string
description?: string
category?: string
category_id?: string | null
tags?: string[]
tree_structure: TreeStructure
is_public?: boolean
is_default?: boolean
}
export interface TreeUpdate {
name?: string
description?: string
category?: string
category_id?: string | null
tags?: string[]
tree_structure?: TreeStructure
is_active?: boolean
is_public?: boolean
}
// Filter params for tree listing
export interface TreeFilters {
category?: string
category_id?: string
tags?: string
folder_id?: string
is_active?: boolean
author_id?: string
is_public?: boolean
skip?: number
limit?: number
}

View File

@@ -5,6 +5,7 @@ export interface User {
email: string
name: string
role: UserRole
is_team_admin: boolean
team_id: string | null
created_at: string
last_login: string | null