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

Merge branch 'nextcloud-filepicker-ui' into 'master'

Nextcloud filepicker ui

See merge request VPU/WebComponents/FileHandling!2
parent c0b78483
No related branches found
No related tags found
No related merge requests found
...@@ -12,6 +12,9 @@ import del from 'rollup-plugin-delete'; ...@@ -12,6 +12,9 @@ import del from 'rollup-plugin-delete';
const build = (typeof process.env.BUILD !== 'undefined') ? process.env.BUILD : 'local'; const build = (typeof process.env.BUILD !== 'undefined') ? process.env.BUILD : 'local';
console.log("build: " + build); console.log("build: " + build);
let nextcloudBaseURL = 'https://cloud.tugraz.at';
let nextcloudFileURL = nextcloudBaseURL + '/apps/files/?dir=';
export default { export default {
input: (build !== 'test') ? ['src/demo.js', 'src/vpu-file-source.js'] : glob.sync('test/**/*.js'), input: (build !== 'test') ? ['src/demo.js', 'src/vpu-file-source.js'] : glob.sync('test/**/*.js'),
output: { output: {
...@@ -27,6 +30,8 @@ export default { ...@@ -27,6 +30,8 @@ export default {
}), }),
consts({ consts({
environment: build, environment: build,
nextcloudBaseURL: nextcloudBaseURL,
nextcloudFileURL: nextcloudFileURL,
}), }),
resolve({ resolve({
customResolveOptions: { customResolveOptions: {
......
...@@ -21,6 +21,14 @@ ...@@ -21,6 +21,14 @@
"folder-last": "In das zuletzt ausgewählte Verzeichnis springen", "folder-last": "In das zuletzt ausgewählte Verzeichnis springen",
"folder-up": "In das übergeordnete Verzeichnis springen", "folder-up": "In das übergeordnete Verzeichnis springen",
"folder-home": "In das Home 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"
} }
} }
...@@ -21,6 +21,14 @@ ...@@ -21,6 +21,14 @@
"folder-last": "Jump to the last directory", "folder-last": "Jump to the last directory",
"folder-up": "Jump to the parent directory", "folder-up": "Jump to the parent directory",
"folder-up": "Jump to the home 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"
} }
} }
...@@ -9,6 +9,8 @@ import {createClient} from 'webdav/web'; ...@@ -9,6 +9,8 @@ import {createClient} from 'webdav/web';
import {classMap} from 'lit-html/directives/class-map.js'; import {classMap} from 'lit-html/directives/class-map.js';
import {humanFileSize} from 'vpu-common/i18next'; import {humanFileSize} from 'vpu-common/i18next';
import Tabulator from 'tabulator-tables'; import Tabulator from 'tabulator-tables';
//import nextcloudFileURL from 'consts:nextcloudFileURL'; TODO
import nextcloudBaseURL from 'consts:nextcloudBaseURL';
/** /**
* NextcloudFilePicker web component * NextcloudFilePicker web component
...@@ -88,22 +90,22 @@ export class NextcloudFilePicker extends ScopedElementsMixin(VPULitElement) { ...@@ -88,22 +90,22 @@ export class NextcloudFilePicker extends ScopedElementsMixin(VPULitElement) {
selectable: this.selectNum, selectable: this.selectNum,
selectableRangeMode: "drag", selectableRangeMode: "drag",
columns: [ 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"); const icon_tag = that.constructor.getScopedTagName("vpu-icon");
let icon = `<${icon_tag} name="empty-file"></${icon_tag}>`; let icon = `<${icon_tag} name="empty-file"></${icon_tag}>`;
return (cell.getValue() === "directory") ? `<${icon_tag} name="folder"></${icon_tag}>` : icon; return (cell.getValue() === "directory") ? `<${icon_tag} name="folder"></${icon_tag}>` : icon;
}}, }},
{title: "Filename", field: "basename"}, {title: i18n.t('nextcloud-file-picker.filename'), field: "basename"},
{title: "Size", field: "size", formatter: (cell, formatterParams, onRendered) => { {title: i18n.t('nextcloud-file-picker.size'), field: "size", formatter: (cell, formatterParams, onRendered) => {
return cell.getRow().getData().type === "directory" ? "" : humanFileSize(cell.getValue());}}, 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') { if(typeof cell.getValue() === 'undefined') {
return ""; return "";
} }
const [fileMainType, fileSubType] = cell.getValue().split('/'); const [fileMainType, fileSubType] = cell.getValue().split('/');
return fileSubType; 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 a_timestamp = Date.parse(a);
const b_timestamp = Date.parse(b); const b_timestamp = Date.parse(b);
return a_timestamp - b_timestamp; //you must return the difference between the two values return a_timestamp - b_timestamp; //you must return the difference between the two values
...@@ -186,11 +188,19 @@ export class NextcloudFilePicker extends ScopedElementsMixin(VPULitElement) { ...@@ -186,11 +188,19 @@ export class NextcloudFilePicker extends ScopedElementsMixin(VPULitElement) {
} }
openFilePicker() { openFilePicker() {
// TODO: translation if(this.webDavClient === null)
this.statusText = "Auth in progress"; {
const authUrl = this.authUrl + "?target-origin=" + encodeURIComponent(window.location.href); this.statusText = i18n.t('nextcloud-file-picker.auth-progress');
this.loginWindow = window.open(authUrl, "Nextcloud Login", const authUrl = this.authUrl + "?target-origin=" + encodeURIComponent(window.location.href);
"width=400,height=400,menubar=no,scrollbars=no,status=no,titlebar=no,toolbar=no"); 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) { onReceiveWindowMessage(event) {
...@@ -202,8 +212,9 @@ export class NextcloudFilePicker extends ScopedElementsMixin(VPULitElement) { ...@@ -202,8 +212,9 @@ export class NextcloudFilePicker extends ScopedElementsMixin(VPULitElement) {
// alert("Login name: " + data.loginName + "\nApp password: " + data.token); // alert("Login name: " + data.loginName + "\nApp password: " + data.token);
const apiUrl = this.webDavUrl + "/" + data.loginName; 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 // https://github.com/perry-mitchell/webdav-client/blob/master/API.md#module_WebDAV.createClient
this.webDavClient = createClient( this.webDavClient = createClient(
apiUrl, apiUrl,
{ {
...@@ -212,7 +223,8 @@ export class NextcloudFilePicker extends ScopedElementsMixin(VPULitElement) { ...@@ -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) { ...@@ -222,12 +234,12 @@ export class NextcloudFilePicker extends ScopedElementsMixin(VPULitElement) {
* @param path * @param path
*/ */
loadDirectory(path) { loadDirectory(path) {
// TODO: translation this.statusText = i18n.t('nextcloud-file-picker.loadpath-nextcloud-file-picker');//"Loading directory from Nextcloud: " + path;
this.statusText = "Loading directory from Nextcloud: " + path;
this.lastDirectoryPath = this.directoryPath; this.lastDirectoryPath = this.directoryPath;
this.directoryPath = path; this.directoryPath = path;
// https://github.com/perry-mitchell/webdav-client#getdirectorycontents // https://github.com/perry-mitchell/webdav-client#getdirectorycontents
this.webDavClient this.webDavClient
.getDirectoryContents(path, {details: true}) .getDirectoryContents(path, {details: true})
.then(contents => { .then(contents => {
...@@ -236,10 +248,25 @@ export class NextcloudFilePicker extends ScopedElementsMixin(VPULitElement) { ...@@ -236,10 +248,25 @@ export class NextcloudFilePicker extends ScopedElementsMixin(VPULitElement) {
this.tabulatorTable.setData(contents.data); this.tabulatorTable.setData(contents.data);
this.isPickerActive = true; this.isPickerActive = true;
}).catch(error => { }).catch(error => {
console.error(error.message); console.error(error.message);
this.statusText = error.message;
this.isPickerActive = false; //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) { directoryClicked(event, file) {
...@@ -270,8 +297,8 @@ export class NextcloudFilePicker extends ScopedElementsMixin(VPULitElement) { ...@@ -270,8 +297,8 @@ export class NextcloudFilePicker extends ScopedElementsMixin(VPULitElement) {
this.statusText = ""; this.statusText = "";
}).catch(error => { }).catch(error => {
console.error(error.message); console.error(error.message);
this.statusText = error.message; this.statusText = error.message;
}); });
} }
...@@ -287,6 +314,43 @@ export class NextcloudFilePicker extends ScopedElementsMixin(VPULitElement) { ...@@ -287,6 +314,43 @@ export class NextcloudFilePicker extends ScopedElementsMixin(VPULitElement) {
return (path === "") ? "/" : path; 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() { static get styles() {
// language=css // language=css
return css` return css`
...@@ -322,7 +386,10 @@ export class NextcloudFilePicker extends ScopedElementsMixin(VPULitElement) { ...@@ -322,7 +386,10 @@ export class NextcloudFilePicker extends ScopedElementsMixin(VPULitElement) {
${this.statusText} ${this.statusText}
</div> </div>
<div class="block ${classMap({hidden: !this.isPickerActive})}"> <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" <button class="button is-small"
title="${i18n.t('nextcloud-file-picker.folder-home')}" title="${i18n.t('nextcloud-file-picker.folder-home')}"
@click="${() => { this.loadDirectory("/"); }}"><vpu-icon name="home"></vpu-icon></button> @click="${() => { this.loadDirectory("/"); }}"><vpu-icon name="home"></vpu-icon></button>
......
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