first commit
This commit is contained in:
424
frontend/node_modules/antd/es/upload/Upload.js
generated
vendored
Normal file
424
frontend/node_modules/antd/es/upload/Upload.js
generated
vendored
Normal file
@@ -0,0 +1,424 @@
|
||||
"use client";
|
||||
|
||||
import _toConsumableArray from "@babel/runtime/helpers/esm/toConsumableArray";
|
||||
var __awaiter = this && this.__awaiter || function (thisArg, _arguments, P, generator) {
|
||||
function adopt(value) {
|
||||
return value instanceof P ? value : new P(function (resolve) {
|
||||
resolve(value);
|
||||
});
|
||||
}
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
function fulfilled(value) {
|
||||
try {
|
||||
step(generator.next(value));
|
||||
} catch (e) {
|
||||
reject(e);
|
||||
}
|
||||
}
|
||||
function rejected(value) {
|
||||
try {
|
||||
step(generator["throw"](value));
|
||||
} catch (e) {
|
||||
reject(e);
|
||||
}
|
||||
}
|
||||
function step(result) {
|
||||
result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected);
|
||||
}
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
};
|
||||
import * as React from 'react';
|
||||
import { flushSync } from 'react-dom';
|
||||
import classNames from 'classnames';
|
||||
import RcUpload from 'rc-upload';
|
||||
import useMergedState from "rc-util/es/hooks/useMergedState";
|
||||
import { devUseWarning } from '../_util/warning';
|
||||
import { ConfigContext } from '../config-provider';
|
||||
import { useComponentConfig } from '../config-provider/context';
|
||||
import DisabledContext from '../config-provider/DisabledContext';
|
||||
import { useLocale } from '../locale';
|
||||
import defaultLocale from '../locale/en_US';
|
||||
import useStyle from './style';
|
||||
import UploadList from './UploadList';
|
||||
import { file2Obj, getFileItem, removeFileItem, updateFileList } from './utils';
|
||||
export const LIST_IGNORE = `__LIST_IGNORE_${Date.now()}__`;
|
||||
const InternalUpload = (props, ref) => {
|
||||
const config = useComponentConfig('upload');
|
||||
const {
|
||||
fileList,
|
||||
defaultFileList,
|
||||
onRemove,
|
||||
showUploadList = true,
|
||||
listType = 'text',
|
||||
onPreview,
|
||||
onDownload,
|
||||
onChange,
|
||||
onDrop,
|
||||
previewFile,
|
||||
disabled: customDisabled,
|
||||
locale: propLocale,
|
||||
iconRender,
|
||||
isImageUrl,
|
||||
progress,
|
||||
prefixCls: customizePrefixCls,
|
||||
className,
|
||||
type = 'select',
|
||||
children,
|
||||
style,
|
||||
itemRender,
|
||||
maxCount,
|
||||
data = {},
|
||||
multiple = false,
|
||||
hasControlInside = true,
|
||||
action = '',
|
||||
accept = '',
|
||||
supportServerRender = true,
|
||||
rootClassName
|
||||
} = props;
|
||||
// ===================== Disabled =====================
|
||||
const disabled = React.useContext(DisabledContext);
|
||||
const mergedDisabled = customDisabled !== null && customDisabled !== void 0 ? customDisabled : disabled;
|
||||
const customRequest = props.customRequest || config.customRequest;
|
||||
const [mergedFileList, setMergedFileList] = useMergedState(defaultFileList || [], {
|
||||
value: fileList,
|
||||
postState: list => list !== null && list !== void 0 ? list : []
|
||||
});
|
||||
const [dragState, setDragState] = React.useState('drop');
|
||||
const upload = React.useRef(null);
|
||||
const wrapRef = React.useRef(null);
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
const warning = devUseWarning('Upload');
|
||||
process.env.NODE_ENV !== "production" ? warning('fileList' in props || !('value' in props), 'usage', '`value` is not a valid prop, do you mean `fileList`?') : void 0;
|
||||
warning.deprecated(!('transformFile' in props), 'transformFile', 'beforeUpload');
|
||||
}
|
||||
// Control mode will auto fill file uid if not provided
|
||||
React.useMemo(() => {
|
||||
// eslint-disable-next-line react-hooks/purity
|
||||
const timestamp = Date.now();
|
||||
(fileList || []).forEach((file, index) => {
|
||||
if (!file.uid && !Object.isFrozen(file)) {
|
||||
file.uid = `__AUTO__${timestamp}_${index}__`;
|
||||
}
|
||||
});
|
||||
}, [fileList]);
|
||||
const onInternalChange = (file, changedFileList, event) => {
|
||||
let cloneList = _toConsumableArray(changedFileList);
|
||||
let exceedMaxCount = false;
|
||||
// Cut to match count
|
||||
if (maxCount === 1) {
|
||||
cloneList = cloneList.slice(-1);
|
||||
} else if (maxCount) {
|
||||
exceedMaxCount = cloneList.length > maxCount;
|
||||
cloneList = cloneList.slice(0, maxCount);
|
||||
}
|
||||
// Prevent React18 auto batch since input[upload] trigger process at same time
|
||||
// which makes fileList closure problem
|
||||
// eslint-disable-next-line react-dom/no-flush-sync
|
||||
flushSync(() => {
|
||||
setMergedFileList(cloneList);
|
||||
});
|
||||
const changeInfo = {
|
||||
file: file,
|
||||
fileList: cloneList
|
||||
};
|
||||
if (event) {
|
||||
changeInfo.event = event;
|
||||
}
|
||||
if (!exceedMaxCount || file.status === 'removed' ||
|
||||
// We should ignore event if current file is exceed `maxCount`
|
||||
cloneList.some(f => f.uid === file.uid)) {
|
||||
// eslint-disable-next-line react-dom/no-flush-sync
|
||||
flushSync(() => {
|
||||
onChange === null || onChange === void 0 ? void 0 : onChange(changeInfo);
|
||||
});
|
||||
}
|
||||
};
|
||||
const mergedBeforeUpload = (file, fileListArgs) => __awaiter(void 0, void 0, void 0, function* () {
|
||||
const {
|
||||
beforeUpload,
|
||||
transformFile
|
||||
} = props;
|
||||
let parsedFile = file;
|
||||
if (beforeUpload) {
|
||||
const result = yield beforeUpload(file, fileListArgs);
|
||||
if (result === false) {
|
||||
return false;
|
||||
}
|
||||
// Hack for LIST_IGNORE, we add additional info to remove from the list
|
||||
delete file[LIST_IGNORE];
|
||||
if (result === LIST_IGNORE) {
|
||||
Object.defineProperty(file, LIST_IGNORE, {
|
||||
value: true,
|
||||
configurable: true
|
||||
});
|
||||
return false;
|
||||
}
|
||||
if (typeof result === 'object' && result) {
|
||||
parsedFile = result;
|
||||
}
|
||||
}
|
||||
if (transformFile) {
|
||||
parsedFile = yield transformFile(parsedFile);
|
||||
}
|
||||
return parsedFile;
|
||||
});
|
||||
const onBatchStart = batchFileInfoList => {
|
||||
// Skip file which marked as `LIST_IGNORE`, these file will not add to file list
|
||||
const filteredFileInfoList = batchFileInfoList.filter(info => !info.file[LIST_IGNORE]);
|
||||
// Nothing to do since no file need upload
|
||||
if (!filteredFileInfoList.length) {
|
||||
return;
|
||||
}
|
||||
const objectFileList = filteredFileInfoList.map(info => file2Obj(info.file));
|
||||
// Concat new files with prev files
|
||||
let newFileList = _toConsumableArray(mergedFileList);
|
||||
objectFileList.forEach(fileObj => {
|
||||
// Replace file if exist
|
||||
newFileList = updateFileList(fileObj, newFileList);
|
||||
});
|
||||
objectFileList.forEach((fileObj, index) => {
|
||||
// Repeat trigger `onChange` event for compatible
|
||||
let triggerFileObj = fileObj;
|
||||
if (!filteredFileInfoList[index].parsedFile) {
|
||||
// `beforeUpload` return false
|
||||
const {
|
||||
originFileObj
|
||||
} = fileObj;
|
||||
let clone;
|
||||
try {
|
||||
clone = new File([originFileObj], originFileObj.name, {
|
||||
type: originFileObj.type
|
||||
});
|
||||
} catch (_a) {
|
||||
clone = new Blob([originFileObj], {
|
||||
type: originFileObj.type
|
||||
});
|
||||
clone.name = originFileObj.name;
|
||||
clone.lastModifiedDate = new Date();
|
||||
clone.lastModified = new Date().getTime();
|
||||
}
|
||||
clone.uid = fileObj.uid;
|
||||
triggerFileObj = clone;
|
||||
} else {
|
||||
// Inject `uploading` status
|
||||
fileObj.status = 'uploading';
|
||||
}
|
||||
onInternalChange(triggerFileObj, newFileList);
|
||||
});
|
||||
};
|
||||
const onSuccess = (response, file, xhr) => {
|
||||
try {
|
||||
if (typeof response === 'string') {
|
||||
response = JSON.parse(response);
|
||||
}
|
||||
} catch (_a) {
|
||||
/* do nothing */
|
||||
}
|
||||
// removed
|
||||
if (!getFileItem(file, mergedFileList)) {
|
||||
return;
|
||||
}
|
||||
const targetItem = file2Obj(file);
|
||||
targetItem.status = 'done';
|
||||
targetItem.percent = 100;
|
||||
targetItem.response = response;
|
||||
targetItem.xhr = xhr;
|
||||
const nextFileList = updateFileList(targetItem, mergedFileList);
|
||||
onInternalChange(targetItem, nextFileList);
|
||||
};
|
||||
const onProgress = (e, file) => {
|
||||
// removed
|
||||
if (!getFileItem(file, mergedFileList)) {
|
||||
return;
|
||||
}
|
||||
const targetItem = file2Obj(file);
|
||||
targetItem.status = 'uploading';
|
||||
targetItem.percent = e.percent;
|
||||
const nextFileList = updateFileList(targetItem, mergedFileList);
|
||||
onInternalChange(targetItem, nextFileList, e);
|
||||
};
|
||||
const onError = (error, response, file) => {
|
||||
// removed
|
||||
if (!getFileItem(file, mergedFileList)) {
|
||||
return;
|
||||
}
|
||||
const targetItem = file2Obj(file);
|
||||
targetItem.error = error;
|
||||
targetItem.response = response;
|
||||
targetItem.status = 'error';
|
||||
const nextFileList = updateFileList(targetItem, mergedFileList);
|
||||
onInternalChange(targetItem, nextFileList);
|
||||
};
|
||||
const handleRemove = file => {
|
||||
let currentFile;
|
||||
Promise.resolve(typeof onRemove === 'function' ? onRemove(file) : onRemove).then(ret => {
|
||||
var _a;
|
||||
// Prevent removing file
|
||||
if (ret === false) {
|
||||
return;
|
||||
}
|
||||
const removedFileList = removeFileItem(file, mergedFileList);
|
||||
if (removedFileList) {
|
||||
currentFile = Object.assign(Object.assign({}, file), {
|
||||
status: 'removed'
|
||||
});
|
||||
mergedFileList === null || mergedFileList === void 0 ? void 0 : mergedFileList.forEach(item => {
|
||||
const matchKey = currentFile.uid !== undefined ? 'uid' : 'name';
|
||||
if (item[matchKey] === currentFile[matchKey] && !Object.isFrozen(item)) {
|
||||
item.status = 'removed';
|
||||
}
|
||||
});
|
||||
(_a = upload.current) === null || _a === void 0 ? void 0 : _a.abort(currentFile);
|
||||
onInternalChange(currentFile, removedFileList);
|
||||
}
|
||||
});
|
||||
};
|
||||
const onFileDrop = e => {
|
||||
setDragState(e.type);
|
||||
if (e.type === 'drop') {
|
||||
onDrop === null || onDrop === void 0 ? void 0 : onDrop(e);
|
||||
}
|
||||
};
|
||||
// Test needs
|
||||
React.useImperativeHandle(ref, () => ({
|
||||
onBatchStart,
|
||||
onSuccess,
|
||||
onProgress,
|
||||
onError,
|
||||
fileList: mergedFileList,
|
||||
upload: upload.current,
|
||||
nativeElement: wrapRef.current
|
||||
}));
|
||||
const {
|
||||
getPrefixCls,
|
||||
direction,
|
||||
upload: ctxUpload
|
||||
} = React.useContext(ConfigContext);
|
||||
const prefixCls = getPrefixCls('upload', customizePrefixCls);
|
||||
const rcUploadProps = Object.assign(Object.assign({
|
||||
onBatchStart,
|
||||
onError,
|
||||
onProgress,
|
||||
onSuccess
|
||||
}, props), {
|
||||
customRequest,
|
||||
data,
|
||||
multiple,
|
||||
action,
|
||||
accept,
|
||||
supportServerRender,
|
||||
prefixCls,
|
||||
disabled: mergedDisabled,
|
||||
beforeUpload: mergedBeforeUpload,
|
||||
onChange: undefined,
|
||||
hasControlInside
|
||||
});
|
||||
delete rcUploadProps.className;
|
||||
delete rcUploadProps.style;
|
||||
// Remove id to avoid open by label when trigger is hidden
|
||||
// !children: https://github.com/ant-design/ant-design/issues/14298
|
||||
// disabled: https://github.com/ant-design/ant-design/issues/16478
|
||||
// https://github.com/ant-design/ant-design/issues/24197
|
||||
if (!children || mergedDisabled) {
|
||||
delete rcUploadProps.id;
|
||||
}
|
||||
const wrapperCls = `${prefixCls}-wrapper`;
|
||||
const [wrapCSSVar, hashId, cssVarCls] = useStyle(prefixCls, wrapperCls);
|
||||
const [contextLocale] = useLocale('Upload', defaultLocale.Upload);
|
||||
const {
|
||||
showRemoveIcon,
|
||||
showPreviewIcon,
|
||||
showDownloadIcon,
|
||||
removeIcon,
|
||||
previewIcon,
|
||||
downloadIcon,
|
||||
extra
|
||||
} = typeof showUploadList === 'boolean' ? {} : showUploadList;
|
||||
// use showRemoveIcon if it is specified explicitly
|
||||
const realShowRemoveIcon = typeof showRemoveIcon === 'undefined' ? !mergedDisabled : showRemoveIcon;
|
||||
const renderUploadList = (button, buttonVisible) => {
|
||||
if (!showUploadList) {
|
||||
return button;
|
||||
}
|
||||
return /*#__PURE__*/React.createElement(UploadList, {
|
||||
prefixCls: prefixCls,
|
||||
listType: listType,
|
||||
items: mergedFileList,
|
||||
previewFile: previewFile,
|
||||
onPreview: onPreview,
|
||||
onDownload: onDownload,
|
||||
onRemove: handleRemove,
|
||||
showRemoveIcon: realShowRemoveIcon,
|
||||
showPreviewIcon: showPreviewIcon,
|
||||
showDownloadIcon: showDownloadIcon,
|
||||
removeIcon: removeIcon,
|
||||
previewIcon: previewIcon,
|
||||
downloadIcon: downloadIcon,
|
||||
iconRender: iconRender,
|
||||
extra: extra,
|
||||
locale: Object.assign(Object.assign({}, contextLocale), propLocale),
|
||||
isImageUrl: isImageUrl,
|
||||
progress: progress,
|
||||
appendAction: button,
|
||||
appendActionVisible: buttonVisible,
|
||||
itemRender: itemRender,
|
||||
disabled: mergedDisabled
|
||||
});
|
||||
};
|
||||
const mergedCls = classNames(wrapperCls, className, rootClassName, hashId, cssVarCls, ctxUpload === null || ctxUpload === void 0 ? void 0 : ctxUpload.className, {
|
||||
[`${prefixCls}-rtl`]: direction === 'rtl',
|
||||
[`${prefixCls}-picture-card-wrapper`]: listType === 'picture-card',
|
||||
[`${prefixCls}-picture-circle-wrapper`]: listType === 'picture-circle'
|
||||
});
|
||||
const mergedStyle = Object.assign(Object.assign({}, ctxUpload === null || ctxUpload === void 0 ? void 0 : ctxUpload.style), style);
|
||||
// ======================== Render ========================
|
||||
if (type === 'drag') {
|
||||
const dragCls = classNames(hashId, prefixCls, `${prefixCls}-drag`, {
|
||||
[`${prefixCls}-drag-uploading`]: mergedFileList.some(file => file.status === 'uploading'),
|
||||
[`${prefixCls}-drag-hover`]: dragState === 'dragover',
|
||||
[`${prefixCls}-disabled`]: mergedDisabled,
|
||||
[`${prefixCls}-rtl`]: direction === 'rtl'
|
||||
});
|
||||
return wrapCSSVar(/*#__PURE__*/React.createElement("span", {
|
||||
className: mergedCls,
|
||||
ref: wrapRef
|
||||
}, /*#__PURE__*/React.createElement("div", {
|
||||
className: dragCls,
|
||||
style: mergedStyle,
|
||||
onDrop: onFileDrop,
|
||||
onDragOver: onFileDrop,
|
||||
onDragLeave: onFileDrop
|
||||
}, /*#__PURE__*/React.createElement(RcUpload, Object.assign({}, rcUploadProps, {
|
||||
ref: upload,
|
||||
className: `${prefixCls}-btn`
|
||||
}), /*#__PURE__*/React.createElement("div", {
|
||||
className: `${prefixCls}-drag-container`
|
||||
}, children))), renderUploadList()));
|
||||
}
|
||||
const uploadBtnCls = classNames(prefixCls, `${prefixCls}-select`, {
|
||||
[`${prefixCls}-disabled`]: mergedDisabled,
|
||||
[`${prefixCls}-hidden`]: !children
|
||||
});
|
||||
const uploadButton = /*#__PURE__*/React.createElement("div", {
|
||||
className: uploadBtnCls,
|
||||
style: mergedStyle
|
||||
}, /*#__PURE__*/React.createElement(RcUpload, Object.assign({}, rcUploadProps, {
|
||||
ref: upload
|
||||
})));
|
||||
if (listType === 'picture-card' || listType === 'picture-circle') {
|
||||
return wrapCSSVar(/*#__PURE__*/React.createElement("span", {
|
||||
className: mergedCls,
|
||||
ref: wrapRef
|
||||
}, renderUploadList(uploadButton, !!children)));
|
||||
}
|
||||
return wrapCSSVar(/*#__PURE__*/React.createElement("span", {
|
||||
className: mergedCls,
|
||||
ref: wrapRef
|
||||
}, uploadButton, renderUploadList()));
|
||||
};
|
||||
const Upload = /*#__PURE__*/React.forwardRef(InternalUpload);
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
Upload.displayName = 'Upload';
|
||||
}
|
||||
export default Upload;
|
||||
Reference in New Issue
Block a user