diff --git a/packages/file-handling/rollup.config.js b/packages/file-handling/rollup.config.js index deba392948445e821c6ac78593a24e448650d072..741134931fda2d6c356c274ba1de4170d828feb8 100644 --- a/packages/file-handling/rollup.config.js +++ b/packages/file-handling/rollup.config.js @@ -12,6 +12,9 @@ import del from 'rollup-plugin-delete'; const build = (typeof process.env.BUILD !== 'undefined') ? process.env.BUILD : 'local'; console.log("build: " + build); +let nextcloudBaseURL = 'https://cloud.tugraz.at'; +let nextcloudFileURL = nextcloudBaseURL + '/apps/files/?dir='; + export default { input: (build !== 'test') ? ['src/demo.js', 'src/vpu-file-source.js'] : glob.sync('test/**/*.js'), output: { @@ -27,6 +30,8 @@ export default { }), consts({ environment: build, + nextcloudBaseURL: nextcloudBaseURL, + nextcloudFileURL: nextcloudFileURL, }), resolve({ customResolveOptions: { diff --git a/packages/file-handling/src/i18n/de/translation.json b/packages/file-handling/src/i18n/de/translation.json index 64e5b3acf1443bac32a138d464aaf438b97f8592..27ae5492ab3ee5d149164f60e82581e16e1c05d3 100644 --- a/packages/file-handling/src/i18n/de/translation.json +++ b/packages/file-handling/src/i18n/de/translation.json @@ -21,6 +21,14 @@ "folder-last": "In das zuletzt ausgewählte Verzeichnis springen", "folder-up": "In das übergeordnete Verzeichnis springen", "folder-home": "In das Home Verzeichnis springen", - "select-files": "Dateien auswählen" + "select-files": "Dateien auswählen", + "refresh-nextcloud-file-picker": "Erneut verbinden", + "loadpath-nextcloud-file-picker": "Das Nextcloud Verzeichnis wird geladen", + "load-path-link": "Gehe zu {{path}}", + "auth-progress": "Anmeldung läuft", + "last-modified": "Geändert", + "mime-type": "Art", + "filename": "Name", + "size": "Größe" } } diff --git a/packages/file-handling/src/i18n/en/translation.json b/packages/file-handling/src/i18n/en/translation.json index 248ddca415bbe94eea4d25177fd966009c065b65..5f61a5cd7e0f54c7418f6ec538a99d917626379e 100644 --- a/packages/file-handling/src/i18n/en/translation.json +++ b/packages/file-handling/src/i18n/en/translation.json @@ -21,6 +21,14 @@ "folder-last": "Jump to the last directory", "folder-up": "Jump to the parent directory", "folder-up": "Jump to the home directory", - "select-files": "Select files" + "select-files": "Select files", + "refresh-nextcloud-file-picker": "Connect again", + "loadpath-nextcloud-file-picker": "Loading directory from Nextcloud", + "load-path-link": "Go to {{path}}", + "auth-progress": "Authentification in progress", + "last-modified": "Last modified", + "mime-type": "Type", + "filename": "Filename", + "size": "Size" } } diff --git a/packages/file-handling/src/vpu-nextcloud-file-picker.js b/packages/file-handling/src/vpu-nextcloud-file-picker.js index 7dcbd49c8ce4b27d9d2f006b4ef1dadd2de5e273..c67df633075045c71d6c6f4d16d15f58c1c9439a 100644 --- a/packages/file-handling/src/vpu-nextcloud-file-picker.js +++ b/packages/file-handling/src/vpu-nextcloud-file-picker.js @@ -9,6 +9,8 @@ import {createClient} from 'webdav/web'; import {classMap} from 'lit-html/directives/class-map.js'; import {humanFileSize} from 'vpu-common/i18next'; import Tabulator from 'tabulator-tables'; +//import nextcloudFileURL from 'consts:nextcloudFileURL'; TODO +import nextcloudBaseURL from 'consts:nextcloudBaseURL'; /** * NextcloudFilePicker web component @@ -88,22 +90,22 @@ export class NextcloudFilePicker extends ScopedElementsMixin(VPULitElement) { selectable: this.selectNum, selectableRangeMode: "drag", columns: [ - {title: "Type", field: "type", align:"center", formatter: (cell, formatterParams, onRendered) => { + {title: "", field: "type", align:"center", formatter: (cell, formatterParams, onRendered) => { const icon_tag = that.constructor.getScopedTagName("vpu-icon"); let icon = `<${icon_tag} name="empty-file"></${icon_tag}>`; return (cell.getValue() === "directory") ? `<${icon_tag} name="folder"></${icon_tag}>` : icon; }}, - {title: "Filename", field: "basename"}, - {title: "Size", field: "size", formatter: (cell, formatterParams, onRendered) => { + {title: i18n.t('nextcloud-file-picker.filename'), field: "basename"}, + {title: i18n.t('nextcloud-file-picker.size'), field: "size", formatter: (cell, formatterParams, onRendered) => { return cell.getRow().getData().type === "directory" ? "" : humanFileSize(cell.getValue());}}, - {title: "Mime", field: "mime", formatter: (cell, formatterParams, onRendered) => { + {title: i18n.t('nextcloud-file-picker.mime-type'), field: "mime", formatter: (cell, formatterParams, onRendered) => { if(typeof cell.getValue() === 'undefined') { return ""; } const [fileMainType, fileSubType] = cell.getValue().split('/'); return fileSubType; }}, - {title: "Last modified", field: "lastmod",sorter: (a, b, aRow, bRow, column, dir, sorterParams) => { + {title: i18n.t('nextcloud-file-picker.last-modified'), field: "lastmod",sorter: (a, b, aRow, bRow, column, dir, sorterParams) => { const a_timestamp = Date.parse(a); const b_timestamp = Date.parse(b); return a_timestamp - b_timestamp; //you must return the difference between the two values @@ -186,11 +188,19 @@ export class NextcloudFilePicker extends ScopedElementsMixin(VPULitElement) { } openFilePicker() { - // TODO: translation - this.statusText = "Auth in progress"; - const authUrl = this.authUrl + "?target-origin=" + encodeURIComponent(window.location.href); - this.loginWindow = window.open(authUrl, "Nextcloud Login", - "width=400,height=400,menubar=no,scrollbars=no,status=no,titlebar=no,toolbar=no"); + if(this.webDavClient === null) + { + this.statusText = i18n.t('nextcloud-file-picker.auth-progress'); + const authUrl = this.authUrl + "?target-origin=" + encodeURIComponent(window.location.href); + this.loginWindow = window.open(authUrl, "Nextcloud Login", + "width=400,height=400,menubar=no,scrollbars=no,status=no,titlebar=no,toolbar=no"); + } + else { + + this.loadDirectory(this.directoryPath, this.webDavClient); + + } + } onReceiveWindowMessage(event) { @@ -202,8 +212,9 @@ export class NextcloudFilePicker extends ScopedElementsMixin(VPULitElement) { // alert("Login name: " + data.loginName + "\nApp password: " + data.token); const apiUrl = this.webDavUrl + "/" + data.loginName; - + console.log("url: ", this.webDavUrl); // https://github.com/perry-mitchell/webdav-client/blob/master/API.md#module_WebDAV.createClient + this.webDavClient = createClient( apiUrl, { @@ -212,7 +223,8 @@ export class NextcloudFilePicker extends ScopedElementsMixin(VPULitElement) { } ); - this.loadDirectory("/"); + this.loadDirectory(this.directoryPath); + } } @@ -222,12 +234,12 @@ export class NextcloudFilePicker extends ScopedElementsMixin(VPULitElement) { * @param path */ loadDirectory(path) { - // TODO: translation - this.statusText = "Loading directory from Nextcloud: " + path; + this.statusText = i18n.t('nextcloud-file-picker.loadpath-nextcloud-file-picker');//"Loading directory from Nextcloud: " + path; this.lastDirectoryPath = this.directoryPath; this.directoryPath = path; // https://github.com/perry-mitchell/webdav-client#getdirectorycontents + this.webDavClient .getDirectoryContents(path, {details: true}) .then(contents => { @@ -236,10 +248,25 @@ export class NextcloudFilePicker extends ScopedElementsMixin(VPULitElement) { this.tabulatorTable.setData(contents.data); this.isPickerActive = true; }).catch(error => { - console.error(error.message); - this.statusText = error.message; - this.isPickerActive = false; + console.error(error.message); + + //try to reload with home directory + if(path != "/"){ + this.loadDirectory("/"); + } + else { + this.statusText = error.message; + this.isPickerActive = false; + } + + //client is broken reload try to reset & reconnect + this.webDavClient = null; + let reloadButton = html`<button class="button" + title="${i18n.t('nextcloud-file-picker.refresh-nextcloud-file-picker')}" + @click="${async () => { this.openFilePicker(); } }"><vpu-icon name="reload"></button>`; + this.statusText = reloadButton; }); + } directoryClicked(event, file) { @@ -270,8 +297,8 @@ export class NextcloudFilePicker extends ScopedElementsMixin(VPULitElement) { this.statusText = ""; }).catch(error => { - console.error(error.message); - this.statusText = error.message; + console.error(error.message); + this.statusText = error.message; }); } @@ -287,6 +314,43 @@ export class NextcloudFilePicker extends ScopedElementsMixin(VPULitElement) { return (path === "") ? "/" : path; } + /** + * Returns the directory path as clickable breadcrumbs + * + * @returns {string} clickable breadcrumb path + */ + getBreadcrumb() { + let htmlpath = []; + htmlpath[0] = html`<a @click="${() => { this.loadDirectory("/"); }}" title="${i18n.t('nextcloud-file-picker.folder-home')}"><vpu-icon name="home"></vpu-icon></a>`; + const directories = this.directoryPath.split('/'); + + for(let i = 1; i < directories.length; i ++) + { + let path = ""; + for(let j = 1; j <= i; j++) + { + path += "/"; + path += directories[j]; + } + + htmlpath[i] = html` / <a @click="${() => { this.loadDirectory(path); }}" title="${i18n.t('nextcloud-file-picker.load-path-link', {path: directories[i]})}">${directories[i]}</a>`; + } + + return htmlpath; + } + + /** + * Returns the directory path as clickable breadcrumbs + * + * @returns {string} clickable breadcrumb path + */ + getNextCloudLink() { + //später ersetzen durch: + //let link = nextcloudFileURL + this.directoryPath; + let link = nextcloudBaseURL + '/apps/files/?dir=' + this.directoryPath; + return link; + } + static get styles() { // language=css return css` @@ -322,7 +386,10 @@ export class NextcloudFilePicker extends ScopedElementsMixin(VPULitElement) { ${this.statusText} </div> <div class="block ${classMap({hidden: !this.isPickerActive})}"> - <h2>${this.directoryPath}</h2> + <h2>${this.getBreadcrumb()}</h2> + <a class="button is-small" + title="${i18n.t('nextcloud-file-picker.open-in-nextcloud')}" + href="${this.getNextCloudLink()}" target="_blank">open in nc</a> <button class="button is-small" title="${i18n.t('nextcloud-file-picker.folder-home')}" @click="${() => { this.loadDirectory("/"); }}"><vpu-icon name="home"></vpu-icon></button>