mirror of https://github.com/abpframework/abp.git
3 changed files with 101 additions and 4 deletions
@ -1,11 +1,12 @@ |
|||
import { NgModule } from '@angular/core'; |
|||
|
|||
import { NgbDropdownModule } from '@ng-bootstrap/ng-bootstrap'; |
|||
import { NzTreeModule } from 'ng-zorro-antd/tree'; |
|||
import { TreeComponent } from './components/tree.component'; |
|||
import { CommonModule } from '@angular/common'; |
|||
|
|||
@NgModule({ |
|||
imports: [], |
|||
exports: [], |
|||
imports: [CommonModule, NzTreeModule, NgbDropdownModule], |
|||
exports: [TreeComponent], |
|||
declarations: [TreeComponent], |
|||
providers: [], |
|||
}) |
|||
export class TreeModule {} |
|||
|
|||
@ -0,0 +1,95 @@ |
|||
export abstract class BaseNode { |
|||
name?: string; |
|||
displayName?: string; |
|||
|
|||
constructor(public id: string, public parentId: string | null) {} |
|||
} |
|||
|
|||
class TreeNode<T extends BaseNode> extends BaseNode { |
|||
title: string | undefined; |
|||
key: string; |
|||
icon: string | null = null; |
|||
children: TreeNode<T>[] = []; |
|||
isLeaf = true; |
|||
checked = false; |
|||
selected = false; |
|||
expanded = false; |
|||
selectable = true; |
|||
disabled = false; |
|||
disableCheckbox = false; |
|||
parentNode?: TreeNode<T> | null; |
|||
|
|||
constructor(public entity: T, private nameResolver = ent => ent.displayName || ent.name) { |
|||
super(entity.id, entity.parentId); |
|||
this.key = entity.id; |
|||
this.title = nameResolver(entity); |
|||
} |
|||
} |
|||
|
|||
export class TreeAdapter<T extends BaseNode = BaseNode> { |
|||
private tree: TreeNode<T>[]; |
|||
|
|||
constructor(private list: T[] = []) { |
|||
this.tree = createTreeFromList(this.list); |
|||
} |
|||
|
|||
getList() { |
|||
return this.list; |
|||
} |
|||
|
|||
getTree() { |
|||
return this.tree; |
|||
} |
|||
|
|||
handleDrop(node: TreeNode<T>) { |
|||
const { key, parentNode } = node; |
|||
const index = this.list.findIndex(({ id }) => id === key); |
|||
this.list[index].parentId = parentNode ? parentNode.key : null; |
|||
this.tree = createTreeFromList(this.list); |
|||
} |
|||
|
|||
handleRemove(node: TreeNode<T>) { |
|||
const { key, parentNode } = node; |
|||
this.list = this.list.filter(({ id, parentId }) => id !== key && parentId !== key); |
|||
this.tree = createTreeFromList(this.list); |
|||
} |
|||
} |
|||
|
|||
// UTILITY FUNCTIONS
|
|||
|
|||
function createTreeFromList<T extends BaseNode>(list: T[]): TreeNode<T>[] { |
|||
const map = createMapFromList(list); |
|||
const tree: TreeNode<T>[] = []; |
|||
|
|||
list.forEach(row => { |
|||
const parentId = row.parentId; |
|||
const node = map.get(row.id); |
|||
if (parentId) { |
|||
const parent = map.get(parentId); |
|||
parent.children.push(node); |
|||
parent.isLeaf = false; |
|||
} else { |
|||
tree.push(node); |
|||
} |
|||
}); |
|||
|
|||
return tree; |
|||
} |
|||
|
|||
function createListFromTree<T extends BaseNode>(tree: TreeNode<T>[], list: T[] = []): T[] { |
|||
tree.forEach(node => { |
|||
list.push({ ...node.entity, parentId: node.parentId }); |
|||
if (node.children) createListFromTree(node.children, list); |
|||
}); |
|||
|
|||
return list; |
|||
} |
|||
|
|||
function createMapFromList<T extends BaseNode>( |
|||
list: T[], |
|||
map = new Map<string, TreeNode<T>>(), |
|||
): Map<string, TreeNode<T>> { |
|||
list.forEach(row => map.set(row.id, new TreeNode(row))); |
|||
|
|||
return map; |
|||
} |
|||
@ -1,2 +1,3 @@ |
|||
export * from './lib/tree.module'; |
|||
export * from './lib/components/tree.component'; |
|||
export * from './lib/utils/nz-tree-adapter'; |
|||
|
|||
Loading…
Reference in new issue