From 86babd16bcd86c849b3cf40d6ca4a27e4ea59ae4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=84=E5=BB=BA=E5=B3=B0?= Date: Wed, 28 Aug 2019 15:06:31 +0800 Subject: [PATCH 01/20] upload-add-download --- components/upload/Upload.tsx | 13 +++++- components/upload/UploadList.tsx | 75 +++++++++++++++++++++--------- components/upload/interface.tsx | 9 +++- components/upload/style/index.less | 30 ++++++++++-- 4 files changed, 99 insertions(+), 28 deletions(-) diff --git a/components/upload/Upload.tsx b/components/upload/Upload.tsx index fa4a6ba59b71..0e6786ef27ff 100644 --- a/components/upload/Upload.tsx +++ b/components/upload/Upload.tsx @@ -205,6 +205,15 @@ class Upload extends React.Component { return true; }; + handleDownload = (file: UploadFile) => { + const { onDownload } = this.props; + if (typeof onDownload === 'function') { + onDownload(file); + } else if (file.url) { + window.open(file.url); + } + }; + handleRemove(file: UploadFile) { const { onRemove } = this.props; const { fileList } = this.state; @@ -257,7 +266,7 @@ class Upload extends React.Component { disabled, locale: propLocale, } = this.props; - const { showRemoveIcon, showPreviewIcon } = showUploadList as any; + const { showRemoveIcon, showPreviewIcon, showDownloadIcon } = showUploadList as any; const { fileList } = this.state; return ( { items={fileList} previewFile={previewFile} onPreview={onPreview} + onDownload={this.handleDownload} onRemove={this.handleManualRemove} showRemoveIcon={!disabled && showRemoveIcon} showPreviewIcon={showPreviewIcon} + showDownloadIcon={showDownloadIcon} locale={{ ...locale, ...propLocale }} /> ); diff --git a/components/upload/UploadList.tsx b/components/upload/UploadList.tsx index 5ffcf7e0868b..df7d88eafd86 100644 --- a/components/upload/UploadList.tsx +++ b/components/upload/UploadList.tsx @@ -16,6 +16,7 @@ export default class UploadList extends React.Component { showInfo: false, }, showRemoveIcon: true, + showDownloadIcon: true, showPreviewIcon: true, previewFile: previewImage, }; @@ -56,6 +57,14 @@ export default class UploadList extends React.Component { return onPreview(file); }; + handleDownload = (file: UploadFile) => { + const { onDownload } = this.props; + if (!onDownload) { + return; + } + return onDownload(file); + }; + handleClose = (file: UploadFile) => { const { onRemove } = this.props; if (onRemove) { @@ -70,6 +79,7 @@ export default class UploadList extends React.Component { listType, showPreviewIcon, showRemoveIcon, + showDownloadIcon, locale, progressAttr, } = this.props; @@ -128,18 +138,36 @@ export default class UploadList extends React.Component { }); const linkProps = typeof file.linkProps === 'string' ? JSON.parse(file.linkProps) : file.linkProps; - const preview = file.url ? ( - this.handlePreview(file, e)} + const downloadOrDelete = listType !== 'picture-card' && ( + - {file.name} - + {file.status !== 'error' && ( + + this.handleDownload(file)} /> + + )} + + this.handleClose(file)} /> + + + ); + const preview = file.url ? ( + + this.handlePreview(file, e)} + > + {file.name} + + {downloadOrDelete} + ) : ( { title={file.name} > {file.name} + {downloadOrDelete} ); const style: React.CSSProperties = { @@ -168,18 +197,20 @@ export default class UploadList extends React.Component { const removeIcon = showRemoveIcon ? ( this.handleClose(file)} /> ) : null; - const removeIconClose = showRemoveIcon ? ( - this.handleClose(file)} /> + const downloadIcon = showDownloadIcon ? ( + this.handleDownload(file)} + /> ) : null; - const actions = - listType === 'picture-card' && file.status !== 'uploading' ? ( - - {previewIcon} - {removeIcon} - - ) : ( - removeIconClose - ); + const actions = listType === 'picture-card' && file.status !== 'uploading' && ( + + {previewIcon} + {downloadIcon} + {removeIcon} + + ); let message; if (file.response && typeof file.response === 'string') { message = file.response; diff --git a/components/upload/interface.tsx b/components/upload/interface.tsx index f24b2ff8435d..b5326ead3c4d 100755 --- a/components/upload/interface.tsx +++ b/components/upload/interface.tsx @@ -40,11 +40,13 @@ export interface UploadChangeParam { export interface ShowUploadListInterface { showRemoveIcon?: boolean; showPreviewIcon?: boolean; + showDownloadIcon?: boolean; } export interface UploadLocale { uploading?: string; removeFile?: string; + downloadFile?: string; uploadError?: string; previewFile?: string; } @@ -53,7 +55,9 @@ export type UploadType = 'drag' | 'select'; export type UploadListType = 'text' | 'picture' | 'picture-card'; type PreviewFileHandler = (file: File | Blob) => PromiseLike; -type TransformFileHandler = (file: UploadFile) => string | Blob | File | PromiseLike; +type TransformFileHandler = ( + file: UploadFile, +) => string | Blob | File | PromiseLike; export interface UploadProps { type?: UploadType; @@ -72,6 +76,7 @@ export interface UploadProps { listType?: UploadListType; className?: string; onPreview?: (file: UploadFile) => void; + onDownload?: (file: UploadFile) => void; onRemove?: (file: UploadFile) => void | boolean | Promise; supportServerRender?: boolean; style?: React.CSSProperties; @@ -94,11 +99,13 @@ export interface UploadState { export interface UploadListProps { listType?: UploadListType; onPreview?: (file: UploadFile) => void; + onDownload?: (file: UploadFile) => void; onRemove?: (file: UploadFile) => void | boolean; items?: Array; progressAttr?: Object; prefixCls?: string; showRemoveIcon?: boolean; + showDownloadIcon?: boolean; showPreviewIcon?: boolean; locale: UploadLocale; previewFile?: PreviewFileHandler; diff --git a/components/upload/style/index.less b/components/upload/style/index.less index 328278335903..fc027122a0b4 100644 --- a/components/upload/style/index.less +++ b/components/upload/style/index.less @@ -147,13 +147,27 @@ font-size: @font-size-base; &-name { display: inline-block; - width: 100%; padding-left: @font-size-base + 8px; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; } + &-card-actions { + position: absolute; + right: 0; + opacity: 0; + &.picture { + top: 25px; + line-height: 1; + opacity: 1; + } + .anticon { + padding-right: 5px; + color: rgba(0, 0, 0, 0.45); + } + } + &-info { height: 100%; padding: 0 12px 0 4px; @@ -196,14 +210,21 @@ opacity: 1; } + &:hover &-card-actions { + opacity: 1; + } + &-error, &-error .@{iconfont-css-prefix}-paper-clip, &-error &-name { color: @error-color; } - &-error .@{iconfont-css-prefix}-close { - color: @error-color !important; + &-error &-card-actions { + .anticon { + padding-right: 5px; + color: @error-color; + } opacity: 1; } @@ -281,7 +302,7 @@ box-sizing: border-box; max-width: 100%; margin: 0 0 0 8px; - padding-right: 8px; + padding-right: 48px; padding-left: 48px; overflow: hidden; line-height: 44px; @@ -353,6 +374,7 @@ transition: all 0.3s; .@{iconfont-css-prefix}-eye-o, + .@{iconfont-css-prefix}-download, .@{iconfont-css-prefix}-delete { z-index: 10; width: 16px; From f06b9aede9cecd197d6a091f97a2f925f4da14c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=84=E5=BB=BA=E5=B3=B0?= Date: Wed, 28 Aug 2019 15:13:10 +0800 Subject: [PATCH 02/20] add local --- components/locale/default.tsx | 1 + components/locale/zh_CN.tsx | 1 + 2 files changed, 2 insertions(+) diff --git a/components/locale/default.tsx b/components/locale/default.tsx index eabf51c069f4..634037f41b11 100644 --- a/components/locale/default.tsx +++ b/components/locale/default.tsx @@ -42,6 +42,7 @@ export default { removeFile: 'Remove file', uploadError: 'Upload error', previewFile: 'Preview file', + downloadFile: 'download file', }, Empty: { description: 'No Data', diff --git a/components/locale/zh_CN.tsx b/components/locale/zh_CN.tsx index 6dd924069e3f..1f5a915c3ff2 100644 --- a/components/locale/zh_CN.tsx +++ b/components/locale/zh_CN.tsx @@ -42,6 +42,7 @@ export default { removeFile: '删除文件', uploadError: '上传错误', previewFile: '预览文件', + downloadFile: '预览文件', }, Empty: { description: '暂无数据', From 30ee3ef70585addff1dc35496c9620e2991e4343 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=84=E5=BB=BA=E5=B3=B0?= Date: Wed, 28 Aug 2019 15:24:29 +0800 Subject: [PATCH 03/20] test --- .../__snapshots__/components.test.js.snap | 219 +++- .../__tests__/__snapshots__/demo.test.js.snap | 886 +++++++++---- .../__snapshots__/uploadlist.test.js.snap | 1095 +++++++++++------ components/upload/__tests__/upload.test.js | 2 +- .../upload/__tests__/uploadlist.test.js | 2 +- 5 files changed, 1537 insertions(+), 667 deletions(-) diff --git a/components/config-provider/__tests__/__snapshots__/components.test.js.snap b/components/config-provider/__tests__/__snapshots__/components.test.js.snap index c5a1285f3924..b1499dfb4786 100644 --- a/components/config-provider/__tests__/__snapshots__/components.test.js.snap +++ b/components/config-provider/__tests__/__snapshots__/components.test.js.snap @@ -17339,30 +17339,61 @@ exports[`ConfigProvider components Upload configProvider 1`] = ` title="xxx.png" > xxx.png + + + + + + + + + + + + - - - @@ -17409,30 +17440,61 @@ exports[`ConfigProvider components Upload normal 1`] = ` title="xxx.png" > xxx.png + + + + + + + + + + + + - - - @@ -17479,30 +17541,61 @@ exports[`ConfigProvider components Upload prefixCls 1`] = ` title="xxx.png" > xxx.png + + + + + + + + + + + + - - - diff --git a/components/upload/__tests__/__snapshots__/demo.test.js.snap b/components/upload/__tests__/__snapshots__/demo.test.js.snap index d681b37ab3a0..c5beb8d0cea1 100644 --- a/components/upload/__tests__/__snapshots__/demo.test.js.snap +++ b/components/upload/__tests__/__snapshots__/demo.test.js.snap @@ -59,38 +59,72 @@ exports[`renders ./components/upload/demo/defaultFileList.md correctly 1`] = ` /> - - xxx.png - + + xxx.png + + + + + + + + + + + + + + - - - - - - - - - @@ -276,38 +354,72 @@ exports[`renders ./components/upload/demo/fileList.md correctly 1`] = ` /> - - xxx.png - + + xxx.png + + + + + + + + + + + + + + - - - @@ -342,15 +454,18 @@ exports[`renders ./components/upload/demo/picture-card.md correctly 1`] = ` src="https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png" /> - - image.png - + + image.png + + + + + - - image.png - + + image.png + + + + + - - image.png - + + image.png + + + + + - - image.png - + + image.png + + + + + - - image.png - + + image.png + + + + + - - xxx.png - + + xxx.png + + + + + + + + + + + + + + - - - - - - @@ -888,38 +1188,72 @@ exports[`renders ./components/upload/demo/picture-style.md correctly 1`] = ` src="https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png" /> - - xxx.png - + + xxx.png + + + + + + + + + + + + + + - - - - - - diff --git a/components/upload/__tests__/__snapshots__/uploadlist.test.js.snap b/components/upload/__tests__/__snapshots__/uploadlist.test.js.snap index 20a9c1020284..5c54b8df47a2 100644 --- a/components/upload/__tests__/__snapshots__/uploadlist.test.js.snap +++ b/components/upload/__tests__/__snapshots__/uploadlist.test.js.snap @@ -58,30 +58,37 @@ exports[`Upload List handle error 1`] = ` title="foo.png" > foo.png + + + + + + + - - -
@@ -167,30 +174,61 @@ exports[`Upload List should be uploading when upload a file 1`] = ` title="foo.png" > foo.png + + + + + + + + + + + +
- - -
@@ -276,30 +314,61 @@ exports[`Upload List should be uploading when upload a file 2`] = ` title="foo.png" > foo.png + + + + + + + + + + + +
- - -
@@ -392,38 +461,72 @@ exports[`Upload List should non-image format file preview 1`] = ` - - not-image - + + not-image + + + + + + + + + + + + + +
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/components/upload/__tests__/upload.test.js b/components/upload/__tests__/upload.test.js index 483df225950b..099f2fde22a4 100644 --- a/components/upload/__tests__/upload.test.js +++ b/components/upload/__tests__/upload.test.js @@ -417,7 +417,7 @@ describe('Upload', () => { const wrapper = mount(); - wrapper.find('div.ant-upload-list-item i.anticon-close').simulate('click'); + wrapper.find('div.ant-upload-list-item i.anticon-delete').simulate('click'); setImmediate(() => { wrapper.update(); diff --git a/components/upload/__tests__/uploadlist.test.js b/components/upload/__tests__/uploadlist.test.js index 0f0b73c968e1..03df54bc8f09 100644 --- a/components/upload/__tests__/uploadlist.test.js +++ b/components/upload/__tests__/uploadlist.test.js @@ -121,7 +121,7 @@ describe('Upload List', () => { wrapper .find('.ant-upload-list-item') .at(0) - .find('.anticon-close') + .find('.anticon-delete') .simulate('click'); await sleep(400); wrapper.update(); From 45edff35de2e758fefc588efe78cb7cb6de49022 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=84=E5=BB=BA=E5=B3=B0?= Date: Wed, 28 Aug 2019 15:44:26 +0800 Subject: [PATCH 04/20] fix test --- components/upload/__tests__/upload.test.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/upload/__tests__/upload.test.js b/components/upload/__tests__/upload.test.js index 099f2fde22a4..ffd70f37c1d1 100644 --- a/components/upload/__tests__/upload.test.js +++ b/components/upload/__tests__/upload.test.js @@ -376,7 +376,7 @@ describe('Upload', () => { }, ]; const wrapper = mount(); - const linkNode = wrapper.find('a.ant-upload-list-item-name'); + const linkNode = wrapper.find('span.ant-upload-list-item-name > a'); expect(linkNode.props().download).toBe('image'); expect(linkNode.props().rel).toBe('noopener'); }); @@ -396,7 +396,7 @@ describe('Upload', () => { }, ]; const wrapper = mount(); - const linkNode = wrapper.find('a.ant-upload-list-item-name'); + const linkNode = wrapper.find('span.ant-upload-list-item-name > a'); expect(linkNode.props().download).toBe('image'); expect(linkNode.props().rel).toBe('noopener'); }); From a774097639a03f26010773ab2a38ffdd4e1a3ec3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=84=E5=BB=BA=E5=B3=B0?= Date: Wed, 28 Aug 2019 15:50:16 +0800 Subject: [PATCH 05/20] doc --- components/upload/index.zh-CN.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/components/upload/index.zh-CN.md b/components/upload/index.zh-CN.md index 3a1d5f5b528e..6ed917a1e313 100644 --- a/components/upload/index.zh-CN.md +++ b/components/upload/index.zh-CN.md @@ -33,13 +33,14 @@ title: Upload | multiple | 是否支持多选文件,`ie10+` 支持。开启后按住 ctrl 可选择多个文件 | boolean | false | | | name | 发到后台的文件参数名 | string | 'file' | | | previewFile | 自定义文件预览逻辑 | (file: File \| Blob) => Promise | 无 | 3.17.0 | -| showUploadList | 是否展示文件列表, 可设为一个对象,用于单独设定 `showPreviewIcon` 和 `showRemoveIcon` | Boolean or { showPreviewIcon?: boolean, showRemoveIcon?: boolean } | true | | +| showUploadList | 是否展示文件列表, 可设为一个对象,用于单独设定 `showPreviewIcon` 和 `showRemoveIcon` 和 `showDownloadIcon` | Boolean or { showPreviewIcon?: boolean, showRemoveIcon?: boolean, showDownloadIcon?: boolean } | true | | | supportServerRender | 服务端渲染时需要打开这个 | boolean | false | | | withCredentials | 上传请求时是否携带 cookie | boolean | false | | | openFileDialogOnClick | 点击打开文件对话框 | boolean | true | 3.10.0 | | onChange | 上传文件改变时的状态,详见 [onChange](#onChange) | Function | 无 | | | onPreview | 点击文件链接或预览图标时的回调 | Function(file) | 无 | | | onRemove   | 点击移除文件时的回调,返回值为 false 时不移除。支持返回一个 Promise 对象,Promise 对象 resolve(false) 或 reject 时不移除。               | Function(file): `boolean | Promise` | 无   | | +| onDelete   | 点击删除文件时的方法,传方法择执行方法逻辑,不传则默认跳转新标签页。               | Function(file): void | 跳转新标签页   | | | transformFile   | 在上传之前转换文件。支持返回一个 Promise 对象   | Function(file): `string | Blob | File | Promise` | 无   | 3.21.0 | ### onChange From 955177e92562bce23bb3ada6364f0ebb9c94fae8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=84=E5=BB=BA=E5=B3=B0?= Date: Wed, 28 Aug 2019 15:53:21 +0800 Subject: [PATCH 06/20] doc en --- components/upload/index.en-US.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/components/upload/index.en-US.md b/components/upload/index.en-US.md index c0b1e33e1223..f89c95e2e8ed 100644 --- a/components/upload/index.en-US.md +++ b/components/upload/index.en-US.md @@ -32,13 +32,14 @@ Uploading is the process of publishing information (web pages, text, pictures, v | multiple | Whether to support selected multiple file. `IE10+` supported. You can select multiple files with CTRL holding down while multiple is set to be true | boolean | false | | | name | The name of uploading file | string | 'file' | | | previewFile | Customize preview file logic | (file: File \| Blob) => Promise | - | 3.17.0 | -| showUploadList | Whether to show default upload list, could be an object to specify `showPreviewIcon` and `showRemoveIcon` individually | Boolean or { showPreviewIcon?: boolean, showRemoveIcon?: boolean } | true | | +| showUploadList | Whether to show default upload list, could be an object to specify `showPreviewIcon` and `showRemoveIcon` and `showDownloadIcon` individually | Boolean or { showPreviewIcon?: boolean, showRemoveIcon?: boolean } | true | | | supportServerRender | Need to be turned on while the server side is rendering | boolean | false | | | withCredentials | ajax upload with cookie sent | boolean | false | | | openFileDialogOnClick | click open file dialog | boolean | true | 3.10.0 | | onChange | A callback function, can be executed when uploading state is changing, see [onChange](#onChange) | Function | - | | | onPreview | A callback function, will be executed when file link or preview icon is clicked | Function(file) | - | | | onRemove | A callback function, will be executed when removing file button is clicked, remove event will be prevented when return value is `false` or a Promise which resolve(false) or reject | Function(file): `boolean | Promise` | - | | +| onDelete   | Click the method to delete the file, pass the method to perform the method logic, do not pass the default jump to the new TAB.               | Function(file): void | Jump to new TAB   | | | transformFile   | Customize transform file before request | Function(file): `string | Blob | File | Promise` | - | 3.21.0 | ### onChange From 05981c59c032b38331474de9ccb1a6576d5ab6dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=84=E5=BB=BA=E5=B3=B0?= Date: Wed, 28 Aug 2019 15:55:03 +0800 Subject: [PATCH 07/20] fix fix fix --- components/upload/index.en-US.md | 2 +- components/upload/index.zh-CN.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/components/upload/index.en-US.md b/components/upload/index.en-US.md index f89c95e2e8ed..99407fbadd9e 100644 --- a/components/upload/index.en-US.md +++ b/components/upload/index.en-US.md @@ -39,7 +39,7 @@ Uploading is the process of publishing information (web pages, text, pictures, v | onChange | A callback function, can be executed when uploading state is changing, see [onChange](#onChange) | Function | - | | | onPreview | A callback function, will be executed when file link or preview icon is clicked | Function(file) | - | | | onRemove | A callback function, will be executed when removing file button is clicked, remove event will be prevented when return value is `false` or a Promise which resolve(false) or reject | Function(file): `boolean | Promise` | - | | -| onDelete   | Click the method to delete the file, pass the method to perform the method logic, do not pass the default jump to the new TAB.               | Function(file): void | Jump to new TAB   | | +| onDownload   | Click the method to download the file, pass the method to perform the method logic, do not pass the default jump to the new TAB.               | Function(file): void | Jump to new TAB   | | | transformFile   | Customize transform file before request | Function(file): `string | Blob | File | Promise` | - | 3.21.0 | ### onChange diff --git a/components/upload/index.zh-CN.md b/components/upload/index.zh-CN.md index 6ed917a1e313..6148fe7baa8e 100644 --- a/components/upload/index.zh-CN.md +++ b/components/upload/index.zh-CN.md @@ -40,7 +40,7 @@ title: Upload | onChange | 上传文件改变时的状态,详见 [onChange](#onChange) | Function | 无 | | | onPreview | 点击文件链接或预览图标时的回调 | Function(file) | 无 | | | onRemove   | 点击移除文件时的回调,返回值为 false 时不移除。支持返回一个 Promise 对象,Promise 对象 resolve(false) 或 reject 时不移除。               | Function(file): `boolean | Promise` | 无   | | -| onDelete   | 点击删除文件时的方法,传方法择执行方法逻辑,不传则默认跳转新标签页。               | Function(file): void | 跳转新标签页   | | +| onDownload   | 点击下载文件时的方法,传方法择执行方法逻辑,不传则默认跳转新标签页。               | Function(file): void | 跳转新标签页   | | | transformFile   | 在上传之前转换文件。支持返回一个 Promise 对象   | Function(file): `string | Blob | File | Promise` | 无   | 3.21.0 | ### onChange From afdf3cbe6a1a8b0c8eb7c73c377e20cdc82baa6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=84=E5=BB=BA=E5=B3=B0?= Date: Wed, 28 Aug 2019 15:57:27 +0800 Subject: [PATCH 08/20] rename --- components/locale/zh_CN.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/locale/zh_CN.tsx b/components/locale/zh_CN.tsx index 1f5a915c3ff2..67534a324a1f 100644 --- a/components/locale/zh_CN.tsx +++ b/components/locale/zh_CN.tsx @@ -42,7 +42,7 @@ export default { removeFile: '删除文件', uploadError: '上传错误', previewFile: '预览文件', - downloadFile: '预览文件', + downloadFile: '下载文件', }, Empty: { description: '暂无数据', From 89dbb1bca6a52cad135b666a8f4463f7b0fbddb3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=84=E5=BB=BA=E5=B3=B0?= Date: Mon, 2 Sep 2019 18:40:52 +0800 Subject: [PATCH 09/20] add test --- components/upload/__tests__/upload.test.js | 27 +++++++++++++++++++ .../upload/__tests__/uploadlist.test.js | 14 ++++++++++ 2 files changed, 41 insertions(+) diff --git a/components/upload/__tests__/upload.test.js b/components/upload/__tests__/upload.test.js index ffd70f37c1d1..3c59cf38328a 100644 --- a/components/upload/__tests__/upload.test.js +++ b/components/upload/__tests__/upload.test.js @@ -429,6 +429,33 @@ describe('Upload', () => { }); }); + it('should not stop download when return use onDownload', done => { + const mockRemove = jest.fn(() => false); + const props = { + onRemove: mockRemove, + fileList: [ + { + uid: '-1', + name: 'foo.png', + status: 'done', + url: 'http://www.baidu.com/xxx.png', + }, + ], + }; + + const wrapper = mount( {}} />); + + wrapper.find('div.ant-upload-list-item i.anticon-download').simulate('click'); + + setImmediate(() => { + wrapper.update(); + + expect(props.fileList).toHaveLength(1); + expect(props.fileList[0].status).toBe('done'); + done(); + }); + }); + // https://github.com/ant-design/ant-design/issues/14439 it('should allow call abort function through upload instance', () => { const wrapper = mount( diff --git a/components/upload/__tests__/uploadlist.test.js b/components/upload/__tests__/uploadlist.test.js index 03df54bc8f09..2b33935a6522 100644 --- a/components/upload/__tests__/uploadlist.test.js +++ b/components/upload/__tests__/uploadlist.test.js @@ -440,6 +440,20 @@ describe('Upload List', () => { return wrapper.props.previewFile(file); }); + it('downloadFile should work correctly', async () => { + const file = new File([''], 'test.txt', { type: 'text/plain' }); + const items = [{ uid: 'upload-list-item', url: '' }]; + const wrapper = mount( + {}} + locale={{ downloadFile: '' }} + />, + ).instance(); + return wrapper.props.onDownload(file); + }); + it('extname should work correctly when url not exists', () => { const items = [{ uid: 'upload-list-item', url: '' }]; const wrapper = mount( From da8e28afdba11b61e46fb67913b7cc78923f3be0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=8F=B6=E6=9E=AB?= <645381995@qq.com> Date: Tue, 3 Sep 2019 09:20:48 +0800 Subject: [PATCH 10/20] add test --- components/upload/Upload.tsx | 12 ++---------- components/upload/UploadList.tsx | 7 ++++--- components/upload/__tests__/uploadlist.test.js | 7 +++++++ 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/components/upload/Upload.tsx b/components/upload/Upload.tsx index 0e6786ef27ff..8e024c8e4c3c 100644 --- a/components/upload/Upload.tsx +++ b/components/upload/Upload.tsx @@ -205,15 +205,6 @@ class Upload extends React.Component { return true; }; - handleDownload = (file: UploadFile) => { - const { onDownload } = this.props; - if (typeof onDownload === 'function') { - onDownload(file); - } else if (file.url) { - window.open(file.url); - } - }; - handleRemove(file: UploadFile) { const { onRemove } = this.props; const { fileList } = this.state; @@ -262,6 +253,7 @@ class Upload extends React.Component { showUploadList, listType, onPreview, + onDownload, previewFile, disabled, locale: propLocale, @@ -274,7 +266,7 @@ class Upload extends React.Component { items={fileList} previewFile={previewFile} onPreview={onPreview} - onDownload={this.handleDownload} + onDownload={onDownload} onRemove={this.handleManualRemove} showRemoveIcon={!disabled && showRemoveIcon} showPreviewIcon={showPreviewIcon} diff --git a/components/upload/UploadList.tsx b/components/upload/UploadList.tsx index df7d88eafd86..4b6782573b19 100644 --- a/components/upload/UploadList.tsx +++ b/components/upload/UploadList.tsx @@ -59,10 +59,11 @@ export default class UploadList extends React.Component { handleDownload = (file: UploadFile) => { const { onDownload } = this.props; - if (!onDownload) { - return; + if (typeof onDownload === 'function') { + onDownload(file); + } else if (file.url) { + window.open(file.url); } - return onDownload(file); }; handleClose = (file: UploadFile) => { diff --git a/components/upload/__tests__/uploadlist.test.js b/components/upload/__tests__/uploadlist.test.js index 2b33935a6522..c4ece202d4b2 100644 --- a/components/upload/__tests__/uploadlist.test.js +++ b/components/upload/__tests__/uploadlist.test.js @@ -431,6 +431,13 @@ describe('Upload List', () => { expect(wrapper.handlePreview()).toBe(undefined); }); + it('return when prop onDownload not exists', () => { + const file = new File([''], 'test.txt', { type: 'text/plain' }); + const items = [{ uid: 'upload-list-item', url: '' }]; + const wrapper = mount().instance(); + expect(wrapper.handleDownload(file)).toBe(undefined); + }); + it('previewFile should work correctly', async () => { const file = new File([''], 'test.txt', { type: 'text/plain' }); const items = [{ uid: 'upload-list-item', url: '' }]; From 8ed0ed650cc07304f0248d5255ca43933a4dbd13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=8F=B6=E6=9E=AB?= <645381995@qq.com> Date: Tue, 3 Sep 2019 11:34:15 +0800 Subject: [PATCH 11/20] add test --- .../upload/__tests__/uploadlist.test.js | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/components/upload/__tests__/uploadlist.test.js b/components/upload/__tests__/uploadlist.test.js index c4ece202d4b2..189090506665 100644 --- a/components/upload/__tests__/uploadlist.test.js +++ b/components/upload/__tests__/uploadlist.test.js @@ -248,6 +248,25 @@ describe('Upload List', () => { expect(handleChange.mock.calls.length).toBe(2); }); + it('should support onDownload', async () => { + const handleDownload = jest.fn(); + const wrapper = mount( + + + , + ); + wrapper + .find('.anticon-download') + .at(0) + .simulate('click'); + expect(handleDownload).toHaveBeenCalledWith(fileList[0]); + wrapper + .find('.anticon-download') + .at(1) + .simulate('click'); + expect(handleDownload).toHaveBeenCalledWith(fileList[1]); + }); + describe('should generate thumbUrl from file', () => { [ { width: 100, height: 200, name: 'height large than width' }, From d7abefd73264196457e23c650e1044246305983d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=8F=B6=E6=9E=AB?= <645381995@qq.com> Date: Tue, 3 Sep 2019 13:25:44 +0800 Subject: [PATCH 12/20] add test --- .../upload/__tests__/uploadlist.test.js | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/components/upload/__tests__/uploadlist.test.js b/components/upload/__tests__/uploadlist.test.js index 189090506665..f6caf2ef2b5e 100644 --- a/components/upload/__tests__/uploadlist.test.js +++ b/components/upload/__tests__/uploadlist.test.js @@ -202,6 +202,16 @@ describe('Upload List', () => { expect(handleChange.mock.calls[0][0].fileList).toHaveLength(3); }); + it('error status does not show Download', () => { + const file = { status: 'error', uid: 'file' }; + const wrapper = mount( + + + , + ); + expect(wrapper.find('div.ant-upload-list-item i.anticon-download').length).toBe(0); + }); + it('should support onPreview', () => { const handlePreview = jest.fn(); const wrapper = mount( @@ -488,6 +498,21 @@ describe('Upload List', () => { expect(wrapper.find('.ant-upload-list-item-thumbnail').length).toBe(2); }); + it('extname should work correctly when url exists', () => { + const items = [{ uid: 'upload-list-item', url: '/example' }]; + const wrapper = mount( + { + expect(file.url).toBe('/example'); + }} + items={items} + locale={{ downloadFile: '' }} + />, + ); + wrapper.find('div.ant-upload-list-item i.anticon-download').simulate('click'); + }); + it('when picture-card is loading, icon should render correctly', () => { const items = [{ status: 'uploading', uid: 'upload-list-item' }]; const wrapper = mount( From fc84915b86c5c0dd38cc8dc072283c53dde8ae38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=8F=B6=E6=9E=AB?= <645381995@qq.com> Date: Tue, 3 Sep 2019 13:46:20 +0800 Subject: [PATCH 13/20] add test --- components/upload/UploadList.tsx | 4 +- .../__snapshots__/uploadlist.test.js.snap | 24 ----------- .../upload/__tests__/uploadlist.test.js | 43 +++++++++++++++---- site/bisheng.config.js | 2 +- 4 files changed, 37 insertions(+), 36 deletions(-) diff --git a/components/upload/UploadList.tsx b/components/upload/UploadList.tsx index 4b6782573b19..29fa839ea0d2 100644 --- a/components/upload/UploadList.tsx +++ b/components/upload/UploadList.tsx @@ -145,7 +145,7 @@ export default class UploadList extends React.Component { listType === 'picture' ? 'picture' : '' }`} > - {file.status !== 'error' && ( + {file.status === 'done' && ( this.handleDownload(file)} /> @@ -208,7 +208,7 @@ export default class UploadList extends React.Component { const actions = listType === 'picture-card' && file.status !== 'uploading' && ( {previewIcon} - {downloadIcon} + {file.status === 'done' && downloadIcon} {removeIcon} ); diff --git a/components/upload/__tests__/__snapshots__/uploadlist.test.js.snap b/components/upload/__tests__/__snapshots__/uploadlist.test.js.snap index 5c54b8df47a2..2a5433cc2227 100644 --- a/components/upload/__tests__/__snapshots__/uploadlist.test.js.snap +++ b/components/upload/__tests__/__snapshots__/uploadlist.test.js.snap @@ -177,30 +177,6 @@ exports[`Upload List should be uploading when upload a file 1`] = ` - - - - - diff --git a/components/upload/__tests__/uploadlist.test.js b/components/upload/__tests__/uploadlist.test.js index f6caf2ef2b5e..7c542e651f41 100644 --- a/components/upload/__tests__/uploadlist.test.js +++ b/components/upload/__tests__/uploadlist.test.js @@ -202,7 +202,7 @@ describe('Upload List', () => { expect(handleChange.mock.calls[0][0].fileList).toHaveLength(3); }); - it('error status does not show Download', () => { + it('In the case of listType=picture, the error status does not show the download.', () => { const file = { status: 'error', uid: 'file' }; const wrapper = mount( @@ -212,6 +212,26 @@ describe('Upload List', () => { expect(wrapper.find('div.ant-upload-list-item i.anticon-download').length).toBe(0); }); + it('In the case of listType=picture-card, the error status does not show the download.', () => { + const file = { status: 'error', uid: 'file' }; + const wrapper = mount( + + + , + ); + expect(wrapper.find('div.ant-upload-list-item i.anticon-download').length).toBe(0); + }); + + it('In the case of listType=text, the error status does not show the download.', () => { + const file = { status: 'error', uid: 'file' }; + const wrapper = mount( + + + , + ); + expect(wrapper.find('div.ant-upload-list-item i.anticon-download').length).toBe(0); + }); + it('should support onPreview', () => { const handlePreview = jest.fn(); const wrapper = mount( @@ -261,7 +281,18 @@ describe('Upload List', () => { it('should support onDownload', async () => { const handleDownload = jest.fn(); const wrapper = mount( - + , ); @@ -269,12 +300,6 @@ describe('Upload List', () => { .find('.anticon-download') .at(0) .simulate('click'); - expect(handleDownload).toHaveBeenCalledWith(fileList[0]); - wrapper - .find('.anticon-download') - .at(1) - .simulate('click'); - expect(handleDownload).toHaveBeenCalledWith(fileList[1]); }); describe('should generate thumbUrl from file', () => { @@ -499,7 +524,7 @@ describe('Upload List', () => { }); it('extname should work correctly when url exists', () => { - const items = [{ uid: 'upload-list-item', url: '/example' }]; + const items = [{ status: 'done', uid: 'upload-list-item', url: '/example' }]; const wrapper = mount( Date: Tue, 3 Sep 2019 16:49:18 +0800 Subject: [PATCH 14/20] add test --- .../upload/__tests__/uploadlist.test.js | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/components/upload/__tests__/uploadlist.test.js b/components/upload/__tests__/uploadlist.test.js index 7c542e651f41..d126b609f30d 100644 --- a/components/upload/__tests__/uploadlist.test.js +++ b/components/upload/__tests__/uploadlist.test.js @@ -302,6 +302,28 @@ describe('Upload List', () => { .simulate('click'); }); + it('should support no onDownload', async () => { + const wrapper = mount( + + + , + ); + wrapper + .find('.anticon-download') + .at(0) + .simulate('click'); + }); + describe('should generate thumbUrl from file', () => { [ { width: 100, height: 200, name: 'height large than width' }, From 20ddd293e9ac08a0c3ad94c8614aed752cda7608 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=8F=B6=E6=9E=AB?= <645381995@qq.com> Date: Tue, 3 Sep 2019 17:50:17 +0800 Subject: [PATCH 15/20] add test --- components/upload/__tests__/uploadlist.test.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/components/upload/__tests__/uploadlist.test.js b/components/upload/__tests__/uploadlist.test.js index d126b609f30d..e81e583255a4 100644 --- a/components/upload/__tests__/uploadlist.test.js +++ b/components/upload/__tests__/uploadlist.test.js @@ -537,6 +537,14 @@ describe('Upload List', () => { return wrapper.props.onDownload(file); }); + it('downloadFile is true should work correctly', async () => { + const items = [{ uid: 'upload-list-item', url: '' }]; + const wrapper = mount( + , + ).instance(); + return expect(wrapper.props.onDownload).toBe(true); + }); + it('extname should work correctly when url not exists', () => { const items = [{ uid: 'upload-list-item', url: '' }]; const wrapper = mount( From 4a55611a8cfa596c94af4584b788abe82af7688d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=8F=B6=E6=9E=AB?= <645381995@qq.com> Date: Tue, 3 Sep 2019 17:54:56 +0800 Subject: [PATCH 16/20] empty From 0f2e785c36d8237c47cd6a9b94b26e9f6f42c95e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=8F=B6=E6=9E=AB?= <645381995@qq.com> Date: Tue, 3 Sep 2019 18:05:40 +0800 Subject: [PATCH 17/20] empty From 87829a7be4e001da8cd29f8f15af9bdf0c29309d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=8F=B6=E6=9E=AB?= Date: Tue, 3 Sep 2019 20:14:46 +0800 Subject: [PATCH 18/20] Update bisheng.config.js --- site/bisheng.config.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/site/bisheng.config.js b/site/bisheng.config.js index 78e0c3471948..ae06141ab053 100644 --- a/site/bisheng.config.js +++ b/site/bisheng.config.js @@ -24,7 +24,7 @@ function alertBabelConfig(rules) { } module.exports = { - port: 8003, + port: 8001, hash: true, source: { components: './components', From bb5eeccaa6f9cf648c68663286103e2ff9e56728 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=8F=B6=E6=9E=AB?= <645381995@qq.com> Date: Wed, 4 Sep 2019 14:23:46 +0800 Subject: [PATCH 19/20] clear up --- components/locale/default.tsx | 2 +- components/upload/index.en-US.md | 2 +- components/upload/index.zh-CN.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/components/locale/default.tsx b/components/locale/default.tsx index 634037f41b11..012f9b4643cc 100644 --- a/components/locale/default.tsx +++ b/components/locale/default.tsx @@ -42,7 +42,7 @@ export default { removeFile: 'Remove file', uploadError: 'Upload error', previewFile: 'Preview file', - downloadFile: 'download file', + downloadFile: 'Download file', }, Empty: { description: 'No Data', diff --git a/components/upload/index.en-US.md b/components/upload/index.en-US.md index 99407fbadd9e..1c8dbc066a74 100644 --- a/components/upload/index.en-US.md +++ b/components/upload/index.en-US.md @@ -32,7 +32,7 @@ Uploading is the process of publishing information (web pages, text, pictures, v | multiple | Whether to support selected multiple file. `IE10+` supported. You can select multiple files with CTRL holding down while multiple is set to be true | boolean | false | | | name | The name of uploading file | string | 'file' | | | previewFile | Customize preview file logic | (file: File \| Blob) => Promise | - | 3.17.0 | -| showUploadList | Whether to show default upload list, could be an object to specify `showPreviewIcon` and `showRemoveIcon` and `showDownloadIcon` individually | Boolean or { showPreviewIcon?: boolean, showRemoveIcon?: boolean } | true | | +| showUploadList | Whether to show default upload list, could be an object to specify `showPreviewIcon` , `showRemoveIcon` and `showDownloadIcon` individually | Boolean or { showPreviewIcon?: boolean, showRemoveIcon?: boolean } | true | | | supportServerRender | Need to be turned on while the server side is rendering | boolean | false | | | withCredentials | ajax upload with cookie sent | boolean | false | | | openFileDialogOnClick | click open file dialog | boolean | true | 3.10.0 | diff --git a/components/upload/index.zh-CN.md b/components/upload/index.zh-CN.md index 6148fe7baa8e..73fd5c5eb6bc 100644 --- a/components/upload/index.zh-CN.md +++ b/components/upload/index.zh-CN.md @@ -33,7 +33,7 @@ title: Upload | multiple | 是否支持多选文件,`ie10+` 支持。开启后按住 ctrl 可选择多个文件 | boolean | false | | | name | 发到后台的文件参数名 | string | 'file' | | | previewFile | 自定义文件预览逻辑 | (file: File \| Blob) => Promise | 无 | 3.17.0 | -| showUploadList | 是否展示文件列表, 可设为一个对象,用于单独设定 `showPreviewIcon` 和 `showRemoveIcon` 和 `showDownloadIcon` | Boolean or { showPreviewIcon?: boolean, showRemoveIcon?: boolean, showDownloadIcon?: boolean } | true | | +| showUploadList | 是否展示文件列表, 可设为一个对象,用于单独设定 `showPreviewIcon` , `showRemoveIcon` 和 `showDownloadIcon` | Boolean or { showPreviewIcon?: boolean, showRemoveIcon?: boolean, showDownloadIcon?: boolean } | true | | | supportServerRender | 服务端渲染时需要打开这个 | boolean | false | | | withCredentials | 上传请求时是否携带 cookie | boolean | false | | | openFileDialogOnClick | 点击打开文件对话框 | boolean | true | 3.10.0 | From ccd01a7eaf9588aeccdd144af340e859a756c7be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=8F=B6=E6=9E=AB?= <645381995@qq.com> Date: Wed, 4 Sep 2019 14:37:05 +0800 Subject: [PATCH 20/20] test --- .../__snapshots__/components.test.js.snap | 6 ++--- .../__tests__/__snapshots__/demo.test.js.snap | 24 +++++++++---------- .../__snapshots__/uploadlist.test.js.snap | 22 ++++++++--------- 3 files changed, 26 insertions(+), 26 deletions(-) diff --git a/components/config-provider/__tests__/__snapshots__/components.test.js.snap b/components/config-provider/__tests__/__snapshots__/components.test.js.snap index b1499dfb4786..5be03a6d61a3 100644 --- a/components/config-provider/__tests__/__snapshots__/components.test.js.snap +++ b/components/config-provider/__tests__/__snapshots__/components.test.js.snap @@ -17343,7 +17343,7 @@ exports[`ConfigProvider components Upload configProvider 1`] = ` class="config-upload-list-item-card-actions " >