Skip to content

Commit

Permalink
Merge pull request #78 from unicef-polymer/develop
Browse files Browse the repository at this point in the history
Develop
  • Loading branch information
acory authored May 4, 2021
2 parents 915a257 + cabc667 commit b6f7e40
Show file tree
Hide file tree
Showing 5 changed files with 92 additions and 61 deletions.
1 change: 1 addition & 0 deletions EtoolsUploadMulti.js
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,7 @@ export class EtoolsUploadMulti extends RequestHelperMulti(CommonMixin(PolymerEle
filetype: files[i].type,
filename: files[i].name,
extraInfo: this.endpointInfo ? this.endpointInfo.extraInfo : '',
parentId: window.OfflineUploadParentId || ((this.endpointInfo && this.endpointInfo.extraInfo) ? this.endpointInfo.extraInfo.parentId : ''),
unsynced: true
}

Expand Down
115 changes: 59 additions & 56 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,76 +3,81 @@
Use to upload files

## Install

`$ npm i --save @unicef-polymer/etools-upload`

## Description

Polymer 3 component used for uploading files.
When `autoUpload` is true and `uploadEndpoint` is set , it automatically uploads the file and returns an `id` stored in the `fileUrl` property.

### Offline functionality
* If the `activateOffline` attribute is set on the <etools-upload-multi> component, if there is no internet connection during the upload, the file is saved in local IndexedDb with a temp id.
* The component expects `window.Etools.AttachmentsDbName` to be set from the parent application.
* The IndexedDb is created on `connectedCallback`. If you need the db to exist prior to this you can call `createAttachmentsDexie` method directly from your code.
* When the files have finished being saved in IndexedDb the same event as for online upload is fired - `upload-finished`. The event detail has the following format
- {success:[{info about file}], error:[{error}]}
* Any other extra information can be saved in IndexedDb along with the file by setting property `endpointInfo.extraInfo` :{} on the component.


- If the `activateOffline` attribute is set on the <etools-upload-multi> component, if there is no internet connection during the upload, the file is saved in local IndexedDb with a temp id.
- The component expects `window.Etools.AttachmentsDbName` to be set from the parent application.
- The IndexedDb is created on `connectedCallback`. If you need the db to exist prior to this you can call `createAttachmentsDexie` method directly from your code.
- When the files have finished being saved in IndexedDb the same event as for online upload is fired - `upload-finished`. The event detail has the following format
- {success:[{info about file}], error:[{error}]}
- Any other extra information can be saved in IndexedDb along with the file by setting property `endpointInfo.extraInfo` :{} on the component.

### Components
* \<etools-upload\>
* \<etools-upload-multi\>

- \<etools-upload\>
- \<etools-upload-multi\>

### Resusable Methods
1. `dexie-operations` file: Methods to interact with Dexie db
2. `upload-helper` file exposes reusable methods that can upload files and receives a `config` object as param:
- you can use `upload` method if you have the binary data of the file
- `uploadFileStoredInDexie` gets a file stored in IndexedDb , uploads it then deletes it from IndexedDb

```
Config param expected format:
config = {
endpointInfo?: {
endpoint: 'url',
extraInfo: {any: any},
rawFilePropertyName: 'attachment'
},
uploadEndpoint: '',
jwtLocalStorageKey?: ''
}

```

1. `dexie-operations` file: Methods to interact with Dexie db
2. `upload-helper` file exposes reusable methods that can upload files and receives a `config` object as param:

- you can use `upload` method if you have the binary data of the file
- `uploadFileStoredInDexie` gets a file stored in IndexedDb , uploads it then deletes it from IndexedDb

```

Config param expected format:
config = {
endpointInfo?: {
endpoint: 'url',
extraInfo: {any: any},
rawFilePropertyName: 'attachment'
},
uploadEndpoint: '',
jwtLocalStorageKey?: ''
}

```
```

### Upload component features

1. `label`: text to be displayed on top of the control
2. `uploadBtnLabel`: text to be displayed on the button, default is 'Upload file'
3. `accept`: accepted file types (Ex: ".doc,.docx,.pdf,.jpg,.png")
4. `file-url`: When a new file is uploaded and the upload has finished it holds the id of the file. After the id is saved on the entity for which the upload was made, it will hold the url to the file.
5. `upload-endpoint`: url for the upload
6. `readonly`: can be used as html attribute or polymer property (Ex: readonly$="[[!permissions.allowEdit]]"), enable/disable upload control
7. `required`: can be used as html attribute or polymer property (Ex: required$="[[permissions.allowEdit]]"), specifies if control must be filled out
8. `auto-validate`: if set to true and control is required validate if control is set
9. `error-message`: custom text to be displayed on upload error
1. `label`: text to be displayed on top of the control
2. `uploadBtnLabel`: text to be displayed on the button, default is 'Upload file'
3. `accept`: accepted file types (Ex: ".doc,.docx,.pdf,.jpg,.png")
4. `file-url`: When a new file is uploaded and the upload has finished it holds the id of the file. After the id is saved on the entity for which the upload was made, it will hold the url to the file.
5. `upload-endpoint`: url for the upload
6. `readonly`: can be used as html attribute or polymer property (Ex: readonly$="[[!permissions.allowEdit]]"), enable/disable upload control
7. `required`: can be used as html attribute or polymer property (Ex: required$="[[permissions.allowEdit]]"), specifies if control must be filled out
8. `auto-validate`: if set to true and control is required validate if control is set
9. `error-message`: custom text to be displayed on upload error
10. `auto-upload`: if `true` it automatically upload the file after selection. default is `true`.
11. `endpointInfo`: can be used to set any other information needed by the upload online or offline. If endpointInfo.endpoint is specified , uploadEndpoint is no longer needed.

- Expected format:
- Expected format:
{
endpoint: 'url',
/** Any extra properties with their values, that need to be set in the FormData on the upload request */
/** Any extra properties with their values, that need to be set in the FormData on the upload request, like parentId */
extraInfo: {any: any},

/**The name of the field that will hold the binary data in the FormData on the upload request. If not specified it defaults to `file*/
rawFilePropertyName: 'file'
}


#Buttons

10. `Download` button will be displayed after uploaded file was saved
11. `show-delete-btn`: if set to true, will display a 'Delete' button after file was selected, in order to be able to remove the file
11. `show-delete-btn`: if set to true, will display a 'Delete' button after file was selected, in order to be able to remove the file
12. `show-change`: if set to true, will display a 'Change' button after file was selected, in order to be able to replace the file
13. `jwtLocalStorageKey` specifies the local storage key where the token is stored. If `window.AppMsalInstance` is set , the component also checks the expiration of the token and silently refreshes it if needed.

Expand All @@ -83,25 +88,23 @@ When `autoUpload` is true and `uploadEndpoint` is set , it automatically uploads
15. `on-change-unsaved-file`: triggered on file selection if previous upload was not saved
16. `on-delete-file`: triggered on file delete with the file url as parameter (Ex: {file: fileUrl})


## Usage example

<etools-upload
label="Upload Example"
accept=".doc,.docx,.pdf,.jpg,.png"
file-url="{{data.file_attachment}}"
upload-endpoint="[[uploadEndpoint]]"
on-upload-finished="_onUploadFinished"
on-upload-started="_onUploadStarted"
show-delete-btn="[[showDeleteBtn(data.status, data.permissions.allowEdit)]]"
on-delete-file="_onAttachDelete"
accept=".doc,.docx,.pdf,.jpg,.png"
readonly$="[[!data.permissions.allowEdit]]"
<etools-upload
label="Upload Example"
accept=".doc,.docx,.pdf,.jpg,.png"
file-url="{{data.file_attachment}}"
upload-endpoint="[[uploadEndpoint]]"
on-upload-finished="\_onUploadFinished"
on-upload-started="\_onUploadStarted"
show-delete-btn="[[showDeleteBtn(data.status, data.permissions.allowEdit)]]"
on-delete-file="\_onAttachDelete"
accept=".doc,.docx,.pdf,.jpg,.png"
readonly$="[[!data.permissions.allowEdit]]"
required$="[[data.attach_required]]"
auto-validate
on-change-unsaved-file="_onChangeUnsavedFile">
</etools-upload>

auto-validate
on-change-unsaved-file="\_onChangeUnsavedFile">
</etools-upload>

## Install the Polymer-CLI

Expand Down
8 changes: 8 additions & 0 deletions offline/dexie-operations.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,11 @@ export declare function getFileFromDexieById(id: string): Promise<any>;
export declare function getFilesFromDexieByIds(ids: string[]): Promise<any[]>;

export declare function deleteFileFromDexie(id: string): Promise<any>; //TODO test if more specific return type can be provided

export declare function updateParentIdInDexie(oldParentId: string, newParentId: string);

export declare function updateProvidedPropertyNameInDexie(attId: string, propName: string, val: string);

export declare function deleteByParentIdFromDexie(parentId: string);

export declare function getFileCountByParentIdFromDexie(parentId: string);
23 changes: 23 additions & 0 deletions offline/dexie-operations.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,26 @@ export function deleteFileFromDexie(id) {
return window.Etools.AttachmentsDb.attachments.delete(id);
}

export function updateParentIdInDexie(oldParentId, newParentId) {
return window.Etools.AttachmentsDb.attachments
.where({parentId: oldParentId}).modify({parentId: newParentId});
}

export function updateProvidedPropertyNameInDexie(attId, propName, val) {
return window.Etools.AttachmentsDb.attachments
.where({id: attId}).modify({[propName]: val});
}

export function deleteByParentIdFromDexie(parentId) {
return window.Etools.AttachmentsDb.attachments
.where({parentId: parentId}).delete();
}

/**
* Avoid returning all files because they contain the binary data also and it's best to save memory
*/
export function getFileCountByParentIdFromDexie(parentId) {
return window.Etools.AttachmentsDb.attachments
.where({parentId: parentId}).count();
}

6 changes: 1 addition & 5 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@unicef-polymer/etools-upload",
"version": "3.4.0",
"version": "3.5.0",
"homepage": "https://github.com/unicef-polymer/etools-upload",
"repository": {
"type": "git",
Expand All @@ -17,7 +17,6 @@
"build": "polymer build",
"lint": "polymer lint",
"test": "polymer test",
"publish": "git push --tags && npm publish",
"test:integration": "polymer build # test that psk builds without error with the CLI",
"gen-typings": "gen-typescript-declarations --deleteExisting --outDir './'"
},
Expand Down Expand Up @@ -48,8 +47,5 @@
},
"engines": {
"node": ">=8.0"
},
"publishConfig": {
"access": "public"
}
}

0 comments on commit b6f7e40

Please sign in to comment.