Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(module:upload): support Observable in nzFilter #2590

Merged
merged 3 commits into from
Dec 11, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 1 addition & 5 deletions components/list/nz-list.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,7 @@ import { NzListGrid } from './interface';
encapsulation : ViewEncapsulation.None,
changeDetection : ChangeDetectionStrategy.OnPush,
styles : [ `
:host {
display: block;
}

nz-spin {
nz-list, nz-list nz-spin {
display: block;
}
` ]
Expand Down
52 changes: 41 additions & 11 deletions components/upload/demo/avatar.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Component } from '@angular/core';
import { NzMessageService, UploadFile } from 'ng-zorro-antd';
import { Observable, Observer } from 'rxjs';

@Component({
selector: 'nz-demo-upload-avatar',
Expand All @@ -20,7 +21,7 @@ import { NzMessageService, UploadFile } from 'ng-zorro-antd';
`,
styles: [
`
:host ::ng-deep .avatar-uploader > .ant-upload {
:host ::ng-deep .avatar-uploader > .ant-upload, :host ::ng-deep .avatar {
width: 128px;
height: 128px;
}
Expand All @@ -39,18 +40,34 @@ export class NzDemoUploadAvatarComponent {
loading = false;
avatarUrl: string;

constructor(private msg: NzMessageService) {}
constructor(private msg: NzMessageService) { }

beforeUpload = (file: File) => {
const isJPG = file.type === 'image/jpeg';
if (!isJPG) {
this.msg.error('You can only upload JPG file!');
}
const isLt2M = file.size / 1024 / 1024 < 2;
if (!isLt2M) {
this.msg.error('Image must smaller than 2MB!');
}
return isJPG && isLt2M;
return new Observable((observer: Observer<boolean>) => {
const isJPG = file.type === 'image/jpeg';
if (!isJPG) {
this.msg.error('You can only upload JPG file!');
observer.complete();
return;
}
const isLt2M = file.size / 1024 / 1024 < 2;
if (!isLt2M) {
this.msg.error('Image must smaller than 2MB!');
observer.complete();
return;
}
// check height
this.checkImageDimension(file).then(dimensionRes => {
if (!dimensionRes) {
this.msg.error('Image only 300x300 above');
observer.complete();
return;
}

observer.next(isJPG && isLt2M && dimensionRes);
observer.complete();
});
});
}

private getBase64(img: File, callback: (img: string) => void): void {
Expand All @@ -59,6 +76,19 @@ export class NzDemoUploadAvatarComponent {
reader.readAsDataURL(img);
}

private checkImageDimension(file: File): Promise<boolean> {
return new Promise(resolve => {
const img = new Image(); // create image
img.src = window.URL.createObjectURL(file);
img.onload = () => {
const width = img.naturalWidth;
const height = img.naturalHeight;
window.URL.revokeObjectURL(img.src);
resolve(width === height && width >= 300);
};
});
}

handleChange(info: { file: UploadFile }): void {
if (info.file.status === 'uploading') {
this.loading = true;
Expand Down
13 changes: 12 additions & 1 deletion components/upload/demo/filter.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Component } from '@angular/core';
import { UploadFile, UploadFilter, NzMessageService } from 'ng-zorro-antd';
import { NzMessageService, UploadFile, UploadFilter } from 'ng-zorro-antd';
import { Observable, Observer } from 'rxjs';

@Component({
selector: 'nz-demo-upload-filter',
Expand Down Expand Up @@ -32,6 +33,16 @@ export class NzDemoUploadFilterComponent {
}
return fileList;
}
},
{
name: 'async',
fn: (fileList: UploadFile[]) => {
return new Observable((observer: Observer<UploadFile[]>) => {
// doing
observer.next(fileList);
observer.complete();
});
}
}
];

Expand Down
2 changes: 1 addition & 1 deletion components/upload/interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ export interface ZipButtonOptions {

export interface UploadFilter {
name: string;
fn: (fileList: UploadFile[]) => UploadFile[];
fn: (fileList: UploadFile[]) => UploadFile[] | Observable<UploadFile[]>;
}

export interface UploadXHRArgs {
Expand Down
24 changes: 18 additions & 6 deletions components/upload/nz-upload-btn.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ import {
ViewChild,
ViewEncapsulation
} from '@angular/core';
import { Observable, Subscription } from 'rxjs';
import { of, Observable, Subscription } from 'rxjs';
import { switchMap } from 'rxjs/operators';

import { NzUpdateHostClassService } from '../core/services/update-host-class.service';

Expand Down Expand Up @@ -143,11 +144,20 @@ export class NzUploadBtnComponent implements OnInit, OnChanges, OnDestroy {
}

uploadFiles(fileList: FileList | File[]): void {
let postFiles: UploadFile[] = Array.prototype.slice.call(fileList);
this.options.filters.forEach(f => postFiles = f.fn(postFiles));
postFiles.forEach((file: UploadFile) => {
this.attachUid(file);
this.upload(file, postFiles);
let filters$: Observable<UploadFile[]> = of(Array.prototype.slice.call(fileList));
this.options.filters.forEach(f => {
filters$ = filters$.pipe(switchMap(list => {
const fnRes = f.fn(list);
return fnRes instanceof Observable ? fnRes : of(fnRes);
}));
});
filters$.subscribe(list => {
list.forEach((file: UploadFile) => {
this.attachUid(file);
this.upload(file, list);
});
}, e => {
console.warn(`Unhandled upload filter error`, e);
});
}

Expand All @@ -165,6 +175,8 @@ export class NzUploadBtnComponent implements OnInit, OnChanges, OnDestroy {
} else if (typeof processedFile === 'boolean' && processedFile !== false) {
this.post(file);
}
}, e => {
console.warn(`Unhandled upload beforeUpload error`, e);
});
} else if (before !== false) {
return this.post(file);
Expand Down
62 changes: 61 additions & 1 deletion components/upload/upload.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { fakeAsync, tick, ComponentFixture, TestBed } from '@angular/core/testin
import { FormsModule } from '@angular/forms';
import { By } from '@angular/platform-browser';
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
import { of, Observable } from 'rxjs';
import { of, throwError, Observable, Observer } from 'rxjs';
import { delay } from 'rxjs/operators';

import { NzI18nModule, NzI18nService } from '../i18n';
Expand Down Expand Up @@ -332,6 +332,17 @@ describe('upload', () => {
pageObject.postSmall();
expect(instance._nzChange).toBeUndefined();
});
it('should be console.warn error', () => {
let warnMsg = '';
console.warn = jasmine.createSpy().and.callFake(res => warnMsg = res);
expect(instance._nzChange).toBeUndefined();
instance.beforeUpload = (file: UploadFile, fileList: UploadFile[]): Observable<any> => {
return throwError('');
};
fixture.detectChanges();
pageObject.postSmall();
expect(warnMsg).toContain(`Unhandled upload beforeUpload error`);
});
});
});

Expand Down Expand Up @@ -380,6 +391,55 @@ describe('upload', () => {
pageObject.postFile(JPGSMALL.target.files);
expect(instance._beforeUploadList.length).toBe(0);
});
describe('with Observable', () => {
it('shoule working', () => {
instance.nzFilter = [
{
name: 'f1',
fn: (fileList: UploadFile[]) => {
return new Observable((observer: Observer<UploadFile[]>) => {
observer.next(fileList.slice(1));
observer.complete();
});
}
},
{
name: 'f2',
fn: (fileList: UploadFile[]) => {
return new Observable((observer: Observer<UploadFile[]>) => {
observer.next(fileList.slice(1));
observer.complete();
});
}
}
];
fixture.detectChanges();
expect(instance._beforeUploadList.length).toBe(0);
pageObject.postFile([
...PNGSMALL.target.files,
...PNGSMALL.target.files,
...PNGSMALL.target.files
]);
expect(instance._beforeUploadList.length).toBe(1);
});
it('should be console.warn error', () => {
let warnMsg = '';
console.warn = jasmine.createSpy().and.callFake(res => warnMsg = res);
instance.nzFilter = [
{
name: 'f1',
fn: (fileList: UploadFile[]) => {
return new Observable((observer: Observer<UploadFile[]>) => {
observer.error('filter error');
});
}
}
];
fixture.detectChanges();
pageObject.postFile(PNGSMALL.target.files);
expect(warnMsg).toContain(`Unhandled upload filter error`);
});
});
});

it('#nzFileList, should be allow empty', () => {
Expand Down