fineui是帆软报表和BI产品线所使用的前端框架。
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

302 lines
9.7 KiB

2 years ago
import {
shortcut,
emptyFn,
i18nText,
isNotNull,
isKey,
HorizontalFillLayout,
Tree,
deepClone,
Func,
concat,
isNotEmptyArray,
each,
uniqBy,
map,
isFunction,
find
} from "@/core";
import { Trigger, Searcher } from "@/base";
import { StateEditor, DefaultTextEditor } from "@/case";
import { MultiLayerSelectTreeInsertSearchPane } from "./multilayerselecttree.insert.search.pane";
import { MultiLayerSelectTreePopup } from "./multilayerselecttree.popup";
2 years ago
@shortcut()
export class MultiLayerSelectTreeTrigger extends Trigger {
static xtype = "bi.multilayer_select_tree_trigger";
static EVENT_FOCUS = "EVENT_FOCUS";
static EVENT_BLUR = "EVENT_BLUR";
static EVENT_SEARCHING = "EVENT_SEARCHING";
static EVENT_STOP = "EVENT_STOP";
static EVENT_START = "EVENT_START";
static EVENT_CHANGE = "EVENT_CHANGE";
static EVENT_ADD_ITEM = "EVENT_ADD_ITEM";
props() {
return {
extraCls: "bi-multi-layer-select-tree-trigger",
height: 24,
2 years ago
itemsCreator: emptyFn,
watermark: i18nText("BI-Basic_Search"),
allowSearchValue: false,
2 years ago
title: () => this._getShowText(),
};
2 years ago
}
2 years ago
render() {
const self = this,
o = this.options;
if (o.itemsCreator === BI.emptyFn) {
this._initData();
}
return {
2 years ago
type: HorizontalFillLayout.xtype,
items: [
{
el: {
2 years ago
type: Searcher.xtype,
ref() {
self.searcher = this;
},
2 years ago
masker: isNotNull(o.container)
? {
offset: {},
container: o.container,
}
: {
offset: {},
},
isAutoSearch: false,
el: {
2 years ago
type: DefaultTextEditor.xtype,
ref() {
self.editor = this;
},
defaultText: o.defaultText,
2 years ago
text: isKey(o.value)
? this._digest(o.value)
: o.text,
value: o.value,
height: o.height,
tipText: "",
watermark: o.watermark,
2 years ago
listeners: [
{
eventName: StateEditor.EVENT_FOCUS,
action() {
self.fireEvent(
MultiLayerSelectTreeTrigger.EVENT_FOCUS
);
},
},
{
eventName: StateEditor.EVENT_BLUR,
action() {
self.fireEvent(
MultiLayerSelectTreeTrigger.EVENT_BLUR
);
},
},
{
eventName: StateEditor.EVENT_CHANGE,
action() {
self.fireEvent(
MultiLayerSelectTreeTrigger.EVENT_SEARCHING
);
},
}
2 years ago
],
},
popup: {
2 years ago
type: o.allowInsertValue
? MultiLayerSelectTreeInsertSearchPane.xtype
: MultiLayerSelectTreePopup.xtype,
itemsCreator:
o.itemsCreator === emptyFn
? emptyFn
: function (op, callback) {
op.keyword = self.editor.getValue();
o.itemsCreator(op, callback);
},
keywordGetter() {
return self.editor.getValue();
},
cls: "bi-card",
2 years ago
listeners: [
{
eventName:
MultiLayerSelectTreeInsertSearchPane.EVENT_ADD_ITEM,
action() {
self.options.text = self
.getSearcher()
.getKeyword();
self.fireEvent(
MultiLayerSelectTreeTrigger.EVENT_ADD_ITEM
);
},
}
2 years ago
],
ref(_ref) {
self.popup = _ref;
2 years ago
},
},
2 years ago
onSearch(obj, callback) {
const keyword = obj.keyword;
if (o.itemsCreator === BI.emptyFn) {
callback(self._getSearchItems(keyword));
2 years ago
o.allowInsertValue &&
self.popup.setKeyword(keyword);
} else {
callback();
}
},
2 years ago
listeners: [
{
eventName: Searcher.EVENT_CHANGE,
action() {
self.fireEvent(
MultiLayerSelectTreeTrigger.EVENT_CHANGE
);
},
}
2 years ago
],
},
width: "fill",
2 years ago
rgap: 24,
}
],
};
2 years ago
}
2 years ago
_initData() {
const o = this.options;
this.tree = new Tree();
this.nodes = Tree.treeFormat(deepClone(o.items));
this.tree.initTree(this.nodes);
2 years ago
}
2 years ago
_getSearchItems(keyword) {
const self = this,
o = this.options;
// 把数组搜索换成用BI.tree搜索节点, 搜到了就不再往下搜索
2 years ago
const items = [];
this.tree.traverse(node => {
const find = Func.getSearchResult(
self.tree.isRoot(node)
? []
: concat(
[node.text],
o.allowSearchValue ? [node.value] : []
),
keyword
);
if (find.find.length > 0 || find.match.length > 0) {
items.push(node);
2 years ago
return true;
}
});
2 years ago
return this._fillTreeStructure4Search(items, "id");
2 years ago
}
2 years ago
_createJson(node, open) {
return {
id: node.id,
pId: node.pId,
text: node.text,
value: node.value,
2 years ago
isParent: isNotEmptyArray(node.children),
open,
};
2 years ago
}
2 years ago
_getChildren(node) {
const self = this;
node.children = node.children || [];
2 years ago
let nodes = [];
each(node.children, (idx, child) => {
const children = self._getChildren(child);
nodes = nodes.concat(children);
});
2 years ago
return node.children.concat(nodes);
2 years ago
}
_fillTreeStructure4Search(leaves) {
const self = this;
let result = [];
const queue = [];
each(leaves, (idx, node) => {
queue.push({ pId: node.pId });
result.push(node);
result = result.concat(self._getChildren(node));
});
queue.reverse();
2 years ago
while (isNotEmptyArray(queue)) {
const node = queue.pop();
const pNode = this.tree.search(this.tree.getRoot(), node.pId, "id");
if (pNode != null) {
pNode.open = true;
queue.push({ pId: pNode.pId });
result.push(pNode);
}
}
2 years ago
return uniqBy(
map(result, (idx, node) => self._createJson(node, node.open)),
"id"
);
}
_digest(v) {
const o = this.options;
if (isFunction(o.valueFormatter)) {
return o.valueFormatter(v);
}
2 years ago
const result = find(o.items, (i, item) => item.value === v);
2 years ago
return isNotNull(result) ? result.text : o.text ?? v;
}
2 years ago
_getShowText() {
return this.editor.getText();
2 years ago
}
2 years ago
stopEditing() {
this.searcher.stopSearch();
2 years ago
}
2 years ago
getSearcher() {
return this.searcher;
2 years ago
}
2 years ago
populate(items) {
this.options.items = items;
this._initData(items);
2 years ago
}
2 years ago
setValue(v) {
this.editor.setState(this._digest(v[0]));
2 years ago
}
2 years ago
getValue() {
return this.searcher.getValue();
2 years ago
}
2 years ago
focus() {
this.searcher.focus();
2 years ago
}
2 years ago
blur() {
this.searcher.blur();
2 years ago
}
2 years ago
setWaterMark(v) {
this.searcher.setWaterMark(v);
}
2 years ago
}