antd#Upload TypeScript Examples
The following examples show how to use
antd#Upload.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: DataImporter.tsx From condo with MIT License | 6 votes |
DataImporter: React.FC<IDataImporterProps> = (props) => {
const uploadConfig = useUploadConfig(props.onUpload)
return (
<Upload
{ ...uploadConfig }
accept={FILE_EXTENSIONS}
>
{props.children}
</Upload>
)
}
Example #2
Source File: InputWithUpload.tsx From jitsu with MIT License | 6 votes |
InputWithUpload: React.FC<InputWithUploadProps> = ({ value, onChange }) => {
const triggerChange = e => {
onChange?.(e.target.value)
}
const beforeUpload = file => {
const reader = new FileReader()
reader.onload = e => {
const content: string = e.target.result as string
onChange?.(content)
}
reader.readAsText(file)
// Prevent upload
return false
}
return value === "" ? (
<Upload showUploadList={true} beforeUpload={beforeUpload}>
<Button icon={<UploadOutlined />}>Click to Upload</Button>
</Upload>
) : (
<Input.TextArea autoSize={{ minRows: 1, maxRows: 5 }} value={value} autoComplete="off" onChange={triggerChange} />
)
}
Example #3
Source File: index.tsx From imove with MIT License | 6 votes |
ImportDSL: React.FC<IProps> = (props) => {
const { flowChart } = props;
const [disabled, setDisabled] = useState(false);
const beforeUpload = (file: any) => {
setDisabled(true);
const reader = new FileReader();
reader.onload = (evt) => {
setDisabled(false);
if (!evt.target) {
message.error('加载文件失败!');
} else {
const dsl = evt.target.result as string;
try {
flowChart.fromJSON(JSON.parse(dsl));
} catch (err) {
message.error('DSL解析失败!');
}
}
};
reader.readAsText(file);
return false;
};
return (
<Upload
className={styles.container}
accept={'.json'}
disabled={disabled}
showUploadList={false}
beforeUpload={beforeUpload}
>
<Button type={'primary'} size={'small'}>
导入DSL
</Button>
</Upload>
);
}
Example #4
Source File: index.tsx From scorpio-h5-design with MIT License | 6 votes |
export default function() {
useEffect(()=>{
//
}, []);
const props = {
name: 'file',
async onChange(info: any) {
if (info.file.status === 'done') {
message.success(`${info.file.name} file uploaded successfully`);
const uploadResult = await ossClient.put(`design/${info.file.name}`, info.file.originFileObj);
} else if (info.file.status === 'error') {
message.error(`${info.file.name} file upload failed.`);
}
},
};
return (
<Upload {...props} className="aliyun-upload">
<Button icon={<UploadOutlined />}>上传</Button>
</Upload>
);
}
Example #5
Source File: index.tsx From whiteboard-demo with MIT License | 6 votes |
private renderUploadImage(): React.ReactNode {
return (
<Upload
key="upload-image"
accept={"image/*"}
showUploadList={false}
customRequest={this.uploadImage}>
<div className="oss-upload-section">
<div className="oss-upload-section-inner">
<div className="oss-upload-title-section">
<div className="oss-upload-title">{this.translate(this.props.i18nLanguage, 'uploadImage')}</div>
<div className="oss-upload-icon">
<img src={image} alt={"image"} />
</div>
</div>
<div className="oss-upload-section-script">
<div className="oss-upload-section-text">
{this.translate(this.props.i18nLanguage, 'uploadImageInner')}
</div>
</div>
</div>
</div>
</Upload>
)
}
Example #6
Source File: index.tsx From erda-ui with GNU Affero General Public License v3.0 | 6 votes |
UploadComp = ({ form, onChangeFile, fileNameKey, fileAccept }: IUploadProps) => {
const acceptProp = { accept: fileAccept };
const uploadProps = getUploadProps({
...acceptProp,
data: {
fileFrom: 'certificate manager',
},
onChange: ({ file }: any) => {
if (file.response) {
const { success, err, data } = file.response;
if (!success) {
message.error(err.msg);
} else {
onChangeFile({ uuid: data.uuid, fileName: data.name });
}
}
return file;
},
});
const deleteFile = () => {
onChangeFile({ uuid: undefined, fileName: undefined });
};
const fileName = form.getFieldValue(fileNameKey);
return (
<div className="upload-container">
<Upload {...uploadProps}>
<Button className="flex items-center">
<ErdaIcon type="upload" size="16" className="mr-1" /> {i18n.t('Upload')}
</Button>
</Upload>
{fileName && (
<div className="flex justify-between items-center upload-file-item nowrap">
<span>{fileName}</span>
<CustomIcon type="thin-del" className="hover-active" onClick={deleteFile} />
</div>
)}
</div>
);
}
Example #7
Source File: index.tsx From whiteboard-demo with MIT License | 6 votes |
private renderUploadAudio(): React.ReactNode {
return (
<Upload
key="upload-audio"
accept={".mp3,audio/mp3"}
showUploadList={false}
customRequest={this.uploadAudio}>
<div className="oss-upload-section">
<div className="oss-upload-section-inner">
<div className="oss-upload-title-section">
<div className="oss-upload-title">{this.translate(this.props.i18nLanguage, 'uploadAudio')}</div>
<div className="oss-upload-icon">
<img src={Audio} alt={"Audio"} />
</div>
</div>
<div className="oss-upload-section-script">
<div className="oss-upload-section-text">{this.translate(this.props.i18nLanguage, 'uploadAudioInner')}</div>
</div>
</div>
</div>
</Upload>
);
}
Example #8
Source File: index.tsx From erda-ui with GNU Affero General Public License v3.0 | 6 votes |
renderPureUploadItem(uploadText: string, queryData: any) {
return (
<div className="image-upload mr-2 mb-2" key="upload">
<Input type="hidden" />
<Upload className="pure-upload" accept=".jpg, .jpeg, .png, .gif" {...this.getUploadProps(queryData)}>
<div className="mt-5">
<ErdaIcon fill="black-8" size="30" key="icon" type="cir-add" />
<div key="text">{uploadText}</div>
</div>
</Upload>
</div>
);
}
Example #9
Source File: AvatarUpload.spec.tsx From next-basics with GNU General Public License v3.0 | 6 votes |
describe("AvatarUpload", () => {
it("should work", () => {
const wrapper = mount(<AvatarUpload {...props} />);
// wrapper.find("Button").simulate("click")
wrapper.find(Upload).invoke("beforeUpload")(
{
uid: "123",
size: 1024 * 1024 * 1024,
} as any,
[]
);
});
it("should work", async () => {
// mockCanvas(global)
const wrapper = mount(<AvatarUpload {...props} imgSrc="mock" />);
// wrapper.find("Button").simulate("click")
const file = new File(["(⌐□_□)"], "chucknorris.png", { type: "image/png" });
wrapper.find(Upload).invoke("beforeUpload")(file as any, []);
await (global as any).flushPromises();
expect(wrapper.find(Modal).prop("visible")).toBe(true);
wrapper.find(Modal).invoke("onOk")({} as any);
// Todo(momo): make assertions.
// expect(mockHttp).toHaveBeenCalled();
});
});
Example #10
Source File: UploadField.tsx From posthog-foss with MIT License | 6 votes |
export function UploadField({
value,
onChange,
}: {
value?: UploadFile | null
onChange?: (file?: UploadFile | null) => void
}): JSX.Element {
return (
<Upload
multiple={false}
fileList={value?.size ? [value] : []}
beforeUpload={(file) => {
onChange?.(file)
return false
}}
onRemove={() => {
onChange?.(null)
return false
}}
className="ph-ignore-input"
>
<Button icon={<UploadOutlined />}>Click to upload</Button>
</Upload>
)
}
Example #11
Source File: ImageUpload.tsx From datart with Apache License 2.0 | 6 votes |
StyleUpload = styled(Upload.Dragger)`
.image-box {
position: relative;
padding: 0 ${SPACE_MD};
margin: auto;
overflow: hidden;
}
.del-button {
position: absolute;
top: 50%;
left: 50%;
display: none;
font-size: 1.5rem;
color: ${p => p.theme.textColorDisabled};
transform: translate(-50%, -50%);
}
.image-box:hover .del-button {
display: block;
}
.image {
width: 100%;
height: auto;
}
`
Example #12
Source File: utils.tsx From antdp with MIT License | 6 votes |
getItem = ({ attr, type, inputNode }: {
attr?: Partial<ItemChildAttr<any, any>>;
type?: ItemChildType;
inputNode?: ((...arg: any[]) => React.ReactNode) | React.ReactNode;
}) => {
let renderItem = undefined;
if (type === 'Input') {
const inputAttr = attr as InputProps;
renderItem = <Input {...inputAttr} />;
} else if (type === 'TextArea') {
const inputAttr = attr as TextAreaProps;
renderItem = <Input.TextArea {...inputAttr} />;
} else if (type === 'InputNumber') {
const inputAttr = attr as InputNumberProps;
renderItem = <InputNumber {...inputAttr} />;
} else if (type === 'AutoComplete') {
const inputAttr = attr as AutoCompleteProps;
renderItem = <AutoComplete {...inputAttr} />;
} else if (type === 'Cascader') {
const inputAttr = attr as CascaderProps;
renderItem = <Cascader {...inputAttr} />;
} else if (type === 'DatePicker') {
const inputAttr = attr as DatePickerProps;
renderItem = <DatePicker {...inputAttr} />;
} else if (type === 'Rate') {
const inputAttr = attr as RateProps;
renderItem = <Rate {...inputAttr} />;
} else if (type === 'Slider') {
const inputAttr = attr as SliderSingleProps;
renderItem = <Slider {...inputAttr} />;
} else if (type === 'TreeSelect') {
const inputAttr = attr as TreeSelectProps<any>;
renderItem = <TreeSelect {...inputAttr} />;
} else if (type === 'Select') {
const inputAttr = attr as SelectProps<any>;
renderItem = <Select {...inputAttr} />;
} else if (type === 'Checkbox') {
const inputAttr = attr as CheckboxGroupProps;
renderItem = <Checkbox.Group {...inputAttr} />;
} else if (type === 'Mentions') {
const inputAttr = attr as MentionProps;
renderItem = <Mentions {...inputAttr} />;
} else if (type === 'Radio') {
const inputAttr = attr as RadioProps;
renderItem = <Radio.Group {...inputAttr} />;
} else if (type === 'Switch') {
const inputAttr = attr as SwitchProps;
renderItem = <Switch {...inputAttr} />;
} else if (type === 'TimePicker') {
const inputAttr = attr as TimePickerProps;
renderItem = <TimePicker {...inputAttr} />;
} else if (type === 'Upload') {
const inputAttr = attr as UploadProps;
renderItem = <Upload {...inputAttr} />;
} else if (type === 'RangePicker') {
const inputAttr = attr as RangePickerProps;
renderItem = <RangePicker {...inputAttr} />;
} else if (type === 'Custom') {
renderItem = inputNode;
}
return renderItem;
}
Example #13
Source File: MultipleFilesForm.tsx From next-basics with GNU General Public License v3.0 | 6 votes |
export function LegacyMultipleFilesForm(
{ fieldList, onFinish, onFinishFailed }: MultipleFilesFormProps,
ref: React.Ref<FormInstance>
): React.ReactElement {
const [form] = Form.useForm();
useImperativeHandle(ref, () => form);
const handleFinish = (data: UploadFormData): void => {
const formData = processFileData(data);
onFinish?.(formData);
};
return (
<Form
form={form}
name="filesForm"
data-testid="files-form"
onFinish={handleFinish}
onFinishFailed={onFinishFailed}
>
{fieldList?.map((item) => (
<Form.Item key={item.name} name={item.name} label={item.name}>
<Upload
maxCount={isMultipleFiles(item.type) ? null : 1}
beforeUpload={() => false}
>
<Button icon={<UploadOutlined />}>upload</Button>
</Upload>
</Form.Item>
))}
</Form>
);
}
Example #14
Source File: inputUtil.tsx From yakit with GNU Affero General Public License v3.0 | 5 votes |
InputFileNameItem: React.FC<InputFileNameItem> = p => {
const [uploadLoading, setUploadLoading] = useState(false);
return <Item>
<Upload.Dragger
className='targets-upload-dragger'
accept={(p.accept || [])?.join(",")}
multiple={false}
maxCount={1}
showUploadList={false}
beforeUpload={(f: any) => {
// 设置名字
p.setFileName && p.setFileName(f?.path)
if (!p.loadContent) {
return false
}
setUploadLoading(true)
ipcRenderer.invoke("fetch-file-content", (f as any).path).then((res) => {
p.setContent && p.setContent(res)
setTimeout(() => {
setUploadLoading(false)
}, 100);
})
return false
}}>
<Spin spinning={uploadLoading}>
{p.loadContent ? <InputItem
label={p.label} setValue={Targets => p.setContent && p.setContent(Targets)}
value={p.content} textarea={true} textareaRow={6}
placeholder="请输入绝对路径"
isBubbing={true}
help={p.hint ? p.hint : (<div>
可将文件拖入框内或<span style={{color: 'rgb(25,143,255)'}}>点击此处</span>上传
</div>)}
/> : <InputItem
label={p.label} value={p.filename} setValue={f => p.setFileName && p.setFileName(f)}
placeholder="请输入绝对路径"
isBubbing={true} allowClear={false} help={p.hint ? p.hint : (<div>
可将文件拖入框内或<span style={{color: 'rgb(25,143,255)'}}>点击此处</span>上传
</div>)}
/>
}
</Spin>
</Upload.Dragger>
</Item>
}
Example #15
Source File: index.tsx From scorpio-h5-design with MIT License | 5 votes |
export default function ImageUpload(props: IProps) {
const { value, onChange } = props;
const handleDelete = function(){
onChange('');
};
const uploadButton = (
<div>
<PlusOutlined />
<div style={{ marginTop: 8 }}>Upload</div>
</div>
);
const customRequest = async function(options:any){
const fileName = `${uuidv4()}.png`;
await ossClient.put(`design/${fileName}`, options.file);
onChange(`https://scorpio-design.lxzyl.cn/design/${fileName}`);
options.onSuccess(null, options.file);
};
return (
<div className="picture-uploader">
<Upload
listType="picture-card"
showUploadList={false}
// onChange={handleChange}
customRequest={customRequest}
>
{value ? (
<div className="picture-uploader-img-container">
<img src={value} alt="avatar" style={{ width: '100%' }} />
</div>
) : uploadButton}
</Upload>
{
value && <div className="delete-img" onClick={handleDelete}><CloseOutlined /></div>
}
</div>
);
}
Example #16
Source File: index.tsx From metaplex with Apache License 2.0 | 5 votes |
{ Dragger } = Upload
Example #17
Source File: FormItemUtil.tsx From yakit with GNU Affero General Public License v3.0 | 5 votes |
{Dragger} = Upload
Example #18
Source File: index.tsx From nebula-studio with Apache License 2.0 | 5 votes |
{ Dragger } = Upload
Example #19
Source File: FileUpload.tsx From datart with Apache License 2.0 | 5 votes |
export function FileUpload({
form,
sourceId,
loading,
onTest,
}: FileUploadProps) {
const [uploadFileLoading, setUploadFileLoading] = useState(false);
const t = useI18NPrefix('source');
const normFile = useCallback(e => {
if (Array.isArray(e)) {
return e;
}
return e && e.fileList;
}, []);
const uploadChange = useCallback(
async ({ file }) => {
if (file.status === 'done') {
const format = file.name
.substr(file.name.lastIndexOf('.') + 1)
.toUpperCase();
const response = file.response as APIResponse<string>;
if (response.success) {
form &&
form.setFieldsValue({ config: { path: response.data, format } });
onTest && onTest();
}
setUploadFileLoading(false);
} else {
setUploadFileLoading(true);
}
},
[form, onTest],
);
return (
<>
<Form.Item
label={t('form.file')}
valuePropName="fileList"
getValueFromEvent={normFile}
>
<Upload
accept=".xlsx,.xls,.csv"
method="post"
action={`${BASE_API_URL}/files/datasource/?sourceId=${sourceId}`}
headers={{ authorization: getToken()! }}
showUploadList={false}
onChange={uploadChange}
>
<Button
icon={<UploadOutlined />}
loading={uploadFileLoading || loading}
>
{t('form.selectFile')}
</Button>
</Upload>
</Form.Item>
<Form.Item
name={['config', 'path']}
css={`
display: none;
`}
>
<Input />
</Form.Item>
<Form.Item
name={['config', 'format']}
css={`
display: none;
`}
>
<Input />
</Form.Item>
</>
);
}
Example #20
Source File: index.tsx From dashboard with Apache License 2.0 | 5 votes |
Uploader: React.FC<ImageUploaderProps> = (props) => {
const {value, onChange, fileType, ...rest} = props;
const [loading, setLoading] = useState<boolean>(false);
return <>
<Upload
{...rest}
key={props.currentKey}
accept={fileMap[fileType].accept}
name='avatar'
listType='picture-card'
className={fileType === 'formImage' ? styles.formImageUploader : styles.uploader}
showUploadList={false}
beforeUpload={(file) => {
if (!fileMap[fileType].contentType.includes(file.type)) {
message.error(`只能上传${fileMap[fileType].accept}格式`);
return false;
}
if (file.size / 1024 / 1024 > fileMap[fileType].limitSize) {
message.error(`图片最大${fileMap[fileType].limitSize}M`);
return false;
}
if(fileType==='PDF'){
// @ts-ignore
const temp = [...props?.fileInfoAry]
temp.push({fileName:file.name,fileSize:file.size,key:props.currentKey})
props?.setFileInfoAry?.(temp || [])
}
return true;
}}
onChange={(info) => {
if (info.file.status === 'uploading') {
setLoading(true);
return;
}
if (info.file.status === 'done') {
setLoading(false);
}
}}
{...(_.omit(props, ['value']))}
>
<div>
{value && (
<Badge
count={
<CloseCircleFilled
onClick={(e) => {
e.preventDefault();
e.stopPropagation();
if (onChange) {
onChange('');
}
setLoading(false);
if(fileType==='PDF'){
// @ts-ignore
const temp = [...props?.fileInfoAry]
for (let i = 0; i < temp.length; i += 1) {
if (temp[i].key === props.currentKey) {
temp.splice(i, 1)
}
}
props?.setFileInfoAry?.(temp || [])
}
}}
style={{color: 'rgb(199,199,199)'}}
/>
}
>
{fileMap[fileType].existValueRender(value, props?.fileInfoAry?.find((item: any) => item.key === props.currentKey) || props.initialFileInfo, fileType)}
</Badge>
)}
{
!value && fileMap[fileType].noValueRender(loading, fileType)
}
</div>
</Upload>
</>;
}
Example #21
Source File: index.tsx From ii-admin-base with MIT License | 5 votes |
export default function IUpload(props: IUpload) {
const {
multiple = true,
iconFontSize = 28,
iconFontStyle,
describe,
extra,
icon,
uploadType = 'dragger',
children,
...restProps
} = props;
if (!restProps.beforeUpload) {
restProps.beforeUpload = beforeUpload;
}
if (uploadType === 'dragger') {
return (
<Dragger multiple={multiple} {...restProps}>
{children}
<p className="myupload-iconpart">
{!icon && (
<UploadOutlined
style={{
fontSize: `${iconFontSize}px`,
color: '#3079FF',
...iconFontStyle,
}}
/>
)}
{icon}
</p>
<p className="myupload-describe">
{describe instanceof Array
? describe.map((item, index: number) => (
<div key={`index${index}`}>{item}</div>
))
: describe}
</p>
<p className="myupload-extra">
{extra instanceof Array
? extra.map((item, index: number) => (
<div key={`index${index}`}>{item}</div>
))
: extra}
</p>
</Dragger>
);
}
return (
<Upload multiple={multiple} {...restProps}>
{children}
</Upload>
);
}
Example #22
Source File: index.tsx From dashboard with Apache License 2.0 | 5 votes |
ImageUploader: React.FC<ImageUploaderProps> = (props) => {
const {value, onChange} = props;
const [loading, setLoading] = useState<boolean>(false);
return (
<Upload
accept={'.jpg,.png,.jpeg'}
name='avatar'
listType='picture-card'
className={styles.imageUploader}
showUploadList={false}
beforeUpload={(file) => {
if (!['image/jpeg', 'image/png', 'image/jpg'].includes(file.type)) {
message.error('只能上传jpg和png格式');
return false;
}
if (file.size / 1024 / 1024 > 20) {
message.error('图片最大20M');
return false;
}
return true;
}}
onChange={(info) => {
if (info.file.status === 'uploading') {
setLoading(true);
return;
}
if (info.file.status === 'done') {
setLoading(false);
}
}}
{...(_.omit(props, ['value']))}
>
<div>
{value && (
<Badge
count={
<CloseCircleFilled
onClick={(e) => {
e.preventDefault();
e.stopPropagation();
if (onChange) {
onChange('');
}
setLoading(false);
}}
style={{color: 'rgb(199,199,199)'}}
/>
}
>
<Image
preview={false}
className={styles.image}
src={value}
fallback={defaultImage}
/>
</Badge>
)}
{!value && (
<div className={styles.button}>
{loading ? <LoadingOutlined/> : <PlusCircleFilled/>}
<div className={styles.text}>上传图片</div>
</div>
)}
</div>
</Upload>
);
}
Example #23
Source File: upload.tsx From erda-ui with GNU Affero General Public License v3.0 | 5 votes |
FormUpload = ({
fixOut = noop,
fixIn = noop,
extensionFix,
requiredCheck,
trigger = 'onChange',
}: any = {}) =>
React.memo(({ fieldConfig, form }: any = {}) => {
const {
key,
handleBeforeUpload,
value,
label,
visible,
valid = [],
disabled,
required,
registerRequiredCheck = noop,
componentProps,
wrapperProps,
labelTip,
fixIn: itemFixIn,
fixOut: itemFixOut,
requiredCheck: _requiredCheck,
} = fieldConfig || {};
const curFixIn = itemFixIn || fixIn;
const curFixOut = itemFixOut || fixOut;
const [loading, setLoading] = React.useState(false);
const [imageUrl, setImageUrl] = React.useState('');
React.useEffect(() => {
setImageUrl(value);
}, [value]);
registerRequiredCheck(_requiredCheck || requiredCheck);
const { uploadText, sizeLimit, supportFormat = [] } = componentProps || {};
const _placeholder = uploadText || '上传图片';
const accept = supportFormat.map((x) => `.${x}`).join(',');
const uploadButton = (
<div className="form-item-upload-button">
<CustomIcon type="cir-add" className="text-xl" />
<div>{_placeholder}</div>
</div>
);
function handleChange(info: any) {
if (info.file.status === 'done') {
const { response } = info.file;
if (!response) {
return;
}
// FIXME: 为什么要将 http(s) 去掉?
const url = (get(response, 'data.url') || '').replace(/^http(s)?:/g, '');
setImageUrl(url);
form.setFieldValue(key, curFixOut(url));
componentProps?.onChange?.(url);
}
}
return (
<FormItem
colon
label={getLabel(label, labelTip)}
className={visible ? '' : 'hidden'}
validateStatus={valid[0]}
help={valid[1]}
required={required}
{...wrapperProps}
>
<Upload listType="picture" accept={accept} onChange={handleChange} {...getUploadProps({}, sizeLimit)}>
{imageUrl ? <img src={imageUrl} alt="avatar" className="form-item-upload-img" /> : uploadButton}
<div className="form-item-upload-tip">
支持格式: {supportFormat?.join(' / ')},不超过 {sizeLimit} M
</div>
</Upload>
</FormItem>
);
})
Example #24
Source File: index.tsx From ii-admin-base with MIT License | 5 votes |
{ Dragger } = Upload
Example #25
Source File: upload-plugin.tsx From erda-ui with GNU Affero General Public License v3.0 | 5 votes |
UploadPlugin = (props: any) => {
let hideLoading: any;
const getUploadProps = (isImage?: boolean) => ({
action: '/api/files',
showUploadList: false,
headers: {
'OPENAPI-CSRF-TOKEN': getCookies('OPENAPI-CSRF-TOKEN'),
org: getOrgFromPath(),
},
beforeUpload: (file: any) => {
const UPLOAD_SIZE_LIMIT = 20; // M
const isLtSize = file.size / 1024 / 1024 < UPLOAD_SIZE_LIMIT;
if (!isLtSize) {
message.warning(i18n.t('common:the uploaded file must not exceed {size}M', { size: UPLOAD_SIZE_LIMIT }));
}
return isLtSize;
},
onChange: ({ file }: any) => {
const { status, response } = file;
if (status === 'uploading' && !hideLoading) {
hideLoading = message.loading(`${i18n.t('uploading')}...`, 0);
}
if (!response) {
return;
}
hideLoading && hideLoading();
hideLoading = undefined;
const { success, err, data } = response;
if (!success) {
message.error(err.msg);
} else {
const { name, size, url } = data;
props.editor.insertText(`\n${isImage ? '!' : ''}[${name}(${size})](${url})\n`);
}
},
});
return (
<Popover
key="yf"
title={i18n.t('common:Add Attachment')}
content={
<div className="upload-plugin-menu">
<Upload accept=".jpg, .jpeg, .png, .gif" {...getUploadProps(true)}>
<div className="upload-item hover-active-bg">{i18n.t('common:Upload Image')}</div>
</Upload>
<Upload {...getUploadProps()}>
<div className="upload-item hover-active-bg">{i18n.t('common:Upload File')}</div>
</Upload>
</div>
}
>
<span className="button button-type-annex" title="annex">
<CustomIcon type="fujian" style={{ lineHeight: 'unset', marginRight: 0 }} />
</span>
</Popover>
);
}
Example #26
Source File: UploadFilesV2.spec.tsx From next-basics with GNU General Public License v3.0 | 4 votes |
describe("UploadFilesV2", () => {
it("should work", async () => {
const onChange = jest.fn();
const wrapper = mount(
<UploadFilesV2 url={url} value={fileList} onChange={onChange} />
);
await Promise.resolve();
expect(wrapper.find(".ant-upload-list-item").length).toBe(1);
wrapper.find(Upload).invoke("onChange")({
file: {
uid: "123",
size: 1234,
type: "image/png",
name: "image.png",
status: "done",
response: {
data: {
objectName: "image.png",
},
},
},
fileList: [...fileList],
});
expect(wrapper.find(".ant-upload-list-item").length).toBe(1);
wrapper.find(Upload).invoke("onChange")({
file: {
uid: "123",
size: 1234,
type: "image/png",
name: "image.png",
status: "removed",
response: {
data: {
objectName: "image.png",
},
},
},
fileList: [],
});
await jest.runAllTimers();
wrapper.update();
expect(wrapper.find(".ant-upload-list-item").length).toBe(0);
wrapper.find(Upload).invoke("onChange")({
file: {
uid: "-img1",
size: 1024,
type: "image/png",
name: "image.png",
status: "uploading",
response: {
data: {
objectName: "image.png",
},
},
},
fileList: [
...fileList,
{
uid: "-img1",
size: 1024,
type: "image/png",
name: "image.png",
status: "uploading",
response: {
data: {
objectName: "image.png",
},
},
},
],
});
expect(wrapper.find(Upload).prop("disabled")).toBe(true);
expect(wrapper.find("Button").text()).toBe("Upload");
expect(wrapper.find("GeneralIcon").at(0).prop("icon")).toEqual({
lib: "antd",
icon: "upload",
theme: "outlined",
});
wrapper.setProps({
uploadButtonProps: {
buttonName: "Upload Now",
buttonIcon: {
lib: "antd",
icon: "cloud-upload",
theme: "outlined",
},
buttonType: "link",
},
});
wrapper.update();
expect(wrapper.find("Button").text()).toBe("Upload Now");
expect(wrapper.find("Button").prop("type")).toBe("link");
expect(wrapper.find("GeneralIcon").at(0).prop("icon")).toEqual({
lib: "antd",
icon: "cloud-upload",
theme: "outlined",
});
});
it("test remove", async () => {
const onChange = jest.fn();
const onRemove = jest.fn();
const wrapper = mount(
<UploadFilesV2 url={url} onChange={onChange} onRemove={onRemove} />
);
wrapper.find(Upload).invoke("onChange")({
file: {
uid: "-img1",
size: 1024,
type: "image/png",
name: "image.png",
status: "done",
response: {
data: {
objectName: "image.png",
},
},
},
fileList: [
...fileList,
{
uid: "-img1",
size: 1024,
type: "image/png",
name: "image.png",
status: "done",
response: {
data: {
objectName: "image.png",
},
},
},
],
});
wrapper.update();
expect(wrapper.find(".ant-upload-list-item").length).toBe(2);
wrapper.find(Upload).invoke("onRemove")({
uid: "-img1",
size: 1024,
type: "image/png",
name: "image.png",
response: {
data: {
objectName: "image.png",
},
},
});
wrapper.update();
expect(onRemove).toHaveBeenCalled();
});
it("test error", async () => {
const onChange = jest.fn();
const onError = jest.fn();
const wrapper = mount(
<UploadFilesV2 url={url} onChange={onChange} onError={onError} />
);
wrapper.find(Upload).invoke("onChange")({
file: {
uid: "-img1",
size: 1024,
type: "image/png",
name: "image.png",
status: "uploading",
},
fileList: [
{
uid: "-img1",
size: 1024,
type: "image/png",
name: "image.png",
status: "uploading",
},
],
});
wrapper.update();
expect(wrapper.find(".ant-upload-list-item").length).toBe(1);
wrapper.find(Upload).invoke("onChange")({
file: {
uid: "-img1",
size: 1024,
type: "image/png",
name: "image.png",
status: "error",
},
fileList: [],
});
await act(async () => {
await jest.runAllTimers();
});
wrapper.update();
expect(wrapper.find(".ant-upload-list-item").length).toBe(0);
expect(onError).toHaveBeenCalled();
});
it("test set value by outside", async () => {
const onChange = jest.fn();
const wrapper = mount(
<UploadFilesV2 url={url} method="put" onChange={onChange} />
);
wrapper.find(Upload).invoke("onChange")({
file: {
uid: "-img1",
size: 1024,
type: "image/png",
name: "image.png",
status: "done",
},
fileList: [
{
uid: "-img1",
size: 1024,
type: "image/png",
name: "image.png",
status: "done",
},
],
});
wrapper.update();
expect(wrapper.find(".ant-upload-list-item").length).toBe(1);
wrapper.setProps({
value: [
{
url: "image2.png",
},
{
url: "image2.png",
},
],
});
await act(async () => {
await jest.runAllTimers();
});
wrapper.update();
expect(wrapper.find(".ant-upload-list-item").length).toBe(2);
});
it("test maxNumber", async () => {
const onChange = jest.fn();
const wrapper = mount(
<UploadFilesV2 url={url} method="put" onChange={onChange} />
);
await act(async () => {
wrapper.find(Upload).invoke("onChange")({
file: {
uid: "-img1",
size: 1024,
type: "image/png",
name: "image.png",
status: "done",
response: {
data: {
objectName: "image.png",
},
},
originFileObj: new File([], "image.png", { type: "image/png" }),
},
fileList: [
{
uid: "-img1",
size: 1024,
type: "image/png",
name: "image.png",
status: "done",
response: {
data: {
objectName: "image.png",
},
},
originFileObj: new File([], "image.png", { type: "image/png" }),
},
],
});
await (global as any).flushPromises();
});
wrapper.update();
expect(wrapper.find(".ant-upload-list-item").length).toBe(1);
wrapper.setProps({
maxNumber: 2,
value: [
{
url: "image2.png",
},
{
url: "image2.png",
},
],
});
await act(async () => {
await jest.runAllTimers();
});
wrapper.update();
expect(wrapper.find(".ant-upload-list-item").length).toBe(2);
expect(
wrapper.find(".ant-upload-select-text button").prop("disabled")
).toBe(true);
wrapper.setProps({
maxNumber: 3,
});
wrapper.update();
expect(
wrapper.find(".ant-upload-select-text button").prop("disabled")
).toBe(undefined);
});
describe("test limitSize", () => {
const wrapper = mount(<UploadFilesV2 url={url} method="put" autoUpload />);
it("while autoUpload is true", async () => {
wrapper.setProps({
limitSize: 1,
});
const notAllowResult = wrapper.find(Upload).invoke("beforeUpload")(
{
size: 1024 * 1024 * 10,
},
[
{
size: 1024 * 1024 * 10,
},
]
);
await expect(notAllowResult).rejects.toStrictEqual(
new Error(i18n.t(`${NS_FORMS}:${K.VOLUME_TOO_BIG}`))
);
wrapper.setProps({
limitSize: 2,
});
const allowResult = wrapper.find(Upload).invoke("beforeUpload")(
{
size: 1024 * 1024,
},
[
{
size: 1024 * 1024,
},
]
);
await expect(allowResult).resolves.toMatchObject({
size: 1024 * 1024,
});
});
it("while autoUpload is false", () => {
wrapper.setProps({
autoUpload: false,
});
wrapper.update();
const autoUploadResult = wrapper.find(Upload).invoke("beforeUpload")(
{
size: 1024 * 1024,
},
[
{
size: 1024 * 1024,
},
]
);
expect(autoUploadResult).toBeFalsy();
});
});
it("test draggable", async () => {
const onChange = jest.fn();
const wrapper = mount(
<UploadFilesV2
url={url}
method="put"
onChange={onChange}
hideDragBtnWhenAchieveMax
uploadDraggable
maxNumber={1}
/>
);
await act(async () => {
wrapper.find(Upload).invoke("onChange")({
file: {
uid: "-img1",
size: 1024,
type: "image/png",
name: "image.png",
status: "done",
response: {
data: {
objectName: "image.png",
},
},
originFileObj: new File([], "image.png", { type: "image/png" }),
},
fileList: [
{
uid: "-img1",
size: 1024,
type: "image/png",
name: "image.png",
status: "done",
response: {
data: {
objectName: "image.png",
},
},
originFileObj: new File([], "image.png", { type: "image/png" }),
},
],
});
await (global as any).flushPromises();
});
wrapper.update();
expect(
wrapper.find(".ant-upload-drag").hasClass("uploadContainerDisplayNone")
).toBeTruthy();
wrapper.setProps({
hideDragBtnWhenAchieveMax: false,
value: [
{
url: "image2.png",
},
],
});
await act(async () => {
wrapper.find(Upload).invoke("onChange")({
file: {
uid: "-img1",
size: 1024,
type: "image/png",
name: "image.png",
status: "done",
response: {
data: {
objectName: "image.png",
},
},
originFileObj: new File([], "image.png", { type: "image/png" }),
},
fileList: [
{
uid: "-img1",
size: 1024,
type: "image/png",
name: "image.png",
status: "done",
response: {
data: {
objectName: "image.png",
},
},
originFileObj: new File([], "image.png", { type: "image/png" }),
},
],
});
await (global as any).flushPromises();
});
wrapper.update();
expect(
wrapper.find(".ant-upload-drag").hasClass("uploadContainerDisplayNone")
).toBeFalsy();
});
it("should show dark icon", () => {
const spyOnUseCurrentTheme = jest
.spyOn(brickKit, "useCurrentTheme")
.mockReturnValue("dark-v2");
const wrapper = mount(
<UploadFilesV2 url={url} value={fileList} uploadDraggable />
);
expect(wrapper.find(GeneralIcon).at(0).prop("icon")).toEqual({
category: "colored-common",
icon: "upload-dark",
lib: "easyops",
});
spyOnUseCurrentTheme.mockRestore();
});
});
Example #27
Source File: asset-modal.tsx From erda-ui with GNU Affero General Public License v3.0 | 4 votes |
AssetModal = ({ scope, visible, onCancel, afterSubmit, mode, formData }: IProps) => {
const { createAsset, addNewVersion, editAsset } = apiMarketStore.effects;
const [suffix, setSuffix] = React.useState(allSuffix);
const formRef = React.useRef({}) as MutableRefObject<FormInstance>;
const [uploadFile, setUploadFile] = React.useState('');
const [loading, setLoading] = React.useState(false);
React.useEffect(() => {
if (!visible) {
setUploadFile('');
}
}, [visible]);
const handleSelectProtocol = (v: API_MARKET.SpecProtocol) => {
setSuffix(protocolMap[v].suffix);
// 文件后缀和资源协议不一致
if (uploadFile && !protocolMap[v].pattern.test(uploadFile)) {
setUploadFile('');
formRef.current && formRef.current.setFieldsValue({ specDiceFileUUID: undefined });
}
};
const nameToId = (e: React.FocusEvent<HTMLInputElement>) => {
const name = e.target.value;
const assetID = formRef.current.getFieldValue('assetID');
if (!assetID && idReg.test(name) && name.length <= 20) {
formRef.current.setFieldsValue({ assetID: name });
}
};
const showVersionField = scope === 'version' || (scope === 'asset' && mode === 'add');
const showAssetField = scope === 'asset';
const fieldsList: IFormItem[] = [
...insertWhen(showAssetField, [
{
label: i18n.t('API name'),
name: 'assetName',
type: 'input',
required: true,
itemProps: {
placeholder: i18n.t('default:please enter'),
autoComplete: 'off',
maxLength: 50,
onBlur: nameToId,
},
},
{
label: 'API ID',
type: 'input',
name: 'assetID',
required: true,
itemProps: {
placeholder: i18n.t('default:please enter'),
autoComplete: 'off',
maxLength: 20,
disabled: mode === 'edit',
},
rules: [
{
pattern: idReg,
message: i18n.t(
'default:start with number or letter, can contain numbers, letters, dots, hyphens and underscores',
),
},
],
},
{
label: i18n.t('API description'),
type: 'textArea',
name: 'desc',
required: false,
itemProps: {
placeholder: i18n.t('default:please enter'),
autoComplete: 'off',
maxLength: 1024,
},
},
]),
...insertWhen(showVersionField, [
{
label: i18n.t('default:Resource version'),
type: 'input',
name: 'version',
required: false,
itemProps: {
placeholder: i18n.t('Please enter version number, such as x.y.z.'),
autoComplete: 'off',
},
rules: [
{
pattern: /^(?:[1-9]\d*|0)\.(?:[1-9]\d*|0)\.(?:[1-9]\d*|0)$/,
message: i18n.t('Please enter a valid version number, such as x.y.z.'),
},
],
},
{
label: i18n.t('API description document protocol'),
type: 'select',
name: 'specProtocol',
options: map(protocolMap, ({ fullName }, key) => ({ name: fullName, value: key })),
itemProps: {
placeholder: i18n.t('Please Select'),
onSelect: handleSelectProtocol,
},
},
]),
...insertWhen(showVersionField, [
{
label: i18n.t('default:API description document'),
name: 'specDiceFileUUID',
required: true,
getComp: ({ form }: { form: FormInstance }) => {
const uploadProps = getUploadProps({
onChange: ({ file }: any) => {
setLoading(true);
if (file.response) {
setLoading(false);
const { success, err, data } = file.response;
if (!success) {
message.error(err.msg);
} else {
form.setFieldsValue({
specDiceFileUUID: data.uuid,
});
setUploadFile(data.name);
}
}
return file;
},
});
return (
<div className="upload-container">
<Upload accept={suffix} {...uploadProps}>
<Button className="flex items-center">
<ErdaIcon type="upload" className="mr-1" size="14" /> {i18n.t('Upload')}
</Button>
</Upload>
<span className="text-desc ml-2">
{uploadFile ? i18n.t('selected {name}', { name: uploadFile }) : null}
</span>
</div>
);
},
},
]),
...insertWhen(showAssetField, [
{
label: i18n.t('API logo'),
name: 'logo',
required: false,
getComp: ({ form }: { form: FormInstance }) => <ImageUpload id="logo" form={form} showHint />,
},
]),
];
const handleOk = () => {
formRef.current.validateFields().then(async (data: any) => {
const payload = formatPayload(scope, mode, data, formData);
let request: any = createAsset;
if (scope === 'version') {
request = addNewVersion;
} else if (scope === 'asset' && mode === 'edit') {
request = editAsset;
} else if (scope === 'asset' && mode === 'add') {
request = createAsset;
}
const res = await request(payload);
onCancel();
afterSubmit && afterSubmit(res);
});
};
const footer = (
<>
<Button key="back" onClick={onCancel}>
{i18n.t('Cancel')}
</Button>
<Button key="submit" type="primary" disabled={loading} onClick={handleOk}>
{i18n.t('OK')}
</Button>
</>
);
return (
<FormModal
title={titleMap[scope][mode]}
visible={visible}
fieldsList={fieldsList}
ref={formRef}
onCancel={onCancel}
formData={formData || {}}
loading={loading}
modalProps={{
destroyOnClose: true,
footer,
}}
/>
);
}
Example #28
Source File: TemplateInfoModal.tsx From yugong with MIT License | 4 votes |
TemplateInfoModal: React.FC<Props> = ({ visible, onOk, onCancel }) => {
const [tags, setTags] = useState<queryTagParams[]>([]);
const pageData = useSelector((state: RootState) => state.pageData);
const [defaultValue, setDefaultValue] = useState<AnyObject>();
const [csrfToken] = useCookie('csrfToken')
const getTags = useCallback(async () => {
const tagsResult = await queryTag();
setTags(tagsResult);
}, []);
useEffect(() => {
const { template = {}, pageTitle } = pageData;
const { title, cove, tag, describe, terminal, isPublic } = template;
const defaultParams: TemplateInfo = {
title: title || pageTitle,
cove: !!cove ? [{thumbUrl: cove}] : [],
tag: !!tag ? tag.split(',') : [],
isPublic: (isPublic === 1),
describe,
terminal,
};
setDefaultValue(defaultParams);
}, [pageData, pageData.template, visible]);
useEffect(() => {
getTags();
}, [getTags]);
const handleSubmit = useCallback(
(data: AnyObject) => {
if (!isType(data, 'Object')) return;
data.describe = data.describe || '';
if (onOk instanceof Function) onOk(data);
},
[onOk]
);
return (
<Modal
key={`${visible}`}
title="模版信息"
visible={visible}
onCancel={onCancel}
okText={'确定'}
cancelText={'取消'}
footer={null}
>
<Form
name="templateInfo"
labelCol={{ span: 5 }}
wrapperCol={{ span: 19 }}
initialValues={defaultValue}
onFinish={handleSubmit}
>
<Form.Item
label="模板标题"
name="title"
rules={[{ required: true, message: '请填写模板标题' }]}
>
<Input />
</Form.Item>
<Form.Item
label="终端"
name="terminal"
rules={[{ required: true, message: '请选择终端' }]}
>
<Select placeholder="请选择">
<Select.Option value="mobile">移动端</Select.Option>
<Select.Option value="pc">PC端</Select.Option>
</Select>
</Form.Item>
<Form.Item
name="cove"
label="封面图片"
valuePropName="fileList"
getValueFromEvent={normFile}
extra="模版封面图片"
rules={[{ required: true, message: '请上传封面图片' }]}
>
<Upload
action="/api/upload"
listType="picture"
maxCount={1}
headers={{
'x-csrf-token': csrfToken || ''
}}
>
<Button icon={<UploadOutlined />}>上传图片</Button>
</Upload>
</Form.Item>
<Form.Item label="描述" name="describe">
<Input.TextArea rows={3} />
</Form.Item>
<Form.Item
label="标签"
name="tag"
rules={[{ required: true, message: '请选择标签' }]}
>
<Select mode="multiple" allowClear placeholder="标签">
{tags.map((item) => (
<Select.Option key={item.id} value={`${item.id}`}>
{item.name}
</Select.Option>
))}
</Select>
</Form.Item>
<Form.Item
name="isPublic"
valuePropName="checked"
wrapperCol={{ offset: 9, span: 17 }}
>
<Checkbox>发布为公共模板</Checkbox>
</Form.Item>
<Form.Item wrapperCol={{ offset: 10, span: 14 }}>
<Button type="primary" htmlType="submit">
确定
</Button>
</Form.Item>
</Form>
</Modal>
);
}
Example #29
Source File: MultipleFileUpload.tsx From condo with MIT License | 4 votes |
MultipleFileUpload: React.FC<IMultipleFileUploadProps> = (props) => {
const intl = useIntl()
const AddFileLabel = intl.formatMessage({ id: 'component.uploadlist.AddFileLabel' })
const FileTooBigErrorMessage = intl.formatMessage({ id: 'component.uploadlist.error.FileTooBig' },
{ maxSizeInMb: MAX_UPLOAD_FILE_SIZE / (1024 * 1024) })
const UploadFailedErrorMessage = intl.formatMessage({ id: 'component.uploadlist.error.UploadFailedErrorMessage' })
const {
setFilesCount,
fileList,
initialCreateValues,
Model,
onFilesChange,
UploadButton,
uploadProps = {},
} = props
const [listFiles, setListFiles] = useState<UploadListFile[]>([])
useEffect(() => {
const convertedFiles = convertFilesToUploadFormat(fileList)
setListFiles(convertedFiles)
}, [fileList])
const createAction = Model.useCreate(initialCreateValues, (file: DBFile) => Promise.resolve(file))
useEffect(() => {
if (listFiles.length === 0) {
setFilesCount(0)
}
}, [listFiles.length, setFilesCount])
const options = {
fileList: listFiles,
multiple: true,
onChange: (info) => {
let fileList = [...info.fileList]
fileList = fileList.map(file => {
if (file.response) {
file.url = file.response.url
}
return file
})
setListFiles(fileList)
},
showUploadList: {
showRemoveIcon: true,
removeIcon: (file) => {
const removeIcon = (
<DeleteFilled onClick={() => {
const { id, uid } = file
const fileError = get(file, 'error')
if (!fileError) {
setFilesCount(filesCount => filesCount - 1)
}
if (!id) {
// remove file that failed to upload from list
setListFiles([...listFiles].filter(file => file.uid !== uid))
onFilesChange({ type: 'delete', payload: file })
return
}
setListFiles([...listFiles].filter(file => file.id !== id))
onFilesChange({ type: 'delete', payload: file })
}} />
)
return removeIcon
},
},
customRequest: (options: UploadRequestOption) => {
const { onSuccess, onError } = options
const file = options.file as UploadFile
if (file.size > MAX_UPLOAD_FILE_SIZE) {
const error = new Error(FileTooBigErrorMessage)
onError(error)
return
}
return createAction({ ...initialCreateValues, file }).then( dbFile => {
const [uploadFile] = convertFilesToUploadFormat([dbFile])
onSuccess(uploadFile, null)
onFilesChange({ type: 'add', payload: dbFile })
setFilesCount(filesCount => filesCount + 1)
}).catch(err => {
const error = new Error(UploadFailedErrorMessage)
console.error('Upload failed', err)
onError(error)
})
},
...uploadProps,
}
return (
<div className={'upload-control-wrapper'}>
<Upload { ...options }>
{
UploadButton || (
<Button
type={'sberDefaultGradient'}
secondary
icon={<EditFilled />}
>
{AddFileLabel}
</Button>
)
}
</Upload>
</div>
)
}