Skip to content
Snippets Groups Projects
Commit 10d574f7 authored by Bekerle, Patrizio's avatar Bekerle, Patrizio :fire: Committed by Reiter, Christoph
Browse files

Integrate modal dialog to FileSink, introduce files property and add documentation (#14)

parent 4a863fbb
No related branches found
No related tags found
No related merge requests found
...@@ -22,10 +22,9 @@ files from a [Nextcloud](https://nextcloud.com/) instance. ...@@ -22,10 +22,9 @@ files from a [Nextcloud](https://nextcloud.com/) instance.
- example `<vpu-file-source allowed-mime-types='image/*'></vpu-file-source>` ... images (of all sub types) only - example `<vpu-file-source allowed-mime-types='image/*'></vpu-file-source>` ... images (of all sub types) only
- example `<vpu-file-source allowed-mime-types='image/png,text/plain'></vpu-file-source>` ... PNGs or TXTs only - example `<vpu-file-source allowed-mime-types='image/png,text/plain'></vpu-file-source>` ... PNGs or TXTs only
- example `<vpu-file-source allowed-mime-types='*/*'></vpu-file-source>` ... all file types (default) - example `<vpu-file-source allowed-mime-types='*/*'></vpu-file-source>` ... all file types (default)
- `enabled-sources` (optional): sets which sources are enabled - `enabled-sources` (optional, default: `local`): sets which sources are enabled
- you can use `local` and `nextcloud` - you can use `local` and `nextcloud`
- default is `local` - example `<vpu-file-source enabled-sources="local,nextcloud"></vpu-file-source>`
- example `<vpu-file-source enabled-sources='local,nextcloud'></vpu-file-source>`
- `disabled` (optional): disable input control - `disabled` (optional): disable input control
- example `<vpu-file-source disabled></vpu-file-source>` - example `<vpu-file-source disabled></vpu-file-source>`
- `decompress-zip` (optional): decompress zip file and send the contained files (including files in folders) - `decompress-zip` (optional): decompress zip file and send the contained files (including files in folders)
...@@ -37,8 +36,12 @@ files from a [Nextcloud](https://nextcloud.com/) instance. ...@@ -37,8 +36,12 @@ files from a [Nextcloud](https://nextcloud.com/) instance.
- `nextcloud-web-dav-url` (optional): Nextcloud WebDav Url to use with the Nextcloud file picker - `nextcloud-web-dav-url` (optional): Nextcloud WebDav Url to use with the Nextcloud file picker
- example `<vpu-file-source nextcloud-web-dav-url="http://localhost:8081/remote.php/dav/files"></vpu-file-source>` - example `<vpu-file-source nextcloud-web-dav-url="http://localhost:8081/remote.php/dav/files"></vpu-file-source>`
- `nextcloud-auth-url` also needs to be set for the Nextcloud file picker to be active - `nextcloud-auth-url` also needs to be set for the Nextcloud file picker to be active
- `dialog-open` (optional): If this attribute is set the dialog for selecting local or Nextcloud files will open - `dialog-open` (optional): if this attribute is set the dialog for selecting local or Nextcloud files will open
- example `<vpu-file-source dialog-open></vpu-file-source>` - example `<vpu-file-source dialog-open></vpu-file-source>`
- `text` (optional): the text that is shown above the button to select files
- example `<vpu-file-source text="Please select some files"></vpu-file-source>`
- `button-label` (optional): the text that is shown on the button to select files
- example `<vpu-file-source button-label="Select files"></vpu-file-source>`
### Outgoing Events ### Outgoing Events
...@@ -61,37 +64,32 @@ This web component is able to receive files and present as them as ZIP file down ...@@ -61,37 +64,32 @@ This web component is able to receive files and present as them as ZIP file down
### Attributes ### Attributes
- `lang` (optional, default: `de`): set to `de` or `en` for German or English - `lang` (optional, default: `de`): set to `de` or `en` for German or English
- example `<vpu-file-source lang="de"></vpu-file-source>` - example `<vpu-file-sink lang="de"></vpu-file-sink>`
- `enabled-destinations` (optional, default: `local`): sets which destination are enabled
- you can use `local` and `nextcloud`
- example `<vpu-file-sink enabled-destinations="local,nextcloud"></vpu-file-sink>`
- `filename` (optional, default: `files.zip`): sets a file name to use for downloading the zip file
- example `<vpu-file-sink filename="signed-documents.zip"></vpu-file-sink>`
- `nextcloud-auth-url` (optional): Nextcloud Auth Url to use with the Nextcloud file picker - `nextcloud-auth-url` (optional): Nextcloud Auth Url to use with the Nextcloud file picker
- example `<vpu-file-source nextcloud-auth-url="http://localhost:8081/index.php/apps/webapppassword"></vpu-file-source>` - example `<vpu-file-sink nextcloud-auth-url="http://localhost:8081/index.php/apps/webapppassword"></vpu-file-sink>`
- `nextcloud-web-dav-url` also needs to be set for the Nextcloud file picker to be active - `nextcloud-web-dav-url` also needs to be set for the Nextcloud file picker to be active
- `nextcloud-web-dav-url` (optional): Nextcloud WebDav Url to use with the Nextcloud file picker - `nextcloud-web-dav-url` (optional): Nextcloud WebDav Url to use with the Nextcloud file picker
- example `<vpu-file-source nextcloud-web-dav-url="http://localhost:8081/remote.php/dav/files"></vpu-file-source>` - example `<vpu-file-sink nextcloud-web-dav-url="http://localhost:8081/remote.php/dav/files"></vpu-file-sink>`
- `nextcloud-auth-url` also needs to be set for the Nextcloud file picker to be active - `nextcloud-auth-url` also needs to be set for the Nextcloud file picker to be active
- `text` (optional): the text that is shown above the button to download the zip file
- example `<vpu-file-sink text="Download files as ZIP-file"></vpu-file-sink>`
- `button-label` (optional): the text that is shown on the button to download the zip file
- example `<vpu-file-sink button-label="Download files"></vpu-file-sink>`
### Incoming Events ### Properties
#### `vpu-file-sink-download-compressed-files`
If this event is received a *save-as* dialog will pop up to store a zip file of the received files. - `files`: an array of File objects which should be downloaded in the dialog
- if the property is set the dialog opens
##### Payload
`{'files': [File], 'filename': 'my-file.zip'}` where `[File]` is an array of binary files which should be
compressed and `filename` is the name of the zip file that should be suggested in the *save-as* dialog
##### Example
```javascript
const detail = { "files": files, "filename": "signed-documents.zip" };
const event = new CustomEvent("vpu-file-sink-download-compressed-files", { "detail": detail });
this._("#file-sink").dispatchEvent(event);
```
## Local development ## Local development
```bash ```bash
# get the source # get the source code
git clone git@gitlab.tugraz.at:VPU/WebComponents/FileHandling.git git clone git@gitlab.tugraz.at:VPU/WebComponents/FileHandling.git
cd FileHandling cd FileHandling
git submodule update --init git submodule update --init
......
...@@ -8,6 +8,7 @@ import * as commonStyles from 'vpu-common/styles'; ...@@ -8,6 +8,7 @@ import * as commonStyles from 'vpu-common/styles';
import {NextcloudFilePicker} from "./vpu-nextcloud-file-picker"; import {NextcloudFilePicker} from "./vpu-nextcloud-file-picker";
import {classMap} from 'lit-html/directives/class-map.js'; import {classMap} from 'lit-html/directives/class-map.js';
import FileSaver from 'file-saver'; import FileSaver from 'file-saver';
import MicroModal from "./micromodal.es";
/** /**
...@@ -19,8 +20,13 @@ export class FileSink extends ScopedElementsMixin(VPULitElement) { ...@@ -19,8 +20,13 @@ export class FileSink extends ScopedElementsMixin(VPULitElement) {
this.lang = 'de'; this.lang = 'de';
this.nextcloudAuthUrl = ''; this.nextcloudAuthUrl = '';
this.nextcloudWebDavUrl = ''; this.nextcloudWebDavUrl = '';
this.text = '';
this._onDownloadCompressedFiles = this.onDownloadCompressedFiles.bind(this); this.buttonLabel = '';
this.filename = "files.zip";
this.files = [];
this.activeDestination = 'local';
this.isDialogOpen = false;
this.enabledDestinations = 'local';
} }
static get scopedElements() { static get scopedElements() {
...@@ -37,24 +43,26 @@ export class FileSink extends ScopedElementsMixin(VPULitElement) { ...@@ -37,24 +43,26 @@ export class FileSink extends ScopedElementsMixin(VPULitElement) {
static get properties() { static get properties() {
return { return {
lang: { type: String }, lang: { type: String },
filename: { type: String },
files: { type: Array, attribute: false },
enabledDestinations: { type: String, attribute: 'enabled-destinations' },
nextcloudAuthUrl: { type: String, attribute: 'nextcloud-auth-url' }, nextcloudAuthUrl: { type: String, attribute: 'nextcloud-auth-url' },
nextcloudWebDavUrl: { type: String, attribute: 'nextcloud-web-dav-url' }, nextcloudWebDavUrl: { type: String, attribute: 'nextcloud-web-dav-url' },
text: { type: String },
buttonLabel: { type: String, attribute: 'button-label' },
isDialogOpen: { type: Boolean, attribute: false },
activeDestination: { type: Boolean, attribute: false },
}; };
} }
async onDownloadCompressedFiles(event) { async downloadCompressedFiles() {
const detail = event.detail;
console.log("event", event);
console.log("detail", detail);
// see: https://stuk.github.io/jszip/ // see: https://stuk.github.io/jszip/
let JSZip = (await import('jszip/dist/jszip.js')).default; let JSZip = (await import('jszip/dist/jszip.js')).default;
let zip = new JSZip(); let zip = new JSZip();
let fileNames = []; let fileNames = [];
// add all signed pdf-files // add all signed pdf-files
detail.files.forEach((file) => { this.files.forEach((file) => {
let fileName = file.name; let fileName = file.name;
// add pseudo-random string on duplicate file name // add pseudo-random string on duplicate file name
...@@ -70,7 +78,7 @@ export class FileSink extends ScopedElementsMixin(VPULitElement) { ...@@ -70,7 +78,7 @@ export class FileSink extends ScopedElementsMixin(VPULitElement) {
let content = await zip.generateAsync({type:"blob"}); let content = await zip.generateAsync({type:"blob"});
// see: https://github.com/eligrey/FileSaver.js#readme // see: https://github.com/eligrey/FileSaver.js#readme
FileSaver.saveAs(content, detail.filename || "files.zip"); FileSaver.saveAs(content, this.filename || "files.zip");
} }
update(changedProperties) { update(changedProperties) {
...@@ -79,25 +87,28 @@ export class FileSink extends ScopedElementsMixin(VPULitElement) { ...@@ -79,25 +87,28 @@ export class FileSink extends ScopedElementsMixin(VPULitElement) {
case "lang": case "lang":
i18n.changeLanguage(this.lang); i18n.changeLanguage(this.lang);
break; break;
case "enabledDestinations":
if (!this.hasEnabledDestination(this.activeDestination)) {
this.activeDestination = this.enabledDestinations.split(",")[0];
}
break;
case "files":
if (this.files.length !== 0 && !this.isDialogOpen) {
this.openDialog();
}
break;
} }
}); });
super.update(changedProperties); super.update(changedProperties);
} }
connectedCallback() { hasEnabledDestination(source) {
super.connectedCallback(); return this.enabledDestinations.split(',').includes(source);
this.updateComplete.then(() => {
this.addEventListener('vpu-file-sink-download-compressed-files', this._onDownloadCompressedFiles);
});
} }
disconnectedCallback() { uploadToNextcloud(directory) {
// remove event listeners console.log(directory);
window.removeEventListener('vpu-file-sink-download-compressed-files', this._onDownloadCompressedFiles);
super.disconnectedCallback();
} }
preventDefaults (e) { preventDefaults (e) {
...@@ -105,29 +116,88 @@ export class FileSink extends ScopedElementsMixin(VPULitElement) { ...@@ -105,29 +116,88 @@ export class FileSink extends ScopedElementsMixin(VPULitElement) {
e.stopPropagation(); e.stopPropagation();
} }
openDialog() {
console.log("openDialog");
MicroModal.show(this._('#modal-picker'), {
onClose: modal => { this.isDialogOpen = false; }
});
}
closeDialog() {
console.log("closeDialog");
MicroModal.close();
}
static get styles() { static get styles() {
// language=css // language=css
return css` return css`
${commonStyles.getGeneralCSS()} ${commonStyles.getGeneralCSS()}
${commonStyles.getButtonCSS()} ${commonStyles.getButtonCSS()}
${commonStyles.getModalDialogCSS()}
#zip-download-block {
height: 100%;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.block {
margin-bottom: 10px;
}
`; `;
} }
render() { render() {
return html` return html`
<!-- <div class="modal micromodal-slide" id="modal-picker" aria-hidden="true">
<vpu-nextcloud-file-picker id="nextcloud-file-picker" <div class="modal-overlay" tabindex="-1" data-micromodal-close>
class="${classMap({hidden: this.nextcloudWebDavUrl === "" || this.nextcloudAuthUrl === ""})}" <div class="modal-container" role="dialog" aria-modal="true" aria-labelledby="modal-picker-title">
directories-only <nav class="modal-nav">
select-button-text="${i18n.t('file-sink.select-directory')}" <div title="${i18n.t('file-sink.nav-local')}"
?disabled="${this.disabled}" @click="${() => { this.activeDestination = "local"; }}"
lang="${this.lang}" class="${classMap({"active": this.activeDestination === "local", hidden: !this.hasEnabledDestination("local")})}">
auth-url="${this.nextcloudAuthUrl}" <vpu-icon class="nav-icon" name="laptop"></vpu-icon>
web-dav-url="${this.nextcloudWebDavUrl}" </div>
@vpu-nextcloud-file-picker-file-downloaded="${(event) => { <div title="Nextcloud"
this.sendFileEvent(event.detail.file); @click="${() => { this.activeDestination = "nextcloud"; }}"
}}"></vpu-nextcloud-file-picker> class="${classMap({"active": this.activeDestination === "nextcloud", hidden: !this.hasEnabledDestination("nextcloud")})}">
--> <vpu-icon class="nav-icon" name="cloud"></vpu-icon>
</div>
</nav>
<main class="modal-content" id="modal-picker-content">
<button title="${i18n.t('file-sink.modal-close')}" class="modal-close" aria-label="Close modal" data-micromodal-close></button>
<div class="source-main ${classMap({"hidden": this.activeDestination !== "local"})}">
<div id="zip-download-block">
<div class="block">
${this.text || i18n.t('file-sink.local-intro', {'amount': this.files.length})}
</div>
<button class="button is-primary"
?disabled="${this.disabled}"
@click="${() => { this.downloadCompressedFiles(); }}">
${this.buttonLabel || i18n.t('file-sink.local-button')}
</button>
</div>
</div>
<div class="source-main ${classMap({"hidden": this.activeDestination !== "nextcloud"})}">
<vpu-nextcloud-file-picker id="nextcloud-file-picker"
class="${classMap({hidden: this.nextcloudWebDavUrl === "" || this.nextcloudAuthUrl === ""})}"
directories-only
max-selected-items="1"
select-button-text="${i18n.t('file-sink.select-directory')}"
?disabled="${this.disabled}"
lang="${this.lang}"
auth-url="${this.nextcloudAuthUrl}"
web-dav-url="${this.nextcloudWebDavUrl}"
@vpu-nextcloud-file-picker-file-downloaded="${(event) => {
this.uploadToNextcloud(event.detail.file);
}}"></vpu-nextcloud-file-picker>
</div>
</main>
</div>
</div>
</div>
`; `;
} }
} }
\ No newline at end of file
...@@ -15,6 +15,12 @@ ...@@ -15,6 +15,12 @@
"modal-close": "Dialog schließen", "modal-close": "Dialog schließen",
"nav-local": "Lokaler Computer" "nav-local": "Lokaler Computer"
}, },
"file-sink": {
"local-intro": "{{amount}} Datei(en) als ZIP-Datei herunterladen",
"local-button": "ZIP-Datei herunterladen",
"modal-close": "Dialog schließen",
"nav-local": "Lokaler Computer"
},
"nextcloud-file-picker": { "nextcloud-file-picker": {
"open": "Nextcloud", "open": "Nextcloud",
"open-nextcloud-file-picker": "Dateien von Ihrer Nextcloud auswählen", "open-nextcloud-file-picker": "Dateien von Ihrer Nextcloud auswählen",
......
...@@ -15,6 +15,12 @@ ...@@ -15,6 +15,12 @@
"modal-close": "Close dialog", "modal-close": "Close dialog",
"nav-local": "My device" "nav-local": "My device"
}, },
"file-sink": {
"local-intro": "Download {{amount}} file(s) as ZIP-file",
"local-button": "Download ZIP-file",
"modal-close": "Close dialog",
"nav-local": "My device"
},
"nextcloud-file-picker": { "nextcloud-file-picker": {
"open": "Nextcloud", "open": "Nextcloud",
"open-nextcloud-file-picker": "Select files from your Nextcloud", "open-nextcloud-file-picker": "Select files from your Nextcloud",
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment