react-admin-kit
Version:
A react based UI components for admin system
158 lines (152 loc) • 6.26 kB
JavaScript
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = exports.FormUploadType = void 0;
var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
var _objectSpread2 = _interopRequireDefault(require("@babel/runtime/helpers/objectSpread2"));
var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties"));
var _antd = require("antd");
var _react = require("react");
var _reactDom = require("react-dom");
var _context = require("../SettingProvider/context");
var _utils = require("../utils");
var _omit = _interopRequireDefault(require("omit.js"));
var _jsxRuntime = require("react/jsx-runtime");
var _excluded = ["multiple", "children", "onFinish", "errorHandle", "responseToFileList", "nameKey", "urlKey"];
/**
* 给 file 对象赋上默认的 status: done
* initialValues 和 setFieldsValue 两种情况下的 file 对象需要带上 status, 否则表单收集不到.
* beforeUpload 为 false 的 file 对象也会进到 fileList, 它的 status 为空, 所以表单不收集
* @param files
*/
function withDefaultStatus() {
var files = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
var $files = files || [];
return $files.map(function (file) {
if (!file.status) {
file.status = 'done';
}
return file;
});
}
function FormUpload(props) {
// 全局默认设置
var setting = (0, _react.useContext)(_context.FormUploadContext) || {};
var safeProps = (0, _omit.default)(props, ['value', 'onChange']);
var mergedProps = (0, _utils.myMergeOptions)(setting, safeProps || {},
// 默认值放在这里,能合并对象类属性
{});
var _mergedProps$multiple = mergedProps.multiple,
multiple = _mergedProps$multiple === void 0 ? true : _mergedProps$multiple,
children = mergedProps.children,
onFinish = mergedProps.onFinish,
errorHandle = mergedProps.errorHandle,
responseToFileList = mergedProps.responseToFileList,
_mergedProps$nameKey = mergedProps.nameKey,
nameKey = _mergedProps$nameKey === void 0 ? 'name' : _mergedProps$nameKey,
_mergedProps$urlKey = mergedProps.urlKey,
urlKey = _mergedProps$urlKey === void 0 ? 'url' : _mergedProps$urlKey,
rest = (0, _objectWithoutProperties2.default)(mergedProps, _excluded);
var value = props.value,
onChange = props.onChange;
/**
* 如果先前的 value 有值 [{name: '', url: ''}], 通过 setFieldsValue 设成空数组[]后, value 会变成 [undefined]
*/
var $value = value ? value.filter(Boolean).map(function (val) {
return (0, _objectSpread2.default)((0, _objectSpread2.default)({}, val), {}, {
name: val[nameKey],
url: val[urlKey]
});
}) : value;
// 是否有调用父组件的 onChange 函数
var emitChangeRef = (0, _react.useRef)(null);
var firstTimeRef = (0, _react.useRef)(true);
var _useState = (0, _react.useState)(withDefaultStatus($value)),
_useState2 = (0, _slicedToArray2.default)(_useState, 2),
innerFileList = _useState2[0],
setInnerFileList = _useState2[1];
var _useState3 = (0, _react.useState)(false),
_useState4 = (0, _slicedToArray2.default)(_useState3, 2),
uploading = _useState4[0],
setUploading = _useState4[1];
/**
* FormUpload 组件的设计是内部维护自己的文件列表, 然后监听外部 value 属性的变化, 来达到近似受控组件的效果.
* 为什么说近似, 是因为有一个例外, 当上传的文件列表中有上传错误的文件时, 通过 props.onChnage 传给外面的文件与内部的文件不一致.
* 传给外面的文件都是上传成功的, 而内部上包含错误文件的.
* 就是这个例外需要两边不同步, 通过一个 emitChangeRef 来标记并阻止他们同步.
*/
(0, _react.useEffect)(function () {
// 忽略第一次
if (firstTimeRef.current) {
firstTimeRef.current = false;
return;
}
/**
* 监听 value, 外部和内部同步. (emitChange 阻止的除外)
*/
if (!emitChangeRef.current) {
setInnerFileList(withDefaultStatus($value));
}
emitChangeRef.current = false;
}, [value]);
var handleOnChange = function handleOnChange(info) {
setUploading(true);
var fileList = (0, _toConsumableArray2.default)(info.fileList);
var $fileList = fileList.map(function (file) {
/**
* 将后端的返回合并进file对象
*/
if (file.response) {
var res = file.response;
var resObj = responseToFileList ? responseToFileList(res) : {};
return (0, _objectSpread2.default)((0, _objectSpread2.default)({}, file), resObj);
}
return file;
});
if (info.file.status === 'error') {
if (errorHandle) {
errorHandle(info.file.response || {});
}
}
(0, _reactDom.flushSync)(function () {
return setInnerFileList($fileList);
});
// beforeUpload为false的文件也会进到onChange里
if ($fileList.every(function (file) {
return file.status !== 'uploading';
})) {
setUploading(false);
emitChangeRef.current = true;
var successFiles = $fileList.filter(function (file) {
return ['done', 'success'].includes(file.status);
});
if (onChange) {
onChange(successFiles);
}
if (onFinish) onFinish(successFiles);
}
};
var renderChildren = function renderChildren() {
if (children && typeof children === 'function') {
return children({
loading: uploading
});
}
return children;
};
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_antd.Upload, (0, _objectSpread2.default)((0, _objectSpread2.default)({
multiple: multiple,
fileList: innerFileList,
onChange: handleOnChange
}, rest), {}, {
children: renderChildren()
}));
}
var _default = exports.default = FormUpload; // 用于生成api文档
/* istanbul ignore next */
var FormUploadType = exports.FormUploadType = function FormUploadType() {
return null;
};