@acpaas-ui/ngx-forms 6.1.10 → 6.1.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +27 -6
- package/.eslintrc.json +0 -42
- package/LICENSE.md +0 -21
- package/dist/README.md +0 -23
- package/dist/package.json +0 -44
- package/karma.conf.js +0 -38
- package/ng-package.json +0 -8
- package/src/lib/auto-complete/README.md +0 -148
- package/src/lib/auto-complete/auto-complete.module.ts +0 -15
- package/src/lib/auto-complete/components/auto-complete/auto-complete.component.html +0 -51
- package/src/lib/auto-complete/components/auto-complete/auto-complete.component.scss +0 -4
- package/src/lib/auto-complete/components/auto-complete/auto-complete.component.spec.ts +0 -378
- package/src/lib/auto-complete/components/auto-complete/auto-complete.component.ts +0 -281
- package/src/lib/auto-complete/public-api.ts +0 -2
- package/src/lib/datepicker/README.md +0 -110
- package/src/lib/datepicker/components/datepicker/datepicker.component.html +0 -47
- package/src/lib/datepicker/components/datepicker/datepicker.component.scss +0 -13
- package/src/lib/datepicker/components/datepicker/datepicker.component.spec.ts +0 -204
- package/src/lib/datepicker/components/datepicker/datepicker.component.ts +0 -251
- package/src/lib/datepicker/datepicker.conf.ts +0 -11
- package/src/lib/datepicker/datepicker.module.ts +0 -50
- package/src/lib/datepicker/public-api.ts +0 -8
- package/src/lib/datepicker/types/datepicker.types.ts +0 -8
- package/src/lib/range-slider/README.md +0 -56
- package/src/lib/range-slider/components/range-slider/range-slider.component.html +0 -46
- package/src/lib/range-slider/components/range-slider/range-slider.component.scss +0 -12
- package/src/lib/range-slider/components/range-slider/range-slider.component.spec.ts +0 -216
- package/src/lib/range-slider/components/range-slider/range-slider.component.ts +0 -301
- package/src/lib/range-slider/public-api.ts +0 -3
- package/src/lib/range-slider/range-slider.module.ts +0 -11
- package/src/lib/range-slider/types/range-slider.types.ts +0 -4
- package/src/lib/search-filter/README.md +0 -86
- package/src/lib/search-filter/components/search-filter/search-filter.component.html +0 -66
- package/src/lib/search-filter/components/search-filter/search-filter.component.scss +0 -23
- package/src/lib/search-filter/components/search-filter/search-filter.component.spec.ts +0 -264
- package/src/lib/search-filter/components/search-filter/search-filter.component.ts +0 -140
- package/src/lib/search-filter/public-api.ts +0 -3
- package/src/lib/search-filter/search-filter.module.ts +0 -13
- package/src/lib/search-filter/types/search-filter.types.ts +0 -4
- package/src/lib/shared/services/search.service.spec.ts +0 -78
- package/src/lib/shared/services/search.service.ts +0 -32
- package/src/lib/shared/types/search.types.ts +0 -6
- package/src/lib/timepicker/README.md +0 -84
- package/src/lib/timepicker/classes/timepicker.validators.spec.ts +0 -54
- package/src/lib/timepicker/classes/timepicker.validators.ts +0 -61
- package/src/lib/timepicker/components/timepicker/timepicker.component.html +0 -37
- package/src/lib/timepicker/components/timepicker/timepicker.component.scss +0 -3
- package/src/lib/timepicker/components/timepicker/timepicker.component.spec.ts +0 -161
- package/src/lib/timepicker/components/timepicker/timepicker.component.ts +0 -128
- package/src/lib/timepicker/public-api.ts +0 -4
- package/src/lib/timepicker/timepicker.module.ts +0 -13
- package/src/lib/timepicker/types/timepicker.types.ts +0 -5
- package/src/lib/upload/README.md +0 -283
- package/src/lib/upload/classes/uploader.class.spec.ts +0 -100
- package/src/lib/upload/classes/uploader.class.ts +0 -144
- package/src/lib/upload/components/upload/upload.component.html +0 -28
- package/src/lib/upload/components/upload/upload.component.scss +0 -3
- package/src/lib/upload/components/upload/upload.component.spec.ts +0 -117
- package/src/lib/upload/components/upload/upload.component.ts +0 -50
- package/src/lib/upload/components/upload-input/upload-input.component.html +0 -11
- package/src/lib/upload/components/upload-input/upload-input.component.spec.ts +0 -55
- package/src/lib/upload/components/upload-input/upload-input.component.ts +0 -35
- package/src/lib/upload/components/upload-queue/upload-queue.component.html +0 -16
- package/src/lib/upload/components/upload-queue/upload-queue.component.spec.ts +0 -99
- package/src/lib/upload/components/upload-queue/upload-queue.component.ts +0 -36
- package/src/lib/upload/components/upload-zone/upload-zone.component.html +0 -55
- package/src/lib/upload/components/upload-zone/upload-zone.component.scss +0 -3
- package/src/lib/upload/components/upload-zone/upload-zone.component.spec.ts +0 -144
- package/src/lib/upload/components/upload-zone/upload-zone.component.ts +0 -142
- package/src/lib/upload/components/validation-list/validation-list.component.html +0 -15
- package/src/lib/upload/components/validation-list/validation-list.component.spec.ts +0 -57
- package/src/lib/upload/components/validation-list/validation-list.component.ts +0 -29
- package/src/lib/upload/public-api.ts +0 -10
- package/src/lib/upload/services/validation-messages.service.spec.ts +0 -66
- package/src/lib/upload/services/validation-messages.service.ts +0 -27
- package/src/lib/upload/types/upload.types.ts +0 -20
- package/src/lib/upload/upload.conf.ts +0 -15
- package/src/lib/upload/upload.module.ts +0 -34
- package/src/public-api.ts +0 -6
- package/src/test.ts +0 -9
- package/tsconfig.lib.json +0 -26
- package/tsconfig.spec.json +0 -17
- /package/{dist/esm2020 → esm2020}/acpaas-ui-ngx-forms.mjs +0 -0
- /package/{dist/esm2020 → esm2020}/lib/auto-complete/auto-complete.module.mjs +0 -0
- /package/{dist/esm2020 → esm2020}/lib/auto-complete/components/auto-complete/auto-complete.component.mjs +0 -0
- /package/{dist/esm2020 → esm2020}/lib/auto-complete/public-api.mjs +0 -0
- /package/{dist/esm2020 → esm2020}/lib/datepicker/components/datepicker/datepicker.component.mjs +0 -0
- /package/{dist/esm2020 → esm2020}/lib/datepicker/datepicker.conf.mjs +0 -0
- /package/{dist/esm2020 → esm2020}/lib/datepicker/datepicker.module.mjs +0 -0
- /package/{dist/esm2020 → esm2020}/lib/datepicker/public-api.mjs +0 -0
- /package/{dist/esm2020 → esm2020}/lib/datepicker/types/datepicker.types.mjs +0 -0
- /package/{dist/esm2020 → esm2020}/lib/range-slider/components/range-slider/range-slider.component.mjs +0 -0
- /package/{dist/esm2020 → esm2020}/lib/range-slider/public-api.mjs +0 -0
- /package/{dist/esm2020 → esm2020}/lib/range-slider/range-slider.module.mjs +0 -0
- /package/{dist/esm2020 → esm2020}/lib/range-slider/types/range-slider.types.mjs +0 -0
- /package/{dist/esm2020 → esm2020}/lib/search-filter/components/search-filter/search-filter.component.mjs +0 -0
- /package/{dist/esm2020 → esm2020}/lib/search-filter/public-api.mjs +0 -0
- /package/{dist/esm2020 → esm2020}/lib/search-filter/search-filter.module.mjs +0 -0
- /package/{dist/esm2020 → esm2020}/lib/search-filter/types/search-filter.types.mjs +0 -0
- /package/{dist/esm2020 → esm2020}/lib/shared/services/search.service.mjs +0 -0
- /package/{dist/esm2020 → esm2020}/lib/shared/types/search.types.mjs +0 -0
- /package/{dist/esm2020 → esm2020}/lib/timepicker/classes/timepicker.validators.mjs +0 -0
- /package/{dist/esm2020 → esm2020}/lib/timepicker/components/timepicker/timepicker.component.mjs +0 -0
- /package/{dist/esm2020 → esm2020}/lib/timepicker/public-api.mjs +0 -0
- /package/{dist/esm2020 → esm2020}/lib/timepicker/timepicker.module.mjs +0 -0
- /package/{dist/esm2020 → esm2020}/lib/timepicker/types/timepicker.types.mjs +0 -0
- /package/{dist/esm2020 → esm2020}/lib/upload/classes/uploader.class.mjs +0 -0
- /package/{dist/esm2020 → esm2020}/lib/upload/components/upload/upload.component.mjs +0 -0
- /package/{dist/esm2020 → esm2020}/lib/upload/components/upload-input/upload-input.component.mjs +0 -0
- /package/{dist/esm2020 → esm2020}/lib/upload/components/upload-queue/upload-queue.component.mjs +0 -0
- /package/{dist/esm2020 → esm2020}/lib/upload/components/upload-zone/upload-zone.component.mjs +0 -0
- /package/{dist/esm2020 → esm2020}/lib/upload/components/validation-list/validation-list.component.mjs +0 -0
- /package/{dist/esm2020 → esm2020}/lib/upload/public-api.mjs +0 -0
- /package/{dist/esm2020 → esm2020}/lib/upload/services/validation-messages.service.mjs +0 -0
- /package/{dist/esm2020 → esm2020}/lib/upload/types/upload.types.mjs +0 -0
- /package/{dist/esm2020 → esm2020}/lib/upload/upload.conf.mjs +0 -0
- /package/{dist/esm2020 → esm2020}/lib/upload/upload.module.mjs +0 -0
- /package/{dist/esm2020 → esm2020}/public-api.mjs +0 -0
- /package/{dist/fesm2015 → fesm2015}/acpaas-ui-ngx-forms.mjs +0 -0
- /package/{dist/fesm2015 → fesm2015}/acpaas-ui-ngx-forms.mjs.map +0 -0
- /package/{dist/fesm2020 → fesm2020}/acpaas-ui-ngx-forms.mjs +0 -0
- /package/{dist/fesm2020 → fesm2020}/acpaas-ui-ngx-forms.mjs.map +0 -0
- /package/{dist/index.d.ts → index.d.ts} +0 -0
- /package/{dist/lib → lib}/auto-complete/auto-complete.module.d.ts +0 -0
- /package/{dist/lib → lib}/auto-complete/components/auto-complete/auto-complete.component.d.ts +0 -0
- /package/{dist/lib → lib}/auto-complete/public-api.d.ts +0 -0
- /package/{dist/lib → lib}/datepicker/components/datepicker/datepicker.component.d.ts +0 -0
- /package/{dist/lib → lib}/datepicker/datepicker.conf.d.ts +0 -0
- /package/{dist/lib → lib}/datepicker/datepicker.module.d.ts +0 -0
- /package/{dist/lib → lib}/datepicker/public-api.d.ts +0 -0
- /package/{dist/lib → lib}/datepicker/types/datepicker.types.d.ts +0 -0
- /package/{dist/lib → lib}/range-slider/components/range-slider/range-slider.component.d.ts +0 -0
- /package/{dist/lib → lib}/range-slider/public-api.d.ts +0 -0
- /package/{dist/lib → lib}/range-slider/range-slider.module.d.ts +0 -0
- /package/{dist/lib → lib}/range-slider/types/range-slider.types.d.ts +0 -0
- /package/{dist/lib → lib}/search-filter/components/search-filter/search-filter.component.d.ts +0 -0
- /package/{dist/lib → lib}/search-filter/public-api.d.ts +0 -0
- /package/{dist/lib → lib}/search-filter/search-filter.module.d.ts +0 -0
- /package/{dist/lib → lib}/search-filter/types/search-filter.types.d.ts +0 -0
- /package/{dist/lib → lib}/shared/services/search.service.d.ts +0 -0
- /package/{dist/lib → lib}/shared/types/search.types.d.ts +0 -0
- /package/{dist/lib → lib}/timepicker/classes/timepicker.validators.d.ts +0 -0
- /package/{dist/lib → lib}/timepicker/components/timepicker/timepicker.component.d.ts +0 -0
- /package/{dist/lib → lib}/timepicker/public-api.d.ts +0 -0
- /package/{dist/lib → lib}/timepicker/timepicker.module.d.ts +0 -0
- /package/{dist/lib → lib}/timepicker/types/timepicker.types.d.ts +0 -0
- /package/{dist/lib → lib}/upload/classes/uploader.class.d.ts +0 -0
- /package/{dist/lib → lib}/upload/components/upload/upload.component.d.ts +0 -0
- /package/{dist/lib → lib}/upload/components/upload-input/upload-input.component.d.ts +0 -0
- /package/{dist/lib → lib}/upload/components/upload-queue/upload-queue.component.d.ts +0 -0
- /package/{dist/lib → lib}/upload/components/upload-zone/upload-zone.component.d.ts +0 -0
- /package/{dist/lib → lib}/upload/components/validation-list/validation-list.component.d.ts +0 -0
- /package/{dist/lib → lib}/upload/public-api.d.ts +0 -0
- /package/{dist/lib → lib}/upload/services/validation-messages.service.d.ts +0 -0
- /package/{dist/lib → lib}/upload/types/upload.types.d.ts +0 -0
- /package/{dist/lib → lib}/upload/upload.conf.d.ts +0 -0
- /package/{dist/lib → lib}/upload/upload.module.d.ts +0 -0
- /package/{dist/public-api.d.ts → public-api.d.ts} +0 -0
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
|
|
2
|
-
|
|
3
|
-
import { InvalidFile, UploadOptions } from '../../types/upload.types';
|
|
4
|
-
import { UPLOAD_OPTIONS_DEFAULT } from '../../upload.conf';
|
|
5
|
-
import { Uploader } from '../../classes/uploader.class';
|
|
6
|
-
|
|
7
|
-
@Component({
|
|
8
|
-
selector: 'aui-upload',
|
|
9
|
-
styleUrls: ['./upload.component.scss'],
|
|
10
|
-
templateUrl: './upload.component.html',
|
|
11
|
-
})
|
|
12
|
-
export class UploadComponent implements OnInit {
|
|
13
|
-
@Input() public id = '';
|
|
14
|
-
@Input() public accept = [];
|
|
15
|
-
@Input() public capture = '';
|
|
16
|
-
@Input() public ariaLabelRemove = 'Verwijder';
|
|
17
|
-
@Input() public disabled = false;
|
|
18
|
-
@Input() public multiple = true;
|
|
19
|
-
@Input() public label = '';
|
|
20
|
-
@Input() public description = '';
|
|
21
|
-
@Input() public options: UploadOptions = UPLOAD_OPTIONS_DEFAULT;
|
|
22
|
-
@Output() public selectUploadedFiles: EventEmitter<object[]> = new EventEmitter<object[]>();
|
|
23
|
-
|
|
24
|
-
public uploader;
|
|
25
|
-
public ariaId;
|
|
26
|
-
public uploadedFiles: object[] = [];
|
|
27
|
-
public invalidFiles: InvalidFile[] = [];
|
|
28
|
-
public queuedFiles: File[] = [];
|
|
29
|
-
|
|
30
|
-
public ngOnInit() {
|
|
31
|
-
if (!this.id) {
|
|
32
|
-
this.ariaId = 'aui-upload-' + Math.random().toString(36).substring(2);
|
|
33
|
-
this.id = this.ariaId;
|
|
34
|
-
}
|
|
35
|
-
this.uploader = new Uploader(this.options);
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
public onUploadedFiles(files: object[]) {
|
|
39
|
-
this.uploadedFiles = this.uploadedFiles.concat(files);
|
|
40
|
-
this.selectUploadedFiles.emit(this.uploadedFiles);
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
public onInvalidFiles(files: InvalidFile[]) {
|
|
44
|
-
this.invalidFiles = files;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
public onQueuedFiles(files: File[]) {
|
|
48
|
-
this.queuedFiles = this.queuedFiles.concat(files);
|
|
49
|
-
}
|
|
50
|
-
}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
<aui-upload (selectUploadedFiles)="onUpload($event)" [options]="options">
|
|
2
|
-
<div class="m-upload__message">
|
|
3
|
-
<ng-content select=".m-upload__message"></ng-content>
|
|
4
|
-
</div>
|
|
5
|
-
<div class="m-upload__description">
|
|
6
|
-
<ng-content select=".m-upload__description"></ng-content>
|
|
7
|
-
</div>
|
|
8
|
-
<div class="m-upload__button">
|
|
9
|
-
<ng-content select=".m-upload__button"></ng-content>
|
|
10
|
-
</div>
|
|
11
|
-
</aui-upload>
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing';
|
|
2
|
-
import { Component, Input } from '@angular/core';
|
|
3
|
-
|
|
4
|
-
import { UploadInputComponent } from './upload-input.component';
|
|
5
|
-
|
|
6
|
-
@Component({
|
|
7
|
-
template: '<div>Upload</div>',
|
|
8
|
-
selector: 'aui-upload',
|
|
9
|
-
})
|
|
10
|
-
class MockUploadComponent {
|
|
11
|
-
@Input() public options;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
describe('The upload zone component', () => {
|
|
15
|
-
let comp: UploadInputComponent;
|
|
16
|
-
let fixture: ComponentFixture<UploadInputComponent>;
|
|
17
|
-
|
|
18
|
-
// waitForAsync beforeEach
|
|
19
|
-
beforeEach(waitForAsync(() => {
|
|
20
|
-
TestBed.configureTestingModule({
|
|
21
|
-
declarations: [UploadInputComponent, MockUploadComponent],
|
|
22
|
-
}).compileComponents(); // compile template and css
|
|
23
|
-
}));
|
|
24
|
-
|
|
25
|
-
// synchronous beforeEach
|
|
26
|
-
beforeEach(() => {
|
|
27
|
-
fixture = TestBed.createComponent(UploadInputComponent);
|
|
28
|
-
comp = fixture.componentInstance;
|
|
29
|
-
});
|
|
30
|
-
|
|
31
|
-
it('Should format data', () => {
|
|
32
|
-
const data = [
|
|
33
|
-
{
|
|
34
|
-
name: 'Test image',
|
|
35
|
-
url: 'http://test.com/image.jpg',
|
|
36
|
-
},
|
|
37
|
-
{
|
|
38
|
-
name: 'Test image 2',
|
|
39
|
-
url: 'http://test.com/image2.jpg',
|
|
40
|
-
},
|
|
41
|
-
];
|
|
42
|
-
comp.format = (d) => {
|
|
43
|
-
return d.map((o) => {
|
|
44
|
-
return o.name;
|
|
45
|
-
});
|
|
46
|
-
};
|
|
47
|
-
fixture.detectChanges();
|
|
48
|
-
spyOn(comp, 'propagateChange');
|
|
49
|
-
comp.onUpload(data);
|
|
50
|
-
expect(comp.propagateChange).toHaveBeenCalledWith([
|
|
51
|
-
'Test image',
|
|
52
|
-
'Test image 2',
|
|
53
|
-
]);
|
|
54
|
-
});
|
|
55
|
-
});
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import { Component, Input } from '@angular/core';
|
|
2
|
-
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
|
|
3
|
-
|
|
4
|
-
import { UploadOptions } from '../../types/upload.types';
|
|
5
|
-
|
|
6
|
-
@Component({
|
|
7
|
-
selector: 'aui-upload-input',
|
|
8
|
-
templateUrl: './upload-input.component.html',
|
|
9
|
-
providers: [{
|
|
10
|
-
provide: NG_VALUE_ACCESSOR,
|
|
11
|
-
useExisting: UploadInputComponent,
|
|
12
|
-
multi: true,
|
|
13
|
-
}],
|
|
14
|
-
})
|
|
15
|
-
export class UploadInputComponent implements ControlValueAccessor {
|
|
16
|
-
@Input() public options: UploadOptions;
|
|
17
|
-
@Input() public format: any;
|
|
18
|
-
|
|
19
|
-
public propagateChange = (_: any) => undefined;
|
|
20
|
-
|
|
21
|
-
public writeValue(value: any) {
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
public registerOnChange(fn) {
|
|
25
|
-
this.propagateChange = fn;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
registerOnTouched() {
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
public onUpload(files) {
|
|
32
|
-
const data = (this.format ? this.format(files) : files);
|
|
33
|
-
this.propagateChange(data);
|
|
34
|
-
}
|
|
35
|
-
}
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
<ul class="m-upload__files u-margin-bottom-xs">
|
|
2
|
-
<li *ngFor="let file of files; let i = index">
|
|
3
|
-
<aui-icon name="ai-common-file-empty"></aui-icon>
|
|
4
|
-
<span class="m-upload__filename">{{ file.name }}</span>
|
|
5
|
-
|
|
6
|
-
<button
|
|
7
|
-
(click)="remove(i)"
|
|
8
|
-
class="m-upload__delete a-button a-button--text a-button--neutral a-button--s has-icon"
|
|
9
|
-
type="button"
|
|
10
|
-
>
|
|
11
|
-
<aui-icon name="ai-close" [ariaLabel]="ariaLabelRemove"></aui-icon>
|
|
12
|
-
</button>
|
|
13
|
-
</li>
|
|
14
|
-
</ul>
|
|
15
|
-
|
|
16
|
-
<button (click)="uploadFiles()" *ngIf="files.length > 0" class="a-button" type="button">Upload</button>
|
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing';
|
|
2
|
-
import { DebugElement } from '@angular/core';
|
|
3
|
-
import { By } from '@angular/platform-browser';
|
|
4
|
-
import { Observable } from 'rxjs';
|
|
5
|
-
import { IconModule } from '@acpaas-ui/ngx-icon';
|
|
6
|
-
|
|
7
|
-
import { UPLOAD_OPTIONS_DEFAULT } from '../../upload.conf';
|
|
8
|
-
import { Uploader } from '../../classes/uploader.class';
|
|
9
|
-
|
|
10
|
-
import { UploadQueueComponent } from './upload-queue.component';
|
|
11
|
-
|
|
12
|
-
const mockFile1 = new File(['file1'], 'filename1.txt', {
|
|
13
|
-
type: 'text/plain',
|
|
14
|
-
lastModified: new Date().getTime(),
|
|
15
|
-
});
|
|
16
|
-
const mockFile2 = new File(['file2'], 'filename2.txt', {
|
|
17
|
-
type: 'text/plain',
|
|
18
|
-
lastModified: new Date().getTime(),
|
|
19
|
-
});
|
|
20
|
-
const mockFileList = [mockFile1, mockFile2];
|
|
21
|
-
|
|
22
|
-
class MockUploader implements Partial<Uploader> {
|
|
23
|
-
public options = UPLOAD_OPTIONS_DEFAULT;
|
|
24
|
-
|
|
25
|
-
constructor(options = {}) {
|
|
26
|
-
this.options = Object.assign({}, this.options, options);
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
public validateFiles(files) {
|
|
30
|
-
return {
|
|
31
|
-
validFiles: mockFileList,
|
|
32
|
-
invalidFiles: [],
|
|
33
|
-
};
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
public uploadFiles(files): Observable<{ progress: number; data: object[] }> {
|
|
37
|
-
return new Observable((observer) => {
|
|
38
|
-
observer.next({
|
|
39
|
-
progress: 0.5,
|
|
40
|
-
data: null,
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
setTimeout(() => {
|
|
44
|
-
observer.next({
|
|
45
|
-
progress: 1,
|
|
46
|
-
data: {
|
|
47
|
-
test: 'ok',
|
|
48
|
-
} as any,
|
|
49
|
-
});
|
|
50
|
-
}, 500);
|
|
51
|
-
});
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
describe('The upload queue component', () => {
|
|
56
|
-
let comp: UploadQueueComponent;
|
|
57
|
-
let fixture: ComponentFixture<UploadQueueComponent>;
|
|
58
|
-
let de: DebugElement;
|
|
59
|
-
const el: HTMLElement = undefined;
|
|
60
|
-
|
|
61
|
-
// waitForAsync beforeEach
|
|
62
|
-
beforeEach(waitForAsync(() => {
|
|
63
|
-
TestBed.configureTestingModule({
|
|
64
|
-
declarations: [UploadQueueComponent],
|
|
65
|
-
imports: [IconModule],
|
|
66
|
-
}).compileComponents(); // compile template and css
|
|
67
|
-
}));
|
|
68
|
-
|
|
69
|
-
// synchronous beforeEach
|
|
70
|
-
beforeEach(() => {
|
|
71
|
-
fixture = TestBed.createComponent(UploadQueueComponent);
|
|
72
|
-
comp = fixture.componentInstance;
|
|
73
|
-
de = fixture.debugElement.query(By.css('.m-upload__files')); // find hero element
|
|
74
|
-
|
|
75
|
-
comp.uploader = new MockUploader() as any;
|
|
76
|
-
comp.files = mockFileList;
|
|
77
|
-
fixture.detectChanges(); // trigger initial data binding
|
|
78
|
-
});
|
|
79
|
-
|
|
80
|
-
it('Should upload file', async () => {
|
|
81
|
-
comp.uploadFiles();
|
|
82
|
-
spyOn(comp.uploadedFiles, 'emit');
|
|
83
|
-
|
|
84
|
-
fixture.detectChanges(); // trigger initial data binding
|
|
85
|
-
|
|
86
|
-
expect(comp.uploadProgress).toEqual(50);
|
|
87
|
-
|
|
88
|
-
setTimeout(() => {
|
|
89
|
-
expect(comp.uploadProgress).toEqual(100);
|
|
90
|
-
expect(comp.uploadedFiles.emit).toHaveBeenCalled();
|
|
91
|
-
}, 600);
|
|
92
|
-
});
|
|
93
|
-
|
|
94
|
-
it('should remove a file', () => {
|
|
95
|
-
expect(comp.files.length).toEqual(2);
|
|
96
|
-
comp.remove(1);
|
|
97
|
-
expect(comp.files.length).toEqual(1);
|
|
98
|
-
});
|
|
99
|
-
});
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
import { Component, EventEmitter, Input, Output } from '@angular/core';
|
|
2
|
-
|
|
3
|
-
import { Uploader } from '../../classes/uploader.class';
|
|
4
|
-
|
|
5
|
-
@Component({
|
|
6
|
-
selector: 'aui-upload-queue',
|
|
7
|
-
templateUrl: './upload-queue.component.html',
|
|
8
|
-
})
|
|
9
|
-
export class UploadQueueComponent {
|
|
10
|
-
@Input() public files: File[];
|
|
11
|
-
@Input() public uploader: Uploader;
|
|
12
|
-
@Input() public ariaLabelRemove = 'Verwijder';
|
|
13
|
-
@Output() public uploadedFiles: EventEmitter<object[]> = new EventEmitter<object[]>();
|
|
14
|
-
|
|
15
|
-
public uploadProgress = 0;
|
|
16
|
-
|
|
17
|
-
public remove(index) {
|
|
18
|
-
this.files.splice(index, 1);
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
public uploadFiles() {
|
|
22
|
-
const progress = undefined;
|
|
23
|
-
const data = undefined;
|
|
24
|
-
this.uploader.uploadFiles(this.files).subscribe(
|
|
25
|
-
(response) => {
|
|
26
|
-
if (response.progress) {
|
|
27
|
-
this.uploadProgress = Math.floor(response.progress * 100);
|
|
28
|
-
}
|
|
29
|
-
if (response.data) {
|
|
30
|
-
this.uploadedFiles.emit(response.data);
|
|
31
|
-
this.files = [];
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
);
|
|
35
|
-
}
|
|
36
|
-
}
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
<div *ngIf="uploader.options.type === 'drop'" [class.is-disabled]="disabled" class="m-upload">
|
|
2
|
-
<div class="m-upload__inner">
|
|
3
|
-
<div class="m-upload__dropzone">
|
|
4
|
-
<input
|
|
5
|
-
#fileInput
|
|
6
|
-
type="file"
|
|
7
|
-
class="m-upload__input"
|
|
8
|
-
[id]="id"
|
|
9
|
-
[attr.aria-labelledby]="ariaId"
|
|
10
|
-
(click)="onFileClick($event)"
|
|
11
|
-
(change)="updateFiles()"
|
|
12
|
-
/>
|
|
13
|
-
|
|
14
|
-
<div *ngIf="!uploadProgress || uploadProgress === 0" class="m-upload__content">
|
|
15
|
-
<label [for]="ariaId" class="m-upload__message">
|
|
16
|
-
{{ label }}
|
|
17
|
-
</label>
|
|
18
|
-
<p class="m-upload__uploads u-text-bold">{{ uploadedFilesString }}</p>
|
|
19
|
-
</div>
|
|
20
|
-
|
|
21
|
-
<ng-container *ngIf="uploadProgress > 0">
|
|
22
|
-
<p class="m-upload__uploads u-text-bold u-margin-bottom-xs">
|
|
23
|
-
<ng-container *ngFor="let file of uploadingFiles; let last = last">
|
|
24
|
-
{{ file.name }}
|
|
25
|
-
<ng-container *ngIf="!last">,</ng-container>
|
|
26
|
-
</ng-container>
|
|
27
|
-
</p>
|
|
28
|
-
<aui-progress-bar [value]="uploadProgress" max="100"></aui-progress-bar>
|
|
29
|
-
</ng-container>
|
|
30
|
-
</div>
|
|
31
|
-
</div>
|
|
32
|
-
|
|
33
|
-
<small class="m-upload__description">
|
|
34
|
-
{{ description }}
|
|
35
|
-
</small>
|
|
36
|
-
</div>
|
|
37
|
-
|
|
38
|
-
<button
|
|
39
|
-
(click)="triggerFile()"
|
|
40
|
-
*ngIf="uploader.options.type === 'button'"
|
|
41
|
-
[disabled]="disabled"
|
|
42
|
-
class="a-button m-upload__button"
|
|
43
|
-
type="button"
|
|
44
|
-
>
|
|
45
|
-
<span [id]="ariaId"><ng-content select=".m-upload__button"></ng-content></span>
|
|
46
|
-
<input
|
|
47
|
-
#fileInput
|
|
48
|
-
type="file"
|
|
49
|
-
class="m-upload__input"
|
|
50
|
-
[id]="id"
|
|
51
|
-
[attr.aria-labelledby]="ariaId"
|
|
52
|
-
(click)="onFileClick($event)"
|
|
53
|
-
(change)="updateFiles()"
|
|
54
|
-
/>
|
|
55
|
-
</button>
|
|
@@ -1,144 +0,0 @@
|
|
|
1
|
-
import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing';
|
|
2
|
-
import { Component, DebugElement, Input } from '@angular/core';
|
|
3
|
-
import { By } from '@angular/platform-browser';
|
|
4
|
-
import { Observable } from 'rxjs';
|
|
5
|
-
|
|
6
|
-
import { UploadZoneComponent } from './upload-zone.component';
|
|
7
|
-
import { UPLOAD_OPTIONS_DEFAULT } from '../../upload.conf';
|
|
8
|
-
import { Uploader } from '../../classes/uploader.class';
|
|
9
|
-
|
|
10
|
-
@Component({
|
|
11
|
-
template: '<progress></progress>',
|
|
12
|
-
selector: 'aui-progress-bar',
|
|
13
|
-
})
|
|
14
|
-
class ProgressBarComponent {
|
|
15
|
-
@Input() public value;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
const mockFile1 = new File(['file1'], 'filename1.txt', {
|
|
19
|
-
type: 'text/plain',
|
|
20
|
-
lastModified: new Date().getTime(),
|
|
21
|
-
});
|
|
22
|
-
const mockFile2 = new File(['file2'], 'filename2.txt', {
|
|
23
|
-
type: 'text/plain',
|
|
24
|
-
lastModified: new Date().getTime(),
|
|
25
|
-
});
|
|
26
|
-
const mockFileList = [mockFile1, mockFile2];
|
|
27
|
-
|
|
28
|
-
class MockUploader implements Partial<Uploader> {
|
|
29
|
-
public options = UPLOAD_OPTIONS_DEFAULT;
|
|
30
|
-
|
|
31
|
-
constructor(options = {}) {
|
|
32
|
-
this.options = Object.assign({}, this.options, options);
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
public validateFiles(files) {
|
|
36
|
-
return {
|
|
37
|
-
validFiles: mockFileList,
|
|
38
|
-
invalidFiles: [],
|
|
39
|
-
};
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
public uploadFiles(files): any {
|
|
43
|
-
return new Observable((observer) => {
|
|
44
|
-
observer.next({
|
|
45
|
-
progress: 0.5,
|
|
46
|
-
data: null,
|
|
47
|
-
});
|
|
48
|
-
|
|
49
|
-
setTimeout(() => {
|
|
50
|
-
observer.next({
|
|
51
|
-
progress: 1,
|
|
52
|
-
data: {
|
|
53
|
-
test: 'ok',
|
|
54
|
-
},
|
|
55
|
-
});
|
|
56
|
-
}, 500);
|
|
57
|
-
});
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
const mockDragEvent = {
|
|
62
|
-
preventDefault: () => {},
|
|
63
|
-
stopPropagation: () => {},
|
|
64
|
-
};
|
|
65
|
-
|
|
66
|
-
const mockDropEvent = {
|
|
67
|
-
preventDefault: () => {},
|
|
68
|
-
stopPropagation: () => {},
|
|
69
|
-
dataTransfer: {
|
|
70
|
-
files: [mockFile1],
|
|
71
|
-
},
|
|
72
|
-
};
|
|
73
|
-
|
|
74
|
-
describe('The upload zone component', () => {
|
|
75
|
-
let comp: UploadZoneComponent;
|
|
76
|
-
let fixture: ComponentFixture<UploadZoneComponent>;
|
|
77
|
-
let de: DebugElement;
|
|
78
|
-
const el: HTMLElement = undefined;
|
|
79
|
-
|
|
80
|
-
// waitForAsync beforeEach
|
|
81
|
-
beforeEach(waitForAsync(() => {
|
|
82
|
-
TestBed.configureTestingModule({
|
|
83
|
-
declarations: [UploadZoneComponent, ProgressBarComponent],
|
|
84
|
-
}).compileComponents(); // compile template and css
|
|
85
|
-
}));
|
|
86
|
-
|
|
87
|
-
// synchronous beforeEach
|
|
88
|
-
beforeEach(() => {
|
|
89
|
-
fixture = TestBed.createComponent(UploadZoneComponent);
|
|
90
|
-
comp = fixture.componentInstance;
|
|
91
|
-
de = fixture.debugElement.query(By.css('.m-upload__dropzone')); // find hero element
|
|
92
|
-
});
|
|
93
|
-
|
|
94
|
-
it('Should have options', () => {
|
|
95
|
-
comp.uploader = new MockUploader() as any;
|
|
96
|
-
fixture.detectChanges(); // trigger initial data binding
|
|
97
|
-
|
|
98
|
-
expect(comp.uploader.options).toEqual(UPLOAD_OPTIONS_DEFAULT);
|
|
99
|
-
});
|
|
100
|
-
|
|
101
|
-
it('Should trigger dragover', () => {
|
|
102
|
-
comp.uploader = new MockUploader() as any;
|
|
103
|
-
fixture.detectChanges(); // trigger initial data binding
|
|
104
|
-
|
|
105
|
-
fixture.debugElement.triggerEventHandler('dragover', mockDragEvent);
|
|
106
|
-
expect(comp.hasDragOver).toBeTruthy();
|
|
107
|
-
});
|
|
108
|
-
|
|
109
|
-
it('Should trigger dragleave', () => {
|
|
110
|
-
comp.uploader = new MockUploader() as any;
|
|
111
|
-
fixture.detectChanges(); // trigger initial data binding
|
|
112
|
-
|
|
113
|
-
fixture.debugElement.triggerEventHandler('dragleave', mockDragEvent);
|
|
114
|
-
expect(comp.hasDragOver).toBeFalsy();
|
|
115
|
-
});
|
|
116
|
-
|
|
117
|
-
it('Should trigger drop and queue files', () => {
|
|
118
|
-
comp.uploader = new MockUploader() as any;
|
|
119
|
-
fixture.detectChanges(); // trigger initial data binding
|
|
120
|
-
|
|
121
|
-
spyOn(comp.queuedFiles, 'emit');
|
|
122
|
-
fixture.debugElement.triggerEventHandler('drop', mockDropEvent);
|
|
123
|
-
expect(comp.hasDragOver).toBeFalsy();
|
|
124
|
-
expect(comp.queuedFiles.emit).toHaveBeenCalled();
|
|
125
|
-
});
|
|
126
|
-
|
|
127
|
-
it('Should trigger click', () => {
|
|
128
|
-
comp.uploader = new MockUploader() as any;
|
|
129
|
-
fixture.detectChanges(); // trigger initial data binding
|
|
130
|
-
|
|
131
|
-
spyOn(comp.fileInput.nativeElement, 'click');
|
|
132
|
-
comp.triggerFile();
|
|
133
|
-
expect(comp.fileInput.nativeElement.click).toHaveBeenCalled();
|
|
134
|
-
});
|
|
135
|
-
|
|
136
|
-
it('Should display a button zone', () => {
|
|
137
|
-
comp.uploader = new MockUploader({ type: 'button' }) as any;
|
|
138
|
-
fixture.detectChanges(); // trigger initial data binding
|
|
139
|
-
|
|
140
|
-
const btn = fixture.debugElement.query(By.css('.a-button'));
|
|
141
|
-
|
|
142
|
-
expect(btn.nativeElement).not.toBeUndefined();
|
|
143
|
-
});
|
|
144
|
-
});
|
|
@@ -1,142 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
AfterViewInit,
|
|
3
|
-
Component,
|
|
4
|
-
ElementRef,
|
|
5
|
-
EventEmitter,
|
|
6
|
-
HostListener,
|
|
7
|
-
Input,
|
|
8
|
-
Output,
|
|
9
|
-
Renderer2,
|
|
10
|
-
ViewChild,
|
|
11
|
-
} from '@angular/core';
|
|
12
|
-
|
|
13
|
-
import { InvalidFile } from '../../types/upload.types';
|
|
14
|
-
import { Uploader } from '../../classes/uploader.class';
|
|
15
|
-
|
|
16
|
-
@Component({
|
|
17
|
-
selector: 'aui-upload-zone',
|
|
18
|
-
styleUrls: ['./upload-zone.component.scss'],
|
|
19
|
-
templateUrl: './upload-zone.component.html',
|
|
20
|
-
})
|
|
21
|
-
export class UploadZoneComponent implements AfterViewInit {
|
|
22
|
-
@ViewChild('fileInput', { static: false }) fileInput: ElementRef;
|
|
23
|
-
|
|
24
|
-
@Input() public uploader: Uploader;
|
|
25
|
-
@Input() public id = '';
|
|
26
|
-
@Input() public accept = [];
|
|
27
|
-
@Input() public capture = '';
|
|
28
|
-
@Input() public ariaId = '';
|
|
29
|
-
@Input() public disabled = false;
|
|
30
|
-
@Input() public multiple = true;
|
|
31
|
-
@Input() public label = '';
|
|
32
|
-
@Input() public description = '';
|
|
33
|
-
|
|
34
|
-
@Output() public uploadedFiles: EventEmitter<object[]> = new EventEmitter<object[]>();
|
|
35
|
-
@Output() public queuedFiles: EventEmitter<File[]> = new EventEmitter<File[]>();
|
|
36
|
-
@Output() public invalidFiles: EventEmitter<InvalidFile[]> = new EventEmitter<InvalidFile[]>();
|
|
37
|
-
|
|
38
|
-
public hasDragOver = false;
|
|
39
|
-
public classNames: string;
|
|
40
|
-
public uploadProgress = 0;
|
|
41
|
-
public uploadingFiles: File[];
|
|
42
|
-
public uploadedFilesString: String;
|
|
43
|
-
|
|
44
|
-
@HostListener('dragover', ['$event'])
|
|
45
|
-
public onDragOver(event: any): void {
|
|
46
|
-
this.preventAndStop(event);
|
|
47
|
-
this.hasDragOver = true;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
@HostListener('dragleave', ['$event'])
|
|
51
|
-
public onDragLeave(event: any): void {
|
|
52
|
-
this.preventAndStop(event);
|
|
53
|
-
this.hasDragOver = false;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
@HostListener('drop', ['$event'])
|
|
57
|
-
public onDrop(event: any): void {
|
|
58
|
-
this.preventAndStop(event);
|
|
59
|
-
this.hasDragOver = false;
|
|
60
|
-
const files = this.fileListToArray(event.dataTransfer.files);
|
|
61
|
-
this.handleFiles(files);
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
constructor(private renderer: Renderer2) {}
|
|
65
|
-
|
|
66
|
-
public triggerFile() {
|
|
67
|
-
this.fileInput.nativeElement.click();
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
public updateFiles() {
|
|
71
|
-
const files: any[] = this.fileListToArray(this.fileInput.nativeElement.files);
|
|
72
|
-
this.uploadedFilesString = files.map((file) => file.name).join(', ');
|
|
73
|
-
this.handleFiles(files);
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
public onFileClick(event) {
|
|
77
|
-
// When removing a file make sure you can add it again later
|
|
78
|
-
// See: https://stackoverflow.com/questions/59870335/ng2-file-upload-not-allowing-me-to-add-same-doc-after-ive-removed-it-from-que
|
|
79
|
-
event.target.value = '';
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
ngAfterViewInit() {
|
|
83
|
-
if (this.multiple !== false) {
|
|
84
|
-
this.renderer.setProperty(this.fileInput.nativeElement, 'multiple', 'multiple');
|
|
85
|
-
}
|
|
86
|
-
if (!!this.accept.length) {
|
|
87
|
-
this.renderer.setProperty(this.fileInput.nativeElement, 'accept', this.accept.join());
|
|
88
|
-
}
|
|
89
|
-
if (this.disabled) {
|
|
90
|
-
this.renderer.setProperty(this.fileInput.nativeElement, 'disabled', 'disabled');
|
|
91
|
-
}
|
|
92
|
-
if (this.capture !== '') {
|
|
93
|
-
this.renderer.setAttribute(this.fileInput.nativeElement, 'capture', this.capture);
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
protected handleFiles(files) {
|
|
98
|
-
const response = this.uploader.validateFiles(files);
|
|
99
|
-
this.invalidFiles.emit(response.invalidFiles);
|
|
100
|
-
|
|
101
|
-
if (this.uploader.options.autoUpload && response.validFiles.length > 0) {
|
|
102
|
-
this.uploadFiles(response.validFiles);
|
|
103
|
-
} else {
|
|
104
|
-
this.queuedFiles.emit(response.validFiles);
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
protected uploadFiles(files) {
|
|
109
|
-
// Reset progress
|
|
110
|
-
this.uploadProgress = 0;
|
|
111
|
-
this.uploadingFiles = files;
|
|
112
|
-
|
|
113
|
-
// upload
|
|
114
|
-
this.uploader.uploadFiles(files).subscribe(
|
|
115
|
-
(response) => {
|
|
116
|
-
if (response.progress) {
|
|
117
|
-
this.uploadProgress = Math.floor(response.progress * 100);
|
|
118
|
-
}
|
|
119
|
-
if (response.data) {
|
|
120
|
-
this.uploadedFiles.emit(response.data);
|
|
121
|
-
}
|
|
122
|
-
},
|
|
123
|
-
(err) => {
|
|
124
|
-
console.log(err);
|
|
125
|
-
}
|
|
126
|
-
);
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
protected fileListToArray(list: FileList): object[] {
|
|
130
|
-
return Array.from(list);
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
protected preventAndStop(event: any): any {
|
|
134
|
-
event.preventDefault();
|
|
135
|
-
event.stopPropagation();
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
public uploadedFilesToString(): string {
|
|
139
|
-
console.log('UPLOADS TO STRING');
|
|
140
|
-
return this.fileInput.nativeElement.files.map((file) => file.name).join('');
|
|
141
|
-
}
|
|
142
|
-
}
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
<ul class="m-upload__files">
|
|
2
|
-
<li *ngFor="let invalidFile of invalidFiles; let i = index" class="is-error">
|
|
3
|
-
<aui-icon name="ai-alert-triangle"></aui-icon>
|
|
4
|
-
<span class="m-upload__filename">{{ invalidFile.file.name }}</span>
|
|
5
|
-
<span class="m-upload__error">{{ formatReasons(invalidFile.reasons) }}</span>
|
|
6
|
-
|
|
7
|
-
<button
|
|
8
|
-
(click)="remove(i)"
|
|
9
|
-
class="m-upload__delete a-button a-button--text a-button--danger a-button--s has-icon"
|
|
10
|
-
type="button"
|
|
11
|
-
>
|
|
12
|
-
<aui-icon name="ai-close" [ariaLabel]="ariaLabelRemove"></aui-icon>
|
|
13
|
-
</button>
|
|
14
|
-
</li>
|
|
15
|
-
</ul>
|