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.
 
 
 

446 lines
15 KiB

import {
shortcut,
extend,
emptyFn,
deepClone,
isKey,
Selection,
remove,
pushDistinct,
createWidget,
isNotEmptyString,
i18nText,
isEmptyArray,
last,
initial,
endWith,
AbsoluteLayout,
isEmptyString,
makeObject,
each,
Func,
map,
concat,
isNotNull,
values,
filter,
contains,
isNull, VerticalFillLayout
} from "@/core";
import { Single, Searcher } from "@/base";
import { MultiSelectBar } from "@/case";
import { SelectPatchEditor } from "../multiselect/trigger/editor/editor.patch";
import { MultiSelectLoader } from "../multiselect/multiselect.loader";
import { MultiSelectSearchInsertPane } from "../multiselect/search/multiselect.search.insert.pane";
import { SearchEditor } from "@/widget/editor/editor.search";
@shortcut()
export class MultiSelectInsertList extends Single {
static xtype = "bi.multi_select_insert_list";
static REQ_GET_DATA_LENGTH = "1";
static REQ_GET_ALL_DATA = "-1";
static EVENT_CHANGE = "EVENT_CHANGE";
_defaultConfig() {
return extend(super._defaultConfig(...arguments), {
baseCls: "bi-multi-select-insert-list",
itemsCreator: emptyFn,
valueFormatter: emptyFn,
searcherHeight: BI.SIZE_CONSANTS.TRIGGER_HEIGHT,
itemHeight: BI.SIZE_CONSANTS.LIST_ITEM_HEIGHT,
});
}
_init() {
super._init(...arguments);
const self = this,
o = this.options;
this.storeValue = this._assertValue(deepClone(o.value) || {});
function assertShowValue() {
isKey(self._startValue) &&
(self.storeValue.type === Selection.All
? remove(self.storeValue.value, self._startValue)
: pushDistinct(self.storeValue.value, self._startValue));
// self.trigger.setValue(self.storeValue);
}
this.adapter = createWidget({
type: MultiSelectLoader.xtype,
cls: "popup-multi-select-list bi-border-left bi-border-right bi-border-bottom",
itemsCreator: o.itemsCreator,
itemHeight: o.itemHeight,
valueFormatter: o.valueFormatter,
itemFormatter: o.itemFormatter,
logic: {
dynamic: false,
},
// onLoaded: o.onLoaded,
el: {},
isDefaultInit: true,
value: o.value,
});
this.adapter.on(MultiSelectLoader.EVENT_CHANGE, function () {
self.storeValue = this.getValue();
assertShowValue();
self.fireEvent(MultiSelectInsertList.EVENT_CHANGE);
});
this.searcherPane = createWidget({
type: MultiSelectSearchInsertPane.xtype,
cls: "bi-border-left bi-border-right bi-border-bottom",
valueFormatter: o.valueFormatter,
itemFormatter: o.itemFormatter,
keywordGetter() {
return self.trigger.getKeyword();
},
itemsCreator(op, callback) {
const keyword = self.trigger.getKeyword();
if (isNotEmptyString(keyword)) {
op.keywords = [keyword];
this.setKeyword(op.keywords[0]);
o.itemsCreator(op, callback);
}
},
itemHeight: o.itemHeight,
});
this.searcherPane.setVisible(false);
this.trigger = createWidget({
type: Searcher.xtype,
el: {
type: SelectPatchEditor.xtype,
el: {
type: SearchEditor.xtype,
watermark: i18nText("BI-Basic_Search_And_Patch_Paste"),
},
ref(ref) {
self.editor = ref;
},
},
isAutoSearch: false,
isAutoSync: false,
onSearch(op, callback) {
callback();
},
adapter: this.adapter,
popup: this.searcherPane,
masker: false,
listeners: [
{
eventName: Searcher.EVENT_START,
action() {
self._showSearcherPane();
self._setStartValue("");
this.setValue(deepClone(self.storeValue));
},
},
{
eventName: Searcher.EVENT_STOP,
action() {
self._showAdapter();
self._setStartValue("");
self.adapter.setValue(self.storeValue);
// 需要刷新回到初始界面,否则搜索的结果不能放在最前面
self.adapter.populate();
},
},
{
eventName: Searcher.EVENT_PAUSE,
action() {
let keywords = self._getKeywords();
if (
keywords[keywords.length - 1] === BI.BlankSplitChar
) {
keywords = keywords.slice(0, keywords.length - 1);
}
const keyword = isEmptyArray(keywords)
? ""
: keywords[keywords.length - 1];
self._join(
{
type: Selection.Multi,
value: [keyword],
},
() => {
if (self.storeValue.type === Selection.Multi) {
pushDistinct(
self.storeValue.value,
keyword
);
}
self._showAdapter();
self.adapter.setValue(self.storeValue);
self._setStartValue(keyword);
assertShowValue();
self.adapter.populate();
self._setStartValue("");
self.fireEvent(
MultiSelectInsertList.EVENT_CHANGE
);
}
);
self._showAdapter();
},
},
{
eventName: Searcher.EVENT_SEARCHING,
action() {
let keywords = self._getKeywords();
const lastKeyword = last(keywords);
keywords = initial(keywords || []);
if (keywords.length > 0) {
self._joinKeywords(keywords, () => {
if (endWith(lastKeyword, BI.BlankSplitChar)) {
self.adapter.setValue(self.storeValue);
assertShowValue();
self.adapter.populate();
self._setStartValue("");
} else {
self.adapter.setValue(self.storeValue);
assertShowValue();
}
self.fireEvent(
MultiSelectInsertList.EVENT_CHANGE
);
});
self._getKeywordsLength() > 2000 &&
BI.Msg.alert(
i18nText("BI-Basic_Prompt"),
i18nText(
"BI-Basic_Too_Much_Value_Get_Two_Thousand"
)
);
}
},
},
{
eventName: Searcher.EVENT_CHANGE,
action(value, obj) {
if (obj instanceof MultiSelectBar) {
self._joinAll(this.getValue(), () => {
assertShowValue();
self.fireEvent(
MultiSelectInsertList.EVENT_CHANGE
);
});
} else {
self._join(this.getValue(), () => {
assertShowValue();
self.fireEvent(
MultiSelectInsertList.EVENT_CHANGE
);
});
}
},
}
],
value: o.value,
});
createWidget({
type: VerticalFillLayout.xtype,
rowSize: ["", "fill"],
element: this,
items: [
{
el: this.trigger,
},
{
el: this.adapter,
}
],
});
createWidget({
type: AbsoluteLayout.xtype,
element: this,
items: [
{
el: this.searcherPane,
top: o.searcherHeight || BI.SIZE_CONSANTS.TRIGGER_HEIGHT,
bottom: 0,
left: 0,
right: 0,
}
],
});
}
_getKeywords() {
const val = this.editor.getValue();
let keywords = val.split(/\u200b\s\u200b/);
if (isEmptyString(keywords[keywords.length - 1])) {
keywords = keywords.slice(0, keywords.length - 1);
}
if (/\u200b\s\u200b$/.test(val)) {
keywords = keywords.concat([BI.BlankSplitChar]);
}
return keywords.length > 2000
? keywords.slice(0, 2000).concat([BI.BlankSplitChar])
: keywords.slice(0, 2000);
}
_getKeywordsLength() {
const val = this.editor.getValue();
const keywords = val.split(/\u200b\s\u200b/);
return keywords.length - 1;
}
_showAdapter() {
this.adapter.setVisible(true);
this.searcherPane.setVisible(false);
}
_showSearcherPane() {
this.searcherPane.setVisible(true);
this.adapter.setVisible(false);
}
_defaultState() {
this.trigger.stopEditing();
}
_assertValue(val) {
val || (val = {});
val.type || (val.type = Selection.Multi);
val.value || (val.value = []);
return val;
}
_makeMap(values) {
return makeObject(values || []);
}
_joinKeywords(keywords, callback) {
const self = this;
this._assertValue(this.storeValue);
// 和复选下拉框同步,allData做缓存是会爆炸的
digest();
function digest() {
each(keywords, (i, val) => {
self.storeValue.type === Selection.Multi
? pushDistinct(self.storeValue.value, val)
: remove(self.storeValue.value, val);
});
callback();
}
}
_joinAll(res, callback) {
const self = this,
o = this.options;
this._assertValue(res);
if (this.storeValue.type === res.type) {
const result = Func.getSearchResult(
map(this.storeValue.value, (_i, v) => {
return {
text: o.valueFormatter(v) || v,
value: v,
};
}),
this.trigger.getKeyword()
);
let change = false;
const tempMap = this._makeMap(this.storeValue.value);
each(concat(result.match, result.find), (i, obj) => {
const v = obj.value;
if (isNotNull(tempMap[v])) {
change = true;
delete tempMap[v];
}
});
change && (this.storeValue.value = values(tempMap));
callback();
return;
}
o.itemsCreator(
{
type: MultiSelectInsertList.REQ_GET_ALL_DATA,
keywords: [this.trigger.getKeyword()],
selectedValues: filter(this.storeValue.value, (_i, v) => !contains(res.value, v)),
},
ob => {
const items = map(ob.items, "value");
const selectedMap = self._makeMap(self.storeValue.value);
const notSelectedMap = self._makeMap(res.value);
const newItems = [];
each(items, (i, item) => {
if (isNotNull(selectedMap[items[i]])) {
delete selectedMap[items[i]];
}
if (isNull(notSelectedMap[items[i]])) {
newItems.push(item);
}
});
self.storeValue.value = newItems.concat(values(selectedMap));
callback();
}
);
}
_join(res, callback) {
const self = this;
this._assertValue(res);
this._assertValue(this.storeValue);
if (this.storeValue.type === res.type) {
const map = this._makeMap(this.storeValue.value);
each(res.value, (i, v) => {
if (!map[v]) {
pushDistinct(self.storeValue.value, v);
map[v] = v;
}
});
let change = false;
each(res.assist, (i, v) => {
if (isNotNull(map[v])) {
change = true;
delete map[v];
}
});
change && (this.storeValue.value = values(map));
callback();
return;
}
this._joinAll(res, callback);
}
_setStartValue(value) {
this._startValue = value;
this.adapter.setStartValue(value);
}
isAllSelected() {
return this.adapter.isAllSelected();
}
resize() {
// this.trigger.getCounter().adjustView();
// this.trigger.adjustView();
}
setValue(v) {
this.storeValue = v || {};
this._assertValue(this.storeValue);
this.adapter.setValue(this.storeValue);
this.trigger.setValue(this.storeValue);
}
getValue() {
return deepClone(this.storeValue);
}
populate() {
this.adapter.populate(...arguments);
this.trigger.populate(...arguments);
}
}