feat: tree search

This commit is contained in:
duanhongbo committed 2020-11-23 13:46:13 +08:00
1 parent fcb27ff156
commit bcbc20ff98
2 files changed
+138 -43

No files matched your search

+130 -43
View File
@@ -1,14 +1,14 @@
import React, { Component } from "react"; import React, { ChangeEvent, Component } from "react";
import { Menu, Input, Tree ,Dropdown} from "antd"; import { Input, Tree, Dropdown } from "antd";
import * as fs from "fs"; import * as fs from "fs";
import * as path from "path"; import * as path from "path";
import { ipcRenderer } from "electron"; import { ipcRenderer } from "electron";
import MainEventType from "../common/MainEventType"; import MainEventType from "../common/MainEventType";
import { DataNode } from "antd/lib/tree"; import { DataNode } from "antd/lib/tree";
import { IconType } from "rc-tree/lib/interface"; import { EventDataNode, IconType } from "rc-tree/lib/interface";
const { Search } = Input; const { Search } = Input;
const { DirectoryTree } = Tree; const { DirectoryTree, TreeNode } = Tree;
export interface PropertiesProps { export interface PropertiesProps {
workdir: string; workdir: string;
@@ -67,9 +67,9 @@ class FileDataNode implements DataNode {
parent: this, parent: this,
}); });
node.children = isFolder&&recursive ? (node.loadChilds(recursive) as FileDataNode[]) : [], (node.children =
isFolder && recursive ? (node.loadChilds(recursive) as FileDataNode[]) : []),
list.push(node); list.push(node);
}); });
return list; return list;
} }
@@ -112,6 +112,15 @@ class FileDataNode implements DataNode {
return null; return null;
} }
getList(): FileDataNode[] {
let ret = new Array<FileDataNode>(this);
for (const child of this.children) {
const childList = child.getList();
ret.push(...childList);
}
return ret;
}
// name:string; // name:string;
// path: string; // path: string;
// isFolder : boolean; // isFolder : boolean;
@@ -121,6 +130,15 @@ class FileDataNode implements DataNode {
interface PropertiesState { interface PropertiesState {
root: FileDataNode; root: FileDataNode;
searchKey: string;
defaultExpandedKeys:string[];
expandedKeys: string[];
autoExpandParent: boolean;
rightClickNode: {
pageX: number;
pageY: number;
key: string;
};
} }
const NodeActions: { [x: string]: string } = { const NodeActions: { [x: string]: string } = {
@@ -134,6 +152,11 @@ const NodeActions: { [x: string]: string } = {
export default class Properties extends Component<PropertiesProps> { export default class Properties extends Component<PropertiesProps> {
state: PropertiesState = { state: PropertiesState = {
root: null, root: null,
searchKey: "",
rightClickNode: null,
expandedKeys: [],
defaultExpandedKeys:[],
autoExpandParent: true,
}; };
curWorkdir: string = ""; curWorkdir: string = "";
@@ -158,7 +181,11 @@ export default class Properties extends Component<PropertiesProps> {
} }
const root = this.getRootNode(workdir); const root = this.getRootNode(workdir);
root.expandSelf(); root.expandSelf();
this.setState({ root: root }); this.setState({
root: root ,
expandedKeys : [root.key],
defaultExpandedKeys: [root.key]
});
} }
getRootNode(workdir: string) { getRootNode(workdir: string) {
@@ -191,14 +218,61 @@ export default class Properties extends Component<PropertiesProps> {
// ); // );
// } // }
// renderNode(node:FileDataNode){ handleOnSearch(value: string, event: ChangeEvent) {
// return (<Dropdown const expandedKeys = this.state.root
// overlay={this.renderContextMeun(node)} .getList()
// trigger={["contextMenu"]} .map((item) => {
// > if(!item.isLeaf)
// <div>{node.title}</div> return null;
// </Dropdown>) const title = item.title as string;
// } if (title.includes(value) && item.parent) {
return item.parent.key;
}
return null;
})
.filter((item, i, self) => item && self.indexOf(item) === i);
if (value && value.length>0) {
this.setState({
searchKey: value,
expandedKeys: expandedKeys,
autoExpandParent: true,
});
} else {
this.setState({
searchKey: "",
expandedKeys: this.state.defaultExpandedKeys,
autoExpandParent: false,
});
}
this.forceUpdate();
}
filterNode(node: EventDataNode): boolean {
const searchKey = this.state.searchKey;
const nodeKey = node.title as string;
return nodeKey.includes(searchKey);
}
titleRender(node:DataNode):React.ReactNode{
const titleStr = node.title as string;
const searchKey = this.state.searchKey;
const index = titleStr.indexOf(searchKey);
const beforeStr = titleStr.substr(0, index);
const afterStr = titleStr.substr(index + searchKey.length);
//return (<span>{titleStr}</span>)
return index > -1 ? (
<span>
{beforeStr}
<span className="site-tree-search-value">{searchKey}</span>
{afterStr}
</span>
) : (
<span>{titleStr}</span>
);
}
render() { render() {
console.log("render Properties"); console.log("render Properties");
@@ -206,34 +280,47 @@ export default class Properties extends Component<PropertiesProps> {
const root = this.state.root; const root = this.state.root;
const nodes = root ? [root] : []; const nodes = root ? [root] : [];
return nodes.length ? ( return nodes.length ? (
<DirectoryTree <div>
selectable <Search
showLine allowClear
expandAction="click" placeholder="Search"
treeData={nodes} onSearch={this.handleOnSearch.bind(this)}
defaultExpandedKeys={[root.key]} />
onCheck={(node) => console.log("onCheck")} <DirectoryTree
onSelect={(keys, info) => { selectable
console.log("onSelect", keys, info); // showLine
if (info.node.isLeaf) { checkStrictly
onOpenTree(keys[0] as string); expandAction="click"
} expandedKeys={this.state.expandedKeys}
}} autoExpandParent={this.state.autoExpandParent}
onExpand={(keys, info) => { titleRender={this.titleRender.bind(this)}
console.log("onExpand", info); treeData={nodes}
if (info.expanded && !info.node.expanded) { filterTreeNode={this.filterNode.bind(this)}
//let newRoot = _.cloneDeep(root); defaultExpandedKeys={[root.key]}
const node = root.findChild(info.node.key as string); onSelect={(keys, info) => {
if (node) { console.log("onSelect", keys, info);
node.expandSelf(); if (info.node.isLeaf) {
this.setState({ root: root }); onOpenTree(keys[0] as string);
this.forceUpdate();
} }
} }}
}} onExpand={(keys, info) => {
onLoad={(keys, info) => console.log("onLoad", keys, info)} console.log("onExpand", info);
onRightClick={(event) => console.log("onRightClick", event)} this.setState({
></DirectoryTree> expandedKeys:keys,
autoExpandParent:false
})
if (info.expanded && !info.node.expanded) {
//let newRoot = _.cloneDeep(root);
const node = root.findChild(info.node.key as string);
if (node) {
node.expandSelf();
this.setState({ root: root });
}
}
this.forceUpdate();
}}
></DirectoryTree>
</div>
) : ( ) : (
`Work Dir (${workdir}) Empty` `Work Dir (${workdir}) Empty`
); );
+8
View File
@@ -41,3 +41,11 @@ body {
height : 50px; height : 50px;
background-color: #818181; background-color: #818181;
} }
.site-tree-search-value {
color: #f50;
}
[data-theme="dark"] .site-tree-search-value {
color: #d84a1b;
}