From 2e11923d58bd1afb3de9b1e677e01dc960aa00fb Mon Sep 17 00:00:00 2001
From: Eugen Neuber <eugen.neuber@tugraz.at>
Date: Wed, 22 Jan 2020 16:04:49 +0100
Subject: [PATCH] Add infrastructure

---
 packages/file-handling/.gitignore             |   5 +
 packages/file-handling/.gitlab-ci.yml         |  20 ++++
 packages/file-handling/.gitmodules            |   3 +
 packages/file-handling/README.md              |  34 +++++-
 packages/file-handling/assets/favicon.ico     | Bin 0 -> 2550 bytes
 packages/file-handling/assets/index.html      |  20 ++++
 .../file-handling/i18next-scanner.config.js   |  15 +++
 packages/file-handling/karma.conf.js          |  23 +++++
 packages/file-handling/package.json           |  49 +++++++++
 packages/file-handling/rollup.config.js       |  49 +++++++++
 packages/file-handling/src/demo.js            |  63 ++++++++++++
 packages/file-handling/src/i18n.js            |   6 ++
 .../src/i18n/de/translation.json              |   7 ++
 .../src/i18n/en/translation.json              |   7 ++
 packages/file-handling/src/index.js           |   1 +
 packages/file-handling/src/vpu-fileupload.js  |  97 ++++++++++++++++++
 packages/file-handling/vendor/common          |   1 +
 17 files changed, 398 insertions(+), 2 deletions(-)
 create mode 100644 packages/file-handling/.gitignore
 create mode 100644 packages/file-handling/.gitlab-ci.yml
 create mode 100644 packages/file-handling/.gitmodules
 create mode 100644 packages/file-handling/assets/favicon.ico
 create mode 100644 packages/file-handling/assets/index.html
 create mode 100644 packages/file-handling/i18next-scanner.config.js
 create mode 100644 packages/file-handling/karma.conf.js
 create mode 100644 packages/file-handling/package.json
 create mode 100644 packages/file-handling/rollup.config.js
 create mode 100644 packages/file-handling/src/demo.js
 create mode 100644 packages/file-handling/src/i18n.js
 create mode 100644 packages/file-handling/src/i18n/de/translation.json
 create mode 100644 packages/file-handling/src/i18n/en/translation.json
 create mode 100644 packages/file-handling/src/index.js
 create mode 100644 packages/file-handling/src/vpu-fileupload.js
 create mode 160000 packages/file-handling/vendor/common

diff --git a/packages/file-handling/.gitignore b/packages/file-handling/.gitignore
new file mode 100644
index 00000000..e62f92aa
--- /dev/null
+++ b/packages/file-handling/.gitignore
@@ -0,0 +1,5 @@
+dist
+node_modules
+.idea
+npm-debug.log
+package-lock.json
diff --git a/packages/file-handling/.gitlab-ci.yml b/packages/file-handling/.gitlab-ci.yml
new file mode 100644
index 00000000..9cadb871
--- /dev/null
+++ b/packages/file-handling/.gitlab-ci.yml
@@ -0,0 +1,20 @@
+image: debian:buster
+
+before_script:
+  - apt update
+  - apt install -y git
+  - "sed -i 's|git@gitlab.tugraz.at:VPU|../..|g' .gitmodules"
+  - git submodule sync
+  - git submodule update --init
+
+stages:
+  - test
+
+test:
+  stage: test
+  script:
+    - apt update
+    - apt install -y npm chromium
+    - npm install
+    - npm run build
+    - npm test
diff --git a/packages/file-handling/.gitmodules b/packages/file-handling/.gitmodules
new file mode 100644
index 00000000..d423707d
--- /dev/null
+++ b/packages/file-handling/.gitmodules
@@ -0,0 +1,3 @@
+[submodule "vendor/common"]
+	path = vendor/common
+	url = git@gitlab.tugraz.at:VPU/WebComponents/Common.git
diff --git a/packages/file-handling/README.md b/packages/file-handling/README.md
index 0414e52c..4fcd80e0 100644
--- a/packages/file-handling/README.md
+++ b/packages/file-handling/README.md
@@ -1,3 +1,33 @@
-# FileUpload
+# VPU FileUpload web component
 
-VPU FileUpload web component
\ No newline at end of file
+[GitLab Repository](https://gitlab.tugraz.at/VPU/WebComponents/FileUpload)
+
+## Usage
+
+```html
+<vpu-fileupload></vpu-fileupload>
+```
+
+## Attributes
+
+- `url`: path to the upload url
+    - example `<vpu-fileupload url="path/to/my/page"></vpu-fileupload>`
+- `lang` (optional, default: `de`): set to `de` or `en` for German or English
+    - example `<vpu-fileupload lang="de"></vpu-fileupload>`
+
+## Local development
+
+```bash
+# get the source
+git clone git@gitlab.tugraz.at:VPU/WebComponents/FileUpload.git
+cd FileUpload
+git submodule update --init
+
+# install dependencies (make sure you have npm version 4+ installed, so symlinks to the git submodules are created automatically)
+npm install
+
+# constantly build dist/bundle.js and run a local web-server on port 8002 
+npm run watch-local
+```
+
+Jump to <http://localhost:8002> and you should get a demo page.
diff --git a/packages/file-handling/assets/favicon.ico b/packages/file-handling/assets/favicon.ico
new file mode 100644
index 0000000000000000000000000000000000000000..f6cf22d1afc22f071d2b64c7779bc5214c3adae5
GIT binary patch
literal 2550
zcmZQzU}Ruo5D);-91Iz(3=C=v3{buTLk0^2Lmw*xg9b>9fq_AR0iuq9fq}t+5kx{U
z68r!E{|pQa{~0DTTx0nE<_yEJYwsDZJ%7$HVdYu|hX2M43=C-u3=A_F7#PklFo3wm
z#taO`X$%a;GZ`3+L1O<QO45uO7}C-h7}91kFr=MfU`YE9(KgeVfnjDE1H;Uj3=A{R
zFfh#g4>pS7j4=blnKTB5Gcy?&&YWRjIP;%@;eQ$f!~dBK4FAtC7=ySB#tg;`X$-~;
zGZ~B-&M+7={0BS9*w~oC*f@>B*mx#`vGExOW8?o2C#4xP7^kH%7^lr-FitzeV4U_J
z;>?-G48}9l7>sAmWH6q2hQWB|e~8o17&923Nn<cRGn2vi%ozsbGyfTk{~I$H|4(Bu
z{y&q!80?P!;1B@0B8>qAXELNQoMA{~_|E|LvavBknsFLKn(<7AG~+W2X~zE{!H{Om
zkd~Ilkd`)+Aua6;Bv@t|Go;N-V@R7hlOb&;NbEl(sLmKOq@9_`kap$_L)w}D;Gj$U
zZ_JSPe<nlP|1%6{K>lVp0|`RonG6tk1{^ChjX|N4#xT<u#QzTo>NI19nZ{`hGt*`=
z%uGAOFw^)y!_1k+3^Qk@G0dDflVRpekXipB(E+wQjbY}QnG7?}oMD)G=07-!X8t#3
zn0Y3RVdnpt3^V_qVVL><KPUx2V*(TcGZ{cG14Zu{V`GLh#%T;^jAt^OF+Rg^#`r%Z
zYC-NuOJg{bHk08D$Q^0_A<;e4nBmOKG=?)XXEL0bd4}Q4%>R%iaK@P7%$YQXGiPQp
zoH=ub;mn!;;AC+I<d*+w3}^n&WH<u~53pN6sR0xVAUi=x)tKSGaT>#a<CzTqjn6Rr
zH~tSvPHDyrXVTIb{-@1k_@8!$;Y`|pND`ZA%<z9^8pHpYGa3HRJj3vR=6_JKWB7l@
znBo7KG=~3YW-|OgbB5vnng0y`{~I%$`Jcw{|Nl&e|NqZ0q@{u4D2*ZQKgbS{*&sD(
z42ld(8RFyP8OqDc8QR*~7^Y2|#&G)dX@*UkHZfekex2d&-Mb8rA3tVz_39PF$B!Qw
ze*E~s@ZtA=h9wIYFf=qYfb$^(I6MA_P@s4R<%9qK8RlI}XAod61>+Q628P?~wlQq0
zO=L(CPiHu~?l8mTy^|Ss)%G&jvhy<B<Xg=UC0oa^rAUM!%<3M)xjF9`YL9+lc&VSx
za9-d%gYn~S45u}ZKnnwkC?+N*CS(Ip`5+z`Gk{12FbQHYfmskfm<bUCGr<Iu4>cLY
zgEGMsIv*@Z1_3JiknzL+3=AOLpvb@g!Yzyp3?TfUpMe34!EwRB0Mmn7&Vou?1_lQf
zG8{6Zw7^0SMw9A!m_8UytbUk!d^E@`ba{{%2&0Q*<6~0?5(8m$_1MJF)qwaQbs!94
zBV%l0$nr2YNF5;zQwyUBsYjQG>4VYe@*|rM3l$g*Dq}zxRK|cXsEh$&a2W$CYtYIW
E03q~Dvj6}9

literal 0
HcmV?d00001

diff --git a/packages/file-handling/assets/index.html b/packages/file-handling/assets/index.html
new file mode 100644
index 00000000..858fbdaa
--- /dev/null
+++ b/packages/file-handling/assets/index.html
@@ -0,0 +1,20 @@
+<!doctype html>
+<html>
+<head>
+    <meta charset="UTF-8">
+    <script type="module" id="vpu-fileupload-src" src="bundle.js"></script>
+</head>
+<style>
+  vpu-fileupload-demo {
+      --FUBorderRadius: 10px;
+      --FUBorder: 2px dashed red;
+      --FUMargin: 20px;
+      --FUPadding: 5px;
+  }
+</style>
+<body>
+
+<vpu-fileupload-demo lang="de" url="http://127.0.0.1:8080"></vpu-fileupload-demo>
+
+</body>
+</html>
diff --git a/packages/file-handling/i18next-scanner.config.js b/packages/file-handling/i18next-scanner.config.js
new file mode 100644
index 00000000..8c277798
--- /dev/null
+++ b/packages/file-handling/i18next-scanner.config.js
@@ -0,0 +1,15 @@
+module.exports = {
+    input: [
+        'src/*.js',
+    ],
+    output: './',
+    options: {
+        debug: false,
+        removeUnusedKeys: true,
+        lngs: ['en','de'],
+        resource: {
+            loadPath: 'src/i18n/{{lng}}/{{ns}}.json',
+            savePath: 'src/i18n/{{lng}}/{{ns}}.json'
+        },
+    },
+}
diff --git a/packages/file-handling/karma.conf.js b/packages/file-handling/karma.conf.js
new file mode 100644
index 00000000..6a646f5e
--- /dev/null
+++ b/packages/file-handling/karma.conf.js
@@ -0,0 +1,23 @@
+// Trick to use the auto-downloaded puppeteer chrome binary
+process.env.CHROME_BIN = require('puppeteer').executablePath();
+
+module.exports = function(config) {
+  config.set({
+    basePath: 'dist',
+    frameworks: ['mocha', 'chai'],
+    files: [
+      {pattern: './*.js', included: true, watched: true, served: true, type: 'module'},
+      {pattern: './**/*', included: false, watched: true, served: true},
+    ],
+    autoWatch: true,
+    browsers: ['ChromeHeadlessNoSandbox'],
+    customLaunchers: {
+      ChromeHeadlessNoSandbox: {
+        base: 'ChromeHeadless',
+        flags: ['--no-sandbox']
+      }
+    },
+    singleRun: false,
+    logLevel: config.LOG_ERROR
+  });
+}
diff --git a/packages/file-handling/package.json b/packages/file-handling/package.json
new file mode 100644
index 00000000..5161f5e8
--- /dev/null
+++ b/packages/file-handling/package.json
@@ -0,0 +1,49 @@
+{
+  "name": "vpu-fileupload",
+  "version": "1.0.0",
+  "main": "src/index.js",
+  "devDependencies": {
+    "chai": "^4.2.0",
+    "i18next-scanner": "^2.10.2",
+    "karma": "^4.2.0",
+    "karma-chai": "^0.1.0",
+    "karma-chrome-launcher": "^3.0.0",
+    "karma-mocha": "^1.3.0",
+    "mocha": "^6.2.0",
+    "node-sass": "^4.12.0",
+    "puppeteer": "^1.15.0",
+    "rollup": "^1.20.0",
+    "rollup-plugin-commonjs": "^10.0.2",
+    "rollup-plugin-consts": "^1.0.1",
+    "rollup-plugin-copy": "^3.1.0",
+    "rollup-plugin-delete": "^1.1.0",
+    "rollup-plugin-json": "^4.0.0",
+    "rollup-plugin-multi-entry": "^2.1.0",
+    "rollup-plugin-node-resolve": "^5.2.0",
+    "rollup-plugin-postcss": "^2.0.3",
+    "rollup-plugin-replace": "^2.2.0",
+    "rollup-plugin-serve": "^1.0.1",
+    "rollup-plugin-terser": "^5.1.1",
+    "vpu-common": "file:./vendor/common"
+  },
+  "dependencies": {
+    "i18next": "^17.0.3",
+    "lit-element": "^2.1.0",
+    "lit-html": "^1.1.1",
+    "material-design-icons-svg": "^3.0.0"
+  },
+  "scripts": {
+    "clean": "rm dist/*",
+    "build": "npm run build-local",
+    "build-local": "rollup -c",
+    "build-dev": "rollup -c --environment BUILD:development",
+    "build-prod": "rollup -c --environment BUILD:production",
+    "build-demo": "rollup -c --environment BUILD:demo",
+    "build-test": "rollup -c --environment BUILD:test",
+    "i18next": "i18next-scanner",
+    "watch": "npm run watch-local",
+    "watch-local": "rollup -c --watch",
+    "watch-dev": "rollup -c --watch --environment BUILD:development",
+    "test": "npm run build-test && karma start --singleRun"
+  }
+}
diff --git a/packages/file-handling/rollup.config.js b/packages/file-handling/rollup.config.js
new file mode 100644
index 00000000..69b00ede
--- /dev/null
+++ b/packages/file-handling/rollup.config.js
@@ -0,0 +1,49 @@
+import path from 'path';
+import resolve from 'rollup-plugin-node-resolve';
+import commonjs from 'rollup-plugin-commonjs';
+import copy from 'rollup-plugin-copy';
+import {terser} from "rollup-plugin-terser";
+import json from 'rollup-plugin-json';
+import serve from 'rollup-plugin-serve';
+import multiEntry from 'rollup-plugin-multi-entry';
+import consts from 'rollup-plugin-consts';
+import del from 'rollup-plugin-delete';
+
+const build = (typeof process.env.BUILD !== 'undefined') ? process.env.BUILD : 'local';
+console.log("build: " + build);
+
+export default {
+    input: (build !== 'test') ? 'src/demo.js' : 'test/**/*.js',
+    output: {
+        file: 'dist/bundle.js',
+        format: 'esm'
+    },
+    plugins: [
+        del({
+            targets: 'dist/*'
+        }),
+        multiEntry(),
+        consts({
+            environment: build,
+        }),
+        resolve({
+            customResolveOptions: {
+                // ignore node_modules from vendored packages
+                moduleDirectory: path.join(process.cwd(), 'node_modules')
+            }
+        }),
+        commonjs({
+            include: 'node_modules/**'
+        }),
+        json(),
+        (build !== 'local' && build !== 'test') ? terser() : false,
+        copy({
+            targets: [
+                {src: 'assets/index.html', dest: 'dist'},
+                {src: 'assets/favicon.ico', dest: 'dist'},
+                {src: 'node_modules/material-design-icons-svg/paths/*.json', dest: 'dist/local/vpu-common/icons'},
+            ],
+        }),
+        (process.env.ROLLUP_WATCH === 'true') ? serve({contentBase: 'dist', host: '127.0.0.1', port: 8002}) : false
+    ]
+};
diff --git a/packages/file-handling/src/demo.js b/packages/file-handling/src/demo.js
new file mode 100644
index 00000000..3f705072
--- /dev/null
+++ b/packages/file-handling/src/demo.js
@@ -0,0 +1,63 @@
+import {i18n} from './i18n';
+import {html, LitElement} from 'lit-element';
+import './vpu-fileupload';
+import * as commonUtils from 'vpu-common/utils';
+
+class FileUploadDemo extends LitElement {
+    constructor() {
+        super();
+        this.lang = 'de';
+        this.url = '';
+    }
+
+    static get properties() {
+        return {
+            lang: { type: String },
+            url: { type: String },
+        };
+    }
+
+    update(changedProperties) {
+        changedProperties.forEach((oldValue, propName) => {
+            if (propName === "lang") {
+                i18n.changeLanguage(this.lang);
+            }
+        });
+
+        super.update(changedProperties);
+    }
+
+    render() {
+        return html`
+            <style>
+                vpu-fileupload.clean {
+                    --FUBorder: initial;
+                    --FUBorderRadius: initial;
+                    --FUMargin: initial;
+                    --FUPadding: initial;
+                }
+                vpu-fileupload.opt {
+                    --FUBorder: 2px solid blue;
+                }
+            </style>
+ 
+            <section class="section">
+                <div class="content">
+                    <h1 class="title">File-Upload-Demo</h1>
+                    <p>You need an upload server listening at <tt>${this.url}</tt> to receive the files...</p>
+                </div>
+                <div class="content">
+                    <h2 class="subtitle">Send to Server</h2>
+                    <p>Drop some files here:</p>
+                    <vpu-fileupload lang="de" url="${this.url}"></vpu-fileupload>
+                </div>
+                <div class="content">
+                    <h2>Log of uploads</h2>
+                    <ul id="log"></ul>
+                </div>
+            </section>
+        `;
+    }
+}
+
+commonUtils.defineCustomElement('vpu-fileupload-demo', FileUploadDemo);
diff --git a/packages/file-handling/src/i18n.js b/packages/file-handling/src/i18n.js
new file mode 100644
index 00000000..02c88eb4
--- /dev/null
+++ b/packages/file-handling/src/i18n.js
@@ -0,0 +1,6 @@
+import {createInstance} from 'vpu-common/i18next.js';
+
+import de from './i18n/de/translation.json';
+import en from './i18n/en/translation.json';
+
+export const i18n = createInstance({en: en, de: de}, 'de', 'en');
\ No newline at end of file
diff --git a/packages/file-handling/src/i18n/de/translation.json b/packages/file-handling/src/i18n/de/translation.json
new file mode 100644
index 00000000..6e81531d
--- /dev/null
+++ b/packages/file-handling/src/i18n/de/translation.json
@@ -0,0 +1,7 @@
+{
+  "error-head": "FEHLER: Information",
+  "is-forbidden": "ist verboten",
+  "troubled-server": "macht Probleme am Server",
+  "unknown-problems": "mit unbekanntem Problem",
+  "was-not-found": "wurde nicht gefunden"
+}
diff --git a/packages/file-handling/src/i18n/en/translation.json b/packages/file-handling/src/i18n/en/translation.json
new file mode 100644
index 00000000..05eb31df
--- /dev/null
+++ b/packages/file-handling/src/i18n/en/translation.json
@@ -0,0 +1,7 @@
+{
+  "error-head": "ERROR: information",
+  "is-forbidden": "is forbidden",
+  "troubled-server": "troubled server",
+  "unknown-problems": "with unknown problems",
+  "was-not-found": "was not found"
+}
diff --git a/packages/file-handling/src/index.js b/packages/file-handling/src/index.js
new file mode 100644
index 00000000..c986b9a9
--- /dev/null
+++ b/packages/file-handling/src/index.js
@@ -0,0 +1 @@
+import './vpu-fileupload';
diff --git a/packages/file-handling/src/vpu-fileupload.js b/packages/file-handling/src/vpu-fileupload.js
new file mode 100644
index 00000000..b629a794
--- /dev/null
+++ b/packages/file-handling/src/vpu-fileupload.js
@@ -0,0 +1,97 @@
+import {i18n} from './i18n';
+import {html} from 'lit-element';
+// import JSONLD from 'vpu-common/jsonld';
+import VPULitElement from 'vpu-common/vpu-lit-element'
+import "vpu-common/vpu-mini-spinner.js";
+import * as commonUtils from "vpu-common/utils";
+import {unsafeHTML} from 'lit-html/directives/unsafe-html.js';
+import 'vpu-common/vpu-icon.js';
+
+/**
+ * KnowledgeBaseWebPageElementView web component
+ */
+class VPUFileUpload extends VPULitElement {
+    constructor() {
+        super();
+        this.lang = 'de';
+        this.url = '';
+    }
+
+    /**
+     * See: https://lit-element.polymer-project.org/guide/properties#initialize
+     */
+    static get properties() {
+        return {
+            lang: { type: String },
+            url: { type: String },
+        };
+    }
+
+
+    update(changedProperties) {
+        changedProperties.forEach((oldValue, propName) => {
+            if (propName === "lang") {
+                i18n.changeLanguage(this.lang);
+            }
+        });
+
+        super.update(changedProperties);
+    }
+
+
+    render() {
+        return html`
+            <style>
+        #drop-area {
+            border: 2px dashed #ccc;
+            border-radius: 20px;
+            width: 480px;
+            font-family: sans-serif;
+            margin: 100px auto;
+            padding: 20px;
+        }
+        #drop-area.highlight {
+            border-color: purple;
+        }
+        p {
+            margin-top: 0;
+        }
+        .my-form {
+            margin-bottom: 10px;
+        }
+        #gallery {
+            margin-top: 10px;
+        }
+        #gallery img {
+            width: 150px;
+            margin-bottom: 10px;
+            margin-right: 10px;
+            vertical-align: middle;
+        }
+        .button {
+            display: inline-block;
+            padding: 10px;
+            background: #ccc;
+            cursor: pointer;
+            border-radius: 5px;
+            border: 1px solid #ccc;
+        }
+        .button:hover {
+            background: #ddd;
+        }
+        #fileElem {
+            display: none;
+        }
+            </style>
+            <div id="drop-area">
+                <form class="my-form">
+                    <p>Upload multiple files with the file dialog or by dragging and dropping images onto the dashed region</p>
+                    <input type="file" id="fileElem" multiple accept="image/*" name='my_file' onchange="handleFiles(this.files)">
+                    <label class="button" for="fileElem">Select some files</label>
+                </form>
+            </div>
+        `;
+    }
+}
+
+commonUtils.defineCustomElement('vpu-fileupload', VPUFileUpload);
diff --git a/packages/file-handling/vendor/common b/packages/file-handling/vendor/common
new file mode 160000
index 00000000..5aa64ec4
--- /dev/null
+++ b/packages/file-handling/vendor/common
@@ -0,0 +1 @@
+Subproject commit 5aa64ec47e7b65d69327f4dec1102917fe33bd22
-- 
GitLab