Compare commits

..

13 Commits

Author SHA1 Message Date
VIJAYA L MACHAVOLU
2d240804f5 Added csv as to filetype list and associating it with xls. 2020-12-06 23:27:33 +05:30
PARAM MITTAL
8171bc831b fix(typo): fix grammatical mistake in readme (#1119) 2019-10-30 17:37:02 +02:00
Vitaliy Makogon
d63c8ce9e2 Merge pull request #1107 from earshinov/update-to-angular8
feta(build): update to Angular 8. Use Angular CLI instead of ngm for building. Ensure compatibility with Ivy on application side.
2019-10-23 12:49:47 +03:00
Vitaliy Makogon
33ac156208 fix(ci): fix xvfb service issue 2019-10-22 16:04:21 +03:00
Eugene Arshinov
2888f4cb11 Provide angularCompilerOptions to ensure compatibility with Ivy (on the application side)
Without this configuration, the following error occurs:

```
error TS-996002: Appears in the NgModule.imports of ...Module, but could not be resolved to an NgModule class
```

Configuruation taken from https://github.com/froala/angular-froala-wysiwyg/pull/329/files#diff-bb630a56aac9aa4924037d7db039769d
2019-08-27 12:39:13 +03:00
Eugene Arshinov
7a342268bb Use Angular CLI instead of ngm for building
Some commands:

npm run build      - to build the library.  Output is in dist/ng2-file-upload/.
npm run test       - to run tests.  Coverage report is in coverage/ as before.
npm run demo.serve - to build demo application and serve it through browsersync
npm run start      - to run demo application using `ng serve`.  Requires the library to be built and linked first.
2019-08-27 12:39:13 +03:00
Eugene Arshinov
6cb3f87e57 Remove unused i18n and e2e stuff from angular.json 2019-08-27 12:39:13 +03:00
Eugene Arshinov
49a3334942 Update tslint and tslint-config-valorsoft 2019-08-27 12:39:13 +03:00
Eugene Arshinov
9fae840b69 Remove unused dependency ng2-page-scroll 2019-08-27 12:39:12 +03:00
Eugene Arshinov
7b4f871200 Run ng update to update to latest Angular 8.3.0 2019-08-27 12:39:12 +03:00
Eugene Arshinov
268534b3e1 Repair npm run test 2019-08-27 12:39:12 +03:00
Eugene Arshinov
77f2466f17 Use ng update to convert .angular-cli.json into angular.json 2019-08-27 12:39:12 +03:00
Eugene Arshinov
01c2d173f3 Update to @angular/core@6.0.0, @angular/cli@6.2.8, rxjs@6.0.0
Aux changes:
- Added package-lock.json to lock dependency versions
- Removed unused @angular/http from dependencies
2019-08-27 12:39:12 +03:00
41 changed files with 10871 additions and 11293 deletions

11
.editorconfig Normal file
View File

@@ -0,0 +1,11 @@
# http://editorconfig.org
root = true
[*]
charset = utf-8
indent_style = space
indent_size = 2
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true

View File

@@ -1,11 +1,13 @@
language: node_js
node_js:
- "6"
- "10"
services:
- xvfb
before_install:
- export CHROME_BIN=chromium-browser
- export DISPLAY=:99.0
- sh -e /etc/init.d/xvfb start
script:
- npm run pretest

View File

@@ -1,108 +1,108 @@
<a name="1.3.0"></a>
# [1.3.0](https://github.com/valor-software/ng2-chunk-file-upload/compare/v1.2.0...v1.3.0) (2017-11-25)
# [1.3.0](https://github.com/valor-software/ng2-file-upload/compare/v1.2.0...v1.3.0) (2017-11-25)
### Features
* **file-upload:** Add response and function to modify the request body ([#901](https://github.com/valor-software/ng2-chunk-file-upload/pull/901))
* **file-upload** add file type .zip ([#911](https://github.com/valor-software/ng2-chunk-file-upload/pull/911))
* **file-upload:** Add response and function to modify the request body ([#901](https://github.com/valor-software/ng2-file-upload/pull/901))
* **file-upload** add file type .zip ([#911](https://github.com/valor-software/ng2-file-upload/pull/911))
### Bug Fixes
* **file-uploader** Update: setOptions ([#904](https://github.com/valor-software/ng2-chunk-file-upload/pull/904))
* **docs** Fix correct path for isHTML5 option ([#844](https://github.com/valor-software/ng2-chunk-file-upload/pull/844))
* **docs** Added onFileDrop() event to documentation ([#857](https://github.com/valor-software/ng2-chunk-file-upload/pull/857))
* **file-uploader** Update: setOptions ([#904](https://github.com/valor-software/ng2-file-upload/pull/904))
* **docs** Fix correct path for isHTML5 option ([#844](https://github.com/valor-software/ng2-file-upload/pull/844))
* **docs** Added onFileDrop() event to documentation ([#857](https://github.com/valor-software/ng2-file-upload/pull/857))
<a name="1.2.1"></a>
## [1.2.1](https://github.com/valor-software/ng2-chunk-file-upload/compare/v1.2.0...v1.2.1) (2017-04-10)
## [1.2.1](https://github.com/valor-software/ng2-file-upload/compare/v1.2.0...v1.2.1) (2017-04-10)
### Features
* **package:** relaxed peer dependencies to allow ng v4 ([#713](https://github.com/valor-software/ng2-chunk-file-upload/issues/713)) ([7704e0e](https://github.com/valor-software/ng2-chunk-file-upload/commit/7704e0e))
* **package:** relaxed peer dependencies to allow ng v4 ([#713](https://github.com/valor-software/ng2-file-upload/issues/713)) ([7704e0e](https://github.com/valor-software/ng2-file-upload/commit/7704e0e))
<a name="1.2.0"></a>
# [1.2.0](https://github.com/valor-software/ng2-chunk-file-upload/compare/v1.1.3-0...v1.2.0) (2017-01-17)
# [1.2.0](https://github.com/valor-software/ng2-file-upload/compare/v1.1.3-0...v1.2.0) (2017-01-17)
### Bug Fixes
* **headers:** Add FileItem headers to XHR ([#553](https://github.com/valor-software/ng2-chunk-file-upload/issues/553)) ([e4a7099](https://github.com/valor-software/ng2-chunk-file-upload/commit/e4a7099)), closes [#552](https://github.com/valor-software/ng2-chunk-file-upload/issues/552)
* **headers:** Add FileItem headers to XHR ([#553](https://github.com/valor-software/ng2-file-upload/issues/553)) ([e4a7099](https://github.com/valor-software/ng2-file-upload/commit/e4a7099)), closes [#552](https://github.com/valor-software/ng2-file-upload/issues/552)
### Features
* **file-select:** Clear file select automatically ([#524](https://github.com/valor-software/ng2-chunk-file-upload/issues/524)) ([410efda](https://github.com/valor-software/ng2-chunk-file-upload/commit/410efda))
* **fileUpload:** added additionalParameter ([#565](https://github.com/valor-software/ng2-chunk-file-upload/issues/565)) ([397de09](https://github.com/valor-software/ng2-chunk-file-upload/commit/397de09))
* **package:** upgrade to ng v2.3+ ([#574](https://github.com/valor-software/ng2-chunk-file-upload/issues/574)) ([3cc6a99](https://github.com/valor-software/ng2-chunk-file-upload/commit/3cc6a99))
* **file-select:** Clear file select automatically ([#524](https://github.com/valor-software/ng2-file-upload/issues/524)) ([410efda](https://github.com/valor-software/ng2-file-upload/commit/410efda))
* **fileUpload:** added additionalParameter ([#565](https://github.com/valor-software/ng2-file-upload/issues/565)) ([397de09](https://github.com/valor-software/ng2-file-upload/commit/397de09))
* **package:** upgrade to ng v2.3+ ([#574](https://github.com/valor-software/ng2-file-upload/issues/574)) ([3cc6a99](https://github.com/valor-software/ng2-file-upload/commit/3cc6a99))
<a name="1.1.3-0"></a>
## [1.1.3-0](https://github.com/valor-software/ng2-chunk-file-upload/compare/v1.1.2...v1.1.3-0) (2016-10-19)
## [1.1.3-0](https://github.com/valor-software/ng2-file-upload/compare/v1.1.2...v1.1.3-0) (2016-10-19)
### Bug Fixes
* **typing:** added authTokenHeader property to options and file upload class ([b55c852](https://github.com/valor-software/ng2-chunk-file-upload/commit/b55c852))
* **typing:** added authTokenHeader property to options and file upload class ([b55c852](https://github.com/valor-software/ng2-file-upload/commit/b55c852))
### Features
* **build:** added support for AoT and ng-cli ([f0b2879](https://github.com/valor-software/ng2-chunk-file-upload/commit/f0b2879)), closes [#436](https://github.com/valor-software/ng2-chunk-file-upload/issues/436)
* **file-upload:** Add the possibility of set the token header ([#213](https://github.com/valor-software/ng2-chunk-file-upload/issues/213)) ([282295c](https://github.com/valor-software/ng2-chunk-file-upload/commit/282295c))
* **build:** added support for AoT and ng-cli ([f0b2879](https://github.com/valor-software/ng2-file-upload/commit/f0b2879)), closes [#436](https://github.com/valor-software/ng2-file-upload/issues/436)
* **file-upload:** Add the possibility of set the token header ([#213](https://github.com/valor-software/ng2-file-upload/issues/213)) ([282295c](https://github.com/valor-software/ng2-file-upload/commit/282295c))
<a name="1.1.2"></a>
## [1.1.2](https://github.com/valor-software/ng2-chunk-file-upload/compare/v1.1.1...v1.1.2) (2016-10-17)
## [1.1.2](https://github.com/valor-software/ng2-file-upload/compare/v1.1.1...v1.1.2) (2016-10-17)
### Features
* **package:** allow of ng2 v2.0.* and v2.*.* ([87395e6](https://github.com/valor-software/ng2-chunk-file-upload/commit/87395e6))
* **package:** allow of ng2 v2.0.* and v2.*.* ([87395e6](https://github.com/valor-software/ng2-file-upload/commit/87395e6))
<a name="1.1.1"></a>
## [1.1.1](https://github.com/valor-software/ng2-chunk-file-upload/compare/v1.0.3...v1.1.1) (2016-10-17)
## [1.1.1](https://github.com/valor-software/ng2-file-upload/compare/v1.0.3...v1.1.1) (2016-10-17)
### Bug Fixes
* **uploader:** Add the ability to upload files via PUT instead of POST ([#239](https://github.com/valor-software/ng2-chunk-file-upload/issues/239)) ([e068511](https://github.com/valor-software/ng2-chunk-file-upload/commit/e068511))
* **zone.js:** error in Safari, Added Typings ([#221](https://github.com/valor-software/ng2-chunk-file-upload/issues/221)) ([db77e89](https://github.com/valor-software/ng2-chunk-file-upload/commit/db77e89))
* **uploader:** Add the ability to upload files via PUT instead of POST ([#239](https://github.com/valor-software/ng2-file-upload/issues/239)) ([e068511](https://github.com/valor-software/ng2-file-upload/commit/e068511))
* **zone.js:** error in Safari, Added Typings ([#221](https://github.com/valor-software/ng2-file-upload/issues/221)) ([db77e89](https://github.com/valor-software/ng2-file-upload/commit/db77e89))
### Features
* **multipart:** Create disableMultipart option in FileUploader ([#224](https://github.com/valor-software/ng2-chunk-file-upload/issues/224)) ([22307d2](https://github.com/valor-software/ng2-chunk-file-upload/commit/22307d2))
* **package:** angular ~2.0.1 stable release ([#425](https://github.com/valor-software/ng2-chunk-file-upload/issues/425)) ([3fec385](https://github.com/valor-software/ng2-chunk-file-upload/commit/3fec385))
* **package:** updated to typescript 2 ([4fef496](https://github.com/valor-software/ng2-chunk-file-upload/commit/4fef496))
* **multipart:** Create disableMultipart option in FileUploader ([#224](https://github.com/valor-software/ng2-file-upload/issues/224)) ([22307d2](https://github.com/valor-software/ng2-file-upload/commit/22307d2))
* **package:** angular ~2.0.1 stable release ([#425](https://github.com/valor-software/ng2-file-upload/issues/425)) ([3fec385](https://github.com/valor-software/ng2-file-upload/commit/3fec385))
* **package:** updated to typescript 2 ([4fef496](https://github.com/valor-software/ng2-file-upload/commit/4fef496))
<a name="1.1.0"></a>
# [1.1.0](https://github.com/valor-software/ng2-chunk-file-upload/compare/v1.0.3...v1.1.0) (2016-09-21)
# [1.1.0](https://github.com/valor-software/ng2-file-upload/compare/v1.0.3...v1.1.0) (2016-09-21)
### Bug Fixes
* **uploader:** Add the ability to upload files via PUT instead of POST ([#239](https://github.com/valor-software/ng2-chunk-file-upload/issues/239)) ([e068511](https://github.com/valor-software/ng2-chunk-file-upload/commit/e068511))
* **zone.js:** error in Safari, Added Typings ([#221](https://github.com/valor-software/ng2-chunk-file-upload/issues/221)) ([db77e89](https://github.com/valor-software/ng2-chunk-file-upload/commit/db77e89))
* **uploader:** Add the ability to upload files via PUT instead of POST ([#239](https://github.com/valor-software/ng2-file-upload/issues/239)) ([e068511](https://github.com/valor-software/ng2-file-upload/commit/e068511))
* **zone.js:** error in Safari, Added Typings ([#221](https://github.com/valor-software/ng2-file-upload/issues/221)) ([db77e89](https://github.com/valor-software/ng2-file-upload/commit/db77e89))
### Features
* **multipart:** Create disableMultipart option in FileUploader ([#224](https://github.com/valor-software/ng2-chunk-file-upload/issues/224)) ([22307d2](https://github.com/valor-software/ng2-chunk-file-upload/commit/22307d2))
* **package:** updated to typescript 2 ([4fef496](https://github.com/valor-software/ng2-chunk-file-upload/commit/4fef496))
* **multipart:** Create disableMultipart option in FileUploader ([#224](https://github.com/valor-software/ng2-file-upload/issues/224)) ([22307d2](https://github.com/valor-software/ng2-file-upload/commit/22307d2))
* **package:** updated to typescript 2 ([4fef496](https://github.com/valor-software/ng2-file-upload/commit/4fef496))
<a name="1.0.3"></a>
## [1.0.3](https://github.com/valor-software/ng2-chunk-file-upload/compare/v1.0.2...v1.0.3) (2016-05-12)
## [1.0.3](https://github.com/valor-software/ng2-file-upload/compare/v1.0.2...v1.0.3) (2016-05-12)
@@ -112,17 +112,17 @@
### Bug Fixes
* **upload:** merge fix and get filters fix ([ef6091c](https://github.com/valor-software/ng2-chunk-file-upload/commit/ef6091c))
* **upload:** merge fix and get filters fix ([ef6091c](https://github.com/valor-software/ng2-file-upload/commit/ef6091c))
### Chores
* **build:** ng2 style guide applied ([aee69d8](https://github.com/valor-software/ng2-chunk-file-upload/commit/aee69d8))
* **build:** ng2 style guide applied ([aee69d8](https://github.com/valor-software/ng2-file-upload/commit/aee69d8))
### Features
* **package:** upgrade to angular 2.0.0-rc.1 ([#176](https://github.com/valor-software/ng2-chunk-file-upload/issues/176)) ([13c5c35](https://github.com/valor-software/ng2-chunk-file-upload/commit/13c5c35)), closes [#180](https://github.com/valor-software/ng2-chunk-file-upload/issues/180)
* **package:** upgrade to angular 2.0.0-rc.1 ([#176](https://github.com/valor-software/ng2-file-upload/issues/176)) ([13c5c35](https://github.com/valor-software/ng2-file-upload/commit/13c5c35)), closes [#180](https://github.com/valor-software/ng2-file-upload/issues/180)
### BREAKING CHANGES

110
README.md
View File

@@ -1,31 +1,31 @@
# ng2-chunk-file-upload [![npm version](https://badge.fury.io/js/ng2-chunk-file-upload.svg)](http://badge.fury.io/js/ng2-chunk-file-upload) [![npm downloads](https://img.shields.io/npm/dm/ng2-chunk-file-upload.svg)](https://npmjs.org/ng2-chunk-file-upload)[![slack](https://ngx-slack.herokuapp.com/badge.svg)](https://ngx-slack.herokuapp.com)
Easy to use Angular2 directives for files upload ([demo](http://valor-software.github.io/ng2-chunk-file-upload/))
# ng2-file-upload [![npm version](https://badge.fury.io/js/ng2-file-upload.svg)](http://badge.fury.io/js/ng2-file-upload) [![npm downloads](https://img.shields.io/npm/dm/ng2-file-upload.svg)](https://npmjs.org/ng2-file-upload)[![slack](https://ngx-slack.herokuapp.com/badge.svg)](https://ngx-slack.herokuapp.com)
Easy to use Angular2 directives for files upload ([demo](http://valor-software.github.io/ng2-file-upload/))
[![Angular 2 Style Guide](https://mgechev.github.io/angular2-style-guide/images/badge.svg)](https://github.com/mgechev/angular2-style-guide)
[![Build Status](https://travis-ci.org/valor-software/ng2-chunk-file-upload.svg?branch=development)](https://travis-ci.org/valor-software/ng2-chunk-file-upload)
[![Dependency Status](https://david-dm.org/valor-software/ng2-chunk-file-upload.svg)](https://david-dm.org/valor-software/ng2-chunk-file-upload)
[![Build Status](https://travis-ci.org/valor-software/ng2-file-upload.svg?branch=development)](https://travis-ci.org/valor-software/ng2-file-upload)
[![Dependency Status](https://david-dm.org/valor-software/ng2-file-upload.svg)](https://david-dm.org/valor-software/ng2-file-upload)
## Quick start
1. A recommended way to install ***ng2-chunk-file-upload*** is through [npm](https://www.npmjs.com/search?q=ng2-chunk-file-upload) package manager using the following command:
1. A recommended way to install ***ng2-file-upload*** is through [npm](https://www.npmjs.com/search?q=ng2-file-upload) package manager using the following command:
`npm i ng2-chunk-file-upload --save`
`npm i ng2-file-upload --save`
Alternatively, you can [download it in a ZIP file](https://github.com/valor-software/ng2-chunk-file-upload/archive/master.zip).
Alternatively, you can [download it in a ZIP file](https://github.com/valor-software/ng2-file-upload/archive/master.zip).
2. Currently `ng2-chunk-file-upload` contains two directives: `ng2-file-select` and `ng2-file-drop`. `ng2-file-select` is used for 'file-input' field of form and
2. Currently `ng2-file-upload` contains two directives: `ng2-file-select` and `ng2-file-drop`. `ng2-file-select` is used for 'file-input' field of form and
`ng2-file-drop` is used for area that will be used for dropping of file or files.
3. More information regarding using of ***ng2-chunk-file-upload*** is located in
[demo](http://valor-software.github.io/ng2-chunk-file-upload/) and [demo sources](https://github.com/valor-software/ng2-chunk-file-upload/tree/master/demo).
3. More information regarding using of ***ng2-file-upload*** is located in
[demo](http://valor-software.github.io/ng2-file-upload/) and [demo sources](https://github.com/valor-software/ng2-file-upload/tree/master/demo).
## Using ***ng2-chunk-file-upload*** in a project
## Using ***ng2-file-upload*** in a project
1. Install as shown in the above section.
2. Import `FileUploadModule` into the module that declares the component using ***ng2-chunk-file-upload***:
2. Import `FileUploadModule` into the module that declares the component using ***ng2-file-upload***:
```import { FileUploadModule } from 'ng2-chunk-file-upload';```
```import { FileUploadModule } from 'ng2-file-upload';```
3. Add it to `[imports]` under `@NgModule`:
@@ -33,7 +33,7 @@ Easy to use Angular2 directives for files upload ([demo](http://valor-software.g
4. Import `FileUploader` into the component:
```import { FileUploader } from 'ng2-chunk-file-upload';```
```import { FileUploader } from 'ng2-file-upload';```
5. Create a variable for the API url:
@@ -47,7 +47,7 @@ Easy to use Angular2 directives for files upload ([demo](http://valor-software.g
### Properties
- `uploader` - (`FileUploader`) - uploader object. See using in [demo](https://github.com/valor-software/ng2-chunk-file-upload/blob/master/demo/components/file-upload/simple-demo.ts)
- `uploader` - (`FileUploader`) - uploader object. See using in [demo](https://github.com/valor-software/ng2-file-upload/blob/master/demo/components/file-upload/simple-demo.ts)
### Events
- `onFileSelected` - fires when files are selected and added to the uploader queue
@@ -56,100 +56,34 @@ Easy to use Angular2 directives for files upload ([demo](http://valor-software.g
### Properties
- `uploader` - (`FileUploader`) - uploader object. See using in [demo](https://github.com/valor-software/ng2-chunk-file-upload/blob/master/demo/components/file-upload/simple-demo.ts)
- `uploader` - (`FileUploader`) - uploader object. See using in [demo](https://github.com/valor-software/ng2-file-upload/blob/master/demo/components/file-upload/simple-demo.ts)
Parameters supported by this object:
1. `url` - URL of File Uploader's route
2. `authToken` - Auth token that will be applied as 'Authorization' header during file send.
3. `disableMultipart` - If 'true', disable using a multipart form for file upload and instead stream the file. Some APIs (e.g. Amazon S3) may expect the file to be streamed rather than sent via a form. Defaults to false.
4. `itemAlias` - item alias (form name redefenition)
4. `itemAlias` - item alias (form name redefinition)
5. `formatDataFunction` - Function to modify the request body. 'DisableMultipart' must be 'true' for this function to be called.
6. `formatDataFunctionIsAsync` - Informs if the function sent in 'formatDataFunction' is asynchronous. Defaults to false.
7. `parametersBeforeFiles` - States if additional parameters should be appended before or after the file. Defaults to false.
8. `chunkSize` - The Size of each chunk in Bytes, if this parameter is set the file chunk upload functionality will run. Defaults to Null.
9. `currentChunkParam` - Parameter Sent with the chunk request, the current chunk number of the file. Defaults to 'current_chunk'.
10. `totalChunkParam` - Parameter Sent with the chunk request, the total number of chunks of the file. Defaults to 'total_chunks'.
11. `chunkMethod` - After the first chunk, this method is set. Defaults to 'PUT' because is the standard for update.
### Events
- `fileOver` - it fires during 'over' and 'out' events for Drop Area; returns `boolean`: `true` if file is over Drop Area, `false` in case of out.
See using in [ts demo](https://github.com/valor-software/ng2-chunk-file-upload/blob/master/demo/components/file-upload/simple-demo.ts) and
[html demo](https://github.com/valor-software/ng2-chunk-file-upload/blob/master/demo/components/file-upload/simple-demo.html)
See using in [ts demo](https://github.com/valor-software/ng2-file-upload/blob/master/demo/components/file-upload/simple-demo.ts) and
[html demo](https://github.com/valor-software/ng2-file-upload/blob/master/demo/components/file-upload/simple-demo.html)
- `onFileDrop` - it fires after a file has been dropped on a Drop Area; you can pass in `$event` to get the list of files that were dropped. i.e. `(onFileDrop)="dropped($event)"`
# Troubleshooting
Please follow this guidelines when reporting bugs and feature requests:
Please follow these guidelines when reporting bugs and feature requests:
1. Use [GitHub Issues](https://github.com/valor-software/ng2-chunk-file-upload/issues) board to report bugs and feature requests (not our email address)
1. Use [GitHub Issues](https://github.com/valor-software/ng2-file-upload/issues) board to report bugs and feature requests (not our email address)
2. Please **always** write steps to reproduce the error. That way we can focus on fixing the bug, not scratching our heads trying to reproduce it.
Thanks for understanding!
## Using/Sending Chunk Files Feature
If you want to send the files chunked you can just set the chunk paramets on the uploader object
If your chunk request changes the link after the first request you should use this code
```typescript
this.uploader.onCompleteChunk = (item,response,status,headers)=>{
response = JSON.parse(response);
if(response['id']){
item.url = YOUR_NEW_URL+response['id']+'/';
}
}
```
### Code snippet on how to use the Chunk File Feature on your code
```typescript
...
import { FileUploader } from 'ng2-chunk-file-upload';
...
export class SimpleDemoComponent {
...
uploader:FileUploader;
...
constructor () {
...
this.uploader = new FileUploader({
url: URL,
disableMultipart : false,
isHTML5: true,
chunkSize: (1024*1024), // 2MB
currentChunkParam: 'current_chunk',
totalChunkParam: 'total_chunks',
chunkMethod: 'PUT',
//authToken = 'JWT '+TOKEN,
});
this.uploader.onBeforeUploadItem = (item) => {
// If you use credentials this might help you with the "Access-Control-Allow-Origin" error
item.withCredentials = false;
};
this.uploader.onCompleteChunk = (item, response, status, headers) => {
//Insert the Logic here to start uploading next chunks
// Example, setting the ID of the File uploaded and chaning the link for the next request
// In my Case the API is using a put method with the link containing the PK of the object
response = JSON.parse(response);
if (response['id']) {
item.setId(response['id']);
item.url = this.media_url + item.getId() + '/';
}
};
this.uploader.onErrorItem = (item, response, status, headers) => {
// Treat the error on the upload
// On the chunk method we try to upload a chunk for 10 times before triggering this error
};
this.uploader.onRemoveItem = (item) => {
// Treat the file removal from the server
};
...
}
```
### License
The MIT License (see the [LICENSE](https://github.com/valor-software/ng2-chunk-file-upload/blob/master/LICENSE) file for the full text)
The MIT License (see the [LICENSE](https://github.com/valor-software/ng2-file-upload/blob/master/LICENSE) file for the full text)

View File

@@ -3,9 +3,23 @@
"version": 1,
"newProjectRoot": "projects",
"projects": {
"ng2-chunk-file-upload": {
"root": "",
"ng2-file-upload": {
"root": ".",
"sourceRoot": "src",
"projectType": "library",
"architect": {
"build": {
"builder": "@angular-devkit/build-ng-packagr:build",
"options": {
"tsConfig": "src/tsconfig.json",
"project": "src/ng-package.json"
}
}
}
},
"ng2-file-upload-demo": {
"root": "demo",
"sourceRoot": "demo/src",
"projectType": "application",
"architect": {
"build": {
@@ -44,64 +58,48 @@
"serve": {
"builder": "@angular-devkit/build-angular:dev-server",
"options": {
"browserTarget": "ng2-chunk-file-upload:build"
"browserTarget": "ng2-file-upload-demo:build"
},
"configurations": {
"production": {
"browserTarget": "ng2-chunk-file-upload:build:production"
"browserTarget": "ng2-file-upload-demo:build:production"
}
}
}
}
},
"extract-i18n": {
"builder": "@angular-devkit/build-angular:extract-i18n",
"options": {
"browserTarget": "ng2-chunk-file-upload:build"
}
},
"ng2-file-upload-test": {
"root": ".",
"sourceRoot": "test",
"projectType": "library",
"architect": {
"test": {
"builder": "@angular-devkit/build-angular:karma",
"options": {
"main": "demo/src/../../scripts/test.ts",
"karmaConfig": "karma.conf.js",
"main": "test/test.ts",
"karmaConfig": "test/karma.conf.js",
"scripts": [],
"styles": [],
"assets": [
"demo/src/assets"
"tsConfig": "test/tsconfig.json"
}
},
"lint": {
"builder": "@angular-devkit/build-angular:tslint",
"options": {
"tsConfig": [
"src/tsconfig.json",
"demo/src/tsconfig.json",
"test/tsconfig.json"
],
"exclude": [
"**/node_modules/**"
]
}
},
"lint": {
"builder": "@angular-devkit/build-angular:tslint",
"options": {
"tsConfig": [],
"exclude": []
}
}
}
},
"ng2-chunk-file-upload-e2e": {
"root": "",
"sourceRoot": "",
"projectType": "application",
"architect": {
"e2e": {
"builder": "@angular-devkit/build-angular:protractor",
"options": {
"protractorConfig": "protractor.conf.js",
"devServerTarget": "ng2-chunk-file-upload:serve"
}
},
"lint": {
"builder": "@angular-devkit/build-angular:tslint",
"options": {
"tsConfig": [],
"exclude": []
}
}
}
}
},
"defaultProject": "ng2-chunk-file-upload",
"defaultProject": "ng2-file-upload-demo",
"schematics": {
"@schematics/angular:component": {
"prefix": "",

12
demo/browserslist Normal file
View File

@@ -0,0 +1,12 @@
# This file is used by the build system to adjust CSS and JS output to support the specified browsers below.
# For additional information regarding the format and rule options, please see:
# https://github.com/browserslist/browserslist#queries
# You can see what browsers were selected by your queries by running:
# npx browserslist
> 0.5%
last 2 versions
Firefox ESR
not dead
not IE 9-11 # For IE 9-11 support, remove 'not'.

View File

@@ -7,18 +7,12 @@ let gettingStarted = require('html-loader!markdown-loader!../getting-started.md'
template: `
<main class="bd-pageheader">
<div class="container">
<h1>ng2-chunk-file-upload</h1>
<h1>ng2-file-upload</h1>
<p>The Angular2 File Upload directives</p>
<a class="btn btn-primary" href="https://github.com/valor-software/ng2-chunk-file-upload">View on GitHub</a>
<a class="btn btn-primary" href="https://github.com/valor-software/ng2-file-upload">View on GitHub</a>
<div class="row">
<div class="col-lg-1">
<iframe src="https://ghbtns.com/github-btn.html?user=valor-software&repo=ng2-chunk-file-upload&type=star&count=true"
frameborder="0" scrolling="0" width="170px" height="20px"></iframe>
</div>
<div class="col-lg-1">
<iframe src="https://ghbtns.com/github-btn.html?user=valor-software&repo=ng2-chunk-file-upload&type=fork&count=true"
frameborder="0" scrolling="0" width="170px" height="20px"></iframe>
</div>
<div class="col-lg-1"><iframe src="https://ghbtns.com/github-btn.html?user=valor-software&repo=ng2-file-upload&type=star&count=true" frameborder="0" scrolling="0" width="170px" height="20px"></iframe></div>
<div class="col-lg-1"><iframe src="https://ghbtns.com/github-btn.html?user=valor-software&repo=ng2-file-upload&type=fork&count=true" frameborder="0" scrolling="0" width="170px" height="20px"></iframe></div>
</div>
</div>
</main>
@@ -31,12 +25,10 @@ let gettingStarted = require('html-loader!markdown-loader!../getting-started.md'
<footer class="footer">
<div class="container">
<p class="text-muted text-center">
<a href="https://github.com/valor-software/ng2-chunk-file-upload">ng2-chunk-file-upload</a>
is maintained by <a href="https://github.com/valor-software">valor-software</a>.</p>
<p class="text-muted text-center"><a href="https://github.com/valor-software/ng2-file-upload">ng2-file-upload</a> is maintained by <a href="https://github.com/valor-software">valor-software</a>.</p>
</div>
</footer>
`,
`
})
export class AppComponent {
public gettingStarted:string = gettingStarted;

View File

@@ -4,24 +4,16 @@ import { FormsModule } from '@angular/forms';
import { BrowserModule } from '@angular/platform-browser';
import { TabsModule } from 'ngx-bootstrap/tabs';
import { FileUploadModule } from '../../../src/file-upload/file-upload.module';
import { FileUploadModule } from 'ng2-file-upload';
import { AppComponent } from './app.component';
import { FileUploadSectionComponent } from './components/file-upload-section';
import { SimpleDemoComponent } from './components/file-upload/simple-demo';
import { HttpModule } from '@angular/http';
@NgModule({
imports: [
HttpModule,
BrowserModule,
CommonModule,
FileUploadModule,
TabsModule.forRoot(),
FormsModule,
],
imports: [BrowserModule, CommonModule, FileUploadModule, TabsModule.forRoot(), FormsModule],
declarations: [AppComponent, FileUploadSectionComponent, SimpleDemoComponent],
bootstrap: [AppComponent],
bootstrap: [AppComponent]
})
export class AppModule {}
export class AppModule {
}

View File

@@ -5,9 +5,9 @@ let doc = require('html-loader!markdown-loader!../../doc.md');
let tabDesc:Array<any> = [
{
heading: 'Simple',
ts: require('!!raw-loader?lang=typescript!./file-upload/simple-demo.ts'),
html: require('!!raw-loader?lang=markup!./file-upload/simple-demo.html'),
js: require('!!raw-loader?lang=javascript!./file-upload/file-catcher.js')
ts: require('!!raw-loader!./file-upload/simple-demo.ts').default,
html: require('!!raw-loader!./file-upload/simple-demo.html').default,
js: require('!!raw-loader!./file-upload/file-catcher.js').default
}
];

View File

@@ -1,5 +1,5 @@
import { Component } from '@angular/core';
import { FileUploader } from 'ng2-chunk-file-upload';
import { FileUploader } from 'ng2-file-upload';
// const URL = '/api/';
const URL = 'https://evening-anchorage-3159.herokuapp.com/api/';

View File

@@ -1,6 +1,6 @@
### Usage
```typescript
import { FileSelectDirective, FileDropDirective, FileUploader } from 'ng2-chunk-file-upload/ng2-chunk-file-upload';
import { FileSelectDirective, FileDropDirective, FileUploader } from 'ng2-file-upload/ng2-file-upload';
```
### Annotations
@@ -18,7 +18,7 @@ import { FileSelectDirective, FileDropDirective, FileUploader } from 'ng2-chunk-
### Properties
- `uploader` - (`FileUploader`) - uploader object. See using in [demo](https://github.com/valor-software/ng2-chunk-file-upload/blob/master/demo/components/file-upload/simple-demo.ts)
- `uploader` - (`FileUploader`) - uploader object. See using in [demo](https://github.com/valor-software/ng2-file-upload/blob/master/demo/components/file-upload/simple-demo.ts)
Parameters supported by this object:
@@ -37,11 +37,11 @@ import { FileSelectDirective, FileDropDirective, FileUploader } from 'ng2-chunk-
### Properties
- `uploader` - (`FileUploader`) - uploader object. See using in [demo](https://github.com/valor-software/ng2-chunk-file-upload/blob/master/demo/components/file-upload/simple-demo.ts)
- `uploader` - (`FileUploader`) - uploader object. See using in [demo](https://github.com/valor-software/ng2-file-upload/blob/master/demo/components/file-upload/simple-demo.ts)
### Events
- `fileOver` - it fires during 'over' and 'out' events for Drop Area; returns `boolean`: `true` if file is over Drop Area, `false` in case of out.
See using in [ts demo](https://github.com/valor-software/ng2-chunk-file-upload/blob/master/demo/components/file-upload/simple-demo.ts) and
[html demo](https://github.com/valor-software/ng2-chunk-file-upload/blob/master/demo/components/file-upload/simple-demo.html)
See using in [ts demo](https://github.com/valor-software/ng2-file-upload/blob/master/demo/components/file-upload/simple-demo.ts) and
[html demo](https://github.com/valor-software/ng2-file-upload/blob/master/demo/components/file-upload/simple-demo.html)
- `onFileDrop` - it fires after a file has been dropped on a Drop Area; you can pass in `$event` to get the list of files that were dropped. i.e. `(onFileDrop)="dropped($event)"`

View File

@@ -6,5 +6,5 @@
Install the components
```
npm install ng2-chunk-file-upload --save
npm install ng2-file-upload --save
```

View File

@@ -9,7 +9,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" href="data:;base64,iVBORw0KGgo=">
<link rel="author" href="https://github.com/valor-software/ng2-chunk-file-upload/graphs/contributors">
<link rel="author" href="https://github.com/valor-software/ng2-file-upload/graphs/contributors">
<!--link to bootstrap.css-->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">

View File

@@ -1,4 +1,4 @@
import './polyfills.ts';
import '../../scripts/polyfills.ts';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { enableProdMode } from '@angular/core';

View File

@@ -1,17 +1,25 @@
{
"compilerOptions": {
"baseUrl": ".",
"declaration": false,
"downlevelIteration": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"noEmitHelpers": false,
"lib": ["es6", "dom"],
"types": ["jasmine", "webpack"],
"mapRoot": "./",
"module": "es6",
"module": "esnext",
"moduleResolution": "node",
"outDir": "../temp/out-tsc",
"sourceMap": true,
"target": "es5",
"typeRoots": ["../node_modules/@types"]
}
"target": "es2015"
},
"files": [
"../../scripts/typings.d.ts",
"main.ts",
"../../scripts/polyfills.ts"
],
"exclude": [
"**/*.spec.ts"
]
}

16
demo/src/typings.d.ts vendored
View File

@@ -1,16 +0,0 @@
// Typings reference file, you can add your own global typings here
// https://www.typescriptlang.org/docs/handbook/writing-declaration-files.html
// tslint:disable
declare const System: any;
declare const ENV:string;
// google code-prettify
declare const PR:any;
// declare const require:any;
// declare const global:any;
declare module jasmine {
interface Matchers {
toHaveCssClass(expected: any): boolean;
}
}

18781
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,128 +1,112 @@
{
"name": "ng2-chunk-file-upload-base",
"name": "ng2-file-upload-base",
"version": "1.3.0",
"private": true,
"description": "Angular file upload directives with Chunk Upload",
"description": "Angular file upload directives",
"scripts": {
"lite-server": "lite-server -c demo/bs-config.json",
"demo.serve": "run-s build link demo.build lite-server",
"demo.gh-pages": "run-s build demo.build demo.deploy",
"demo.build": "ng build -prod --aot",
"demo.build": "ng build ng2-file-upload-demo --prod",
"demo.deploy": "gh-pages -d demo/dist",
"link": "ngm link -p src --here",
"link": "cd dist/ng2-file-upload/ && npm link && cd ../../ && npm link ng2-file-upload",
"lint": "exit 0",
"disable-lint": "tslint \"**/*.ts\" -c tslint.json --fix --type-check -t prose -e \"node_modules/**\" -e \"dist/**\" -e \"temp/**\" -e \"scripts/docs/**\"",
"flow.changelog": "conventional-changelog -i CHANGELOG.md -s -p angular",
"flow.github-release": "conventional-github-releaser -p angular",
"build": "ngm build -p src --clean",
"build.watch": "ngm build -p src --watch --skip-bundles",
"start": "ng serve --aot",
"build": "ng build ng2-file-upload",
"build.watch": "ng build ng2-file-upload --watch",
"start": "ng serve ng2-file-upload-demo --aot",
"pretest": "run-s lint build link",
"test": "ng test -sr",
"test-coverage": "ng test -sr -cc",
"test": "ng test ng2-file-upload-test",
"test-coverage": "ng test ng2-file-upload-test --code-coverage",
"version": "npm run flow.changelog && git add -A"
},
"main": "bundles/ng2-chunk-file-upload.umd.js",
"module": "index.js",
"typings": "index.d.ts",
"keywords": [
"angular2",
"bootstrap",
"angularjs",
"twitter-bootstrap",
"file-upload",
"angular-file-upload",
"chunk-file-upload",
"azure-blob-storage"
"angular-file-upload"
],
"author": "Paulo Peres Jr <paulo@myog.io>",
"author": "Vyacheslav Chub <vyacheslav.chub@valor-software.com>",
"license": "MIT",
"repository": {
"type": "git",
"url": "git+ssh://git@github.com/PauloPeres/ng2-chunk-file-upload.git"
"url": "git+ssh://git@github.com/valor-software/ng2-file-upload.git"
},
"bugs": {
"url": "https://github.com/PauloPeres/ng2-chunk-file-upload/issues"
},
"homepage": "https://github.com/PauloPeres/ng2-chunk-file-upload#readme",
"dependencies": {},
"peerDependencies": {
"@angular/common": "^4.3.0 || >=4.3.0",
"@angular/core": "^4.3.0 || >=4.3.0",
"@angular/http": "^4.3.0 || >=4.3.0"
"url": "https://github.com/valor-software/ng2-file-upload/issues"
},
"homepage": "https://github.com/valor-software/ng2-file-upload#readme",
"peerDependencies": {},
"devDependencies": {
"@angular-devkit/build-angular": "~0.6.3",
"@angular/cdk": "^6.1.0",
"@angular/cli": "^6.0.3",
"@angular/common": "^6.0.1",
"@angular/compiler": "^6.0.1",
"@angular/compiler-cli": "^6.0.1",
"@angular/core": "^6.0.1",
"@angular/forms": "^6.0.1",
"@angular/http": "^6.0.1",
"@angular/language-service": "^6.0.1",
"@angular/material": "^6.1.0",
"@angular/platform-browser": "^6.0.1",
"@angular/platform-browser-dynamic": "^6.0.1",
"@angular/router": "^6.0.1",
"@angular/tsc-wrapped": "4.4.6",
"@types/jasmine": "2.8.7",
"@types/marked": "0.3.0",
"@types/node": "10.1.2",
"@types/webpack": "^4.4.0",
"ajv": "^6.0.0",
"bootstrap": "4.1.1",
"@angular-devkit/build-angular": "~0.803.0",
"@angular-devkit/build-ng-packagr": "^0.803.0",
"@angular/cli": "^8.3.0",
"@angular/common": "^8.2.3",
"@angular/compiler": "^8.2.3",
"@angular/compiler-cli": "^8.2.3",
"@angular/core": "^8.2.3",
"@angular/forms": "^8.2.3",
"@angular/language-service": "8.2.3",
"@angular/platform-browser": "^8.2.3",
"@angular/platform-browser-dynamic": "^8.2.3",
"@angular/router": "^8.2.3",
"@types/jasmine": "2.5.40",
"@types/marked": "0.0.28",
"@types/node": "7.0.0",
"@types/webpack": "^3.8.18",
"bootstrap": "3.3.7",
"chokidar-cli": "1.2.0",
"classlist-polyfill": "1.2.0",
"codecov": "3.0.2",
"codelyzer": "~4.3.0",
"conventional-changelog-cli": "1.3.22",
"conventional-github-releaser": "2.0.2",
"classlist-polyfill": "1.0.3",
"codecov": "1.0.1",
"codelyzer": "^5.0.1",
"conventional-changelog-cli": "1.2.0",
"conventional-github-releaser": "1.1.3",
"core-js": "^2.4.1",
"cpy": "7.0.0",
"cpy": "5.0.0",
"cpy-cli": "1.0.1",
"del-cli": "1.1.0",
"gh-pages": "1.1.0",
"del-cli": "0.2.1",
"gh-pages": "0.12.0",
"gitignore-to-glob": "0.3.0",
"google-code-prettify": "1.0.5",
"html-loader": "0.5.5",
"jasmine": "3.1.0",
"html-loader": "^0.5.5",
"jasmine-core": "3.1.0",
"jasmine-data-provider": "2.2.0",
"jasmine-spec-reporter": "4.2.1",
"jquery": "^1.9.1",
"karma": "2.0.2",
"karma-chrome-launcher": "^2.0.0",
"karma": "4.1.0",
"karma-chrome-launcher": "2.2.0",
"karma-cli": "^1.0.1",
"karma-coverage-istanbul-reporter": "^2.0.1",
"karma-jasmine": "^1.0.2",
"karma-coverage-istanbul-reporter": "1.4.3",
"karma-jasmine": "1.1.2",
"karma-remap-istanbul": "0.6.0",
"karma-sauce-launcher": "1.2.0",
"lite-server": "2.3.0",
"lodash": "4.17.10",
"markdown-loader": "^2.0.2",
"marked": "0.4.0",
"ngm-cli": "1.0.4",
"ngx-bootstrap": "3.0.0",
"lite-server": "2.2.2",
"lodash": "4.17.4",
"markdown-loader": "^5.1.0",
"marked": "0.3.6",
"ng-packagr": "^5.5.0",
"ngx-bootstrap": "1.6.6",
"npm-run-all": "^4.0.1",
"popper.js": "^1.14.3",
"pre-commit": "1.2.2",
"protractor": "5.3.2",
"reflect-metadata": "0.1.12",
"require-dir": "1.0.0",
"rxjs": "^6.2.0",
"rxjs-compat": "^6.1.0",
"rxjs-tslint": "^0.1.4",
"systemjs-builder": "0.16.13",
"protractor": "5.0.0",
"raw-loader": "^3.1.0",
"reflect-metadata": "0.1.9",
"require-dir": "0.3.1",
"rxjs": "^6.5.2",
"systemjs-builder": "0.15.34",
"ts-helpers": "^1.1.1",
"ts-node": "6.0.3",
"tslint": "5.10.0",
"typedoc": "0.11.1",
"typescript": "^2.7.2",
"wallaby-webpack": "3.9.8",
"webdriver-manager": "12.0.6",
"zone.js": "0.8.26"
"ts-node": "2.0.0",
"tsickle": "^0.37.0",
"tslint": "^5.19.0",
"tslint-config-valorsoft": "^2.2.1",
"typedoc": "0.5.5",
"typescript": "3.5.3",
"wallaby-webpack": "0.0.30",
"webdriver-manager": "11.1.1",
"zone.js": "~0.9.1"
},
"contributors": [
{
@@ -144,11 +128,9 @@
"name": "Oleksandr Telnov",
"email": "otelnov@gmail.com",
"url": "https://github.com/otelnov"
},
{
"name": "Paulo Peres Jr",
"email": "paulo@myog.io",
"url": "https://github.com/PauloPeres/"
}
]
],
"dependencies": {
"tslib": "^1.10.0"
}
}

1
scripts/.gitignore vendored
View File

@@ -1 +0,0 @@
!**/*.js

View File

@@ -1,242 +0,0 @@
export class FileChunk {
public stepSize: number = 1024 * 1024 * 3;
public rawFile: any = null;
public uploadProgress: number = null;
public uploading: boolean = null;
public uploadComplete: boolean = null;
public byteStepSize: number = null;
public totalSize: number = null;
public startByte: number = null;
public endByte: number = null;
public currentChunk: number = 0;
public totalChunks: number = null;
public uniqueIdentifier: string = null;
public totalSent: number = null;
public extraData: any = {};
constructor(rawFile: any, options: any = {}) {
this.setByteStepSize(this.stepSize);
if (typeof options !== 'undefined') {
if (typeof options.byteStepSize !== 'undefined') {
this.setByteStepSize(options.byteStepSize);
}
}
this.setRawFile(rawFile);
this.setRawFile(rawFile);
this.setUploadProgress(0);
this.setUploading(false);
this.setUploadComplete(false);
this.setTotalSize(this.getRawFile().size);
this.setStartByte(0);
this.setEndByte(this.getByteStepSize());
this.setCurrentChunk(0);
if (!this.getBrowserSliceMethod()) {
this.setTotalChunks(1);
} else {
this.setTotalChunks(Math.ceil(this.totalSize / this.byteStepSize));
}
this.setUniqueIdenfier(this.generateUniqueIdentifier());
this.setTotalSent(0);
}
public setExtraData(index: any, value: any) {
this.extraData[index] = value;
}
public getExtraData(index: any) {
return this.extraData[index];
}
//getters and setters
public setProgress(v: number) {
this.uploadProgress = v;
}
public getProgress():number {
return this.uploadProgress;
}
public setUploading(v: boolean) {
this.uploading = v;
}
public getUploading():boolean {
return this.uploading;
}
public getUploadComplete():boolean {
return this.uploadComplete;
}
public setUploadComplete(v: boolean) {
this.uploadComplete = v;
}
public setUploadProgress(v: number) {
this.uploadProgress = v;
}
public getUploadProgress():number {
return this.uploadProgress;
}
public getStartByte():number {
return this.startByte;
}
public setStartByte(v: number) {
this.startByte = v;
}
public getEndByte():number {
return this.endByte;
}
public setEndByte(v: number) {
this.endByte = v;
}
public getByteStepSize():number {
return this.byteStepSize;
}
public setByteStepSize(v: number) {
this.byteStepSize = v;
}
public setTotalSize(v: number) {
this.totalSize = v;
}
public getTotalSize():number {
return this.totalSize;
}
public getRawFile():any {
return this.rawFile;
}
public setRawFile(v: File) {
this.rawFile = v;
}
public getCurrentChunk():number {
return this.currentChunk;
}
public setCurrentChunk(v: number) {
this.currentChunk = v;
}
public getTotalChunks():number {
return this.totalChunks;
}
public setTotalChunks(v: number) {
this.totalChunks = v;
}
public setUniqueIdenfier(v: string) {
this.uniqueIdentifier = v;
}
public getUniqueIdenfier():string {
return this.uniqueIdentifier;
}
public getRawFileExtension() {
const extension = this.getRawFileName().split('.');
return extension[extension.length - 1];
}
public getRawFileName() {
return this.getRawFile().name;
}
public getContentType() {
return this.getRawFile().type;
}
public getTotalSent() {
return this.totalSent;
}
public setTotalSent(v: number) {
this.totalSent = v;
}
public getCurrentRawFileChunk() {
if (!this.getBrowserSliceMethod()) {
return this.getRawFile();
}
else {
return this.getRawFile()[this.getBrowserSliceMethod()](this.getStartByte(), this.getEndByte());
}
}
public retrocedeChunk() {
if (!this.getBrowserSliceMethod()) {
return false;
}
this.setEndByte(this.getStartByte());
this.setStartByte(this.getStartByte() - this.getByteStepSize());
this.setCurrentChunk(this.getCurrentChunk() - 1);
if (this.getTotalSent() != 0) {
this.setTotalSent(this.getTotalSent() - this.getByteStepSize());
}
}
public prepareNextChunk() {
if (!this.getBrowserSliceMethod()) {
return false;
}
if (this.getEndByte() > this.getTotalSize() && this.getCurrentChunk() < this.getTotalChunks()) { // finished
return false;
}
this.setStartByte(this.getEndByte());
this.setEndByte(this.getEndByte() + this.getByteStepSize());
this.setCurrentChunk(this.getCurrentChunk() + 1);
if (this.getEndByte() > this.getTotalSize() && this.getCurrentChunk() === this.getTotalChunks()) {
// something went wrong with the calculations
this.setEndByte(this.getTotalSize());
}
return true;
}
public getBrowserSliceMethod(): string {
if (this.rawFile && typeof this.rawFile !== 'undefined') {
if (this.rawFile.slice && typeof this.rawFile.slice === 'function') {
return 'slice';
}
else if (this.rawFile.mozSlice && typeof this.rawFile.mozSlice === 'function') {
return 'mozSlice';
}
else if (this.rawFile.webkitSlice && typeof this.rawFile.webkitSlice === 'function') {
return 'webkitSlice';
}
}
else {
return null;
}
}//getBrowserSliceMethod() ends here
public generateUniqueIdentifier(): string {
let d = new Date().getTime();
if (typeof performance !== 'undefined' && typeof performance.now === 'function') {
d += performance.now(); // use high-precision timer if available
}
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
const r = (d + Math.random() * 16) % 16 | 0;
d = Math.floor(d / 16);
return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16);
});
}
}

View File

@@ -1,11 +1,9 @@
import { HttpHeaders } from '@angular/common/http';
import { FileLikeObject } from './file-like-object.class';
import { FileUploader, FileUploaderOptions } from './file-uploader.class';
import { FileChunk } from './file-chunk.class'
import { FileUploader, ParsedResponseHeaders, FileUploaderOptions } from './file-uploader.class';
export class FileItem {
public file: FileLikeObject;
public _file: File;
public id: any;
public alias: string;
public url: string = '/';
public method: string;
@@ -18,15 +16,11 @@ export class FileItem {
public isSuccess: boolean = false;
public isCancel: boolean = false;
public isError: boolean = false;
public isRemoving: boolean = false;
public progress: number = 0;
public index: number = void 0;
public downloadUrl?: string = null;
public _xhr: XMLHttpRequest;
public _form: any;
public _fileChunks: FileChunk;
protected chunkTotalRetries = 10;
protected chunkRetries = 0;
protected uploader: FileUploader;
protected some: File;
protected options: FileUploaderOptions;
@@ -37,96 +31,58 @@ export class FileItem {
this.options = options;
this.file = new FileLikeObject(some);
this._file = some;
if (uploader.options) {
this.method = uploader.options.method || 'POST';
this.alias = uploader.options.itemAlias || 'file';
}
this.url = uploader.options.url;
}
public upload(): void {
try {
this.uploader.uploadItem(this);
} catch (e) {
this.uploader._onCompleteItem(this, '', 0, new HttpHeaders());
this.uploader._onErrorItem(this, '', 0, new HttpHeaders());
this.uploader._onCompleteItem(this, '', 0, {});
this.uploader._onErrorItem(this, '', 0, {});
}
}
public createFileChunk(chunkSize: number): void {
this.fileChunks = new FileChunk(this._file, { byteStepSize: chunkSize });
}
public getCurrentChunkFile(): any {
return this.fileChunks.getCurrentRawFileChunk();
}
public prepareNextChunk(): void {
this.fileChunks.prepareNextChunk();
}
public getCurrentChunk(): number {
return this.fileChunks.getCurrentChunk()
}
public getTotalChunks(): number {
return this.fileChunks.getTotalChunks()
}
public setIsUploading(val: boolean) {
this.isUploading = val;
if (this.fileChunks) {
this.fileChunks.setUploading(val)
}
}
public set fileChunks(val: FileChunk) {
this._fileChunks = val;
}
public get fileChunks(): FileChunk {
return this._fileChunks;
}
public getId(): any {
return this.id;
}
public setId(id: any) {
this.id = id;
}
public cancel(): void {
this.uploader.cancelItem(this);
}
public remove(): void {
this.uploader.removeFromQueue(this);
}
public removeOnline(): void {
this.isRemoving = true;
this.uploader.uploaderService.deleteEntry(this,{},true).subscribe(
(result:any) => {
this.isRemoving = false;
this.remove();
},
(error:any) => {
this.isRemoving = false;
}
);
}
public onBeforeUpload(): void {
return void 0;
}
public onBuildForm(form: any): any {
return { form };
}
public onProgress(progress: number): any {
return { progress };
}
public onSuccess(response: string, status: number, headers: HttpHeaders): any {
public onSuccess(response: string, status: number, headers: ParsedResponseHeaders): any {
return { response, status, headers };
}
public onError(response: string, status: number, headers: HttpHeaders): any {
public onError(response: string, status: number, headers: ParsedResponseHeaders): any {
return { response, status, headers };
}
public onCancel(): any {
return {};
}
public onComplete(response: string, status: number, headers: HttpHeaders): any {
public onCancel(response: string, status: number, headers: ParsedResponseHeaders): any {
return { response, status, headers };
}
public onCompleteChunk(response: string, status: number, headers: HttpHeaders): any {
public onComplete(response: string, status: number, headers: ParsedResponseHeaders): any {
return { response, status, headers };
}
public _onBeforeUpload(): void {
this.isReady = true;
this.isUploading = true;
@@ -137,14 +93,17 @@ export class FileItem {
this.progress = 0;
this.onBeforeUpload();
}
public _onBuildForm(form: any): void {
this.onBuildForm(form);
}
public _onProgress(progress: number): void {
this.progress = progress;
this.onProgress(progress);
}
public _onSuccess(response: string, status: number, headers: HttpHeaders): void {
public _onSuccess(response: string, status: number, headers: ParsedResponseHeaders): void {
this.isReady = false;
this.isUploading = false;
this.isUploaded = true;
@@ -155,7 +114,8 @@ export class FileItem {
this.index = void 0;
this.onSuccess(response, status, headers);
}
public _onError(response: string, status: number, headers: HttpHeaders): void {
public _onError(response: string, status: number, headers: ParsedResponseHeaders): void {
this.isReady = false;
this.isUploading = false;
this.isUploaded = true;
@@ -166,7 +126,8 @@ export class FileItem {
this.index = void 0;
this.onError(response, status, headers);
}
public _onCancel(): void {
public _onCancel(response: string, status: number, headers: ParsedResponseHeaders): void {
this.isReady = false;
this.isUploading = false;
this.isUploaded = false;
@@ -175,34 +136,17 @@ export class FileItem {
this.isError = false;
this.progress = 0;
this.index = void 0;
this.onCancel();
this.onCancel(response, status, headers);
}
public _onComplete(response: string, status: number, headers: HttpHeaders): void {
public _onComplete(response: string, status: number, headers: ParsedResponseHeaders): void {
this.onComplete(response, status, headers);
if (this.uploader.options.removeAfterUpload) {
this.remove();
}
}
public _onCompleteChunk(response: string, status: number, headers: HttpHeaders): void {
this.chunkRetries = 0;
this._onCompleteChunkCallNext();
this.onCompleteChunk(response, status, headers);
}
public _onCompleteChunkCallNext(): void {
this.uploader.uploaderService.uploadFile(this,this.uploader.options);
this.prepareNextChunk()
}
public _onErrorChunk(response: string, status: number, headers: HttpHeaders): void {
if (this.chunkRetries > this.chunkTotalRetries) {
this.uploader.onErrorItem(this, response, status, headers);
this.uploader.onCompleteItem(this, response, status, headers);
} else {
this.chunkRetries++;
this.fileChunks.retrocedeChunk();
this._onCompleteChunkCallNext();
}
}
public _prepareToUploading(): void {
this.index = this.index || ++this.uploader._nextIndex;
this.isReady = true;

View File

@@ -1,4 +1,4 @@
import { FileLikeObject } from "../ng2-chunk-file-upload";
import { FileLikeObject } from "../index";
export class FileType {
/* MS office */
@@ -125,6 +125,7 @@ export class FileType {
'xls': 'xls',
'xlsx': 'xls',
'ods': 'xls',
'csv': 'xls',
'mp4': 'video',
'avi': 'video',
'wmv': 'video',

View File

@@ -1,10 +1,8 @@
import { Headers } from './file-uploader.class';
import { EventEmitter } from '@angular/core';
import { FileLikeObject } from './file-like-object.class';
import { FileItem } from './file-item.class';
import { FileType } from './file-type.class';
import { HttpEvent, HttpResponse, HttpHeaders } from '@angular/common/http';
import { HttpUploadProgressEvent, HttpProgressEvent, HttpSentEvent, HttpErrorResponse } from '@angular/common/http/src/response';
function isFile(value: any): boolean {
return (File && value instanceof File);
}
@@ -14,6 +12,7 @@ export interface Headers {
value: string;
}
export type ParsedResponseHeaders = { [ headerFieldName: string ]: string };
export type FilterFunction = {
name: string,
@@ -21,7 +20,6 @@ export type FilterFunction = {
};
export interface FileUploaderOptions {
uploaderService: any;
allowedMimeType?: string[];
allowedFileType?: string[];
autoUpload?: boolean;
@@ -44,7 +42,7 @@ export interface FileUploaderOptions {
}
export class FileUploader {
public uploaderService: any;
public authToken: string;
public isUploading: boolean = false;
public queue: FileItem[] = [];
@@ -53,9 +51,8 @@ export class FileUploader {
public autoUpload: any;
public authTokenHeader: string;
public response: EventEmitter<any>;
public chunkSize: number = null;
public options: FileUploaderOptions = {
uploaderService: null,
autoUpload: false,
isHTML5: true,
filters: [],
@@ -71,10 +68,10 @@ export class FileUploader {
this.setOptions(options);
this.response = new EventEmitter<any>();
}
public setOptions(options: FileUploaderOptions): void {
this.options = Object.assign(this.options, options);
this.uploaderService = this.options.uploaderService;
this.uploaderService.uploader = this;
this.authToken = this.options.authToken;
this.authTokenHeader = this.options.authTokenHeader || 'Authorization';
this.autoUpload = this.options.autoUpload;
@@ -139,7 +136,6 @@ export class FileUploader {
}
this.queue.splice(index, 1);
this.progress = this._getTotalProgress();
this.onRemoveItem(item);
}
public clearQueue(): void {
@@ -152,24 +148,26 @@ export class FileUploader {
public uploadItem(value: FileItem): void {
let index = this.getIndexOfItem(value);
let item = this.queue[ index ];
let transport = this.options.isHTML5 ? '_xhrTransport' : '_iframeTransport';
item._prepareToUploading();
if (this.isUploading) {
return;
}
this.isUploading = true;
this._uploadFile(item);
(this as any)[ transport ](item);
}
public cancelItem(value: FileItem): void {
const index = this.getIndexOfItem(value);
const item = this.queue[index];
let index = this.getIndexOfItem(value);
let item = this.queue[ index ];
let prop = this.options.isHTML5 ? item._xhr : item._form;
if (item && item.isUploading) {
this.uploaderService.stopUpload()
prop.abort();
}
}
public uploadAll(): void {
const items = this.getNotUploadedItems().filter((item: FileItem) => !item.isUploading);
let items = this.getNotUploadedItems().filter((item: FileItem) => !item.isUploading);
if (!items.length) {
return;
}
@@ -178,7 +176,7 @@ export class FileUploader {
}
public cancelAll(): void {
const items = this.getNotUploadedItems();
let items = this.getNotUploadedItems();
items.map((item: FileItem) => item.cancel());
}
@@ -194,23 +192,6 @@ export class FileUploader {
return typeof value === 'number' ? value : this.queue.indexOf(value);
}
public getIsErrorItems(): any[] {
return this.queue.filter((item: FileItem) => item.isError);
}
public getIsCancelItems(): any[] {
return this.queue.filter((item: FileItem) => item.isCancel);
}
public getIsSuccessItems(): any[] {
return this.queue.filter((item: FileItem) => item.isSuccess);
}
public getAllItems(): any[] {
return this.queue;
}
public getNotUploadedItems(): any[] {
return this.queue.filter((item: FileItem) => !item.isUploaded);
}
@@ -253,27 +234,19 @@ export class FileUploader {
return { progress };
}
public onSuccessItem(item: FileItem, response: string, status: number, headers: HttpHeaders): any {
public onSuccessItem(item: FileItem, response: string, status: number, headers: ParsedResponseHeaders): any {
return { item, response, status, headers };
}
public onErrorItem(item: FileItem, response: string, status: number, headers: HttpHeaders): any {
public onErrorItem(item: FileItem, response: string, status: number, headers: ParsedResponseHeaders): any {
return { item, response, status, headers };
}
public onCancelItem(item: FileItem): any {
return { item };
}
public onRemoveItem(item: FileItem): any {
return { item };
}
public onCompleteChunk(item: FileItem, response: string, status: number, headers: HttpHeaders): any {
public onCancelItem(item: FileItem, response: string, status: number, headers: ParsedResponseHeaders): any {
return { item, response, status, headers };
}
public onErrorChunk(item: FileItem, response: string, status: number, headers: HttpHeaders): any {
return { item, response, status, headers };
}
public onCompleteItem(item: FileItem, response: string, status: number, headers: HttpHeaders): any {
public onCompleteItem(item: FileItem, response: string, status: number, headers: ParsedResponseHeaders): any {
return { item, response, status, headers };
}
@@ -294,17 +267,12 @@ export class FileUploader {
this.options.allowedFileType.indexOf(FileType.getMimeClass(item)) === -1);
}
public _onErrorItem(item: FileItem, response: string, status: number, headers: HttpHeaders): void {
public _onErrorItem(item: FileItem, response: string, status: number, headers: ParsedResponseHeaders): void {
item._onError(response, status, headers);
this.onErrorItem(item, response, status, headers);
}
public _onCompleteChunk(item: FileItem, response: string, status: number, headers: HttpHeaders): void {
this.onCompleteChunk(item, response, status, headers);
item._onCompleteChunk(response, status, headers);
this.progress = this._getTotalProgress();
this._render();
}
public _onCompleteItem(item: FileItem, response?: string, status?: number, headers?: HttpHeaders): void {
public _onCompleteItem(item: FileItem, response: string, status: number, headers: ParsedResponseHeaders): void {
item._onComplete(response, status, headers);
this.onCompleteItem(item, response, status, headers);
let nextItem = this.getReadyItems()[ 0 ];
@@ -318,74 +286,104 @@ export class FileUploader {
this._render();
}
protected _onProgress(event: HttpProgressEvent, item: FileItem) {
event = event;
let progress = (100 * event.loaded / event.total);
if (this.uploaderService.options.chunkSize > 0) {
progress = ( 100 * item.getCurrentChunk() / item.getTotalChunks() ) + (progress / item.getTotalChunks() );
protected _headersGetter(parsedHeaders: ParsedResponseHeaders): any {
return (name: any): any => {
if (name) {
return parsedHeaders[ name.toLowerCase() ] || void 0;
}
// TODO: Check why it's not showing upload progress per item only on complete.
this._onProgressItem(item, Math.round(progress) );
}
public onProgress(event: HttpProgressEvent, item: FileItem) {
this._onProgress(event, item);
}
protected _onStart(event: HttpSentEvent, item: FileItem) {
}
public onStart(event: HttpSentEvent, item: FileItem) {
this._onStart(event, item);
}
protected _onLoad(event: HttpResponse<any>, item: FileItem) {
const headers = event.headers;
const response = this._transformResponse(event.body, headers);
const gist = this._isSuccessCode(event.status) ? 'Success' : 'Error';
const method = '_on' + gist + 'Item';
if (this.uploaderService.options.chunkSize > 0) {
if ( (item.getCurrentChunk() +1) >= item.getTotalChunks()) {
(this as any)[method](item, response, event.status, headers);
this._onCompleteItem(item, response, event.status, headers);
} else {
this._onCompleteChunk(item, response, event.status, headers);
}
} else {
(this as any)[method](item, response, event.status, headers);
this._onCompleteItem(item, response, event.status, headers);
return parsedHeaders;
};
}
}
public onLoad(event: HttpResponse<any>, item: FileItem) {
this._onLoad(event, item);
}
protected _onError(error: any, item: FileItem) {
const headers: HttpHeaders = error.Headers
const response = this._transformResponse(error.error, headers);
if (this.uploaderService.options.chunkSize > 0) {
this._onErrorChunk(item, response, error.status, headers);
} else {
this._onErrorItem(item, response, error.status, headers);
this._onCompleteItem(item, response, error.status, headers);
}
}
public onError(error: HttpErrorResponse, item: FileItem) {
this._onError(error,item);
}
protected _onAbort(error: HttpErrorResponse, item: FileItem) {
this._onCancelItem(item);
this._onCompleteItem(item);
}
public onAbort(error: HttpErrorResponse, item: FileItem) {
this._onAbort(error, item);
}
protected _uploadFile(item: FileItem): any {
protected _xhrTransport(item: FileItem): any {
let that = this;
let xhr = item._xhr = new XMLHttpRequest();
let sendable: any;
this._onBeforeUploadItem(item);
if (typeof item._file.size !== 'number') {
throw new TypeError('The file specified is no longer valid');
}
this.uploaderService.uploadFile(item, this.options);
if (!this.options.disableMultipart) {
sendable = new FormData();
this._onBuildItemForm(item, sendable);
const appendFile = () => sendable.append(item.alias, item._file, item.file.name);
if (!this.options.parametersBeforeFiles) {
appendFile();
}
// For AWS, Additional Parameters must come BEFORE Files
if (this.options.additionalParameter !== undefined) {
Object.keys(this.options.additionalParameter).forEach((key: string) => {
let paramVal = this.options.additionalParameter[ key ];
// Allow an additional parameter to include the filename
if (typeof paramVal === 'string' && paramVal.indexOf('{{file_name}}') >= 0) {
paramVal = paramVal.replace('{{file_name}}', item.file.name);
}
sendable.append(key, paramVal);
});
}
if (this.options.parametersBeforeFiles) {
appendFile();
}
} else {
sendable = this.options.formatDataFunction(item);
}
xhr.upload.onprogress = (event: any) => {
let progress = Math.round(event.lengthComputable ? event.loaded * 100 / event.total : 0);
this._onProgressItem(item, progress);
};
xhr.onload = () => {
let headers = this._parseHeaders(xhr.getAllResponseHeaders());
let response = this._transformResponse(xhr.response, headers);
let gist = this._isSuccessCode(xhr.status) ? 'Success' : 'Error';
let method = '_on' + gist + 'Item';
(this as any)[ method ](item, response, xhr.status, headers);
this._onCompleteItem(item, response, xhr.status, headers);
};
xhr.onerror = () => {
let headers = this._parseHeaders(xhr.getAllResponseHeaders());
let response = this._transformResponse(xhr.response, headers);
this._onErrorItem(item, response, xhr.status, headers);
this._onCompleteItem(item, response, xhr.status, headers);
};
xhr.onabort = () => {
let headers = this._parseHeaders(xhr.getAllResponseHeaders());
let response = this._transformResponse(xhr.response, headers);
this._onCancelItem(item, response, xhr.status, headers);
this._onCompleteItem(item, response, xhr.status, headers);
};
xhr.open(item.method, item.url, true);
xhr.withCredentials = item.withCredentials;
if (this.options.headers) {
for (let header of this.options.headers) {
xhr.setRequestHeader(header.name, header.value);
}
}
if (item.headers.length) {
for (let header of item.headers) {
xhr.setRequestHeader(header.name, header.value);
}
}
if (this.authToken) {
xhr.setRequestHeader(this.authTokenHeader, this.authToken);
}
xhr.onreadystatechange = function () {
if (xhr.readyState == XMLHttpRequest.DONE) {
that.response.emit(xhr.responseText)
}
}
if (this.options.formatDataFunctionIsAsync) {
sendable.then(
(result: any) => xhr.send(JSON.stringify(result))
);
} else {
xhr.send(sendable);
}
this._render();
}
protected _getTotalProgress(value: number = 0): number {
@@ -434,10 +432,29 @@ export class FileUploader {
return (status >= 200 && status < 300) || status === 304;
}
protected _transformResponse(response: string, headers: HttpHeaders): string {
protected _transformResponse(response: string, headers: ParsedResponseHeaders): string {
return response;
}
protected _parseHeaders(headers: string): ParsedResponseHeaders {
let parsed: any = {};
let key: any;
let val: any;
let i: any;
if (!headers) {
return parsed;
}
headers.split('\n').map((line: any) => {
i = line.indexOf(':');
key = line.slice(0, i).trim().toLowerCase();
val = line.slice(i + 1).trim();
if (key) {
parsed[ key ] = parsed[ key ] ? parsed[ key ] + ', ' + val : val;
}
});
return parsed;
}
protected _onWhenAddingFileFailed(item: FileLikeObject, filter: any, options: any): void {
this.onWhenAddingFileFailed(item, filter, options);
}
@@ -455,30 +472,27 @@ export class FileUploader {
this.onBeforeUploadItem(item);
}
public _onBuildItemForm(item: FileItem, form: any): void {
protected _onBuildItemForm(item: FileItem, form: any): void {
item._onBuildForm(form);
this.onBuildItemForm(item, form);
}
protected _onProgressItem(item: FileItem, progress: any): void {
const total = this._getTotalProgress(progress);
let total = this._getTotalProgress(progress);
this.progress = total;
item._onProgress(progress);
this.onProgressItem(item, progress);
this.onProgressAll(total);
this._render();
}
protected _onErrorChunk(item: FileItem, response: string, status: number, headers: HttpHeaders): void {
item._onErrorChunk(response, status, headers);
this.onErrorChunk(item, response, status, headers)
}
protected _onSuccessItem(item: FileItem, response: string, status: number, headers: HttpHeaders): void {
protected _onSuccessItem(item: FileItem, response: string, status: number, headers: ParsedResponseHeaders): void {
item._onSuccess(response, status, headers);
this.onSuccessItem(item, response, status, headers);
}
protected _onCancelItem(item: FileItem): void {
item._onCancel();
this.onCancelItem(item);
protected _onCancelItem(item: FileItem, response: string, status: number, headers: ParsedResponseHeaders): void {
item._onCancel(response, status, headers);
this.onCancelItem(item, response, status, headers);
}
}

View File

@@ -1,358 +0,0 @@
import { HttpErrorResponse } from '@angular/common/http/src/response';
import { FileUploaderOptions, FileUploader } from './file-uploader.class';
import { FileItem } from './file-item.class';
import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders, HttpRequest, HttpEventType } from '@angular/common/http';
import { Observable, of} from 'rxjs';
import { map } from 'rxjs/operators';
export interface UploaderLinksOptions {
downloadEntry: string;
updateEntry: string;
createEntry: string;
deleteEntry: string;
}
export interface UploaderServiceOptions {
createMethod: string;
updateMethod: string;
authorizationHeaderName?: string;
tokenPattern?: string;
token?: string;
chunkSize?: number;
totalChunkParamName?: string;
currentChunkParamName?: string;
fileParamName?: string;
idAttribute?: string;
}
@Injectable()
export class FileUploaderService {
public defaultLinks: UploaderLinksOptions = {
downloadEntry: '',
updateEntry: '',
createEntry: '',
deleteEntry: ''
};
public defaultOptions: UploaderServiceOptions = {
createMethod: 'POST',
updateMethod: 'POST',
authorizationHeaderName: 'Authorization',
tokenPattern: null,
token: null,
chunkSize: 0,
totalChunkParamName: 'total_chunks',
currentChunkParamName: 'current_chunk',
fileParamName: 'file',
idAttribute: 'id'
};
public additionalHeaders:any = {};
protected cancelError = 'UPLOAD CANCELED';
protected uploadSubscription: any = null;
public links: UploaderLinksOptions;
public options: UploaderServiceOptions;
private _uploader: FileUploader = null;
constructor(protected http: HttpClient) {
this.links = Object.assign({}, this.defaultLinks, this.links);
this.options = Object.assign({}, this.defaultOptions, this.options);
}
get uploader(): FileUploader {
return this._uploader;
}
set uploader(theUploader: FileUploader) {
this._uploader = theUploader;
}
public onBeforeUpload(
item: FileItem,
options: FileUploaderOptions
): Promise<any> {
const promise = new Promise((resolve, reject) => {
resolve(true);
});
return promise;
}
public uploadFile(item: FileItem, options: FileUploaderOptions): void {
this.onBeforeUpload(item, options).then(() => {
this._uploadFile(item, options);
});
}
public onBeforeGetDefaultHeaders(): Promise<any> {
const promise = new Promise((resolve, reject) => {
resolve(true);
});
return promise;
}
protected _getDefaultHeaders(): Promise<any> {
return new Promise((resolve, reject) => {
this.onBeforeGetDefaultHeaders().then(
result => {
const h: any = {};
if (this.options.tokenPattern && this.options.token) {
h[
this.options.authorizationHeaderName
] = this.options.tokenPattern.replace(
'#token#',
this.options.token
);
}
for (const key in this.additionalHeaders) {
if (this.additionalHeaders.hasOwnProperty(key)) {
h[key] = this.additionalHeaders[key];
}
}
resolve(h);
},
error => {
reject(error);
}
);
});
}
protected _getRequestHeaders(
item: FileItem,
options: FileUploaderOptions
): Promise<any> {
return new Promise((resolve, reject) => {
this._getDefaultHeaders().then(
h => {
if (options.headers) {
for (let header of options.headers) {
h[header.name] = header.value;
}
}
if (item.headers.length) {
for (let header of item.headers) {
h[header.name] = header.value;
}
}
resolve(h);
},
error => {
reject(error);
}
);
});
}
public buildPackageToSend(item: FileItem, options: FileUploaderOptions) {
let sendable: FormData = new FormData();
this.uploader._onBuildItemForm(item, sendable);
let file: any = null;
if (this.options.chunkSize > 0) {
file = item.getCurrentChunkFile();
} else {
file = item._file;
}
const appendFile = () =>
sendable.append(this.options.fileParamName, file, item.file.name);
if (!options.parametersBeforeFiles) {
appendFile();
}
// For AWS, Additional Parameters must come BEFORE Files
if (options.additionalParameter !== undefined) {
Object.keys(options.additionalParameter).forEach((key: string) => {
let paramVal = options.additionalParameter[key];
// Allow an additional parameter to include the filename
if (
typeof paramVal === 'string' &&
paramVal.indexOf('{{file_name}}') >= 0
) {
paramVal = paramVal.replace('{{file_name}}', item.file.name);
}
sendable.append(key, paramVal);
});
}
if (this.options.chunkSize > 0 && this.options.totalChunkParamName) {
sendable.append(
this.options.totalChunkParamName,
item.getTotalChunks().toString()
);
}
if (this.options.chunkSize > 0 && this.options.currentChunkParamName) {
sendable.append(
this.options.currentChunkParamName,
(item.getCurrentChunk() + 1).toString()
);
}
if (options.parametersBeforeFiles) {
appendFile();
}
return sendable;
}
protected _uploadFile(item: FileItem, options: FileUploaderOptions): void {
this._getRequestHeaders(item, options).then(
headers => {
let request_method = this.options.createMethod;
let link = this.links.createEntry;
item.setIsUploading(true);
if (this.options.chunkSize > 0) {
try {
item.getCurrentChunk();
} catch (err) {
item.createFileChunk(this.options.chunkSize);
}
request_method =
item.getCurrentChunk() > 0
? this.options.updateMethod
: this.options.createMethod;
link =
item.getCurrentChunk() > 0
? this.links.updateEntry
: this.links.createEntry;
}
if (item.getId()) {
link = link.replace('#id#', item.getId());
}
const data = this.buildPackageToSend(item, options);
const request = new HttpRequest(request_method, link, data, {
headers: new HttpHeaders(headers),
reportProgress: true,
withCredentials: item.withCredentials,
});
this.uploadSubscription = this.http.request(request).subscribe(
(event: any) => {
this.getEventMessage(event, item);
},
(error: any) => {
if (this.cancelError === error) {
this.uploader.onAbort(error, item);
} else {
this.uploader.onError(error, item);
}
}
);
},
error => {}
);
}
public stopUpload() {
if (this.uploadSubscription && this.uploadSubscription.unsubscribe) {
this.uploadSubscription.error(this.cancelError);
}
}
private getEventMessage(event: any, item: FileItem) {
switch (event.type) {
case HttpEventType.ResponseHeader:
break;
case HttpEventType.Sent:
this.uploader.onStart(event, item);
break;
case HttpEventType.UploadProgress:
this.uploader.onProgress(event, item);
break;
case HttpEventType.Response:
if (this.options.chunkSize > 0) {
if (item.getCurrentChunk() === 0) {
const response = event.body;
if (response[this.options.idAttribute]) {
item.setId(response[this.options.idAttribute]);
}
}
}
this.uploader.onLoad(event, item);
break;
default:
break;
}
}
private handleError(item: FileItem) {
const userMessage = `${item.file.name} upload failed.`;
return (error: HttpErrorResponse) => {
this.uploader.onError(error, item);
const message =
error.error instanceof Error
? error.error.message
: `server returned code ${error.status} with body "${error.error}"`;
return of (userMessage);
};
}
public deleteEntry(
item: FileItem,
options = {},
skipConfirmation = false
): Observable <any> {
if (item.getId() && this.links['deleteEntry']) {
let link = this.links['deleteEntry'].replace(/#id#/g, item.getId());
let confirmation = false;
if (skipConfirmation) {
confirmation = true;
} else {
confirmation = confirm('Are you sure you want to delete this entry?');
}
if (confirmation) {
return this.delete(link, options)
} else {
return of(false);
}
} else {
return of(false);
}
}
protected delete(url: string, options = {}): Observable<any> {
return new Observable((observe:any) => {
this._getDefaultHeaders().then(
function(headers: any) {
return this.http
.delete(url, { headers: new HttpHeaders(headers) })
.subscribe(
(response: Response) => {
observe.next(response);
},
(error: any) => {
observe.error(error);
}
);
}.bind(this),
error => {
observe.error(error);
}
);
});
}
/*
HTTP General methos only bellow
*/
protected get(url: string): Observable<any> {
return new Observable(observe => {
this._getDefaultHeaders().then(
function(headers:any) {
return this.http
.get(url, { headers: new HttpHeaders(headers) })
.subscribe(
(response: Response) => {
observe.next(response);
},
(error: any) => {
observe.error(error);
}
);
}.bind(this),
error => {
observe.error(error);
}
);
});
}
public addHeader(name:string = null, value:any = null) {
this.additionalHeaders[name] = value;
}
public removeHeader(name:string = null) {
if (this.additionalHeaders.hasOwnProperty(name)) {
delete this.additionalHeaders[name];
}
}
}

View File

@@ -3,6 +3,5 @@ export * from './file-upload/file-drop.directive';
export * from './file-upload/file-uploader.class';
export * from './file-upload/file-item.class';
export * from './file-upload/file-like-object.class';
export * from './file-upload/file-uploader.service';
export { FileUploadModule } from './file-upload/file-upload.module';

7
src/ng-package.json Normal file
View File

@@ -0,0 +1,7 @@
{
"$schema": "../node_modules/ng-packagr/ng-package.schema.json",
"dest": "../dist/ng2-file-upload",
"lib": {
"entryFile": "index.ts"
}
}

View File

@@ -1 +0,0 @@
export * from './index';

View File

@@ -1,5 +1,5 @@
{
"name": "ng2-chunk-file-upload",
"name": "ng2-file-upload",
"version": "1.3.0",
"peerDependencies": {
"@angular/common": "*",

View File

@@ -1,8 +1,9 @@
{
"compilerOptions": {
"baseUrl": ".",
"outDir": "../dist",
"target": "es5",
"module": "commonjs",
"module": "esnext",
"moduleResolution": "node",
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
@@ -14,24 +15,19 @@
"stripInternal": true,
"noUnusedLocals": false,
"noUnusedParameters": false,
"lib": ["dom", "es6"],
"types": [
"jasmine",
"webpack"
],
"typeRoots": [
"../node_modules/@types"
]
"lib": ["dom", "es6"]
},
"exclude": [
"node_modules"
],
"files": [
"../scripts/typings.d.ts",
"./ng2-chunk-file-upload.ts",
"./index.ts"
],
"angularCompilerOptions": {
"genDir": "../temp/factories"
}
"annotateForClosureCompiler": true,
"strictMetadataEmit": true,
"skipTemplateCodegen": true,
"flatModuleOutFile": "ng2-file-upload.js",
"flatModuleId": "ng2-file-upload"
},
"include": [
"../scripts/typings.d.ts"
],
"exclude": [
"**/*.spec.ts"
]
}

View File

@@ -1,7 +1,7 @@
// Karma configuration file, see link for more information
// https://karma-runner.github.io/0.13/config/configuration-file.html
const customLaunchers = require('./scripts/sauce-browsers').customLaunchers;
const customLaunchers = require('./sauce-browsers').customLaunchers;
module.exports = function (config) {
const configuration = {
@@ -13,33 +13,30 @@ module.exports = function (config) {
require('karma-coverage-istanbul-reporter'),
require('@angular-devkit/build-angular/plugins/karma')
],
files: [
{pattern: './scripts/test.ts', watched: false}
],
preprocessors: {
'./scripts/test.ts': ['@angular-devkit/build-angular']
},
coverageIstanbulReporter: {
dir: require('path').join(__dirname, 'coverage'), reports: [ 'html', 'lcovonly' ],
dir: require('path').join(__dirname, '../coverage'), reports: [ 'html', 'lcovonly' ],
fixWebpackSourcePaths: false
},
angularCli: {
config: './angular-cli.json',
environment: 'dev'
},
reporters: config.angularCli && config.angularCli.codeCoverage
? ['dots', 'coverage-istanbul']
: ['dots'],
reporters: ['dots', 'coverage-istanbul'],
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: true,
browsers: ['Chrome'],
singleRun: false,
browsers: ['ChromeHeadless'],
browserNoActivityTimeout: 20000,
browserDisconnectTolerance: 2,
browserDisconnectTimeout: 5000,
singleRun: true,
customLaunchers: {
Chrome_travis_ci: {
base: 'Chrome',
flags: ['--no-sandbox']
base: 'ChromeHeadless',
flags: [
'--headless',
'--disable-gpu',
'--no-sandbox',
'--remote-debugging-port=9222'
]
}
},
mime: { 'text/x-typescript': ['ts','tsx'] },
@@ -70,10 +67,10 @@ module.exports = function (config) {
},
public: 'public'
};
configuration.captureTimeout = 0;
configuration.captureTimeout = 60000;
configuration.customLaunchers = customLaunchers();
configuration.browsers = Object.keys(configuration.customLaunchers);
configuration.concurrency = 3;
configuration.concurrency = 4;
configuration.browserDisconnectTolerance = 2;
configuration.browserNoActivityTimeout = 20000;
configuration.browserDisconnectTimeout = 5000;

View File

@@ -1,4 +1,4 @@
import '../demo/src/polyfills.ts';
import '../scripts/polyfills.ts';
import 'zone.js/dist/long-stack-trace-zone';
import 'zone.js/dist/proxy.js';

22
test/tsconfig.json Normal file
View File

@@ -0,0 +1,22 @@
{
"compilerOptions": {
"experimentalDecorators": true,
"module": "esnext",
"moduleResolution": "node",
"target": "es2015",
"outDir": "./out-tsc/spec",
"types": [
"jasmine",
"node"
]
},
"files": [
"../scripts/typings.d.ts",
"test.ts",
"../scripts/polyfills.ts",
],
"include": [
"../src/**/*.spec.ts",
"../demo/src/**/*.spec.ts"
]
}

View File

@@ -1,24 +0,0 @@
{
"compileOnSave": false,
"compilerOptions": {
"outDir": "./dist/out-tsc",
"sourceMap": true,
"declaration": false,
"moduleResolution": "node",
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"target": "es5",
"typeRoots": [
"node_modules/@types"
],
"lib": [
"es2017",
"dom"
],
"plugins": [
{
"name": "tslint-language-service"
}
]
}
}

View File

@@ -1,136 +1,12 @@
{
"rulesDirectory": [
"node_modules/codelyzer"
],
"extends": "tslint-config-valorsoft",
"rulesDirectory": "./node_modules/codelyzer",
"rules": {
"trailing-comma": [
true,
{
"multiline": "always",
"singleline": "never"
}
],
"arrow-return-shorthand": true,
"callable-types": true,
"class-name": true,
"comment-format": [
true,
"check-space"
],
"eofline": true,
"forin": true,
"import-blacklist": [
true
],
"import-spacing": true,
"indent": [
true,
"tabs",
4
],
"interface-over-type-literal": true,
"label-position": true,
"max-line-length": [
true,
180
],
"member-access": false,
"no-arg": true,
"no-console": [
true,
"debug",
"log",
"time",
"timeEnd",
"trace"
],
"no-construct": true,
"no-debugger": true,
"no-duplicate-super": true,
"no-empty": false,
"no-empty-interface": true,
"no-eval": true,
"no-misused-new": true,
"no-non-null-assertion": true,
"no-shadowed-variable": true,
"no-string-literal": false,
"no-string-throw": true,
"no-switch-case-fall-through": true,
"no-trailing-whitespace": true,
"no-unnecessary-initializer": true,
"no-use-before-declare": true,
"no-var-keyword": true,
"object-literal-sort-keys": false,
"one-line": [
true,
"check-open-brace",
"check-catch",
"check-else",
"check-whitespace"
],
"prefer-const": true,
"quotemark": [
true,
"single"
],
"radix": true,
"semicolon": [
true
],
"triple-equals": [
true,
"allow-null-check"
],
"typedef-whitespace": [
true,
{
"call-signature": "nospace",
"index-signature": "nospace",
"parameter": "nospace",
"property-declaration": "nospace",
"variable-declaration": "nospace"
}
],
"typeof-compare": true,
"unified-signatures": true,
"variable-name": false,
"whitespace": [
true,
"check-branch",
"check-decl",
"check-operator",
"check-separator",
"check-type"
],
"directive-selector": [
true,
"attribute",
"ngx",
"camelCase"
],
"component-selector": [
true,
"element",
"ngx",
"kebab-case"
],
"ban": [
true,
"eval",
"fit",
"fdescribe",
{
"name": "$",
"message": "please don't"
}
],
"use-input-property-decorator": true,
"use-output-property-decorator": true,
"no-output-rename": true,
"use-life-cycle-interface": true,
"use-pipe-transform-interface": true,
"component-class-suffix": true,
"directive-class-suffix": true,
"no-unused-variable": true
"no-forward-ref": false,
"no-null-keyword": false,
"only-arrow-functions": false,
"no-access-missing-member": false,
"directive-selector": false,
"component-selector": false
}
}