@choerodon/master
Version:
A package of Master for Choerodon platform.
370 lines (313 loc) • 15.1 kB
JavaScript
import "choerodon-ui/pro/lib/data-set/style";
import _DataSet from "choerodon-ui/pro/lib/data-set";
import "choerodon-ui/pro/lib/button/style";
import _Button from "choerodon-ui/pro/lib/button";
import "choerodon-ui/pro/lib/tooltip/style";
import _Tooltip from "choerodon-ui/pro/lib/tooltip";
var _excluded = ["value", "text", "maxTagTextLength"];
function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); }
function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }
function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }
function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
function _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e; try { for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
import React, { useState, useMemo, useEffect, useRef, useImperativeHandle, useCallback } from 'react'; // @ts-ignore
import { unstable_batchedUpdates as batchedUpdates } from 'react-dom';
import { omit, debounce } from 'lodash';
import { usePersistFn } from 'ahooks';
import FragmentForSearch from "./FragmentForSearch";
import "./index.less";
function applyMiddleWares(data, middleWares) {
return middleWares.reduce(function (preData, middleWare) {
return middleWare(preData);
}, data);
}
function noop(data) {
return data;
}
/**
* 从对象中获取值,可以传一个key或路径,比如 date.str
* @param object
* @param path
*/
function getValueByPath(object, path) {
var paths = path.split('.');
var result = object;
while (paths.length > 0) {
var key = paths.shift();
if (Object.prototype.hasOwnProperty.call(object, key)) {
// @ts-ignore
result = result[key];
} else {
return undefined;
}
}
return result;
}
export default function useSelect(config, ref) {
var _useState = useState([]),
_useState2 = _slicedToArray(_useState, 2),
data = _useState2[0],
setData = _useState2[1];
var _useState3 = useState(1),
_useState4 = _slicedToArray(_useState3, 2),
currentPage = _useState4[0],
setPage = _useState4[1];
var _useState5 = useState(false),
_useState6 = _slicedToArray(_useState5, 2),
canLoadMore = _useState6[0],
setCanLoadMore = _useState6[1];
var textRef = useRef('');
var dataSetRef = useRef();
var cacheRef = useRef(new Map());
var defaultRender = useCallback(function (item, tooltip) {
var text = (item === null || item === void 0 ? void 0 : item.meaning) || getValueByPath(item, config.textField);
return tooltip ? /*#__PURE__*/React.createElement(_Tooltip, {
title: text,
placement: "bottomLeft"
}, text) : text;
}, [config.textField]);
var firstRef = useRef(true);
var _config$textField = config.textField,
textField = _config$textField === void 0 ? 'meaning' : _config$textField,
_config$valueField = config.valueField,
valueField = _config$valueField === void 0 ? 'value' : _config$valueField,
_config$optionRendere = config.optionRenderer,
optionRenderer = _config$optionRendere === void 0 ? defaultRender : _config$optionRendere,
_onOption = config.onOption,
requestFn = config.request,
_config$middleWare = config.middleWare,
middleWare = _config$middleWare === void 0 ? noop : _config$middleWare,
afterLoadFn = config.afterLoad,
_config$paging = config.paging,
paging = _config$paging === void 0 ? true : _config$paging,
props = config.props,
combo = config.combo;
var request = usePersistFn(requestFn);
var afterLoad = usePersistFn(afterLoadFn || noop);
var renderer = useCallback(function (_ref) {
var _cacheRef$current;
var value = _ref.value,
originText = _ref.text,
maxTagTextLength = _ref.maxTagTextLength,
ote = _objectWithoutProperties(_ref, _excluded);
// 兼容primitiveValue为false
var item = value && typeof value === 'object' ? value : (_cacheRef$current = cacheRef.current) === null || _cacheRef$current === void 0 ? void 0 : _cacheRef$current.get(value);
if (item) {
var result = optionRenderer(item);
var text = maxTagTextLength && typeof result === 'string' && result.length > maxTagTextLength ? "".concat(result.slice(0, maxTagTextLength), "...") : result;
return text;
}
if (combo && !firstRef.current && value === originText) {
return originText;
}
return '';
}, [combo, optionRenderer]); // 不分页时,本地搜索
var localSearch = !paging;
var loadData = useCallback( /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee() {
var _ref3,
_ref3$filter,
filter,
_ref3$page,
page,
res,
_args = arguments;
return regeneratorRuntime.wrap(function _callee$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
_ref3 = _args.length > 0 && _args[0] !== undefined ? _args[0] : {}, _ref3$filter = _ref3.filter, filter = _ref3$filter === void 0 ? textRef.current : _ref3$filter, _ref3$page = _ref3.page, page = _ref3$page === void 0 ? 1 : _ref3$page;
_context.next = 3;
return request({
filter: filter,
page: page
});
case 3:
res = _context.sent;
batchedUpdates(function () {
if (paging) {
var list = res.list,
hasNextPage = res.hasNextPage;
if (afterLoad && firstRef.current) {
afterLoad(list);
firstRef.current = false;
}
setData(function (d) {
return page > 1 ? d.concat(list) : list;
});
setPage(page);
setCanLoadMore(hasNextPage);
} else {
if (afterLoad && firstRef.current) {
afterLoad(res);
firstRef.current = false;
}
setData(res);
}
}); // TODO: 更好的实现
case 5:
case "end":
return _context.stop();
}
}
}, _callee);
})), [afterLoad, paging, request]);
var searchData = useMemo(function () {
return debounce(function (filter) {
loadData({
filter: filter
});
}, 500);
}, [loadData]);
useEffect(function () {
loadData({
filter: ''
});
}, [loadData]);
useImperativeHandle(ref, function () {
return {
refresh: loadData
};
});
var handleLoadMore = useCallback(function () {
loadData({
page: currentPage + 1
});
}, [currentPage, loadData]);
var handleInput = useCallback(function (e) {
var value = e.target.value;
textRef.current = value;
if (!localSearch) {
searchData(value);
}
}, [localSearch, searchData]);
var filterOptions = useCallback(function (_ref4) {
var record = _ref4.record,
text = _ref4.text;
// @ts-ignore
var meaning = optionRenderer === defaultRender ? getValueByPath(record.data, textField) : optionRenderer(record.data);
if (!meaning) {
return true;
}
var name = ''; // 一般情况,option的children是一个字符串
if (typeof meaning === 'string') {
name = meaning;
} else if ( /*#__PURE__*/React.isValidElement(meaning)) {
// 其他情况, children是一个元素,那么约定这个元素上的name属性进行搜索
// @ts-ignore
// eslint-disable-next-line prefer-destructuring
name = meaning.props.name;
} else {
return true;
}
return name.toLowerCase().indexOf(text.toLowerCase()) >= 0;
}, [defaultRender, optionRenderer, textField]);
var optionData = useMemo(function () {
return (applyMiddleWares(data, [middleWare]) || []).map(function (item) {
return _objectSpread(_objectSpread({}, item), {}, {
meaning: item[textField],
value: item[valueField]
});
});
}, [data, middleWare, textField, valueField]);
var finalData = useMemo(function () {
return canLoadMore ? [].concat(_toConsumableArray(optionData), [{
loadMoreButton: true
}]) : optionData;
}, [canLoadMore, optionData]);
var loadMoreButton = useMemo(function () {
return /*#__PURE__*/React.createElement(_Button, {
onClick: function onClick(e) {
e.stopPropagation();
handleLoadMore();
},
style: {
margin: '-4px -12px',
width: 'calc(100% + 24px)'
}
}, "\u52A0\u8F7D\u66F4\u591A");
}, [handleLoadMore]);
var options = useMemo(function () {
if (!dataSetRef.current) {
dataSetRef.current = new _DataSet({
data: finalData,
paging: false
});
} else {
dataSetRef.current.loadData(finalData);
}
optionData.forEach(function (item) {
var _cacheRef$current2;
(_cacheRef$current2 = cacheRef.current) === null || _cacheRef$current2 === void 0 ? void 0 : _cacheRef$current2.set(item[valueField], item);
});
return dataSetRef.current;
}, [finalData, optionData, valueField]);
var renderOption = function renderOption(_ref5) {
var record = _ref5.record;
if (!record) {
return null;
}
if (record.get('loadMoreButton') === true) {
return loadMoreButton;
}
return optionRenderer(record.toData(), config.tooltip);
};
var selectProps = _objectSpread({
searchable: true,
onInput: handleInput,
onClear: function onClear() {
textRef.current = '';
searchData('');
},
// 弹出时自动请求
onPopupHiddenChange: function onPopupHiddenChange(hidden) {
if (hidden === false && textRef.current !== '' && paging) {
textRef.current = '';
searchData('');
}
},
searchMatcher: paging ? function () {
return true;
} : filterOptions,
valueField: valueField,
// 这里不传递textField,因为由useSelect来渲染
textField: textField,
options: options,
// @ts-ignore
optionRenderer: renderOption,
// TODO: 考虑如何获取record,来渲染,例如用户
renderer: renderer,
// renderer: renderer ? ({
// // @ts-ignore
// value, text, name, record, dataSet,
// }) => {
// return (record ? renderer() : null);
// } : undefined,
// @ts-ignore
onOption: function onOption(_ref6) {
var record = _ref6.record;
if (record.get('loadMoreButton') === true) {
return {
className: 'load_more',
disabled: true
};
}
return _onOption ? _onOption({
record: record
}) : {};
}
}, omit(props, 'renderer', 'optionRenderer'));
return selectProps;
}
export { FragmentForSearch };